on xenial help sign in
merge trunk
db432c9Michael Zanetti
ApplicationArguments.hnew file+49
@@ -0,0 +1,49 @@
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_ARGUMENTS_H
21+#define APPLICATION_ARGUMENTS_H
22+
23+#include <QObject>
24+#include <QSize>
25+#include <QStringList>
26+
27+class ApplicationArguments : public QObject
28+{
29+ Q_OBJECT
30+public:
31+ ApplicationArguments(const QStringList& args) {
32+ if (args.contains(QLatin1String("-geometry")) && args.size() > args.indexOf(QLatin1String("-geometry")) + 1) {
33+ QStringList geometryArg = args.at(args.indexOf(QLatin1String("-geometry")) + 1).split('x');
34+ if (geometryArg.size() == 2) {
35+ m_size.rwidth() = geometryArg.at(0).toInt();
36+ m_size.rheight() = geometryArg.at(1).toInt();
37+ }
38+ }
39+ }
40+
41+ Q_INVOKABLE bool hasGeometry() const { return m_size.isValid(); }
42+ Q_INVOKABLE int width() const { return m_size.width(); }
43+ Q_INVOKABLE int height() const { return m_size.height(); }
44+
45+private:
46+ QSize m_size;
47+};
48+
49+#endif // APPLICATION_ARGUMENTS_H
Applications/applications.js+2−2
@@ -70,10 +70,10 @@ var __availableApplications = {
70 'exec': '/usr/bin/qmlscene /usr/share/notes-app/NotesApp.qml',
70 'exec': '/usr/bin/qmlscene /usr/share/notes-app/NotesApp.qml',
71 'stage': SideStage
71 'stage': SideStage
72 },
72 },
73− '/usr/share/applications/ubuntu-calendar-app.desktop': {
73+ '/usr/share/applications/calendar-app.desktop': {
74 'name': i18n.tr("Calendar"),
74 'name': i18n.tr("Calendar"),
75 'icon': 'calendar',
75 'icon': 'calendar',
76− 'exec': '/usr/bin/qmlscene /usr/share/ubuntu-calendar-app/calendar.qml',
76+ 'exec': '/usr/bin/qmlscene /usr/share/calendar-app/calendar.qml',
77 'stage': SideStage
77 'stage': SideStage
78 },
78 },
79 '/usr/share/applications/mediaplayer-app.desktop': {
79 '/usr/share/applications/mediaplayer-app.desktop': {
CMakeLists.txt+5−3
@@ -91,9 +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−
95+declare_autopilot_test(indicators_client unity8.indicators_client ${CMAKE_SOURCE_DIR}/tests/autopilot/)
96−add_subdirectory(tests)
97
96
98set(SHELL_APP unity8)
97set(SHELL_APP unity8)
99
98
@@ -102,6 +101,7 @@ set(shell_app_HDRS
102
101
103add_executable(${SHELL_APP}
102add_executable(${SHELL_APP}
104 ${shellapplication_MOC_SRCS}
103 ${shellapplication_MOC_SRCS}
104+ ApplicationArguments.h
105 main.cpp
105 main.cpp
106 MouseTouchAdaptor.cpp
106 MouseTouchAdaptor.cpp
107 )
107 )
@@ -132,7 +132,9 @@ install(FILES ${QML_JS_FILES}
132 )
132 )
133
133
134# add subdirectories to build
134# add subdirectories to build
135+add_subdirectory(tests)
135add_subdirectory(plugins)
136add_subdirectory(plugins)
137+add_subdirectory(src)
136
138
137# install subdirectories
139# install subdirectories
138set(QML_DIRS
140set(QML_DIRS
CODING+5−6
@@ -23,15 +23,12 @@ $ cd ~/unity8/trunk
23$ ./build --setup
23$ ./build --setup
24
24
25 this will:
25 this will:
26− - add the following PPA's
27− - ppa:phablet-team/desktop-deps
28− - ppa:canonical-qt5-edgers/qt5-proper
29− - ppa:ubuntu-sdk-team
26+ - add ppa:ubuntu-unity/next
30 - install the required dependencies to build, as well as run on the desktop
27 - install the required dependencies to build, as well as run on the desktop
31 - it should also install unity-scope-home and unity-lens-application which
28 - it should also install unity-scope-home and unity-lens-application which
32 are technically "recommends", not strict dependencies
29 are technically "recommends", not strict dependencies
33
30
34−Note, once the PPA's are added, the script runs apt-get update, if you have
31+Note, once the PPA is added, the script runs apt-get update, if you have
35any failures associated with it, the build script will bail out of the setup
32any failures associated with it, the build script will bail out of the setup
36and fail to install all the required dependencies.
33and fail to install all the required dependencies.
37
34
@@ -45,6 +42,7 @@ $ ./build
45You may also rebuild with the -c for clean, which just deletes the build
42You may also rebuild with the -c for clean, which just deletes the build
46directory.
43directory.
47
44
45+
48Running Unity 8 on your desktop
46Running Unity 8 on your desktop
49===============================
47===============================
50
48
@@ -73,6 +71,7 @@ Notes
73 - Create an EDS address book
71 - Create an EDS address book
74 - Populate the address book with sample data
72 - Populate the address book with sample data
75
73
74+
76Running Unity 8 on devices
75Running Unity 8 on devices
77==========================
76==========================
78- Ubuntu Touch builds are currently only available in 13.10 flavour
77- Ubuntu Touch builds are currently only available in 13.10 flavour
@@ -91,7 +90,6 @@ $ cd ~/unity/trunk
91$ ./run_on_device --setup
90$ ./run_on_device --setup
92 this will:
91 this will:
93 - install your public SSH key on the device
92 - install your public SSH key on the device
94− - add ppa:canonical-qt5-edgers/qt5-proper and ppa:phablet-team
95 - install the needed dependencies
93 - install the needed dependencies
96
94
97$ ./run_on_device
95$ ./run_on_device
@@ -109,6 +107,7 @@ $ ./run_on_device -p OR -k
109Notes
107Notes
110-----
108-----
111- using adb over TCP has some advantages, Google will be of help here
109- using adb over TCP has some advantages, Google will be of help here
110+ - NOTE: this is not yet available for flipped images
112 - TL;DR: `adb tcpip 5555; adb connect $your_device_ip`
111 - TL;DR: `adb tcpip 5555; adb connect $your_device_ip`
113 - you can persist the above via `adb shell setprop persist.adb.tcp.port 5555`
112 - you can persist the above via `adb shell setprop persist.adb.tcp.port 5555`
114 - it's unsafe - anyone can connect to your device
113 - it's unsafe - anyone can connect to your device
Components/ApplicationScreenshot.qml+1−1
@@ -46,7 +46,7 @@ Item {
46 Rectangle {
46 Rectangle {
47 id: background
47 id: background
48 anchors.fill: parent
48 anchors.fill: parent
49− color: "white"
49+ color: "white" // FIXME should use normal background color of Suru theme
50 visible: applicationScreenshot.withBackground
50 visible: applicationScreenshot.withBackground
51 }
51 }
52
52
Components/Carousel.qml+38−1
@@ -52,6 +52,12 @@ Item {
52 /// @param itemY is y of the clicked delegate
52 /// @param itemY is y of the clicked delegate
53 signal clicked(int index, var delegateItem, real itemY)
53 signal clicked(int index, var delegateItem, real itemY)
54
54
55+ /// Emitted when the user pressed and held on an item
56+ /// @param index is the index of the held item
57+ /// @param delegateItem is the held component/delegate itself
58+ /// @param itemY is y of the held delegate
59+ signal pressAndHold(int index, var delegateItem, real itemY)
60+
55 implicitHeight: listView.tileHeight * selectedItemScaleFactor
61 implicitHeight: listView.tileHeight * selectedItemScaleFactor
56
62
57 /* Basic idea behind the carousel effect is to move the items of the delegates (compacting /stuffing them).
63 /* Basic idea behind the carousel effect is to move the items of the delegates (compacting /stuffing them).
@@ -159,6 +165,30 @@ Item {
159 newContentXAnimation.start()
165 newContentXAnimation.start()
160 }
166 }
161
167
168+ function itemPressAndHold(index, delegateItem) {
169+ var x = CarouselJS.getXFromContinuousIndex(index,
170+ realWidth,
171+ realContentWidth,
172+ tileWidth,
173+ gapToMiddlePhase,
174+ gapToEndPhase,
175+ carousel.drawBuffer);
176+
177+ if (Math.abs(x - contentX) < 1) {
178+ /* We're pressAndHold the selected item and
179+ we're in the neighbourhood of radius 1 pixel from it.
180+ Let's emit the pressAndHold signal. */
181+ carousel.pressAndHold(index, delegateItem, delegateItem.y);
182+ return;
183+ }
184+
185+ stepAnimation.stop();
186+ newContentXAnimation.stop();
187+
188+ newContentX = x;
189+ newContentXAnimation.start();
190+ }
191+
162 onMovementStarted: {
192 onMovementStarted: {
163 stepAnimation.stop()
193 stepAnimation.stop()
164 newContentXAnimation.stop()
194 newContentXAnimation.stop()
@@ -279,7 +309,14 @@ Item {
279
309
280 anchors.fill: parent
310 anchors.fill: parent
281
311
312+ onClicked: {
282− onClicked: listView.itemClicked(index, item)
313+ listView.itemClicked(index, item)
314+ }
315+
316+ onPressAndHold: {
317+ listView.itemPressAndHold(index, item)
318+ }
319+
283 }
320 }
284 }
321 }
285 }
322 }
Components/FilterGrid.qml+2−2
@@ -99,7 +99,7 @@ Item {
99
99
100 UbuntuShape {
100 UbuntuShape {
101 anchors.fill: parent
101 anchors.fill: parent
102− color: "#33ffffff"
102+ color: "#33ffffff" // FIXME no palette
103 radius: "small"
103 radius: "small"
104 }
104 }
105
105
@@ -123,7 +123,7 @@ Item {
123 }
123 }
124 text: (filter) ? "+ View all (" + model.count + ")" : "- Show fewer"
124 text: (filter) ? "+ View all (" + model.count + ")" : "- Show fewer"
125 fontSize: "small"
125 fontSize: "small"
126− color: "#f3f3e7"
126+ color: Theme.palette.selected.backgroundText
127 opacity: 0.6
127 opacity: 0.6
128 style: Text.Raised
128 style: Text.Raised
129 styleColor: "black"
129 styleColor: "black"
Components/ListItems/Header.qml+1−1
@@ -45,7 +45,7 @@ Item {
45 verticalCenter: parent.verticalCenter
45 verticalCenter: parent.verticalCenter
46 }
46 }
47
47
48− color: "#f3f3e7" //at 60%
48+ color: Theme.palette.selected.backgroundText //at 60%
49 opacity: 0.6
49 opacity: 0.6
50 font.family: "Ubuntu"
50 font.family: "Ubuntu"
51 fontSize: "medium"
51 fontSize: "medium"
Components/OpenEffect.qml+9−1
@@ -19,11 +19,13 @@ import QtQuick 2.0
19Item {
19Item {
20 id: effect
20 id: effect
21 property bool enabled: topGapPx != positionPx || bottomGapPx != positionPx
21 property bool enabled: topGapPx != positionPx || bottomGapPx != positionPx
22+ property alias live: effectSource.live
22 property Item sourceItem
23 property Item sourceItem
23 property ShaderEffectSource source: ShaderEffectSource {
24 property ShaderEffectSource source: ShaderEffectSource {
25+ id: effectSource
24 sourceItem: effect.enabled ? effect.sourceItem : null
26 sourceItem: effect.enabled ? effect.sourceItem : null
25 hideSource: effect.enabled
27 hideSource: effect.enabled
26− live: effect.enabled
28+ live: false
27 sourceRect: {
29 sourceRect: {
28 if (effect.enabled) {
30 if (effect.enabled) {
29 Qt.rect(0, -effect.topOverflow, sourceItem.width, sourceItem.height + effect.topOverflow + effect.bottomOverflow)
31 Qt.rect(0, -effect.topOverflow, sourceItem.width, sourceItem.height + effect.topOverflow + effect.bottomOverflow)
@@ -33,6 +35,8 @@ Item {
33 }
35 }
34 }
36 }
35
37
38+ onEnabledChanged: if (!live && enabled) scheduleUpdate()
39+
36 /*!
40 /*!
37 \qmlproperty real positionPx
41 \qmlproperty real positionPx
38 The y coordinate of where to perform the split.
42 The y coordinate of where to perform the split.
@@ -60,6 +64,10 @@ Item {
60
64
61 property real __roundedPositionPx: Math.round(positionPx)
65 property real __roundedPositionPx: Math.round(positionPx)
62
66
67+ function scheduleUpdate() {
68+ source.scheduleUpdate();
69+ }
70+
63 ShaderEffect {
71 ShaderEffect {
64 id: top
72 id: top
65 visible: effect.enabled
73 visible: effect.enabled
Components/PageHeader.qml+1−1
@@ -90,7 +90,7 @@ Item {
90 verticalCenter: parent.verticalCenter
90 verticalCenter: parent.verticalCenter
91 }
91 }
92
92
93− color: "#f3f3e7"
93+ color: Theme.palette.selected.backgroundText
94 opacity: 0.8
94 opacity: 0.8
95 font.family: "Ubuntu"
95 font.family: "Ubuntu"
96 font.weight: Font.Light
96 font.weight: Font.Light
Components/Showable.qml+5−14
@@ -52,7 +52,7 @@ Item {
52 function show() {
52 function show() {
53 required = true;
53 required = true;
54 if (created) {
54 if (created) {
55− __reallyShow(true);
55+ __reallyShow();
56 } else {
56 } else {
57 __shouldShow = true;
57 __shouldShow = true;
58 }
58 }
@@ -60,16 +60,12 @@ Item {
60
60
61 onCreatedChanged: {
61 onCreatedChanged: {
62 if (created && __shouldShow) {
62 if (created && __shouldShow) {
63− __reallyShow(true);
63+ __reallyShow();
64 __shouldShow = false;
64 __shouldShow = false;
65 }
65 }
66 }
66 }
67
67
68− function showWithoutAnimation() {
69− __reallyShow(false);
68+ function __reallyShow() {
70− }
71−
72− function __reallyShow(animated) {
73 if (!available) {
69 if (!available) {
74 return false;
70 return false;
75 }
71 }
@@ -81,13 +77,8 @@ Item {
81 }
77 }
82
78
83 if (showAnimation != undefined) {
79 if (showAnimation != undefined) {
84− if (animated) {
85− if (!showAnimation.running) {
80+ if (!showAnimation.running) {
86− showAnimation.restart()
81+ showAnimation.restart()
87− }
88− } else {
89− showAnimation.start();
90− showAnimation.complete();
91 }
82 }
92 } else {
83 } else {
93 visible = true;
84 visible = true;
Components/Tile.qml+1−1
@@ -75,7 +75,7 @@ AbstractButton {
75 rightMargin: units.gu(1)
75 rightMargin: units.gu(1)
76 }
76 }
77
77
78− color: "#f3f3e7"
78+ color: Theme.palette.selected.backgroundText
79 opacity: 0.9
79 opacity: 0.9
80 style: Text.Raised
80 style: Text.Raised
81 styleColor: "black"
81 styleColor: "black"
Dash/Apps/RunningApplicationTile.qml+1−1
@@ -113,7 +113,7 @@ AbstractButton {
113 }
113 }
114 text: (application) ? application.name : ""
114 text: (application) ? application.name : ""
115
115
116− color: "#f3f3e7"
116+ color: Theme.palette.selected.backgroundText
117 opacity: 0.9
117 opacity: 0.9
118 style: Text.Raised
118 style: Text.Raised
119 styleColor: "black"
119 styleColor: "black"
Dash/Dash.qml−3
@@ -27,9 +27,6 @@ Showable {
27 property string showScopeOnLoaded: "home.scope"
27 property string showScopeOnLoaded: "home.scope"
28 property real contentScale: 1.0
28 property real contentScale: 1.0
29
29
30− width: units.gu(40)
31− height: units.gu(71)
32−
33 function setCurrentScope(scopeId, animate, reset) {
30 function setCurrentScope(scopeId, animate, reset) {
34 var scopeIndex = filteredScopes.findFirst(Scopes.RoleId, scopeId)
31 var scopeIndex = filteredScopes.findFirst(Scopes.RoleId, scopeId)
35
32
Dash/DashBar.qml+1−1
@@ -117,7 +117,7 @@ Item {
117
117
118 Rectangle {
118 Rectangle {
119 id: highlightLine
119 id: highlightLine
120− color: "#dd4814"
120+ color: Theme.palette.selected.foreground
121 height: parent.height
121 height: parent.height
122 anchors.bottom: parent.bottom
122 anchors.bottom: parent.bottom
123 z: 1
123 z: 1
Dash/DashContent.qml−2
@@ -20,8 +20,6 @@ import Unity 0.1
20
20
21Item {
21Item {
22 id: dashContent
22 id: dashContent
23− width: units.gu(40)
24− height: units.gu(71)
25
23
26 property var model: null
24 property var model: null
27 property var scopes: null
25 property var scopes: null
Dash/DashPreview.qml+1−1
@@ -92,7 +92,7 @@ Rectangle {
92 elide: Text.ElideRight
92 elide: Text.ElideRight
93 fontSize: "x-large"
93 fontSize: "x-large"
94 font.weight: Font.Light
94 font.weight: Font.Light
95− color: "#f3f3e7"
95+ color: Theme.palette.selected.backgroundText
96 opacity: 0.9
96 opacity: 0.9
97 text: root.title
97 text: root.title
98 style: Text.Raised
98 style: Text.Raised
Dash/Generic/GenericCarousel.qmlnew file+58
@@ -0,0 +1,58 @@
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 Ubuntu.Components 0.1
19+import "../../Components"
20+import "../../Components/IconUtil.js" as IconUtil
21+
22+Carousel {
23+ id: genericCarousel
24+
25+ tileAspectRatio: 198 / 288
26+ minimumTileWidth: units.gu(13)
27+ itemComponent: carouselDelegateGeneric
28+ selectedItemScaleFactor: 1.14
29+ cacheBuffer: 1404 // 18px * 13gu * 6
30+ height: implicitHeight + units.gu(6)
31+
32+ Component {
33+ id: carouselDelegateGeneric
34+
35+ BaseCarouselDelegate {
36+ id: item
37+
38+ UbuntuShape {
39+ anchors.fill: parent
40+ radius: "medium"
41+ borderSource: ""
42+ image: Image {
43+ asynchronous: true
44+ sourceSize { width: item.width; height: item.height }
45+ source: model ? IconUtil.from_gicon(model.icon) : ""
46+ }
47+ }
48+
49+ BorderImage {
50+ anchors.centerIn: parent
51+ opacity: 0.6
52+ source: "../../Components/graphics/non-selected.sci"
53+ width: parent.width + units.gu(1.5)
54+ height: parent.height + units.gu(1.5)
55+ }
56+ }
57+ }
58+}
Dash/Generic/GenericFilterGrid.qmlnew file+59
@@ -0,0 +1,59 @@
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 "../../Components"
19+import "../../Components/IconUtil.js" as IconUtil
20+
21+FilterGrid {
22+ id: filtergrid
23+
24+ filter: false
25+ minimumHorizontalSpacing: units.gu(0.5)
26+ delegateWidth: units.gu(11)
27+ delegateHeight: units.gu(9.5)
28+ verticalSpacing: units.gu(2)
29+
30+ property int iconWidth: units.gu(8)
31+ property int iconHeight: units.gu(7.5)
32+
33+ signal clicked(int index, var delegateItem, real itemY)
34+ signal pressAndHold(int index, var delegateItem, real itemY)
35+
36+ delegate: Tile {
37+ id: tile
38+ objectName: "delegate" + index
39+ width: filtergrid.cellWidth
40+ height: filtergrid.cellHeight
41+ text: model.title
42+ imageWidth: filtergrid.iconWidth
43+ imageHeight: filtergrid.iconHeight
44+
45+ source: IconUtil.from_gicon(model.icon)
46+
47+ fillMode: Image.PreserveAspectCrop
48+
49+ onClicked: {
50+ var data = { model: model }
51+ filtergrid.clicked(index, data, tile.y)
52+ }
53+
54+ onPressAndHold: {
55+ var data = { model: model }
56+ filtergrid.pressAndHold(index, data, tile.y)
57+ }
58+ }
59+}
Panel/Menus/IndicatorMenuWindow.qml → Dash/Generic/GenericFilterGridPotrait.qmlrenamed+9−14
@@ -15,21 +15,16 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import "../../Components"
18
19
19−Item {
20+GenericFilterGrid {
20− id: menuWindow
21+ id: filtergrid
21
22
22− property bool shown: false
23+ minimumHorizontalSpacing: units.gu(0.5)
23− property int contentHeight: height
24+ delegateWidth: units.gu(11)
24− property string headingText: name
25+ delegateHeight: units.gu(18)
25− property string name
26+ verticalSpacing: units.gu(2)
26
27
27− enabled: shown
28+ iconWidth: (width / columns) * 0.8
28− opacity: shown ? 1.0 : 0.0
29+ iconHeight: iconWidth * 16 / 11
29− Behavior on opacity { NumberAnimation {duration: shown ? 300 : 150 } }
30−
31− // don't pass any events under this screen
32− MouseArea {
33− anchors.fill: parent
34− }
35}
30}
Dash/Generic/GenericPreview.qmlnew file+84
@@ -0,0 +1,84 @@
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 Ubuntu.Components 0.1
19+import "../../Components"
20+import "../../Components/ListItems" as ListItems
21+import "../../Components/IconUtil.js" as IconUtil
22+import ".."
23+
24+DashPreview {
25+ id: genericPreview
26+ property var previewData
27+
28+ title: previewData.title
29+ url: IconUtil.from_gicon(previewData.image)
30+ previewWidthRatio: 0.6
31+
32+ buttons: GridView {
33+ id: buttons
34+ model: genericPreview.previewData.actions
35+
36+ property int numOfRows: (count + 1) / 2
37+ property int spacing: units.gu(1)
38+ height: Math.max(units.gu(4), units.gu(4)*numOfRows + spacing*(numOfRows - 1))
39+
40+ cellWidth: Math.max(units.gu(9), width / 2)
41+ cellHeight: buttonHeight + spacing
42+ property int buttonWidth: Math.max(0, width / 2 - spacing)
43+ property int buttonHeight: units.gu(4)
44+
45+ delegate: Button {
46+ width: Math.max(units.gu(4), buttons.buttonWidth)
47+ height: buttons.buttonHeight
48+ color: "#dd4814"
49+ text: modelData.displayName
50+ iconSource: modelData.iconHint
51+ iconPosition: "right"
52+ visible: true
53+ onClicked: {
54+ genericPreview.previewData.execute(modelData.id, { })
55+ }
56+ }
57+ focus: false
58+ }
59+ description: Column {
60+ spacing: units.gu(2)
61+
62+ Label {
63+ visible: text != ""
64+ fontSize: "medium"
65+ opacity: 0.6
66+ color: "white"
67+ text: previewData.subtitle
68+ style: Text.Raised
69+ styleColor: "black"
70+ wrapMode: Text.WordWrap
71+ }
72+
73+ Label {
74+ visible: text != ""
75+ fontSize: "small"
76+ opacity: 0.6
77+ color: "white"
78+ text: previewData.description
79+ style: Text.Raised
80+ styleColor: "black"
81+ wrapMode: Text.WordWrap
82+ }
83+ }
84+}
Dash/GenericScopeView.qml+141−17
@@ -22,6 +22,7 @@ import "../Components/IconUtil.js" as IconUtil
22
22
23ScopeView {
23ScopeView {
24 id: scopeView
24 id: scopeView
25+ property alias previewShown: previewLoader.onScreen
25
26
26 onIsCurrentChanged: {
27 onIsCurrentChanged: {
27 pageHeader.resetSearch();
28 pageHeader.resetSearch();
@@ -47,35 +48,54 @@ ScopeView {
47 id: categoryView
48 id: categoryView
48 anchors.fill: parent
49 anchors.fill: parent
49 model: scopeView.categories
50 model: scopeView.categories
51+ forceNoClip: previewLoader.onScreen
52+
50 onAtYEndChanged: if (atYEnd) endReached()
53 onAtYEndChanged: if (atYEnd) endReached()
51 onMovingChanged: if (moving && atYEnd) endReached()
54 onMovingChanged: if (moving && atYEnd) endReached()
52
55
53 delegate: ListItems.Base {
56 delegate: ListItems.Base {
54 highlightWhenPressed: false
57 highlightWhenPressed: false
55
58
56− FilterGrid {
59+ Loader {
57− id: filtergrid
60+ id: rendererLoader
58− model: results
59−
60 anchors {
61 anchors {
61 top: parent.top
62 top: parent.top
62 left: parent.left
63 left: parent.left
63 right: parent.right
64 right: parent.right
64 }
65 }
65
66
66− filter: false
67+ source: getRenderer(model.renderer, model.contentType)
67− minimumHorizontalSpacing: units.gu(0.5)
68+
68− delegateWidth: units.gu(11)
69+ onLoaded: {
69− delegateHeight: units.gu(18)
70+ item.model = results
70− verticalSpacing: units.gu(2)
71+ }
71−
72+
72− delegate: Tile {
73+ Connections {
73− width: filtergrid.cellWidth
74+ target: rendererLoader.item
74− height: filtergrid.cellHeight
75+ onClicked: {
75− text: title
76+ effect.positionPx = mapToItem(categoryView, 0, itemY).y
76− imageWidth: units.gu(11)
77+ scopeView.scope.activate(delegateItem.model.uri,
77− imageHeight: units.gu(16)
78+ delegateItem.model.icon,
78− source: IconUtil.from_gicon(icon)
79+ delegateItem.model.category,
80+ 0,
81+ delegateItem.model.mimetype,
82+ delegateItem.model.title,
83+ delegateItem.model.comment,
84+ delegateItem.model.dndUri,
85+ delegateItem.model.metadata)
86+ }
87+ onPressAndHold: {
88+ effect.positionPx = mapToItem(categoryView, 0, itemY).y
89+ scopeView.scope.preview( delegateItem.model.uri,
90+ delegateItem.model.icon,
91+ delegateItem.model.category,
92+ 0,
93+ delegateItem.model.mimetype,
94+ delegateItem.model.title,
95+ delegateItem.model.comment,
96+ delegateItem.model.dndUri,
97+ delegateItem.model.metadata)
98+ }
79 }
99 }
80 }
100 }
81 }
101 }
@@ -93,4 +113,108 @@ ScopeView {
93 searchEntryEnabled: true
113 searchEntryEnabled: true
94 }
114 }
95 }
115 }
116+
117+ function getRenderer(rendererId, contentType) {
118+ switch (rendererId) {
119+ case "grid": {
120+ switch (contentType) {
121+ case "video": return "Generic/GenericFilterGridPotrait.qml";
122+ default: return "Generic/GenericFilterGrid.qml";
123+ }
124+ }
125+ case "carousel": return "Generic/GenericCarousel.qml";
126+ default: return "Generic/GenericFilterGrid.qml";
127+ }
128+ }
129+
130+ OpenEffect {
131+ id: effect
132+ anchors {
133+ fill: parent
134+ bottomMargin: -bottomOverflow
135+ }
136+ sourceItem: categoryView
137+
138+ enabled: gap > 0.0
139+
140+ topGapPx: (1 - gap) * positionPx
141+ topOpacity: (1 - gap * 1.2)
142+ bottomGapPx: positionPx + gap * (targetBottomGapPx - positionPx)
143+ bottomOverflow: units.gu(20)
144+ bottomOpacity: 1 - (gap * 0.8)
145+
146+ property int targetBottomGapPx: height - units.gu(8) - bottomOverflow
147+ property real gap: previewLoader.open ? 1.0 : 0.0
148+
149+ Behavior on gap {
150+ NumberAnimation {
151+ duration: 200
152+ easing.type: Easing.InOutQuad
153+ onRunningChanged: {
154+ if (!previewLoader.open && !running) {
155+ previewLoader.onScreen = false
156+ }
157+ }
158+ }
159+ }
160+ }
161+
162+ Connections {
163+ target: scopeView.scope
164+ onPreviewReady: {
165+ previewLoader.previewData = preview
166+ previewLoader.open = true
167+ }
168+ }
169+
170+ PreviewDelegateMapper {
171+ id: previewDelegateMapper
172+ }
173+
174+ Connections {
175+ ignoreUnknownSignals: true
176+ target: previewLoader.valid ? previewLoader.item : null
177+ onClose: {
178+ previewLoader.open = false
179+ }
180+ }
181+
182+ Loader {
183+ id: previewLoader
184+ property var previewData
185+ height: effect.bottomGapPx - effect.topGapPx
186+ anchors {
187+ top: parent.top
188+ topMargin: effect.topGapPx
189+ left: parent.left
190+ right: parent.right
191+ }
192+ source: onScreen ? previewDelegateMapper.map(previewLoader.previewData.rendererName) : ""
193+
194+ property bool open: false
195+ property bool onScreen: false
196+ property bool valid: item !== null
197+
198+ onOpenChanged: {
199+ if (open) {
200+ onScreen = true
201+ }
202+ }
203+
204+ onLoaded: {
205+ item.previewData = previewLoader.previewData
206+ }
207+ }
208+
209+ // TODO: Move as InverseMouseArea to DashPreview
210+ MouseArea {
211+ enabled: previewLoader.onScreen
212+ anchors {
213+ fill: parent
214+ topMargin: effect.bottomGapPx
215+ }
216+ onClicked: {
217+ previewLoader.open = false;
218+ }
219+ }
96}
220}
Dash/Music/AlbumTile.qml+2−2
@@ -69,7 +69,7 @@ AbstractButton {
69 rightMargin: units.gu(1)
69 rightMargin: units.gu(1)
70 }
70 }
71
71
72− color: "#f3f3e7"
72+ color: Theme.palette.selected.backgroundText
73 opacity: 0.9
73 opacity: 0.9
74 style: Text.Raised
74 style: Text.Raised
75 styleColor: "black"
75 styleColor: "black"
@@ -97,7 +97,7 @@ AbstractButton {
97 rightMargin: units.gu(1)
97 rightMargin: units.gu(1)
98 }
98 }
99
99
100− color: "#f3f3e7"
100+ color: Theme.palette.selected.backgroundText
101 opacity: 0.9
101 opacity: 0.9
102 style: Text.Raised
102 style: Text.Raised
103 styleColor: "black"
103 styleColor: "black"
Dash/PreviewDelegateMapper.qmlnew file+34
@@ -0,0 +1,34 @@
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+
19+QtObject {
20+ property var d: QtObject {
21+ readonly property string genericPreview: "Generic/GenericPreview.qml"
22+ property var previewDelegateMapping: {"preview-generic": genericPreview,
23+ }
24+ }
25+
26+ function map(rendererName) {
27+ var customPreview = d.previewDelegateMapping[rendererName]
28+ if (customPreview != undefined) {
29+ return customPreview
30+ }
31+ console.debug("Renderer "+rendererName+" not found, using preview-generic")
32+ return d.genericPreview
33+ }
34+}
Dash/Video/VideoPreview.qml+3−3
@@ -48,7 +48,7 @@ DashPreview {
48 property int buttonWidth: Math.min(units.gu(22), (width - spacing) / 2)
48 property int buttonWidth: Math.min(units.gu(22), (width - spacing) / 2)
49 Button {
49 Button {
50 width: parent.buttonWidth
50 width: parent.buttonWidth
51− color: "#dd4814"
51+ color: Theme.palette.selected.foreground
52 text: nfo.ready && nfo.video.buyPrice != "" ? "Buy for " + nfo.video.buyPrice : ""
52 text: nfo.ready && nfo.video.buyPrice != "" ? "Buy for " + nfo.video.buyPrice : ""
53 visible: text != ""
53 visible: text != ""
54 iconSource: "graphics/icon_button_amazon.png"
54 iconSource: "graphics/icon_button_amazon.png"
@@ -56,7 +56,7 @@ DashPreview {
56 }
56 }
57 Button {
57 Button {
58 width: parent.buttonWidth
58 width: parent.buttonWidth
59− color: "#dd4814"
59+ color: Theme.palette.selected.foreground
60 text: nfo.ready && nfo.video.buyPrice != "" ? "Rent for " + nfo.video.rentPrice : ""
60 text: nfo.ready && nfo.video.buyPrice != "" ? "Rent for " + nfo.video.rentPrice : ""
61 visible: text != ""
61 visible: text != ""
62 iconSource: "graphics/icon_button_u1.png"
62 iconSource: "graphics/icon_button_u1.png"
@@ -73,7 +73,7 @@ DashPreview {
73
73
74 Label {
74 Label {
75 text: nfo.ready ? nfo.video.plot : ""
75 text: nfo.ready ? nfo.video.plot : ""
76− color: "#f3f3e7"
76+ color: Theme.palette.selected.backgroundText
77 opacity: .6
77 opacity: .6
78 fontSize: "medium"
78 fontSize: "medium"
79 width: parent.width
79 width: parent.width
Launcher/LauncherPanel.qml+6−5
@@ -86,6 +86,7 @@ Item {
86 height: width
86 height: width
87 anchors.centerIn: parent
87 anchors.centerIn: parent
88 source: "graphics/home.png"
88 source: "graphics/home.png"
89+ rotation: root.rotation
89 }
90 }
90 }
91 }
91 ThinDivider {
92 ThinDivider {
@@ -178,7 +179,7 @@ Item {
178 property int startY
179 property int startY
179
180
180
181
181− Item {
182+/* Item {
182 id: fakeDragItem
183 id: fakeDragItem
183 width: launcherListView.itemSize
184 width: launcherListView.itemSize
184 height: launcherListView.itemSize
185 height: launcherListView.itemSize
@@ -207,16 +208,16 @@ Item {
207 height: width
208 height: width
208 }
209 }
209 }
210 }
210−
211+*/
211−/* LauncherDelegate {
212+ LauncherDelegate {
212 id: fakeDragItem
213 id: fakeDragItem
213− visible: dndArea.draggedItem !== undefined
214+ visible: dndArea.draggedIndex >= 0
214 iconName: "gmail"
215 iconName: "gmail"
215 height: launcherListView.itemSize
216 height: launcherListView.itemSize
216 width: height
217 width: height
217 rotation: root.rotation
218 rotation: root.rotation
218 }
219 }
219−*/
220+
220 onPressed: {
221 onPressed: {
221 var realContentY = launcherListView.contentY + launcherListView.topMargin
222 var realContentY = launcherListView.contentY + launcherListView.topMargin
222 selectedItem = launcherListView.itemAt(mouseX, mouseY + realContentY)
223 selectedItem = launcherListView.itemAt(mouseX, mouseY + realContentY)
Notifications/Notification.qml+6−5
@@ -28,6 +28,7 @@ UbuntuShape {
28 property var actions
28 property var actions
29 property var notificationId
29 property var notificationId
30 property var type
30 property var type
31+ property var hints
31 property var notification
32 property var notification
32
33
33 objectName: "background"
34 objectName: "background"
@@ -117,7 +118,7 @@ UbuntuShape {
117 }
118 }
118 fontSize: "medium"
119 fontSize: "medium"
119 font.bold: true
120 font.bold: true
120− color: "#f3f3e7"
121+ color: Theme.palette.selected.backgroundText
121 elide: Text.ElideRight
122 elide: Text.ElideRight
122 }
123 }
123
124
@@ -131,7 +132,7 @@ UbuntuShape {
131 }
132 }
132 visible: body != ""
133 visible: body != ""
133 fontSize: "small"
134 fontSize: "small"
134− color: "#f3f3e7"
135+ color: Theme.palette.selected.backgroundText
135 opacity: 0.6
136 opacity: 0.6
136 wrapMode: Text.WordWrap
137 wrapMode: Text.WordWrap
137 maximumLineCount: 10
138 maximumLineCount: 10
@@ -164,7 +165,7 @@ UbuntuShape {
164 bottom: parent.bottom
165 bottom: parent.bottom
165 }
166 }
166 text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
167 text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
167− color: "#cdcdcb"
168+ gradient: UbuntuColors.greyGradient
168 onClicked: {
169 onClicked: {
169 if (actionRepeater.count > 2) {
170 if (actionRepeater.count > 2) {
170 buttonRow.expanded = !buttonRow.expanded
171 buttonRow.expanded = !buttonRow.expanded
@@ -194,7 +195,7 @@ UbuntuShape {
194 top: parent.top
195 top: parent.top
195 bottom: parent.bottom
196 bottom: parent.bottom
196 }
197 }
197− color: "#d85317"
198+ gradient: notification.hints == Notification.ButtonTint ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient
198 visible: width > 0
199 visible: width > 0
199 onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
200 onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
200 }
201 }
@@ -241,7 +242,7 @@ UbuntuShape {
241
242
242 text: loader.actionLabel
243 text: loader.actionLabel
243 height: units.gu(4)
244 height: units.gu(4)
244− color: "#cdcdcb"
245+ gradient: UbuntuColors.greyGradient
245 onClicked: notification.notification.invokeAction(loader.actionId)
246 onClicked: notification.notification.invokeAction(loader.actionId)
246 }
247 }
247 }
248 }
Notifications/Notifications.qml+1
@@ -32,6 +32,7 @@ ListView {
32 right: parent.right
32 right: parent.right
33 }
33 }
34 type: model.type
34 type: model.type
35+ hints: model.hints
35 iconSource: model.icon
36 iconSource: model.icon
36 secondaryIconSource: model.secondaryIcon
37 secondaryIconSource: model.secondaryIcon
37 summary: model.summary
38 summary: model.summary
Panel/IndicatorItem.qml+23−36
@@ -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: Theme.palette.selected.foreground
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+6−5
@@ -21,10 +21,9 @@ 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"
28
27
29 Behavior on y {NumberAnimation {duration: 300; easing.type: Easing.OutCubic} }
28 Behavior on y {NumberAnimation {duration: 300; easing.type: Easing.OutCubic} }
30
29
@@ -54,13 +53,15 @@ Item {
54 id: rowRepeater
53 id: rowRepeater
55 objectName: "rowRepeater"
54 objectName: "rowRepeater"
56 model: indicatorsModel ? indicatorsModel : undefined
55 model: indicatorsModel ? indicatorsModel : undefined
56+
57 IndicatorItem {
57 IndicatorItem {
58 id: indicatorItem
58 id: indicatorItem
59
59
60 property int ownIndex: index
60 property int ownIndex: index
61
61
62− label: model.label
62+ widgetSource: model.widgetSource
63− iconSource: model.iconSource
63+
64+ indicatorProperties : model.indicatorProperties
64 highlighted: indicatorRow.state == "reveal" || indicatorRow.state == "locked" || indicatorRow.state == "commit" ? ownIndex == indicatorRow.currentItemIndex : false
65 highlighted: indicatorRow.state == "reveal" || indicatorRow.state == "locked" || indicatorRow.state == "commit" ? ownIndex == indicatorRow.currentItemIndex : false
65 dimmed: { //See FIXME in Indicators regarding the "states" change
66 dimmed: { //See FIXME in Indicators regarding the "states" change
66 if (indicatorRow.state == "initial" || indicatorRow.state == "") {
67 if (indicatorRow.state == "initial" || indicatorRow.state == "") {
@@ -74,7 +75,7 @@ Item {
74 height: indicatorRow.height
75 height: indicatorRow.height
75 y: {
76 y: {
76 //FIXME: all indicators will be initial for now.
77 //FIXME: all indicators will be initial for now.
77− if (!highlighted && !overviewActive && (indicatorRow.state == "locked" || indicatorRow.state == "commit")) {
78+ if (!highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit")) {
78 return -indicatorRow.height
79 return -indicatorRow.height
79 } else {
80 } else {
80 return 0
81 return 0
Panel/Indicators.qml+23−49
@@ -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"
@@ -57,37 +56,22 @@ Showable {
57
56
58 onHeightChanged: {
57 onHeightChanged: {
59 // need to use handle.get_height(). As the handle height depends on indicators.height changes (but this is called first!)
58 // need to use handle.get_height(). As the handle height depends on indicators.height changes (but this is called first!)
60− var contentProgress = indicators.height - handle.get_height()
59+ var contentProgress = indicators.height - handle.get_height();
61 if (!showAnimation.running && !hideAnimation.running) {
60 if (!showAnimation.running && !hideAnimation.running) {
62 if (contentProgress <= hintValue && indicators.state == "reveal") {
61 if (contentProgress <= hintValue && indicators.state == "reveal") {
63− indicators.state = "hint"
62+ indicators.state = "hint";
64− menuContent.hideAll()
65 } else if (contentProgress > hintValue && contentProgress < lockThreshold) {
63 } else if (contentProgress > hintValue && contentProgress < lockThreshold) {
66− menuContent.showMenu()
67− indicators.state = "reveal"
64+ indicators.state = "reveal";
68 } else if (contentProgress >= lockThreshold && lockThreshold > 0) {
65 } else if (contentProgress >= lockThreshold && lockThreshold > 0) {
69− // If we've shown the overview and are closing the view with progress changes (revealer handle),
70− // we dont want to switch to a indicator menu until we hit reveal state.
71− if (menuContent.overviewActive) {
72− menuContent.showOverview()
73− }
74− else {
75− menuContent.showMenu()
76− }
77− indicators.state = "locked"
66+ indicators.state = "locked";
78 }
67 }
79 }
68 }
80
69
81 if (contentProgress == 0) {
70 if (contentProgress == 0) {
82− menuContent.releaseContent()
71+ menuContent.releaseContent();
83 }
72 }
84 }
73 }
85
74
86− function openOverview() {
87− indicatorRow.currentItem = null
88− menuContent.showOverview()
89− }
90−
91 function calculateCurrentItem(xValue, useBuffer) {
75 function calculateCurrentItem(xValue, useBuffer) {
92 var rowCoordinates
76 var rowCoordinates
93 var itemCoordinates
77 var itemCoordinates
@@ -95,7 +79,7 @@ Showable {
95 var distanceFromRightEdge
79 var distanceFromRightEdge
96 var bufferExceeded = false
80 var bufferExceeded = false
97
81
98− if (indicators.state == "commit" || indicators.state == "locked" || showAnimation.running || hideAnimation.running) return
82+ if (indicators.state == "commit" || indicators.state == "locked" || showAnimation.running || hideAnimation.running) return;
99
83
100 /*
84 /*
101 If user drags the indicator handle bar down a distance hintValue or less, this is 0.
85 If user drags the indicator handle bar down a distance hintValue or less, this is 0.
@@ -104,14 +88,14 @@ Showable {
104 */
88 */
105 var verticalProgress =
89 var verticalProgress =
106 MathLocal.clamp((indicators.height - handle.height - hintValue) /
90 MathLocal.clamp((indicators.height - handle.height - hintValue) /
107− (lockThreshold - hintValue), 0, 1)
91+ (lockThreshold - hintValue), 0, 1);
108
92
109 /*
93 /*
110 Percentage of an indicator icon's width the user's press can stray horizontally from the
94 Percentage of an indicator icon's width the user's press can stray horizontally from the
111 focused icon before we change focus to another icon. E.g. a value of 0.5 means you must
95 focused icon before we change focus to another icon. E.g. a value of 0.5 means you must
112 go right a distance of half an icon's width before focus moves to the icon on the right
96 go right a distance of half an icon's width before focus moves to the icon on the right
113 */
97 */
114− var maxBufferThreshold = 0.5
98+ var maxBufferThreshold = 0.5;
115
99
116 /*
100 /*
117 To help users find the indicator of their choice while opening the indicators, we add logic to add a
101 To help users find the indicator of their choice while opening the indicators, we add logic to add a
@@ -128,12 +112,12 @@ Showable {
128 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
112 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
129 distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width)
113 distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width)
130 if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) {
114 if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) {
131− bufferExceeded = true
115+ bufferExceeded = true;
132 } else {
116 } else {
133 if (indicatorRow.currentItemIndex < currentItem.ownIndex && distanceFromRightEdge < (1 - effectiveBufferThreshold)) {
117 if (indicatorRow.currentItemIndex < currentItem.ownIndex && distanceFromRightEdge < (1 - effectiveBufferThreshold)) {
134− bufferExceeded = true
118+ bufferExceeded = true;
135 } else if (indicatorRow.currentItemIndex > currentItem.ownIndex && distanceFromRightEdge > effectiveBufferThreshold) {
119 } else if (indicatorRow.currentItemIndex > currentItem.ownIndex && distanceFromRightEdge > effectiveBufferThreshold) {
136− bufferExceeded = true
120+ bufferExceeded = true;
137 }
121 }
138 }
122 }
139 if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItem < 0 || indicatorRow.currentItem == null) {
123 if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItem < 0 || indicatorRow.currentItem == null) {
@@ -174,8 +158,7 @@ Showable {
174 bottom: parent.bottom
158 bottom: parent.bottom
175 }
159 }
176 indicatorsModel: indicatorsModel
160 indicatorsModel: indicatorsModel
177− animate: false
178− clip: indicators.partiallyOpened
161+ clip: !indicators.fullyOpened
179
162
180 onMenuSelected: {
163 onMenuSelected: {
181 indicatorRow.setItem(index)
164 indicatorRow.setItem(index)
@@ -211,7 +194,7 @@ Showable {
211 clip: height < handleImage.height
194 clip: height < handleImage.height
212
195
213 function get_height() {
196 function get_height() {
214− return Math.max(Math.min(handleImage.height, indicators.height - handleImage.height), 0)
197+ return Math.max(Math.min(handleImage.height, indicators.height - handleImage.height), 0);
215 }
198 }
216
199
217 BorderImage {
200 BorderImage {
@@ -266,15 +249,13 @@ Showable {
266 height: indicators.panelHeight
249 height: indicators.panelHeight
267 indicatorsModel: indicatorsModel
250 indicatorsModel: indicatorsModel
268 state: indicators.state
251 state: indicators.state
269− overviewActive: menuContent.overviewActive
270
252
271 onCurrentItemIndexChanged: menuContent.currentIndex = currentItemIndex
253 onCurrentItemIndexChanged: menuContent.currentIndex = currentItemIndex
272
254
273 }
255 }
274
256
275− ChewieUI.PluginModel {
257+ IndicatorsDataModel {
276 id: indicatorsModel
258 id: indicatorsModel
277− Component.onCompleted: load()
278 }
259 }
279
260
280 Connections {
261 Connections {
@@ -282,9 +263,11 @@ Showable {
282 onRunningChanged: {
263 onRunningChanged: {
283 if (hideAnimation.running) {
264 if (hideAnimation.running) {
284 indicators.state = "initial"
265 indicators.state = "initial"
285− menuContent.hideAll()
286 } else {
266 } else {
267+ if (state == "initial") {
287− if (state == "initial") indicatorRow.setDefaultItem()
268+ indicatorRow.setDefaultItem();
269+ menuContent.releaseContent();
270+ }
288 }
271 }
289 }
272 }
290 }
273 }
@@ -292,14 +275,8 @@ Showable {
292 target: showAnimation
275 target: showAnimation
293 onRunningChanged: {
276 onRunningChanged: {
294 if (showAnimation.running) {
277 if (showAnimation.running) {
295− if (indicators.state == "initial") {
296− openOverview()
297− }
298− else {
299− indicators.calculateCurrentItem(dragHandle.touchX, false)
278+ indicators.calculateCurrentItem(dragHandle.touchX, false);
300− menuContent.showMenu()
301− }
302− indicators.state = "commit"
279+ indicators.state = "commit";
303 }
280 }
304 }
281 }
305 }
282 }
@@ -307,8 +284,8 @@ Showable {
307 Connections {
284 Connections {
308 target: dragHandle
285 target: dragHandle
309 onTouchXChanged: {
286 onTouchXChanged: {
310− var buffer = dragHandle.dragging ? true : false
287+ var buffer = dragHandle.dragging ? true : false;
311− indicators.calculateCurrentItem(dragHandle.touchX, buffer)
288+ indicators.calculateCurrentItem(dragHandle.touchX, buffer);
312 }
289 }
313 }
290 }
314
291
@@ -343,8 +320,7 @@ Showable {
343
320
344 onStatusChanged: {
321 onStatusChanged: {
345 if (status === DirectionalDragArea.Recognized) {
322 if (status === DirectionalDragArea.Recognized) {
346− menuContent.hideAll()
347− menuContent.activateContent()
323+ menuContent.activateContent();
348 }
324 }
349 }
325 }
350 }
326 }
@@ -372,7 +348,6 @@ Showable {
372 State {
348 State {
373 name: "reveal"
349 name: "reveal"
374 extend: "hint"
350 extend: "hint"
375− PropertyChanges { target: menuContent; animate: true }
376 StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
351 StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
377 },
352 },
378 State {
353 State {
@@ -394,7 +369,6 @@ Showable {
394 },
369 },
395 State {
370 State {
396 name: "reveal"
371 name: "reveal"
397− PropertyChanges { target: menuContent; animate: true }
398 StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
372 StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
399 },
373 },
400 State {
374 State {
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: Theme.palette.selected.backgroundText
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: Theme.palette.selected.backgroundText
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: Theme.palette.selected.backgroundText
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: Theme.palette.selected.backgroundText
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+79
@@ -0,0 +1,79 @@
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+ }
53+ }
54+
55+ ICNetwork.NetworkAgent {
56+ id: networkAgent
57+
58+ onSecretRequested: {
59+ _network.push(passwordPageComponent, {"token": token});
60+ }
61+ }
62+
63+ function start()
64+ {
65+ push(_mainPage);
66+ _pluginItem.start();
67+ }
68+
69+ function stop()
70+ {
71+ clear();
72+ _pluginItem.stop();
73+ }
74+
75+ function reset()
76+ {
77+ _pluginItem.reset();
78+ }
79+}
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+34−86
@@ -16,50 +16,32 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19−import "Menus"
19+import Unity.Indicators 0.1 as Indicators
20import "../Components"
20import "../Components"
21
21
22Rectangle {
22Rectangle {
23 id: content
23 id: content
24
24
25 property QtObject indicatorsModel: null
25 property QtObject indicatorsModel: null
26− property bool animate: true // FIXME: Remove. This doesnt seem to be being used and it's referenced in Indicators.
27− property bool overviewActive: true // "state of the menu"
28− property bool __shown: false
29 property bool __contentActive: false
26 property bool __contentActive: false
30 property alias currentIndex : menus.currentIndex
27 property alias currentIndex : menus.currentIndex
31− property color backgroundColor: "#221e1c"
28+ property color backgroundColor: "#221e1c" // FIXME not in palette yet
32− property int contentReleaseInterval: 5000
29+ property int contentReleaseInterval: 20000
33
30
34 width: units.gu(40)
31 width: units.gu(40)
35 height: units.gu(42)
32 height: units.gu(42)
36 color: backgroundColor
33 color: backgroundColor
37− enabled: __shown
38
34
39 signal menuSelected(int index)
35 signal menuSelected(int index)
40
36
41− function showMenu() {
42− __shown = true
43− overviewActive = false
44− }
45−
46− function showOverview() {
47− __shown = true
48− overviewActive = true
49− }
50−
51− function hideAll() {
52− __shown = false
53− }
54−
55 function activateContent() {
37 function activateContent() {
56− contentReleaseTimer.stop()
38+ contentReleaseTimer.stop();
57− __contentActive = true
39+ __contentActive = true;
58 }
40 }
59
41
60 function releaseContent() {
42 function releaseContent() {
61 if (__contentActive)
43 if (__contentActive)
62− contentReleaseTimer.restart()
44+ contentReleaseTimer.restart();
63 }
45 }
64
46
65 ListView {
47 ListView {
@@ -71,7 +53,6 @@ Rectangle {
71 width: parent.width
53 width: parent.width
72
54
73 spacing: units.gu(0.5)
55 spacing: units.gu(0.5)
74− opacity: !overviewActive && __shown ? 1 : 0
75 enabled: opacity != 0
56 enabled: opacity != 0
76 orientation: ListView.Horizontal
57 orientation: ListView.Horizontal
77 model: indicatorsModel
58 model: indicatorsModel
@@ -82,47 +63,36 @@ Rectangle {
82
63
83 delegate: Loader {
64 delegate: Loader {
84 clip: true
65 clip: true
85− property bool contentActive: content.__contentActive
66+ property bool contentActive: content.__contentActive && menuActivator.content[index].active
86
67
87 onContentActiveChanged: {
68 onContentActiveChanged: {
88 if (contentActive && item) {
69 if (contentActive && item) {
89− item.start()
70+ item.start();
90 } else if (!contentActive && item) {
71 } else if (!contentActive && item) {
91− item.stop()
72+ item.stop();
92 }
73 }
93 }
74 }
94
75
95 width: menus.width
76 width: menus.width
96 height: menus.height
77 height: menus.height
97− sourceComponent: component
78+ source: pageSource
98− visible: content.__shown
99 onVisibleChanged: {
79 onVisibleChanged: {
100 // Reset the indicator states
80 // Reset the indicator states
101 if (!visible && item && item["reset"]) {
81 if (!visible && item && item["reset"]) {
102− item.reset()
82+ item.reset();
103 }
83 }
104 }
84 }
105 asynchronous: true
85 asynchronous: true
106
86
107− onStatusChanged: {
87+ 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) {
88+ for(var pName in indicatorProperties) {
113− if (item.hasOwnProperty(pName)) {
89+ if (item.hasOwnProperty(pName)) {
114− item[pName] = initialProperties[pName]
90+ item[pName] = indicatorProperties[pName];
115− }
116− }
117− if (contentActive && menus.visible) {
118− item.start()
119 }
91 }
120 }
92 }
121− }
93+ if (contentActive && menus.visible) {
122−
94+ item.start();
123− // FIXME: QTBUG-30632 - asynchronous loader crashes when changing index quickly.
95+ }
124− Component.onDestruction: {
125− active = false;
126 }
96 }
127
97
128 // Need to use a binding because the handle height changes.
98 // Need to use a binding because the handle height changes.
@@ -133,40 +103,6 @@ Rectangle {
133 value: handle.height
103 value: handle.height
134 }
104 }
135 }
105 }
136−
137− Behavior on opacity { NumberAnimation {duration: 200} }
138− }
139−
140− Overview {
141− id: overview
142− objectName: "overview"
143−
144− anchors.top: header.bottom
145− anchors.bottom: parent.bottom
146− // FIXME: Dont know why we're using handle height (introduces dep).. Check with design about bottom margin
147− anchors.bottomMargin: handle.height
148−
149− width: content.width
150− indicatorsModel: content.indicatorsModel
151− enabled: content.overviewActive && content.__shown
152− opacity: content.overviewActive && content.__shown ? 1 : 0
153− Behavior on opacity {NumberAnimation{duration: 200}}
154− visible: opacity != 0
155−
156− onMenuSelected: {
157− var storedDuration = menus.highlightMoveDuration
158− var storedVelocity = menus.highlightMoveVelocity
159− menus.highlightMoveDuration = 0
160− menus.highlightMoveVelocity = 100000
161−
162− menus.currentIndex = modelIndex
163− content.overviewActive = false
164−
165− menus.highlightMoveDuration = storedDuration
166− menus.highlightMoveVelocity = storedVelocity
167−
168− content.menuSelected(modelIndex)
169− }
170 }
106 }
171
107
172 Rectangle {
108 Rectangle {
@@ -189,9 +125,11 @@ Rectangle {
189 left: parent.left
125 left: parent.left
190 right: parent.right
126 right: parent.right
191 }
127 }
128+ text: {
192− text: content.overviewActive ? i18n.tr("Device") : (indicatorsModel && menus.currentIndex >= 0 && menus.currentIndex < indicatorsModel.count) ? indicatorsModel.get(menus.currentIndex).title : ""
129+ if (indicatorsModel && menus.currentIndex >= 0 && menus.currentIndex < indicatorsModel.count)
193− opacity: __shown ? 1 : 0
130+ return indicatorsModel.data(menus.currentIndex, Indicators.IndicatorsModelRole.Title);
194− Behavior on opacity {NumberAnimation{duration: 100}}
131+ return "";
132+ }
195 }
133 }
196 }
134 }
197
135
@@ -199,6 +137,16 @@ Rectangle {
199 id: contentReleaseTimer
137 id: contentReleaseTimer
200
138
201 interval: contentReleaseInterval
139 interval: contentReleaseInterval
140+ onTriggered: {
202− onTriggered: __contentActive = false
141+ __contentActive = false;
142+ menuActivator.clear();
143+ }
144+ }
145+
146+ Indicators.MenuContentActivator {
147+ id: menuActivator
148+ running: content.__contentActive
149+ baseIndex: content.currentIndex
150+ count: indicatorsModel.count
203 }
151 }
204}
152}
Panel/Menus/Overview.qmldeleted−70
@@ -1,70 +0,0 @@
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 Ubuntu.Components 0.1
19−import "../../Components/ListItems" as ListItems
20−import "Overview"
21−
22−IndicatorMenuWindow {
23− id: overview
24−
25− property QtObject indicatorsModel: null
26−
27− signal menuSelected(int modelIndex)
28−
29− VisualItemModel {
30− id: itemModel
31−
32− FlightModeWidget {
33− anchors {
34− left: parent ? parent.left : undefined
35− right: parent ? parent.right : undefined
36− }
37− height: units.gu(8)
38−
39− ListItems.ThinDivider {
40− anchors {
41− bottom: parent.bottom
42− bottomMargin: -units.dp(1)
43− }
44− }
45− }
46−
47− VolumeWidget {
48− anchors {
49− left: parent ? parent.left : undefined
50− right: parent ? parent.right : undefined
51− }
52− height: units.gu(10)
53− }
54−
55− OverviewGrid {
56− model: indicatorsModel
57− anchors {
58− left: parent ? parent.left : undefined
59− right: parent ? parent.right : undefined
60− }
61− }
62− }
63−
64− ListView {
65− id: listView
66− anchors.fill: parent
67− model: itemModel
68− interactive: false
69− }
70−}
Panel/Menus/Overview/FlightModeWidget.qmldeleted−60
@@ -1,60 +0,0 @@
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 Ubuntu.Components 0.1
19−
20−Item {
21− id: flightModeWidget
22−
23− Image {
24− id: flightIcon
25− source: "graphics/plane_icon.png"
26− anchors {
27− left: parent.left
28− leftMargin: units.gu(2)
29− verticalCenter: parent.verticalCenter
30− }
31− width: units.gu(4)
32− height: units.gu(4)
33− }
34−
35− Label {
36− anchors {
37− left: flightIcon.right
38− right: flightModeSwitch.left
39− margins: units.gu(2)
40− verticalCenter: parent.verticalCenter
41− }
42− text: i18n.tr("Flight mode")
43− color: "#f3f3e7"
44− style: Text.Raised
45− styleColor: "black"
46− opacity: 0.6;
47− fontSize: "medium"
48− elide: Text.ElideRight
49− horizontalAlignment: Text.AlignLeft
50− }
51−
52− Switch {
53− id: flightModeSwitch
54− anchors {
55− right: parent.right
56− rightMargin: units.gu(2)
57− verticalCenter: parent.verticalCenter
58− }
59− }
60−}
Panel/Menus/Overview/OverviewGrid.qmldeleted−144
@@ -1,144 +0,0 @@
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 Ubuntu.Components 0.1
19−
20−import "../../../Components/ListItems" as ListItems
21−
22−Item {
23− id: overviewGrid
24−
25− height: childrenRect.height
26−
27− property var model
28−
29− UbuntuShape {
30− id: gridBackground
31− anchors.fill: grid
32− color: "#282421"
33− radius: "medium"
34− }
35−
36− GridView {
37− id: grid
38− objectName: "overviewGrid"
39−
40− property int columnCount: 3
41− property int rowCount: Math.ceil(model.count / columnCount)
42−
43− anchors {
44− top: parent.top
45− left: parent.left
46− right: parent.right
47− topMargin: units.gu(3)
48− leftMargin: units.gu(2)
49− rightMargin: units.gu(2)
50− }
51− height: cellWidth * rowCount
52− cellWidth: Math.floor((width) / columnCount)
53− cellHeight: cellWidth
54− model: overviewGrid.model
55− visible: opacity != 0
56− interactive: false
57− delegate:
58− AbstractButton {
59− objectName: "overviewGridButton" + index
60− width: grid.cellWidth
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−
77− Label {
78− id: labelIcon
79− text: label
80− color: "#f3f3e7"
81− opacity: 0.8
82− font.family: "Ubuntu"
83− fontSize: "large"
84− anchors {
85− centerIn: parent
86− verticalCenterOffset: -units.gu(1)
87− }
88− }
89−
90− Label {
91− text: title
92− color: "#f3f3e7"
93− fontSize: "small"
94− anchors {
95− left: parent.left
96− right: parent.right
97− bottom: parent.bottom
98− leftMargin: units.gu(0.5)
99− rightMargin: units.gu(0.5)
100− bottomMargin: units.gu(1.5)
101− }
102− elide: Text.ElideRight
103− horizontalAlignment: Text.AlignHCenter
104−
105− }
106− onClicked: overview.menuSelected(index)
107− }
108− }
109−
110− Item {
111− id: gridOverlay
112− anchors.fill: grid
113−
114− Column {
115− anchors {
116− left: parent.left
117− right: parent.right
118− }
119− spacing: grid.cellHeight
120− y: grid.cellHeight - units.dp(1)
121− Repeater {
122− model: grid.rowCount - 1
123− ListItems.ThinDivider {
124− anchors.margins: units.dp(1)
125− }
126− }
127− }
128−
129− Row {
130− anchors {
131− top: parent.top
132− bottom: parent.bottom
133− }
134− spacing: grid.cellWidth - units.dp(1)
135− x: grid.cellWidth - units.dp(1)
136− Repeater {
137− model: grid.columnCount - 1
138− ListItems.VerticalThinDivider {
139− anchors.margins: units.dp(1)
140− }
141− }
142− }
143− }
144−}
Panel/Menus/Overview/VolumeWidget.qmldeleted−88
@@ -1,88 +0,0 @@
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 Ubuntu.Components 0.1
19−import "../../../Components/"
20−
21−Item {
22− id: volumeWidget
23−
24− Image {
25− id: minVolumeIcon
26− objectName: "minVolumeIcon"
27− source: "graphics/sound_off_icon.png"
28− anchors {
29− left: parent.left
30− leftMargin: units.gu(2)
31− verticalCenter: parent.verticalCenter
32− }
33− width: units.gu(4)
34− height: units.gu(4)
35−
36− MouseArea {
37− anchors.fill: parent
38− onClicked: volumeControl.volumeDown();
39− }
40− }
41−
42− Slider {
43− id: slider
44− objectName: "volumeSlider"
45− anchors {
46− left: minVolumeIcon.right
47− right: maxVolumeIcon.left
48− margins: units.gu(1)
49− verticalCenter: parent.verticalCenter
50− }
51− live: false
52− minimumValue: 0
53− maximumValue: 100
54− value: 50
55−
56− onValueChanged: {
57− volumeControl.volume = value;
58− }
59−
60− Binding {
61− target: slider
62− property: "value"
63− value: volumeControl.volume
64− }
65−
66− function formatValue(v) {
67− return ""
68− }
69− }
70−
71− Image {
72− id: maxVolumeIcon
73− objectName: "maxVolumeIcon"
74− source: "graphics/sound_on_icon.png"
75− anchors {
76− right: parent.right
77− rightMargin: units.gu(2)
78− verticalCenter: parent.verticalCenter
79− }
80− width: units.gu(4)
81− height: units.gu(4)
82−
83− MouseArea {
84− anchors.fill: parent
85− onClicked: volumeControl.volumeUp();
86− }
87− }
88−}
Panel/Menus/Overview/graphics/plane_icon@18.pngdeleted

Binary file not shown.

Panel/Menus/Overview/graphics/sound_off_icon@18.pngdeleted

Binary file not shown.

Panel/Menus/Overview/graphics/sound_on_icon@18.pngdeleted

Binary file not shown.

Panel/graphics/time_and_date@18.pngnew file

Binary file not shown.

Shell.qml+4−5
@@ -36,8 +36,8 @@ FocusScope {
36
36
37 // this is only here to select the width / height of the window if not running fullscreen
37 // this is only here to select the width / height of the window if not running fullscreen
38 property bool tablet: false
38 property bool tablet: false
39− width: tablet ? units.gu(160) : units.gu(40)
39+ width: tablet ? units.gu(160) : ApplicationArguments.hasGeometry() ? ApplicationArguments.width() : units.gu(40)
40− height: tablet ? units.gu(100) : units.gu(71)
40+ height: tablet ? units.gu(100) : ApplicationArguments.hasGeometry() ? ApplicationArguments.height() : units.gu(71)
41
41
42 property real edgeSize: units.gu(2)
42 property real edgeSize: units.gu(2)
43 property url default_background: shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg"
43 property url default_background: shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg"
@@ -62,6 +62,8 @@ FocusScope {
62 property var applicationManager: ApplicationManagerWrapper {}
62 property var applicationManager: ApplicationManagerWrapper {}
63
63
64 Component.onCompleted: {
64 Component.onCompleted: {
65+ Theme.name = "Ubuntu.Components.Themes.SuruGradient"
66+
65 applicationManager.sideStageEnabled = Qt.binding(function() { return sideStage.enabled })
67 applicationManager.sideStageEnabled = Qt.binding(function() { return sideStage.enabled })
66
68
67 // FIXME: if application focused before shell starts, shell draws on top of it only.
69 // FIXME: if application focused before shell starts, shell draws on top of it only.
@@ -263,9 +265,6 @@ FocusScope {
263 function show() {
265 function show() {
264 stages.show();
266 stages.show();
265 }
267 }
266− function showWithoutAnimation() {
267− stages.showWithoutAnimation();
268− }
269 function hide() {
268 function hide() {
270 }
269 }
271
270
build+2−5
@@ -36,17 +36,14 @@ BUILD_TYPE="debug"
36[ $# -eq 1 ] && BUILD_TYPE="$1"
36[ $# -eq 1 ] && BUILD_TYPE="$1"
37
37
38install_dependencies() {
38install_dependencies() {
39− [ -f /etc/apt/sources.list.d/phablet-team-desktop-deps-${DISTRIB_CODENAME}.list ] || sudo add-apt-repository ppa:phablet-team/desktop-deps || exit 1
39+ [ -f /etc/apt/sources.list.d/ubuntu-unity-next-${DISTRIB_CODENAME}.list ] || sudo add-apt-repository ppa:ubuntu-unity/next || exit 1
40− [ -f /etc/apt/sources.list.d/canonical-qt5-edgers-qt5-proper-${DISTRIB_CODENAME}.list ] || sudo add-apt-repository ppa:canonical-qt5-edgers/qt5-proper || exit 2;
41− [ -f /etc/apt/sources.list.d/ubuntu-sdk-team-ppa-${DISTRIB_CODENAME}.list ] || sudo add-apt-repository ppa:ubuntu-sdk-team/ppa || exit 3
42 sudo apt-get update || exit 4
40 sudo apt-get update || exit 4
43 echo "Installing Unity 8 dependencies.."
41 echo "Installing Unity 8 dependencies.."
44 sudo apt-get install devscripts \
42 sudo apt-get install devscripts \
45 equivs \
43 equivs \
44+ qmenumodel-qml \
46 qtdeclarative5-ubuntu-ui-toolkit-plugin \
45 qtdeclarative5-ubuntu-ui-toolkit-plugin \
47 qtdeclarative5-dee-plugin \
46 qtdeclarative5-dee-plugin \
48− indicators-client \
49− indicators-client-plugin-* \
50 ubuntu-mobile-icons \
47 ubuntu-mobile-icons \
51 unity-notifications-impl-1 \
48 unity-notifications-impl-1 \
52 unity-scope-home \
49 unity-scope-home \
cmake/modules/Plugins.cmake+25−15
@@ -1,17 +1,12 @@
1−# Creates targets for copying and installing qmlfiles and generating the qmltypes file for a plugin
1+# Creates target for copying and installing qmlfiles
2#
2#
3−# export_qmlplugin(plugin version sub_path [TARGETS target1 [target2 ...]])
3+# export_qmlfiles(plugin sub_path)
4#
4#
5−# TARGETS additional install targets (eg the plugin shared object)
6#
5#
7−# Two targets will be created:
6+# Target to be created:
8# - plugin-qmlfiles - Copies the qml files (*.qml, *.js, qmldir) into the shadow build folder.
7# - plugin-qmlfiles - Copies the qml files (*.qml, *.js, qmldir) into the shadow build folder.
9−# - plugin-qmltypes - Generates the qmltypes file in the shadow build folder.
10−
11
8
12−macro(export_qmlplugin PLUGIN VERSION PLUGIN_SUBPATH)
9+macro(export_qmlfiles PLUGIN PLUGIN_SUBPATH)
13− set(multi_value_keywords TARGETS)
14− cmake_parse_arguments(qmlplugin "" "" "${multi_value_keywords}" ${ARGN})
15
10
16 file(GLOB QMLFILES
11 file(GLOB QMLFILES
17 *.qml
12 *.qml
@@ -25,17 +20,32 @@ macro(export_qmlplugin PLUGIN VERSION PLUGIN_SUBPATH)
25 DEPENDS ${QMLFILES}
20 DEPENDS ${QMLFILES}
26 )
21 )
27
22
23+ # install the qmlfiles file.
24+ install(FILES ${QMLFILES}
25+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
26+ )
27+endmacro(export_qmlfiles)
28+
29+
30+# Creates target for generating the qmltypes file for a plugin and installs plugin files
31+#
32+# export_qmlplugin(plugin version sub_path [TARGETS target1 [target2 ...]])
33+#
34+# TARGETS additional install targets (eg the plugin shared object)
35+#
36+# Target to be created:
37+# - plugin-qmltypes - Generates the qmltypes file in the shadow build folder.
38+
39+macro(export_qmlplugin PLUGIN VERSION PLUGIN_SUBPATH)
40+ set(multi_value_keywords TARGETS)
41+ cmake_parse_arguments(qmlplugin "" "" "${multi_value_keywords}" ${ARGN})
42+
28 # create the plugin.qmltypes file
43 # create the plugin.qmltypes file
29 add_custom_target(${PLUGIN}-qmltypes ALL
44 add_custom_target(${PLUGIN}-qmltypes ALL
30 COMMAND qmlplugindump -notrelocatable ${PLUGIN} ${VERSION} ${CMAKE_BINARY_DIR}/plugins > ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
45 COMMAND qmlplugindump -notrelocatable ${PLUGIN} ${VERSION} ${CMAKE_BINARY_DIR}/plugins > ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
31 )
46 )
32 add_dependencies(${PLUGIN}-qmltypes ${PLUGIN}-qmlfiles ${qmlplugin_TARGETS})
47 add_dependencies(${PLUGIN}-qmltypes ${PLUGIN}-qmlfiles ${qmlplugin_TARGETS})
33
48
34− # install the qmldir file.
35− install(FILES ${QMLFILES}
36− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
37− )
38−
39 # install the qmltypes file.
49 # install the qmltypes file.
40 install(FILES ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
50 install(FILES ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
41 DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
51 DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
@@ -45,4 +55,4 @@ macro(export_qmlplugin PLUGIN VERSION PLUGIN_SUBPATH)
45 install(TARGETS ${qmlplugin_TARGETS}
55 install(TARGETS ${qmlplugin_TARGETS}
46 DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
56 DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
47 )
57 )
48−endmacro(export_qmlplugin)
58+endmacro(export_qmlplugin)
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/changelog+99
@@ -1,3 +1,102 @@
1+unity8 (7.81.3+13.10.20130718ubuntu.unity.next-0ubuntu1) saucy; urgency=low
2+
3+ [ Andrea Cimitan ]
4+ * Add support for the colour palette.
5+
6+ [ Omer Akram ]
7+ * fix the calendar icon in the launcher. (LP: #1201905)
8+
9+ [ Nick Dedekind ]
10+ * Export indicator plugin symbols using Q_DECL_EXPORT.
11+
12+ [ Ying-Chun Liu ]
13+ * Don't include .moc in previewbindingstest.cpp.
14+
15+ [ Ubuntu daily release ]
16+ * Automatic snapshot from revision 118 (ubuntu-unity/next)
17+
18+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 18 Jul 2013 06:07:00 +0000
19+
20+unity8 (7.81.3+13.10.20130717ubuntu.unity.next-0ubuntu1) saucy; urgency=low
21+
22+ [ Daniel d'Andrada ]
23+ * Remove dead code: Showable::showWithoutAnimation.
24+
25+ [ Nick Dedekind ]
26+ * Split Plugins export macro into export_qmlfiles and
27+ export_qmlplugins. Added qmltypes to indicators plugin.
28+
29+ [ Ubuntu daily release ]
30+ * Automatic snapshot from revision 112 (ubuntu-unity/next)
31+
32+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 17 Jul 2013 03:14:49 +0000
33+
34+unity8 (7.81.3+13.10.20130716ubuntu.unity.next-0ubuntu1) saucy; urgency=low
35+
36+ [ Pete Woods ]
37+ * Rename the demo user "single" to "phablet" Fix the infographics on
38+ the device At the moment the mock lightdm backend we are using says
39+ the current user is called "single", while in reality the processes
40+ all run as the "phablet" user.
41+
42+ [ Michał Sawicz ]
43+ * Only use ppa:ubuntu-unity/next and clean build scripts and CODING,
44+ accordingly.
45+ * Do not recommend indicator-power and indicator-sound. On device
46+ they're provided by lp:indicator-server for the time being.
47+ * Fix the Network page to provide the correct token. (LP: #1201529)
48+
49+ [ Ubuntu daily release ]
50+ * Automatic snapshot from revision 109 (ubuntu-unity/next)
51+
52+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 16 Jul 2013 02:32:03 +0000
53+
54+unity8 (7.81.3+13.10.20130714ubuntu.unity.next-0ubuntu1) saucy; urgency=low
55+
56+ [ Michael Terry ]
57+ * Change Ok to OK. (LP: #1131842)
58+
59+ [ Ubuntu daily release ]
60+ * Automatic snapshot from revision 104 (ubuntu-unity/next)
61+
62+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Sun, 14 Jul 2013 02:31:57 +0000
63+
64+unity8 (7.81.3+13.10.20130712ubuntu.unity.next-0ubuntu1) saucy; urgency=low
65+
66+ [ Michael Zanetti ]
67+ * Make use of the launcher API defined in unity-api and separate the
68+ model from the backend.
69+
70+ [ Michał Sawicz ]
71+ * Issue wrap-and-sort -abt on debian/.
72+
73+ [ Nick Dedekind ]
74+ * Moved indicators-client code into unity8. (LP: #1191132, #1191822)
75+
76+ [ Ubuntu daily release ]
77+ * Automatic snapshot from revision 102 (ubuntu-unity/next)
78+
79+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 12 Jul 2013 02:31:59 +0000
80+
81+unity8 (7.81.3+13.10.20130711ubuntu.unity.next-0ubuntu1) saucy; urgency=low
82+
83+ [ Michael Zanetti ]
84+ * invert the home button too in case the whole panel is inverted. (LP:
85+ #1199622)
86+
87+ [ Michał Sawicz ]
88+ * Make the OpenEffect non-live by default to improve performance. (LP:
89+ #1124584)
90+
91+ [ Ying-Chun Liu ]
92+ * Add Generic Preview. Modify GenericScopeView to support activate and
93+ preview.
94+
95+ [ Ubuntu daily release ]
96+ * Automatic snapshot from revision 98 (ubuntu-unity/next)
97+
98+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 11 Jul 2013 03:00:53 +0000
99+
1unity8 (7.81.3+13.10.20130710ubuntu.unity.next-0ubuntu1) saucy; urgency=low
100unity8 (7.81.3+13.10.20130710ubuntu.unity.next-0ubuntu1) saucy; urgency=low
2
101
3 [ Michael Zanetti ]
102 [ Michael Zanetti ]
debian/control+52−40
@@ -4,23 +4,27 @@ Priority: optional
4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
5Build-Depends: cmake,
5Build-Depends: cmake,
6 debhelper (>= 9),
6 debhelper (>= 9),
7− libjson-perl,
8 libdee-qt5-dev (>= 3.0),
7 libdee-qt5-dev (>= 3.0),
9 libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],
8 libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],
10 libgl1-mesa-dri,
9 libgl1-mesa-dri,
11 libgles2-mesa-dev[armhf],
10 libgles2-mesa-dev[armhf],
12 libhud-client2-dev,
11 libhud-client2-dev,
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-core-6.0-dev (<< 7.80),
16 libunity-api-dev (>= 7.80.3),
18 libunity-api-dev (>= 7.80.3),
19+ libunity-core-6.0-dev (<< 7.80),
17 libunity-dev (>= 7.0.3),
20 libunity-dev (>= 7.0.3),
21+ libunity-scopes-json-def-phone,
18 libusermetricsoutput1-dev,
22 libusermetricsoutput1-dev,
19 libxcb1-dev,
23 libxcb1-dev,
20 pkg-config,
24 pkg-config,
21− python3,
22 python (>= 2.7),
25 python (>= 2.7),
23 python-setuptools,
26 python-setuptools,
27+ python3,
24 qt5-default,
28 qt5-default,
25 qtbase5-dev,
29 qtbase5-dev,
26 qtbase5-private-dev,
30 qtbase5-private-dev,
@@ -32,7 +36,6 @@ Build-Depends: cmake,
32 qtdeclarative5-ubuntu-ui-toolkit-plugin,
36 qtdeclarative5-ubuntu-ui-toolkit-plugin,
33 qtdeclarative5-xmllistmodel-plugin,
37 qtdeclarative5-xmllistmodel-plugin,
34 ttf-ubuntu-font-family,
38 ttf-ubuntu-font-family,
35− libunity-scopes-json-def-phone,
36Standards-Version: 3.9.4
39Standards-Version: 3.9.4
37Homepage: http://launchpad.net/unity
40Homepage: http://launchpad.net/unity
38# If you aren't a member of ~unity-team but need to upload
41# If you aren't a member of ~unity-team but need to upload
@@ -41,47 +44,56 @@ 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: ${misc:Depends},
59+Depends: qmenumodel-qml,
47− ${shlibs:Depends},
48− unity8-private (= ${binary:Version}),
49− indicators-client (>= 0.6.1),
50 qtdeclarative5-dee-plugin,
60 qtdeclarative5-dee-plugin,
51 qtdeclarative5-ubuntu-ui-toolkit-plugin,
61 qtdeclarative5-ubuntu-ui-toolkit-plugin,
52 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
62 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
53− unity-notifications-impl-1,
54 qtdeclarative5-xmllistmodel-plugin,
63 qtdeclarative5-xmllistmodel-plugin,
64+ unity-launcher-impl-2,
65+ unity-notifications-impl-1,
55 unity8-fake-env | qtubuntu-shell,
66 unity8-fake-env | qtubuntu-shell,
67+ unity8-private (= ${binary:Version}),
56 unity8-private | unity-launcher-impl,
68 unity8-private | unity-launcher-impl,
57− unity-launcher-impl-2,
69+ ${misc:Depends},
70+ ${shlibs:Depends},
71+Recommends: indicator-battery,
72+ indicator-messages,
73+ indicator-time,
58−Recommends: ${unity-default-masterscopes},
74+ ${unity-default-masterscopes},
59− indicators-client-plugin-datetime (>= 0.6.1),
60− indicators-client-plugin-messaging (>= 0.6.1),
61− indicators-client-plugin-network (>= 0.6.1),
62− indicators-client-plugin-power (>= 0.6.1),
63− indicators-client-plugin-sound (>= 0.6.1),
64Description: Unity 8 shell
75Description: Unity 8 shell
65 The Unity 8 shell is the primary user interface for Ubuntu devices.
76 The Unity 8 shell is the primary user interface for Ubuntu devices.
66
77
67−Package: unity8-private
78+Package: unity8-autopilot
68−Architecture: any
79+Architecture: all
69−Multi-Arch: same
80+Depends: indicators-client (>= ${source:Version}),
81+ libautopilot-qt,
82+ libqt5test5,
83+ libqt5widgets5,
84+ python-evdev,
85+ unity8 (>= ${source:Version}),
86+ unity8-fake-env (>= ${source:Version}),
70−Pre-Depends: ${misc:Pre-Depends}
87+ ${misc:Depends},
71−Depends: ${misc:Depends},
88+ ${python:Depends},
72 ${shlibs:Depends},
89 ${shlibs:Depends},
73−Provides: unity-launcher-impl,
90+Description: Test package for Unity 8 shell
74− unity-launcher-impl-2
91+ Autopilot tests for the unity8 package
75−Description: Unity 8 private libs
76− The Unity 8 shell is the primary user interface for Ubuntu devices.
77− .
78− This package contains the private libraries for QML and other components
79− only used by the shell.
80
92
81Package: unity8-fake-env
93Package: unity8-fake-env
82Architecture: any
94Architecture: any
83Multi-Arch: same
95Multi-Arch: same
84−Pre-Depends: ${misc:Pre-Depends}
96+Pre-Depends: ${misc:Pre-Depends},
85Depends: ${misc:Depends},
97Depends: ${misc:Depends},
86 ${shlibs:Depends},
98 ${shlibs:Depends},
87Provides: qtubuntu-shell,
99Provides: qtubuntu-shell,
@@ -89,16 +101,16 @@ Description: Fake environment for running Unity 8 shell
89 Provides fake implementations of some QML modules used by Unity 8 shell
101 Provides fake implementations of some QML modules used by Unity 8 shell
90 (e.g Ubuntu.Application) so that you can run it in a sandboxed environment.
102 (e.g Ubuntu.Application) so that you can run it in a sandboxed environment.
91
103
92−Package: unity8-autopilot
104+Package: unity8-private
93−Architecture: all
105+Architecture: any
106+Multi-Arch: same
107+Pre-Depends: ${misc:Pre-Depends},
94Depends: ${misc:Depends},
108Depends: ${misc:Depends},
95 ${shlibs:Depends},
109 ${shlibs:Depends},
96− ${python:Depends},
110+Provides: unity-launcher-impl,
97− libautopilot-qt,
111+ unity-launcher-impl-2,
98− libqt5test5,
112+Description: Unity 8 private libs
99− libqt5widgets5,
113+ The Unity 8 shell is the primary user interface for Ubuntu devices.
100− python-evdev,
114+ .
101− unity8 (>= ${source:Version}),
115+ This package contains the private libraries for QML and other components
102− unity8-fake-env (>= ${source:Version}),
116+ only used by the shell.
103−Description: Test package for Unity 8 shell
104− Autopilot tests for the unity8 package
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+5−8
@@ -18,10 +18,12 @@
18 */
18 */
19
19
20// Qt
20// Qt
21+#include <QtQml>
21#include <QtQuick/QQuickView>
22#include <QtQuick/QQuickView>
22#include <QtGui/QIcon>
23#include <QtGui/QIcon>
23#include <QtGui/QGuiApplication>
24#include <QtGui/QGuiApplication>
24#include <QtQml/QQmlEngine>
25#include <QtQml/QQmlEngine>
26+#include <QtQml/QQmlContext>
25#include <qpa/qplatformnativeinterface.h>
27#include <qpa/qplatformnativeinterface.h>
26#include <QLibrary>
28#include <QLibrary>
27#include <libintl.h>
29#include <libintl.h>
@@ -29,6 +31,7 @@
29// local
31// local
30#include "paths.h"
32#include "paths.h"
31#include "MouseTouchAdaptor.h"
33#include "MouseTouchAdaptor.h"
34+#include "ApplicationArguments.h"
32
35
33namespace {
36namespace {
34
37
@@ -85,6 +88,7 @@ int main(int argc, char** argv)
85 resolveIconTheme();
88 resolveIconTheme();
86
89
87 QStringList args = application.arguments();
90 QStringList args = application.arguments();
91+ ApplicationArguments qmlArgs(args);
88
92
89 // The testability driver is only loaded by QApplication but not by QGuiApplication.
93 // The testability driver is only loaded by QApplication but not by QGuiApplication.
90 // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
94 // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
@@ -109,6 +113,7 @@ int main(int argc, char** argv)
109 view->setResizeMode(QQuickView::SizeRootObjectToView);
113 view->setResizeMode(QQuickView::SizeRootObjectToView);
110 view->setTitle("Qml Phone Shell");
114 view->setTitle("Qml Phone Shell");
111 view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory()));
115 view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory()));
116+ view->rootContext()->setContextProperty("ApplicationArguments", &qmlArgs);
112 if (args.contains(QLatin1String("-frameless"))) {
117 if (args.contains(QLatin1String("-frameless"))) {
113 view->setFlags(Qt::FramelessWindowHint);
118 view->setFlags(Qt::FramelessWindowHint);
114 }
119 }
@@ -131,8 +136,6 @@ int main(int argc, char** argv)
131 nativeInterface->setProperty("ubuntuSessionType", 1);
136 nativeInterface->setProperty("ubuntuSessionType", 1);
132 view->setProperty("role", 2); // INDICATOR_ACTOR_ROLE
137 view->setProperty("role", 2); // INDICATOR_ACTOR_ROLE
133
138
134− QObject::connect(view->engine(), SIGNAL(quit()), qApp, SLOT(quit()));
135−
136 QUrl source("Shell.qml");
139 QUrl source("Shell.qml");
137 prependImportPaths(view->engine(), ::overrideImportPaths());
140 prependImportPaths(view->engine(), ::overrideImportPaths());
138 appendImportPaths(view->engine(), ::fallbackImportPaths());
141 appendImportPaths(view->engine(), ::fallbackImportPaths());
@@ -142,12 +145,6 @@ int main(int argc, char** argv)
142 if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || args.contains(QLatin1String("-fullscreen"))) {
145 if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || args.contains(QLatin1String("-fullscreen"))) {
143 view->showFullScreen();
146 view->showFullScreen();
144 } else {
147 } else {
145− if (args.contains(QLatin1String("-geometry")) && args.size() > args.indexOf(QLatin1String("-geometry")) + 1) {
146− QStringList geometryArg = args.at(args.indexOf(QLatin1String("-geometry")) + 1).split('x');
147− if (geometryArg.size() == 2) {
148− view->resize(geometryArg.at(0).toInt(), geometryArg.at(1).toInt());
149− }
150− }
151 view->show();
148 view->show();
152 }
149 }
153
150
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/HudClient/CMakeLists.txt+2−1
@@ -38,5 +38,6 @@ target_link_libraries(HudClientQml
38
38
39qt5_use_modules(HudClientQml Qml)
39qt5_use_modules(HudClientQml Qml)
40
40
41−# export the qmldir and qmltypes files
41+# export the qmldir qmltypes and plugin files
42+export_qmlfiles(HudClient HudClient)
42export_qmlplugin(HudClient 0.1 HudClient TARGETS HudClientQml)
43export_qmlplugin(HudClient 0.1 HudClient TARGETS HudClientQml)
plugins/LightDM/CMakeLists.txt+2−1
@@ -35,5 +35,6 @@ target_link_libraries(LightDM-qml
35
35
36qt5_use_modules(LightDM-qml Gui Qml)
36qt5_use_modules(LightDM-qml Gui Qml)
37
37
38−# export the qmldir and qmltypes files
38+# export the qmldir qmltypes and plugin files
39+export_qmlfiles(LightDM LightDM)
39export_qmlplugin(LightDM 0.1 LightDM TARGETS LightDM-qml)
40export_qmlplugin(LightDM 0.1 LightDM TARGETS LightDM-qml)
plugins/ListViewWithPageHeader/CMakeLists.txt+2−1
@@ -33,5 +33,6 @@ target_link_libraries(ListViewWithPageHeader-qml
33
33
34qt5_use_modules(ListViewWithPageHeader-qml Qml Quick)
34qt5_use_modules(ListViewWithPageHeader-qml Qml Quick)
35
35
36−# export the qmldir and qmltypes files
36+# export the qmldir qmltypes and plugin files
37+export_qmlfiles(ListViewWithPageHeader ListViewWithPageHeader)
37export_qmlplugin(ListViewWithPageHeader 0.1 ListViewWithPageHeader TARGETS ListViewWithPageHeader-qml)
38export_qmlplugin(ListViewWithPageHeader 0.1 ListViewWithPageHeader TARGETS ListViewWithPageHeader-qml)
plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+1−1
@@ -806,7 +806,7 @@ void ListViewWithPageHeader::onModelUpdated(const QQuickChangeSet &changeSet, bo
806 Q_FOREACH(const QQuickChangeSet::Insert &insert, changeSet.inserts()) {
806 Q_FOREACH(const QQuickChangeSet::Insert &insert, changeSet.inserts()) {
807// qDebug() << "ListViewWithPageHeader::onModelUpdated Insert" << insert.index << insert.count;
807// qDebug() << "ListViewWithPageHeader::onModelUpdated Insert" << insert.index << insert.count;
808 const bool insertingInValidIndexes = insert.index > m_firstVisibleIndex && insert.index < m_firstVisibleIndex + m_visibleItems.count();
808 const bool insertingInValidIndexes = insert.index > m_firstVisibleIndex && insert.index < m_firstVisibleIndex + m_visibleItems.count();
809− const bool firstItemWithViewOnTop = insert.index == 0 && m_firstVisibleIndex == 0 && m_visibleItems.first()->y() + m_clipItem->y() > contentY();
809+ const bool firstItemWithViewOnTop = insert.index == 0 && m_firstVisibleIndex == 0 && !m_visibleItems.isEmpty() && m_visibleItems.first()->y() + m_clipItem->y() > contentY();
810 if (insertingInValidIndexes || firstItemWithViewOnTop)
810 if (insertingInValidIndexes || firstItemWithViewOnTop)
811 {
811 {
812 // If the items we are adding won't be really visible
812 // If the items we are adding won't be really visible
plugins/Ubuntu/Gestures/CMakeLists.txt+2−1
@@ -23,5 +23,6 @@ qt5_use_modules(UbuntuGestureQml Core Quick)
23# So that Foo.cpp can #include "Foo.moc"
23# So that Foo.cpp can #include "Foo.moc"
24include_directories(${CMAKE_CURRENT_BINARY_DIR})
24include_directories(${CMAKE_CURRENT_BINARY_DIR})
25
25
26−# export the qmldir and qmltypes files
26+# export the qmldir qmltypes and plugin files
27+export_qmlfiles(Ubuntu.Gestures Ubuntu/Gestures)
27export_qmlplugin(Ubuntu.Gestures 0.1 Ubuntu/Gestures TARGETS UbuntuGestureQml)
28export_qmlplugin(Ubuntu.Gestures 0.1 Ubuntu/Gestures TARGETS UbuntuGestureQml)
plugins/Unity/CMakeLists.txt+4−1
@@ -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)
@@ -46,7 +48,8 @@ target_link_libraries(Unity-qml
46
48
47qt5_use_modules(Unity-qml Qml)
49qt5_use_modules(Unity-qml Qml)
48
50
49−# export the qmldir and qmltypes files
51+# export the qmldir qmltypes and plugin files
52+export_qmlfiles(Unity Unity)
50export_qmlplugin(Unity 0.1 Unity TARGETS Unity-qml)
53export_qmlplugin(Unity 0.1 Unity TARGETS Unity-qml)
51
54
52add_subdirectory(Launcher)
55add_subdirectory(Launcher)
plugins/Unity/Indicators/CMakeLists.txtnew file+51
@@ -0,0 +1,51 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
4+project(IndicatorsQml)
5+
6+pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
7+find_package(Qt5Core REQUIRED)
8+find_package(Qt5Quick REQUIRED)
9+
10+add_subdirectory(qml)
11+add_subdirectory(Messaging)
12+add_subdirectory(Network)
13+
14+include_directories(
15+ ${CMAKE_CURRENT_SOURCE_DIR}
16+ ${CMAKE_CURRENT_BINARY_DIR}
17+ ${QMENUMODEL_INCLUDE_DIRS}
18+)
19+
20+set(IndicatorsQML_SOURCES
21+ flatmenuproxymodel.cpp
22+ indicator.cpp
23+ indicators.h
24+ indicatorsmanager.cpp
25+ indicatorsmodel.cpp
26+ menucontentactivator.cpp
27+ plugin.cpp
28+)
29+add_definitions(-DUNITYINDICATORS_LIBRARY)
30+
31+set(IndicatorsQML_RESOURCES
32+ resources/indicators.qrc
33+)
34+
35+qt5_add_resources(IndicatorsQML_RESOURCES_RCC
36+ ${IndicatorsQML_RESOURCES}
37+)
38+
39+add_library(IndicatorsQml SHARED
40+ ${IndicatorsQML_RESOURCES_RCC}
41+ ${IndicatorsQML_SOURCES}
42+)
43+
44+target_link_libraries(IndicatorsQml
45+ ${QMENUMODEL_LDFLAGS}
46+)
47+
48+qt5_use_modules(IndicatorsQml Core Qml Quick)
49+
50+# export the qmltypes and plugin files
51+export_qmlplugin(Unity.Indicators 0.1 Unity/Indicators TARGETS IndicatorsQml)
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+5
@@ -0,0 +1,5 @@
1+# export_qmlfiles macro
2+include(Plugins)
3+
4+# export the qmldir, *.qml files.
5+export_qmlfiles(Unity.Indicators.Messaging Unity/Indicators/Messaging)
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+45
@@ -0,0 +1,45 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
4+project(IndicatorsNetworkQml)
5+
6+pkg_check_modules(GLIB glib-2.0>=2.32)
7+pkg_check_modules(LIBNM_GLIB libnm-glib>=0.9.6)
8+pkg_check_modules(LIBNM_UTIL libnm-util>=0.9.6)
9+
10+if(LIBNM_GLIB_FOUND AND LIBNM_UTIL_FOUND AND GLIB_FOUND)
11+ set(INDICATORS_NETWORK_SRC
12+ networkagent.cpp
13+ plugin.cpp
14+ secret-agent.c
15+ )
16+
17+ add_library(IndicatorsNetworkQml MODULE
18+ ${INDICATORS_NETWORK_SRC}
19+ )
20+
21+ qt5_use_modules(IndicatorsNetworkQml Core Qml Widgets)
22+
23+ set_target_properties(IndicatorsNetworkQml PROPERTIES COMPILE_FLAGS -fPIC)
24+
25+ include_directories(
26+ ${CMAKE_CURRENT_SOURCE_DIR}
27+ ${GLIB_INCLUDE_DIRS}
28+ ${LIBNM_GLIB_INCLUDE_DIRS}
29+ ${LIBNM_UTIL_INCLUDE_DIRS}
30+ )
31+
32+ target_link_libraries(IndicatorsNetworkQml
33+ ${GLIB_LIBRARIES}
34+ ${LIBNM_GLIB_LIBRARIES}
35+ ${LIBNM_UTIL_LIBRARIES}
36+ )
37+
38+ # export the qmltypes and plugin files
39+ export_qmlplugin(Unity.Indicators.Network 0.1 Unity/Indicators/Network TARGETS IndicatorsNetworkQml)
40+
41+else()
42+ message(WARNING "Missing glib or libnm dependency for the network plugin, not building")
43+endif()
44+
45+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+5
@@ -0,0 +1,5 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
4+# export the qmldir, *.qml files.
5+export_qmlfiles(Unity.Indicators.Network Unity/Indicators/Network)
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+9
@@ -0,0 +1,9 @@
1+module Unity.Indicators.Network
2+plugin IndicatorsNetworkQml
3+typeinfo plugin.qmltypes
4+
5+NetworkPage 0.1 NetworkPage.qml
6+AccessPoint 0.1 AccessPoint.qml
7+PasswordPage 0.1 PasswordPage.qml
8+PasswordTextField 0.1 PasswordTextField.qml
9+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+93
@@ -0,0 +1,93 @@
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 "unityindicatorsglobal.h"
24+
25+#include <QAbstractProxyModel>
26+#include <qdbusmenumodel.h>
27+
28+class SectionInfo;
29+
30+class UNITYINDICATORS_EXPORT FlatMenuProxyModel : public QAbstractProxyModel
31+{
32+ Q_OBJECT
33+ Q_PROPERTY(int count READ count NOTIFY countChanged)
34+ Q_PROPERTY(int busType READ busType WRITE setIntBusType NOTIFY busTypeChanged)
35+ Q_PROPERTY(QString busName READ busName WRITE setBusName NOTIFY busNameChanged)
36+ Q_PROPERTY(QString objectPath READ objectPath WRITE setObjectPath NOTIFY objectPathChanged)
37+ Q_PROPERTY(int status READ status NOTIFY statusChanged)
38+
39+ Q_ENUMS(Roles)
40+public:
41+ FlatMenuProxyModel(QAbstractItemModel *source=0);
42+ ~FlatMenuProxyModel();
43+
44+ void setSourceModel(QAbstractItemModel * sourceModel);
45+
46+ Q_INVOKABLE QVariant data(int row, int role = Qt::DisplayRole) const;
47+
48+ QModelIndex mapFromSource(const QModelIndex &index) const;
49+ QModelIndex mapToSource(const QModelIndex &index) const;
50+
51+ QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
52+ QModelIndex parent(const QModelIndex &index) const;
53+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
54+ int count() const;
55+ int columnCount(const QModelIndex &parent) const;
56+
57+ void setBusName(const QString &busName);
58+ QString busName() const;
59+
60+ void setObjectPath(const QString &busName);
61+ QString objectPath() const;
62+
63+ DBusEnums::BusType busType() const;
64+ void setIntBusType(int type);
65+
66+ int status() const;
67+
68+public Q_SLOTS:
69+ void onModelAboutToBeReset();
70+ void onModelReset();
71+
72+ void start();
73+ void stop();
74+
75+Q_SIGNALS:
76+ void countChanged();
77+
78+ void busTypeChanged();
79+ void busNameChanged();
80+ void objectPathChanged();
81+ void statusChanged();
82+
83+private:
84+ QDBusMenuModel *m_model;
85+ mutable QMap<int, QString> m_indexCache;
86+ int m_rowCount;
87+
88+ int rowOffsetOf(const QModelIndex &index, int row, bool inclusive = false) const;
89+ int recursiveRowCount(const QModelIndex &index) const;
90+ QModelIndex index(int row, int rowCount, const QModelIndex &parent, const QString &key) const;
91+};
92+
93+#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+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+#ifndef INDICATOR_H
22+#define INDICATOR_H
23+
24+#include "unityindicatorsglobal.h"
25+
26+#include <QObject>
27+#include <QSettings>
28+
29+class UNITYINDICATORS_EXPORT Indicator : public QObject
30+{
31+ Q_OBJECT
32+ Q_PROPERTY(QString identifier READ identifier NOTIFY identifierChanged)
33+ Q_PROPERTY(QVariant indicatorProperties READ indicatorProperties NOTIFY indicatorPropertiesChanged)
34+
35+public:
36+ typedef QSharedPointer<Indicator> Ptr;
37+
38+ Indicator(QObject *parent = 0);
39+ virtual ~Indicator();
40+
41+ void init(const QString& busName, const QSettings& settings);
42+
43+ QString identifier() const;
44+ QVariant indicatorProperties() const;
45+
46+Q_SIGNALS:
47+ void identifierChanged(const QString &identifier);
48+ void indicatorPropertiesChanged(const QVariant &properties);
49+
50+protected:
51+ void setId(const QString &id);
52+ void setIndicatorProperties(const QVariant &properties);
53+
54+private:
55+ QString m_identifier;
56+ QVariant m_properties;
57+};
58+
59+#endif // INDICATOR_H
plugins/Unity/Indicators/indicators.hnew file+105
@@ -0,0 +1,105 @@
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 "unityindicatorsglobal.h"
23+
24+#include <QObject>
25+
26+class UNITYINDICATORS_EXPORT ActionState : public QObject
27+{
28+ Q_OBJECT
29+public:
30+ Q_ENUMS(ActionStates)
31+ enum ActionStates {
32+ Label = 0x00,
33+ IconSource = 0x01,
34+ AccessableName = 0x02,
35+ Visible = 0x03,
36+ };
37+
38+ ActionState(QObject*parent=0):QObject(parent) {}
39+};
40+
41+class UNITYINDICATORS_EXPORT NetworkActionState : public QObject
42+{
43+ Q_OBJECT
44+public:
45+ Q_ENUMS(NetworkActionStates)
46+ enum NetworkActionStates {
47+ Connection = 0x01,
48+ SignalStrength = 0x02,
49+ };
50+
51+ NetworkActionState(QObject*parent=0):QObject(parent) {}
52+};
53+
54+class UNITYINDICATORS_EXPORT NetworkConnection : public QObject
55+{
56+ Q_OBJECT
57+public:
58+ Q_ENUMS(NetworkConnectionStates)
59+ enum NetworkConnectionStates {
60+ Initial = 0x00,
61+ Activating = 0x01,
62+ Activated = 0x02,
63+ Deactivating = 0x03,
64+ };
65+
66+ NetworkConnection(QObject*parent=0):QObject(parent) {}
67+};
68+
69+class UNITYINDICATORS_EXPORT IndicatorsModelRole : public QObject
70+{
71+ Q_OBJECT
72+public:
73+ Q_ENUMS(Roles)
74+ enum Roles {
75+ Identifier = 0,
76+ Priority,
77+ Title,
78+ Description,
79+ WidgetSource,
80+ PageSource,
81+ IndicatorProperties,
82+ IsValid
83+ };
84+
85+ IndicatorsModelRole(QObject*parent=0):QObject(parent) {}
86+};
87+
88+class UNITYINDICATORS_EXPORT FlatMenuProxyModelRole : public QObject
89+{
90+ Q_OBJECT
91+public:
92+ Q_ENUMS(Roles)
93+ enum Roles {
94+ Action = Qt::DisplayRole + 1,
95+ Label,
96+ Extra,
97+ Depth,
98+ hasSection,
99+ hasSubMenu
100+ };
101+
102+ FlatMenuProxyModelRole(QObject*parent=0):QObject(parent) {}
103+};
104+
105+#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+74
@@ -0,0 +1,74 @@
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 "indicator.h"
23+#include "unityindicatorsglobal.h"
24+
25+#include <QObject>
26+#include <QFileSystemWatcher>
27+#include <QDir>
28+#include <QHash>
29+#include <QSharedPointer>
30+
31+class UNITYINDICATORS_EXPORT IndicatorsManager : public QObject
32+{
33+ Q_OBJECT
34+ Q_PROPERTY(bool loaded READ isLoaded NOTIFY loadedChanged)
35+public:
36+ explicit IndicatorsManager(QObject* parent = 0);
37+ ~IndicatorsManager();
38+
39+ Q_INVOKABLE void load();
40+ Q_INVOKABLE void unload();
41+
42+ Indicator::Ptr indicator(const QString& indicator_name);
43+
44+ QList<Indicator::Ptr> indicators();
45+
46+ bool isLoaded() const;
47+
48+Q_SIGNALS:
49+ void loadedChanged(bool);
50+
51+ void indicatorLoaded(const QString& indicator_name);
52+ void indicatorAboutToBeUnloaded(const QString& indicator_name);
53+
54+private Q_SLOTS:
55+ void onDirectoryChanged(const QString& directory);
56+ void onFileChanged(const QString& file);
57+
58+private:
59+ void loadDir(const QDir& dir);
60+ void loadFile(const QFileInfo& file);
61+ void unloadFile(const QFileInfo& dir);
62+
63+ void startVerify(const QString& path);
64+ void endVerify(const QString& path);
65+
66+ void setLoaded(bool);
67+
68+ class IndicatorData;
69+ QHash<QString, IndicatorData*> m_indicatorsData;
70+ QSharedPointer<QFileSystemWatcher> m_fsWatcher;
71+ bool m_loaded;
72+};
73+
74+#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+33−45
@@ -15,65 +15,36 @@
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"
25+#include "unityindicatorsglobal.h"
22
26
23#include <QAbstractListModel>
27#include <QAbstractListModel>
24#include <QQmlEngine>
28#include <QQmlEngine>
25
29
30+class IndicatorsManager;
26
31
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
32+class UNITYINDICATORS_EXPORT IndicatorsModel : public QAbstractListModel
52{
33{
53 Q_OBJECT
34 Q_OBJECT
54− Q_PROPERTY(WidgetsMap* widgetsMap READ widgetsMap NOTIFY widgetsMapChanged)
35+ Q_ENUMS(Roles)
55 Q_PROPERTY(int count READ count NOTIFY countChanged)
36 Q_PROPERTY(int count READ count NOTIFY countChanged)
37+ Q_PROPERTY(QVariant indicatorData READ indicatorData WRITE setIndicatorData NOTIFY indicatorDataChanged)
56
38
57public:
39public:
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
40
71− WidgetsMap* widgetsMap() const;
41+ IndicatorsModel(QObject *parent=0);
42+ ~IndicatorsModel();
72
43
73 Q_INVOKABLE void load();
44 Q_INVOKABLE void load();
74 Q_INVOKABLE void unload();
45 Q_INVOKABLE void unload();
75
46
76− Q_INVOKABLE QVariantMap get(int row) const;
47+ Q_INVOKABLE QVariant data(int row, int role = Qt::DisplayRole) const;
77
48
78 /* QAbstractItemModel */
49 /* QAbstractItemModel */
79 QHash<int, QByteArray> roleNames() const;
50 QHash<int, QByteArray> roleNames() const;
@@ -82,13 +53,30 @@ public:
82 QModelIndex parent (const QModelIndex &index) const;
53 QModelIndex parent (const QModelIndex &index) const;
83 int rowCount(const QModelIndex &parent = QModelIndex()) const;
54 int rowCount(const QModelIndex &parent = QModelIndex()) const;
84
55
56+ void setIndicatorData(const QVariant& data);
57+ QVariant indicatorData() const;
58+
85Q_SIGNALS:
59Q_SIGNALS:
86− void widgetsMapChanged(WidgetsMap *widgetsMap);
87 void countChanged();
60 void countChanged();
61+ void indicatorDataChanged(const QVariant& data);
62+
63+private Q_SLOTS:
64+ void onIdentifierChanged();
65+ void onIndicatorPropertiesChanged();
66+ void onIndicatorLoaded(const QString& indicator);
67+ void onIndicatorAboutToBeUnloaded(const QString& indicator);
88
68
89private:
69private:
90− WidgetsMap* m_widgetsMap;
70+ IndicatorsManager *m_manager;
71+
72+ QList<Indicator::Ptr> m_indicators;
73+ QVariant m_indicator_data;
74+ QMap<QString, QVariantMap> m_parsed_indicator_data;
75+
76+ void notifyDataChanged(QObject *sender, int role);
91 int count() const;
77 int count() const;
78+ QVariant indicatorData(const Indicator::Ptr& indicator, int role) const;
79+ static QVariant defaultData(Indicator::Ptr indicator, int role);
92};
80};
93
81
94−#endif
82+#endif // INDICATORSMODEL_H
plugins/Unity/Indicators/menucontentactivator.cppnew file+345
@@ -0,0 +1,345 @@
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 "menucontentactivator.h"
20+
21+// Essentially a QTimer wrapper
22+class ContentTimer : public UnityIndicators::AbstractTimer
23+{
24+ Q_OBJECT
25+public:
26+ ContentTimer(QObject *parent) : UnityIndicators::AbstractTimer(parent) {
27+ m_timer.setSingleShot(false);
28+ connect(&m_timer, &QTimer::timeout,
29+ this, &UnityIndicators::AbstractTimer::timeout);
30+ }
31+ virtual int interval() const { return m_timer.interval(); }
32+ virtual void setInterval(int msecs) { m_timer.setInterval(msecs); }
33+ virtual void start() { m_timer.start(); UnityIndicators::AbstractTimer::start(); }
34+ virtual void stop() { m_timer.stop(); UnityIndicators::AbstractTimer::stop(); }
35+private:
36+ QTimer m_timer;
37+};
38+
39+class MenuContentActivatorPrivate : public QObject
40+{
41+ Q_OBJECT
42+public:
43+ MenuContentActivatorPrivate(MenuContentActivator* parent)
44+ : m_running(false),
45+ m_baseIndex(0),
46+ m_delta(0),
47+ m_count(0),
48+ m_timer(NULL),
49+ q(parent)
50+ {}
51+
52+ ~MenuContentActivatorPrivate()
53+ {
54+ qDeleteAll(m_content);
55+ m_content.clear();
56+ }
57+
58+ int findNextInactiveDelta(bool* finished = NULL);
59+
60+ static int content_count(QQmlListProperty<MenuContentState> *prop);
61+ static MenuContentState* content_at(QQmlListProperty<MenuContentState> *prop, int index);
62+
63+ bool m_running;
64+ int m_baseIndex;
65+ int m_delta;
66+ int m_count;
67+ UnityIndicators::AbstractTimer* m_timer;
68+ QMap<int, MenuContentState*> m_content;
69+ MenuContentActivator* q;
70+};
71+
72+MenuContentActivator::MenuContentActivator(QObject* parent)
73+ : QObject(parent),
74+ d(new MenuContentActivatorPrivate(this))
75+{
76+ qRegisterMetaType<QQmlListProperty<MenuContentState> > ("QQmlListProperty<MenuContentState>");
77+
78+ setContentTimer(new ContentTimer(this));
79+ d->m_timer->setInterval(75);
80+}
81+
82+MenuContentActivator::~MenuContentActivator()
83+{
84+ delete d;
85+}
86+
87+void MenuContentActivator::restart()
88+{
89+ // when we start, make sure we have the base index in the list.
90+ setMenuContentState(d->m_baseIndex, true);
91+ setDelta(0);
92+
93+ // check if we've finished before starting the timer.
94+ bool finished = false;
95+ d->findNextInactiveDelta(&finished);
96+ if (!finished) {
97+ d->m_timer->start();
98+ } else {
99+ d->m_timer->stop();
100+ }
101+
102+ if (!d->m_running) {
103+ d->m_running = true;
104+ Q_EMIT runningChanged(true);
105+ }
106+}
107+
108+void MenuContentActivator::stop()
109+{
110+ d->m_timer->stop();
111+ if (!d->m_running) {
112+ d->m_running = false;
113+ Q_EMIT runningChanged(false);
114+ }
115+}
116+
117+void MenuContentActivator::clear()
118+{
119+ qDeleteAll(d->m_content);
120+ d->m_content.clear();
121+
122+ setDelta(0);
123+ d->m_timer->stop();
124+
125+ Q_EMIT contentChanged();
126+}
127+
128+bool MenuContentActivator::isMenuContentActive(int index) const
129+{
130+ if (d->m_content.contains(index))
131+ return d->m_content[index]->isActive();
132+ return false;
133+}
134+
135+void MenuContentActivator::setRunning(bool running)
136+{
137+ if (running) {
138+ restart();
139+ } else {
140+ stop();
141+ }
142+}
143+
144+bool MenuContentActivator::isRunning() const
145+{
146+ return d->m_running;
147+}
148+
149+void MenuContentActivator::setBaseIndex(int index)
150+{
151+ if (d->m_baseIndex != index) {
152+ d->m_baseIndex = index;
153+
154+ if (isRunning()) {
155+ restart();
156+ }
157+
158+ Q_EMIT baseIndexChanged(index);
159+ }
160+}
161+
162+int MenuContentActivator::baseIndex() const
163+{
164+ return d->m_baseIndex;
165+}
166+
167+void MenuContentActivator::setCount(int count)
168+{
169+ if (d->m_count != count) {
170+ d->m_count = count;
171+ Q_EMIT countChanged(count);
172+
173+ if (isRunning()) {
174+ restart();
175+ }
176+ }
177+}
178+
179+int MenuContentActivator::count() const
180+{
181+ return d->m_count;
182+}
183+
184+void MenuContentActivator::setDelta(int delta)
185+{
186+ if (d->m_delta != delta) {
187+ d->m_delta = delta;
188+ Q_EMIT deltaChanged(d->m_delta);
189+ }
190+}
191+
192+int MenuContentActivator::delta() const
193+{
194+ return d->m_delta;
195+}
196+
197+QQmlListProperty<MenuContentState> MenuContentActivator::content()
198+{
199+ return QQmlListProperty<MenuContentState>(this,
200+ 0,
201+ MenuContentActivatorPrivate::content_count,
202+ MenuContentActivatorPrivate::content_at);
203+}
204+
205+void MenuContentActivator::onTimeout()
206+{
207+ bool finished = false;
208+ int tempDelta = d->findNextInactiveDelta(&finished);
209+ if (!finished) {
210+ setMenuContentState(d->m_baseIndex + tempDelta, true);
211+ setDelta(tempDelta);
212+ }
213+
214+ if (finished) {
215+ d->m_timer->stop();
216+ }
217+}
218+
219+void MenuContentActivator::setContentTimer(UnityIndicators::AbstractTimer *timer)
220+{
221+ int interval = 0;
222+ bool timerWasRunning = false;
223+
224+ // can be null when called from the constructor
225+ if (d->m_timer) {
226+ interval = d->m_timer->interval();
227+ timerWasRunning = d->m_timer->isRunning();
228+ if (d->m_timer->parent() == this) {
229+ delete d->m_timer;
230+ }
231+ }
232+
233+ d->m_timer = timer;
234+ timer->setInterval(interval);
235+ connect(timer, &UnityIndicators::AbstractTimer::timeout,
236+ this, &MenuContentActivator::onTimeout);
237+ if (timerWasRunning) {
238+ d->m_timer->start();
239+ }
240+}
241+
242+void MenuContentActivator::setMenuContentState(int index, bool active)
243+{
244+ if (d->m_content.contains(index)) {
245+ d->m_content[index]->setActive(active);
246+ } else {
247+ d->m_content[index] = new MenuContentState(active);
248+ Q_EMIT contentChanged();
249+ }
250+}
251+
252+int MenuContentActivatorPrivate::findNextInactiveDelta(bool* finished)
253+{
254+ if (m_count == 0 || m_baseIndex >= m_count) {
255+ if (finished) *finished = true;
256+ return 0;
257+ }
258+
259+ int tmpDelta = m_delta;
260+ bool topReached = false, bottomReached = false;
261+ while(true) {
262+
263+ // prechecks for bottom and top limits.
264+ if (tmpDelta > 0 && bottomReached) tmpDelta = -tmpDelta;
265+ if (tmpDelta < 0 && topReached) tmpDelta = (-tmpDelta) + 1;
266+
267+ if (tmpDelta > 0) {
268+ // negative of baseIndex
269+ tmpDelta = -tmpDelta;
270+ // reached the bottom?
271+ if (m_baseIndex + tmpDelta < 0) {
272+ bottomReached = true;
273+ // if we've reached the top as well, then we know we're done.
274+ if (topReached) {
275+ if (finished) *finished = true;
276+ return 0;
277+ }
278+ continue;
279+ }
280+ } else {
281+ // positive of baseIndex
282+ tmpDelta = (-tmpDelta) + 1;
283+ // reached the top?
284+ if (m_baseIndex + tmpDelta >= m_count) {
285+ topReached = true;
286+ // if we've reached the bottom as well, then we know we're done.
287+ if (bottomReached) {
288+ if (finished) *finished = true;
289+ return 0;
290+ }
291+ continue;
292+ }
293+ }
294+
295+ if (q->isMenuContentActive(m_baseIndex + tmpDelta)) {
296+ continue;
297+ }
298+ break;
299+ }
300+ if (finished) *finished = false;
301+ return tmpDelta;
302+}
303+
304+int MenuContentActivatorPrivate::content_count(QQmlListProperty<MenuContentState> *prop)
305+{
306+ MenuContentActivator *p = qobject_cast<MenuContentActivator*>(prop->object);
307+ // we'll create MenuContentState on demand.
308+ return p->count();
309+}
310+
311+MenuContentState* MenuContentActivatorPrivate::content_at(QQmlListProperty<MenuContentState> *prop, int index)
312+{
313+ MenuContentActivator *p = qobject_cast<MenuContentActivator*>(prop->object);
314+ MenuContentActivatorPrivate *d = p->d;
315+
316+ if (!d->m_content.contains(index)) {
317+ MenuContentState* content = new MenuContentState(false);
318+ d->m_content[index] = content;
319+ Q_EMIT p->contentChanged();
320+ return content;
321+ }
322+
323+ return d->m_content[index];
324+}
325+
326+MenuContentState::MenuContentState(bool active)
327+ : m_active(active)
328+{
329+}
330+
331+bool MenuContentState::isActive() const
332+{
333+ return m_active;
334+}
335+
336+void MenuContentState::setActive(bool active)
337+{
338+ if (m_active != active) {
339+ m_active = active;
340+ Q_EMIT activeChanged();
341+ }
342+}
343+
344+// Because we are defining a new QObject-based class (ContentTimer) here.
345+#include "menucontentactivator.moc"
plugins/Unity/Indicators/menucontentactivator.hnew file+117
@@ -0,0 +1,117 @@
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 MENUCONTENTACTIVATOR_H
20+#define MENUCONTENTACTIVATOR_H
21+
22+#include "unityindicatorsglobal.h"
23+
24+#include <QObject>
25+#include <QTimer>
26+#include <QQmlListProperty>
27+
28+
29+namespace UnityIndicators {
30+/* Defines an interface for a Timer. */
31+class UNITYINDICATORS_EXPORT AbstractTimer : public QObject {
32+ Q_OBJECT
33+public:
34+ AbstractTimer(QObject *parent) : QObject(parent), m_isRunning(false) {}
35+ virtual int interval() const = 0;
36+ virtual void setInterval(int msecs) = 0;
37+ virtual void start() { m_isRunning = true; };
38+ virtual void stop() { m_isRunning = false; }
39+ bool isRunning() const { return m_isRunning; }
40+Q_SIGNALS:
41+ void timeout();
42+private:
43+ bool m_isRunning;
44+};
45+}
46+
47+/* Defines a object to express the active state of a menu. */
48+class UNITYINDICATORS_EXPORT MenuContentState : public QObject
49+{
50+ Q_OBJECT
51+ Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
52+public:
53+ MenuContentState(bool active);
54+
55+ bool isActive() const;
56+ void setActive(bool active);
57+
58+Q_SIGNALS:
59+ void activeChanged();
60+private:
61+ bool m_active;
62+};
63+
64+class MenuContentActivatorPrivate;
65+
66+class UNITYINDICATORS_EXPORT MenuContentActivator : public QObject
67+{
68+ Q_OBJECT
69+ Q_PROPERTY(int baseIndex READ baseIndex WRITE setBaseIndex NOTIFY baseIndexChanged)
70+ Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
71+ Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged)
72+ Q_PROPERTY(QQmlListProperty<MenuContentState> content READ content NOTIFY contentChanged DESIGNABLE false)
73+public:
74+ MenuContentActivator(QObject* parent = NULL);
75+ ~MenuContentActivator();
76+
77+ Q_INVOKABLE void restart();
78+ Q_INVOKABLE void stop();
79+ Q_INVOKABLE void clear();
80+ Q_INVOKABLE bool isMenuContentActive(int index) const;
81+
82+ void setRunning(bool running);
83+ bool isRunning() const;
84+
85+ void setBaseIndex(int index);
86+ int baseIndex() const;
87+
88+ void setCount(int index);
89+ int count() const;
90+
91+ void setDelta(int index);
92+ int delta() const;
93+
94+ QQmlListProperty<MenuContentState> content();
95+
96+ // Replaces the existing Timer with the given one.
97+ //
98+ // Useful for providing a fake timer when testing.
99+ void setContentTimer(UnityIndicators::AbstractTimer *timer);
100+ void setMenuContentState(int index, bool active);
101+
102+Q_SIGNALS:
103+ void baseIndexChanged(int baseIndex);
104+ void deltaChanged(int delta);
105+ void runningChanged(bool running);
106+ void countChanged(int count);
107+ void contentChanged();
108+
109+private Q_SLOTS:
110+ void onTimeout();
111+
112+private:
113+ MenuContentActivatorPrivate* d;
114+ friend class MenuContentActivatorPrivate;
115+};
116+
117+#endif // MENUCONTENTACTIVATOR_H
plugins/Unity/Indicators/plugin.cppnew file+47
@@ -0,0 +1,47 @@
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+#include "menucontentactivator.h"
31+
32+void IndicatorsPlugin::registerTypes(const char *uri)
33+{
34+ Q_INIT_RESOURCE(indicators);
35+
36+ qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
37+ qmlRegisterType<FlatMenuProxyModel>(uri, 0, 1, "FlatMenuProxyModel");
38+ qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
39+ qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
40+
41+ qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
42+ qmlRegisterUncreatableType<ActionState>(uri, 0, 1, "ActionState", "Can't create ActionState class");
43+ qmlRegisterUncreatableType<NetworkActionState>(uri, 0, 1, "NetworkActionState", "Can't create NetworkActionState class");
44+ qmlRegisterUncreatableType<NetworkConnection>(uri, 0, 1, "NetworkConnection", "Can't create NetworkConnection class");
45+ qmlRegisterUncreatableType<IndicatorsModelRole>(uri, 0, 1, "IndicatorsModelRole", "Can't create IndicatorsModelRole class");
46+ qmlRegisterUncreatableType<FlatMenuProxyModelRole>(uri, 0, 1, "FlatMenuProxyModelRole", "Can't create FlatMenuProxyModelRole class");
47+}
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+5
@@ -0,0 +1,5 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
4+# export the qmldir, *.qml files.
5+export_qmlfiles(Unity.Indicators Unity/Indicators)
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+191
@@ -0,0 +1,191 @@
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+}
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+21
@@ -0,0 +1,21 @@
1+module Unity.Indicators
2+plugin IndicatorsQml
3+typeinfo plugin.qmltypes
4+
5+BasicMenuItem 0.1 BasicMenuItem.qml
6+ButtonMenuItem 0.1 ButtonMenuItem.qml
7+DivMenuItem 0.1 DivMenuItem.qml
8+HLine 0.1 HLine.qml
9+IndicatorBase 0.1 IndicatorBase.qml
10+IndicatorPage 0.1 IndicatorPage.qml
11+IndicatorWidget 0.1 IndicatorWidget.qml
12+MenuItem 0.1 MenuItem.qml
13+MenuAction 0.1 MenuAction.qml
14+MenuActionBinding 0.1 MenuActionBinding.qml
15+MenuItemFactory 0.1 MenuItemFactory.qml
16+ProgressMenuItem 0.1 ProgressMenuItem.qml
17+SectionMenuItem 0.1 SectionMenuItem.qml
18+SliderMenuItem 0.1 SliderMenuItem.qml
19+SwitchMenuItem 0.1 SwitchMenuItem.qml
20+
21+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/Unity/Indicators/unityindicatorsglobal.hnew file+23
@@ -0,0 +1,23 @@
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+#include <QtCore/QtGlobal>
18+
19+#if defined(UNITYINDICATORS_LIBRARY)
20+# define UNITYINDICATORS_EXPORT Q_DECL_EXPORT
21+#else
22+# define UNITYINDICATORS_EXPORT Q_DECL_IMPORT
23+#endif
plugins/Unity/Launcher/CMakeLists.txt+2−2
@@ -1,6 +1,5 @@
1−# Dependencies
2include(FindPkgConfig)
1include(FindPkgConfig)
3−pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher)
2+pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=2)
4
3
5include_directories(
4include_directories(
6 ${CMAKE_CURRENT_SOURCE_DIR}
5 ${CMAKE_CURRENT_SOURCE_DIR}
@@ -25,4 +24,5 @@ add_library(UnityLauncher-qml MODULE
25qt5_use_modules(UnityLauncher-qml Qml)
24qt5_use_modules(UnityLauncher-qml Qml)
26
25
27# export the qmldir and qmltypes files
26# export the qmldir and qmltypes files
27+export_qmlfiles(Unity.Launcher Unity/Launcher)
28export_qmlplugin(Unity.Launcher 0.1 Unity/Launcher TARGETS UnityLauncher-qml)
28export_qmlplugin(Unity.Launcher 0.1 Unity/Launcher TARGETS UnityLauncher-qml)
plugins/Unity/Launcher/backend/launcherbackend.cpp+3−3
@@ -37,7 +37,7 @@ LauncherBackend::LauncherBackend(QObject *parent):
37 QLatin1String("gmail-webapp.desktop") <<
37 QLatin1String("gmail-webapp.desktop") <<
38 QLatin1String("ubuntu-weather-app.desktop") <<
38 QLatin1String("ubuntu-weather-app.desktop") <<
39 QLatin1String("notes-app.desktop") <<
39 QLatin1String("notes-app.desktop") <<
40− QLatin1String("ubuntu-calendar-app.desktop");
40+ QLatin1String("calendar-app.desktop");
41
41
42 // TODO: get stuff from desktop files instead this hardcoded map
42 // TODO: get stuff from desktop files instead this hardcoded map
43 m_displayNameMap.insert("phone-app.desktop", "Phone");
43 m_displayNameMap.insert("phone-app.desktop", "Phone");
@@ -49,7 +49,7 @@ LauncherBackend::LauncherBackend(QObject *parent):
49 m_displayNameMap.insert("gmail-webapp.desktop", "GMail");
49 m_displayNameMap.insert("gmail-webapp.desktop", "GMail");
50 m_displayNameMap.insert("ubuntu-weather-app.desktop", "Weather");
50 m_displayNameMap.insert("ubuntu-weather-app.desktop", "Weather");
51 m_displayNameMap.insert("notes-app.desktop", "Notes");
51 m_displayNameMap.insert("notes-app.desktop", "Notes");
52− m_displayNameMap.insert("ubuntu-calendar-app.desktop", "Calendar");
52+ m_displayNameMap.insert("calendar-app.desktop", "Calendar");
53
53
54 // TODO: get stuff from desktop files instead this hardcoded map
54 // TODO: get stuff from desktop files instead this hardcoded map
55 m_iconMap.insert("phone-app.desktop", "phone-app");
55 m_iconMap.insert("phone-app.desktop", "phone-app");
@@ -61,7 +61,7 @@ LauncherBackend::LauncherBackend(QObject *parent):
61 m_iconMap.insert("gmail-webapp.desktop", "gmail");
61 m_iconMap.insert("gmail-webapp.desktop", "gmail");
62 m_iconMap.insert("ubuntu-weather-app.desktop", "weather");
62 m_iconMap.insert("ubuntu-weather-app.desktop", "weather");
63 m_iconMap.insert("notes-app.desktop", "notepad");
63 m_iconMap.insert("notes-app.desktop", "notepad");
64− m_iconMap.insert("ubuntu-calendar-app.desktop", "calendar");
64+ m_iconMap.insert("calendar-app.desktop", "calendar");
65
65
66}
66}
67
67
plugins/Unity/Launcher/qmldir+1
@@ -1,2 +1,3 @@
1module Unity.Launcher
1module Unity.Launcher
2plugin UnityLauncher-qml
2plugin UnityLauncher-qml
3+typeinfo plugin.qmltypes
plugins/Utils/CMakeLists.txt+3−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
@@ -22,5 +23,6 @@ set_target_properties(Utils-qml PROPERTIES COMPILE_FLAGS -fvisibility=default)
22
23
23qt5_use_modules(Utils-qml Qml Quick)
24qt5_use_modules(Utils-qml Qml Quick)
24
25
25−# export the qmldir and qmltypes files
26+# export the qmldir qmltypes and plugin files
27+export_qmlfiles(Utils Utils)
26export_qmlplugin(Utils 0.1 Utils TARGETS Utils-qml)
28export_qmlplugin(Utils 0.1 Utils TARGETS Utils-qml)
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}
po/ar.po+3−27
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-22 16:15+0000\n"
11+"PO-Revision-Date: 2013-06-26 23:26+0000\n"
12"Last-Translator: Ibrahim Saed <ibraheem5000@gmail.com>\n"
12"Last-Translator: Ibrahim Saed <ibraheem5000@gmail.com>\n"
13"Language-Team: Arabic <ar@li.org>\n"
13"Language-Team: Arabic <ar@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,27 +218,3 @@ msgstr "عذراً، لا يوجد ما يطابق بحثك."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "أشخاص"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "الشاشة الرئيسية"
227−
228−#~ msgid "Favourite People"
229−#~ msgstr "الأشخاص المفضلون"
230−
231−#~ msgid "People Recently in Touch"
232−#~ msgstr "أشخاص كانوا على اتصال مؤخرا"
233−
234−#~ msgid "A-Z"
235−#~ msgstr "A-Z"
236−
237−#~ msgid "Recently in touch"
238−#~ msgstr "على اتصال موخرا"
239−
240−#~ msgid "New Contacts"
241−#~ msgstr "أشخاص جدد"
242−
243−#~ msgid "Favourites"
244−#~ msgstr "المفضلات"
po/az.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-26 23:48+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Azerbaijani <az@li.org>\n"
13"Language-Team: Azerbaijani <az@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Bağışlayın, amma axtarışınıza heç bir nəticə uyğun gəlmir."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "İnsanlar"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Əsas Ekran"
po/bg.po+3−15
@@ -8,15 +8,15 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-19 15:47+0000\n"
11+"PO-Revision-Date: 2013-06-27 00:06+0000\n"
12"Last-Translator: Miroslav E. Hadzhiev (Хаджиев) "
12"Last-Translator: Miroslav E. Hadzhiev (Хаджиев) "
13"<miroslav.hadzhiev@gmail.com>\n"
13"<miroslav.hadzhiev@gmail.com>\n"
14"Language-Team: Bulgarian <bg@li.org>\n"
14"Language-Team: Bulgarian <bg@li.org>\n"
15"MIME-Version: 1.0\n"
15"MIME-Version: 1.0\n"
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
19−"X-Generator: Launchpad (build 16681)\n"
19+"X-Generator: Launchpad (build 16696)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -219,15 +219,3 @@ msgstr "Съжаляваме, няма нищо, което да отговар
219#, qt-format
219#, qt-format
220msgid "Please enter %1"
220msgid "Please enter %1"
221msgstr ""
221msgstr ""
222−
223−#~ msgid "Favourites"
224−#~ msgstr "Любими"
225−
226−#~ msgid "People"
227−#~ msgstr "Хора"
228−
229−#~ msgid "A-Z"
230−#~ msgstr "А-Я"
231−
232−#~ msgid "Home screen"
233−#~ msgstr "Начален екран"
po/ca.po+4−16
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 00:24+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Catalan <ca@li.org>\n"
13"Language-Team: Catalan <ca@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,15 +218,3 @@ msgstr "No hi ha res que coincideixi amb la cerca"
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Gent"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Pantalla d'inici"
227−
228−#~ msgid "Favourite People"
229−#~ msgstr "Gent preferida"
230−
231−#~ msgid "People Recently in Touch"
232−#~ msgstr "Gent amb qui heu parlat"
po/de.po+5−29
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-29 12:53+0000\n"
11+"PO-Revision-Date: 2013-06-27 00:37+0000\n"
12−"Last-Translator: Phillip Sz <Unknown>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: German <de@li.org>\n"
13"Language-Team: German <de@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-30 07:12+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16692)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -217,28 +217,4 @@ msgstr "Entschuldigung, es wurden keine Treffer erzielt."
217#: Shell.qml:383
217#: Shell.qml:383
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220−msgstr "Bitte geben Sie %1 ein"
220+msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Personen"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Startseite"
227−
228−#~ msgid "Favourite People"
229−#~ msgstr "Lieblingspersonen"
230−
231−#~ msgid "People Recently in Touch"
232−#~ msgstr "Zuletzt kontaktierte Personen"
233−
234−#~ msgid "A-Z"
235−#~ msgstr "A-Z"
236−
237−#~ msgid "Recently in touch"
238−#~ msgstr "Kürzlich im Gespräch"
239−
240−#~ msgid "New Contacts"
241−#~ msgstr "Neue Kontakte"
242−
243−#~ msgid "Favourites"
244−#~ msgstr "Favoriten"
po/el.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 00:53+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Greek <el@li.org>\n"
13"Language-Team: Greek <el@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Λυπούμαστε, δεν υπάρχει τίποτα που να τ
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Πρόσωπα"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Αρχική οθόνη"
po/en_AU.po+3−27
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-18 20:36+0000\n"
11+"PO-Revision-Date: 2013-06-27 01:13+0000\n"
12"Last-Translator: Jackson Doak <Doak.jackson@gmail.com>\n"
12"Last-Translator: Jackson Doak <Doak.jackson@gmail.com>\n"
13"Language-Team: English (Australia) <en_AU@li.org>\n"
13"Language-Team: English (Australia) <en_AU@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,27 +218,3 @@ msgstr "Sorry, there is nothing that matches your search."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "People"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Home screen"
227−
228−#~ msgid "Favourite People"
229−#~ msgstr "Favourite People"
230−
231−#~ msgid "People Recently in Touch"
232−#~ msgstr "People Recently in Touch"
233−
234−#~ msgid "A-Z"
235−#~ msgstr "A-Z"
236−
237−#~ msgid "Recently in touch"
238−#~ msgstr "Recently in touch"
239−
240−#~ msgid "New Contacts"
241−#~ msgstr "New Contacts"
242−
243−#~ msgid "Favourites"
244−#~ msgstr "Favourites"
po/en_GB.po+4−28
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-27 00:22+0000\n"
11+"PO-Revision-Date: 2013-06-27 08:53+0000\n"
12−"Last-Translator: Andi Chandler <Unknown>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
13"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,27 +218,3 @@ msgstr "Sorry, there is nothing that matches your search."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr "Please enter %1"
220msgstr "Please enter %1"
221−
222−#~ msgid "Favourite People"
223−#~ msgstr "Favourite People"
224−
225−#~ msgid "People Recently in Touch"
226−#~ msgstr "People Recently in Touch"
227−
228−#~ msgid "People"
229−#~ msgstr "People"
230−
231−#~ msgid "A-Z"
232−#~ msgstr "A-Z"
233−
234−#~ msgid "Recently in touch"
235−#~ msgstr "Recently in touch"
236−
237−#~ msgid "New Contacts"
238−#~ msgstr "New Contacts"
239−
240−#~ msgid "Favourites"
241−#~ msgstr "Favourites"
242−
243−#~ msgid "Home screen"
244−#~ msgstr "Home screen"
po/eo.po+3−3
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-26 22:35+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Esperanto <eo@li.org>\n"
13"Language-Team: Esperanto <eo@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/es.po+1−1
@@ -14,7 +14,7 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-09 06:13+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18"X-Generator: Launchpad (build 16696)\n"
18"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
po/fi.po+4−25
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-10 16:19+0000\n"
11+"PO-Revision-Date: 2013-06-27 02:43+0000\n"
12−"Last-Translator: Jiri Grönroos <Unknown>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Finnish <fi@li.org>\n"
13"Language-Team: Finnish <fi@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,24 +218,3 @@ msgstr "Hakuun täsmääviä tuloksia ei löydy."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Ihmiset"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Kotinäyttö"
227−
228−#~ msgid "Favourite People"
229−#~ msgstr "Suosikkihenkilöt"
230−
231−#~ msgid "People Recently in Touch"
232−#~ msgstr "Viimeksi yhteydessä olleet henkilöt"
233−
234−#~ msgid "Favourites"
235−#~ msgstr "Suosikit"
236−
237−#~ msgid "Recently in touch"
238−#~ msgstr "Viimeksi yhteydessä"
239−
240−#~ msgid "New Contacts"
241−#~ msgstr "Uudet yhteystiedot"
po/fo.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 02:57+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Faroese <fo@li.org>\n"
13"Language-Team: Faroese <fo@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Tíanverri er tað einki sum hóskar til tína leiting."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Fólk"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Heimaskíggi"
po/fr.po+40−61
@@ -8,62 +8,62 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-26 15:11+0000\n"
11+"PO-Revision-Date: 2013-06-27 03:21+0000\n"
12−"Last-Translator: Anne <anneonyme017@gmail.com>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: French <fr@li.org>\n"
13"Language-Team: French <fr@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
22−msgstr "Téléphone"
22+msgstr ""
23
23
24#: Applications/applications.js:29
24#: Applications/applications.js:29
25msgid "Camera"
25msgid "Camera"
26−msgstr "Appareil photo"
26+msgstr ""
27
27
28#: Applications/applications.js:35
28#: Applications/applications.js:35
29msgid "Gallery"
29msgid "Gallery"
30−msgstr "Galerie"
30+msgstr ""
31
31
32#: Applications/applications.js:40
32#: Applications/applications.js:40
33msgid "Facebook"
33msgid "Facebook"
34−msgstr "Facebook"
34+msgstr ""
35
35
36#: Applications/applications.js:46
36#: Applications/applications.js:46
37msgid "Browser"
37msgid "Browser"
38−msgstr "Navigateur"
38+msgstr ""
39
39
40#: Applications/applications.js:51
40#: Applications/applications.js:51
41msgid "Twitter"
41msgid "Twitter"
42−msgstr "Twitter"
42+msgstr ""
43
43
44#: Applications/applications.js:57
44#: Applications/applications.js:57
45msgid "GMail"
45msgid "GMail"
46−msgstr "GMail"
46+msgstr ""
47
47
48#: Applications/applications.js:62
48#: Applications/applications.js:62
49msgid "Weather"
49msgid "Weather"
50−msgstr "Météo"
50+msgstr ""
51
51
52#: Applications/applications.js:68
52#: Applications/applications.js:68
53msgid "Notepad"
53msgid "Notepad"
54−msgstr "Bloc-notes"
54+msgstr ""
55
55
56#: Applications/applications.js:74
56#: Applications/applications.js:74
57msgid "Calendar"
57msgid "Calendar"
58−msgstr "Agenda"
58+msgstr ""
59
59
60#: Applications/applications.js:80
60#: Applications/applications.js:80
61msgid "Media Player"
61msgid "Media Player"
62−msgstr "Lecteur multimédia"
62+msgstr ""
63
63
64#: Applications/applications.js:86
64#: Applications/applications.js:86
65msgid "Evernote"
65msgid "Evernote"
66−msgstr "Evernote"
66+msgstr ""
67
67
68#: Applications/applications.js:91
68#: Applications/applications.js:91
69msgid "Map"
69msgid "Map"
@@ -71,27 +71,27 @@ msgstr ""
71
71
72#: Applications/applications.js:96
72#: Applications/applications.js:96
73msgid "Pinterest"
73msgid "Pinterest"
74−msgstr "Pinterest"
74+msgstr ""
75
75
76#: Applications/applications.js:101
76#: Applications/applications.js:101
77msgid "SoundCloud"
77msgid "SoundCloud"
78−msgstr "SoundCloud"
78+msgstr ""
79
79
80#: Applications/applications.js:106
80#: Applications/applications.js:106
81msgid "Wikipedia"
81msgid "Wikipedia"
82−msgstr "Wikipédia"
82+msgstr ""
83
83
84#: Applications/applications.js:111
84#: Applications/applications.js:111
85msgid "YouTube"
85msgid "YouTube"
86−msgstr "YouTube"
86+msgstr ""
87
87
88#: Components/PageHeader.qml:300
88#: Components/PageHeader.qml:300
89msgid "Recent searches"
89msgid "Recent searches"
90−msgstr "Recherches récentes"
90+msgstr ""
91
91
92#: Dash/DashApps.qml:65
92#: Dash/DashApps.qml:65
93msgid "Running apps"
93msgid "Running apps"
94−msgstr "Applications en cours d’exécution"
94+msgstr ""
95
95
96#: Dash/DashApps.qml:68
96#: Dash/DashApps.qml:68
97msgid "Frequently used"
97msgid "Frequently used"
@@ -99,7 +99,7 @@ msgstr ""
99
99
100#: Dash/DashApps.qml:71
100#: Dash/DashApps.qml:71
101msgid "Installed"
101msgid "Installed"
102−msgstr "Installées"
102+msgstr ""
103
103
104#: Dash/DashApps.qml:74
104#: Dash/DashApps.qml:74
105msgid "Available for download"
105msgid "Available for download"
@@ -111,19 +111,19 @@ msgstr "Applications"
111
111
112#: Dash/DashHome.qml:40
112#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114−msgstr "Applications fréquemment utilisées"
114+msgstr ""
115
115
116#: Dash/DashHome.qml:43
116#: Dash/DashHome.qml:43
117msgid "Recent Music"
117msgid "Recent Music"
118−msgstr "Musique récente"
118+msgstr ""
119
119
120#: Dash/DashHome.qml:46
120#: Dash/DashHome.qml:46
121msgid "Videos Popular Online"
121msgid "Videos Popular Online"
122−msgstr "Vidéos populaires en ligne"
122+msgstr ""
123
123
124#: Dash/DashHome.qml:175
124#: Dash/DashHome.qml:175
125msgid "Home"
125msgid "Home"
126−msgstr "Accueil"
126+msgstr ""
127
127
128#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
128#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
129msgid "Featured"
129msgid "Featured"
@@ -135,7 +135,7 @@ msgstr ""
135
135
136#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
136#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
137msgid "New Releases"
137msgid "New Releases"
138−msgstr "Nouveautés"
138+msgstr ""
139
139
140#: Dash/DashMusic.qml:30
140#: Dash/DashMusic.qml:30
141msgid "Top Charting"
141msgid "Top Charting"
@@ -155,15 +155,15 @@ msgstr "Vidéos"
155
155
156#: Dash/Video/VideoPreview.qml:98
156#: Dash/Video/VideoPreview.qml:98
157msgid "Directed by:"
157msgid "Directed by:"
158−msgstr "Réalisé par :"
158+msgstr ""
159
159
160#: Dash/Video/VideoPreview.qml:121
160#: Dash/Video/VideoPreview.qml:121
161msgid "Starring:"
161msgid "Starring:"
162−msgstr "Acteurs :"
162+msgstr ""
163
163
164#: Dash/Video/VideoPreview.qml:144
164#: Dash/Video/VideoPreview.qml:144
165msgid "Author:"
165msgid "Author:"
166−msgstr "Auteur :"
166+msgstr ""
167
167
168#: Greeter/Lockscreen.qml:133
168#: Greeter/Lockscreen.qml:133
169msgid "Emergency call"
169msgid "Emergency call"
@@ -172,27 +172,27 @@ msgstr ""
172#: Greeter/PassphraseLockscreen.qml:59
172#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
173#, qt-format
174msgid "Hello %1"
174msgid "Hello %1"
175−msgstr "Bonjour %1"
175+msgstr ""
176
176
177#: Greeter/PassphraseLockscreen.qml:59
177#: Greeter/PassphraseLockscreen.qml:59
178msgid "Hello"
178msgid "Hello"
179−msgstr "Bonjour"
179+msgstr ""
180
180
181#: Hud/HudParametrizedActionsPage.qml:132
181#: Hud/HudParametrizedActionsPage.qml:132
182msgid "Confirm"
182msgid "Confirm"
183−msgstr "Confirmer"
183+msgstr ""
184
184
185#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
185#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
186msgid "Type or say a command"
186msgid "Type or say a command"
187−msgstr "Entrez ou dictez une commande"
187+msgstr ""
188
188
189#: Hud/Hud.qml:84
189#: Hud/Hud.qml:84
190msgid "Loading. Please Wait..."
190msgid "Loading. Please Wait..."
191−msgstr "Chargement. Veuillez patienter..."
191+msgstr ""
192
192
193#: Hud/Hud.qml:89
193#: Hud/Hud.qml:89
194msgid "Speak Now..."
194msgid "Speak Now..."
195−msgstr "Parlez maintenant..."
195+msgstr ""
196
196
197#: Hud/Hud.qml:94
197#: Hud/Hud.qml:94
198msgid "Speaking..."
198msgid "Speaking..."
@@ -204,38 +204,17 @@ msgstr ""
204
204
205#: Panel/Menus/Overview/FlightModeWidget.qml:42
205#: Panel/Menus/Overview/FlightModeWidget.qml:42
206msgid "Flight mode"
206msgid "Flight mode"
207−msgstr "Mode avion"
207+msgstr ""
208
208
209#: Panel/SearchIndicator.qml:26
209#: Panel/SearchIndicator.qml:26
210msgid "Search"
210msgid "Search"
211−msgstr "Rechercher"
211+msgstr ""
212
212
213#: plugins/Unity/scope.cpp:268
213#: plugins/Unity/scope.cpp:268
214msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
215−msgstr "Désolé, aucun résultat ne correspond à votre recherche."
215+msgstr ""
216
216
217#: Shell.qml:383
217#: Shell.qml:383
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "Home screen"
223−#~ msgstr "Écran d’accueil"
224−
225−#~ msgid "People"
226−#~ msgstr "Contacts"
227−
228−#~ msgid "Favourite People"
229−#~ msgstr "Contacts favoris"
230−
231−#~ msgid "People Recently in Touch"
232−#~ msgstr "Contacts récents"
233−
234−#~ msgid "A-Z"
235−#~ msgstr "A-Z"
236−
237−#~ msgid "New Contacts"
238−#~ msgstr "Nouveaux contacts"
239−
240−#~ msgid "Favourites"
241−#~ msgstr "Favoris"
po/gl.po+4−16
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 03:38+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Galician <gl@li.org>\n"
13"Language-Team: Galician <gl@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,15 +218,3 @@ msgstr "Sentímolo, non hai nada que coincida con esta busca."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Persoas"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Pantalla de inicio"
227−
228−#~ msgid "Favourite People"
229−#~ msgstr "Xente favorita"
230−
231−#~ msgid "People Recently in Touch"
232−#~ msgstr "Xente contactada recentemente"
po/he.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 03:54+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Hebrew <he@li.org>\n"
13"Language-Team: Hebrew <he@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "שום דבר אינו תואם לחיפוש שלך, עמך הסליחה
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "אנשים"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "מסך הבית"
po/hr.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 04:14+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Croatian <hr@li.org>\n"
13"Language-Team: Croatian <hr@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Nažalost, ne postoji ništa što odgovara vašoj pretrazi."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Osobe"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Početni zaslon"
po/hu.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 04:28+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Elnézést, nincs találat a keresésre."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Emberek"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Kezdőképernyő"
po/hy.po+3−15
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-07 12:42+0000\n"
11+"PO-Revision-Date: 2013-06-27 04:43+0000\n"
12"Last-Translator: iAbaS <sosabazyan@yandex.ru>\n"
12"Last-Translator: iAbaS <sosabazyan@yandex.ru>\n"
13"Language-Team: Armenian <hy@li.org>\n"
13"Language-Team: Armenian <hy@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,15 +218,3 @@ msgstr "Կներերք, բայց Ձեր հարցումով ոչինչ չկար"
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People Recently in Touch"
223−#~ msgstr "Վերջին մարդիկ"
224−
225−#~ msgid "Favourite People"
226−#~ msgstr "Ֆավորիտներ"
227−
228−#~ msgid "People"
229−#~ msgstr "Մարդիկ"
230−
231−#~ msgid "Home screen"
232−#~ msgstr "Տուն"
po/id.po+3−3
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-26 22:35+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Indonesian <id@li.org>\n"
13"Language-Team: Indonesian <id@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/it.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 05:14+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Italian <it@li.org>\n"
13"Language-Team: Italian <it@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Nessun risultato corrispondente alla ricerca."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Contatti"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Home"
po/ja.po+3−3
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-15 14:12+0000\n"
11+"PO-Revision-Date: 2013-06-26 22:36+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Japanese <ja@li.org>\n"
13"Language-Team: Japanese <ja@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/kn.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 05:43+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Kannada <kn@li.org>\n"
13"Language-Team: Kannada <kn@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "ಕ್ಷಮಿಸಿ ನಿಮ್ಮ ಶೋಧನೆಗೆ ಸರಿಯ
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "ಜನರು"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "ಹೋಮ್ ಸ್ಕ್ರೀನ್"
po/ko.po+4−4
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 05:59+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Korean <ko@li.org>\n"
13"Language-Team: Korean <ko@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/ky.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 06:17+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Kirghiz <ky@li.org>\n"
13"Language-Team: Kirghiz <ky@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Тилекке каршы, сиздин издөөңүзгө эч нер
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Адамдар"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Башкы экран"
po/lv.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 06:31+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Latvian <lv@li.org>\n"
13"Language-Team: Latvian <lv@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Diemžēl nekas neatbilst jūsu meklētajam."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Cilvēki"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Mājas ekrāns"
po/my.po+4−7
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 06:47+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Burmese <my@li.org>\n"
13"Language-Team: Burmese <my@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,6 +218,3 @@ msgstr "ဆောရီး၊ သင်၏ရှာဖွေမူနှင့
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "လူ"
po/nb.po+3−9
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-17 09:10+0000\n"
11+"PO-Revision-Date: 2013-06-27 07:02+0000\n"
12"Last-Translator: Joakim Langvand <jlangvand@gmail.com>\n"
12"Last-Translator: Joakim Langvand <jlangvand@gmail.com>\n"
13"Language-Team: Norwegian Bokmal <nb@li.org>\n"
13"Language-Team: Norwegian Bokmal <nb@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Søket ga ingen treff."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Personer"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Hjemmeskjerm"
po/nl.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 07:19+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Dutch <nl@li.org>\n"
13"Language-Team: Dutch <nl@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Er is helaas niets dat met uw zoekopdracht overeenkomt."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Mensen"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Startscherm"
po/pl.po+8−32
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:43+0000\n"
11+"PO-Revision-Date: 2013-06-27 08:52+0000\n"
12−"Last-Translator: Piotr Merski <Unknown>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Polish <pl@li.org>\n"
13"Language-Team: Polish <pl@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -167,16 +167,16 @@ msgstr "Autor:"
167
167
168#: Greeter/Lockscreen.qml:133
168#: Greeter/Lockscreen.qml:133
169msgid "Emergency call"
169msgid "Emergency call"
170−msgstr ""
170+msgstr "Telefon alarmowy"
171
171
172#: Greeter/PassphraseLockscreen.qml:59
172#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
173#, qt-format
174msgid "Hello %1"
174msgid "Hello %1"
175−msgstr ""
175+msgstr "Witaj %1"
176
176
177#: Greeter/PassphraseLockscreen.qml:59
177#: Greeter/PassphraseLockscreen.qml:59
178msgid "Hello"
178msgid "Hello"
179−msgstr ""
179+msgstr "Witaj"
180
180
181#: Hud/HudParametrizedActionsPage.qml:132
181#: Hud/HudParametrizedActionsPage.qml:132
182msgid "Confirm"
182msgid "Confirm"
@@ -217,28 +217,4 @@ msgstr "Nie znaleziono pasujących wyników."
217#: Shell.qml:383
217#: Shell.qml:383
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220−msgstr ""
220+msgstr "Wprowadź %1"
221−
222−#~ msgid "Home screen"
223−#~ msgstr "Ekran domowy"
224−
225−#~ msgid "People"
226−#~ msgstr "Ludzie"
227−
228−#~ msgid "People Recently in Touch"
229−#~ msgstr "Osoby ostatnio w kontakcie"
230−
231−#~ msgid "Favourite People"
232−#~ msgstr "Ulubione kontakty"
233−
234−#~ msgid "A-Z"
235−#~ msgstr "A-Z"
236−
237−#~ msgid "Recently in touch"
238−#~ msgstr "Ostatnio w kontakcie"
239−
240−#~ msgid "New Contacts"
241−#~ msgstr "Nowe kontakty"
242−
243−#~ msgid "Favourites"
244−#~ msgstr "Ulubione"
po/pt_BR.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 07:39+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
13"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Desculpe, não há nada que corresponda à sua pesquisa."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Pessoas"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Tela inicial"
po/ro.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 07:53+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Romanian <ro@li.org>\n"
13"Language-Team: Romanian <ro@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -219,9 +219,3 @@ msgstr ""
219#, qt-format
219#, qt-format
220msgid "Please enter %1"
220msgid "Please enter %1"
221msgstr ""
221msgstr ""
222−
223−#~ msgid "People"
224−#~ msgstr "Persoane"
225−
226−#~ msgid "Home screen"
227−#~ msgstr "Ecran principal"
po/ru.po+22−37
@@ -8,58 +8,58 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-21 10:08+0000\n"
11+"PO-Revision-Date: 2013-06-28 06:40+0000\n"
12−"Last-Translator: Andrey Dedikov <iamawesome.ndr@gmail.com>\n"
12+"Last-Translator: Eugene Marshal <Unknown>\n"
13"Language-Team: Russian <ru@li.org>\n"
13"Language-Team: Russian <ru@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
22−msgstr ""
22+msgstr "Телефон"
23
23
24#: Applications/applications.js:29
24#: Applications/applications.js:29
25msgid "Camera"
25msgid "Camera"
26−msgstr ""
26+msgstr "Камера"
27
27
28#: Applications/applications.js:35
28#: Applications/applications.js:35
29msgid "Gallery"
29msgid "Gallery"
30−msgstr ""
30+msgstr "Галерея"
31
31
32#: Applications/applications.js:40
32#: Applications/applications.js:40
33msgid "Facebook"
33msgid "Facebook"
34−msgstr ""
34+msgstr "Facebook"
35
35
36#: Applications/applications.js:46
36#: Applications/applications.js:46
37msgid "Browser"
37msgid "Browser"
38−msgstr ""
38+msgstr "Обозреватель"
39
39
40#: Applications/applications.js:51
40#: Applications/applications.js:51
41msgid "Twitter"
41msgid "Twitter"
42−msgstr ""
42+msgstr "Twitter"
43
43
44#: Applications/applications.js:57
44#: Applications/applications.js:57
45msgid "GMail"
45msgid "GMail"
46−msgstr ""
46+msgstr "GMail"
47
47
48#: Applications/applications.js:62
48#: Applications/applications.js:62
49msgid "Weather"
49msgid "Weather"
50−msgstr ""
50+msgstr "Погода"
51
51
52#: Applications/applications.js:68
52#: Applications/applications.js:68
53msgid "Notepad"
53msgid "Notepad"
54−msgstr ""
54+msgstr "Блокнот"
55
55
56#: Applications/applications.js:74
56#: Applications/applications.js:74
57msgid "Calendar"
57msgid "Calendar"
58−msgstr ""
58+msgstr "Календарь"
59
59
60#: Applications/applications.js:80
60#: Applications/applications.js:80
61msgid "Media Player"
61msgid "Media Player"
62−msgstr ""
62+msgstr "Медиапроигрыватель"
63
63
64#: Applications/applications.js:86
64#: Applications/applications.js:86
65msgid "Evernote"
65msgid "Evernote"
@@ -67,7 +67,7 @@ msgstr "Evernote"
67
67
68#: Applications/applications.js:91
68#: Applications/applications.js:91
69msgid "Map"
69msgid "Map"
70−msgstr ""
70+msgstr "Карта"
71
71
72#: Applications/applications.js:96
72#: Applications/applications.js:96
73msgid "Pinterest"
73msgid "Pinterest"
@@ -79,11 +79,11 @@ msgstr "SoundCloud"
79
79
80#: Applications/applications.js:106
80#: Applications/applications.js:106
81msgid "Wikipedia"
81msgid "Wikipedia"
82−msgstr ""
82+msgstr "Википедия"
83
83
84#: Applications/applications.js:111
84#: Applications/applications.js:111
85msgid "YouTube"
85msgid "YouTube"
86−msgstr ""
86+msgstr "YouTube"
87
87
88#: Components/PageHeader.qml:300
88#: Components/PageHeader.qml:300
89msgid "Recent searches"
89msgid "Recent searches"
@@ -131,7 +131,7 @@ msgstr ""
131
131
132#: Dash/DashMusic.qml:28 Dash/DashVideos.qml:29
132#: Dash/DashMusic.qml:28 Dash/DashVideos.qml:29
133msgid "Recent"
133msgid "Recent"
134−msgstr ""
134+msgstr "Недавние"
135
135
136#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
136#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
137msgid "New Releases"
137msgid "New Releases"
@@ -163,11 +163,11 @@ msgstr "В главных ролях"
163
163
164#: Dash/Video/VideoPreview.qml:144
164#: Dash/Video/VideoPreview.qml:144
165msgid "Author:"
165msgid "Author:"
166−msgstr ""
166+msgstr "Автор:"
167
167
168#: Greeter/Lockscreen.qml:133
168#: Greeter/Lockscreen.qml:133
169msgid "Emergency call"
169msgid "Emergency call"
170−msgstr ""
170+msgstr "Экстренный вызов"
171
171
172#: Greeter/PassphraseLockscreen.qml:59
172#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
173#, qt-format
@@ -217,19 +217,4 @@ msgstr "Извините, поиск не дал результатов."
217#: Shell.qml:383
217#: Shell.qml:383
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220−msgstr ""
220+msgstr "Пожалуйста, введите %1"
221−
222−#~ msgid "People"
223−#~ msgstr "Люди"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Главный экран"
227−
228−#~ msgid "Favourite People"
229−#~ msgstr "Избранные контакты"
230−
231−#~ msgid "People Recently in Touch"
232−#~ msgstr "Недавние контакты"
233−
234−#~ msgid "New Contacts"
235−#~ msgstr "Новые контакты"
po/si.po+3−3
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-26 22:36+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Sinhalese <si@li.org>\n"
13"Language-Team: Sinhalese <si@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/sl.po+1−1
@@ -14,7 +14,7 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-06 08:44+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18"X-Generator: Launchpad (build 16696)\n"
18"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
po/sr.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 09:19+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Serbian <sr@li.org>\n"
13"Language-Team: Serbian <sr@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Нажалост, претрага није наишла на икакв
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Људи"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Почетни екран"
po/sv.po+3−3
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-26 22:36+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Swedish <sv@li.org>\n"
13"Language-Team: Swedish <sv@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/te.po+4−4
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 09:57+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Telugu <te@li.org>\n"
13"Language-Team: Telugu <te@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/tr.po+3−24
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-24 17:24+0000\n"
11+"PO-Revision-Date: 2013-06-27 10:08+0000\n"
12"Last-Translator: Adar Cem EREN <adarcemeren34@gmail.com>\n"
12"Last-Translator: Adar Cem EREN <adarcemeren34@gmail.com>\n"
13"Language-Team: Turkish <tr@li.org>\n"
13"Language-Team: Turkish <tr@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,24 +218,3 @@ msgstr "Üzgünüz, aramanızla eşleşen hiçbir şey yok."
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Kişiler"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Başlangıç ekranı"
227−
228−#~ msgid "Favourite People"
229−#~ msgstr "Favori Kişiler"
230−
231−#~ msgid "People Recently in Touch"
232−#~ msgstr "En Son Konuşulan Kişiler"
233−
234−#~ msgid "A-Z"
235−#~ msgstr "A-Z"
236−
237−#~ msgid "New Contacts"
238−#~ msgstr "Yeni Kişiler"
239−
240−#~ msgid "Favourites"
241−#~ msgstr "Favoriler"
po/ug.po+6−27
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-28 04:36+0000\n"
11+"PO-Revision-Date: 2013-06-27 11:02+0000\n"
12−"Last-Translator: Gheyret T.Kenji <Unknown>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Uyghur <ug@li.org>\n"
13"Language-Team: Uyghur <ug@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-30 07:12+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16692)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -172,7 +172,7 @@ msgstr "جىددىي تېلېفون"
172#: Greeter/PassphraseLockscreen.qml:59
172#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
173#, qt-format
174msgid "Hello %1"
174msgid "Hello %1"
175−msgstr "سالام %1"
175+msgstr ""
176
176
177#: Greeter/PassphraseLockscreen.qml:59
177#: Greeter/PassphraseLockscreen.qml:59
178msgid "Hello"
178msgid "Hello"
@@ -217,25 +217,4 @@ msgstr "كەچۈرۈڭ، ئىزدىگىنىڭىزگە ماس نەتىجە تېپ
217#: Shell.qml:383
217#: Shell.qml:383
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220−msgstr "%1 نى كىرگۈزۈڭ"
220+msgstr ""
221−
222−#~ msgid "Favourite People"
223−#~ msgstr "ھەمىشە ئالاقە قىلىدىغان كىشىلەر"
224−
225−#~ msgid "People Recently in Touch"
226−#~ msgstr "يېقىندا ئالاقە قىلغان كىشىلەر"
227−
228−#~ msgid "People"
229−#~ msgstr "كىشىلەر"
230−
231−#~ msgid "Home screen"
232−#~ msgstr "ماكان ئېكران"
233−
234−#~ msgid "A-Z"
235−#~ msgstr "A-Z"
236−
237−#~ msgid "Recently in touch"
238−#~ msgstr "يېقىندا ئالاقە قىلغانلار"
239−
240−#~ msgid "New Contacts"
241−#~ msgstr "يېڭى ئالاقەداشلار"
po/uk.po+4−28
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-29 14:27+0000\n"
11+"PO-Revision-Date: 2013-07-21 05:47+0000\n"
12−"Last-Translator: Roman Koshkin <mar2008m@rambler.ru>\n"
12+"Last-Translator: Ярослав Смук <Smuk.Slavko@yandex.ua>\n"
13"Language-Team: Ukrainian <uk@li.org>\n"
13"Language-Team: Ukrainian <uk@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-30 07:12+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-22 06:19+0000\n"
18−"X-Generator: Launchpad (build 16692)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,27 +218,3 @@ msgstr "Вибачте, для вказаних вами ключових слі
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr "Будь ласка, введіть %1"
220msgstr "Будь ласка, введіть %1"
221−
222−#~ msgid "People"
223−#~ msgstr "Люди"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Екран домівки"
227−
228−#~ msgid "Favourite People"
229−#~ msgstr "Вибрані контакти"
230−
231−#~ msgid "People Recently in Touch"
232−#~ msgstr "Недавні контакти"
233−
234−#~ msgid "A-Z"
235−#~ msgstr "А-Я"
236−
237−#~ msgid "New Contacts"
238−#~ msgstr "Нові контакти"
239−
240−#~ msgid "Favourites"
241−#~ msgstr "Улюблене"
242−
243−#~ msgid "Recently in touch"
244−#~ msgstr "Нещодавні контакти"
po/zh_CN.po+3−27
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-22 21:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 10:33+0000\n"
12"Last-Translator: Anthony Wong <anthony.wong@canonical.com>\n"
12"Last-Translator: Anthony Wong <anthony.wong@canonical.com>\n"
13"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
13"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,27 +218,3 @@ msgstr "对不起,没有找到您想要的结果。"
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "Home screen"
223−#~ msgstr "主页"
224−
225−#~ msgid "Favourite People"
226−#~ msgstr "常用联系人"
227−
228−#~ msgid "People Recently in Touch"
229−#~ msgstr "近期联系人"
230−
231−#~ msgid "People"
232−#~ msgstr "联系人"
233−
234−#~ msgid "Recently in touch"
235−#~ msgstr "最近联系"
236−
237−#~ msgid "New Contacts"
238−#~ msgstr "新建联系人"
239−
240−#~ msgid "Favourites"
241−#~ msgstr "最爱"
242−
243−#~ msgid "A-Z"
244−#~ msgstr "A-Z"
po/zh_TW.po+4−16
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-27 10:24+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
13"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -218,15 +218,3 @@ msgstr "很抱歉,找不到符合您想搜尋的結果。"
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220msgstr ""
220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "朋友"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "家屋畫面"
227−
228−#~ msgid "Favourite People"
229−#~ msgstr "喜歡的朋友"
230−
231−#~ msgid "People Recently in Touch"
232−#~ msgstr "最近接觸的朋友"
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
run_on_device+4−22
@@ -33,7 +33,7 @@ usage() {
33}
33}
34
34
35exec_with_ssh() {
35exec_with_ssh() {
36− ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -t $USER@$TARGET_IP -p $TARGET_SSH_PORT "bash -ic \"$@\""
36+ ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -t $USER@$TARGET_IP -p $TARGET_SSH_PORT sudo -u $USER -i bash -ic \"$@\"
37}
37}
38
38
39exec_with_adb() {
39exec_with_adb() {
@@ -65,11 +65,9 @@ setup_adb_forwarding() {
65}
65}
66
66
67install_dependencies() {
67install_dependencies() {
68+ exec_with_adb apt-get update
68 exec_with_adb apt-get -y install openssh-server
69 exec_with_adb apt-get -y install openssh-server
69 exec_with_ssh $SUDO apt-get -y install build-essential rsync bzr ccache gdb ninja-build devscripts equivs
70 exec_with_ssh $SUDO apt-get -y install build-essential rsync bzr ccache gdb ninja-build devscripts equivs
70− exec_with_ssh $SUDO add-apt-repository -y ppa:canonical-qt5-edgers/qt5-proper
71− exec_with_ssh $SUDO add-apt-repository -s -y ppa:phablet-team/ppa
72− exec_with_ssh $SUDO apt-get update
73}
71}
74
72
75sync_code() {
73sync_code() {
@@ -85,17 +83,6 @@ build() {
85}
83}
86
84
87run() {
85run() {
88− SERVICEFILE="${CHROOT_PREFIX}/etc/device-services"
89− adb shell "egrep '$BINARY' $SERVICEFILE"
90− CONTAINS_SHELL=$?
91− if [ $CONTAINS_SHELL -eq 0 ]; then
92− echo "Modifying $SERVICEFILE on device. Old contents will be saved in $SERVICEFILE.backup"
93− adb shell cp $SERVICEFILE $SERVICEFILE.backup
94− adb shell sed -i "/$BINARY/d" $SERVICEFILE
95− if $FLIPPED; then exec_with_adb /usr/bin/service ubuntu-touch-session restart
96− else exec_with_adb /usr/bin/service ubuntu-session restart; fi
97− fi
98− adb shell pkill $BINARY
99 ARGS="--nomousetouch"
86 ARGS="--nomousetouch"
100 if $GDB; then
87 if $GDB; then
101 ARGS="$ARGS --gdb"
88 ARGS="$ARGS --gdb"
@@ -107,14 +94,9 @@ run() {
107 ARGS="$ARGS -k"
94 ARGS="$ARGS -k"
108 fi
95 fi
109
96
97+ exec_with_ssh "stop unity8"
110 exec_with_ssh "cd $CODE_DIR/ && ./run $ARGS -- $RUN_OPTIONS"
98 exec_with_ssh "cd $CODE_DIR/ && ./run $ARGS -- $RUN_OPTIONS"
111−
99+ exec_with_ssh "start unity8"
112− if [ $CONTAINS_SHELL -eq 0 ]; then
113− echo "Restoring $SERVICEFILE on device from $SERVICEFILE.backup"
114− adb shell cp $SERVICEFILE.backup $SERVICEFILE
115− if $FLIPPED; then exec_with_adb /usr/bin/service ubuntu-touch-session restart
116− else exec_with_adb /usr/bin/service ubuntu-session restart; fi
117− fi
118}
100}
119
101
120set -- `getopt -n$0 -u -a --longoptions="setup,gdb,pinlock,keylock,help" "sgpkh" "$@"`
102set -- `getopt -n$0 -u -a --longoptions="setup,gdb,pinlock,keylock,help" "sgpkh" "$@"`
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/LightDM/demo/InfographicModelPrivate.cpp+3−3
@@ -54,7 +54,7 @@ void InfographicModelPrivate::generateFakeData()
54 QSharedPointer<InfographicData> data(
54 QSharedPointer<InfographicData> data(
55 new InfographicData("<b>52km</b> travelled", yellowTheme, firstMonth,
55 new InfographicData("<b>52km</b> travelled", yellowTheme, firstMonth,
56 orangeTheme, secondMonth, this));
56 orangeTheme, secondMonth, this));
57− m_fakeData.insert("guest", data);
57+ m_fakeData.insert("phablet", data);
58 }
58 }
59
59
60 {
60 {
@@ -69,7 +69,7 @@ void InfographicModelPrivate::generateFakeData()
69 QSharedPointer<InfographicData> data(
69 QSharedPointer<InfographicData> data(
70 new InfographicData("<b>33</b> messages today", pinkTheme,
70 new InfographicData("<b>33</b> messages today", pinkTheme,
71 firstMonth, orangeTheme, secondMonth, this));
71 firstMonth, orangeTheme, secondMonth, this));
72− m_fakeData.insert("guest", data);
72+ m_fakeData.insert("phablet", data);
73 }
73 }
74
74
75 {
75 {
@@ -84,7 +84,7 @@ void InfographicModelPrivate::generateFakeData()
84 QSharedPointer<InfographicData> data(
84 QSharedPointer<InfographicData> data(
85 new InfographicData("<b>69</b> minutes talk time", darkPurpleTheme,
85 new InfographicData("<b>69</b> minutes talk time", darkPurpleTheme,
86 firstMonth, redTheme, secondMonth, this));
86 firstMonth, redTheme, secondMonth, this));
87− m_fakeData.insert("guest", data);
87+ m_fakeData.insert("phablet", data);
88 }
88 }
89}
89}
90
90
tests/mocks/LightDM/demo/UsersModelPrivate.cpp+1−1
@@ -26,7 +26,7 @@ UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
26{
26{
27 entries =
27 entries =
28 {
28 {
29− { "single", "Guest", 0, 0, false, false, 0, 0 },
29+ { "phablet", "Guest", 0, 0, false, false, 0, 0 },
30 };
30 };
31}
31}
32
32
tests/mocks/Ubuntu/Application/ApplicationManager.cpp+2−2
@@ -321,10 +321,10 @@ void ApplicationManager::buildListOfAvailableApplications()
321 m_availableApplications.append(application);
321 m_availableApplications.append(application);
322
322
323 application = new ApplicationInfo(this);
323 application = new ApplicationInfo(this);
324− application->setDesktopFile("/usr/share/applications/ubuntu-calendar-app.desktop");
324+ application->setDesktopFile("/usr/share/applications/calendar-app.desktop");
325 application->setName("Calendar");
325 application->setName("Calendar");
326 application->setIcon("calendar");
326 application->setIcon("calendar");
327− application->setExec("/usr/bin/qmlscene /usr/share/ubuntu-calendar-app/calendar.qml");
327+ application->setExec("/usr/bin/qmlscene /usr/share/calendar-app/calendar.qml");
328 application->setStage(ApplicationInfo::SideStage);
328 application->setStage(ApplicationInfo::SideStage);
329 application->setHandle(nextHandle++);
329 application->setHandle(nextHandle++);
330 m_availableApplications.append(application);
330 m_availableApplications.append(application);
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+49
@@ -0,0 +1,49 @@
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+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/menucontentactivator.cpp
16+)
17+
18+set(IndicatorsFakeQml_RESOURCES
19+ indicators_fake.qrc
20+)
21+
22+qt5_add_resources(IndicatorsFakeQml_RESOURCES_RCC
23+ ${IndicatorsFakeQml_RESOURCES}
24+)
25+
26+add_library(IndicatorsFakeQml SHARED
27+ ${IndicatorsFakeQml_RESOURCES_RCC}
28+ ${IndicatorsFakeQml_SOURCES}
29+)
30+add_definitions(-DUNITYINDICATORS_LIBRARY)
31+
32+target_link_libraries(IndicatorsFakeQml)
33+
34+qt5_use_modules(IndicatorsFakeQml Core Qml Quick)
35+
36+file(GLOB IndicatorsFake_QMLFILES
37+ IndicatorsModel.qml
38+ qml/FakeMenuPage.qml
39+)
40+
41+# copy qmldir file into build directory for shadow builds
42+file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
43+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
44+)
45+
46+# copy qmldir file into build directory for shadow builds
47+file(COPY ${IndicatorsFake_QMLFILES}
48+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
49+)
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+41
@@ -0,0 +1,41 @@
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+#include "menucontentactivator.h"
28+
29+void IndicatorsFakePlugin::registerTypes(const char * uri)
30+{
31+ Q_INIT_RESOURCE(indicators_fake);
32+
33+ qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
34+
35+ qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
36+ qmlRegisterUncreatableType<ActionState>(uri, 0, 1, "ActionState", "Can't create ActionState class");
37+ qmlRegisterUncreatableType<NetworkActionState>(uri, 0, 1, "NetworkActionState", "Can't create NetworkActionState class");
38+ qmlRegisterUncreatableType<NetworkConnection>(uri, 0, 1, "NetworkConnection", "Can't create NetworkConnection class");
39+ qmlRegisterUncreatableType<IndicatorsModelRole>(uri, 0, 1, "IndicatorsModelRole", "Can't create IndicatorsModelRole class");
40+ qmlRegisterUncreatableType<FlatMenuProxyModelRole>(uri, 0, 1, "FlatMenuProxyModelRole", "Can't create FlatMenuProxyModelRole class");
41+}
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/mocks/Unity/Launcher/CMakeLists.txt+1−6
@@ -1,10 +1,5 @@
1−set(CMAKE_AUTOMOC ON)
2−
3include(FindPkgConfig)
1include(FindPkgConfig)
4−find_package(Qt5Core REQUIRED)
5−find_package(Qt5Quick REQUIRED)
6−
7−pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher)
2+pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=2)
8
3
9include_directories(
4include_directories(
10 ${CMAKE_CURRENT_SOURCE_DIR}
5 ${CMAKE_CURRENT_SOURCE_DIR}
tests/mocks/Unity/Launcher/MockLauncherModel.cpp+1−1
@@ -40,7 +40,7 @@ MockLauncherModel::MockLauncherModel(QObject* parent): LauncherModelInterface(pa
40 m_list.append(item);
40 m_list.append(item);
41 item = new MockLauncherItem("notes-app", "/usr/share/applications/notes-app.desktop", "Notepad", "notepad");
41 item = new MockLauncherItem("notes-app", "/usr/share/applications/notes-app.desktop", "Notepad", "notepad");
42 m_list.append(item);
42 m_list.append(item);
43− item = new MockLauncherItem("ubuntu-calendar-app", "/usr/share/applications/ubuntu-calendar-app.desktop","Calendar", "calendar");
43+ item = new MockLauncherItem("calendar-app", "/usr/share/applications/calendar-app.desktop","Calendar", "calendar");
44 m_list.append(item);
44 m_list.append(item);
45}
45}
46
46
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+19
@@ -991,6 +991,25 @@ private Q_SLOTS:
991 QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
991 QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
992 }
992 }
993
993
994+ void testInsertToEmpty()
995+ {
996+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 6));
997+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 0);
998+ QCOMPARE(lvwph->m_minYExtent, 0.);
999+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1000+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1001+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1002+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1003+ QCOMPARE(lvwph->contentY(), 0.);
1004+
1005+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 100));
1006+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 125));
1007+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 2);
1008+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1009+ verifyItem(0, 50., 125., false);
1010+ verifyItem(1, 175., 100., false);
1011+ }
1012+
994 void testRemoveItemsAtTop()
1013 void testRemoveItemsAtTop()
995 {
1014 {
996 QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2));
1015 QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2));
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cpp+19
@@ -1121,6 +1121,25 @@ private Q_SLOTS:
1121 QCOMPARE(lvwph->m_topSectionItem->y(), -23.);
1121 QCOMPARE(lvwph->m_topSectionItem->y(), -23.);
1122 }
1122 }
1123
1123
1124+ void testInsertToEmpty()
1125+ {
1126+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 6));
1127+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 0);
1128+ QCOMPARE(lvwph->m_minYExtent, 0.);
1129+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1130+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1131+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1132+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1133+ QCOMPARE(lvwph->contentY(), 0.);
1134+
1135+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
1136+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular"));
1137+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 2);
1138+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1139+ verifyItem(0, 50., 140., false, "Agressive", false);
1140+ verifyItem(1, 190., 165., false, "Regular", false);
1141+ }
1142+
1124 void testRemoveItemsAtTop()
1143 void testRemoveItemsAtTop()
1125 {
1144 {
1126 QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2));
1145 QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2));
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+28
@@ -0,0 +1,28 @@
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+ menucontentactivatortest
28+ )
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/plugins/Unity/Indicators/menucontentactivatortest.cppnew file+303
@@ -0,0 +1,303 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#include "menucontentactivator.h"
21+#include "paths.h"
22+
23+#include <QtTest>
24+#include <QDebug>
25+
26+class FakeTimer : public UnityIndicators::AbstractTimer
27+{
28+ Q_OBJECT
29+public:
30+ FakeTimer(QObject *parent = 0)
31+ : UnityIndicators::AbstractTimer(parent)
32+ {}
33+
34+ virtual int interval() const { return m_duration; }
35+ virtual void setInterval(int msecs) { m_duration = msecs; }
36+
37+ void emitTimeout() {
38+ if (isRunning()) {
39+ Q_EMIT timeout();
40+ }
41+ }
42+private:
43+ int m_duration;
44+};
45+
46+
47+class MenuConentActivatorTest : public QObject
48+{
49+ Q_OBJECT
50+private Q_SLOTS:
51+ void init() // called right before each and every test function is executed
52+ {
53+ m_fakeTimeSource = new FakeTimer(this);
54+ m_deltas.clear();
55+ }
56+ void cleanup() // called right after each and every test function is executed
57+ {
58+ delete m_fakeTimeSource;
59+ m_fakeTimeSource = 0;
60+ }
61+
62+ /*
63+ * Tests the ordering of activation
64+ */
65+ void testContentActiveChange()
66+ {
67+ MenuContentActivator activator;
68+ activator.setContentTimer(m_fakeTimeSource);
69+ activator.setCount(10);
70+ activator.setBaseIndex(5);
71+ activator.restart();
72+
73+ QCOMPARE(activator.isMenuContentActive(4), false);
74+ QCOMPARE(activator.isMenuContentActive(5), true); // always active at base index.
75+ QCOMPARE(activator.isMenuContentActive(6), false);
76+
77+ m_fakeTimeSource->emitTimeout();
78+ QCOMPARE(activator.isMenuContentActive(4), false);
79+ QCOMPARE(activator.isMenuContentActive(5), true);
80+ QCOMPARE(activator.isMenuContentActive(6), true);
81+ QCOMPARE(activator.isMenuContentActive(7), false);
82+
83+ m_fakeTimeSource->emitTimeout();
84+ QCOMPARE(activator.isMenuContentActive(3), false);
85+ QCOMPARE(activator.isMenuContentActive(4), true);
86+ QCOMPARE(activator.isMenuContentActive(5), true);
87+ QCOMPARE(activator.isMenuContentActive(6), true);
88+ QCOMPARE(activator.isMenuContentActive(7), false);
89+
90+ m_fakeTimeSource->emitTimeout();
91+ QCOMPARE(activator.isMenuContentActive(3), false);
92+ QCOMPARE(activator.isMenuContentActive(4), true);
93+ QCOMPARE(activator.isMenuContentActive(5), true);
94+ QCOMPARE(activator.isMenuContentActive(6), true);
95+ QCOMPARE(activator.isMenuContentActive(7), true);
96+ QCOMPARE(activator.isMenuContentActive(8), false);
97+
98+ m_fakeTimeSource->emitTimeout();
99+ QCOMPARE(activator.isMenuContentActive(2), false);
100+ QCOMPARE(activator.isMenuContentActive(3), true);
101+ QCOMPARE(activator.isMenuContentActive(4), true);
102+ QCOMPARE(activator.isMenuContentActive(5), true);
103+ QCOMPARE(activator.isMenuContentActive(6), true);
104+ QCOMPARE(activator.isMenuContentActive(7), true);
105+ QCOMPARE(activator.isMenuContentActive(8), false);
106+
107+ m_fakeTimeSource->emitTimeout();
108+ QCOMPARE(activator.isMenuContentActive(2), false);
109+ QCOMPARE(activator.isMenuContentActive(3), true);
110+ QCOMPARE(activator.isMenuContentActive(4), true);
111+ QCOMPARE(activator.isMenuContentActive(5), true);
112+ QCOMPARE(activator.isMenuContentActive(6), true);
113+ QCOMPARE(activator.isMenuContentActive(7), true);
114+ QCOMPARE(activator.isMenuContentActive(8), true);
115+ QCOMPARE(activator.isMenuContentActive(9), false);
116+
117+ m_fakeTimeSource->emitTimeout();
118+ QCOMPARE(activator.isMenuContentActive(1), false);
119+ QCOMPARE(activator.isMenuContentActive(2), true);
120+ QCOMPARE(activator.isMenuContentActive(3), true);
121+ QCOMPARE(activator.isMenuContentActive(4), true);
122+ QCOMPARE(activator.isMenuContentActive(5), true);
123+ QCOMPARE(activator.isMenuContentActive(6), true);
124+ QCOMPARE(activator.isMenuContentActive(7), true);
125+ QCOMPARE(activator.isMenuContentActive(8), true);
126+ QCOMPARE(activator.isMenuContentActive(9), false);
127+
128+ m_fakeTimeSource->emitTimeout();
129+ QCOMPARE(activator.isMenuContentActive(1), false);
130+ QCOMPARE(activator.isMenuContentActive(2), true);
131+ QCOMPARE(activator.isMenuContentActive(3), true);
132+ QCOMPARE(activator.isMenuContentActive(4), true);
133+ QCOMPARE(activator.isMenuContentActive(5), true);
134+ QCOMPARE(activator.isMenuContentActive(6), true);
135+ QCOMPARE(activator.isMenuContentActive(7), true);
136+ QCOMPARE(activator.isMenuContentActive(8), true);
137+ QCOMPARE(activator.isMenuContentActive(9), true);
138+ QCOMPARE(activator.isMenuContentActive(10), false);
139+
140+ m_fakeTimeSource->emitTimeout();
141+ QCOMPARE(activator.isMenuContentActive(0), false);
142+ QCOMPARE(activator.isMenuContentActive(1), true);
143+ QCOMPARE(activator.isMenuContentActive(2), true);
144+ QCOMPARE(activator.isMenuContentActive(3), true);
145+ QCOMPARE(activator.isMenuContentActive(4), true);
146+ QCOMPARE(activator.isMenuContentActive(5), true);
147+ QCOMPARE(activator.isMenuContentActive(6), true);
148+ QCOMPARE(activator.isMenuContentActive(7), true);
149+ QCOMPARE(activator.isMenuContentActive(8), true);
150+ QCOMPARE(activator.isMenuContentActive(9), true);
151+ QCOMPARE(activator.isMenuContentActive(10), false);
152+
153+ m_fakeTimeSource->emitTimeout();
154+ QCOMPARE(activator.isMenuContentActive(-1), false);
155+ QCOMPARE(activator.isMenuContentActive(0), true);
156+ QCOMPARE(activator.isMenuContentActive(1), true);
157+ QCOMPARE(activator.isMenuContentActive(2), true);
158+ QCOMPARE(activator.isMenuContentActive(3), true);
159+ QCOMPARE(activator.isMenuContentActive(4), true);
160+ QCOMPARE(activator.isMenuContentActive(5), true);
161+ QCOMPARE(activator.isMenuContentActive(6), true);
162+ QCOMPARE(activator.isMenuContentActive(7), true);
163+ QCOMPARE(activator.isMenuContentActive(8), true);
164+ QCOMPARE(activator.isMenuContentActive(9), true);
165+ QCOMPARE(activator.isMenuContentActive(10), false);
166+ }
167+
168+ /*
169+ * Tests the delta calculation for each timeout.
170+ */
171+ void testDelta()
172+ {
173+ MenuContentActivator activator;
174+ activator.setContentTimer(m_fakeTimeSource);
175+ activator.setCount(9);
176+ activator.setBaseIndex(3);
177+
178+ connect(&activator, &MenuContentActivator::deltaChanged,
179+ this, &MenuConentActivatorTest::onDeltaChange);
180+ activator.restart();
181+
182+ QCOMPARE(m_deltas, QList<int>()); // empty
183+ QCOMPARE(getIndexList(&activator), QList<int>()); // empty
184+
185+ m_fakeTimeSource->emitTimeout();
186+ QCOMPARE(m_deltas, QList<int>() << 1);
187+ QCOMPARE(getIndexList(&activator), QList<int>() << 4);
188+
189+ m_fakeTimeSource->emitTimeout();
190+ QCOMPARE(m_deltas, QList<int>() << 1 << -1);
191+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2);
192+
193+ m_fakeTimeSource->emitTimeout();
194+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2);
195+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5);
196+
197+ m_fakeTimeSource->emitTimeout();
198+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2 << -2);
199+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5 << 1);
200+
201+ m_fakeTimeSource->emitTimeout();
202+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2 << -2 << 3);
203+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5 << 1 << 6);
204+
205+ m_fakeTimeSource->emitTimeout();
206+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2 << -2 << 3 << -3);
207+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5 << 1 << 6 << 0);
208+
209+ m_fakeTimeSource->emitTimeout();
210+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2 << -2 << 3 << -3 << 4);
211+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5 << 1 << 6 << 0 << 7);
212+
213+ m_fakeTimeSource->emitTimeout();
214+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2 << -2 << 3 << -3 << 4 << 5);
215+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5 << 1 << 6 << 0 << 7 << 8);
216+
217+ m_fakeTimeSource->emitTimeout();
218+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2 << -2 << 3 << -3 << 4 << 5);
219+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5 << 1 << 6 << 0 << 7 << 8);
220+ }
221+
222+ /*
223+ * Tests that changing the base index re-prioritizes the activation
224+ * around the base index.
225+ */
226+ void testBaseIndexChange()
227+ {
228+ MenuContentActivator activator;
229+ activator.setContentTimer(m_fakeTimeSource);
230+ activator.setCount(12);
231+ activator.setBaseIndex(5);
232+ activator.restart();
233+
234+ m_fakeTimeSource->emitTimeout();
235+ m_fakeTimeSource->emitTimeout();
236+ QCOMPARE(activator.isMenuContentActive(3), false);
237+ QCOMPARE(activator.isMenuContentActive(4), true);
238+ QCOMPARE(activator.isMenuContentActive(5), true); // always active at base index.
239+ QCOMPARE(activator.isMenuContentActive(6), true);
240+ QCOMPARE(activator.isMenuContentActive(7), false);
241+
242+ activator.setBaseIndex(8);
243+ QCOMPARE(activator.isMenuContentActive(3), false);
244+ QCOMPARE(activator.isMenuContentActive(4), true);
245+ QCOMPARE(activator.isMenuContentActive(5), true);
246+ QCOMPARE(activator.isMenuContentActive(6), true);
247+ QCOMPARE(activator.isMenuContentActive(7), false);
248+ QCOMPARE(activator.isMenuContentActive(8), true);
249+ QCOMPARE(activator.isMenuContentActive(9), false);
250+
251+ m_fakeTimeSource->emitTimeout();
252+ QCOMPARE(activator.isMenuContentActive(3), false);
253+ QCOMPARE(activator.isMenuContentActive(4), true);
254+ QCOMPARE(activator.isMenuContentActive(5), true);
255+ QCOMPARE(activator.isMenuContentActive(6), true);
256+ QCOMPARE(activator.isMenuContentActive(7), false);
257+ QCOMPARE(activator.isMenuContentActive(8), true);
258+ QCOMPARE(activator.isMenuContentActive(9), true);
259+ QCOMPARE(activator.isMenuContentActive(10), false);
260+
261+ m_fakeTimeSource->emitTimeout();
262+ QCOMPARE(activator.isMenuContentActive(3), false);
263+ QCOMPARE(activator.isMenuContentActive(4), true);
264+ QCOMPARE(activator.isMenuContentActive(5), true);
265+ QCOMPARE(activator.isMenuContentActive(6), true);
266+ QCOMPARE(activator.isMenuContentActive(7), true);
267+ QCOMPARE(activator.isMenuContentActive(8), true);
268+ QCOMPARE(activator.isMenuContentActive(9), true);
269+ QCOMPARE(activator.isMenuContentActive(10), false);
270+
271+ m_fakeTimeSource->emitTimeout();
272+ QCOMPARE(activator.isMenuContentActive(3), false);
273+ QCOMPARE(activator.isMenuContentActive(4), true);
274+ QCOMPARE(activator.isMenuContentActive(5), true);
275+ QCOMPARE(activator.isMenuContentActive(6), true);
276+ QCOMPARE(activator.isMenuContentActive(7), true);
277+ QCOMPARE(activator.isMenuContentActive(8), true);
278+ QCOMPARE(activator.isMenuContentActive(9), true);
279+ QCOMPARE(activator.isMenuContentActive(10), true);
280+ QCOMPARE(activator.isMenuContentActive(11), false);
281+ }
282+
283+ void onDeltaChange(int delta)
284+ {
285+ m_deltas << delta;
286+ }
287+
288+private:
289+ QList<int> getIndexList(MenuContentActivator* activator)
290+ {
291+ QList<int> list;
292+ Q_FOREACH(int delta, m_deltas) {
293+ list << (activator->baseIndex() + delta);
294+ }
295+ return list;
296+ }
297+
298+ FakeTimer* m_fakeTimeSource;
299+ QList<int> m_deltas;
300+};
301+
302+QTEST_MAIN(MenuConentActivatorTest)
303+#include "menucontentactivatortest.moc"
tests/plugins/Unity/previewbindingstest.cpp−2
@@ -165,5 +165,3 @@ void PreviewBindingsTest::testSocialPreview()
165}
165}
166
166
167QTEST_MAIN(PreviewBindingsTest)
167QTEST_MAIN(PreviewBindingsTest)
168−
169−#include "previewbindingstest.moc"
tests/qmltests/CMakeLists.txt−2
@@ -61,10 +61,8 @@ add_qml_test(Notifications Notifications IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_P
61add_qml_test(Panel IndicatorRow)
61add_qml_test(Panel IndicatorRow)
62add_qml_test(Panel Indicators IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
62add_qml_test(Panel Indicators IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
63add_qml_test(Panel MenuContent)
63add_qml_test(Panel MenuContent)
64−add_qml_test(Panel Overview)
65add_qml_test(Panel Panel IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
64add_qml_test(Panel Panel IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
66add_qml_test(Panel SearchIndicator)
65add_qml_test(Panel SearchIndicator)
67−add_qml_test(Panel/Menus IndicatorMenuWindow IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS})
68add_qml_test(SideStage SideStage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
66add_qml_test(SideStage SideStage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
69 ${CMAKE_BINARY_DIR}/tests/mocks
67 ${CMAKE_BINARY_DIR}/tests/mocks
70 ${CMAKE_BINARY_DIR}/plugins)
68 ${CMAKE_BINARY_DIR}/plugins)
tests/qmltests/Components/tst_OpenEffect.qml+1−1
@@ -28,7 +28,7 @@ TestCase {
28 function test_openeffect_shadereffectsource() {
28 function test_openeffect_shadereffectsource() {
29 compare(openEffect1.source.hideSource, true, "OpenEffect ShaderEffectSource is incorrect")
29 compare(openEffect1.source.hideSource, true, "OpenEffect ShaderEffectSource is incorrect")
30 compare(openEffect1.source.sourceItem, rectangle2, "OpenEffect ShaderEffectSource is incorrect")
30 compare(openEffect1.source.sourceItem, rectangle2, "OpenEffect ShaderEffectSource is incorrect")
31− compare(openEffect1.source.live, true, "OpenEffect ShaderEffectSource is incorrect")
31+ compare(openEffect1.source.live, false, "OpenEffect ShaderEffectSource is incorrect")
32 compare(openEffect1.source.sourceRect.x, 0, "OpenEffect ShaderEffectSource is incorrect")
32 compare(openEffect1.source.sourceRect.x, 0, "OpenEffect ShaderEffectSource is incorrect")
33 compare(openEffect1.source.sourceRect.y, 0, "OpenEffect ShaderEffectSource is incorrect")
33 compare(openEffect1.source.sourceRect.y, 0, "OpenEffect ShaderEffectSource is incorrect")
34 compare(openEffect1.source.sourceRect.width, 50, "OpenEffect ShaderEffectSource is incorrect")
34 compare(openEffect1.source.sourceRect.width, 50, "OpenEffect ShaderEffectSource is incorrect")
tests/qmltests/Notifications/tst_Notifications.qml+20−9
@@ -48,6 +48,7 @@ Row {
48 function addSnapDecisionNotification() {
48 function addSnapDecisionNotification() {
49 var n = {
49 var n = {
50 type: Notification.SnapDecision,
50 type: Notification.SnapDecision,
51+ hints: Notification.ButtonTint,
51 summary: "Tom Ato",
52 summary: "Tom Ato",
52 body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
53 body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
53 icon: "../graphics/avatars/funky.png",
54 icon: "../graphics/avatars/funky.png",
@@ -189,8 +190,9 @@ Row {
189 function test_NotificationRenderer_data() {
190 function test_NotificationRenderer_data() {
190 return [
191 return [
191 {
192 {
192− tag: "Snap Decision with secondary icon",
193+ tag: "Snap Decision with secondary icon and button-tint",
193 type: Notification.SnapDecision,
194 type: Notification.SnapDecision,
195+ hints: Notification.ButtonTint,
194 summary: "Tom Ato",
196 summary: "Tom Ato",
195 body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
197 body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
196 icon: "../graphics/avatars/funky.png",
198 icon: "../graphics/avatars/funky.png",
@@ -205,7 +207,8 @@ Row {
205 interactiveAreaEnabled: false,
207 interactiveAreaEnabled: false,
206 iconVisible: true,
208 iconVisible: true,
207 secondaryIconVisible: true,
209 secondaryIconVisible: true,
208− buttonRowVisible: true
210+ buttonRowVisible: true,
211+ buttonTinted: true
209 },
212 },
210 {
213 {
211 tag: "Ephemeral notification - icon-summary layout",
214 tag: "Ephemeral notification - icon-summary layout",
@@ -220,7 +223,8 @@ Row {
220 interactiveAreaEnabled: false,
223 interactiveAreaEnabled: false,
221 iconVisible: false,
224 iconVisible: false,
222 secondaryIconVisible: true,
225 secondaryIconVisible: true,
223− buttonRowVisible: false
226+ buttonRowVisible: false,
227+ buttonTinted: false
224 },
228 },
225 {
229 {
226 tag: "Ephemeral notification - check suppression of secondary icon for icon-summary layout",
230 tag: "Ephemeral notification - check suppression of secondary icon for icon-summary layout",
@@ -235,7 +239,8 @@ Row {
235 interactiveAreaEnabled: false,
239 interactiveAreaEnabled: false,
236 iconVisible: false,
240 iconVisible: false,
237 secondaryIconVisible: true,
241 secondaryIconVisible: true,
238− buttonRowVisible: false
242+ buttonRowVisible: false,
243+ buttonTinted: false
239 },
244 },
240 {
245 {
241 tag: "Interactive notification",
246 tag: "Interactive notification",
@@ -250,10 +255,11 @@ Row {
250 interactiveAreaEnabled: true,
255 interactiveAreaEnabled: true,
251 iconVisible: true,
256 iconVisible: true,
252 secondaryIconVisible: false,
257 secondaryIconVisible: false,
253− buttonRowVisible: false
258+ buttonRowVisible: false,
259+ buttonTinted: false
254 },
260 },
255 {
261 {
256− tag: "Snap Decision without secondary icon",
262+ tag: "Snap Decision without secondary icon and no button-tint",
257 type: Notification.SnapDecision,
263 type: Notification.SnapDecision,
258 summary: "Bro Coly",
264 summary: "Bro Coly",
259 body: "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
265 body: "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
@@ -266,7 +272,8 @@ Row {
266 interactiveAreaEnabled: false,
272 interactiveAreaEnabled: false,
267 iconVisible: true,
273 iconVisible: true,
268 secondaryIconVisible: false,
274 secondaryIconVisible: false,
269− buttonRowVisible: true
275+ buttonRowVisible: true,
276+ buttonTinted: false
270 },
277 },
271 {
278 {
272 tag: "Ephemeral notification",
279 tag: "Ephemeral notification",
@@ -281,7 +288,8 @@ Row {
281 interactiveAreaEnabled: false,
288 interactiveAreaEnabled: false,
282 iconVisible: true,
289 iconVisible: true,
283 secondaryIconVisible: true,
290 secondaryIconVisible: true,
284− buttonRowVisible: false
291+ buttonRowVisible: false,
292+ buttonTinted: false
285 }
293 }
286 ]
294 ]
287 }
295 }
@@ -356,6 +364,9 @@ Row {
356 actionSpy.clear()
364 actionSpy.clear()
357 }
365 }
358
366
367+ // check the tinting of the positive/right button
368+ verify(buttonAccept.gradient === data.buttonTinted ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient, "button has the wrong color-tint")
369+
359 // click the positive/right button
370 // click the positive/right button
360 mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2)
371 mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2)
361 actionSpy.wait()
372 actionSpy.wait()
@@ -370,7 +381,7 @@ Row {
370 mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
381 mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
371 waitForRendering(notification)
382 waitForRendering(notification)
372 actionSpy.clear()
383 actionSpy.clear()
373− 
384+
374 // test the additional buttons
385 // test the additional buttons
375 for (var i = 2; i < data.actions.length; i++) {
386 for (var i = 2; i < data.actions.length; i++) {
376 waitForRendering(notification)
387 waitForRendering(notification)
tests/qmltests/Panel/Menus/tst_IndicatorMenuWindow.qmldeleted−68
@@ -1,68 +0,0 @@
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−import QtTest 1.0
19−import "../.."
20−import "../../../../Panel/Menus"
21−import Ubuntu.Components 0.1
22−import Unity.Test 0.1 as UT
23−
24−Item {
25− id: testIndicatorMenuWindowItem
26− width: units.gu(9)
27− height: units.gu(3)
28−
29− MouseArea {
30− id: mouseArea
31− anchors.fill: parent
32− }
33−
34− IndicatorMenuWindow {
35− id: indicatorMenuWindow
36− name: "TestIndicatorMenuWindow"
37− anchors.fill: parent
38− }
39−
40− UT.UnityTestCase {
41− name: "IndicatorMenuWindow"
42− when: windowShown
43−
44− function test_mouseEvent_data() {
45− return [
46− {tag: "visible", shown: true, opacity: 1.0, mouseClicks: 0},
47− {tag: "invisible", shown: false, opacity: 0.0, mouseClicks: 1},
48− ]
49− }
50−
51− function test_mouseEvent(data) {
52− indicatorMenuWindow.shown = data.shown
53− tryCompare(indicatorMenuWindow, "opacity", data.opacity)
54−
55− clickedSpy.clear()
56− mouseClick(indicatorMenuWindow, indicatorMenuWindow.width / 2,
57− indicatorMenuWindow.height / 2)
58− compare(clickedSpy.count, data.mouseClicks,
59− "Check for Mouse event eating by indicatorMenuWindow failed")
60− }
61− }
62−
63− SignalSpy {
64− id: clickedSpy
65− target: mouseArea
66− signalName: "clicked"
67− }
68−}
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+3−16
@@ -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
@@ -32,7 +32,6 @@ Item {
32
32
33 function init_test()
33 function init_test()
34 {
34 {
35− indicatorRow.overviewActive = false;
36 indicatorRow.state = "initial";
35 indicatorRow.state = "initial";
37 indicatorRow.currentItem = null;
36 indicatorRow.currentItem = null;
38 }
37 }
@@ -51,8 +50,9 @@ Item {
51 indicatorsModel: indicatorModel
50 indicatorsModel: indicatorModel
52 }
51 }
53
52
54− ChewieUI.PluginModel {
53+ Indicators.IndicatorsModel {
55 id: indicatorModel
54 id: indicatorModel
55+ Component.onCompleted: load()
56 }
56 }
57
57
58 UT.UnityTestCase {
58 UT.UnityTestCase {
@@ -240,18 +240,5 @@ Item {
240 compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in locked state");
240 compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in locked state");
241 compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in locked state");
241 compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in locked state");
242 }
242 }
243−
244− function test_active_overview_() {
245− init_test();
246−
247− indicatorRow.overviewActive = true;
248− indicatorRow.state = "commit";
249−
250− compare(get_indicator_item_at(0).dimmed, true, "Indicator should dim when in overview");
251− compare(get_indicator_item_at(1).dimmed, true, "Indicator should dim when in overview");
252− compare(get_indicator_item_at(2).dimmed, true, "Indicator should dim when in overview");
253− compare(get_indicator_item_at(3).dimmed, true, "Indicator should dim when in overview");
254− compare(get_indicator_item_at(4).dimmed, true, "Indicator should dim when in overview");
255− }
256 }
243 }
257}
244}
tests/qmltests/Panel/tst_Indicators.qml+2−41
@@ -69,10 +69,8 @@ Item {
69
69
70 onClicked: {
70 onClicked: {
71 if (!indicators.shown) {
71 if (!indicators.shown) {
72− indicators.openOverview();
73 indicators.show();
72 indicators.show();
74− }
75− else {
73+ } else {
76 indicators.hide();
74 indicators.hide();
77 }
75 }
78 }
76 }
@@ -90,47 +88,10 @@ Item {
90 tryCompare(indicators, "state", "initial");
88 tryCompare(indicators, "state", "initial");
91 }
89 }
92
90
93− // Showing the indicators should fully open the indicator panel with the overview menu visible.
91+ // Showing the indicators should fully open the indicator panel.
94 function test_show() {
92 function test_show() {
95 indicators.show()
93 indicators.show()
96 tryCompare(indicators, "fullyOpened", true);
94 tryCompare(indicators, "fullyOpened", true);
97−
98− // A show must open the indicators.
99− compare(findChild(indicators, "indicatorRow").overviewActive, true, "Overview indicator should be active when opened overview.")
100− }
101−
102− // Opening the overview menu will activate the overview panel.
103− function test_open_overview() {
104− indicators.openOverview();
105− compare(findChild(indicators, "indicatorRow").overviewActive, true, "Overview should be active when opened overview.")
106− }
107−
108− // Showing the indicators, then changing the progress (simulating drag) should keep the overview panel open until
109− // the reveal state is reached.
110− function test_slow_close_open_overview() {
111−
112− var indicator_row = findChild(indicators, "indicatorRow");
113− verify(indicator_row != undefined);
114−
115− indicators.show()
116− // wait for animation to end. (progress needs to be updated)
117− tryCompare(indicators.showAnimation, "running", false);
118− compare(indicator_row.overviewActive, true, "Overview should be active when opened overview.")
119−
120− // iteratively decrease the progress and ensure that it keeps the correct behaviour
121− var current_progress = indicators.progress - shell.height/20;
122− while (current_progress > 0) {
123− indicators.progress = current_progress;
124−
125− if (indicators.state == "commit" || indicators.state == "locked") {
126− compare(indicator_row.overviewActive, true, "Overview should be active when in locked or commit state after show.")
127− }
128− else if (indicators.state == "reveal" || indicators.state == "hint") {
129− compare(indicator_row.overviewActive, false, "Overview should be not active when not in commit or locked state.")
130− }
131−
132− current_progress = current_progress - shell.height/20;
133− }
134 }
95 }
135
96
136 // Test the change in the revealer lateral position changes the current panel menu to fit the position
97 // Test the change in the revealer lateral position changes the current panel menu to fit the position
tests/qmltests/Panel/tst_MenuContent.qml+21−90
@@ -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 {
@@ -51,8 +52,8 @@ Item {
51 height: parent.height - 50
52 height: parent.height - 50
52 }
53 }
53
54
54− Item {
55+ Rectangle {
55− id: click_me
56+ color: "#bbbbbb"
56
57
57 height: 50
58 height: 50
58 anchors {
59 anchors {
@@ -61,50 +62,16 @@ Item {
61 right: parent.right
62 right: parent.right
62 }
63 }
63
64
64− Rectangle {
65+ Text {
65− color: "#999999"
66+ text: "Next Indicator"
66−
67− anchors {
68− top: parent.top
69− left: parent.left
70− right: parent.horizontalCenter
71− bottom: parent.bottom
72− }
73−
74− Text {
75− text: "Devices"
76− anchors.fill: parent
67+ anchors.fill: parent
77− horizontalAlignment: Text.AlignHCenter
68+ horizontalAlignment: Text.AlignHCenter
78− verticalAlignment: Text.AlignVCenter
69+ verticalAlignment: Text.AlignVCenter
79− }
80−
81− MouseArea {
82− anchors.fill: parent
83− onClicked: menuContent.showOverview()
84− }
85 }
70 }
86
71
87− Rectangle {
88− color: "#bbbbbb"
89−
90− anchors {
91− top: parent.top
92− left: parent.horizontalCenter
93− right: parent.right
94− bottom: parent.bottom
95− }
96−
97− Text {
98− text: "Next Indicator"
99− anchors.fill: parent
100− horizontalAlignment: Text.AlignHCenter
101− verticalAlignment: Text.AlignVCenter
102− }
103−
104− MouseArea {
72+ MouseArea {
105− anchors.fill: parent
73+ anchors.fill: parent
106− onClicked: activate_next_content()
74+ onClicked: activate_next_content()
107− }
108 }
75 }
109 }
76 }
110
77
@@ -119,24 +86,23 @@ Item {
119 function activate_content(index)
86 function activate_content(index)
120 {
87 {
121 menuContent.currentIndex = index
88 menuContent.currentIndex = index
122− menuContent.showMenu();
123 }
89 }
124
90
125 function get_test_menu_objecName(index) {
91 function get_test_menu_objecName(index) {
126− return "menu_plugin"+(index+1);
92+ return "menu_page"+(index+1);
127 }
93 }
128
94
129 property string test_menu_objectName : ""
95 property string test_menu_objectName : ""
130 function current_menu_equals_test_menu() {
96 function current_menu_equals_test_menu() {
131 var current_loader = menu_content_test.findChild(menuContent, "menus").currentItem
97 var current_loader = menu_content_test.findChild(menuContent, "menus").currentItem
132 if (current_loader == undefined) {
98 if (current_loader == undefined) {
133− console.log("current_loader undefined");
99+ console.log("current_loader 'menus' undefined");
134 return false;
100 return false;
135 }
101 }
136
102
137 var menu = menu_content_test.findChild(menuContent, test_menu_objectName);
103 var menu = menu_content_test.findChild(menuContent, test_menu_objectName);
138 if (menu == undefined) {
104 if (menu == undefined) {
139− console.log("test_menu undefined");
105+ console.log("test_menu " + test_menu_objectName + " undefined");
140 return false;
106 return false;
141 }
107 }
142
108
@@ -150,7 +116,6 @@ Item {
150 when: windowShown
116 when: windowShown
151
117
152 function init() {
118 function init() {
153− menuContent.hideAll();
154 if (menuContent.__contentActive)
119 if (menuContent.__contentActive)
155 menuContent.releaseContent();
120 menuContent.releaseContent();
156 tryCompare(menuContent, "__contentActive", false);
121 tryCompare(menuContent, "__contentActive", false);
@@ -173,40 +138,6 @@ Item {
173 compare(menus.currentIndex, menu_index, "Current menu index does not match selected menu index");
138 compare(menus.currentIndex, menu_index, "Current menu index does not match selected menu index");
174 tryCompareFunction(current_menu_equals_test_menu, true);
139 tryCompareFunction(current_menu_equals_test_menu, true);
175 }
140 }
176− // overview should not be visible.
177− tryCompare(findChild(menuContent, "overview"), "visible", false);
178− }
179−
180− function test_show_overview() {
181− menuContent.showOverview();
182−
183− var overview = findChild(menuContent, "overview");
184− tryCompare(overview, "visible", true);
185− tryCompare(overview, "enabled", true);
186− tryCompare(overview, "opacity", 1.0);
187−
188− // menus should not be enabled.
189− tryCompare(findChild(menuContent, "menus"), "opacity", 0);
190− tryCompare(findChild(menuContent, "menus"), "enabled", false);
191− }
192−
193− function test_overview_menuSelected_signal() {
194− menuContent.showOverview();
195−
196− var overview = findChild(menuContent, "overview");
197− var menus = menu_content_test.findChild(menuContent, "menus")
198−
199− var menu_count = indicatorsModel.count;
200− verify(menu_count > 0, "Menu count should be greater than zero");
201− for (var i = 0; i < menu_count; i++) {
202− // manually emit signal from overview.
203− // we dont want to go with mouse events here, otherwise we're testing the overview and not the signal.
204− overview.menuSelected(i);
205−
206− test_menu_objectName = get_test_menu_objecName(i);
207− compare(menus.currentIndex, i, "Current menu index does not match selected menu index");
208− tryCompareFunction(current_menu_equals_test_menu, true);
209− }
210 }
141 }
211
142
212 // Calling activateContent should call start on all menus
143 // Calling activateContent should call start on all menus
tests/qmltests/Panel/tst_Overview.qmldeleted−154
@@ -1,154 +0,0 @@
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−import QtTest 1.0
19−import ".."
20−import "../../../Panel/Menus"
21−import "../../../Components"
22−import Unity.Test 0.1 as UT
23−
24−Rectangle {
25− id: shell
26− width: units.gu(40)
27− height: units.gu(80)
28− color: "black"
29−
30− Overview {
31− id: overview
32− anchors.fill: parent
33− indicatorsModel: mockModel
34− shown: true
35− }
36−
37− Item {
38− id: volumeControl
39− property int volume
40− function volumeUp() {
41− volume = Math.min(100, volume + 10);
42− }
43− function volumeDown() {
44− volume = Math.max(0, volume - 10);
45− }
46− }
47−
48− ListModel {
49− id: mockModel
50− ListElement {title: "foo"; label: "foo"; iconSource: "graphics/sound_on_icon.png"}
51− ListElement {title: "bar"; label: ""; iconSource: "graphics/sound_on_icon.png"}
52− ListElement {title: "baz"; label: "baz"; iconSource: "graphics/sound_on_icon.png"}
53− }
54−
55− ListModel {
56− id: mockModel2
57− }
58−
59− SignalSpy {
60− id: clickSpy
61− target: overview
62− signalName: "menuSelected"
63− }
64−
65− UT.UnityTestCase {
66− name: "Overview"
67− when: windowShown
68−
69− function initTestCase() {
70− // Spin the event loop once because the UI builds up delayed
71− wait(0);
72− }
73−
74− function test_menuSelected() {
75− overview.indicatorsModel = mockModel;
76−
77− for (var i = 0; i < mockModel.count; ++i) {
78− var button = findChild(overview, "overviewGridButton" + i);
79− clickSpy.clear();
80− mouseClick(button, button.width / 2, button.height / 2);
81− compare(clickSpy.count, 1, "Clicking on grid didn't work");
82− compare(clickSpy.signalArguments[0][0], i, "Clicking the grid returned a wrong index");
83− }
84− }
85−
86− function test_dynamic_addition() {
87− var overviewGrid = findChild(overview, "overviewGrid");
88−
89− for(var i = 0; i < mockModel.count; ++i) {
90− mockModel2.append(mockModel.get(i));
91− }
92− overview.indicatorsModel = mockModel2;
93− overviewGrid.forceLayout();
94− waitForRendering(overviewGrid);
95−
96− var button = findChild(overview, "overviewGridButton2");
97− verify(button !== undefined, "button2 wasn't found");
98− button = findChild(overview, "overviewGridButton3");
99− compare(button, undefined, "There should only be 3 buttons... found at least 4...");
100−
101− mockModel2.append({title: "humppa", label: "", iconSource: "graphics/sound_on_icon.png"})
102− overviewGrid.forceLayout();
103− waitForRendering(overviewGrid);
104−
105− button = findChild(overview, "overviewGridButton3");
106− verify(button !== undefined, "button3 wasn't found");
107− }
108−
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() {
123− return [
124− {tag: "0%", sliderPos:0},
125− {tag: "100%", sliderPos: 100},
126− {tag: "50%", sliderPos: 50}
127− ];
128− }
129−
130− function test_volume_slider(data) {
131− var volumeSlider = findChild(overview, "volumeSlider");
132− var startX = volumeSlider.width * volumeSlider.value / 100;
133− var startY = volumeSlider.y + volumeSlider.height / 2;
134− var stopX = (volumeSlider.width - units.gu(5)) * data.sliderPos / 100;
135− var stopY = volumeSlider.y + volumeSlider.height / 2;
136− mouseFlick(volumeSlider, startX, startY, stopX, stopY, true, true, 0.1);
137− }
138−
139− function test_volume_buttons(data) {
140− var volumeDownButton = findChild(overview, "minVolumeIcon");
141− var volumeUpButton = findChild(overview, "maxVolumeIcon");
142−
143− for (var i = 0; i < 10; ++i) {
144− mouseClick(volumeDownButton, volumeDownButton.width / 2, volumeDownButton.height / 2);
145− wait(0)
146− }
147− tryCompare(volumeControl, "volume", 0);
148− for (var i = 0; i < 10; ++i) {
149− mouseClick(volumeUpButton, 1, 1);
150− wait(0)
151− }
152− }
153− }
154−}
tests/qmltests/Panel/tst_Panel.qml+33−34
@@ -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
@@ -63,14 +62,14 @@ Item {
63
62
64 function get_indicator_item(index) {
63 function get_indicator_item(index) {
65 var row_repeater = findChild(panel.indicators, "rowRepeater");
64 var row_repeater = findChild(panel.indicators, "rowRepeater");
66− verify(row_repeater != undefined)
65+ verify(row_repeater != undefined);
67 return row_repeater.itemAt(index);
66 return row_repeater.itemAt(index);
68 }
67 }
69
68
70 function get_indicator_item_position(index) {
69 function get_indicator_item_position(index) {
71
70
72 var indicator_row = findChild(panel.indicators, "indicatorRow");
71 var indicator_row = findChild(panel.indicators, "indicatorRow");
73− verify(indicator_row != undefined)
72+ verify(indicator_row != undefined);
74
73
75 var indicator_item = get_indicator_item(index);
74 var indicator_item = get_indicator_item(index);
76 verify(indicator_item != undefined);
75 verify(indicator_item != undefined);
@@ -84,11 +83,11 @@ Item {
84 panel.fullscreenMode = false;
83 panel.fullscreenMode = false;
85 // Wait for the indicators to get into position.
84 // Wait for the indicators to get into position.
86 // (switches between normal and fullscreen modes are animated)
85 // (switches between normal and fullscreen modes are animated)
87− tryCompare(panel.indicators, "y", 0)
86+ tryCompare(panel.indicators, "y", 0);
88
87
89 var indicator_item_coord = get_indicator_item_position(0);
88 var indicator_item_coord = get_indicator_item_position(0);
90
89
91− touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2)
90+ touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2);
92
91
93 // hint animation should be run, meaning that indicators will move downwards
92 // hint animation should be run, meaning that indicators will move downwards
94 // by hintValue pixels without any drag taking place
93 // by hintValue pixels without any drag taking place
@@ -97,7 +96,7 @@ Item {
97 tryCompare(panel.indicators, "partiallyOpened", true);
96 tryCompare(panel.indicators, "partiallyOpened", true);
98 tryCompare(panel.indicators, "fullyOpened", false);
97 tryCompare(panel.indicators, "fullyOpened", false);
99
98
100− touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2)
99+ touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2);
101 }
100 }
102
101
103 // Pressing on the top edge of the screen should have no effect if the panel
102 // Pressing on the top edge of the screen should have no effect if the panel
@@ -106,31 +105,31 @@ Item {
106 panel.fullscreenMode = true;
105 panel.fullscreenMode = true;
107 // Wait for the indicators to get into position.
106 // Wait for the indicators to get into position.
108 // (switches between normal and fullscreen modes are animated)
107 // (switches between normal and fullscreen modes are animated)
109− tryCompare(panel.indicators, "y", -panel.panelHeight)
108+ tryCompare(panel.indicators, "y", -panel.panelHeight);
110
109
111 var indicator_item_coord = get_indicator_item_position(0);
110 var indicator_item_coord = get_indicator_item_position(0);
112
111
113− touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2)
112+ touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2);
114
113
115 // Give some time for a hint animation to change things, if any
114 // Give some time for a hint animation to change things, if any
116− wait(500)
115+ wait(500);
117
116
118 // no hint animation when fullscreen
117 // no hint animation when fullscreen
119− compare(panel.indicators.y, -panel.panelHeight)
118+ compare(panel.indicators.y, -panel.panelHeight);
120 var indicatorRow = findChild(panel.indicators, "indicatorRow");
119 var indicatorRow = findChild(panel.indicators, "indicatorRow");
121− verify(indicatorRow != undefined)
120+ verify(indicatorRow != undefined);
122− compare(indicatorRow.y, 0)
121+ compare(indicatorRow.y, 0);
123− compare(panel.indicators.height, panel.indicators.panelHeight)
122+ compare(panel.indicators.height, panel.indicators.panelHeight);
124 compare(panel.indicators.partiallyOpened, false,
123 compare(panel.indicators.partiallyOpened, false,
125 "Indicator should not be partially opened when panel is pressed in" +
124 "Indicator should not be partially opened when panel is pressed in" +
126− " fullscreenmode")
125+ " fullscreenmode");
127 compare(panel.indicators.fullyOpened, false, "Indicator should not be partially" +
126 compare(panel.indicators.fullyOpened, false, "Indicator should not be partially" +
128− " opened when panel is pressed in fullscreenmode")
127+ " opened when panel is pressed in fullscreenmode");
129
128
130− touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2)
129+ touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2);
131 }
130 }
132
131
133− function test_drag_show_data() { return get_window_data() }
132+ function test_drag_show_data() { return get_window_data(); }
134
133
135 // Dragging from a indicator item in the panel will gradually expose the
134 // Dragging from a indicator item in the panel will gradually expose the
136 // indicators, first by running the hint animation, then after dragging down will
135 // indicators, first by running the hint animation, then after dragging down will
@@ -139,50 +138,50 @@ Item {
139 panel.fullscreenMode = data.fullscreenFlag;
138 panel.fullscreenMode = data.fullscreenFlag;
140
139
141 var indicator_row = findChild(panel.indicators, "indicatorRow");
140 var indicator_row = findChild(panel.indicators, "indicatorRow");
142− verify(indicator_row != undefined)
141+ verify(indicator_row != undefined);
143
142
144 var row_repeater = findChild(panel.indicators, "rowRepeater");
143 var row_repeater = findChild(panel.indicators, "rowRepeater");
145− verify(indicator_row != undefined)
144+ verify(indicator_row != undefined);
146
145
147 var menu_content = findChild(panel.indicators, "menuContent");
146 var menu_content = findChild(panel.indicators, "menuContent");
148− verify(indicator_row != undefined)
147+ verify(indicator_row != undefined);
149
148
150 // Wait for the indicators to get into position.
149 // Wait for the indicators to get into position.
151 // (switches between normal and fullscreen modes are animated)
150 // (switches between normal and fullscreen modes are animated)
152 if (data.fullscreenFlag) {
151 if (data.fullscreenFlag) {
153− tryCompare(panel.indicators, "y", -panel.panelHeight)
152+ tryCompare(panel.indicators, "y", -panel.panelHeight);
154 } else {
153 } else {
155− tryCompare(panel.indicators, "y", 0)
154+ tryCompare(panel.indicators, "y", 0);
156 }
155 }
157
156
158 // do this for each indicator item
157 // do this for each indicator item
159 for (var i = 0; i < row_repeater.count; i++) {
158 for (var i = 0; i < row_repeater.count; i++) {
160
159
161 var indicator_item = get_indicator_item(i);
160 var indicator_item = get_indicator_item(i);
162− verify(indicator_item != undefined)
161+ verify(indicator_item != undefined);
163
162
164 var indicator_item_coord = get_indicator_item_position(i);
163 var indicator_item_coord = get_indicator_item_position(i);
165
164
166 touchPress(panel,
165 touchPress(panel,
167− indicator_item_coord.x, panel.panelHeight / 2)
166+ indicator_item_coord.x, panel.panelHeight / 2);
168
167
169 // 1) Drag the mouse down
168 // 1) Drag the mouse down
170 touchFlick(panel,
169 touchFlick(panel,
171 indicator_item_coord.x, panel.panelHeight / 2,
170 indicator_item_coord.x, panel.panelHeight / 2,
172 indicator_item_coord.x, panel.height * 0.8,
171 indicator_item_coord.x, panel.height * 0.8,
173− false /* beginTouch */, false /* endTouch */)
172+ false /* beginTouch */, false /* endTouch */);
174
173
175 // Indicators height should follow the drag, and therefore increase accordingly.
174 // Indicators height should follow the drag, and therefore increase accordingly.
176 // They should be at least half-way through the screen
175 // They should be at least half-way through the screen
177 tryCompareFunction(
176 tryCompareFunction(
178 function() {return panel.indicators.height >= panel.height * 0.5},
177 function() {return panel.indicators.height >= panel.height * 0.5},
179− true)
178+ true);
180
179
181− touchRelease(panel, indicator_item_coord.x, panel.height * 0.8)
180+ touchRelease(panel, indicator_item_coord.x, panel.height * 0.8);
182
181
183 compare(indicator_row.currentItem, indicator_item,
182 compare(indicator_row.currentItem, indicator_item,
184− "Incorrect item activated at position " + i)
183+ "Incorrect item activated at position " + i);
185− compare(menu_content.__shown, true, "Menu conetent should be enabled for item at position " + i);
184+ compare(menu_content.currentIndex, i, "Menu conetent should be enabled for item at position " + i);
186
185
187 // init for next indicator_item
186 // init for next indicator_item
188 init();
187 init();
@@ -196,23 +195,23 @@ Item {
196 var search_indicator = findChild(panel, "search");
195 var search_indicator = findChild(panel, "search");
197 verify(search_indicator != undefined);
196 verify(search_indicator != undefined);
198
197
199− tap(search_indicator, 1, 1)
198+ tap(search_indicator, 1, 1);
200
199
201 compare(search_clicked, true,
200 compare(search_clicked, true,
202− "Tapping search indicator while it was enabled did not emit searchClicked signal")
201+ "Tapping search indicator while it was enabled did not emit searchClicked signal");
203 }
202 }
204
203
205 function test_search_click_when_not_visible() {
204 function test_search_click_when_not_visible() {
206 panel.fullscreenMode = false;
205 panel.fullscreenMode = false;
207− panel.searchVisible = false
206+ panel.searchVisible = false;
208
207
209 var search_indicator = findChild(panel, "search");
208 var search_indicator = findChild(panel, "search");
210 verify(search_indicator != undefined);
209 verify(search_indicator != undefined);
211
210
212− tap(search_indicator, 1, 1)
211+ tap(search_indicator, 1, 1);
213
212
214 compare(search_clicked, false,
213 compare(search_clicked, false,
215− "Tapping search indicator while it was not visible emitted searchClicked signal")
214+ "Tapping search indicator while it was not visible emitted searchClicked signal");
216 }
215 }
217 }
216 }
218}
217}
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 ]