diff options
Diffstat (limited to 'libqmenumodel/src')
-rw-r--r-- | libqmenumodel/src/unitymenumodel.cpp | 175 | ||||
-rw-r--r-- | libqmenumodel/src/unitymenumodel.h | 24 | ||||
-rw-r--r-- | libqmenumodel/src/unityqmlmenumodel.cpp | 66 | ||||
-rw-r--r-- | libqmenumodel/src/unityqmlmenumodel.h | 17 |
4 files changed, 133 insertions, 149 deletions
diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp index 45cb9c4..ba1fac4 100644 --- a/libqmenumodel/src/unitymenumodel.cpp +++ b/libqmenumodel/src/unitymenumodel.cpp @@ -29,8 +29,8 @@ G_DEFINE_QUARK (UNITY_SUBMENU_MODEL, unity_submenu_model) class UnityMenuModelPrivate { public: - static UnityMenuModelPrivate * forBusMenu(UnityMenuModel *model, const QByteArray &busName, - const QByteArray &actionGroupObjectPath, const QByteArray &menuObjectPath); + UnityMenuModelPrivate(UnityMenuModel *model); + static UnityMenuModelPrivate * forSubMenu(UnityMenuModel *model, GtkMenuTrackerItem *item); ~UnityMenuModelPrivate(); @@ -39,14 +39,20 @@ public: void activate(int position); UnityMenuModel * submenu(int position); -private: - UnityMenuModelPrivate(UnityMenuModel *model); + void clearItems(bool resetModel=true); + void clearName(); + void updateActions(); + void updateMenuModel(); UnityMenuModel *model; GtkActionMuxer *muxer; GtkMenuTracker *menutracker; GSequence *items; - QByteArray actionGroupObjectPath; + GDBusConnection *connection; + QByteArray busName; + QByteArray nameOwner; + guint nameWatchId; + QByteArray actionObjectPath; QByteArray menuObjectPath; static void freeMenuItem(gpointer data, gpointer user_data); @@ -77,6 +83,7 @@ UnityMenuModelPrivate::UnityMenuModelPrivate(UnityMenuModel *model) { this->model = model; this->menutracker = NULL; + this->nameWatchId = 0; this->muxer = gtk_action_muxer_new (); g_object_set_qdata (G_OBJECT (this->muxer), unity_menu_model_quark (), model); @@ -84,20 +91,6 @@ UnityMenuModelPrivate::UnityMenuModelPrivate(UnityMenuModel *model) this->items = g_sequence_new (NULL); } -UnityMenuModelPrivate * UnityMenuModelPrivate::forBusMenu(UnityMenuModel *model, const QByteArray &busName, - const QByteArray &actionGroupObjectPath, const QByteArray &menuObjectPath) -{ - UnityMenuModelPrivate *priv = new UnityMenuModelPrivate(model); - - priv->actionGroupObjectPath = actionGroupObjectPath; - priv->menuObjectPath = menuObjectPath; - - g_bus_watch_name (G_BUS_TYPE_SESSION, busName.constData(), G_BUS_NAME_WATCHER_FLAGS_AUTO_START, - nameAppeared, nameVanished, priv, NULL); - - return priv; -} - UnityMenuModelPrivate * UnityMenuModelPrivate::forSubMenu(UnityMenuModel *model, GtkMenuTrackerItem *item) { UnityMenuModelPrivate *priv = new UnityMenuModelPrivate(model); @@ -109,17 +102,18 @@ UnityMenuModelPrivate * UnityMenuModelPrivate::forSubMenu(UnityMenuModel *model, UnityMenuModelPrivate::~UnityMenuModelPrivate() { - if (this->items) { - g_sequence_foreach_iter_range (g_sequence_get_begin_iter (this->items), g_sequence_get_end_iter (this->items), - freeMenuItem, NULL); - g_sequence_free (this->items); - } + this->clearItems(false); if (this->menutracker) gtk_menu_tracker_free (this->menutracker); if (this->muxer) g_object_unref (this->muxer); + + g_clear_object (&this->connection); + + if (this->nameWatchId) + g_bus_unwatch_name (this->nameWatchId); } int UnityMenuModelPrivate::nrItems() @@ -190,45 +184,81 @@ void UnityMenuModelPrivate::freeMenuItem (gpointer data, gpointer user_data) g_object_unref (item); } -void UnityMenuModelPrivate::nameAppeared(GDBusConnection *connection, const gchar *name, const gchar *owner, gpointer user_data) +void UnityMenuModelPrivate::clearItems(bool resetModel) { - UnityMenuModelPrivate *priv = (UnityMenuModelPrivate *)user_data; - GDBusActionGroup *actions; - GDBusMenuModel *menu; + GSequenceIter *begin; + GSequenceIter *end; + + if (resetModel) + model->beginResetModel(); - priv->model->beginResetModel(); + begin = g_sequence_get_begin_iter (this->items); + end = g_sequence_get_end_iter (this->items); + g_sequence_foreach_iter_range (begin, end, freeMenuItem, NULL); + g_sequence_remove_range (begin, end); - actions = g_dbus_action_group_get (connection, owner, priv->actionGroupObjectPath.constData()); - menu = g_dbus_menu_model_get (connection, owner, priv->menuObjectPath.constData()); + if (resetModel) + model->endResetModel(); +} - gtk_action_muxer_insert (priv->muxer, "indicator", G_ACTION_GROUP (actions)); - priv->menutracker = gtk_menu_tracker_new (GTK_ACTION_OBSERVABLE (priv->muxer), - G_MENU_MODEL (menu), TRUE, "indicator", - menuItemInserted, menuItemRemoved, priv); +void UnityMenuModelPrivate::clearName() +{ + this->clearItems(); - priv->model->endResetModel(); + this->nameOwner = QByteArray(); - g_object_unref (menu); - g_object_unref (actions); + this->updateActions(); + this->updateMenuModel(); } -void UnityMenuModelPrivate::nameVanished(GDBusConnection *connection, const gchar *name, gpointer user_data) +void UnityMenuModelPrivate::updateActions() +{ + if (!this->nameOwner.isEmpty()) { + GDBusActionGroup *actions; + + actions = g_dbus_action_group_get (this->connection, this->nameOwner, this->actionObjectPath.constData()); + gtk_action_muxer_insert (this->muxer, "indicator", G_ACTION_GROUP (actions)); + + g_object_unref (actions); + } + else { + gtk_action_muxer_remove (this->muxer, "indicator"); + } +} + +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, "indicator", + menuItemInserted, menuItemRemoved, this); + + g_object_unref (menu); + } +} + +void UnityMenuModelPrivate::nameAppeared(GDBusConnection *connection, const gchar *name, const gchar *owner, gpointer user_data) { UnityMenuModelPrivate *priv = (UnityMenuModelPrivate *)user_data; - GSequenceIter *begin; - GSequenceIter *end; - priv->model->beginResetModel(); + priv->connection = (GDBusConnection *) g_object_ref (connection); + priv->nameOwner = owner; - begin = g_sequence_get_begin_iter (priv->items); - end = g_sequence_get_end_iter (priv->items); - g_sequence_foreach_iter_range (begin, end, freeMenuItem, NULL); - g_sequence_remove_range (begin, end); + priv->updateActions(); + priv->updateMenuModel(); +} - gtk_action_muxer_remove (priv->muxer, "indicator"); - g_clear_pointer (&priv->menutracker, gtk_menu_tracker_free); +void UnityMenuModelPrivate::nameVanished(GDBusConnection *connection, const gchar *name, gpointer user_data) +{ + UnityMenuModelPrivate *priv = (UnityMenuModelPrivate *)user_data; - priv->model->endResetModel(); + priv->clearName(); } void UnityMenuModelPrivate::menuItemInserted(GtkMenuTrackerItem *item, gint position, gpointer user_data) @@ -278,26 +308,51 @@ void UnityMenuModelPrivate::menuItemChanged(GObject *object, GParamSpec *pspec, UnityMenuModel::UnityMenuModel(QObject *parent): QAbstractListModel(parent) { + priv = new UnityMenuModelPrivate(this); +} + +UnityMenuModel::~UnityMenuModel() +{ + delete priv; } -UnityMenuModel::UnityMenuModel(const QByteArray &busName, - const QByteArray &actionGroupObjectPath, - const QByteArray &menuObjectPath, - QObject *parent): - QAbstractListModel(parent), - priv(NULL) +QByteArray UnityMenuModel::busName() const { - init(busName, actionGroupObjectPath, menuObjectPath); + return priv->busName; } -void UnityMenuModel::init(const QByteArray &busName, const QByteArray &actionGroupObjectPath, const QByteArray &menuObjectPath) +void UnityMenuModel::setBusName(const QByteArray &name) { - priv = UnityMenuModelPrivate::forBusMenu(this, busName, actionGroupObjectPath, menuObjectPath); + 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); } -UnityMenuModel::~UnityMenuModel() +QByteArray UnityMenuModel::actionObjectPath() const { - delete priv; + return priv->actionObjectPath; +} + +void UnityMenuModel::setActionObjectPath(const QByteArray &path) +{ + priv->actionObjectPath = path; + priv->updateActions(); +} + +QByteArray UnityMenuModel::menuObjectPath() const +{ + return priv->menuObjectPath; +} + +void UnityMenuModel::setMenuObjectPath(const QByteArray &path) +{ + priv->menuObjectPath = path; + priv->updateMenuModel(); } int UnityMenuModel::rowCount(const QModelIndex &parent) const diff --git a/libqmenumodel/src/unitymenumodel.h b/libqmenumodel/src/unitymenumodel.h index 6e735a4..cdfceac 100644 --- a/libqmenumodel/src/unitymenumodel.h +++ b/libqmenumodel/src/unitymenumodel.h @@ -24,6 +24,9 @@ class UnityMenuModel: public QAbstractListModel { Q_OBJECT + Q_PROPERTY(QByteArray busName READ busName WRITE setBusName NOTIFY busNameChanged) + Q_PROPERTY(QByteArray actionObjectPath READ actionObjectPath WRITE setActionObjectPath NOTIFY actionObjectPathChanged) + Q_PROPERTY(QByteArray menuObjectPath READ menuObjectPath WRITE setMenuObjectPath NOTIFY menuObjectPathChanged) public: enum MenuRoles { @@ -34,10 +37,18 @@ public: }; public: - UnityMenuModel(const QByteArray &busName, const QByteArray &actionGroupObjectPath, - const QByteArray &menuObjectPath, QObject *parent = NULL); + UnityMenuModel(QObject *parent = NULL); virtual ~UnityMenuModel(); + QByteArray busName() const; + void setBusName(const QByteArray &name); + + QByteArray actionObjectPath() const; + void setActionObjectPath(const QByteArray &path); + + QByteArray menuObjectPath() const; + void setMenuObjectPath(const QByteArray &path); + int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; @@ -47,13 +58,14 @@ public: Q_INVOKABLE QObject * submenu(int position); +Q_SIGNALS: + void busNameChanged(const QByteArray &name); + void actionObjectPathChanged(const QByteArray &path); + void menuObjectPathChanged(const QByteArray &path); + public Q_SLOTS: void activate(int index); -protected: - UnityMenuModel(QObject *parent = NULL); - void init(const QByteArray &busName, const QByteArray &actionGroupObjectPath, const QByteArray &menuObjectPath); - private: class UnityMenuModelPrivate *priv; friend class UnityMenuModelPrivate; diff --git a/libqmenumodel/src/unityqmlmenumodel.cpp b/libqmenumodel/src/unityqmlmenumodel.cpp index 775d974..36bb2bd 100644 --- a/libqmenumodel/src/unityqmlmenumodel.cpp +++ b/libqmenumodel/src/unityqmlmenumodel.cpp @@ -18,22 +18,13 @@ #include "unityqmlmenumodel.h" -struct UnityQmlMenuModelPrivate -{ - QByteArray busName; - QByteArray actionObjectPath; - QByteArray menuObjectPath; -}; - UnityQmlMenuModel::UnityQmlMenuModel(QObject *parent): UnityMenuModel(parent) { - priv = new UnityQmlMenuModelPrivate; } UnityQmlMenuModel::~UnityQmlMenuModel() { - delete priv; } void UnityQmlMenuModel::classBegin() @@ -42,61 +33,4 @@ void UnityQmlMenuModel::classBegin() void UnityQmlMenuModel::componentComplete() { - if (priv->busName.isEmpty()) - qWarning("UnityQmlMenuModel: property 'busName' must be set"); - else if (priv->actionObjectPath.isEmpty()) - qWarning("UnityQmlMenuModel: property 'actionObjectPath' must be set"); - else if (priv->menuObjectPath.isEmpty()) - qWarning("UnityQmlMenuModel: property 'menuObjectPath' must be set"); - else - UnityQmlMenuModel::init(priv->busName, priv->actionObjectPath, priv->menuObjectPath); -} - -QByteArray UnityQmlMenuModel::busName() const -{ - return priv->busName; -} - -void UnityQmlMenuModel::setBusName(const QByteArray &name) -{ - if (!priv->busName.isEmpty()) { - qWarning("UnityQmlMenuModel: cannot change bus name after creation"); - return; - } - - priv->busName = name; - Q_EMIT busNameChanged(name); -} - -QByteArray UnityQmlMenuModel::actionObjectPath() const -{ - return priv->actionObjectPath; } - -void UnityQmlMenuModel::setActionObjectPath(const QByteArray &path) -{ - if (!priv->actionObjectPath.isEmpty()) { - qWarning("UnityQmlMenuModel: cannot change object paths after creation"); - return; - } - - priv->actionObjectPath = path; - Q_EMIT actionObjectPathChanged(path); -} - -QByteArray UnityQmlMenuModel::menuObjectPath() const -{ - return priv->menuObjectPath; -} - -void UnityQmlMenuModel::setMenuObjectPath(const QByteArray &path) -{ - if (!priv->menuObjectPath.isEmpty()) { - qWarning("UnityQmlMenuModel: cannot change object paths after creation"); - return; - } - - priv->menuObjectPath = path; - Q_EMIT menuObjectPathChanged(path); -} - diff --git a/libqmenumodel/src/unityqmlmenumodel.h b/libqmenumodel/src/unityqmlmenumodel.h index a375e8e..d57d52e 100644 --- a/libqmenumodel/src/unityqmlmenumodel.h +++ b/libqmenumodel/src/unityqmlmenumodel.h @@ -27,9 +27,6 @@ class UnityQmlMenuModel: public UnityMenuModel, public QQmlParserStatus { Q_OBJECT Q_INTERFACES(QQmlParserStatus) - Q_PROPERTY(QByteArray busName READ busName WRITE setBusName NOTIFY busNameChanged) - Q_PROPERTY(QByteArray actionObjectPath READ actionObjectPath WRITE setActionObjectPath NOTIFY actionObjectPathChanged) - Q_PROPERTY(QByteArray menuObjectPath READ menuObjectPath WRITE setMenuObjectPath NOTIFY menuObjectPathChanged) public: UnityQmlMenuModel(QObject *parent = NULL); @@ -38,20 +35,6 @@ public: void classBegin(); void componentComplete(); - QByteArray busName() const; - void setBusName(const QByteArray &name); - - QByteArray actionObjectPath() const; - void setActionObjectPath(const QByteArray &path); - - QByteArray menuObjectPath() const; - void setMenuObjectPath(const QByteArray &path); - -Q_SIGNALS: - void busNameChanged(const QByteArray &name); - void actionObjectPathChanged(const QByteArray &path); - void menuObjectPathChanged(const QByteArray &path); - private: struct UnityQmlMenuModelPrivate *priv; }; |