aboutsummaryrefslogtreecommitdiff
path: root/libqmenumodel/src/unitymenumodel.cpp
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/src/unitymenumodel.cpp
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/src/unitymenumodel.cpp')
-rw-r--r--libqmenumodel/src/unitymenumodel.cpp142
1 files changed, 141 insertions, 1 deletions
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();
+ }
+}