on xenial help sign in
Moved indicators-client code into unity8. Fixes: https://bugs.launchpad.net/bugs/1191132, https://bugs.launchpad.net/bugs/1191822.
33fdf7cNick Dedekind
CMakeLists.txt+3−1
@@ -91,7 +91,8 @@ enable_testing()
91
91
92# Autopilot tests
92# Autopilot tests
93include(autopilot)
93include(autopilot)
94−declare_autopilot_test(unity8 ${CMAKE_SOURCE_DIR}/tests/autopilot/)
94+declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
95+declare_autopilot_test(indicators_client unity8.indicators_client ${CMAKE_SOURCE_DIR}/tests/autopilot/)
95
96
96set(SHELL_APP unity8)
97set(SHELL_APP unity8)
97
98
@@ -132,6 +133,7 @@ install(FILES ${QML_JS_FILES}
132# add subdirectories to build
133# add subdirectories to build
133add_subdirectory(tests)
134add_subdirectory(tests)
134add_subdirectory(plugins)
135add_subdirectory(plugins)
136+add_subdirectory(src)
135
137
136# install subdirectories
138# install subdirectories
137set(QML_DIRS
139set(QML_DIRS
Panel/IndicatorItem.qml+22−35
@@ -16,55 +16,42 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19+import Unity.Indicators 0.1 as Indicators
19
20
20Item {
21Item {
21 id: indicatorItem
22 id: indicatorItem
22
23
23− property alias iconSource: itemImage.source
24+ property alias widgetSource: loader.source
24− property alias label: itemLabel.text
25 property bool highlighted: false
25 property bool highlighted: false
26 property bool dimmed: false
26 property bool dimmed: false
27+ property var indicatorProperties: undefined
28+
29+ opacity: dimmed ? 0.4 : 1
27
30
28 // only visible when non-empty
31 // only visible when non-empty
29− visible: label != "" || iconSource != ""
32+ visible: loader.item != undefined && loader.status == Loader.Ready ? loader.item.enabled : false
30− width: itemRow.width + units.gu(1)
33+ width: visible ? loader.item.width : 0
34+
35+ Loader {
36+ id: loader
37+
38+ onLoaded: {
39+ item.height = Qt.binding(function() { return indicatorItem.height; });
40+
41+ for(var pName in indicatorProperties) {
42+ if (item.hasOwnProperty(pName)) {
43+ item[pName] = indicatorProperties[pName];
44+ }
45+ }
46+ }
47+ }
31
48
32 Rectangle {
49 Rectangle {
33 color: "#dd4814"
50 color: "#dd4814"
51+ objectName: "highlight"
34 height: units.dp(2)
52 height: units.dp(2)
35 width: parent.width
53 width: parent.width
36 anchors.top: parent.bottom
54 anchors.top: parent.bottom
37 visible: highlighted
55 visible: highlighted
38 }
56 }
39−
40− Row {
41− id: itemRow
42− objectName: "itemRow"
43− anchors {
44− top: parent.top
45− bottom: parent.bottom
46− horizontalCenter: parent.horizontalCenter
47− }
48− spacing: units.gu(0.5)
49− opacity: dimmed ? 0.4 : 1
50−
51− Image {
52− id: itemImage
53− objectName: "itemImage"
54− visible: source != ""
55− height: units.gu(2.5)
56− width: units.gu(2.5)
57− anchors.verticalCenter: parent.verticalCenter
58− }
59−
60− Label {
61− id: itemLabel
62− objectName: "itemLabel"
63− color: "#f3f3e7"
64− opacity: 0.8
65− font.family: "Ubuntu"
66− fontSize: "medium"
67− anchors.verticalCenter: parent.verticalCenter
68− }
69− }
70}
57}
Panel/IndicatorRow.qml+5−3
@@ -21,7 +21,7 @@ Item {
21 id: indicatorRow
21 id: indicatorRow
22
22
23 property QtObject currentItem : null
23 property QtObject currentItem : null
24− property int currentItemIndex: currentItem ? currentItem.ownIndex : -1
24+ readonly property int currentItemIndex: currentItem ? currentItem.ownIndex : -1
25 property alias row: row
25 property alias row: row
26 property QtObject indicatorsModel: null
26 property QtObject indicatorsModel: null
27 property bool overviewActive: false // "state of the menu"
27 property bool overviewActive: false // "state of the menu"
@@ -54,13 +54,15 @@ Item {
54 id: rowRepeater
54 id: rowRepeater
55 objectName: "rowRepeater"
55 objectName: "rowRepeater"
56 model: indicatorsModel ? indicatorsModel : undefined
56 model: indicatorsModel ? indicatorsModel : undefined
57+
57 IndicatorItem {
58 IndicatorItem {
58 id: indicatorItem
59 id: indicatorItem
59
60
60 property int ownIndex: index
61 property int ownIndex: index
61
62
62− label: model.label
63+ widgetSource: model.widgetSource
63− iconSource: model.iconSource
64+
65+ indicatorProperties : model.indicatorProperties
64 highlighted: indicatorRow.state == "reveal" || indicatorRow.state == "locked" || indicatorRow.state == "commit" ? ownIndex == indicatorRow.currentItemIndex : false
66 highlighted: indicatorRow.state == "reveal" || indicatorRow.state == "locked" || indicatorRow.state == "commit" ? ownIndex == indicatorRow.currentItemIndex : false
65 dimmed: { //See FIXME in Indicators regarding the "states" change
67 dimmed: { //See FIXME in Indicators regarding the "states" change
66 if (indicatorRow.state == "initial" || indicatorRow.state == "") {
68 if (indicatorRow.state == "initial" || indicatorRow.state == "") {
Panel/Indicators.qml+3−7
@@ -17,7 +17,6 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Ubuntu.Gestures 0.1
19import Ubuntu.Gestures 0.1
20−import Ubuntu.ChewieUI 0.1 as ChewieUI
21
20
22import "../Components"
21import "../Components"
23import "../Components/ListItems"
22import "../Components/ListItems"
@@ -70,8 +69,7 @@ Showable {
70 // we dont want to switch to a indicator menu until we hit reveal state.
69 // we dont want to switch to a indicator menu until we hit reveal state.
71 if (menuContent.overviewActive) {
70 if (menuContent.overviewActive) {
72 menuContent.showOverview()
71 menuContent.showOverview()
73− }
74− else {
72+ } else {
75 menuContent.showMenu()
73 menuContent.showMenu()
76 }
74 }
77 indicators.state = "locked"
75 indicators.state = "locked"
@@ -272,9 +270,8 @@ Showable {
272
270
273 }
271 }
274
272
275− ChewieUI.PluginModel {
273+ IndicatorsDataModel {
276 id: indicatorsModel
274 id: indicatorsModel
277− Component.onCompleted: load()
278 }
275 }
279
276
280 Connections {
277 Connections {
@@ -294,8 +291,7 @@ Showable {
294 if (showAnimation.running) {
291 if (showAnimation.running) {
295 if (indicators.state == "initial") {
292 if (indicators.state == "initial") {
296 openOverview()
293 openOverview()
297− }
298− else {
294+ } else {
299 indicators.calculateCurrentItem(dragHandle.touchX, false)
295 indicators.calculateCurrentItem(dragHandle.touchX, false)
300 menuContent.showMenu()
296 menuContent.showMenu()
301 }
297 }
Panel/Indicators/DatetimeIndicatorPage.qmlnew file+97
@@ -0,0 +1,97 @@
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: "../graphics/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: timeLabel
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: dateLabel
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 * 10 // 10 seconds
79+ running: true
80+ repeat: true
81+ triggeredOnStart: true
82+ onTriggered: updateTime();
83+ }
84+
85+ function updateTime() {
86+ var dt = new Date();
87+ var time = Qt.formatTime(dt);
88+ var space = time.indexOf(" ");
89+ timeLabel.text = time.substr(0, space > 0 ? space : 5);
90+ dateLabel.text = Qt.formatDateTime(dt, "dddd,\ndd MMMM");
91+ }
92+
93+ // Make it compatible with the PluginItem interface
94+ function start() {}
95+ function stop() {}
96+ function reset() {}
97+}
Panel/Indicators/DatetimeIndicatorWidget.qmlnew 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+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Unity.Indicators 0.1 as Indicators
23+
24+Indicators.IndicatorWidget {
25+ id: indicatorWidget
26+
27+ width: timeLabel.width + units.gu(1)
28+
29+ property alias label: timeLabel.text
30+
31+ Label {
32+ id: timeLabel
33+ objectName: "timeLabel"
34+ color: "#f3f3e7"
35+ opacity: 0.8
36+ font.family: "Ubuntu"
37+ fontSize: "medium"
38+ anchors.centerIn: parent
39+ text: Qt.formatTime(timer.dateNow)
40+ }
41+
42+ Timer {
43+ id: timer
44+ interval: 1000 * 10
45+ running: indicatorWidget.visible
46+ repeat: true
47+ triggeredOnStart: true
48+ property date dateNow
49+
50+ onTriggered: dateNow = new Date
51+ }
52+
53+ onActionStateChanged: {
54+ if (action == undefined || !action.valid) {
55+ return;
56+ }
57+
58+ if (action.state == undefined) {
59+ visible = false;
60+ return;
61+ }
62+
63+ indicatorWidget.visible = action.state[3];
64+ }
65+}
Panel/Indicators/DefaultIndicatorPage.qmlnew file+25
@@ -0,0 +1,25 @@
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+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Unity.Indicators 0.1 as Indicators
22+
23+Indicators.IndicatorPage {
24+ anchors.fill: parent
25+}
Panel/Indicators/DefaultIndicatorWidget.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+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Unity.Indicators 0.1 as Indicators
23+
24+Indicators.IndicatorWidget {
25+ id: indicatorWidget
26+
27+ width: itemRow.width + units.gu(1)
28+
29+ property alias label: itemLabel.text
30+ property alias iconSource: itemImage.source
31+
32+ Row {
33+ id: itemRow
34+ objectName: "itemRow"
35+ anchors {
36+ top: parent.top
37+ bottom: parent.bottom
38+ horizontalCenter: parent.horizontalCenter
39+ }
40+ spacing: units.gu(0.5)
41+
42+ // FIXME : Should us Ubuntu.Icon . results in low res images
43+ Image {
44+ id: itemImage
45+ objectName: "itemImage"
46+ visible: source != ""
47+ height: indicatorWidget.iconSize
48+ width: indicatorWidget.iconSize
49+ anchors.verticalCenter: parent.verticalCenter
50+ }
51+
52+ Label {
53+ id: itemLabel
54+ objectName: "itemLabel"
55+ color: "#f3f3e7"
56+ opacity: 0.8
57+ font.family: "Ubuntu"
58+ fontSize: "medium"
59+ anchors.verticalCenter: parent.verticalCenter
60+ visible: text != ""
61+ }
62+ }
63+
64+ onActionStateChanged: {
65+ if (action == undefined || !action.valid) {
66+ return;
67+ }
68+
69+ if (action.state == undefined) {
70+ label = "";
71+ iconSource = "";
72+ enabled = false;
73+ return;
74+ }
75+
76+ label = action.state[Indicators.ActionState.Label];
77+ iconSource = "image://gicon/" + action.state[Indicators.ActionState.IconSource];
78+ enabled = action.state[Indicators.ActionState.Visible];
79+ }
80+}
Panel/Indicators/MessagingIndicatorPage.qmlnew 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+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Unity.Indicators 0.1 as Indicators
23+
24+Indicators.IndicatorPage {
25+ anchors.fill: parent
26+
27+ highlightFollowsCurrentItem: false
28+ emptyText: "You have no more outstanding messages."
29+
30+ function stop() {
31+ // never stops the service
32+ // this will keep all objects in memory, consume more memory
33+ // but will optimize the menu contruction on the screen
34+ }
35+}
Panel/Indicators/MessagingIndicatorWidget.qmlnew file+25
@@ -0,0 +1,25 @@
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+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+
22+DefaultIndicatorWidget {
23+ // default the icon so we have something to show when we don't have the bus.
24+ iconSource: "image://gicon/indicator-messages"
25+}
Panel/Indicators/NetworkIndicatorPage.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 Unity.Indicators 0.1 as Indicators
22+import Unity.Indicators.Network 0.1 as ICNetwork
23+import Ubuntu.Components 0.1
24+
25+PageStack {
26+ id: _network
27+
28+ property alias title: _mainPage.title
29+ property alias emptyText: _pluginItem.emptyText
30+ property alias busType: _pluginItem.busType
31+ property alias busName: _pluginItem.busName
32+ property alias actionsObjectPath : _pluginItem.actionsObjectPath
33+ property alias menuObjectPaths : _pluginItem.menuObjectPaths
34+
35+ __showHeader: false
36+ anchors.fill: parent
37+
38+ Page {
39+ id: _mainPage
40+
41+ Indicators.IndicatorPage {
42+ id: _pluginItem
43+ anchors.fill: parent
44+ }
45+ }
46+
47+ Component {
48+ id: passwordPageComponent
49+
50+ ICNetwork.PasswordPage {
51+ agent: networkAgent
52+ token: token
53+ }
54+ }
55+
56+ ICNetwork.NetworkAgent {
57+ id: networkAgent
58+
59+ onSecretRequested: {
60+ _network.push(passwordPageComponent);
61+ }
62+ }
63+
64+ function start()
65+ {
66+ push(_mainPage);
67+ _pluginItem.start();
68+ }
69+
70+ function stop()
71+ {
72+ clear();
73+ _pluginItem.stop();
74+ }
75+
76+ function reset()
77+ {
78+ _pluginItem.reset();
79+ }
80+}
Panel/Indicators/NetworkIndicatorWidget.qmlnew file+109
@@ -0,0 +1,109 @@
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+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Unity.Indicators 0.1 as Indicators
23+
24+Indicators.IndicatorWidget {
25+ id: indicatorWidget
26+
27+ width: networkIcon.width + units.gu(1)
28+
29+ property int signalStrength: 0
30+ property int connectionState: Indicators.NetworkConnection.Initial
31+ rootMenuType: "com.canonical.indicator.root.network"
32+
33+ // FIXME : Should us Ubuntu.Icon . results in low res images
34+ Image {
35+ id: networkIcon
36+ objectName: "itemImage"
37+ source: get_icon_for_signal(connectionState, signalStrength)
38+ visible: source != ""
39+ height: indicatorWidget.iconSize
40+ width: indicatorWidget.iconSize
41+ anchors.centerIn: parent
42+ }
43+
44+ onActionStateChanged: {
45+ if (action == undefined || !action.valid) {
46+ return;
47+ }
48+
49+ if (action.state == undefined) {
50+ connectionState = 0;
51+ return;
52+ }
53+
54+ connectionState = action.state[Indicators.NetworkActionState.Connection];
55+ if (connectionState == Indicators.NetworkConnection.Activated) {
56+ signalStrength = action.state[Indicators.NetworkActionState.SignalStrength];
57+ }
58+ }
59+
60+ NumberAnimation {
61+ id: activation_animation
62+ target: indicatorWidget
63+ property: "signalStrength"
64+ from: 0
65+ to: 100
66+ duration: 2500 // 5 states in 2.5 seconds
67+ loops: Animation.Infinite
68+ }
69+
70+ states: [
71+ State {
72+ name: "unknown"
73+ when: connectionState < Indicators.NetworkConnection.Activating || connectionState > Indicators.NetworkConnection.Deactivating
74+ PropertyChanges { target: activation_animation; running: false }
75+ },
76+ State {
77+ name: "activating"
78+ when: connectionState == Indicators.NetworkConnection.Activating
79+ PropertyChanges { target: activation_animation; running: true }
80+ },
81+ State {
82+ name: "activated"
83+ when: connectionState == Indicators.NetworkConnection.Activated
84+ PropertyChanges { target: activation_animation; running: false }
85+ },
86+ State {
87+ name: "deactivating"
88+ when: connectionState == Indicators.NetworkConnection.Deactivating
89+ PropertyChanges { target: activation_animation; running: true }
90+ }
91+ ]
92+
93+
94+ function get_icon_for_signal(con_state, value) {
95+ if (con_state >= Indicators.NetworkConnection.Activating && con_state <= Indicators.NetworkConnection.Deactivating) {
96+ if (value == 0) {
97+ return "image://gicon/nm-signal-00";
98+ } else if (value <= 25) {
99+ return "image://gicon/nm-signal-25";
100+ } else if (value <= 50) {
101+ return "image://gicon/nm-signal-50";
102+ } else if (value <= 75) {
103+ return "image://gicon/nm-signal-75";
104+ }
105+ return "image://gicon/nm-signal-100";
106+ }
107+ return "image://gicon/wifi-none";
108+ }
109+}
Panel/Indicators/SoundIndicatorWidget.qmlnew file+25
@@ -0,0 +1,25 @@
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+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+
22+DefaultIndicatorWidget {
23+ // default the icon so we have something to show when we don't have the bus.
24+ iconSource: "image://gicon/audio-volume-high"
25+}
Panel/Indicators/client/IndicatorsClient.qmlnew file+42
@@ -0,0 +1,42 @@
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+Rectangle {
25+ color: "black"
26+ id: root
27+
28+ PageStack {
29+ id: pages
30+
31+ anchors.fill: parent
32+ Component.onCompleted: root.reset()
33+ }
34+
35+ function reset() {
36+ pages.clear();
37+ var component = Qt.createComponent("IndicatorsList.qml");
38+ var page = component.createObject(pages);
39+ console.log(component.errorString());
40+ pages.push(page);
41+ }
42+}
Panel/Indicators/client/IndicatorsList.qmlnew file+62
@@ -0,0 +1,62 @@
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 Unity.Indicators 0.1 as Indicators
24+import "../.."
25+
26+Page {
27+ id: page
28+ anchors.fill: parent
29+ title: "Plugin list"
30+
31+ IndicatorsDataModel {
32+ id: indicatorsModel
33+ }
34+
35+ ListView {
36+ id: mainMenu
37+ objectName: "mainMenu"
38+ anchors.fill: parent
39+ model: indicatorsModel
40+
41+ delegate: Indicators.MenuItem {
42+ anchors.left: parent.left
43+ anchors.right: parent.right
44+ progression: isValid
45+ objectName: identifier
46+
47+ Label {
48+ anchors.left: parent.left
49+ anchors.leftMargin: units.gu(0.5)
50+ anchors.verticalCenter: parent.verticalCenter
51+ text: title
52+ }
53+
54+ onClicked: {
55+ if (progression) {
56+ var new_page = Qt.createComponent("IndicatorsPage.qml");
57+ page.pageStack.push(new_page.createObject(pages), {"indicatorProperties" : model.indicatorProperties, "pageSource" : model.pageSource});
58+ }
59+ }
60+ }
61+ }
62+}
Panel/Indicators/client/IndicatorsPage.qmlnew file+49
@@ -0,0 +1,49 @@
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+Page {
24+ id: _page
25+
26+ title: indicatorProperties && indicatorProperties.title ? indicatorProperties.title : ""
27+ property variant indicatorProperties
28+ property alias pageSource : page_loader.source
29+
30+ anchors.fill: parent
31+
32+ Loader {
33+ id: page_loader
34+ objectName: "page_loader"
35+
36+ anchors.fill: parent
37+
38+ onStatusChanged: {
39+ if (status == Loader.Ready) {
40+ for(var pName in indicatorProperties) {
41+ if (item.hasOwnProperty(pName)) {
42+ item[pName] = indicatorProperties[pName];
43+ }
44+ }
45+ item.start();
46+ }
47+ }
48+ }
49+}
Panel/IndicatorsDataModel.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 Unity.Indicators 0.1 as Indicators
22+import Utils 0.1
23+
24+Indicators.IndicatorsModel {
25+ id: ic_model
26+
27+ Component.onCompleted: load()
28+
29+ indicatorData : {
30+ 'indicator-messaging' : {
31+ 'title': 'Messaging',
32+ 'description' : '',
33+ 'priority': 10,
34+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/MessagingIndicatorWidget.qml',
35+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/MessagingIndicatorPage.qml'
36+ },
37+ 'indicator-sound' : {
38+ 'title': 'Sound',
39+ 'description' : '',
40+ 'priority': 20,
41+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/SoundIndicatorWidget.qml',
42+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage.qml'
43+ },
44+ 'indicator-network' : {
45+ 'title': 'Networks',
46+ 'description' : '',
47+ 'priority': 30,
48+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/NetworkIndicatorWidget.qml',
49+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/NetworkIndicatorPage.qml'
50+ },
51+ 'indicator-battery' : {
52+ 'title': 'Battery',
53+ 'description' : '',
54+ 'priority': 40,
55+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget.qml',
56+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage.qml'
57+ },
58+ 'indicator-time' : {
59+ 'title': 'Date and Time',
60+ 'description' : '',
61+ 'priority': 100,
62+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DatetimeIndicatorWidget.qml',
63+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DatetimeIndicatorPage.qml'
64+ }
65+ }
66+}
Panel/MenuContent.qml+17−20
@@ -16,6 +16,7 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19+import Unity.Indicators 0.1 as Indicators
19import "Menus"
20import "Menus"
20import "../Components"
21import "../Components"
21
22
@@ -29,7 +30,7 @@ Rectangle {
29 property bool __contentActive: false
30 property bool __contentActive: false
30 property alias currentIndex : menus.currentIndex
31 property alias currentIndex : menus.currentIndex
31 property color backgroundColor: "#221e1c"
32 property color backgroundColor: "#221e1c"
32− property int contentReleaseInterval: 5000
33+ property int contentReleaseInterval: 20000
33
34
34 width: units.gu(40)
35 width: units.gu(40)
35 height: units.gu(42)
36 height: units.gu(42)
@@ -94,7 +95,7 @@ Rectangle {
94
95
95 width: menus.width
96 width: menus.width
96 height: menus.height
97 height: menus.height
97− sourceComponent: component
98+ source: pageSource
98 visible: content.__shown
99 visible: content.__shown
99 onVisibleChanged: {
100 onVisibleChanged: {
100 // Reset the indicator states
101 // Reset the indicator states
@@ -104,25 +105,15 @@ Rectangle {
104 }
105 }
105 asynchronous: true
106 asynchronous: true
106
107
107− onStatusChanged: {
108+ onLoaded: {
108− if (status == Loader.Ready) {
109− if (indicatorsModel.widgetsMap && item.hasOwnProperty("widgetsMap")) {
110− item["widgetsMap"] = indicatorsModel.widgetsMap
111− }
112− for(var pName in initialProperties) {
109+ for(var pName in indicatorProperties) {
113− if (item.hasOwnProperty(pName)) {
110+ if (item.hasOwnProperty(pName)) {
114− item[pName] = initialProperties[pName]
111+ item[pName] = indicatorProperties[pName]
115− }
116− }
117− if (contentActive && menus.visible) {
118− item.start()
119 }
112 }
120 }
113 }
114+ if (contentActive && menus.visible) {
115+ item.start()
121− }
116+ }
122−
123− // FIXME: QTBUG-30632 - asynchronous loader crashes when changing index quickly.
124− Component.onDestruction: {
125− active = false;
126 }
117 }
127
118
128 // Need to use a binding because the handle height changes.
119 // Need to use a binding because the handle height changes.
@@ -189,7 +180,13 @@ Rectangle {
189 left: parent.left
180 left: parent.left
190 right: parent.right
181 right: parent.right
191 }
182 }
183+ text: {
184+ if (content.overviewActive)
185+ return i18n.tr("Device");
192− text: content.overviewActive ? i18n.tr("Device") : (indicatorsModel && menus.currentIndex >= 0 && menus.currentIndex < indicatorsModel.count) ? indicatorsModel.get(menus.currentIndex).title : ""
186+ if (indicatorsModel && menus.currentIndex >= 0 && menus.currentIndex < indicatorsModel.count)
187+ return indicatorsModel.data(menus.currentIndex, Indicators.IndicatorsModelRole.Title);
188+ return "";
189+ }
193 opacity: __shown ? 1 : 0
190 opacity: __shown ? 1 : 0
194 Behavior on opacity {NumberAnimation{duration: 100}}
191 Behavior on opacity {NumberAnimation{duration: 100}}
195 }
192 }
Panel/Menus/Overview/OverviewGrid.qml+15−24
@@ -59,31 +59,22 @@ Item {
59 objectName: "overviewGridButton" + index
59 objectName: "overviewGridButton" + index
60 width: grid.cellWidth
60 width: grid.cellWidth
61 height: grid.cellHeight
61 height: grid.cellHeight
62− Image {
63− id: imageIcon
64− objectName: "overviewGridButtonImage"
65− source: iconSource
66− width: units.gu(4)
67− height: units.gu(4)
68− anchors {
69− centerIn: parent
70− verticalCenterOffset: -units.gu(1)
71− }
72− sourceSize.width: width
73− sourceSize.height: height
74− visible: labelIcon.text === ""
75− }
76
62
77− Label {
63+ Loader {
78− id: labelIcon
64+ id: loader
79− text: label
65+ source: widgetSource
80− color: "#f3f3e7"
66+
81− opacity: 0.8
67+ width: units.gu(5)
82− font.family: "Ubuntu"
68+ height: units.gu(5)
83− fontSize: "large"
84− anchors {
85− centerIn: parent
69+ anchors.centerIn: parent
86− verticalCenterOffset: -units.gu(1)
70+ anchors.verticalCenterOffset: -units.gu(1)
71+
72+ onLoaded: {
73+ for(var pName in indicatorProperties) {
74+ if (item.hasOwnProperty(pName)) {
75+ item[pName] = indicatorProperties[pName]
76+ }
77+ }
87 }
78 }
88 }
79 }
89
80
Panel/graphics/time_and_date@18.pngnew file

Binary file not shown.

build+1−2
@@ -43,10 +43,9 @@ install_dependencies() {
43 echo "Installing Unity 8 dependencies.."
43 echo "Installing Unity 8 dependencies.."
44 sudo apt-get install devscripts \
44 sudo apt-get install devscripts \
45 equivs \
45 equivs \
46+ qmenumodel-qml \
46 qtdeclarative5-ubuntu-ui-toolkit-plugin \
47 qtdeclarative5-ubuntu-ui-toolkit-plugin \
47 qtdeclarative5-dee-plugin \
48 qtdeclarative5-dee-plugin \
48− indicators-client \
49− indicators-client-plugin-* \
50 ubuntu-mobile-icons \
49 ubuntu-mobile-icons \
51 unity-notifications-impl-1 \
50 unity-notifications-impl-1 \
52 unity-scope-home \
51 unity-scope-home \
cmake/modules/autopilot.cmake+7−4
@@ -1,7 +1,10 @@
1add_custom_target(autopilot)
1add_custom_target(autopilot)
2
2
3−function(declare_autopilot_test TEST_NAME WORKING_DIR)
3+function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR)
4− add_custom_command(TARGET autopilot
4+ add_custom_target(autopilot-${TEST_NAME}
5− COMMAND autopilot run ${TEST_NAME}
5+ COMMAND autopilot run ${TEST_SUITE}
6− WORKING_DIRECTORY ${WORKING_DIR})
6+ WORKING_DIRECTORY ${WORKING_DIR}
7+ )
8+
9+ add_dependencies(autopilot autopilot-${TEST_NAME})
7endfunction()
10endfunction()
debian/control+21−7
@@ -10,7 +10,10 @@ Build-Depends: cmake,
10 libgles2-mesa-dev[armhf],
10 libgles2-mesa-dev[armhf],
11 libhud-client2-dev,
11 libhud-client2-dev,
12 libjson-perl,
12 libjson-perl,
13+ libnm-glib-dev,
14+ libnm-util-dev,
13 libpulse-dev,
15 libpulse-dev,
16+ libqmenumodel-dev,
14 libqt5v8-5-private-dev,
17 libqt5v8-5-private-dev,
15 libunity-api-dev (>= 7.80.3),
18 libunity-api-dev (>= 7.80.3),
16 libunity-core-6.0-dev (<< 7.80),
19 libunity-core-6.0-dev (<< 7.80),
@@ -41,9 +44,19 @@ Homepage: http://launchpad.net/unity
41Vcs-Bzr: https://code.launchpad.net/unity8
44Vcs-Bzr: https://code.launchpad.net/unity8
42Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity8/trunk
45Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity8/trunk
43
46
47+Package: indicators-client
48+Architecture: amd64 armhf i386
49+Depends: qmenumodel-qml,
50+ qtdeclarative5-ubuntu-ui-toolkit-plugin | qt-components-ubuntu,
51+ unity8 (= ${binary:Version}),
52+ ${misc:Depends},
53+ ${shlibs:Depends},
54+Description: Indicators client test application
55+ This package contains the client application for indicators used by autopilot
56+
44Package: unity8
57Package: unity8
45Architecture: any
58Architecture: any
46−Depends: indicators-client (>= 0.6.1),
59+Depends: qmenumodel-qml,
47 qtdeclarative5-dee-plugin,
60 qtdeclarative5-dee-plugin,
48 qtdeclarative5-ubuntu-ui-toolkit-plugin,
61 qtdeclarative5-ubuntu-ui-toolkit-plugin,
49 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
62 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
@@ -55,18 +68,19 @@ Depends: indicators-client (>= 0.6.1),
55 unity8-private | unity-launcher-impl,
68 unity8-private | unity-launcher-impl,
56 ${misc:Depends},
69 ${misc:Depends},
57 ${shlibs:Depends},
70 ${shlibs:Depends},
58−Recommends: indicators-client-plugin-datetime (>= 0.6.1),
71+Recommends: indicator-battery,
59− indicators-client-plugin-messaging (>= 0.6.1),
72+ indicator-messages,
60− indicators-client-plugin-network (>= 0.6.1),
73+ indicator-network,
61− indicators-client-plugin-power (>= 0.6.1),
74+ indicator-sound,
62− indicators-client-plugin-sound (>= 0.6.1),
75+ indicator-time,
63 ${unity-default-masterscopes},
76 ${unity-default-masterscopes},
64Description: Unity 8 shell
77Description: Unity 8 shell
65 The Unity 8 shell is the primary user interface for Ubuntu devices.
78 The Unity 8 shell is the primary user interface for Ubuntu devices.
66
79
67Package: unity8-autopilot
80Package: unity8-autopilot
68Architecture: all
81Architecture: all
82+Depends: indicators-client (>= ${source:Version}),
69−Depends: libautopilot-qt,
83+ libautopilot-qt,
70 libqt5test5,
84 libqt5test5,
71 libqt5widgets5,
85 libqt5widgets5,
72 python-evdev,
86 python-evdev,
debian/indicators-client.installnew file+1
@@ -0,0 +1 @@
1+/usr/bin/indicators-client
debian/unity8.install+1
@@ -13,3 +13,4 @@ usr/share/unity8/Panel
13usr/share/unity8/Shell.qml
13usr/share/unity8/Shell.qml
14usr/share/unity8/SideStage
14usr/share/unity8/SideStage
15usr/share/unity8/graphics
15usr/share/unity8/graphics
16+usr/share/unity8/unity/indicators/*
main.cpp+1−2
@@ -22,6 +22,7 @@
22#include <QtGui/QIcon>
22#include <QtGui/QIcon>
23#include <QtGui/QGuiApplication>
23#include <QtGui/QGuiApplication>
24#include <QtQml/QQmlEngine>
24#include <QtQml/QQmlEngine>
25+#include <QtQml/QQmlContext>
25#include <qpa/qplatformnativeinterface.h>
26#include <qpa/qplatformnativeinterface.h>
26#include <QLibrary>
27#include <QLibrary>
27#include <libintl.h>
28#include <libintl.h>
@@ -131,8 +132,6 @@ int main(int argc, char** argv)
131 nativeInterface->setProperty("ubuntuSessionType", 1);
132 nativeInterface->setProperty("ubuntuSessionType", 1);
132 view->setProperty("role", 2); // INDICATOR_ACTOR_ROLE
133 view->setProperty("role", 2); // INDICATOR_ACTOR_ROLE
133
134
134− QObject::connect(view->engine(), SIGNAL(quit()), qApp, SLOT(quit()));
135−
136 QUrl source("Shell.qml");
135 QUrl source("Shell.qml");
137 prependImportPaths(view->engine(), ::overrideImportPaths());
136 prependImportPaths(view->engine(), ::overrideImportPaths());
138 appendImportPaths(view->engine(), ::fallbackImportPaths());
137 appendImportPaths(view->engine(), ::fallbackImportPaths());
paths.h.in+15
@@ -23,6 +23,7 @@
23// Qt
23// Qt
24#include <QtCore/QCoreApplication>
24#include <QtCore/QCoreApplication>
25#include <QtCore/QDir>
25#include <QtCore/QDir>
26+#include <QStandardPaths>
26
27
27inline bool isRunningInstalled() {
28inline bool isRunningInstalled() {
28 static bool installed = (QCoreApplication::applicationDirPath() ==
29 static bool installed = (QCoreApplication::applicationDirPath() ==
@@ -65,6 +66,20 @@ inline QStringList fallbackImportPaths() {
65 return paths;
66 return paths;
66}
67}
67
68
69+inline QStringList shellDataDirs() {
70+ QStringList dirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
71+ if (!isRunningInstalled()) {
72+ if (getenv("UNITY_TEST_ENV")==NULL) {
73+ dirs.prepend("@CMAKE_BINARY_DIR@/share");
74+ }
75+ }
76+ else {
77+ // append so by default we use xdg files.
78+ dirs.append(shellAppDirectory());
79+ }
80+ return dirs;
81+}
82+
68inline QString sourceDirectory() {
83inline QString sourceDirectory() {
69 return QString("@CMAKE_SOURCE_DIR@/");
84 return QString("@CMAKE_SOURCE_DIR@/");
70}
85}
plugins/Unity/CMakeLists.txt+2
@@ -1,6 +1,8 @@
1# export_qmlplugin macro
1# export_qmlplugin macro
2include(Plugins)
2include(Plugins)
3
3
4+add_subdirectory(Indicators)
5+
4# Dependencies
6# Dependencies
5include(FindPkgConfig)
7include(FindPkgConfig)
6pkg_check_modules(QTDEE REQUIRED libdee-qt5)
8pkg_check_modules(QTDEE REQUIRED libdee-qt5)
plugins/Unity/Indicators/CMakeLists.txtnew file+52
@@ -0,0 +1,52 @@
1+project(IndicatorsQml)
2+
3+pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
4+find_package(Qt5Core REQUIRED)
5+find_package(Qt5Quick REQUIRED)
6+
7+add_subdirectory(qml)
8+add_subdirectory(Messaging)
9+add_subdirectory(Network)
10+
11+include_directories(
12+ ${CMAKE_CURRENT_SOURCE_DIR}
13+ ${CMAKE_CURRENT_BINARY_DIR}
14+ ${QMENUMODEL_INCLUDE_DIRS}
15+)
16+
17+set(IndicatorsQML_SOURCES
18+ flatmenuproxymodel.cpp
19+ indicator.cpp
20+ indicators.h
21+ indicatorsmanager.cpp
22+ indicatorsmodel.cpp
23+ plugin.cpp
24+)
25+
26+set(IndicatorsQML_RESOURCES
27+ resources/indicators.qrc
28+)
29+
30+qt5_add_resources(IndicatorsQML_RESOURCES_RCC
31+ ${IndicatorsQML_RESOURCES}
32+)
33+
34+add_library(IndicatorsQml SHARED
35+ ${IndicatorsQML_RESOURCES_RCC}
36+ ${IndicatorsQML_SOURCES}
37+)
38+# Because this is an internal support library, we want
39+# to expose all symbols in it. Consider changing this
40+# either to a static library or just using the
41+# files directly in targets.
42+set_target_properties(IndicatorsQml PROPERTIES COMPILE_FLAGS -fvisibility=default)
43+
44+target_link_libraries(IndicatorsQml
45+ ${QMENUMODEL_LDFLAGS}
46+)
47+
48+qt5_use_modules(IndicatorsQml Core Qml Quick)
49+
50+install(TARGETS IndicatorsQml
51+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Unity/Indicators
52+ )
plugins/Unity/Indicators/Messaging/CMakeLists.txtnew file+1
@@ -0,0 +1 @@
1+add_subdirectory(qml)
plugins/Unity/Indicators/Messaging/qml/ActionButton.qmlnew file+43
@@ -0,0 +1,43 @@
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 Unity.Indicators 0.1 as Indicators
24+
25+Button {
26+ id: button
27+ property QtObject actionGroup: null
28+ property string action
29+
30+ property var actionParameter: null
31+
32+ Indicators.MenuAction {
33+ id: menuAction
34+ actionGroup: button.actionGroup
35+ action: button.action
36+ }
37+
38+ onClicked: {
39+ if (menuAction.valid) {
40+ menuAction.activate(actionParameter);
41+ }
42+ }
43+}
plugins/Unity/Indicators/Messaging/qml/ActionTextField.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+ * 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 actionGroup: sendButton.actionGroup
26+ property alias action: sendButton.action
27+
28+ property alias text: replyField.text
29+ property alias buttonText: sendButton.text
30+
31+ TextField {
32+ id: replyField
33+
34+ anchors {
35+ top: parent.top
36+ bottom: parent.bottom
37+ left: parent.left
38+ right: sendButton.left
39+ rightMargin: units.gu(1)
40+ }
41+ placeholderText: "Reply"
42+ hasClearButton: false
43+
44+ onEnabledChanged: {
45+ //Make sure that the component lost focus when enabled = false,
46+ //otherwise it will get focus again when enable = true
47+ if (!enabled) {
48+ focus = false;
49+ }
50+ }
51+ }
52+
53+ ActionButton {
54+ id: sendButton
55+
56+ actionParameter: replyField.text
57+ anchors {
58+ top: parent.top
59+ bottom: parent.bottom
60+ right: parent.right
61+ }
62+ width: units.gu(9)
63+ enabled: replyField.text !== ""
64+ color: enabled ? "#c94212" : "#bababa"
65+ }
66+}
plugins/Unity/Indicators/Messaging/qml/CMakeLists.txtnew file+15
@@ -0,0 +1,15 @@
1+file(GLOB IndicatorsMessaging_QMLFILES
2+ *.qml
3+ *.js
4+ qmldir
5+)
6+
7+# copy qml & qmldir files into build directory for shadow builds
8+add_custom_target(UnityIndicatorsMessagingQmlFiles ALL
9+ COMMAND cp ${IndicatorsMessaging_QMLFILES} ${CMAKE_BINARY_DIR}/plugins/Unity/Indicators/Messaging
10+ DEPENDS ${IndicatorsMessaging_QMLFILES}
11+)
12+
13+install(FILES ${IndicatorsMessaging_QMLFILES}
14+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Unity/Indicators/Messaging
15+)
plugins/Unity/Indicators/Messaging/qml/GroupedMessage.qmlnew file+96
@@ -0,0 +1,96 @@
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 Unity.Indicators 0.1 as Indicators
24+
25+Indicators.BasicMenuItem {
26+ id: groupedMessage
27+ property alias count: label.text
28+
29+ color: "#221e1b"
30+ implicitHeight: units.gu(10)
31+
32+ Indicators.MenuAction {
33+ id: menuAction
34+ actionGroup: groupedMessage.actionGroup
35+ action: menu ? menu.action : ""
36+ }
37+
38+ Row {
39+ anchors.fill: parent
40+ anchors.margins: units.gu(2)
41+ spacing: units.gu(4)
42+
43+ UbuntuShape {
44+ height: units.gu(6)
45+ width: units.gu(6)
46+ image: Image {
47+ source: menu && (menu.extra.canonical_icon.length > 0) ? "image://gicon/" + encodeURI(menu.extra.canonical_icon) : "qrc:/indicators/artwork/messaging/default_app.svg"
48+ fillMode: Image.PreserveAspectFit
49+ }
50+ }
51+
52+ Label {
53+ anchors.verticalCenter: parent.verticalCenter
54+ color: "#e8e1d0"
55+ font.weight: Font.DemiBold
56+ fontSize: "medium"
57+ text: menu && menu.label ? menu.label : ""
58+ }
59+
60+ Label {
61+ id: label
62+ anchors.verticalCenter: parent.verticalCenter
63+ width: parent.width - x
64+ horizontalAlignment: Text.AlignRight
65+ color: "#e8e1d0"
66+ font.weight: Font.DemiBold
67+ fontSize: "medium"
68+ text: menuAction.valid ? menuAction.state[0] : "0"
69+ }
70+ }
71+
72+ Indicators.HLine {
73+ anchors.top: parent.top
74+ color: "#403b37"
75+ }
76+
77+ Indicators.HLine {
78+ anchors.bottom: parent.bottom
79+ color: "#060606"
80+ }
81+
82+ MouseArea {
83+ anchors.fill: parent
84+ onClicked: {
85+ if (menuAction.valid) {
86+ menuAction.activate(true);
87+ }
88+ }
89+ }
90+
91+ onItemRemoved: {
92+ if (menuAction.valid) {
93+ menuAction.activate(false);
94+ }
95+ }
96+}
plugins/Unity/Indicators/Messaging/qml/HeroMessage.qmlnew file+120
@@ -0,0 +1,120 @@
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 Unity.Indicators 0.1 as Indicators
24+
25+Indicators.BasicMenuItem {
26+ id: heroMessage
27+
28+ property variant actionsDescription: null
29+ property alias heroMessageHeader: __heroMessageHeader
30+ property real collapsedHeight: heroMessageHeader.y + heroMessageHeader.bodyBottom + units.gu(2)
31+ property real expandedHeight: collapsedHeight
32+
33+ color: "#221e1c"
34+
35+ removable: state !== "expanded"
36+ implicitHeight: collapsedHeight
37+
38+ Indicators.MenuAction {
39+ id: menuAction
40+ actionGroup: heroMessage.actionGroup
41+ action: menu ? menu.action : ""
42+ }
43+
44+ HeroMessageHeader {
45+ id: __heroMessageHeader
46+
47+ anchors.top: parent.top
48+ anchors.left: parent.left
49+ anchors.right: parent.right
50+
51+ avatar: menu && (menu.extra.canonical_icon.length > 0) ? "image://gicon/" + encodeURI(menu.extra.canonical_icon) : "qrc:/indicators/artwork/messaging/default_contact.png"
52+ icon: menu && (menu.extra.canonical_app_icon.length > 0) ? "image://gicon/" + encodeURI(menu.extra.canonical_app_icon) : ""
53+ appIcon: icon
54+
55+ state: heroMessage.state
56+
57+ onAppIconClicked: {
58+ if (menuAction.valid) {
59+ deactivateMenu();
60+ action.activate(true);
61+ }
62+ }
63+ }
64+
65+ onClicked: {
66+ if (menuActivated) {
67+ deactivateMenu();
68+ } else {
69+ activateMenu();
70+ }
71+ }
72+
73+ Indicators.HLine {
74+ id: __topHLine
75+ anchors.top: parent.top
76+ color: "#403b37"
77+ }
78+
79+ Indicators.HLine {
80+ id: __bottomHLine
81+ anchors.bottom: parent.bottom
82+ color: "#060606"
83+ }
84+
85+ states: State {
86+ name: "expanded"
87+ when: menuActivated
88+
89+ PropertyChanges {
90+ target: heroMessage
91+ color: "#333130"
92+ implicitHeight: heroMessage.expandedHeight
93+ }
94+ PropertyChanges {
95+ target: __topHLine
96+ opacity: 0.0
97+ }
98+ PropertyChanges {
99+ target: __bottomHLine
100+ opacity: 0.0
101+ }
102+ }
103+
104+ transitions: Transition {
105+ ParallelAnimation {
106+ NumberAnimation {
107+ properties: "opacity,implicitHeight"
108+ duration: 200
109+ easing.type: Easing.OutQuad
110+ }
111+ ColorAnimation {}
112+ }
113+ }
114+
115+ onItemRemoved: {
116+ if (menuAction.valid) {
117+ menuAction.activate(false);
118+ }
119+ }
120+}
plugins/Unity/Indicators/Messaging/qml/HeroMessageHeader.qmlnew file+161
@@ -0,0 +1,161 @@
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 {
42+ top: parent.top
43+ topMargin: units.gu(2)
44+ left: parent.left
45+ leftMargin: units.gu(2)
46+ }
47+ height: units.gu(6)
48+ width: units.gu(6)
49+ image: Image {
50+ id: avatarImage
51+ fillMode: Image.PreserveAspectFit
52+ }
53+ }
54+
55+ Image {
56+ id: iconImage
57+ anchors {
58+ top: parent.top
59+ topMargin: units.gu(2)
60+ left: avatarImageContainer.right
61+ leftMargin: units.gu(1)
62+ }
63+ height: units.gu(1.5)
64+ width: units.gu(2)
65+ horizontalAlignment: Image.AlignHCenter
66+ verticalAlignment: Image.AlignBottom
67+ fillMode: Image.PreserveAspectFit
68+ }
69+
70+ Label {
71+ id: __titleText
72+ anchors {
73+ baseline: iconImage.bottom
74+ left: iconImage.right
75+ leftMargin: units.gu(1)
76+ right: __appIcon.left
77+ rightMargin: units.gu(2)
78+ }
79+ elide: Text.ElideRight
80+ color: "#e8e1d0"
81+ font.weight: Font.DemiBold
82+ fontSize: "medium"
83+ }
84+
85+ Label {
86+ id: __subtitleText
87+ anchors {
88+ baseline: __titleText.baseline
89+ baselineOffset: units.gu(2.5)
90+ left: __titleText.left
91+ right: __titleText.right
92+ }
93+ elide: Text.ElideRight
94+ color: "#8f8f88"
95+ fontSize: "small"
96+ }
97+
98+ Label {
99+ id: __bodyText
100+ anchors {
101+ baseline: __subtitleText.baseline
102+ baselineOffset: units.gu(2.5)
103+ left: __titleText.left
104+ right: parent.right
105+ rightMargin: units.gu(2)
106+ }
107+ maximumLineCount: 2
108+ wrapMode: Text.WordWrap
109+ elide: Text.ElideRight
110+ color: "#e8e1d0"
111+ fontSize: "small"
112+ }
113+
114+ Item {
115+ id: __appIcon
116+ width: units.gu(7)
117+ height: units.gu(7)
118+ anchors {
119+ top: parent.top
120+ right: parent.right
121+ }
122+ opacity: 0.0
123+ enabled: heroMessageHeader.state === "expanded"
124+
125+ Image {
126+ id: appIconImage
127+ height: width
128+ anchors {
129+ left: parent.left
130+ leftMargin: units.gu(2)
131+ right: parent.right
132+ rightMargin: units.gu(2)
133+ topMargin: units.gu(1)
134+ verticalCenter: parent.verticalCenter
135+ }
136+ fillMode: Image.PreserveAspectFit
137+ }
138+
139+ MouseArea {
140+ anchors.fill: parent
141+ onClicked: heroMessageHeader.appIconClicked()
142+ }
143+ }
144+
145+ states: State {
146+ name: "expanded"
147+
148+ PropertyChanges {
149+ target: __appIcon
150+ opacity: 1.0
151+ }
152+ }
153+
154+ transitions: Transition {
155+ NumberAnimation {
156+ property: "opacity"
157+ duration: 200
158+ easing.type: Easing.OutQuad
159+ }
160+ }
161+}
plugins/Unity/Indicators/Messaging/qml/MessageMenuItem.qmlnew file+96
@@ -0,0 +1,96 @@
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 Unity.Indicators 0.1 as Indicators
24+
25+Indicators.BasicMenuItem {
26+ property variant actionsDescription: menu ? menu.extra.canonical_message_actions : undefined
27+
28+ onActionGroupChanged: loadItem()
29+ onActionsDescriptionChanged: loadItem()
30+ implicitHeight: contents.status == Loader.Ready ? contents.item.implicitHeight : 0
31+
32+ Loader {
33+ id: contents
34+
35+ anchors.fill: parent
36+ // Binding all properties for the item, to make sure that any change in the
37+ // property will be propagated to the contents.item at any time
38+ Binding {
39+ target: contents.item
40+ property: "menuActivated"
41+ value: menuActivated
42+ when: (contents.status == Loader.Ready)
43+ }
44+
45+ Binding {
46+ target: contents.item
47+ property: "actionGroup"
48+ value: actionGroup
49+ when: (contents.status == Loader.Ready)
50+ }
51+
52+ Binding {
53+ target: contents.item
54+ property: "menu"
55+ value: menu
56+ when: (contents.status == Loader.Ready)
57+ }
58+
59+ Binding {
60+ target: contents.item
61+ property: "actionsDescription"
62+ value: actionsDescription
63+ when: (contents.status == Loader.Ready)
64+ }
65+
66+ Connections {
67+ target: contents.item ? contents.item : null
68+ onActivateMenu: activateMenu()
69+ onDeactivateMenu: deactivateMenu()
70+ }
71+ }
72+
73+
74+ function loadItem()
75+ {
76+ var parameterType = ""
77+ for (var actIndex in actionsDescription) {
78+ var desc = actionsDescription[actIndex];
79+ if (desc["parameter-type"] !== undefined) {
80+ parameterType += desc["parameter-type"];
81+ } else {
82+ parameterType += "_";
83+ }
84+ }
85+
86+ if (parameterType === "") {
87+ contents.source = "SimpleTextMessage.qml";
88+ } else if (parameterType === "s") {
89+ contents.source = "TextMessage.qml";
90+ } else if (parameterType === "_s") {
91+ contents.source = "SnapDecision.qml";
92+ } else {
93+ console.debug("Unknown paramater type: " + parameterType);
94+ }
95+ }
96+}
plugins/Unity/Indicators/Messaging/qml/QuickReply.qmlnew file+160
@@ -0,0 +1,160 @@
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 Unity.Indicators 0.1 as Indicators
24+
25+Item {
26+ property alias actionGroup: actionTextField.actionGroup
27+ property alias action: actionTextField.action
28+
29+ property alias buttonText: actionTextField.buttonText
30+ property real expandedHeight: childrenRect.height
31+ property alias messages : messagelistRepeater.model
32+
33+ Item {
34+ id: header
35+ anchors.top: parent.top
36+ anchors.left: parent.left
37+ anchors.right: parent.right
38+ height: units.gu(4)
39+
40+ Row {
41+ anchors {
42+ fill: parent
43+ leftMargin: units.gu(2)
44+ rightMargin: units.gu(2)
45+ topMargin: units.gu(1)
46+ bottomMargin: units.gu(1)
47+ }
48+ spacing: units.gu(1)
49+
50+ Image {
51+ width: units.gu(2)
52+ height: width
53+ fillMode: Image.PreserveAspectFit
54+ source: "qrc:/indicators/artwork/messaging/message_sms01_54px.png"
55+ }
56+
57+ Label {
58+ height: parent.height
59+ verticalAlignment: Text.AlignVCenter
60+ fontSize: "small"
61+ color: "#8f8f88"
62+ text: "Quick reply with:"
63+ }
64+ }
65+
66+ Indicators.HLine {
67+ anchors.bottom: parent.bottom
68+ color: "#20201F"
69+ }
70+ }
71+
72+ Column {
73+ id: messagelist
74+ anchors {
75+ left: parent.left
76+ right: parent.right
77+ top: header.bottom
78+ }
79+ height: childrenRect.height
80+
81+ Repeater {
82+ id: messagelistRepeater
83+
84+ height: childrenRect.height
85+
86+ Rectangle {
87+ width: messagelist.width
88+ height: units.gu(5)
89+ color: "#333230"
90+
91+ Label {
92+ id: __label
93+
94+ anchors {
95+ fill: parent
96+ leftMargin: units.gu(2)
97+ rightMargin: units.gu(2)
98+ }
99+ verticalAlignment: Text.AlignVCenter
100+ fontSize: "medium"
101+ color: "#e8e1d0"
102+ text: modelData
103+ }
104+
105+ Indicators.HLine {
106+ anchors.top: parent.top
107+ color: "#464543"
108+ }
109+
110+ Indicators.HLine {
111+ anchors.bottom: parent.bottom
112+ color: "#20201F"
113+ }
114+
115+ MouseArea {
116+ id: __mouseArea
117+
118+ anchors.fill: parent
119+ onClicked: {
120+ actionTextField.text = modelData;
121+ }
122+ }
123+
124+ Rectangle {
125+ id: __mask
126+
127+ anchors.fill: parent
128+ color: "black"
129+ opacity: __mouseArea.pressed ? 0.3 : 0.0
130+ Behavior on opacity {
131+ NumberAnimation {
132+ duration: 200
133+ easing.type: Easing.OutQuad
134+ }
135+ }
136+ }
137+ }
138+
139+ }
140+ }
141+
142+ Item {
143+ anchors.top: messagelist.bottom
144+ anchors.left: parent.left
145+ anchors.right: parent.right
146+ height: units.gu(6)
147+
148+ ActionTextField {
149+ id: actionTextField
150+
151+ anchors.fill: parent
152+ anchors.margins: units.gu(1)
153+ }
154+
155+ Indicators.HLine {
156+ anchors.top: parent.top
157+ color: "#464543"
158+ }
159+ }
160+}
plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qmlnew file+97
@@ -0,0 +1,97 @@
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: footerLoader.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 {
39+ left: parent.left
40+ leftMargin: units.gu(2)
41+ right: parent.right
42+ rightMargin: units.gu(2)
43+ top: heroMessageHeader.bottom
44+ }
45+ height: childrenRect.height
46+ opacity: 0.0
47+ enabled: false
48+
49+ Label {
50+ id: bodyText
51+ anchors {
52+ top: parent.top
53+ left: parent.left
54+ right: parent.right
55+ }
56+ wrapMode: Text.WordWrap
57+ elide: Text.ElideRight
58+ color: "#e8e1d0"
59+ fontSize: "medium"
60+ text: heroMessageHeader.bodyText.text
61+ }
62+
63+ Loader {
64+ id: footerLoader
65+
66+ anchors {
67+ top: bodyText.bottom
68+ topMargin: units.gu(2)
69+ left: parent.left
70+ right: parent.right
71+ }
72+ height: item != undefined ? units.gu(4) : 0
73+ }
74+
75+ states: State {
76+ name: "expanded"
77+ when: __heroMessage.state === "expanded"
78+
79+ PropertyChanges {
80+ target: heroMessageHeader.bodyText
81+ opacity: 0.0
82+ }
83+
84+ PropertyChanges {
85+ target: fullMessage
86+ opacity: 1.0
87+ enabled: true
88+ }
89+ }
90+ transitions: Transition {
91+ NumberAnimation {
92+ property: "opacity"
93+ duration: 200
94+ }
95+ }
96+ }
97+}
plugins/Unity/Indicators/Messaging/qml/SnapDecision.qmlnew file+142
@@ -0,0 +1,142 @@
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 Unity.Indicators 0.1 as Indicators
24+import "utils.js" as Utils
25+
26+HeroMessage {
27+ id: snapDecision
28+
29+ expandedHeight: buttons.y + buttons.height + quickreply.height + units.gu(2)
30+ heroMessageHeader.titleText.text: menu ? menu.label : ""
31+ heroMessageHeader.subtitleText.text: menu ? menu.extra.canonical_text : ""
32+ heroMessageHeader.subtitleText.color: "#e8e1d0"
33+ heroMessageHeader.bodyText.text: menu ? Utils.formatDate(menu.extra.canonical_time) : ""
34+ heroMessageHeader.bodyText.color: "#8f8f88"
35+
36+ Item {
37+ id: buttons
38+
39+ anchors.left: parent.left
40+ anchors.leftMargin: units.gu(2)
41+ anchors.right: parent.right
42+ anchors.rightMargin: units.gu(2)
43+ anchors.top: heroMessageHeader.bottom
44+ anchors.topMargin: units.gu(1)
45+ height: units.gu(4)
46+ opacity: 0.0
47+
48+ Button {
49+ text: "Message"
50+ color: "#bababa"
51+ anchors.left: parent.left
52+ anchors.top: parent.top
53+ anchors.bottom: parent.bottom
54+ width: (parent.width - units.gu(1)) / 2
55+
56+ onClicked: {
57+ if (quickreply.state === "") {
58+ quickreply.state = "expanded";
59+ } else {
60+ quickreply.state = "";
61+ }
62+ }
63+ }
64+
65+ ActionButton {
66+ actionGroup: snapDecision.actionGroup
67+ action: actionsDescription[0].name
68+
69+ text: actionsDescription ? actionsDescription[0].label : "Call back"
70+ color: "#c94212"
71+ anchors.right: parent.right
72+ anchors.top: parent.top
73+ anchors.bottom: parent.bottom
74+ width: (parent.width - units.gu(1)) / 2
75+ }
76+
77+ states: State {
78+ name: "expanded"
79+ when: snapDecision.state === "expanded"
80+
81+ PropertyChanges {
82+ target: buttons
83+ opacity: 1.0
84+ }
85+ }
86+ transitions: Transition {
87+ NumberAnimation {
88+ property: "opacity"
89+ duration: 200
90+ easing.type: Easing.OutQuad
91+ }
92+ }
93+ }
94+
95+ QuickReply {
96+ id: quickreply
97+
98+ actionGroup: snapDecision.actionGroup
99+ action: actionsDescription[1].name
100+
101+ messages: actionsDescription ? actionsDescription[1]["parameter-hint"] : ""
102+ buttonText: actionsDescription ? actionsDescription[1].label : "send"
103+ anchors {
104+ top: buttons.bottom
105+ topMargin: units.gu(2)
106+ left: parent.left
107+ right: parent.right
108+ }
109+ height: 0
110+ opacity: 0.0
111+ enabled: false
112+
113+ states: State {
114+ name: "expanded"
115+
116+ PropertyChanges {
117+ target: quickreply
118+ height: expandedHeight
119+ opacity: 1.0
120+ }
121+
122+ PropertyChanges {
123+ target: quickreply
124+ enabled: true
125+ }
126+ }
127+
128+ transitions: Transition {
129+ NumberAnimation {
130+ properties: "opacity,height"
131+ duration: 200
132+ easing.type: Easing.OutQuad
133+ }
134+ }
135+ }
136+
137+ onStateChanged: {
138+ if (state === "") {
139+ quickreply.state = "";
140+ }
141+ }
142+}
plugins/Unity/Indicators/Messaging/qml/TextMessage.qmlnew 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+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+import Unity.Indicators 0.1 as Indicators
24+
25+SimpleTextMessage {
26+ id: simpleMessage
27+
28+ footer: ActionTextField {
29+ anchors.fill: parent
30+ actionGroup: simpleMessage.actionGroup
31+ action: actionsDescription[0].name
32+
33+ buttonText: actionsDescription ? actionsDescription[0].label : "Send"
34+ }
35+}
plugins/Unity/Indicators/Messaging/qml/qmldirnew file+12
@@ -0,0 +1,12 @@
1+module Unity.Indicators.Messaging
2+
3+ActionButton 0.1 ActionButton.qml
4+ActionTextField 0.1 ActionTextField.qml
5+GroupedMessage 0.1 GroupedMessage.qml
6+HeroMessage 0.1 HeroMessage.qml
7+HeroMessageHeader 0.1 HeroMessageHeader.qml
8+MessageMenuItem 0.1 MessageMenuItem.qml
9+QuickReply 0.1 QuickReply.qml
10+SimpleTextMessage 0.1 SimpleTextMessage.qml
11+SnapDecision 0.1 SnapDecision.qml
12+TextMessage 0.1 TextMessage.qml
plugins/Unity/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/Unity/Indicators/Network/CMakeLists.txtnew file+42
@@ -0,0 +1,42 @@
1+project(IndicatorsNetworkQml)
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+
7+if(LIBNM_GLIB_FOUND AND LIBNM_UTIL_FOUND AND GLIB_FOUND)
8+ set(INDICATORS_NETWORK_SRC
9+ networkagent.cpp
10+ plugin.cpp
11+ secret-agent.c
12+ )
13+
14+ add_library(IndicatorsNetworkQml MODULE
15+ ${INDICATORS_NETWORK_SRC}
16+ )
17+
18+ qt5_use_modules(IndicatorsNetworkQml Core Qml Widgets)
19+
20+ set_target_properties(IndicatorsNetworkQml PROPERTIES COMPILE_FLAGS -fPIC)
21+
22+ include_directories(
23+ ${CMAKE_CURRENT_SOURCE_DIR}
24+ ${GLIB_INCLUDE_DIRS}
25+ ${LIBNM_GLIB_INCLUDE_DIRS}
26+ ${LIBNM_UTIL_INCLUDE_DIRS}
27+ )
28+
29+ target_link_libraries(IndicatorsNetworkQml
30+ ${GLIB_LIBRARIES}
31+ ${LIBNM_GLIB_LIBRARIES}
32+ ${LIBNM_UTIL_LIBRARIES}
33+ )
34+
35+ install(TARGETS IndicatorsNetworkQml
36+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Unity/Indicators/Network
37+ )
38+else()
39+ message(WARNING "Missing glib or libnm dependency for the network plugin, not building")
40+endif()
41+
42+add_subdirectory(qml)
plugins/Unity/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/Unity/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
tests/mocks/Ubuntu/ChewieUI/fake_chewie_plugin.cpp → plugins/Unity/Indicators/Network/plugin.cpprenamed+12−11
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2012, 2013 Canonical, Ltd.
2+ * Copyright (C) 2012 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -12,19 +12,20 @@
12 *
12 *
13 * You should have received a copy of the GNU General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
15 */
17 */
16
18
17−#include "fake_chewie_plugin.h"
19+// Qt
18−#include "fake_pluginmodel.h"
20+#include <QtQml>
19
21
22+// self
20−#include <qqml.h>
23+#include "plugin.h"
21
24
22−void FakeChewieQmlPlugin::registerTypes(const char *uri)
25+// local
23−{
26+#include "networkagent.h"
24−// #ifndef GLIB_VERSION_2_36
25−// g_type_init();
26−// #endif
27
27
28− qmlRegisterUncreatableType<WidgetsMap>(uri, 0, 1, "WidgetsMap", "WidgetsMap must be created by PluginModel");
28+void IndicatorsNetworkPlugin::registerTypes(const char *uri)
29+{
29− qmlRegisterType<PluginModel>(uri, 0, 1, "PluginModel");
30+ qmlRegisterType<NetworkAgent>(uri, 0, 1, "NetworkAgent");
30}
31}
plugins/Unity/Indicators/Network/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 INDICATORS_NETWORK_PLUGIN_H
20+#define INDICATORS_NETWORK_PLUGIN_H
21+
22+#include <QtQml/QQmlExtensionPlugin>
23+
24+class IndicatorsNetworkPlugin : 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 // INDICATORS_NETWORK_PLUGIN_H
plugins/Unity/Indicators/Network/qml/AccessPoint.qmlnew file+68
@@ -0,0 +1,68 @@
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 Unity.Indicators 0.1 as Indicators
24+
25+Indicators.MenuItem {
26+ id: accessPoint
27+ property variant actionWifiApStrength : menu && actionGroup ? actionGroup.action(menu.extra.canonical_wifi_ap_strength_action) : null
28+ property variant wifiApStrength : actionWifiApStrength && actionWifiApStrength.valid ? actionWifiApStrength.state : "0"
29+
30+ function getNetworkIcon(data) {
31+ var imageName = "nm-signal-100"
32+ var signalStrength = parseInt(wifiApStrength)
33+
34+ if (data.extra.canonical_wifi_ap_is_adhoc) {
35+ imageName = "nm-adhoc";
36+ } else if (signalStrength == 0) {
37+ imageName = "nm-signal-00";
38+ } else if (signalStrength <= 25) {
39+ imageName = "nm-signal-25";
40+ } else if (signalStrength <= 50) {
41+ imageName = "nm-signal-50";
42+ } else if (signalStrength <= 75) {
43+ imageName = "nm-signal-75";
44+ }
45+
46+ if (data.extra.canonical_wifi_ap_is_secure) {
47+ imageName += "-secure";
48+ }
49+
50+ return "image://gicon/" + imageName;
51+ }
52+
53+ icon: menu && wifiApStrength ? getNetworkIcon(menu) : "image://gicon/wifi-none"
54+ iconFrame: false
55+ control: CheckBox {
56+ id: checkBoxActive
57+ height: units.gu(4)
58+ width: units.gu(4)
59+ anchors.centerIn: parent
60+ }
61+
62+ Indicators.MenuActionBinding {
63+ actionGroup: accessPoint.actionGroup
64+ action: menu ? menu.action : ""
65+ target: checkBoxActive
66+ property: "checked"
67+ }
68+}
plugins/Unity/Indicators/Network/qml/CMakeLists.txtnew file+15
@@ -0,0 +1,15 @@
1+file(GLOB IndicatorsNetwork_QMLFILES
2+ *.qml
3+ *.js
4+ qmldir
5+)
6+
7+# copy qml & qmldir files into build directory for shadow builds
8+add_custom_target(UnityIndicatorsNetworkQmlFiles ALL
9+ COMMAND cp ${IndicatorsNetwork_QMLFILES} ${CMAKE_BINARY_DIR}/plugins/Unity/Indicators/Network
10+ DEPENDS ${IndicatorsNetwork_QMLFILES}
11+)
12+
13+install(FILES ${IndicatorsNetwork_QMLFILES}
14+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Unity/Indicators/Network
15+)
plugins/Unity/Indicators/Network/qml/PasswordPage.qmlnew file+88
@@ -0,0 +1,88 @@
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 Unity.Indicators 0.1 as Indicators
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+ Indicators.SectionMenuItem {
41+ label: "Authentication"
42+ }
43+
44+ Indicators.MenuItem {
45+ implicitHeight: password.height + units.gu(1)
46+
47+ PasswordTextField {
48+ id: password
49+ anchors {
50+ left: parent.left
51+ right: parent.right
52+ margins: units.gu(3)
53+ verticalCenter: parent.verticalCenter
54+ }
55+ }
56+ }
57+
58+ Indicators.MenuItem {
59+ Row {
60+ anchors {
61+ right: parent.right
62+ verticalCenter: parent.verticalCenter
63+ margins: units.gu(3)
64+ }
65+
66+ spacing: units.gu(1)
67+
68+ Button {
69+ text: "Cancel"
70+ width: units.gu(10)
71+ onClicked: {
72+ agent.cancel(token);
73+ pageStack.pop();
74+ }
75+ }
76+
77+ Button {
78+ text: "Ok"
79+ width: units.gu(10)
80+ onClicked: {
81+ agent.authenticate(token, password.text);
82+ pageStack.pop();
83+ }
84+ }
85+ }
86+ }
87+ }
88+}
plugins/Unity/Indicators/Network/qml/PasswordTextField.qmlnew file+68
@@ -0,0 +1,68 @@
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+Item {
24+ id: textMenu
25+
26+ property alias text: textField.text
27+
28+ height: contentColumn.height
29+
30+ Column {
31+ id: contentColumn
32+ spacing: units.gu(0.5)
33+ anchors {
34+ left: parent.left
35+ right: parent.right
36+ }
37+
38+ TextField {
39+ id: textField
40+
41+ anchors {
42+ left: parent.left
43+ right: parent.right
44+ }
45+
46+ placeholderText: "Password"
47+ echoMode: showPassword.checked ? TextInput.Normal : TextInput.Password
48+ }
49+
50+ Row {
51+ anchors {
52+ left: parent.left
53+ right: parent.right
54+ }
55+
56+ spacing: units.gu(1)
57+
58+ CheckBox {
59+ id: showPassword
60+ }
61+
62+ Label {
63+ text: "Show password"
64+ anchors.verticalCenter: showPassword.verticalCenter
65+ }
66+ }
67+ }
68+}
plugins/Unity/Indicators/Network/qml/WifiSection.qmlnew 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+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Unity.Indicators 0.1 as Indicators
23+
24+Indicators.SectionMenuItem {
25+ id: wifiSectionMenu
26+
27+ Indicators.MenuAction {
28+ id: busyAction
29+ actionGroup: wifiSectionMenu.actionGroup
30+ action: menu ? menu.extra.canonical_busy_action : ""
31+ }
32+
33+ busy: busyAction.valid ? busyAction.state : false
34+}
plugins/Unity/Indicators/Network/qml/qmldirnew file+8
@@ -0,0 +1,8 @@
1+module Unity.Indicators.Network
2+plugin IndicatorsNetworkQml
3+
4+NetworkPage 0.1 NetworkPage.qml
5+AccessPoint 0.1 AccessPoint.qml
6+PasswordPage 0.1 PasswordPage.qml
7+PasswordTextField 0.1 PasswordTextField.qml
8+WifiSection 0.1 WifiSection.qml
plugins/Unity/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/Unity/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/Unity/Indicators/flatmenuproxymodel.cppnew file+272
@@ -0,0 +1,272 @@
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+
57+ // FIXME - not working correctly with dynamic inserts/removes
58+
59+ connect(source,
60+ SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
61+ SLOT(onModelAboutToBeReset()));
62+ connect(source,
63+ SIGNAL(rowsInserted(QModelIndex,int,int)),
64+ SLOT(onModelReset()));
65+
66+ connect(source,
67+ SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
68+ SLOT(onModelAboutToBeReset()));
69+ connect(source,
70+ SIGNAL(rowsRemoved(QModelIndex,int,int)),
71+ SLOT(onModelReset()));
72+
73+ connect(source,
74+ SIGNAL(modelAboutToBeReset()),
75+ SLOT(onModelAboutToBeReset()));
76+ connect(source,
77+ SIGNAL(modelReset()),
78+ SLOT(onModelReset()));
79+
80+ connect(source,
81+ SIGNAL(statusChanged(DBusEnums::ConnectionStatus)),
82+ SIGNAL(statusChanged()));
83+
84+ // initiliaze rowCount
85+ QModelIndex lastItem = source->index(source->rowCount() - 1, 0);
86+ m_rowCount = recursiveRowCount(lastItem);
87+ } else {
88+ m_rowCount = 0;
89+ }
90+
91+ Q_EMIT countChanged();
92+}
93+
94+void FlatMenuProxyModel::setBusName(const QString &busName)
95+{
96+ m_model->setBusName(busName);
97+}
98+
99+QString FlatMenuProxyModel::busName() const
100+{
101+ return m_model->busName();
102+}
103+
104+void FlatMenuProxyModel::setObjectPath(const QString &busPath)
105+{
106+ m_model->setObjectPath(busPath);
107+}
108+
109+QString FlatMenuProxyModel::objectPath() const
110+{
111+ return m_model->objectPath();
112+}
113+
114+int FlatMenuProxyModel::status() const
115+{
116+ return m_model->status();
117+}
118+
119+DBusEnums::BusType FlatMenuProxyModel::busType() const
120+{
121+ return m_model->busType();
122+}
123+
124+void FlatMenuProxyModel::setIntBusType(int type)
125+{
126+ m_model->setBusType((DBusEnums::BusType) type);
127+}
128+
129+void FlatMenuProxyModel::start()
130+{
131+ m_model->start();
132+}
133+
134+void FlatMenuProxyModel::stop()
135+{
136+ m_model->stop();
137+}
138+
139+QModelIndex FlatMenuProxyModel::mapFromSource(const QModelIndex &index) const
140+{
141+ if (!index.isValid()) {
142+ return QModelIndex();
143+ }
144+
145+ QModelIndex result = createIndex(rowOffsetOf(index, index.row()), 0);
146+ return result;
147+}
148+
149+QModelIndex FlatMenuProxyModel::mapToSource(const QModelIndex &index) const
150+{
151+ if (sourceModel() && m_indexCache.contains(index.row())) {
152+ QString key = m_indexCache.value(index.row());
153+ QStringList sections = key.split('.', QString::SkipEmptyParts);
154+ QModelIndex sourceIndex = QModelIndex();
155+ for(int i=0; i < sections.size(); i++) {
156+ sourceIndex = sourceModel()->index(sections.at(i).toInt(), 9, sourceIndex);
157+ }
158+ return sourceIndex;
159+ } else {
160+ return QModelIndex();
161+ }
162+}
163+
164+QModelIndex FlatMenuProxyModel::index(int row, int sectionRow, const QModelIndex &parent, const QString &key) const
165+{
166+ for (int i = 0, count = 0; i < sourceModel()->rowCount(parent); i++) {
167+ QModelIndex sourceIndex = sourceModel()->index(i, 0, parent);
168+ int indexCount = recursiveRowCount(sourceIndex);
169+
170+ if (count == sectionRow) {
171+ QString sectionKey = key + "." + QString::number(i);
172+ m_indexCache.insert(row, sectionKey);
173+ return createIndex(row, 0);
174+ } else if ((count + indexCount) >= sectionRow) {
175+ count++;
176+ return index(row, sectionRow - count, sourceIndex, key + "." + QString::number(i));
177+ }
178+
179+ count += indexCount + 1;
180+ }
181+ return QModelIndex();
182+}
183+
184+QModelIndex FlatMenuProxyModel::index(int row, int, const QModelIndex &) const
185+{
186+ return index(row, row, QModelIndex(), "");
187+}
188+
189+QModelIndex FlatMenuProxyModel::parent(const QModelIndex &) const
190+{
191+ return QModelIndex();
192+}
193+
194+int FlatMenuProxyModel::columnCount(const QModelIndex &) const
195+{
196+ return 1;
197+}
198+
199+int FlatMenuProxyModel::rowCount(const QModelIndex &) const
200+{
201+ return m_rowCount;
202+}
203+
204+int FlatMenuProxyModel::count() const
205+{
206+ return rowCount(QModelIndex());
207+}
208+
209+void FlatMenuProxyModel::onModelAboutToBeReset()
210+{
211+ beginResetModel();
212+}
213+
214+void FlatMenuProxyModel::onModelReset()
215+{
216+ // initiliaze rowCount
217+ m_rowCount = 0;
218+ for (int i = 0, iMax = sourceModel()->rowCount(); i < iMax; i++) {
219+ QModelIndex index = sourceModel()->index(i, 0);
220+ m_rowCount += recursiveRowCount(index) + 1;
221+ }
222+ m_indexCache.clear();
223+ endResetModel();
224+ Q_EMIT countChanged();
225+}
226+
227+int FlatMenuProxyModel::recursiveRowCount(const QModelIndex &index) const
228+{
229+ int size = sourceModel()->rowCount(index);
230+ for (int i=0, iMax=size; i < iMax; i++) {
231+ QModelIndex currentIndex = sourceModel()->index(i, 0, index);
232+ size += recursiveRowCount(currentIndex);
233+ }
234+
235+ return size;
236+}
237+
238+int FlatMenuProxyModel::rowOffsetOf(const QModelIndex &index, int row, bool inclusive) const
239+{
240+ int offset = 0;
241+
242+ QModelIndex parent = index.parent();
243+
244+ // Check row 0 offset
245+ while(parent.isValid()) {
246+ offset += 1;
247+ for (int i = 0; i < parent.row(); i++) {
248+ QModelIndex currentIndex = sourceModel()->index(i, 0, parent);
249+ offset += recursiveRowCount(currentIndex) + 1;
250+ }
251+ parent = parent.parent();
252+ }
253+
254+ // Check index.row() offset
255+ for(int i = 0; i < row; i++) {
256+ QModelIndex currentIndex = sourceModel()->index(i, 0, index.parent());
257+ offset += recursiveRowCount(currentIndex) + 1;
258+ }
259+
260+ if (inclusive) {
261+ // itself
262+ QModelIndex currentIndex = sourceModel()->index(row, 0, index.parent());
263+ offset += recursiveRowCount(currentIndex);
264+ }
265+
266+ return offset;
267+}
268+
269+QVariant FlatMenuProxyModel::data(int row, int role) const
270+{
271+ return QAbstractProxyModel::data(index(row, 0), role);
272+}
plugins/Unity/Indicators/flatmenuproxymodel.hnew file+91
@@ -0,0 +1,91 @@
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+ Q_ENUMS(Roles)
38+public:
39+ FlatMenuProxyModel(QAbstractItemModel *source=0);
40+ ~FlatMenuProxyModel();
41+
42+ void setSourceModel(QAbstractItemModel * sourceModel);
43+
44+ Q_INVOKABLE QVariant data(int row, int role = Qt::DisplayRole) const;
45+
46+ QModelIndex mapFromSource(const QModelIndex &index) const;
47+ QModelIndex mapToSource(const QModelIndex &index) const;
48+
49+ QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
50+ QModelIndex parent(const QModelIndex &index) const;
51+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
52+ int count() const;
53+ int columnCount(const QModelIndex &parent) const;
54+
55+ void setBusName(const QString &busName);
56+ QString busName() const;
57+
58+ void setObjectPath(const QString &busName);
59+ QString objectPath() const;
60+
61+ DBusEnums::BusType busType() const;
62+ void setIntBusType(int type);
63+
64+ int status() const;
65+
66+public Q_SLOTS:
67+ void onModelAboutToBeReset();
68+ void onModelReset();
69+
70+ void start();
71+ void stop();
72+
73+Q_SIGNALS:
74+ void countChanged();
75+
76+ void busTypeChanged();
77+ void busNameChanged();
78+ void objectPathChanged();
79+ void statusChanged();
80+
81+private:
82+ QDBusMenuModel *m_model;
83+ mutable QMap<int, QString> m_indexCache;
84+ int m_rowCount;
85+
86+ int rowOffsetOf(const QModelIndex &index, int row, bool inclusive = false) const;
87+ int recursiveRowCount(const QModelIndex &index) const;
88+ QModelIndex index(int row, int rowCount, const QModelIndex &parent, const QString &key) const;
89+};
90+
91+#endif
plugins/Unity/Indicators/indicator.cppnew file+88
@@ -0,0 +1,88 @@
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 "indicator.h"
21+
22+#include <QStringList>
23+
24+Indicator::Indicator(QObject *parent)
25+ : QObject(parent)
26+{
27+}
28+
29+Indicator::~Indicator()
30+{
31+}
32+
33+void Indicator::init(const QString& busName, const QSettings& settings)
34+{
35+ setId(settings.value("Indicator Service/Name").toString());
36+
37+ QString actionObjectPath = settings.value("Indicator Service/ObjectPath").toString();
38+
39+ QVariantMap mapMenuObjectPaths;
40+ Q_FOREACH(const QString& childGroup, settings.childGroups())
41+ {
42+ if (childGroup == "Indicator Service")
43+ continue;
44+
45+ QString menuPath = childGroup+"/ObjectPath";
46+ if (settings.contains(menuPath))
47+ {
48+ mapMenuObjectPaths[childGroup] = settings.value(menuPath).toString();
49+ }
50+ }
51+
52+
53+ QVariantMap properties;
54+ properties.clear();
55+ properties.insert("busType", 1);
56+ properties.insert("busName", busName);
57+ properties.insert("actionsObjectPath", actionObjectPath);
58+ properties.insert("menuObjectPaths", mapMenuObjectPaths);
59+ setIndicatorProperties(properties);
60+}
61+
62+QString Indicator::identifier() const
63+{
64+ return m_identifier;
65+}
66+
67+void Indicator::setId(const QString &identifier)
68+{
69+ if (identifier != m_identifier) {
70+ m_identifier = identifier;
71+ Q_EMIT identifierChanged(m_identifier);
72+ }
73+}
74+
75+
76+QVariant Indicator::indicatorProperties() const
77+{
78+ return m_properties;
79+}
80+
81+void Indicator::setIndicatorProperties(const QVariant &properties)
82+{
83+ if (m_properties != properties)
84+ {
85+ m_properties = properties;
86+ Q_EMIT indicatorPropertiesChanged(m_properties);
87+ }
88+}
plugins/Unity/Indicators/indicator.hnew file+57
@@ -0,0 +1,57 @@
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 INDICATOR_H
22+#define INDICATOR_H
23+
24+#include <QObject>
25+#include <QSettings>
26+
27+class Indicator : public QObject
28+{
29+ Q_OBJECT
30+ Q_PROPERTY(QString identifier READ identifier NOTIFY identifierChanged)
31+ Q_PROPERTY(QVariant indicatorProperties READ indicatorProperties NOTIFY indicatorPropertiesChanged)
32+
33+public:
34+ typedef QSharedPointer<Indicator> Ptr;
35+
36+ Indicator(QObject *parent = 0);
37+ virtual ~Indicator();
38+
39+ void init(const QString& busName, const QSettings& settings);
40+
41+ QString identifier() const;
42+ QVariant indicatorProperties() const;
43+
44+Q_SIGNALS:
45+ void identifierChanged(const QString &identifier);
46+ void indicatorPropertiesChanged(const QVariant &properties);
47+
48+protected:
49+ void setId(const QString &id);
50+ void setIndicatorProperties(const QVariant &properties);
51+
52+private:
53+ QString m_identifier;
54+ QVariant m_properties;
55+};
56+
57+#endif // INDICATOR_H
plugins/Unity/Indicators/indicators.hnew file+103
@@ -0,0 +1,103 @@
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_H
20+#define INDICATORS_H
21+
22+#include <QObject>
23+
24+class ActionState : public QObject
25+{
26+ Q_OBJECT
27+public:
28+ Q_ENUMS(ActionStates)
29+ enum ActionStates {
30+ Label = 0x00,
31+ IconSource = 0x01,
32+ AccessableName = 0x02,
33+ Visible = 0x03,
34+ };
35+
36+ ActionState(QObject*parent=0):QObject(parent) {}
37+};
38+
39+class NetworkActionState : public QObject
40+{
41+ Q_OBJECT
42+public:
43+ Q_ENUMS(NetworkActionStates)
44+ enum NetworkActionStates {
45+ Connection = 0x01,
46+ SignalStrength = 0x02,
47+ };
48+
49+ NetworkActionState(QObject*parent=0):QObject(parent) {}
50+};
51+
52+class NetworkConnection : public QObject
53+{
54+ Q_OBJECT
55+public:
56+ Q_ENUMS(NetworkConnectionStates)
57+ enum NetworkConnectionStates {
58+ Initial = 0x00,
59+ Activating = 0x01,
60+ Activated = 0x02,
61+ Deactivating = 0x03,
62+ };
63+
64+ NetworkConnection(QObject*parent=0):QObject(parent) {}
65+};
66+
67+class IndicatorsModelRole : public QObject
68+{
69+ Q_OBJECT
70+public:
71+ Q_ENUMS(Roles)
72+ enum Roles {
73+ Identifier = 0,
74+ Priority,
75+ Title,
76+ Description,
77+ WidgetSource,
78+ PageSource,
79+ IndicatorProperties,
80+ IsValid
81+ };
82+
83+ IndicatorsModelRole(QObject*parent=0):QObject(parent) {}
84+};
85+
86+class FlatMenuProxyModelRole : public QObject
87+{
88+ Q_OBJECT
89+public:
90+ Q_ENUMS(Roles)
91+ enum Roles {
92+ Action = Qt::DisplayRole + 1,
93+ Label,
94+ Extra,
95+ Depth,
96+ hasSection,
97+ hasSubMenu
98+ };
99+
100+ FlatMenuProxyModelRole(QObject*parent=0):QObject(parent) {}
101+};
102+
103+#endif // INDICATORS_H
plugins/Unity/Indicators/indicatorsmanager.cppnew file+285
@@ -0,0 +1,285 @@
1+/*
2+ * Copyright (C) 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 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+#include "indicatorsmanager.h"
20+
21+#include <QSettings>
22+#include <QDebug>
23+
24+#include "paths.h"
25+
26+
27+class IndicatorsManager::IndicatorData
28+{
29+public:
30+ IndicatorData(const QString& name, const QFileInfo& fileInfo)
31+ : m_name(name)
32+ , m_fileInfo(fileInfo)
33+ , m_verified (true)
34+ {}
35+
36+ QString m_name;
37+ QFileInfo m_fileInfo;
38+
39+ bool m_verified;
40+ Indicator::Ptr m_indicator;
41+};
42+
43+IndicatorsManager::IndicatorsManager(QObject* parent)
44+ : QObject(parent)
45+ , m_loaded(false)
46+{
47+}
48+
49+IndicatorsManager::~IndicatorsManager()
50+{
51+ unload();
52+}
53+
54+void IndicatorsManager::load()
55+{
56+ unload();
57+ QStringList xdgLocations = shellDataDirs();//QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
58+
59+ m_fsWatcher.reset(new QFileSystemWatcher(this));
60+
61+ Q_FOREACH(const QString& xdgLocation, xdgLocations)
62+ {
63+ QString indicator_path = QDir::cleanPath(xdgLocation + "/unity/indicators");
64+ QDir indicator_dir(indicator_path);
65+ if (indicator_dir.exists())
66+ {
67+ // watch folder for changes.
68+ m_fsWatcher->addPath(indicator_path);
69+
70+ loadDir(indicator_dir);
71+ }
72+ }
73+
74+ QObject::connect(m_fsWatcher.data(), SIGNAL(directoryChanged(const QString&)), this, SLOT(onDirectoryChanged(const QString&)));
75+ QObject::connect(m_fsWatcher.data(), SIGNAL(fileChanged(const QString&)), this, SLOT(onFileChanged(const QString&)));
76+ setLoaded(true);
77+}
78+
79+void IndicatorsManager::onDirectoryChanged(const QString& directory)
80+{
81+ loadDir(QDir(directory));
82+}
83+
84+void IndicatorsManager::onFileChanged(const QString& file)
85+{
86+ QFileInfo file_info(file);
87+ if (!file_info.exists())
88+ {
89+ unloadFile(file_info);
90+ return;
91+ }
92+ else
93+ {
94+ loadFile(QFileInfo(file));
95+ }
96+}
97+
98+void IndicatorsManager::loadDir(const QDir& dir)
99+{
100+ startVerify(dir.canonicalPath());
101+
102+ QFileInfoList indicator_files = dir.entryInfoList(QStringList(), QDir::Files|QDir::NoDotAndDotDot);
103+ Q_FOREACH(const QFileInfo& indicator_file, indicator_files)
104+ {
105+ loadFile(indicator_file);
106+ }
107+
108+ endVerify(dir.canonicalPath());
109+}
110+
111+void IndicatorsManager::loadFile(const QFileInfo& file_info)
112+{
113+ QSettings indicator_settings(file_info.absoluteFilePath(), QSettings::IniFormat, this);
114+ QString name = indicator_settings.value("Indicator Service/Name").toString();
115+
116+ auto iter = m_indicatorsData.find(name);
117+ if (iter != m_indicatorsData.end())
118+ {
119+ QString newFileInfoDir = QDir::cleanPath(file_info.canonicalPath());
120+ IndicatorData* currentData = (*iter);
121+ currentData->m_verified = true;
122+
123+ int file_info_location = -1;
124+ int current_data_location = -1;
125+
126+ QString currentDataDir = QDir::cleanPath(currentData->m_fileInfo.canonicalPath());
127+
128+ // if we've already got this indicator, we need to make sure we're not overwriting data which is
129+ // from a lower priority standard path
130+ QStringList xdgLocations = shellDataDirs();
131+ for (int i = 0; i < xdgLocations.size(); i++)
132+ {
133+ QString indicatorDir = QDir::cleanPath(xdgLocations[i] + "/unity/indicators");
134+
135+ if (newFileInfoDir == indicatorDir)
136+ {
137+ file_info_location = i;
138+ }
139+ if (currentDataDir == indicatorDir)
140+ {
141+ current_data_location = i;
142+ }
143+
144+ if (file_info_location != -1 && current_data_location != -1)
145+ {
146+ break;
147+ }
148+ }
149+
150+ // file location is higher (or of equal) priority. overwrite.
151+ if (file_info_location <= current_data_location &&
152+ file_info != currentData->m_fileInfo)
153+ {
154+ currentData->m_fileInfo = file_info;
155+ Q_EMIT indicatorLoaded(name);
156+ }
157+ }
158+ else
159+ {
160+ IndicatorData* data = new IndicatorData(name, file_info);
161+ data->m_verified = true;
162+ m_indicatorsData[name]= data;
163+ Q_EMIT indicatorLoaded(name);
164+ }
165+}
166+
167+void IndicatorsManager::unload()
168+{
169+ QHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
170+ while(iter.hasNext())
171+ {
172+ iter.next();
173+ Q_EMIT indicatorAboutToBeUnloaded(iter.key());
174+ }
175+
176+ qDeleteAll(m_indicatorsData);
177+ m_indicatorsData.clear();
178+
179+ setLoaded(false);
180+}
181+
182+void IndicatorsManager::unloadFile(const QFileInfo& file)
183+{
184+ QMutableHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
185+ while(iter.hasNext())
186+ {
187+ iter.next();
188+ IndicatorData* data = iter.value();
189+ if (data->m_fileInfo.absoluteFilePath() == file.absoluteFilePath())
190+ {
191+ if (!data->m_verified)
192+ {
193+ QString name = data->m_name;
194+ Q_EMIT indicatorAboutToBeUnloaded(name);
195+
196+ delete data;
197+ iter.remove();
198+ }
199+ }
200+ }
201+
202+ setLoaded(m_indicatorsData.size() > 0);
203+}
204+
205+void IndicatorsManager::setLoaded(bool loaded)
206+{
207+ if (loaded != m_loaded)
208+ {
209+ m_loaded = loaded;
210+ Q_EMIT loadedChanged(m_loaded);
211+ }
212+}
213+
214+void IndicatorsManager::startVerify(const QString& path)
215+{
216+ QHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
217+ while(iter.hasNext())
218+ {
219+ iter.next();
220+ IndicatorData* data = iter.value();
221+ if (data->m_fileInfo.canonicalPath() == path)
222+ {
223+ data->m_verified = false;
224+ }
225+ }
226+}
227+
228+void IndicatorsManager::endVerify(const QString& path)
229+{
230+ QMutableHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
231+ while(iter.hasNext())
232+ {
233+ iter.next();
234+ IndicatorData* data = iter.value();
235+ if (data->m_fileInfo.canonicalPath() == path)
236+ {
237+ if (!data->m_verified)
238+ {
239+ QString name = data->m_name;
240+ Q_EMIT indicatorAboutToBeUnloaded(name);
241+
242+ delete data;
243+ iter.remove();
244+ }
245+ }
246+ }
247+}
248+
249+Indicator::Ptr IndicatorsManager::indicator(const QString& indicator_name)
250+{
251+ if (!m_indicatorsData.contains(indicator_name))
252+ {
253+ qWarning() << Q_FUNC_INFO << "Invalid indicator name: " << indicator_name;
254+ return Indicator::Ptr();
255+ }
256+
257+ IndicatorData *data = m_indicatorsData[indicator_name];
258+ if (data->m_indicator)
259+ {
260+ return data->m_indicator;
261+ }
262+
263+ Indicator::Ptr new_indicator(new Indicator(this));
264+ data->m_indicator = new_indicator;
265+ QSettings settings(data->m_fileInfo.absoluteFilePath(), QSettings::IniFormat, this);
266+ new_indicator->init(data->m_fileInfo.fileName(), settings);
267+ return new_indicator;
268+}
269+
270+QList<Indicator::Ptr> IndicatorsManager::indicators()
271+{
272+ QList<Indicator::Ptr> list;
273+ Q_FOREACH(IndicatorData* data, m_indicatorsData)
274+ {
275+ Indicator::Ptr ret = indicator(data->m_name);
276+ if (ret)
277+ list.append(ret);
278+ }
279+ return list;
280+}
281+
282+bool IndicatorsManager::isLoaded() const
283+{
284+ return m_loaded;
285+}
plugins/Unity/Indicators/indicatorsmanager.hnew file+73
@@ -0,0 +1,73 @@
1+/*
2+ * Copyright (C) 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 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_MANAGER_H
20+#define INDICATORS_MANAGER_H
21+
22+#include <QObject>
23+#include <QFileSystemWatcher>
24+#include <QDir>
25+#include <QHash>
26+#include <QSharedPointer>
27+
28+#include "indicator.h"
29+
30+class IndicatorsManager : public QObject
31+{
32+ Q_OBJECT
33+ Q_PROPERTY(bool loaded READ isLoaded NOTIFY loadedChanged)
34+public:
35+ explicit IndicatorsManager(QObject* parent = 0);
36+ ~IndicatorsManager();
37+
38+ Q_INVOKABLE void load();
39+ Q_INVOKABLE void unload();
40+
41+ Indicator::Ptr indicator(const QString& indicator_name);
42+
43+ QList<Indicator::Ptr> indicators();
44+
45+ bool isLoaded() const;
46+
47+Q_SIGNALS:
48+ void loadedChanged(bool);
49+
50+ void indicatorLoaded(const QString& indicator_name);
51+ void indicatorAboutToBeUnloaded(const QString& indicator_name);
52+
53+private Q_SLOTS:
54+ void onDirectoryChanged(const QString& directory);
55+ void onFileChanged(const QString& file);
56+
57+private:
58+ void loadDir(const QDir& dir);
59+ void loadFile(const QFileInfo& file);
60+ void unloadFile(const QFileInfo& dir);
61+
62+ void startVerify(const QString& path);
63+ void endVerify(const QString& path);
64+
65+ void setLoaded(bool);
66+
67+ class IndicatorData;
68+ QHash<QString, IndicatorData*> m_indicatorsData;
69+ QSharedPointer<QFileSystemWatcher> m_fsWatcher;
70+ bool m_loaded;
71+};
72+
73+#endif // INDICATORS_MANAGER_H
plugins/Unity/Indicators/indicatorsmodel.cppnew file+321
@@ -0,0 +1,321 @@
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 "indicator.h"
23+#include "indicators.h"
24+#include "paths.h"
25+
26+#include <QQmlContext>
27+#include <QQmlEngine>
28+#include <QDebug>
29+
30+/*!
31+ \qmltype IndicatorsModel
32+ \inherits QAbstractListModel
33+
34+ \brief The IndicatorsModel class defines the list model for indicators
35+
36+ \b {This component is under heavy development.}
37+
38+ This class expose the available indicators.
39+
40+ \code
41+ IndicatorsModel {
42+ id: menuModel
43+ }
44+
45+ ListView {
46+ id: view
47+ model: menuModel
48+ Component.onCompleted: menuModel.load()
49+ }
50+ \endcode
51+*/
52+IndicatorsModel::IndicatorsModel(QObject *parent)
53+ : QAbstractListModel(parent)
54+{
55+ m_manager = new IndicatorsManager(this);
56+ QObject::connect(m_manager, SIGNAL(indicatorLoaded(const QString&)), this, SLOT(onIndicatorLoaded(const QString&)));
57+ QObject::connect(m_manager, SIGNAL(indicatorAboutToBeUnloaded(const QString&)), this, SLOT(onIndicatorAboutToBeUnloaded(const QString&)));
58+
59+ QObject::connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
60+ QObject::connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
61+ QObject::connect(this, SIGNAL(modelReset()), this, SIGNAL(countChanged()));
62+}
63+
64+/*! \internal */
65+IndicatorsModel::~IndicatorsModel()
66+{
67+ disconnect(m_manager, 0, 0, 0);
68+ m_manager->deleteLater();
69+}
70+
71+/*!
72+ \qmlproperty IndicatorsModel::count
73+ The number of data entries in the model.
74+
75+ \b Note: methods should only be called after the Component has completed.
76+*/
77+int IndicatorsModel::count() const
78+{
79+ return rowCount();
80+}
81+
82+/*!
83+ \qmlmethod IndicatorsModel::unload()
84+
85+ Load all indicators.
86+*/
87+void IndicatorsModel::load()
88+{
89+ m_indicators.clear();
90+ m_manager->load();
91+}
92+
93+/*!
94+ \qmlmethod IndicatorsModel::unload()
95+
96+ Unload all indicators.
97+*/
98+void IndicatorsModel::unload()
99+{
100+ m_manager->unload();
101+}
102+
103+/*! \internal */
104+void IndicatorsModel::onIndicatorLoaded(const QString& indicator_name)
105+{
106+ Indicator::Ptr indicator = m_manager->indicator(indicator_name);
107+ if (!indicator)
108+ {
109+ return;
110+ }
111+
112+ if (m_indicators.indexOf(indicator) >= 0)
113+ {
114+ return;
115+ }
116+
117+ // find the insert position
118+ int pos = 0;
119+ while (pos < count())
120+ {
121+ // keep going while the existing priority is less.
122+ if (indicatorData(indicator, IndicatorsModelRole::Priority).toInt() < data(index(pos), IndicatorsModelRole::Priority).toInt())
123+ break;
124+ pos++;
125+ }
126+
127+ QObject::connect(indicator.data(), SIGNAL(identifierChanged(const QString&)), this, SLOT(onIdentifierChanged()));
128+ QObject::connect(indicator.data(), SIGNAL(indicatorPropertiesChanged(const QVariant&)), this, SLOT(onIndicatorPropertiesChanged()));
129+
130+ beginInsertRows(QModelIndex(), pos, pos);
131+
132+ m_indicators.insert(pos, indicator);
133+ endInsertRows();
134+}
135+
136+/*! \internal */
137+void IndicatorsModel::onIndicatorAboutToBeUnloaded(const QString& indicator_name)
138+{
139+ Indicator::Ptr indicator = m_manager->indicator(indicator_name);
140+ if (!indicator)
141+ {
142+ return;
143+ }
144+
145+ int i = 0;
146+ QMutableListIterator<Indicator::Ptr> iter(m_indicators);
147+ while(iter.hasNext())
148+ {
149+ if (indicator == iter.next())
150+ {
151+ beginRemoveRows(QModelIndex(), i, i);
152+ iter.remove();
153+ endRemoveRows();
154+ break;
155+ }
156+ i++;
157+ }
158+
159+}
160+
161+/*! \internal */
162+void IndicatorsModel::onIdentifierChanged()
163+{
164+ notifyDataChanged(QObject::sender(), IndicatorsModelRole::Identifier);
165+}
166+
167+/*! \internal */
168+void IndicatorsModel::onIndicatorPropertiesChanged()
169+{
170+ notifyDataChanged(QObject::sender(), IndicatorsModelRole::IndicatorProperties);
171+}
172+
173+/*! \internal */
174+void IndicatorsModel::notifyDataChanged(QObject *sender, int role)
175+{
176+ Indicator* indicator = qobject_cast<Indicator*>(sender);
177+ if (!indicator)
178+ {
179+ return;
180+ }
181+
182+ int index = 0;
183+ QMutableListIterator<Indicator::Ptr> iter(m_indicators);
184+ while(iter.hasNext())
185+ {
186+ if (indicator == iter.next())
187+ {
188+ QModelIndex changedIndex = this->index(index);
189+ dataChanged(changedIndex, changedIndex, QVector<int>() << role);
190+ break;
191+ }
192+ index++;
193+ }
194+}
195+
196+/*! \internal */
197+QHash<int, QByteArray> IndicatorsModel::roleNames() const
198+{
199+ static QHash<int, QByteArray> roles;
200+ if (roles.isEmpty())
201+ {
202+ roles[IndicatorsModelRole::Identifier] = "identifier";
203+ roles[IndicatorsModelRole::Priority] = "priority";
204+ roles[IndicatorsModelRole::Title] = "title";
205+ roles[IndicatorsModelRole::Description] = "description";
206+ roles[IndicatorsModelRole::WidgetSource] = "widgetSource";
207+ roles[IndicatorsModelRole::PageSource] = "pageSource";
208+ roles[IndicatorsModelRole::IndicatorProperties] = "indicatorProperties";
209+ roles[IndicatorsModelRole::IsValid] = "isValid";
210+ }
211+ return roles;
212+}
213+
214+/*! \internal */
215+int IndicatorsModel::columnCount(const QModelIndex &) const
216+{
217+ return 1;
218+}
219+
220+/*! \internal */
221+QVariant IndicatorsModel::defaultData(Indicator::Ptr indicator, int role)
222+{
223+ switch (role)
224+ {
225+ case IndicatorsModelRole::Priority:
226+ return 0;
227+ case IndicatorsModelRole::Title:
228+ return indicator ? indicator->identifier() : "Unknown";
229+ case IndicatorsModelRole::Description:
230+ return "";
231+ case IndicatorsModelRole::WidgetSource:
232+ return shellAppDirectory()+"/Panel/Indicators/DefaultIndicatorWidget.qml";
233+ case IndicatorsModelRole::PageSource:
234+ return shellAppDirectory()+"/Panel/Indicators/DefaultIndicatorPage.qml";
235+ }
236+ return QVariant();
237+}
238+
239+Q_INVOKABLE QVariant IndicatorsModel::data(int row, int role) const
240+{
241+ return data(index(row, 0), role);
242+}
243+
244+/*! \internal */
245+QVariant IndicatorsModel::data(const QModelIndex &index, int role) const
246+{
247+ if (!index.isValid() || index.row() >= m_indicators.size())
248+ return QVariant();
249+
250+ Indicator::Ptr indicator = m_indicators[index.row()];
251+
252+ switch (role)
253+ {
254+ case IndicatorsModelRole::Identifier:
255+ if (indicator)
256+ {
257+ return QVariant(indicator->identifier());
258+ }
259+ break;
260+ case IndicatorsModelRole::IndicatorProperties:
261+ if (indicator)
262+ {
263+ return QVariant(indicator->indicatorProperties());
264+ }
265+ break;
266+ case IndicatorsModelRole::IsValid:
267+ return (indicator ? true : false);
268+ case IndicatorsModelRole::Priority:
269+ case IndicatorsModelRole::Title:
270+ case IndicatorsModelRole::Description:
271+ case IndicatorsModelRole::WidgetSource:
272+ case IndicatorsModelRole::PageSource:
273+ return indicatorData(indicator, role);
274+ default:
275+ break;
276+ }
277+ return QVariant();
278+}
279+
280+QVariant IndicatorsModel::indicatorData(const Indicator::Ptr& indicator, int role) const
281+{
282+ if (indicator && m_parsed_indicator_data.contains(indicator->identifier()))
283+ {
284+ QVariantMap data = m_parsed_indicator_data[indicator->identifier()];
285+ return data.value(roleNames()[role], QVariant());
286+ }
287+ return defaultData(indicator, role);
288+}
289+
290+/*! \internal */
291+QModelIndex IndicatorsModel::parent(const QModelIndex&) const
292+{
293+ return QModelIndex();
294+}
295+
296+/*! \internal */
297+int IndicatorsModel::rowCount(const QModelIndex&) const
298+{
299+ return m_indicators.count();
300+}
301+
302+void IndicatorsModel::setIndicatorData(const QVariant& data)
303+{
304+ m_indicator_data = data;
305+
306+ m_parsed_indicator_data.clear();
307+ QMap<QString, QVariant> map = data.toMap();
308+ QMapIterator<QString, QVariant> iter(map);
309+ while(iter.hasNext())
310+ {
311+ iter.next();
312+ m_parsed_indicator_data[iter.key()] = iter.value().toMap();
313+ }
314+
315+ Q_EMIT indicatorDataChanged(m_indicator_data);
316+}
317+
318+QVariant IndicatorsModel::indicatorData() const
319+{
320+ return m_indicator_data;
321+}
tests/mocks/Ubuntu/ChewieUI/fake_pluginmodel.h → plugins/Unity/Indicators/indicatorsmodel.hrenamed+32−45
@@ -15,65 +15,35 @@
15 *
15 *
16 * Authors:
16 * Authors:
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ * Nick Dedekind <nick.dedekind@canonical.com>
18 */
19 */
19
20
20−#ifndef PLUGINMODEL_H
21+#ifndef INDICATORSMODEL_H
21−#define PLUGINMODEL_H
22+#define INDICATORSMODEL_H
23+
24+#include "indicator.h"
22
25
23#include <QAbstractListModel>
26#include <QAbstractListModel>
24#include <QQmlEngine>
27#include <QQmlEngine>
25
28
29+class IndicatorsManager;
26
30
27−class WidgetsMap : public QObject
28−{
29− Q_OBJECT
30−public:
31− WidgetsMap(QObject *parent=0)
32− : QObject(parent)
33− {}
34−
35− void append(QMap<QString, QUrl> types)
36− {
37− Q_FOREACH(QString key, types.keys()) {
38− m_map.insert(key, types[key]);
39− }
40− }
41− void clear() { m_map.clear(); }
42−
43− Q_INVOKABLE QMap<QString, QUrl> map() const { return m_map; }
44− Q_INVOKABLE QUrl find(const QString &widget) const { return m_map[widget]; }
45−
46−private:
47− QMap<QString, QUrl> m_map;
48−};
49−
50−
51−class PluginModel : public QAbstractListModel
31+class IndicatorsModel : public QAbstractListModel
52{
32{
53 Q_OBJECT
33 Q_OBJECT
54− Q_PROPERTY(WidgetsMap* widgetsMap READ widgetsMap NOTIFY widgetsMapChanged)
34+ Q_ENUMS(Roles)
55 Q_PROPERTY(int count READ count NOTIFY countChanged)
35 Q_PROPERTY(int count READ count NOTIFY countChanged)
36+ Q_PROPERTY(QVariant indicatorData READ indicatorData WRITE setIndicatorData NOTIFY indicatorDataChanged)
56
37
57public:
38public:
58− enum ModelRoles {
59− Title = 0,
60− IconSource,
61− Label,
62− Description,
63− QMLComponent,
64− InitialProperties,
65− IsValid
66− };
67−
68− PluginModel(QObject *parent=0);
69− ~PluginModel();
70
39
71− WidgetsMap* widgetsMap() const;
40+ IndicatorsModel(QObject *parent=0);
41+ ~IndicatorsModel();
72
42
73 Q_INVOKABLE void load();
43 Q_INVOKABLE void load();
74 Q_INVOKABLE void unload();
44 Q_INVOKABLE void unload();
75
45
76− Q_INVOKABLE QVariantMap get(int row) const;
46+ Q_INVOKABLE QVariant data(int row, int role = Qt::DisplayRole) const;
77
47
78 /* QAbstractItemModel */
48 /* QAbstractItemModel */
79 QHash<int, QByteArray> roleNames() const;
49 QHash<int, QByteArray> roleNames() const;
@@ -82,13 +52,30 @@ public:
82 QModelIndex parent (const QModelIndex &index) const;
52 QModelIndex parent (const QModelIndex &index) const;
83 int rowCount(const QModelIndex &parent = QModelIndex()) const;
53 int rowCount(const QModelIndex &parent = QModelIndex()) const;
84
54
55+ void setIndicatorData(const QVariant& data);
56+ QVariant indicatorData() const;
57+
85Q_SIGNALS:
58Q_SIGNALS:
86− void widgetsMapChanged(WidgetsMap *widgetsMap);
87 void countChanged();
59 void countChanged();
60+ void indicatorDataChanged(const QVariant& data);
61+
62+private Q_SLOTS:
63+ void onIdentifierChanged();
64+ void onIndicatorPropertiesChanged();
65+ void onIndicatorLoaded(const QString& indicator);
66+ void onIndicatorAboutToBeUnloaded(const QString& indicator);
88
67
89private:
68private:
90− WidgetsMap* m_widgetsMap;
69+ IndicatorsManager *m_manager;
70+
71+ QList<Indicator::Ptr> m_indicators;
72+ QVariant m_indicator_data;
73+ QMap<QString, QVariantMap> m_parsed_indicator_data;
74+
75+ void notifyDataChanged(QObject *sender, int role);
91 int count() const;
76 int count() const;
77+ QVariant indicatorData(const Indicator::Ptr& indicator, int role) const;
78+ static QVariant defaultData(Indicator::Ptr indicator, int role);
92};
79};
93
80
94−#endif
81+#endif // INDICATORSMODEL_H
plugins/Unity/Indicators/plugin.cppnew file+44
@@ -0,0 +1,44 @@
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+// Qt
20+#include <QtQml>
21+
22+// self
23+#include "plugin.h"
24+
25+// local
26+#include "flatmenuproxymodel.h"
27+#include "indicatorsmanager.h"
28+#include "indicatorsmodel.h"
29+#include "indicators.h"
30+
31+void IndicatorsPlugin::registerTypes(const char *uri)
32+{
33+ Q_INIT_RESOURCE(indicators);
34+
35+ qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
36+ qmlRegisterType<FlatMenuProxyModel>(uri, 0, 1, "FlatMenuProxyModel");
37+ qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
38+
39+ qmlRegisterUncreatableType<ActionState>(uri, 0, 1, "ActionState", "Can't create ActionState class");
40+ qmlRegisterUncreatableType<NetworkActionState>(uri, 0, 1, "NetworkActionState", "Can't create NetworkActionState class");
41+ qmlRegisterUncreatableType<NetworkConnection>(uri, 0, 1, "NetworkConnection", "Can't create NetworkConnection class");
42+ qmlRegisterUncreatableType<IndicatorsModelRole>(uri, 0, 1, "IndicatorsModelRole", "Can't create IndicatorsModelRole class");
43+ qmlRegisterUncreatableType<FlatMenuProxyModelRole>(uri, 0, 1, "FlatMenuProxyModelRole", "Can't create FlatMenuProxyModelRole class");
44+}
tests/mocks/Ubuntu/ChewieUI/fake_chewie_plugin.h → plugins/Unity/Indicators/plugin.hrenamed+8−7
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2012, 2013 Canonical, Ltd.
2+ * Copyright (C) 2012 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -12,14 +12,16 @@
12 *
12 *
13 * You should have received a copy of the GNU General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
15 */
17 */
16
18
17−#ifndef PLUGIN_H
19+#ifndef INDICATORS_PLUGIN_H
18−#define PLUGIN_H
20+#define INDICATORS_PLUGIN_H
19
21
20−#include <QQmlExtensionPlugin>
22+#include <QtQml/QQmlExtensionPlugin>
21
23
22−class FakeChewieQmlPlugin : public QQmlExtensionPlugin
24+class IndicatorsPlugin : public QQmlExtensionPlugin
23{
25{
24 Q_OBJECT
26 Q_OBJECT
25 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
27 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
@@ -27,5 +29,4 @@ public:
27 void registerTypes(const char *uri);
29 void registerTypes(const char *uri);
28};
30};
29
31
30−
32+#endif // INDICATORS_PLUGIN_H
31−#endif
plugins/Unity/Indicators/qml/BasicMenuItem.qmlnew file+48
@@ -0,0 +1,48 @@
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: stdListItem
25+
26+ property bool menuActivated: false
27+ property QtObject menu
28+ property QtObject actionGroup
29+ property alias color: background.color
30+
31+ signal activateMenu()
32+ signal deactivateMenu()
33+
34+ showDivider: false
35+ __foregroundColor: "#e8e1d0"
36+
37+ backgroundIndicator: RemoveBackground {
38+ state: stdListItem.swipingState
39+ }
40+
41+ Rectangle {
42+ id: background
43+
44+ anchors.fill: parent
45+ color: "#221e1c"
46+ z: -1
47+ }
48+}
plugins/Unity/Indicators/qml/ButtonMenuItem.qmlnew file+47
@@ -0,0 +1,47 @@
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+BasicMenuItem {
24+ id: buttonMenu
25+ color: "#221e1b"
26+ implicitHeight: units.gu(7)
27+
28+ Button {
29+ id: button
30+ enabled: menuAction.valid
31+ text: menu ? menu.label : ""
32+ anchors.centerIn: parent
33+ height: units.gu(4)
34+ width: units.gu(16)
35+ color: "#1b1817"
36+
37+ onClicked: {
38+ menuAction.activate()
39+ }
40+ }
41+
42+ MenuAction {
43+ id: menuAction
44+ actionGroup: buttonMenu.actionGroup
45+ action: menu ? menu.action : ""
46+ }
47+}
plugins/Unity/Indicators/qml/CMakeLists.txtnew file+14
@@ -0,0 +1,14 @@
1+file(GLOB Indicators_QMLFILES
2+ *.qml
3+ qmldir
4+)
5+
6+# copy qml & qmldir files into build directory for shadow builds
7+add_custom_target(UnityIndicatorsQmlFiles ALL
8+ COMMAND cp ${Indicators_QMLFILES} ${CMAKE_BINARY_DIR}/plugins/Unity/Indicators
9+ DEPENDS ${Indicators_QMLFILES}
10+)
11+
12+install(FILES ${Indicators_QMLFILES}
13+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Unity/Indicators
14+)
plugins/Unity/Indicators/qml/DivMenuItem.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/Unity/Indicators/qml/HLine.qmlnew file+29
@@ -0,0 +1,29 @@
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 {
26+ left: parent.left
27+ right: parent.right
28+ }
29+}
plugins/Unity/Indicators/qml/IndicatorBase.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+ * Nick Dedekind <nick.dedekind@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import QMenuModel 0.1
23+import Unity.Indicators 0.1 as Indicators
24+
25+Item {
26+ id: indicatorItem
27+
28+ //const
29+ property string title
30+ property int busType
31+ property string busName
32+ property string actionsObjectPath
33+ property var menuObjectPaths: undefined
34+ readonly property string device: "phone"
35+
36+ property string deviceMenuObjectPath: menuObjectPaths.hasOwnProperty(device) ? menuObjectPaths[device] : ""
37+
38+ signal actionGroupUpdated()
39+ signal modelUpdated()
40+
41+ property var actionGroup: QDBusActionGroup {
42+ busType: indicatorItem.busType
43+ busName: indicatorItem.busName
44+ objectPath: indicatorItem.actionsObjectPath
45+
46+ onActionAppear: indicatorItem.actionGroupUpdated();
47+ }
48+
49+ property var proxyModel: Indicators.FlatMenuProxyModel {
50+ busType: indicatorItem.busType
51+ busName: indicatorItem.busName
52+ objectPath: indicatorItem.deviceMenuObjectPath
53+
54+ onStatusChanged: indicatorItem.modelUpdated();
55+ onRowsInserted: indicatorItem.modelUpdated();
56+ onRowsRemoved: indicatorItem.modelUpdated();
57+ onDataChanged: indicatorItem.modelUpdated();
58+ }
59+}
plugins/Unity/Indicators/qml/IndicatorPage.qmlnew file+197
@@ -0,0 +1,197 @@
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+import QtQuick 2.0
22+import Ubuntu.Components 0.1 as Components
23+
24+IndicatorBase {
25+ id: main
26+
27+ //const
28+ property alias emptyText: emptyLabel.text
29+ property alias highlightFollowsCurrentItem : mainMenu.highlightFollowsCurrentItem
30+ property bool __active: false
31+
32+ ListView {
33+ id: mainMenu
34+
35+ property int visibleItems: 0
36+
37+ model: proxyModel
38+ anchors {
39+ fill: parent
40+ bottomMargin: Qt.inputMethod.visible ? (Qt.inputMethod.keyboardRectangle.height - main.anchors.bottomMargin) : 0
41+
42+ Behavior on bottomMargin {
43+ NumberAnimation {
44+ duration: 175
45+ easing.type: Easing.OutQuad
46+ }
47+ }
48+ // TODO - does ever frame.
49+ onBottomMarginChanged: {
50+ mainMenu.positionViewAtIndex(mainMenu.currentIndex, ListView.End)
51+ }
52+ }
53+
54+ // Ensure all delegates are cached in order to improve smoothness of scrolling
55+ cacheBuffer: 10000
56+
57+ // Only allow flicking if the content doesn't fit on the page
58+ interactive: contentHeight > height
59+
60+ currentIndex: -1
61+ delegate: Item {
62+ id: item
63+ property bool ready: false
64+ property alias empty: factory.empty
65+
66+ anchors {
67+ left: parent.left
68+ right: parent.right
69+ }
70+ height: div.height + factory.implicitHeight
71+ visible: height > 0
72+
73+ Component.onCompleted: {
74+ if (!item.empty) {
75+ mainMenu.visibleItems += 1;
76+ }
77+ ready = true;
78+ }
79+ Component.onDestruction: {
80+ if (!item.empty) {
81+ mainMenu.visibleItems -= 1;
82+ }
83+ ready = false;
84+ }
85+
86+ onEmptyChanged: {
87+ if (!ready) {
88+ return;
89+ }
90+ if (empty) {
91+ mainMenu.visibleItems -= 1;
92+ } else {
93+ mainMenu.visibleItems += 1;
94+ }
95+ }
96+
97+ ListView.onRemove: {
98+ if (!highlightFollowsCurrentItem) {
99+ mainMenu.currentIndex = -1;
100+ }
101+ }
102+
103+ Column {
104+ id: contents
105+
106+ anchors.fill: parent
107+
108+ DivMenuItem {
109+ id: div
110+
111+ anchors.left: parent.left
112+ anchors.right: parent.right
113+ // only visible if is a root or a section header element and the factory is visible
114+ height: {
115+ // skipe first item
116+ if (item.y == 0) {
117+ return 0;
118+ }
119+ if (hasSection || ((depth == 0) && (!factory.empty))) {
120+ return implicitHeight;
121+ } else {
122+ return 0;
123+ }
124+ }
125+ }
126+
127+ MenuItemFactory {
128+ id: factory
129+
130+ actionGroup: main.actionGroup
131+ isCurrentItem: item.ListView.isCurrentItem
132+ anchors {
133+ left: parent.left
134+ right: parent.right
135+ }
136+ menu: model
137+
138+ Connections {
139+ target : factory
140+ onActivated: item.ListView.view.currentIndex = index
141+ onDeactivated: item.ListView.view.currentIndex = -1
142+ }
143+ }
144+ }
145+ }
146+ }
147+
148+ Components.Label {
149+ id: emptyLabel
150+ visible: (mainMenu.visibleItems === 0)
151+ anchors {
152+ top: parent.top
153+ left: parent.left
154+ right: parent.right
155+ topMargin: units.gu(2)
156+ }
157+ wrapMode: Text.WordWrap
158+ horizontalAlignment: Text.AlignHCenter
159+
160+ //style
161+ color: "#e8e1d0"
162+ fontSize: "medium"
163+
164+ text: "Empty!"
165+ }
166+
167+ function start()
168+ {
169+ reset()
170+ if (!__active) {
171+ proxyModel.start();
172+ actionGroup.start();
173+ __active = true;
174+ }
175+ }
176+
177+ function stop()
178+ {
179+ if (__active) {
180+ __active = false;
181+ proxyModel.stop();
182+ actionGroup.stop();
183+ }
184+ }
185+
186+ function reset()
187+ {
188+ mainMenu.currentIndex = -1;
189+ mainMenu.positionViewAtBeginning();
190+ }
191+
192+ Component.onCompleted: {
193+ if ((busType != 0) && (busName != "") && (deviceMenuObjectPath != "")) {
194+ start();
195+ }
196+ }
197+}
plugins/Unity/Indicators/qml/IndicatorWidget.qmlnew file+68
@@ -0,0 +1,68 @@
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+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Unity.Indicators 0.1 as Indicators
22+
23+IndicatorBase {
24+ id: indicatorWidget
25+
26+// enabled: false // FIXME : should be disabled until bus available when we have desktop indicators
27+ property var action: undefined
28+ property bool started: (busType != 0) && (busName != "") && (deviceMenuObjectPath != "")
29+ property int iconSize: height - units.gu(0.5)
30+ property string rootMenuType: "com.canonical.indicator.root"
31+
32+ signal actionStateChanged()
33+
34+ onStartedChanged: {
35+ if (started) {
36+ proxyModel.start();
37+ actionGroup.start();
38+ } else {
39+ proxyModel.stop();
40+ actionGroup.stop();
41+ }
42+ }
43+ onActionChanged: actionStateChanged()
44+ onActionGroupUpdated: update_state()
45+ onModelUpdated: update_state()
46+
47+
48+ function update_state() {
49+ var extra = proxyModel.data(0, Indicators.FlatMenuProxyModelRole.Extra);
50+ if (extra == undefined) {
51+ return;
52+ }
53+
54+ if (!extra.hasOwnProperty("canonical_type")) {
55+ return;
56+ }
57+
58+ if (extra.canonical_type === rootMenuType) {
59+ action = actionGroup.action(proxyModel.data(0, Indicators.FlatMenuProxyModelRole.Action));
60+ }
61+ }
62+
63+ Connections {
64+ target: action == undefined ? null : action
65+ onStateChanged: actionStateChanged()
66+ onValidChanged: actionStateChanged()
67+ }
68+}
plugins/Unity/Indicators/qml/MenuAction.qmlnew file+86
@@ -0,0 +1,86 @@
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 MenuAction
24+ \inqmlmodule Indicators 0.1
25+ \brief Helper class to connect to a qmenumodel action
26+
27+ Example:
28+ \qml
29+ Button {
30+ id: slide
31+ onClick: { action.activate() }
32+ }
33+ MenuAction {
34+ id: action
35+ actionGroup: menuItem.actionGroup
36+ action: "/ubuntu/sound/enabled"
37+ }
38+ \endqml
39+*/
40+
41+Item {
42+ id: menuAction
43+
44+ /*!
45+ \preliminary
46+ The dbus action name
47+ */
48+ property string action: ""
49+
50+ /*!
51+ \preliminary
52+ The dbus action group object
53+ */
54+ property QtObject actionGroup: null
55+
56+ /*!
57+ \preliminary
58+ This is a read-only property with the current validity of the action
59+ */
60+ readonly property bool valid: actionObject ? actionObject.valid : false
61+
62+ readonly property var state: actionObject ? actionObject.state : undefined
63+
64+ // internal
65+ property QtObject actionObject: null
66+
67+ function activate(param) {
68+ if (valid) {
69+ actionObject.activate(param);
70+ }
71+ }
72+
73+ onActionGroupChanged: updateAction()
74+ onActionChanged: updateAction()
75+
76+ Connections {
77+ target: menuAction.actionGroup != undefined ? menuAction.actionGroup : null
78+ onActionAppear: menuAction.updateAction();
79+ onActionVanish: menuAction.updateAction();
80+ onStatusChanged: menuAction.updateAction();
81+ }
82+
83+ function updateAction() {
84+ actionObject = action !== "" && actionGroup ? actionGroup.action(action) : null
85+ }
86+}
plugins/Unity/Indicators/qml/MenuActionBinding.qmlnew file+106
@@ -0,0 +1,106 @@
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 MenuActionBinding
24+ \inqmlmodule Indicators 0.1
25+ \brief Helper class to connect a qmenumodel action state with a qml components property
26+
27+ Example:
28+ \qml
29+ Slider {
30+ id: slide
31+ }
32+ MenuActionBinding {
33+ actionGroup: menuItem.actionGroup
34+ action: "/ubuntu/sound/volume"
35+ target: slider
36+ property: "value"
37+ }
38+ \endqml
39+*/
40+
41+MenuAction {
42+ id: menuAction
43+
44+ /*!
45+ \preliminary
46+ The component which will have the property changed by action
47+ */
48+ property QtObject target: null
49+
50+ /*!
51+ \preliminary
52+ The property name of \l target component which will be linked with action state
53+ */
54+ property string property
55+
56+ /*!
57+ \preliminary
58+ Use this to enable or disable the action state propagation to component property.
59+ */
60+ property bool active: true
61+
62+ Component.onCompleted: connectViewChanges()
63+ onTargetChanged: connectViewChanges()
64+ onPropertyChanged: connectViewChanges()
65+
66+ Item {
67+ id: d
68+ property var currentTarget: undefined
69+ property string currentSignal
70+ }
71+
72+ Binding {
73+ id: propertyBinding
74+ target: menuAction.target
75+ property: menuAction.property
76+ value: menuAction.state
77+ when: menuAction.actionObject && menuAction.active
78+ }
79+
80+ // TODO - re-evaluate in c++
81+ function connectViewChanges() {
82+ if (d.currentTarget != undefined && d.currentSignal !== "") {
83+ if (d.currentTarget[d.currentSignal] !== undefined) {
84+ d.currentTarget[d.currentSignal].disconnect(onViewValueChanged);
85+ }
86+ }
87+
88+ d.currentTarget = null;
89+ d.currentSignal = "";
90+ if (target) {
91+ var signal = "on%1Changed".arg(property.charAt(0).toUpperCase() + property.slice(1));
92+ if (target[signal] !== undefined) {
93+ target[signal].connect(onViewValueChanged);
94+ d.currentTarget = target;
95+ d.currentSignal = signal;
96+ }
97+ }
98+ }
99+
100+ function onViewValueChanged() {
101+ if (valid) {
102+ var propertyValue = target[property];
103+ actionObject.updateState(propertyValue);
104+ }
105+ }
106+}
plugins/Unity/Indicators/qml/MenuItem.qmlnew file+40
@@ -0,0 +1,40 @@
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+BasicMenuItem {
25+ objectName: menu ? menu.action : ""
26+ progression: menu && (menu.linkSubMenu !== undefined)
27+ text: menu && menu.label ? menu.label : ""
28+ color: "#221e1c"
29+ implicitHeight: units.gu(7)
30+
31+ HLine {
32+ anchors.top: parent.top
33+ color: "#403b37"
34+ }
35+
36+ HLine {
37+ anchors.bottom: parent.bottom
38+ color: "#060606"
39+ }
40+}
plugins/Unity/Indicators/qml/MenuItemFactory.qmlnew file+110
@@ -0,0 +1,110 @@
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+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Unity.Indicators 0.1 as Indicators
22+import Unity.Indicators.Messaging 0.1 as ICMessaging
23+import Unity.Indicators.Network 0.1 as ICNetwork
24+
25+Item {
26+ id: menuFactory
27+
28+ property QtObject menu
29+ property QtObject listView
30+ property QtObject actionGroup
31+ property bool isCurrentItem
32+ readonly property bool empty: (loader.item !== undefined && loader.status == Loader.Ready) ? loader.item.state === "EMPTY" : true
33+
34+ implicitHeight: loader.height
35+
36+ signal activated()
37+ signal deactivated()
38+
39+ property var _map: {
40+ "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
41+ "unity.widgets.systemsettings.tablet.switch" : switchMenu,
42+
43+ "com.canonical.indicator.button" : buttonMenu,
44+ "com.canonical.indicator.div" : divMenu,
45+ "com.canonical.indicator.section" : sectionMenu,
46+ "com.canonical.indicator.progress" : progressMenu,
47+ "com.canonical.indicator.slider" : sliderMenu,
48+ "com.canonical.indicator.switch" : switchMenu,
49+
50+ "com.canonical.indicator.messages.messageitem" : messageItem,
51+ "com.canonical.indicator.messages.snapdecision" : snapDecision,
52+ "com.canonical.indicator.messages.sourceitem" : groupedMessage,
53+
54+ "unity.widget.systemsettings.tablet.sectiontitle" : wifiSection,
55+ "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
56+ "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
57+ }
58+
59+ Component { id: sliderMenu; Indicators.SliderMenuItem {} }
60+ Component { id: switchMenu; Indicators.SwitchMenuItem {} }
61+ Component { id: buttonMenu; Indicators.ButtonMenuItem {} }
62+ Component { id: divMenu; Indicators.DivMenuItem {} }
63+ Component { id: sectionMenu; Indicators.SectionMenuItem {} }
64+ Component { id: progressMenu; Indicators.ProgressMenuItem {} }
65+ Component { id: messageItem; ICMessaging.MessageMenuItem {} }
66+ Component { id: snapDecision; ICMessaging.SnapDecision {} }
67+ Component { id: groupedMessage; ICMessaging.GroupedMessage {} }
68+ Component { id: wifiSection; ICNetwork.WifiSection {} }
69+ Component { id: accessPoint; ICNetwork.AccessPoint {} }
70+ Component { id: indicatorMenu; Indicators.MenuItem {} }
71+
72+ Loader {
73+ id: loader
74+ asynchronous: true
75+
76+ anchors {
77+ left: parent.left
78+ right: parent.right
79+ }
80+
81+ sourceComponent: {
82+ if (!menuFactory.menu || !menuFactory.menu.extra) {
83+ return undefined;
84+ }
85+
86+ var widgetType = menuFactory.menu.extra.canonical_type;
87+ if (widgetType) {
88+ return _map[widgetType];
89+ } else {
90+ if (widgetType === "com.canonical.indicator.root") {
91+ return undefined;
92+ // Try discovery the item based on the basic properties
93+ } else if (menu.hasSection) {
94+ return sectionMenu;
95+ } else {
96+ return indicatorMenu;
97+ }
98+ }
99+ }
100+
101+ onLoaded: {
102+ item.menuActivated = Qt.binding(function() { return isCurrentItem; });
103+ item.actionGroup = Qt.binding(function() { return menuFactory.actionGroup; });
104+ item.menu = Qt.binding(function() { return menuFactory.menu; });
105+
106+ item.activateMenu.connect(function() { menuFactory.activated(); });
107+ item.deactivateMenu.connect(function() { menuFactory.deactivated(); });
108+ }
109+ }
110+}
plugins/Unity/Indicators/qml/ProgressMenuItem.qmlnew 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+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+MenuItem {
24+ id: progressMenu
25+ property alias value : progressBar.value
26+
27+ // TODO: Replace this with the official ProgressBar component as soon as
28+ // it is available. For now, this rebuilds the Mockup as close as possible.
29+ UbuntuShape {
30+ id: progressBar
31+ anchors {
32+ right: parent.right
33+ rightMargin: units.gu(2)
34+ left: parent.left
35+ leftMargin: units.gu(2)
36+ }
37+ height: units.gu(4)
38+ anchors.verticalCenter: parent.verticalCenter
39+ color: "transparent"
40+
41+ property int minimumValue: 0
42+ property int maximumValue: 100
43+ property int value: 50
44+
45+ UbuntuShape {
46+ anchors.fill: parent
47+ anchors.rightMargin: parent.width - (parent.width * parent.value / parent.maximumValue)
48+ color: "#c94212"
49+ }
50+
51+ Label {
52+ anchors.centerIn: parent
53+ text: parent.value + " %"
54+ fontSize: "medium"
55+ color: "#e8e1d0"
56+ }
57+ }
58+
59+ MenuActionBinding {
60+ actionGroup: progressMenu.actionGroup
61+ action: menu ? menu.action : ""
62+ target: progressBar
63+ property: "value"
64+ }
65+}
plugins/Unity/Indicators/qml/RemoveBackground.qmlnew file+55
@@ -0,0 +1,55 @@
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+ anchors.fill: parent
22+ color: "#333130"
23+ Label {
24+ id: backgroundText
25+
26+ anchors.fill: parent
27+ verticalAlignment: Text.AlignVCenter
28+ text: "Clear"
29+ fontSize: "medium"
30+ color: "#e8e1d0"
31+ font.bold: true
32+ }
33+
34+ states: [
35+ State {
36+ name: "SwipingRight"
37+ PropertyChanges {
38+ target: backgroundText
39+ anchors.rightMargin: units.gu(3)
40+ anchors.leftMargin: 0
41+ horizontalAlignment: Text.AlignRight
42+
43+ }
44+ },
45+ State {
46+ name: "SwipingLeft"
47+ PropertyChanges {
48+ target: backgroundText
49+ anchors.rightMargin: 0
50+ anchors.leftMargin: units.gu(3)
51+ horizontalAlignment: Text.AlignLeft
52+ }
53+ }
54+ ]
55+}
plugins/Unity/Indicators/qml/SectionMenuItem.qmlnew file+57
@@ -0,0 +1,57 @@
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+BasicMenuItem {
25+ property string label: menu && menu.label ? menu.label : ""
26+ property bool busy: false
27+ property int count: menu && menu.linkSection ? menu.linkSection.count : 0
28+
29+ color: "#221e1b"
30+ implicitHeight: label !== "" ? __header.height : 0
31+ state: count === 0 ? "EMPTY" : ""
32+
33+ ListItem.Header {
34+ id: __header
35+
36+ text: label
37+ height: units.gu(4)
38+ anchors {
39+ left: parent.left
40+ right: parent.right
41+ top: parent.top
42+ }
43+ visible: text != ""
44+
45+ ActivityIndicator {
46+ id: indicator
47+ running: busy
48+ anchors {
49+ margins: units.gu(0.5)
50+ right: parent.right
51+ }
52+ height: parent.height - (anchors.margins * 2)
53+ width: height
54+ anchors.verticalCenter: parent.verticalCenter
55+ }
56+ }
57+}
plugins/Unity/Indicators/qml/SliderMenuItem.qmlnew file+64
@@ -0,0 +1,64 @@
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+MenuItem {
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+ enabled: menuAction.valid
33+ width: _sliderMenu.text ? units.gu(20) : _sliderMenu.width - units.gu(4)
34+ anchors.verticalCenter: parent.verticalCenter
35+ live: false
36+ // FIXME: The interval should be [0.0 - 1.0]. Unfortunately, when
37+ // reaching the boundaries (0.0 or 1.0), the value is converted
38+ // to an integer when automatically wrapped in a variant when
39+ // passed to QStateAction::updateState(…). The server chokes on
40+ // those values, complaining that they’re not of the right type…
41+ minimumValue: menu.extra.canonical_min ? menu.extra.canonical_min * 1.000001 : 0.0000001
42+ maximumValue: {
43+ var maximum = menu.extra.canonical_max ? menu.extra.canonical_max * 1.000001 : 0.9999999
44+ if (maximum <= minimumValue) {
45+ return minimumValue + 1;
46+ }
47+ return maximum;
48+ }
49+
50+ // FIXME - to be deprecated in Ubuntu.Components.
51+ // Use this to disable the label, since there is not way to do it on the component.
52+ function formatValue(v) {
53+ return "";
54+ }
55+ }
56+
57+ MenuActionBinding {
58+ id: menuAction
59+ actionGroup: _sliderMenu.actionGroup
60+ action: menu ? menu.action : ""
61+ target: slider
62+ property: "value"
63+ }
64+}
plugins/Unity/Indicators/qml/SwitchMenuItem.qmlnew file+43
@@ -0,0 +1,43 @@
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+MenuItem {
24+ id: switchMenu
25+
26+ property alias checked: switcher.checked
27+
28+ control: Switch {
29+ id: switcher
30+ enabled: menuAction.valid
31+
32+ anchors.verticalCenter: parent.verticalCenter
33+ anchors.right: parent.right
34+ }
35+
36+ MenuActionBinding {
37+ id: menuAction
38+ actionGroup: switchMenu.actionGroup
39+ action: menu ? menu.action : ""
40+ target: switcher
41+ property: "checked"
42+ }
43+}
plugins/Unity/Indicators/qml/qmldirnew file+20
@@ -0,0 +1,20 @@
1+module Unity.Indicators
2+plugin IndicatorsQml
3+
4+BasicMenuItem 0.1 BasicMenuItem.qml
5+ButtonMenuItem 0.1 ButtonMenuItem.qml
6+DivMenuItem 0.1 DivMenuItem.qml
7+HLine 0.1 HLine.qml
8+IndicatorBase 0.1 IndicatorBase.qml
9+IndicatorPage 0.1 IndicatorPage.qml
10+IndicatorWidget 0.1 IndicatorWidget.qml
11+MenuItem 0.1 MenuItem.qml
12+MenuAction 0.1 MenuAction.qml
13+MenuActionBinding 0.1 MenuActionBinding.qml
14+MenuItemFactory 0.1 MenuItemFactory.qml
15+ProgressMenuItem 0.1 ProgressMenuItem.qml
16+SectionMenuItem 0.1 SectionMenuItem.qml
17+SliderMenuItem 0.1 SliderMenuItem.qml
18+SwitchMenuItem 0.1 SwitchMenuItem.qml
19+
20+internal RemoveBackground RemoveBackground.qml
plugins/Unity/Indicators/resources/artwork/messaging/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/Unity/Indicators/resources/artwork/messaging/default_contact.pngnew file

Binary file not shown.

plugins/Unity/Indicators/resources/artwork/messaging/message_sms01_54px.pngnew file

Binary file not shown.

plugins/Unity/Indicators/resources/indicators.qrcnew file+7
@@ -0,0 +1,7 @@
1+<RCC>
2+ <qresource prefix="/indicators">
3+ <file>artwork/messaging/default_contact.png</file>
4+ <file>artwork/messaging/default_app.svg</file>
5+ <file>artwork/messaging/message_sms01_54px.png</file>
6+ </qresource>
7+</RCC>
plugins/Utils/CMakeLists.txt+1
@@ -5,6 +5,7 @@ include_directories(
5)
5)
6
6
7set(QMLPLUGIN_SRC
7set(QMLPLUGIN_SRC
8+ applicationpaths.h
8 qlimitproxymodelqml.cpp
9 qlimitproxymodelqml.cpp
9 qsortfilterproxymodelqml.cpp
10 qsortfilterproxymodelqml.cpp
10 ubuntuwindow.cpp
11 ubuntuwindow.cpp
plugins/Utils/applicationpaths.hnew file+38
@@ -0,0 +1,38 @@
1+/*
2+ * Copyright (C) 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 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+ * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+
20+#ifndef APPLICATION_PATHS_H
21+#define APPLICATION_PATHS_H
22+
23+#include <QObject>
24+#include "paths.h"
25+
26+class ApplicationPaths : public QObject
27+{
28+ Q_OBJECT
29+public:
30+ Q_INVOKABLE bool isRunningInstalled() const { return ::isRunningInstalled(); }
31+ Q_INVOKABLE QString shellAppDirectory() const { return ::shellAppDirectory(); }
32+ Q_INVOKABLE QStringList overrideImportPaths() const { return ::overrideImportPaths(); }
33+ Q_INVOKABLE QStringList fallbackImportPaths() const { return ::fallbackImportPaths(); }
34+ Q_INVOKABLE QStringList shellDataDirs() const { return ::shellDataDirs(); }
35+ Q_INVOKABLE QString sourceDirectory() const { return ::sourceDirectory(); }
36+};
37+
38+#endif // APPLICATION_PATHS_H
plugins/Utils/plugin.cpp+8
@@ -24,10 +24,17 @@
24#include "plugin.h"
24#include "plugin.h"
25
25
26// local
26// local
27+#include "applicationpaths.h"
27#include "qlimitproxymodelqml.h"
28#include "qlimitproxymodelqml.h"
28#include "qsortfilterproxymodelqml.h"
29#include "qsortfilterproxymodelqml.h"
29#include "ubuntuwindow.h"
30#include "ubuntuwindow.h"
30
31
32+static QObject* applicationsPathsSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
33+ Q_UNUSED(engine);
34+ Q_UNUSED(scriptEngine);
35+ return new ApplicationPaths;
36+}
37+
31void UtilsPlugin::registerTypes(const char *uri)
38void UtilsPlugin::registerTypes(const char *uri)
32{
39{
33 Q_ASSERT(uri == QLatin1String("Utils"));
40 Q_ASSERT(uri == QLatin1String("Utils"));
@@ -35,4 +42,5 @@ void UtilsPlugin::registerTypes(const char *uri)
35 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
42 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
36 qmlRegisterType<QSortFilterProxyModelQML>(uri, 0, 1, "SortFilterProxyModel");
43 qmlRegisterType<QSortFilterProxyModelQML>(uri, 0, 1, "SortFilterProxyModel");
37 qmlRegisterExtendedType<QQuickWindow, UbuntuWindow>(uri, 0, 1, "Window");
44 qmlRegisterExtendedType<QQuickWindow, UbuntuWindow>(uri, 0, 1, "Window");
45+ qmlRegisterSingletonType<ApplicationPaths>(uri, 0, 1, "ApplicationPaths", applicationsPathsSingleton);
38}
46}
run+3−3
@@ -40,17 +40,17 @@ do
40done
40done
41
41
42if $FAKE; then
42if $FAKE; then
43− export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins
43+ export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins:$PWD/builddir/modules
44 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single
44 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single
45fi
45fi
46
46
47if $PINLOCK; then
47if $PINLOCK; then
48− export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins
48+ export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins:$PWD/builddir/modules
49 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single-pin
49 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single-pin
50fi
50fi
51
51
52if $KEYLOCK; then
52if $KEYLOCK; then
53− export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins
53+ export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins:$PWD/builddir/modules
54 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single-passphrase
54 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single-passphrase
55fi
55fi
56
56
src/CMakeLists.txtnew file+1
@@ -0,0 +1 @@
1+add_subdirectory(Panel)
src/Panel/CMakeLists.txtnew file+1
@@ -0,0 +1 @@
1+add_subdirectory(Indicators)
src/Panel/Indicators/CMakeLists.txtnew file+2
@@ -0,0 +1,2 @@
1+add_subdirectory(client)
2+add_subdirectory(servicefiles)
src/Panel/Indicators/client/CMakeLists.txtnew file+25
@@ -0,0 +1,25 @@
1+project(indicators_client)
2+set(INDICATORS_CLIENT_APP indicators-client)
3+
4+set(INDICATORS_CLIENT_SRC
5+ main.cpp
6+ indicatorsclient.cpp
7+)
8+
9+set(INDICATORS_CLIENT_HEADERS
10+ indicatorsclient.h
11+)
12+add_executable(${INDICATORS_CLIENT_APP}
13+ ${INDICATORS_CLIENT_SRC}
14+ ${INDICATORS_CLIENT_HEADERS}
15+)
16+
17+include_directories(
18+ ${CMAKE_BINARY_DIR}
19+)
20+
21+qt5_use_modules(${INDICATORS_CLIENT_APP} Core Widgets Quick)
22+set_target_properties(${INDICATORS_CLIENT_APP} PROPERTIES COMPILE_FLAGS -fPIC)
23+
24+install(TARGETS ${INDICATORS_CLIENT_APP}
25+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
src/Panel/Indicators/client/indicatorsclient.cppnew file+99
@@ -0,0 +1,99 @@
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+#include "indicatorsclient.h"
22+#include "paths.h"
23+
24+#include <QQuickView>
25+#include <QQmlContext>
26+#include <QQmlEngine>
27+#include <QDebug>
28+
29+void prependImportPaths(QQmlEngine *engine, const QStringList &paths)
30+{
31+ QStringList importPathList = engine->importPathList();
32+ for (int i = paths.count()-1; i >= 0; i--) {
33+ importPathList.prepend(paths[i]);
34+ }
35+ engine->setImportPathList(importPathList);
36+}
37+
38+/* When you append and import path to the list of import paths it will be the *last*
39+ place where Qt will search for QML modules.
40+ The usual QQmlEngine::addImportPath() actually prepends the given path.*/
41+void appendImportPaths(QQmlEngine *engine, const QStringList &paths)
42+{
43+ QStringList importPathList = engine->importPathList();
44+ Q_FOREACH(const QString& path, paths) {
45+ // don't duplicate
46+ QStringList::iterator iter = qFind(importPathList.begin(), importPathList.end(), path);
47+ if (iter == importPathList.end()) {
48+ importPathList.append(path);
49+ }
50+ }
51+ engine->setImportPathList(importPathList);
52+}
53+
54+IndicatorsClient::IndicatorsClient(int &argc, char **argv)
55+ : QObject(0),
56+ m_view(0)
57+{
58+ m_application = new QApplication(argc, argv);
59+ QStringList args = m_application->arguments();
60+
61+ m_view = new QQuickView;
62+ m_view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory()+"Panel/Indicators/client/"));
63+ prependImportPaths(m_view->engine(), ::overrideImportPaths());
64+ appendImportPaths(m_view->engine(), ::fallbackImportPaths());
65+
66+ m_view->setSource(QUrl("IndicatorsClient.qml"));
67+ m_view->setResizeMode(QQuickView::SizeRootObjectToView);
68+
69+ if (args.contains(QLatin1String("-geometry")) && args.size() > args.indexOf(QLatin1String("-geometry")) + 1) {
70+ QStringList geometryArg = args.at(args.indexOf(QLatin1String("-geometry")) + 1).split('x');
71+ if (geometryArg.size() == 2) {
72+ m_view->resize(geometryArg.at(0).toInt(), geometryArg.at(1).toInt());
73+ }
74+ }
75+ else {
76+ //Usable size on desktop
77+ m_view->setMinimumSize(QSize(480, 720));
78+ }
79+}
80+
81+IndicatorsClient::~IndicatorsClient()
82+{
83+ if (m_view != 0) {
84+ delete m_view;
85+ }
86+
87+ delete m_application;
88+}
89+
90+void IndicatorsClient::setupUI()
91+{
92+
93+}
94+
95+int IndicatorsClient::run()
96+{
97+ m_view->show();
98+ return m_application->exec();
99+}
src/Panel/Indicators/client/indicatorsclient.hnew file+45
@@ -0,0 +1,45 @@
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 INDICATORS_CLIENT_H
22+#define INDICATORS_CLIENT_H
23+
24+#include <QApplication>
25+#include <QQuickView>
26+
27+class PluginManager;
28+
29+class IndicatorsClient : public QObject
30+{
31+ Q_OBJECT
32+public:
33+ IndicatorsClient(int &argc, char **argv);
34+ ~IndicatorsClient();
35+
36+ int run();
37+
38+private:
39+ QApplication *m_application;
40+ QQuickView *m_view;
41+
42+ void setupUI();
43+};
44+
45+#endif
src/Panel/Indicators/client/main.cppnew 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+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ */
19+
20+#include "indicatorsclient.h"
21+
22+int main(int argc, char** argv)
23+{
24+ IndicatorsClient client(argc, argv);
25+ return client.run();
26+}
src/Panel/Indicators/servicefiles/CMakeLists.txtnew file+18
@@ -0,0 +1,18 @@
1+file(GLOB INDICATOR_SERVICE_FILES
2+ ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.indicator.battery
3+ ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.indicator.messages
4+ ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.indicator.time
5+ ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.settings.network
6+ ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.settings.sound
7+)
8+
9+# copy indicators files into build directory for shadow builds
10+add_custom_target(IndicatorsServiceFiles ALL
11+ COMMAND mkdir -p ${CMAKE_BINARY_DIR}/share/unity/indicators
12+ COMMAND cp ${INDICATOR_SERVICE_FILES} ${CMAKE_BINARY_DIR}/share/unity/indicators
13+ DEPENDS ${INDICATOR_SERVICE_FILES}
14+)
15+
16+install(FILES ${INDICATOR_SERVICE_FILES}
17+ DESTINATION ${SHELL_APP_DIR}/unity/indicators
18+)
src/Panel/Indicators/servicefiles/com.canonical.indicator.batterynew file+9
@@ -0,0 +1,9 @@
1+[Indicator Service]
2+Name=indicator-battery
3+ObjectPath=/com/canonical/indicator/battery
4+
5+[phone]
6+ObjectPath=/com/canonical/indicator/battery/phone
7+
8+[desktop]
9+ObjectPath=/com/canonical/indicator/battery/phone
src/Panel/Indicators/servicefiles/com.canonical.indicator.messagesnew file+9
@@ -0,0 +1,9 @@
1+[Indicator Service]
2+Name=indicator-messaging
3+ObjectPath=/com/canonical/indicator/messages
4+
5+[phone]
6+ObjectPath=/com/canonical/indicator/messages/phone
7+
8+[desktop]
9+ObjectPath=/com/canonical/indicator/messages/menu
src/Panel/Indicators/servicefiles/com.canonical.indicator.timenew file+9
@@ -0,0 +1,9 @@
1+[Indicator Service]
2+Name=indicator-time
3+ObjectPath=/com/canonical/indicator/time
4+
5+[phone]
6+ObjectPath=/com/canonical/indicator/time/phone
7+
8+[desktop]
9+ObjectPath=/com/canonical/indicator/time/desktop
src/Panel/Indicators/servicefiles/com.canonical.settings.networknew file+9
@@ -0,0 +1,9 @@
1+[Indicator Service]
2+Name=indicator-network
3+ObjectPath=/com/canonical/settings/network
4+
5+[phone]
6+ObjectPath=/com/canonical/settings/network/phone
7+
8+[desktop]
9+ObjectPath=/com/canonical/settings/network/desktop
src/Panel/Indicators/servicefiles/com.canonical.settings.soundnew file+9
@@ -0,0 +1,9 @@
1+[Indicator Service]
2+Name=indicator-sound
3+ObjectPath=/com/canonical/settings/sound
4+
5+[phone]
6+ObjectPath=/com/canonical/settings/sound/phone
7+
8+[desktop]
9+ObjectPath=/com/canonical/settings/sound/desktop
tests/autopilot/unity8/indicators_client/__init__.pynew file+8
@@ -0,0 +1,8 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+# Copyright 2013 Canonical
3+#
4+# This program is free software: you can redistribute it and/or modify it
5+# under the terms of the GNU General Public License version 3, as published
6+# by the Free Software Foundation.
7+
8+"""unity8 indicators-client autopilot tests and emulators - sub level package."""
tests/autopilot/unity8/indicators_client/emulators/__init__.pynew file+31
@@ -0,0 +1,31 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+# Copyright 2013 Canonical
3+#
4+# This program is free software: you can redistribute it and/or modify it
5+# under the terms of the GNU General Public License version 3, as published
6+# by the Free Software Foundation.
7+
8+from autopilot.introspection.dbus import DBusIntrospectionObject
9+from autopilot.input import Mouse, Touch, Pointer
10+from autopilot.platform import model
11+
12+from time import sleep
13+
14+from autopilot.introspection.dbus import IntrospectableObjectMetaclass
15+
16+class IndicatorsIntrospectionObject(DBusIntrospectionObject):
17+
18+ """A common class that provides introspection and other helpers to indictors."""
19+
20+ if model() == 'Desktop':
21+ scenarios = [
22+ ('with mouse', dict(input_device_class=Mouse)),
23+ ]
24+ else:
25+ scenarios = [
26+ ('with touch', dict(input_device_class=Touch)),
27+ ]
28+
29+ def setUp(self):
30+ self.pointing_device = Pointer(self.input_device_class.create())
31+ super(IndicatorsTestCase, self).setUp()
tests/autopilot/unity8/indicators_client/emulators/common.pynew file+14
@@ -0,0 +1,14 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+# Copyright 2013 Canonical
3+#
4+# This program is free software: you can redistribute it and/or modify it
5+# under the terms of the GNU General Public License version 3, as published
6+# by the Free Software Foundation.
7+
8+from indicators_client.emulators import IndicatorsIntrospectionObject
9+
10+class SwitchMenu(IndicatorsIntrospectionObject):
11+ """A switch menu control."""
12+
13+class Switch(IndicatorsIntrospectionObject):
14+ """A switch control."""
tests/autopilot/unity8/indicators_client/emulators/main_window.pynew file+27
@@ -0,0 +1,27 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+# Copyright 2013 Canonical
3+#
4+# This program is free software: you can redistribute it and/or modify it
5+# under the terms of the GNU General Public License version 3, as published
6+# by the Free Software Foundation.
7+
8+class MainWindow(object):
9+ """An emulator class that makes it easy to interact with the shell"""
10+
11+ def __init__(self, app):
12+ self.app = app
13+
14+ def get_qml_view(self):
15+ """Get the main QML view"""
16+ return self.app.select_single("QQuickView")
17+
18+ def get_indicators_client(self):
19+ return self.app.select_single("IndicatorsClient")
20+
21+ def get_page_stack(self):
22+ """Get the page stack"""
23+ return self.app.select_single("PageStack")
24+
25+ def get_battery_menu(self):
26+ """Get the battery menu from the list"""
27+ return self.app.select_single("BasicMenuItem", objectName="indicator-battery");
tests/autopilot/unity8/indicators_client/tests/__init__.pynew file+87
@@ -0,0 +1,87 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+# Copyright 2013 Canonical
3+#
4+# This program is free software: you can redistribute it and/or modify it
5+# under the terms of the GNU General Public License version 3, as published
6+# by the Free Software Foundation.
7+
8+"""qml-phone-shell autopilot tests."""
9+
10+import os.path
11+
12+from autopilot.input import Mouse, Touch, Pointer
13+from autopilot.testcase import AutopilotTestCase
14+from autopilot.matchers import Eventually
15+from autopilot.platform import model
16+from testtools.matchers import Equals
17+
18+from unity8.indicators_client.emulators.main_window import MainWindow
19+from logging import getLogger
20+import sys
21+from time import sleep
22+
23+log = getLogger(__name__)
24+
25+class FormFactors(object):
26+ Phone, Tablet, Desktop = range(3)
27+
28+class IndicatorsTestCase(AutopilotTestCase):
29+
30+ """A common test case class that provides several useful methods for indicator tests."""
31+
32+ if model() == 'Desktop':
33+ scenarios = [
34+ ('with mouse', dict(input_device_class=Mouse)),
35+ ]
36+ else:
37+ scenarios = [
38+ ('with touch', dict(input_device_class=Touch)),
39+ ]
40+
41+ def setUp(self, geometry, grid_size):
42+ self.pointing_device = Pointer(self.input_device_class.create())
43+ super(IndicatorsTestCase, self).setUp()
44+ if grid_size != "0":
45+ os.environ['GRID_UNIT_PX'] = grid_size
46+ self.grid_size = int(grid_size)
47+ else:
48+ self.grid_size = int(os.environ['GRID_UNIT_PX'])
49+
50+ if os.path.realpath(__file__).startswith("/usr/"):
51+ self.launch_test_installed(geometry)
52+ else:
53+ self.launch_test_local(geometry)
54+
55+ def launch_test_local(self, geometry):
56+ if geometry != "0x0":
57+ self.app = self.launch_test_application("../../builddir/src/Panel/Indicators/client/indicators-client",
58+ "-geometry", geometry, app_type='qt')
59+ else:
60+ self.app = self.launch_test_application("../../builddir/src/Panel/Indicators/client/indicators-client",
61+ app_type='qt')
62+
63+ def launch_test_installed(self, geometry):
64+ if geometry != "0x0":
65+ self.app = self.launch_test_application("indicators-client", "-geometry", geometry, app_type='qt')
66+ else:
67+ self.app = self.launch_test_application("indicators-client", app_type='qt')
68+
69+ def skipWrapper(*args, **kwargs):
70+ pass
71+
72+ def form_factor(self):
73+ return FormFactors.Desktop
74+
75+ def __getattribute__(self, attr_name):
76+ attr = object.__getattribute__(self, attr_name);
77+ if attr_name.startswith("test_"):
78+ try:
79+ if self.form_factor() in attr.blacklist:
80+ return self.skipWrapper
81+ except:
82+ pass
83+ return attr
84+
85+ @property
86+ def main_window(self):
87+ return MainWindow(self.app)
tests/autopilot/unity8/indicators_client/tests/test_battery.pynew file+99
@@ -0,0 +1,99 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+# Copyright 2013 Canonical
3+#
4+# This program is free software: you can redistribute it and/or modify it
5+# under the terms of the GNU General Public License version 3, as published
6+# by the Free Software Foundation.
7+
8+"""Add tests here if you want to ensure the behaviour of the power indicator menus are correct"""
9+
10+from testtools.matchers import Equals, NotEquals
11+from autopilot.matchers import Eventually
12+
13+from unity8.indicators_client.tests import IndicatorsTestCase
14+from time import sleep
15+import random
16+import math
17+
18+class TestDisplayMenus(IndicatorsTestCase):
19+ def setUp(self):
20+ super(TestDisplayMenus, self).setUp("400x800", "12")
21+
22+ # This opens the messaging menu so you don't have to do that in
23+ # every test case
24+ self.assertThat(lambda: self.main_window.get_battery_menu(), Eventually(NotEquals(None)));
25+ self.pointing_device.move_to_object(self.main_window.get_battery_menu())
26+ self.pointing_device.click()
27+
28+ fn_loader = lambda: self.app.select_single("IndicatorsPage/QQuickLoader", objectName="page_loader");
29+ self.assertThat(fn_loader, Eventually(NotEquals(None)));
30+ page_loader = fn_loader();
31+ self.assertThat(page_loader.progress, Eventually(Equals(1.0)))
32+
33+ def tearDown(self):
34+ # self.main_window.get_indicators_client().reset()
35+ super(TestDisplayMenus, self).tearDown()
36+
37+ # START SECTION
38+ # We need to move these to emulators once autopilot supports emulators for
39+ # applications started with AutopilotTestCase.launch_test_application
40+
41+ def switch_auto_brightness(self, auto_brightness):
42+ ab_switch = auto_brightness.select_single("CheckBox");
43+ self.assertThat(ab_switch, NotEquals(None))
44+
45+ self.pointing_device.move_to_object(ab_switch)
46+ self.pointing_device.click()
47+
48+ def set_brightness_to_value(self, brightness_menu, new_value):
49+ brightness_slider = brightness_menu.select_single("Slider");
50+ self.assertThat(brightness_slider, NotEquals(None))
51+
52+ self.pointing_device.move_to_object(brightness_slider)
53+
54+ old_ab_value = brightness_slider.value
55+ pixel_ratio = brightness_slider.width / (brightness_slider.maximumValue - brightness_slider.minimumValue)
56+
57+ while True:
58+
59+ pixels_to_move = int(pixel_ratio * (new_value - old_ab_value) / 15)
60+ if pixels_to_move == 0:
61+ break;
62+
63+ self.pointing_device.drag(self.pointing_device.x, self.pointing_device.y, self.pointing_device.x + pixels_to_move, self.pointing_device.y)
64+
65+ old_ab_value = brightness_slider.value
66+
67+ def test_auto_bright_switch(self):
68+ """Test the auto-bright switch"""
69+
70+ # wait for the switch menu item
71+ fn_auto_brightness = lambda: self.app.select_single("SwitchMenuItem", objectName="auto-brightness");
72+ self.assertThat(fn_auto_brightness, Eventually(NotEquals(None)));
73+ auto_brightness = fn_auto_brightness();
74+
75+ old_ab_value = auto_brightness.checked
76+
77+ self.switch_auto_brightness(auto_brightness)
78+
79+ # TODO - should check backend when it's introspectable.
80+ self.assertThat(auto_brightness.checked, Eventually(NotEquals(old_ab_value)))
81+
82+ def test_brightness_slider(self):
83+ """Test the auto-bright switch"""
84+
85+ fn_brightness_menu = lambda: self.app.select_single("SliderMenuItem", objectName="brightness");
86+ self.assertThat(fn_brightness_menu, Eventually(NotEquals(None)));
87+ brightness_menu = fn_brightness_menu();
88+
89+ old_ab_value = brightness_menu.value
90+ # find a new value to do to. At least 1/4 distance away from current value
91+ while True:
92+ desired_value = random.uniform(brightness_menu.minimumValue, brightness_menu.maximumValue)
93+ if (abs(desired_value - old_ab_value) >= (brightness_menu.maximumValue - brightness_menu.minimumValue)/4):
94+ break;
95+
96+ self.set_brightness_to_value(brightness_menu, desired_value)
97+
98+ # TODO - should check backend when it's introspectable.
99+ self.assertThat(brightness_menu.value, Eventually(NotEquals(old_ab_value)))
tests/autopilot/unity8/shell/__init__.pynew file+8
@@ -0,0 +1,8 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+# Copyright 2013 Canonical
3+#
4+# This program is free software: you can redistribute it and/or modify it
5+# under the terms of the GNU General Public License version 3, as published
6+# by the Free Software Foundation.
7+
8+"""unity8 shell autopilot tests and emulators - sub level package."""
tests/autopilot/unity8/emulators/__init__.py → tests/autopilot/unity8/shell/emulators/__init__.pyrenamed

The content is the same.

tests/autopilot/unity8/emulators/main_window.py → tests/autopilot/unity8/shell/emulators/main_window.pyrenamed

The content is the same.

tests/autopilot/unity8/tests/__init__.py → tests/autopilot/unity8/shell/tests/__init__.pyrenamed+1−1
@@ -15,7 +15,7 @@ from autopilot.matchers import Eventually
15from autopilot.platform import model
15from autopilot.platform import model
16from testtools.matchers import Equals
16from testtools.matchers import Equals
17
17
18−from unity8.emulators.main_window import MainWindow
18+from unity8.shell.emulators.main_window import MainWindow
19
19
20class FormFactors(object):
20class FormFactors(object):
21 Phone, Tablet, Desktop = range(3)
21 Phone, Tablet, Desktop = range(3)
tests/autopilot/unity8/tests/helpers.py → tests/autopilot/unity8/shell/tests/helpers.pyrenamed

The content is the same.

tests/autopilot/unity8/tests/testbigscreen.py → tests/autopilot/unity8/shell/tests/testbigscreen.pyrenamed+1−1
@@ -10,7 +10,7 @@
10from testtools.matchers import Equals
10from testtools.matchers import Equals
11from autopilot.matchers import Eventually
11from autopilot.matchers import Eventually
12
12
13−from unity8.tests import ShellTestCase
13+from unity8.shell.tests import ShellTestCase
14
14
15class TestBig(ShellTestCase):
15class TestBig(ShellTestCase):
16 def setUp(self):
16 def setUp(self):
tests/autopilot/unity8/tests/testhud.py → tests/autopilot/unity8/shell/tests/testhud.pyrenamed+2−2
@@ -25,8 +25,8 @@
25
25
26from __future__ import absolute_import
26from __future__ import absolute_import
27
27
28−from unity8.tests import ShellTestCase, FormFactors
28+from unity8.shell.tests import ShellTestCase, FormFactors
29−from unity8.tests.helpers import TestShellHelpers
29+from unity8.shell.tests.helpers import TestShellHelpers
30
30
31from autopilot.input import Mouse, Touch, Pointer
31from autopilot.input import Mouse, Touch, Pointer
32from testtools.matchers import Equals, NotEquals, GreaterThan, MismatchError
32from testtools.matchers import Equals, NotEquals, GreaterThan, MismatchError
tests/autopilot/unity8/tests/testlockscreen.py → tests/autopilot/unity8/shell/tests/testlockscreen.pyrenamed+2−2
@@ -25,8 +25,8 @@
25
25
26from __future__ import absolute_import
26from __future__ import absolute_import
27
27
28−from unity8.tests import ShellTestCase, FormFactors
28+from unity8.shell.tests import ShellTestCase, FormFactors
29−from unity8.tests.helpers import TestShellHelpers
29+from unity8.shell.tests.helpers import TestShellHelpers
30
30
31from autopilot.input import Mouse, Touch, Pointer
31from autopilot.input import Mouse, Touch, Pointer
32from testtools.matchers import Equals, NotEquals, GreaterThan, MismatchError
32from testtools.matchers import Equals, NotEquals, GreaterThan, MismatchError
tests/data/unity/indicators/com.canonical.indicator.fake1new file+9
@@ -0,0 +1,9 @@
1+[Indicator Service]
2+Name=indicator-fake1
3+ObjectPath=/com/canonical/indicator/fake1
4+
5+[phone]
6+ObjectPath=/com/canonical/indicator/fake1/phone
7+
8+[desktop]
9+ObjectPath=/com/canonical/indicator/fake1/desktop
tests/data/unity/indicators/com.canonical.indicator.fake2new file+9
@@ -0,0 +1,9 @@
1+[Indicator Service]
2+Name=indicator-fake2
3+ObjectPath=/com/canonical/indicator/fake2
4+
5+[phone]
6+ObjectPath=/com/canonical/indicator/fake2/phone
7+
8+[desktop]
9+ObjectPath=/com/canonical/indicator/fake2/desktop
tests/data/unity/indicators/com.canonical.indicator.fake3new file+9
@@ -0,0 +1,9 @@
1+[Indicator Service]
2+Name=indicator-fake3
3+ObjectPath=/com/canonical/indicator/fake3
4+
5+[phone]
6+ObjectPath=/com/canonical/indicator/fake3/phone
7+
8+[desktop]
9+ObjectPath=/com/canonical/indicator/fake3/desktop
tests/data/unity/indicators/com.canonical.indicator.fake4new file+9
@@ -0,0 +1,9 @@
1+[Indicator Service]
2+Name=indicator-fake4
3+ObjectPath=/com/canonical/indicator/fake4
4+
5+[phone]
6+ObjectPath=/com/canonical/indicator/fake4/phone
7+
8+[desktop]
9+ObjectPath=/com/canonical/indicator/fake4/desktop
tests/mocks/Ubuntu/CMakeLists.txt−1
@@ -1,2 +1 @@
1add_subdirectory(Application)
1add_subdirectory(Application)
2−add_subdirectory(ChewieUI)
tests/mocks/Ubuntu/ChewieUI/CMakeLists.txtdeleted−33
@@ -1,33 +0,0 @@
1−set(CMAKE_AUTOMOC ON)
2−
3−include(FindPkgConfig)
4−find_package(Qt5Core REQUIRED)
5−find_package(Qt5Quick REQUIRED)
6−
7−set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wextra -std=c++11")
8−
9−include_directories(
10− ${CMAKE_CURRENT_BINARY_DIR}
11− ${Qt5Core_INCLUDE_DIRS}
12− ${Qt5Quick_INCLUDE_DIRS}
13−)
14−
15−add_definitions(-DQT_NO_KEYWORDS)
16−
17−set(ChewieUIQML_SOURCES
18− fake_chewie_plugin.cpp
19− fake_pluginmodel.cpp
20−)
21−
22−add_library(FakeChewieUIQml MODULE ${ChewieUIQML_SOURCES})
23−target_link_libraries(FakeChewieUIQml
24− ${Qt5Core_LIBRARIES}
25− ${Qt5Quick_LIBRARIES}
26−)
27−
28−qt5_use_modules(FakeChewieUIQml Qml)
29−
30−# copy qmldir file into build directory for shadow builds
31−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
32− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
33− )
tests/mocks/Ubuntu/ChewieUI/fake_pluginmodel.cppdeleted−206
@@ -1,206 +0,0 @@
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 "fake_pluginmodel.h"
21−#include "paths.h"
22−
23−#include <QQmlContext>
24−#include <QQmlEngine>
25−#include <QDebug>
26−#include <QQmlComponent>
27−
28−struct Indicator {
29− Indicator(QString const& title, QString iconSource, QString label, QString description, QString componentSource)
30− : title(title)
31− , iconSource(iconSource)
32− , label(label)
33− , description(description)
34− , componentSource(componentSource)
35− , isValid(true)
36− {}
37−
38− QString title;
39− QString iconSource;
40− QString label;
41− QString description;
42− QString componentSource;
43− QMap<QString, QVariant> initialProperties;
44− bool isValid;
45−};
46−
47−const QList<Indicator> indicator_list = QList<Indicator>()
48− << Indicator("Menu1", sourceDirectory()+"Panel/graphics/Battery@18.png", "", "", sourceDirectory()+"tests/qmltests/Panel/qml/fake_menu_plugin1.qml")
49− << Indicator("Menu2", sourceDirectory()+"Panel/graphics/Bluetooth@18.png", "", "", sourceDirectory()+"tests/qmltests/Panel/qml/fake_menu_plugin2.qml")
50− << Indicator("Menu3", sourceDirectory()+"Panel/graphics/Clock@18.png", "", "", sourceDirectory()+"tests/qmltests/Panel/qml/fake_menu_plugin3.qml")
51− << Indicator("Menu4", sourceDirectory()+"Panel/graphics/Location@18.png", "", "", sourceDirectory()+"tests/qmltests/Panel/qml/fake_menu_plugin4.qml")
52− << Indicator("Menu5", sourceDirectory()+"Panel/graphics/Network@18.png", "", "", sourceDirectory()+"tests/qmltests/Panel/qml/fake_menu_plugin5.qml");
53−
54−
55−PluginModel::PluginModel(QObject *parent)
56− : QAbstractListModel(parent)
57−{
58− m_widgetsMap = new WidgetsMap;
59−
60− QObject::connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
61− QObject::connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
62− QObject::connect(this, SIGNAL(modelReset()), this, SIGNAL(countChanged()));
63−}
64−
65−/*! \internal */
66−PluginModel::~PluginModel()
67−{
68− delete m_widgetsMap;
69−}
70−
71−/*!
72− \qmlmethod PluginModel::get(int)
73−
74− Returns the item at index in the model. This allows the item data to be accessed from JavaScript:
75− \b Note: methods should only be called after the Component has completed.
76−*/
77−QVariantMap PluginModel::get(int row) const
78−{
79− QVariantMap result;
80−
81− QModelIndex index = this->index(row);
82− if (index.isValid()) {
83− QMap<int, QVariant> data = itemData(index);
84− const QHash<int, QByteArray> roleNames = this->roleNames();
85− Q_FOREACH(int i, roleNames.keys()) {
86− result.insert(roleNames[i], data[i]);
87− }
88− }
89− return result;
90−}
91−
92−/*!
93− \qmlproperty PluginModel::count
94− The number of data entries in the model.
95−
96− \b Note: methods should only be called after the Component has completed.
97−*/
98−int PluginModel::count() const
99−{
100− return rowCount();
101−}
102−
103−/*!
104− \qmlproperty WidgetsMap PluginModel::widgetsMap
105− This property holds the map for all new widgets registered by dynamically loaded plugins.
106−*/
107−WidgetsMap* PluginModel::widgetsMap() const
108−{
109− return m_widgetsMap;
110−}
111−
112−/*!
113− \qmlmethod PluginModel::load()
114−
115− Load all plugin information available on baseDir.
116−*/
117−void PluginModel::load()
118−{
119−
120−}
121−
122−/*!
123− \qmlmethod PluginModel::unload()
124−
125− Unload all plugins.
126−*/
127−void PluginModel::unload()
128−{
129− m_widgetsMap->clear();
130−}
131−
132−/*! \internal */
133−QHash<int, QByteArray> PluginModel::roleNames() const
134−{
135− static QHash<int, QByteArray> roles;
136− if (roles.isEmpty()) {
137− roles[Title] = "title";
138− roles[IconSource] = "iconSource";
139− roles[Label] = "label";
140− roles[Description] = "description";
141− roles[QMLComponent] = "component";
142− roles[InitialProperties] = "initialProperties";
143− roles[IsValid] = "isValid";
144− }
145− return roles;
146−}
147−
148−/*! \internal */
149−int PluginModel::columnCount(const QModelIndex &) const
150−{
151− return 1;
152−}
153−
154−/*! \internal */
155−QVariant PluginModel::data(const QModelIndex &index, int role) const
156−{
157− QVariant attribute;
158−
159− if ((index.row() >= 0) && (index.row() < indicator_list.size())) {
160− Indicator indicator = (indicator_list[index.row()]);
161−
162− switch (role) {
163− case Title:
164− attribute = indicator.title;
165− break;
166− case IconSource:
167− attribute = indicator.iconSource;
168− break;
169− case Label:
170− attribute = indicator.label;
171− break;
172− case Description:
173− attribute = indicator.description;
174− break;
175− case QMLComponent:
176− {
177− QQmlContext *context = QQmlEngine::contextForObject(this);
178− if (context) {
179− QQmlComponent* component = new QQmlComponent(context->parentContext()->engine(), QUrl(indicator.componentSource), NULL);
180− attribute = QVariant::fromValue<QQmlComponent*>(component);
181− }
182− } break;
183− case InitialProperties:
184− attribute = indicator.initialProperties;
185− break;
186− case IsValid:
187− attribute = indicator.isValid;
188− break;
189− default:
190− break;
191− }
192− }
193− return attribute;
194−}
195−
196−/*! \internal */
197−QModelIndex PluginModel::parent(const QModelIndex&) const
198−{
199− return QModelIndex();
200−}
201−
202−/*! \internal */
203−int PluginModel::rowCount(const QModelIndex &) const
204−{
205− return indicator_list.size();
206−}
tests/mocks/Ubuntu/ChewieUI/qmldirdeleted−1
@@ -1 +0,0 @@
1−plugin FakeChewieUIQml
tests/mocks/Unity/CMakeLists.txt+2
@@ -1,5 +1,7 @@
1set(CMAKE_AUTOMOC ON)
1set(CMAKE_AUTOMOC ON)
2
2
3+add_subdirectory(Indicators)
4+
3include(FindPkgConfig)
5include(FindPkgConfig)
4find_package(Qt5Core REQUIRED)
6find_package(Qt5Core REQUIRED)
5find_package(Qt5Quick REQUIRED)
7find_package(Qt5Quick REQUIRED)
tests/mocks/Unity/Indicators/CMakeLists.txtnew file+52
@@ -0,0 +1,52 @@
1+project(IndicatorsFakeQml)
2+
3+find_package(Qt5Core REQUIRED)
4+find_package(Qt5Quick REQUIRED)
5+
6+include_directories(
7+ ${CMAKE_CURRENT_SOURCE_DIR}
8+ ${CMAKE_CURRENT_BINARY_DIR}
9+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators
10+)
11+
12+set(IndicatorsFakeQml_SOURCES
13+ fakeplugin.cpp
14+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
15+)
16+
17+set(IndicatorsFakeQml_RESOURCES
18+ indicators_fake.qrc
19+)
20+
21+qt5_add_resources(IndicatorsFakeQml_RESOURCES_RCC
22+ ${IndicatorsFakeQml_RESOURCES}
23+)
24+
25+add_library(IndicatorsFakeQml SHARED
26+ ${IndicatorsFakeQml_RESOURCES_RCC}
27+ ${IndicatorsFakeQml_SOURCES}
28+)
29+# Because this is an internal support library, we want
30+# to expose all symbols in it. Consider changing this
31+# either to a static library or just using the
32+# files directly in targets.
33+set_target_properties(IndicatorsFakeQml PROPERTIES COMPILE_FLAGS -fvisibility=default)
34+
35+target_link_libraries(IndicatorsFakeQml)
36+
37+qt5_use_modules(IndicatorsFakeQml Core Qml Quick)
38+
39+file(GLOB IndicatorsFake_QMLFILES
40+ IndicatorsModel.qml
41+ qml/FakeMenuPage.qml
42+)
43+
44+# copy qmldir file into build directory for shadow builds
45+file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
46+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
47+)
48+
49+# copy qmldir file into build directory for shadow builds
50+file(COPY ${IndicatorsFake_QMLFILES}
51+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
52+)
tests/mocks/Unity/Indicators/IndicatorsModel.qmlnew file+104
@@ -0,0 +1,104 @@
1+/*
2+ * Copyright (C) 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 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+
17+import QtQuick 2.0
18+import Unity.Indicators 0.1 as Indicators
19+
20+ListModel {
21+
22+ property var indicatorData : undefined
23+
24+ function load() {}
25+
26+ ListElement {
27+ identifier: "indicator-fake1";
28+ priority: 0
29+ title: "Menu1";
30+ description: "";
31+ widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget1.qml";
32+ pageSource: "qrc:/tests/indciators/qml/fake_menu_page1.qml";
33+ indicatorProperties: "";
34+ isValid: "";
35+ }
36+ ListElement {
37+ identifier: "indicator-fake2";
38+ priority: 1
39+ title: "Menu2";
40+ description: "";
41+ widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget2.qml";
42+ pageSource: "qrc:/tests/indciators/qml/fake_menu_page2.qml";
43+ indicatorProperties: "";
44+ isValid: "";
45+ }
46+ ListElement {
47+ identifier: "indicator-fake3";
48+ priority: 2
49+ title: "Menu3";
50+ description: "";
51+ widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget3.qml";
52+ pageSource: "qrc:/tests/indciators/qml/fake_menu_page3.qml";
53+ indicatorProperties: "";
54+ isValid: "";
55+ }
56+ ListElement {
57+ identifier: "indicator-fake4";
58+ priority: 3
59+ title: "Menu4";
60+ description: "";
61+ widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget4.qml";
62+ pageSource: "qrc:/tests/indciators/qml/fake_menu_page4.qml";
63+ indicatorProperties: "";
64+ isValid: "";
65+ }
66+ ListElement {
67+ identifier: "indicator-fake4";
68+ priority: 4
69+ title: "Menu5";
70+ description: "";
71+ widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget5.qml";
72+ pageSource: "qrc:/tests/indciators/qml/fake_menu_page5.qml";
73+ indicatorProperties: "";
74+ isValid: "";
75+ }
76+
77+ function data(row, role) {
78+ if (role == Indicators.IndicatorsModelRole.Identifier) {
79+ return get(row).identifier;
80+ }
81+ else if (role == Indicators.IndicatorsModelRole.Priority) {
82+ return get(row).priority
83+ }
84+ else if (role == Indicators.IndicatorsModelRole.Title) {
85+ return get(row).title
86+ }
87+ else if (role == Indicators.IndicatorsModelRole.Description) {
88+ return get(row).description
89+ }
90+ else if (role == Indicators.IndicatorsModelRole.WidgetSource) {
91+ return get(row).widgetSource
92+ }
93+ else if (role == Indicators.IndicatorsModelRole.PageSource) {
94+ return get(row).pageSource
95+ }
96+ else if (role == Indicators.IndicatorsModelRole.IndicatorProperties) {
97+ return get(row).indicatorProperties
98+ }
99+ else if (role == Indicators.IndicatorsModelRole.IsValid) {
100+ return get(row).isValid
101+ }
102+ }
103+
104+}
tests/mocks/Unity/Indicators/fakeplugin.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 "fakeplugin.h"
24+
25+// local
26+#include "indicators.h"
27+
28+void IndicatorsFakePlugin::registerTypes(const char * uri)
29+{
30+ Q_INIT_RESOURCE(indicators_fake);
31+
32+ qmlRegisterUncreatableType<ActionState>(uri, 0, 1, "ActionState", "Can't create ActionState class");
33+ qmlRegisterUncreatableType<NetworkActionState>(uri, 0, 1, "NetworkActionState", "Can't create NetworkActionState class");
34+ qmlRegisterUncreatableType<NetworkConnection>(uri, 0, 1, "NetworkConnection", "Can't create NetworkConnection class");
35+ qmlRegisterUncreatableType<IndicatorsModelRole>(uri, 0, 1, "IndicatorsModelRole", "Can't create IndicatorsModelRole class");
36+ qmlRegisterUncreatableType<FlatMenuProxyModelRole>(uri, 0, 1, "FlatMenuProxyModelRole", "Can't create FlatMenuProxyModelRole class");
37+}
tests/mocks/Unity/Indicators/fakeplugin.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 INDICATORS_FAKE_PLUGIN_H
20+#define INDICATORS_FAKE_PLUGIN_H
21+
22+#include <QtQml/QQmlExtensionPlugin>
23+
24+class IndicatorsFakePlugin : 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 // INDICATORS_FAKE_PLUGIN_H
tests/mocks/Unity/Indicators/indicators_fake.qrcnew file+14
@@ -0,0 +1,14 @@
1+<RCC>
2+ <qresource prefix="/tests/indciators">
3+ <file>qml/fake_menu_widget1.qml</file>
4+ <file>qml/fake_menu_widget2.qml</file>
5+ <file>qml/fake_menu_widget3.qml</file>
6+ <file>qml/fake_menu_widget4.qml</file>
7+ <file>qml/fake_menu_widget5.qml</file>
8+ <file>qml/fake_menu_page1.qml</file>
9+ <file>qml/fake_menu_page2.qml</file>
10+ <file>qml/fake_menu_page3.qml</file>
11+ <file>qml/fake_menu_page4.qml</file>
12+ <file>qml/fake_menu_page5.qml</file>
13+ </qresource>
14+</RCC>
tests/qmltests/Panel/qml/FakeMenuPlugin.qml → tests/mocks/Unity/Indicators/qml/FakeMenuPage.qmlrenamed

The content is the same.

tests/qmltests/Panel/qml/fake_menu_plugin1.qml → tests/mocks/Unity/Indicators/qml/fake_menu_page1.qmlrenamed+3−2
@@ -15,10 +15,11 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import Unity.Indicators 0.1 as Indicators
18
19
19−FakeMenuPlugin {
20+Indicators.FakeMenuPage {
20 id: menu_plugin1
21 id: menu_plugin1
21− objectName: "menu_plugin1"
22+ objectName: "menu_page1"
22
23
23 Rectangle {
24 Rectangle {
24 id: contents
25 id: contents
tests/qmltests/Panel/qml/fake_menu_plugin2.qml → tests/mocks/Unity/Indicators/qml/fake_menu_page2.qmlrenamed+3−2
@@ -15,10 +15,11 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import Unity.Indicators 0.1 as Indicators
18
19
19−FakeMenuPlugin {
20+Indicators.FakeMenuPage {
20 id: menu_plugin2
21 id: menu_plugin2
21− objectName: "menu_plugin2"
22+ objectName: "menu_page2"
22
23
23 Rectangle {
24 Rectangle {
24 id: contents
25 id: contents
tests/qmltests/Panel/qml/fake_menu_plugin3.qml → tests/mocks/Unity/Indicators/qml/fake_menu_page3.qmlrenamed+3−2
@@ -15,10 +15,11 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import Unity.Indicators 0.1 as Indicators
18
19
19−FakeMenuPlugin {
20+Indicators.FakeMenuPage {
20 id: menu_plugin3
21 id: menu_plugin3
21− objectName: "menu_plugin3"
22+ objectName: "menu_page3"
22
23
23 Rectangle {
24 Rectangle {
24 id: contents
25 id: contents
tests/qmltests/Panel/qml/fake_menu_plugin4.qml → tests/mocks/Unity/Indicators/qml/fake_menu_page4.qmlrenamed+3−2
@@ -15,10 +15,11 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import Unity.Indicators 0.1 as Indicators
18
19
19−FakeMenuPlugin {
20+Indicators.FakeMenuPage {
20 id: menu_plugin4
21 id: menu_plugin4
21− objectName: "menu_plugin4"
22+ objectName: "menu_page4"
22
23
23 Rectangle {
24 Rectangle {
24 id: contents
25 id: contents
tests/qmltests/Panel/qml/fake_menu_plugin5.qml → tests/mocks/Unity/Indicators/qml/fake_menu_page5.qmlrenamed+3−2
@@ -15,10 +15,11 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import Unity.Indicators 0.1 as Indicators
18
19
19−FakeMenuPlugin {
20+Indicators.FakeMenuPage {
20 id: menu_plugin5
21 id: menu_plugin5
21− objectName: "menu_plugin5"
22+ objectName: "menu_page5"
22
23
23 Rectangle {
24 Rectangle {
24 id: contents
25 id: contents
tests/mocks/Unity/Indicators/qml/fake_menu_widget1.qmlnew file+23
@@ -0,0 +1,23 @@
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 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+
17+import QtQuick 2.0
18+
19+Rectangle {
20+ width: 40
21+ height: 40
22+ color : "red"
23+}
tests/mocks/Unity/Indicators/qml/fake_menu_widget2.qmlnew file+23
@@ -0,0 +1,23 @@
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 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+
17+import QtQuick 2.0
18+
19+Rectangle {
20+ width: 40
21+ height: 40
22+ color : "yellow"
23+}
tests/mocks/Unity/Indicators/qml/fake_menu_widget3.qmlnew file+23
@@ -0,0 +1,23 @@
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 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+
17+import QtQuick 2.0
18+
19+Rectangle {
20+ width: 40
21+ height: 40
22+ color : "blue"
23+}
tests/mocks/Unity/Indicators/qml/fake_menu_widget4.qmlnew file+23
@@ -0,0 +1,23 @@
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 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+
17+import QtQuick 2.0
18+
19+Rectangle {
20+ width: 40
21+ height: 40
22+ color : "green"
23+}
tests/mocks/Unity/Indicators/qml/fake_menu_widget5.qmlnew file+23
@@ -0,0 +1,23 @@
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 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+
17+import QtQuick 2.0
18+
19+Rectangle {
20+ width: 40
21+ height: 40
22+ color : "orange"
23+}
tests/mocks/Unity/Indicators/qmldirnew file+5
@@ -0,0 +1,5 @@
1+module Unity.Indicators
2+plugin IndicatorsFakeQml
3+
4+IndicatorsModel 0.1 IndicatorsModel.qml
5+FakeMenuPage 0.1 FakeMenuPage.qml
tests/plugins/Unity/CMakeLists.txt+2
@@ -1,3 +1,5 @@
1+add_subdirectory(Indicators)
2+
1pkg_check_modules(UNITYCORE REQUIRED unity-core-6.0)
3pkg_check_modules(UNITYCORE REQUIRED unity-core-6.0)
2pkg_check_modules(LIBUNITYPROTO REQUIRED unity-protocol-private)
4pkg_check_modules(LIBUNITYPROTO REQUIRED unity-protocol-private)
3
5
tests/plugins/Unity/Indicators/CMakeLists.txtnew file+27
@@ -0,0 +1,27 @@
1+include_directories(
2+ ${CMAKE_CURRENT_BINARY_DIR}
3+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../plugins/Unity/Indicators
4+ )
5+
6+macro(run_tests)
7+ set(_test_list "")
8+ foreach(_test ${ARGN})
9+ set(testCommand ${CMAKE_CURRENT_BINARY_DIR}/${_test}Exec
10+ -o ${CMAKE_BINARY_DIR}/${_test}.xml,xunitxml
11+ -o -,txt)
12+ add_test(NAME ${_test} COMMAND ${testCommand})
13+ add_custom_target(${_test} ${testCommand})
14+ add_executable(${_test}Exec ${_test}.cpp
15+ )
16+ qt5_use_modules(${_test}Exec Test Core Qml)
17+ target_link_libraries(${_test}Exec
18+ IndicatorsQml
19+ )
20+ set(_test_list "${_test_list};${_test}")
21+ endforeach()
22+endmacro(run_tests)
23+
24+run_tests(
25+ indicatorsmanagertest
26+ indicatorsmodeltest
27+ )
tests/plugins/Unity/Indicators/indicatorsmanagertest.cppnew file+138
@@ -0,0 +1,138 @@
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 "indicatorsmanager.h"
21+#include "paths.h"
22+
23+#include <QtTest>
24+#include <QDebug>
25+
26+class IndicatorsManagerTest : public QObject
27+{
28+ Q_OBJECT
29+private Q_SLOTS:
30+
31+ void initTestCase()
32+ {
33+ setenv("UNITY_TEST_ENV", "1", 1);
34+ setenv("XDG_DATA_DIRS", (sourceDirectory() + "/tests/data").toLatin1().data(), 1);
35+ }
36+
37+ void cleanupTestCase()
38+ {
39+ unsetenv("UNITY_TEST_ENV");
40+ }
41+
42+ /*
43+ * Test if all plugins is loaded correct
44+ */
45+ void testLoad()
46+ {
47+ IndicatorsManager manager;
48+
49+ QVERIFY(!manager.isLoaded());
50+ QCOMPARE(manager.indicators().count(), 0);
51+
52+ manager.load();
53+
54+ QVERIFY(manager.isLoaded());
55+ QCOMPARE(manager.indicators().count(), 4);
56+
57+ manager.unload();
58+
59+ QVERIFY(!manager.isLoaded());
60+ QCOMPARE(manager.indicators().count(), 0);
61+ }
62+
63+ /*
64+ * Test the creation & initialising of the indicator data
65+ */
66+ void testPluginInterface()
67+ {
68+ IndicatorsManager manager;
69+ manager.load();
70+
71+ Indicator::Ptr indicator = manager.indicator("indicator-fake1");
72+ QVERIFY(indicator ? true : false);
73+
74+ QCOMPARE(indicator->identifier(), QString("indicator-fake1"));
75+
76+ // Check that the initial properties have been set.
77+ QVariantMap props = indicator->indicatorProperties().toMap();
78+ QCOMPARE(props.count(), 4);
79+ QCOMPARE(props["busType"].toInt(), 1);
80+ QCOMPARE(props["busName"].toString(), QString("com.canonical.indicator.fake1"));
81+ QCOMPARE(props["actionsObjectPath"].toString(), QString("/com/canonical/indicator/fake1"));
82+
83+ QVariantMap objectPaths = props["menuObjectPaths"].toMap();
84+ QCOMPARE(objectPaths["phone"].toString(), QString("/com/canonical/indicator/fake1/phone"));
85+ QCOMPARE(objectPaths["desktop"].toString(), QString("/com/canonical/indicator/fake1/desktop"));
86+ }
87+
88+ /*
89+ * Test if a new plugin object is create for each different plugin
90+ */
91+ void testPluginInstance()
92+ {
93+ IndicatorsManager manager;
94+ manager.load();
95+
96+ Indicator::Ptr i0 = manager.indicator("indicator-fake1");
97+ Indicator::Ptr i1 = manager.indicator("indicator-fake1");
98+ QVERIFY(i0?true:false);
99+ QVERIFY(i1?true:false);
100+ QCOMPARE(i0, i1);
101+
102+ Indicator::Ptr i2 = manager.indicator("indicator-fake2");
103+ QVERIFY(i2?true:false);
104+ QVERIFY(i2 != i1);
105+ QVERIFY(i2 != i1);
106+ }
107+
108+ /*
109+ * Test if a new plugin init function is called only once
110+ */
111+ void testPluginInitAndShutdown()
112+ {
113+ IndicatorsManager manager;
114+ manager.load();
115+
116+ QWeakPointer<Indicator> wp0;
117+ QWeakPointer<Indicator> wp1;
118+ {
119+ Indicator::Ptr i0 = manager.indicator("indicator-fake1");
120+ wp0 = i0.toWeakRef();
121+
122+ Indicator::Ptr i1 = manager.indicator("indicator-fake1");
123+ wp1 = i1.toWeakRef();
124+
125+ manager.unload();
126+ // still alive while we have the shared pointers.
127+ QVERIFY(!wp0.isNull());
128+ QVERIFY(!wp1.isNull());
129+ }
130+
131+ // no more smart pointers. should have been released.
132+ QVERIFY(wp0.isNull());
133+ QVERIFY(wp1.isNull());
134+ }
135+};
136+
137+QTEST_MAIN(IndicatorsManagerTest)
138+#include "indicatorsmanagertest.moc"
tests/plugins/Unity/Indicators/indicatorsmodeltest.cppnew file+102
@@ -0,0 +1,102 @@
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 "indicators.h"
22+#include "paths.h"
23+
24+#include <QtTest>
25+#include <QDebug>
26+
27+class IndicatorsModelTest : public QObject
28+{
29+ Q_OBJECT
30+private Q_SLOTS:
31+
32+ void initTestCase()
33+ {
34+ setenv("UNITY_TEST_ENV", "1", 1);
35+ setenv("XDG_DATA_DIRS", (sourceDirectory() + "/tests/data").toLatin1().data(), 1);
36+ }
37+
38+ void cleanupTestCase()
39+ {
40+ unsetenv("UNITY_TEST_ENV");
41+ }
42+
43+ /*
44+ * Testa that all the plugins are loaded / unloaded correctly
45+ */
46+ void testLoad()
47+ {
48+ IndicatorsModel model;
49+
50+ QCOMPARE(model.property("count").toInt(), 0);
51+
52+ model.load();
53+
54+ QCOMPARE(model.property("count").toInt(), 4);
55+
56+ model.unload();
57+
58+ QCOMPARE(model.property("count").toInt(), 0);
59+
60+ }
61+
62+ /*
63+ * Testa that the plugin data was loaded correctly
64+ */
65+ void testDataAndOrder()
66+ {
67+ // Priority order. (2, 1, 4, 3)
68+ QVariantMap map;
69+ QVariantMap map1; map1["priority"] = 1; map1["title"] = "fake1";
70+ QVariantMap map2; map2["priority"] = 0; map2["title"] = "fake2";
71+ QVariantMap map3; map3["priority"] = 3; map3["title"] = "fake3";
72+ QVariantMap map4; map4["priority"] = 2; map4["title"] = "fake4";
73+ map["indicator-fake1"] = map1;
74+ map["indicator-fake2"] = map2;
75+ map["indicator-fake3"] = map3;
76+ map["indicator-fake4"] = map4;
77+
78+ IndicatorsModel model;
79+ model.setIndicatorData(map);
80+ model.load();
81+
82+ QCOMPARE(model.data(0, IndicatorsModelRole::Identifier).toString(), QString("indicator-fake2"));
83+ QCOMPARE(model.data(0, IndicatorsModelRole::Title).toString(), QString("fake2"));
84+ QCOMPARE(model.data(0, IndicatorsModelRole::IndicatorProperties).toMap()["busName"].toString(), QString("com.canonical.indicator.fake2"));
85+
86+ QCOMPARE(model.data(1, IndicatorsModelRole::Identifier).toString(), QString("indicator-fake1"));
87+ QCOMPARE(model.data(1, IndicatorsModelRole::Title).toString(), QString("fake1"));
88+ QCOMPARE(model.data(1, IndicatorsModelRole::IndicatorProperties).toMap()["busName"].toString(), QString("com.canonical.indicator.fake1"));
89+
90+ QCOMPARE(model.data(2, IndicatorsModelRole::Identifier).toString(), QString("indicator-fake4"));
91+ QCOMPARE(model.data(2, IndicatorsModelRole::Title).toString(), QString("fake4"));
92+ QCOMPARE(model.data(2, IndicatorsModelRole::IndicatorProperties).toMap()["busName"].toString(), QString("com.canonical.indicator.fake4"));
93+
94+ QCOMPARE(model.data(3, IndicatorsModelRole::Identifier).toString(), QString("indicator-fake3"));
95+ QCOMPARE(model.data(3, IndicatorsModelRole::Title).toString(), QString("fake3"));
96+ QCOMPARE(model.data(3, IndicatorsModelRole::IndicatorProperties).toMap()["busName"].toString(), QString("com.canonical.indicator.fake3"));
97+ }
98+};
99+
100+QTEST_MAIN(IndicatorsModelTest)
101+
102+#include "indicatorsmodeltest.moc"
tests/qmltests/Panel/tst_IndicatorItem.qml+13−28
@@ -29,54 +29,39 @@ Rectangle {
29 IndicatorItem {
29 IndicatorItem {
30 id: indicatorItem
30 id: indicatorItem
31 anchors.fill: parent
31 anchors.fill: parent
32− iconSource: "../../../Panel/graphics/Clock.png"
33− label: "Clock"
34 }
32 }
35
33
36 UT.UnityTestCase {
34 UT.UnityTestCase {
37 name: "IndicatorItem"
35 name: "IndicatorItem"
38
36
39 function init_test() {
37 function init_test() {
40− indicatorItem.iconSource = "../../../Panel/graphics/Clock.png"
41− indicatorItem.label = "Clock"
42 }
38 }
43
39
44 function test_dimmed() {
40 function test_dimmed() {
45 init_test()
41 init_test()
46
42
47− var itemRow = findChild(indicatorItem, "itemRow")
48 indicatorItem.dimmed = true
43 indicatorItem.dimmed = true
49− compare(itemRow.opacity > 0, true, "IndicatorItem opacity should not be 0")
44+ compare(indicatorItem.opacity > 0, true, "IndicatorItem opacity should not be 0")
50− compare(itemRow.opacity < 1, true, "IndicatorItem opacity should not be 1")
45+ compare(indicatorItem.opacity < 1, true, "IndicatorItem opacity should not be 1")
51 }
46 }
52
47
53− function test_empty() {
48+ function test_highlight() {
54− init_test()
55−
56− indicatorItem.iconSource = ""
57− indicatorItem.label = ""
49+ var itemHighlight = findChild(indicatorItem, "highlight")
58− compare(indicatorItem.visible, false, "IndicatorItem should not be visible")
50+ verify(itemHighlight != undefined)
59− }
60
51
61− function test_noLabel() {
52+ indicatorItem.highlighted = true;
62− init_test()
53+ compare(itemHighlight.visible, true, "Indicator should be highlighted")
63
54
64− var itemImage = findChild(indicatorItem, "itemImage")
55+ indicatorItem.highlighted = false;
65− var itemLabel = findChild(indicatorItem, "itemLabel")
56+ compare(itemHighlight.visible, false, "Indicator should not be highlighted")
66− indicatorItem.label = ""
67− compare(itemImage.visible, true, "The image should be visible")
68− compare(itemImage.width > 0, true, "The image should have a positive width")
69− compare(itemLabel.width > 0, false, "The label should not have a positive width")
70 }
57 }
71
58
72− function test_noImage() {
59+ function test_empty() {
73 init_test()
60 init_test()
74
61
75− var itemImage = findChild(indicatorItem, "itemImage")
76− var itemLabel = findChild(indicatorItem, "itemLabel")
77− indicatorItem.iconSource = ""
78− compare(itemImage.visible, false, "The image should not be visible")
62+ compare(indicatorItem.visible, false, "IndicatorItem should not be visible.")
79− compare(itemLabel.width > 0, true, "The label should have a positive width")
63+ indicatorItem.widgetSource = "qrc:/tests/indciators/qml/fake_menu_widget1.qml";
64+ tryCompare(indicatorItem, "visible", true)
80 }
65 }
81 }
66 }
82}
67}
tests/qmltests/Panel/tst_IndicatorRow.qml+4−3
@@ -19,7 +19,7 @@ import QtTest 1.0
19import Unity.Test 0.1 as UT
19import Unity.Test 0.1 as UT
20import ".."
20import ".."
21import "../../../Panel"
21import "../../../Panel"
22−import Ubuntu.ChewieUI 0.1 as ChewieUI
22+import Unity.Indicators 0.1 as Indicators
23
23
24/*
24/*
25 This tests the IndicatorRow component by using a fake model to stage data in the indicators
25 This tests the IndicatorRow component by using a fake model to stage data in the indicators
@@ -51,8 +51,9 @@ Item {
51 indicatorsModel: indicatorModel
51 indicatorsModel: indicatorModel
52 }
52 }
53
53
54− ChewieUI.PluginModel {
54+ Indicators.IndicatorsModel {
55 id: indicatorModel
55 id: indicatorModel
56+ Component.onCompleted: load()
56 }
57 }
57
58
58 UT.UnityTestCase {
59 UT.UnityTestCase {
@@ -241,7 +242,7 @@ Item {
241 compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in locked state");
242 compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in locked state");
242 }
243 }
243
244
244− function test_active_overview_() {
245+ function test_active_overview() {
245 init_test();
246 init_test();
246
247
247 indicatorRow.overviewActive = true;
248 indicatorRow.overviewActive = true;
tests/qmltests/Panel/tst_Indicators.qml+1−2
@@ -71,8 +71,7 @@ Item {
71 if (!indicators.shown) {
71 if (!indicators.shown) {
72 indicators.openOverview();
72 indicators.openOverview();
73 indicators.show();
73 indicators.show();
74− }
75− else {
74+ } else {
76 indicators.hide();
75 indicators.hide();
77 }
76 }
78 }
77 }
tests/qmltests/Panel/tst_MenuContent.qml+11−10
@@ -19,7 +19,7 @@ import QtTest 1.0
19import Unity.Test 0.1 as UT
19import Unity.Test 0.1 as UT
20import ".."
20import ".."
21import "../../../Panel"
21import "../../../Panel"
22−import Ubuntu.ChewieUI 0.1 as ChewieUI
22+import Unity.Indicators 0.1 as Indicators
23
23
24Item {
24Item {
25 id: shell
25 id: shell
@@ -27,11 +27,11 @@ Item {
27 height: units.gu(70)
27 height: units.gu(70)
28
28
29 property var indicator_status: {
29 property var indicator_status: {
30− 'menu_plugin1': { 'started': false, 'reset': 0 },
30+ 'menu_page1': { 'started': false, 'reset': 0 },
31− 'menu_plugin2': { 'started': false, 'reset': 0 },
31+ 'menu_page2': { 'started': false, 'reset': 0 },
32− 'menu_plugin3': { 'started': false, 'reset': 0 },
32+ 'menu_page3': { 'started': false, 'reset': 0 },
33− 'menu_plugin4': { 'started': false, 'reset': 0 },
33+ 'menu_page4': { 'started': false, 'reset': 0 },
34− 'menu_plugin5': { 'started': false, 'reset': 0 }
34+ 'menu_page5': { 'started': false, 'reset': 0 }
35 }
35 }
36
36
37 // Dummy objects
37 // Dummy objects
@@ -39,8 +39,9 @@ Item {
39 Item { id: handle }
39 Item { id: handle }
40
40
41
41
42− ChewieUI.PluginModel {
42+ Indicators.IndicatorsModel {
43 id: indicatorsModel
43 id: indicatorsModel
44+ Component.onCompleted: load()
44 }
45 }
45
46
46 MenuContent {
47 MenuContent {
@@ -123,20 +124,20 @@ Item {
123 }
124 }
124
125
125 function get_test_menu_objecName(index) {
126 function get_test_menu_objecName(index) {
126− return "menu_plugin"+(index+1);
127+ return "menu_page"+(index+1);
127 }
128 }
128
129
129 property string test_menu_objectName : ""
130 property string test_menu_objectName : ""
130 function current_menu_equals_test_menu() {
131 function current_menu_equals_test_menu() {
131 var current_loader = menu_content_test.findChild(menuContent, "menus").currentItem
132 var current_loader = menu_content_test.findChild(menuContent, "menus").currentItem
132 if (current_loader == undefined) {
133 if (current_loader == undefined) {
133− console.log("current_loader undefined");
134+ console.log("current_loader 'menus' undefined");
134 return false;
135 return false;
135 }
136 }
136
137
137 var menu = menu_content_test.findChild(menuContent, test_menu_objectName);
138 var menu = menu_content_test.findChild(menuContent, test_menu_objectName);
138 if (menu == undefined) {
139 if (menu == undefined) {
139− console.log("test_menu undefined");
140+ console.log("test_menu " + test_menu_objectName + " undefined");
140 return false;
141 return false;
141 }
142 }
142
143
tests/qmltests/Panel/tst_Overview.qml+5−17
@@ -20,6 +20,7 @@ import ".."
20import "../../../Panel/Menus"
20import "../../../Panel/Menus"
21import "../../../Components"
21import "../../../Components"
22import Unity.Test 0.1 as UT
22import Unity.Test 0.1 as UT
23+import Unity.Indicators 0.1 as Indicators
23
24
24Rectangle {
25Rectangle {
25 id: shell
26 id: shell
@@ -47,9 +48,9 @@ Rectangle {
47
48
48 ListModel {
49 ListModel {
49 id: mockModel
50 id: mockModel
50− ListElement {title: "foo"; label: "foo"; iconSource: "graphics/sound_on_icon.png"}
51+ ListElement {title: "fake1"; widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget1.qml"; indicatorProperties: ""}
51− ListElement {title: "bar"; label: ""; iconSource: "graphics/sound_on_icon.png"}
52+ ListElement {title: "fake2"; widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget2.qml"; indicatorProperties: ""}
52− ListElement {title: "baz"; label: "baz"; iconSource: "graphics/sound_on_icon.png"}
53+ ListElement {title: "fake3"; widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget3.qml"; indicatorProperties: ""}
53 }
54 }
54
55
55 ListModel {
56 ListModel {
@@ -98,7 +99,7 @@ Rectangle {
98 button = findChild(overview, "overviewGridButton3");
99 button = findChild(overview, "overviewGridButton3");
99 compare(button, undefined, "There should only be 3 buttons... found at least 4...");
100 compare(button, undefined, "There should only be 3 buttons... found at least 4...");
100
101
101− mockModel2.append({title: "humppa", label: "", iconSource: "graphics/sound_on_icon.png"})
102+ mockModel2.append({title: "humppa", widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget4.qml", indicatorProperties: ""})
102 overviewGrid.forceLayout();
103 overviewGrid.forceLayout();
103 waitForRendering(overviewGrid);
104 waitForRendering(overviewGrid);
104
105
@@ -106,19 +107,6 @@ Rectangle {
106 verify(button !== undefined, "button3 wasn't found");
107 verify(button !== undefined, "button3 wasn't found");
107 }
108 }
108
109
109− function test_text_or_icon_data() {
110− return [
111− {tag: "text", index: 0, imageVisible: false},
112− {tag: "image", index: 1, imageVisible: true}
113− ]
114− }
115−
116− function test_text_or_icon(data) {
117− var button = findChild(overview, "overviewGridButton" + data.index);
118− var image = findChild(button, "overviewGridButtonImage");
119− compare(image.visible, data.imageVisible)
120− }
121−
122 function test_volume_slider_data() {
110 function test_volume_slider_data() {
123 return [
111 return [
124 {tag: "0%", sliderPos:0},
112 {tag: "0%", sliderPos:0},
tests/qmltests/Panel/tst_Panel.qml−1
@@ -19,7 +19,6 @@ import QtTest 1.0
19import Unity.Test 0.1 as UT
19import Unity.Test 0.1 as UT
20import ".."
20import ".."
21import "../../../Panel"
21import "../../../Panel"
22−import Ubuntu.ChewieUI 0.1 as ChewieUI
23
22
24/*
23/*
25 This tests the Panel component using a fake model to stage data in the indicators
24 This tests the Panel component using a fake model to stage data in the indicators
tests/qmltests/modules/CMakeLists.txtnew file+1
@@ -0,0 +1 @@
1+add_subdirectory(Unity)
tests/qmltests/modules/Unity/CMakeLists.txtnew file+1
@@ -0,0 +1 @@
1+add_subdirectory(Indicators)
unity8.qmlproject+1
@@ -18,6 +18,7 @@ Project {
18 /* List of plugin directories passed to QML runtime */
18 /* List of plugin directories passed to QML runtime */
19 importPaths: [
19 importPaths: [
20 "builddir/plugins",
20 "builddir/plugins",
21+ "builddir/modules",
21 "builddir/tests/plugins",
22 "builddir/tests/plugins",
22 "builddir/tests/utils/modules"
23 "builddir/tests/utils/modules"
23 ]
24 ]