From a3aa532c698c5eab037b17870275d8e27e77a498 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Wed, 12 Sep 2012 14:47:26 -0300 Subject: Added QML documentation. --- CMakeLists.txt | 18 ++++--- src/common/CMakeLists.txt | 2 + src/common/converter.cpp | 61 +++++++++++++++++++++++ src/common/converter.h | 36 ++++++++++++++ src/common/qdbusactiongroup.cpp | 106 ++++++++++++++++++++++++++++++---------- src/common/qdbusactiongroup.h | 23 +++++---- src/common/qdbusmenumodel.cpp | 69 +++++++++++++++++--------- src/common/qdbusmenumodel.h | 7 --- src/common/qdbusobject.cpp | 50 +++++++++++++++++-- src/common/qmenumodel.cpp | 83 +++++++++---------------------- src/common/qmenumodel.h | 1 - tests/client/CMakeLists.txt | 1 + tests/script/dbusmenuscript.cpp | 13 +++++ tests/script/dbusmenuscript.h | 2 + tests/script/menuscript.py | 53 +++++++++++++++++--- 15 files changed, 383 insertions(+), 142 deletions(-) create mode 100644 src/common/converter.cpp create mode 100644 src/common/converter.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 65e6fa8..fe36672 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,12 +36,16 @@ else() add_subdirectory(tests) endif() +# Doc +OPTION(GENERATE_DOC "Enable qdoc generation" OFF) +if(GENERATE_DOC) + message(STATUS "QDoc enabled.") + find_program(QDOC_BIN qdoc3) + if(NOT QDOC_BIN) + message(FATAL_ERROR "qdoc command not found") + else() + add_subdirectory(doc) + endif() +endif() -# Tests Tools -#if(NOT DBUS_RUNNER) -# message(STATUS "dbus-test-runner not found tests disabled.") -#else() -# enable_testing() -# add_subdirectory(tests) -#endif() diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 1428000..a4f5e2e 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,6 +1,7 @@ project(qmenumodelcommon) set(QMENUMODELCOMMON_SRC + converter.cpp qmenumodel.cpp qdbusobject.cpp qdbusmenumodel.cpp @@ -8,6 +9,7 @@ set(QMENUMODELCOMMON_SRC ) set(QMENUMODELCOMMON_HEADERS + converter.h qmenumodel.h qdbusobject.h qdbusmenumodel.h diff --git a/src/common/converter.cpp b/src/common/converter.cpp new file mode 100644 index 0000000..a8ccb0f --- /dev/null +++ b/src/common/converter.cpp @@ -0,0 +1,61 @@ +#include "converter.h" + +#include + +/*! \internal */ +QVariant Converter::parseGVariant(GVariant *value) +{ + QVariant result; + if (value == NULL) { + return result; + } + + const GVariantType *type = g_variant_get_type(value); + if (g_variant_type_equal(type, G_VARIANT_TYPE_BOOLEAN)) { + result.setValue((bool)g_variant_get_boolean(value)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE)) { + result.setValue(g_variant_get_byte(value)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16)) { + result.setValue(g_variant_get_int16(value)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16)) { + result.setValue(g_variant_get_uint16(value)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32)) { + result.setValue(g_variant_get_int32(value)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32)) { + result.setValue(g_variant_get_uint32(value)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64)) { + result.setValue(g_variant_get_int64(value)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64)) { + result.setValue(g_variant_get_uint64(value)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_DOUBLE)) { + result.setValue(g_variant_get_double(value)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_STRING)) { + gsize size = 0; + const gchar *v = g_variant_get_string(value, &size); + result.setValue(QString::fromLatin1(v, size)); + } else { + qWarning() << "Unsupported GVariant value"; + } + + /* TODO: implement convertions to others types + * G_VARIANT_TYPE_HANDLE + * G_VARIANT_TYPE_OBJECT_PATH + * G_VARIANT_TYPE_SIGNATURE + * G_VARIANT_TYPE_VARIANT + * G_VARIANT_TYPE_ANY + * 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 + * G_VARIANT_TYPE_STRING_ARRAY + * G_VARIANT_TYPE_BYTESTRING + * G_VARIANT_TYPE_OBJECT_PATH_ARRAY + * G_VARIANT_TYPE_BYTESTRING_ARRAY + * G_VARIANT_TYPE_VARDICT + */ + + return result; +} diff --git a/src/common/converter.h b/src/common/converter.h new file mode 100644 index 0000000..adbad71 --- /dev/null +++ b/src/common/converter.h @@ -0,0 +1,36 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Authors: + * Renato Araujo Oliveira Filho + */ + +#ifndef CONVERTER_H +#define CONVERTER_H + +#include +#include + +class Converter +{ +public: + static QVariant parseGVariant(GVariant *value); + +private: + Converter(); + Converter(const Converter &other); +}; + +#endif diff --git a/src/common/qdbusactiongroup.cpp b/src/common/qdbusactiongroup.cpp index 51bc4ac..e453215 100644 --- a/src/common/qdbusactiongroup.cpp +++ b/src/common/qdbusactiongroup.cpp @@ -18,26 +18,60 @@ */ #include "qdbusactiongroup.h" +#include "converter.h" #include #include +/*! + \qmlclass QDBusActionGroup + \inherits QDBusObject + + \brief A DBusActionGroup implementation to be used with \l QDBusMenuModel + + \bold {This component is under heavy development.} + + This class can be used as a proxy for an action group that is exported over D-Bus + + \code + QDBusActionGroup { + id: actionGroup + busType: 1 + busName: "com.ubuntu.menu" + objectPath: "com/ubuntu/menu/actions" + } + + Button { + onClicked: actionGroup.getAction("app.quit").trigger() + } + \endcode +*/ + +/*! \internal */ QDBusActionGroup::QDBusActionGroup(QObject *parent) :QObject(parent), m_actionGroup(NULL) { } +/*! \internal */ QDBusActionGroup::~QDBusActionGroup() { clear(); } -QAction *QDBusActionGroup::getAction(const QString &actionName) +/*! + \qmlmethod QDBusActionGroup::action(QString name) + + Look for a action with the same name and return a \l QAction object. + + \bold Note: methods should only be called after the Component has completed. +*/ +QAction *QDBusActionGroup::action(const QString &name) { Q_FOREACH(QAction *act, m_actions) { - if (act->text() == actionName) { + if (act->text() == name) { return act; } } @@ -45,11 +79,22 @@ QAction *QDBusActionGroup::getAction(const QString &actionName) return NULL; } +/*! + \qmlproperty int QDBusActionGroup::count + This property holds the number of actions inside of \l QDBusActionGroup +*/ +int QDBusActionGroup::count() const +{ + return m_actions.count(); +} + +/*! \internal */ void QDBusActionGroup::serviceVanish(GDBusConnection *) { clear(); } +/*! \internal */ void QDBusActionGroup::serviceAppear(GDBusConnection *connection) { GDBusActionGroup *ag = g_dbus_action_group_get(connection, @@ -61,36 +106,19 @@ void QDBusActionGroup::serviceAppear(GDBusConnection *connection) } } +/*! \internal */ void QDBusActionGroup::start() { QDBusObject::connect(); } +/*! \internal */ void QDBusActionGroup::stop() { QDBusObject::disconnect(); } -void QDBusActionGroup::busTypeChanged(BusType) -{ - busTypeChanged(); -} - -void QDBusActionGroup::busNameChanged(const QString &) -{ - busNameChanged(); -} - -void QDBusActionGroup::objectPathChanged(const QString &objectPath) -{ - objectPathChanged(); -} - -void QDBusActionGroup::statusChanged(ConnectionStatus status) -{ - statusChanged(); -} - +/*! \internal */ void QDBusActionGroup::setIntBusType(int busType) { if ((busType > None) && (busType < LastBusType)) { @@ -98,6 +126,7 @@ void QDBusActionGroup::setIntBusType(int busType) } } +/*! \internal */ void QDBusActionGroup::setActionGroup(GDBusActionGroup *ag) { if (m_actionGroup == reinterpret_cast(ag)) { @@ -107,16 +136,16 @@ void QDBusActionGroup::setActionGroup(GDBusActionGroup *ag) if (m_actionGroup) { g_signal_handler_disconnect(m_actionGroup, m_signalActionAddId); g_signal_handler_disconnect(m_actionGroup, m_signalActionRemovedId); - m_signalActionAddId = m_signalActionRemovedId = 0; + g_signal_handler_disconnect(m_actionGroup, m_signalStateChangedId); + m_signalActionAddId = m_signalActionRemovedId = m_signalStateChangedId = 0; g_object_unref(m_actionGroup); } m_actionGroup = reinterpret_cast(ag); if (m_actionGroup) { - m_signalActionAddId = g_signal_connect(m_actionGroup, - "action-add", + "action-added", G_CALLBACK(QDBusActionGroup::onActionAdded), this); @@ -125,6 +154,11 @@ void QDBusActionGroup::setActionGroup(GDBusActionGroup *ag) G_CALLBACK(QDBusActionGroup::onActionRemoved), this); + m_signalStateChangedId = g_signal_connect(m_actionGroup, + "action-state-changed", + G_CALLBACK(QDBusActionGroup::onActionStateChanged), + this); + gchar **actionNames = g_action_group_list_actions(m_actionGroup); for(int i=0; actionNames[i] != NULL; i++) { addAction(actionNames[i]); @@ -133,6 +167,7 @@ void QDBusActionGroup::setActionGroup(GDBusActionGroup *ag) } } +/*! \internal */ void QDBusActionGroup::addAction(const char *actionName) { QAction *act = new QAction(actionName, this); @@ -150,35 +185,51 @@ void QDBusActionGroup::addAction(const char *actionName) } } + QObject::connect(act, SIGNAL(triggered()), this, SLOT(onActionTriggered())); + // remove any older action with the same name removeAction(actionName); m_actions.insert(act); + Q_EMIT countChanged(m_actions.count()); } +/*! \internal */ +void QDBusActionGroup::onActionTriggered() +{ + QAction *act = qobject_cast(QObject::sender()); + g_action_group_activate_action(m_actionGroup, act->text().toLatin1(), NULL); +} + +/*! \internal */ void QDBusActionGroup::removeAction(const char *actionName) { Q_FOREACH(QAction *act, m_actions) { if (act->text() == actionName) { m_actions.remove(act); delete act; + Q_EMIT countChanged(m_actions.count()); break; } } } +/*! \internal */ void QDBusActionGroup::updateAction(const char *actionName, GVariant *state) { - QAction *action = getAction(actionName); + QAction *action = this->action(actionName); if ((action != NULL) && (state != NULL)) { const GVariantType *stateType = g_variant_get_type(state); if (stateType == G_VARIANT_TYPE_BOOLEAN) { action->setChecked(g_variant_get_boolean(state)); } + + Q_EMIT actionStateChanged(actionName, Converter::parseGVariant(state)); } } +/*! \internal */ void QDBusActionGroup::clear() { Q_FOREACH(QAction *act, m_actions) { @@ -192,12 +243,14 @@ void QDBusActionGroup::clear() } } +/*! \internal */ void QDBusActionGroup::onActionAdded(GDBusActionGroup *, gchar *actionName, gpointer data) { QDBusActionGroup *self = reinterpret_cast(data); self->addAction(actionName); } +/*! \internal */ void QDBusActionGroup::onActionRemoved(GDBusActionGroup *, gchar *actionName, gpointer data) { QDBusActionGroup *self = reinterpret_cast(data); @@ -205,6 +258,7 @@ void QDBusActionGroup::onActionRemoved(GDBusActionGroup *, gchar *actionName, gp } +/*! \internal */ void QDBusActionGroup::onActionStateChanged(GDBusActionGroup *ag, gchar *actionName, GVariant *value, gpointer data) { QDBusActionGroup *self = reinterpret_cast(data); diff --git a/src/common/qdbusactiongroup.h b/src/common/qdbusactiongroup.h index 4ae0074..3ff7927 100644 --- a/src/common/qdbusactiongroup.h +++ b/src/common/qdbusactiongroup.h @@ -33,36 +33,41 @@ class QDBusActionGroup : public QObject, public QDBusObject Q_PROPERTY(QString busName READ busName WRITE setBusName NOTIFY busNameChanged) Q_PROPERTY(QString objectPath READ objectPath WRITE setObjectPath NOTIFY objectPathChanged) Q_PROPERTY(int status READ status NOTIFY statusChanged) + Q_PROPERTY(int count READ count NOTIFY countChanged) public: QDBusActionGroup(QObject *parent=0); ~QDBusActionGroup(); + int count() const; + Q_SIGNALS: - void busTypeChanged(); - void busNameChanged(); - void objectPathChanged(); - void statusChanged(); + void busTypeChanged(BusType type); + void busNameChanged(const QString &busNameChanged); + void objectPathChanged(const QString &objectPath); + void statusChanged(ConnectionStatus status); + void actionStateChanged(const QString &name, QVariant value); + void countChanged(int count); public Q_SLOTS: void start(); void stop(); - QAction *getAction(const QString &actionName); + QAction *action(const QString &actionName); protected: virtual void serviceAppear(GDBusConnection *connection); virtual void serviceVanish(GDBusConnection *connection); - virtual void busTypeChanged(BusType type); - virtual void busNameChanged(const QString &busNameChanged); - virtual void objectPathChanged(const QString &objectPath); - virtual void statusChanged(ConnectionStatus status); + +private Q_SLOTS: + void onActionTriggered(); private: GActionGroup *m_actionGroup; QSet m_actions; int m_signalActionAddId; int m_signalActionRemovedId; + int m_signalStateChangedId; // workaround to support int as bustType void setIntBusType(int busType); diff --git a/src/common/qdbusmenumodel.cpp b/src/common/qdbusmenumodel.cpp index cae1288..9b824b4 100644 --- a/src/common/qdbusmenumodel.cpp +++ b/src/common/qdbusmenumodel.cpp @@ -20,30 +20,76 @@ #include "qdbusmenumodel.h" #include +/*! + \qmlclass QDBusMenuModel + \inherits QDBusObject + + \brief The QDBusMenuModel class defines the list model for DBus menus + + \bold {This component is under heavy development.} + + This class expose the menu previous exported over DBus. + + \code + QDBusMenuModel { + id: menuModel + busType: 1 + busName: "com.ubuntu.menu" + objectPath: "com/ubuntu/menu" + } + + ListView { + id: view + model: menuModel + Component.onCompleted: menuModel.start() + } + \endcode +*/ + +/*! \internal */ QDBusMenuModel::QDBusMenuModel(QObject *parent) :QMenuModel(0, parent) { } +/*! \internal */ QDBusMenuModel::~QDBusMenuModel() { } +/*! + \qmlmethod QDBusMenuModel::start() + + Start dbus watch for the busName and wait until it appears. + The status will change to connecting after call this function, and as soon the busName + apperas and the objectPat was found this will change to Connected. + + \bold Note: methods should only be called after the Component has completed. +*/ void QDBusMenuModel::start() { QDBusObject::connect(); } +/*! + \qmlmethod QDBusMenuModel::stop() + + Stops dbus watch and clear the model, the status wil change to Disconnected. + + \bold Note: methods should only be called after the Component has completed. +*/ void QDBusMenuModel::stop() { QDBusObject::disconnect(); } +/*! \internal */ void QDBusMenuModel::serviceVanish(GDBusConnection *) { setMenuModel(NULL); } +/*! \internal */ void QDBusMenuModel::serviceAppear(GDBusConnection *connection) { GMenuModel *model = reinterpret_cast(g_dbus_menu_model_get(connection, @@ -55,28 +101,7 @@ void QDBusMenuModel::serviceAppear(GDBusConnection *connection) } } -/* -void QDBusMenuModel::busTypeChanged(BusType) -{ - busTypeChanged(); -} - -void QDBusMenuModel::busNameChanged(const QString &) -{ - busNameChanged(); -} - -void QDBusMenuModel::objectPathChanged(const QString &objectPath) -{ - objectPathChanged(); -} - -void QDBusMenuModel::statusChanged(ConnectionStatus status) -{ - statusChanged(); -} -*/ - +/*! \internal */ void QDBusMenuModel::setIntBusType(int busType) { if ((busType > None) && (busType < LastBusType)) { diff --git a/src/common/qdbusmenumodel.h b/src/common/qdbusmenumodel.h index 14ac4a2..8308268 100644 --- a/src/common/qdbusmenumodel.h +++ b/src/common/qdbusmenumodel.h @@ -51,13 +51,6 @@ protected: virtual void serviceAppear(GDBusConnection *connection); virtual void serviceVanish(GDBusConnection *connection); - /* - virtual void busTypeChanged(BusType type); - virtual void busNameChanged(const QString &busNameChanged); - virtual void objectPathChanged(const QString &objectPath); - virtual void statusChanged(ConnectionStatus status); - */ - private: // workaround to support int as bustType void setIntBusType(int busType); diff --git a/src/common/qdbusobject.cpp b/src/common/qdbusobject.cpp index 174a9d8..d5ac44b 100644 --- a/src/common/qdbusobject.cpp +++ b/src/common/qdbusobject.cpp @@ -21,12 +21,58 @@ #include +/*! + \qmlclass QDBusObject + \brief The QDBusObject is a base class + + \bold {This component is under heavy development.} + + This is a abstracted class used by QDBusMenuModel and QDBusActionGroup +*/ + +/*! + \qmlproperty int QDBusObject::busType + This property holds the dbus session type which will be used during the connection. + + This must be seteed before call start method + The valid values are: + \list + \o 1 - SessionBus + \o 2 - SystemBus + \endlist +*/ + +/*! + \qmlproperty int QDBusObject::busName + This property holds the dbus service name related with menu. + + This must be seteed before call start method +*/ + +/*! + \qmlproperty int QDBusObject::objectPath + This property holds the dbus object path related with the menu. + + This must be seteed before call start method +*/ + +/*! + \qmlproperty int QDBusObject::status + This property holds current dbus connection status + + Te velid status are: + \list + \o 0 - Disconnected + \o 1 - Connecting + \o 2 - Connected + \endlist +*/ + QDBusObject::QDBusObject() :m_watchId(0), m_busType(None), m_status(QDBusObject::Disconnected) { - qDebug() << "DBUS CREATED"; qRegisterMetaType("QDBusObject::ConnectionStatus"); } @@ -128,7 +174,6 @@ void QDBusObject::disconnect() void QDBusObject::onServiceAppeared(GDBusConnection *connection, const gchar *, const gchar *, gpointer data) { QDBusObject *self = reinterpret_cast(data); - qDebug() << "service appear"; self->setStatus(QDBusObject::Connected); self->serviceAppear(connection); @@ -137,7 +182,6 @@ void QDBusObject::onServiceAppeared(GDBusConnection *connection, const gchar *, void QDBusObject::onServiceFanished(GDBusConnection *connection, const gchar *, gpointer data) { QDBusObject *self = reinterpret_cast(data); - qDebug() << "service disappear"; self->setStatus(QDBusObject::Connecting); self->serviceVanish(connection); diff --git a/src/common/qmenumodel.cpp b/src/common/qmenumodel.cpp index 230365c..ffb3fb6 100644 --- a/src/common/qmenumodel.cpp +++ b/src/common/qmenumodel.cpp @@ -18,9 +18,20 @@ */ #include "qmenumodel.h" +#include "converter.h" #include +/*! + \qmlclass QMenuModel + \brief The QMenuModel class implements the base list model for menus + + \bold {This component is under heavy development.} + + This is a abstracted class used by \l QDBusMenuModel. +*/ + +/*! \internal */ QMenuModel::QMenuModel(GMenuModel *other, QObject *parent) : QAbstractListModel(parent), m_menuModel(0), @@ -38,11 +49,13 @@ QMenuModel::QMenuModel(GMenuModel *other, QObject *parent) setMenuModel(other); } +/*! \internal */ QMenuModel::~QMenuModel() { setMenuModel(NULL); } +/*! \internal */ void QMenuModel::setMenuModel(GMenuModel *other) { if (m_menuModel == other) { @@ -71,17 +84,19 @@ void QMenuModel::setMenuModel(GMenuModel *other) endResetModel(); } +/*! \internal */ GMenuModel *QMenuModel::menuModel() const { return m_menuModel; } -/* QAbstractItemModel */ +/*! \internal */ int QMenuModel::columnCount(const QModelIndex &) const { return 1; } +/*! \internal */ QVariant QMenuModel::data(const QModelIndex &index, int role) const { QVariant attribute; @@ -113,11 +128,13 @@ QVariant QMenuModel::data(const QModelIndex &index, int role) const return attribute; } +/*! \internal */ QModelIndex QMenuModel::parent(const QModelIndex &index) const { return QModelIndex(); } +/*! \internal */ int QMenuModel::rowCount(const QModelIndex &) const { if (m_menuModel) { @@ -126,6 +143,7 @@ int QMenuModel::rowCount(const QModelIndex &) const return 0; } +/*! \internal */ QVariant QMenuModel::getStringAttribute(const QModelIndex &index, const QString &attribute) const { @@ -142,6 +160,7 @@ QVariant QMenuModel::getStringAttribute(const QModelIndex &index, return result; } +/*! \internal */ QVariant QMenuModel::getLink(const QModelIndex &index, const QString &linkName) const { @@ -159,6 +178,7 @@ QVariant QMenuModel::getLink(const QModelIndex &index, return QVariant(); } +/*! \internal */ QVariant QMenuModel::getExtraProperties(const QModelIndex &index) const { GMenuAttributeIter *iter = g_menu_model_iterate_item_attributes(m_menuModel, index.row()); @@ -171,14 +191,14 @@ QVariant QMenuModel::getExtraProperties(const QModelIndex &index) const GVariant *value = NULL; while (g_menu_attribute_iter_get_next (iter, &attrName, &value)) { if (strncmp("x-", attrName, 2) == 0) { - extra->setProperty(attrName, parseGVariant(value)); + extra->setProperty(attrName, Converter::parseGVariant(value)); } } return QVariant::fromValue(extra); } - +/*! \internal */ void QMenuModel::onItemsChanged(GMenuModel *, gint position, gint removed, @@ -198,60 +218,3 @@ void QMenuModel::onItemsChanged(GMenuModel *, } } -QVariant QMenuModel::parseGVariant(GVariant *value) -{ - QVariant result; - if (value == NULL) { - return result; - } - - const GVariantType *type = g_variant_get_type(value); - if (g_variant_type_equal(type, G_VARIANT_TYPE_BOOLEAN)) { - result.setValue((bool)g_variant_get_boolean(value)); - } else if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE)) { - result.setValue(g_variant_get_byte(value)); - } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16)) { - result.setValue(g_variant_get_int16(value)); - } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16)) { - result.setValue(g_variant_get_uint16(value)); - } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32)) { - result.setValue(g_variant_get_int32(value)); - } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32)) { - result.setValue(g_variant_get_uint32(value)); - } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64)) { - result.setValue(g_variant_get_int64(value)); - } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64)) { - result.setValue(g_variant_get_uint64(value)); - } else if (g_variant_type_equal(type, G_VARIANT_TYPE_DOUBLE)) { - result.setValue(g_variant_get_double(value)); - } else if (g_variant_type_equal(type, G_VARIANT_TYPE_STRING)) { - gsize size = 0; - const gchar *v = g_variant_get_string(value, &size); - result.setValue(QString::fromLatin1(v, size)); - } else { - qWarning() << "Unsupported GVariant value"; - } - - /* TODO: implement convertions to others types - * G_VARIANT_TYPE_HANDLE - * G_VARIANT_TYPE_OBJECT_PATH - * G_VARIANT_TYPE_SIGNATURE - * G_VARIANT_TYPE_VARIANT - * G_VARIANT_TYPE_ANY - * 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 - * G_VARIANT_TYPE_STRING_ARRAY - * G_VARIANT_TYPE_BYTESTRING - * G_VARIANT_TYPE_OBJECT_PATH_ARRAY - * G_VARIANT_TYPE_BYTESTRING_ARRAY - * G_VARIANT_TYPE_VARDICT - */ - - return result; -} - diff --git a/src/common/qmenumodel.h b/src/common/qmenumodel.h index e594ea7..e102f72 100644 --- a/src/common/qmenumodel.h +++ b/src/common/qmenumodel.h @@ -58,7 +58,6 @@ private: QVariant getExtraProperties(const QModelIndex &index) const; static void onItemsChanged(GMenuModel *model, gint position, gint removed, gint added, gpointer data); - static QVariant parseGVariant(GVariant *value); }; #endif diff --git a/tests/client/CMakeLists.txt b/tests/client/CMakeLists.txt index bf77461..473ebcd 100644 --- a/tests/client/CMakeLists.txt +++ b/tests/client/CMakeLists.txt @@ -44,3 +44,4 @@ endif() declare_test(servicetest) declare_test(menuchangestest) declare_test(modeltest) +declare_test(actiongrouptest) diff --git a/tests/script/dbusmenuscript.cpp b/tests/script/dbusmenuscript.cpp index baf5ac2..b190d5b 100644 --- a/tests/script/dbusmenuscript.cpp +++ b/tests/script/dbusmenuscript.cpp @@ -91,3 +91,16 @@ void DBusMenuScript::run() QTest::qWait(WAIT_TIMEOUT); } } + +QString DBusMenuScript::popActivatedAction() +{ + if (m_script) { + QDBusMessage reply = m_script->call("popActivatedAction"); + if (reply.arguments().count() > 0) { + return reply.arguments()[0].toString(); + } + } + + return QString(); +} + diff --git a/tests/script/dbusmenuscript.h b/tests/script/dbusmenuscript.h index 6e9532b..8a93e83 100644 --- a/tests/script/dbusmenuscript.h +++ b/tests/script/dbusmenuscript.h @@ -47,6 +47,8 @@ public: void publishMenu(); void unpublishMenu(); + QString popActivatedAction(); + private: QDBusInterface *m_script; }; diff --git a/tests/script/menuscript.py b/tests/script/menuscript.py index 05e226c..f50aacd 100644 --- a/tests/script/menuscript.py +++ b/tests/script/menuscript.py @@ -53,6 +53,11 @@ class Script(dbus.service.Object): self._list.walk() steps -= 1 + @dbus.service.method(dbus_interface=INTERFACE_NAME, + in_signature='', out_signature='s') + def popActivatedAction(self): + return self._list._activatedActions.pop(0) + @staticmethod def create(aList): global bus @@ -87,6 +92,12 @@ class Action(object): item = Gio.MenuItem.new(self._kargs['label'], self._kargs['actionName']) self.setProperties(item, self._kargs['properties']) parent.append_item(item) + + # Action + act = Gio.SimpleAction.new(self._kargs['actionName'], None) + act.connect('activate', self._list._onActionActivated) + self._list._rootAction.insert(act) + elif self._kargs['link'] == 'section': section = Gio.Menu() parent.append_section(self._kargs['label'], section) @@ -99,6 +110,9 @@ class Action(object): (menu, mId) = self._list.getMenu(menuId) if mId != -1: menu.remove(mId) + if self._kargs['actionName']: + # Remove action + self._list._rootAction.remove(self._kargs['actionName']) else: print "Remove menu item" @@ -111,11 +125,15 @@ class Action(object): class ActionList(object): def __init__(self, objectPath): self._actions = [] + self._actions_bk = [] self._objectPath = objectPath self._bux = None - self._exportID = None + self._exportMenuID = None + self._exportActionID = None self._ownNameID = None self._root = None + self._rootAction = None + self._activatedActions = [] def appendItem(self, label, actionName, link=None, parentId=None, properties=None): self._actions.append(Action(self, 'append', @@ -125,9 +143,20 @@ class ActionList(object): link=link, properties=properties)) - def removeItem(self, menuId): + def removeItem(self, menuId, actionName=None): self._actions.append(Action(self, 'remove', - menuId=menuId)) + menuId=menuId, + actionName=actionName)) + + def _save(self): + self._actions_bk = [] + self._actions_bk.extend(self._actions) + + + def _restore(self): + if len(self._actions_bk): + self._actions = [] + self._actions.extend(self._actions_bk) def _findMenu(self, root, ids): if len(ids) == 0: @@ -155,18 +184,28 @@ class ActionList(object): def _exportService(self, connection, name): self._root = Gio.Menu() + self._rootAction = Gio.SimpleActionGroup() self._bus = connection - self._exportID = connection.export_menu_model(MENU_OBJECT_PATH, self._root) + self._exportMenuID = connection.export_menu_model(MENU_OBJECT_PATH, self._root) + self._exportActionID = connection.export_action_group(MENU_OBJECT_PATH, self._rootAction) def start(self): + self._save() 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._exportMenuID: + self._bus.unexport_menu_model(self._exportMenuID) + self._exportMenuID = None + + if self._exportActionID: + self._bus.unexport_action_group(self._exportActionID) + self._exportActionID = None if self._ownNameID: Gio.bus_unown_name(self._ownNameID) self._ownNameID = None + self._restore() + def _onActionActivated(self, action, parameter): + self._activatedActions.append(action.get_name()) -- cgit v1.2.3