diff options
author | Robert Tari <robert@tari.in> | 2021-11-16 08:10:18 +0100 |
---|---|---|
committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2021-11-17 13:14:54 +0100 |
commit | f8036895f95acc49f484af564d2b56f14c158dd9 (patch) | |
tree | 8d4b07d34520f61b2557cd5ba4977343ee496cb8 /libqmenumodel/src/unitymenumodel.cpp | |
parent | 8089cd5052ff617c05ef981b24881d4b89b5436c (diff) | |
download | qmenumodel-f8036895f95acc49f484af564d2b56f14c158dd9.tar.gz qmenumodel-f8036895f95acc49f484af564d2b56f14c158dd9.tar.bz2 qmenumodel-f8036895f95acc49f484af564d2b56f14c158dd9.zip |
Rename unity* source files
Diffstat (limited to 'libqmenumodel/src/unitymenumodel.cpp')
-rw-r--r-- | libqmenumodel/src/unitymenumodel.cpp | 1064 |
1 files changed, 0 insertions, 1064 deletions
diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp deleted file mode 100644 index fafed4c..0000000 --- a/libqmenumodel/src/unitymenumodel.cpp +++ /dev/null @@ -1,1064 +0,0 @@ -/* - * 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: Lars Uebernickel <lars.uebernickel@canonical.com> - */ - -#include "unitymenumodel.h" -#include "converter.h" -#include "actionstateparser.h" -#include "unitymenumodelevents.h" -#include "unitymenuaction.h" -#include "unitymenuactionevents.h" -#include "logging.h" - -#include <QIcon> -#include <QQmlComponent> -#include <QCoreApplication> -#include <QKeySequence> - -extern "C" { - #include "gtk/gtkactionmuxer.h" - #include "gtk/gtkmenutracker.h" - #include "gtk/gtksimpleactionobserver.h" -} - -Q_LOGGING_CATEGORY(unitymenumodel, "qmenumodel.unitymenumodel", QtCriticalMsg) - -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, - SensitiveRole, - IsSeparatorRole, - IconRole, - TypeRole, - ExtendedAttributesRole, - ActionRole, - ActionStateRole, - IsCheckRole, - IsRadioRole, - IsToggledRole, - ShortcutRole, - HasSubmenuRole -}; - -class UnityMenuModelPrivate -{ -public: - UnityMenuModelPrivate(UnityMenuModel *model); - UnityMenuModelPrivate(const UnityMenuModelPrivate& other, UnityMenuModel *model); - ~UnityMenuModelPrivate(); - - void clearItems(bool resetModel=true); - void clearName(); - void updateActions(); - void updateMenuModel(); - QVariant itemState(GtkMenuTrackerItem *item); - - UnityMenuModel *model; - GtkActionMuxer *muxer; - GtkMenuTracker *menutracker; - GSequence *items; - GDBusConnection *connection; - QByteArray busName; - QByteArray nameOwner; - guint nameWatchId; - QVariantMap actions; - QByteArray menuObjectPath; - QHash<QByteArray, int> roles; - ActionStateParser* actionStateParser; - QHash<UnityMenuAction*, GtkSimpleActionObserver*> registeredActions; - bool destructorGuard; - - 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(GPtrArray *items, gint position, gpointer user_data); - static void menuItemRemoved(gint position, gint n_items, gpointer user_data); - static void menuItemChanged(GObject *object, GParamSpec *pspec, gpointer user_data); - - static void registeredActionAdded(GtkSimpleActionObserver *observer_item, - const gchar *action_name, - gboolean enabled, - GVariant *state); - 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) -{ - GtkMenuTrackerItem *item = (GtkMenuTrackerItem *) data; - - g_signal_handlers_disconnect_by_func (item, (gpointer) UnityMenuModelPrivate::menuItemChanged, NULL); - g_object_unref (item); -} - -UnityMenuModelPrivate::UnityMenuModelPrivate(UnityMenuModel *model) -{ - this->model = model; - this->menutracker = NULL; - this->connection = NULL; - this->nameWatchId = 0; - this->actionStateParser = new ActionStateParser(model); - this->destructorGuard = false; - - this->muxer = gtk_action_muxer_new (); - - 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->destructorGuard = false; - - this->muxer = GTK_ACTION_MUXER( g_object_ref(other.muxer)); - - this->items = g_sequence_new (menu_item_free); -} - -UnityMenuModelPrivate::~UnityMenuModelPrivate() -{ - this->destructorGuard = true; - this->clearItems(false); - - g_sequence_free(this->items); - g_clear_pointer (&this->menutracker, gtk_menu_tracker_free); - g_clear_object (&this->muxer); - g_clear_object (&this->connection); - - QHash<UnityMenuAction*, GtkSimpleActionObserver*>::const_iterator it = this->registeredActions.constBegin(); - for (; it != this->registeredActions.constEnd(); ++it) { - g_object_unref(it.value()); - it.key()->setModel(NULL); - } - this->registeredActions.clear(); - - if (this->nameWatchId) - g_bus_unwatch_name (this->nameWatchId); -} - -void UnityMenuModelPrivate::clearItems(bool resetModel) -{ - UnityMenuModelClearEvent ummce(resetModel); - QCoreApplication::sendEvent(model, &ummce); -} - -void UnityMenuModelPrivate::clearName() -{ - this->clearItems(); - - this->nameOwner = QByteArray(); - - this->updateActions(); - this->updateMenuModel(); - - Q_EMIT model->nameOwnerChanged (this->nameOwner); -} - -void UnityMenuModelPrivate::updateActions() -{ - Q_FOREACH (QString prefix, this->actions.keys()) - gtk_action_muxer_remove (this->muxer, prefix.toUtf8()); - - if (this->nameOwner.isEmpty()) - return; - - for (QVariantMap::const_iterator it = this->actions.constBegin(); it != this->actions.constEnd(); ++it) { - GDBusActionGroup *actions; - - actions = g_dbus_action_group_get (this->connection, this->nameOwner, it.value().toByteArray()); - gtk_action_muxer_insert (this->muxer, it.key().toUtf8(), G_ACTION_GROUP (actions)); - - g_object_unref (actions); - } -} - -void UnityMenuModelPrivate::updateMenuModel() -{ - this->clearItems(); - g_clear_pointer (&this->menutracker, gtk_menu_tracker_free); - - if (!this->nameOwner.isEmpty()) { - GDBusMenuModel *menu; - - menu = g_dbus_menu_model_get (this->connection, this->nameOwner, this->menuObjectPath.constData()); - this->menutracker = gtk_menu_tracker_new (GTK_ACTION_OBSERVABLE (this->muxer), - G_MENU_MODEL (menu), TRUE, NULL, - menuItemInserted, menuItemRemoved, this); - - g_object_unref (menu); - } -} - -QVariant UnityMenuModelPrivate::itemState(GtkMenuTrackerItem *item) -{ - QVariant result; - - GVariant *state = gtk_menu_tracker_item_get_action_state (item); - if (state != NULL) { - if (actionStateParser != NULL) { - result = actionStateParser->toQVariant(state); - } - g_variant_unref (state); - } - - return result; -} - -void UnityMenuModelPrivate::nameAppeared(GDBusConnection *connection, const gchar *name, const gchar *owner, gpointer user_data) -{ - UnityMenuModelPrivate *priv = (UnityMenuModelPrivate *)user_data; - - priv->connection = (GDBusConnection *) g_object_ref (connection); - priv->nameOwner = owner; - - priv->updateActions(); - priv->updateMenuModel(); - - Q_EMIT priv->model->nameOwnerChanged (priv->nameOwner); -} - -void UnityMenuModelPrivate::nameVanished(GDBusConnection *connection, const gchar *name, gpointer user_data) -{ - UnityMenuModelPrivate *priv = (UnityMenuModelPrivate *)user_data; - - priv->clearName(); -} - -void UnityMenuModelPrivate::menuItemInserted(GPtrArray *items, gint position, gpointer user_data) -{ - UnityMenuModelPrivate *priv = (UnityMenuModelPrivate *)user_data; - - UnityMenuModelAddRowEvent ummare(items, position); - QCoreApplication::sendEvent(priv->model, &ummare); -} - -void UnityMenuModelPrivate::menuItemRemoved(gint position, gint n_items, gpointer user_data) -{ - UnityMenuModelPrivate *priv = (UnityMenuModelPrivate *)user_data; - - UnityMenuModelRemoveRowEvent ummrre(position, n_items); - QCoreApplication::sendEvent(priv->model, &ummrre); -} - -void UnityMenuModelPrivate::menuItemChanged(GObject *object, GParamSpec *pspec, gpointer user_data) -{ - GSequenceIter *it = (GSequenceIter *) user_data; - GtkMenuTrackerItem *item; - GtkActionObservable *muxer; - UnityMenuModel *model; - gint position; - - item = (GtkMenuTrackerItem *) g_sequence_get (it); - muxer = _gtk_menu_tracker_item_get_observable (item); - model = (UnityMenuModel *) g_object_get_qdata (G_OBJECT (item), unity_menu_model_quark ()); - position = g_sequence_iter_get_position (it); - - UnityMenuModelDataChangeEvent ummdce(position); - QCoreApplication::sendEvent(model, &ummdce); -} - -UnityMenuModel::UnityMenuModel(QObject *parent): - QAbstractListModel(parent) -{ - priv = new UnityMenuModelPrivate(this); -} - -UnityMenuModel::UnityMenuModel(const UnityMenuModelPrivate& other, UnityMenuModel *parent): - QAbstractListModel(parent) -{ - priv = new UnityMenuModelPrivate(other, this); -} - -UnityMenuModel::~UnityMenuModel() -{ - delete priv; -} - -QByteArray UnityMenuModel::busName() const -{ - return priv->busName; -} - -QByteArray UnityMenuModel::nameOwner() const -{ - return priv->nameOwner; -} - -void UnityMenuModel::setBusName(const QByteArray &name) -{ - if (name == priv->busName) - return; - - priv->clearName(); - - if (priv->nameWatchId) - g_bus_unwatch_name (priv->nameWatchId); - - priv->nameWatchId = g_bus_watch_name (G_BUS_TYPE_SESSION, name.constData(), G_BUS_NAME_WATCHER_FLAGS_AUTO_START, - UnityMenuModelPrivate::nameAppeared, UnityMenuModelPrivate::nameVanished, - priv, NULL); - priv->busName = name; - Q_EMIT busNameChanged (priv->busName); -} - -QVariantMap UnityMenuModel::actions() const -{ - return priv->actions; -} - -void UnityMenuModel::setActions(const QVariantMap &actions) -{ - priv->actions = actions; - priv->updateActions(); -} - -QByteArray UnityMenuModel::menuObjectPath() const -{ - return priv->menuObjectPath; -} - -void UnityMenuModel::setMenuObjectPath(const QByteArray &path) -{ - priv->menuObjectPath = path; - priv->updateMenuModel(); -} - -ActionStateParser* UnityMenuModel::actionStateParser() const -{ - return priv->actionStateParser; -} - -void UnityMenuModel::setActionStateParser(ActionStateParser* actionStateParser) -{ - if (priv->actionStateParser != actionStateParser) { - priv->actionStateParser = actionStateParser; - Q_EMIT actionStateParserChanged(actionStateParser); - } -} - -int UnityMenuModel::rowCount(const QModelIndex &parent) const -{ - return !parent.isValid() ? g_sequence_get_length (priv->items) : 0; -} - -int UnityMenuModel::columnCount(const QModelIndex &parent) const -{ - return 1; -} - -static QString iconUri(GIcon *icon) -{ - QString uri; - - if (G_IS_THEMED_ICON (icon)) { - const gchar* const* iconNames = g_themed_icon_get_names (G_THEMED_ICON (icon)); - guint index = 0; - while(iconNames[index] != NULL) { - if (QIcon::hasThemeIcon(iconNames[index])) { - uri = QString("image://theme/") + iconNames[index]; - break; - } - index++; - } - } - else if (G_IS_FILE_ICON (icon)) { - GFile *file; - - file = g_file_icon_get_file (G_FILE_ICON (icon)); - if (file) { - gchar *fileuri; - - fileuri = g_file_get_uri (file); - uri = QString(fileuri); - - g_free (fileuri); - } - } - else if (G_IS_BYTES_ICON (icon)) { - gsize size; - gconstpointer data; - gchar *base64; - - data = g_bytes_get_data (g_bytes_icon_get_bytes (G_BYTES_ICON (icon)), &size); - base64 = g_base64_encode ((const guchar *) data, size); - - uri = QString("data://"); - uri.append (base64); - - g_free (base64); - } - - return uri; -} - -QVariant UnityMenuModel::data(const QModelIndex &index, int role) const -{ - GSequenceIter *it; - GtkMenuTrackerItem *item; - - it = g_sequence_get_iter_at_pos (priv->items, index.row()); - if (g_sequence_iter_is_end (it)) { - return QVariant(); - } - - item = (GtkMenuTrackerItem *) g_sequence_get (it); - if (!item) { - return QVariant(); - } - - switch (role) { - case LabelRole: - return gtk_menu_tracker_item_get_label (item); - - case SensitiveRole: - return gtk_menu_tracker_item_get_sensitive (item) == TRUE ? true : false; - - case IsSeparatorRole: - return gtk_menu_tracker_item_get_is_separator (item) == TRUE ? true : false; - - case IconRole: { - GIcon *icon = gtk_menu_tracker_item_get_icon (item); - if (icon) { - QString uri = iconUri(icon); - g_object_unref (icon); - return uri; - } - else - return QString(); - } - - case TypeRole: { - gchar *type; - auto ret = gtk_menu_tracker_item_get_attribute (item, "x-ayatana-type", "s", &type); - - // If we can't get x-ayatana-type, try legacy x-canonical-type type - if (!ret) - ret = gtk_menu_tracker_item_get_attribute (item, "x-canonical-type", "s", &type); - - if (ret) { - QVariant v(type); - g_free (type); - return v; - } - else - return QVariant(); - } - - case ExtendedAttributesRole: { - QVariantMap *map = (QVariantMap *) g_object_get_qdata (G_OBJECT (item), unity_menu_item_extended_attributes_quark ()); - return map ? *map : QVariant(); - } - - 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); - - case IsCheckRole: - return gtk_menu_tracker_item_get_role (item) == GTK_MENU_TRACKER_ITEM_ROLE_CHECK; - - case IsRadioRole: - return gtk_menu_tracker_item_get_role (item) == GTK_MENU_TRACKER_ITEM_ROLE_RADIO; - - case IsToggledRole: - return gtk_menu_tracker_item_get_toggled (item) != FALSE; - - case ShortcutRole: - return QKeySequence(gtk_menu_tracker_item_get_accel (item), QKeySequence::NativeText); - - case HasSubmenuRole: - return gtk_menu_tracker_item_get_has_submenu (item) != FALSE; - - default: - return QVariant(); - } -} - -QModelIndex UnityMenuModel::index(int row, int column, const QModelIndex &parent) const -{ - return createIndex(row, column); -} - -QModelIndex UnityMenuModel::parent(const QModelIndex &index) const -{ - return QModelIndex(); -} - -QHash<int, QByteArray> UnityMenuModel::roleNames() const -{ - QHash<int, QByteArray> names; - - names[LabelRole] = "label"; - names[SensitiveRole] = "sensitive"; - names[IsSeparatorRole] = "isSeparator"; - names[IconRole] = "icon"; - names[TypeRole] = "type"; - names[ExtendedAttributesRole] = "ext"; - names[ActionRole] = "action"; - names[ActionStateRole] = "actionState"; - names[IsCheckRole] = "isCheck"; - names[IsRadioRole] = "isRadio"; - names[IsToggledRole] = "isToggled"; - names[ShortcutRole] = "shortcut"; - names[HasSubmenuRole] = "hasSubmenu"; - - return names; -} - -QObject * UnityMenuModel::submenu(int position, QQmlComponent* actionStateParser) -{ - GSequenceIter *it; - GtkMenuTrackerItem *item; - UnityMenuModel *model; - - it = g_sequence_get_iter_at_pos (priv->items, position); - if (g_sequence_iter_is_end (it)) { - return NULL; - } - - item = (GtkMenuTrackerItem *) g_sequence_get (it); - if (!item || !gtk_menu_tracker_item_get_has_submenu (item)) { - return NULL; - } - - model = (UnityMenuModel *) g_object_get_qdata (G_OBJECT (item), unity_submenu_model_quark ()); - if (model == NULL) { - model = new UnityMenuModel(*priv, this); - - if (actionStateParser) { - ActionStateParser* parser = qobject_cast<ActionStateParser*>(actionStateParser->create()); - if (parser) { - model->setActionStateParser(parser); - } - } - - model->priv->menutracker = gtk_menu_tracker_new_for_item_submenu (item, - UnityMenuModelPrivate::menuItemInserted, - UnityMenuModelPrivate::menuItemRemoved, - model->priv); - g_object_set_qdata (G_OBJECT (item), unity_submenu_model_quark (), model); - } - - return model; -} - -static void freeExtendedAttrs(gpointer data) -{ - QVariantMap *extendedAttrs = (QVariantMap *) data; - delete extendedAttrs; -} - -static QVariant attributeToQVariant(GVariant *value, const QString &type) -{ - QVariant result; - - if (type == "int") { - if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT32)) { - result = QVariant(g_variant_get_int32(value)); - } - } - else if (type == "int64") { - if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT64)) { - result = QVariant((qlonglong)g_variant_get_int64(value)); - } - } - else if (type == "bool") { - if (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)) { - result = QVariant(g_variant_get_boolean(value)); - } - } - else if (type == "string") { - if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) { - result = QVariant(g_variant_get_string(value, NULL)); - } - } - else if (type == "double") { - if (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)) { - result = QVariant(g_variant_get_double(value)); - } - } - else if (type == "variant") { - if (g_variant_is_of_type (value, G_VARIANT_TYPE_VARIANT)) { - result = Converter::toQVariant(value); - } - } - else if (type == "icon") { - GIcon *icon = g_icon_deserialize (value); - if (icon) { - result = iconUri(icon); - g_object_unref (icon); - } - else { - result = QVariant(""); - } - } - - return result; -} - -/* convert 'some-key' to 'someKey' or 'SomeKey'. (from dconf-qt) */ -static QString qtify_name(const char *name) -{ - bool next_cap = false; - QString result; - - while (*name) { - if (*name == '-') { - next_cap = true; - } else if (next_cap) { - result.append(toupper(*name)); - next_cap = false; - } else { - result.append(*name); - } - - name++; - } - - return result; -} - -bool UnityMenuModel::loadExtendedAttributes(int position, const QVariantMap &schema) -{ - GSequenceIter *it; - GtkMenuTrackerItem *item; - QVariantMap *extendedAttrs; - - it = g_sequence_get_iter_at_pos (priv->items, position); - if (g_sequence_iter_is_end (it)) { - return false; - } - - item = (GtkMenuTrackerItem *) g_sequence_get (it); - if (!item) { - return false; - } - - extendedAttrs = new QVariantMap; - - for (QVariantMap::const_iterator it = schema.constBegin(); it != schema.constEnd(); ++it) { - QString name = it.key(); - QString type = it.value().toString(); - - GVariant *value = gtk_menu_tracker_item_get_attribute_value (item, name.toUtf8(), NULL); - if (value == NULL) { - qCWarning(unitymenumodel, "loadExtendedAttributes: menu item does not contain '%s'", it.key().toUtf8().constData()); - continue; - } - - const QVariant &qvalue = attributeToQVariant(value, type); - if (qvalue.isValid()) - extendedAttrs->insert(qtify_name (name.toUtf8()), qvalue); - else - qCWarning(unitymenumodel, "loadExtendedAttributes: key '%s' is of type '%s' (expected '%s')", - name.toUtf8().constData(), g_variant_get_type_string(value), type.constData()); - - g_variant_unref (value); - } - - g_object_set_qdata_full (G_OBJECT (item), unity_menu_item_extended_attributes_quark (), - extendedAttrs, freeExtendedAttrs); - - Q_EMIT dataChanged(index(position, 0), index(position, 0), QVector<int>() << ExtendedAttributesRole); - return true; -} - -QVariant UnityMenuModel::get(int row, const QByteArray &role) -{ - if (priv->roles.isEmpty()) { - QHash<int, QByteArray> names = roleNames(); - Q_FOREACH (int role, names.keys()) - priv->roles.insert(names[role], role); - } - - return this->data(this->index(row, 0), priv->roles[role]); -} - -void UnityMenuModel::activate(int index, const QVariant& parameter) -{ - GSequenceIter *it; - GtkMenuTrackerItem *item; - GVariant *value; - const GVariantType *parameter_type; - - it = g_sequence_get_iter_at_pos (priv->items, index); - if (g_sequence_iter_is_end (it)) { - return; - } - - item = (GtkMenuTrackerItem *) g_sequence_get (it); - if (!item) { - return; - } - - if (parameter.isValid()) { - gchar *action; - - action = gtk_menu_tracker_item_get_action_name (item); - parameter_type = g_action_group_get_action_parameter_type (G_ACTION_GROUP (priv->muxer), action); - value = Converter::toGVariantWithSchema(parameter, g_variant_type_peek_string (parameter_type)); - g_action_group_activate_action (G_ACTION_GROUP (priv->muxer), action, value); - - g_free (action); - } else { - gtk_menu_tracker_item_activated (item); - } -} - -void UnityMenuModel::aboutToShow(int index) -{ - GSequenceIter *it = g_sequence_get_iter_at_pos (priv->items, index); - if (g_sequence_iter_is_end (it)) { - return; - } - - auto item = static_cast<GtkMenuTrackerItem*>(g_sequence_get(it)); - if (!item) { - return; - } - - quint64 actionTag; - if (gtk_menu_tracker_item_get_attribute (item, "qtubuntu-tag", "t", &actionTag)) { - // Child UnityMenuModel have priv->connection null, so climb to the parent until we find a non null one - UnityMenuModelPrivate *privToUse = priv; - while (privToUse && !privToUse->connection) { - auto pModel = dynamic_cast<UnityMenuModel*>(privToUse->model->QObject::parent()); - if (pModel) { - privToUse = pModel->priv; - } else { - privToUse = nullptr; - } - } - if (privToUse) { - g_dbus_connection_call (privToUse->connection, - privToUse->busName, - privToUse->menuObjectPath, - "qtubuntu.actions.extra", - "aboutToShow", - g_variant_new("(t)", actionTag), - nullptr, - G_DBUS_CALL_FLAGS_NO_AUTO_START, - G_MAXINT, - nullptr, - nullptr, - nullptr); - } - } -} - -void UnityMenuModel::activateByVariantString(int index, const QString& parameter) -{ - activate(index, Converter::toQVariantFromVariantString(parameter)); -} - -void UnityMenuModel::changeStateByVariantString(int index, const QString& parameter) -{ - changeState(index, Converter::toQVariantFromVariantString(parameter)); -} - -void UnityMenuModel::changeState(int index, const QVariant& parameter) -{ - GSequenceIter *it; - GtkMenuTrackerItem* item; - GVariant* data; - GVariant* current_state; - - it = g_sequence_get_iter_at_pos (priv->items, index); - if (g_sequence_iter_is_end (it)) { - return; - } - - item = (GtkMenuTrackerItem *) g_sequence_get (it); - if (!item) { - return; - } - - current_state = gtk_menu_tracker_item_get_action_state (item); - if (current_state) { - // Attempt to convert the parameter to the expected type - data = Converter::toGVariantWithSchema(parameter, g_variant_get_type_string(current_state)); - g_variant_unref (current_state); - } else { - data = Converter::toGVariant(parameter); - } - - gtk_menu_tracker_item_change_state (item, data); - if (data) { - g_variant_unref(data); - } -} - - -bool UnityMenuModel::event(QEvent* e) -{ - if (e->type() == UnityMenuModelClearEvent::eventType) { - UnityMenuModelClearEvent *emmce = static_cast<UnityMenuModelClearEvent*>(e); - - GSequenceIter *begin; - GSequenceIter *end; - - if (emmce->reset) - beginResetModel(); - - begin = g_sequence_get_begin_iter (priv->items); - end = g_sequence_get_end_iter (priv->items); - g_sequence_remove_range (begin, end); - - if (emmce->reset) - endResetModel(); - - return true; - } else if (e->type() == UnityMenuModelAddRowEvent::eventType) { - UnityMenuModelAddRowEvent *ummrce = static_cast<UnityMenuModelAddRowEvent*>(e); - - GSequenceIter *it; - it = g_sequence_get_iter_at_pos (priv->items, ummrce->position); - - beginInsertRows(QModelIndex(), ummrce->position, ummrce->position + ummrce->items->len - 1); - - for (gint i = ummrce->items->len - 1; i >= 0; --i) { - GtkMenuTrackerItem *item = (GtkMenuTrackerItem*)g_ptr_array_index(ummrce->items, i); - it = g_sequence_insert_before (it, g_object_ref (item)); - g_object_set_qdata (G_OBJECT (item), unity_menu_model_quark (), this); - g_signal_connect (item, "notify", G_CALLBACK (UnityMenuModelPrivate::menuItemChanged), it); - } - - endInsertRows(); - return true; - } else if (e->type() == UnityMenuModelRemoveRowEvent::eventType) { - UnityMenuModelRemoveRowEvent *ummrre = static_cast<UnityMenuModelRemoveRowEvent*>(e); - - beginRemoveRows(QModelIndex(), ummrre->position, ummrre->position + ummrre->nItems - 1); - for (int i = 0; i < ummrre->nItems; ++i) { - GSequenceIter *it = g_sequence_get_iter_at_pos (priv->items, ummrre->position); - if (!g_sequence_iter_is_end (it)) { - g_sequence_remove (it); - } - } - endRemoveRows(); - - return true; - } else if (e->type() == UnityMenuModelDataChangeEvent::eventType) { - UnityMenuModelDataChangeEvent *ummdce = static_cast<UnityMenuModelDataChangeEvent*>(e); - - Q_EMIT dataChanged(index(ummdce->position, 0), index(ummdce->position, 0)); - return true; - } - return QAbstractListModel::event(e); -} - -void UnityMenuModel::registerAction(UnityMenuAction* action) -{ - if (priv->destructorGuard) - return; - - if (!priv->registeredActions.contains(action)) { - GtkSimpleActionObserver* observer_item; - observer_item = gtk_simple_action_observer_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&))); - 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&))); - } -} - -void UnityMenuModel::unregisterAction(UnityMenuAction* action) -{ - if (priv->destructorGuard) - return; - - if (priv->registeredActions.contains(action)) { - GtkSimpleActionObserver* observer_item; - observer_item = priv->registeredActions[action]; - g_object_unref(observer_item); - priv->registeredActions.remove(action); - - disconnect(action); - } -} - -/* 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) -{ - GSequenceIter *iter; - QByteArray bytes; - const gchar *name; - gchar *full_name = NULL; - - 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)) { - GtkMenuTrackerItem *item; - const gchar *action_namespace; - - item = (GtkMenuTrackerItem *) g_sequence_get (iter); - if (!item) { - return g_strdup (name); - } - - 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); -} - -void UnityMenuModelPrivate::updateRegisteredAction(UnityMenuAction *action) -{ - GtkSimpleActionObserver *observer_item; - gchar *action_name; - gboolean enabled; - GVariant *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); - - if (state) { - g_variant_unref (state); - } - } - - g_free(action_name); -} - -void UnityMenuModel::onRegisteredActionNameChanged(const QString& name) -{ - priv->updateRegisteredAction(qobject_cast<UnityMenuAction*>(sender())); -} - -void UnityMenuModel::onRegisteredActionIndexChanged(int index) -{ - priv->updateRegisteredAction(qobject_cast<UnityMenuAction*>(sender())); -} - -void UnityMenuModel::onRegisteredActionActivated(const QVariant& parameter) -{ - UnityMenuAction* action = qobject_cast<UnityMenuAction*>(sender()); - if (!action || action->name().isEmpty()) - return; - - 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) -{ - UnityMenuAction* action = qobject_cast<UnityMenuAction*>(sender()); - if (!action || action->name().isEmpty()) - return; - - 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, - const gchar *action_name, - gboolean enabled, - GVariant *state) -{ - UnityMenuAction *action; - action = (UnityMenuAction *) g_object_get_qdata (G_OBJECT (observer_item), unity_menu_action_quark ()); - - if (action) { - UnityMenuActionAddEvent umaae(enabled, Converter::toQVariant(state)); - QCoreApplication::sendEvent(action, &umaae); - } -} - -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 ()); - - if (action) { - UnityMenuActionEnabledChangedEvent umaece(enabled); - QCoreApplication::sendEvent(action, &umaece); - } -} - -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 ()); - - if (action) { - UnityMenuActionStateChangeEvent umasce(Converter::toQVariant(state)); - QCoreApplication::sendEvent(action, &umasce); - } -} - -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 ()); - - if (action) { - UnityMenuActionRemoveEvent umare; - QCoreApplication::sendEvent(action, &umare); - } -} |