Merge lp:~nick-dedekind/unity8/rtm-1385331 into lp:unity8/rtm-14.09

Proposed by Michał Sawicz
Status: Merged
Approved by: Michael Zanetti
Approved revision: 1432
Merged at revision: 1414
Proposed branch: lp:~nick-dedekind/unity8/rtm-1385331
Merge into: lp:unity8/rtm-14.09
Prerequisite: lp:~unity-team/unity8/rtm-20150113
Diff against target: 1841 lines (+1038/-301)
33 files modified
debian/control (+3/-3)
plugins/Lights/Lights.cpp (+9/-24)
plugins/Unity/Indicators/CMakeLists.txt (+3/-1)
plugins/Unity/Indicators/actionrootstate.cpp (+97/-0)
plugins/Unity/Indicators/actionrootstate.h (+55/-0)
plugins/Unity/Indicators/modelactionrootstate.cpp (+127/-0)
plugins/Unity/Indicators/modelactionrootstate.h (+61/-0)
plugins/Unity/Indicators/plugin.cpp (+4/-2)
plugins/Unity/Indicators/rootstateparser.cpp (+75/-142)
plugins/Unity/Indicators/rootstateparser.h (+20/-36)
qml/Greeter/Clock.qml (+1/-1)
qml/Panel/IndicatorItem.qml (+0/-8)
qml/Panel/Indicators/IndicatorBase.qml (+1/-1)
qml/Panel/Indicators/IndicatorsLight.qml (+19/-1)
qml/Panel/IndicatorsBar.qml (+29/-20)
qml/Panel/IndicatorsMenu.qml (+5/-0)
tests/mocks/CMakeLists.txt (+1/-0)
tests/mocks/Lights/CMakeLists.txt (+8/-0)
tests/mocks/Lights/Lights.cpp (+84/-0)
tests/mocks/Lights/Lights.h (+66/-0)
tests/mocks/Lights/plugin.cpp (+33/-0)
tests/mocks/Lights/plugin.h (+32/-0)
tests/mocks/Lights/qmldir (+3/-0)
tests/mocks/QMenuModel/CMakeLists.txt (+1/-0)
tests/mocks/QMenuModel/QDBusActionGroup.qml (+7/-57)
tests/mocks/QMenuModel/actiondata.h (+52/-0)
tests/mocks/QMenuModel/plugin.cpp (+10/-0)
tests/mocks/Unity/Indicators/ActionRootState.qml (+46/-0)
tests/mocks/Unity/Indicators/qmldir (+2/-1)
tests/plugins/Unity/Indicators/rootactionstatetest.cpp (+4/-4)
tests/qmltests/CMakeLists.txt (+1/-0)
tests/qmltests/Panel/Indicators/tst_IndicatorsLight.qml (+129/-0)
tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml (+50/-0)
To merge this branch: bzr merge lp:~nick-dedekind/unity8/rtm-1385331
Reviewer Review Type Date Requested Status
Michael Zanetti (community) Approve
Michał Sawicz Needs Fixing
Review via email: mp+246403@code.launchpad.net

Commit message

Unhook Lights interface from indicator widgets
Approved by: Albert Astals Cid

Description of the change

Led fix

To post a comment you must log in.
Revision history for this message
Michał Sawicz (saviq) wrote :

Hey, this caused a FTBFS:

unity8-8.02+15.04.20150114~rtm/plugins/Unity/Indicators/plugin.cpp:34:29: fatal error: rootactionstate.h: No such file or directory
 #include "rootactionstate.h"
                             ^
compilation terminated.

review: Needs Fixing
lp:~nick-dedekind/unity8/rtm-1385331 updated
1428. By Nick Dedekind

removed old file

1429. By Nick Dedekind

removed multiple new lines

Revision history for this message
Michał Sawicz (saviq) wrote :

