on xenial help sign in
Moved chewie ui (indicators-client) into unity. renamed.
commit81d8ab24e8dd8034bfbd03d5d5d136f0db33494d authorNick Dedekind <nicholas.dedekind@gmail.com> dateFri 7 Jun 2013, 14:48 (13 years ago) parente8b206a
86 files changed+6083−7
Panel/Indicators.qml+2−2 plugins/CMakeLists.txt+1 plugins/IndicatorsClient/CMakeLists.txt+103 plugins/IndicatorsClient/flatmenuproxymodel.cpp+325 plugins/IndicatorsClient/flatmenuproxymodel.h+94 plugins/IndicatorsClient/indicatorclientinterface.h+137 plugins/IndicatorsClient/indicators/CMakeLists.txt+6 plugins/IndicatorsClient/indicators/common/CMakeLists.txt+32 plugins/IndicatorsClient/indicators/common/indicatorclient_common.cpp+303 plugins/IndicatorsClient/indicators/common/indicatorclient_common.h+102 plugins/IndicatorsClient/indicators/common/indicatorclient_common.qrc+5 plugins/IndicatorsClient/indicators/common/qml/commonplugin.qml+24 plugins/IndicatorsClient/indicators/datetime/CMakeLists.txt+29 plugins/IndicatorsClient/indicators/datetime/artwork/time_and_date@18.png plugins/IndicatorsClient/indicators/datetime/indicatorclient_datetime.cpp+123 plugins/IndicatorsClient/indicators/datetime/indicatorclient_datetime.h+53 plugins/IndicatorsClient/indicators/datetime/indicatorclient_datetime.qrc+6 plugins/IndicatorsClient/indicators/datetime/qml/ClockPage.qml+98 plugins/IndicatorsClient/indicators/messaging/CMakeLists.txt+28 plugins/IndicatorsClient/indicators/messaging/artwork/default_app.svg+42 plugins/IndicatorsClient/indicators/messaging/artwork/default_contact.png plugins/IndicatorsClient/indicators/messaging/artwork/message_sms01_54px.png plugins/IndicatorsClient/indicators/messaging/indicatorclient_messaging.cpp+61 plugins/IndicatorsClient/indicators/messaging/indicatorclient_messaging.h+38 plugins/IndicatorsClient/indicators/messaging/indicatorclient_messaging.qrc+19 plugins/IndicatorsClient/indicators/messaging/qml/ActionButton.qml+33 plugins/IndicatorsClient/indicators/messaging/qml/ActionTextField.qml+60 plugins/IndicatorsClient/indicators/messaging/qml/GroupedMessage.qml+92 plugins/IndicatorsClient/indicators/messaging/qml/HeroMessage.qml+115 plugins/IndicatorsClient/indicators/messaging/qml/HeroMessageHeader.qml+147 plugins/IndicatorsClient/indicators/messaging/qml/MessageItem.qml+92 plugins/IndicatorsClient/indicators/messaging/qml/QuickReply.qml+152 plugins/IndicatorsClient/indicators/messaging/qml/SimpleTextMessage.qml+91 plugins/IndicatorsClient/indicators/messaging/qml/SnapDecision.qml+135 plugins/IndicatorsClient/indicators/messaging/qml/TextMessage.qml+32 plugins/IndicatorsClient/indicators/messaging/qml/messagingplugin.qml+32 plugins/IndicatorsClient/indicators/messaging/qml/utils.js+27 plugins/IndicatorsClient/indicators/network/CMakeLists.txt+36 plugins/IndicatorsClient/indicators/network/indicatorclient_network.cpp+174 plugins/IndicatorsClient/indicators/network/indicatorclient_network.h+51 plugins/IndicatorsClient/indicators/network/indicatorclient_network.qrc+8 plugins/IndicatorsClient/indicators/network/networkagent.cpp+146 plugins/IndicatorsClient/indicators/network/networkagent.h+65 plugins/IndicatorsClient/indicators/network/qml/Accesspoint.qml+69 plugins/IndicatorsClient/indicators/network/qml/NetworkPage.qml+71 plugins/IndicatorsClient/indicators/network/qml/PasswordDialog.qml+80 plugins/IndicatorsClient/indicators/network/qml/WifiSection.qml+27 plugins/IndicatorsClient/indicators/network/secret-agent.c+382 plugins/IndicatorsClient/indicators/network/secret-agent.h+102 plugins/IndicatorsClient/indicators/power/CMakeLists.txt+28 plugins/IndicatorsClient/indicators/power/artwork/battery_mock@18.png plugins/IndicatorsClient/indicators/power/indicatorclient_power.cpp+34 plugins/IndicatorsClient/indicators/power/indicatorclient_power.h+35 plugins/IndicatorsClient/indicators/power/indicatorclient_power.qrc+4 plugins/IndicatorsClient/indicators/sound/CMakeLists.txt+32 plugins/IndicatorsClient/indicators/sound/indicatorclient_sound.cpp+35 plugins/IndicatorsClient/indicators/sound/indicatorclient_sound.h+34 plugins/IndicatorsClient/indicators/sound/indicatorclient_sound.qrc+4 plugins/IndicatorsClient/indicatorsfactory.cpp+55 plugins/IndicatorsClient/indicatorsfactory.h+59 plugins/IndicatorsClient/indicatorsmanager.cpp+258 plugins/IndicatorsClient/indicatorsmanager.h+70 plugins/IndicatorsClient/indicatorsmodel.cpp+320 plugins/IndicatorsClient/indicatorsmodel.h+86 plugins/IndicatorsClient/plugin.cpp+37 plugins/IndicatorsClient/plugin.h+32 plugins/IndicatorsClient/qml/BasicMenu.qml+51 plugins/IndicatorsClient/qml/ButtonMenu.qml+44 plugins/IndicatorsClient/qml/DBusActionState.qml+104 plugins/IndicatorsClient/qml/DivMenu.qml+26 plugins/IndicatorsClient/qml/FactoryMenu.qml+89 plugins/IndicatorsClient/qml/HLine.qml+27 plugins/IndicatorsClient/qml/Menu.qml+44 plugins/IndicatorsClient/qml/PluginItem.qml+214 plugins/IndicatorsClient/qml/ProgressMenu.qml+60 plugins/IndicatorsClient/qml/RemoveBackground.qml+59 plugins/IndicatorsClient/qml/SectionMenu.qml+59 plugins/IndicatorsClient/qml/SliderMenu.qml+66 plugins/IndicatorsClient/qml/SwitchMenu.qml+36 plugins/IndicatorsClient/qml/TextMenu.qml+81 plugins/IndicatorsClient/qmldir+18 plugins/IndicatorsClient/widgetsmap.cpp+82 plugins/IndicatorsClient/widgetsmap.h+46 tests/qmltests/Panel/tst_IndicatorRow.qml+2−2 tests/qmltests/Panel/tst_MenuContent.qml+2−2 tests/qmltests/Panel/tst_Panel.qml−1
Panel/Indicators.qml+2−2
@@ -16,7 +16,7 @@
1616
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
19−import Ubuntu.ChewieUI 0.1 as ChewieUI
19+import IndicatorsClient 0.1 as IndicatorsClient
2020
2121import "../Components"
2222import "../Components/Math.js" as MathLocal
@@ -225,7 +225,7 @@ Showable {
225225
226226 }
227227
228− ChewieUI.PluginModel {
228+ IndicatorsClient.IndicatorsModel {
229229 id: indicatorsModel
230230 Component.onCompleted: load()
231231 }
plugins/CMakeLists.txt+1
@@ -2,4 +2,5 @@ add_subdirectory(Ubuntu)
22add_subdirectory(Utils)
33add_subdirectory(Unity)
44add_subdirectory(HudClient)
5+add_subdirectory(IndicatorsClient)
56add_subdirectory(LightDM)
plugins/IndicatorsClient/CMakeLists.txtnew file+103
@@ -0,0 +1,103 @@
1+project(IndicatorsClientQml)
2+
3+pkg_check_modules(GLIB glib-2.0>=2.32)
4+pkg_check_modules(LIBNM_GLIB libnm-glib>=0.9.6)
5+pkg_check_modules(LIBNM_UTIL libnm-util>=0.9.6)
6+pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
7+find_package(Qt5Core REQUIRED)
8+find_package(Qt5Quick REQUIRED)
9+
10+if(LIBNM_GLIB_FOUND AND LIBNM_UTIL_FOUND AND GLIB_FOUND)
11+ set(NETWORK_PLUGIN_ENABLED 1)
12+else()
13+ set(NETWORK_PLUGIN_ENABLED 0)
14+ message(WARNING "Missing glib or libnm dependency for the network plugin, not building")
15+endif()
16+
17+
18+add_subdirectory(indicators)
19+
20+if(NETWORK_PLUGIN_ENABLED)
21+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNETWORK_PLUGIN_ENABLED" )
22+endif()
23+
24+include_directories(
25+ ${CMAKE_CURRENT_SOURCE_DIR}
26+ ${CMAKE_CURRENT_BINARY_DIR}
27+ ${Qt5Core_INCLUDE_DIRS}
28+ ${Qt5Quick_INCLUDE_DIRS}
29+ ${GLIB_INCLUDE_DIRS}
30+ ${QMENUMODEL_INCLUDE_DIRS}
31+ ${indicatorclient_common_SOURCE_DIR}
32+)
33+
34+set(IndicatorsClientQML_SOURCES
35+ flatmenuproxymodel.cpp
36+ indicatorsfactory.cpp
37+ indicatorsmanager.cpp
38+ indicatorsmodel.cpp
39+ plugin.cpp
40+ widgetsmap.cpp
41+)
42+
43+set(IndicatorsClientQML_QML
44+ qml/BasicMenu.qml
45+ qml/ButtonMenu.qml
46+ qml/DBusActionState.qml
47+ qml/DivMenu.qml
48+ qml/FactoryMenu.qml
49+ qml/HLine.qml
50+ qml/Menu.qml
51+ qml/PluginItem.qml
52+ qml/RemoveBackground.qml
53+ qml/SectionMenu.qml
54+ qml/SliderMenu.qml
55+ qml/SwitchMenu.qml
56+ qml/TextMenu.qml
57+ qml/ProgressMenu.qml
58+)
59+
60+set(IndicatorsClientQM_RESOURCES
61+ indicatorsclient.qrc
62+)
63+
64+add_library(IndicatorsClientQml MODULE
65+ ${IndicatorsClientQML_RCC}
66+ ${IndicatorsClientQML_SOURCES}
67+)
68+
69+target_link_libraries(IndicatorsClientQml
70+ ${Qt5Core_LIBRARIES}
71+ ${Qt5Quick_LIBRARIES}
72+ ${GOBJECT_LDFLAGS}
73+ ${QMENUMODEL_LDFLAGS}
74+ indicatorclient_datetime
75+ indicatorclient_messaging
76+ indicatorclient_power
77+ indicatorclient_sound
78+ indicatorclient_network
79+)
80+
81+qt5_use_modules(IndicatorsClientQml Qml)
82+
83+# copy qmldir file into build directory for shadow builds
84+file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
85+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
86+)
87+
88+# copy qmldir file into build directory for shadow builds
89+file(COPY ${IndicatorsClientQML_QML}
90+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/qml
91+ )
92+
93+install(TARGETS IndicatorsClientQml
94+ DESTINATION ${SHELL_APP_DIR}/plugins/IndicatorsClient
95+)
96+
97+install(FILES qmldir
98+ DESTINATION ${SHELL_APP_DIR}/plugins/IndicatorsClient
99+)
100+
101+install(FILES ${IndicatorsClientQML_QML}
102+ DESTINATION ${SHELL_APP_DIR}/plugins/IndicatorsClient/qml
103+)
plugins/IndicatorsClient/flatmenuproxymodel.cppnew file+325
@@ -0,0 +1,325 @@
1+/*
2+ * Copyright 2012 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+ */
19+
20+extern "C" {
21+#include <gio/gio.h>
22+}
23+
24+#include "flatmenuproxymodel.h"
25+#include <QString>
26+#include <QStringList>
27+
28+FlatMenuProxyModel::FlatMenuProxyModel(QAbstractItemModel *source)
29+ : QAbstractProxyModel(source),
30+ m_rowCount(0)
31+{
32+ m_model = new QDBusMenuModel;
33+ setSourceModel(m_model);
34+}
35+
36+/*! \internal */
37+FlatMenuProxyModel::~FlatMenuProxyModel()
38+{
39+ delete m_model;
40+}
41+
42+void FlatMenuProxyModel::setSourceModel(QAbstractItemModel *source)
43+{
44+ if (sourceModel()) {
45+ QAbstractItemModel *oldSource = sourceModel();
46+ if (oldSource == source) {
47+ return;
48+ }
49+
50+ oldSource->disconnect(this);
51+ }
52+
53+ QAbstractProxyModel::setSourceModel(source);
54+
55+ if (source) {
56+ connect(source,
57+ SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
58+ SLOT(onRowsAboutToBeInserted(QModelIndex,int,int)));
59+ connect(source,
60+ SIGNAL(rowsInserted(QModelIndex,int,int)),
61+ SLOT(onRowsInserted(QModelIndex,int,int)));
62+
63+ connect(source,
64+ SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
65+ SLOT(onRowsAboutToBeRemoved(QModelIndex,int,int)));
66+ connect(source,
67+ SIGNAL(rowsRemoved(QModelIndex,int,int)),
68+ SLOT(onRowsRemoved(QModelIndex,int,int)));
69+
70+ connect(source,
71+ SIGNAL(modelAboutToBeReset()),
72+ SLOT(onModelAboutToBeReset()));
73+ connect(source,
74+ SIGNAL(modelReset()),
75+ SLOT(onModelReset()));
76+
77+ connect(source,
78+ SIGNAL(rowsInserted(QModelIndex,int,int)),
79+ SIGNAL(countChanged()));
80+ connect(source,
81+ SIGNAL(rowsRemoved(QModelIndex,int,int)),
82+ SIGNAL(countChanged()));
83+ connect(source,
84+ SIGNAL(modelReset()),
85+ SIGNAL(countChanged()));
86+
87+ // initiliaze rowCount
88+ QModelIndex lastItem = source->index(source->rowCount() - 1, 0);
89+ m_rowCount = recursiveRowCount(lastItem);
90+ } else {
91+ m_rowCount = 0;
92+ }
93+
94+ Q_EMIT countChanged();
95+}
96+
97+void FlatMenuProxyModel::setBusName(const QString &busName)
98+{
99+ m_model->setBusName(busName);
100+}
101+
102+QString FlatMenuProxyModel::busName() const
103+{
104+ return m_model->busName();
105+}
106+
107+void FlatMenuProxyModel::setObjectPath(const QString &busPath)
108+{
109+ m_model->setObjectPath(busPath);
110+}
111+
112+QString FlatMenuProxyModel::objectPath() const
113+{
114+ return m_model->objectPath();
115+}
116+
117+int FlatMenuProxyModel::status() const
118+{
119+ return m_model->status();
120+}
121+
122+DBusEnums::BusType FlatMenuProxyModel::busType() const
123+{
124+ return m_model->busType();
125+}
126+
127+void FlatMenuProxyModel::setIntBusType(int type)
128+{
129+ m_model->setBusType((DBusEnums::BusType) type);
130+}
131+
132+void FlatMenuProxyModel::start()
133+{
134+ m_model->start();
135+}
136+
137+void FlatMenuProxyModel::stop()
138+{
139+ m_model->stop();
140+}
141+
142+QModelIndex FlatMenuProxyModel::mapFromSource(const QModelIndex &index) const
143+{
144+ if (!index.isValid()) {
145+ return QModelIndex();
146+ }
147+
148+ QModelIndex result = createIndex(rowOffsetOf(index, index.row()), 0);
149+ return result;
150+}
151+
152+QModelIndex FlatMenuProxyModel::mapToSource(const QModelIndex &index) const
153+{
154+ if (sourceModel() && m_indexCache.contains(index.row())) {
155+ QString key = m_indexCache.value(index.row());
156+ QStringList sections = key.split('.', QString::SkipEmptyParts);
157+ QModelIndex sourceIndex = QModelIndex();
158+ for(int i=0; i < sections.size(); i++) {
159+ sourceIndex = sourceModel()->index(sections.at(i).toInt(), 9, sourceIndex);
160+ }
161+ return sourceIndex;
162+ } else {
163+ return QModelIndex();
164+ }
165+}
166+
167+QModelIndex FlatMenuProxyModel::index(int row, int sectionRow, const QModelIndex &parent, const QString &key) const
168+{
169+ for (int i = 0, count = 0; i < sourceModel()->rowCount(parent); i++) {
170+ QModelIndex sourceIndex = sourceModel()->index(i, 0, parent);
171+ int indexCount = recursiveRowCount(sourceIndex);
172+
173+ if (count == sectionRow) {
174+ QString sectionKey = key + "." + QString::number(i);
175+ m_indexCache.insert(row, sectionKey);
176+ return createIndex(row, 0);
177+ } else if ((count + indexCount) >= sectionRow) {
178+ count++;
179+ return index(row, sectionRow - count, sourceIndex, key + "." + QString::number(i));
180+ }
181+
182+ count += indexCount + 1;
183+ }
184+ return QModelIndex();
185+}
186+
187+QModelIndex FlatMenuProxyModel::index(int row, int, const QModelIndex &) const
188+{
189+ return index(row, row, QModelIndex(), "");
190+}
191+
192+QModelIndex FlatMenuProxyModel::parent(const QModelIndex &) const
193+{
194+ return QModelIndex();
195+}
196+
197+int FlatMenuProxyModel::columnCount(const QModelIndex &) const
198+{
199+ return 1;
200+}
201+
202+int FlatMenuProxyModel::rowCount(const QModelIndex &) const
203+{
204+ return m_rowCount;
205+}
206+
207+int FlatMenuProxyModel::count() const
208+{
209+ return rowCount(QModelIndex());
210+}
211+
212+void FlatMenuProxyModel::onRowsAboutToBeInserted(const QModelIndex &index, int first, int last)
213+{
214+
215+ if (index.isValid()) {
216+ int firstIndex = rowOffsetOf(index, first);
217+ int lastIndex = rowOffsetOf(index, last, true);
218+
219+ beginInsertRows(QModelIndex(), firstIndex, lastIndex);
220+ m_rowCount += (lastIndex - firstIndex + 1);
221+ }
222+}
223+
224+void FlatMenuProxyModel::onRowsAboutToBeRemoved(const QModelIndex &index, int first, int last)
225+{
226+ if (index.isValid()) {
227+ int firstIndex = rowOffsetOf(index, first);
228+ int lastIndex = rowOffsetOf(index, last, true);
229+
230+ m_indexCache.clear();
231+ beginRemoveRows(QModelIndex(), firstIndex, lastIndex);
232+ m_rowCount -= (lastIndex - firstIndex + 1);
233+ }
234+}
235+
236+void FlatMenuProxyModel::onModelAboutToBeReset()
237+{
238+ beginResetModel();
239+}
240+
241+void FlatMenuProxyModel::onRowsInserted(const QModelIndex &index, int first, int last)
242+{
243+ if (index.isValid()) {
244+ m_indexCache.clear();
245+ endInsertRows();
246+ for (int i=first; i <= last; i++) {
247+ QModelIndex subIndex = sourceModel()->index(i, 0, index.parent());
248+ if (subIndex.isValid()) {
249+ int subSectionSize = recursiveRowCount(subIndex);
250+ if (subSectionSize > 0) {
251+ int firstIndex = rowOffsetOf(index, i) + 1;
252+ int lastIndex = rowOffsetOf(index, i, true);
253+
254+ beginInsertRows(QModelIndex(), firstIndex, lastIndex);
255+ m_rowCount += lastIndex - firstIndex + 1;
256+ endInsertRows();
257+ }
258+ }
259+ }
260+ }
261+ Q_EMIT countChanged();
262+}
263+
264+void FlatMenuProxyModel::onRowsRemoved(const QModelIndex &index, int, int)
265+{
266+ if (index.isValid()) {
267+ endRemoveRows();
268+ Q_EMIT countChanged();
269+ }
270+}
271+
272+void FlatMenuProxyModel::onModelReset()
273+{
274+ // initiliaze rowCount
275+ m_rowCount = 0;
276+ for (int i = 0, iMax = sourceModel()->rowCount(); i < iMax; i++) {
277+ QModelIndex index = sourceModel()->index(i, 0);
278+ m_rowCount += recursiveRowCount(index) + 1;
279+ }
280+ m_indexCache.clear();
281+ endResetModel();
282+ Q_EMIT countChanged();
283+}
284+
285+int FlatMenuProxyModel::recursiveRowCount(const QModelIndex &index) const
286+{
287+ int size = sourceModel()->rowCount(index);
288+ for (int i=0, iMax=size; i < iMax; i++) {
289+ QModelIndex currentIndex = sourceModel()->index(i, 0, index);
290+ size += recursiveRowCount(currentIndex);
291+ }
292+
293+ return size;
294+}
295+
296+int FlatMenuProxyModel::rowOffsetOf(const QModelIndex &index, int row, bool inclusive) const
297+{
298+ int offset = 0;
299+
300+ QModelIndex parent = index.parent();
301+
302+ // Check row 0 offset
303+ while(parent.isValid()) {
304+ offset += 1;
305+ for (int i = 0; i < parent.row(); i++) {
306+ QModelIndex currentIndex = sourceModel()->index(i, 0, parent);
307+ offset += recursiveRowCount(currentIndex) + 1;
308+ }
309+ parent = parent.parent();
310+ }
311+
312+ // Check index.row() offset
313+ for(int i = 0; i < row; i++) {
314+ QModelIndex currentIndex = sourceModel()->index(i, 0, index.parent());
315+ offset += recursiveRowCount(currentIndex) + 1;
316+ }
317+
318+ if (inclusive) {
319+ // itself
320+ QModelIndex currentIndex = sourceModel()->index(row, 0, index.parent());
321+ offset += recursiveRowCount(currentIndex);
322+ }
323+
324+ return offset;
325+}
plugins/IndicatorsClient/flatmenuproxymodel.hnew file+94
@@ -0,0 +1,94 @@
1+/*
2+ * Copyright 2012 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+ */
19+
20+#ifndef FLATMENUPROXYMODEL_H
21+#define FLATMENUPROXYMODEL_H
22+
23+#include <QAbstractProxyModel>
24+#include <qdbusmenumodel.h>
25+
26+class SectionInfo;
27+
28+class FlatMenuProxyModel : public QAbstractProxyModel
29+{
30+ Q_OBJECT
31+ Q_PROPERTY(int count READ count NOTIFY countChanged)
32+ Q_PROPERTY(int busType READ busType WRITE setIntBusType NOTIFY busTypeChanged)
33+ Q_PROPERTY(QString busName READ busName WRITE setBusName NOTIFY busNameChanged)
34+ Q_PROPERTY(QString objectPath READ objectPath WRITE setObjectPath NOTIFY objectPathChanged)
35+ Q_PROPERTY(int status READ status NOTIFY statusChanged)
36+
37+public:
38+ FlatMenuProxyModel(QAbstractItemModel *source=0);
39+ ~FlatMenuProxyModel();
40+
41+ void setSourceModel(QAbstractItemModel * sourceModel);
42+
43+ QModelIndex mapFromSource(const QModelIndex &index) const;
44+ QModelIndex mapToSource(const QModelIndex &index) const;
45+
46+ QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
47+ QModelIndex parent(const QModelIndex &index) const;
48+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
49+ int count() const;
50+ int columnCount(const QModelIndex &parent) const;
51+
52+ void setBusName(const QString &busName);
53+ QString busName() const;
54+
55+ void setObjectPath(const QString &busName);
56+ QString objectPath() const;
57+
58+ DBusEnums::BusType busType() const;
59+ void setIntBusType(int type);
60+
61+ int status() const;
62+
63+public Q_SLOTS:
64+ void onRowsInserted(const QModelIndex &parent, int start, int end);
65+ void onRowsAboutToBeInserted(const QModelIndex &parent, int start, int end);
66+
67+ void onRowsRemoved(const QModelIndex &parent, int start, int end);
68+ void onRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
69+
70+ void onModelAboutToBeReset();
71+ void onModelReset();
72+
73+ void start();
74+ void stop();
75+
76+Q_SIGNALS:
77+ void countChanged();
78+
79+ void busTypeChanged();
80+ void busNameChanged();
81+ void objectPathChanged();
82+ void statusChanged();
83+
84+private:
85+ QDBusMenuModel *m_model;
86+ mutable QMap<int, QString> m_indexCache;
87+ int m_rowCount;
88+
89+ int rowOffsetOf(const QModelIndex &index, int row, bool inclusive = false) const;
90+ int recursiveRowCount(const QModelIndex &index) const;
91+ QModelIndex index(int row, int rowCount, const QModelIndex &parent, const QString &key) const;
92+};
93+
94+#endif
plugins/IndicatorsClient/indicatorclientinterface.hnew file+137
@@ -0,0 +1,137 @@
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+ */
19+
20+#ifndef INDICATORCLIENTININTERFACE_H
21+#define INDICATORCLIENTININTERFACE_H
22+
23+#include <QMap>
24+#include <QString>
25+#include <QUrl>
26+#include <QObject>
27+#include <QQmlComponent>
28+#include <QQmlEngine>
29+#include <QSettings>
30+
31+#include <memory>
32+
33+class IndicatorClientInterface
34+{
35+public:
36+ typedef QMap<QString, QVariant> PropertiesMap;
37+ typedef QMap<QString, QUrl> WidgetsMap;
38+
39+ typedef std::shared_ptr<IndicatorClientInterface> Ptr;
40+
41+ enum IndicatorPriority {
42+ MESSAGING = 0,
43+ SOUND = 10,
44+ NETWORK = 20,
45+ POWER = 30,
46+ DATETIME = 100
47+ };
48+ /**
49+ * @brief This fuction will be called by PluginManager after create the plugin object
50+ * @param config The dbus configuration used by this plugin
51+ */
52+ virtual void init(const QSettings& settings) = 0;
53+
54+ /**
55+ * @brief This function will be called by PluginManager before destroy the plugin
56+ */
57+ virtual void shutdown() = 0;
58+
59+ /**
60+ * @brief Used to retrieve the current plugin icon
61+ * @return The icon url
62+ *
63+ * This function can be used to retrieve the indicator icon which will appear on the panel
64+ */
65+ virtual QUrl icon() const = 0;
66+
67+
68+ /**
69+ * @brief Used to retrieve the current plugin title
70+ * @return The title
71+ *
72+ * This function can be used to retrieve the indicator title which can be used as plugin name on the menu
73+ */
74+ virtual QString title() const = 0;
75+
76+ /**
77+ * @brief Used to retrieve the current plugin label
78+ * @return The label
79+ *
80+ * This function can be used to retrieve the indicator label which can appear in the panel
81+ */
82+ virtual QString label() const = 0;
83+
84+ /**
85+ * @brief Used to retrieve the current plugin label
86+ * @return The label
87+ *
88+ * This function can be used to retrieve the indicator description which can appear in the panel
89+ */
90+ virtual QString description() const = 0;
91+
92+ /**
93+ * @brief Used to retrieve the current plugin visibility
94+ * @return The visibility
95+ *
96+ * This function can be used to retrieve the indicator is visible on the panel or not
97+ */
98+ virtual bool visible() const = 0;
99+
100+ /**
101+ * @brief Used to retrieve the current plugin accessible name
102+ * @return The accessible name is plugin name as seen by assistive technologies
103+ */
104+ virtual QString accessibleName() const = 0;
105+
106+
107+ /**
108+ * @brief Used to retrieve the current plugin priority
109+ * @return The priorty value for the plugin, this will be used to arrange the plugin on the indicator panel
110+ */
111+ virtual int priority() const = 0;
112+
113+
114+ /**
115+ * @brief Used to retrieve the plugin initial component
116+ * @param engine The current \l QDeclarativeEngine used to parse the componente code
117+ * @param parent The parent of the returned object
118+ * @return A new \l QDeclarativeComponent with the initial plugin view
119+ */
120+ virtual QQmlComponent *component(QQmlEngine *engine, QObject *parent=0) = 0;
121+
122+ /**
123+ * @brief Used during the plugin Component instanciation to set the initial properties
124+ * @return The map with the initial property and value: {'property-name' : property-value}
125+ */
126+
127+ virtual PropertiesMap initialProperties() = 0;
128+
129+ /**
130+ * @brief The plugin should implement this function to return the custom widgets
131+ * implemente by the plugin
132+ * @return The map with the widget name and url: {'WifiAccessPointItem' : 'wifi-widget.qml'}
133+ */
134+ virtual WidgetsMap widgets() = 0;
135+};
136+
137+#endif
plugins/IndicatorsClient/indicators/CMakeLists.txtnew file+6
@@ -0,0 +1,6 @@
1+add_subdirectory(common)
2+add_subdirectory(messaging)
3+add_subdirectory(sound)
4+add_subdirectory(power)
5+add_subdirectory(datetime)
6+add_subdirectory(network)
plugins/IndicatorsClient/indicators/common/CMakeLists.txtnew file+32
@@ -0,0 +1,32 @@
1+project(indicatorclient_common)
2+
3+set(INDICATORCLIENT_COMMON_SRC
4+ indicatorclient_common.cpp
5+)
6+
7+set(INDICATORCLIENT_COMMON_RESOURCES
8+ indicatorclient_common.qrc
9+)
10+
11+qt5_add_resources(INDICATORCLIENT_COMMON_RESOURCES_RCC
12+ ${INDICATORCLIENT_COMMON_RESOURCES}
13+)
14+
15+add_library(indicatorclient_common STATIC
16+ ${INDICATORCLIENT_COMMON_RESOURCES_RCC}
17+ ${INDICATORCLIENT_COMMON_SRC}
18+)
19+
20+qt5_use_modules(indicatorclient_common Core Qml)
21+
22+set_target_properties(indicatorclient_common PROPERTIES COMPILE_FLAGS -fPIC)
23+
24+include_directories(
25+ ${CMAKE_CURRENT_SOURCE_DIR}
26+ ${QMENUMODEL_INCLUDE_DIRS}
27+ ${IndicatorsClientQml_SOURCE_DIR}
28+)
29+
30+target_link_libraries(indicatorclient_common
31+ ${QMENUMODEL_LDFLAGS}
32+)
plugins/IndicatorsClient/indicators/common/indicatorclient_common.cppnew file+303
@@ -0,0 +1,303 @@
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+ */
19+
20+#include "indicatorclient_common.h"
21+
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>
31+
32+#include <qdbusmenumodel.h>
33+#include <qdbusactiongroup.h>
34+#include <qstateaction.h>
35+
36+//TODO: load this property dynamically
37+#define TARGET_DEVICE "phone"
38+
39+IndicatorClientCommon::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)
48+{
49+}
50+
51+IndicatorClientCommon::~IndicatorClientCommon()
52+{
53+ shutdown();
54+}
55+
56+void IndicatorClientCommon::init(const QSettings& settings)
57+{
58+ Q_INIT_RESOURCE(indicatorclient_common);
59+
60+ QString dbusService = settings.value("Indicator Service/DBusName").toString();
61+ QString objectPath = settings.value("Indicator Service/ObjectPath").toString();
62+
63+ m_model = new QDBusMenuModel(this);
64+ m_model->setBusName(dbusService);
65+ m_model->setObjectPath(objectPath + "/" + TARGET_DEVICE);
66+ m_model->setBusType(DBusEnums::SessionBus);
67+
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()));
73+
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);
78+
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);
84+
85+ m_actionGroup->start();
86+ m_model->start();
87+}
88+
89+void IndicatorClientCommon::onModelChanged()
90+{
91+ DBusEnums::ConnectionStatus status = m_model->status();
92+
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+ }
106+}
107+
108+bool IndicatorClientCommon::parseRootElement(const QString &type, QMap<int, QVariant> data)
109+{
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+ }
121+
122+ QVariant action = data[QDBusMenuModel::Action];
123+ m_action = m_actionGroup->action(action.toString());
124+
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+ }
131+}
132+
133+void IndicatorClientCommon::updateState(const QVariant &state)
134+{
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+ }
146+
147+ setLabel("");
148+ setIcon(QUrl());
149+ setVisible(false);
150+ setAccessibleName("");
151+}
152+
153+void IndicatorClientCommon::shutdown()
154+{
155+ delete m_component;
156+ m_component = 0;
157+
158+ delete m_model;
159+ m_model = 0;
160+
161+ delete m_action;
162+ m_action = 0;
163+
164+ delete m_actionGroup;
165+ m_actionGroup = 0;
166+}
167+
168+QUrl IndicatorClientCommon::icon() const
169+{
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+ }
175+}
176+
177+void IndicatorClientCommon::setIcon(const QUrl &icon)
178+{
179+ if (icon != m_icon) {
180+ m_icon = icon;
181+ Q_EMIT iconChanged(m_icon);
182+ }
183+}
184+
185+QString IndicatorClientCommon::title() const
186+{
187+ return m_title;
188+}
189+
190+void IndicatorClientCommon::setTitle(const QString &title)
191+{
192+ if (title != m_title) {
193+ m_title = title;
194+ Q_EMIT titleChanged(m_title);
195+ }
196+}
197+
198+QString IndicatorClientCommon::description() const
199+{
200+ return m_description;
201+}
202+
203+void IndicatorClientCommon::setDescription(const QString &description)
204+{
205+ if (description != m_description) {
206+ m_description = description;
207+ Q_EMIT titleChanged(m_description);
208+ }
209+}
210+
211+int IndicatorClientCommon::priority() const
212+{
213+ return m_priority;
214+}
215+
216+void IndicatorClientCommon::setPriority(int priority)
217+{
218+ if (priority != m_priority) {
219+ m_priority = priority;
220+ Q_EMIT priorityChanged(m_priority);
221+ }
222+}
223+
224+QString IndicatorClientCommon::accessibleName() const
225+{
226+ return m_accessibleName;
227+}
228+
229+void IndicatorClientCommon::setAccessibleName(const QString &accesibleName)
230+{
231+ if (accesibleName != m_accessibleName) {
232+ m_accessibleName = accesibleName;
233+ Q_EMIT accessibleNameChanged(m_accessibleName);
234+ }
235+}
236+
237+bool IndicatorClientCommon::visible() const
238+{
239+ return m_visible;
240+}
241+
242+void IndicatorClientCommon::setVisible(bool visible)
243+{
244+ if (visible != m_visible) {
245+ m_visible = visible;
246+ Q_EMIT visibleChanged(m_visible);
247+ }
248+}
249+
250+QString IndicatorClientCommon::label() const
251+{
252+ return m_label;
253+}
254+
255+void IndicatorClientCommon::setLabel(const QString &label)
256+{
257+ if (label != m_label) {
258+ m_label = label;
259+ Q_EMIT labelChanged(m_label);
260+ }
261+}
262+
263+QDBusActionGroup *IndicatorClientCommon::actionGroup() const
264+{
265+ return m_actionGroup;
266+}
267+
268+QQmlComponent *IndicatorClientCommon::createComponent(QQmlEngine *engine, QObject *parent) const
269+{
270+ return new QQmlComponent(engine, QUrl("qrc:/indicatorsclient/qml/commonplugin.qml"), parent);
271+}
272+
273+QQmlComponent *IndicatorClientCommon::component(QQmlEngine *engine, QObject *parent)
274+{
275+ if (m_component == 0) {
276+ m_component = createComponent(engine, parent);
277+ }
278+ return m_component;
279+}
280+
281+IndicatorClientInterface::PropertiesMap IndicatorClientCommon::initialProperties()
282+{
283+ return m_initialProperties;
284+}
285+
286+IndicatorClientInterface::WidgetsMap IndicatorClientCommon::widgets()
287+{
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"));
294+
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;
303+}
plugins/IndicatorsClient/indicators/common/indicatorclient_common.hnew file+102
@@ -0,0 +1,102 @@
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+ * Nick Dedekind <nick.dedekind@canonical.com>
19+ */
20+
21+#ifndef INDICATORCLIENT_COMMON_H
22+#define INDICATORCLIENT_COMMON_H
23+
24+#include <indicatorclientinterface.h>
25+#include <QObject>
26+
27+class QDBusActionGroup;
28+class QDBusMenuModel;
29+class QStateAction;
30+
31+class IndicatorClientCommon : public QObject, public IndicatorClientInterface
32+{
33+ Q_OBJECT
34+ Q_PROPERTY(QString title READ title NOTIFY titleChanged)
35+ Q_PROPERTY(QString label READ label NOTIFY labelChanged)
36+ Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
37+ Q_PROPERTY(QUrl icon READ icon NOTIFY iconChanged)
38+ Q_PROPERTY(QString accessibleName READ accessibleName NOTIFY accessibleNameChanged)
39+ Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
40+ Q_PROPERTY(int priority READ priority NOTIFY priorityChanged)
41+
42+public:
43+ IndicatorClientCommon(QObject *parent = 0);
44+ ~IndicatorClientCommon();
45+
46+ void init(const QSettings& settings);
47+ void shutdown();
48+
49+ QUrl icon() const;
50+ QString title() const;
51+ bool visible() const;
52+ QString description() const;
53+ QString accessibleName() const;
54+ QString label() const;
55+ int priority() const;
56+
57+ QQmlComponent *component(QQmlEngine *engine, QObject *parent=0);
58+ PropertiesMap initialProperties();
59+ WidgetsMap widgets();
60+
61+Q_SIGNALS:
62+ void iconChanged(const QUrl &icon);
63+ void titleChanged(const QString &title);
64+ void visibleChanged(bool visible);
65+ void descriptionChanged(const QString &description);
66+ void accessibleNameChanged(const QString &assesibleName);
67+ void labelChanged(const QString &label);
68+ void priorityChanged(int priority);
69+
70+protected:
71+ PropertiesMap m_initialProperties;
72+
73+ void setIcon(const QUrl &icon);
74+ void setTitle(const QString &title);
75+ void setDescription(const QString &description);
76+ void setVisible(bool visible);
77+ void setAccessibleName(const QString &accessibleName);
78+ void setLabel(const QString &title);
79+ void setPriority(int priority);
80+ virtual bool parseRootElement(const QString &type, QMap<int, QVariant> data);
81+ virtual QQmlComponent *createComponent(QQmlEngine *engine, QObject *parent=0) const;
82+ QDBusActionGroup *actionGroup() const;
83+
84+private Q_SLOTS:
85+ void onModelChanged();
86+ void updateState(const QVariant &state);
87+
88+private:
89+ QUrl m_icon;
90+ QString m_title;
91+ QString m_description;
92+ QString m_accessibleName;
93+ QString m_label;
94+ bool m_visible;
95+ int m_priority;
96+ QDBusMenuModel *m_model;
97+ QDBusActionGroup *m_actionGroup;
98+ QStateAction *m_action;
99+ QQmlComponent *m_component;
100+};
101+
102+#endif // INDICATORCLIENT_COMMON_H
plugins/IndicatorsClient/indicators/common/indicatorclient_common.qrcnew file+5
@@ -0,0 +1,5 @@
1+<RCC>
2+ <qresource prefix="/indicatorsclient">
3+ <file>qml/commonplugin.qml</file>
4+ </qresource>
5+</RCC>
plugins/IndicatorsClient/indicators/common/qml/commonplugin.qmlnew file+24
@@ -0,0 +1,24 @@
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+ */
19+
20+import IndicatorsClient 0.1 as IndicatorsClient
21+
22+IndicatorsClient.PluginItem {
23+ anchors.fill: parent
24+}
plugins/IndicatorsClient/indicators/datetime/CMakeLists.txtnew file+29
@@ -0,0 +1,29 @@
1+set(INDICATORCLIENT_DATETIME_SRC
2+ indicatorclient_datetime.cpp
3+)
4+
5+qt5_add_resources(INDICATORCLIENT_DATETIME_RESOURCES_RCC
6+ indicatorclient_datetime.qrc
7+)
8+
9+add_library(indicatorclient_datetime STATIC
10+ ${INDICATORCLIENT_DATETIME_RESOURCES_RCC}
11+ ${INDICATORCLIENT_DATETIME_SRC}
12+)
13+
14+qt5_use_modules(indicatorclient_datetime Core Qml)
15+
16+set_target_properties(indicatorclient_datetime PROPERTIES COMPILE_FLAGS -fPIC)
17+
18+include_directories(
19+ ${CMAKE_CURRENT_SOURCE_DIR}
20+ ${QMENUMODEL_INCLUDE_DIRS}
21+ ${indicatorclient_common_SOURCE_DIR}
22+ ${IndicatorsClientQml_SOURCE_DIR}
23+)
24+
25+target_link_libraries(indicatorclient_datetime
26+ indicatorclient_common
27+ ${QMENUMODEL_LDFLAGS}
28+)
29+
plugins/IndicatorsClient/indicators/datetime/artwork/time_and_date@18.pngnew file

