on a4713ff help sign in
unity8/plugins/IndicatorsClient/indicators/common/indicatorclient_common.cpp
317 lines 8.8 kB history raw
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
18 */
20#include "indicatorclient_common.h"
22#include <QUrl>
23#include <QtPlugin>
24#include <QResource>
25#include <QDebug>
26#include <QFileInfo>
27#include <QDir>
28#include <QQmlEngine>
29#include <QQmlContext>
30#include <QJsonObject>
32#include <qdbusmenumodel.h>
33#include <qdbusactiongroup.h>
34#include <qstateaction.h>
36//TODO: load this property dynamically
37#define TARGET_DEVICE "phone"
39IndicatorClientCommon::IndicatorClientCommon(QObject *parent)
40 : QObject(parent),
41 m_icon(""),
42 m_visible(false),
43 m_priority(0),
44 m_model(0),
45 m_actionGroup(0),
46 m_action(0),
47 m_component(0)
51IndicatorClientCommon::~IndicatorClientCommon()
53 shutdown();
56void IndicatorClientCommon::init(const QSettings& settings)
58 Q_INIT_RESOURCE(indicatorclient_common);
60 setId(settings.value("Indicator Service/Name").toString());
61 QString dbusService = settings.value("Indicator Service/DBusName").toString();
62 QString objectPath = settings.value("Indicator Service/ObjectPath").toString();
64 m_model = new QDBusMenuModel(this);
65 m_model->setBusName(dbusService);
66 m_model->setObjectPath(objectPath + "/" + TARGET_DEVICE);
67 m_model->setBusType(DBusEnums::SessionBus);
69 //keep track of any change in the model
70 connect(m_model, SIGNAL(statusChanged(DBusEnums::ConnectionStatus)), SLOT(onModelChanged()));
71 connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(onModelChanged()));
72 connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(onModelChanged()));
73 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(onModelChanged()));
75 m_actionGroup = new QDBusActionGroup(this);
76 m_actionGroup->setBusType(m_model->busType());
77 m_actionGroup->setBusName(m_model->busName());
78 m_actionGroup->setObjectPath(objectPath);
80 m_initialProperties.clear();
81 m_initialProperties.insert("title", m_title);
82 m_initialProperties.insert("busType", 1);
83 m_initialProperties.insert("busName", dbusService);
84 m_initialProperties.insert("objectPath", objectPath);
86 m_actionGroup->start();
87 m_model->start();
90void IndicatorClientCommon::onModelChanged()
92 DBusEnums::ConnectionStatus status = m_model->status();
94 if (status == DBusEnums::Connected) {
95 QModelIndex index = m_model->index(0);
96 if (index.isValid()) {
97 QVariant extra = m_model->data(index, QDBusMenuModel::Extra);
98 QVariantMap extraMap = extra.toMap();
99 if (extraMap.contains("canonical_type")) {
100 QString type = extraMap["canonical_type"].toString();
101 parseRootElement(type, m_model->itemData(index));
102 }
103 }
104 } else {
105 parseRootElement("", QMap<int, QVariant>());
106 }
109bool IndicatorClientCommon::parseRootElement(const QString &type, QMap<int, QVariant> data)
111 if (type.isEmpty()) {
112 return false;
113 } else if (type != "com.canonical.indicator.root") {
114 if (!type.startsWith("com.canonical.indicator.root")) {
115 qWarning() << "indicator" << title() << "does not support root element";
116 }
117 return false;
118 } else {
119 if (m_action != 0) {
120 delete m_action;
121 }
123 QVariant action = data[QDBusMenuModel::Action];
124 m_action = m_actionGroup->action(action.toString());
126 if (m_action->isValid()) {
127 updateState(m_action->state());
128 }
129 QObject::connect(m_action, SIGNAL(stateChanged(QVariant)), this, SLOT(updateState(QVariant)));
130 return true;
131 }
134void IndicatorClientCommon::updateState(const QVariant &state)
136 if (state.isValid()) {
137 // (sssb) : the current label, icon name, accessible name, and visibility state of the indicator.
138 QVariantList states = state.toList();
139 if (states.size() == 4) {
140 setLabel(states[0].toString());
141 setIcon(QUrl(states[1].toString()));
142 setVisible(states[2].toBool());
143 setAccessibleName(states[3].toString());
144 return;
145 }
146 }
148 setLabel("");
149 setIcon(QUrl());
150 setVisible(false);
151 setAccessibleName("");
154void IndicatorClientCommon::shutdown()
156 delete m_component;
157 m_component = 0;
159 delete m_model;
160 m_model = 0;
162 delete m_action;
163 m_action = 0;
165 delete m_actionGroup;
166 m_actionGroup = 0;
169QString IndicatorClientCommon::identifier() const
171 return m_identifier;
174void IndicatorClientCommon::setId(const QString &identifier)
176 if (identifier != m_identifier) {
177 m_identifier = identifier;
178 Q_EMIT identifierChanged(m_identifier);
179 }
182QUrl IndicatorClientCommon::icon() const
184 if (!m_icon.isEmpty() && m_icon.scheme().isEmpty()) {
185 return QString("image://gicon/") + QUrl::toPercentEncoding(m_icon.toString());
186 } else {
187 return m_icon;
188 }
191void IndicatorClientCommon::setIcon(const QUrl &icon)
193 if (icon != m_icon) {
194 m_icon = icon;
195 Q_EMIT iconChanged(m_icon);
196 }
199QString IndicatorClientCommon::title() const
201 return m_title;
204void IndicatorClientCommon::setTitle(const QString &title)
206 if (title != m_title) {
207 m_title = title;
208 Q_EMIT titleChanged(m_title);
209 }
212QString IndicatorClientCommon::description() const
214 return m_description;
217void IndicatorClientCommon::setDescription(const QString &description)
219 if (description != m_description) {
220 m_description = description;
221 Q_EMIT titleChanged(m_description);
222 }
225int IndicatorClientCommon::priority() const
227 return m_priority;
230void IndicatorClientCommon::setPriority(int priority)
232 if (priority != m_priority) {
233 m_priority = priority;
234 Q_EMIT priorityChanged(m_priority);
235 }
238QString IndicatorClientCommon::accessibleName() const
240 return m_accessibleName;
243void IndicatorClientCommon::setAccessibleName(const QString &accesibleName)
245 if (accesibleName != m_accessibleName) {
246 m_accessibleName = accesibleName;
247 Q_EMIT accessibleNameChanged(m_accessibleName);
248 }
251bool IndicatorClientCommon::visible() const
253 return m_visible;
256void IndicatorClientCommon::setVisible(bool visible)
258 if (visible != m_visible) {
259 m_visible = visible;
260 Q_EMIT visibleChanged(m_visible);
261 }
264QString IndicatorClientCommon::label() const
266 return m_label;
269void IndicatorClientCommon::setLabel(const QString &label)
271 if (label != m_label) {
272 m_label = label;
273 Q_EMIT labelChanged(m_label);
274 }
277QDBusActionGroup *IndicatorClientCommon::actionGroup() const
279 return m_actionGroup;
282QQmlComponent *IndicatorClientCommon::createComponent(QQmlEngine *engine, QObject *parent) const
284 return new QQmlComponent(engine, QUrl("qrc:/indicatorsclient/qml/commonplugin.qml"), parent);
287QQmlComponent *IndicatorClientCommon::component(QQmlEngine *engine, QObject *parent)
289 if (m_component == 0) {
290 m_component = createComponent(engine, parent);
291 }
292 return m_component;
295IndicatorClientInterface::PropertiesMap IndicatorClientCommon::initialProperties()
297 return m_initialProperties;
300IndicatorClientInterface::WidgetsMap IndicatorClientCommon::widgets()
302 // Register all basic/native widgets
303 static WidgetsMap w;
304 if (w.isEmpty()) {
305 //TODO: use a generic name for volumecontrol widget (Slider)
306 w.insert("unity.widgets.systemsettings.tablet.volumecontrol", QUrl("SliderMenu.qml"));
307 w.insert("unity.widgets.systemsettings.tablet.switch", QUrl("SwitchMenu.qml"));
309 w.insert("com.canonical.indicator.button", QUrl("ButtonMenu.qml"));
310 w.insert("com.canonical.indicator.div", QUrl("DivMenu.qml"));
311 w.insert("com.canonical.indicator.section", QUrl("MenuSection.qml"));
312 w.insert("com.canonical.indicator.progress", QUrl("ProgressMenu.qml"));
313 w.insert("com.canonical.indicator.slider", QUrl("SliderMenu.qml"));
314 w.insert("com.canonical.indicator.switch", QUrl("SwitchMenu.qml"));
315 }
316 return w;