diff options
-rw-r--r-- | libqmenumodel/src/converter.cpp | 132 | ||||
-rw-r--r-- | libqmenumodel/src/converter.h | 4 | ||||
-rw-r--r-- | libqmenumodel/src/unitymenumodel.cpp | 16 | ||||
-rw-r--r-- | tests/client/convertertest.cpp | 53 |
4 files changed, 203 insertions, 2 deletions
diff --git a/libqmenumodel/src/converter.cpp b/libqmenumodel/src/converter.cpp index d9d90bd..69e6629 100644 --- a/libqmenumodel/src/converter.cpp +++ b/libqmenumodel/src/converter.cpp @@ -195,3 +195,135 @@ GVariant* Converter::toGVariant(const QVariant &value) return result; } +GVariant* Converter::toGVariantWithSchema(const QVariant &value, const char* schema) +{ + if (!g_variant_type_string_is_valid(schema)) { + return Converter::toGVariant(value); + } + + GVariant* result = NULL; + const GVariantType* schema_type; + schema_type = g_variant_type_new(schema); + + if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_BOOLEAN)) { + if (value.canConvert<bool>()) { + result = g_variant_new_boolean (value.value<bool>()); + } + } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_BYTE)) { + if (value.canConvert<uchar>()) { + result = g_variant_new_byte (value.value<uchar>()); + } + } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_INT16)) { + if (value.canConvert<qint16>()) { + result = g_variant_new_int16 (value.value<qint16>()); + } + } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_UINT16)) { + if (value.canConvert<quint16>()) { + result = g_variant_new_uint16 (value.value<quint16>()); + } + } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_INT32)) { + if (value.canConvert<qint32>()) { + result = g_variant_new_int32 (value.value<qint32>()); + } + } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_UINT32)) { + if (value.canConvert<quint32>()) { + result = g_variant_new_uint32 (value.value<quint32>()); + } + } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_INT64)) { + if (value.canConvert<qint64>()) { + result = g_variant_new_int64 (value.value<qint64>()); + } + } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_UINT64)) { + if (value.canConvert<quint64>()) { + result = g_variant_new_uint64 (value.value<quint64>()); + } + } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_DOUBLE)) { + if (value.canConvert<double>()) { + result = g_variant_new_double (value.value<double>()); + } + } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_STRING)) { + if (value.canConvert<QString>()) { + result = g_variant_new_string(value.toString().toUtf8().data()); + } + } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_VARIANT)) { + result = Converter::toGVariant(value); + } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_VARDICT)) { + if (value.canConvert(QVariant::Map)) { + result = Converter::toGVariant(value.toMap()); + } + } else if (g_variant_type_is_array(schema_type)) { + if (value.canConvert(QVariant::List)) { + + const GVariantType* entry_type; + GVariant* data; + entry_type = g_variant_type_element(schema_type); + gchar* entryTypeString = g_variant_type_dup_string(entry_type); + + QVariantList lst = value.toList(); + GVariant **vars = g_new(GVariant*, lst.size()); + + bool ok = true; + for (int i=0; i < lst.size(); i++) { + data = Converter::toGVariantWithSchema(lst[i], entryTypeString); + + if (data) { + vars[i] = data; + } + else { + ok = false; + qWarning() << "Failed to convert list to array with schema:" << schema; + break; + } + } + if (ok) { + result = g_variant_new_array(entry_type, vars, lst.size()); + } + g_free(entryTypeString); + g_free(vars); + } + } else if (g_variant_type_is_tuple(schema_type)) { + if (value.canConvert(QVariant::List)) { + GVariant* data; + + QVariantList lst = value.toList(); + GVariant **vars = g_new(GVariant*, lst.size()); + + const GVariantType* entry_type = g_variant_type_first(schema_type); + + bool ok = true; + for (int i=0; i < lst.size(); i++) { + + gchar* entryTypeString = g_variant_type_dup_string(entry_type); + + data = Converter::toGVariantWithSchema(lst[i], entryTypeString); + + if (data) { + vars[i] = data; + } + else { + ok = false; + qWarning() << "Failed to convert list to tuple with schema:" << schema; + g_free(entryTypeString); + break; + } + g_free(entryTypeString); + + entry_type = g_variant_type_next(entry_type); + if (!entry_type) { + break; + } + } + if (ok) { + result = g_variant_new_tuple(vars, lst.size()); + } + g_free(vars); + } + } + + // fallback to straight convert. + if (!result) { + result = Converter::toGVariant(value); + } + return result; +} + diff --git a/libqmenumodel/src/converter.h b/libqmenumodel/src/converter.h index 5f05bc7..f47c09e 100644 --- a/libqmenumodel/src/converter.h +++ b/libqmenumodel/src/converter.h @@ -28,6 +28,10 @@ class Converter public: static QVariant toQVariant(GVariant *value); static GVariant* toGVariant(const QVariant &value); + + // This converts a QVariant to a GVariant using a provided gvariant schema as + // a conversion base (it will attempt to convert to this format). + static GVariant* toGVariantWithSchema(const QVariant &value, const char* schema); }; #endif // CONVERTER_H diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp index e5407ab..50eff1c 100644 --- a/libqmenumodel/src/unitymenumodel.cpp +++ b/libqmenumodel/src/unitymenumodel.cpp @@ -607,13 +607,25 @@ void UnityMenuModel::activate(int index, const QVariant& parameter) void UnityMenuModel::changeState(int index, const QVariant& parameter) { GtkMenuTrackerItem* item; + GVariant* data; + GVariant* current_state; item = (GtkMenuTrackerItem *) g_sequence_get (g_sequence_get_iter_at_pos (priv->items, index)); if (!item) return; - GVariant* data = Converter::toGVariant(parameter); + current_state = gtk_menu_tracker_item_get_action_state (item); + if (current_state) { + // Attempt to convert the parameter to the expected type + data = Converter::toGVariantWithSchema(parameter, g_variant_get_type_string(current_state)); + g_variant_unref (current_state); + } else { + data = Converter::toGVariant(parameter); + } + gtk_menu_tracker_item_change_state (item, data); - g_variant_unref(data); + if (data) { + g_variant_unref(data); + } } diff --git a/tests/client/convertertest.cpp b/tests/client/convertertest.cpp index f382332..db2807f 100644 --- a/tests/client/convertertest.cpp +++ b/tests/client/convertertest.cpp @@ -45,6 +45,22 @@ private: g_variant_unref(gv); return result; } + bool compareWithSchema(const QVariant &qv, const QString strType) + { + GVariantType* expected_type; + expected_type = g_variant_type_new(strType.toUtf8().data()); + + bool result; + GVariant *gv = Converter::toGVariantWithSchema(qv, strType.toUtf8().data()); + result = g_variant_type_equal(g_variant_get_type(gv), expected_type); + if (!result) { + qWarning() << "types are different: QVariant:" << qv.typeName() + << "Result:" << (const char*) g_variant_get_type(gv) + << "Expected:"<< (const char*) expected_type; + } + g_variant_unref(gv); + return result; + } private Q_SLOTS: @@ -118,6 +134,43 @@ private Q_SLOTS: g_variant_unref(gTuple); } + void testSchemaConvert() + { + // convert to integer + compareWithSchema(QVariant::fromValue<int>(1), "i"); + compareWithSchema(QVariant::fromValue<double>(1.1), "i"); + + // convert to integer + compareWithSchema(QVariant::fromValue<bool>(true), "b"); + compareWithSchema(QVariant::fromValue<int>(1), "b"); + + // convert to double + compareWithSchema(QVariant::fromValue<double>(1.0), "d"); + compareWithSchema(QVariant::fromValue<int>(1), "d"); + + // convert to string + compareWithSchema(QVariant::fromValue<int>(1), "s"); + compareWithSchema(QVariant::fromValue<double>(1.1), "s"); + + // convert to tuple + compareWithSchema(QVariantList() << QVariant::fromValue<bool>(true) << QVariant::fromValue<int>(1) << QVariant::fromValue<int>(1) << QVariant::fromValue<QString>("test1"), "(bdis)"); + + // convert to array + compareWithSchema(QVariantList() << QVariant::fromValue<int>(1) << QVariant::fromValue<int>(1), "ad"); + compareWithSchema(QVariantList() << QVariant::fromValue<QString>("test1") << QVariant::fromValue<QString>("test2"), "as"); + + // convert to array of tuple + QVariantList si1(QVariantList() << QVariant::fromValue<QString>("test1") << QVariant::fromValue<int>(1)); + QVariantList si2(QVariantList() << QVariant::fromValue<QString>("test1") << QVariant::fromValue<int>(1)); + compareWithSchema(QVariantList() << QVariant::fromValue(si1) << QVariant::fromValue(si2), "a(sd)"); + + // convert to vardict + QVariantMap map; + map["test1"] = QVariant::fromValue<int>(1); + map["test2"] = QVariant::fromValue<double>(1); + compareWithSchema(map, "a{sv}"); + } + }; QTEST_MAIN(ConverterTest) |