Binary file not shown.

plugins/IndicatorsClient/indicators/datetime/indicatorclient_datetime.cppnew file+123
@@ -0,0 +1,123 @@
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+ * Ubo Riboni <ugo.riboni@canonical.com>
19+ */
20+
21+#include "indicatorclient_datetime.h"
22+
23+#include <qdbusmenumodel.h>
24+#include <qdbusactiongroup.h>
25+#include <qstateaction.h>
26+#include <QDateTime>
27+#include <QDebug>
28+
29+IndicatorClientDateTime::IndicatorClientDateTime(QObject *parent)
30+ : IndicatorClientCommon(parent),
31+ m_action(0)
32+{
33+ setTitle("Date and Time");
34+ setPriority(IndicatorPriority::DATETIME);
35+
36+ connect(&m_timer, SIGNAL(timeout()), SLOT(onTimeout()));
37+}
38+
39+IndicatorClientDateTime::~IndicatorClientDateTime()
40+{
41+ if (m_action) {
42+ delete m_action;
43+ }
44+}
45+
46+void IndicatorClientDateTime::init(const QSettings& settings)
47+{
48+ IndicatorClientCommon::init(settings);
49+ Q_INIT_RESOURCE(indicatorclient_datetime);
50+
51+ m_timer.start(1000 * 10);
52+}
53+
54+void IndicatorClientDateTime::shutdown()
55+{
56+ m_timer.stop();
57+}
58+
59+
60+QString IndicatorClientDateTime::dateTime() const
61+{
62+ static char timestr[255];
63+ time_t t;
64+ struct tm *tmp;
65+
66+ t = time(NULL);
67+ tmp = localtime(&t);
68+ if (tmp == 0) {
69+ return "";
70+ }
71+
72+ int size = strftime(timestr, 255, m_format.toUtf8().data(), tmp);
73+ if (size == 0) {
74+ return "";
75+ }
76+
77+ return QString::fromLatin1(timestr, size);
78+}
79+
80+bool IndicatorClientDateTime::parseRootElement(const QString &type, QMap<int, QVariant> data)
81+{
82+ if (type == "com.canonical.indicator.root.time") {
83+ if (m_action != 0) {
84+ delete m_action;
85+ }
86+
87+ QVariant action = data[QDBusMenuModel::Action];
88+ m_action = actionGroup()->action(action.toString());
89+ if (m_action->isValid()) {
90+ updateTimeFormat(m_action->state());
91+ }
92+ QObject::connect(m_action, SIGNAL(stateChanged(QVariant)), this, SLOT(updateTimeFormat(QVariant)));
93+ return true;
94+ } else {
95+ return false;
96+ }
97+}
98+
99+void IndicatorClientDateTime::updateTimeFormat(const QVariant &state)
100+{
101+ if (state.isValid()) {
102+ // (sssb) : time format, icon, accessible name format, visible
103+ QVariantList states = state.toList();
104+ if (states.size() == 4) {
105+ m_format = states[0].toString();
106+ setIcon(QUrl(states[1].toString()));
107+ setVisible(states[2].toBool());
108+ setAccessibleName(states[3].toString());
109+ onTimeout();
110+ }
111+ }
112+}
113+
114+QQmlComponent *IndicatorClientDateTime::createComponent(QQmlEngine *engine, QObject *parent) const
115+{
116+ return new QQmlComponent(engine, QUrl("qrc:/indicatorsclient/datetime/qml/ClockPage.qml"), parent);
117+}
118+
119+void IndicatorClientDateTime::onTimeout()
120+{
121+ QString newValue = dateTime();
122+ setLabel(newValue);
123+}
plugins/IndicatorsClient/indicators/datetime/indicatorclient_datetime.hnew file+53
@@ -0,0 +1,53 @@
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+ * Ubo Riboni <ugo.riboni@canonical.com>
19+ */
20+
21+#ifndef INDICATORCLIENT_DATETIME_H
22+#define INDICATORCLIENT_DATETIME_H
23+
24+#include "indicatorclient_common.h"
25+#include <QTimer>
26+#include <QDateTime>
27+
28+class QStateAction;
29+
30+class IndicatorClientDateTime : public IndicatorClientCommon
31+{
32+ Q_OBJECT
33+public:
34+ IndicatorClientDateTime(QObject *parent=0);
35+ ~IndicatorClientDateTime();
36+
37+ void init(const QSettings& settings);
38+ void shutdown();
39+ QString dateTime() const;
40+ bool parseRootElement(const QString &type, QMap<int, QVariant> data);
41+ QQmlComponent *createComponent(QQmlEngine *engine, QObject *parent=0) const;
42+
43+private Q_SLOTS:
44+ void onTimeout();
45+ void updateTimeFormat(const QVariant &state);
46+
47+private:
48+ QTimer m_timer;
49+ QString m_format;
50+ QStateAction *m_action;
51+};
52+
53+#endif
plugins/IndicatorsClient/indicators/datetime/indicatorclient_datetime.qrcnew file+6
@@ -0,0 +1,6 @@
1+<RCC>
2+ <qresource prefix="/indicatorsclient/datetime">
3+ <file>qml/ClockPage.qml</file>
4+ <file>artwork/time_and_date@18.png</file>
5+ </qresource>
6+</RCC>
plugins/IndicatorsClient/indicators/datetime/qml/ClockPage.qmlnew file+98
@@ -0,0 +1,98 @@
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+ * Ubo Riboni <ugo.riboni@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+
24+Flickable {
25+ id: page
26+
27+ contentHeight: image.height
28+
29+ Image {
30+ id: image
31+ anchors {
32+ left: parent.left
33+ right: parent.right
34+ }
35+ source: "qrc:/indicatorsclient/datetime/artwork/time_and_date@18.png"
36+ fillMode: Image.PreserveAspectFit
37+ }
38+
39+ Item {
40+ anchors {
41+ top: parent.top
42+ topMargin: units.gu(5)
43+ left: parent.left
44+ right: parent.right
45+ }
46+
47+ height: units.gu(30)
48+
49+ Label {
50+ id: __time
51+ anchors {
52+ horizontalCenter: parent.horizontalCenter
53+ verticalCenter: parent.verticalCenter
54+ }
55+
56+ text: ""
57+ color: "#f3f3e7"
58+ font.weight: Font.Light
59+ font.pixelSize: units.gu(6)
60+ }
61+
62+ Label {
63+ id: __date
64+
65+ anchors {
66+ left: parent.left
67+ leftMargin: units.gu(2)
68+ bottom: parent.bottom
69+ bottomMargin: units.gu(1.5)
70+ }
71+ text: ""
72+ color: "#f3f3e7"
73+ fontSize: "small"
74+ }
75+ }
76+
77+ Timer {
78+ interval: 1000 * 60 // one minute
79+ running: true
80+ repeat: true
81+ onTriggered: updateTime();
82+
83+ Component.onCompleted: updateTime();
84+ }
85+
86+ function updateTime() {
87+ var dt = new Date()
88+ var time = Qt.formatTime(dt)
89+ var space = time.indexOf(" ")
90+ __time.text = time.substr(0, space > 0 ? space : 5)
91+ __date.text = Qt.formatDateTime(dt, "dddd,\ndd MMMM")
92+ }
93+
94+ // Make it compatible with the PluginItem interface
95+ function start() {}
96+ function stop() {}
97+ function reset() {}
98+}
plugins/IndicatorsClient/indicators/messaging/CMakeLists.txtnew file+28
@@ -0,0 +1,28 @@
1+set(INDICATORCLIENT_MESSAGING_SRC
2+ indicatorclient_messaging.cpp
3+)
4+
5+qt5_add_resources(INDICATORCLIENT_MESSAGING_RESOURCES_RCC
6+ indicatorclient_messaging.qrc
7+)
8+
9+add_library(indicatorclient_messaging STATIC
10+ ${INDICATORCLIENT_MESSAGING_RESOURCES_RCC}
11+ ${INDICATORCLIENT_MESSAGING_SRC}
12+)
13+
14+qt5_use_modules(indicatorclient_messaging Core Qml)
15+
16+set_target_properties(indicatorclient_messaging PROPERTIES COMPILE_FLAGS -fPIC)
17+
18+include_directories(
19+ ${CMAKE_CURRENT_SOURCE_DIR}
20+ ${indicatorclient_common_SOURCE_DIR}
21+ ${IndicatorsClientQml_SOURCE_DIR}
22+)
23+
24+target_link_libraries(indicatorclient_messaging
25+ indicatorclient_common
26+ ${QMENUMODEL_LDFLAGS}
27+)
28+
plugins/IndicatorsClient/indicators/messaging/artwork/default_app.svgnew file+42
@@ -0,0 +1,42 @@
1+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+<!-- Created with Inkscape (http://www.inkscape.org/) -->
3+<svg id="svg15137" xmlns="http://www.w3.org/2000/svg" height="48" width="48" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
4+ <defs id="defs15139">
5+ <radialGradient id="radialGradient2612" gradientUnits="userSpaceOnUse" cy="4.625" cx="62.625" gradientTransform="matrix(1 0 0 .34118 0 3.0471)" r="10.625">
6+ <stop id="stop8840" offset="0"/>
7+ <stop id="stop8842" style="stop-opacity:0" offset="1"/>
8+ </radialGradient>
9+ <linearGradient id="linearGradient15133" y2=".24326" gradientUnits="userSpaceOnUse" x2="62.2" gradientTransform="matrix(2.1499 0 0 2.1499 -110.12 31.935)" y1="-12.489" x1="62.2">
10+ <stop id="stop4875" style="stop-color:#fff" offset="0"/>
11+ <stop id="stop4877" style="stop-color:#fff;stop-opacity:0" offset="1"/>
12+ </linearGradient>
13+ <radialGradient id="radialGradient15127" gradientUnits="userSpaceOnUse" cy="-8.7256" cx="62.2" gradientTransform="matrix(2.4129 0 0 2.413 -126.48 34.231)" r="9.7553">
14+ <stop id="stop8649" style="stop-color:#8fb1dc" offset="0"/>
15+ <stop id="stop8651" style="stop-color:#3465a4" offset="1"/>
16+ </radialGradient>
17+ <radialGradient id="radialGradient2418" gradientUnits="userSpaceOnUse" cy="24.149" cx="17.814" gradientTransform="matrix(-2.644 0 2.9365e-8 2.5344 78.725 -37.986)" r="9.125">
18+ <stop id="stop4847" style="stop-color:#fff" offset="0"/>
19+ <stop id="stop4849" style="stop-color:#b6b6b6" offset="1"/>
20+ </radialGradient>
21+ <radialGradient id="radialGradient5145" gradientUnits="userSpaceOnUse" cy="13.067" cx="23.86" gradientTransform="matrix(-1.5425 0 0 -.84553 60.718 23.829)" r="18.098">
22+ <stop id="stop14112" style="stop-color:#557695" offset="0"/>
23+ <stop id="stop14114" style="stop-color:#15395c" offset="1"/>
24+ </radialGradient>
25+ <radialGradient id="radialGradient5147" gradientUnits="userSpaceOnUse" cy="-3.442" cx="62.225" gradientTransform="matrix(1.1035 0 0 1.0265 -4.1555 -1.8158)" r="10.081">
26+ <stop id="stop14118" style="stop-color:#9e9e9e" offset="0"/>
27+ <stop id="stop14120" style="stop-color:#9e9e9e;stop-opacity:0" offset="1"/>
28+ </radialGradient>
29+ </defs>
30+ <g id="layer1">
31+ <path id="path8836" style="opacity:.4;fill-rule:evenodd;fill:url(#radialGradient2612)" d="m73.25 4.625a10.625 3.625 0 1 1 -21.25 0 10.625 3.625 0 1 1 21.25 0z" transform="matrix(2.1647 0 0 2.5637 -111.56 26.85)"/>
32+ <g id="g15122" transform="translate(.79042 -.78563)">
33+ <path id="path6495" style="stroke:#204a87;fill:url(#radialGradient15127)" d="m43.505 24.387c0 10.99-8.9091 19.899-19.897 19.899-10.989 0-19.898-8.9091-19.898-19.899 0-10.989 8.9086-19.897 19.898-19.897 10.988 0 19.897 8.9081 19.897 19.897z"/>
34+ <path id="path6534" style="stroke:url(#radialGradient5147);stroke-width:1.1035;fill:url(#radialGradient5145)" d="m23.726 5.3141c-1.5283 0.12067-3.0328 0.36544-4.4919 0.84567-1.23 0.48843 0.88689-0.42988-0.37486-0.60468-0.75942-0.12994-1.0776 0.65251-1.7561 0.67046-0.7741 0.023841-1.3048 0.71572-2.0319 0.79898-0.26187 1.4432-0.59924-0.56894-0.83949 0.13173 0.19047 0.7212-0.07796 1.1928-0.63582 1.6119-0.60156 0.68249-0.03584 1.2934 0.54212 0.69395 0.2775-0.83446 1.1825-1.7618 2.0655-1.2049 0.8837 0.48448 1.7582 1.6525 2.4938 0.40935-0.75488-0.090735-1.0462-0.73637-1.4079-1.2096-0.40023 0.031761-2.0794-0.32019-1.0059-0.24024 0.5284-0.17249 1.549-0.68558 1.9239-0.66537-0.94013 0.49026 0.35015 0.81268 0.73202 1.2035 0.68671 0.20357 0.99776 1.0757 0.37414 1.527-0.80181 0.4162 0.05573 1.1017 0.221 1.6748 0.12828 0.99827 0.99623 0.43282 1.2716-0.18046 0.39803-1.1153 1.6733-1.0767 2.5958-1.5522 1.008-0.51754 1.0248-0.53575 1.5034 0.20195 0.36764 0.21151 1.5947-0.55825 0.78901-0.929-0.68957 0.03713-1.142 0.46029-0.56364-0.60801 0.13915-0.57404 0.6791-1.3235 0.58092-1.7937-0.662-0.2603-1.324-0.5207-1.986-0.7811zm-9.3732 3.6945c0.35612 0.3643 1.5564 1.0234 1.4368 0.11255-0.14419-0.61744-1.0418-0.62308-1.4368-0.11255zm18.165-0.44471c-0.82412 0.16922-1.6412 0.35467-2.292 0.92363 0.19457 0.7853-0.8341 0.89786-1.2851 1.3281-0.12036 0.25242-0.02467 1.8403 0.51105 1.1573 0.58162-0.77246 0.83368 0.40868 1.4478 0.52687 0.4451-0.14324 0.5002-1.1438 0.33275-1.6043 0.28525-0.46984 0.75058-1.1195 1.3539-1.0659-0.37419 0.57099-0.80163 2.0315 0.3911 1.4345 0.34518-0.006-0.93958 0.75452-1.0166 1.273-0.48258 0.51284-0.9934 0.90587-1.6905 0.50847-0.33355-0.28162-0.50305-1.0992-0.71414-0.17566 0.43341 0.73252-1.089 0.04718-1.0514 1.0356-0.31972 0.61514-0.89623 0.8671-1.563 0.91149 0.24198 0.19141 1.1924 1.3314 0.24953 1.1701-0.60352 0.06628-1.4857 0.40701-1.2414 1.1653-0.27486 0.9444 0.4249 0.70654 0.85522 1.2977 0.70116-0.19916 1.1488-0.62908 1.2634-1.3621 0.65618-0.19273 0.73557-0.93195 1.456-0.91702 0.7182-0.40381 0.88559 0.73738 1.5587 0.82181 0.07058 0.4087-0.33464 1.281 0.45659 0.4693 0.76441-0.55387-0.79512-1.2716-0.30963-1.4066 0.69099 0.22071 0.94006 0.87671 1.051 1.519 0.56306 0.9634 0.70185 0.44404 0.74672-0.40362 0.87723-0.39439 1.1473 1.641 2.3881 1.1397 0.92678 0.19174 0.59949 0.8304-0.01904 1.2203-0.50066 0.47112-1.3382 0.17338-1.9265-0.01558-0.56472-0.27756-1.3196-0.24813-1.6214 0.38347-0.46529-0.21764-0.94642-0.91135-1.4178-1.3118-1.1647-0.5139-2.4314-0.07571-3.5919 0.23946-0.99563 1.1632-2.1949 2.219-2.6236 3.7359-0.62778 0.63853 0.54336 1.0082-0.24392 1.556-0.6428 0.51279 0.10805 1.1629 0.2458 1.7527 0.60445 0.74395 1.6306 3.0723 2.5708 2.1452 0.52705-0.80245 0.81963 0.61582 1.4399-0.30194 0.4952-0.39949 0.9695 0.45802 1.6897 0.14331 0.69372 0.4284 0.56095 1.0433 0.27484 1.6928 0.15583 0.54087 0.93098 0.9344 0.62978 1.6677-0.27366 0.68309 0.58312 1.201 0.41038 1.7987-0.5748 1.1512-0.43928 2.5747 0.09386 3.7157 0.42668 1.0325 0.67699 2.1484 0.64366 3.2692 0.74277 0.2222 1.1367-0.72912 1.8776-0.51313 0.72333 0.09324 0.99191-0.82974 1.5008-1.2158 0.56704-0.46747-0.07223-1.1873 0.82794-1.5185 0.87331-0.42523-1.106-1.0213 0.0152-1.4024 0.46515-0.51761 1.4132-0.69776 1.6008-1.3735-0.33834-1.0398-0.21797-2.1801-0.16738-3.2436 0.32552-0.84167 0.72975-1.6312 1.4262-2.2272 0.28082-0.92669 0.94924-1.7777 0.88942-2.7709-1.6476 0.50399-1.1482-0.21491-0.22962-0.87318 0.63508-0.42199 1.4051-0.84564 1.7006-1.5617 0.14435-0.81048-0.45227-2.1297-1.0079-0.90496-0.24511-0.4707-1.1542-0.71744-1.113-1.3307-0.17659-1.2625 0.34462-0.14427 0.86051 0.10789 1.1146-0.60521 1.6818 1.7766 2.3893 0.35503-0.618-4.471-3.052-8.528-6.34-11.567-0.571-1.0949-0.921 0.75-1.501 0.68-0.464-0.485-1.33-1.1394-0.122-0.914 1.034-0.3028 0.333-0.7027-0.425-0.6842-0.574-0.0697-1.101-0.2706-1.635-0.4789zm-20.56 0.4447c-0.275 1.3534-2.0109 1.1954-2.6162 2.5304-2.9783 3.153-4.8166 7.302-5.32 11.598 0.26584 1.0071 1.1105 1.4908 1.9601 1.9373 0.72184 0.41932 1.7801 0.2342 2.1848 1.1124 0.45187 0.36983 0.93948 1.0997 1.5856 0.87722 0.93664-0.09099 0.36019 0.85823 0.19973 1.3392-0.059277 0.607-0.80778 0.99372-0.52016 1.5778-0.24136 0.66166-0.43304 1.3177 0.10262 1.8906 0.45551 0.83988 0.82632 1.7478 1.6708 2.2751 0.59217 0.49728 1.2625 1.1553 1.0304 1.9974-0.12338 0.68167 0.04306 1.3099 0.3725 1.908-0.11816 0.67146-0.36073 1.3584-0.4105 2.0183 0.87949 0.62206 2.6705 2.0606 2.8031 0.49489 0.50176-0.45161 0.5321-1.1784 1.3743-1.1804 0.3909-0.47777 0.52549-1.2283 0.81706-1.8117-0.42572-0.5384 0.16631-1.3697 0.8046-1.3477 0.81594 0.06128 0.78593-0.89448 1.1111-1.4232-0.0073-0.77224-0.38892-1.6471 0.30542-2.227 0.52242-0.47344 0.46827-1.1675 0.5498-1.8097-1.171-0.7244-2.712-1.0911-3.6386-2.0687-0.18364-0.76504-0.7598-1.0229-1.4925-1.0784-0.30936-0.43256-0.25697-1.4628-0.79753-1.5131-0.69628 0.13369-1.3857 0.24089-1.8917-0.3644-0.573-0.776-1.069 0.2-1.593 0.546-0.492 0.856-1.8683-0.043-1.7038-1.007 0.4839-1.334-1.6425 0.148-0.7699-1.425 0.4151-1.715-0.7067-0.396-1.2952-0.011-0.71822 0.0081-0.98953-0.70747-0.86146-1.3625-0.091117-0.78733 0.48283-1.1877 1.0669-1.5822 0.78161 0.12038 0.97989-0.56085 1.5654-0.4722 0.73603-0.03767 1.0049 0.66782 1.4232 1.1357 0.17514-0.66797-0.18345-1.6152 0.55606-1.9879 0.56414-0.42781 1.137-0.84927 1.2721-1.5904 0.13304-0.77598 1.2893-0.46761 1.4837-1.2526 0.26877-0.8206 1.5114-0.15823 1.7899-0.96804 0.8733-0.82086-0.27242-0.57178-0.89854-0.59806-1.2353 0.12695 0.1228-0.32763 0.58598-0.58155 0.68608 0.09073 1.3195-0.13384 1.9499-0.37629 0.08445 0.85843 0.24597 1.3112 0.68417 0.30788-0.85421-0.20211-0.11618-1.0402-0.95973-1.2614-0.66764 0.04697 0.0066-1.4189-0.81571-1.2577-1.0697 0.70782-0.11401-0.50251-0.9854-0.66347-0.68736-0.74222-0.85436 0.47657-1.2276 0.9183 0.24207 0.84702-0.79095 0.66525-0.97976 1.3606-0.41814 1.2534-0.24143-0.08931-0.74055-0.41035-0.61653-0.24732-1.3592-0.3784-1.3637-1.1899 0.82658-0.60512 2.0667-0.96189 2.5994-1.9148 0.3095-0.74008-0.26215-1.1445-0.96618-1.0889l-0.000005-2e-7zm14.675 1.642c-0.12491 0.65746 0.5475 1.009 0.30788 1.7104-0.21487 0.76842-0.27728 1.3789 0.68289 0.93046 0.99668-0.51183 0.36052-0.90148-0.03867-1.5728-0.27187-0.44613-0.24574-1.275-0.9521-1.0681zm-0.75259 1.0947c-0.79414-0.24012-0.61745 1.4493-0.12164 1.0118 0.7276-0.17916 0.23703-0.5252 0.12164-1.0118zm10.023 8.9969c0.95184 0.84444 1.277 2.0946 1.8858 3.1596 0.90428 0.39972 0.0415 1.0795 0.44521 1.5712 0.84897 0.92228-1.1752 0.24516-0.90606-0.67899-0.1971-1.2139-1.0559-2.044-1.4678-3.1045-0.04294-0.3526-0.38552-0.71788 0.04284-0.94732z"/>
35+ <path id="path8655" style="opacity:.4;stroke:url(#linearGradient15133);fill:none" d="m42.409 24.387c0 10.384-8.4184 18.803-18.801 18.803-10.384 0-18.802-8.4184-18.802-18.803 0-10.384 8.418-18.801 18.802-18.801 10.383 0 18.801 8.4175 18.801 18.801z"/>
36+ </g>
37+ <g id="g2414" transform="matrix(.99991 -.013701 .013701 .99991 -.28870 .53585)">
38+ <path id="path3970" style="stroke-linejoin:round;fill-rule:evenodd;stroke:#666;fill:url(#radialGradient2418)" d="m30.5 20.937 17 16.5-7.75 0.25s3.25 6.75 3.25 6.75c1 3-3.5 4.125-4.25 1.875l-3-6.75-5.5 5.875 0.25-24.5z"/>
39+ <path id="path4853" style="opacity:.4;stroke:#fff;fill:none" d="m31.657 23.379 13.476 13.186-6.9219 0.27746l3.8721 7.7566c0.40273 1.6501-2.0283 2.4126-2.5071 1.1529l-3.6831-7.845-4.4247 4.7083 0.18907-19.236z"/>
40+ </g>
41+ </g>
42+</svg>
plugins/IndicatorsClient/indicators/messaging/artwork/default_contact.pngnew file

Binary file not shown.

plugins/IndicatorsClient/indicators/messaging/artwork/message_sms01_54px.pngnew file

Binary file not shown.

plugins/IndicatorsClient/indicators/messaging/indicatorclient_messaging.cppnew file+61
@@ -0,0 +1,61 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+#include "indicatorclient_messaging.h"
22+
23+#include <QUrl>
24+#include <QtPlugin>
25+
26+IndicatorClientMessaging::IndicatorClientMessaging(QObject *parent)
27+ : IndicatorClientCommon(parent)
28+{
29+ setTitle("Messages");
30+ setPriority(IndicatorPriority::MESSAGING);
31+}
32+
33+IndicatorClientMessaging::~IndicatorClientMessaging()
34+{
35+}
36+
37+void IndicatorClientMessaging::init(const QSettings& settings)
38+{
39+ IndicatorClientCommon::init(settings);
40+ Q_INIT_RESOURCE(indicatorclient_messaging);
41+
42+ m_initialProperties.insert("emptyText", "You have no more outstanding messages.");
43+ m_initialProperties.insert("highlightFollowsCurrentItem", false);
44+}
45+
46+QQmlComponent *IndicatorClientMessaging::createComponent(QQmlEngine *engine, QObject *parent) const
47+{
48+ return new QQmlComponent(engine, QUrl("qrc:/indicatorsclient/messaging/qml/messagingplugin.qml"), parent);
49+}
50+
51+IndicatorClientInterface::WidgetsMap IndicatorClientMessaging::widgets()
52+{
53+ static WidgetsMap w;
54+ if (w.isEmpty()) {
55+ w.insert("com.canonical.indicator.messages.messageitem", QUrl("qrc:/indicatorsclient/messaging/qml/MessageItem.qml"));
56+ w.insert("com.canonical.indicator.messages.snapdecision", QUrl("qrc:/indicatorsclient/messaging/qml/MessageItem.qml"));
57+ w.insert("com.canonical.indicator.messages.sourceitem", QUrl("qrc:/indicatorsclient/messaging/qml/GroupedMessage.qml"));
58+ }
59+ return w;
60+}
61+
plugins/IndicatorsClient/indicators/messaging/indicatorclient_messaging.hnew file+38
@@ -0,0 +1,38 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+#ifndef INDICATORCLIENT_MESSAGING_H
22+#define INDICATORCLIENT_MESSAGING_H
23+
24+#include "indicatorclient_common.h"
25+
26+class IndicatorClientMessaging : public IndicatorClientCommon
27+{
28+ Q_OBJECT
29+public:
30+ IndicatorClientMessaging(QObject *parent=0);
31+ ~IndicatorClientMessaging();
32+
33+ void init(const QSettings& settings);
34+ QQmlComponent* createComponent(QQmlEngine *engine, QObject *parent) const;
35+ WidgetsMap widgets();
36+};
37+
38+#endif
plugins/IndicatorsClient/indicators/messaging/indicatorclient_messaging.qrcnew file+19
@@ -0,0 +1,19 @@
1+<RCC>
2+ <qresource prefix="/indicatorsclient/messaging">
3+ <file>qml/ActionButton.qml</file>
4+ <file>qml/ActionTextField.qml</file>
5+ <file>qml/HeroMessageHeader.qml</file>
6+ <file>qml/HeroMessage.qml</file>
7+ <file>qml/MessageItem.qml</file>
8+ <file>qml/TextMessage.qml</file>
9+ <file>qml/SimpleTextMessage.qml</file>
10+ <file>qml/SnapDecision.qml</file>
11+ <file>qml/QuickReply.qml</file>
12+ <file>qml/GroupedMessage.qml</file>
13+ <file>qml/utils.js</file>
14+ <file>artwork/default_contact.png</file>
15+ <file>artwork/default_app.svg</file>
16+ <file>artwork/message_sms01_54px.png</file>
17+ <file>qml/messagingplugin.qml</file>
18+ </qresource>
19+</RCC>
plugins/IndicatorsClient/indicators/messaging/qml/ActionButton.qmlnew file+33
@@ -0,0 +1,33 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+
24+Button {
25+ property variant action: null
26+ property variant actionParameter: null
27+
28+ onClicked: {
29+ if (action && action.valid) {
30+ action.activate(actionParameter)
31+ }
32+ }
33+}
plugins/IndicatorsClient/indicators/messaging/qml/ActionTextField.qmlnew file+60
@@ -0,0 +1,60 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+
24+Item {
25+ property alias action: __sendButton.action
26+ property alias text: __replyField.text
27+ property alias buttonText: __sendButton.text
28+
29+ TextField {
30+ id: __replyField
31+
32+ anchors.top: parent.top
33+ anchors.bottom: parent.bottom
34+ anchors.left: parent.left
35+ anchors.right: __sendButton.left
36+ anchors.rightMargin: units.gu(1)
37+ placeholderText: "Reply"
38+ hasClearButton: false
39+
40+ onEnabledChanged: {
41+ //Make sure that the component lost focus when enabled = false,
42+ //otherwise it will get focus again when enable = true
43+ if (!enabled) {
44+ focus = false
45+ }
46+ }
47+ }
48+
49+ ActionButton {
50+ id: __sendButton
51+
52+ actionParameter: __replyField.text
53+ anchors.top: parent.top
54+ anchors.bottom: parent.bottom
55+ anchors.right: parent.right
56+ width: units.gu(9)
57+ enabled: __replyField.text !== ""
58+ color: enabled ? "#c94212" : "#bababa"
59+ }
60+}
plugins/IndicatorsClient/indicators/messaging/qml/GroupedMessage.qmlnew file+92
@@ -0,0 +1,92 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+import IndicatorsClient 0.1 as IndicatorsClient
24+
25+IndicatorsClient.RemovableMenu {
26+ property variant action: menu && actionGroup ? actionGroup.action(menu.action) : undefined
27+ property alias count: label.text
28+
29+ color: "#221e1b"
30+ implicitHeight: units.gu(10)
31+
32+ onSwipingChanged: listView.interactive = !swiping
33+
34+ Row {
35+ anchors.fill: parent
36+ anchors.margins: units.gu(2)
37+ spacing: units.gu(4)
38+
39+ UbuntuShape {
40+ height: units.gu(6)
41+ width: units.gu(6)
42+ image: Image {
43+ source: menu && (menu.extra.canonical_icon.length > 0) ? "image://gicon/" + encodeURI(menu.extra.canonical_icon) : "qrc:/indicatorsclient/messaging/artwork/default_app.svg"
44+ fillMode: Image.PreserveAspectFit
45+ }
46+ }
47+
48+ Label {
49+ anchors.verticalCenter: parent.verticalCenter
50+ color: "#e8e1d0"
51+ font.weight: Font.DemiBold
52+ fontSize: "medium"
53+ text: menu && menu.label ? menu.label : ""
54+ }
55+
56+ Label {
57+ id: label
58+ anchors.verticalCenter: parent.verticalCenter
59+ width: parent.width - x
60+ horizontalAlignment: Text.AlignRight
61+ color: "#e8e1d0"
62+ font.weight: Font.DemiBold
63+ fontSize: "medium"
64+ text: action && action.valid && action.state ? action.state[0] : "0"
65+ }
66+ }
67+
68+ IndicatorsClient.HLine {
69+ anchors.top: parent.top
70+ color: "#403b37"
71+ }
72+
73+ IndicatorsClient.HLine {
74+ anchors.bottom: parent.bottom
75+ color: "#060606"
76+ }
77+
78+ MouseArea {
79+ anchors.fill: parent
80+ onClicked: {
81+ if (action && action.valid) {
82+ action.activate(true)
83+ }
84+ }
85+ }
86+
87+ onItemRemoved: {
88+ if (action && action.valid) {
89+ action.activate(false)
90+ }
91+ }
92+}
plugins/IndicatorsClient/indicators/messaging/qml/HeroMessage.qmlnew file+115
@@ -0,0 +1,115 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+import IndicatorsClient 0.1 as IndicatorsClient
24+
25+IndicatorsClient.BasicMenu {
26+ id: __heroMessage
27+
28+ property variant actionsDescription: null
29+ property variant action: menu && actionGroup ? actionGroup.action(menu.action) : undefined
30+ property alias heroMessageHeader: __heroMessageHeader
31+ property real collapsedHeight: heroMessageHeader.y + heroMessageHeader.bodyBottom + units.gu(2)
32+ property real expandedHeight: collapsedHeight
33+
34+ color: "#221e1c"
35+
36+ removable: state !== "expanded"
37+ implicitHeight: collapsedHeight
38+
39+ HeroMessageHeader {
40+ id: __heroMessageHeader
41+
42+ anchors.top: parent.top
43+ anchors.left: parent.left
44+ anchors.right: parent.right
45+
46+ avatar: menu && (menu.extra.canonical_icon.length > 0) ? "image://gicon/" + encodeURI(menu.extra.canonical_icon) : "qrc:/indicatorsclient/messaging/artwork/default_contact.png"
47+ icon: menu && (menu.extra.canonical_app_icon.length > 0) ? "image://gicon/" + encodeURI(menu.extra.canonical_app_icon) : ""
48+ appIcon: icon
49+
50+ state: __heroMessage.state
51+
52+ onAppIconClicked: {
53+ if (action && action.valid) {
54+ listViewSelectItem(-1)
55+ action.activate(true)
56+ }
57+ }
58+ }
59+
60+ onClicked: {
61+ if (listViewIsCurrentItem) {
62+ listViewSelectItem(-1)
63+ } else {
64+ listViewSelectItem(index)
65+ }
66+ }
67+
68+ IndicatorsClient.HLine {
69+ id: __topHLine
70+ anchors.top: parent.top
71+ color: "#403b37"
72+ }
73+
74+ IndicatorsClient.HLine {
75+ id: __bottomHLine
76+ anchors.bottom: parent.bottom
77+ color: "#060606"
78+ }
79+
80+ states: State {
81+ name: "expanded"
82+ when: listViewIsCurrentItem
83+
84+ PropertyChanges {
85+ target: __heroMessage
86+ color: "#333130"
87+ implicitHeight: __heroMessage.expandedHeight
88+ }
89+ PropertyChanges {
90+ target: __topHLine
91+ opacity: 0.0
92+ }
93+ PropertyChanges {
94+ target: __bottomHLine
95+ opacity: 0.0
96+ }
97+ }
98+
99+ transitions: Transition {
100+ ParallelAnimation {
101+ NumberAnimation {
102+ properties: "opacity,implicitHeight"
103+ duration: 200
104+ easing.type: Easing.OutQuad
105+ }
106+ ColorAnimation {}
107+ }
108+ }
109+
110+ onItemRemoved: {
111+ if (action && action.valid) {
112+ action.activate(false)
113+ }
114+ }
115+}
plugins/IndicatorsClient/indicators/messaging/qml/HeroMessageHeader.qmlnew file+147
@@ -0,0 +1,147 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+
24+Item {
25+ id: __heroMessageHeader
26+
27+ property alias avatar: __avatarImage.source
28+ property alias icon: __iconImage.source
29+ property alias appIcon: __appIconImage.source
30+ property alias titleText: __titleText
31+ property alias subtitleText: __subtitleText
32+ property alias bodyText: __bodyText
33+ property real bodyBottom: __bodyText.y + __bodyText.height
34+
35+ signal appIconClicked()
36+
37+ height: units.gu(9)
38+
39+ UbuntuShape {
40+ id: __avatarImageContainer
41+ anchors.top: parent.top
42+ anchors.topMargin: units.gu(2)
43+ anchors.left: parent.left
44+ anchors.leftMargin: units.gu(2)
45+ height: units.gu(6)
46+ width: units.gu(6)
47+ image: Image {
48+ id: __avatarImage
49+ fillMode: Image.PreserveAspectFit
50+ }
51+ }
52+
53+ Image {
54+ id: __iconImage
55+ anchors.top: parent.top
56+ anchors.topMargin: units.gu(2)
57+ anchors.left: __avatarImageContainer.right
58+ anchors.leftMargin: units.gu(1)
59+ height: units.gu(1.5)
60+ width: units.gu(2)
61+ horizontalAlignment: Image.AlignHCenter
62+ verticalAlignment: Image.AlignBottom
63+ fillMode: Image.PreserveAspectFit
64+ }
65+
66+ Label {
67+ id: __titleText
68+ anchors.baseline: __iconImage.bottom
69+ anchors.left: __iconImage.right
70+ anchors.leftMargin: units.gu(1)
71+ anchors.right: __appIcon.left
72+ anchors.rightMargin: units.gu(2)
73+ elide: Text.ElideRight
74+ color: "#e8e1d0"
75+ font.weight: Font.DemiBold
76+ fontSize: "medium"
77+ }
78+
79+ Label {
80+ id: __subtitleText
81+ anchors.baseline: __titleText.baseline
82+ anchors.baselineOffset: units.gu(2.5)
83+ anchors.left: __titleText.left
84+ anchors.right: __titleText.right
85+ elide: Text.ElideRight
86+ color: "#8f8f88"
87+ fontSize: "small"
88+ }
89+
90+ Label {
91+ id: __bodyText
92+ anchors.baseline: __subtitleText.baseline
93+ anchors.baselineOffset: units.gu(2.5)
94+ anchors.left: __titleText.left
95+ anchors.right: parent.right
96+ anchors.rightMargin: units.gu(2)
97+ maximumLineCount: 2
98+ wrapMode: Text.WordWrap
99+ elide: Text.ElideRight
100+ color: "#e8e1d0"
101+ fontSize: "small"
102+ }
103+
104+ Item {
105+ id: __appIcon
106+ width: units.gu(7)
107+ height: units.gu(7)
108+ anchors.top: parent.top
109+ anchors.right: parent.right
110+ opacity: 0.0
111+ enabled: __heroMessageHeader.state === "expanded"
112+
113+ Image {
114+ id: __appIconImage
115+ height: width
116+ anchors.left: parent.left
117+ anchors.leftMargin: units.gu(2)
118+ anchors.right: parent.right
119+ anchors.rightMargin: units.gu(2)
120+ anchors.topMargin: units.gu(1)
121+ anchors.verticalCenter: parent.verticalCenter
122+ fillMode: Image.PreserveAspectFit
123+ }
124+
125+ MouseArea {
126+ anchors.fill: parent
127+ onClicked: __heroMessageHeader.appIconClicked()
128+ }
129+ }
130+
131+ states: State {
132+ name: "expanded"
133+
134+ PropertyChanges {
135+ target: __appIcon
136+ opacity: 1.0
137+ }
138+ }
139+
140+ transitions: Transition {
141+ NumberAnimation {
142+ property: "opacity"
143+ duration: 200
144+ easing.type: Easing.OutQuad
145+ }
146+ }
147+}
plugins/IndicatorsClient/indicators/messaging/qml/MessageItem.qmlnew file+92
@@ -0,0 +1,92 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+import IndicatorsClient 0.1 as IndicatorsClient
24+
25+IndicatorsClient.BasicMenu {
26+ id: __messageItem
27+
28+ property variant actionsDescription: menu ? menu.extra.canonical_message_actions : undefined
29+
30+ onActionGroupChanged: loadItem()
31+ onActionsDescriptionChanged: loadItem()
32+ implicitHeight: __contents.status == Loader.Ready ? __contents.item.implicitHeight : 0
33+
34+ Loader {
35+ id: __contents
36+
37+ anchors.fill: parent
38+ // Binding all properties for the item, to make sure that any change in the
39+ // property will be propagated to the __contents.item at any time
40+ Binding {
41+ target: __contents.item
42+ property: "listViewIsCurrentItem"
43+ value: listViewIsCurrentItem
44+ when: (__contents.status == Loader.Ready)
45+ }
46+
47+ Binding {
48+ target: __contents.item
49+ property: "actionGroup"
50+ value: actionGroup
51+ when: (__contents.status == Loader.Ready)
52+ }
53+
54+ Binding {
55+ target: __contents.item
56+ property: "menu"
57+ value: menu
58+ when: (__contents.status == Loader.Ready)
59+ }
60+
61+ Binding {
62+ target: __contents.item
63+ property: "actionsDescription"
64+ value: actionsDescription
65+ when: (__contents.status == Loader.Ready)
66+ }
67+ }
68+
69+
70+ function loadItem()
71+ {
72+ var parameterType = ""
73+ for (var actIndex in actionsDescription) {
74+ var desc = actionsDescription[actIndex]
75+ if (desc["parameter-type"] !== undefined) {
76+ parameterType += desc["parameter-type"]
77+ } else {
78+ parameterType += "_"
79+ }
80+ }
81+
82+ if (parameterType === "") {
83+ __contents.source = "SimpleTextMessage.qml"
84+ } else if (parameterType === "s") {
85+ __contents.source = "TextMessage.qml"
86+ } else if (parameterType === "_s") {
87+ __contents.source = "SnapDecision.qml"
88+ } else {
89+ console.debug("Unknown paramater type: " + parameterType)
90+ }
91+ }
92+}
plugins/IndicatorsClient/indicators/messaging/qml/QuickReply.qmlnew file+152
@@ -0,0 +1,152 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+import IndicatorsClient 0.1 as IndicatorsClient
24+
25+Item {
26+ property alias action: __actionTextField.action
27+ property alias buttonText: __actionTextField.buttonText
28+ property real expandedHeight: childrenRect.height
29+ property alias messages : __messagelistRepeater.model
30+
31+ Item {
32+ id: __header
33+ anchors.top: parent.top
34+ anchors.left: parent.left
35+ anchors.right: parent.right
36+ height: units.gu(4)
37+
38+ Row {
39+ anchors.fill: parent
40+ anchors.leftMargin: units.gu(2)
41+ anchors.rightMargin: units.gu(2)
42+ anchors.topMargin: units.gu(1)
43+ anchors.bottomMargin: units.gu(1)
44+ spacing: units.gu(1)
45+
46+ Image {
47+ width: units.gu(2)
48+ height: width
49+ fillMode: Image.PreserveAspectFit
50+ source: "qrc:/indicatorsclient/messaging/artwork/message_sms01_54px.png"
51+ }
52+
53+ Label {
54+ height: parent.height
55+ verticalAlignment: Text.AlignVCenter
56+ fontSize: "small"
57+ color: "#8f8f88"
58+ text: "Quick reply with:"
59+ }
60+ }
61+
62+ IndicatorsClient.HLine {
63+ anchors.bottom: parent.bottom
64+ color: "#20201F"
65+ }
66+ }
67+
68+ Column {
69+ id: __messagelist
70+ anchors.left: parent.left
71+ anchors.right: parent.right
72+ anchors.top: __header.bottom
73+ height: childrenRect.height
74+
75+ Repeater {
76+ id: __messagelistRepeater
77+
78+ height: childrenRect.height
79+
80+ Rectangle {
81+ width: __messagelist.width
82+ height: units.gu(5)
83+ color: "#333230"
84+
85+ Label {
86+ id: __label
87+
88+ anchors.fill: parent
89+ anchors.leftMargin: units.gu(2)
90+ anchors.rightMargin: units.gu(2)
91+ verticalAlignment: Text.AlignVCenter
92+ fontSize: "medium"
93+ color: "#e8e1d0"
94+ text: modelData
95+ }
96+
97+ IndicatorsClient.HLine {
98+ anchors.top: parent.top
99+ color: "#464543"
100+ }
101+
102+ IndicatorsClient.HLine {
103+ anchors.bottom: parent.bottom
104+ color: "#20201F"
105+ }
106+
107+ MouseArea {
108+ id: __mouseArea
109+
110+ anchors.fill: parent
111+ onClicked: {
112+ __actionTextField.text = modelData
113+ }
114+ }
115+
116+ Rectangle {
117+ id: __mask
118+
119+ anchors.fill: parent
120+ color: "black"
121+ opacity: __mouseArea.pressed ? 0.3 : 0.0
122+ Behavior on opacity {
123+ NumberAnimation {
124+ duration: 200
125+ easing.type: Easing.OutQuad
126+ }
127+ }
128+ }
129+ }
130+
131+ }
132+ }
133+
134+ Item {
135+ anchors.top: __messagelist.bottom
136+ anchors.left: parent.left
137+ anchors.right: parent.right
138+ height: units.gu(6)
139+
140+ ActionTextField {
141+ id: __actionTextField
142+
143+ anchors.fill: parent
144+ anchors.margins: units.gu(1)
145+ }
146+
147+ IndicatorsClient.HLine {
148+ anchors.top: parent.top
149+ color: "#464543"
150+ }
151+ }
152+}
plugins/IndicatorsClient/indicators/messaging/qml/SimpleTextMessage.qmlnew file+91
@@ -0,0 +1,91 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+import "utils.js" as Utils
24+
25+HeroMessage {
26+ id: __heroMessage
27+
28+ property alias footer: __footer.sourceComponent
29+
30+ expandedHeight: __fullMessage.y + __fullMessage.height + units.gu(2)
31+ heroMessageHeader.titleText.text: menu ? menu.label : ""
32+ heroMessageHeader.subtitleText.text: menu ? Utils.formatDate(menu.extra.canonical_time) : ""
33+ heroMessageHeader.bodyText.text: menu ? menu.extra.canonical_text : ""
34+
35+ Item {
36+ id: __fullMessage
37+
38+ anchors.left: parent.left
39+ anchors.leftMargin: units.gu(2)
40+ anchors.right: parent.right
41+ anchors.rightMargin: units.gu(2)
42+ anchors.top: heroMessageHeader.bottom
43+ height: childrenRect.height
44+ opacity: 0.0
45+ enabled: false
46+
47+ Label {
48+ id: __bodyText
49+ anchors.top: parent.top
50+ anchors.left: parent.left
51+ anchors.right: parent.right
52+ wrapMode: Text.WordWrap
53+ elide: Text.ElideRight
54+ color: "#e8e1d0"
55+ fontSize: "medium"
56+ text: heroMessageHeader.bodyText.text
57+ }
58+
59+ Loader {
60+ id: __footer
61+
62+ anchors.top: __bodyText.bottom
63+ anchors.topMargin: units.gu(2)
64+ anchors.left: parent.left
65+ anchors.right: parent.right
66+ height: __footer.item != undefined ? units.gu(4) : 0
67+ }
68+
69+ states: State {
70+ name: "expanded"
71+ when: __heroMessage.state === "expanded"
72+
73+ PropertyChanges {
74+ target: heroMessageHeader.bodyText
75+ opacity: 0.0
76+ }
77+
78+ PropertyChanges {
79+ target: __fullMessage
80+ opacity: 1.0
81+ enabled: true
82+ }
83+ }
84+ transitions: Transition {
85+ NumberAnimation {
86+ property: "opacity"
87+ duration: 200
88+ }
89+ }
90+ }
91+}
plugins/IndicatorsClient/indicators/messaging/qml/SnapDecision.qmlnew file+135
@@ -0,0 +1,135 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+import "utils.js" as Utils
24+
25+HeroMessage {
26+ id: __heroMessage
27+
28+ expandedHeight: __buttons.y + __buttons.height + __quickreply.height + units.gu(2)
29+ heroMessageHeader.titleText.text: menu ? menu.label : ""
30+ heroMessageHeader.subtitleText.text: menu ? menu.extra.canonical_text : ""
31+ heroMessageHeader.subtitleText.color: "#e8e1d0"
32+ heroMessageHeader.bodyText.text: menu ? Utils.formatDate(menu.extra.canonical_time) : ""
33+ heroMessageHeader.bodyText.color: "#8f8f88"
34+
35+ Item {
36+ id: __buttons
37+
38+ anchors.left: parent.left
39+ anchors.leftMargin: units.gu(2)
40+ anchors.right: parent.right
41+ anchors.rightMargin: units.gu(2)
42+ anchors.top: heroMessageHeader.bottom
43+ anchors.topMargin: units.gu(1)
44+ height: units.gu(4)
45+ opacity: 0.0
46+
47+ Button {
48+ text: "Message"
49+ color: "#bababa"
50+ anchors.left: parent.left
51+ anchors.top: parent.top
52+ anchors.bottom: parent.bottom
53+ width: (parent.width - units.gu(1)) / 2
54+
55+ onClicked: {
56+ if (__quickreply.state === "") {
57+ __quickreply.state = "expanded"
58+ } else {
59+ __quickreply.state = ""
60+ }
61+ }
62+ }
63+
64+ ActionButton {
65+ action: menu && actionGroup && actionsDescription ? actionGroup.action(actionsDescription[0].name) : undefined
66+ text: actionsDescription ? actionsDescription[0].label : "Call back"
67+ color: "#c94212"
68+ anchors.right: parent.right
69+ anchors.top: parent.top
70+ anchors.bottom: parent.bottom
71+ width: (parent.width - units.gu(1)) / 2
72+ }
73+
74+ states: State {
75+ name: "expanded"
76+ when: __heroMessage.state === "expanded"
77+
78+ PropertyChanges {
79+ target: __buttons
80+ opacity: 1.0
81+ }
82+ }
83+ transitions: Transition {
84+ NumberAnimation {
85+ property: "opacity"
86+ duration: 200
87+ easing.type: Easing.OutQuad
88+ }
89+ }
90+ }
91+
92+ QuickReply {
93+ id: __quickreply
94+
95+ messages: actionsDescription ? actionsDescription[1]["parameter-hint"] : ""
96+ buttonText: actionsDescription ? actionsDescription[1].label : "send"
97+ action: menu && actionGroup && actionsDescription ? actionGroup.action(actionsDescription[1].name) : undefined
98+ anchors.top: __buttons.bottom
99+ anchors.topMargin: units.gu(2)
100+ anchors.left: parent.left
101+ anchors.right: parent.right
102+ height: 0
103+ opacity: 0.0
104+ enabled: false
105+
106+ states: State {
107+ name: "expanded"
108+
109+ PropertyChanges {
110+ target: __quickreply
111+ height: expandedHeight
112+ opacity: 1.0
113+ }
114+
115+ PropertyChanges {
116+ target: __quickreply
117+ enabled: true
118+ }
119+ }
120+
121+ transitions: Transition {
122+ NumberAnimation {
123+ properties: "opacity,height"
124+ duration: 200
125+ easing.type: Easing.OutQuad
126+ }
127+ }
128+ }
129+
130+ onStateChanged: {
131+ if (state === "") {
132+ __quickreply.state = ""
133+ }
134+ }
135+}
plugins/IndicatorsClient/indicators/messaging/qml/TextMessage.qmlnew file+32
@@ -0,0 +1,32 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+
24+SimpleTextMessage {
25+ id: __heroMessage
26+
27+ footer: ActionTextField {
28+ anchors.fill: parent
29+ action: menu && actionGroup && actionsDescription ? actionGroup.action(actionsDescription[0].name) : undefined
30+ buttonText: actionsDescription ? actionsDescription[0].label : "Send"
31+ }
32+}
plugins/IndicatorsClient/indicators/messaging/qml/messagingplugin.qmlnew file+32
@@ -0,0 +1,32 @@
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.filho@canonical.com>
18+ */
19+
20+import IndicatorsClient 0.1 as IndicatorsClient
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+
24+IndicatorsClient.PluginItem {
25+ anchors.fill: parent
26+
27+ function stop() {
28+ // never stops the service
29+ // this will keep all objects in memory, consume more memory
30+ // but will optimize the menu contruction on the screen
31+ }
32+}
plugins/IndicatorsClient/indicators/messaging/qml/utils.jsnew file+27
@@ -0,0 +1,27 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+.pragma library
22+
23+function formatDate(timestamp) {
24+ // timestamp is in microseconds since epoch
25+ var date = new Date(timestamp / 1000);
26+ return Qt.formatDateTime(date, "hh:mm - MMM dd")
27+}
plugins/IndicatorsClient/indicators/network/CMakeLists.txtnew file+36
@@ -0,0 +1,36 @@
1+set(INDICATORCLIENT_NETWORK_SRC
2+ indicatorclient_network.cpp
3+ networkagent.cpp
4+ secret-agent.c
5+)
6+
7+qt5_add_resources(INDICATORCLIENT_NETWORK_RESOURCES_RCC
8+ indicatorclient_network.qrc
9+)
10+
11+add_library(indicatorclient_network
12+ ${INDICATORCLIENT_NETWORK_RESOURCES_RCC}
13+ ${INDICATORCLIENT_NETWORK_SRC}
14+)
15+
16+qt5_use_modules(indicatorclient_network Core Qml Widgets)
17+
18+set_target_properties(indicatorclient_network PROPERTIES COMPILE_FLAGS -fPIC)
19+
20+include_directories(
21+ ${CMAKE_CURRENT_SOURCE_DIR}
22+ ${GLIB_INCLUDE_DIRS}
23+ ${LIBNM_GLIB_INCLUDE_DIRS}
24+ ${LIBNM_UTIL_INCLUDE_DIRS}
25+ ${QMENUMODEL_INCLUDE_DIRS}
26+ ${indicatorclient_common_SOURCE_DIR}
27+ ${IndicatorsClientQml_SOURCE_DIR}
28+)
29+
30+target_link_libraries(indicatorclient_network
31+ indicatorclient_common
32+ ${GLIB_LIBRARIES}
33+ ${LIBNM_GLIB_LIBRARIES}
34+ ${LIBNM_UTIL_LIBRARIES}
35+ ${QMENUMODEL_LDFLAGS}
36+)
plugins/IndicatorsClient/indicators/network/indicatorclient_network.cppnew file+174
@@ -0,0 +1,174 @@
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+ */
19+
20+#include "indicatorclient_network.h"
21+#include "networkagent.h"
22+
23+#include <QUrl>
24+#include <QtQml>
25+#include <QtPlugin>
26+
27+#include <qdbusmenumodel.h>
28+#include <qdbusactiongroup.h>
29+#include <qstateaction.h>
30+
31+IndicatorClientNetwork::IndicatorClientNetwork(QObject *parent)
32+ : IndicatorClientCommon(parent),
33+ m_action(0)
34+{
35+ setTitle("Networks");
36+ setPriority(IndicatorPriority::NETWORK);
37+
38+ m_timedAnimation.setInterval(500);
39+ connect(&m_timedAnimation, SIGNAL(timeout()), SLOT(animationNextFrame()));
40+}
41+
42+IndicatorClientNetwork::~IndicatorClientNetwork()
43+{
44+}
45+
46+void IndicatorClientNetwork::init(const QSettings& settings)
47+{
48+ IndicatorClientCommon::init(settings);
49+ Q_INIT_RESOURCE(indicatorclient_network);
50+
51+ qmlRegisterType<NetworkAgent>("NetworkSettings", 0, 1, "NetworkAgent");
52+ setIcon(QUrl("image://gicon/wifi-none"));
53+}
54+
55+QQmlComponent *IndicatorClientNetwork::createComponent(QQmlEngine *engine, QObject *parent) const
56+{
57+ return new QQmlComponent(engine, QUrl("qrc:/indicatorclient/network/qml/NetworkPage.qml"), parent);
58+}
59+
60+IndicatorClientInterface::WidgetsMap IndicatorClientNetwork::widgets()
61+{
62+ static WidgetsMap w;
63+ if (w.isEmpty()) {
64+ w.insert("unity.widget.systemsettings.tablet.sectiontitle", QUrl("qrc:/indicatorclient/network/qml/WifiSection.qml"));
65+ w.insert("unity.widgets.systemsettings.tablet.wifisection", QUrl("qrc:/indicatorclient/network/qml/WifiSection.qml"));
66+ w.insert("unity.widgets.systemsettings.tablet.accesspoint", QUrl("qrc:/indicatorclient/network/qml/Accesspoint.qml"));
67+ }
68+ return w;
69+}
70+
71+bool IndicatorClientNetwork::parseRootElement(const QString &type, QMap<int, QVariant> data)
72+{
73+ if (type == "com.canonical.indicator.root.network") {
74+ if (m_action != 0) {
75+ delete m_action;
76+ }
77+
78+ QVariant action = data[QDBusMenuModel::Action];
79+ m_action = actionGroup()->action(action.toString());
80+ if (m_action->isValid()) {
81+ updateNetworkStatus(m_action->state());
82+ }
83+ connect(m_action, SIGNAL(stateChanged(QVariant)), SLOT(updateNetworkStatus(QVariant)));
84+ return true;
85+ } else {
86+ return false;
87+ }
88+}
89+
90+QString IndicatorClientNetwork::getIconBasedOnSingal(uint signal) const
91+{
92+ if (signal == 0) {
93+ return "nm-signal-00";
94+ } else if (signal <= 25) {
95+ return "nm-signal-25";
96+ } else if (signal <= 50) {
97+ return "nm-signal-50";
98+ } else if (signal <= 75) {
99+ return "nm-signal-75";
100+ } else {
101+ return "nm-signal-100";
102+ }
103+}
104+
105+void IndicatorClientNetwork::animationNextFrame()
106+{
107+ static int frame = 0;
108+ QString iconName;
109+ switch (frame) {
110+ case 0:
111+ iconName = "nm-signal-00";
112+ break;
113+ case 1:
114+ iconName = "nm-signal-25";
115+ break;
116+ case 2:
117+ iconName = "nm-signal-50";
118+ break;
119+ case 3:
120+ iconName = "nm-signal-75";
121+ break;
122+ case 4:
123+ iconName = "nm-signal-100";
124+ break;
125+ }
126+
127+ if (frame < 4) {
128+ frame++;
129+ } else {
130+ frame = 0;
131+ }
132+ setIcon(QUrl("image://gicon/" + iconName));
133+}
134+
135+void IndicatorClientNetwork::updateNetworkStatus(const QVariant &state)
136+{
137+ if (state.isValid()) {
138+ // (uuu)
139+ // - Device type
140+ // - Connection state
141+ // - Extended state
142+ QVariantList states = state.toList();
143+ if (states.size() == 3) {
144+ QString iconName;
145+ uint connectionState = states[1].toUInt();
146+ switch (connectionState)
147+ {
148+ case 3: // NM_ACTIVE_CONNECTION_STATE_DEACTIVATING
149+ case 1: // NM_ACTIVE_CONNECTION_STATE_ACTIVATING
150+ m_timedAnimation.start();
151+ iconName = "nm-signal-100";
152+ break;
153+ case 2: // NM_ACTIVE_CONNECTION_STATE_ACTIVATED
154+ m_timedAnimation.stop();
155+ iconName = getIconBasedOnSingal(states[2].toUInt());
156+ break;
157+ case 0: // NM_ACTIVE_CONNECTION_STATE_UNKNOWN
158+ default:
159+ m_timedAnimation.stop();
160+ iconName = "wifi-none";
161+ break;
162+ }
163+
164+ setIcon(QUrl("image://gicon/" + iconName));
165+ return;
166+ } else {
167+ qWarning() << "Invalid network root state value";
168+ m_timedAnimation.stop();
169+ setIcon(QUrl());
170+ }
171+ } else {
172+ qWarning() << "Invalid network root state";
173+ }
174+}
plugins/IndicatorsClient/indicators/network/indicatorclient_network.hnew file+51
@@ -0,0 +1,51 @@
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+ */
19+
20+#ifndef INDICATORCLIENT_NETWORK_H
21+#define INDICATORCLIENT_NETWORK_H
22+
23+#include "indicatorclient_common.h"
24+#include <QTimer>
25+
26+class QStateAction;
27+
28+class IndicatorClientNetwork : public IndicatorClientCommon
29+{
30+ Q_OBJECT
31+public:
32+ IndicatorClientNetwork(QObject *parent=0);
33+ ~IndicatorClientNetwork();
34+
35+ void init(const QSettings& settings);
36+ QQmlComponent *createComponent(QQmlEngine *engine, QObject *parent=0) const;
37+ WidgetsMap widgets();
38+ bool parseRootElement(const QString &type, QMap<int, QVariant> data);
39+
40+private Q_SLOTS:
41+ void animationNextFrame();
42+ void updateNetworkStatus(const QVariant &state);
43+
44+private:
45+ QStateAction *m_action;
46+ QTimer m_timedAnimation;
47+
48+ QString getIconBasedOnSingal(uint signal) const;
49+};
50+
51+#endif
plugins/IndicatorsClient/indicators/network/indicatorclient_network.qrcnew file+8
@@ -0,0 +1,8 @@
1+<RCC>
2+ <qresource prefix="/indicatorclient/network">
3+ <file>qml/WifiSection.qml</file>
4+ <file>qml/Accesspoint.qml</file>
5+ <file>qml/NetworkPage.qml</file>
6+ <file>qml/PasswordDialog.qml</file>
7+ </qresource>
8+</RCC>
plugins/IndicatorsClient/indicators/network/networkagent.cppnew file+146
@@ -0,0 +1,146 @@
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+ * Alberto Ruiz <alberto.ruiz@canonical.com>
18+ * Renato Araujo Oliveira Filho <renato@canonical.com>
19+ */
20+
21+#include "networkagent.h"
22+
23+#include <QVariant>
24+#include <QApplication>
25+#include <QDebug>
26+
27+class NetworkAgentToken
28+{
29+public:
30+ NMConnection *connection;
31+ NMSettingWirelessSecurity *wisec;
32+ guint id;
33+ QByteArray keyMgmt;
34+
35+ NetworkAgentToken(NMConnection *connection,
36+ NMSettingWirelessSecurity *wisec,
37+ guint id,
38+ QByteArray keyMgmt)
39+ : connection(connection),
40+ wisec(wisec),
41+ id(id),
42+ keyMgmt(keyMgmt)
43+ {
44+ if (connection) {
45+ g_object_ref(connection);
46+ } else {
47+ qWarning() << "invalid connection object";
48+ }
49+ }
50+
51+ ~NetworkAgentToken()
52+ {
53+ if (connection) {
54+ g_object_unref(connection);
55+ }
56+ }
57+};
58+
59+NetworkAgent::NetworkAgent(QObject *parent)
60+ : QObject(parent)
61+{
62+ m_agent = unity_settings_secret_agent_new();
63+ g_signal_connect(G_OBJECT(m_agent),
64+ UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED,
65+ G_CALLBACK(onSecretRequested),
66+ this);
67+
68+ g_signal_connect(G_OBJECT(m_agent),
69+ UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED,
70+ G_CALLBACK(onSecretRequestCancelled),
71+ this);
72+}
73+
74+NetworkAgent::~NetworkAgent()
75+{
76+ nm_secret_agent_unregister(NM_SECRET_AGENT(m_agent));
77+ g_object_unref(m_agent);
78+}
79+
80+void NetworkAgent::authenticate(const QVariant &token, const QString &key)
81+{
82+ NetworkAgentToken *pToken = (NetworkAgentToken *) token.value<void *>();
83+ if (pToken == NULL) {
84+ return;
85+ }
86+
87+ if ((pToken->keyMgmt == "wpa-none") || (pToken->keyMgmt == "wpa-psk")) {
88+ g_object_set(G_OBJECT(pToken->wisec),
89+ NM_SETTING_WIRELESS_SECURITY_PSK, qPrintable(key),
90+ NULL);
91+ } else if (pToken->keyMgmt == "none") {
92+ g_object_set(G_OBJECT(pToken->wisec),
93+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, qPrintable(key),
94+ NULL);
95+ }
96+
97+ GHashTable *settings = nm_connection_to_hash(pToken->connection,
98+ NM_SETTING_HASH_FLAG_ALL);
99+
100+ unity_settings_secret_agent_provide_secret(m_agent,
101+ pToken->id, settings);
102+ g_hash_table_unref(settings);
103+ delete pToken;
104+}
105+
106+void NetworkAgent::cancel(const QVariant &token)
107+{
108+ NetworkAgentToken *pToken = (NetworkAgentToken *) token.value<void *>();
109+ if (pToken != NULL) {
110+ unity_settings_secret_agent_cancel_request(m_agent, pToken->id);
111+ delete pToken;
112+ }
113+}
114+
115+void NetworkAgent::onSecretRequested(UnitySettingsSecretAgent* /*agent*/,
116+ guint id,
117+ NMConnection* connection,
118+ const char* /*setting_name*/,
119+ const char** /*hints*/,
120+ NMSecretAgentGetSecretsFlags /*flags*/,
121+ NetworkAgent* self)
122+{
123+ NetworkAgentToken *token = new NetworkAgentToken(connection,
124+ NULL,
125+ id,
126+ NULL);
127+
128+ token->wisec = nm_connection_get_setting_wireless_security(connection);
129+ if (token->wisec) {
130+ token->keyMgmt = nm_setting_wireless_security_get_key_mgmt(token->wisec);
131+ }
132+
133+ QVariant varToken = qVariantFromValue((void *) token);
134+ Q_EMIT self->secretRequested(varToken);
135+}
136+
137+void NetworkAgent::onSecretRequestCancelled(UnitySettingsSecretAgent* /*agent*/,
138+ guint /*id*/,
139+ NMConnection* /*connection*/,
140+ const char* /*setting_name*/,
141+ const char** /*hints*/,
142+ NMSecretAgentGetSecretsFlags /*flags*/,
143+ NetworkAgent* /*self*/)
144+{
145+ //Do nothing for now
146+}
plugins/IndicatorsClient/indicators/network/networkagent.hnew file+65
@@ -0,0 +1,65 @@
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+ * Alberto Ruiz <alberto.ruiz@canonical.com>
18+ * Renato Araujo Oliveira Filho <renato@canonical.com>
19+ */
20+
21+#ifndef NETWORKAGENT_H
22+#define NETWORKAGENT_H
23+
24+#include "secret-agent.h"
25+
26+#include <QObject>
27+
28+class NetworkAgentToken;
29+
30+class NetworkAgent : public QObject
31+{
32+ Q_OBJECT
33+public:
34+ NetworkAgent(QObject *parent=0);
35+ ~NetworkAgent();
36+
37+ Q_INVOKABLE void authenticate(const QVariant &token, const QString &key);
38+ Q_INVOKABLE void cancel(const QVariant &token);
39+
40+Q_SIGNALS:
41+ void secretRequested(const QVariant &token);
42+ void secretRequestCancelled();
43+
44+private:
45+ UnitySettingsSecretAgent *m_agent;
46+
47+ static void onSecretRequested(UnitySettingsSecretAgent *agent,
48+ guint id,
49+ NMConnection *connection,
50+ const char *setting_name,
51+ const char **hints,
52+ NMSecretAgentGetSecretsFlags flags,
53+ NetworkAgent *self);
54+
55+ static void onSecretRequestCancelled(UnitySettingsSecretAgent *agent,
56+ guint id,
57+ NMConnection *connection,
58+ const char *setting_name,
59+ const char **hints,
60+ NMSecretAgentGetSecretsFlags flags,
61+ NetworkAgent *self);
62+
63+};
64+
65+#endif
plugins/IndicatorsClient/indicators/network/qml/Accesspoint.qmlnew file+69
@@ -0,0 +1,69 @@
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+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Ubuntu.Components.ListItems 0.1 as ListItem
23+import IndicatorsClient 0.1 as IndicatorsClient
24+
25+IndicatorsClient.Menu {
26+ property variant actionWifiApStrength : menu && actionGroup ? actionGroup.action(menu.extra.canonical_wifi_ap_strength_action) : null
27+ property variant wifiApStrength : actionWifiApStrength && actionWifiApStrength.valid ? actionWifiApStrength.state : "0"
28+
29+ implicitHeight: units.gu(7)
30+
31+ function getNetworkIcon(data) {
32+ var imageName = "nm-signal-100"
33+ var signalStrength = parseInt(wifiApStrength)
34+
35+ if (data.extra.canonical_wifi_ap_is_adhoc) {
36+ imageName = "nm-adhoc"
37+ } else if (signalStrength == 0) {
38+ imageName = "nm-signal-00"
39+ } else if (signalStrength <= 25) {
40+ imageName = "nm-signal-25"
41+ } else if (signalStrength <= 50) {
42+ imageName = "nm-signal-50"
43+ } else if (signalStrength <= 75) {
44+ imageName = "nm-signal-75"
45+ }
46+
47+ if (data.extra.canonical_wifi_ap_is_secure) {
48+ imageName += "-secure"
49+ }
50+
51+ return "image://gicon/" + imageName;
52+ }
53+
54+ icon: menu && wifiApStrength ? getNetworkIcon(menu) : "image://gicon/nm-no-connection"
55+ iconFrame: false
56+ control: CheckBox {
57+ id: checkBoxActive
58+ height: units.gu(4)
59+ width: units.gu(4)
60+ anchors.horizontalCenter: parent.horizontalCenter
61+ anchors.verticalCenter: parent.verticalCenter
62+ }
63+
64+ IndicatorsClient.DBusActionState {
65+ action: menu ? menu.action : undefined
66+ target: checkBoxActive
67+ property: "checked"
68+ }
69+}
plugins/IndicatorsClient/indicators/network/qml/NetworkPage.qmlnew file+71
@@ -0,0 +1,71 @@
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+ */
19+
20+import IndicatorsClient 0.1 as IndicatorsClient
21+import Ubuntu.Components 0.1
22+import NetworkSettings 0.1
23+
24+PageStack {
25+ id: _network
26+
27+ property alias title: _mainPage.title
28+ property alias emptyText: _pluginItem.emptyText
29+ property alias widgetsMap : _pluginItem.widgetsMap
30+ property alias busType: _pluginItem.busType
31+ property alias busName: _pluginItem.busName
32+ property alias objectPath: _pluginItem.objectPath
33+
34+ __showHeader: false
35+ anchors.fill: parent
36+
37+ Page {
38+ id: _mainPage
39+
40+ IndicatorsClient.PluginItem {
41+ id: _pluginItem
42+ anchors.fill: parent
43+ }
44+ }
45+
46+ NetworkAgent {
47+ id: networkAgent
48+
49+ onSecretRequested: {
50+ _network.push(Qt.createComponent("PasswordDialog.qml"),
51+ {"agent" : networkAgent, "token" : token})
52+ }
53+ }
54+
55+ function start()
56+ {
57+ push(_mainPage)
58+ _pluginItem.start()
59+ }
60+
61+ function stop()
62+ {
63+ clear()
64+ _pluginItem.stop()
65+ }
66+
67+ function reset()
68+ {
69+ _pluginItem.reset()
70+ }
71+}
plugins/IndicatorsClient/indicators/network/qml/PasswordDialog.qmlnew file+80
@@ -0,0 +1,80 @@
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+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Ubuntu.Components.ListItems 0.1 as ListItem
23+import IndicatorsClient 0.1 as IndicatorsClient
24+
25+Page {
26+ id: pagePassword
27+
28+ property variant agent
29+ property variant token
30+
31+ anchors.fill: parent
32+ title: "Network Authentication"
33+
34+ Column {
35+ anchors {
36+ left: parent.left
37+ right: parent.right
38+ }
39+
40+ IndicatorsClient.SectionMenu {
41+ label: "Authentication"
42+ }
43+
44+ IndicatorsClient.TextMenu {
45+ id: _password
46+
47+ password: true
48+ }
49+
50+ IndicatorsClient.Menu {
51+ Row {
52+ anchors {
53+ right: parent.right
54+ verticalCenter: parent.verticalCenter
55+ margins: units.gu(3)
56+ }
57+
58+ spacing: units.gu(1)
59+
60+ Button {
61+ text: "Cancel"
62+ width: units.gu(10)
63+ onClicked: {
64+ agent.cancel(token);
65+ pageStack.pop()
66+ }
67+ }
68+
69+ Button {
70+ text: "Ok"
71+ width: units.gu(10)
72+ onClicked: {
73+ agent.authenticate(token, _password.text)
74+ pageStack.pop()
75+ }
76+ }
77+ }
78+ }
79+ }
80+}
plugins/IndicatorsClient/indicators/network/qml/WifiSection.qmlnew file+27
@@ -0,0 +1,27 @@
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+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import IndicatorsClient 0.1 as IndicatorsClient
23+
24+IndicatorsClient.SectionMenu {
25+ property variant busyAction : actionGroup ? actionGroup.action(menu.extra.canonical_busy_action) : undefined
26+ busy: busyAction && busyAction.valid ? busyAction.state : false
27+}
plugins/IndicatorsClient/indicators/network/secret-agent.cnew file+382
@@ -0,0 +1,382 @@
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+ * Alberto Ruiz <alberto.ruiz@canonical.com>
18+ * Renato Araujo Oliveira Filho <renato@canonical.com>
19+ */
20+
21+
22+#include <glib.h>
23+#include <glib-object.h>
24+#include <nm-secret-agent.h>
25+#include "secret-agent.h"
26+
27+#define UNITY_SETTINGS_TYPE_SECRET_AGENT (unity_settings_secret_agent_get_type ())
28+#define UNITY_SETTINGS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgent))
29+#define UNITY_SETTINGS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
30+#define UNITY_SETTINGS_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT))
31+#define UNITY_SETTINGS_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT))
32+#define UNITY_SETTINGS_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
33+#define UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentPrivate))
34+
35+#define AGENT_ID "com.canonical.settings.network.nm-agent"
36+
37+static gpointer unity_settings_secret_agent_parent_class = NULL;
38+
39+typedef struct _UnitySettingsSecretAgentPrivate UnitySettingsSecretAgentPrivate;
40+
41+struct _UnitySettingsSecretAgentPrivate {
42+ GQueue *requests;
43+};
44+
45+typedef struct _SecretRequest {
46+ gint id;
47+ NMSecretAgent *agent;
48+ NMConnection *connection;
49+ const char *connection_path;
50+ const char *setting_name;
51+ const char **hints;
52+ NMSecretAgentGetSecretsFlags flags;
53+ NMSecretAgentGetSecretsFunc callback;
54+ gpointer callback_data;
55+} SecretRequest;
56+
57+GType unity_settings_secret_agent_get_type (void) G_GNUC_CONST;
58+enum {
59+ UNITY_SETTINGS_SECRET_AGENT_DUMMY_PROPERTY
60+};
61+
62+enum {
63+ SECRET_REQUESTED,
64+ REQUEST_CANCELLED,
65+ LAST_SIGNAL
66+};
67+
68+static guint signals[LAST_SIGNAL] = { 0 };
69+
70+UnitySettingsSecretAgent* unity_settings_secret_agent_new (void);
71+UnitySettingsSecretAgent* unity_settings_secret_agent_construct (GType object_type);
72+
73+int
74+secret_request_find (SecretRequest *req,
75+ guint *id)
76+{
77+ if (req->id > *id)
78+ return -1;
79+
80+ if (req->id < *id)
81+ return 1;
82+
83+ return 0;
84+}
85+
86+void
87+unity_settings_secret_agent_provide_secret (UnitySettingsSecretAgent *agent,
88+ guint request,
89+ GHashTable *secrets)
90+{
91+ GList *iter;
92+ SecretRequest *req;
93+ UnitySettingsSecretAgentPrivate *priv = agent->priv;
94+
95+ iter = g_queue_find_custom (priv->requests,
96+ &request,
97+ (GCompareFunc)secret_request_find);
98+
99+ if (iter == NULL || iter->data == NULL)
100+ {
101+ g_warning ("Secret request with id <%d> was not found", (int)request);
102+ return;
103+ }
104+
105+ req = iter->data;
106+
107+ req->callback (NM_SECRET_AGENT (agent),
108+ req->connection,
109+ secrets,
110+ NULL,
111+ req->callback_data);
112+
113+ g_queue_remove_all (priv->requests, req);
114+ g_free (req);
115+ return;
116+}
117+
118+void
119+free_request (SecretRequest *req)
120+{
121+ g_object_unref (req->connection);
122+ g_free (req);
123+}
124+
125+void
126+unity_settings_secret_agent_cancel_request (UnitySettingsSecretAgent *agent,
127+ guint request)
128+{
129+ GList *iter;
130+ SecretRequest *req;
131+ UnitySettingsSecretAgentPrivate *priv = agent->priv;
132+ GError *error;
133+
134+ iter = g_queue_find_custom (priv->requests,
135+ &request,
136+ (GCompareFunc)secret_request_find);
137+
138+ if (iter == NULL || iter->data == NULL)
139+ {
140+ g_warning ("Secret request with id <%d> was not found", (int)request);
141+ return;
142+ }
143+
144+ req = iter->data;
145+ error = g_error_new (NM_SECRET_AGENT_ERROR,
146+ NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
147+ "This secret request was canceled by the user.");
148+
149+ req->callback (NM_SECRET_AGENT (agent),
150+ req->connection,
151+ NULL,
152+ error,
153+ req->callback_data);
154+
155+ g_queue_remove_all (priv->requests, req);
156+ free_request (req);
157+ return;
158+}
159+
160+static void
161+delete_secrets (NMSecretAgent *agent,
162+ NMConnection *connection,
163+ const char *connection_path,
164+ NMSecretAgentDeleteSecretsFunc callback,
165+ gpointer callback_data)
166+{
167+ g_debug ("delete secrets");
168+}
169+
170+/* If it returns G_MAXUINT it's considered an error */
171+static guint
172+find_available_id (UnitySettingsSecretAgentPrivate *priv)
173+{
174+ guint i = 0;
175+ guint candidate = 0;
176+
177+ if (g_queue_get_length (priv->requests) == G_MAXUINT)
178+ return G_MAXUINT;
179+
180+ while (i < g_queue_get_length (priv->requests))
181+ {
182+ SecretRequest *req = (SecretRequest*)g_queue_peek_nth (priv->requests, i);
183+
184+ if (req->id == candidate)
185+ {
186+ candidate++;
187+ i = 0;
188+ }
189+ else
190+ {
191+ i++;
192+ }
193+ }
194+
195+ return i;
196+}
197+
198+static void
199+get_secrets (NMSecretAgent *agent,
200+ NMConnection *connection,
201+ const char *connection_path,
202+ const char *setting_name,
203+ const char **hints,
204+ NMSecretAgentGetSecretsFlags flags,
205+ NMSecretAgentGetSecretsFunc callback,
206+ gpointer callback_data)
207+{
208+ guint id;
209+ UnitySettingsSecretAgentPrivate *priv = UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE (agent);
210+ SecretRequest *req = NULL;
211+
212+ if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE)
213+ {
214+ GError *error = g_error_new (NM_SECRET_AGENT_ERROR,
215+ NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
216+ "No password found for this connection.");
217+ callback (agent, connection, NULL, error, callback_data);
218+ g_error_free (error);
219+ return;
220+ }
221+
222+ id = find_available_id (priv);
223+ if (id == G_MAXUINT)
224+ {
225+ GError *error = g_error_new (NM_SECRET_AGENT_ERROR,
226+ NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
227+ "Reached maximum number of requests.");
228+ callback (agent, connection, NULL, error, callback_data);
229+ g_error_free (error);
230+ return;
231+ }
232+
233+ /* Adding a request */
234+ req = (SecretRequest*) g_malloc0 (sizeof (SecretRequest));
235+ *req = ((SecretRequest)
236+ { id,
237+ agent,
238+ connection,
239+ connection_path,
240+ setting_name,
241+ hints,
242+ flags,
243+ callback,
244+ callback_data });
245+
246+ g_object_ref (connection);
247+
248+ g_queue_push_tail (priv->requests, req);
249+
250+ g_signal_emit_by_name (agent,
251+ UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED,
252+ id,
253+ connection,
254+ setting_name,
255+ hints,
256+ flags);
257+}
258+
259+static void
260+save_secrets (NMSecretAgent *agent,
261+ NMConnection *connection,
262+ const char *connection_path,
263+ NMSecretAgentSaveSecretsFunc callback,
264+ gpointer callback_data)
265+{
266+ g_debug ("save secrets");
267+}
268+
269+static void
270+cancel_get_secrets (NMSecretAgent *agent,
271+ const char *connection_path,
272+ const char *setting_name)
273+{
274+ g_debug ("cancel get secrets");
275+}
276+
277+UnitySettingsSecretAgent*
278+unity_settings_secret_agent_construct (GType object_type)
279+{
280+ UnitySettingsSecretAgent * self = NULL;
281+ self = (UnitySettingsSecretAgent*) g_object_new (object_type,
282+ NM_SECRET_AGENT_IDENTIFIER, AGENT_ID,
283+ NULL);
284+ return self;
285+}
286+
287+
288+UnitySettingsSecretAgent*
289+unity_settings_secret_agent_new (void)
290+{
291+ return unity_settings_secret_agent_construct (UNITY_SETTINGS_TYPE_SECRET_AGENT);
292+}
293+
294+static void
295+destroy_pending_request (gpointer data)
296+{
297+ SecretRequest* req = (SecretRequest*)data;
298+ /* Reporting the cancellation of all pending requests */
299+ g_signal_emit_by_name (req->agent,
300+ UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED,
301+ req->id);
302+
303+ free_request (req);
304+}
305+
306+static void
307+unity_settings_secret_agent_finalize (GObject *agent)
308+{
309+ UnitySettingsSecretAgentPrivate *priv = UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE (agent);
310+
311+ g_queue_free_full (priv->requests, destroy_pending_request);
312+}
313+
314+static void
315+unity_settings_secret_agent_class_init (UnitySettingsSecretAgentClass *klass)
316+{
317+ unity_settings_secret_agent_parent_class = g_type_class_peek_parent (klass);
318+ NMSecretAgentClass *parent_class = NM_SECRET_AGENT_CLASS (klass);
319+ parent_class->get_secrets = get_secrets;
320+ parent_class->save_secrets = save_secrets;
321+ parent_class->delete_secrets = delete_secrets;
322+ parent_class->cancel_get_secrets = cancel_get_secrets;
323+
324+ g_type_class_add_private (klass, sizeof(UnitySettingsSecretAgentPrivate));
325+ G_OBJECT_CLASS (klass)->finalize = unity_settings_secret_agent_finalize;
326+
327+
328+ signals[SECRET_REQUESTED] = g_signal_new (UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED,
329+ G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),
330+ G_SIGNAL_RUN_FIRST,
331+ G_STRUCT_OFFSET (UnitySettingsSecretAgentClass, secret_requested),
332+ NULL, NULL, NULL,
333+ G_TYPE_NONE, 5,
334+ G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT);
335+
336+ signals[REQUEST_CANCELLED] = g_signal_new (UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED,
337+ G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),
338+ G_SIGNAL_RUN_FIRST,
339+ G_STRUCT_OFFSET (UnitySettingsSecretAgentClass, request_cancelled),
340+ NULL, NULL, NULL,
341+ G_TYPE_NONE, 1,
342+ G_TYPE_UINT);
343+}
344+
345+
346+static void
347+unity_settings_secret_agent_instance_init (UnitySettingsSecretAgent *self)
348+{
349+ self->priv = UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE (self);
350+ self->priv->requests = g_queue_new ();
351+}
352+
353+GType
354+unity_settings_secret_agent_get_type (void)
355+{
356+ static volatile gsize unity_settings_secret_agent_type_id__volatile = 0;
357+ if (g_once_init_enter (&unity_settings_secret_agent_type_id__volatile))
358+ {
359+ static const GTypeInfo g_define_type_info =
360+ {
361+ sizeof (UnitySettingsSecretAgentClass),
362+ (GBaseInitFunc) NULL,
363+ (GBaseFinalizeFunc) NULL,
364+ (GClassInitFunc) unity_settings_secret_agent_class_init,
365+ (GClassFinalizeFunc) NULL,
366+ NULL,
367+ sizeof (UnitySettingsSecretAgent),
368+ 0,
369+ (GInstanceInitFunc) unity_settings_secret_agent_instance_init,
370+ NULL
371+ };
372+ GType unity_settings_secret_agent_type_id;
373+ unity_settings_secret_agent_type_id = g_type_register_static (NM_TYPE_SECRET_AGENT,
374+ "UnitySettingsSecretAgent",
375+ &g_define_type_info,
376+ 0);
377+ g_once_init_leave (&unity_settings_secret_agent_type_id__volatile,
378+ unity_settings_secret_agent_type_id);
379+ }
380+
381+ return unity_settings_secret_agent_type_id__volatile;
382+}
plugins/IndicatorsClient/indicators/network/secret-agent.hnew file+102
@@ -0,0 +1,102 @@
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+ * Alberto Ruiz <alberto.ruiz@canonical.com>
18+ * Renato Araujo Oliveira Filho <renato@canonical.com>
19+ */
20+
21+#ifndef __SECRET_AGENT_H__
22+#define __SECRET_AGENT_H__
23+
24+#include <glib.h>
25+#include <glib-object.h>
26+#include <nm-secret-agent.h>
27+
28+/*
29+ * This class is a basic implementation of the NetworkManager SecretAgent base class.
30+ *
31+ * The purpose of this class is to handle credential requests from the network,
32+ * for example, from a WiFi hotspot or a VPN network.
33+ *
34+ * It queues requests objects (SecretRequest) on a GQueue in the private struct
35+ * of the class. And notifies the consumer of the class through the "secret-request"
36+ * and the "request-cancelled" signals with the following callback prototypes:
37+ *
38+ * void (*secret_requested) (UnitySettingsSecretAgent *self,
39+ * guint id,
40+ * NMConnection *connection,
41+ * const char *setting_name,
42+ * const char **hints,
43+ * NMSecretAgentGetSecretsFlags flags,
44+ * gpointer user_data);
45+ *
46+ * void (*request_cancelled) (UnitySettingsSecretAgent *self,
47+ * guint id,
48+ * gpointer user_data);
49+ *
50+ */
51+
52+
53+G_BEGIN_DECLS
54+
55+
56+#define UNITY_SETTINGS_TYPE_SECRET_AGENT (unity_settings_secret_agent_get_type ())
57+#define UNITY_SETTINGS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgent))
58+#define UNITY_SETTINGS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
59+#define UNITY_SETTINGS_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT))
60+#define UNITY_SETTINGS_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT))
61+#define UNITY_SETTINGS_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
62+
63+#define UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED "secret-requested"
64+#define UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED "request-cancelled"
65+
66+typedef struct _UnitySettingsSecretAgent UnitySettingsSecretAgent;
67+typedef struct _UnitySettingsSecretAgentClass UnitySettingsSecretAgentClass;
68+typedef struct _UnitySettingsSecretAgentPrivate UnitySettingsSecretAgentPrivate;
69+
70+struct _UnitySettingsSecretAgent {
71+ NMSecretAgent parent_instance;
72+ UnitySettingsSecretAgentPrivate * priv;
73+};
74+
75+struct _UnitySettingsSecretAgentClass {
76+ NMSecretAgentClass parent_class;
77+
78+ void (*secret_requested) (UnitySettingsSecretAgent *self,
79+ guint id,
80+ NMConnection *connection,
81+ const char *setting_name,
82+ const char **hints,
83+ NMSecretAgentGetSecretsFlags flags);
84+
85+ void (*request_cancelled) (UnitySettingsSecretAgent *self,
86+ guint id);
87+};
88+
89+
90+GType unity_settings_secret_agent_get_type (void) G_GNUC_CONST;
91+UnitySettingsSecretAgent* unity_settings_secret_agent_new (void);
92+UnitySettingsSecretAgent* unity_settings_secret_agent_construct (GType object_type);
93+
94+void unity_settings_secret_agent_provide_secret (UnitySettingsSecretAgent *agent,
95+ guint request,
96+ GHashTable *secrets);
97+void unity_settings_secret_agent_cancel_request (UnitySettingsSecretAgent *agent,
98+ guint request);
99+
100+G_END_DECLS
101+
102+#endif
plugins/IndicatorsClient/indicators/power/CMakeLists.txtnew file+28
@@ -0,0 +1,28 @@
1+set(INDICATORCLIENT_POWER_SRC
2+ indicatorclient_power.cpp
3+)
4+
5+qt5_add_resources(INDICATORCLIENT_POWER_RESOURCES_RCC
6+ indicatorclient_power.qrc
7+)
8+
9+add_library(indicatorclient_power STATIC
10+ ${INDICATORCLIENT_POWER_RESOURCES_RCC}
11+ ${INDICATORCLIENT_POWER_SRC}
12+)
13+
14+qt5_use_modules(indicatorclient_power Core Qml)
15+
16+set_target_properties(indicatorclient_power PROPERTIES COMPILE_FLAGS -fPIC)
17+
18+include_directories(
19+ ${CMAKE_CURRENT_SOURCE_DIR}
20+ ${indicatorclient_common_SOURCE_DIR}
21+ ${IndicatorsClientQml_SOURCE_DIR}
22+)
23+
24+target_link_libraries(indicatorclient_power
25+ indicatorclient_common
26+ ${QMENUMODEL_LDFLAGS}
27+)
28+
plugins/IndicatorsClient/indicators/power/artwork/battery_mock@18.pngnew file

