From fa058d5fa53b7abc0e1df5f150c8c451029893ff Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 2 Sep 2013 14:51:38 +0200 Subject: gtk_menu_tracker_item_get_action_name: return full name, including namespace --- libqmenumodel/src/gtk/gtkmenutrackeritem.c | 19 +++++++++++++------ libqmenumodel/src/gtk/gtkmenutrackeritem.h | 2 +- libqmenumodel/src/unitymenumodel.cpp | 8 ++++++-- 3 files changed, 20 insertions(+), 9 deletions(-) (limited to 'libqmenumodel') diff --git a/libqmenumodel/src/gtk/gtkmenutrackeritem.c b/libqmenumodel/src/gtk/gtkmenutrackeritem.c index e2ed1f0..3dc1d13 100644 --- a/libqmenumodel/src/gtk/gtkmenutrackeritem.c +++ b/libqmenumodel/src/gtk/gtkmenutrackeritem.c @@ -181,7 +181,7 @@ gtk_menu_tracker_item_get_property (GObject *object, g_value_set_boolean (value, gtk_menu_tracker_item_get_submenu_shown (self)); break; case PROP_ACTION_NAME: - g_value_set_string (value, gtk_menu_tracker_item_get_action_name (self)); + g_value_take_string (value, gtk_menu_tracker_item_get_action_name (self)); case PROP_ACTION_STATE: g_value_set_variant (value, self->action_state); break; @@ -621,16 +621,23 @@ gtk_menu_tracker_item_get_submenu_shown (GtkMenuTrackerItem *self) * gtk_menu_tracker_item_get_action_name: * @self: A #GtkMenuTrackerItem instance * - * Returns the action name + * Returns a newly-allocated string containing the name of the action + * associated with this menu item. + * + * Returns: (transfer full): the action name, free it with g_free() */ -const gchar * +gchar * gtk_menu_tracker_item_get_action_name (GtkMenuTrackerItem *self) { - const gchar *action_name = NULL; + const gchar *action_name; - g_menu_item_get_attribute (self->item, G_MENU_ATTRIBUTE_ACTION, "&s", &action_name); + if (!g_menu_item_get_attribute (self->item, G_MENU_ATTRIBUTE_ACTION, "&s", &action_name)) + return NULL; - return action_name; + if (self->action_namespace) + return g_strjoin (".", self->action_namespace, action_name, NULL); + else + return g_strdup (action_name); } GVariant * diff --git a/libqmenumodel/src/gtk/gtkmenutrackeritem.h b/libqmenumodel/src/gtk/gtkmenutrackeritem.h index 59a7080..c0d61f0 100644 --- a/libqmenumodel/src/gtk/gtkmenutrackeritem.h +++ b/libqmenumodel/src/gtk/gtkmenutrackeritem.h @@ -87,7 +87,7 @@ void gtk_menu_tracker_item_request_submenu_shown (GtkMenu gboolean gtk_menu_tracker_item_get_submenu_shown (GtkMenuTrackerItem *self); -const gchar * gtk_menu_tracker_item_get_action_name (GtkMenuTrackerItem *self); +gchar * gtk_menu_tracker_item_get_action_name (GtkMenuTrackerItem *self); GVariant * gtk_menu_tracker_item_get_action_state (GtkMenuTrackerItem *self); diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp index d457cad..5144127 100644 --- a/libqmenumodel/src/unitymenumodel.cpp +++ b/libqmenumodel/src/unitymenumodel.cpp @@ -432,8 +432,12 @@ QVariant UnityMenuModel::data(const QModelIndex &index, int role) const return map ? *map : QVariant(); } - case ActionRole: - return gtk_menu_tracker_item_get_action_name (item); + case ActionRole: { + gchar *action_name = gtk_menu_tracker_item_get_action_name (item); + QString v(action_name); + g_free(action_name); + return v; + } case ActionStateRole: return priv->itemState(item); -- cgit v1.2.3 From f58b7c76605623a171d2e6eba82cdbf7a788657d Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 2 Sep 2013 14:55:08 +0200 Subject: UnityMenuModel::activate: use gtk_menu_tracker_item_get_action_name Instead of fetching the action name directly. This will make sure we always get the full action name, including the name space if one is set. --- libqmenumodel/src/unitymenumodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libqmenumodel') diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp index 5144127..ff65e69 100644 --- a/libqmenumodel/src/unitymenumodel.cpp +++ b/libqmenumodel/src/unitymenumodel.cpp @@ -650,7 +650,7 @@ void UnityMenuModel::activate(int index, const QVariant& parameter) if (parameter.isValid()) { gchar *action; - gtk_menu_tracker_item_get_attribute (item, "action", "s", &action); + action = gtk_menu_tracker_item_get_action_name (item); g_action_group_activate_action (G_ACTION_GROUP (priv->muxer), action, Converter::toGVariant(parameter)); g_free (action); -- cgit v1.2.3 From 2641328dca5a7db154e5dbca7d9904d3c321974e Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 2 Sep 2013 18:35:00 +0200 Subject: Add UnityMenuModel::getAction A method that returns a UnityMenuAction for a menu item. It must be used if the action name came from an attribute on the menu item so that the menu item's namespace can be prepended to the action name. --- libqmenumodel/src/gtk/gtkmenutrackeritem.c | 6 ++++++ libqmenumodel/src/gtk/gtkmenutrackeritem.h | 2 ++ libqmenumodel/src/unitymenumodel.cpp | 28 ++++++++++++++++++++++++++++ libqmenumodel/src/unitymenumodel.h | 1 + 4 files changed, 37 insertions(+) (limited to 'libqmenumodel') diff --git a/libqmenumodel/src/gtk/gtkmenutrackeritem.c b/libqmenumodel/src/gtk/gtkmenutrackeritem.c index 3dc1d13..34e168a 100644 --- a/libqmenumodel/src/gtk/gtkmenutrackeritem.c +++ b/libqmenumodel/src/gtk/gtkmenutrackeritem.c @@ -649,6 +649,12 @@ gtk_menu_tracker_item_get_action_state (GtkMenuTrackerItem *self) return NULL; } +const gchar * +gtk_menu_tracker_item_get_action_namespace (GtkMenuTrackerItem *self) +{ + return self->action_namespace; +} + static void gtk_menu_tracker_item_set_submenu_shown (GtkMenuTrackerItem *self, gboolean submenu_shown) diff --git a/libqmenumodel/src/gtk/gtkmenutrackeritem.h b/libqmenumodel/src/gtk/gtkmenutrackeritem.h index c0d61f0..dc62bf1 100644 --- a/libqmenumodel/src/gtk/gtkmenutrackeritem.h +++ b/libqmenumodel/src/gtk/gtkmenutrackeritem.h @@ -91,6 +91,8 @@ gchar * gtk_menu_tracker_item_get_action_name (GtkMen GVariant * gtk_menu_tracker_item_get_action_state (GtkMenuTrackerItem *self); +const gchar * gtk_menu_tracker_item_get_action_namespace (GtkMenuTrackerItem *self); + gboolean gtk_menu_tracker_item_get_attribute (GtkMenuTrackerItem *self, const gchar *attribute, const gchar *format, diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp index ff65e69..026cb93 100644 --- a/libqmenumodel/src/unitymenumodel.cpp +++ b/libqmenumodel/src/unitymenumodel.cpp @@ -641,6 +641,34 @@ QVariant UnityMenuModel::get(int row, const QByteArray &role) return this->data(this->index(row, 0), priv->roles[role]); } +UnityMenuAction * UnityMenuModel::getAction(int row, const QByteArray &name) +{ + GSequenceIter *iter; + GtkMenuTrackerItem *item; + const gchar *action_namespace; + gchar *action_name; + UnityMenuAction *action; + + iter = g_sequence_get_iter_at_pos (priv->items, row); + if (g_sequence_iter_is_end (iter)) + return NULL; + + item = (GtkMenuTrackerItem *) g_sequence_get (iter); + action_namespace = gtk_menu_tracker_item_get_action_namespace (item); + if (action_namespace != NULL) + action_name = g_strjoin (".", action_namespace, name.constData(), NULL); + else + action_name = g_strdup (name.constData()); + + action = new UnityMenuAction(this); + action->setModel(this); + action->setName(action_name); + + g_free (action_name); + + return action; +} + void UnityMenuModel::activate(int index, const QVariant& parameter) { GtkMenuTrackerItem *item; diff --git a/libqmenumodel/src/unitymenumodel.h b/libqmenumodel/src/unitymenumodel.h index a229f09..1391b27 100644 --- a/libqmenumodel/src/unitymenumodel.h +++ b/libqmenumodel/src/unitymenumodel.h @@ -58,6 +58,7 @@ public: 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); + Q_INVOKABLE UnityMenuAction * getAction(int row, const QByteArray &name); Q_INVOKABLE void activate(int index, const QVariant& parameter = QVariant()); Q_INVOKABLE void changeState(int index, const QVariant& parameter); -- cgit v1.2.3 From 936588550f0f91ee95386931a5297b46c3ba9c14 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 3 Sep 2013 12:02:47 +0200 Subject: Add UnityMenuAction::index property --- libqmenumodel/src/unitymenuaction.cpp | 16 +++++- libqmenumodel/src/unitymenuaction.h | 7 +++ libqmenumodel/src/unitymenumodel.cpp | 103 +++++++++++++++++++--------------- libqmenumodel/src/unitymenumodel.h | 2 +- 4 files changed, 82 insertions(+), 46 deletions(-) (limited to 'libqmenumodel') diff --git a/libqmenumodel/src/unitymenuaction.cpp b/libqmenumodel/src/unitymenuaction.cpp index b41fd3e..46edf16 100644 --- a/libqmenumodel/src/unitymenuaction.cpp +++ b/libqmenumodel/src/unitymenuaction.cpp @@ -26,7 +26,8 @@ UnityMenuAction::UnityMenuAction(QObject* parent) : QObject(parent), m_valid(false), m_enabled(false), - m_model(NULL) + m_model(NULL), + m_index(-1) { } @@ -106,6 +107,19 @@ void UnityMenuAction::setValid(bool valid) } } +int UnityMenuAction::index() const +{ + return m_index; +} + +void UnityMenuAction::setIndex(int i) +{ + if (i != m_index) { + m_index = i; + Q_EMIT indexChanged(m_index); + } +} + void UnityMenuAction::registerAction() { if (m_model) { diff --git a/libqmenumodel/src/unitymenuaction.h b/libqmenumodel/src/unitymenuaction.h index b8391fe..7479d2c 100644 --- a/libqmenumodel/src/unitymenuaction.h +++ b/libqmenumodel/src/unitymenuaction.h @@ -32,6 +32,8 @@ class UnityMenuAction: public QObject 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) + Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged) + public: UnityMenuAction(QObject* parent = 0); ~UnityMenuAction(); @@ -42,6 +44,9 @@ public: UnityMenuModel* model() const; void setModel(UnityMenuModel* model); + int index() const; + void setIndex(int i); + QVariant state() const; bool isEnabled() const; bool isValid() const; @@ -55,6 +60,7 @@ Q_SIGNALS: void stateChanged(const QVariant& name); void enabledChanged(bool enabled); void validChanged(bool valid); + void indexChanged(int index); protected: virtual bool event(QEvent* e); @@ -72,6 +78,7 @@ private: bool m_valid; bool m_enabled; UnityMenuModel* m_model; + int m_index; }; #endif // UNITYMENUACTIONGROUP_H diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp index 026cb93..2000d5b 100644 --- a/libqmenumodel/src/unitymenumodel.cpp +++ b/libqmenumodel/src/unitymenumodel.cpp @@ -93,6 +93,9 @@ public: 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); + + gchar * fullActionName(UnityMenuAction *action); + void updateRegisteredAction(UnityMenuAction *action); }; void menu_item_free (gpointer data) @@ -641,34 +644,6 @@ QVariant UnityMenuModel::get(int row, const QByteArray &role) return this->data(this->index(row, 0), priv->roles[role]); } -UnityMenuAction * UnityMenuModel::getAction(int row, const QByteArray &name) -{ - GSequenceIter *iter; - GtkMenuTrackerItem *item; - const gchar *action_namespace; - gchar *action_name; - UnityMenuAction *action; - - iter = g_sequence_get_iter_at_pos (priv->items, row); - if (g_sequence_iter_is_end (iter)) - return NULL; - - item = (GtkMenuTrackerItem *) g_sequence_get (iter); - action_namespace = gtk_menu_tracker_item_get_action_namespace (item); - if (action_namespace != NULL) - action_name = g_strjoin (".", action_namespace, name.constData(), NULL); - else - action_name = g_strdup (name.constData()); - - action = new UnityMenuAction(this); - action->setModel(this); - action->setName(action_name); - - g_free (action_name); - - return action; -} - void UnityMenuModel::activate(int index, const QVariant& parameter) { GtkMenuTrackerItem *item; @@ -783,6 +758,7 @@ void UnityMenuModel::registerAction(UnityMenuAction* action) priv->registeredActions[action] = observer_item; connect(action, SIGNAL(nameChanged(const QString&)), SLOT(onRegisteredActionNameChanged(const QString&))); + connect(action, SIGNAL(indexChanged(int)), SLOT(onRegisteredActionIndexChanged(int))); connect(action, SIGNAL(activate(const QVariant&)), SLOT(onRegisteredActionActivated(const QVariant&))); connect(action, SIGNAL(changeState(const QVariant&)), SLOT(onRegisteredActionStateChanged(const QVariant&))); } @@ -800,26 +776,51 @@ void UnityMenuModel::unregisterAction(UnityMenuAction* action) } } -void UnityMenuModel::onRegisteredActionNameChanged(const QString& name) +/* Returns the full name for @action + * + * If @action is associated with a menu item that is inside of a + * section or submenu with "action-namespace" set, this namespace + * is prepended to @action->name() + */ +char * UnityMenuModelPrivate::fullActionName(UnityMenuAction *action) { - UnityMenuAction* action = qobject_cast(sender()); - if (!action || !priv->registeredActions.contains(action)) - return; + GSequenceIter *iter; + const gchar *name; + gchar *full_name = NULL; - GtkSimpleActionObserver* observer_item; - observer_item = priv->registeredActions[action]; + name = action->name().toUtf8().constData(); - QByteArray nameArray = name.toUtf8(); - const gchar* action_name = nameArray.constData(); + iter = g_sequence_get_iter_at_pos (this->items, action->index()); + if (!g_sequence_iter_is_end (iter)) { + GtkMenuTrackerItem *item; + const gchar *action_namespace; - gtk_simple_action_observer_register_action (observer_item, action_name); + item = (GtkMenuTrackerItem *) g_sequence_get (iter); + action_namespace = gtk_menu_tracker_item_get_action_namespace (item); + if (action_namespace != NULL) + return g_strjoin (".", action_namespace, name, NULL); + } + + return g_strdup (name); +} - const GVariantType *parameter_type; +void UnityMenuModelPrivate::updateRegisteredAction(UnityMenuAction *action) +{ + GtkSimpleActionObserver *observer_item; + gchar *action_name; gboolean enabled; GVariant *state; - if (g_action_group_query_action (G_ACTION_GROUP (priv->muxer), action_name, - &enabled, ¶meter_type, NULL, NULL, &state)) + if (!action || !this->registeredActions.contains(action)) + return; + + action_name = fullActionName(action); + + observer_item = this->registeredActions[action]; + gtk_simple_action_observer_register_action (observer_item, action_name); + + if (g_action_group_query_action (G_ACTION_GROUP (this->muxer), action_name, + &enabled, NULL, NULL, NULL, &state)) { UnityMenuActionAddEvent umaae(enabled, Converter::toQVariant(state)); QCoreApplication::sendEvent(action, &umaae); @@ -828,6 +829,18 @@ void UnityMenuModel::onRegisteredActionNameChanged(const QString& name) g_variant_unref (state); } } + + g_free(action_name); +} + +void UnityMenuModel::onRegisteredActionNameChanged(const QString& name) +{ + priv->updateRegisteredAction(qobject_cast(sender())); +} + +void UnityMenuModel::onRegisteredActionIndexChanged(int index) +{ + priv->updateRegisteredAction(qobject_cast(sender())); } void UnityMenuModel::onRegisteredActionActivated(const QVariant& parameter) @@ -836,10 +849,11 @@ void UnityMenuModel::onRegisteredActionActivated(const QVariant& parameter) if (!action || action->name().isEmpty()) return; - QByteArray nameArray = action->name().toUtf8(); - const gchar* action_name = nameArray.constData(); + gchar* action_name = priv->fullActionName(action); g_action_group_activate_action (G_ACTION_GROUP (priv->muxer), action_name, Converter::toGVariant(parameter)); + + g_free(action_name); } void UnityMenuModel::onRegisteredActionStateChanged(const QVariant& parameter) @@ -848,10 +862,11 @@ void UnityMenuModel::onRegisteredActionStateChanged(const QVariant& parameter) if (!action || action->name().isEmpty()) return; - QByteArray nameArray = action->name().toUtf8(); - const gchar* action_name = nameArray.constData(); + gchar* action_name = priv->fullActionName(action); g_action_group_change_action_state (G_ACTION_GROUP (priv->muxer), action_name, Converter::toGVariant(parameter)); + + g_free(action_name); } void UnityMenuModelPrivate::registeredActionAdded(GtkSimpleActionObserver *observer_item, diff --git a/libqmenumodel/src/unitymenumodel.h b/libqmenumodel/src/unitymenumodel.h index 1391b27..30bc62d 100644 --- a/libqmenumodel/src/unitymenumodel.h +++ b/libqmenumodel/src/unitymenumodel.h @@ -58,7 +58,6 @@ public: 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); - Q_INVOKABLE UnityMenuAction * getAction(int row, const QByteArray &name); Q_INVOKABLE void activate(int index, const QVariant& parameter = QVariant()); Q_INVOKABLE void changeState(int index, const QVariant& parameter); @@ -74,6 +73,7 @@ Q_SIGNALS: protected Q_SLOTS: void onRegisteredActionNameChanged(const QString& name); + void onRegisteredActionIndexChanged(int); void onRegisteredActionActivated(const QVariant& parameter); void onRegisteredActionStateChanged(const QVariant& parameter); -- cgit v1.2.3 From e01b6b5a513c57c7a52c1a14d4a44dcf6a42025d Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 3 Sep 2013 13:17:30 +0200 Subject: fullActioName: make sure 'name' is valid for the duration of the function --- libqmenumodel/src/unitymenumodel.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'libqmenumodel') diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp index 2000d5b..a0ab4ff 100644 --- a/libqmenumodel/src/unitymenumodel.cpp +++ b/libqmenumodel/src/unitymenumodel.cpp @@ -785,10 +785,12 @@ void UnityMenuModel::unregisterAction(UnityMenuAction* action) char * UnityMenuModelPrivate::fullActionName(UnityMenuAction *action) { GSequenceIter *iter; + QByteArray bytes; const gchar *name; gchar *full_name = NULL; - name = action->name().toUtf8().constData(); + bytes = action->name().toUtf8(); + name = bytes.constData(); iter = g_sequence_get_iter_at_pos (this->items, action->index()); if (!g_sequence_iter_is_end (iter)) { -- cgit v1.2.3