aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Uebernickel <lars.uebernickel@canonical.com>2013-07-25 06:09:59 +0200
committerLars Uebernickel <lars.uebernickel@canonical.com>2013-07-25 06:09:59 +0200
commitca81974f1fe8454c725e80aa943705d40398a2ad (patch)
treef6549c3fdddef6ef2ae7bfd4aecc4106be389d4d
parent6aaafd55328c1860fd1b734fa29ff77673538a2b (diff)
downloadqmenumodel-ca81974f1fe8454c725e80aa943705d40398a2ad.tar.gz
qmenumodel-ca81974f1fe8454c725e80aa943705d40398a2ad.tar.bz2
qmenumodel-ca81974f1fe8454c725e80aa943705d40398a2ad.zip
unitymenumodel: expose type and extended attributes to qml
-rw-r--r--libqmenumodel/src/gtk/gtkmenutrackeritem.c41
-rw-r--r--libqmenumodel/src/gtk/gtkmenutrackeritem.h9
-rw-r--r--libqmenumodel/src/unitymenumodel.cpp114
-rw-r--r--libqmenumodel/src/unitymenumodel.h1
4 files changed, 164 insertions, 1 deletions
diff --git a/libqmenumodel/src/gtk/gtkmenutrackeritem.c b/libqmenumodel/src/gtk/gtkmenutrackeritem.c
index 2d712a1..356422d 100644
--- a/libqmenumodel/src/gtk/gtkmenutrackeritem.c
+++ b/libqmenumodel/src/gtk/gtkmenutrackeritem.c
@@ -786,3 +786,44 @@ gtk_menu_tracker_item_request_submenu_shown (GtkMenuTrackerItem *self,
else
gtk_menu_tracker_item_set_submenu_shown (self, shown);
}
+
+gboolean
+gtk_menu_tracker_item_get_attribute (GtkMenuTrackerItem *self,
+ const gchar *attribute,
+ const gchar *format,
+ ...)
+{
+ gboolean success = FALSE;
+ GVariant *value;
+
+ g_return_val_if_fail (GTK_IS_MENU_TRACKER_ITEM (self), FALSE);
+ g_return_val_if_fail (attribute != NULL, FALSE);
+ g_return_val_if_fail (format != NULL, FALSE);
+
+ value = g_menu_item_get_attribute_value (self->item, attribute, NULL);
+ if (value)
+ {
+ if (g_variant_check_format_string (value, format, TRUE))
+ {
+ va_list args;
+
+ va_start (args, format);
+ g_variant_get_va (value, format, NULL, &args);
+ va_end (args);
+
+ success = TRUE;
+ }
+
+ g_variant_unref (value);
+ }
+
+ return success;
+}
+
+GVariant *
+gtk_menu_tracker_item_get_attribute_value (GtkMenuTrackerItem *self,
+ const gchar *attribute,
+ const GVariantType *expected_type)
+{
+ return g_menu_item_get_attribute_value (self->item, attribute, expected_type);
+}
diff --git a/libqmenumodel/src/gtk/gtkmenutrackeritem.h b/libqmenumodel/src/gtk/gtkmenutrackeritem.h
index 9db30eb..7e98a55 100644
--- a/libqmenumodel/src/gtk/gtkmenutrackeritem.h
+++ b/libqmenumodel/src/gtk/gtkmenutrackeritem.h
@@ -81,4 +81,13 @@ void gtk_menu_tracker_item_request_submenu_shown (GtkMenu
gboolean gtk_menu_tracker_item_get_submenu_shown (GtkMenuTrackerItem *self);
+gboolean gtk_menu_tracker_item_get_attribute (GtkMenuTrackerItem *self,
+ const gchar *attribute,
+ const gchar *format,
+ ...);
+
+GVariant * gtk_menu_tracker_item_get_attribute_value (GtkMenuTrackerItem *self,
+ const gchar *attribute,
+ const GVariantType *expected_type);
+
#endif
diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp
index db70936..0fc5612 100644
--- a/libqmenumodel/src/unitymenumodel.cpp
+++ b/libqmenumodel/src/unitymenumodel.cpp
@@ -26,13 +26,16 @@ extern "C" {
G_DEFINE_QUARK (UNITY_MENU_MODEL, unity_menu_model)
G_DEFINE_QUARK (UNITY_SUBMENU_MODEL, unity_submenu_model)
G_DEFINE_QUARK (UNITY_MENU_ITEM_ITERATOR, unity_menu_item_iterator)
+G_DEFINE_QUARK (UNITY_MENU_ITEM_EXTENDED_ATTRIBUTES, unity_menu_item_extended_attributes)
enum MenuRoles {
ActionRole = Qt::DisplayRole + 1,
LabelRole,
SensitiveRole,
IsSeparatorRole,
- IconRole
+ IconRole,
+ TypeRole,
+ ExtendedAttributesRole,
};
class UnityMenuModelPrivate
@@ -348,6 +351,22 @@ QVariant UnityMenuModel::data(const QModelIndex &index, int role) const
return QString();
}
+ case TypeRole: {
+ gchar *type;
+ if (gtk_menu_tracker_item_get_attribute (item, "x-canonical-type", "s", &type)) {
+ QVariant v(type);
+ g_free (type);
+ return v;
+ }
+ else
+ return QVariant();
+ }
+
+ case ExtendedAttributesRole: {
+ QVariantMap *map = (QVariantMap *) g_object_get_qdata (G_OBJECT (item), unity_menu_item_extended_attributes_quark ());
+ return map ? *map : QVariant();
+ }
+
default:
return QVariant();
}
@@ -372,6 +391,8 @@ QHash<int, QByteArray> UnityMenuModel::roleNames() const
names[SensitiveRole] = "sensitive";
names[IsSeparatorRole] = "isSeparator";
names[IconRole] = "icon";
+ names[TypeRole] = "type";
+ names[ExtendedAttributesRole] = "ext";
return names;
}
@@ -411,3 +432,94 @@ void UnityMenuModel::activate(int index)
item = (GtkMenuTrackerItem *) g_sequence_get (g_sequence_get_iter_at_pos (priv->items, index));
gtk_menu_tracker_item_activated (item);
}
+
+static void freeExtendedAttrs(gpointer data)
+{
+ QVariantMap *extendedAttrs = (QVariantMap *) data;
+ delete extendedAttrs;
+}
+
+static QVariant attributeToQVariant(GVariant *value, const QString &type)
+{
+ QVariant result;
+
+ if (type == "int") {
+ if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT32))
+ result = QVariant(g_variant_get_int32(value));
+ }
+ if (type == "bool") {
+ if (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN))
+ result = QVariant(g_variant_get_int32(value));
+ }
+ else if (type == "string") {
+ if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+ result = QVariant(g_variant_get_string(value, NULL));
+ }
+ else if (type == "icon") {
+ GIcon *icon = g_icon_deserialize (value);
+ if (icon) {
+ result = iconUri(icon);
+ g_object_unref (icon);
+ }
+ else {
+ result = QVariant("");
+ }
+ }
+
+ return result;
+}
+
+/* convert 'some-key' to 'someKey' or 'SomeKey'. (from dconf-qt) */
+static QString qtify_name(const char *name)
+{
+ bool next_cap = false;
+ QString result;
+
+ while (*name) {
+ if (*name == '-') {
+ next_cap = true;
+ } else if (next_cap) {
+ result.append(toupper(*name));
+ next_cap = false;
+ } else {
+ result.append(*name);
+ }
+
+ name++;
+ }
+
+ return result;
+}
+
+bool UnityMenuModel::loadExtendedAttributes(int position, const QVariantMap &schema)
+{
+ GtkMenuTrackerItem *item;
+ QVariantMap *extendedAttrs;
+
+ item = (GtkMenuTrackerItem *) g_sequence_get (g_sequence_get_iter_at_pos (priv->items, position));
+
+ extendedAttrs = new QVariantMap;
+
+ for (QVariantMap::const_iterator it = schema.constBegin(); it != schema.constEnd(); ++it) {
+ QString name = it.key();
+ QString type = it.value().toString();
+
+ GVariant *value = gtk_menu_tracker_item_get_attribute_value (item, name.toUtf8(), NULL);
+ if (value == NULL) {
+ qWarning("loadExtendedAttributes: menu item does not contain '%s'", it.key().toUtf8().constData());
+ continue;
+ }
+
+ QVariant qvalue = attributeToQVariant(value, type);
+ if (qvalue.isValid())
+ extendedAttrs->insert(qtify_name (name.toUtf8()), qvalue);
+ else
+ qWarning("loadExtendedAttributes: key '%s' is of type '%s' (expected '%s')",
+ name.toUtf8().constData(), g_variant_get_type_string(value), type.constData());
+
+ g_variant_unref (value);
+ }
+
+ g_object_set_qdata_full (G_OBJECT (item), unity_menu_item_extended_attributes_quark (),
+ extendedAttrs, freeExtendedAttrs);
+}
diff --git a/libqmenumodel/src/unitymenumodel.h b/libqmenumodel/src/unitymenumodel.h
index 896c806..9151217 100644
--- a/libqmenumodel/src/unitymenumodel.h
+++ b/libqmenumodel/src/unitymenumodel.h
@@ -49,6 +49,7 @@ public:
QHash<int, QByteArray> roleNames() const;
Q_INVOKABLE QObject * submenu(int position);
+ Q_INVOKABLE bool loadExtendedAttributes(int position, const QVariantMap &schema);
Q_SIGNALS:
void busNameChanged(const QByteArray &name);