From 72cd124bc6a71d7be3bf9e6602c9de55156508ee Mon Sep 17 00:00:00 2001 From: Nick Dedekind Date: Wed, 21 Aug 2013 21:39:47 +0100 Subject: Added UnityMenuAction for out-of-line actions. Action muxer copied to submenus. --- libqmenumodel/QMenuModel/plugin.cpp | 2 + libqmenumodel/src/CMakeLists.txt | 4 + libqmenumodel/src/gtk/gtkactionobserveritem.c | 152 ++++++++++++++++++++++++++ libqmenumodel/src/gtk/gtkactionobserveritem.h | 67 ++++++++++++ libqmenumodel/src/unitymenuaction.cpp | 136 +++++++++++++++++++++++ libqmenumodel/src/unitymenuaction.h | 73 +++++++++++++ libqmenumodel/src/unitymenumodel.cpp | 142 +++++++++++++++++++++++- libqmenumodel/src/unitymenumodel.h | 10 ++ 8 files changed, 585 insertions(+), 1 deletion(-) create mode 100644 libqmenumodel/src/gtk/gtkactionobserveritem.c create mode 100644 libqmenumodel/src/gtk/gtkactionobserveritem.h create mode 100644 libqmenumodel/src/unitymenuaction.cpp create mode 100644 libqmenumodel/src/unitymenuaction.h (limited to 'libqmenumodel') 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(uri, 0, 1, "QDBusMenuModel"); qmlRegisterType(uri, 0, 1, "QDBusActionGroup"); qmlRegisterType(uri, 0, 1, "UnityMenuModel"); + qmlRegisterType(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 . + * + * Authors: Nick Dedekind . + * + * Authors: Nick Dedekind + */ + +#include "unitymenuaction.h" +#include "unitymenumodel.h" + +#include + +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 . + * + * Authors: Nick Dedekind + */ + +#ifndef UNITYMENUACTION_H +#define UNITYMENUACTION_H + +#include +#include +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 #include @@ -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 roles; ActionStateParser* actionStateParser; + QHash 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::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->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(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, ¶meter_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 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 -- cgit v1.2.3 From d912a0aed3c62b8f615c37fd9406583b9f0a6a36 Mon Sep 17 00:00:00 2001 From: Nick Dedekind Date: Thu, 22 Aug 2013 12:03:08 +0100 Subject: Added activate/changeState to UnityMenuModel --- libqmenumodel/src/unitymenuaction.h | 3 +++ libqmenumodel/src/unitymenumodel.cpp | 26 ++++++++++++++++++++++++++ libqmenumodel/src/unitymenumodel.h | 2 ++ 3 files changed, 31 insertions(+) (limited to 'libqmenumodel') diff --git a/libqmenumodel/src/unitymenuaction.h b/libqmenumodel/src/unitymenuaction.h index e6cc4d9..7c19fc5 100644 --- a/libqmenumodel/src/unitymenuaction.h +++ b/libqmenumodel/src/unitymenuaction.h @@ -53,6 +53,9 @@ public Q_SLOTS: void onStateChanged(const QVariant &state); Q_SIGNALS: + Q_INVOKABLE void activate(const QVariant& parameter = QVariant()); + Q_INVOKABLE void changeState(const QVariant& parameter); + void nameChanged(const QString& name); void modelChanged(UnityMenuModel* model); void stateChanged(const QVariant& name); diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp index 920761c..953af01 100644 --- a/libqmenumodel/src/unitymenumodel.cpp +++ b/libqmenumodel/src/unitymenumodel.cpp @@ -727,6 +727,8 @@ void UnityMenuModel::registerAction(UnityMenuAction* action) priv->registeredActions[action] = observer_item; connect(action, SIGNAL(nameChanged(const QString&)), SLOT(onRegisteredActionNameChanged(const QString&))); + connect(action, SIGNAL(activate(const QVariant&)), SLOT(onRegisteredActionActivated(const QVariant&))); + connect(action, SIGNAL(changeState(const QVariant&)), SLOT(onRegisteredActionStateChanged(const QVariant&))); } } @@ -770,6 +772,30 @@ void UnityMenuModel::onRegisteredActionNameChanged(const QString& name) } } +void UnityMenuModel::onRegisteredActionActivated(const QVariant& parameter) +{ + UnityMenuAction* action = qobject_cast(sender()); + if (!action || action->name().isEmpty()) + return; + + QByteArray nameArray = action->name().toUtf8(); + const gchar* action_name = nameArray.constData(); + + g_action_group_activate_action (G_ACTION_GROUP (priv->muxer), action_name, Converter::toGVariant(parameter)); +} + +void UnityMenuModel::onRegisteredActionStateChanged(const QVariant& parameter) +{ + UnityMenuAction* action = qobject_cast(sender()); + if (!action || action->name().isEmpty()) + return; + + QByteArray nameArray = action->name().toUtf8(); + const gchar* action_name = nameArray.constData(); + + g_action_group_change_action_state (G_ACTION_GROUP (priv->muxer), action_name, Converter::toGVariant(parameter)); +} + void UnityMenuModelPrivate::registeredActionAdded(GtkActionObserverItem *observer_item, const gchar *action_name, gboolean enabled, diff --git a/libqmenumodel/src/unitymenumodel.h b/libqmenumodel/src/unitymenumodel.h index 21a4c3c..0c18121 100644 --- a/libqmenumodel/src/unitymenumodel.h +++ b/libqmenumodel/src/unitymenumodel.h @@ -73,6 +73,8 @@ Q_SIGNALS: protected Q_SLOTS: void onRegisteredActionNameChanged(const QString& name); + void onRegisteredActionActivated(const QVariant& parameter); + void onRegisteredActionStateChanged(const QVariant& parameter); protected: -- cgit v1.2.3 From c2746565786204a732ff5531434bf636f8df605c Mon Sep 17 00:00:00 2001 From: Nick Dedekind Date: Thu, 22 Aug 2013 12:56:43 +0100 Subject: Using qt event loop to pass UnityMenuAction events --- libqmenumodel/src/CMakeLists.txt | 1 + libqmenumodel/src/unitymenuaction.cpp | 71 +++++++++++++++++------------ libqmenumodel/src/unitymenuaction.h | 13 +++--- libqmenumodel/src/unitymenuactionevents.cpp | 46 +++++++++++++++++++ libqmenumodel/src/unitymenuactionevents.h | 65 ++++++++++++++++++++++++++ libqmenumodel/src/unitymenumodel.cpp | 23 ++++++---- 6 files changed, 176 insertions(+), 43 deletions(-) create mode 100644 libqmenumodel/src/unitymenuactionevents.cpp create mode 100644 libqmenumodel/src/unitymenuactionevents.h (limited to 'libqmenumodel') diff --git a/libqmenumodel/src/CMakeLists.txt b/libqmenumodel/src/CMakeLists.txt index be278dd..e360a70 100644 --- a/libqmenumodel/src/CMakeLists.txt +++ b/libqmenumodel/src/CMakeLists.txt @@ -11,6 +11,7 @@ set(QMENUMODEL_SRC qdbusactiongroup.cpp qstateaction.cpp unitymenuaction.cpp + unitymenuactionevents.cpp unitymenumodel.cpp unitymenumodelevents.cpp unitythemediconprovider.cpp diff --git a/libqmenumodel/src/unitymenuaction.cpp b/libqmenumodel/src/unitymenuaction.cpp index c2c7034..b41fd3e 100644 --- a/libqmenumodel/src/unitymenuaction.cpp +++ b/libqmenumodel/src/unitymenuaction.cpp @@ -18,6 +18,7 @@ #include "unitymenuaction.h" #include "unitymenumodel.h" +#include "unitymenuactionevents.h" #include @@ -71,41 +72,20 @@ QVariant UnityMenuAction::state() const return m_state; } -bool UnityMenuAction::isEnabled() const +void UnityMenuAction::setState(const QVariant& state) { - 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() +bool UnityMenuAction::isEnabled() const { - if (m_valid != false) { - m_valid = false; - Q_EMIT validChanged(m_valid); - } + return m_enabled; } -void UnityMenuAction::onEnabledChanged(bool enabled) +void UnityMenuAction::setEnabled(bool enabled) { if (m_enabled != enabled) { m_enabled = enabled; @@ -113,11 +93,16 @@ void UnityMenuAction::onEnabledChanged(bool enabled) } } -void UnityMenuAction::onStateChanged(const QVariant &state) +bool UnityMenuAction::isValid() const { - if (m_state != state) { - m_state = state; - Q_EMIT stateChanged(m_state); + return m_valid; +} + +void UnityMenuAction::setValid(bool valid) +{ + if (m_valid != valid) { + m_valid = valid; + Q_EMIT validChanged(m_valid); } } @@ -134,3 +119,31 @@ void UnityMenuAction::unregisterAction() m_model->unregisterAction(this); } } + +bool UnityMenuAction::event(QEvent* e) +{ + if (e->type() == UnityMenuActionAddEvent::eventType) { + UnityMenuActionAddEvent *umaae = static_cast(e); + + setEnabled(umaae->enabled); + setState(umaae->state); + setValid(true); + return true; + } else if (e->type() == UnityMenuActionEnabledChangedEvent::eventType) { + UnityMenuActionEnabledChangedEvent *umaece = static_cast(e); + + setEnabled(umaece->enabled); + return true; + } else if (e->type() == UnityMenuActionStateChangeEvent::eventType) { + UnityMenuActionStateChangeEvent *umasce = static_cast(e); + + setState(umasce->state); + return true; + } else if (e->type() == UnityMenuActionRemoveEvent::eventType) { + UnityMenuActionRemoveEvent *umare = static_cast(e); + + setValid(false); + return true; + } + return QObject::event(e); +} diff --git a/libqmenumodel/src/unitymenuaction.h b/libqmenumodel/src/unitymenuaction.h index 7c19fc5..b8391fe 100644 --- a/libqmenumodel/src/unitymenuaction.h +++ b/libqmenumodel/src/unitymenuaction.h @@ -46,12 +46,6 @@ public: 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: Q_INVOKABLE void activate(const QVariant& parameter = QVariant()); Q_INVOKABLE void changeState(const QVariant& parameter); @@ -62,6 +56,13 @@ Q_SIGNALS: void enabledChanged(bool enabled); void validChanged(bool valid); +protected: + virtual bool event(QEvent* e); + + void setState(const QVariant& state); + void setEnabled(bool enabled); + void setValid(bool valid); + private: void unregisterAction(); void registerAction(); diff --git a/libqmenumodel/src/unitymenuactionevents.cpp b/libqmenumodel/src/unitymenuactionevents.cpp new file mode 100644 index 0000000..f05e536 --- /dev/null +++ b/libqmenumodel/src/unitymenuactionevents.cpp @@ -0,0 +1,46 @@ +/* + * 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 . + * + * Authors: + * Nicholas Dedekind (QEvent::registerEventType()); +const QEvent::Type UnityMenuActionRemoveEvent::eventType = static_cast(QEvent::registerEventType()); +const QEvent::Type UnityMenuActionEnabledChangedEvent::eventType = static_cast(QEvent::registerEventType()); +const QEvent::Type UnityMenuActionStateChangeEvent::eventType = static_cast(QEvent::registerEventType()); + +UnityMenuActionAddEvent::UnityMenuActionAddEvent(bool _enabled, const QVariant& _state) + : QEvent(UnityMenuActionAddEvent::eventType), + enabled(_enabled), + state(_state) +{} + +UnityMenuActionRemoveEvent::UnityMenuActionRemoveEvent() + : QEvent(UnityMenuActionRemoveEvent::eventType) +{ +} + +UnityMenuActionEnabledChangedEvent::UnityMenuActionEnabledChangedEvent(bool _enabled) + : QEvent(UnityMenuActionEnabledChangedEvent::eventType), + enabled(_enabled) +{} + +UnityMenuActionStateChangeEvent::UnityMenuActionStateChangeEvent(const QVariant& _state) + : QEvent(UnityMenuActionStateChangeEvent::eventType), + state(_state) +{} diff --git a/libqmenumodel/src/unitymenuactionevents.h b/libqmenumodel/src/unitymenuactionevents.h new file mode 100644 index 0000000..44cb5de --- /dev/null +++ b/libqmenumodel/src/unitymenuactionevents.h @@ -0,0 +1,65 @@ +/* + * 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 . + * + * Authors: + * Nicholas Dedekind +#include + +/* Event for a unitymenuaction add */ +class UnityMenuActionAddEvent : public QEvent +{ +public: + static const QEvent::Type eventType; + UnityMenuActionAddEvent(bool enabled, const QVariant& state); + + bool enabled; + QVariant state; +}; + +/* Event for a unitymenuaction remove */ +class UnityMenuActionRemoveEvent : public QEvent +{ +public: + static const QEvent::Type eventType; + UnityMenuActionRemoveEvent(); +}; + +/* Event for change in enabled value of a unitymenuaction */ +class UnityMenuActionEnabledChangedEvent : public QEvent +{ +public: + static const QEvent::Type eventType; + UnityMenuActionEnabledChangedEvent(bool enabled); + + int enabled; +}; + +/* Event for change in state value of a unitymenuaction */ +class UnityMenuActionStateChangeEvent : public QEvent +{ +public: + static const QEvent::Type eventType; + UnityMenuActionStateChangeEvent(const QVariant& state); + + QVariant state; +}; + +#endif //UNITYMENUACTIONEVENTS_H diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp index 953af01..b99f406 100644 --- a/libqmenumodel/src/unitymenumodel.cpp +++ b/libqmenumodel/src/unitymenumodel.cpp @@ -21,6 +21,7 @@ #include "actionstateparser.h" #include "unitymenumodelevents.h" #include "unitymenuaction.h" +#include "unitymenuactionevents.h" #include #include @@ -765,7 +766,9 @@ void UnityMenuModel::onRegisteredActionNameChanged(const QString& name) if (g_action_group_query_action (G_ACTION_GROUP (priv->muxer), action_name, &enabled, ¶meter_type, NULL, NULL, &state)) { - action->onAdded(enabled, Converter::toQVariant(state)); + UnityMenuActionAddEvent umaae(enabled, Converter::toQVariant(state)); + QCoreApplication::sendEvent(action, &umaae); + if (state) { g_variant_unref (state); } @@ -805,7 +808,8 @@ void UnityMenuModelPrivate::registeredActionAdded(GtkActionObserverItem *obse 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)); + UnityMenuActionAddEvent umaae(enabled, Converter::toQVariant(state)); + QCoreApplication::sendEvent(action, &umaae); } } @@ -813,9 +817,10 @@ void UnityMenuModelPrivate::registeredActionEnabledChanged(GtkActionObserverItem { 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); + UnityMenuActionEnabledChangedEvent umaece(enabled); + QCoreApplication::sendEvent(action, &umaece); } } @@ -823,9 +828,10 @@ void UnityMenuModelPrivate::registeredActionStateChanged(GtkActionObserverItem * { 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)); + UnityMenuActionStateChangeEvent umasce(Converter::toQVariant(state)); + QCoreApplication::sendEvent(action, &umasce); } } @@ -833,8 +839,9 @@ void UnityMenuModelPrivate::registeredActionRemoved(GtkActionObserverItem *obser { 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(); + UnityMenuActionRemoveEvent umare; + QCoreApplication::sendEvent(action, &umare); } } -- cgit v1.2.3 From 9ed45386062b3bfcf801feb5d37cab993c4aa89e Mon Sep 17 00:00:00 2001 From: Nick Dedekind Date: Thu, 22 Aug 2013 20:36:50 +0100 Subject: Added copywrite headers --- libqmenumodel/src/gtk/gtkactionobserveritem.c | 18 ++++++++++++++++++ libqmenumodel/src/gtk/gtkactionobserveritem.h | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'libqmenumodel') diff --git a/libqmenumodel/src/gtk/gtkactionobserveritem.c b/libqmenumodel/src/gtk/gtkactionobserveritem.c index aebbcc3..db4c544 100644 --- a/libqmenumodel/src/gtk/gtkactionobserveritem.c +++ b/libqmenumodel/src/gtk/gtkactionobserveritem.c @@ -1,3 +1,21 @@ +/* + * Copyright © 2013 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 . + * + * Authors: Nick Dedekind Date: Thu, 22 Aug 2013 20:43:49 +0100 Subject: removed newline --- libqmenumodel/src/unitymenumodel.h | 1 - 1 file changed, 1 deletion(-) (limited to 'libqmenumodel') diff --git a/libqmenumodel/src/unitymenumodel.h b/libqmenumodel/src/unitymenumodel.h index 0c18121..a229f09 100644 --- a/libqmenumodel/src/unitymenumodel.h +++ b/libqmenumodel/src/unitymenumodel.h @@ -77,7 +77,6 @@ protected Q_SLOTS: void onRegisteredActionStateChanged(const QVariant& parameter); protected: - virtual bool event(QEvent* e); private: -- cgit v1.2.3 From ebace67d14edcd8e0e4d3d1ebe5e54e2b59270b3 Mon Sep 17 00:00:00 2001 From: Nick Dedekind Date: Tue, 27 Aug 2013 17:24:38 +0100 Subject: Review comments --- libqmenumodel/src/CMakeLists.txt | 4 +- libqmenumodel/src/gtk/gtkactionobserveritem.c | 170 ------------------------ libqmenumodel/src/gtk/gtkactionobserveritem.h | 67 ---------- libqmenumodel/src/gtk/gtksimpleactionobserver.c | 160 ++++++++++++++++++++++ libqmenumodel/src/gtk/gtksimpleactionobserver.h | 67 ++++++++++ libqmenumodel/src/unitymenumodel.cpp | 34 ++--- 6 files changed, 246 insertions(+), 256 deletions(-) delete mode 100644 libqmenumodel/src/gtk/gtkactionobserveritem.c delete mode 100644 libqmenumodel/src/gtk/gtkactionobserveritem.h create mode 100644 libqmenumodel/src/gtk/gtksimpleactionobserver.c create mode 100644 libqmenumodel/src/gtk/gtksimpleactionobserver.h (limited to 'libqmenumodel') diff --git a/libqmenumodel/src/CMakeLists.txt b/libqmenumodel/src/CMakeLists.txt index e360a70..84f4daa 100644 --- a/libqmenumodel/src/CMakeLists.txt +++ b/libqmenumodel/src/CMakeLists.txt @@ -21,8 +21,8 @@ set(QMENUMODEL_SRC gtk/gtkactionobservable.h gtk/gtkactionobserver.c gtk/gtkactionobserver.h - gtk/gtkactionobserveritem.c - gtk/gtkactionobserveritem.h + gtk/gtksimpleactionobserver.c + gtk/gtksimpleactionobserver.h gtk/gtkmenutracker.c gtk/gtkmenutracker.h gtk/gtkmenutrackeritem.c diff --git a/libqmenumodel/src/gtk/gtkactionobserveritem.c b/libqmenumodel/src/gtk/gtkactionobserveritem.c deleted file mode 100644 index db4c544..0000000 --- a/libqmenumodel/src/gtk/gtkactionobserveritem.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright © 2013 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 . - * - * Authors: Nick Dedekind 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 deleted file mode 100644 index 315cadc..0000000 --- a/libqmenumodel/src/gtk/gtkactionobserveritem.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright © 2013 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 . - * - * Authors: Nick Dedekind . + * + * Authors: Nick Dedekind observable); + + g_free(self->action_name); + + G_OBJECT_CLASS (gtk_simple_action_observer_parent_class)->finalize (object); +} + +static void +gtk_simple_action_observer_init (GtkSimpleActionObserver * self) +{ +} + +static void +gtk_simple_action_observer_class_init (GtkSimpleActionObserverClass *class) +{ + class->finalize = gtk_simple_action_observer_finalize; +} + +static void +gtk_simple_action_observer_action_added (GtkActionObserver *observer, + GtkActionObservable *observable, + const gchar *action_name, + const GVariantType *parameter_type, + gboolean enabled, + GVariant *state) +{ + GtkSimpleActionObserver* self; + self = GTK_SIMPLE_ACTION_OBSERVER (observer); + self->action_added(self, action_name, enabled, state); +} + +static void +gtk_simple_action_observer_action_enabled_changed (GtkActionObserver *observer, + GtkActionObservable *observable, + const gchar *action_name, + gboolean enabled) +{ + GtkSimpleActionObserver* self; + self = GTK_SIMPLE_ACTION_OBSERVER (observer); + self->action_enabled_changed(self, action_name, enabled); +} + +static void +gtk_simple_action_observer_action_state_changed (GtkActionObserver *observer, + GtkActionObservable *observable, + const gchar *action_name, + GVariant *state) +{ + GtkSimpleActionObserver* self; + self = GTK_SIMPLE_ACTION_OBSERVER (observer); + self->action_state_changed(self, action_name, state); +} + +static void +gtk_simple_action_observer_action_removed (GtkActionObserver *observer, + GtkActionObservable *observable, + const gchar *action_name) +{ + GtkSimpleActionObserver* self; + self = GTK_SIMPLE_ACTION_OBSERVER (observer); + self->action_removed(self, action_name); +} + +static void +gtk_simple_action_observer_init_observer_iface (GtkActionObserverInterface *iface) +{ + iface->action_added = gtk_simple_action_observer_action_added; + iface->action_enabled_changed = gtk_simple_action_observer_action_enabled_changed; + iface->action_state_changed = gtk_simple_action_observer_action_state_changed; + iface->action_removed = gtk_simple_action_observer_action_removed; +} + +GtkSimpleActionObserver* +gtk_simple_action_observer_new (GtkActionObservable *observable, + GtkActionAddedFunc action_added, + GtkActionEnabledChangedFunc action_enabled_changed, + GtkActionStateChangedFunc action_state_changed, + GtkActionRemovedFunc action_removed) +{ + GtkSimpleActionObserver* self; + self = g_object_new (GTK_TYPE_SIMPLE_ACTION_OBSERVER, 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_simple_action_observer_register_action (GtkSimpleActionObserver *self, + const gchar *action_name) +{ + gtk_simple_action_observer_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_simple_action_observer_unregister_action (GtkSimpleActionObserver *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/gtksimpleactionobserver.h b/libqmenumodel/src/gtk/gtksimpleactionobserver.h new file mode 100644 index 0000000..4276786 --- /dev/null +++ b/libqmenumodel/src/gtk/gtksimpleactionobserver.h @@ -0,0 +1,67 @@ +/* + * Copyright © 2013 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 . + * + * Authors: Nick Dedekind roles; ActionStateParser* actionStateParser; - QHash registeredActions; + QHash 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); @@ -86,13 +86,13 @@ public: static void menuItemRemoved(gint position, gpointer user_data); static void menuItemChanged(GObject *object, GParamSpec *pspec, gpointer user_data); - static void registeredActionAdded(GtkActionObserverItem *observer_item, + static void registeredActionAdded(GtkSimpleActionObserver *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); + static void registeredActionEnabledChanged(GtkSimpleActionObserver *observer_item, const gchar *action_name, gboolean enabled); + static void registeredActionStateChanged(GtkSimpleActionObserver *observer_item, const gchar *action_name, GVariant *state); + static void registeredActionRemoved(GtkSimpleActionObserver *observer_item, const gchar *action_name); }; void menu_item_free (gpointer data) @@ -137,7 +137,7 @@ UnityMenuModelPrivate::~UnityMenuModelPrivate() g_clear_object (&this->muxer); g_clear_object (&this->connection); - QHash::const_iterator it = this->registeredActions.constBegin(); + QHash::const_iterator it = this->registeredActions.constBegin(); for (; it != this->registeredActions.constEnd(); ++it) { g_object_unref(it.value()); } @@ -716,8 +716,8 @@ bool UnityMenuModel::event(QEvent* 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), + GtkSimpleActionObserver* observer_item; + observer_item = gtk_simple_action_observer_new(GTK_ACTION_OBSERVABLE (priv->muxer), UnityMenuModelPrivate::registeredActionAdded, UnityMenuModelPrivate::registeredActionEnabledChanged, UnityMenuModelPrivate::registeredActionStateChanged, @@ -736,7 +736,7 @@ void UnityMenuModel::registerAction(UnityMenuAction* action) void UnityMenuModel::unregisterAction(UnityMenuAction* action) { if (priv->registeredActions.contains(action)) { - GtkActionObserverItem* observer_item; + GtkSimpleActionObserver* observer_item; observer_item = priv->registeredActions[action]; g_object_unref(observer_item); priv->registeredActions.remove(action); @@ -751,13 +751,13 @@ void UnityMenuModel::onRegisteredActionNameChanged(const QString& name) if (!action || !priv->registeredActions.contains(action)) return; - GtkActionObserverItem* observer_item; + GtkSimpleActionObserver* 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); + gtk_simple_action_observer_register_action (observer_item, action_name); const GVariantType *parameter_type; gboolean enabled; @@ -799,21 +799,21 @@ void UnityMenuModel::onRegisteredActionStateChanged(const QVariant& parameter) g_action_group_change_action_state (G_ACTION_GROUP (priv->muxer), action_name, Converter::toGVariant(parameter)); } -void UnityMenuModelPrivate::registeredActionAdded(GtkActionObserverItem *observer_item, +void UnityMenuModelPrivate::registeredActionAdded(GtkSimpleActionObserver *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) { UnityMenuActionAddEvent umaae(enabled, Converter::toQVariant(state)); QCoreApplication::sendEvent(action, &umaae); } } -void UnityMenuModelPrivate::registeredActionEnabledChanged(GtkActionObserverItem *observer_item, const gchar *action_name, gboolean enabled) +void UnityMenuModelPrivate::registeredActionEnabledChanged(GtkSimpleActionObserver *observer_item, const gchar *action_name, gboolean enabled) { UnityMenuAction *action; action = (UnityMenuAction *) g_object_get_qdata (G_OBJECT (observer_item), unity_menu_action_quark ()); @@ -824,7 +824,7 @@ void UnityMenuModelPrivate::registeredActionEnabledChanged(GtkActionObserverItem } } -void UnityMenuModelPrivate::registeredActionStateChanged(GtkActionObserverItem *observer_item, const gchar *action_name, GVariant *state) +void UnityMenuModelPrivate::registeredActionStateChanged(GtkSimpleActionObserver *observer_item, const gchar *action_name, GVariant *state) { UnityMenuAction *action; action = (UnityMenuAction *) g_object_get_qdata (G_OBJECT (observer_item), unity_menu_action_quark ()); @@ -835,7 +835,7 @@ void UnityMenuModelPrivate::registeredActionStateChanged(GtkActionObserverItem * } } -void UnityMenuModelPrivate::registeredActionRemoved(GtkActionObserverItem *observer_item, const gchar *action_name) +void UnityMenuModelPrivate::registeredActionRemoved(GtkSimpleActionObserver *observer_item, const gchar *action_name) { UnityMenuAction *action; action = (UnityMenuAction *) g_object_get_qdata (G_OBJECT (observer_item), unity_menu_action_quark ()); -- cgit v1.2.3