From 6bacc0d5db885a72202cb7f80e505642a36052d4 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Tue, 11 Sep 2012 17:57:08 -0300 Subject: Splitted qmenumodel plugin in two libraries to make it testable. Create unit test for qmenumodel library. --- tests/CMakeLists.txt | 2 + tests/client/CMakeLists.txt | 46 ++++++++ tests/client/menuchangestest.cpp | 65 ++++++++++++ tests/client/modeltest.cpp | 185 +++++++++++++++++++++++++++++++++ tests/client/script_menuchangestest.py | 14 +++ tests/client/script_modeltest.py | 31 ++++++ tests/client/script_servicetest.py | 12 +++ tests/client/servicetest.cpp | 101 ++++++++++++++++++ tests/script/CMakeLists.txt | 34 ++++++ tests/script/dbusmenuscript.cpp | 75 +++++++++++++ tests/script/dbusmenuscript.h | 35 +++++++ tests/script/menuscript.py | 172 ++++++++++++++++++++++++++++++ 12 files changed, 772 insertions(+) create mode 100644 tests/CMakeLists.txt create mode 100644 tests/client/CMakeLists.txt create mode 100644 tests/client/menuchangestest.cpp create mode 100644 tests/client/modeltest.cpp create mode 100755 tests/client/script_menuchangestest.py create mode 100755 tests/client/script_modeltest.py create mode 100755 tests/client/script_servicetest.py create mode 100644 tests/client/servicetest.cpp create mode 100644 tests/script/CMakeLists.txt create mode 100644 tests/script/dbusmenuscript.cpp create mode 100644 tests/script/dbusmenuscript.h create mode 100644 tests/script/menuscript.py (limited to 'tests') diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..96c4bad --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(script) +add_subdirectory(client) diff --git a/tests/client/CMakeLists.txt b/tests/client/CMakeLists.txt new file mode 100644 index 0000000..bf77461 --- /dev/null +++ b/tests/client/CMakeLists.txt @@ -0,0 +1,46 @@ +macro(declare_test testname) + set(TEST_MOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/${testname}.moc) + qt4_generate_moc(${testname}.cpp ${TEST_MOC_FILE}) + + add_executable(${testname} ${testname}.cpp ${TEST_MOC_FILE}) + target_link_libraries(${testname} + qmenumodelcommon + dbusmenuscript + ${QT_QTTEST_LIBRARY} + ${QT_QTCORE_LIBRARY} + ${QT_QTGUI_LIBRARY} + ${QT_QTDBUS_LIBRARY} + ${GLIB_LDFLAGS} + ${GIO_LDFLAGS}) + + add_test(${testname} + ${DBUS_RUNNER} + --task ${CMAKE_CURRENT_BINARY_DIR}/${testname} --task-name Client + --task ${CMAKE_CURRENT_SOURCE_DIR}/script_${testname}.py --task-name Server + --ignore-return) + set_tests_properties(${testname} PROPERTIES + TIMEOUT ${CTEST_TESTING_TIMEOUT} + ENVIRONMENT "PYTHONPATH=${TEST_PYTHONPATH}") + +endmacro(declare_test testname) + +include_directories(${qmenumodelcommon_SOURCE_DIR} + ${dbusmenuscript_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${QT_INCLUDE_DIR} + ${QT_QTTEST_INCLUDE_DIR} + ${QT_QTCORE_INCLUDE_DIR} + ${QT_QTGUI_INCLUDE_DIR} + ${QT_QTDBUS_INCLUDE_DIR} + ${GLIB_INCLUDE_DIRS} + ${GIO_INCLUDE_DIRS}) + +add_definitions(-DTEST_SUITE) +set(TEST_PYTHONPATH ${dbusmenuscript_SOURCE_DIR}) +if(NOT CTEST_TESTING_TIMEOUT) + set(CTEST_TESTING_TIMEOUT 60) +endif() + +declare_test(servicetest) +declare_test(menuchangestest) +declare_test(modeltest) diff --git a/tests/client/menuchangestest.cpp b/tests/client/menuchangestest.cpp new file mode 100644 index 0000000..7e6379c --- /dev/null +++ b/tests/client/menuchangestest.cpp @@ -0,0 +1,65 @@ +#include "qdbusmenumodel.h" +#include "dbusmenuscript.h" + +#include +#include +#include +#include + +class MenuChangesTest : public QObject +{ + Q_OBJECT +private: + DBusMenuScript m_script; + QDBusMenuModel m_model; + +private Q_SLOTS: + void initTestCase() + { + Q_ASSERT(m_script.connect()); + } + + void cleanupTestCase() + { + m_script.quit(); + } + + void init() + { + m_model.stop(); + m_model.setBusType(QDBusObject::SessionBus); + m_model.setBusName(MENU_SERVICE_NAME); + m_model.setObjectPath(MENU_OBJECT_PATH); + } + + void cleanup() + { + m_script.unpublishMenu(); + } + + void testMenuItemAppend() + { + m_script.publishMenu(); + m_model.start(); + + // Create first Item + m_script.walk(); + QCOMPARE(m_model.rowCount(), 1); + + // Create second item + m_script.walk(); + QCOMPARE(m_model.rowCount(), 2); + + // Remove item0 + m_script.walk(); + QCOMPARE(m_model.rowCount(), 1); + + // Remove item1 + m_script.walk(); + QCOMPARE(m_model.rowCount(), 0); + } +}; + +QTEST_MAIN(MenuChangesTest) + +#include "menuchangestest.moc" diff --git a/tests/client/modeltest.cpp b/tests/client/modeltest.cpp new file mode 100644 index 0000000..1963327 --- /dev/null +++ b/tests/client/modeltest.cpp @@ -0,0 +1,185 @@ +#include "qdbusmenumodel.h" +#include "dbusmenuscript.h" + +#include +#include +#include +#include + +class ModelTest : public QObject +{ + Q_OBJECT +private: + DBusMenuScript m_script; + QDBusMenuModel m_model; + +private Q_SLOTS: + void initTestCase() + { + Q_ASSERT(m_script.connect()); + } + + void cleanupTestCase() + { + m_script.quit(); + } + + void init() + { + m_model.stop(); + m_model.setBusType(QDBusObject::SessionBus); + m_model.setBusName(MENU_SERVICE_NAME); + m_model.setObjectPath(MENU_OBJECT_PATH); + } + + void cleanup() + { + m_script.unpublishMenu(); + } + + void testColumnCount() + { + QCOMPARE(m_model.columnCount(), 1); + } + + void testParent() + { + QCOMPARE(m_model.parent(QModelIndex()), QModelIndex()); + } + + void testBusTypeProperty() + { + m_model.setProperty("busType", 1); + QCOMPARE(m_model.busType(), QDBusObject::SessionBus); + + m_model.setProperty("busType", 2); + QCOMPARE(m_model.busType(), QDBusObject::SystemBus); + + m_model.setProperty("busType", 0); + QCOMPARE(m_model.busType(), QDBusObject::SystemBus); + + m_model.setProperty("busType", 10); + QCOMPARE(m_model.busType(), QDBusObject::SystemBus); + + } + + void testData() + { + // Make menu available + m_script.publishMenu(); + m_script.run(); + + // start model + m_model.start(); + + // Wait for dbus sync + QTest::qWait(500); + + QCOMPARE(m_model.status(), QDBusObject::Connected); + QCOMPARE(m_model.rowCount(), 4); + + // Label (String) + QVariant label = m_model.data(m_model.index(0, 0), QMenuModel::Label); + QVERIFY(label.isValid()); + QCOMPARE(label.type(), QVariant::String); + QCOMPARE(label.toString(), QString("Menu0")); + + // Action (String) + QVariant action = m_model.data(m_model.index(1, 0), QMenuModel::Action); + QVERIFY(action.isValid()); + QCOMPARE(action.type(), QVariant::String); + QCOMPARE(action.toString(), QString("Menu1Act")); + + // Section (QObject) + QVariant vSection = m_model.data(m_model.index(2, 0), QMenuModel::LinkSection); + QVERIFY(vSection.isValid()); + QMenuModel *section = qobject_cast(vSection.value()); + QVERIFY(section); + QCOMPARE(section->rowCount(), 2); + + // SubMenu (QObject) + QVariant vSubMenu = m_model.data(m_model.index(3, 0), QMenuModel::LinkSubMenu); + QVERIFY(vSubMenu.isValid()); + QMenuModel *submenu = qobject_cast(vSubMenu.value()); + QVERIFY(submenu); + + // Wait for menu load (submenus are loaded async) + QTest::qWait(500); + QCOMPARE(submenu->rowCount(), 2); + } + + void testExtraData() + { + // Make menu available + m_script.publishMenu(); + m_script.run(); + + // start model + m_model.start(); + + // Wait for dbus sync + QTest::qWait(500); + + QCOMPARE(m_model.status(), QDBusObject::Connected); + QCOMPARE(m_model.rowCount(), 4); + + QVariant e = m_model.data(m_model.index(0, 0), QMenuModel::Extra); + QVERIFY(e.isValid()); + QObject *extra = e.value(); + + // Boolean + QVariant v = extra->property("x-boolean"); + QCOMPARE(v.type(), QVariant::Bool); + QCOMPARE(v.toBool(), true); + + // Byte + v = extra->property("x-byte"); + QCOMPARE(v.typeName(), "uchar"); + QCOMPARE(v.value(), (uchar)42); + + // Int16 + v = extra->property("x-int16"); + QCOMPARE(v.typeName(), "short"); + QCOMPARE(v.value(), (short)-42); + + // UInt16 + v = extra->property("x-uint16"); + QCOMPARE(v.typeName(), "ushort"); + QCOMPARE(v.value(), (ushort)42); + + // Int32 + v = extra->property("x-int32"); + QCOMPARE(v.type(), QVariant::Int); + QCOMPARE(v.toInt(), -42); + + // UInt32 + v = extra->property("x-uint32"); + QCOMPARE(v.type(), QVariant::UInt); + QCOMPARE(v.toUInt(), (uint) 42); + + // Int64 + v = extra->property("x-int64"); + QCOMPARE(v.typeName(), "long"); + QCOMPARE(v.value(), (long) -42); + + // UInt64 + v = extra->property("x-uint64"); + QCOMPARE(v.typeName(), "ulong"); + QCOMPARE(v.value(), (ulong) 42); + + // Double + v = extra->property("x-double"); + QCOMPARE(v.type(), QVariant::Double); + QCOMPARE(v.toDouble(), 42.42); + + // String + v = extra->property("x-string"); + QCOMPARE(v.type(), QVariant::String); + QCOMPARE(v.toString(), QString("42")); + } + +}; + +QTEST_MAIN(ModelTest) + +#include "modeltest.moc" diff --git a/tests/client/script_menuchangestest.py b/tests/client/script_menuchangestest.py new file mode 100755 index 0000000..67f2ee0 --- /dev/null +++ b/tests/client/script_menuchangestest.py @@ -0,0 +1,14 @@ +#!/usr/bin/python2.7 + +import time +from menuscript import Script, ActionList, MENU_OBJECT_PATH + +al = ActionList(MENU_OBJECT_PATH) +al.appendItem("Menu0", "Menu0") +al.appendItem("Menu1", "Menu1") +al.removeItem(0) # remove Menu0 +al.removeItem(0) # remove Menu1 + +t = Script.create(al) +t.run() + diff --git a/tests/client/script_modeltest.py b/tests/client/script_modeltest.py new file mode 100755 index 0000000..db4e28b --- /dev/null +++ b/tests/client/script_modeltest.py @@ -0,0 +1,31 @@ +#!/usr/bin/python2.7 + +import time +from gi.repository import GLib +from menuscript import Script, ActionList, MENU_OBJECT_PATH + +al = ActionList(MENU_OBJECT_PATH) +al.appendItem("Menu0", "Menu0Act", None, None, {'x-boolean' : GLib.Variant('b', True), + 'x-byte' : GLib.Variant('y', 42), + 'x-int16' : GLib.Variant('n', -42), + 'x-uint16' : GLib.Variant('q', 42), + 'x-int32' : GLib.Variant('i', -42), + 'x-uint32' : GLib.Variant('u', 42), + 'x-int64' : GLib.Variant('x', -42), + 'x-uint64' : GLib.Variant('t', 42), + 'x-double' : GLib.Variant('d', 42.42), + 'x-string' : GLib.Variant('s', u'42') + }) +al.appendItem("Menu1", "Menu1Act") + +al.appendItem("Menu2", "Menu2Act", "section") +al.appendItem("Menu2.1", "Menu2.1Act", None, "2") +al.appendItem("Menu2.2", "Menu2.2Act", None, "2") + +al.appendItem("Menu3", "Menu3Act", "submenu") +al.appendItem("Menu3.1", "Menu3.1Act", None, "3") +al.appendItem("Menu3.2", "Menu3.2Act", None, "3") + +t = Script.create(al) +t.run() + diff --git a/tests/client/script_servicetest.py b/tests/client/script_servicetest.py new file mode 100755 index 0000000..385256c --- /dev/null +++ b/tests/client/script_servicetest.py @@ -0,0 +1,12 @@ +#!/usr/bin/python2.7 + +import time +from menuscript import Script, ActionList, MENU_OBJECT_PATH + +al = ActionList(MENU_OBJECT_PATH) +al.appendItem("Menu0", "Menu0") +al.appendItem("Menu1", "Menu1") + +t = Script.create(al) +t.run() + diff --git a/tests/client/servicetest.cpp b/tests/client/servicetest.cpp new file mode 100644 index 0000000..3faddd0 --- /dev/null +++ b/tests/client/servicetest.cpp @@ -0,0 +1,101 @@ +#include "qdbusmenumodel.h" +#include "dbusmenuscript.h" + +#include +#include +#include +#include + +class ServiceTest : public QObject +{ + Q_OBJECT +private: + DBusMenuScript m_script; + QDBusMenuModel m_model; + + void setupModel(QDBusMenuModel *model) + { + model->setBusType(QDBusObject::SessionBus); + model->setBusName(MENU_SERVICE_NAME); + model->setObjectPath(MENU_OBJECT_PATH); + } + +private Q_SLOTS: + void initTestCase() + { + Q_ASSERT(m_script.connect()); + } + + void cleanupTestCase() + { + m_script.quit(); + } + + void init() + { + qDebug() << "init>>>>>>>>>>>>>>>>>>>>>"; + m_model.stop(); + m_model.setBusType(QDBusObject::SessionBus); + m_model.setBusName(MENU_SERVICE_NAME); + m_model.setObjectPath(MENU_OBJECT_PATH); + } + + void cleanup() + { + qDebug() << "cleanup>>>>>>>>>>>>>>>>>>"; + m_script.unpublishMenu(); + } + + void testMenuStartStopWithNoService() + { + m_model.start(); + QCOMPARE(m_model.status(), QDBusObject::Connecting); + + m_model.stop(); + QCOMPARE(m_model.status(), QDBusObject::Disconnected); + } + + void testMenuStartStopWithService() + { + // Make menu available + m_script.publishMenu(); + + // start model + m_model.start(); + + // Wait for dbus sync + QTest::qWait(500); + + QCOMPARE(m_model.status(), QDBusObject::Connected); + + // Diconnect model + m_model.stop(); + QCOMPARE(m_model.status(), QDBusObject::Disconnected); + } + + void testMenuServiceAppearAndDissapear() + { + m_model.start(); + QCOMPARE(m_model.status(), QDBusObject::Connecting); + + QSignalSpy spy(&m_model, SIGNAL(statusChanged(QDBusObject::ConnectionStatus))); + + // Make menu available + m_script.publishMenu(); + + // singal changed to connected + QCOMPARE(spy.count(), 1); + QCOMPARE(m_model.status(), QDBusObject::Connected); + + // remove menu service + m_script.unpublishMenu(); + + // signal changed to connecting + QCOMPARE(spy.count(), 2); + QCOMPARE(m_model.status(), QDBusObject::Connecting); + } +}; + +QTEST_MAIN(ServiceTest) + +#include "servicetest.moc" diff --git a/tests/script/CMakeLists.txt b/tests/script/CMakeLists.txt new file mode 100644 index 0000000..11af44e --- /dev/null +++ b/tests/script/CMakeLists.txt @@ -0,0 +1,34 @@ +project(dbusmenuscript) + +set(DBUSMENUSCRIPT_SRC + dbusmenuscript.cpp +) + +set(DBUSMENUSCRIPT_HEADERS + dbusmenuscript.h +) + +qt4_wrap_cpp(DBUSMENUSCRIPT_MOC + ${DBUSMENUSCRIPT_HEADERS} +) + +add_library(dbusmenuscript STATIC + ${DBUSMENUSCRIPT_SRC} + ${DBUSMENUSCRIPT_MOC} +) + +set_target_properties(dbusmenuscript PROPERTIES COMPILE_FLAGS -fPIC) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${QT_INCLUDE_DIR} + ${QT_QTTEST_INCLUDE_DIR} + ${QT_QTCORE_INCLUDE_DIR} + ${QT_QTDBUS_INCLUDE_DIR} +) + +target_link_libraries(dbusmenuscript + ${QT_QTCORE_LIBRARY} + ${QT_QTTEST_LIBRARY} + ${QT_QTDBUS_LIBRARY} +) diff --git a/tests/script/dbusmenuscript.cpp b/tests/script/dbusmenuscript.cpp new file mode 100644 index 0000000..cc332f7 --- /dev/null +++ b/tests/script/dbusmenuscript.cpp @@ -0,0 +1,75 @@ + +#include "dbusmenuscript.h" +#include +#include +#include + +#define WAIT_TIMEOUT 500 + +DBusMenuScript::DBusMenuScript() + :m_script(0) +{ +} + +DBusMenuScript::~DBusMenuScript() +{ + quit(); +} + +bool DBusMenuScript::connect() +{ + QTest::qWait(WAIT_TIMEOUT); + m_script = new QDBusInterface(SCRIPT_SERVICE_NAME, + SCRIPT_OBJECT_PATH, + SCRIPT_INTERFACE_NAME, + QDBusConnection::sessionBus(), 0); + if (m_script && m_script->isValid()) { + return true; + } else { + qWarning() << "DBUS ERROR:" << m_script->lastError().message(); + return false; + } +} + +void DBusMenuScript::publishMenu() +{ + if (m_script) { + m_script->call("publishMenu"); + QTest::qWait(WAIT_TIMEOUT); + } +} + +void DBusMenuScript::unpublishMenu() +{ + if (m_script) { + m_script->call("unpublishMenu"); + QTest::qWait(WAIT_TIMEOUT); + } +} + + +void DBusMenuScript::quit() +{ + if (m_script) { + m_script->call("quit"); + QTest::qWait(WAIT_TIMEOUT); + delete m_script; + m_script = 0; + } +} + +void DBusMenuScript::walk(int steps) +{ + if (m_script) { + m_script->call("walk", steps); + QTest::qWait(WAIT_TIMEOUT); + } +} + +void DBusMenuScript::run() +{ + if (m_script) { + m_script->call("walk", -1); + QTest::qWait(WAIT_TIMEOUT); + } +} diff --git a/tests/script/dbusmenuscript.h b/tests/script/dbusmenuscript.h new file mode 100644 index 0000000..3d0d3c9 --- /dev/null +++ b/tests/script/dbusmenuscript.h @@ -0,0 +1,35 @@ +#ifndef DBUSMENUSCRIPT_H +#define DBUSMENUSCRITP_H + +#include +#include +#include + +#define SCRIPT_SERVICE_NAME "com.canonical.test" +#define SCRIPT_OBJECT_PATH "/com/canonical/test/menuscript" +#define SCRIPT_INTERFACE_NAME "com.canonical.test.menuscript" + +#define MENU_SERVICE_NAME SCRIPT_SERVICE_NAME ".menu" +#define MENU_OBJECT_PATH SCRIPT_OBJECT_PATH "/menu" + + +class DBusMenuScript +{ +public: + DBusMenuScript(); + ~DBusMenuScript(); + + bool connect(); + void quit(); + + void walk(int steps = 1); + void run(); + + void publishMenu(); + void unpublishMenu(); + +private: + QDBusInterface *m_script; +}; + +#endif diff --git a/tests/script/menuscript.py b/tests/script/menuscript.py new file mode 100644 index 0000000..05e226c --- /dev/null +++ b/tests/script/menuscript.py @@ -0,0 +1,172 @@ +import dbus +import dbus.service +from dbus import glib +from dbus.mainloop.glib import DBusGMainLoop +from gi.repository import GObject +from gi.repository import GLib +from gi.repository import Gio + +SERVICE_NAME = "com.canonical.test" +INTERFACE_NAME = "com.canonical.test.menuscript" +OBJECT_PATH = "/com/canonical/test/menuscript" +MENU_SERVICE_NAME= SERVICE_NAME + ".menu" +MENU_OBJECT_PATH = OBJECT_PATH + "/menu" +bus = None + +class Script(dbus.service.Object): + def __init__(self, aList, session, object_path): + dbus.service.Object.__init__(self, session, object_path) + self._list = aList + self._session = session + + def run(self): + self._loop = GObject.MainLoop() + self._loop.run() + + @dbus.service.method(dbus_interface=INTERFACE_NAME, + in_signature='', out_signature='', + sender_keyword='sender') + def publishMenu(self, sender=None): + self._list.start() + + @dbus.service.method(dbus_interface=INTERFACE_NAME, + in_signature='', out_signature='', + sender_keyword='sender') + def unpublishMenu(self, sender=None): + self._list.stop() + + @dbus.service.method(dbus_interface=INTERFACE_NAME, + in_signature='', out_signature='', + sender_keyword='sender') + def quit(self, sender=None): + self.unpublishMenu(); + self._loop.quit() + + @dbus.service.method(dbus_interface=INTERFACE_NAME, + in_signature='i', out_signature='', + sender_keyword='sender') + def walk(self, steps, sender=None): + if steps == -1 or steps > self._list.size(): + steps = self._list.size() + + while(steps > 0): + self._list.walk() + steps -= 1 + + @staticmethod + def create(aList): + global bus + + GObject.threads_init() + glib.threads_init() + + dbus_loop = DBusGMainLoop() + bus = dbus.SessionBus(mainloop=dbus_loop) + bus_name = dbus.service.BusName(SERVICE_NAME, bus=bus) + return Script(aList, bus_name, OBJECT_PATH) + +class Action(object): + def __init__(self, aList, action, **kwargs): + self._list = aList + self._action = action + self._kargs = kwargs + + def setProperties(self, menu, props): + if props: + for key in props: + menu.set_attribute_value(key, props[key]) + + def appendItem(self): + parentId = self._kargs['parentId'] + if parentId and len(parentId): + parent = self._list.getMenu(parentId)[0] + else: + parent = self._list._root + + if self._kargs['link'] == None: + item = Gio.MenuItem.new(self._kargs['label'], self._kargs['actionName']) + self.setProperties(item, self._kargs['properties']) + parent.append_item(item) + elif self._kargs['link'] == 'section': + section = Gio.Menu() + parent.append_section(self._kargs['label'], section) + elif self._kargs['link'] == 'submenu': + submenu = Gio.Menu() + parent.append_submenu(self._kargs['label'], submenu) + + def removeItem(self): + menuId = self._kargs['menuId'] + (menu, mId) = self._list.getMenu(menuId) + if mId != -1: + menu.remove(mId) + else: + print "Remove menu item" + + def run(self): + if self._action == 'append': + self.appendItem() + elif self._action == 'remove': + self.removeItem() + +class ActionList(object): + def __init__(self, objectPath): + self._actions = [] + self._objectPath = objectPath + self._bux = None + self._exportID = None + self._ownNameID = None + self._root = None + + def appendItem(self, label, actionName, link=None, parentId=None, properties=None): + self._actions.append(Action(self, 'append', + parentId=parentId, + label=label, + actionName=actionName, + link=link, + properties=properties)) + + def removeItem(self, menuId): + self._actions.append(Action(self, 'remove', + menuId=menuId)) + + def _findMenu(self, root, ids): + if len(ids) == 0: + return (root, -1) + + currentId = int(ids[0]) + link = root.get_item_link(currentId, 'section') + if link == None: + link = root.get_item_link(currentId, 'submenu') + + if link: + return self._findMenu(link, ids[1:]) + else: + return (root, currentId) + + def getMenu(self, menuId): + return self._findMenu(self._root, str(menuId).split('.')); + + def walk(self): + item = self._actions.pop(0) + item.run() + + def size(self): + return len(self._actions) + + def _exportService(self, connection, name): + self._root = Gio.Menu() + self._bus = connection + self._exportID = connection.export_menu_model(MENU_OBJECT_PATH, self._root) + + def start(self): + self._ownNameID = Gio.bus_own_name(2, MENU_SERVICE_NAME, 0, self._exportService, None, None) + + def stop(self): + if self._exportID: + self._bus.unexport_menu_model(self._exportID) + self._exportID = None + + if self._ownNameID: + Gio.bus_unown_name(self._ownNameID) + self._ownNameID = None + -- cgit v1.2.3