:(

file:///usr/share/unity8/Shell.qml:685:9: Type Panel unavailable
             Panel {
             ^
file:///usr/share/unity8/Panel/Panel.qml:116:9: Type IndicatorsMenu unavailable
             IndicatorsMenu {
             ^
file:///usr/share/unity8/Panel/IndicatorsMenu.qml:63:5: IndicatorsLight is not a type
         IndicatorsLight {
         ^

review: Needs Fixing
lp:~nick-dedekind/unity8/rtm-1385331 updated
1430. By Nick Dedekind

merged parent

1431. By Nick Dedekind

added import

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> :(
>
> file:///usr/share/unity8/Shell.qml:685:9: Type Panel unavailable
> Panel {
> ^
> file:///usr/share/unity8/Panel/Panel.qml:116:9: Type IndicatorsMenu
> unavailable
> IndicatorsMenu {
> ^
> file:///usr/share/unity8/Panel/IndicatorsMenu.qml:63:5: IndicatorsLight is not
> a type
> IndicatorsLight {
> ^

Fixed.

Revision history for this message
Michael Zanetti (mzanetti) wrote :

This seems to break the panel: http://i.imgur.com/8ASuvJE.png?1

lp:~nick-dedekind/unity8/rtm-1385331 updated
1432. By Nick Dedekind

fixes for indicators

Revision history for this message
Michael Zanetti (mzanetti) wrote :

seems to work fine now.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2015-01-08 12:51:33 +0000
3+++ debian/control 2015-01-19 17:39:20 +0000
4@@ -23,7 +23,7 @@
5 libpam0g-dev,
6 libpay2-dev,
7 libpulse-dev,
8- libqmenumodel-dev (>= 0.2.8),
9+ libqmenumodel-dev (>= 0.2.9),
10 libqt5xmlpatterns5-dev,
11 libunity-api-dev (>= 7.94~),
12 libusermetricsoutput1-dev,
13@@ -59,7 +59,7 @@
14
15 Package: indicators-client
16 Architecture: amd64 armhf i386
17-Depends: qmenumodel-qml (>= 0.2.8),
18+Depends: qmenumodel-qml (>= 0.2.9),
19 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 0.1.49) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 0.1.49),
20 unity8 (= ${binary:Version}),
21 ${misc:Depends},
22@@ -83,7 +83,7 @@
23 Depends: gsettings-desktop-schemas,
24 libcap2-bin,
25 libglib2.0-bin,
26- qmenumodel-qml (>= 0.2.8),
27+ qmenumodel-qml (>= 0.2.9),
28 qml-module-qtquick-xmllistmodel,
29 qtdeclarative5-gsettings1.0,
30 qtdeclarative5-qtmir-plugin (>= 0.4.4),
31
32=== modified file 'plugins/Lights/Lights.cpp'
33--- plugins/Lights/Lights.cpp 2014-09-08 15:07:24 +0000
34+++ plugins/Lights/Lights.cpp 2015-01-19 17:39:20 +0000
35@@ -44,12 +44,20 @@
36
37 void Lights::setState(Lights::State newState)
38 {
39+ if (!init()) {
40+ qWarning() << "No lights device";
41+ return;
42+ }
43+
44 if (m_state != newState) {
45 if (newState == Lights::On) {
46 turnOn();
47 } else {
48 turnOff();
49 }
50+
51+ m_state = newState;
52+ Q_EMIT stateChanged(m_state);
53 }
54 }
55
56@@ -115,6 +123,7 @@
57 err = module->methods->open(module, LIGHT_ID_NOTIFICATIONS, &device);
58 if (err == 0) {
59 m_lightDevice = (light_device_t*)device;
60+ turnOff();
61 return true;
62 } else {
63 qWarning() << "Failed to access notification lights";
64@@ -127,15 +136,6 @@
65
66 void Lights::turnOn()
67 {
68- if (!init()) {
69- qWarning() << "No lights device";
70- return;
71- }
72-
73- if (m_state == Lights::On) {
74- return;
75- }
76-
77 // pulse
78 light_state_t state;
79 memset(&state, 0, sizeof(light_state_t));
80@@ -147,23 +147,11 @@
81
82 if (m_lightDevice->set_light(m_lightDevice, &state) != 0) {
83 qWarning() << "Failed to turn the light off";
84- } else {
85- m_state = Lights::On;
86- Q_EMIT stateChanged(m_state);
87 }
88 }
89
90 void Lights::turnOff()
91 {
92- if (!init()) {
93- qWarning() << "No lights device";
94- return;
95- }
96-
97- if (m_state == Lights::Off) {
98- return;
99- }
100-
101 light_state_t state;
102 memset(&state, 0, sizeof(light_state_t));
103 state.color = 0x00000000;
104@@ -174,8 +162,5 @@
105
106 if (m_lightDevice->set_light(m_lightDevice, &state) != 0) {
107 qWarning() << "Failed to turn the light off";
108- } else {
109- m_state = Lights::Off;
110- Q_EMIT stateChanged(m_state);
111 }
112 }
113
114=== modified file 'plugins/Unity/Indicators/CMakeLists.txt'
115--- plugins/Unity/Indicators/CMakeLists.txt 2014-10-03 10:53:02 +0000
116+++ plugins/Unity/Indicators/CMakeLists.txt 2015-01-19 17:39:20 +0000
117@@ -16,14 +16,16 @@
118 )
119
120 set(IndicatorsQML_SOURCES
121+ actionrootstate.cpp
122 indicator.cpp
123 indicators.h
124 indicatorsmanager.cpp
125 indicatorsmodel.cpp
126 menucontentactivator.cpp
127+ modelactionrootstate.cpp
128 modelprinter.cpp
129 plugin.cpp
130- rootactionstate.cpp
131+ rootstateparser.cpp
132 sharedunitymenumodel.cpp
133 unitymenumodelcache.cpp
134 unitymenumodelstack.cpp
135
136=== added file 'plugins/Unity/Indicators/actionrootstate.cpp'
137--- plugins/Unity/Indicators/actionrootstate.cpp 1970-01-01 00:00:00 +0000
138+++ plugins/Unity/Indicators/actionrootstate.cpp 2015-01-19 17:39:20 +0000
139@@ -0,0 +1,97 @@
140+/*
141+ * Copyright 2014 Canonical Ltd.
142+ *
143+ * This program is free software; you can redistribute it and/or modify
144+ * it under the terms of the GNU Lesser General Public License as published by
145+ * the Free Software Foundation; version 3.
146+ *
147+ * This program is distributed in the hope that it will be useful,
148+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
149+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
150+ * GNU Lesser General Public License for more details.
151+ *
152+ * You should have received a copy of the GNU Lesser General Public License
153+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
154+ */
155+
156+#include "actionrootstate.h"
157+
158+#include <qdbusactiongroup.h>
159+#include <QDebug>
160+
161+ActionRootState::ActionRootState(QObject *parent)
162+ : RootStateObject(parent)
163+ , m_actionGroup(nullptr)
164+{
165+}
166+
167+QDBusActionGroup *ActionRootState::actionGroup() const
168+{
169+ return m_actionGroup;
170+}
171+
172+void ActionRootState::setActionGroup(QDBusActionGroup *actionGroup)
173+{
174+ if (m_actionGroup != actionGroup) {
175+ bool wasValid = valid();
176+
177+ if (m_actionGroup) {
178+ disconnect(m_actionGroup, 0, this, 0);
179+ }
180+ m_actionGroup = actionGroup;
181+
182+ if (m_actionGroup) {
183+ connect(m_actionGroup, &QDBusActionGroup::statusChanged, this, [&](bool) { updateActionState(); });
184+ connect(m_actionGroup, &QDBusActionGroup::actionAppear, this, [&](const QString&) { updateActionState(); });
185+ connect(m_actionGroup, &QDBusActionGroup::actionVanish, this, [&](const QString&) { updateActionState(); });
186+ connect(m_actionGroup, &QDBusActionGroup::actionStateChanged, this, [&](QVariant) { updateActionState(); });
187+
188+ connect(m_actionGroup, &QObject::destroyed, this, [&](QObject*) { updateActionState(); });
189+ }
190+ updateActionState();
191+ Q_EMIT actionGroupChanged();
192+
193+ if (wasValid != valid()) Q_EMIT validChanged();
194+ }
195+}
196+
197+QString ActionRootState::actionName() const
198+{
199+ return m_actionName;
200+}
201+
202+void ActionRootState::setActionName(const QString &actionName)
203+{
204+ if (m_actionName != actionName) {
205+ bool wasValid = valid();
206+
207+ m_actionName = actionName;
208+ updateActionState();
209+
210+ Q_EMIT actionNameChanged();
211+
212+ if (wasValid != valid()) Q_EMIT validChanged();
213+ }
214+}
215+
216+bool ActionRootState::valid() const
217+{
218+ return m_actionGroup && m_actionGroup->status() == DBusEnums::Connected &&
219+ !m_actionName.isEmpty() && m_actionGroup->hasAction(m_actionName);
220+}
221+
222+void ActionRootState::updateActionState()
223+{
224+ if (valid()) {
225+ ActionStateParser* oldParser = m_actionGroup->actionStateParser();
226+ m_actionGroup->setActionStateParser(&m_parser);
227+
228+ QVariantMap state = m_actionGroup->actionState(m_actionName).toMap();
229+
230+ m_actionGroup->setActionStateParser(oldParser);
231+
232+ setCurrentState(state);
233+ } else {
234+ setCurrentState(QVariantMap());
235+ }
236+}
237
238=== added file 'plugins/Unity/Indicators/actionrootstate.h'
239--- plugins/Unity/Indicators/actionrootstate.h 1970-01-01 00:00:00 +0000
240+++ plugins/Unity/Indicators/actionrootstate.h 2015-01-19 17:39:20 +0000
241@@ -0,0 +1,55 @@
242+/*
243+ * Copyright 2014 Canonical Ltd.
244+ *
245+ * This program is free software; you can redistribute it and/or modify
246+ * it under the terms of the GNU Lesser General Public License as published by
247+ * the Free Software Foundation; version 3.
248+ *
249+ * This program is distributed in the hope that it will be useful,
250+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
251+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
252+ * GNU Lesser General Public License for more details.
253+ *
254+ * You should have received a copy of the GNU Lesser General Public License
255+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
256+ */
257+
258+#ifndef ACTIONROOTSTATE_H
259+#define ACTIONROOTSTATE_H
260+
261+#include "unityindicatorsglobal.h"
262+
263+#include "rootstateparser.h"
264+
265+class QDBusActionGroup;
266+
267+class UNITYINDICATORS_EXPORT ActionRootState : public RootStateObject
268+{
269+ Q_OBJECT
270+ Q_PROPERTY(QDBusActionGroup* actionGroup READ actionGroup WRITE setActionGroup NOTIFY actionGroupChanged)
271+ Q_PROPERTY(QString actionName READ actionName WRITE setActionName NOTIFY actionNameChanged)
272+
273+public:
274+ ActionRootState(QObject *parent = 0);
275+
276+ QDBusActionGroup *actionGroup() const;
277+ void setActionGroup(QDBusActionGroup *actionGroup);
278+
279+ QString actionName() const;
280+ void setActionName(const QString& actionName);
281+
282+ bool valid() const override;
283+
284+Q_SIGNALS:
285+ void actionGroupChanged();
286+ void actionNameChanged();
287+
288+private Q_SLOTS:
289+ void updateActionState();
290+
291+private:
292+ QDBusActionGroup* m_actionGroup;
293+ QString m_actionName;
294+};
295+
296+#endif // ACTIONROOTSTATE_H
297
298=== added file 'plugins/Unity/Indicators/modelactionrootstate.cpp'
299--- plugins/Unity/Indicators/modelactionrootstate.cpp 1970-01-01 00:00:00 +0000
300+++ plugins/Unity/Indicators/modelactionrootstate.cpp 2015-01-19 17:39:20 +0000
301@@ -0,0 +1,127 @@
302+/*
303+ * Copyright 2013 Canonical Ltd.
304+ *
305+ * This program is free software; you can redistribute it and/or modify
306+ * it under the terms of the GNU Lesser General Public License as published by
307+ * the Free Software Foundation; version 3.
308+ *
309+ * This program is distributed in the hope that it will be useful,
310+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
311+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
312+ * GNU Lesser General Public License for more details.
313+ *
314+ * You should have received a copy of the GNU Lesser General Public License
315+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
316+ *
317+ * Authors:
318+ * Nick Dedekind <nick.dedekind@canonical.com>
319+ */
320+
321+#include "modelactionrootstate.h"
322+#include "indicators.h"
323+
324+#include <unitymenumodel.h>
325+#include <QVariant>
326+#include <QIcon>
327+
328+extern "C" {
329+#include <glib.h>
330+#include <gio/gio.h>
331+}
332+
333+ModelActionRootState::ModelActionRootState(QObject *parent)
334+ : RootStateObject(parent),
335+ m_menu(nullptr)
336+{
337+}
338+
339+ModelActionRootState::~ModelActionRootState()
340+{
341+}
342+
343+UnityMenuModel* ModelActionRootState::menu() const
344+{
345+ return m_menu;
346+}
347+
348+void ModelActionRootState::setMenu(UnityMenuModel* menu)
349+{
350+ if (m_menu != menu) {
351+ bool wasValid = valid();
352+
353+ if (m_menu) {
354+ m_menu->disconnect(this);
355+ }
356+ m_menu = menu;
357+
358+ if (m_menu) {
359+ connect(m_menu, SIGNAL(rowsInserted(const QModelIndex&, int, int)), SLOT(onModelRowsAdded(const QModelIndex&, int, int)));
360+ connect(m_menu, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), SLOT(onModelRowsRemoved(const QModelIndex&, int, int)));
361+ connect(m_menu, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)), SLOT(onModelDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
362+
363+ connect(m_menu, SIGNAL(destroyed()), SLOT(reset()));
364+ }
365+ updateActionState();
366+ Q_EMIT menuChanged();
367+
368+ if (wasValid != valid())
369+ Q_EMIT validChanged();
370+ }
371+}
372+
373+bool ModelActionRootState::valid() const
374+{
375+ return m_menu && m_menu->rowCount() > 0;
376+}
377+
378+void ModelActionRootState::onModelRowsAdded(const QModelIndex& parent, int start, int end)
379+{
380+ Q_UNUSED(parent);
381+ if (start == 0 && end >= 0) {
382+ updateActionState();
383+ }
384+}
385+
386+void ModelActionRootState::onModelRowsRemoved(const QModelIndex& parent, int start, int end)
387+{
388+ Q_UNUSED(parent);
389+ if (start == 0 && end >= 0) {
390+ updateActionState();
391+ }
392+}
393+
394+void ModelActionRootState::onModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles)
395+{
396+ Q_UNUSED(roles);
397+ if (!topLeft.isValid() || !bottomRight.isValid()) {
398+ return;
399+ }
400+
401+ if (topLeft.row() <= 0 && bottomRight.row() >= 0) {
402+ updateActionState();
403+ }
404+}
405+
406+void ModelActionRootState::reset()
407+{
408+ m_menu = nullptr;
409+
410+ Q_EMIT menuChanged();
411+ setCurrentState(QVariantMap());
412+}
413+
414+void ModelActionRootState::updateActionState()
415+{
416+ if (m_menu && m_menu->rowCount() > 0) {
417+ ActionStateParser* oldParser = m_menu->actionStateParser();
418+ m_menu->setActionStateParser(&m_parser);
419+
420+ QVariantMap state = m_menu->get(0, "actionState").toMap();
421+
422+ m_menu->setActionStateParser(oldParser);
423+
424+ setCurrentState(state);
425+ } else {
426+ setCurrentState(QVariantMap());
427+ }
428+}
429
430=== added file 'plugins/Unity/Indicators/modelactionrootstate.h'
431--- plugins/Unity/Indicators/modelactionrootstate.h 1970-01-01 00:00:00 +0000
432+++ plugins/Unity/Indicators/modelactionrootstate.h 2015-01-19 17:39:20 +0000
433@@ -0,0 +1,61 @@
434+/*
435+ * Copyright 2013 Canonical Ltd.
436+ *
437+ * This program is free software; you can redistribute it and/or modify
438+ * it under the terms of the GNU Lesser General Public License as published by
439+ * the Free Software Foundation; version 3.
440+ *
441+ * This program is distributed in the hope that it will be useful,
442+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
443+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
444+ * GNU Lesser General Public License for more details.
445+ *
446+ * You should have received a copy of the GNU Lesser General Public License
447+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
448+ *
449+ * Authors:
450+ * Nick Dedekind <nick.dedekind@canonical.com>
451+ */
452+
453+#ifndef MODELACTIONROOTSTATE_H
454+#define MODELACTIONROOTSTATE_H
455+
456+#include "unityindicatorsglobal.h"
457+
458+#include "rootstateparser.h"
459+
460+class UnityMenuModel;
461+
462+class UNITYINDICATORS_EXPORT ModelActionRootState : public RootStateObject
463+{
464+ Q_OBJECT
465+ Q_PROPERTY(UnityMenuModel* menu READ menu WRITE setMenu NOTIFY menuChanged)
466+public:
467+ ModelActionRootState(QObject *parent = 0);
468+ virtual ~ModelActionRootState();
469+
470+ UnityMenuModel* menu() const;
471+ void setMenu(UnityMenuModel* menu);
472+
473+ int index() const;
474+ void setIndex(int index);
475+
476+ bool valid() const override;
477+
478+Q_SIGNALS:
479+ void menuChanged();
480+ void indexChanged();
481+
482+private Q_SLOTS:
483+ void onModelRowsAdded(const QModelIndex& parent, int start, int end);
484+ void onModelRowsRemoved(const QModelIndex& parent, int start, int end);
485+ void onModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>&);
486+ void reset();
487+
488+private:
489+ void updateActionState();
490+
491+ UnityMenuModel* m_menu;
492+};
493+
494+#endif // MODELACTIONROOTSTATE_H
495
496=== modified file 'plugins/Unity/Indicators/plugin.cpp'
497--- plugins/Unity/Indicators/plugin.cpp 2014-10-07 10:28:59 +0000
498+++ plugins/Unity/Indicators/plugin.cpp 2015-01-19 17:39:20 +0000
499@@ -24,12 +24,13 @@
500 #include "plugin.h"
501
502 // local
503+#include "actionrootstate.h"
504 #include "indicators.h"
505 #include "indicatorsmanager.h"
506 #include "indicatorsmodel.h"
507 #include "menucontentactivator.h"
508+#include "modelactionrootstate.h"
509 #include "modelprinter.h"
510-#include "rootactionstate.h"
511 #include "sharedunitymenumodel.h"
512 #include "unitymenumodelcache.h"
513 #include "unitymenumodelstack.h"
514@@ -51,7 +52,8 @@
515 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
516 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
517 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
518- qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
519+ qmlRegisterType<ModelActionRootState>(uri, 0, 1, "ModelActionRootState");
520+ qmlRegisterType<ActionRootState>(uri, 0, 1, "ActionRootState");
521 qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
522 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
523 qmlRegisterType<SharedUnityMenuModel>(uri, 0, 1, "SharedUnityMenuModel");
524
525=== renamed file 'plugins/Unity/Indicators/rootactionstate.cpp' => 'plugins/Unity/Indicators/rootstateparser.cpp'
526--- plugins/Unity/Indicators/rootactionstate.cpp 2014-10-20 12:38:16 +0000
527+++ plugins/Unity/Indicators/rootstateparser.cpp 2015-01-19 17:39:20 +0000
528@@ -12,155 +12,18 @@
529 *
530 * You should have received a copy of the GNU Lesser General Public License
531 * along with this program. If not, see <http://www.gnu.org/licenses/>.
532- *
533- * Authors:
534- * Nick Dedekind <nick.dedekind@canonical.com>
535 */
536
537-#include "rootactionstate.h"
538-#include "indicators.h"
539-
540-#include <unitymenumodel.h>
541-#include <QVariant>
542-#include <QIcon>
543+#include "rootstateparser.h"
544
545 extern "C" {
546 #include <glib.h>
547 #include <gio/gio.h>
548 }
549
550-RootActionState::RootActionState(QObject *parent)
551- : ActionStateParser(parent),
552- m_menu(nullptr)
553-{
554-}
555-
556-RootActionState::~RootActionState()
557-{
558-}
559-
560-UnityMenuModel* RootActionState::menu() const
561-{
562- return m_menu;
563-}
564-
565-void RootActionState::setMenu(UnityMenuModel* menu)
566-{
567- if (m_menu != menu) {
568- if (m_menu) {
569- m_menu->disconnect(this);
570- }
571- m_menu = menu;
572-
573- if (m_menu) {
574- connect(m_menu, SIGNAL(rowsInserted(const QModelIndex&, int, int)), SLOT(onModelRowsAdded(const QModelIndex&, int, int)));
575- connect(m_menu, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), SLOT(onModelRowsRemoved(const QModelIndex&, int, int)));
576- connect(m_menu, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)), SLOT(onModelDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
577-
578- connect(m_menu, SIGNAL(destroyed()), SLOT(reset()));
579- }
580- updateActionState();
581- Q_EMIT menuChanged();
582- }
583-}
584-
585-void RootActionState::onModelRowsAdded(const QModelIndex& parent, int start, int end)
586-{
587- Q_UNUSED(parent);
588- if (start == 0 && end >= 0) {
589- updateActionState();
590- }
591-}
592-
593-void RootActionState::onModelRowsRemoved(const QModelIndex& parent, int start, int end)
594-{
595- Q_UNUSED(parent);
596- if (start == 0 && end >= 0) {
597- updateActionState();
598- }
599-}
600-
601-void RootActionState::onModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles)
602-{
603- Q_UNUSED(roles);
604- if (!topLeft.isValid() || !bottomRight.isValid()) {
605- return;
606- }
607-
608- if (topLeft.row() <= 0 && bottomRight.row() >= 0) {
609- updateActionState();
610- }
611-}
612-
613-void RootActionState::reset()
614-{
615- m_cachedState.clear();
616- m_menu = nullptr;
617-
618- Q_EMIT menuChanged();
619- Q_EMIT updated();
620-}
621-
622-void RootActionState::updateActionState()
623-{
624- if (m_menu && m_menu->rowCount() > 0) {
625- ActionStateParser* oldParser = m_menu->actionStateParser();
626- m_menu->setActionStateParser(this);
627-
628- m_cachedState = m_menu->get(0, "actionState").toMap();
629-
630- m_menu->setActionStateParser(oldParser);
631- } else {
632- m_cachedState.clear();
633- }
634- Q_EMIT updated();
635-}
636-
637-bool RootActionState::isValid() const
638-{
639- return m_menu && m_menu->rowCount() > 0;
640-}
641-
642-QString RootActionState::title() const
643-{
644- if (!isValid()) return QString();
645-
646- return m_cachedState.value("title", QVariant::fromValue(QString())).toString();
647-}
648-
649-QString RootActionState::leftLabel() const
650-{
651- if (!isValid()) return QString();
652-
653- return m_cachedState.value("pre-label", QVariant::fromValue(QString())).toString();
654-}
655-
656-QString RootActionState::rightLabel() const
657-{
658- if (!isValid()) return QString();
659-
660- return m_cachedState.value("label", QVariant::fromValue(QString())).toString();
661-}
662-
663-QStringList RootActionState::icons() const
664-{
665- if (!isValid()) return QStringList();
666-
667- return m_cachedState.value("icons", QVariant::fromValue(QStringList())).toStringList();
668-}
669-
670-QString RootActionState::accessibleName() const
671-{
672- if (!isValid()) return QString();
673-
674- return m_cachedState.value("accessible-desc", QVariant::fromValue(QString())).toString();
675-}
676-
677-bool RootActionState::indicatorVisible() const
678-{
679- if (!isValid()) return false;
680-
681- return m_cachedState.value("visible", QVariant::fromValue(true)).toBool();
682+RootStateParser::RootStateParser(QObject* parent)
683+ : ActionStateParser(parent)
684+{
685 }
686
687 static QString iconUri(GIcon *icon)
688@@ -209,7 +72,7 @@
689 return uri;
690 }
691
692-QVariant RootActionState::toQVariant(GVariant* state) const
693+QVariant RootStateParser::toQVariant(GVariant* state) const
694 {
695 if (!state) {
696 return QVariant();
697@@ -296,3 +159,73 @@
698 }
699 return ActionStateParser::toQVariant(state);
700 }
701+
702+
703+RootStateObject::RootStateObject(QObject* parent)
704+ : QObject(parent)
705+{
706+}
707+
708+QString RootStateObject::title() const
709+{
710+ if (!valid()) return QString();
711+
712+ return m_currentState.value("title", QVariant::fromValue(QString())).toString();
713+}
714+
715+QString RootStateObject::leftLabel() const
716+{
717+ if (!valid()) return QString();
718+
719+ return m_currentState.value("pre-label", QVariant::fromValue(QString())).toString();
720+}
721+
722+QString RootStateObject::rightLabel() const
723+{
724+ if (!valid()) return QString();
725+
726+ return m_currentState.value("label", QVariant::fromValue(QString())).toString();
727+}
728+
729+QStringList RootStateObject::icons() const
730+{
731+ if (!valid()) return QStringList();
732+
733+ return m_currentState.value("icons", QVariant::fromValue(QStringList())).toStringList();
734+}
735+
736+QString RootStateObject::accessibleName() const
737+{
738+ if (!valid()) return QString();
739+
740+ return m_currentState.value("accessible-desc", QVariant::fromValue(QString())).toString();
741+}
742+
743+bool RootStateObject::indicatorVisible() const
744+{
745+ if (!valid()) return false;
746+
747+ return m_currentState.value("visible", QVariant::fromValue(true)).toBool();
748+}
749+
750+void RootStateObject::setCurrentState(const QVariantMap& newState)
751+{
752+ QString oldTitle = title();
753+ QString oldLeftLabel = leftLabel();
754+ QString oldRightLabel = rightLabel();
755+ QStringList oldIcons = icons();
756+ QString oldAccessibleName = accessibleName();
757+ bool oldIndicatorVisible = indicatorVisible();
758+
759+ if (m_currentState != newState) {
760+ m_currentState = newState;
761+ Q_EMIT updated();
762+
763+ if (oldTitle != title()) Q_EMIT titleChanged();
764+ if (oldLeftLabel != leftLabel()) Q_EMIT leftLabelChanged();
765+ if (oldRightLabel != rightLabel()) Q_EMIT rightLabelChanged();
766+ if (oldIcons != icons()) Q_EMIT iconsChanged();
767+ if (oldAccessibleName != accessibleName()) Q_EMIT accessibleNameChanged();
768+ if (oldIndicatorVisible != indicatorVisible()) Q_EMIT indicatorVisibleChanged();
769+ }
770+}
771
772=== renamed file 'plugins/Unity/Indicators/rootactionstate.h' => 'plugins/Unity/Indicators/rootstateparser.h'
773--- plugins/Unity/Indicators/rootactionstate.h 2014-10-20 12:38:16 +0000
774+++ plugins/Unity/Indicators/rootstateparser.h 2015-01-19 17:39:20 +0000
775@@ -12,26 +12,27 @@
776 *
777 * You should have received a copy of the GNU Lesser General Public License
778 * along with this program. If not, see <http://www.gnu.org/licenses/>.
779- *
780- * Authors:
781- * Nick Dedekind <nick.dedekind@canonical.com>
782 */
783
784-#ifndef ROOTACTIONSTATE_H
785-#define ROOTACTIONSTATE_H
786+#ifndef ROOTSTATEPARSER_H
787+#define ROOTSTATEPARSER_H
788
789 #include "unityindicatorsglobal.h"
790
791 #include <actionstateparser.h>
792
793-class UnityMenuModel;
794+class UNITYINDICATORS_EXPORT RootStateParser : public ActionStateParser
795+{
796+public:
797+ RootStateParser(QObject* parent = nullptr);
798+ virtual QVariant toQVariant(GVariant* state) const override;
799+};
800
801-class UNITYINDICATORS_EXPORT RootActionState : public ActionStateParser
802+class UNITYINDICATORS_EXPORT RootStateObject : public QObject
803 {
804 Q_OBJECT
805- Q_PROPERTY(UnityMenuModel* menu READ menu WRITE setMenu NOTIFY menuChanged)
806
807- Q_PROPERTY(bool valid READ isValid NOTIFY validChanged)
808+ Q_PROPERTY(bool valid READ valid NOTIFY validChanged)
809 Q_PROPERTY(QString title READ title NOTIFY titleChanged)
810 Q_PROPERTY(QString leftLabel READ leftLabel NOTIFY leftLabelChanged)
811 Q_PROPERTY(QString rightLabel READ rightLabel NOTIFY rightLabelChanged)
812@@ -39,16 +40,10 @@
813 Q_PROPERTY(QString accessibleName READ accessibleName NOTIFY accessibleNameChanged)
814 Q_PROPERTY(bool indicatorVisible READ indicatorVisible NOTIFY indicatorVisibleChanged)
815 public:
816- RootActionState(QObject *parent = 0);
817- virtual ~RootActionState();
818-
819- UnityMenuModel* menu() const;
820- void setMenu(UnityMenuModel* menu);
821-
822- int index() const;
823- void setIndex(int index);
824-
825- bool isValid() const;
826+ RootStateObject(QObject* parent = 0);
827+
828+ virtual bool valid() const = 0;
829+
830 QString title() const;
831 QString leftLabel() const;
832 QString rightLabel() const;
833@@ -56,15 +51,12 @@
834 QString accessibleName() const;
835 bool indicatorVisible() const;
836
837- // from ActionStateParser
838- virtual QVariant toQVariant(GVariant* state) const override;
839+ QVariantMap currentState() const { return m_currentState; }
840+ void setCurrentState(const QVariantMap& currentState);
841
842 Q_SIGNALS:
843 void updated();
844
845- void menuChanged();
846- void indexChanged();
847-
848 void validChanged();
849 void titleChanged();
850 void leftLabelChanged();
851@@ -73,17 +65,9 @@
852 void accessibleNameChanged();
853 void indicatorVisibleChanged();
854
855-private Q_SLOTS:
856- void onModelRowsAdded(const QModelIndex& parent, int start, int end);
857- void onModelRowsRemoved(const QModelIndex& parent, int start, int end);
858- void onModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>&);
859- void reset();
860-
861-private:
862- void updateActionState();
863-
864- UnityMenuModel* m_menu;
865- QVariantMap m_cachedState;
866+protected:
867+ RootStateParser m_parser;
868+ QVariantMap m_currentState;
869 };
870
871-#endif // ROOTACTIONSTATE_H
872+#endif // ROOTSTATEPARSER_H
873
874=== modified file 'qml/Greeter/Clock.qml'
875--- qml/Greeter/Clock.qml 2014-10-07 10:28:59 +0000
876+++ qml/Greeter/Clock.qml 2015-01-19 17:39:20 +0000
877@@ -43,7 +43,7 @@
878 menuObjectPath: clock.visible ? "/com/canonical/indicator/datetime/phone" : ""
879 }
880
881- Indicators.RootActionState {
882+ Indicators.ModelActionRootState {
883 menu: timeModel.model
884 onUpdated: {
885 if (timeLabel.text != rightLabel) {
886
887=== modified file 'qml/Panel/IndicatorItem.qml'
888--- qml/Panel/IndicatorItem.qml 2014-10-17 14:55:35 +0000
889+++ qml/Panel/IndicatorItem.qml 2015-01-19 17:39:20 +0000
890@@ -45,14 +45,6 @@
891 onClicked: parent.clicked()
892 }
893
894- // FIXME: For now we will enable led indicator support only for messaging indicator
895- // in the future we should export a led API insted of doing that,
896- Loader {
897- id: indicatorLed
898- // only load source Component if the icons contains the new message icon
899- source: (root.icons && (String(root.icons).indexOf("indicator-messages-new") != -1)) ? Qt.resolvedUrl("Indicators/IndicatorsLight.qml") : ""
900- }
901-
902 Item {
903 id: mainItems
904 anchors.centerIn: parent
905
906=== modified file 'qml/Panel/Indicators/IndicatorBase.qml'
907--- qml/Panel/Indicators/IndicatorBase.qml 2014-10-17 14:55:35 +0000
908+++ qml/Panel/Indicators/IndicatorBase.qml 2015-01-19 17:39:20 +0000
909@@ -40,7 +40,7 @@
910 menuObjectPath: indicatorItem.menuObjectPath
911 }
912
913- RootActionState {
914+ ModelActionRootState {
915 id: rootAction
916 menu: menuModel ? menuModel : null
917 onUpdated: indicatorItem.rootActionStateChanged()
918
919=== modified file 'qml/Panel/Indicators/IndicatorsLight.qml'
920--- qml/Panel/Indicators/IndicatorsLight.qml 2014-08-05 14:31:12 +0000
921+++ qml/Panel/Indicators/IndicatorsLight.qml 2015-01-19 17:39:20 +0000
922@@ -20,16 +20,34 @@
923 import QtQuick 2.0
924 import Powerd 0.1
925 import Lights 0.1
926+import QMenuModel 0.1 as QMenuModel
927+import Unity.Indicators 0.1 as Indicators
928
929 QtObject {
930 id: root
931
932+ property var _actionGroup: QMenuModel.QDBusActionGroup {
933+ busType: 1
934+ busName: "com.canonical.indicator.messages"
935+ objectPath: "/com/canonical/indicator/messages"
936+ }
937+
938+ property var _rootState: Indicators.ActionRootState {
939+ actionGroup: _actionGroup
940+ actionName: "messages"
941+ Component.onCompleted: actionGroup.start()
942+
943+ property bool hasMessages: valid && (String(icons).indexOf("indicator-messages-new") != -1)
944+ }
945+
946 Component.onDestruction: Lights.state = Lights.Off
947
948 // QtObject does not have children
949 property var _binding: Binding {
950 target: Lights
951 property: "state"
952- value: (Powerd.status === Powerd.Off) ? Lights.On : Lights.Off
953+ value: {
954+ return (Powerd.status === Powerd.Off && _rootState.hasMessages) ? Lights.On : Lights.Off
955+ }
956 }
957 }
958
959=== modified file 'qml/Panel/IndicatorsBar.qml'
960--- qml/Panel/IndicatorsBar.qml 2014-10-20 20:35:50 +0000
961+++ qml/Panel/IndicatorsBar.qml 2015-01-19 17:39:20 +0000
962@@ -46,13 +46,14 @@
963
964 function addScrollOffset(scrollAmmout) {
965 if (scrollAmmout < 0) { // left scroll
966- if (flickable.contentX < 0) return; // already off the left.
967- if (flickable.contentX + scrollAmmout < 0) scrollAmmout = -flickable.contentX; // going to be off the left
968+ if (flickable.contentX + flickable.width > row.width) return; // already off the left.
969+
970+ if (flickable.contentX + flickable.width - scrollAmmout > row.width) { // going to be off the right
971+ scrollAmmout = (flickable.contentX + flickable.width) - row.width;
972+ }
973 } else { // right scroll
974- if (flickable.contentX + flickable.width > row.width) return; // already off the right.
975- if (flickable.contentX + flickable.width + scrollAmmout > row.width) { // going to be off the right
976- scrollAmmout = row.width - (flickable.contentX + flickable.width);
977- }
978+ if (flickable.contentX < 0) return; // already off the right.
979+ if (flickable.contentX - scrollAmmout < 0) scrollAmmout = flickable.contentX; // going to be off the right
980 }
981 d.scrollOffset = d.scrollOffset + scrollAmmout;
982 }
983@@ -91,24 +92,26 @@
984 flickable.resetContentXComponents();
985
986 if (expanded && !flickable.moving) {
987-
988 // gap between left and row?
989- if (flickable.contentX < 0) {
990- d.alignmentAdjustment += flickable.contentX;
991- // gap between right and row?
992- } else if (flickable.contentX + flickable.width > row.width) {
993+ if (flickable.contentX + flickable.width > row.width) {
994 // row width is less than flickable
995 if (row.width < flickable.width) {
996- d.alignmentAdjustment += flickable.contentX;
997+ d.alignmentAdjustment -= flickable.contentX;
998 } else {
999- d.alignmentAdjustment += ((flickable.contentX + flickable.width) - row.width);
1000+ d.alignmentAdjustment -= ((flickable.contentX + flickable.width) - row.width);
1001 }
1002+
1003+ // gap between right and row?
1004+ } else if (flickable.contentX < 0) {
1005+ d.alignmentAdjustment -= flickable.contentX;
1006+
1007 // current item overlap on left
1008- } else if (row.currentItem && row.currentItem.x < flickable.contentX) {
1009- d.alignmentAdjustment -= (row.currentItem.x - flickable.contentX);
1010+ } else if (row.currentItem && (flickable.contentX + flickable.width) < (row.width - row.currentItem.x)) {
1011+ d.alignmentAdjustment += ((row.width - row.currentItem.x) - (flickable.contentX + flickable.width));
1012+
1013 // current item overlap on right
1014- } else if (row.currentItem && row.currentItem.x + row.currentItem.width > flickable.contentX + flickable.width) {
1015- d.alignmentAdjustment -= ((row.currentItem.x + row.currentItem.width) - (flickable.contentX + flickable.width));
1016+ } else if (row.currentItem && flickable.contentX > (row.width - row.currentItem.x - row.currentItem.width)) {
1017+ d.alignmentAdjustment -= flickable.contentX - (row.width - row.currentItem.x - row.currentItem.width);
1018 }
1019 }
1020 }
1021@@ -134,16 +137,19 @@
1022 id: flickable
1023 objectName: "flickable"
1024
1025+ // we rotate it because we want the Flickable to align its content item
1026+ // on the right instead of on the left
1027+ rotation: 180
1028+
1029 anchors.fill: parent
1030 contentWidth: row.width
1031+ contentX: d.combinedOffset
1032 interactive: false
1033- // align right + offset from row selection + scrolling
1034- contentX: row.width - flickable.width - d.combinedOffset
1035
1036 // contentX can change by user interaction as well as user offset changes
1037 // This function re-aligns the offsets so that the offsets match the contentX
1038 function resetContentXComponents() {
1039- d.scrollOffset += (flickable.contentX - (row.width - flickable.width - d.combinedOffset));
1040+ d.scrollOffset += d.combinedOffset - flickable.contentX;
1041 }
1042
1043 rebound: Transition {
1044@@ -162,6 +168,9 @@
1045 bottom: parent.bottom
1046 }
1047
1048+ // Compensate for the Flickable rotation (ie, counter-rotate)
1049+ rotation: 180
1050+
1051 lateralPosition: {
1052 if (root.lateralPosition == -1) return -1;
1053
1054
1055=== modified file 'qml/Panel/IndicatorsMenu.qml'
1056--- qml/Panel/IndicatorsMenu.qml 2014-10-21 19:32:03 +0000
1057+++ qml/Panel/IndicatorsMenu.qml 2015-01-19 17:39:20 +0000
1058@@ -18,6 +18,7 @@
1059 import Ubuntu.Components 1.1
1060 import Ubuntu.Gestures 0.1
1061 import "../Components"
1062+import "Indicators"
1063
1064 Showable {
1065 id: root
1066@@ -60,6 +61,10 @@
1067 onUnitProgressChanged: d.updateState()
1068 clip: root.partiallyOpened
1069
1070+ IndicatorsLight {
1071+ id: indicatorLights
1072+ }
1073+
1074 // eater
1075 MouseArea {
1076 anchors.fill: parent
1077
1078=== modified file 'tests/mocks/CMakeLists.txt'
1079--- tests/mocks/CMakeLists.txt 2014-06-11 15:36:51 +0000
1080+++ tests/mocks/CMakeLists.txt 2015-01-19 17:39:20 +0000
1081@@ -33,6 +33,7 @@
1082 add_subdirectory(HudClient)
1083 add_subdirectory(libusermetrics)
1084 add_subdirectory(LightDM)
1085+add_subdirectory(Lights)
1086 add_subdirectory(Powerd)
1087 add_subdirectory(QMenuModel)
1088 add_subdirectory(Ubuntu)
1089
1090=== added directory 'tests/mocks/Lights'
1091=== added file 'tests/mocks/Lights/CMakeLists.txt'
1092--- tests/mocks/Lights/CMakeLists.txt 1970-01-01 00:00:00 +0000
1093+++ tests/mocks/Lights/CMakeLists.txt 2015-01-19 17:39:20 +0000
1094@@ -0,0 +1,8 @@
1095+add_library(MockLights-qml MODULE
1096+ plugin.cpp
1097+ Lights.cpp
1098+ )
1099+
1100+qt5_use_modules(MockLights-qml Qml Gui)
1101+
1102+add_unity8_mock(Lights 0.1 Lights TARGETS MockLights-qml)
1103
1104=== added file 'tests/mocks/Lights/Lights.cpp'
1105--- tests/mocks/Lights/Lights.cpp 1970-01-01 00:00:00 +0000
1106+++ tests/mocks/Lights/Lights.cpp 2015-01-19 17:39:20 +0000
1107@@ -0,0 +1,84 @@
1108+/*
1109+ * Copyright (C) 2014 Canonical, Ltd.
1110+ *
1111+ * This program is free software; you can redistribute it and/or modify
1112+ * it under the terms of the GNU General Public License as published by
1113+ * the Free Software Foundation; version 3.
1114+ *
1115+ * This program is distributed in the hope that it will be useful,
1116+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1117+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1118+ * GNU General Public License for more details.
1119+ *
1120+ * You should have received a copy of the GNU General Public License
1121+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1122+ */
1123+
1124+#include "Lights.h"
1125+
1126+#include <QDebug>
1127+
1128+Lights::Lights(QObject* parent)
1129+ : QObject(parent),
1130+ m_color("blue"),
1131+ m_state(Lights::Off),
1132+ m_onMs(1000),
1133+ m_offMs(3000)
1134+{
1135+}
1136+
1137+Lights::~Lights()
1138+{
1139+}
1140+
1141+void Lights::setState(Lights::State newState)
1142+{
1143+ if (m_state != newState) {
1144+ m_state = newState;
1145+ Q_EMIT stateChanged(m_state);
1146+ }
1147+}
1148+
1149+Lights::State Lights::state() const
1150+{
1151+ return m_state;
1152+}
1153+
1154+void Lights::setColor(const QColor &color)
1155+{
1156+ if (m_color != color) {
1157+ m_color = color;
1158+ Q_EMIT colorChanged(m_color);
1159+ }
1160+}
1161+
1162+QColor Lights::color() const
1163+{
1164+ return m_color;
1165+}
1166+
1167+int Lights::onMillisec() const
1168+{
1169+ return m_onMs;
1170+}
1171+
1172+void Lights::setOnMillisec(int onMs)
1173+{
1174+ if (m_onMs != onMs) {
1175+ m_onMs = onMs;
1176+ Q_EMIT onMillisecChanged(m_onMs);
1177+ }
1178+}
1179+
1180+int Lights::offMillisec() const
1181+{
1182+ return m_offMs;
1183+}
1184+
1185+void Lights::setOffMillisec(int offMs)
1186+{
1187+ if (m_offMs != offMs) {
1188+ m_offMs = offMs;
1189+ Q_EMIT offMillisecChanged(m_offMs);
1190+ }
1191+}
1192
1193=== added file 'tests/mocks/Lights/Lights.h'
1194--- tests/mocks/Lights/Lights.h 1970-01-01 00:00:00 +0000
1195+++ tests/mocks/Lights/Lights.h 2015-01-19 17:39:20 +0000
1196@@ -0,0 +1,66 @@
1197+/*
1198+ * Copyright (C) 2014 Canonical, Ltd.
1199+ *
1200+ * This program is free software; you can redistribute it and/or modify
1201+ * it under the terms of the GNU General Public License as published by
1202+ * the Free Software Foundation; version 3.
1203+ *
1204+ * This program is distributed in the hope that it will be useful,
1205+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1206+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1207+ * GNU General Public License for more details.
1208+ *
1209+ * You should have received a copy of the GNU General Public License
1210+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1211+ */
1212+
1213+#ifndef UNITY_MOCK_LIGHTS_H
1214+#define UNITY_MOCK_LIGHTS_H
1215+
1216+#include <QtCore/QObject>
1217+#include <QtGui/QColor>
1218+
1219+class Lights: public QObject
1220+{
1221+ Q_OBJECT
1222+ Q_ENUMS(State)
1223+ Q_PROPERTY(State state READ state WRITE setState NOTIFY stateChanged)
1224+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
1225+ Q_PROPERTY(int onMillisec READ onMillisec WRITE setOnMillisec NOTIFY onMillisecChanged)
1226+ Q_PROPERTY(int offMillisec READ offMillisec WRITE setOffMillisec NOTIFY offMillisecChanged)
1227+
1228+public:
1229+ enum State {
1230+ Off,
1231+ On,
1232+ };
1233+
1234+ explicit Lights(QObject *parent = 0);
1235+ ~Lights();
1236+
1237+ void setState(State newState);
1238+ State state() const;
1239+
1240+ void setColor(const QColor &color);
1241+ QColor color() const;
1242+
1243+ int onMillisec() const;
1244+ void setOnMillisec(int onMs);
1245+
1246+ int offMillisec() const;
1247+ void setOffMillisec(int offMs);
1248+
1249+Q_SIGNALS:
1250+ void stateChanged(State newState);
1251+ void colorChanged(const QColor &color);
1252+ void onMillisecChanged(int onMs);
1253+ void offMillisecChanged(int offMs);
1254+
1255+private:
1256+ QColor m_color;
1257+ State m_state;
1258+ int m_onMs;
1259+ int m_offMs;
1260+};
1261+
1262+#endif
1263
1264=== added file 'tests/mocks/Lights/plugin.cpp'
1265--- tests/mocks/Lights/plugin.cpp 1970-01-01 00:00:00 +0000
1266+++ tests/mocks/Lights/plugin.cpp 2015-01-19 17:39:20 +0000
1267@@ -0,0 +1,33 @@
1268+/*
1269+ * Copyright (C) 2012,2013 Canonical, Ltd.
1270+ *
1271+ * This program is free software; you can redistribute it and/or modify
1272+ * it under the terms of the GNU General Public License as published by
1273+ * the Free Software Foundation; version 3.
1274+ *
1275+ * This program is distributed in the hope that it will be useful,
1276+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1277+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1278+ * GNU General Public License for more details.
1279+ *
1280+ * You should have received a copy of the GNU General Public License
1281+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1282+ */
1283+
1284+#include "plugin.h"
1285+#include "Lights.h"
1286+
1287+#include <QtQml/qqml.h>
1288+
1289+static QObject *lights_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
1290+{
1291+ Q_UNUSED(engine)
1292+ Q_UNUSED(scriptEngine)
1293+ return new Lights();
1294+}
1295+
1296+void PowerdPlugin::registerTypes(const char *uri)
1297+{
1298+ Q_ASSERT(uri == QLatin1String("Lights"));
1299+ qmlRegisterSingletonType<Lights>(uri, 0, 1, "Lights", lights_provider);
1300+}
1301
1302=== added file 'tests/mocks/Lights/plugin.h'
1303--- tests/mocks/Lights/plugin.h 1970-01-01 00:00:00 +0000
1304+++ tests/mocks/Lights/plugin.h 2015-01-19 17:39:20 +0000
1305@@ -0,0 +1,32 @@
1306+/*
1307+ * Copyright (C) 2012,2013 Canonical, Ltd.
1308+ *
1309+ * This program is free software; you can redistribute it and/or modify
1310+ * it under the terms of the GNU General Public License as published by
1311+ * the Free Software Foundation; version 3.
1312+ *
1313+ * This program is distributed in the hope that it will be useful,
1314+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1315+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1316+ * GNU General Public License for more details.
1317+ *
1318+ * You should have received a copy of the GNU General Public License
1319+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1320+ */
1321+
1322+#ifndef MOCK_POWER_PLUGIN_H
1323+#define MOCK_POWER_PLUGIN_H
1324+
1325+#include <QtQml/QQmlEngine>
1326+#include <QtQml/QQmlExtensionPlugin>
1327+
1328+class PowerdPlugin : public QQmlExtensionPlugin
1329+{
1330+ Q_OBJECT
1331+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
1332+
1333+public:
1334+ void registerTypes(const char *uri);
1335+};
1336+
1337+#endif
1338
1339=== added file 'tests/mocks/Lights/qmldir'
1340--- tests/mocks/Lights/qmldir 1970-01-01 00:00:00 +0000
1341+++ tests/mocks/Lights/qmldir 2015-01-19 17:39:20 +0000
1342@@ -0,0 +1,3 @@
1343+module Lights
1344+plugin MockLights-qml
1345+typeinfo Lights.qmltypes
1346
1347=== modified file 'tests/mocks/QMenuModel/CMakeLists.txt'
1348--- tests/mocks/QMenuModel/CMakeLists.txt 2014-05-02 22:57:21 +0000
1349+++ tests/mocks/QMenuModel/CMakeLists.txt 2015-01-19 17:39:20 +0000
1350@@ -4,6 +4,7 @@
1351 )
1352
1353 set(QMenuModelQml_SOURCES
1354+ actiondata.h
1355 actionstateparser.cpp
1356 plugin.cpp
1357 unitymenumodel.cpp
1358
1359=== modified file 'tests/mocks/QMenuModel/QDBusActionGroup.qml'
1360--- tests/mocks/QMenuModel/QDBusActionGroup.qml 2014-07-04 17:53:52 +0000
1361+++ tests/mocks/QMenuModel/QDBusActionGroup.qml 2015-01-19 17:39:20 +0000
1362@@ -19,69 +19,19 @@
1363
1364 import QtQuick 2.0
1365 import Ubuntu.Settings.Menus 0.1 as Menus
1366+import QMenuModel 0.1
1367
1368 QtObject {
1369 property int busType
1370 property string busName
1371 property string objectPath
1372+ property var actions: ActionData ? ActionData.data : undefined
1373+
1374+ signal dataChanged
1375+
1376 function start() {}
1377+
1378 function action(actionName) {
1379- switch (actionName) {
1380- case "transfer-state.queued":
1381- return {
1382- 'valid': true,
1383- 'state': {
1384- 'state': Menus.TransferState.Queued,
1385- 'percent': 0.0
1386- }
1387- }
1388- case "transfer-state.running":
1389- return {
1390- 'valid': true,
1391- 'state': {
1392- 'state': Menus.TransferState.Running,
1393- 'seconds-left': 100,
1394- 'percent': 0.1
1395- }
1396- }
1397- case "transfer-state.paused":
1398- return {
1399- 'valid': true,
1400- 'state': {
1401- 'state': Menus.TransferState.Paused,
1402- 'seconds-left': 100,
1403- 'percent': 0.5
1404- }
1405- }
1406- case "transfer-state.cancelled":
1407- return {
1408- 'valid': true,
1409- 'state': {
1410- 'state': Menus.TransferState.Canceled,
1411- 'percent': 0.4
1412- }
1413- }
1414- case "transfer-state.finished": return {
1415- 'valid': true,
1416- 'state': {
1417- 'state': Menus.TransferState.Finished,
1418- 'seconds-left': 0,
1419- 'percent': 1.0
1420- }
1421- }
1422- case "transfer-state.error":
1423- return {
1424- 'valid': true,
1425- 'state': {
1426- 'state': Menus.TransferState.Error,
1427- 'seconds-left': 100,
1428- 'percent': 0.0
1429- }
1430- }
1431- default:
1432- break;
1433- }
1434-
1435- return null;
1436+ return actions[actionName];
1437 }
1438 }
1439
1440=== added file 'tests/mocks/QMenuModel/actiondata.h'
1441--- tests/mocks/QMenuModel/actiondata.h 1970-01-01 00:00:00 +0000
1442+++ tests/mocks/QMenuModel/actiondata.h 2015-01-19 17:39:20 +0000
1443@@ -0,0 +1,52 @@
1444+/*
1445+ * Copyright (C) 2013 Canonical, Ltd.
1446+ *
1447+ * This program is free software; you can redistribute it and/or modify
1448+ * it under the terms of the GNU General Public License as published by
1449+ * the Free Software Foundation; version 3.
1450+ *
1451+ * This program is distributed in the hope that it will be useful,
1452+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1453+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1454+ * GNU General Public License for more details.
1455+ *
1456+ * You should have received a copy of the GNU General Public License
1457+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1458+ *
1459+ * Authors: Nick Dedekind <nick.dedekind@canonical.com>
1460+ */
1461+
1462+#ifndef ACTIONDATA_H
1463+#define ACTIONDATA_H
1464+
1465+#include <QObject>
1466+#include <QVariant>
1467+
1468+typedef struct _GVariant GVariant;
1469+
1470+class Q_DECL_EXPORT ActionData : public QObject
1471+{
1472+ Q_OBJECT
1473+ Q_PROPERTY(QVariant data READ data WRITE setData NOTIFY dataChanged)
1474+public:
1475+ ActionData(QObject* parent = 0)
1476+ : QObject(parent)
1477+ {}
1478+
1479+ QVariant data() const { return m_data; }
1480+ void setData(const QVariant& data)
1481+ {
1482+ if (m_data != data) {
1483+ m_data = data;
1484+ Q_EMIT dataChanged();
1485+ }
1486+ }
1487+
1488+Q_SIGNALS:
1489+ void dataChanged();
1490+
1491+private:
1492+ QVariant m_data;
1493+};
1494+
1495+#endif // ACTIONDATA_H
1496
1497=== modified file 'tests/mocks/QMenuModel/plugin.cpp'
1498--- tests/mocks/QMenuModel/plugin.cpp 2013-11-19 17:01:25 +0000
1499+++ tests/mocks/QMenuModel/plugin.cpp 2015-01-19 17:39:20 +0000
1500@@ -18,13 +18,23 @@
1501
1502 #include "plugin.h"
1503 #include "unitymenumodel.h"
1504+#include "actiondata.h"
1505 #include "actionstateparser.h"
1506
1507 #include <QtQml/qqml.h>
1508
1509+static QObject* actionDataSingleton(QQmlEngine* engine, QJSEngine* scriptEngine)
1510+{
1511+ Q_UNUSED(engine);
1512+ Q_UNUSED(scriptEngine);
1513+ return new ActionData;
1514+}
1515+
1516 void QMenuModelPlugin::registerTypes(const char *uri)
1517 {
1518 Q_ASSERT(uri == QLatin1String("QMenuModel"));
1519 qmlRegisterType<UnityMenuModel>(uri, 0, 1, "UnityMenuModel");
1520 qmlRegisterType<ActionStateParser>(uri, 0, 1, "ActionStateParser");
1521+
1522+ qmlRegisterSingletonType<ActionData>(uri, 0, 1, "ActionData", actionDataSingleton);
1523 }
1524
1525=== added file 'tests/mocks/Unity/Indicators/ActionRootState.qml'
1526--- tests/mocks/Unity/Indicators/ActionRootState.qml 1970-01-01 00:00:00 +0000
1527+++ tests/mocks/Unity/Indicators/ActionRootState.qml 2015-01-19 17:39:20 +0000
1528@@ -0,0 +1,46 @@
1529+/*
1530+ * Copyright 2013 Canonical Ltd.
1531+ *
1532+ * This program is free software; you can redistribute it and/or modify
1533+ * it under the terms of the GNU Lesser General Public License as published by
1534+ * the Free Software Foundation; version 3.
1535+ *
1536+ * This program is distributed in the hope that it will be useful,
1537+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1538+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1539+ * GNU Lesser General Public License for more details.
1540+ *
1541+ * You should have received a copy of the GNU Lesser General Public License
1542+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1543+ *
1544+ * Authors:
1545+ * Nick Dedekind <nick.dedekind@canonical.com>
1546+ */
1547+
1548+import QtQuick 2.0
1549+
1550+QtObject {
1551+ property var actionGroup
1552+ property var actionName
1553+
1554+ property var action: actionGroup ? actionGroup.actions[actionName] : undefined
1555+ property var state: action && action.hasOwnProperty("state") ? action.state : undefined
1556+
1557+ property bool valid: action && action.hasOwnProperty("valid") ? action.valid : false
1558+ property string title: state && state.hasOwnProperty("title") ? state["title"] : ""
1559+ property string leftLabel: state && state.hasOwnProperty("pre-label") ? state["pre-label"] : ""
1560+ property string rightLabel: state && state.hasOwnProperty("label") ? state["label"] : ""
1561+ property var icons: state && state.hasOwnProperty("icons") ? state["icons"] : []
1562+ property string accessibleName: state && state.hasOwnProperty("accessible-desc") ? state["accessible-desc"] : ""
1563+ property bool visible: state && state.hasOwnProperty("visible") ? state["visible"] : true
1564+
1565+ signal updated
1566+
1567+ onValidChanged: updated()
1568+ onTitleChanged: updated()
1569+ onLeftLabelChanged: updated()
1570+ onRightLabelChanged: updated()
1571+ onIconsChanged: updated()
1572+ onAccessibleNameChanged: updated()
1573+ onVisibleChanged: updated()
1574+}
1575
1576=== renamed file 'tests/mocks/Unity/Indicators/RootActionState.qml' => 'tests/mocks/Unity/Indicators/ModelActionRootState.qml'
1577=== modified file 'tests/mocks/Unity/Indicators/qmldir'
1578--- tests/mocks/Unity/Indicators/qmldir 2014-10-07 10:28:59 +0000
1579+++ tests/mocks/Unity/Indicators/qmldir 2015-01-19 17:39:20 +0000
1580@@ -2,5 +2,6 @@
1581 plugin IndicatorsFakeQml
1582 typeinfo Indicators.qmltypes
1583
1584+ActionRootState 0.1 ActionRootState.qml
1585 IndicatorsModel 0.1 IndicatorsModel.qml
1586-RootActionState 0.1 RootActionState.qml
1587+ModelActionRootState 0.1 ModelActionRootState.qml
1588
1589=== modified file 'tests/plugins/Unity/Indicators/rootactionstatetest.cpp'
1590--- tests/plugins/Unity/Indicators/rootactionstatetest.cpp 2014-08-26 08:14:44 +0000
1591+++ tests/plugins/Unity/Indicators/rootactionstatetest.cpp 2015-01-19 17:39:20 +0000
1592@@ -17,7 +17,7 @@
1593 * Nick Dedekind <nick.dedekind@canonical.com>
1594 */
1595
1596-#include "rootactionstate.h"
1597+#include "modelactionrootstate.h"
1598
1599 #include <unitymenumodel.h>
1600 #include <QtTest>
1601@@ -32,7 +32,7 @@
1602 {
1603 UnityMenuModel* menuModel = new UnityMenuModel();
1604 ActionStateParser* originalParser = menuModel->actionStateParser();
1605- RootActionState* rootState = new RootActionState();
1606+ ModelActionRootState* rootState = new ModelActionRootState();
1607
1608 rootState->setMenu(menuModel);
1609
1610@@ -44,7 +44,7 @@
1611 void testDeleteUnityMenuModel()
1612 {
1613 UnityMenuModel* menuModel = new UnityMenuModel();
1614- RootActionState* rootState = new RootActionState();
1615+ ModelActionRootState* rootState = new ModelActionRootState();
1616
1617 rootState->setMenu(menuModel);
1618
1619@@ -77,7 +77,7 @@
1620
1621 GVariant* params = g_variant_builder_end (&builderParams);
1622
1623- RootActionState rootState;
1624+ RootStateParser rootState;
1625 QVariant result = rootState.toQVariant(params);
1626 g_variant_unref(params);
1627
1628
1629=== modified file 'tests/qmltests/CMakeLists.txt'
1630--- tests/qmltests/CMakeLists.txt 2014-11-10 09:14:30 +0000
1631+++ tests/qmltests/CMakeLists.txt 2015-01-19 17:39:20 +0000
1632@@ -81,6 +81,7 @@
1633 add_qml_test(Panel MenuContent ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
1634 add_qml_test(Panel Panel ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
1635 add_qml_test(Panel SearchIndicator)
1636+add_qml_test(Panel/Indicators IndicatorsLight ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
1637 # These MenuItemFactory tests need the test/mocks/ to come before plugins/
1638 add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
1639 add_qml_test(Panel/Indicators MessageMenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
1640
1641=== added file 'tests/qmltests/Panel/Indicators/tst_IndicatorsLight.qml'
1642--- tests/qmltests/Panel/Indicators/tst_IndicatorsLight.qml 1970-01-01 00:00:00 +0000
1643+++ tests/qmltests/Panel/Indicators/tst_IndicatorsLight.qml 2015-01-19 17:39:20 +0000
1644@@ -0,0 +1,129 @@
1645+/*
1646+ * Copyright 2014 Canonical Ltd.
1647+ *
1648+ * This program is free software; you can redistribute it and/or modify
1649+ * it under the terms of the GNU General Public License as published by
1650+ * the Free Software Foundation; version 3.
1651+ *
1652+ * This program is distributed in the hope that it will be useful,
1653+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1654+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1655+ * GNU General Public License for more details.
1656+ *
1657+ * You should have received a copy of the GNU General Public License
1658+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1659+ */
1660+
1661+import QtQuick 2.0
1662+import QtQuick.Layouts 1.1
1663+import Unity.Test 0.1 as UT
1664+import Unity.Indicators 0.1 as Indicators
1665+import Ubuntu.Components 1.1
1666+import Powerd 0.1
1667+import Lights 0.1
1668+import QMenuModel 0.1
1669+import "../../../../qml/Panel/Indicators"
1670+
1671+Item {
1672+ id: root
1673+ width: units.gu(30)
1674+ height: units.gu(30)
1675+
1676+ property var newMessage: {
1677+ "messages" : {
1678+ 'valid': true,
1679+ 'state': {
1680+ 'icons': [ 'indicator-messages-new' ]
1681+ }
1682+ }
1683+ };
1684+ property var noNewMessage: {
1685+ "messages" : {
1686+ 'valid': true,
1687+ 'state': {
1688+ 'icons': [ 'indicator-messages' ]
1689+ }
1690+ }
1691+ };
1692+
1693+ Component {
1694+ id: light
1695+ IndicatorsLight {}
1696+ }
1697+
1698+ Loader {
1699+ id: loader
1700+ sourceComponent: light
1701+ }
1702+
1703+ Component.onCompleted: {
1704+ ActionData.data = newMessage;
1705+ Powerd.status = Powerd.On
1706+ }
1707+
1708+ RowLayout {
1709+ anchors.fill: parent
1710+ anchors.margins: units.gu(1)
1711+
1712+ Item {
1713+ Layout.fillWidth: true
1714+ Layout.fillHeight: true
1715+
1716+ Rectangle {
1717+ width: units.gu(4)
1718+ height: width
1719+ radius: width / 2
1720+ anchors.centerIn: parent
1721+
1722+ color: Lights.state === Lights.On ? Lights.color : "transparent"
1723+
1724+ border.color: "black"
1725+ border.width: 1
1726+ }
1727+ }
1728+
1729+ ColumnLayout {
1730+ Layout.alignment: Qt.AlignTop
1731+ Layout.fillWidth: false
1732+ Layout.preferredWidth: units.gu(15)
1733+
1734+ Button {
1735+ Layout.fillWidth: true
1736+ text: Powerd.status === Powerd.On ? "Power Off" : "Power On"
1737+ onClicked: {
1738+ if (Powerd.status === Powerd.On) Powerd.status = Powerd.Off;
1739+ else Powerd.status = Powerd.On;
1740+ }
1741+ }
1742+ }
1743+ }
1744+
1745+ UT.UnityTestCase {
1746+ name: "IndicatorsLight"
1747+ when: windowShown
1748+
1749+ function init() {
1750+ // reload
1751+ ActionData.data = noNewMessage;
1752+ loader.sourceComponent = undefined;
1753+ loader.sourceComponent = light;
1754+ Powerd.status = Powerd.On
1755+ }
1756+
1757+ function test_LightsStatus_data() {
1758+ return [
1759+ { tag: "Powerd.On with No Message", powerd: Powerd.On, actionData: noNewMessage, expected: Lights.Off },
1760+ { tag: "Powerd.Off with No Message", powerd: Powerd.Off, actionData: noNewMessage, expected: Lights.Off },
1761+ { tag: "Powerd.On with New Message", powerd: Powerd.On, actionData: newMessage, expected: Lights.Off },
1762+ { tag: "Powerd.Off with New Message", powerd: Powerd.Off, actionData: newMessage, expected: Lights.On },
1763+ ]
1764+ }
1765+
1766+ function test_LightsStatus(data) {
1767+ Powerd.status = data.powerd;
1768+ ActionData.data = data.actionData;
1769+
1770+ compare(Lights.state, data.expected, "Light does not match expected value");
1771+ }
1772+ }
1773+}
1774
1775=== modified file 'tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml'
1776--- tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml 2014-11-05 00:20:05 +0000
1777+++ tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml 2015-01-19 17:39:20 +0000
1778@@ -17,6 +17,7 @@
1779 import QtQuick 2.0
1780 import QtTest 1.0
1781 import Unity.Test 0.1 as UT
1782+import Ubuntu.Settings.Menus 0.1 as Menus
1783 import QMenuModel 0.1
1784 import Utils 0.1 as Utils
1785 import "../../../../qml/Panel/Indicators"
1786@@ -448,6 +449,55 @@
1787 }
1788
1789 function test_create_transferMenu(data) {
1790+ ActionData.data = {
1791+ "transfer-state.queued": {
1792+ 'valid': true,
1793+ 'state': {
1794+ 'state': Menus.TransferState.Queued,
1795+ 'percent': 0.0
1796+ }
1797+ },
1798+ "transfer-state.running": {
1799+ 'valid': true,
1800+ 'state': {
1801+ 'state': Menus.TransferState.Running,
1802+ 'seconds-left': 100,
1803+ 'percent': 0.1
1804+ }
1805+ },
1806+ "transfer-state.paused": {
1807+ 'valid': true,
1808+ 'state': {
1809+ 'state': Menus.TransferState.Paused,
1810+ 'seconds-left': 100,
1811+ 'percent': 0.5
1812+ }
1813+ },
1814+ "transfer-state.cancelled": {
1815+ 'valid': true,
1816+ 'state': {
1817+ 'state': Menus.TransferState.Canceled,
1818+ 'percent': 0.4
1819+ }
1820+ },
1821+ "transfer-state.finished": {
1822+ 'valid': true,
1823+ 'state': {
1824+ 'state': Menus.TransferState.Finished,
1825+ 'seconds-left': 0,
1826+ 'percent': 1.0
1827+ }
1828+ },
1829+ "transfer-state.error": {
1830+ 'valid': true,
1831+ 'state': {
1832+ 'state': Menus.TransferState.Error,
1833+ 'seconds-left': 100,
1834+ 'percent': 0.0
1835+ }
1836+ }
1837+ };
1838+
1839 menuData.type = "com.canonical.indicator.transfer";
1840 menuData.label = data.label;
1841 menuData.sensitive = data.enabled;

Subscribers

People subscribed via source and target branches

to all changes: