on 4c4b83e help sign in
unity8/plugins/IndicatorsClient/indicators/common/indicatorclient_common.cpp
303 lines 8.5 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 QString dbusService = settings.value("Indicator Service/DBusName").toString();
61 QString objectPath = settings.value("Indicator Service/ObjectPath").toString();
63 m_model = new QDBusMenuModel(this);
64 m_model->setBusName(dbusService);
65 m_model->setObjectPath(objectPath + "/" + TARGET_DEVICE);
66 m_model->setBusType(DBusEnums::SessionBus);
68 //keep track of any change in the model
69 connect(m_model, SIGNAL(statusChanged(DBusEnums::ConnectionStatus)), SLOT(onModelChanged()));
70 connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(onModelChanged()));
71 connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(onModelChanged()));
72 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(onModelChanged()));
74 m_actionGroup = new QDBusActionGroup(this);
75 m_actionGroup->setBusType(m_model->busType());
76 m_actionGroup->setBusName(m_model->busName());
77 m_actionGroup->setObjectPath(objectPath);
79 m_initialProperties.clear();
80 m_initialProperties.insert("title", m_title);
81 m_initialProperties.insert("busType", 1);
82 m_initialProperties.insert("busName", dbusService);
83 m_initialProperties.insert("objectPath", objectPath);
85 m_actionGroup->start();
86 m_model->start();
89void IndicatorClientCommon::onModelChanged()
91 DBusEnums::ConnectionStatus status = m_model->status();
93 if (status == DBusEnums::Connected) {
94 QModelIndex index = m_model->index(0);
95 if (index.isValid()) {
96 QVariant extra = m_model->data(index, QDBusMenuModel::Extra);
97 QVariantMap extraMap = extra.toMap();
98 if (extraMap.contains("canonical_type")) {
99 QString type = extraMap["canonical_type"].toString();
100 parseRootElement(type, m_model->itemData(index));
101 }
102 }
103 } else {
104 parseRootElement("", QMap<int, QVariant>());
105 }
108bool IndicatorClientCommon::parseRootElement(const QString &type, QMap<int, QVariant> data)
110 if (type.isEmpty()) {
111 return false;
112 } else if (type != "com.canonical.indicator.root") {
113 if (!type.startsWith("com.canonical.indicator.root")) {
114 qWarning() << "indicator" << title() << "does not support root element";
115 }
116 return false;
117 } else {
118 if (m_action != 0) {
119 delete m_action;
120 }
122 QVariant action = data[QDBusMenuModel::Action];
123 m_action = m_actionGroup->action(action.toString());
125 if (m_action->isValid()) {
126 updateState(m_action->state());
127 }
128 QObject::connect(m_action, SIGNAL(stateChanged(QVariant)), this, SLOT(updateState(QVariant)));
129 return true;
130 }
133void IndicatorClientCommon::updateState(const QVariant &state)
135 if (state.isValid()) {
136 // (sssb) : the current label, icon name, accessible name, and visibility state of the indicator.
137 QVariantList states = state.toList();
138 if (states.size() == 4) {
139 setLabel(states[0].toString());
140 setIcon(QUrl(states[1].toString()));
141 setVisible(states[2].toBool());
142 setAccessibleName(states[3].toString());
143 return;
144 }
145 }
147 setLabel("");
148 setIcon(QUrl());
149 setVisible(false);
150 setAccessibleName("");
153void IndicatorClientCommon::shutdown()
155 delete m_component;
156 m_component = 0;
158 delete m_model;
159 m_model = 0;
161 delete m_action;
162 m_action = 0;
164 delete m_actionGroup;
165 m_actionGroup = 0;
168QUrl IndicatorClientCommon::icon() const
170 if (!m_icon.isEmpty() && m_icon.scheme().isEmpty()) {
171 return QString("image://gicon/") + QUrl::toPercentEncoding(m_icon.toString());
172 } else {
173 return m_icon;
174 }
177void IndicatorClientCommon::setIcon(const QUrl &icon)
179 if (icon != m_icon) {
180 m_icon = icon;
181 Q_EMIT iconChanged(m_icon);
182 }
185QString IndicatorClientCommon::title() const
187 return m_title;
190void IndicatorClientCommon::setTitle(const QString &title)
192 if (title != m_title) {
193 m_title = title;
194 Q_EMIT titleChanged(m_title);
195 }
198QString IndicatorClientCommon::description() const
200 return m_description;
203void IndicatorClientCommon::setDescription(const QString &description)
205 if (description != m_description) {
206 m_description = description;
207 Q_EMIT titleChanged(m_description);
208 }
211int IndicatorClientCommon::priority() const
213 return m_priority;
216void IndicatorClientCommon::setPriority(int priority)
218 if (priority != m_priority) {
219 m_priority = priority;
220 Q_EMIT priorityChanged(m_priority);
221 }
224QString IndicatorClientCommon::accessibleName() const
226 return m_accessibleName;
229void IndicatorClientCommon::setAccessibleName(const QString &accesibleName)
231 if (accesibleName != m_accessibleName) {
232 m_accessibleName = accesibleName;
233 Q_EMIT accessibleNameChanged(m_accessibleName);
234 }
237bool IndicatorClientCommon::visible() const
239 return m_visible;
242void IndicatorClientCommon::setVisible(bool visible)
244 if (visible != m_visible) {
245 m_visible = visible;
246 Q_EMIT visibleChanged(m_visible);
247 }
250QString IndicatorClientCommon::label() const
252 return m_label;
255void IndicatorClientCommon::setLabel(const QString &label)
257 if (label != m_label) {
258 m_label = label;
259 Q_EMIT labelChanged(m_label);
260 }
263QDBusActionGroup *IndicatorClientCommon::actionGroup() const
265 return m_actionGroup;
268QQmlComponent *IndicatorClientCommon::createComponent(QQmlEngine *engine, QObject *parent) const
270 return new QQmlComponent(engine, QUrl("qrc:/indicatorsclient/qml/commonplugin.qml"), parent);
273QQmlComponent *IndicatorClientCommon::component(QQmlEngine *engine, QObject *parent)
275 if (m_component == 0) {
276 m_component = createComponent(engine, parent);
277 }
278 return m_component;
281IndicatorClientInterface::PropertiesMap IndicatorClientCommon::initialProperties()
283 return m_initialProperties;
286IndicatorClientInterface::WidgetsMap IndicatorClientCommon::widgets()
288 // Register all basic/native widgets
289 static WidgetsMap w;
290 if (w.isEmpty()) {
291 //TODO: use a generic name for volumecontrol widget (Slider)
292 w.insert("unity.widgets.systemsettings.tablet.volumecontrol", QUrl("SliderMenu.qml"));
293 w.insert("unity.widgets.systemsettings.tablet.switch", QUrl("SwitchMenu.qml"));
295 w.insert("com.canonical.indicator.button", QUrl("ButtonMenu.qml"));
296 w.insert("com.canonical.indicator.div", QUrl("DivMenu.qml"));
297 w.insert("com.canonical.indicator.section", QUrl("MenuSection.qml"));
298 w.insert("com.canonical.indicator.progress", QUrl("ProgressMenu.qml"));
299 w.insert("com.canonical.indicator.slider", QUrl("SliderMenu.qml"));
300 w.insert("com.canonical.indicator.switch", QUrl("SwitchMenu.qml"));
301 }
302 return w;