diff options
author | Renato Araujo Oliveira Filho <renato.filho@canonical.com> | 2012-11-28 20:07:56 -0300 |
---|---|---|
committer | Renato Araujo Oliveira Filho <renato.filho@canonical.com> | 2012-11-28 20:07:56 -0300 |
commit | 98ed17ed5c2ebab3a396906d4219af2e99988370 (patch) | |
tree | 526d7f52989723d623e426862393890c60b6cece | |
parent | 53dfc2a919fd03f5570cb106d71d3989a3f528d9 (diff) | |
parent | da5a0437d57df35409fedb568b7ebf4e3d6af0da (diff) | |
download | qmenumodel-98ed17ed5c2ebab3a396906d4219af2e99988370.tar.gz qmenumodel-98ed17ed5c2ebab3a396906d4219af2e99988370.tar.bz2 qmenumodel-98ed17ed5c2ebab3a396906d4219af2e99988370.zip |
Merged mainline.
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | debian/changelog | 24 | ||||
-rw-r--r-- | libqmenumodel/src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | libqmenumodel/src/converter.cpp | 28 | ||||
-rw-r--r-- | libqmenumodel/src/qdbusactiongroup.cpp | 4 | ||||
-rw-r--r-- | libqmenumodel/src/qdbusmenumodel.cpp | 11 | ||||
-rw-r--r-- | libqmenumodel/src/qmenumodel.cpp | 31 | ||||
-rw-r--r-- | libqmenumodel/src/qmenumodel.h | 2 | ||||
-rw-r--r-- | libqmenumodel/src/qstateaction.cpp | 42 | ||||
-rw-r--r-- | libqmenumodel/src/qstateaction.h | 14 | ||||
-rw-r--r-- | tests/client/CMakeLists.txt | 8 | ||||
-rw-r--r-- | tests/client/actiongrouptest.cpp | 9 | ||||
-rw-r--r-- | tests/client/convertertest.cpp | 28 | ||||
-rw-r--r-- | tests/client/modeltest.cpp | 20 | ||||
-rwxr-xr-x | tests/client/script_actiongrouptest.py | 5 | ||||
-rwxr-xr-x | tests/client/script_modeltest.py | 1 | ||||
-rw-r--r-- | tests/script/dbusmenuscript.cpp | 11 | ||||
-rw-r--r-- | tests/script/dbusmenuscript.h | 2 | ||||
-rw-r--r-- | tests/script/menuscript.py | 15 |
19 files changed, 201 insertions, 57 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f60630..f3799b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ endif() add_subdirectory(libqmenumodel) # Tests Tools +OPTION(TEST_XML_OUTPUT "Print test results on xml files" ON) if(NOT DBUS_RUNNER) message(STATUS "dbus-test-runner not found tests disabled.") else() diff --git a/debian/changelog b/debian/changelog index 60de143..6d87540 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,27 @@ +qmenumodel (0.1.8) quantal; urgency=low + + [ Renato Araujo Oliveira Filho ] + * Fixed memory leak after the service disappear. + * Implemented support to tuple conversions. + * Added 'TEST_XML_OUTPUT' option on cmake to enable/disalbe test output in + xml. + * Removed QAction dependency from QStateAction. + * Fixed QMenumodel behavior when the GMenuModel is destroyed. + + [ Olivier Tilloy ] + * Reimplement roleNames() instead of using setRoleNames(…). + + -- Renato Araujo Oliveira Filho <renato@canonical.com> Fri, 23 Nov 2012 16:15:00 -0300 + +qmenumodel (0.1.7) quantal; urgency=low + + [ Renato Araujo Oliveira Filho ] + * Fixed tests to avoid crashing if dbus session is not available. + * Updated debian package to use debhelper instead of cdbs. + * Updates to get coverage and test results in jenkins. + + -- Olivier Tilloy <olivier.tilloy@canonical.com> Wed, 14 Nov 2012 10:43:15 +0100 + qmenumodel (0.1.6) quantal; urgency=low [ Renato Araujo Oliveira Filho ] diff --git a/libqmenumodel/src/CMakeLists.txt b/libqmenumodel/src/CMakeLists.txt index 8edb3e1..fe7d433 100644 --- a/libqmenumodel/src/CMakeLists.txt +++ b/libqmenumodel/src/CMakeLists.txt @@ -31,7 +31,7 @@ target_link_libraries(${SHAREDLIBNAME} ${GIO_LDFLAGS} ) -qt5_use_modules(${SHAREDLIBNAME} Core Widgets) +qt5_use_modules(${SHAREDLIBNAME} Core) install(TARGETS ${SHAREDLIBNAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/libqmenumodel/src/converter.cpp b/libqmenumodel/src/converter.cpp index 75733ce..6c2411c 100644 --- a/libqmenumodel/src/converter.cpp +++ b/libqmenumodel/src/converter.cpp @@ -51,8 +51,21 @@ QVariant Converter::toQVariant(GVariant *value) } result.setValue(qmap); + } else if (g_variant_type_is_tuple(type)) { + gsize size = g_variant_n_children(value); + QVariantList vlist; + + for (gsize i=0; i < size; i++) { + GVariant *v = g_variant_get_child_value(value, i); + if (v) { + vlist << toQVariant(v); + g_variant_unref(v); + } + } + + result.setValue(vlist); } else { - qWarning() << "Unsupported GVariant value"; + qWarning() << "Unsupported GVariant value" << (char*) type; } /* TODO: implement convertions to others types @@ -64,7 +77,6 @@ QVariant Converter::toQVariant(GVariant *value) * G_VARIANT_TYPE_BASIC * G_VARIANT_TYPE_MAYBE * G_VARIANT_TYPE_ARRAY - * G_VARIANT_TYPE_TUPLE * G_VARIANT_TYPE_UNIT * G_VARIANT_TYPE_DICT_ENTRY * G_VARIANT_TYPE_DICTIONARY @@ -72,7 +84,6 @@ QVariant Converter::toQVariant(GVariant *value) * G_VARIANT_TYPE_BYTESTRING * G_VARIANT_TYPE_OBJECT_PATH_ARRAY * G_VARIANT_TYPE_BYTESTRING_ARRAY - * G_VARIANT_TYPE_VARDICT */ return result; @@ -137,6 +148,17 @@ GVariant* Converter::toGVariant(const QVariant &value) g_variant_builder_unref(b); break; } + case QVariant::List: + { + QVariantList lst = value.toList(); + GVariant **vars = g_new(GVariant*, lst.size()); + for (int i=0; i < lst.size(); i++) { + vars[i] = toGVariant(lst[i]); + } + result = g_variant_new_tuple(vars, lst.size()); + g_free(vars); + break; + } default: result = ::toGVariant(value.typeName(), value); } diff --git a/libqmenumodel/src/qdbusactiongroup.cpp b/libqmenumodel/src/qdbusactiongroup.cpp index 756bb76..824b5f0 100644 --- a/libqmenumodel/src/qdbusactiongroup.cpp +++ b/libqmenumodel/src/qdbusactiongroup.cpp @@ -104,7 +104,7 @@ bool QDBusActionGroup::hasAction(const QString &name) QStateAction *QDBusActionGroup::actionImpl(const QString &name) { Q_FOREACH(QStateAction *act, this->findChildren<QStateAction*>()) { - if (act->text() == name) { + if (act->name() == name) { return act; } } @@ -194,7 +194,7 @@ void QDBusActionGroup::setActionGroup(GDBusActionGroup *ag) void QDBusActionGroup::clear() { Q_FOREACH(QStateAction *act, this->findChildren<QStateAction*>()) { - Q_EMIT actionVanish(act->text()); + Q_EMIT actionVanish(act->name()); } if (m_actionGroup != NULL) { diff --git a/libqmenumodel/src/qdbusmenumodel.cpp b/libqmenumodel/src/qdbusmenumodel.cpp index 97990b4..b404d0b 100644 --- a/libqmenumodel/src/qdbusmenumodel.cpp +++ b/libqmenumodel/src/qdbusmenumodel.cpp @@ -95,13 +95,12 @@ void QDBusMenuModel::serviceVanish(GDBusConnection *) /*! \internal */ void QDBusMenuModel::serviceAppear(GDBusConnection *connection) { - GMenuModel *model = reinterpret_cast<GMenuModel*>(g_dbus_menu_model_get(connection, - busName().toUtf8().data(), - objectPath().toUtf8().data())); + GMenuModel *model = G_MENU_MODEL(g_dbus_menu_model_get(connection, + busName().toUtf8().data(), + objectPath().toUtf8().data())); setMenuModel(model); - if (model == NULL) { - stop(); - } + //setModel take care of the ref + g_object_unref(model); } /*! \internal */ diff --git a/libqmenumodel/src/qmenumodel.cpp b/libqmenumodel/src/qmenumodel.cpp index a704d85..5bf740d 100644 --- a/libqmenumodel/src/qmenumodel.cpp +++ b/libqmenumodel/src/qmenumodel.cpp @@ -41,15 +41,6 @@ QMenuModel::QMenuModel(GMenuModel *other, QObject *parent) m_menuModel(0), m_signalChangedId(0) { - static QHash<int, QByteArray> rolesNames; - if (rolesNames.empty()) { - rolesNames[Action] = "action"; - rolesNames[Label] = "label"; - rolesNames[LinkSection] = "linkSection"; - rolesNames[LinkSubMenu] = "linkSubMenu"; - rolesNames[Extra] = "extra"; - } - setRoleNames(rolesNames); setMenuModel(other); QObject::connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SIGNAL(countChanged())); @@ -113,6 +104,7 @@ void QMenuModel::setMenuModel(GMenuModel *other) m_menuModel = other; if (m_menuModel) { + g_object_ref(m_menuModel); // this will trigger the menu load (void) g_menu_model_get_n_items(m_menuModel); m_signalChangedId = g_signal_connect(m_menuModel, @@ -139,6 +131,25 @@ void QMenuModel::clearModel() g_object_unref(m_menuModel); m_menuModel = NULL; } + + QList<QMenuModel*> list = findChildren<QMenuModel*>(QString(), Qt::FindDirectChildrenOnly); + Q_FOREACH(QMenuModel *model, list) { + delete model; + } +} + +/*! \internal */ +QHash<int, QByteArray> QMenuModel::roleNames() const +{ + static QHash<int, QByteArray> roles; + if (roles.isEmpty()) { + roles[Action] = "action"; + roles[Label] = "label"; + roles[LinkSection] = "linkSection"; + roles[LinkSubMenu] = "linkSubMenu"; + roles[Extra] = "extra"; + } + return roles; } /*! \internal */ @@ -215,7 +226,7 @@ QVariant QMenuModel::getLink(const QModelIndex &index, index.row(), linkName.toUtf8().data()); - if (link) { + if (link) { QMenuModel *other = new QMenuModel(link, const_cast<QMenuModel*>(this)); return QVariant::fromValue<QObject*>(other); } diff --git a/libqmenumodel/src/qmenumodel.h b/libqmenumodel/src/qmenumodel.h index ac40db5..f923658 100644 --- a/libqmenumodel/src/qmenumodel.h +++ b/libqmenumodel/src/qmenumodel.h @@ -26,6 +26,7 @@ typedef int gint; typedef unsigned int guint; typedef void* gpointer; typedef struct _GMenuModel GMenuModel; +typedef struct _GObject GObject; class QMenuModel : public QAbstractListModel { @@ -47,6 +48,7 @@ public: int count() const; /* QAbstractItemModel */ + QHash<int, QByteArray> roleNames() const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; QModelIndex parent (const QModelIndex &index) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; diff --git a/libqmenumodel/src/qstateaction.cpp b/libqmenumodel/src/qstateaction.cpp index dd4e541..1861aea 100644 --- a/libqmenumodel/src/qstateaction.cpp +++ b/libqmenumodel/src/qstateaction.cpp @@ -47,11 +47,10 @@ /*! \internal */ QStateAction::QStateAction(QDBusActionGroup *group, const QString &name) - : QAction(name, group), - m_group(group) + : QObject(group), + m_group(group), + m_name(name) { - QObject::connect(this, SIGNAL(triggered()), this, SLOT(onTriggered())); - // This keep the code clean // But maybe we need move the action state control to QActionGroup to optimizations QObject::connect(m_group, SIGNAL(actionAppear(QString)), @@ -89,9 +88,28 @@ bool QStateAction::isValid() const return m_valid; } -void QStateAction::updateState(const QVariant &state) +/*! + Request for the state of action to be changed to \a paramenter. + This call merely requests a change. The action may refuse to change its state or may change its state to something other than \a paramenter. +*/ +void QStateAction::updateState(const QVariant ¶meter) +{ + m_group->updateActionState(m_name, parameter); +} + +/*! + Activates the action passing \a parameter. + \a parameter must be the correct type of parameter for the action +*/ +void QStateAction::activate(const QVariant ¶meter) +{ + m_group->activateAction(m_name, parameter); +} + +/*! \internal */ +QString QStateAction::name() const { - m_group->updateActionState(text(), state); + return m_name; } /*! \internal */ @@ -113,15 +131,9 @@ void QStateAction::setState(const QVariant &state) } /*! \internal */ -void QStateAction::onTriggered() -{ - m_group->activateAction(text(), QVariant()); -} - -/*! \internal */ void QStateAction::onActionAppear(const QString &name) { - if (text() == name) { + if (m_name == name) { setState(m_group->actionState(name)); setValid(true); } @@ -130,7 +142,7 @@ void QStateAction::onActionAppear(const QString &name) /*! \internal */ void QStateAction::onActionVanish(const QString &name) { - if (text() == name) { + if (m_name == name) { setState(QVariant()); setValid(false); } @@ -139,7 +151,7 @@ void QStateAction::onActionVanish(const QString &name) /*! \internal */ void QStateAction::onActionStateChanged(const QString &name, const QVariant &state) { - if (text() == name) { + if (m_name == name) { setState(state); } } diff --git a/libqmenumodel/src/qstateaction.h b/libqmenumodel/src/qstateaction.h index 85f207a..0fc68c2 100644 --- a/libqmenumodel/src/qstateaction.h +++ b/libqmenumodel/src/qstateaction.h @@ -20,21 +20,23 @@ #ifndef QDBUSACTION_H #define QDBUSACTION_H -#include <QAction> +#include <QObject> #include <QVariant> class QDBusActionGroup; -class QStateAction : public QAction +class QStateAction : public QObject { Q_OBJECT - Q_PROPERTY(QVariant state READ state WRITE setState NOTIFY stateChanged) + Q_PROPERTY(QString name READ name) + Q_PROPERTY(QVariant state READ state NOTIFY stateChanged) Q_PROPERTY(bool valid READ isValid NOTIFY validChanged) public: QVariant state() const; bool isValid() const; - Q_INVOKABLE void updateState(const QVariant &state); + Q_INVOKABLE void activate(const QVariant ¶meter = QVariant()); + Q_INVOKABLE void updateState(const QVariant ¶meter); Q_SIGNALS: void stateChanged(QVariant state); @@ -44,16 +46,18 @@ private Q_SLOTS: void onActionAppear(const QString &name); void onActionVanish(const QString &name); void onActionStateChanged(const QString &name, const QVariant &state); - void onTriggered(); private: QDBusActionGroup *m_group; QVariant m_state; bool m_valid; + QString m_name; QStateAction(QDBusActionGroup *group, const QString &name); + void setValid(bool valid); void setState(const QVariant &state); + QString name() const; friend class QDBusActionGroup; }; diff --git a/tests/client/CMakeLists.txt b/tests/client/CMakeLists.txt index d946fad..392437c 100644 --- a/tests/client/CMakeLists.txt +++ b/tests/client/CMakeLists.txt @@ -8,9 +8,15 @@ macro(declare_test testname) ${GIO_LDFLAGS}
)
+ if(TEST_XML_OUTPUT)
+ set(TEST_ARGS -p -xunitxml -p -o -p test_${testname}.xml)
+ else()
+ set(TEST_ARGS "")
+ endif()
+
add_test(${testname}
${DBUS_RUNNER}
- --task ${CMAKE_CURRENT_BINARY_DIR}/${testname} -p -xunitxml -p -o -p test_${testname}.xml --task-name Client
+ --task ${CMAKE_CURRENT_BINARY_DIR}/${testname} ${TEST_ARGS} --task-name Client
--task ${CMAKE_CURRENT_SOURCE_DIR}/script_${testname}.py --task-name Server
--ignore-return)
set_tests_properties(${testname} PROPERTIES
diff --git a/tests/client/actiongrouptest.cpp b/tests/client/actiongrouptest.cpp index 6598d2e..d187ea7 100644 --- a/tests/client/actiongrouptest.cpp +++ b/tests/client/actiongrouptest.cpp @@ -141,11 +141,16 @@ private Q_SLOTS: QStateAction *act = m_actionGroup.action(action.toString()); QVERIFY(act); - act->trigger(); + // test action name + QCOMPARE(act->property("name").toString(), QString("Menu1Act")); + + act->activate(QVariant("42")); // wait for dbus propagation QTest::qWait(500); - QCOMPARE(m_script.popActivatedAction(), QString("Menu1Act")); + QPair<QString, QVariant> result = m_script.popActivatedAction(); + QCOMPARE(result.first, QString("Menu1Act")); + QCOMPARE(result.second.toString(), QString("42")); } /* diff --git a/tests/client/convertertest.cpp b/tests/client/convertertest.cpp index 5301653..f382332 100644 --- a/tests/client/convertertest.cpp +++ b/tests/client/convertertest.cpp @@ -88,6 +88,34 @@ private Q_SLOTS: // Map QVERIFY(compare(QVariantMap(), G_VARIANT_TYPE_VARDICT)); + + } + + void testTupleConversion() + { + QVariantList qTuple; + qTuple << 1 << "2" << 3.3; + + GVariant *gTuple = Converter::toGVariant(qTuple); + QVERIFY(g_variant_type_is_tuple(g_variant_get_type(gTuple))); + QCOMPARE(g_variant_n_children(gTuple), (gsize)3); + + GVariant *v = g_variant_get_child_value(gTuple, 0); + int v0 = g_variant_get_int32(v); + QCOMPARE(v0, 1); + g_variant_unref(v); + + v = g_variant_get_child_value(gTuple, 1); + const gchar *v1 = g_variant_get_string(v, NULL); + QCOMPARE(QString(v1), QString("2")); + g_variant_unref(v); + + v = g_variant_get_child_value(gTuple, 2); + gdouble v2 = g_variant_get_double(v); + QCOMPARE(v2, 3.3); + g_variant_unref(v); + + g_variant_unref(gTuple); } }; diff --git a/tests/client/modeltest.cpp b/tests/client/modeltest.cpp index c6b2f0e..8be92a6 100644 --- a/tests/client/modeltest.cpp +++ b/tests/client/modeltest.cpp @@ -25,6 +25,19 @@ #include <QtTest> #include <QDebug> +extern "C" { +#include <gio/gio.h> +} + +class TestMenuModel : public QMenuModel +{ +public: + TestMenuModel(GMenuModel *other, QObject *parent=0) + : QMenuModel(other, parent) + { + } +}; + class ModelTest : public QObject { Q_OBJECT @@ -218,6 +231,12 @@ private Q_SLOTS: QCOMPARE(v.type(), QVariant::String); QCOMPARE(v.toString(), QString("dança")); + // Tuple + v = extra["tuple"]; + QVariantList lst; + lst << "1" << 2 << 3.3; + QCOMPARE(v.type(), QVariant::List); + QCOMPARE(v.toList(), lst); } /* @@ -241,7 +260,6 @@ private Q_SLOTS: delete model; } - }; QTEST_MAIN(ModelTest) diff --git a/tests/client/script_actiongrouptest.py b/tests/client/script_actiongrouptest.py index 2af4841..bb54dae 100755 --- a/tests/client/script_actiongrouptest.py +++ b/tests/client/script_actiongrouptest.py @@ -3,10 +3,11 @@ import time from gi.repository import GLib from menuscript import Script, ActionList, MENU_OBJECT_PATH +from gi._gi import variant_type_from_string al = ActionList(MENU_OBJECT_PATH) -al.appendItem("Menu0", "Menu0Act") -al.appendItem("Menu1", "Menu1Act") +al.appendItem("Menu0", "Menu0Act", actionStateType=variant_type_from_string('s')) +al.appendItem("Menu1", "Menu1Act", actionStateType=variant_type_from_string('s')) al.removeItem("1", "Menu1Act") t = Script.create(al) diff --git a/tests/client/script_modeltest.py b/tests/client/script_modeltest.py index 72c294c..9f5df9c 100755 --- a/tests/client/script_modeltest.py +++ b/tests/client/script_modeltest.py @@ -24,6 +24,7 @@ al.appendItem("Menu0", "Menu0Act", None, None, {'x-boolean' : GLib.Variant('b', 'x-string' : GLib.Variant('s', '42'), 'x-utf8' : GLib.Variant('s', 'dança'), 'x-map' : GLib.Variant('a{sv}', pmap), + 'x-tuple' : GLib.Variant('(sid)', ("1", 2, 3.3)), }) al.appendItem("Menu1", "Menu1Act") diff --git a/tests/script/dbusmenuscript.cpp b/tests/script/dbusmenuscript.cpp index b190d5b..8fa46c7 100644 --- a/tests/script/dbusmenuscript.cpp +++ b/tests/script/dbusmenuscript.cpp @@ -92,15 +92,20 @@ void DBusMenuScript::run() } } -QString DBusMenuScript::popActivatedAction() +QPair<QString, QVariant> DBusMenuScript::popActivatedAction() { if (m_script) { QDBusMessage reply = m_script->call("popActivatedAction"); if (reply.arguments().count() > 0) { - return reply.arguments()[0].toString(); + QVariant value; + QString name = reply.arguments()[0].toString(); + if (reply.arguments().count() > 1) { + value = reply.arguments()[1]; + } + return qMakePair(name, value); } } - return QString(); + return qMakePair(QString(), QVariant()); } diff --git a/tests/script/dbusmenuscript.h b/tests/script/dbusmenuscript.h index 8a93e83..862686c 100644 --- a/tests/script/dbusmenuscript.h +++ b/tests/script/dbusmenuscript.h @@ -47,7 +47,7 @@ public: void publishMenu(); void unpublishMenu(); - QString popActivatedAction(); + QPair<QString, QVariant> popActivatedAction(); private: QDBusInterface *m_script; diff --git a/tests/script/menuscript.py b/tests/script/menuscript.py index 60cb33b..542308a 100644 --- a/tests/script/menuscript.py +++ b/tests/script/menuscript.py @@ -53,8 +53,9 @@ class Script(dbus.service.Object): self._list.walk() steps -= 1 + """ TODO: We only support string states for now """ @dbus.service.method(dbus_interface=INTERFACE_NAME, - in_signature='', out_signature='s') + in_signature='', out_signature='ss') def popActivatedAction(self): return self._list._activatedActions.pop(0) @@ -94,7 +95,7 @@ class Action(object): parent.append_item(item) # Action - act = Gio.SimpleAction.new(self._kargs['actionName'], None) + act = Gio.SimpleAction.new(self._kargs['actionName'], self._kargs['actionStateType']) act.connect('activate', self._list._onActionActivated) self._list._rootAction.insert(act) @@ -135,13 +136,14 @@ class ActionList(object): self._rootAction = None self._activatedActions = [] - def appendItem(self, label, actionName, link=None, parentId=None, properties=None): + def appendItem(self, label, actionName, link=None, parentId=None, properties=None, actionStateType=None): self._actions.append(Action(self, 'append', parentId=parentId, label=label, actionName=actionName, link=link, - properties=properties)) + properties=properties, + actionStateType=actionStateType)) def removeItem(self, menuId, actionName=None): self._actions.append(Action(self, 'remove', @@ -205,7 +207,10 @@ class ActionList(object): if self._ownNameID: Gio.bus_unown_name(self._ownNameID) self._ownNameID = None + + self._root = None + self._rootAction = None self._restore() def _onActionActivated(self, action, parameter): - self._activatedActions.append(action.get_name()) + self._activatedActions.append((action.get_name(), parameter.get_string())) |