diff options
-rw-r--r-- | libqmenumodel/src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | libqmenumodel/src/actionstateparser.cpp | 34 | ||||
-rw-r--r-- | libqmenumodel/src/actionstateparser.h | 37 | ||||
-rw-r--r-- | libqmenumodel/src/unitymenumodel.cpp | 63 | ||||
-rw-r--r-- | libqmenumodel/src/unitymenumodel.h | 9 |
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); |