aboutsummaryrefslogtreecommitdiff
path: root/libqmenumodel/src
diff options
context:
space:
mode:
Diffstat (limited to 'libqmenumodel/src')
-rw-r--r--libqmenumodel/src/unitymenumodel.cpp175
-rw-r--r--libqmenumodel/src/unitymenumodel.h24
-rw-r--r--libqmenumodel/src/unityqmlmenumodel.cpp66
-rw-r--r--libqmenumodel/src/unityqmlmenumodel.h17
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;
};