Merge lp:~nick-dedekind/qmenumodel/QTBUG-32859 into lp:~phablet-team/qmenumodel/trunk

Proposed by Nick Dedekind
Status: Merged
Approved by: Lars Karlitski
Approved revision: 72
Merged at revision: 77
Proposed branch: lp:~nick-dedekind/qmenumodel/QTBUG-32859
Merge into: lp:~phablet-team/qmenumodel/trunk
Diff against target: 621 lines (+335/-54)
12 files modified
libqmenumodel/src/CMakeLists.txt (+1/-0)
libqmenumodel/src/menunode.cpp (+5/-10)
libqmenumodel/src/qdbusactiongroup.cpp (+37/-5)
libqmenumodel/src/qdbusactiongroup.h (+3/-1)
libqmenumodel/src/qdbusmenumodel.cpp (+22/-5)
libqmenumodel/src/qdbusmenumodel.h (+2/-0)
libqmenumodel/src/qdbusobject.cpp (+31/-8)
libqmenumodel/src/qdbusobject.h (+5/-1)
libqmenumodel/src/qmenumodel.cpp (+32/-21)
libqmenumodel/src/qmenumodel.h (+2/-3)
libqmenumodel/src/qmenumodelevents.cpp (+96/-0)
libqmenumodel/src/qmenumodelevents.h (+99/-0)
To merge this branch: bzr merge lp:~nick-dedekind/qmenumodel/QTBUG-32859
Reviewer Review Type Date Requested Status
Lars Karlitski (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+179344@code.launchpad.net

Commit message

Adds qt event spawning to direct glib main loop callbacks.

Description of the change

Adds qt event spawning to direct glib main loop callbacks.
Fixes bug https://bugreports.qt-project.org/browse/QTBUG-32859

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
72. By Nick Dedekind

moved events to separate file.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Lars Karlitski (larsu) wrote :

Looks good to me, thanks.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libqmenumodel/src/CMakeLists.txt'
2--- libqmenumodel/src/CMakeLists.txt 2013-01-03 21:38:23 +0000
3+++ libqmenumodel/src/CMakeLists.txt 2013-08-09 08:02:09 +0000
4@@ -8,6 +8,7 @@
5 qdbusobject.cpp
6 qdbusmenumodel.cpp
7 qdbusactiongroup.cpp
8+ qmenumodelevents.cpp
9 qstateaction.cpp
10 )
11
12
13=== modified file 'libqmenumodel/src/menunode.cpp'
14--- libqmenumodel/src/menunode.cpp 2013-01-15 00:22:16 +0000
15+++ libqmenumodel/src/menunode.cpp 2013-08-09 08:02:09 +0000
16@@ -18,9 +18,11 @@
17 */
18
19 #include "menunode.h"
20+#include "qmenumodelevents.h"
21
22 #include <QMetaMethod>
23 #include <QDebug>
24+#include <QCoreApplication>
25
26 MenuNode::MenuNode(const QString &linkType, GMenuModel *model, MenuNode *parent, int pos, QObject *listener)
27 : m_model(model),
28@@ -242,15 +244,8 @@
29 self->m_currentOpAdded = added;
30 self->m_currentOpRemoved = removed;
31
32- const QMetaObject *mobj = self->m_listener->metaObject();
33- if (!mobj->invokeMethod(self->m_listener,
34- "onItemsChanged",
35- Q_ARG(MenuNode*, self),
36- Q_ARG(int, position),
37- Q_ARG(int, removed),
38- Q_ARG(int, added)))
39- {
40- qWarning() << "Slot 'onItemsChanged(MenuNode*, int, int, int)' not found in" << self->m_listener;
41- }
42+ MenuNodeItemChangeEvent mnice(self, position, added, removed);
43+ QCoreApplication::sendEvent(self->m_listener, &mnice);
44+
45 self->commitOperation();
46 }
47
48=== modified file 'libqmenumodel/src/qdbusactiongroup.cpp'
49--- libqmenumodel/src/qdbusactiongroup.cpp 2012-11-22 19:13:02 +0000
50+++ libqmenumodel/src/qdbusactiongroup.cpp 2013-08-09 08:02:09 +0000
51@@ -20,6 +20,10 @@
52 #include "qdbusactiongroup.h"
53 #include "qstateaction.h"
54 #include "converter.h"
55+#include "qmenumodelevents.h"
56+
57+// Qt
58+#include <QCoreApplication>
59
60 extern "C" {
61 #include <glib.h>
62@@ -53,7 +57,8 @@
63 /*! \internal */
64 QDBusActionGroup::QDBusActionGroup(QObject *parent)
65 :QObject(parent),
66- m_actionGroup(NULL)
67+ QDBusObject(this),
68+ m_actionGroup(NULL)
69 {
70 }
71
72@@ -184,7 +189,8 @@
73
74 gchar **actions = g_action_group_list_actions(m_actionGroup);
75 for(guint i=0; i < g_strv_length(actions); i++) {
76- Q_EMIT actionAppear(actions[i]);
77+ DBusActionVisiblityEvent dave(actions[i], true);
78+ QCoreApplication::sendEvent(this, &dave);
79 }
80 g_strfreev(actions);
81 }
82@@ -218,23 +224,49 @@
83 }
84 }
85
86+bool QDBusActionGroup::event(QEvent* e)
87+{
88+ if (QDBusObject::event(e)) {
89+ return true;
90+ } else if (e->type() == DBusActionVisiblityEvent::eventType) {
91+ DBusActionVisiblityEvent *dave = static_cast<DBusActionVisiblityEvent*>(e);
92+
93+ if (dave->visible) {
94+ Q_EMIT actionAppear(dave->name);
95+ } else {
96+ Q_EMIT actionVanish(dave->name);
97+ }
98+ } else if (e->type() == DBusActionStateEvent::eventType) {
99+ DBusActionStateEvent *dase = static_cast<DBusActionStateEvent*>(e);
100+
101+ Q_EMIT actionStateChanged(dase->name, dase->state);
102+ }
103+ return QObject::event(e);
104+}
105+
106 /*! \internal */
107 void QDBusActionGroup::onActionAdded(GDBusActionGroup *, gchar *name, gpointer data)
108 {
109 QDBusActionGroup *self = reinterpret_cast<QDBusActionGroup*>(data);
110- Q_EMIT self->actionAppear(name);
111+
112+ DBusActionVisiblityEvent dave(name, true);
113+ QCoreApplication::sendEvent(self, &dave);
114 }
115
116 /*! \internal */
117 void QDBusActionGroup::onActionRemoved(GDBusActionGroup *, gchar *name, gpointer data)
118 {
119 QDBusActionGroup *self = reinterpret_cast<QDBusActionGroup*>(data);
120- Q_EMIT self->actionVanish(name);
121+
122+ DBusActionVisiblityEvent dave(name, false);
123+ QCoreApplication::sendEvent(self, &dave);
124 }
125
126 /*! \internal */
127 void QDBusActionGroup::onActionStateChanged(GDBusActionGroup *, gchar *name, GVariant *value, gpointer data)
128 {
129 QDBusActionGroup *self = reinterpret_cast<QDBusActionGroup*>(data);
130- Q_EMIT self->actionStateChanged(name, Converter::toQVariant(value));
131+
132+ DBusActionStateEvent dase(name, Converter::toQVariant(value));
133+ QCoreApplication::sendEvent(self, &dase);
134 }
135
136=== modified file 'libqmenumodel/src/qdbusactiongroup.h'
137--- libqmenumodel/src/qdbusactiongroup.h 2012-10-30 11:51:31 +0000
138+++ libqmenumodel/src/qdbusactiongroup.h 2013-08-09 08:02:09 +0000
139@@ -69,6 +69,8 @@
140 virtual void serviceAppear(GDBusConnection *connection);
141 virtual void serviceVanish(GDBusConnection *connection);
142
143+ virtual bool event(QEvent* e);
144+
145 private:
146 GActionGroup *m_actionGroup;
147 int m_signalActionAddId;
148@@ -89,4 +91,4 @@
149 static void onActionStateChanged(GDBusActionGroup *ag, gchar *name, GVariant *value, gpointer data);
150 };
151
152-#endif
153+#endif // QDBUSACTIONGROUP_H
154
155=== modified file 'libqmenumodel/src/qdbusmenumodel.cpp'
156--- libqmenumodel/src/qdbusmenumodel.cpp 2013-01-03 21:38:23 +0000
157+++ libqmenumodel/src/qdbusmenumodel.cpp 2013-08-09 08:02:09 +0000
158@@ -22,6 +22,9 @@
159 }
160
161 #include "qdbusmenumodel.h"
162+#include "qmenumodelevents.h"
163+
164+#include <QCoreApplication>
165
166 /*!
167 \qmltype QDBusMenuModel
168@@ -49,7 +52,8 @@
169 \endcode
170 */
171 QDBusMenuModel::QDBusMenuModel(QObject *parent)
172- : QMenuModel(0, parent)
173+ : QMenuModel(0, parent),
174+ QDBusObject(this)
175 {
176 }
177
178@@ -83,13 +87,24 @@
179 void QDBusMenuModel::stop()
180 {
181 QDBusObject::disconnect();
182- setMenuModel(NULL);
183+
184+ MenuModelEvent mme(NULL);
185+ QCoreApplication::sendEvent(this, &mme);
186+}
187+
188+bool QDBusMenuModel::event(QEvent* e)
189+{
190+ if (QDBusObject::event(e)) {
191+ return true;
192+ }
193+ return QMenuModel::event(e);
194 }
195
196 /*! \internal */
197 void QDBusMenuModel::serviceVanish(GDBusConnection *)
198 {
199- setMenuModel(NULL);
200+ MenuModelEvent mme(NULL);
201+ QCoreApplication::sendEvent(this, &mme);
202 }
203
204 /*! \internal */
205@@ -98,8 +113,10 @@
206 GMenuModel *model = G_MENU_MODEL(g_dbus_menu_model_get(connection,
207 busName().toUtf8().data(),
208 objectPath().toUtf8().data()));
209- setMenuModel(model);
210- //setModel take care of the ref
211+
212+ MenuModelEvent mme(model);
213+ QCoreApplication::sendEvent(this, &mme);
214+ //event handling takes care of the ref
215 g_object_unref(model);
216 }
217
218
219=== modified file 'libqmenumodel/src/qdbusmenumodel.h'
220--- libqmenumodel/src/qdbusmenumodel.h 2012-10-11 08:54:49 +0000
221+++ libqmenumodel/src/qdbusmenumodel.h 2013-08-09 08:02:09 +0000
222@@ -49,6 +49,8 @@
223 virtual void serviceAppear(GDBusConnection *connection);
224 virtual void serviceVanish(GDBusConnection *connection);
225
226+ virtual bool event(QEvent* e);
227+
228 private:
229 // workaround to support int as busType
230 void setIntBusType(int busType);
231
232=== modified file 'libqmenumodel/src/qdbusobject.cpp'
233--- libqmenumodel/src/qdbusobject.cpp 2012-10-30 12:06:35 +0000
234+++ libqmenumodel/src/qdbusobject.cpp 2013-08-09 08:02:09 +0000
235@@ -23,8 +23,10 @@
236 }
237
238 #include "qdbusobject.h"
239+#include "qmenumodelevents.h"
240
241 #include <QDebug>
242+#include <QCoreApplication>
243
244 /*!
245 \qmltype QDBusObject
246@@ -73,8 +75,9 @@
247 \endlist
248 */
249
250-QDBusObject::QDBusObject()
251- :m_watchId(0),
252+QDBusObject::QDBusObject(QObject* listener)
253+ :m_listener(listener),
254+ m_watchId(0),
255 m_busType(DBusEnums::None),
256 m_status(DBusEnums::Disconnected)
257 {
258@@ -181,14 +184,34 @@
259 {
260 QDBusObject *self = reinterpret_cast<QDBusObject*>(data);
261
262- self->serviceAppear(connection);
263- self->setStatus(DBusEnums::Connected);
264+ if (self->m_listener) {
265+ DbusObjectServiceEvent dose(connection, true);
266+ QCoreApplication::sendEvent(self->m_listener, &dose);
267+ }
268 }
269
270 void QDBusObject::onServiceVanished(GDBusConnection *connection, const gchar *, gpointer data)
271 {
272- QDBusObject *self = reinterpret_cast<QDBusObject*>(data);
273-
274- self->setStatus(DBusEnums::Connecting);
275- self->serviceVanish(connection);
276+ QDBusObject *self = reinterpret_cast<QDBusObject*>(data);
277+
278+ if (self->m_listener) {
279+ DbusObjectServiceEvent dose(connection, false);
280+ QCoreApplication::sendEvent(self->m_listener, &dose);
281+ }
282+}
283+
284+bool QDBusObject::event(QEvent* e)
285+{
286+ if (e->type() == DbusObjectServiceEvent::eventType) {
287+ DbusObjectServiceEvent *dose = static_cast<DbusObjectServiceEvent*>(e);
288+ if (dose->visible) {
289+ serviceAppear(dose->connection);
290+ setStatus(DBusEnums::Connected);
291+ } else {
292+ setStatus(DBusEnums::Connecting);
293+ serviceVanish(dose->connection);
294+ }
295+ return true;
296+ }
297+ return false;
298 }
299
300=== modified file 'libqmenumodel/src/qdbusobject.h'
301--- libqmenumodel/src/qdbusobject.h 2012-10-10 07:41:24 +0000
302+++ libqmenumodel/src/qdbusobject.h 2013-08-09 08:02:09 +0000
303@@ -32,7 +32,7 @@
304 class QDBusObject
305 {
306 public:
307- QDBusObject();
308+ QDBusObject(QObject* listener);
309 ~QDBusObject();
310
311 DBusEnums::BusType busType() const;
312@@ -59,7 +59,11 @@
313 virtual void objectPathChanged(const QString &objectPath) = 0;
314 virtual void statusChanged(DBusEnums::ConnectionStatus status) = 0;
315
316+ // This is not a Qbject, but we are passed events from superclass qobjects.
317+ virtual bool event(QEvent* e);
318+
319 private:
320+ QObject* m_listener;
321 guint m_watchId;
322 DBusEnums::BusType m_busType;
323 QString m_busName;
324
325=== modified file 'libqmenumodel/src/qmenumodel.cpp'
326--- libqmenumodel/src/qmenumodel.cpp 2013-05-23 08:44:41 +0000
327+++ libqmenumodel/src/qmenumodel.cpp 2013-08-09 08:02:09 +0000
328@@ -25,6 +25,8 @@
329 #include "qmenumodel.h"
330 #include "menunode.h"
331 #include "converter.h"
332+#include "qmenumodelevents.h"
333+
334 #include <QCoreApplication>
335 #include <QThread>
336
337@@ -225,28 +227,37 @@
338 return extra;
339 }
340
341-/*! \internal */
342-void QMenuModel::onItemsChanged(MenuNode *node,
343- int position,
344- int removed,
345- int added)
346+bool QMenuModel::event(QEvent* e)
347 {
348- QModelIndex index = indexFromNode(node);
349- if (removed > 0) {
350- beginRemoveRows(index, position, position + removed - 1);
351-
352- node->commitOperation();
353-
354- endRemoveRows();
355- }
356-
357- if (added > 0) {
358- beginInsertRows(index, position, position + added - 1);
359-
360- node->commitOperation();
361-
362- endInsertRows();
363- }
364+ if (e->type() == MenuNodeItemChangeEvent::eventType) {
365+ MenuNodeItemChangeEvent *mnice = static_cast<MenuNodeItemChangeEvent*>(e);
366+
367+ QModelIndex index = indexFromNode(mnice->node);
368+ if (mnice->removed > 0) {
369+ beginRemoveRows(index, mnice->position, mnice->position + mnice->removed - 1);
370+
371+ mnice->node->commitOperation();
372+
373+ endRemoveRows();
374+ }
375+
376+ if (mnice->added > 0) {
377+ beginInsertRows(index, mnice->position, mnice->position + mnice->added - 1);
378+
379+ mnice->node->commitOperation();
380+
381+ endInsertRows();
382+ }
383+ return true;
384+
385+ } else if (e->type() == MenuModelEvent::eventType) {
386+
387+ MenuModelEvent *mme = static_cast<MenuModelEvent*>(e);
388+
389+ setMenuModel(mme->model);
390+ return true;
391+ }
392+ return QAbstractItemModel::event(e);
393 }
394
395 /*! \internal */
396
397=== modified file 'libqmenumodel/src/qmenumodel.h'
398--- libqmenumodel/src/qmenumodel.h 2013-01-03 21:38:23 +0000
399+++ libqmenumodel/src/qmenumodel.h 2013-08-09 08:02:09 +0000
400@@ -52,14 +52,13 @@
401 Q_SIGNALS:
402 void countChanged();
403
404-public Q_SLOTS:
405- void onItemsChanged(MenuNode *node, int position, int removed, int added);
406-
407 protected:
408 QMenuModel(GMenuModel *other=0, QObject *parent=0);
409 void setMenuModel(GMenuModel *model);
410 GMenuModel *menuModel() const;
411
412+ virtual bool event(QEvent* e);
413+
414 private:
415 MenuNode *m_root;
416
417
418=== added file 'libqmenumodel/src/qmenumodelevents.cpp'
419--- libqmenumodel/src/qmenumodelevents.cpp 1970-01-01 00:00:00 +0000
420+++ libqmenumodel/src/qmenumodelevents.cpp 2013-08-09 08:02:09 +0000
421@@ -0,0 +1,96 @@
422+/*
423+ * Copyright 2013 Canonical Ltd.
424+ *
425+ * This program is free software; you can redistribute it and/or modify
426+ * it under the terms of the GNU Lesser General Public License as published by
427+ * the Free Software Foundation; version 3.
428+ *
429+ * This program is distributed in the hope that it will be useful,
430+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
431+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
432+ * GNU Lesser General Public License for more details.
433+ *
434+ * You should have received a copy of the GNU Lesser General Public License
435+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
436+ *
437+ * Authors:
438+ * Nicholas Dedekind <nick.dedekind@canonical.com
439+ */
440+
441+extern "C" {
442+#include <glib-object.h>
443+#include <gio/gio.h>
444+}
445+
446+#include "qmenumodelevents.h"
447+
448+const QEvent::Type MenuNodeItemChangeEvent::eventType = static_cast<QEvent::Type>(QEvent::registerEventType());
449+const QEvent::Type DBusActionStateEvent::eventType = static_cast<QEvent::Type>(QEvent::registerEventType());
450+const QEvent::Type DBusActionVisiblityEvent::eventType = static_cast<QEvent::Type>(QEvent::registerEventType());
451+const QEvent::Type MenuModelEvent::eventType = static_cast<QEvent::Type>(QEvent::registerEventType());
452+const QEvent::Type DbusObjectServiceEvent::eventType = static_cast<QEvent::Type>(QEvent::registerEventType());
453+
454+MenuNodeItemChangeEvent::MenuNodeItemChangeEvent(MenuNode* _node, int _position, int _removed, int _added)
455+ : QEvent(MenuNodeItemChangeEvent::eventType),
456+ node(_node),
457+ position(_position),
458+ removed(_removed),
459+ added(_added)
460+{}
461+
462+
463+DBusActionEvent::DBusActionEvent(const QString& _name, QEvent::Type type)
464+ : QEvent(type),
465+ name(_name)
466+{
467+}
468+
469+
470+DBusActionVisiblityEvent::DBusActionVisiblityEvent(const QString& _name, bool _visible)
471+ : DBusActionEvent(_name, DBusActionVisiblityEvent::eventType),
472+ visible(_visible)
473+{
474+}
475+
476+
477+DBusActionStateEvent::DBusActionStateEvent(const QString& _name, const QVariant& _state)
478+ : DBusActionEvent(_name, DBusActionStateEvent::eventType),
479+ state(_state)
480+{
481+}
482+
483+
484+DbusObjectServiceEvent::DbusObjectServiceEvent(GDBusConnection* _connection, bool _visible)
485+ : QEvent(DbusObjectServiceEvent::eventType),
486+ connection(_connection),
487+ visible(_visible)
488+{
489+ if (connection) {
490+ g_object_ref(connection);
491+ }
492+}
493+
494+
495+DbusObjectServiceEvent::~DbusObjectServiceEvent()
496+{
497+ if (connection) {
498+ g_object_unref(connection);
499+ }
500+}
501+
502+
503+MenuModelEvent::MenuModelEvent(GMenuModel* _model)
504+ : QEvent(MenuModelEvent::eventType),
505+ model(_model)
506+{
507+ if (model) {
508+ g_object_ref(model);
509+ }
510+}
511+
512+MenuModelEvent::~MenuModelEvent()
513+{
514+ if (model) {
515+ g_object_unref(model);
516+ }
517+}
518
519=== added file 'libqmenumodel/src/qmenumodelevents.h'
520--- libqmenumodel/src/qmenumodelevents.h 1970-01-01 00:00:00 +0000
521+++ libqmenumodel/src/qmenumodelevents.h 2013-08-09 08:02:09 +0000
522@@ -0,0 +1,99 @@
523+/*
524+ * Copyright 2013 Canonical Ltd.
525+ *
526+ * This program is free software; you can redistribute it and/or modify
527+ * it under the terms of the GNU Lesser General Public License as published by
528+ * the Free Software Foundation; version 3.
529+ *
530+ * This program is distributed in the hope that it will be useful,
531+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
532+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
533+ * GNU Lesser General Public License for more details.
534+ *
535+ * You should have received a copy of the GNU Lesser General Public License
536+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
537+ *
538+ * Authors:
539+ * Nicholas Dedekind <nick.dedekind@canonical.com
540+ */
541+
542+#ifndef QMENUMODELEVENTS_H
543+#define QMENUMODELEVENTS_H
544+
545+#include <QEvent>
546+#include <QVariant>
547+
548+class MenuNode;
549+typedef struct _GDBusConnection GDBusConnection;
550+typedef struct _GMenuModel GMenuModel;
551+
552+/* Event for a connection update for a dbus object */
553+class DbusObjectServiceEvent : public QEvent
554+{
555+public:
556+ static const QEvent::Type eventType;
557+ DbusObjectServiceEvent(GDBusConnection* connection, bool visible);
558+ ~DbusObjectServiceEvent();
559+
560+ GDBusConnection* connection;
561+ bool visible;
562+};
563+
564+/* Event for an update to the gmenumodel */
565+class MenuModelEvent : public QEvent
566+{
567+public:
568+ static const QEvent::Type eventType;
569+
570+ MenuModelEvent(GMenuModel *model);
571+ ~MenuModelEvent();
572+
573+ GMenuModel *model;
574+};
575+
576+/* Event for a GAction (base) */
577+class DBusActionEvent : public QEvent
578+{
579+public:
580+ QString name;
581+
582+protected:
583+ DBusActionEvent(const QString& name, QEvent::Type type);
584+};
585+
586+/* Event for a GAction add/remove */
587+class DBusActionVisiblityEvent : public DBusActionEvent
588+{
589+public:
590+ static const QEvent::Type eventType;
591+ DBusActionVisiblityEvent(const QString& name, bool visible);
592+
593+ bool visible;
594+};
595+
596+/* Event for a GAction state value update */
597+class DBusActionStateEvent : public DBusActionEvent
598+{
599+public:
600+ static const QEvent::Type eventType;
601+
602+ DBusActionStateEvent(const QString& name, const QVariant& state);
603+
604+ QVariant state;
605+};
606+
607+/* Event for changing gmenumodel entries */
608+class MenuNodeItemChangeEvent : public QEvent
609+{
610+public:
611+ static const QEvent::Type eventType;
612+
613+ MenuNodeItemChangeEvent(MenuNode* node, int position, int removed, int added);
614+
615+ MenuNode* node;
616+ int position;
617+ int removed;
618+ int added;
619+};
620+
621+#endif //QMENUMODELEVENTS_H

Subscribers

People subscribed via source and target branches