Binary file not shown.

plugins/IndicatorsClient/indicators/power/indicatorclient_power.cppnew file+34
@@ -0,0 +1,34 @@
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+ * Ubo Riboni <ugo.riboni@canonical.com>
19+ */
20+
21+#include "indicatorclient_power.h"
22+
23+IndicatorClientPower::IndicatorClientPower(QObject *parent)
24+ : IndicatorClientCommon(parent)
25+{
26+ setTitle("Battery");
27+ setPriority(IndicatorPriority::POWER);
28+}
29+
30+void IndicatorClientPower::init(const QSettings& settings)
31+{
32+ IndicatorClientCommon::init(settings);
33+ Q_INIT_RESOURCE(indicatorclient_power);
34+}
plugins/IndicatorsClient/indicators/power/indicatorclient_power.hnew file+35
@@ -0,0 +1,35 @@
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+ * Ubo Riboni <ugo.riboni@canonical.com>
19+ */
20+
21+#ifndef INDICATORCLIENT_POWER_H
22+#define INDICATORCLIENT_POWER_H
23+
24+#include "indicatorclient_common.h"
25+
26+class IndicatorClientPower : public IndicatorClientCommon
27+{
28+ Q_OBJECT
29+public:
30+ IndicatorClientPower(QObject *parent=0);
31+
32+ void init(const QSettings& settings);
33+};
34+
35+#endif
plugins/IndicatorsClient/indicators/power/indicatorclient_power.qrcnew file+4
@@ -0,0 +1,4 @@
1+<RCC>
2+ <qresource prefix="/indicatorclient/power">
3+ </qresource>
4+</RCC>
plugins/IndicatorsClient/indicators/sound/CMakeLists.txtnew file+32
@@ -0,0 +1,32 @@
1+set(INDICATORCLIENT_SOUND_SRC
2+ indicatorclient_sound.cpp
3+)
4+
5+set(INDICATORCLIENT_SOUND_RESOURCES
6+ indicatorclient_sound.qrc
7+)
8+
9+qt5_add_resources(INDICATORCLIENT_SOUND_RESOURCES_RCC
10+ ${INDICATORCLIENT_SOUND_RESOURCES}
11+)
12+
13+add_library(indicatorclient_sound STATIC
14+ ${INDICATORCLIENT_SOUND_RESOURCES_RCC}
15+ ${INDICATORCLIENT_SOUND_SRC}
16+)
17+
18+qt5_use_modules(indicatorclient_sound Core Qml)
19+
20+set_target_properties(indicatorclient_sound PROPERTIES COMPILE_FLAGS -fPIC)
21+
22+include_directories(
23+ ${CMAKE_CURRENT_SOURCE_DIR}
24+ ${indicatorclient_common_SOURCE_DIR}
25+ ${IndicatorsClientQml_SOURCE_DIR}
26+)
27+
28+target_link_libraries(indicatorclient_sound
29+ indicatorclient_common
30+ ${QMENUMODEL_LDFLAGS}
31+)
32+
plugins/IndicatorsClient/indicators/sound/indicatorclient_sound.cppnew file+35
@@ -0,0 +1,35 @@
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+ */
19+
20+#include "indicatorclient_sound.h"
21+
22+IndicatorClientSound::IndicatorClientSound(QObject *parent)
23+ : IndicatorClientCommon(parent)
24+{
25+ setTitle("Sound");
26+ setPriority(IndicatorPriority::SOUND);
27+ setIcon(QUrl("audio-volume-high"));
28+}
29+
30+
31+void IndicatorClientSound::init(const QSettings& settings)
32+{
33+ IndicatorClientCommon::init(settings);
34+ Q_INIT_RESOURCE(indicatorclient_sound);
35+}
plugins/IndicatorsClient/indicators/sound/indicatorclient_sound.hnew file+34
@@ -0,0 +1,34 @@
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+ */
19+
20+#ifndef INDICATORCLIENT_SOUND_H
21+#define INDICATORCLIENT_SOUND_H
22+
23+#include "indicatorclient_common.h"
24+
25+class IndicatorClientSound : public IndicatorClientCommon
26+{
27+ Q_OBJECT
28+public:
29+ IndicatorClientSound(QObject *parent=0);
30+
31+ void init(const QSettings& settings);
32+};
33+
34+#endif
plugins/IndicatorsClient/indicators/sound/indicatorclient_sound.qrcnew file+4
@@ -0,0 +1,4 @@
1+<RCC>
2+ <qresource prefix="/soundplugin">
3+ </qresource>
4+</RCC>
plugins/IndicatorsClient/indicatorsfactory.cppnew file+55
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Michał Sawicz <michal.sawicz@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// local
21+#include "indicatorsfactory.h"
22+
23+// indicators
24+#include "indicators/datetime/indicatorclient_datetime.h"
25+#include "indicators/messaging/indicatorclient_messaging.h"
26+#include "indicators/network/indicatorclient_network.h"
27+#include "indicators/power/indicatorclient_power.h"
28+#include "indicators/sound/indicatorclient_sound.h"
29+
30+IndicatorsFactory::IndicatorsFactory()
31+{
32+ registerItem<IndicatorClientDateTime>("indicator-datetime");
33+ registerItem<IndicatorClientMessaging>("indicator-messaging");
34+ registerItem<IndicatorClientNetwork>("indicator-network");
35+ registerItem<IndicatorClientPower>("indicator-battery");
36+ registerItem<IndicatorClientSound>("indicator-sound");
37+}
38+
39+IndicatorsFactory::~IndicatorsFactory()
40+{
41+ qDeleteAll(m_factoryItems);
42+}
43+
44+template<class TYPE>
45+void IndicatorsFactory::registerItem(const QString& indicator)
46+{
47+ m_factoryItems[indicator] = new IndicatorFactoryItemTyped<TYPE>();
48+}
49+
50+IndicatorClientInterface::Ptr IndicatorsFactory::create(const QString& indicator, QObject* parent)
51+{
52+ if (!m_factoryItems.contains(indicator))
53+ return IndicatorClientInterface::Ptr();
54+ return m_factoryItems[indicator]->create(parent);
55+}
plugins/IndicatorsClient/indicatorsfactory.hnew file+59
@@ -0,0 +1,59 @@
1+/*
2+ * Copyright (C) 2012 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU 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 General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+#ifndef INDICATORS_FACTORY_H
20+#define INDICATORS_FACTORY_H
21+
22+#include <QString>
23+#include <QObject>
24+#include <QHash>
25+
26+#include "indicatorclientinterface.h"
27+
28+class IndicatorFactoryItem
29+{
30+public:
31+ virtual ~IndicatorFactoryItem() {}
32+ virtual IndicatorClientInterface::Ptr create(QObject* parent = 0) = 0;
33+};
34+
35+template<class TYPE>
36+class IndicatorFactoryItemTyped : public IndicatorFactoryItem
37+{
38+public:
39+ IndicatorFactoryItemTyped() {}
40+
41+ IndicatorClientInterface::Ptr create(QObject* parent = 0) { return std::make_shared<TYPE>(parent); }
42+};
43+
44+class IndicatorsFactory
45+{
46+public:
47+ IndicatorsFactory();
48+ virtual ~IndicatorsFactory();
49+
50+ IndicatorClientInterface::Ptr create(const QString& indicator, QObject* parent = 0);
51+
52+ template<class TYPE>
53+ void registerItem(const QString& indicator);
54+
55+private:
56+ QHash<QString, IndicatorFactoryItem*> m_factoryItems;
57+};
58+
59+#endif // INDICATORSCLIENT_PLUGIN_H
plugins/IndicatorsClient/indicatorsmanager.cppnew file+258
@@ -0,0 +1,258 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Michał Sawicz <michal.sawicz@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#include "indicatorsmanager.h"
21+#include "indicatorsfactory.h"
22+
23+#include <QStandardPaths>
24+#include <QSettings>
25+#include <QDebug>
26+
27+
28+class IndicatorsManager::IndicatorData
29+{
30+public:
31+ IndicatorData(const QString& name, const QFileInfo& fileInfo)
32+ : m_name(name)
33+ , m_fileInfo(fileInfo)
34+ , m_verified (true)
35+ {}
36+
37+ QString m_name;
38+ QFileInfo m_fileInfo;
39+
40+ bool m_verified;
41+ IndicatorClientInterface::Ptr m_obj;
42+};
43+
44+IndicatorsManager::IndicatorsManager(QObject* parent)
45+: QObject(parent)
46+, m_factory(new IndicatorsFactory())
47+{
48+}
49+
50+IndicatorsManager::~IndicatorsManager()
51+{
52+ unload();
53+}
54+
55+void IndicatorsManager::load()
56+{
57+ unload();
58+ QStringList xdgLocations = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
59+
60+ m_fsWatcher.reset(new QFileSystemWatcher(this));
61+
62+ Q_FOREACH(const QString& xdgLocation, xdgLocations)
63+ {
64+ QString indicator_path = QDir::cleanPath(xdgLocation + "/unity/indicators");
65+ QDir indicator_dir(indicator_path);
66+ if (indicator_dir.exists())
67+ {
68+ // watch folder for changes.
69+ m_fsWatcher->addPath(indicator_path);
70+
71+ load(indicator_dir);
72+ }
73+ }
74+
75+ QObject::connect(m_fsWatcher.data(), SIGNAL(directoryChanged(const QString&)), this, SLOT(onDirectoryChanged(const QString&)));
76+ QObject::connect(m_fsWatcher.data(), SIGNAL(fileChanged(const QString&)), this, SLOT(onFileChanged(const QString&)));
77+}
78+
79+void IndicatorsManager::onDirectoryChanged(const QString& direcory)
80+{
81+ load(QDir(direcory));
82+}
83+
84+void IndicatorsManager::onFileChanged(const QString& file)
85+{
86+ QFileInfo file_info(file);
87+ if (!file_info.exists())
88+ {
89+ unload(file_info);
90+ return;
91+ }
92+ else
93+ {
94+ load(QFileInfo(file));
95+ }
96+}
97+
98+void IndicatorsManager::load(const QDir& dir)
99+{
100+ startVerify(dir.canonicalPath());
101+
102+ QFileInfoList indicator_files = dir.entryInfoList(QStringList() << "*.indicator", QDir::Files);
103+ Q_FOREACH(const QFileInfo& indicator_file, indicator_files)
104+ {
105+ load(indicator_file);
106+ }
107+
108+ endVerify(dir.canonicalPath());
109+}
110+
111+void IndicatorsManager::load(const QFileInfo& file_info)
112+{
113+ QSettings indicator_settings(file_info.absoluteFilePath(), QSettings::IniFormat, this);
114+ indicator_settings.beginGroup("Indicator Service");
115+ QString name = indicator_settings.value("Name").toString();
116+
117+ auto iter = m_indicatorsData.find(name);
118+ if (iter != m_indicatorsData.end())
119+ {
120+ QString newFileInfoDir = QDir::cleanPath(file_info.canonicalPath());
121+ IndicatorData* currentData = (*iter);
122+ currentData->m_verified = true;
123+
124+ int file_info_location = -1;
125+ int current_data_location = -1;
126+
127+ QString currentDataDir = QDir::cleanPath(currentData->m_fileInfo.canonicalPath());
128+
129+ // if we've already got this indicator, we need to make sure we're not overwriting data which is
130+ // from a lower priority standard path
131+ QStringList xdgLocations = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
132+ for (int i = 0; i < xdgLocations.size(); i++)
133+ {
134+ QString indicatorDir = QDir::cleanPath(xdgLocations[i] + "/unity/indicators");
135+
136+ if (newFileInfoDir == indicatorDir)
137+ file_info_location = i;
138+ if (currentDataDir == indicatorDir)
139+ current_data_location = i;
140+
141+ if (file_info_location != -1 && current_data_location != -1)
142+ break;
143+ }
144+
145+ // file location is higher (or of equal) priority. overwrite.
146+ if (file_info_location <= current_data_location &&
147+ file_info != currentData->m_fileInfo)
148+ {
149+ currentData->m_fileInfo = file_info;
150+ Q_EMIT loaded(name);
151+ }
152+ }
153+ else
154+ {
155+ IndicatorData* data = new IndicatorData(name, file_info);
156+ data->m_verified = true;
157+ m_indicatorsData[name]= data;
158+ Q_EMIT loaded(name);
159+ }
160+}
161+
162+void IndicatorsManager::unload()
163+{
164+ QHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
165+ while(iter.hasNext())
166+ {
167+ iter.next();
168+ Q_EMIT aboutToBeUnloaded(iter.key());
169+ }
170+
171+ qDeleteAll(m_indicatorsData);
172+ m_indicatorsData.clear();
173+}
174+
175+void IndicatorsManager::unload(const QFileInfo& file)
176+{
177+ QMutableHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
178+ while(iter.hasNext())
179+ {
180+ iter.next();
181+ IndicatorData* data = iter.value();
182+ if (data->m_fileInfo.absoluteFilePath() == file.absoluteFilePath())
183+ {
184+ if (!data->m_verified)
185+ {
186+ QString name = data->m_name;
187+ Q_EMIT aboutToBeUnloaded(name);
188+
189+ delete data;
190+ iter.remove();
191+ }
192+ }
193+ }
194+}
195+
196+void IndicatorsManager::startVerify(const QString& path)
197+{
198+ QHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
199+ while(iter.hasNext())
200+ {
201+ iter.next();
202+ IndicatorData* data = iter.value();
203+ if (data->m_fileInfo.canonicalPath() == path)
204+ data->m_verified = false;
205+ }
206+}
207+
208+void IndicatorsManager::endVerify(const QString& path)
209+{
210+ QMutableHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
211+ while(iter.hasNext())
212+ {
213+ iter.next();
214+ IndicatorData* data = iter.value();
215+ if (data->m_fileInfo.canonicalPath() == path)
216+ {
217+ if (!data->m_verified)
218+ {
219+ QString name = data->m_name;
220+ Q_EMIT aboutToBeUnloaded(name);
221+
222+ delete data;
223+ iter.remove();
224+ }
225+ }
226+ }
227+}
228+
229+IndicatorClientInterface::Ptr IndicatorsManager::indicator(const QString& indicator)
230+{
231+ if (!m_indicatorsData.contains(indicator)) {
232+ qWarning() << Q_FUNC_INFO << "Invalid plugin name: " << indicator;
233+ return 0;
234+ }
235+
236+ IndicatorData *data = m_indicatorsData[indicator];
237+ if (data->m_obj)
238+ return data->m_obj;
239+
240+ IndicatorClientInterface::Ptr plugin = m_factory->create(indicator, this);
241+ if (plugin)
242+ {
243+ data->m_obj = plugin;
244+ plugin->init(QSettings(data->m_fileInfo.absoluteFilePath(), QSettings::IniFormat, this));
245+ }
246+ return plugin;
247+}
248+
249+QList<IndicatorClientInterface::Ptr> IndicatorsManager::indicators()
250+{
251+ QList<IndicatorClientInterface::Ptr> list;
252+ Q_FOREACH(IndicatorData* data, m_indicatorsData)
253+ {
254+ IndicatorClientInterface::Ptr plugin = indicator(data->m_name);
255+ list.append(plugin);
256+ }
257+ return list;
258+}
plugins/IndicatorsClient/indicatorsmanager.hnew file+70
@@ -0,0 +1,70 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Michał Sawicz <michal.sawicz@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+
21+#ifndef INDICATORS_MANAGER_H
22+#define INDICATORS_MANAGER_H
23+
24+#include <QObject>
25+#include <QFileSystemWatcher>
26+#include <QDir>
27+#include <QHash>
28+#include <QSharedPointer>
29+
30+#include "indicatorclientinterface.h"
31+
32+class IndicatorsFactory;
33+
34+class IndicatorsManager : public QObject
35+{
36+ Q_OBJECT
37+public:
38+ explicit IndicatorsManager(QObject* parent = 0);
39+ ~IndicatorsManager();
40+
41+ Q_INVOKABLE void load();
42+ Q_INVOKABLE void unload();
43+
44+ IndicatorClientInterface::Ptr indicator(const QString& indicator);
45+
46+ QList<IndicatorClientInterface::Ptr> indicators();
47+
48+Q_SIGNALS:
49+ void loaded(const QString& indicator);
50+ void aboutToBeUnloaded(const QString& indicator);
51+
52+private Q_SLOTS:
53+ void onDirectoryChanged(const QString& direcory);
54+ void onFileChanged(const QString& file);
55+
56+private:
57+ void load(const QDir& dir);
58+ void load(const QFileInfo& file);
59+ void unload(const QFileInfo& dir);
60+
61+ void startVerify(const QString& path);
62+ void endVerify(const QString& path);
63+
64+ class IndicatorData;
65+ QHash<QString, IndicatorData*> m_indicatorsData;
66+ QSharedPointer<QFileSystemWatcher> m_fsWatcher;
67+ IndicatorsFactory* m_factory;
68+};
69+
70+#endif // INDICATORS_MANAGER_H
plugins/IndicatorsClient/indicatorsmodel.cppnew file+320
@@ -0,0 +1,320 @@
1+/*
2+ * Copyright 2012 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+ */
19+
20+#include "indicatorsmodel.h"
21+#include "indicatorsmanager.h"
22+#include "widgetsmap.h"
23+#include "indicatorclientinterface.h"
24+
25+#include <QQmlContext>
26+#include <QQmlEngine>
27+#include <QDebug>
28+
29+
30+static bool comparePlugins(const IndicatorClientInterface::Ptr obj1, const IndicatorClientInterface::Ptr obj2)
31+{
32+ return obj1->priority() < obj2->priority();
33+}
34+
35+/*!
36+ \qmltype IndicatorsModel
37+ \inherits QAbstractListModel
38+
39+ \brief The IndicatorsModel class defines the list model for indicators plugins
40+
41+ \b {This component is under heavy development.}
42+
43+ This class expose the available indicators.
44+
45+ \code
46+ IndicatorsModel {
47+ id: menuModel
48+ }
49+
50+ ListView {
51+ id: view
52+ model: menuModel
53+ Component.onCompleted: menuModel.load()
54+ }
55+ \endcode
56+*/
57+IndicatorsModel::IndicatorsModel(QObject *parent)
58+ : QAbstractListModel(parent)
59+{
60+ m_manager = new IndicatorsManager(this);
61+ QObject::connect(m_manager, SIGNAL(loaded(const QString&)), this, SLOT(onIndicatorLoaded(const QString&)));
62+ QObject::connect(m_manager, SIGNAL(aboutToBeUnloaded(const QString&)), this, SLOT(onIndicatorAboutToBeUnloaded(const QString&)));
63+ m_widgetsMap = new WidgetsMap;
64+
65+ QObject::connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
66+ QObject::connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
67+ QObject::connect(this, SIGNAL(modelReset()), this, SIGNAL(countChanged()));
68+}
69+
70+/*! \internal */
71+IndicatorsModel::~IndicatorsModel()
72+{
73+ delete m_widgetsMap;
74+ delete m_manager;
75+}
76+
77+/*!
78+ \qmlmethod IndicatorsModel::get(int)
79+
80+ Returns the item at index in the model. This allows the item data to be accessed from JavaScript:
81+ \b Note: methods should only be called after the Component has completed.
82+*/
83+QVariantMap IndicatorsModel::get(int row) const
84+{
85+ QVariantMap result;
86+
87+ QModelIndex index = this->index(row);
88+ if (index.isValid()) {
89+ QMap<int, QVariant> data = itemData(index);
90+ const QHash<int, QByteArray> roleNames = this->roleNames();
91+ Q_FOREACH(int i, roleNames.keys()) {
92+ result.insert(roleNames[i], data[i]);
93+ }
94+ }
95+ return result;
96+}
97+
98+/*!
99+ \qmlproperty IndicatorsModel::count
100+ The number of data entries in the model.
101+
102+ \b Note: methods should only be called after the Component has completed.
103+*/
104+int IndicatorsModel::count() const
105+{
106+ return rowCount();
107+}
108+
109+/*!
110+ \qmlproperty WidgetsMap IndicatorsModel::widgetsMap
111+ This property holds the map for all new widgets registered by dynamically loaded plugins.
112+*/
113+WidgetsMap* IndicatorsModel::widgetsMap() const
114+{
115+ return m_widgetsMap;
116+}
117+
118+/*!
119+ \qmlmethod IndicatorsModel::unload()
120+
121+ Load all plugins.
122+*/
123+void IndicatorsModel::load()
124+{
125+ m_widgetsMap->clear();
126+ m_plugins.clear();
127+ m_manager->load();
128+}
129+
130+/*!
131+ \qmlmethod IndicatorsModel::unload()
132+
133+ Unload all plugins.
134+*/
135+void IndicatorsModel::unload()
136+{
137+ m_widgetsMap->clear();
138+ m_manager->unload();
139+}
140+
141+/*! \internal */
142+void IndicatorsModel::onIndicatorLoaded(const QString& indicator)
143+{
144+ IndicatorClientInterface::Ptr plugin = m_manager->indicator(indicator);
145+ if (!plugin)
146+ return;
147+
148+ QList<IndicatorClientInterface::Ptr>::iterator i = qLowerBound(m_plugins.begin(), m_plugins.end(), plugin, comparePlugins);
149+ int insert_pos = qMin(i - m_plugins.begin(), m_plugins.count());
150+
151+ beginInsertRows(QModelIndex(), insert_pos, insert_pos);
152+
153+ m_widgetsMap->append(plugin->widgets());
154+
155+ QObject* obj = dynamic_cast<QObject*>(plugin.get());
156+ if (obj)
157+ {
158+ QObject::connect(obj, SIGNAL(iconChanged(const QUrl&)), this, SLOT(onIconChanged()));
159+ QObject::connect(obj, SIGNAL(titleChanged(const QString&)), this, SLOT(onTitleChanged()));
160+ QObject::connect(obj, SIGNAL(labelChanged(const QString&)), this, SLOT(onLabelChanged()));
161+ }
162+
163+ m_plugins.insert(i, plugin);
164+
165+ endInsertRows();
166+
167+ Q_EMIT widgetsMapChanged(m_widgetsMap);
168+}
169+
170+/*! \internal */
171+void IndicatorsModel::onIndicatorAboutToBeUnloaded(const QString& indicator)
172+{
173+ IndicatorClientInterface::Ptr plugin = m_manager->indicator(indicator);
174+ if (!plugin)
175+ return;
176+
177+ int i = 0;
178+ QMutableListIterator<IndicatorClientInterface::Ptr> iter(m_plugins);
179+ while(iter.hasNext())
180+ {
181+ if (plugin == iter.next())
182+ {
183+ beginRemoveRows(QModelIndex(), i, i);
184+ iter.remove();
185+ endRemoveRows();
186+ }
187+ i++;
188+ }
189+
190+}
191+
192+/*! \internal */
193+void IndicatorsModel::onIconChanged()
194+{
195+ notifyDataChanged(QObject::sender(), IconSource);
196+}
197+
198+/*! \internal */
199+void IndicatorsModel::onTitleChanged()
200+{
201+ notifyDataChanged(QObject::sender(), Title);
202+}
203+
204+/*! \internal */
205+void IndicatorsModel::onLabelChanged()
206+{
207+ notifyDataChanged(QObject::sender(), Label);
208+}
209+
210+/*! \internal */
211+void IndicatorsModel::notifyDataChanged(QObject *sender, int role)
212+{
213+ IndicatorClientInterface* plugin = dynamic_cast<IndicatorClientInterface*>(sender);
214+ if (!plugin)
215+ return;
216+
217+ int index = 0;
218+ QMutableListIterator<IndicatorClientInterface::Ptr> iter(m_plugins);
219+ while(iter.hasNext())
220+ {
221+ if (iter.next().get() == plugin)
222+ {
223+ QModelIndex changedIndex = this->index(index);
224+ dataChanged(changedIndex, changedIndex, QVector<int>() << role);
225+ break;
226+ }
227+ index++;
228+ }
229+}
230+
231+/*! \internal */
232+QHash<int, QByteArray> IndicatorsModel::roleNames() const
233+{
234+ static QHash<int, QByteArray> roles;
235+ if (roles.isEmpty()) {
236+ roles[Title] = "title";
237+ roles[IconSource] = "iconSource";
238+ roles[Label] = "label";
239+ roles[Description] = "description";
240+ roles[QMLComponent] = "component";
241+ roles[InitialProperties] = "initialProperties";
242+ roles[IsValid] = "isValid";
243+ }
244+ return roles;
245+}
246+
247+/*! \internal */
248+int IndicatorsModel::columnCount(const QModelIndex &) const
249+{
250+ return 1;
251+}
252+
253+/*! \internal */
254+QVariant IndicatorsModel::data(const QModelIndex &index, int role) const
255+{
256+ if (!index.isValid() || index.row() >= m_plugins.size())
257+ return QVariant();
258+
259+ QVariant attribute;
260+
261+ IndicatorClientInterface::Ptr plugin = m_plugins[index.row()];
262+
263+ switch (role) {
264+ case Title:
265+ if (plugin) {
266+ attribute = QVariant(plugin->title());
267+ }
268+ break;
269+ case IconSource:
270+ if (plugin) {
271+ return plugin->icon().toString();
272+ } else {
273+ attribute = QVariant("No plugin");
274+ }
275+ break;
276+ case Label:
277+ if (plugin) {
278+ attribute = QVariant(plugin->label());
279+ }
280+ break;
281+ case Description:
282+ {
283+ if (plugin) {
284+ attribute = QVariant(plugin->description());
285+ }
286+ break;
287+ }
288+ case QMLComponent:
289+ if (plugin) {
290+ QQmlContext *context = QQmlEngine::contextForObject(this);
291+ if (context) {
292+ attribute = QVariant::fromValue<QQmlComponent*>(plugin->component(context->parentContext()->engine()));
293+ }
294+ }
295+ break;
296+ case InitialProperties:
297+ if (plugin) {
298+ attribute = plugin->initialProperties();
299+ }
300+ break;
301+ case IsValid:
302+ attribute = QVariant(plugin != 0);
303+ break;
304+ default:
305+ break;
306+ }
307+ return attribute;
308+}
309+
310+/*! \internal */
311+QModelIndex IndicatorsModel::parent(const QModelIndex&) const
312+{
313+ return QModelIndex();
314+}
315+
316+/*! \internal */
317+int IndicatorsModel::rowCount(const QModelIndex&) const
318+{
319+ return m_plugins.count();
320+}
plugins/IndicatorsClient/indicatorsmodel.hnew file+86
@@ -0,0 +1,86 @@
1+/*
2+ * Copyright 2012 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+ * Nick Dedekind <nick.dedekind@canonical.com>
19+ */
20+
21+#ifndef INDICATORSMODEL_H
22+#define INDICATORSMODEL_H
23+
24+#include "indicatorclientinterface.h"
25+
26+#include <QAbstractListModel>
27+#include <QQmlEngine>
28+
29+class WidgetsMap;
30+class IndicatorsManager;
31+
32+class IndicatorsModel : public QAbstractListModel
33+{
34+ Q_OBJECT
35+ Q_PROPERTY(WidgetsMap* widgetsMap READ widgetsMap NOTIFY widgetsMapChanged)
36+ Q_PROPERTY(int count READ count NOTIFY countChanged)
37+
38+public:
39+ enum ModelRoles {
40+ Title = 0,
41+ IconSource,
42+ Label,
43+ Description,
44+ QMLComponent,
45+ InitialProperties,
46+ IsValid
47+ };
48+
49+ IndicatorsModel(QObject *parent=0);
50+ ~IndicatorsModel();
51+
52+ WidgetsMap* widgetsMap() const;
53+
54+ Q_INVOKABLE void load();
55+ Q_INVOKABLE void unload();
56+
57+ Q_INVOKABLE QVariantMap get(int row) const;
58+
59+ /* QAbstractItemModel */
60+ QHash<int, QByteArray> roleNames() const;
61+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
62+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
63+ QModelIndex parent (const QModelIndex &index) const;
64+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
65+
66+Q_SIGNALS:
67+ void widgetsMapChanged(WidgetsMap *widgetsMap);
68+ void countChanged();
69+
70+private Q_SLOTS:
71+ void onIconChanged();
72+ void onTitleChanged();
73+ void onLabelChanged();
74+ void onIndicatorLoaded(const QString& indicator);
75+ void onIndicatorAboutToBeUnloaded(const QString& indicator);
76+
77+private:
78+ IndicatorsManager *m_manager;
79+ WidgetsMap* m_widgetsMap;
80+ QList<IndicatorClientInterface::Ptr> m_plugins;
81+
82+ void notifyDataChanged(QObject *sender, int role);
83+ int count() const;
84+};
85+
86+#endif // INDICATORSMODEL_H
plugins/IndicatorsClient/plugin.cppnew file+37
@@ -0,0 +1,37 @@
1+/*
2+ * Copyright (C) 2012 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU 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 General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Michał Sawicz <michal.sawicz@canonical.com>
17+ */
18+
19+// Qt
20+#include <QtQml>
21+
22+// self
23+#include "plugin.h"
24+
25+// local
26+#include "flatmenuproxymodel.h"
27+#include "indicatorsmanager.h"
28+#include "widgetsmap.h"
29+#include "indicatorsmodel.h"
30+
31+void IndicatorsClientPlugin::registerTypes(const char *uri)
32+{
33+ qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
34+ qmlRegisterUncreatableType<WidgetsMap>(uri, 0, 1, "WidgetsMap", "WidgetsMap must be created by PluginModel");
35+ qmlRegisterType<FlatMenuProxyModel>(uri, 0, 1, "FlatMenuProxyModel");
36+ qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
37+}
plugins/IndicatorsClient/plugin.hnew file+32
@@ -0,0 +1,32 @@
1+/*
2+ * Copyright (C) 2012 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU 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 General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+#ifndef INDICATORSCLIENT_PLUGIN_H
20+#define INDICATORSCLIENT_PLUGIN_H
21+
22+#include <QtQml/QQmlExtensionPlugin>
23+
24+class IndicatorsClientPlugin : public QQmlExtensionPlugin
25+{
26+ Q_OBJECT
27+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
28+public:
29+ void registerTypes(const char *uri);
30+};
31+
32+#endif // INDICATORSCLIENT_PLUGIN_H
plugins/IndicatorsClient/qml/BasicMenu.qmlnew file+51
@@ -0,0 +1,51 @@
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+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components.ListItems 0.1 as ListItem
22+
23+ListItem.Standard {
24+ id: _priv
25+
26+ property bool listViewIsCurrentItem : false
27+ property QtObject menu
28+ property QtObject actionGroup
29+ property alias color: __bg.color
30+
31+ showDivider: false
32+ __foregroundColor: "#e8e1d0"
33+
34+ backgroundIndicator: RemoveBackground {
35+ state: _priv.swipingState
36+ }
37+
38+ Rectangle {
39+ id: __bg
40+
41+ anchors.fill: parent
42+ color: "#221e1c"
43+ z: -1
44+ }
45+
46+ function listViewSelectItem(targetIndex) {
47+ if (__menuFactory != undefined) {
48+ return __menuFactory.selectItem(targetIndex)
49+ }
50+ }
51+}
plugins/IndicatorsClient/qml/ButtonMenu.qmlnew file+44
@@ -0,0 +1,44 @@
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+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+BasicMenu {
24+ property variant action: menu && actionGroup ? actionGroup.action(menu.action) : undefined
25+
26+ color: "#221e1b"
27+ height: undefined // If we're using implicitHieght, we need to make sure height is not set.
28+ implicitHeight: units.gu(7)
29+
30+ Button {
31+ text: menu ? menu.label : ""
32+ anchors.horizontalCenter: parent.horizontalCenter
33+ anchors.verticalCenter: parent.verticalCenter
34+ height: units.gu(4)
35+ width: units.gu(16)
36+ color: "#1b1817"
37+
38+ onClicked: {
39+ if (action && action.valid) {
40+ action.activate()
41+ }
42+ }
43+ }
44+}
plugins/IndicatorsClient/qml/DBusActionState.qmlnew file+104
@@ -0,0 +1,104 @@
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+ */
19+
20+import QtQuick 2.0
21+
22+/*!
23+ \qmltype DBusActionState
24+ \inqmlmodule IndicatorsClient 0.1
25+ \brief Helper class to connect dbus action state with qml components property
26+
27+ Exampiles:
28+ \qml
29+ Slider {
30+ id: slide
31+ }
32+ DBusActionState {
33+ action: "/ubuntu/sound/volume"
34+ target: slider
35+ property: "value"
36+ }
37+ \endqml
38+
39+ \b{This component is under heavy development.}
40+*/
41+
42+Item {
43+ id: dbusActionState
44+
45+ /*!
46+ \preliminary
47+ The dbus action name
48+ */
49+ property string action : undefined
50+
51+ /*!
52+ \preliminary
53+ This is a read-only property with the action current value
54+ */
55+ property variant value : undefined
56+
57+ /*!
58+ \preliminary
59+ The component which will have the property changed by action
60+ */
61+ property alias target: propertyBinding.target
62+
63+ /*!
64+ \preliminary
65+ The property name of \l target component which will be linked with action state
66+ */
67+ property alias property: propertyBinding.property
68+
69+ /*!
70+ \preliminary
71+ Use this to enable or disable the action state propagation to component property.
72+ */
73+ property bool active: true
74+
75+ Component.onCompleted: connectViewChanges ()
76+ onTargetChanged: connectViewChanges()
77+ onPropertyChanged: connectViewChanges()
78+
79+ Item {
80+ id: priv
81+ property variant actionObject : action && actionGroup ? actionGroup.action(action) : null
82+ property variant actionState: actionObject && actionObject.valid ? actionObject.state : undefined
83+
84+ Binding {
85+ id: propertyBinding
86+ value: priv.actionState
87+ when: (actionGroup && active && priv.actionObject && priv.actionObject.valid)
88+ }
89+ }
90+
91+ function connectViewChanges() {
92+ if (target && property) {
93+ var signalName = "on%1Changed".arg(property.charAt(0).toUpperCase() + property.slice(1));
94+ target[signalName].connect(onViewValueChanged);
95+ }
96+ }
97+
98+ function onViewValueChanged() {
99+ if (priv.actionObject.valid) {
100+ var propertyValue = target[property];
101+ priv.actionObject.updateState(propertyValue)
102+ }
103+ }
104+}
plugins/IndicatorsClient/qml/DivMenu.qmlnew file+26
@@ -0,0 +1,26 @@
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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+Rectangle {
24+ color: "#181514"
25+ implicitHeight: units.gu(1)
26+}
plugins/IndicatorsClient/qml/FactoryMenu.qmlnew file+89
@@ -0,0 +1,89 @@
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+ */
19+
20+import QtQuick 2.0
21+
22+Item {
23+ id: __menuFactory
24+
25+ property QtObject menu
26+ property QtObject listView
27+ property QtObject actionGroup
28+ property variant widgetsMap
29+ property bool isCurrentItem
30+ readonly property bool empty: (__loader.source !== "" && __loader.status == Loader.Ready) ? __loader.item.state === "EMPTY" : true
31+
32+ signal selectItem(int targetIndex)
33+
34+ implicitHeight: (__loader.status === Loader.Ready) ? __loader.item.implicitHeight : 0
35+ Loader {
36+ id: __loader
37+ anchors.fill: parent
38+ asynchronous: true
39+ source: {
40+ if (!__menuFactory.menu || !__menuFactory.menu.extra || !__menuFactory.widgetsMap) {
41+ return ''
42+ }
43+ var widgetType = __menuFactory.menu.extra.canonical_type
44+ var sourceFile = null
45+ if (widgetType) {
46+ sourceFile = __menuFactory.widgetsMap.find(widgetType)
47+ }
48+ if (!sourceFile) {
49+ if (widgetType === "com.canonical.indicator.root") {
50+ sourceFile == ""
51+ // Try discovery the item based on the basic properties
52+ } else if (menu.hasSection) {
53+ sourceFile = "SectionMenu.qml"
54+ } else {
55+ sourceFile = "Menu.qml"
56+ }
57+ }
58+ return sourceFile
59+ }
60+ onStatusChanged: {
61+ if (status == Loader.Ready) {
62+ item.listViewIsCurrentItem = __menuFactory.isCurrentItem
63+ }
64+ }
65+
66+ // Binding all properties for the item, to make sure that any change in the
67+ // property will be propagated to the __loader.item at any time
68+ Binding {
69+ target: __loader.item
70+ property: "listViewIsCurrentItem"
71+ value: isCurrentItem
72+ when: (__loader.status == Loader.Ready)
73+ }
74+
75+ Binding {
76+ target: __loader.item
77+ property: "actionGroup"
78+ value: __menuFactory.actionGroup
79+ when: (__loader.status == Loader.Ready)
80+ }
81+
82+ Binding {
83+ target: __loader.item
84+ property: "menu"
85+ value: __menuFactory.menu
86+ when: (__loader.status == Loader.Ready)
87+ }
88+ }
89+}
plugins/IndicatorsClient/qml/HLine.qmlnew file+27
@@ -0,0 +1,27 @@
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+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+Rectangle {
24+ height: units.dp(1)
25+ anchors.left: parent.left
26+ anchors.right: parent.right
27+}
plugins/IndicatorsClient/qml/Menu.qmlnew file+44
@@ -0,0 +1,44 @@
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+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Ubuntu.Components.ListItems 0.1 as ListItem
23+
24+BasicMenu {
25+ id: __menu
26+
27+ progression: menu && (menu.linkSubMenu !== undefined)
28+ text: menu && menu.label ? menu.label : ""
29+ color: "#221e1c"
30+ height: undefined // If we're using implicitHieght, we need to make sure height is not set.
31+ implicitHeight: units.gu(7)
32+
33+ HLine {
34+ id: ___topHLine
35+ anchors.top: parent.top
36+ color: "#403b37"
37+ }
38+
39+ HLine {
40+ id: ___bottomHLine
41+ anchors.bottom: parent.bottom
42+ color: "#060606"
43+ }
44+}
plugins/IndicatorsClient/qml/PluginItem.qmlnew file+214
@@ -0,0 +1,214 @@
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+ */
19+
20+import QtQuick 2.0
21+import QMenuModel 0.1
22+import Ubuntu.Components 0.1
23+import Ubuntu.Components.ListItems 0.1 as ListItem
24+import IndicatorsClient 0.1 as IndicatorsClient
25+
26+Item {
27+ id: main
28+
29+ //const
30+ property string device: "phone"
31+ property string title
32+ property alias emptyText: emptyLabel.text
33+ property variant widgetsMap : null
34+ property int busType
35+ property string busName
36+ property string objectPath
37+ property alias highlightFollowsCurrentItem : mainMenu.highlightFollowsCurrentItem
38+ readonly property real overshootHeight: (mainMenu.contentY < 0) ? -mainMenu.contentY : 0
39+ property bool __active: false
40+
41+ anchors.fill: parent
42+
43+ QDBusActionGroup {
44+ id: __actionGroup
45+ busType: main.busType
46+ busName: main.busName
47+ objectPath: main.objectPath
48+ }
49+
50+ IndicatorsClient.FlatMenuProxyModel {
51+ id: __proxyModel
52+
53+ busType: main.busType
54+ busName: main.busName
55+ objectPath: main.objectPath + "/" + device
56+ }
57+
58+ ListView {
59+ id: mainMenu
60+
61+ property int visibleItems: 0
62+
63+ model: __proxyModel
64+ anchors {
65+ fill: parent
66+ bottomMargin: Qt.inputMethod.visible ? (Qt.inputMethod.keyboardRectangle.height - main.anchors.bottomMargin) : 0
67+
68+ Behavior on bottomMargin {
69+ NumberAnimation {
70+ duration: 175
71+ easing.type: Easing.OutQuad
72+ }
73+ }
74+ onBottomMarginChanged: mainMenu.positionViewAtIndex(mainMenu.currentIndex, ListView.End)
75+ }
76+
77+ // Ensure all delegates are cached in order to improve smoothness of scrolling
78+ cacheBuffer: 10000
79+
80+ // Only allow flicking if the content doesn't fit on the page
81+ interactive: contentHeight > height
82+
83+ currentIndex: -1
84+ delegate: Item {
85+ id: item
86+ property bool ready: false
87+ property alias empty: factory.empty
88+
89+ anchors.left: parent.left
90+ anchors.right: parent.right
91+ height: div.height + factory.implicitHeight
92+ visible: height > 0
93+
94+ Component.onCompleted: {
95+ if (!item.empty) {
96+ mainMenu.visibleItems += 1;
97+ }
98+ ready = true
99+ }
100+ Component.onDestruction: {
101+ if (!item.empty) {
102+ mainMenu.visibleItems -= 1;
103+ }
104+ ready = false
105+ }
106+
107+ onEmptyChanged: {
108+ if (!ready) {
109+ return;
110+ }
111+ if (empty) {
112+ mainMenu.visibleItems -= 1;
113+ } else {
114+ mainMenu.visibleItems += 1;
115+ }
116+ }
117+
118+ ListView.onRemove: {
119+ if (!highlightFollowsCurrentItem) {
120+ mainMenu.currentIndex = -1;
121+ }
122+ }
123+
124+ Column {
125+ id: contents
126+
127+ anchors.fill: parent
128+
129+ DivMenu {
130+ id: div
131+
132+ anchors.left: parent.left
133+ anchors.right: parent.right
134+ // only visible if is a root or a section header element and the factory is visible
135+ height: {
136+ // skipe first item
137+ if (item.y == 0) {
138+ return 0;
139+ }
140+ if (hasSection || ((depth == 0) && (!factory.empty))) {
141+ return implicitHeight
142+ } else {
143+ return 0
144+ }
145+ }
146+ }
147+
148+ FactoryMenu {
149+ id: factory
150+
151+ actionGroup: __actionGroup
152+ isCurrentItem: item.ListView.isCurrentItem
153+ anchors.left: parent.left
154+ anchors.right: parent.right
155+ height: implicitHeight
156+ widgetsMap: main ? main.widgetsMap : null
157+ menu: model
158+
159+ onSelectItem: item.ListView.view.currentIndex = targetIndex
160+ }
161+ }
162+ }
163+ }
164+
165+ Label {
166+ id: emptyLabel
167+ visible: (mainMenu.visibleItems === 0)
168+ anchors.top: parent.top
169+ anchors.left: parent.left
170+ anchors.right: parent.right
171+ anchors.topMargin: units.gu(2)
172+ height: paintedHeight
173+ wrapMode: Text.WordWrap
174+ horizontalAlignment: Text.AlignHCenter
175+
176+ //style
177+ color: "#e8e1d0"
178+ fontSize: "medium"
179+
180+ text: "Empty!"
181+ }
182+
183+ function start()
184+ {
185+ reset()
186+ if (!main.__active) {
187+ __proxyModel.start()
188+ __actionGroup.start()
189+ main.__active = true
190+ }
191+ }
192+
193+ function stop()
194+ {
195+ if (main.__active) {
196+ main.__active = false
197+ __proxyModel.stop()
198+ __actionGroup.stop()
199+ }
200+ }
201+
202+ function reset()
203+ {
204+ mainMenu.currentIndex = -1
205+ mainMenu.positionViewAtBeginning()
206+ }
207+
208+ Component.onCompleted: {
209+ if ((busType != 0) && (busName != "") && (objectPath != "")) {
210+ start();
211+ }
212+ }
213+}
214+
plugins/IndicatorsClient/qml/ProgressMenu.qmlnew file+60
@@ -0,0 +1,60 @@
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+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+Menu {
24+
25+ // TODO: Replace this with the official ProgressBar component as soon as
26+ // it is available. For now, this rebuilds the Mockup as close as possible.
27+ UbuntuShape {
28+ id: progressBar
29+ anchors.right: parent.right
30+ anchors.rightMargin: units.gu(2)
31+ anchors.left: parent.left
32+ anchors.leftMargin: units.gu(2)
33+ height: units.gu(4)
34+ anchors.verticalCenter: parent.verticalCenter
35+ color: "#00000000"
36+
37+ property int minimumValue: 0
38+ property int maximumValue: 100
39+ property int value: 50
40+
41+ UbuntuShape {
42+ anchors.fill: parent
43+ anchors.rightMargin: parent.width - (parent.width * parent.value / parent.maximumValue)
44+ color: "#c94212"
45+ }
46+
47+ Label {
48+ anchors.centerIn: parent
49+ text: parent.value + " %"
50+ fontSize: "medium"
51+ color: "#e8e1d0"
52+ }
53+ }
54+
55+ DBusActionState {
56+ action: menu ? menu.action : undefined
57+ target: progressBar
58+ property: "value"
59+ }
60+}
plugins/IndicatorsClient/qml/RemoveBackground.qmlnew file+59
@@ -0,0 +1,59 @@
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+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Rectangle {
21+ id: __backgroundItem
22+
23+ anchors.fill: parent
24+ color: "#333130"
25+ Label {
26+ id: __backgroundText
27+
28+ property int slidingMargin: units.gu(3)
29+
30+ anchors.fill: parent
31+ verticalAlignment: Text.AlignVCenter
32+ text: "Clear"
33+ fontSize: "medium"
34+ color: "#e8e1d0"
35+ font.bold: true
36+ }
37+
38+ states: [
39+ State {
40+ name: "SwipingRight"
41+ PropertyChanges {
42+ target: __backgroundText
43+ anchors.rightMargin: __backgroundText.slidingMargin
44+ anchors.leftMargin: 0
45+ horizontalAlignment: Text.AlignRight
46+
47+ }
48+ },
49+ State {
50+ name: "SwipingLeft"
51+ PropertyChanges {
52+ target: __backgroundText
53+ anchors.rightMargin: 0
54+ anchors.leftMargin: __backgroundText.slidingMargin
55+ horizontalAlignment: Text.AlignLeft
56+ }
57+ }
58+ ]
59+}
plugins/IndicatorsClient/qml/SectionMenu.qmlnew file+59
@@ -0,0 +1,59 @@
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+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Ubuntu.Components.ListItems 0.1 as ListItem
23+
24+BasicMenu {
25+ id: __sectionMenu
26+
27+ property string label: menu && menu.label ? menu.label : ""
28+ property bool busy: false
29+ property variant _widgetsMap : widgetsMap
30+ property int count: menu && menu.linkSection ? menu.linkSection.count : 0
31+
32+ color: "#221e1b"
33+ anchors.left: parent ? parent.left : undefined
34+ anchors.right: parent ? parent.right : undefined
35+ height: undefined // If we're using implicitHieght, we need to make sure height is not set.
36+ implicitHeight: label !== "" ? __header.height : 0
37+ state: count === 0 ? "EMPTY" : ""
38+
39+ ListItem.Header {
40+ id: __header
41+
42+ text: label
43+ height: units.gu(4)
44+ anchors.left: parent.left
45+ anchors.right: parent.right
46+ anchors.top: parent.top
47+ visible: text != ""
48+
49+ ActivityIndicator {
50+ id: indicator
51+ running: busy
52+ anchors.margins: units.gu(0.5)
53+ anchors.right: parent.right
54+ height: parent.height - (anchors.margins * 2)
55+ width: height
56+ anchors.verticalCenter: parent.verticalCenter
57+ }
58+ }
59+}
plugins/IndicatorsClient/qml/SliderMenu.qmlnew file+66
@@ -0,0 +1,66 @@
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+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+Menu {
24+ id: _sliderMenu
25+
26+ property alias minimumValue: slider.minimumValue
27+ property alias maximumValue: slider.maximumValue
28+ property alias value: slider.value
29+
30+ control: Slider {
31+ id: slider
32+ width: _sliderMenu.text ? units.gu(20) : _sliderMenu.width - units.gu(4)
33+ anchors.verticalCenter: parent.verticalCenter
34+ live: false
35+ // FIXME: The interval should be [0.0 - 1.0]. Unfortunately, when
36+ // reaching the boundaries (0.0 or 1.0), the value is converted
37+ // to an integer when automatically wrapped in a variant when
38+ // passed to QStateAction::updateState(…). The server chokes on
39+ // those values, complaining that they’re not of the right type…
40+ minimumValue: menu.extra.canonical_min ? menu.extra.canonical_min * 1.000001 : 0.0000001
41+ maximumValue: menu.extra.canonical_max ? menu.extra.canonical_max * 1.000001 : 0.9999999
42+
43+ Binding {
44+ target: slider.ItemStyle.style
45+ property: "backgroundColor"
46+ value: Qt.rgba(0.5, 0.5, 0.5, 0.1)
47+ }
48+
49+ Binding {
50+ target: slider.ItemStyle.style
51+ property: "backgroundOpacity"
52+ value: 1.0
53+ }
54+
55+ // Use this to disable the label, since there is not way to do it on the component.
56+ function formatValue(v) {
57+ return ""
58+ }
59+ }
60+
61+ DBusActionState {
62+ action: menu ? menu.action : undefined
63+ target: slider
64+ property: "value"
65+ }
66+}
plugins/IndicatorsClient/qml/SwitchMenu.qmlnew file+36
@@ -0,0 +1,36 @@
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+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+Menu {
24+ control: Switch {
25+ id: switcher
26+
27+ anchors.verticalCenter: parent.verticalCenter
28+ anchors.right: parent.right
29+ }
30+
31+ DBusActionState {
32+ action: menu ? menu.action : undefined
33+ target: switcher
34+ property: "checked"
35+ }
36+}
plugins/IndicatorsClient/qml/TextMenu.qmlnew file+81
@@ -0,0 +1,81 @@
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+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+Menu {
24+ id: _textMenu
25+
26+ property alias text: _textField.text
27+ property alias password: _showPassword.visible
28+
29+ implicitHeight: password ? units.gu(10) : units.gu(7)
30+
31+ Column {
32+ id: _contentColumn
33+ spacing: units.gu(0.5)
34+ anchors {
35+ left: parent.left
36+ right: parent.right
37+ verticalCenter: parent.verticalCenter
38+ margins: units.gu(3)
39+ }
40+
41+ TextField {
42+ id: _textField
43+
44+ anchors {
45+ left: parent.left
46+ right: parent.right
47+ }
48+
49+ placeholderText: "Password"
50+ echoMode: _textMenu.password && !_checkBox.checked ? TextInput.Password : TextInput.Normal
51+ }
52+
53+ Row {
54+ id: _showPassword
55+
56+ visible: false
57+ anchors {
58+ left: parent.left
59+ right: parent.right
60+
61+ }
62+
63+ spacing: units.gu(1)
64+
65+ CheckBox {
66+ id: _checkBox
67+ }
68+
69+ Label {
70+ text: "Show password"
71+ anchors.verticalCenter: _checkBox.verticalCenter
72+ }
73+ }
74+ }
75+
76+ DBusActionState {
77+ action: menu ? menu.action : undefined
78+ target: _textField
79+ property: "text"
80+ }
81+}
plugins/IndicatorsClient/qmldirnew file+18
@@ -0,0 +1,18 @@
1+plugin IndicatorsClientQml
2+
3+BasicMenu 0.1 qml/BasicMenu.qml
4+ButtonMenu 0.1 qml/ButtonMenu.qml
5+DBusActionState 0.1 qml/DBusActionState.qml
6+DivMenu 0.1 qml/DivMenu.qml
7+FactoryMenu 0.1 qml/FactoryMenu.qml
8+HLine 0.1 qml/HLine.qml
9+Menu 0.1 qml/Menu.qml
10+PluginItem 0.1 qml/PluginItem.qml
11+RemovableMenu 0.1 qml/RemovableMenu.qml
12+SectionMenu 0.1 qml/SectionMenu.qml
13+SliderMenu 0.1 qml/SliderMenu.qml
14+SwitchMenu 0.1 qml/SwitchMenu.qml
15+TextMenu 0.1 qml/TextMenu.qml
16+ProgressMenu 0.1 qml/ProgressMenu.qml
17+
18+internal RemoveBackground qml/RemoveBackground.qml
plugins/IndicatorsClient/widgetsmap.cppnew file+82
@@ -0,0 +1,82 @@
1+/*
2+ * Copyright 2012 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+ */
19+
20+#include "widgetsmap.h"
21+
22+/*!
23+ \qmltype WidgetsMap
24+ \inherits QObject
25+
26+ \brief The WidgetsMap class defines a auxiliary map class with all widgets registered by the plugins.
27+
28+ \b {This component is under heavy development.}
29+
30+ \code
31+ PluginModel {
32+ id: menuModel
33+ baseDir: "/usr/share/indicators"
34+ }
35+
36+ ListView {
37+ id: view
38+ model: menuModel
39+ delegate: menuModel.widgetsMap.find("myWidget")
40+ Component.onCompleted: menuModel.load()
41+ }
42+ \endcode
43+*/
44+WidgetsMap::WidgetsMap(QObject *parent)
45+ :QObject(parent)
46+{
47+}
48+
49+/*! \internal */
50+void WidgetsMap::append(WidgetsMapType types)
51+{
52+ Q_FOREACH(QString key, types.keys()) {
53+ m_map.insert(key, types[key]);
54+ }
55+}
56+
57+/*! \internal */
58+void WidgetsMap::clear()
59+{
60+ m_map.clear();
61+}
62+
63+/*!
64+ \qmlmethod WidgetsMap::map()
65+
66+ Return a QVariantMap with the WidgetsMap contents.
67+*/
68+WidgetsMapType WidgetsMap::map() const
69+{
70+ return m_map;
71+}
72+
73+/*!
74+ \qmlmethod WidgetsMap::find(QString widgetType)
75+
76+ Look for a widgetType registered by any plugin and return the file that represent
77+ this type, or a empty QUrl if the type does not exists.
78+*/
79+QUrl WidgetsMap::find(const QString &widget) const
80+{
81+ return m_map[widget];
82+}
plugins/IndicatorsClient/widgetsmap.hnew file+46
@@ -0,0 +1,46 @@
1+/*
2+ * Copyright 2012 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+ */
19+
20+#ifndef WIDGETSMAP_H
21+#define WIDGETSMAP_H
22+
23+#include <QObject>
24+#include <QMap>
25+#include <QString>
26+#include <QUrl>
27+
28+typedef QMap<QString, QUrl> WidgetsMapType;
29+
30+class WidgetsMap : public QObject
31+{
32+ Q_OBJECT
33+public:
34+ WidgetsMap(QObject *parent=0);
35+
36+ void append(WidgetsMapType types);
37+ void clear();
38+
39+ Q_INVOKABLE WidgetsMapType map() const;
40+ Q_INVOKABLE QUrl find(const QString &widget) const;
41+
42+private:
43+ WidgetsMapType m_map;
44+};
45+
46+#endif
tests/qmltests/Panel/tst_IndicatorRow.qml+2−2
@@ -19,7 +19,7 @@ import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import ".."
2121import "../../../Panel"
22−import Ubuntu.ChewieUI 0.1 as ChewieUI
22+import IndicatorsClient 0.1 as IndicatorsClient
2323
2424/*
2525 This tests the IndicatorRow component by using a fake model to stage data in the indicators
@@ -51,7 +51,7 @@ Item {
5151 indicatorsModel: indicatorModel
5252 }
5353
54− ChewieUI.PluginModel {
54+ IndicatorsClient.IndicatorsModel {
5555 id: indicatorModel
5656 }
5757
tests/qmltests/Panel/tst_MenuContent.qml+2−2
@@ -19,7 +19,7 @@ import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import ".."
2121import "../../../Panel"
22−import Ubuntu.ChewieUI 0.1 as ChewieUI
22+import IndicatorsClient 0.1 as IndicatorsClient
2323
2424Item {
2525 id: shell
@@ -39,7 +39,7 @@ Item {
3939 Item { id: handle }
4040
4141
42− ChewieUI.PluginModel {
42+ IndicatorsClient.IndicatorsModel {
4343 id: indicatorsModel
4444 }
4545
tests/qmltests/Panel/tst_Panel.qml−1
@@ -19,7 +19,6 @@ import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import ".."
2121import "../../../Panel"
22−import Ubuntu.ChewieUI 0.1 as ChewieUI
2322
2423/*
2524 This tests the Panel component using a fake model to stage data in the indicators