aboutsummaryrefslogtreecommitdiff
path: root/libqmenumodel/src/qdbusactiongroup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libqmenumodel/src/qdbusactiongroup.cpp')
-rw-r--r--libqmenumodel/src/qdbusactiongroup.cpp232
1 files changed, 232 insertions, 0 deletions
diff --git a/libqmenumodel/src/qdbusactiongroup.cpp b/libqmenumodel/src/qdbusactiongroup.cpp
new file mode 100644
index 0000000..5a9e0bd
--- /dev/null
+++ b/libqmenumodel/src/qdbusactiongroup.cpp
@@ -0,0 +1,232 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Renato Araujo Oliveira Filho <renato@canonical.com>
+ */
+
+#include "qdbusactiongroup.h"
+#include "qstateaction.h"
+#include "converter.h"
+
+extern "C" {
+#include <gio/gio.h>
+}
+
+/*!
+ \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();
+}
+
+/*!
+ \qmlmethod QDBusActionGroup::action(QString name)
+
+ Look for a action with the same name and return a \l QStateAction object.
+
+ \bold Note: methods should only be called after the Component has completed.
+*/
+QStateAction *QDBusActionGroup::action(const QString &name)
+{
+ QStateAction *act = actionImpl(name);
+ if (act == 0) {
+ act = new QStateAction(this, name);
+ }
+
+ return act;
+}
+
+QVariant QDBusActionGroup::actionState(const QString &name)
+{
+ QVariant result;
+ GVariant *state = g_action_group_get_action_state(m_actionGroup, name.toLatin1());
+ result = Converter::toQVariant(state);
+ if (state) {
+ g_variant_unref(state);
+ }
+ return result;
+}
+
+
+bool QDBusActionGroup::hasAction(const QString &name)
+{
+ if (m_actionGroup) {
+ return g_action_group_has_action(m_actionGroup, name.toLatin1());
+ } else {
+ return false;
+ }
+}
+
+QStateAction *QDBusActionGroup::actionImpl(const QString &name)
+{
+ Q_FOREACH(QStateAction *act, this->findChildren<QStateAction*>()) {
+ if (act->text() == name) {
+ return act;
+ }
+ }
+ return 0;
+}
+
+/*! \internal */
+void QDBusActionGroup::serviceVanish(GDBusConnection *)
+{
+ setActionGroup(NULL);
+}
+
+/*! \internal */
+void QDBusActionGroup::serviceAppear(GDBusConnection *connection)
+{
+ GDBusActionGroup *ag = g_dbus_action_group_get(connection,
+ busName().toLatin1(),
+ objectPath().toLatin1());
+ setActionGroup(ag);
+ if (ag == NULL) {
+ stop();
+ }
+}
+
+/*! \internal */
+void QDBusActionGroup::start()
+{
+ QDBusObject::connect();
+}
+
+/*! \internal */
+void QDBusActionGroup::stop()
+{
+ QDBusObject::disconnect();
+}
+
+/*! \internal */
+void QDBusActionGroup::setIntBusType(int busType)
+{
+ if ((busType > DBusEnums::None) && (busType < DBusEnums::LastBusType)) {
+ setBusType(static_cast<DBusEnums::BusType>(busType));
+ }
+}
+
+/*! \internal */
+void QDBusActionGroup::setActionGroup(GDBusActionGroup *ag)
+{
+ if (m_actionGroup == reinterpret_cast<GActionGroup*>(ag)) {
+ return;
+ }
+
+ if (m_actionGroup) {
+ g_signal_handler_disconnect(m_actionGroup, m_signalActionAddId);
+ g_signal_handler_disconnect(m_actionGroup, m_signalActionRemovedId);
+ g_signal_handler_disconnect(m_actionGroup, m_signalStateChangedId);
+ m_signalActionAddId = m_signalActionRemovedId = m_signalStateChangedId = 0;
+ clear();
+ }
+
+ m_actionGroup = reinterpret_cast<GActionGroup*>(ag);
+
+ if (m_actionGroup) {
+ m_signalActionAddId = g_signal_connect(m_actionGroup,
+ "action-added",
+ G_CALLBACK(QDBusActionGroup::onActionAdded),
+ this);
+
+ m_signalActionRemovedId = g_signal_connect(m_actionGroup,
+ "action-removed",
+ G_CALLBACK(QDBusActionGroup::onActionRemoved),
+ this);
+
+ m_signalStateChangedId = g_signal_connect(m_actionGroup,
+ "action-state-changed",
+ G_CALLBACK(QDBusActionGroup::onActionStateChanged),
+ this);
+
+ gchar **actions = g_action_group_list_actions(m_actionGroup);
+ for(guint i=0; i < g_strv_length(actions); i++) {
+ Q_EMIT actionAppear(actions[i]);
+ }
+ g_strfreev(actions);
+ }
+}
+
+/*! \internal */
+void QDBusActionGroup::clear()
+{
+ Q_FOREACH(QStateAction *act, this->findChildren<QStateAction*>()) {
+ Q_EMIT actionVanish(act->text());
+ }
+
+ if (m_actionGroup != NULL) {
+ g_object_unref(m_actionGroup);
+ m_actionGroup = NULL;
+ }
+}
+
+/*! \internal */
+void QDBusActionGroup::updateActionState(const QString &name, const QVariant &state)
+{
+ if (m_actionGroup != NULL) {
+ g_action_group_activate_action(m_actionGroup, name.toLatin1(), Converter::toGVariant(state));
+ }
+}
+
+/*! \internal */
+void QDBusActionGroup::onActionAdded(GDBusActionGroup *, gchar *name, gpointer data)
+{
+ QDBusActionGroup *self = reinterpret_cast<QDBusActionGroup*>(data);
+ Q_EMIT self->actionAppear(name);
+}
+
+/*! \internal */
+void QDBusActionGroup::onActionRemoved(GDBusActionGroup *, gchar *name, gpointer data)
+{
+ QDBusActionGroup *self = reinterpret_cast<QDBusActionGroup*>(data);
+ Q_EMIT self->actionVanish(name);
+}
+
+/*! \internal */
+void QDBusActionGroup::onActionStateChanged(GDBusActionGroup *, gchar *name, GVariant *value, gpointer data)
+{
+ QDBusActionGroup *self = reinterpret_cast<QDBusActionGroup*>(data);
+ Q_EMIT self->actionStateChanged(name, Converter::toQVariant(value));
+}