aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libqmenumodel/src/converter.cpp132
-rw-r--r--libqmenumodel/src/converter.h4
-rw-r--r--libqmenumodel/src/unitymenumodel.cpp16
-rw-r--r--tests/client/convertertest.cpp53
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 031de9a..3ea61ec 100644
--- a/libqmenumodel/src/unitymenumodel.cpp
+++ b/libqmenumodel/src/unitymenumodel.cpp
@@ -621,13 +621,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)