aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libqmenumodel/src/CMakeLists.txt2
-rw-r--r--libqmenumodel/src/actionstateparser.cpp34
-rw-r--r--libqmenumodel/src/actionstateparser.h37
-rw-r--r--libqmenumodel/src/unitymenumodel.cpp63
-rw-r--r--libqmenumodel/src/unitymenumodel.h9
5 files changed, 130 insertions, 15 deletions
diff --git a/libqmenumodel/src/CMakeLists.txt b/libqmenumodel/src/CMakeLists.txt
index 24b65d2..cf9c426 100644
--- a/libqmenumodel/src/CMakeLists.txt
+++ b/libqmenumodel/src/CMakeLists.txt
@@ -1,6 +1,7 @@
project(src)
set(QMENUMODEL_SRC
+ actionstateparser.cpp
converter.cpp
dbus-enums.h
menunode.cpp
@@ -49,6 +50,7 @@ qt5_use_modules(${SHAREDLIBNAME} Core Qml Quick)
install(TARGETS ${SHAREDLIBNAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
set(QMENUMODEL_HEADERS
+ actionstateparser.h
dbus-enums.h
qdbusactiongroup.h
qdbusmenumodel.h
diff --git a/libqmenumodel/src/actionstateparser.cpp b/libqmenumodel/src/actionstateparser.cpp
new file mode 100644
index 0000000..6637b56
--- /dev/null
+++ b/libqmenumodel/src/actionstateparser.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Nick Dedekind <nick.dedekind@canonical.com>
+ */
+
+#include "actionstateparser.h"
+#include "converter.h"
+
+ActionStateParser::ActionStateParser(QObject* parent)
+ : QObject(parent)
+{
+}
+
+QVariant ActionStateParser::toQVariant(GVariant* state) const
+{
+ if (state) {
+ return Converter::toQVariant(state);
+ }
+ return QVariant();
+} \ No newline at end of file
diff --git a/libqmenumodel/src/actionstateparser.h b/libqmenumodel/src/actionstateparser.h
new file mode 100644
index 0000000..044dea1
--- /dev/null
+++ b/libqmenumodel/src/actionstateparser.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Nick Dedekind <nick.dedekind@canonical.com>
+ */
+
+#ifndef ACTIONSTATEPARSER_H
+#define ACTIONSTATEPARSER_H
+
+#include <QObject>
+#include <QVariant>
+
+typedef struct _GVariant GVariant;
+
+class ActionStateParser : public QObject
+{
+ Q_OBJECT
+public:
+ ActionStateParser(QObject* parent = 0);
+
+ virtual QVariant toQVariant(GVariant* state) const;
+};
+
+#endif // ACTIONSTATEPARSER_H
diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp
index d40c813..8bbb601 100644
--- a/libqmenumodel/src/unitymenumodel.cpp
+++ b/libqmenumodel/src/unitymenumodel.cpp
@@ -18,6 +18,12 @@
#include "unitymenumodel.h"
#include "converter.h"
+#include "actionstateparser.h"
+
+#include <QIcon>
+#include <QQmlComponent>
+
+#include <QIcon>
extern "C" {
#include "gtk/gtkactionmuxer.h"
@@ -26,7 +32,6 @@ 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 {
@@ -62,6 +67,7 @@ public:
QVariantMap actions;
QByteArray menuObjectPath;
QHash<QByteArray, int> roles;
+ ActionStateParser* actionStateParser;
static void nameAppeared(GDBusConnection *connection, const gchar *name, const gchar *owner, gpointer user_data);
static void nameVanished(GDBusConnection *connection, const gchar *name, gpointer user_data);
@@ -84,9 +90,9 @@ UnityMenuModelPrivate::UnityMenuModelPrivate(UnityMenuModel *model)
this->menutracker = NULL;
this->connection = NULL;
this->nameWatchId = 0;
+ this->actionStateParser = new ActionStateParser(model);
this->muxer = gtk_action_muxer_new ();
- g_object_set_qdata (G_OBJECT (this->muxer), unity_menu_model_quark (), model);
this->items = g_sequence_new (menu_item_free);
}
@@ -170,7 +176,9 @@ QVariant UnityMenuModelPrivate::itemState(GtkMenuTrackerItem *item)
GVariant *state = gtk_menu_tracker_item_get_action_state (item);
if (state != NULL) {
- result = Converter::toQVariant(state);
+ if (actionStateParser != NULL) {
+ result = actionStateParser->toQVariant(state);
+ }
g_variant_unref (state);
}
@@ -204,7 +212,7 @@ void UnityMenuModelPrivate::menuItemInserted(GtkMenuTrackerItem *item, gint posi
it = g_sequence_get_iter_at_pos (priv->items, position);
it = g_sequence_insert_before (it, g_object_ref (item));
- g_object_set_qdata (G_OBJECT (item), unity_menu_item_iterator_quark (), it);
+ g_object_set_qdata (G_OBJECT (item), unity_menu_model_quark (), priv->model);
g_signal_connect (item, "notify", G_CALLBACK (menuItemChanged), it);
priv->model->endInsertRows();
@@ -224,16 +232,15 @@ void UnityMenuModelPrivate::menuItemRemoved(gint position, gpointer user_data)
void UnityMenuModelPrivate::menuItemChanged(GObject *object, GParamSpec *pspec, gpointer user_data)
{
- GSequenceIter *it;
+ GSequenceIter *it = (GSequenceIter *) user_data;
GtkMenuTrackerItem *item;
GtkActionObservable *muxer;
UnityMenuModel *model;
gint position;
- it = (GSequenceIter *) g_object_get_qdata (object, unity_menu_item_iterator_quark ());
item = (GtkMenuTrackerItem *) g_sequence_get (it);
muxer = _gtk_menu_tracker_item_get_observable (item);
- model = (UnityMenuModel *) g_object_get_qdata (G_OBJECT (muxer), unity_menu_model_quark ());
+ model = (UnityMenuModel *) g_object_get_qdata (G_OBJECT (item), unity_menu_model_quark ());
position = g_sequence_iter_get_position (it);
Q_EMIT model->dataChanged(model->index(position, 0), model->index(position, 0));
@@ -265,6 +272,7 @@ void UnityMenuModel::setBusName(const QByteArray &name)
priv->nameWatchId = g_bus_watch_name (G_BUS_TYPE_SESSION, name.constData(), G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
UnityMenuModelPrivate::nameAppeared, UnityMenuModelPrivate::nameVanished,
priv, NULL);
+ priv->busName = name;
}
QVariantMap UnityMenuModel::actions() const
@@ -289,6 +297,22 @@ void UnityMenuModel::setMenuObjectPath(const QByteArray &path)
priv->updateMenuModel();
}
+ActionStateParser* UnityMenuModel::actionStateParser() const
+{
+ return priv->actionStateParser;
+}
+
+void UnityMenuModel::setActionStateParser(ActionStateParser* actionStateParser)
+{
+ if (priv->actionStateParser != actionStateParser) {
+ if (priv->actionStateParser && priv->actionStateParser->parent() == this) {
+ delete priv->actionStateParser;
+ }
+ priv->actionStateParser = actionStateParser;
+ Q_EMIT actionStateParserChanged(actionStateParser);
+ }
+}
+
int UnityMenuModel::rowCount(const QModelIndex &parent) const
{
return !parent.isValid() ? g_sequence_get_length (priv->items) : 0;
@@ -304,11 +328,15 @@ static QString iconUri(GIcon *icon)
QString uri;
if (G_IS_THEMED_ICON (icon)) {
- const gchar * const *names;
-
- names = g_themed_icon_get_names (G_THEMED_ICON (icon));
- if (names && names[0] && *names[0])
- uri = QString("image://theme/") + names[0];
+ const gchar* const* iconNames = g_themed_icon_get_names (G_THEMED_ICON (icon));
+ guint index = 0;
+ while(iconNames[index] != NULL) {
+ if (QIcon::hasThemeIcon(iconNames[index])) {
+ uri = QString("image://theme/") + iconNames[index];
+ break;
+ }
+ index++;
+ }
}
else if (G_IS_FILE_ICON (icon)) {
GFile *file;
@@ -417,7 +445,7 @@ QHash<int, QByteArray> UnityMenuModel::roleNames() const
return names;
}
-QObject * UnityMenuModel::submenu(int position)
+QObject * UnityMenuModel::submenu(int position, QQmlComponent* actionStateParser)
{
GSequenceIter *it;
GtkMenuTrackerItem *item;
@@ -434,7 +462,14 @@ QObject * UnityMenuModel::submenu(int position)
model = (UnityMenuModel *) g_object_get_qdata (G_OBJECT (item), unity_submenu_model_quark ());
if (model == NULL) {
model = new UnityMenuModel(this);
- model->priv = new UnityMenuModelPrivate(model);
+
+ if (actionStateParser) {
+ ActionStateParser* parser = qobject_cast<ActionStateParser*>(actionStateParser->create());
+ if (parser) {
+ model->setActionStateParser(parser);
+ }
+ }
+
model->priv->menutracker = gtk_menu_tracker_new_for_item_submenu (item,
UnityMenuModelPrivate::menuItemInserted,
UnityMenuModelPrivate::menuItemRemoved,
diff --git a/libqmenumodel/src/unitymenumodel.h b/libqmenumodel/src/unitymenumodel.h
index 396eea3..ad409ba 100644
--- a/libqmenumodel/src/unitymenumodel.h
+++ b/libqmenumodel/src/unitymenumodel.h
@@ -20,6 +20,8 @@
#define UNITYMENUMODEL_H
#include <QAbstractListModel>
+class ActionStateParser;
+class QQmlComponent;
class UnityMenuModel: public QAbstractListModel
{
@@ -27,6 +29,7 @@ class UnityMenuModel: public QAbstractListModel
Q_PROPERTY(QByteArray busName READ busName WRITE setBusName NOTIFY busNameChanged)
Q_PROPERTY(QVariantMap actions READ actions WRITE setActions NOTIFY actionsChanged)
Q_PROPERTY(QByteArray menuObjectPath READ menuObjectPath WRITE setMenuObjectPath NOTIFY menuObjectPathChanged)
+ Q_PROPERTY(ActionStateParser* actionStateParser READ actionStateParser WRITE setActionStateParser NOTIFY actionStateParserChanged)
public:
UnityMenuModel(QObject *parent = NULL);
@@ -41,6 +44,9 @@ public:
QByteArray menuObjectPath() const;
void setMenuObjectPath(const QByteArray &path);
+ ActionStateParser* actionStateParser() const;
+ void setActionStateParser(ActionStateParser* actionStateParser);
+
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
@@ -48,7 +54,7 @@ public:
QModelIndex parent(const QModelIndex &index) const;
QHash<int, QByteArray> roleNames() const;
- Q_INVOKABLE QObject * submenu(int position);
+ Q_INVOKABLE QObject * submenu(int position, QQmlComponent* actionStateParser = NULL);
Q_INVOKABLE bool loadExtendedAttributes(int position, const QVariantMap &schema);
Q_INVOKABLE QVariant get(int row, const QByteArray &role);
@@ -56,6 +62,7 @@ Q_SIGNALS:
void busNameChanged(const QByteArray &name);
void actionsChanged(const QByteArray &path);
void menuObjectPathChanged(const QByteArray &path);
+ void actionStateParserChanged(ActionStateParser* parser);
public Q_SLOTS:
void activate(int index);