aboutsummaryrefslogtreecommitdiff
path: root/libqmenumodel
diff options
context:
space:
mode:
authorNick Dedekind <nicholas.dedekind@gmail.com>2013-08-21 21:39:47 +0100
committerNick Dedekind <nicholas.dedekind@gmail.com>2013-08-21 21:39:47 +0100
commit72cd124bc6a71d7be3bf9e6602c9de55156508ee (patch)
treeeb1ca7e866de1e219dd4fe8b15ad48feefc59044 /libqmenumodel
parentbac9f37d6fc619e3c1c57754e0afe7b197c7668c (diff)
downloadqmenumodel-72cd124bc6a71d7be3bf9e6602c9de55156508ee.tar.gz
qmenumodel-72cd124bc6a71d7be3bf9e6602c9de55156508ee.tar.bz2
qmenumodel-72cd124bc6a71d7be3bf9e6602c9de55156508ee.zip
Added UnityMenuAction for out-of-line actions. Action muxer copied to submenus.
Diffstat (limited to 'libqmenumodel')
-rw-r--r--libqmenumodel/QMenuModel/plugin.cpp2
-rw-r--r--libqmenumodel/src/CMakeLists.txt4
-rw-r--r--libqmenumodel/src/gtk/gtkactionobserveritem.c152
-rw-r--r--libqmenumodel/src/gtk/gtkactionobserveritem.h67
-rw-r--r--libqmenumodel/src/unitymenuaction.cpp136
-rw-r--r--libqmenumodel/src/unitymenuaction.h73
-rw-r--r--libqmenumodel/src/unitymenumodel.cpp142
-rw-r--r--libqmenumodel/src/unitymenumodel.h10
8 files changed, 585 insertions, 1 deletions
diff --git a/libqmenumodel/QMenuModel/plugin.cpp b/libqmenumodel/QMenuModel/plugin.cpp
index 0629099..117a37a 100644
--- a/libqmenumodel/QMenuModel/plugin.cpp
+++ b/libqmenumodel/QMenuModel/plugin.cpp
@@ -22,6 +22,7 @@
#include "qdbusmenumodel.h"
#include "qdbusactiongroup.h"
#include "qstateaction.h"
+#include "unitymenuaction.h"
#include "unitymenumodel.h"
#include "unitythemediconprovider.h"
@@ -44,4 +45,5 @@ void QMenuModelQmlPlugin::registerTypes(const char *uri)
qmlRegisterType<QDBusMenuModel>(uri, 0, 1, "QDBusMenuModel");
qmlRegisterType<QDBusActionGroup>(uri, 0, 1, "QDBusActionGroup");
qmlRegisterType<UnityMenuModel>(uri, 0, 1, "UnityMenuModel");
+ qmlRegisterType<UnityMenuAction>(uri, 0, 1, "UnityMenuAction");
}
diff --git a/libqmenumodel/src/CMakeLists.txt b/libqmenumodel/src/CMakeLists.txt
index ad7c6ab..be278dd 100644
--- a/libqmenumodel/src/CMakeLists.txt
+++ b/libqmenumodel/src/CMakeLists.txt
@@ -10,6 +10,7 @@ set(QMENUMODEL_SRC
qdbusmenumodel.cpp
qdbusactiongroup.cpp
qstateaction.cpp
+ unitymenuaction.cpp
unitymenumodel.cpp
unitymenumodelevents.cpp
unitythemediconprovider.cpp
@@ -19,6 +20,8 @@ set(QMENUMODEL_SRC
gtk/gtkactionobservable.h
gtk/gtkactionobserver.c
gtk/gtkactionobserver.h
+ gtk/gtkactionobserveritem.c
+ gtk/gtkactionobserveritem.h
gtk/gtkmenutracker.c
gtk/gtkmenutracker.h
gtk/gtkmenutrackeritem.c
@@ -58,6 +61,7 @@ set(QMENUMODEL_HEADERS
qdbusobject.h
qmenumodel.h
qstateaction.h
+ unitymenuaction.h
unitymenumodel.h
unitythemediconprovider.h
)
diff --git a/libqmenumodel/src/gtk/gtkactionobserveritem.c b/libqmenumodel/src/gtk/gtkactionobserveritem.c
new file mode 100644
index 0000000..aebbcc3
--- /dev/null
+++ b/libqmenumodel/src/gtk/gtkactionobserveritem.c
@@ -0,0 +1,152 @@
+
+#include "gtkactionobserveritem.h"
+
+typedef GObjectClass GtkActionObserverItemClass;
+
+struct _GtkActionObserverItem
+{
+ GObject parent_instance;
+ GtkActionObservable *observable;
+ gchar* action_name;
+
+ GtkActionAddedFunc action_added;
+ GtkActionEnabledChangedFunc action_enabled_changed;
+ GtkActionStateChangedFunc action_state_changed;
+ GtkActionRemovedFunc action_removed;
+};
+
+static void gtk_action_observer_item_init_observer_iface (GtkActionObserverInterface *iface);
+G_DEFINE_TYPE_WITH_CODE (GtkActionObserverItem, gtk_action_observer_item, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTION_OBSERVER, gtk_action_observer_item_init_observer_iface))
+
+static void
+gtk_action_observer_item_finalize (GObject *object)
+{
+ GtkActionObserverItem *self = GTK_ACTION_OBSERVER_ITEM (object);
+
+ if (self->observable)
+ g_object_unref (self->observable);
+
+ if (self->action_name)
+ g_free(self->action_name);
+
+ G_OBJECT_CLASS (gtk_action_observer_item_parent_class)->finalize (object);
+}
+
+static void
+gtk_action_observer_item_init (GtkActionObserverItem * self)
+{
+}
+
+static void
+gtk_action_observer_item_class_init (GtkActionObserverItemClass *class)
+{
+ class->finalize = gtk_action_observer_item_finalize;
+}
+
+static void
+gtk_action_observer_item_action_added (GtkActionObserver *observer,
+ GtkActionObservable *observable,
+ const gchar *action_name,
+ const GVariantType *parameter_type,
+ gboolean enabled,
+ GVariant *state)
+{
+ g_return_if_fail (GTK_IS_ACTION_OBSERVER_ITEM (observer));
+
+ GtkActionObserverItem* self;
+ self = GTK_ACTION_OBSERVER_ITEM (observer);
+ self->action_added(self, action_name, enabled, state);
+}
+
+static void
+gtk_action_observer_item_action_enabled_changed (GtkActionObserver *observer,
+ GtkActionObservable *observable,
+ const gchar *action_name,
+ gboolean enabled)
+{
+ g_return_if_fail (GTK_IS_ACTION_OBSERVER_ITEM (observer));
+
+ GtkActionObserverItem* self;
+ self = GTK_ACTION_OBSERVER_ITEM (observer);
+ self->action_enabled_changed(self, action_name, enabled);
+}
+
+static void
+gtk_action_observer_item_action_state_changed (GtkActionObserver *observer,
+ GtkActionObservable *observable,
+ const gchar *action_name,
+ GVariant *state)
+{
+ g_return_if_fail (GTK_IS_ACTION_OBSERVER_ITEM (observer));
+
+ GtkActionObserverItem* self;
+ self = GTK_ACTION_OBSERVER_ITEM (observer);
+ self->action_state_changed(self, action_name, state);
+}
+
+static void
+gtk_action_observer_item_action_removed (GtkActionObserver *observer,
+ GtkActionObservable *observable,
+ const gchar *action_name)
+{
+ g_return_if_fail (GTK_IS_ACTION_OBSERVER_ITEM (observer));
+
+ GtkActionObserverItem* self;
+ self = GTK_ACTION_OBSERVER_ITEM (observer);
+ self->action_removed(self, action_name);
+}
+
+static void
+gtk_action_observer_item_init_observer_iface (GtkActionObserverInterface *iface)
+{
+ iface->action_added = gtk_action_observer_item_action_added;
+ iface->action_enabled_changed = gtk_action_observer_item_action_enabled_changed;
+ iface->action_state_changed = gtk_action_observer_item_action_state_changed;
+ iface->action_removed = gtk_action_observer_item_action_removed;
+}
+
+GtkActionObserverItem*
+gtk_action_observer_item_new (GtkActionObservable *observable,
+ GtkActionAddedFunc action_added,
+ GtkActionEnabledChangedFunc action_enabled_changed,
+ GtkActionStateChangedFunc action_state_changed,
+ GtkActionRemovedFunc action_removed)
+{
+ GtkActionObserverItem* self;
+ self = g_object_new (GTK_TYPE_ACTION_OBSERVER_ITEM, NULL);
+ self->observable = g_object_ref (observable);
+ self->action_name = NULL;
+
+ self->action_added = action_added;
+ self->action_enabled_changed = action_enabled_changed;
+ self->action_state_changed = action_state_changed;
+ self->action_removed = action_removed;
+
+ return self;
+}
+
+void
+gtk_action_observer_item_register_action (GtkActionObserverItem *self,
+ const gchar* action_name)
+{
+ gtk_action_observer_item_unregister_action(self);
+
+ if (action_name && g_strcmp0(action_name, "") != 0) {
+ self->action_name = g_strdup (action_name);
+
+ if (g_strcmp0(self->action_name, "") != 0) {
+ gtk_action_observable_register_observer (self->observable, self->action_name, GTK_ACTION_OBSERVER (self));
+ }
+ }
+}
+
+void
+gtk_action_observer_item_unregister_action (GtkActionObserverItem *self)
+{
+ if (self->action_name) {
+ gtk_action_observable_unregister_observer(self->observable, self->action_name, GTK_ACTION_OBSERVER (self));
+ g_free(self->action_name);
+ self->action_name = NULL;
+ }
+}
diff --git a/libqmenumodel/src/gtk/gtkactionobserveritem.h b/libqmenumodel/src/gtk/gtkactionobserveritem.h
new file mode 100644
index 0000000..ed36974
--- /dev/null
+++ b/libqmenumodel/src/gtk/gtkactionobserveritem.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2011 Canonical Limited
+ *
+ * This library 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; either version 2 of the
+ * licence or (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Nick Dedekind <nick.dedekind@canonical.com
+ */
+
+#ifndef __GTK_ACTION_OBSERVER_ITEM_H__
+#define __GTK_ACTION_OBSERVER_ITEM_H__
+
+#include "gtkactionobserver.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_ACTION_OBSERVER_ITEM (gtk_action_observer_item_get_type ())
+#define GTK_ACTION_OBSERVER_ITEM(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
+ GTK_TYPE_ACTION_OBSERVER_ITEM, GtkActionObserverItem))
+#define GTK_IS_ACTION_OBSERVER_ITEM(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
+ GTK_TYPE_ACTION_OBSERVER_ITEM))
+
+typedef struct _GtkActionObserverItem GtkActionObserverItem;
+
+typedef void (* GtkActionAddedFunc) (GtkActionObserverItem *observer_item,
+ const gchar *action_name,
+ gboolean enabled,
+ GVariant *state);
+
+typedef void (* GtkActionEnabledChangedFunc) (GtkActionObserverItem *observer_item,
+ const gchar *action_name,
+ gboolean enabled);
+
+typedef void (* GtkActionStateChangedFunc) (GtkActionObserverItem *observer_item,
+ const gchar *action_name,
+ GVariant *state);
+
+typedef void (* GtkActionRemovedFunc) (GtkActionObserverItem *observer_item,
+ const gchar *action_name);
+
+GType gtk_action_observer_item_get_type (void) G_GNUC_CONST;
+
+GtkActionObserverItem* gtk_action_observer_item_new (GtkActionObservable *observable,
+ GtkActionAddedFunc action_added,
+ GtkActionEnabledChangedFunc action_enabled_changed,
+ GtkActionStateChangedFunc action_state_changed,
+ GtkActionRemovedFunc action_removed);
+
+
+void gtk_action_observer_item_register_action (GtkActionObserverItem *self,
+ const gchar* action_name);
+
+void gtk_action_observer_item_unregister_action (GtkActionObserverItem *self);
+
+G_END_DECLS
+
+#endif // __GTK_ACTION_OBSERVER_ITEM_H__ \ No newline at end of file
diff --git a/libqmenumodel/src/unitymenuaction.cpp b/libqmenumodel/src/unitymenuaction.cpp
new file mode 100644
index 0000000..c2c7034
--- /dev/null
+++ b/libqmenumodel/src/unitymenuaction.cpp
@@ -0,0 +1,136 @@
+/*
+ * 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 "unitymenuaction.h"
+#include "unitymenumodel.h"
+
+#include <QDebug>
+
+UnityMenuAction::UnityMenuAction(QObject* parent)
+ : QObject(parent),
+ m_valid(false),
+ m_enabled(false),
+ m_model(NULL)
+{
+}
+
+UnityMenuAction::~UnityMenuAction()
+{
+ if (m_model) {
+ m_model->unregisterAction(this);
+ }
+}
+
+QString UnityMenuAction::name() const
+{
+ return m_name;
+}
+
+void UnityMenuAction::setName(const QString& name)
+{
+ if (m_name != name) {
+ m_name = name;
+ Q_EMIT nameChanged(m_name);
+ }
+}
+
+UnityMenuModel* UnityMenuAction::model() const
+{
+ return m_model;
+}
+
+void UnityMenuAction::setModel(UnityMenuModel* model)
+{
+ if (m_model != model) {
+ if (!model) {
+ unregisterAction();
+ }
+ m_model = model;
+ registerAction();
+ Q_EMIT modelChanged(model);
+ }
+}
+
+QVariant UnityMenuAction::state() const
+{
+ return m_state;
+}
+
+bool UnityMenuAction::isEnabled() const
+{
+ return m_enabled;
+}
+
+bool UnityMenuAction::isValid() const
+{
+ return m_valid;
+}
+
+void UnityMenuAction::onAdded(bool enabled, const QVariant &state)
+{
+ if (m_enabled != enabled) {
+ m_enabled = enabled;
+ Q_EMIT enabledChanged(m_enabled);
+ }
+ if (m_state != state) {
+ m_state = state;
+ Q_EMIT stateChanged(m_state);
+ }
+ if (m_valid != true) {
+ m_valid = true;
+ Q_EMIT validChanged(m_valid);
+ }
+}
+
+void UnityMenuAction::onRemoved()
+{
+ if (m_valid != false) {
+ m_valid = false;
+ Q_EMIT validChanged(m_valid);
+ }
+}
+
+void UnityMenuAction::onEnabledChanged(bool enabled)
+{
+ if (m_enabled != enabled) {
+ m_enabled = enabled;
+ Q_EMIT enabledChanged(m_enabled);
+ }
+}
+
+void UnityMenuAction::onStateChanged(const QVariant &state)
+{
+ if (m_state != state) {
+ m_state = state;
+ Q_EMIT stateChanged(m_state);
+ }
+}
+
+void UnityMenuAction::registerAction()
+{
+ if (m_model) {
+ m_model->registerAction(this);
+ }
+}
+
+void UnityMenuAction::unregisterAction()
+{
+ if (m_model) {
+ m_model->unregisterAction(this);
+ }
+}
diff --git a/libqmenumodel/src/unitymenuaction.h b/libqmenumodel/src/unitymenuaction.h
new file mode 100644
index 0000000..e6cc4d9
--- /dev/null
+++ b/libqmenumodel/src/unitymenuaction.h
@@ -0,0 +1,73 @@
+/*
+ * 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 UNITYMENUACTION_H
+#define UNITYMENUACTION_H
+
+#include <QObject>
+#include <QVariant>
+class UnityMenuModel;
+
+class UnityMenuAction: public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(QVariant state READ state NOTIFY stateChanged)
+ Q_PROPERTY(bool enabled READ isEnabled NOTIFY enabledChanged)
+ Q_PROPERTY(bool valid READ isValid NOTIFY validChanged)
+ Q_PROPERTY(UnityMenuModel* model READ model WRITE setModel NOTIFY modelChanged)
+public:
+ UnityMenuAction(QObject* parent = 0);
+ ~UnityMenuAction();
+
+ QString name() const;
+ void setName(const QString& str);
+
+ UnityMenuModel* model() const;
+ void setModel(UnityMenuModel* model);
+
+ QVariant state() const;
+ bool isEnabled() const;
+ bool isValid() const;
+
+public Q_SLOTS:
+ void onAdded(bool enabled, const QVariant &state);
+ void onRemoved();
+ void onEnabledChanged(bool enabled);
+ void onStateChanged(const QVariant &state);
+
+Q_SIGNALS:
+ void nameChanged(const QString& name);
+ void modelChanged(UnityMenuModel* model);
+ void stateChanged(const QVariant& name);
+ void enabledChanged(bool enabled);
+ void validChanged(bool valid);
+
+private:
+ void unregisterAction();
+ void registerAction();
+
+ QString m_name;
+ QVariant m_state;
+ bool m_valid;
+ bool m_enabled;
+ UnityMenuModel* m_model;
+};
+
+#endif // UNITYMENUACTIONGROUP_H
diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp
index e5407ab..920761c 100644
--- a/libqmenumodel/src/unitymenumodel.cpp
+++ b/libqmenumodel/src/unitymenumodel.cpp
@@ -20,6 +20,7 @@
#include "converter.h"
#include "actionstateparser.h"
#include "unitymenumodelevents.h"
+#include "unitymenuaction.h"
#include <QIcon>
#include <QQmlComponent>
@@ -28,11 +29,14 @@
extern "C" {
#include "gtk/gtkactionmuxer.h"
#include "gtk/gtkmenutracker.h"
+ #include "gtk/gtkactionobserveritem.h"
}
G_DEFINE_QUARK (UNITY_MENU_MODEL, unity_menu_model)
G_DEFINE_QUARK (UNITY_SUBMENU_MODEL, unity_submenu_model)
G_DEFINE_QUARK (UNITY_MENU_ITEM_EXTENDED_ATTRIBUTES, unity_menu_item_extended_attributes)
+G_DEFINE_QUARK (UNITY_MENU_ACTION, unity_menu_action)
+
enum MenuRoles {
LabelRole = Qt::DisplayRole + 1,
@@ -52,6 +56,7 @@ class UnityMenuModelPrivate
{
public:
UnityMenuModelPrivate(UnityMenuModel *model);
+ UnityMenuModelPrivate(const UnityMenuModelPrivate& other, UnityMenuModel *model);
~UnityMenuModelPrivate();
void clearItems(bool resetModel=true);
@@ -72,12 +77,21 @@ public:
QByteArray menuObjectPath;
QHash<QByteArray, int> roles;
ActionStateParser* actionStateParser;
+ QHash<UnityMenuAction*, GtkActionObserverItem*> registeredActions;
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);
static void menuItemInserted(GtkMenuTrackerItem *item, gint position, gpointer user_data);
static void menuItemRemoved(gint position, gpointer user_data);
static void menuItemChanged(GObject *object, GParamSpec *pspec, gpointer user_data);
+
+ static void registeredActionAdded(GtkActionObserverItem *observer_item,
+ const gchar *action_name,
+ gboolean enabled,
+ GVariant *state);
+ static void registeredActionEnabledChanged(GtkActionObserverItem *observer_item, const gchar *action_name, gboolean enabled);
+ static void registeredActionStateChanged(GtkActionObserverItem *observer_item, const gchar *action_name, GVariant *state);
+ static void registeredActionRemoved(GtkActionObserverItem *observer_item, const gchar *action_name);
};
void menu_item_free (gpointer data)
@@ -101,6 +115,19 @@ UnityMenuModelPrivate::UnityMenuModelPrivate(UnityMenuModel *model)
this->items = g_sequence_new (menu_item_free);
}
+UnityMenuModelPrivate::UnityMenuModelPrivate(const UnityMenuModelPrivate& other, UnityMenuModel *model)
+{
+ this->model = model;
+ this->menutracker = NULL;
+ this->connection = NULL;
+ this->nameWatchId = 0;
+ this->actionStateParser = new ActionStateParser(model);
+
+ this->muxer = GTK_ACTION_MUXER( g_object_ref(other.muxer));
+
+ this->items = g_sequence_new (menu_item_free);
+}
+
UnityMenuModelPrivate::~UnityMenuModelPrivate()
{
this->clearItems(false);
@@ -109,6 +136,12 @@ UnityMenuModelPrivate::~UnityMenuModelPrivate()
g_clear_object (&this->muxer);
g_clear_object (&this->connection);
+ QHash<UnityMenuAction*, GtkActionObserverItem*>::const_iterator it = this->registeredActions.constBegin();
+ for (; it != this->registeredActions.constEnd(); ++it) {
+ g_object_unref(it.value());
+ }
+ this->registeredActions.clear();
+
if (this->nameWatchId)
g_bus_unwatch_name (this->nameWatchId);
}
@@ -236,6 +269,12 @@ UnityMenuModel::UnityMenuModel(QObject *parent):
priv = new UnityMenuModelPrivate(this);
}
+UnityMenuModel::UnityMenuModel(const UnityMenuModelPrivate& other, QObject *parent):
+ QAbstractListModel(parent)
+{
+ priv = new UnityMenuModelPrivate(other, this);
+}
+
UnityMenuModel::~UnityMenuModel()
{
delete priv;
@@ -461,7 +500,7 @@ QObject * UnityMenuModel::submenu(int position, QQmlComponent* actionStateParser
model = (UnityMenuModel *) g_object_get_qdata (G_OBJECT (item), unity_submenu_model_quark ());
if (model == NULL) {
- model = new UnityMenuModel(this);
+ model = new UnityMenuModel(*priv, this);
if (actionStateParser) {
ActionStateParser* parser = qobject_cast<ActionStateParser*>(actionStateParser->create());
@@ -672,3 +711,104 @@ bool UnityMenuModel::event(QEvent* e)
}
return QAbstractListModel::event(e);
}
+
+void UnityMenuModel::registerAction(UnityMenuAction* action)
+{
+ if (!priv->registeredActions.contains(action)) {
+ GtkActionObserverItem* observer_item;
+ observer_item = gtk_action_observer_item_new(GTK_ACTION_OBSERVABLE (priv->muxer),
+ UnityMenuModelPrivate::registeredActionAdded,
+ UnityMenuModelPrivate::registeredActionEnabledChanged,
+ UnityMenuModelPrivate::registeredActionStateChanged,
+ UnityMenuModelPrivate::registeredActionRemoved);
+
+ g_object_set_qdata (G_OBJECT (observer_item), unity_menu_action_quark (), action);
+
+ priv->registeredActions[action] = observer_item;
+
+ connect(action, SIGNAL(nameChanged(const QString&)), SLOT(onRegisteredActionNameChanged(const QString&)));
+ }
+}
+
+void UnityMenuModel::unregisterAction(UnityMenuAction* action)
+{
+ if (priv->registeredActions.contains(action)) {
+ GtkActionObserverItem* observer_item;
+ observer_item = priv->registeredActions[action];
+ g_object_unref(observer_item);
+ priv->registeredActions.remove(action);
+
+ disconnect(action);
+ }
+}
+
+void UnityMenuModel::onRegisteredActionNameChanged(const QString& name)
+{
+ UnityMenuAction* action = qobject_cast<UnityMenuAction*>(sender());
+ if (!action || !priv->registeredActions.contains(action))
+ return;
+
+ GtkActionObserverItem* observer_item;
+ observer_item = priv->registeredActions[action];
+
+ QByteArray nameArray = name.toUtf8();
+ const gchar* action_name = nameArray.constData();
+
+ gtk_action_observer_item_register_action (observer_item, action_name);
+
+ const GVariantType *parameter_type;
+ gboolean enabled;
+ GVariant *state;
+
+ if (g_action_group_query_action (G_ACTION_GROUP (priv->muxer), action_name,
+ &enabled, &parameter_type, NULL, NULL, &state))
+ {
+ action->onAdded(enabled, Converter::toQVariant(state));
+ if (state) {
+ g_variant_unref (state);
+ }
+ }
+}
+
+void UnityMenuModelPrivate::registeredActionAdded(GtkActionObserverItem *observer_item,
+ const gchar *action_name,
+ gboolean enabled,
+ GVariant *state)
+{
+ UnityMenuAction *action;
+ action = (UnityMenuAction *) g_object_get_qdata (G_OBJECT (observer_item), unity_menu_action_quark ());
+ // FIXME - needs to go through event loop
+ if (action) {
+ action->onAdded(enabled, Converter::toQVariant(state));
+ }
+}
+
+void UnityMenuModelPrivate::registeredActionEnabledChanged(GtkActionObserverItem *observer_item, const gchar *action_name, gboolean enabled)
+{
+ UnityMenuAction *action;
+ action = (UnityMenuAction *) g_object_get_qdata (G_OBJECT (observer_item), unity_menu_action_quark ());
+ // FIXME - needs to go through event loop
+ if (action) {
+ action->onEnabledChanged(enabled);
+ }
+}
+
+void UnityMenuModelPrivate::registeredActionStateChanged(GtkActionObserverItem *observer_item, const gchar *action_name, GVariant *state)
+{
+ UnityMenuAction *action;
+ action = (UnityMenuAction *) g_object_get_qdata (G_OBJECT (observer_item), unity_menu_action_quark ());
+ // FIXME - needs to go through event loop
+ if (action) {
+ action->onStateChanged(Converter::toQVariant(state));
+ }
+}
+
+void UnityMenuModelPrivate::registeredActionRemoved(GtkActionObserverItem *observer_item, const gchar *action_name)
+{
+ UnityMenuAction *action;
+ action = (UnityMenuAction *) g_object_get_qdata (G_OBJECT (observer_item), unity_menu_action_quark ());
+ // FIXME - needs to go through event loop
+ if (action) {
+ action->onRemoved();
+ }
+}
diff --git a/libqmenumodel/src/unitymenumodel.h b/libqmenumodel/src/unitymenumodel.h
index df35f08..21a4c3c 100644
--- a/libqmenumodel/src/unitymenumodel.h
+++ b/libqmenumodel/src/unitymenumodel.h
@@ -22,6 +22,7 @@
#include <QAbstractListModel>
class ActionStateParser;
class QQmlComponent;
+class UnityMenuAction;
class UnityMenuModel: public QAbstractListModel
{
@@ -61,18 +62,27 @@ public:
Q_INVOKABLE void activate(int index, const QVariant& parameter = QVariant());
Q_INVOKABLE void changeState(int index, const QVariant& parameter);
+ void registerAction(UnityMenuAction* action);
+ void unregisterAction(UnityMenuAction* action);
+
Q_SIGNALS:
void busNameChanged(const QByteArray &name);
void actionsChanged(const QByteArray &path);
void menuObjectPathChanged(const QByteArray &path);
void actionStateParserChanged(ActionStateParser* parser);
+protected Q_SLOTS:
+ void onRegisteredActionNameChanged(const QString& name);
+
protected:
+
virtual bool event(QEvent* e);
private:
class UnityMenuModelPrivate *priv;
friend class UnityMenuModelPrivate;
+
+ UnityMenuModel(const UnityMenuModelPrivate& other, QObject *parent);
};
#endif