on xenial help sign in
merge trunk
commitdb432c90c80392c9090c4588dca3f28c4f30e7be authorMichael Zanetti <michael.zanetti@canonical.com> dateTue 23 Jul 2013, 10:44 (13 years ago) parente7019dd57720af
262 files changed+8744−2148
ApplicationArguments.h+49 Applications/applications.js+2−2 CMakeLists.txt+5−3 CODING+5−6 Components/ApplicationScreenshot.qml+1−1 Components/Carousel.qml+38−1 Components/FilterGrid.qml+2−2 Components/ListItems/Header.qml+1−1 Components/OpenEffect.qml+9−1 Components/PageHeader.qml+1−1 Components/Showable.qml+5−14 Components/Tile.qml+1−1 Dash/Apps/RunningApplicationTile.qml+1−1 Dash/Dash.qml−3 Dash/DashBar.qml+1−1 Dash/DashContent.qml−2 Dash/DashPreview.qml+1−1 Dash/Generic/GenericCarousel.qml+58 Dash/Generic/GenericFilterGrid.qml+59 Panel/Menus/IndicatorMenuWindow.qml → Dash/Generic/GenericFilterGridPotrait.qml+9−14 Dash/Generic/GenericPreview.qml+84 Dash/GenericScopeView.qml+141−17 Dash/Music/AlbumTile.qml+2−2 Dash/PreviewDelegateMapper.qml+34 Dash/Video/VideoPreview.qml+3−3 Launcher/LauncherPanel.qml+6−5 Notifications/Notification.qml+6−5 Notifications/Notifications.qml+1 Panel/IndicatorItem.qml+23−36 Panel/IndicatorRow.qml+6−5 Panel/Indicators.qml+23−49 Panel/Indicators/DatetimeIndicatorPage.qml+97 Panel/Indicators/DatetimeIndicatorWidget.qml+65 Panel/Indicators/DefaultIndicatorPage.qml+25 Panel/Indicators/DefaultIndicatorWidget.qml+80 Panel/Indicators/MessagingIndicatorPage.qml+35 Panel/Indicators/MessagingIndicatorWidget.qml+25 Panel/Indicators/NetworkIndicatorPage.qml+79 Panel/Indicators/NetworkIndicatorWidget.qml+109 Panel/Indicators/SoundIndicatorWidget.qml+25 Panel/Indicators/client/IndicatorsClient.qml+42 Panel/Indicators/client/IndicatorsList.qml+62 Panel/Indicators/client/IndicatorsPage.qml+49 Panel/IndicatorsDataModel.qml+66 Panel/MenuContent.qml+34−86 Panel/Menus/Overview.qml−70 Panel/Menus/Overview/FlightModeWidget.qml−60 Panel/Menus/Overview/OverviewGrid.qml−144 Panel/Menus/Overview/VolumeWidget.qml−88 Panel/Menus/Overview/graphics/plane_icon@18.png Panel/Menus/Overview/graphics/sound_off_icon@18.png Panel/Menus/Overview/graphics/sound_on_icon@18.png Panel/graphics/time_and_date@18.png Shell.qml+4−5 build+2−5 cmake/modules/Plugins.cmake+25−15 cmake/modules/autopilot.cmake+7−4 debian/changelog+99 debian/control+52−40 debian/indicators-client.install+1 debian/unity8.install+1 main.cpp+5−8 paths.h.in+15 plugins/HudClient/CMakeLists.txt+2−1 plugins/LightDM/CMakeLists.txt+2−1 plugins/ListViewWithPageHeader/CMakeLists.txt+2−1 plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+1−1 plugins/Ubuntu/Gestures/CMakeLists.txt+2−1 plugins/Unity/CMakeLists.txt+4−1 plugins/Unity/Indicators/CMakeLists.txt+51 plugins/Unity/Indicators/Messaging/CMakeLists.txt+1 plugins/Unity/Indicators/Messaging/qml/ActionButton.qml+43 plugins/Unity/Indicators/Messaging/qml/ActionTextField.qml+66 plugins/Unity/Indicators/Messaging/qml/CMakeLists.txt+5 plugins/Unity/Indicators/Messaging/qml/GroupedMessage.qml+96 plugins/Unity/Indicators/Messaging/qml/HeroMessage.qml+120 plugins/Unity/Indicators/Messaging/qml/HeroMessageHeader.qml+161 plugins/Unity/Indicators/Messaging/qml/MessageMenuItem.qml+96 plugins/Unity/Indicators/Messaging/qml/QuickReply.qml+160 plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qml+97 plugins/Unity/Indicators/Messaging/qml/SnapDecision.qml+142 plugins/Unity/Indicators/Messaging/qml/TextMessage.qml+35 plugins/Unity/Indicators/Messaging/qml/qmldir+12 plugins/Unity/Indicators/Messaging/qml/utils.js+27 plugins/Unity/Indicators/Network/CMakeLists.txt+45 plugins/Unity/Indicators/Network/networkagent.cpp+146 plugins/Unity/Indicators/Network/networkagent.h+65 tests/mocks/Ubuntu/ChewieUI/fake_chewie_plugin.cpp → plugins/Unity/Indicators/Network/plugin.cpp+12−11 plugins/Unity/Indicators/Network/plugin.h+32 plugins/Unity/Indicators/Network/qml/AccessPoint.qml+68 plugins/Unity/Indicators/Network/qml/CMakeLists.txt+5 plugins/Unity/Indicators/Network/qml/PasswordPage.qml+88 plugins/Unity/Indicators/Network/qml/PasswordTextField.qml+68 plugins/Unity/Indicators/Network/qml/WifiSection.qml+34 plugins/Unity/Indicators/Network/qml/qmldir+9 plugins/Unity/Indicators/Network/secret-agent.c+382 plugins/Unity/Indicators/Network/secret-agent.h+102 plugins/Unity/Indicators/flatmenuproxymodel.cpp+272 plugins/Unity/Indicators/flatmenuproxymodel.h+93 plugins/Unity/Indicators/indicator.cpp+88 plugins/Unity/Indicators/indicator.h+59 plugins/Unity/Indicators/indicators.h+105 plugins/Unity/Indicators/indicatorsmanager.cpp+285 plugins/Unity/Indicators/indicatorsmanager.h+74 plugins/Unity/Indicators/indicatorsmodel.cpp+321 tests/mocks/Ubuntu/ChewieUI/fake_pluginmodel.h → plugins/Unity/Indicators/indicatorsmodel.h+33−45 plugins/Unity/Indicators/menucontentactivator.cpp+345 plugins/Unity/Indicators/menucontentactivator.h+117 plugins/Unity/Indicators/plugin.cpp+47 tests/mocks/Ubuntu/ChewieUI/fake_chewie_plugin.h → plugins/Unity/Indicators/plugin.h+8−7 plugins/Unity/Indicators/qml/BasicMenuItem.qml+48 plugins/Unity/Indicators/qml/ButtonMenuItem.qml+47 plugins/Unity/Indicators/qml/CMakeLists.txt+5 plugins/Unity/Indicators/qml/DivMenuItem.qml+26 plugins/Unity/Indicators/qml/HLine.qml+29 plugins/Unity/Indicators/qml/IndicatorBase.qml+59 plugins/Unity/Indicators/qml/IndicatorPage.qml+191 plugins/Unity/Indicators/qml/IndicatorWidget.qml+68 plugins/Unity/Indicators/qml/MenuAction.qml+86 plugins/Unity/Indicators/qml/MenuActionBinding.qml+106 plugins/Unity/Indicators/qml/MenuItem.qml+40 plugins/Unity/Indicators/qml/MenuItemFactory.qml+110 plugins/Unity/Indicators/qml/ProgressMenuItem.qml+65 plugins/Unity/Indicators/qml/RemoveBackground.qml+55 plugins/Unity/Indicators/qml/SectionMenuItem.qml+57 plugins/Unity/Indicators/qml/SliderMenuItem.qml+64 plugins/Unity/Indicators/qml/SwitchMenuItem.qml+43 plugins/Unity/Indicators/qml/qmldir+21 plugins/Unity/Indicators/resources/artwork/messaging/default_app.svg+42 plugins/Unity/Indicators/resources/artwork/messaging/default_contact.png plugins/Unity/Indicators/resources/artwork/messaging/message_sms01_54px.png plugins/Unity/Indicators/resources/indicators.qrc+7 plugins/Unity/Indicators/unityindicatorsglobal.h+23 plugins/Unity/Launcher/CMakeLists.txt+2−2 plugins/Unity/Launcher/backend/launcherbackend.cpp+3−3 plugins/Unity/Launcher/qmldir+1 plugins/Utils/CMakeLists.txt+3−1 plugins/Utils/applicationpaths.h+38 plugins/Utils/plugin.cpp+8 po/ar.po+3−27 po/az.po+4−10 po/bg.po+3−15 po/ca.po+4−16 po/de.po+5−29 po/el.po+4−10 po/en_AU.po+3−27 po/en_GB.po+4−28 po/eo.po+3−3 po/es.po+1−1 po/fi.po+4−25 po/fo.po+4−10 po/fr.po+40−61 po/gl.po+4−16 po/he.po+4−10 po/hr.po+4−10 po/hu.po+4−10 po/hy.po+3−15 po/id.po+3−3 po/it.po+4−10 po/ja.po+3−3 po/kn.po+4−10 po/ko.po+4−4 po/ky.po+4−10 po/lv.po+4−10 po/my.po+4−7 po/nb.po+3−9 po/nl.po+4−10 po/pl.po+8−32 po/pt_BR.po+4−10 po/ro.po+4−10 po/ru.po+22−37 po/si.po+3−3 po/sl.po+1−1 po/sr.po+4−10 po/sv.po+3−3 po/te.po+4−4 po/tr.po+3−24 po/ug.po+6−27 po/uk.po+4−28 po/zh_CN.po+3−27 po/zh_TW.po+4−16 run+3−3 run_on_device+4−22 src/CMakeLists.txt+1 src/Panel/CMakeLists.txt+1 src/Panel/Indicators/CMakeLists.txt+2 src/Panel/Indicators/client/CMakeLists.txt+25 src/Panel/Indicators/client/indicatorsclient.cpp+99 src/Panel/Indicators/client/indicatorsclient.h+45 src/Panel/Indicators/client/main.cpp+26 src/Panel/Indicators/servicefiles/CMakeLists.txt+18 src/Panel/Indicators/servicefiles/com.canonical.indicator.battery+9 src/Panel/Indicators/servicefiles/com.canonical.indicator.messages+9 src/Panel/Indicators/servicefiles/com.canonical.indicator.time+9 src/Panel/Indicators/servicefiles/com.canonical.settings.network+9 src/Panel/Indicators/servicefiles/com.canonical.settings.sound+9 tests/autopilot/unity8/indicators_client/__init__.py+8 tests/autopilot/unity8/indicators_client/emulators/__init__.py+31 tests/autopilot/unity8/indicators_client/emulators/common.py+14 tests/autopilot/unity8/indicators_client/emulators/main_window.py+27 tests/autopilot/unity8/indicators_client/tests/__init__.py+87 tests/autopilot/unity8/indicators_client/tests/test_battery.py+99 tests/autopilot/unity8/shell/__init__.py+8 tests/autopilot/unity8/emulators/__init__.py → tests/autopilot/unity8/shell/emulators/__init__.py tests/autopilot/unity8/emulators/main_window.py → tests/autopilot/unity8/shell/emulators/main_window.py tests/autopilot/unity8/tests/__init__.py → tests/autopilot/unity8/shell/tests/__init__.py+1−1 tests/autopilot/unity8/tests/helpers.py → tests/autopilot/unity8/shell/tests/helpers.py tests/autopilot/unity8/tests/testbigscreen.py → tests/autopilot/unity8/shell/tests/testbigscreen.py+1−1 tests/autopilot/unity8/tests/testhud.py → tests/autopilot/unity8/shell/tests/testhud.py+2−2 tests/autopilot/unity8/tests/testlockscreen.py → tests/autopilot/unity8/shell/tests/testlockscreen.py+2−2 tests/data/unity/indicators/com.canonical.indicator.fake1+9 tests/data/unity/indicators/com.canonical.indicator.fake2+9 tests/data/unity/indicators/com.canonical.indicator.fake3+9 tests/data/unity/indicators/com.canonical.indicator.fake4+9 tests/mocks/LightDM/demo/InfographicModelPrivate.cpp+3−3 tests/mocks/LightDM/demo/UsersModelPrivate.cpp+1−1 tests/mocks/Ubuntu/Application/ApplicationManager.cpp+2−2 tests/mocks/Ubuntu/CMakeLists.txt−1 tests/mocks/Ubuntu/ChewieUI/CMakeLists.txt−33 tests/mocks/Ubuntu/ChewieUI/fake_pluginmodel.cpp−206 tests/mocks/Ubuntu/ChewieUI/qmldir−1 tests/mocks/Unity/CMakeLists.txt+2 tests/mocks/Unity/Indicators/CMakeLists.txt+49 tests/mocks/Unity/Indicators/IndicatorsModel.qml+104 tests/mocks/Unity/Indicators/fakeplugin.cpp+41 tests/mocks/Unity/Indicators/fakeplugin.h+32 tests/mocks/Unity/Indicators/indicators_fake.qrc+14 tests/qmltests/Panel/qml/FakeMenuPlugin.qml → tests/mocks/Unity/Indicators/qml/FakeMenuPage.qml tests/qmltests/Panel/qml/fake_menu_plugin1.qml → tests/mocks/Unity/Indicators/qml/fake_menu_page1.qml+3−2 tests/qmltests/Panel/qml/fake_menu_plugin2.qml → tests/mocks/Unity/Indicators/qml/fake_menu_page2.qml+3−2 tests/qmltests/Panel/qml/fake_menu_plugin3.qml → tests/mocks/Unity/Indicators/qml/fake_menu_page3.qml+3−2 tests/qmltests/Panel/qml/fake_menu_plugin4.qml → tests/mocks/Unity/Indicators/qml/fake_menu_page4.qml+3−2 tests/qmltests/Panel/qml/fake_menu_plugin5.qml → tests/mocks/Unity/Indicators/qml/fake_menu_page5.qml+3−2 tests/mocks/Unity/Indicators/qml/fake_menu_widget1.qml+23 tests/mocks/Unity/Indicators/qml/fake_menu_widget2.qml+23 tests/mocks/Unity/Indicators/qml/fake_menu_widget3.qml+23 tests/mocks/Unity/Indicators/qml/fake_menu_widget4.qml+23 tests/mocks/Unity/Indicators/qml/fake_menu_widget5.qml+23 tests/mocks/Unity/Indicators/qmldir+5 tests/mocks/Unity/Launcher/CMakeLists.txt+1−6 tests/mocks/Unity/Launcher/MockLauncherModel.cpp+1−1 tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+19 tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cpp+19 tests/plugins/Unity/CMakeLists.txt+2 tests/plugins/Unity/Indicators/CMakeLists.txt+28 tests/plugins/Unity/Indicators/indicatorsmanagertest.cpp+138 tests/plugins/Unity/Indicators/indicatorsmodeltest.cpp+102 tests/plugins/Unity/Indicators/menucontentactivatortest.cpp+303 tests/plugins/Unity/previewbindingstest.cpp−2 tests/qmltests/CMakeLists.txt−2 tests/qmltests/Components/tst_OpenEffect.qml+1−1 tests/qmltests/Notifications/tst_Notifications.qml+20−9 tests/qmltests/Panel/Menus/tst_IndicatorMenuWindow.qml−68 tests/qmltests/Panel/tst_IndicatorItem.qml+13−28 tests/qmltests/Panel/tst_IndicatorRow.qml+3−16 tests/qmltests/Panel/tst_Indicators.qml+2−41 tests/qmltests/Panel/tst_MenuContent.qml+21−90 tests/qmltests/Panel/tst_Overview.qml−154 tests/qmltests/Panel/tst_Panel.qml+33−34 tests/qmltests/modules/CMakeLists.txt+1 tests/qmltests/modules/Unity/CMakeLists.txt+1 unity8.qmlproject+1
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 = {
7070 'exec': '/usr/bin/qmlscene /usr/share/notes-app/NotesApp.qml',
7171 'stage': SideStage
7272 },
73− '/usr/share/applications/ubuntu-calendar-app.desktop': {
73+ '/usr/share/applications/calendar-app.desktop': {
7474 'name': i18n.tr("Calendar"),
7575 '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',
7777 'stage': SideStage
7878 },
7979 '/usr/share/applications/mediaplayer-app.desktop': {
CMakeLists.txt+5−3
@@ -91,9 +91,8 @@ enable_testing()
9191
9292# Autopilot tests
9393include(autopilot)
94−declare_autopilot_test(unity8 ${CMAKE_SOURCE_DIR}/tests/autopilot/)
95−
96−add_subdirectory(tests)
94+declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
95+declare_autopilot_test(indicators_client unity8.indicators_client ${CMAKE_SOURCE_DIR}/tests/autopilot/)
9796
9897set(SHELL_APP unity8)
9998
@@ -102,6 +101,7 @@ set(shell_app_HDRS
102101
103102add_executable(${SHELL_APP}
104103 ${shellapplication_MOC_SRCS}
104+ ApplicationArguments.h
105105 main.cpp
106106 MouseTouchAdaptor.cpp
107107 )
@@ -132,7 +132,9 @@ install(FILES ${QML_JS_FILES}
132132 )
133133
134134# add subdirectories to build
135+add_subdirectory(tests)
135136add_subdirectory(plugins)
137+add_subdirectory(src)
136138
137139# install subdirectories
138140set(QML_DIRS
CODING+5−6
@@ -23,15 +23,12 @@ $ cd ~/unity8/trunk
2323$ ./build --setup
2424
2525 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
3027 - install the required dependencies to build, as well as run on the desktop
3128 - it should also install unity-scope-home and unity-lens-application which
3229 are technically "recommends", not strict dependencies
3330
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
3532any failures associated with it, the build script will bail out of the setup
3633and fail to install all the required dependencies.
3734
@@ -45,6 +42,7 @@ $ ./build
4542You may also rebuild with the -c for clean, which just deletes the build
4643directory.
4744
45+
4846Running Unity 8 on your desktop
4947===============================
5048
@@ -73,6 +71,7 @@ Notes
7371 - Create an EDS address book
7472 - Populate the address book with sample data
7573
74+
7675Running Unity 8 on devices
7776==========================
7877- Ubuntu Touch builds are currently only available in 13.10 flavour
@@ -91,7 +90,6 @@ $ cd ~/unity/trunk
9190$ ./run_on_device --setup
9291 this will:
9392 - install your public SSH key on the device
94− - add ppa:canonical-qt5-edgers/qt5-proper and ppa:phablet-team
9593 - install the needed dependencies
9694
9795$ ./run_on_device
@@ -109,6 +107,7 @@ $ ./run_on_device -p OR -k
109107Notes
110108-----
111109- using adb over TCP has some advantages, Google will be of help here
110+ - NOTE: this is not yet available for flipped images
112111 - TL;DR: `adb tcpip 5555; adb connect $your_device_ip`
113112 - you can persist the above via `adb shell setprop persist.adb.tcp.port 5555`
114113 - it's unsafe - anyone can connect to your device
Components/ApplicationScreenshot.qml+1−1
@@ -46,7 +46,7 @@ Item {
4646 Rectangle {
4747 id: background
4848 anchors.fill: parent
49− color: "white"
49+ color: "white" // FIXME should use normal background color of Suru theme
5050 visible: applicationScreenshot.withBackground
5151 }
5252
Components/Carousel.qml+38−1
@@ -52,6 +52,12 @@ Item {
5252 /// @param itemY is y of the clicked delegate
5353 signal clicked(int index, var delegateItem, real itemY)
5454
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+
5561 implicitHeight: listView.tileHeight * selectedItemScaleFactor
5662
5763 /* Basic idea behind the carousel effect is to move the items of the delegates (compacting /stuffing them).
@@ -159,6 +165,30 @@ Item {
159165 newContentXAnimation.start()
160166 }
161167
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+
162192 onMovementStarted: {
163193 stepAnimation.stop()
164194 newContentXAnimation.stop()
@@ -279,7 +309,14 @@ Item {
279309
280310 anchors.fill: parent
281311
282− onClicked: listView.itemClicked(index, item)
312+ onClicked: {
313+ listView.itemClicked(index, item)
314+ }
315+
316+ onPressAndHold: {
317+ listView.itemPressAndHold(index, item)
318+ }
319+
283320 }
284321 }
285322 }
Components/FilterGrid.qml+2−2
@@ -99,7 +99,7 @@ Item {
9999
100100 UbuntuShape {
101101 anchors.fill: parent
102− color: "#33ffffff"
102+ color: "#33ffffff" // FIXME no palette
103103 radius: "small"
104104 }
105105
@@ -123,7 +123,7 @@ Item {
123123 }
124124 text: (filter) ? "+ View all (" + model.count + ")" : "- Show fewer"
125125 fontSize: "small"
126− color: "#f3f3e7"
126+ color: Theme.palette.selected.backgroundText
127127 opacity: 0.6
128128 style: Text.Raised
129129 styleColor: "black"
Components/ListItems/Header.qml+1−1
@@ -45,7 +45,7 @@ Item {
4545 verticalCenter: parent.verticalCenter
4646 }
4747
48− color: "#f3f3e7" //at 60%
48+ color: Theme.palette.selected.backgroundText //at 60%
4949 opacity: 0.6
5050 font.family: "Ubuntu"
5151 fontSize: "medium"
Components/OpenEffect.qml+9−1
@@ -19,11 +19,13 @@ import QtQuick 2.0
1919Item {
2020 id: effect
2121 property bool enabled: topGapPx != positionPx || bottomGapPx != positionPx
22+ property alias live: effectSource.live
2223 property Item sourceItem
2324 property ShaderEffectSource source: ShaderEffectSource {
25+ id: effectSource
2426 sourceItem: effect.enabled ? effect.sourceItem : null
2527 hideSource: effect.enabled
26− live: effect.enabled
28+ live: false
2729 sourceRect: {
2830 if (effect.enabled) {
2931 Qt.rect(0, -effect.topOverflow, sourceItem.width, sourceItem.height + effect.topOverflow + effect.bottomOverflow)
@@ -33,6 +35,8 @@ Item {
3335 }
3436 }
3537
38+ onEnabledChanged: if (!live && enabled) scheduleUpdate()
39+
3640 /*!
3741 \qmlproperty real positionPx
3842 The y coordinate of where to perform the split.
@@ -60,6 +64,10 @@ Item {
6064
6165 property real __roundedPositionPx: Math.round(positionPx)
6266
67+ function scheduleUpdate() {
68+ source.scheduleUpdate();
69+ }
70+
6371 ShaderEffect {
6472 id: top
6573 visible: effect.enabled
Components/PageHeader.qml+1−1
@@ -90,7 +90,7 @@ Item {
9090 verticalCenter: parent.verticalCenter
9191 }
9292
93− color: "#f3f3e7"
93+ color: Theme.palette.selected.backgroundText
9494 opacity: 0.8
9595 font.family: "Ubuntu"
9696 font.weight: Font.Light
Components/Showable.qml+5−14
@@ -52,7 +52,7 @@ Item {
5252 function show() {
5353 required = true;
5454 if (created) {
55− __reallyShow(true);
55+ __reallyShow();
5656 } else {
5757 __shouldShow = true;
5858 }
@@ -60,16 +60,12 @@ Item {
6060
6161 onCreatedChanged: {
6262 if (created && __shouldShow) {
63− __reallyShow(true);
63+ __reallyShow();
6464 __shouldShow = false;
6565 }
6666 }
6767
68− function showWithoutAnimation() {
69− __reallyShow(false);
70− }
71−
72− function __reallyShow(animated) {
68+ function __reallyShow() {
7369 if (!available) {
7470 return false;
7571 }
@@ -81,13 +77,8 @@ Item {
8177 }
8278
8379 if (showAnimation != undefined) {
84− if (animated) {
85− if (!showAnimation.running) {
86− showAnimation.restart()
87− }
88− } else {
89− showAnimation.start();
90− showAnimation.complete();
80+ if (!showAnimation.running) {
81+ showAnimation.restart()
9182 }
9283 } else {
9384 visible = true;
Components/Tile.qml+1−1
@@ -75,7 +75,7 @@ AbstractButton {
7575 rightMargin: units.gu(1)
7676 }
7777
78− color: "#f3f3e7"
78+ color: Theme.palette.selected.backgroundText
7979 opacity: 0.9
8080 style: Text.Raised
8181 styleColor: "black"
Dash/Apps/RunningApplicationTile.qml+1−1
@@ -113,7 +113,7 @@ AbstractButton {
113113 }
114114 text: (application) ? application.name : ""
115115
116− color: "#f3f3e7"
116+ color: Theme.palette.selected.backgroundText
117117 opacity: 0.9
118118 style: Text.Raised
119119 styleColor: "black"
Dash/Dash.qml−3
@@ -27,9 +27,6 @@ Showable {
2727 property string showScopeOnLoaded: "home.scope"
2828 property real contentScale: 1.0
2929
30− width: units.gu(40)
31− height: units.gu(71)
32−
3330 function setCurrentScope(scopeId, animate, reset) {
3431 var scopeIndex = filteredScopes.findFirst(Scopes.RoleId, scopeId)
3532
Dash/DashBar.qml+1−1
@@ -117,7 +117,7 @@ Item {
117117
118118 Rectangle {
119119 id: highlightLine
120− color: "#dd4814"
120+ color: Theme.palette.selected.foreground
121121 height: parent.height
122122 anchors.bottom: parent.bottom
123123 z: 1
Dash/DashContent.qml−2
@@ -20,8 +20,6 @@ import Unity 0.1
2020
2121Item {
2222 id: dashContent
23− width: units.gu(40)
24− height: units.gu(71)
2523
2624 property var model: null
2725 property var scopes: null
Dash/DashPreview.qml+1−1
@@ -92,7 +92,7 @@ Rectangle {
9292 elide: Text.ElideRight
9393 fontSize: "x-large"
9494 font.weight: Font.Light
95− color: "#f3f3e7"
95+ color: Theme.palette.selected.backgroundText
9696 opacity: 0.9
9797 text: root.title
9898 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 @@
1515 */
1616
1717import QtQuick 2.0
18+import "../../Components"
1819
19−Item {
20− id: menuWindow
20+GenericFilterGrid {
21+ id: filtergrid
2122
22− property bool shown: false
23− property int contentHeight: height
24− property string headingText: name
25− property string name
23+ minimumHorizontalSpacing: units.gu(0.5)
24+ delegateWidth: units.gu(11)
25+ delegateHeight: units.gu(18)
26+ verticalSpacing: units.gu(2)
2627
27− enabled: shown
28− opacity: shown ? 1.0 : 0.0
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− }
28+ iconWidth: (width / columns) * 0.8
29+ iconHeight: iconWidth * 16 / 11
3530}
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
2222
2323ScopeView {
2424 id: scopeView
25+ property alias previewShown: previewLoader.onScreen
2526
2627 onIsCurrentChanged: {
2728 pageHeader.resetSearch();
@@ -47,35 +48,54 @@ ScopeView {
4748 id: categoryView
4849 anchors.fill: parent
4950 model: scopeView.categories
51+ forceNoClip: previewLoader.onScreen
52+
5053 onAtYEndChanged: if (atYEnd) endReached()
5154 onMovingChanged: if (moving && atYEnd) endReached()
5255
5356 delegate: ListItems.Base {
5457 highlightWhenPressed: false
5558
56− FilterGrid {
57− id: filtergrid
58− model: results
59−
59+ Loader {
60+ id: rendererLoader
6061 anchors {
6162 top: parent.top
6263 left: parent.left
6364 right: parent.right
6465 }
6566
66− filter: false
67− minimumHorizontalSpacing: units.gu(0.5)
68− delegateWidth: units.gu(11)
69− delegateHeight: units.gu(18)
70− verticalSpacing: units.gu(2)
71−
72− delegate: Tile {
73− width: filtergrid.cellWidth
74− height: filtergrid.cellHeight
75− text: title
76− imageWidth: units.gu(11)
77− imageHeight: units.gu(16)
78− source: IconUtil.from_gicon(icon)
67+ source: getRenderer(model.renderer, model.contentType)
68+
69+ onLoaded: {
70+ item.model = results
71+ }
72+
73+ Connections {
74+ target: rendererLoader.item
75+ onClicked: {
76+ effect.positionPx = mapToItem(categoryView, 0, itemY).y
77+ scopeView.scope.activate(delegateItem.model.uri,
78+ delegateItem.model.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+ }
7999 }
80100 }
81101 }
@@ -93,4 +113,108 @@ ScopeView {
93113 searchEntryEnabled: true
94114 }
95115 }
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+ }
96220}
Dash/Music/AlbumTile.qml+2−2
@@ -69,7 +69,7 @@ AbstractButton {
6969 rightMargin: units.gu(1)
7070 }
7171
72− color: "#f3f3e7"
72+ color: Theme.palette.selected.backgroundText
7373 opacity: 0.9
7474 style: Text.Raised
7575 styleColor: "black"
@@ -97,7 +97,7 @@ AbstractButton {
9797 rightMargin: units.gu(1)
9898 }
9999
100− color: "#f3f3e7"
100+ color: Theme.palette.selected.backgroundText
101101 opacity: 0.9
102102 style: Text.Raised
103103 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 {
4848 property int buttonWidth: Math.min(units.gu(22), (width - spacing) / 2)
4949 Button {
5050 width: parent.buttonWidth
51− color: "#dd4814"
51+ color: Theme.palette.selected.foreground
5252 text: nfo.ready && nfo.video.buyPrice != "" ? "Buy for " + nfo.video.buyPrice : ""
5353 visible: text != ""
5454 iconSource: "graphics/icon_button_amazon.png"
@@ -56,7 +56,7 @@ DashPreview {
5656 }
5757 Button {
5858 width: parent.buttonWidth
59− color: "#dd4814"
59+ color: Theme.palette.selected.foreground
6060 text: nfo.ready && nfo.video.buyPrice != "" ? "Rent for " + nfo.video.rentPrice : ""
6161 visible: text != ""
6262 iconSource: "graphics/icon_button_u1.png"
@@ -73,7 +73,7 @@ DashPreview {
7373
7474 Label {
7575 text: nfo.ready ? nfo.video.plot : ""
76− color: "#f3f3e7"
76+ color: Theme.palette.selected.backgroundText
7777 opacity: .6
7878 fontSize: "medium"
7979 width: parent.width
Launcher/LauncherPanel.qml+6−5
@@ -86,6 +86,7 @@ Item {
8686 height: width
8787 anchors.centerIn: parent
8888 source: "graphics/home.png"
89+ rotation: root.rotation
8990 }
9091 }
9192 ThinDivider {
@@ -178,7 +179,7 @@ Item {
178179 property int startY
179180
180181
181− Item {
182+/* Item {
182183 id: fakeDragItem
183184 width: launcherListView.itemSize
184185 height: launcherListView.itemSize
@@ -207,16 +208,16 @@ Item {
207208 height: width
208209 }
209210 }
210−
211−/* LauncherDelegate {
211+*/
212+ LauncherDelegate {
212213 id: fakeDragItem
213− visible: dndArea.draggedItem !== undefined
214+ visible: dndArea.draggedIndex >= 0
214215 iconName: "gmail"
215216 height: launcherListView.itemSize
216217 width: height
217218 rotation: root.rotation
218219 }
219−*/
220+
220221 onPressed: {
221222 var realContentY = launcherListView.contentY + launcherListView.topMargin
222223 selectedItem = launcherListView.itemAt(mouseX, mouseY + realContentY)
Notifications/Notification.qml+6−5
@@ -28,6 +28,7 @@ UbuntuShape {
2828 property var actions
2929 property var notificationId
3030 property var type
31+ property var hints
3132 property var notification
3233
3334 objectName: "background"
@@ -117,7 +118,7 @@ UbuntuShape {
117118 }
118119 fontSize: "medium"
119120 font.bold: true
120− color: "#f3f3e7"
121+ color: Theme.palette.selected.backgroundText
121122 elide: Text.ElideRight
122123 }
123124
@@ -131,7 +132,7 @@ UbuntuShape {
131132 }
132133 visible: body != ""
133134 fontSize: "small"
134− color: "#f3f3e7"
135+ color: Theme.palette.selected.backgroundText
135136 opacity: 0.6
136137 wrapMode: Text.WordWrap
137138 maximumLineCount: 10
@@ -164,7 +165,7 @@ UbuntuShape {
164165 bottom: parent.bottom
165166 }
166167 text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
167− color: "#cdcdcb"
168+ gradient: UbuntuColors.greyGradient
168169 onClicked: {
169170 if (actionRepeater.count > 2) {
170171 buttonRow.expanded = !buttonRow.expanded
@@ -194,7 +195,7 @@ UbuntuShape {
194195 top: parent.top
195196 bottom: parent.bottom
196197 }
197− color: "#d85317"
198+ gradient: notification.hints == Notification.ButtonTint ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient
198199 visible: width > 0
199200 onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
200201 }
@@ -241,7 +242,7 @@ UbuntuShape {
241242
242243 text: loader.actionLabel
243244 height: units.gu(4)
244− color: "#cdcdcb"
245+ gradient: UbuntuColors.greyGradient
245246 onClicked: notification.notification.invokeAction(loader.actionId)
246247 }
247248 }
Notifications/Notifications.qml+1
@@ -32,6 +32,7 @@ ListView {
3232 right: parent.right
3333 }
3434 type: model.type
35+ hints: model.hints
3536 iconSource: model.icon
3637 secondaryIconSource: model.secondaryIcon
3738 summary: model.summary
Panel/IndicatorItem.qml+23−36
@@ -16,55 +16,42 @@
1616
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
19+import Unity.Indicators 0.1 as Indicators
1920
2021Item {
2122 id: indicatorItem
2223
23− property alias iconSource: itemImage.source
24− property alias label: itemLabel.text
24+ property alias widgetSource: loader.source
2525 property bool highlighted: false
2626 property bool dimmed: false
27+ property var indicatorProperties: undefined
28+
29+ opacity: dimmed ? 0.4 : 1
2730
2831 // only visible when non-empty
29− visible: label != "" || iconSource != ""
30− width: itemRow.width + units.gu(1)
32+ visible: loader.item != undefined && loader.status == Loader.Ready ? loader.item.enabled : false
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+ }
3148
3249 Rectangle {
33− color: "#dd4814"
50+ color: Theme.palette.selected.foreground
51+ objectName: "highlight"
3452 height: units.dp(2)
3553 width: parent.width
3654 anchors.top: parent.bottom
3755 visible: highlighted
3856 }
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− }
7057}
Panel/IndicatorRow.qml+6−5
@@ -21,10 +21,9 @@ Item {
2121 id: indicatorRow
2222
2323 property QtObject currentItem : null
24− property int currentItemIndex: currentItem ? currentItem.ownIndex : -1
24+ readonly property int currentItemIndex: currentItem ? currentItem.ownIndex : -1
2525 property alias row: row
2626 property QtObject indicatorsModel: null
27− property bool overviewActive: false // "state of the menu"
2827
2928 Behavior on y {NumberAnimation {duration: 300; easing.type: Easing.OutCubic} }
3029
@@ -54,13 +53,15 @@ Item {
5453 id: rowRepeater
5554 objectName: "rowRepeater"
5655 model: indicatorsModel ? indicatorsModel : undefined
56+
5757 IndicatorItem {
5858 id: indicatorItem
5959
6060 property int ownIndex: index
6161
62− label: model.label
63− iconSource: model.iconSource
62+ widgetSource: model.widgetSource
63+
64+ indicatorProperties : model.indicatorProperties
6465 highlighted: indicatorRow.state == "reveal" || indicatorRow.state == "locked" || indicatorRow.state == "commit" ? ownIndex == indicatorRow.currentItemIndex : false
6566 dimmed: { //See FIXME in Indicators regarding the "states" change
6667 if (indicatorRow.state == "initial" || indicatorRow.state == "") {
@@ -74,7 +75,7 @@ Item {
7475 height: indicatorRow.height
7576 y: {
7677 //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")) {
7879 return -indicatorRow.height
7980 } else {
8081 return 0
Panel/Indicators.qml+23−49
@@ -17,7 +17,6 @@
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import Ubuntu.Gestures 0.1
20−import Ubuntu.ChewieUI 0.1 as ChewieUI
2120
2221import "../Components"
2322import "../Components/ListItems"
@@ -57,37 +56,22 @@ Showable {
5756
5857 onHeightChanged: {
5958 // 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();
6160 if (!showAnimation.running && !hideAnimation.running) {
6261 if (contentProgress <= hintValue && indicators.state == "reveal") {
63− indicators.state = "hint"
64− menuContent.hideAll()
62+ indicators.state = "hint";
6563 } else if (contentProgress > hintValue && contentProgress < lockThreshold) {
66− menuContent.showMenu()
67− indicators.state = "reveal"
64+ indicators.state = "reveal";
6865 } 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";
7867 }
7968 }
8069
8170 if (contentProgress == 0) {
82− menuContent.releaseContent()
71+ menuContent.releaseContent();
8372 }
8473 }
8574
86− function openOverview() {
87− indicatorRow.currentItem = null
88− menuContent.showOverview()
89− }
90−
9175 function calculateCurrentItem(xValue, useBuffer) {
9276 var rowCoordinates
9377 var itemCoordinates
@@ -95,7 +79,7 @@ Showable {
9579 var distanceFromRightEdge
9680 var bufferExceeded = false
9781
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;
9983
10084 /*
10185 If user drags the indicator handle bar down a distance hintValue or less, this is 0.
@@ -104,14 +88,14 @@ Showable {
10488 */
10589 var verticalProgress =
10690 MathLocal.clamp((indicators.height - handle.height - hintValue) /
107− (lockThreshold - hintValue), 0, 1)
91+ (lockThreshold - hintValue), 0, 1);
10892
10993 /*
11094 Percentage of an indicator icon's width the user's press can stray horizontally from the
11195 focused icon before we change focus to another icon. E.g. a value of 0.5 means you must
11296 go right a distance of half an icon's width before focus moves to the icon on the right
11397 */
114− var maxBufferThreshold = 0.5
98+ var maxBufferThreshold = 0.5;
11599
116100 /*
117101 To help users find the indicator of their choice while opening the indicators, we add logic to add a
@@ -128,12 +112,12 @@ Showable {
128112 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
129113 distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width)
130114 if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) {
131− bufferExceeded = true
115+ bufferExceeded = true;
132116 } else {
133117 if (indicatorRow.currentItemIndex < currentItem.ownIndex && distanceFromRightEdge < (1 - effectiveBufferThreshold)) {
134− bufferExceeded = true
118+ bufferExceeded = true;
135119 } else if (indicatorRow.currentItemIndex > currentItem.ownIndex && distanceFromRightEdge > effectiveBufferThreshold) {
136− bufferExceeded = true
120+ bufferExceeded = true;
137121 }
138122 }
139123 if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItem < 0 || indicatorRow.currentItem == null) {
@@ -174,8 +158,7 @@ Showable {
174158 bottom: parent.bottom
175159 }
176160 indicatorsModel: indicatorsModel
177− animate: false
178− clip: indicators.partiallyOpened
161+ clip: !indicators.fullyOpened
179162
180163 onMenuSelected: {
181164 indicatorRow.setItem(index)
@@ -211,7 +194,7 @@ Showable {
211194 clip: height < handleImage.height
212195
213196 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);
215198 }
216199
217200 BorderImage {
@@ -266,15 +249,13 @@ Showable {
266249 height: indicators.panelHeight
267250 indicatorsModel: indicatorsModel
268251 state: indicators.state
269− overviewActive: menuContent.overviewActive
270252
271253 onCurrentItemIndexChanged: menuContent.currentIndex = currentItemIndex
272254
273255 }
274256
275− ChewieUI.PluginModel {
257+ IndicatorsDataModel {
276258 id: indicatorsModel
277− Component.onCompleted: load()
278259 }
279260
280261 Connections {
@@ -282,9 +263,11 @@ Showable {
282263 onRunningChanged: {
283264 if (hideAnimation.running) {
284265 indicators.state = "initial"
285− menuContent.hideAll()
286266 } else {
287− if (state == "initial") indicatorRow.setDefaultItem()
267+ if (state == "initial") {
268+ indicatorRow.setDefaultItem();
269+ menuContent.releaseContent();
270+ }
288271 }
289272 }
290273 }
@@ -292,14 +275,8 @@ Showable {
292275 target: showAnimation
293276 onRunningChanged: {
294277 if (showAnimation.running) {
295− if (indicators.state == "initial") {
296− openOverview()
297− }
298− else {
299− indicators.calculateCurrentItem(dragHandle.touchX, false)
300− menuContent.showMenu()
301− }
302− indicators.state = "commit"
278+ indicators.calculateCurrentItem(dragHandle.touchX, false);
279+ indicators.state = "commit";
303280 }
304281 }
305282 }
@@ -307,8 +284,8 @@ Showable {
307284 Connections {
308285 target: dragHandle
309286 onTouchXChanged: {
310− var buffer = dragHandle.dragging ? true : false
311− indicators.calculateCurrentItem(dragHandle.touchX, buffer)
287+ var buffer = dragHandle.dragging ? true : false;
288+ indicators.calculateCurrentItem(dragHandle.touchX, buffer);
312289 }
313290 }
314291
@@ -343,8 +320,7 @@ Showable {
343320
344321 onStatusChanged: {
345322 if (status === DirectionalDragArea.Recognized) {
346− menuContent.hideAll()
347− menuContent.activateContent()
323+ menuContent.activateContent();
348324 }
349325 }
350326 }
@@ -372,7 +348,6 @@ Showable {
372348 State {
373349 name: "reveal"
374350 extend: "hint"
375− PropertyChanges { target: menuContent; animate: true }
376351 StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
377352 },
378353 State {
@@ -394,7 +369,6 @@ Showable {
394369 },
395370 State {
396371 name: "reveal"
397− PropertyChanges { target: menuContent; animate: true }
398372 StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
399373 },
400374 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 @@
1616
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
19−import "Menus"
19+import Unity.Indicators 0.1 as Indicators
2020import "../Components"
2121
2222Rectangle {
2323 id: content
2424
2525 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
2926 property bool __contentActive: false
3027 property alias currentIndex : menus.currentIndex
31− property color backgroundColor: "#221e1c"
32− property int contentReleaseInterval: 5000
28+ property color backgroundColor: "#221e1c" // FIXME not in palette yet
29+ property int contentReleaseInterval: 20000
3330
3431 width: units.gu(40)
3532 height: units.gu(42)
3633 color: backgroundColor
37− enabled: __shown
3834
3935 signal menuSelected(int index)
4036
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−
5537 function activateContent() {
56− contentReleaseTimer.stop()
57− __contentActive = true
38+ contentReleaseTimer.stop();
39+ __contentActive = true;
5840 }
5941
6042 function releaseContent() {
6143 if (__contentActive)
62− contentReleaseTimer.restart()
44+ contentReleaseTimer.restart();
6345 }
6446
6547 ListView {
@@ -71,7 +53,6 @@ Rectangle {
7153 width: parent.width
7254
7355 spacing: units.gu(0.5)
74− opacity: !overviewActive && __shown ? 1 : 0
7556 enabled: opacity != 0
7657 orientation: ListView.Horizontal
7758 model: indicatorsModel
@@ -82,47 +63,36 @@ Rectangle {
8263
8364 delegate: Loader {
8465 clip: true
85− property bool contentActive: content.__contentActive
66+ property bool contentActive: content.__contentActive && menuActivator.content[index].active
8667
8768 onContentActiveChanged: {
8869 if (contentActive && item) {
89− item.start()
70+ item.start();
9071 } else if (!contentActive && item) {
91− item.stop()
72+ item.stop();
9273 }
9374 }
9475
9576 width: menus.width
9677 height: menus.height
97− sourceComponent: component
98− visible: content.__shown
78+ source: pageSource
9979 onVisibleChanged: {
10080 // Reset the indicator states
10181 if (!visible && item && item["reset"]) {
102− item.reset()
82+ item.reset();
10383 }
10484 }
10585 asynchronous: true
10686
107− onStatusChanged: {
108− if (status == Loader.Ready) {
109− if (indicatorsModel.widgetsMap && item.hasOwnProperty("widgetsMap")) {
110− item["widgetsMap"] = indicatorsModel.widgetsMap
111− }
112− for(var pName in initialProperties) {
113− if (item.hasOwnProperty(pName)) {
114− item[pName] = initialProperties[pName]
115− }
116− }
117− if (contentActive && menus.visible) {
118− item.start()
87+ onLoaded: {
88+ for(var pName in indicatorProperties) {
89+ if (item.hasOwnProperty(pName)) {
90+ item[pName] = indicatorProperties[pName];
11991 }
12092 }
121− }
122−
123− // FIXME: QTBUG-30632 - asynchronous loader crashes when changing index quickly.
124− Component.onDestruction: {
125− active = false;
93+ if (contentActive && menus.visible) {
94+ item.start();
95+ }
12696 }
12797
12898 // Need to use a binding because the handle height changes.
@@ -133,40 +103,6 @@ Rectangle {
133103 value: handle.height
134104 }
135105 }
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− }
170106 }
171107
172108 Rectangle {
@@ -189,9 +125,11 @@ Rectangle {
189125 left: parent.left
190126 right: parent.right
191127 }
192− text: content.overviewActive ? i18n.tr("Device") : (indicatorsModel && menus.currentIndex >= 0 && menus.currentIndex < indicatorsModel.count) ? indicatorsModel.get(menus.currentIndex).title : ""
193− opacity: __shown ? 1 : 0
194− Behavior on opacity {NumberAnimation{duration: 100}}
128+ text: {
129+ if (indicatorsModel && menus.currentIndex >= 0 && menus.currentIndex < indicatorsModel.count)
130+ return indicatorsModel.data(menus.currentIndex, Indicators.IndicatorsModelRole.Title);
131+ return "";
132+ }
195133 }
196134 }
197135
@@ -199,6 +137,16 @@ Rectangle {
199137 id: contentReleaseTimer
200138
201139 interval: contentReleaseInterval
202− onTriggered: __contentActive = false
140+ onTriggered: {
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
203151 }
204152}
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 {
3636
3737 // this is only here to select the width / height of the window if not running fullscreen
3838 property bool tablet: false
39− width: tablet ? units.gu(160) : units.gu(40)
40− height: tablet ? units.gu(100) : units.gu(71)
39+ width: tablet ? units.gu(160) : ApplicationArguments.hasGeometry() ? ApplicationArguments.width() : units.gu(40)
40+ height: tablet ? units.gu(100) : ApplicationArguments.hasGeometry() ? ApplicationArguments.height() : units.gu(71)
4141
4242 property real edgeSize: units.gu(2)
4343 property url default_background: shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg"
@@ -62,6 +62,8 @@ FocusScope {
6262 property var applicationManager: ApplicationManagerWrapper {}
6363
6464 Component.onCompleted: {
65+ Theme.name = "Ubuntu.Components.Themes.SuruGradient"
66+
6567 applicationManager.sideStageEnabled = Qt.binding(function() { return sideStage.enabled })
6668
6769 // FIXME: if application focused before shell starts, shell draws on top of it only.
@@ -263,9 +265,6 @@ FocusScope {
263265 function show() {
264266 stages.show();
265267 }
266− function showWithoutAnimation() {
267− stages.showWithoutAnimation();
268− }
269268 function hide() {
270269 }
271270
build+2−5
@@ -36,17 +36,14 @@ BUILD_TYPE="debug"
3636[ $# -eq 1 ] && BUILD_TYPE="$1"
3737
3838install_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
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
39+ [ -f /etc/apt/sources.list.d/ubuntu-unity-next-${DISTRIB_CODENAME}.list ] || sudo add-apt-repository ppa:ubuntu-unity/next || exit 1
4240 sudo apt-get update || exit 4
4341 echo "Installing Unity 8 dependencies.."
4442 sudo apt-get install devscripts \
4543 equivs \
44+ qmenumodel-qml \
4645 qtdeclarative5-ubuntu-ui-toolkit-plugin \
4746 qtdeclarative5-dee-plugin \
48− indicators-client \
49− indicators-client-plugin-* \
5047 ubuntu-mobile-icons \
5148 unity-notifications-impl-1 \
5249 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
22#
3−# export_qmlplugin(plugin version sub_path [TARGETS target1 [target2 ...]])
3+# export_qmlfiles(plugin sub_path)
44#
5−# TARGETS additional install targets (eg the plugin shared object)
65#
7−# Two targets will be created:
6+# Target to be created:
87# - 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−
118
12−macro(export_qmlplugin PLUGIN VERSION PLUGIN_SUBPATH)
13− set(multi_value_keywords TARGETS)
14− cmake_parse_arguments(qmlplugin "" "" "${multi_value_keywords}" ${ARGN})
9+macro(export_qmlfiles PLUGIN PLUGIN_SUBPATH)
1510
1611 file(GLOB QMLFILES
1712 *.qml
@@ -25,17 +20,32 @@ macro(export_qmlplugin PLUGIN VERSION PLUGIN_SUBPATH)
2520 DEPENDS ${QMLFILES}
2621 )
2722
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+
2843 # create the plugin.qmltypes file
2944 add_custom_target(${PLUGIN}-qmltypes ALL
3045 COMMAND qmlplugindump -notrelocatable ${PLUGIN} ${VERSION} ${CMAKE_BINARY_DIR}/plugins > ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
3146 )
3247 add_dependencies(${PLUGIN}-qmltypes ${PLUGIN}-qmlfiles ${qmlplugin_TARGETS})
3348
34− # install the qmldir file.
35− install(FILES ${QMLFILES}
36− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
37− )
38−
3949 # install the qmltypes file.
4050 install(FILES ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
4151 DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
@@ -45,4 +55,4 @@ macro(export_qmlplugin PLUGIN VERSION PLUGIN_SUBPATH)
4555 install(TARGETS ${qmlplugin_TARGETS}
4656 DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
4757 )
48−endmacro(export_qmlplugin)
58+endmacro(export_qmlplugin)
cmake/modules/autopilot.cmake+7−4
@@ -1,7 +1,10 @@
11add_custom_target(autopilot)
22
3−function(declare_autopilot_test TEST_NAME WORKING_DIR)
4− add_custom_command(TARGET autopilot
5− COMMAND autopilot run ${TEST_NAME}
6− WORKING_DIRECTORY ${WORKING_DIR})
3+function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR)
4+ add_custom_target(autopilot-${TEST_NAME}
5+ COMMAND autopilot run ${TEST_SUITE}
6+ WORKING_DIRECTORY ${WORKING_DIR}
7+ )
8+
9+ add_dependencies(autopilot autopilot-${TEST_NAME})
710endfunction()
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+
1100unity8 (7.81.3+13.10.20130710ubuntu.unity.next-0ubuntu1) saucy; urgency=low
2101
3102 [ Michael Zanetti ]
debian/control+52−40
@@ -4,23 +4,27 @@ Priority: optional
44Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
55Build-Depends: cmake,
66 debhelper (>= 9),
7− libjson-perl,
87 libdee-qt5-dev (>= 3.0),
98 libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],
109 libgl1-mesa-dri,
1110 libgles2-mesa-dev[armhf],
1211 libhud-client2-dev,
12+ libjson-perl,
13+ libnm-glib-dev,
14+ libnm-util-dev,
1315 libpulse-dev,
16+ libqmenumodel-dev,
1417 libqt5v8-5-private-dev,
15− libunity-core-6.0-dev (<< 7.80),
1618 libunity-api-dev (>= 7.80.3),
19+ libunity-core-6.0-dev (<< 7.80),
1720 libunity-dev (>= 7.0.3),
21+ libunity-scopes-json-def-phone,
1822 libusermetricsoutput1-dev,
1923 libxcb1-dev,
2024 pkg-config,
21− python3,
2225 python (>= 2.7),
2326 python-setuptools,
27+ python3,
2428 qt5-default,
2529 qtbase5-dev,
2630 qtbase5-private-dev,
@@ -32,7 +36,6 @@ Build-Depends: cmake,
3236 qtdeclarative5-ubuntu-ui-toolkit-plugin,
3337 qtdeclarative5-xmllistmodel-plugin,
3438 ttf-ubuntu-font-family,
35− libunity-scopes-json-def-phone,
3639Standards-Version: 3.9.4
3740Homepage: http://launchpad.net/unity
3841# If you aren't a member of ~unity-team but need to upload
@@ -41,47 +44,56 @@ Homepage: http://launchpad.net/unity
4144Vcs-Bzr: https://code.launchpad.net/unity8
4245Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity8/trunk
4346
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+
4457Package: unity8
4558Architecture: any
46−Depends: ${misc:Depends},
47− ${shlibs:Depends},
48− unity8-private (= ${binary:Version}),
49− indicators-client (>= 0.6.1),
59+Depends: qmenumodel-qml,
5060 qtdeclarative5-dee-plugin,
5161 qtdeclarative5-ubuntu-ui-toolkit-plugin,
5262 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
53− unity-notifications-impl-1,
5463 qtdeclarative5-xmllistmodel-plugin,
64+ unity-launcher-impl-2,
65+ unity-notifications-impl-1,
5566 unity8-fake-env | qtubuntu-shell,
67+ unity8-private (= ${binary:Version}),
5668 unity8-private | unity-launcher-impl,
57− unity-launcher-impl-2,
58−Recommends: ${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),
69+ ${misc:Depends},
70+ ${shlibs:Depends},
71+Recommends: indicator-battery,
72+ indicator-messages,
73+ indicator-time,
74+ ${unity-default-masterscopes},
6475Description: Unity 8 shell
6576 The Unity 8 shell is the primary user interface for Ubuntu devices.
6677
67−Package: unity8-private
68−Architecture: any
69−Multi-Arch: same
70−Pre-Depends: ${misc:Pre-Depends}
71−Depends: ${misc:Depends},
78+Package: unity8-autopilot
79+Architecture: all
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}),
87+ ${misc:Depends},
88+ ${python:Depends},
7289 ${shlibs:Depends},
73−Provides: unity-launcher-impl,
74− unity-launcher-impl-2
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.
90+Description: Test package for Unity 8 shell
91+ Autopilot tests for the unity8 package
8092
8193Package: unity8-fake-env
8294Architecture: any
8395Multi-Arch: same
84−Pre-Depends: ${misc:Pre-Depends}
96+Pre-Depends: ${misc:Pre-Depends},
8597Depends: ${misc:Depends},
8698 ${shlibs:Depends},
8799Provides: qtubuntu-shell,
@@ -89,16 +101,16 @@ Description: Fake environment for running Unity 8 shell
89101 Provides fake implementations of some QML modules used by Unity 8 shell
90102 (e.g Ubuntu.Application) so that you can run it in a sandboxed environment.
91103
92−Package: unity8-autopilot
93−Architecture: all
104+Package: unity8-private
105+Architecture: any
106+Multi-Arch: same
107+Pre-Depends: ${misc:Pre-Depends},
94108Depends: ${misc:Depends},
95109 ${shlibs:Depends},
96− ${python:Depends},
97− libautopilot-qt,
98− libqt5test5,
99− libqt5widgets5,
100− python-evdev,
101− unity8 (>= ${source:Version}),
102− unity8-fake-env (>= ${source:Version}),
103−Description: Test package for Unity 8 shell
104− Autopilot tests for the unity8 package
110+Provides: unity-launcher-impl,
111+ unity-launcher-impl-2,
112+Description: Unity 8 private libs
113+ The Unity 8 shell is the primary user interface for Ubuntu devices.
114+ .
115+ This package contains the private libraries for QML and other components
116+ only used by the shell.
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
1313usr/share/unity8/Shell.qml
1414usr/share/unity8/SideStage
1515usr/share/unity8/graphics
16+usr/share/unity8/unity/indicators/*
main.cpp+5−8
@@ -18,10 +18,12 @@
1818 */
1919
2020// Qt
21+#include <QtQml>
2122#include <QtQuick/QQuickView>
2223#include <QtGui/QIcon>
2324#include <QtGui/QGuiApplication>
2425#include <QtQml/QQmlEngine>
26+#include <QtQml/QQmlContext>
2527#include <qpa/qplatformnativeinterface.h>
2628#include <QLibrary>
2729#include <libintl.h>
@@ -29,6 +31,7 @@
2931// local
3032#include "paths.h"
3133#include "MouseTouchAdaptor.h"
34+#include "ApplicationArguments.h"
3235
3336namespace {
3437
@@ -85,6 +88,7 @@ int main(int argc, char** argv)
8588 resolveIconTheme();
8689
8790 QStringList args = application.arguments();
91+ ApplicationArguments qmlArgs(args);
8892
8993 // The testability driver is only loaded by QApplication but not by QGuiApplication.
9094 // 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)
109113 view->setResizeMode(QQuickView::SizeRootObjectToView);
110114 view->setTitle("Qml Phone Shell");
111115 view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory()));
116+ view->rootContext()->setContextProperty("ApplicationArguments", &qmlArgs);
112117 if (args.contains(QLatin1String("-frameless"))) {
113118 view->setFlags(Qt::FramelessWindowHint);
114119 }
@@ -131,8 +136,6 @@ int main(int argc, char** argv)
131136 nativeInterface->setProperty("ubuntuSessionType", 1);
132137 view->setProperty("role", 2); // INDICATOR_ACTOR_ROLE
133138
134− QObject::connect(view->engine(), SIGNAL(quit()), qApp, SLOT(quit()));
135−
136139 QUrl source("Shell.qml");
137140 prependImportPaths(view->engine(), ::overrideImportPaths());
138141 appendImportPaths(view->engine(), ::fallbackImportPaths());
@@ -142,12 +145,6 @@ int main(int argc, char** argv)
142145 if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || args.contains(QLatin1String("-fullscreen"))) {
143146 view->showFullScreen();
144147 } 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− }
151148 view->show();
152149 }
153150
paths.h.in+15
@@ -23,6 +23,7 @@
2323// Qt
2424#include <QtCore/QCoreApplication>
2525#include <QtCore/QDir>
26+#include <QStandardPaths>
2627
2728inline bool isRunningInstalled() {
2829 static bool installed = (QCoreApplication::applicationDirPath() ==
@@ -65,6 +66,20 @@ inline QStringList fallbackImportPaths() {
6566 return paths;
6667}
6768
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+
6883inline QString sourceDirectory() {
6984 return QString("@CMAKE_SOURCE_DIR@/");
7085}
plugins/HudClient/CMakeLists.txt+2−1
@@ -38,5 +38,6 @@ target_link_libraries(HudClientQml
3838
3939qt5_use_modules(HudClientQml Qml)
4040
41−# export the qmldir and qmltypes files
41+# export the qmldir qmltypes and plugin files
42+export_qmlfiles(HudClient HudClient)
4243export_qmlplugin(HudClient 0.1 HudClient TARGETS HudClientQml)
plugins/LightDM/CMakeLists.txt+2−1
@@ -35,5 +35,6 @@ target_link_libraries(LightDM-qml
3535
3636qt5_use_modules(LightDM-qml Gui Qml)
3737
38−# export the qmldir and qmltypes files
38+# export the qmldir qmltypes and plugin files
39+export_qmlfiles(LightDM LightDM)
3940export_qmlplugin(LightDM 0.1 LightDM TARGETS LightDM-qml)
plugins/ListViewWithPageHeader/CMakeLists.txt+2−1
@@ -33,5 +33,6 @@ target_link_libraries(ListViewWithPageHeader-qml
3333
3434qt5_use_modules(ListViewWithPageHeader-qml Qml Quick)
3535
36−# export the qmldir and qmltypes files
36+# export the qmldir qmltypes and plugin files
37+export_qmlfiles(ListViewWithPageHeader ListViewWithPageHeader)
3738export_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
806806 Q_FOREACH(const QQuickChangeSet::Insert &insert, changeSet.inserts()) {
807807// qDebug() << "ListViewWithPageHeader::onModelUpdated Insert" << insert.index << insert.count;
808808 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();
810810 if (insertingInValidIndexes || firstItemWithViewOnTop)
811811 {
812812 // 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)
2323# So that Foo.cpp can #include "Foo.moc"
2424include_directories(${CMAKE_CURRENT_BINARY_DIR})
2525
26−# export the qmldir and qmltypes files
26+# export the qmldir qmltypes and plugin files
27+export_qmlfiles(Ubuntu.Gestures Ubuntu/Gestures)
2728export_qmlplugin(Ubuntu.Gestures 0.1 Ubuntu/Gestures TARGETS UbuntuGestureQml)
plugins/Unity/CMakeLists.txt+4−1
@@ -1,6 +1,8 @@
11# export_qmlplugin macro
22include(Plugins)
33
4+add_subdirectory(Indicators)
5+
46# Dependencies
57include(FindPkgConfig)
68pkg_check_modules(QTDEE REQUIRED libdee-qt5)
@@ -46,7 +48,8 @@ target_link_libraries(Unity-qml
4648
4749qt5_use_modules(Unity-qml Qml)
4850
49−# export the qmldir and qmltypes files
51+# export the qmldir qmltypes and plugin files
52+export_qmlfiles(Unity Unity)
5053export_qmlplugin(Unity 0.1 Unity TARGETS Unity-qml)
5154
5255add_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 @@
11/*
2− * Copyright (C) 2012, 2013 Canonical, Ltd.
2+ * Copyright (C) 2012 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -12,19 +12,20 @@
1212 *
1313 * You should have received a copy of the GNU General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
1517 */
1618
17−#include "fake_chewie_plugin.h"
18−#include "fake_pluginmodel.h"
19+// Qt
20+#include <QtQml>
1921
20−#include <qqml.h>
22+// self
23+#include "plugin.h"
2124
22−void FakeChewieQmlPlugin::registerTypes(const char *uri)
23−{
24−// #ifndef GLIB_VERSION_2_36
25−// g_type_init();
26−// #endif
25+// local
26+#include "networkagent.h"
2727
28− qmlRegisterUncreatableType<WidgetsMap>(uri, 0, 1, "WidgetsMap", "WidgetsMap must be created by PluginModel");
29− qmlRegisterType<PluginModel>(uri, 0, 1, "PluginModel");
28+void IndicatorsNetworkPlugin::registerTypes(const char *uri)
29+{
30+ qmlRegisterType<NetworkAgent>(uri, 0, 1, "NetworkAgent");
3031}
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 @@
1515 *
1616 * Authors:
1717 * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ * Nick Dedekind <nick.dedekind@canonical.com>
1819 */
1920
20−#ifndef PLUGINMODEL_H
21−#define PLUGINMODEL_H
21+#ifndef INDICATORSMODEL_H
22+#define INDICATORSMODEL_H
23+
24+#include "indicator.h"
25+#include "unityindicatorsglobal.h"
2226
2327#include <QAbstractListModel>
2428#include <QQmlEngine>
2529
30+class IndicatorsManager;
2631
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
5233{
5334 Q_OBJECT
54− Q_PROPERTY(WidgetsMap* widgetsMap READ widgetsMap NOTIFY widgetsMapChanged)
35+ Q_ENUMS(Roles)
5536 Q_PROPERTY(int count READ count NOTIFY countChanged)
37+ Q_PROPERTY(QVariant indicatorData READ indicatorData WRITE setIndicatorData NOTIFY indicatorDataChanged)
5638
5739public:
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();
7040
71− WidgetsMap* widgetsMap() const;
41+ IndicatorsModel(QObject *parent=0);
42+ ~IndicatorsModel();
7243
7344 Q_INVOKABLE void load();
7445 Q_INVOKABLE void unload();
7546
76− Q_INVOKABLE QVariantMap get(int row) const;
47+ Q_INVOKABLE QVariant data(int row, int role = Qt::DisplayRole) const;
7748
7849 /* QAbstractItemModel */
7950 QHash<int, QByteArray> roleNames() const;
@@ -82,13 +53,30 @@ public:
8253 QModelIndex parent (const QModelIndex &index) const;
8354 int rowCount(const QModelIndex &parent = QModelIndex()) const;
8455
56+ void setIndicatorData(const QVariant& data);
57+ QVariant indicatorData() const;
58+
8559Q_SIGNALS:
86− void widgetsMapChanged(WidgetsMap *widgetsMap);
8760 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);
8868
8969private:
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);
9177 int count() const;
78+ QVariant indicatorData(const Indicator::Ptr& indicator, int role) const;
79+ static QVariant defaultData(Indicator::Ptr indicator, int role);
9280};
9381
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 @@
11/*
2− * Copyright (C) 2012, 2013 Canonical, Ltd.
2+ * Copyright (C) 2012 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -12,14 +12,16 @@
1212 *
1313 * You should have received a copy of the GNU General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
1517 */
1618
17−#ifndef PLUGIN_H
18−#define PLUGIN_H
19+#ifndef INDICATORS_PLUGIN_H
20+#define INDICATORS_PLUGIN_H
1921
20−#include <QQmlExtensionPlugin>
22+#include <QtQml/QQmlExtensionPlugin>
2123
22−class FakeChewieQmlPlugin : public QQmlExtensionPlugin
24+class IndicatorsPlugin : public QQmlExtensionPlugin
2325{
2426 Q_OBJECT
2527 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
@@ -27,5 +29,4 @@ public:
2729 void registerTypes(const char *uri);
2830};
2931
30−
31−#endif
32+#endif // INDICATORS_PLUGIN_H
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
21include(FindPkgConfig)
3−pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher)
2+pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=2)
43
54include_directories(
65 ${CMAKE_CURRENT_SOURCE_DIR}
@@ -25,4 +24,5 @@ add_library(UnityLauncher-qml MODULE
2524qt5_use_modules(UnityLauncher-qml Qml)
2625
2726# export the qmldir and qmltypes files
27+export_qmlfiles(Unity.Launcher Unity/Launcher)
2828export_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):
3737 QLatin1String("gmail-webapp.desktop") <<
3838 QLatin1String("ubuntu-weather-app.desktop") <<
3939 QLatin1String("notes-app.desktop") <<
40− QLatin1String("ubuntu-calendar-app.desktop");
40+ QLatin1String("calendar-app.desktop");
4141
4242 // TODO: get stuff from desktop files instead this hardcoded map
4343 m_displayNameMap.insert("phone-app.desktop", "Phone");
@@ -49,7 +49,7 @@ LauncherBackend::LauncherBackend(QObject *parent):
4949 m_displayNameMap.insert("gmail-webapp.desktop", "GMail");
5050 m_displayNameMap.insert("ubuntu-weather-app.desktop", "Weather");
5151 m_displayNameMap.insert("notes-app.desktop", "Notes");
52− m_displayNameMap.insert("ubuntu-calendar-app.desktop", "Calendar");
52+ m_displayNameMap.insert("calendar-app.desktop", "Calendar");
5353
5454 // TODO: get stuff from desktop files instead this hardcoded map
5555 m_iconMap.insert("phone-app.desktop", "phone-app");
@@ -61,7 +61,7 @@ LauncherBackend::LauncherBackend(QObject *parent):
6161 m_iconMap.insert("gmail-webapp.desktop", "gmail");
6262 m_iconMap.insert("ubuntu-weather-app.desktop", "weather");
6363 m_iconMap.insert("notes-app.desktop", "notepad");
64− m_iconMap.insert("ubuntu-calendar-app.desktop", "calendar");
64+ m_iconMap.insert("calendar-app.desktop", "calendar");
6565
6666}
6767
plugins/Unity/Launcher/qmldir+1
@@ -1,2 +1,3 @@
11module Unity.Launcher
22plugin UnityLauncher-qml
3+typeinfo plugin.qmltypes
plugins/Utils/CMakeLists.txt+3−1
@@ -5,6 +5,7 @@ include_directories(
55)
66
77set(QMLPLUGIN_SRC
8+ applicationpaths.h
89 qlimitproxymodelqml.cpp
910 qsortfilterproxymodelqml.cpp
1011 ubuntuwindow.cpp
@@ -22,5 +23,6 @@ set_target_properties(Utils-qml PROPERTIES COMPILE_FLAGS -fvisibility=default)
2223
2324qt5_use_modules(Utils-qml Qml Quick)
2425
25−# export the qmldir and qmltypes files
26+# export the qmldir qmltypes and plugin files
27+export_qmlfiles(Utils Utils)
2628export_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 @@
2424#include "plugin.h"
2525
2626// local
27+#include "applicationpaths.h"
2728#include "qlimitproxymodelqml.h"
2829#include "qsortfilterproxymodelqml.h"
2930#include "ubuntuwindow.h"
3031
32+static QObject* applicationsPathsSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
33+ Q_UNUSED(engine);
34+ Q_UNUSED(scriptEngine);
35+ return new ApplicationPaths;
36+}
37+
3138void UtilsPlugin::registerTypes(const char *uri)
3239{
3340 Q_ASSERT(uri == QLatin1String("Utils"));
@@ -35,4 +42,5 @@ void UtilsPlugin::registerTypes(const char *uri)
3542 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
3643 qmlRegisterType<QSortFilterProxyModelQML>(uri, 0, 1, "SortFilterProxyModel");
3744 qmlRegisterExtendedType<QQuickWindow, UbuntuWindow>(uri, 0, 1, "Window");
45+ qmlRegisterSingletonType<ApplicationPaths>(uri, 0, 1, "ApplicationPaths", applicationsPathsSingleton);
3846}
po/ar.po+3−27
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: Ibrahim Saed <ibraheem5000@gmail.com>\n"
1313"Language-Team: Arabic <ar@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,27 +218,3 @@ msgstr "عذراً، لا يوجد ما يطابق بحثك."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-26 23:48+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Azerbaijani <az@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Bağışlayın, amma axtarışınıza heç bir nəticə uyğun gəlmir."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: Miroslav E. Hadzhiev (Хаджиев) "
1313"<miroslav.hadzhiev@gmail.com>\n"
1414"Language-Team: Bulgarian <bg@li.org>\n"
1515"MIME-Version: 1.0\n"
1616"Content-Type: text/plain; charset=UTF-8\n"
1717"Content-Transfer-Encoding: 8bit\n"
18−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
19−"X-Generator: Launchpad (build 16681)\n"
18+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
19+"X-Generator: Launchpad (build 16696)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -219,15 +219,3 @@ msgstr "Съжаляваме, няма нищо, което да отговар
219219#, qt-format
220220msgid "Please enter %1"
221221msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 00:24+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Catalan <ca@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,15 +218,3 @@ msgstr "No hi ha res que coincideixi amb la cerca"
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-29 12:53+0000\n"
12−"Last-Translator: Phillip Sz <Unknown>\n"
11+"PO-Revision-Date: 2013-06-27 00:37+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: German <de@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-30 07:12+0000\n"
18−"X-Generator: Launchpad (build 16692)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -217,28 +217,4 @@ msgstr "Entschuldigung, es wurden keine Treffer erzielt."
217217#: Shell.qml:383
218218#, qt-format
219219msgid "Please enter %1"
220−msgstr "Bitte geben Sie %1 ein"
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"
220+msgstr ""
po/el.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 00:53+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Greek <el@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Λυπούμαστε, δεν υπάρχει τίποτα που να τ
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Πρόσωπα"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Αρχική οθόνη"
po/en_AU.po+3−27
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: Jackson Doak <Doak.jackson@gmail.com>\n"
1313"Language-Team: English (Australia) <en_AU@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,27 +218,3 @@ msgstr "Sorry, there is nothing that matches your search."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-27 00:22+0000\n"
12−"Last-Translator: Andi Chandler <Unknown>\n"
11+"PO-Revision-Date: 2013-06-27 08:53+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,27 +218,3 @@ msgstr "Sorry, there is nothing that matches your search."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr "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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Esperanto <eo@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
po/es.po+1−1
@@ -14,7 +14,7 @@ msgstr ""
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"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"
1818"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
po/fi.po+4−25
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-10 16:19+0000\n"
12−"Last-Translator: Jiri Grönroos <Unknown>\n"
11+"PO-Revision-Date: 2013-06-27 02:43+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Finnish <fi@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,24 +218,3 @@ msgstr "Hakuun täsmääviä tuloksia ei löydy."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 02:57+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Faroese <fo@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Tíanverri er tað einki sum hóskar til tína leiting."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-26 15:11+0000\n"
12−"Last-Translator: Anne <anneonyme017@gmail.com>\n"
11+"PO-Revision-Date: 2013-06-27 03:21+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: French <fr@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
22−msgstr "Téléphone"
22+msgstr ""
2323
2424#: Applications/applications.js:29
2525msgid "Camera"
26−msgstr "Appareil photo"
26+msgstr ""
2727
2828#: Applications/applications.js:35
2929msgid "Gallery"
30−msgstr "Galerie"
30+msgstr ""
3131
3232#: Applications/applications.js:40
3333msgid "Facebook"
34−msgstr "Facebook"
34+msgstr ""
3535
3636#: Applications/applications.js:46
3737msgid "Browser"
38−msgstr "Navigateur"
38+msgstr ""
3939
4040#: Applications/applications.js:51
4141msgid "Twitter"
42−msgstr "Twitter"
42+msgstr ""
4343
4444#: Applications/applications.js:57
4545msgid "GMail"
46−msgstr "GMail"
46+msgstr ""
4747
4848#: Applications/applications.js:62
4949msgid "Weather"
50−msgstr "Météo"
50+msgstr ""
5151
5252#: Applications/applications.js:68
5353msgid "Notepad"
54−msgstr "Bloc-notes"
54+msgstr ""
5555
5656#: Applications/applications.js:74
5757msgid "Calendar"
58−msgstr "Agenda"
58+msgstr ""
5959
6060#: Applications/applications.js:80
6161msgid "Media Player"
62−msgstr "Lecteur multimédia"
62+msgstr ""
6363
6464#: Applications/applications.js:86
6565msgid "Evernote"
66−msgstr "Evernote"
66+msgstr ""
6767
6868#: Applications/applications.js:91
6969msgid "Map"
@@ -71,27 +71,27 @@ msgstr ""
7171
7272#: Applications/applications.js:96
7373msgid "Pinterest"
74−msgstr "Pinterest"
74+msgstr ""
7575
7676#: Applications/applications.js:101
7777msgid "SoundCloud"
78−msgstr "SoundCloud"
78+msgstr ""
7979
8080#: Applications/applications.js:106
8181msgid "Wikipedia"
82−msgstr "Wikipédia"
82+msgstr ""
8383
8484#: Applications/applications.js:111
8585msgid "YouTube"
86−msgstr "YouTube"
86+msgstr ""
8787
8888#: Components/PageHeader.qml:300
8989msgid "Recent searches"
90−msgstr "Recherches récentes"
90+msgstr ""
9191
9292#: Dash/DashApps.qml:65
9393msgid "Running apps"
94−msgstr "Applications en cours d’exécution"
94+msgstr ""
9595
9696#: Dash/DashApps.qml:68
9797msgid "Frequently used"
@@ -99,7 +99,7 @@ msgstr ""
9999
100100#: Dash/DashApps.qml:71
101101msgid "Installed"
102−msgstr "Installées"
102+msgstr ""
103103
104104#: Dash/DashApps.qml:74
105105msgid "Available for download"
@@ -111,19 +111,19 @@ msgstr "Applications"
111111
112112#: Dash/DashHome.qml:40
113113msgid "Frequent Apps"
114−msgstr "Applications fréquemment utilisées"
114+msgstr ""
115115
116116#: Dash/DashHome.qml:43
117117msgid "Recent Music"
118−msgstr "Musique récente"
118+msgstr ""
119119
120120#: Dash/DashHome.qml:46
121121msgid "Videos Popular Online"
122−msgstr "Vidéos populaires en ligne"
122+msgstr ""
123123
124124#: Dash/DashHome.qml:175
125125msgid "Home"
126−msgstr "Accueil"
126+msgstr ""
127127
128128#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
129129msgid "Featured"
@@ -135,7 +135,7 @@ msgstr ""
135135
136136#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
137137msgid "New Releases"
138−msgstr "Nouveautés"
138+msgstr ""
139139
140140#: Dash/DashMusic.qml:30
141141msgid "Top Charting"
@@ -155,15 +155,15 @@ msgstr "Vidéos"
155155
156156#: Dash/Video/VideoPreview.qml:98
157157msgid "Directed by:"
158−msgstr "Réalisé par :"
158+msgstr ""
159159
160160#: Dash/Video/VideoPreview.qml:121
161161msgid "Starring:"
162−msgstr "Acteurs :"
162+msgstr ""
163163
164164#: Dash/Video/VideoPreview.qml:144
165165msgid "Author:"
166−msgstr "Auteur :"
166+msgstr ""
167167
168168#: Greeter/Lockscreen.qml:133
169169msgid "Emergency call"
@@ -172,27 +172,27 @@ msgstr ""
172172#: Greeter/PassphraseLockscreen.qml:59
173173#, qt-format
174174msgid "Hello %1"
175−msgstr "Bonjour %1"
175+msgstr ""
176176
177177#: Greeter/PassphraseLockscreen.qml:59
178178msgid "Hello"
179−msgstr "Bonjour"
179+msgstr ""
180180
181181#: Hud/HudParametrizedActionsPage.qml:132
182182msgid "Confirm"
183−msgstr "Confirmer"
183+msgstr ""
184184
185185#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
186186msgid "Type or say a command"
187−msgstr "Entrez ou dictez une commande"
187+msgstr ""
188188
189189#: Hud/Hud.qml:84
190190msgid "Loading. Please Wait..."
191−msgstr "Chargement. Veuillez patienter..."
191+msgstr ""
192192
193193#: Hud/Hud.qml:89
194194msgid "Speak Now..."
195−msgstr "Parlez maintenant..."
195+msgstr ""
196196
197197#: Hud/Hud.qml:94
198198msgid "Speaking..."
@@ -204,38 +204,17 @@ msgstr ""
204204
205205#: Panel/Menus/Overview/FlightModeWidget.qml:42
206206msgid "Flight mode"
207−msgstr "Mode avion"
207+msgstr ""
208208
209209#: Panel/SearchIndicator.qml:26
210210msgid "Search"
211−msgstr "Rechercher"
211+msgstr ""
212212
213213#: plugins/Unity/scope.cpp:268
214214msgid "Sorry, there is nothing that matches your search."
215−msgstr "Désolé, aucun résultat ne correspond à votre recherche."
215+msgstr ""
216216
217217#: Shell.qml:383
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 03:38+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Galician <gl@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,15 +218,3 @@ msgstr "Sentímolo, non hai nada que coincida con esta busca."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 03:54+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Hebrew <he@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "שום דבר אינו תואם לחיפוש שלך, עמך הסליחה
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "אנשים"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "מסך הבית"
po/hr.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 04:14+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Croatian <hr@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Nažalost, ne postoji ništa što odgovara vašoj pretrazi."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 04:28+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Hungarian <hu@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Elnézést, nincs találat a keresésre."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: iAbaS <sosabazyan@yandex.ru>\n"
1313"Language-Team: Armenian <hy@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,15 +218,3 @@ msgstr "Կներերք, բայց Ձեր հարցումով ոչինչ չկար"
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Indonesian <id@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
po/it.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 05:14+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Italian <it@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Nessun risultato corrispondente alla ricerca."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Japanese <ja@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
po/kn.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 05:43+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Kannada <kn@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "ಕ್ಷಮಿಸಿ ನಿಮ್ಮ ಶೋಧನೆಗೆ ಸರಿಯ
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "ಜನರು"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "ಹೋಮ್ ಸ್ಕ್ರೀನ್"
po/ko.po+4−4
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 05:59+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Korean <ko@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
po/ky.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 06:17+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Kirghiz <ky@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Тилекке каршы, сиздин издөөңүзгө эч нер
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Адамдар"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Башкы экран"
po/lv.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 06:31+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Latvian <lv@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Diemžēl nekas neatbilst jūsu meklētajam."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 06:47+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Burmese <my@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,6 +218,3 @@ msgstr "ဆောရီး၊ သင်၏ရှာဖွေမူနှင့
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "လူ"
po/nb.po+3−9
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: Joakim Langvand <jlangvand@gmail.com>\n"
1313"Language-Team: Norwegian Bokmal <nb@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Søket ga ingen treff."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 07:19+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Dutch <nl@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Er is helaas niets dat met uw zoekopdracht overeenkomt."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:43+0000\n"
12−"Last-Translator: Piotr Merski <Unknown>\n"
11+"PO-Revision-Date: 2013-06-27 08:52+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Polish <pl@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -167,16 +167,16 @@ msgstr "Autor:"
167167
168168#: Greeter/Lockscreen.qml:133
169169msgid "Emergency call"
170−msgstr ""
170+msgstr "Telefon alarmowy"
171171
172172#: Greeter/PassphraseLockscreen.qml:59
173173#, qt-format
174174msgid "Hello %1"
175−msgstr ""
175+msgstr "Witaj %1"
176176
177177#: Greeter/PassphraseLockscreen.qml:59
178178msgid "Hello"
179−msgstr ""
179+msgstr "Witaj"
180180
181181#: Hud/HudParametrizedActionsPage.qml:132
182182msgid "Confirm"
@@ -217,28 +217,4 @@ msgstr "Nie znaleziono pasujących wyników."
217217#: Shell.qml:383
218218#, qt-format
219219msgid "Please enter %1"
220−msgstr ""
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"
220+msgstr "Wprowadź %1"
po/pt_BR.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 07:39+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Desculpe, não há nada que corresponda à sua pesquisa."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 07:53+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Romanian <ro@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -219,9 +219,3 @@ msgstr ""
219219#, qt-format
220220msgid "Please enter %1"
221221msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-21 10:08+0000\n"
12−"Last-Translator: Andrey Dedikov <iamawesome.ndr@gmail.com>\n"
11+"PO-Revision-Date: 2013-06-28 06:40+0000\n"
12+"Last-Translator: Eugene Marshal <Unknown>\n"
1313"Language-Team: Russian <ru@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
22−msgstr ""
22+msgstr "Телефон"
2323
2424#: Applications/applications.js:29
2525msgid "Camera"
26−msgstr ""
26+msgstr "Камера"
2727
2828#: Applications/applications.js:35
2929msgid "Gallery"
30−msgstr ""
30+msgstr "Галерея"
3131
3232#: Applications/applications.js:40
3333msgid "Facebook"
34−msgstr ""
34+msgstr "Facebook"
3535
3636#: Applications/applications.js:46
3737msgid "Browser"
38−msgstr ""
38+msgstr "Обозреватель"
3939
4040#: Applications/applications.js:51
4141msgid "Twitter"
42−msgstr ""
42+msgstr "Twitter"
4343
4444#: Applications/applications.js:57
4545msgid "GMail"
46−msgstr ""
46+msgstr "GMail"
4747
4848#: Applications/applications.js:62
4949msgid "Weather"
50−msgstr ""
50+msgstr "Погода"
5151
5252#: Applications/applications.js:68
5353msgid "Notepad"
54−msgstr ""
54+msgstr "Блокнот"
5555
5656#: Applications/applications.js:74
5757msgid "Calendar"
58−msgstr ""
58+msgstr "Календарь"
5959
6060#: Applications/applications.js:80
6161msgid "Media Player"
62−msgstr ""
62+msgstr "Медиапроигрыватель"
6363
6464#: Applications/applications.js:86
6565msgid "Evernote"
@@ -67,7 +67,7 @@ msgstr "Evernote"
6767
6868#: Applications/applications.js:91
6969msgid "Map"
70−msgstr ""
70+msgstr "Карта"
7171
7272#: Applications/applications.js:96
7373msgid "Pinterest"
@@ -79,11 +79,11 @@ msgstr "SoundCloud"
7979
8080#: Applications/applications.js:106
8181msgid "Wikipedia"
82−msgstr ""
82+msgstr "Википедия"
8383
8484#: Applications/applications.js:111
8585msgid "YouTube"
86−msgstr ""
86+msgstr "YouTube"
8787
8888#: Components/PageHeader.qml:300
8989msgid "Recent searches"
@@ -131,7 +131,7 @@ msgstr ""
131131
132132#: Dash/DashMusic.qml:28 Dash/DashVideos.qml:29
133133msgid "Recent"
134−msgstr ""
134+msgstr "Недавние"
135135
136136#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
137137msgid "New Releases"
@@ -163,11 +163,11 @@ msgstr "В главных ролях"
163163
164164#: Dash/Video/VideoPreview.qml:144
165165msgid "Author:"
166−msgstr ""
166+msgstr "Автор:"
167167
168168#: Greeter/Lockscreen.qml:133
169169msgid "Emergency call"
170−msgstr ""
170+msgstr "Экстренный вызов"
171171
172172#: Greeter/PassphraseLockscreen.qml:59
173173#, qt-format
@@ -217,19 +217,4 @@ msgstr "Извините, поиск не дал результатов."
217217#: Shell.qml:383
218218#, qt-format
219219msgid "Please enter %1"
220−msgstr ""
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 "Новые контакты"
220+msgstr "Пожалуйста, введите %1"
po/si.po+3−3
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Sinhalese <si@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
po/sl.po+1−1
@@ -14,7 +14,7 @@ msgstr ""
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"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"
1818"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
po/sr.po+4−10
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 09:19+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Serbian <sr@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,9 +218,3 @@ msgstr "Нажалост, претрага није наишла на икакв
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
221−
222−#~ msgid "People"
223−#~ msgstr "Људи"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Почетни екран"
po/sv.po+3−3
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Swedish <sv@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
po/te.po+4−4
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 09:57+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Telugu <te@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
po/tr.po+3−24
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: Adar Cem EREN <adarcemeren34@gmail.com>\n"
1313"Language-Team: Turkish <tr@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,24 +218,3 @@ msgstr "Üzgünüz, aramanızla eşleşen hiçbir şey yok."
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-28 04:36+0000\n"
12−"Last-Translator: Gheyret T.Kenji <Unknown>\n"
11+"PO-Revision-Date: 2013-06-27 11:02+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Uyghur <ug@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-30 07:12+0000\n"
18−"X-Generator: Launchpad (build 16692)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -172,7 +172,7 @@ msgstr "جىددىي تېلېفون"
172172#: Greeter/PassphraseLockscreen.qml:59
173173#, qt-format
174174msgid "Hello %1"
175−msgstr "سالام %1"
175+msgstr ""
176176
177177#: Greeter/PassphraseLockscreen.qml:59
178178msgid "Hello"
@@ -217,25 +217,4 @@ msgstr "كەچۈرۈڭ، ئىزدىگىنىڭىزگە ماس نەتىجە تېپ
217217#: Shell.qml:383
218218#, qt-format
219219msgid "Please enter %1"
220−msgstr "%1 نى كىرگۈزۈڭ"
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 "يېڭى ئالاقەداشلار"
220+msgstr ""
po/uk.po+4−28
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-29 14:27+0000\n"
12−"Last-Translator: Roman Koshkin <mar2008m@rambler.ru>\n"
11+"PO-Revision-Date: 2013-07-21 05:47+0000\n"
12+"Last-Translator: Ярослав Смук <Smuk.Slavko@yandex.ua>\n"
1313"Language-Team: Ukrainian <uk@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-30 07:12+0000\n"
18−"X-Generator: Launchpad (build 16692)\n"
17+"X-Launchpad-Export-Date: 2013-07-22 06:19+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,27 +218,3 @@ msgstr "Вибачте, для вказаних вами ключових слі
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr "Будь ласка, введіть %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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: Anthony Wong <anthony.wong@canonical.com>\n"
1313"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,27 +218,3 @@ msgstr "对不起,没有找到您想要的结果。"
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
11+"PO-Revision-Date: 2013-06-27 10:24+0000\n"
12+"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
17+"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Generator: Launchpad (build 16696)\n"
1919
2020#: Applications/applications.js:23
2121msgid "Phone"
@@ -218,15 +218,3 @@ msgstr "很抱歉,找不到符合您想搜尋的結果。"
218218#, qt-format
219219msgid "Please enter %1"
220220msgstr ""
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
4040done
4141
4242if $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
4444 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single
4545fi
4646
4747if $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
4949 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single-pin
5050fi
5151
5252if $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
5454 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single-passphrase
5555fi
5656
run_on_device+4−22
@@ -33,7 +33,7 @@ usage() {
3333}
3434
3535exec_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 \"$@\"
3737}
3838
3939exec_with_adb() {
@@ -65,11 +65,9 @@ setup_adb_forwarding() {
6565}
6666
6767install_dependencies() {
68+ exec_with_adb apt-get update
6869 exec_with_adb apt-get -y install openssh-server
6970 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
7371}
7472
7573sync_code() {
@@ -85,17 +83,6 @@ build() {
8583}
8684
8785run() {
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
9986 ARGS="--nomousetouch"
10087 if $GDB; then
10188 ARGS="$ARGS --gdb"
@@ -107,14 +94,9 @@ run() {
10794 ARGS="$ARGS -k"
10895 fi
10996
97+ exec_with_ssh "stop unity8"
11098 exec_with_ssh "cd $CODE_DIR/ && ./run $ARGS -- $RUN_OPTIONS"
111−
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
99+ exec_with_ssh "start unity8"
118100}
119101
120102set -- `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
1515from autopilot.platform import model
1616from testtools.matchers import Equals
1717
18−from unity8.emulators.main_window import MainWindow
18+from unity8.shell.emulators.main_window import MainWindow
1919
2020class FormFactors(object):
2121 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 @@
1010from testtools.matchers import Equals
1111from autopilot.matchers import Eventually
1212
13−from unity8.tests import ShellTestCase
13+from unity8.shell.tests import ShellTestCase
1414
1515class TestBig(ShellTestCase):
1616 def setUp(self):
tests/autopilot/unity8/tests/testhud.py → tests/autopilot/unity8/shell/tests/testhud.pyrenamed+2−2
@@ -25,8 +25,8 @@
2525
2626from __future__ import absolute_import
2727
28−from unity8.tests import ShellTestCase, FormFactors
29−from unity8.tests.helpers import TestShellHelpers
28+from unity8.shell.tests import ShellTestCase, FormFactors
29+from unity8.shell.tests.helpers import TestShellHelpers
3030
3131from autopilot.input import Mouse, Touch, Pointer
3232from 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 @@
2525
2626from __future__ import absolute_import
2727
28−from unity8.tests import ShellTestCase, FormFactors
29−from unity8.tests.helpers import TestShellHelpers
28+from unity8.shell.tests import ShellTestCase, FormFactors
29+from unity8.shell.tests.helpers import TestShellHelpers
3030
3131from autopilot.input import Mouse, Touch, Pointer
3232from 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()
5454 QSharedPointer<InfographicData> data(
5555 new InfographicData("<b>52km</b> travelled", yellowTheme, firstMonth,
5656 orangeTheme, secondMonth, this));
57− m_fakeData.insert("guest", data);
57+ m_fakeData.insert("phablet", data);
5858 }
5959
6060 {
@@ -69,7 +69,7 @@ void InfographicModelPrivate::generateFakeData()
6969 QSharedPointer<InfographicData> data(
7070 new InfographicData("<b>33</b> messages today", pinkTheme,
7171 firstMonth, orangeTheme, secondMonth, this));
72− m_fakeData.insert("guest", data);
72+ m_fakeData.insert("phablet", data);
7373 }
7474
7575 {
@@ -84,7 +84,7 @@ void InfographicModelPrivate::generateFakeData()
8484 QSharedPointer<InfographicData> data(
8585 new InfographicData("<b>69</b> minutes talk time", darkPurpleTheme,
8686 firstMonth, redTheme, secondMonth, this));
87− m_fakeData.insert("guest", data);
87+ m_fakeData.insert("phablet", data);
8888 }
8989}
9090
tests/mocks/LightDM/demo/UsersModelPrivate.cpp+1−1
@@ -26,7 +26,7 @@ UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
2626{
2727 entries =
2828 {
29− { "single", "Guest", 0, 0, false, false, 0, 0 },
29+ { "phablet", "Guest", 0, 0, false, false, 0, 0 },
3030 };
3131}
3232
tests/mocks/Ubuntu/Application/ApplicationManager.cpp+2−2
@@ -321,10 +321,10 @@ void ApplicationManager::buildListOfAvailableApplications()
321321 m_availableApplications.append(application);
322322
323323 application = new ApplicationInfo(this);
324− application->setDesktopFile("/usr/share/applications/ubuntu-calendar-app.desktop");
324+ application->setDesktopFile("/usr/share/applications/calendar-app.desktop");
325325 application->setName("Calendar");
326326 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");
328328 application->setStage(ApplicationInfo::SideStage);
329329 application->setHandle(nextHandle++);
330330 m_availableApplications.append(application);
tests/mocks/Ubuntu/CMakeLists.txt−1
@@ -1,2 +1 @@
11add_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 @@
11set(CMAKE_AUTOMOC ON)
22
3+add_subdirectory(Indicators)
4+
35include(FindPkgConfig)
46find_package(Qt5Core REQUIRED)
57find_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 @@
1515 */
1616
1717import QtQuick 2.0
18+import Unity.Indicators 0.1 as Indicators
1819
19−FakeMenuPlugin {
20+Indicators.FakeMenuPage {
2021 id: menu_plugin1
21− objectName: "menu_plugin1"
22+ objectName: "menu_page1"
2223
2324 Rectangle {
2425 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 @@
1515 */
1616
1717import QtQuick 2.0
18+import Unity.Indicators 0.1 as Indicators
1819
19−FakeMenuPlugin {
20+Indicators.FakeMenuPage {
2021 id: menu_plugin2
21− objectName: "menu_plugin2"
22+ objectName: "menu_page2"
2223
2324 Rectangle {
2425 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 @@
1515 */
1616
1717import QtQuick 2.0
18+import Unity.Indicators 0.1 as Indicators
1819
19−FakeMenuPlugin {
20+Indicators.FakeMenuPage {
2021 id: menu_plugin3
21− objectName: "menu_plugin3"
22+ objectName: "menu_page3"
2223
2324 Rectangle {
2425 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 @@
1515 */
1616
1717import QtQuick 2.0
18+import Unity.Indicators 0.1 as Indicators
1819
19−FakeMenuPlugin {
20+Indicators.FakeMenuPage {
2021 id: menu_plugin4
21− objectName: "menu_plugin4"
22+ objectName: "menu_page4"
2223
2324 Rectangle {
2425 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 @@
1515 */
1616
1717import QtQuick 2.0
18+import Unity.Indicators 0.1 as Indicators
1819
19−FakeMenuPlugin {
20+Indicators.FakeMenuPage {
2021 id: menu_plugin5
21− objectName: "menu_plugin5"
22+ objectName: "menu_page5"
2223
2324 Rectangle {
2425 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−
31include(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)
83
94include_directories(
105 ${CMAKE_CURRENT_SOURCE_DIR}
tests/mocks/Unity/Launcher/MockLauncherModel.cpp+1−1
@@ -40,7 +40,7 @@ MockLauncherModel::MockLauncherModel(QObject* parent): LauncherModelInterface(pa
4040 m_list.append(item);
4141 item = new MockLauncherItem("notes-app", "/usr/share/applications/notes-app.desktop", "Notepad", "notepad");
4242 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");
4444 m_list.append(item);
4545}
4646
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+19
@@ -991,6 +991,25 @@ private Q_SLOTS:
991991 QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
992992 }
993993
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+
9941013 void testRemoveItemsAtTop()
9951014 {
9961015 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:
11211121 QCOMPARE(lvwph->m_topSectionItem->y(), -23.);
11221122 }
11231123
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+
11241143 void testRemoveItemsAtTop()
11251144 {
11261145 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+
13pkg_check_modules(UNITYCORE REQUIRED unity-core-6.0)
24pkg_check_modules(LIBUNITYPROTO REQUIRED unity-protocol-private)
35
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()
165165}
166166
167167QTEST_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
6161add_qml_test(Panel IndicatorRow)
6262add_qml_test(Panel Indicators IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
6363add_qml_test(Panel MenuContent)
64−add_qml_test(Panel Overview)
6564add_qml_test(Panel Panel IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
6665add_qml_test(Panel SearchIndicator)
67−add_qml_test(Panel/Menus IndicatorMenuWindow IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS})
6866add_qml_test(SideStage SideStage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
6967 ${CMAKE_BINARY_DIR}/tests/mocks
7068 ${CMAKE_BINARY_DIR}/plugins)
tests/qmltests/Components/tst_OpenEffect.qml+1−1
@@ -28,7 +28,7 @@ TestCase {
2828 function test_openeffect_shadereffectsource() {
2929 compare(openEffect1.source.hideSource, true, "OpenEffect ShaderEffectSource is incorrect")
3030 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")
3232 compare(openEffect1.source.sourceRect.x, 0, "OpenEffect ShaderEffectSource is incorrect")
3333 compare(openEffect1.source.sourceRect.y, 0, "OpenEffect ShaderEffectSource is incorrect")
3434 compare(openEffect1.source.sourceRect.width, 50, "OpenEffect ShaderEffectSource is incorrect")
tests/qmltests/Notifications/tst_Notifications.qml+20−9
@@ -48,6 +48,7 @@ Row {
4848 function addSnapDecisionNotification() {
4949 var n = {
5050 type: Notification.SnapDecision,
51+ hints: Notification.ButtonTint,
5152 summary: "Tom Ato",
5253 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.",
5354 icon: "../graphics/avatars/funky.png",
@@ -189,8 +190,9 @@ Row {
189190 function test_NotificationRenderer_data() {
190191 return [
191192 {
192− tag: "Snap Decision with secondary icon",
193+ tag: "Snap Decision with secondary icon and button-tint",
193194 type: Notification.SnapDecision,
195+ hints: Notification.ButtonTint,
194196 summary: "Tom Ato",
195197 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.",
196198 icon: "../graphics/avatars/funky.png",
@@ -205,7 +207,8 @@ Row {
205207 interactiveAreaEnabled: false,
206208 iconVisible: true,
207209 secondaryIconVisible: true,
208− buttonRowVisible: true
210+ buttonRowVisible: true,
211+ buttonTinted: true
209212 },
210213 {
211214 tag: "Ephemeral notification - icon-summary layout",
@@ -220,7 +223,8 @@ Row {
220223 interactiveAreaEnabled: false,
221224 iconVisible: false,
222225 secondaryIconVisible: true,
223− buttonRowVisible: false
226+ buttonRowVisible: false,
227+ buttonTinted: false
224228 },
225229 {
226230 tag: "Ephemeral notification - check suppression of secondary icon for icon-summary layout",
@@ -235,7 +239,8 @@ Row {
235239 interactiveAreaEnabled: false,
236240 iconVisible: false,
237241 secondaryIconVisible: true,
238− buttonRowVisible: false
242+ buttonRowVisible: false,
243+ buttonTinted: false
239244 },
240245 {
241246 tag: "Interactive notification",
@@ -250,10 +255,11 @@ Row {
250255 interactiveAreaEnabled: true,
251256 iconVisible: true,
252257 secondaryIconVisible: false,
253− buttonRowVisible: false
258+ buttonRowVisible: false,
259+ buttonTinted: false
254260 },
255261 {
256− tag: "Snap Decision without secondary icon",
262+ tag: "Snap Decision without secondary icon and no button-tint",
257263 type: Notification.SnapDecision,
258264 summary: "Bro Coly",
259265 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 {
266272 interactiveAreaEnabled: false,
267273 iconVisible: true,
268274 secondaryIconVisible: false,
269− buttonRowVisible: true
275+ buttonRowVisible: true,
276+ buttonTinted: false
270277 },
271278 {
272279 tag: "Ephemeral notification",
@@ -281,7 +288,8 @@ Row {
281288 interactiveAreaEnabled: false,
282289 iconVisible: true,
283290 secondaryIconVisible: true,
284− buttonRowVisible: false
291+ buttonRowVisible: false,
292+ buttonTinted: false
285293 }
286294 ]
287295 }
@@ -356,6 +364,9 @@ Row {
356364 actionSpy.clear()
357365 }
358366
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+
359370 // click the positive/right button
360371 mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2)
361372 actionSpy.wait()
@@ -370,7 +381,7 @@ Row {
370381 mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
371382 waitForRendering(notification)
372383 actionSpy.clear()
373− 
384+
374385 // test the additional buttons
375386 for (var i = 2; i < data.actions.length; i++) {
376387 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 {
2929 IndicatorItem {
3030 id: indicatorItem
3131 anchors.fill: parent
32− iconSource: "../../../Panel/graphics/Clock.png"
33− label: "Clock"
3432 }
3533
3634 UT.UnityTestCase {
3735 name: "IndicatorItem"
3836
3937 function init_test() {
40− indicatorItem.iconSource = "../../../Panel/graphics/Clock.png"
41− indicatorItem.label = "Clock"
4238 }
4339
4440 function test_dimmed() {
4541 init_test()
4642
47− var itemRow = findChild(indicatorItem, "itemRow")
4843 indicatorItem.dimmed = true
49− compare(itemRow.opacity > 0, true, "IndicatorItem opacity should not be 0")
50− compare(itemRow.opacity < 1, true, "IndicatorItem opacity should not be 1")
44+ compare(indicatorItem.opacity > 0, true, "IndicatorItem opacity should not be 0")
45+ compare(indicatorItem.opacity < 1, true, "IndicatorItem opacity should not be 1")
5146 }
5247
53− function test_empty() {
54− init_test()
55−
56− indicatorItem.iconSource = ""
57− indicatorItem.label = ""
58− compare(indicatorItem.visible, false, "IndicatorItem should not be visible")
59− }
48+ function test_highlight() {
49+ var itemHighlight = findChild(indicatorItem, "highlight")
50+ verify(itemHighlight != undefined)
6051
61− function test_noLabel() {
62− init_test()
52+ indicatorItem.highlighted = true;
53+ compare(itemHighlight.visible, true, "Indicator should be highlighted")
6354
64− var itemImage = findChild(indicatorItem, "itemImage")
65− var itemLabel = findChild(indicatorItem, "itemLabel")
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")
55+ indicatorItem.highlighted = false;
56+ compare(itemHighlight.visible, false, "Indicator should not be highlighted")
7057 }
7158
72− function test_noImage() {
59+ function test_empty() {
7360 init_test()
7461
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")
79− compare(itemLabel.width > 0, true, "The label should have a positive width")
62+ compare(indicatorItem.visible, false, "IndicatorItem should not be visible.")
63+ indicatorItem.widgetSource = "qrc:/tests/indciators/qml/fake_menu_widget1.qml";
64+ tryCompare(indicatorItem, "visible", true)
8065 }
8166 }
8267}
tests/qmltests/Panel/tst_IndicatorRow.qml+3−16
@@ -19,7 +19,7 @@ import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import ".."
2121import "../../../Panel"
22−import Ubuntu.ChewieUI 0.1 as ChewieUI
22+import Unity.Indicators 0.1 as Indicators
2323
2424/*
2525 This tests the IndicatorRow component by using a fake model to stage data in the indicators
@@ -32,7 +32,6 @@ Item {
3232
3333 function init_test()
3434 {
35− indicatorRow.overviewActive = false;
3635 indicatorRow.state = "initial";
3736 indicatorRow.currentItem = null;
3837 }
@@ -51,8 +50,9 @@ Item {
5150 indicatorsModel: indicatorModel
5251 }
5352
54− ChewieUI.PluginModel {
53+ Indicators.IndicatorsModel {
5554 id: indicatorModel
55+ Component.onCompleted: load()
5656 }
5757
5858 UT.UnityTestCase {
@@ -240,18 +240,5 @@ Item {
240240 compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in locked state");
241241 compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in locked state");
242242 }
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− }
256243 }
257244}
tests/qmltests/Panel/tst_Indicators.qml+2−41
@@ -69,10 +69,8 @@ Item {
6969
7070 onClicked: {
7171 if (!indicators.shown) {
72− indicators.openOverview();
7372 indicators.show();
74− }
75− else {
73+ } else {
7674 indicators.hide();
7775 }
7876 }
@@ -90,47 +88,10 @@ Item {
9088 tryCompare(indicators, "state", "initial");
9189 }
9290
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.
9492 function test_show() {
9593 indicators.show()
9694 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− }
13495 }
13596
13697 // 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
1919import Unity.Test 0.1 as UT
2020import ".."
2121import "../../../Panel"
22−import Ubuntu.ChewieUI 0.1 as ChewieUI
22+import Unity.Indicators 0.1 as Indicators
2323
2424Item {
2525 id: shell
@@ -27,11 +27,11 @@ Item {
2727 height: units.gu(70)
2828
2929 property var indicator_status: {
30− 'menu_plugin1': { 'started': false, 'reset': 0 },
31− 'menu_plugin2': { 'started': false, 'reset': 0 },
32− 'menu_plugin3': { 'started': false, 'reset': 0 },
33− 'menu_plugin4': { 'started': false, 'reset': 0 },
34− 'menu_plugin5': { 'started': false, 'reset': 0 }
30+ 'menu_page1': { 'started': false, 'reset': 0 },
31+ 'menu_page2': { 'started': false, 'reset': 0 },
32+ 'menu_page3': { 'started': false, 'reset': 0 },
33+ 'menu_page4': { 'started': false, 'reset': 0 },
34+ 'menu_page5': { 'started': false, 'reset': 0 }
3535 }
3636
3737 // Dummy objects
@@ -39,8 +39,9 @@ Item {
3939 Item { id: handle }
4040
4141
42− ChewieUI.PluginModel {
42+ Indicators.IndicatorsModel {
4343 id: indicatorsModel
44+ Component.onCompleted: load()
4445 }
4546
4647 MenuContent {
@@ -51,8 +52,8 @@ Item {
5152 height: parent.height - 50
5253 }
5354
54− Item {
55− id: click_me
55+ Rectangle {
56+ color: "#bbbbbb"
5657
5758 height: 50
5859 anchors {
@@ -61,50 +62,16 @@ Item {
6162 right: parent.right
6263 }
6364
64− Rectangle {
65− color: "#999999"
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
77− horizontalAlignment: Text.AlignHCenter
78− verticalAlignment: Text.AlignVCenter
79− }
80−
81− MouseArea {
82− anchors.fill: parent
83− onClicked: menuContent.showOverview()
84− }
65+ Text {
66+ text: "Next Indicator"
67+ anchors.fill: parent
68+ horizontalAlignment: Text.AlignHCenter
69+ verticalAlignment: Text.AlignVCenter
8570 }
8671
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 {
105− anchors.fill: parent
106− onClicked: activate_next_content()
107− }
72+ MouseArea {
73+ anchors.fill: parent
74+ onClicked: activate_next_content()
10875 }
10976 }
11077
@@ -119,24 +86,23 @@ Item {
11986 function activate_content(index)
12087 {
12188 menuContent.currentIndex = index
122− menuContent.showMenu();
12389 }
12490
12591 function get_test_menu_objecName(index) {
126− return "menu_plugin"+(index+1);
92+ return "menu_page"+(index+1);
12793 }
12894
12995 property string test_menu_objectName : ""
13096 function current_menu_equals_test_menu() {
13197 var current_loader = menu_content_test.findChild(menuContent, "menus").currentItem
13298 if (current_loader == undefined) {
133− console.log("current_loader undefined");
99+ console.log("current_loader 'menus' undefined");
134100 return false;
135101 }
136102
137103 var menu = menu_content_test.findChild(menuContent, test_menu_objectName);
138104 if (menu == undefined) {
139− console.log("test_menu undefined");
105+ console.log("test_menu " + test_menu_objectName + " undefined");
140106 return false;
141107 }
142108
@@ -150,7 +116,6 @@ Item {
150116 when: windowShown
151117
152118 function init() {
153− menuContent.hideAll();
154119 if (menuContent.__contentActive)
155120 menuContent.releaseContent();
156121 tryCompare(menuContent, "__contentActive", false);
@@ -173,40 +138,6 @@ Item {
173138 compare(menus.currentIndex, menu_index, "Current menu index does not match selected menu index");
174139 tryCompareFunction(current_menu_equals_test_menu, true);
175140 }
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− }
210141 }
211142
212143 // 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
1919import Unity.Test 0.1 as UT
2020import ".."
2121import "../../../Panel"
22−import Ubuntu.ChewieUI 0.1 as ChewieUI
2322
2423/*
2524 This tests the Panel component using a fake model to stage data in the indicators
@@ -63,14 +62,14 @@ Item {
6362
6463 function get_indicator_item(index) {
6564 var row_repeater = findChild(panel.indicators, "rowRepeater");
66− verify(row_repeater != undefined)
65+ verify(row_repeater != undefined);
6766 return row_repeater.itemAt(index);
6867 }
6968
7069 function get_indicator_item_position(index) {
7170
7271 var indicator_row = findChild(panel.indicators, "indicatorRow");
73− verify(indicator_row != undefined)
72+ verify(indicator_row != undefined);
7473
7574 var indicator_item = get_indicator_item(index);
7675 verify(indicator_item != undefined);
@@ -84,11 +83,11 @@ Item {
8483 panel.fullscreenMode = false;
8584 // Wait for the indicators to get into position.
8685 // (switches between normal and fullscreen modes are animated)
87− tryCompare(panel.indicators, "y", 0)
86+ tryCompare(panel.indicators, "y", 0);
8887
8988 var indicator_item_coord = get_indicator_item_position(0);
9089
91− touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2)
90+ touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2);
9291
9392 // hint animation should be run, meaning that indicators will move downwards
9493 // by hintValue pixels without any drag taking place
@@ -97,7 +96,7 @@ Item {
9796 tryCompare(panel.indicators, "partiallyOpened", true);
9897 tryCompare(panel.indicators, "fullyOpened", false);
9998
100− touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2)
99+ touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2);
101100 }
102101
103102 // Pressing on the top edge of the screen should have no effect if the panel
@@ -106,31 +105,31 @@ Item {
106105 panel.fullscreenMode = true;
107106 // Wait for the indicators to get into position.
108107 // (switches between normal and fullscreen modes are animated)
109− tryCompare(panel.indicators, "y", -panel.panelHeight)
108+ tryCompare(panel.indicators, "y", -panel.panelHeight);
110109
111110 var indicator_item_coord = get_indicator_item_position(0);
112111
113− touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2)
112+ touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2);
114113
115114 // Give some time for a hint animation to change things, if any
116− wait(500)
115+ wait(500);
117116
118117 // no hint animation when fullscreen
119− compare(panel.indicators.y, -panel.panelHeight)
118+ compare(panel.indicators.y, -panel.panelHeight);
120119 var indicatorRow = findChild(panel.indicators, "indicatorRow");
121− verify(indicatorRow != undefined)
122− compare(indicatorRow.y, 0)
123− compare(panel.indicators.height, panel.indicators.panelHeight)
120+ verify(indicatorRow != undefined);
121+ compare(indicatorRow.y, 0);
122+ compare(panel.indicators.height, panel.indicators.panelHeight);
124123 compare(panel.indicators.partiallyOpened, false,
125124 "Indicator should not be partially opened when panel is pressed in" +
126− " fullscreenmode")
125+ " fullscreenmode");
127126 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");
129128
130− touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2)
129+ touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2);
131130 }
132131
133− function test_drag_show_data() { return get_window_data() }
132+ function test_drag_show_data() { return get_window_data(); }
134133
135134 // Dragging from a indicator item in the panel will gradually expose the
136135 // indicators, first by running the hint animation, then after dragging down will
@@ -139,50 +138,50 @@ Item {
139138 panel.fullscreenMode = data.fullscreenFlag;
140139
141140 var indicator_row = findChild(panel.indicators, "indicatorRow");
142− verify(indicator_row != undefined)
141+ verify(indicator_row != undefined);
143142
144143 var row_repeater = findChild(panel.indicators, "rowRepeater");
145− verify(indicator_row != undefined)
144+ verify(indicator_row != undefined);
146145
147146 var menu_content = findChild(panel.indicators, "menuContent");
148− verify(indicator_row != undefined)
147+ verify(indicator_row != undefined);
149148
150149 // Wait for the indicators to get into position.
151150 // (switches between normal and fullscreen modes are animated)
152151 if (data.fullscreenFlag) {
153− tryCompare(panel.indicators, "y", -panel.panelHeight)
152+ tryCompare(panel.indicators, "y", -panel.panelHeight);
154153 } else {
155− tryCompare(panel.indicators, "y", 0)
154+ tryCompare(panel.indicators, "y", 0);
156155 }
157156
158157 // do this for each indicator item
159158 for (var i = 0; i < row_repeater.count; i++) {
160159
161160 var indicator_item = get_indicator_item(i);
162− verify(indicator_item != undefined)
161+ verify(indicator_item != undefined);
163162
164163 var indicator_item_coord = get_indicator_item_position(i);
165164
166165 touchPress(panel,
167− indicator_item_coord.x, panel.panelHeight / 2)
166+ indicator_item_coord.x, panel.panelHeight / 2);
168167
169168 // 1) Drag the mouse down
170169 touchFlick(panel,
171170 indicator_item_coord.x, panel.panelHeight / 2,
172171 indicator_item_coord.x, panel.height * 0.8,
173− false /* beginTouch */, false /* endTouch */)
172+ false /* beginTouch */, false /* endTouch */);
174173
175174 // Indicators height should follow the drag, and therefore increase accordingly.
176175 // They should be at least half-way through the screen
177176 tryCompareFunction(
178177 function() {return panel.indicators.height >= panel.height * 0.5},
179− true)
178+ true);
180179
181− touchRelease(panel, indicator_item_coord.x, panel.height * 0.8)
180+ touchRelease(panel, indicator_item_coord.x, panel.height * 0.8);
182181
183182 compare(indicator_row.currentItem, indicator_item,
184− "Incorrect item activated at position " + i)
185− compare(menu_content.__shown, true, "Menu conetent should be enabled for item at position " + i);
183+ "Incorrect item activated at position " + i);
184+ compare(menu_content.currentIndex, i, "Menu conetent should be enabled for item at position " + i);
186185
187186 // init for next indicator_item
188187 init();
@@ -196,23 +195,23 @@ Item {
196195 var search_indicator = findChild(panel, "search");
197196 verify(search_indicator != undefined);
198197
199− tap(search_indicator, 1, 1)
198+ tap(search_indicator, 1, 1);
200199
201200 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");
203202 }
204203
205204 function test_search_click_when_not_visible() {
206205 panel.fullscreenMode = false;
207− panel.searchVisible = false
206+ panel.searchVisible = false;
208207
209208 var search_indicator = findChild(panel, "search");
210209 verify(search_indicator != undefined);
211210
212− tap(search_indicator, 1, 1)
211+ tap(search_indicator, 1, 1);
213212
214213 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");
216215 }
217216 }
218217}
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 {
1818 /* List of plugin directories passed to QML runtime */
1919 importPaths: [
2020 "builddir/plugins",
21+ "builddir/modules",
2122 "builddir/tests/plugins",
2223 "builddir/tests/utils/modules"
2324 ]