on xenial help sign in
Merge from trunk
commitcbc5044accb969c570da6b390d756d0b955e76de authorMichael Terry <michael.terry@canonical.com> dateFri 9 Jan 2015, 16:59 (12 years ago) parent940e1fc5137887
102 files changed+2072−795
cmake/modules/QmlTest.cmake+3 debian/changelog+46 debian/control+7−5 plugins/LightDM/CMakeLists.txt+1−1 plugins/LightDM/UsersModel.cpp+1−1 plugins/LightDM/UsersModel.h+2−2 plugins/Lights/Lights.cpp+9−24 plugins/Unity/Indicators/CMakeLists.txt+3−1 plugins/Unity/Indicators/Indicators.qmltypes+18−7 plugins/Unity/Indicators/actionrootstate.cpp+97 plugins/Unity/Indicators/actionrootstate.h+55 plugins/Unity/Indicators/modelactionrootstate.cpp+127 plugins/Unity/Indicators/modelactionrootstate.h+61 plugins/Unity/Indicators/plugin.cpp+4−2 plugins/Unity/Indicators/rootactionstate.cpp → plugins/Unity/Indicators/rootstateparser.cpp+74−141 plugins/Unity/Indicators/rootactionstate.h → plugins/Unity/Indicators/rootstateparser.h+18−34 plugins/Utils/CMakeLists.txt+1−1 plugins/Utils/plugin.cpp+2−2 plugins/Utils/qsortfilterproxymodelqml.cpp → plugins/Utils/unitysortfilterproxymodelqml.cpp+15−15 plugins/Utils/qsortfilterproxymodelqml.h → plugins/Utils/unitysortfilterproxymodelqml.h+5−5 po/am.po+96−93 po/br.po+1−1 po/hu.po+61−61 po/ro.po+101−90 qml/Dash/Dash.qml+4−10 qml/Dash/DashContent.qml+2−2 qml/Dash/DashNavigation.qml+4 qml/Dash/DashNavigationButton.qml+2 qml/Dash/GenericScopeView.qml+3−3 qml/Dash/ScopesList.qml+1 qml/Greeter/Clock.qml+1−1 qml/Greeter/Infographics.qml+9−7 qml/Notifications/Notifications.qml+1−1 qml/Panel/IndicatorItem.qml−8 qml/Panel/Indicators/IndicatorBase.qml+1−1 qml/Panel/Indicators/IndicatorsLight.qml+19−1 qml/Panel/Indicators/VisibleIndicators.qml+2−2 qml/Panel/IndicatorsMenu.qml+5 qml/Shell.qml+21−3 src/main.cpp−6 tests/autopilot/unity8/shell/emulators/create_interactive_notification.py−1 tests/autopilot/unity8/shell/emulators/edges_demo.py+140 tests/autopilot/unity8/shell/fixture_setup.py+38 tests/autopilot/unity8/shell/tests/test_edges_demo.py+52 tests/mocks/CMakeLists.txt+1 tests/mocks/LightDM/CMakeLists.txt+1−1 tests/mocks/LightDM/Greeter.cpp+6 tests/mocks/LightDM/Greeter.h+3 tests/mocks/Lights/CMakeLists.txt+8 tests/mocks/Lights/Lights.cpp+84 tests/mocks/Lights/Lights.h+66 tests/mocks/Lights/Lights.qmltypes+45 tests/mocks/Lights/plugin.cpp+33 tests/mocks/Lights/plugin.h+32 tests/mocks/Lights/qmldir+3 tests/mocks/QMenuModel/CMakeLists.txt+1 tests/mocks/QMenuModel/QDBusActionGroup.qml+20−67 tests/mocks/QMenuModel/actiondata.h+52 tests/mocks/QMenuModel/plugin.cpp+10 tests/mocks/Unity/Indicators/ActionRootState.qml+46 tests/mocks/Unity/Indicators/RootActionState.qml → tests/mocks/Unity/Indicators/ModelActionRootState.qml tests/mocks/Unity/Indicators/qmldir+2−1 tests/plugins/LightDM/CMakeLists.txt+4−8 tests/plugins/LightDM/dbus.cpp+11−2 tests/plugins/Unity/Indicators/rootactionstatetest.cpp+4−4 tests/plugins/Utils/CMakeLists.txt+1−1 tests/plugins/Utils/qsortfilterproxymodeltest.cpp → tests/plugins/Utils/unitysortfilterproxymodeltest.cpp+14−14 tests/qmltests/CMakeLists.txt+1 tests/qmltests/Components/tst_Carousel.qml+5−5 tests/qmltests/Components/tst_Lockscreen.qml+1−1 tests/qmltests/Components/tst_ResponsiveVerticalJournal.qml+1−1 tests/qmltests/Dash/Previews/tst_PreviewActions.qml+3−3 tests/qmltests/Dash/Previews/tst_PreviewAudioPlayback.qml+5−5 tests/qmltests/Dash/Previews/tst_PreviewExpandable.qml+2−2 tests/qmltests/Dash/Previews/tst_PreviewImageGallery.qml+6−6 tests/qmltests/Dash/Previews/tst_PreviewPayments.qml+5−5 tests/qmltests/Dash/Previews/tst_PreviewRatingDisplay.qml+1−1 tests/qmltests/Dash/Previews/tst_PreviewRatingInput.qml+2−2 tests/qmltests/Dash/Previews/tst_PreviewZoomableImage.qml+2−2 tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingBoolean.qml+2−2 tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingNumber.qml+3−3 tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingString.qml+2−2 tests/qmltests/Dash/tst_Card.qml+2−2 tests/qmltests/Dash/tst_Dash.qml+42−25 tests/qmltests/Dash/tst_DashContent.qml+48−27 tests/qmltests/Dash/tst_GenericScopeView.qml+26−26 tests/qmltests/Dash/tst_PageHeader.qml+1−1 tests/qmltests/Dash/tst_PreviewListView.qml+2−2 tests/qmltests/Launcher/tst_Launcher.qml+8−8 tests/qmltests/Notifications/tst_Notifications.qml+6−6 tests/qmltests/Notifications/tst_OptionToggle.qml+7−7 tests/qmltests/Notifications/tst_SwipeToAct.qml+1−1 tests/qmltests/Notifications/tst_VisualSnapDecisionsQueue.qml+2−2 tests/qmltests/Panel/Indicators/tst_IndicatorsLight.qml+129 tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml+52−1 tests/qmltests/Panel/tst_IndicatorsBar.qml+1−1 tests/qmltests/Stages/tst_PhoneStage.qml+2 tests/qmltests/Wizard/tst_Wizard.qml+36−12 tests/qmltests/tst_Shell.qml+3−3 tests/qmltests/tst_ShellWithPin.qml+31 tests/qmltests/tst_TabletShell.qml+1−1 tests/utils/modules/Unity/Test/UnityTestCase.qml+71
cmake/modules/QmlTest.cmake+3
@@ -153,7 +153,9 @@ endmacro(add_qml_test_internal)
153153
154154macro(add_binary_qml_test CLASS_NAME LD_PATH DEPS ENVVAR)
155155 set(testCommand
156+ ${ENVVAR}
156157 LD_LIBRARY_PATH=${LD_PATH}
158+ dbus-launch
157159 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
158160 -o ${CMAKE_BINARY_DIR}/test${CLASS_NAME}.xml,xunitxml
159161 -o -,txt)
@@ -171,6 +173,7 @@ macro(add_binary_qml_test CLASS_NAME LD_PATH DEPS ENVVAR)
171173 ${ENVVAR}
172174 LD_LIBRARY_PATH=${LD_PATH}
173175 xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum
176+ dbus-launch
174177 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
175178 -o ${CMAKE_BINARY_DIR}/test${CLASS_NAME}.xml,xunitxml
176179 -o -,txt)
debian/changelog+46
@@ -1,3 +1,49 @@
1+unity8 (8.02+15.04.20150109.2-0ubuntu1) vivid; urgency=low
2+
3+ [ Michał Sawicz ]
4+ * We don't need the SIGSTOP in main() any more.
5+ * Add a test to make sure the shell always starts disabled until it is
6+ enabled by a complete PAM interaction.
7+
8+ [ Leo Arias ]
9+ * Added an autopilot test for the edges demo.
10+
11+ [ Nick Dedekind ]
12+ * Unhook Lights interface from indicator widgets (LP: #1385331)
13+
14+ [ Albert Astals ]
15+ * Fix going to scopes when the Manage Dash is open (LP: #1403464)
16+ * QSortFilterProxyModelQML -> UnitySortFilterProxyModelQML
17+ * Clip the Scopes List header
18+ * Fix ScopesList not being under finger
19+ * Make waitForRendering with no item fail instead of crash
20+ * Disable Dash horizontal scroll while Navigation InverseMouseArea is
21+ pressed (LP: #1403048)
22+ * Test: Make sure the mouse area is enabled before clicking into it
23+ * Test: We actually need to click on the customBackButton and not on
24+ backButton
25+ * Test: By default mouseX act on the middle
26+
27+ [ Michael Terry ]
28+ * Don't block handling power events on loading the greeter's qml and
29+ the background image.
30+ * Show OSK above the wizard. (LP: #1401213)
31+ * Unify the name of the Greeter DBus test, make it use our standard
32+ binary test macro (which also nicely exports xml results), and make
33+ the test a little more robust against timing issues.
34+ * Add a test to make sure the shell always starts disabled until it is
35+ enabled by a complete PAM interaction.
36+
37+ [ Martin Pitt ]
38+ * tests: Fix Notify.Notification.add_action invocation to work also
39+ with unpatched libnotify API. (LP: #1223401)
40+
41+ [ Rodney Dawes ]
42+ * Depend on :native version of g++ to allow cross-compiling to work.
43+ (LP: #1353855)
44+
45+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 09 Jan 2015 10:43:06 +0000
46+
147unity8 (8.02+15.04.20141216.1-0ubuntu1) vivid; urgency=low
248
349 [ Ubuntu daily release ]
debian/control+7−5
@@ -10,8 +10,10 @@ Build-Depends: cmake,
1010 gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
1111# We rely on C++11 features, and to prevent from ABI breaks
1212# in libstdc++ causing us issues, we explicitly select a G++
13−# version.
14− g++-4.9,
13+# version. To allow cross-compiling to work, we also must
14+# append :native to g++-4.9 so we don't try to run armhf g++
15+# on an x86 CPU for eaxmple, when cross-compiling.
16+ g++-4.9:native,
1517 libconnectivity-qt1-dev,
1618 libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],
1719 libgl1-mesa-dri,
@@ -22,7 +24,7 @@ Build-Depends: cmake,
2224 libpam0g-dev,
2325 libpay2-dev,
2426 libpulse-dev,
25− libqmenumodel-dev (>= 0.2.8),
27+ libqmenumodel-dev (>= 0.2.9),
2628 libqt5xmlpatterns5-dev,
2729 libsystemsettings-dev,
2830 libunity-api-dev (>= 7.94),
@@ -61,7 +63,7 @@ X-Ubuntu-Use-Langpack: yes
6163
6264Package: indicators-client
6365Architecture: amd64 armhf i386
64−Depends: qmenumodel-qml (>= 0.2.8),
66+Depends: qmenumodel-qml (>= 0.2.9),
6567 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.1.1239) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.1.1239),
6668 unity8 (= ${binary:Version}),
6769 ${misc:Depends},
@@ -85,7 +87,7 @@ Provides: indicator-renderer,
8587Depends: gsettings-desktop-schemas,
8688 libcap2-bin,
8789 libglib2.0-bin,
88− qmenumodel-qml (>= 0.2.8),
90+ qmenumodel-qml (>= 0.2.9),
8991 qml-module-qt-labs-folderlistmodel,
9092 qml-module-qtquick-xmllistmodel,
9193 qtdeclarative5-gsettings1.0,
plugins/LightDM/CMakeLists.txt+1−1
@@ -15,7 +15,7 @@ include_directories(
1515)
1616
1717set(QMLPLUGIN_SRC
18− ../Utils/qsortfilterproxymodelqml.cpp # FIXME evaluate a more generic approach for using other plugins
18+ ../Utils/unitysortfilterproxymodelqml.cpp # FIXME evaluate a more generic approach for using other plugins
1919 DBusGreeter.cpp
2020 DBusGreeterList.cpp
2121 Greeter.cpp
plugins/LightDM/UsersModel.cpp+1−1
@@ -58,7 +58,7 @@ QVariant MangleModel::data(const QModelIndex &index, int role) const
5858// **** Now we continue with actual UsersModel class ****
5959
6060UsersModel::UsersModel(QObject* parent)
61− : QSortFilterProxyModelQML(parent)
61+ : UnitySortFilterProxyModelQML(parent)
6262{
6363 setModel(new MangleModel(this));
6464 setSortCaseSensitivity(Qt::CaseInsensitive);
plugins/LightDM/UsersModel.h+2−2
@@ -23,10 +23,10 @@
2323#ifndef UNITY_USERSMODEL_H
2424#define UNITY_USERSMODEL_H
2525
26−#include <qsortfilterproxymodelqml.h>
26+#include <unitysortfilterproxymodelqml.h>
2727#include <QtCore/QObject>
2828
29−class UsersModel : public QSortFilterProxyModelQML
29+class UsersModel : public UnitySortFilterProxyModelQML
3030{
3131 Q_OBJECT
3232
plugins/Lights/Lights.cpp+9−24
@@ -44,12 +44,20 @@ Lights::~Lights()
4444
4545void Lights::setState(Lights::State newState)
4646{
47+ if (!init()) {
48+ qWarning() << "No lights device";
49+ return;
50+ }
51+
4752 if (m_state != newState) {
4853 if (newState == Lights::On) {
4954 turnOn();
5055 } else {
5156 turnOff();
5257 }
58+
59+ m_state = newState;
60+ Q_EMIT stateChanged(m_state);
5361 }
5462}
5563
@@ -115,6 +123,7 @@ bool Lights::init()
115123 err = module->methods->open(module, LIGHT_ID_NOTIFICATIONS, &device);
116124 if (err == 0) {
117125 m_lightDevice = (light_device_t*)device;
126+ turnOff();
118127 return true;
119128 } else {
120129 qWarning() << "Failed to access notification lights";
@@ -127,15 +136,6 @@ bool Lights::init()
127136
128137void Lights::turnOn()
129138{
130− if (!init()) {
131− qWarning() << "No lights device";
132− return;
133− }
134−
135− if (m_state == Lights::On) {
136− return;
137− }
138−
139139 // pulse
140140 light_state_t state;
141141 memset(&state, 0, sizeof(light_state_t));
@@ -147,23 +147,11 @@ void Lights::turnOn()
147147
148148 if (m_lightDevice->set_light(m_lightDevice, &state) != 0) {
149149 qWarning() << "Failed to turn the light off";
150− } else {
151− m_state = Lights::On;
152− Q_EMIT stateChanged(m_state);
153150 }
154151}
155152
156153void Lights::turnOff()
157154{
158− if (!init()) {
159− qWarning() << "No lights device";
160− return;
161− }
162−
163− if (m_state == Lights::Off) {
164− return;
165− }
166−
167155 light_state_t state;
168156 memset(&state, 0, sizeof(light_state_t));
169157 state.color = 0x00000000;
@@ -174,8 +162,5 @@ void Lights::turnOff()
174162
175163 if (m_lightDevice->set_light(m_lightDevice, &state) != 0) {
176164 qWarning() << "Failed to turn the light off";
177− } else {
178− m_state = Lights::Off;
179− Q_EMIT stateChanged(m_state);
180165 }
181166}
plugins/Unity/Indicators/CMakeLists.txt+3−1
@@ -16,14 +16,16 @@ include_directories(
1616)
1717
1818set(IndicatorsQML_SOURCES
19+ actionrootstate.cpp
1920 indicator.cpp
2021 indicators.h
2122 indicatorsmanager.cpp
2223 indicatorsmodel.cpp
2324 menucontentactivator.cpp
25+ modelactionrootstate.cpp
2426 modelprinter.cpp
2527 plugin.cpp
26− rootactionstate.cpp
28+ rootstateparser.cpp
2729 sharedunitymenumodel.cpp
2830 unitymenumodelcache.cpp
2931 unitymenumodelstack.cpp
plugins/Unity/Indicators/Indicators.qmltypes+18−7
@@ -7,6 +7,14 @@ import QtQuick.tooling 1.1
77// 'qmlplugindump -notrelocatable Unity.Indicators 0.1 plugins'
88
99Module {
10+ Component {
11+ name: "ActionRootState"
12+ prototype: "RootStateObject"
13+ exports: ["Unity.Indicators/ActionRootState 0.1"]
14+ exportMetaObjectRevisions: [0]
15+ Property { name: "actionGroup"; type: "QDBusActionGroup"; isPointer: true }
16+ Property { name: "actionName"; type: "string" }
17+ }
1018 Component {
1119 name: "ActionState"
1220 prototype: "QObject"
@@ -23,7 +31,6 @@ Module {
2331 }
2432 }
2533 }
26− Component { name: "ActionStateParser"; prototype: "QObject" }
2734 Component {
2835 name: "FlatMenuProxyModelRole"
2936 prototype: "QObject"
@@ -146,6 +153,14 @@ Module {
146153 exportMetaObjectRevisions: [0]
147154 Property { name: "active"; type: "bool"; isReadonly: true }
148155 }
156+ Component {
157+ name: "ModelActionRootState"
158+ prototype: "RootStateObject"
159+ exports: ["Unity.Indicators/ModelActionRootState 0.1"]
160+ exportMetaObjectRevisions: [0]
161+ Property { name: "menu"; type: "UnityMenuModel"; isPointer: true }
162+ Signal { name: "indexChanged" }
163+ }
149164 Component {
150165 name: "ModelPrinter"
151166 prototype: "QObject"
@@ -192,11 +207,8 @@ Module {
192207 }
193208 Component { name: "QIdentityProxyModel"; prototype: "QAbstractProxyModel" }
194209 Component {
195− name: "RootActionState"
196− prototype: "ActionStateParser"
197− exports: ["Unity.Indicators/RootActionState 0.1"]
198− exportMetaObjectRevisions: [0]
199− Property { name: "menu"; type: "UnityMenuModel"; isPointer: true }
210+ name: "RootStateObject"
211+ prototype: "QObject"
200212 Property { name: "valid"; type: "bool"; isReadonly: true }
201213 Property { name: "title"; type: "string"; isReadonly: true }
202214 Property { name: "leftLabel"; type: "string"; isReadonly: true }
@@ -205,7 +217,6 @@ Module {
205217 Property { name: "accessibleName"; type: "string"; isReadonly: true }
206218 Property { name: "visible"; type: "bool"; isReadonly: true }
207219 Signal { name: "updated" }
208− Signal { name: "indexChanged" }
209220 }
210221 Component {
211222 name: "SharedUnityMenuModel"
plugins/Unity/Indicators/actionrootstate.cppnew file+97
@@ -0,0 +1,97 @@
1+/*
2+ * Copyright 2014 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+#include "actionrootstate.h"
18+
19+#include <qdbusactiongroup.h>
20+#include <QDebug>
21+
22+ActionRootState::ActionRootState(QObject *parent)
23+ : RootStateObject(parent)
24+ , m_actionGroup(nullptr)
25+{
26+}
27+
28+QDBusActionGroup *ActionRootState::actionGroup() const
29+{
30+ return m_actionGroup;
31+}
32+
33+void ActionRootState::setActionGroup(QDBusActionGroup *actionGroup)
34+{
35+ if (m_actionGroup != actionGroup) {
36+ bool wasValid = valid();
37+
38+ if (m_actionGroup) {
39+ disconnect(m_actionGroup, 0, this, 0);
40+ }
41+ m_actionGroup = actionGroup;
42+
43+ if (m_actionGroup) {
44+ connect(m_actionGroup, &QDBusActionGroup::statusChanged, this, [&](bool) { updateActionState(); });
45+ connect(m_actionGroup, &QDBusActionGroup::actionAppear, this, [&](const QString&) { updateActionState(); });
46+ connect(m_actionGroup, &QDBusActionGroup::actionVanish, this, [&](const QString&) { updateActionState(); });
47+ connect(m_actionGroup, &QDBusActionGroup::actionStateChanged, this, [&](QVariant) { updateActionState(); });
48+
49+ connect(m_actionGroup, &QObject::destroyed, this, [&](QObject*) { updateActionState(); });
50+ }
51+ updateActionState();
52+ Q_EMIT actionGroupChanged();
53+
54+ if (wasValid != valid()) Q_EMIT validChanged();
55+ }
56+}
57+
58+QString ActionRootState::actionName() const
59+{
60+ return m_actionName;
61+}
62+
63+void ActionRootState::setActionName(const QString &actionName)
64+{
65+ if (m_actionName != actionName) {
66+ bool wasValid = valid();
67+
68+ m_actionName = actionName;
69+ updateActionState();
70+
71+ Q_EMIT actionNameChanged();
72+
73+ if (wasValid != valid()) Q_EMIT validChanged();
74+ }
75+}
76+
77+bool ActionRootState::valid() const
78+{
79+ return m_actionGroup && m_actionGroup->status() == DBusEnums::Connected &&
80+ !m_actionName.isEmpty() && m_actionGroup->hasAction(m_actionName);
81+}
82+
83+void ActionRootState::updateActionState()
84+{
85+ if (valid()) {
86+ ActionStateParser* oldParser = m_actionGroup->actionStateParser();
87+ m_actionGroup->setActionStateParser(&m_parser);
88+
89+ QVariantMap state = m_actionGroup->actionState(m_actionName).toMap();
90+
91+ m_actionGroup->setActionStateParser(oldParser);
92+
93+ setCurrentState(state);
94+ } else {
95+ setCurrentState(QVariantMap());
96+ }
97+}
plugins/Unity/Indicators/actionrootstate.hnew file+55
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright 2014 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+#ifndef ACTIONROOTSTATE_H
18+#define ACTIONROOTSTATE_H
19+
20+#include "unityindicatorsglobal.h"
21+
22+#include "rootstateparser.h"
23+
24+class QDBusActionGroup;
25+
26+class UNITYINDICATORS_EXPORT ActionRootState : public RootStateObject
27+{
28+ Q_OBJECT
29+ Q_PROPERTY(QDBusActionGroup* actionGroup READ actionGroup WRITE setActionGroup NOTIFY actionGroupChanged)
30+ Q_PROPERTY(QString actionName READ actionName WRITE setActionName NOTIFY actionNameChanged)
31+
32+public:
33+ ActionRootState(QObject *parent = 0);
34+
35+ QDBusActionGroup *actionGroup() const;
36+ void setActionGroup(QDBusActionGroup *actionGroup);
37+
38+ QString actionName() const;
39+ void setActionName(const QString& actionName);
40+
41+ bool valid() const override;
42+
43+Q_SIGNALS:
44+ void actionGroupChanged();
45+ void actionNameChanged();
46+
47+private Q_SLOTS:
48+ void updateActionState();
49+
50+private:
51+ QDBusActionGroup* m_actionGroup;
52+ QString m_actionName;
53+};
54+
55+#endif // ACTIONROOTSTATE_H
plugins/Unity/Indicators/modelactionrootstate.cppnew file+127
@@ -0,0 +1,127 @@
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 "modelactionrootstate.h"
21+#include "indicators.h"
22+
23+#include <unitymenumodel.h>
24+#include <QVariant>
25+#include <QIcon>
26+
27+extern "C" {
28+#include <glib.h>
29+#include <gio/gio.h>
30+}
31+
32+ModelActionRootState::ModelActionRootState(QObject *parent)
33+ : RootStateObject(parent),
34+ m_menu(nullptr)
35+{
36+}
37+
38+ModelActionRootState::~ModelActionRootState()
39+{
40+}
41+
42+UnityMenuModel* ModelActionRootState::menu() const
43+{
44+ return m_menu;
45+}
46+
47+void ModelActionRootState::setMenu(UnityMenuModel* menu)
48+{
49+ if (m_menu != menu) {
50+ bool wasValid = valid();
51+
52+ if (m_menu) {
53+ m_menu->disconnect(this);
54+ }
55+ m_menu = menu;
56+
57+ if (m_menu) {
58+ connect(m_menu, SIGNAL(rowsInserted(const QModelIndex&, int, int)), SLOT(onModelRowsAdded(const QModelIndex&, int, int)));
59+ connect(m_menu, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), SLOT(onModelRowsRemoved(const QModelIndex&, int, int)));
60+ connect(m_menu, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)), SLOT(onModelDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
61+
62+ connect(m_menu, SIGNAL(destroyed()), SLOT(reset()));
63+ }
64+ updateActionState();
65+ Q_EMIT menuChanged();
66+
67+ if (wasValid != valid())
68+ Q_EMIT validChanged();
69+ }
70+}
71+
72+bool ModelActionRootState::valid() const
73+{
74+ return m_menu && m_menu->rowCount() > 0;
75+}
76+
77+void ModelActionRootState::onModelRowsAdded(const QModelIndex& parent, int start, int end)
78+{
79+ Q_UNUSED(parent);
80+ if (start == 0 && end >= 0) {
81+ updateActionState();
82+ }
83+}
84+
85+void ModelActionRootState::onModelRowsRemoved(const QModelIndex& parent, int start, int end)
86+{
87+ Q_UNUSED(parent);
88+ if (start == 0 && end >= 0) {
89+ updateActionState();
90+ }
91+}
92+
93+void ModelActionRootState::onModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles)
94+{
95+ Q_UNUSED(roles);
96+ if (!topLeft.isValid() || !bottomRight.isValid()) {
97+ return;
98+ }
99+
100+ if (topLeft.row() <= 0 && bottomRight.row() >= 0) {
101+ updateActionState();
102+ }
103+}
104+
105+void ModelActionRootState::reset()
106+{
107+ m_menu = nullptr;
108+
109+ Q_EMIT menuChanged();
110+ setCurrentState(QVariantMap());
111+}
112+
113+void ModelActionRootState::updateActionState()
114+{
115+ if (m_menu && m_menu->rowCount() > 0) {
116+ ActionStateParser* oldParser = m_menu->actionStateParser();
117+ m_menu->setActionStateParser(&m_parser);
118+
119+ QVariantMap state = m_menu->get(0, "actionState").toMap();
120+
121+ m_menu->setActionStateParser(oldParser);
122+
123+ setCurrentState(state);
124+ } else {
125+ setCurrentState(QVariantMap());
126+ }
127+}
plugins/Unity/Indicators/modelactionrootstate.hnew file+61
@@ -0,0 +1,61 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#ifndef MODELACTIONROOTSTATE_H
21+#define MODELACTIONROOTSTATE_H
22+
23+#include "unityindicatorsglobal.h"
24+
25+#include "rootstateparser.h"
26+
27+class UnityMenuModel;
28+
29+class UNITYINDICATORS_EXPORT ModelActionRootState : public RootStateObject
30+{
31+ Q_OBJECT
32+ Q_PROPERTY(UnityMenuModel* menu READ menu WRITE setMenu NOTIFY menuChanged)
33+public:
34+ ModelActionRootState(QObject *parent = 0);
35+ virtual ~ModelActionRootState();
36+
37+ UnityMenuModel* menu() const;
38+ void setMenu(UnityMenuModel* menu);
39+
40+ int index() const;
41+ void setIndex(int index);
42+
43+ bool valid() const override;
44+
45+Q_SIGNALS:
46+ void menuChanged();
47+ void indexChanged();
48+
49+private Q_SLOTS:
50+ void onModelRowsAdded(const QModelIndex& parent, int start, int end);
51+ void onModelRowsRemoved(const QModelIndex& parent, int start, int end);
52+ void onModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>&);
53+ void reset();
54+
55+private:
56+ void updateActionState();
57+
58+ UnityMenuModel* m_menu;
59+};
60+
61+#endif // MODELACTIONROOTSTATE_H
plugins/Unity/Indicators/plugin.cpp+4−2
@@ -24,12 +24,13 @@
2424#include "plugin.h"
2525
2626// local
27+#include "actionrootstate.h"
2728#include "indicators.h"
2829#include "indicatorsmanager.h"
2930#include "indicatorsmodel.h"
3031#include "menucontentactivator.h"
32+#include "modelactionrootstate.h"
3133#include "modelprinter.h"
32−#include "rootactionstate.h"
3334#include "sharedunitymenumodel.h"
3435#include "unitymenumodelcache.h"
3536#include "unitymenumodelstack.h"
@@ -51,7 +52,8 @@ void IndicatorsPlugin::registerTypes(const char *uri)
5152 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
5253 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
5354 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
54− qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
55+ qmlRegisterType<ModelActionRootState>(uri, 0, 1, "ModelActionRootState");
56+ qmlRegisterType<ActionRootState>(uri, 0, 1, "ActionRootState");
5557 qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
5658 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
5759 qmlRegisterType<SharedUnityMenuModel>(uri, 0, 1, "SharedUnityMenuModel");
plugins/Unity/Indicators/rootactionstate.cpp → plugins/Unity/Indicators/rootstateparser.cpprenamed+74−141
@@ -12,155 +12,18 @@
1212 *
1313 * You should have received a copy of the GNU Lesser General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Authors:
17− * Nick Dedekind <nick.dedekind@canonical.com>
1815 */
1916
20−#include "rootactionstate.h"
21−#include "indicators.h"
22−
23−#include <unitymenumodel.h>
24−#include <QVariant>
25−#include <QIcon>
17+#include "rootstateparser.h"
2618
2719extern "C" {
2820#include <glib.h>
2921#include <gio/gio.h>
3022}
3123
32−RootActionState::RootActionState(QObject *parent)
33− : ActionStateParser(parent),
34− m_menu(nullptr)
35−{
36−}
37−
38−RootActionState::~RootActionState()
39−{
40−}
41−
42−UnityMenuModel* RootActionState::menu() const
43−{
44− return m_menu;
45−}
46−
47−void RootActionState::setMenu(UnityMenuModel* menu)
48−{
49− if (m_menu != menu) {
50− if (m_menu) {
51− m_menu->disconnect(this);
52− }
53− m_menu = menu;
54−
55− if (m_menu) {
56− connect(m_menu, SIGNAL(rowsInserted(const QModelIndex&, int, int)), SLOT(onModelRowsAdded(const QModelIndex&, int, int)));
57− connect(m_menu, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), SLOT(onModelRowsRemoved(const QModelIndex&, int, int)));
58− connect(m_menu, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)), SLOT(onModelDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
59−
60− connect(m_menu, SIGNAL(destroyed()), SLOT(reset()));
61− }
62− updateActionState();
63− Q_EMIT menuChanged();
64− }
65−}
66−
67−void RootActionState::onModelRowsAdded(const QModelIndex& parent, int start, int end)
24+RootStateParser::RootStateParser(QObject* parent)
25+ : ActionStateParser(parent)
6826{
69− Q_UNUSED(parent);
70− if (start == 0 && end >= 0) {
71− updateActionState();
72− }
73−}
74−
75−void RootActionState::onModelRowsRemoved(const QModelIndex& parent, int start, int end)
76−{
77− Q_UNUSED(parent);
78− if (start == 0 && end >= 0) {
79− updateActionState();
80− }
81−}
82−
83−void RootActionState::onModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles)
84−{
85− Q_UNUSED(roles);
86− if (!topLeft.isValid() || !bottomRight.isValid()) {
87− return;
88− }
89−
90− if (topLeft.row() <= 0 && bottomRight.row() >= 0) {
91− updateActionState();
92− }
93−}
94−
95−void RootActionState::reset()
96−{
97− m_cachedState.clear();
98− m_menu = nullptr;
99−
100− Q_EMIT menuChanged();
101− Q_EMIT updated();
102−}
103−
104−void RootActionState::updateActionState()
105−{
106− if (m_menu && m_menu->rowCount() > 0) {
107− ActionStateParser* oldParser = m_menu->actionStateParser();
108− m_menu->setActionStateParser(this);
109−
110− m_cachedState = m_menu->get(0, "actionState").toMap();
111−
112− m_menu->setActionStateParser(oldParser);
113− } else {
114− m_cachedState.clear();
115− }
116− Q_EMIT updated();
117−}
118−
119−bool RootActionState::isValid() const
120−{
121− return m_menu && m_menu->rowCount() > 0;
122−}
123−
124−QString RootActionState::title() const
125−{
126− if (!isValid()) return QString();
127−
128− return m_cachedState.value("title", QVariant::fromValue(QString())).toString();
129−}
130−
131−QString RootActionState::leftLabel() const
132−{
133− if (!isValid()) return QString();
134−
135− return m_cachedState.value("pre-label", QVariant::fromValue(QString())).toString();
136−}
137−
138−QString RootActionState::rightLabel() const
139−{
140− if (!isValid()) return QString();
141−
142− return m_cachedState.value("label", QVariant::fromValue(QString())).toString();
143−}
144−
145−QStringList RootActionState::icons() const
146−{
147− if (!isValid()) return QStringList();
148−
149− return m_cachedState.value("icons", QVariant::fromValue(QStringList())).toStringList();
150−}
151−
152−QString RootActionState::accessibleName() const
153−{
154− if (!isValid()) return QString();
155−
156− return m_cachedState.value("accessible-desc", QVariant::fromValue(QString())).toString();
157−}
158−
159−bool RootActionState::indicatorVisible() const
160−{
161− if (!isValid()) return false;
162−
163− return m_cachedState.value("visible", QVariant::fromValue(true)).toBool();
16427}
16528
16629static QString iconUri(GIcon *icon)
@@ -209,7 +72,7 @@ static QString iconUri(GIcon *icon)
20972 return uri;
21073}
21174
212−QVariant RootActionState::toQVariant(GVariant* state) const
75+QVariant RootStateParser::toQVariant(GVariant* state) const
21376{
21477 if (!state) {
21578 return QVariant();
@@ -296,3 +159,73 @@ QVariant RootActionState::toQVariant(GVariant* state) const
296159 }
297160 return ActionStateParser::toQVariant(state);
298161}
162+
163+
164+RootStateObject::RootStateObject(QObject* parent)
165+ : QObject(parent)
166+{
167+}
168+
169+QString RootStateObject::title() const
170+{
171+ if (!valid()) return QString();
172+
173+ return m_currentState.value("title", QVariant::fromValue(QString())).toString();
174+}
175+
176+QString RootStateObject::leftLabel() const
177+{
178+ if (!valid()) return QString();
179+
180+ return m_currentState.value("pre-label", QVariant::fromValue(QString())).toString();
181+}
182+
183+QString RootStateObject::rightLabel() const
184+{
185+ if (!valid()) return QString();
186+
187+ return m_currentState.value("label", QVariant::fromValue(QString())).toString();
188+}
189+
190+QStringList RootStateObject::icons() const
191+{
192+ if (!valid()) return QStringList();
193+
194+ return m_currentState.value("icons", QVariant::fromValue(QStringList())).toStringList();
195+}
196+
197+QString RootStateObject::accessibleName() const
198+{
199+ if (!valid()) return QString();
200+
201+ return m_currentState.value("accessible-desc", QVariant::fromValue(QString())).toString();
202+}
203+
204+bool RootStateObject::indicatorVisible() const
205+{
206+ if (!valid()) return false;
207+
208+ return m_currentState.value("visible", QVariant::fromValue(true)).toBool();
209+}
210+
211+void RootStateObject::setCurrentState(const QVariantMap& newState)
212+{
213+ QString oldTitle = title();
214+ QString oldLeftLabel = leftLabel();
215+ QString oldRightLabel = rightLabel();
216+ QStringList oldIcons = icons();
217+ QString oldAccessibleName = accessibleName();
218+ bool oldIndicatorVisible = indicatorVisible();
219+
220+ if (m_currentState != newState) {
221+ m_currentState = newState;
222+ Q_EMIT updated();
223+
224+ if (oldTitle != title()) Q_EMIT titleChanged();
225+ if (oldLeftLabel != leftLabel()) Q_EMIT leftLabelChanged();
226+ if (oldRightLabel != rightLabel()) Q_EMIT rightLabelChanged();
227+ if (oldIcons != icons()) Q_EMIT iconsChanged();
228+ if (oldAccessibleName != accessibleName()) Q_EMIT accessibleNameChanged();
229+ if (oldIndicatorVisible != indicatorVisible()) Q_EMIT indicatorVisibleChanged();
230+ }
231+}
plugins/Unity/Indicators/rootactionstate.h → plugins/Unity/Indicators/rootstateparser.hrenamed+18−34
@@ -12,26 +12,27 @@
1212 *
1313 * You should have received a copy of the GNU Lesser General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Authors:
17− * Nick Dedekind <nick.dedekind@canonical.com>
1815 */
1916
20−#ifndef ROOTACTIONSTATE_H
21−#define ROOTACTIONSTATE_H
17+#ifndef ROOTSTATEPARSER_H
18+#define ROOTSTATEPARSER_H
2219
2320#include "unityindicatorsglobal.h"
2421
2522#include <actionstateparser.h>
2623
27−class UnityMenuModel;
24+class UNITYINDICATORS_EXPORT RootStateParser : public ActionStateParser
25+{
26+public:
27+ RootStateParser(QObject* parent = nullptr);
28+ virtual QVariant toQVariant(GVariant* state) const override;
29+};
2830
29−class UNITYINDICATORS_EXPORT RootActionState : public ActionStateParser
31+class UNITYINDICATORS_EXPORT RootStateObject : public QObject
3032{
3133 Q_OBJECT
32− Q_PROPERTY(UnityMenuModel* menu READ menu WRITE setMenu NOTIFY menuChanged)
3334
34− Q_PROPERTY(bool valid READ isValid NOTIFY validChanged)
35+ Q_PROPERTY(bool valid READ valid NOTIFY validChanged)
3536 Q_PROPERTY(QString title READ title NOTIFY titleChanged)
3637 Q_PROPERTY(QString leftLabel READ leftLabel NOTIFY leftLabelChanged)
3738 Q_PROPERTY(QString rightLabel READ rightLabel NOTIFY rightLabelChanged)
@@ -39,16 +40,10 @@ class UNITYINDICATORS_EXPORT RootActionState : public ActionStateParser
3940 Q_PROPERTY(QString accessibleName READ accessibleName NOTIFY accessibleNameChanged)
4041 Q_PROPERTY(bool indicatorVisible READ indicatorVisible NOTIFY indicatorVisibleChanged)
4142public:
42− RootActionState(QObject *parent = 0);
43− virtual ~RootActionState();
43+ RootStateObject(QObject* parent = 0);
4444
45− UnityMenuModel* menu() const;
46− void setMenu(UnityMenuModel* menu);
45+ virtual bool valid() const = 0;
4746
48− int index() const;
49− void setIndex(int index);
50−
51− bool isValid() const;
5247 QString title() const;
5348 QString leftLabel() const;
5449 QString rightLabel() const;
@@ -56,15 +51,12 @@ public:
5651 QString accessibleName() const;
5752 bool indicatorVisible() const;
5853
59− // from ActionStateParser
60− virtual QVariant toQVariant(GVariant* state) const override;
54+ QVariantMap currentState() const { return m_currentState; }
55+ void setCurrentState(const QVariantMap& currentState);
6156
6257Q_SIGNALS:
6358 void updated();
6459
65− void menuChanged();
66− void indexChanged();
67−
6860 void validChanged();
6961 void titleChanged();
7062 void leftLabelChanged();
@@ -73,17 +65,9 @@ Q_SIGNALS:
7365 void accessibleNameChanged();
7466 void indicatorVisibleChanged();
7567
76−private Q_SLOTS:
77− void onModelRowsAdded(const QModelIndex& parent, int start, int end);
78− void onModelRowsRemoved(const QModelIndex& parent, int start, int end);
79− void onModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>&);
80− void reset();
81−
82−private:
83− void updateActionState();
84−
85− UnityMenuModel* m_menu;
86− QVariantMap m_cachedState;
68+protected:
69+ RootStateParser m_parser;
70+ QVariantMap m_currentState;
8771};
8872
89−#endif // ROOTACTIONSTATE_H
73+#endif // ROOTSTATEPARSER_H
plugins/Utils/CMakeLists.txt+1−1
@@ -12,7 +12,7 @@ include_directories(
1212
1313set(QMLPLUGIN_SRC
1414 qlimitproxymodelqml.cpp
15− qsortfilterproxymodelqml.cpp
15+ unitysortfilterproxymodelqml.cpp
1616 relativetimeformatter.cpp
1717 timeformatter.cpp
1818 unitymenumodelpaths.cpp
plugins/Utils/plugin.cpp+2−2
@@ -27,7 +27,7 @@
2727
2828// local
2929#include "qlimitproxymodelqml.h"
30−#include "qsortfilterproxymodelqml.h"
30+#include "unitysortfilterproxymodelqml.h"
3131#include "relativetimeformatter.h"
3232#include "timeformatter.h"
3333#include "unitymenumodelpaths.h"
@@ -39,7 +39,7 @@ void UtilsPlugin::registerTypes(const char *uri)
3939 Q_ASSERT(uri == QLatin1String("Utils"));
4040 qmlRegisterType<QAbstractItemModel>();
4141 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
42− qmlRegisterType<QSortFilterProxyModelQML>(uri, 0, 1, "SortFilterProxyModel");
42+ qmlRegisterType<UnitySortFilterProxyModelQML>(uri, 0, 1, "UnitySortFilterProxyModel");
4343 qmlRegisterType<UnityMenuModelPaths>(uri, 0, 1, "UnityMenuModelPaths");
4444 qmlRegisterType<TimeFormatter>(uri, 0, 1, "TimeFormatter");
4545 qmlRegisterType<WindowKeysFilter>(uri, 0, 1, "WindowKeysFilter");
plugins/Utils/qsortfilterproxymodelqml.cpp → plugins/Utils/unitysortfilterproxymodelqml.cpprenamed+15−15
@@ -15,12 +15,12 @@
1515 */
1616
1717// self
18−#include "qsortfilterproxymodelqml.h"
18+#include "unitysortfilterproxymodelqml.h"
1919
2020// Qt
2121#include <QDebug>
2222
23−QSortFilterProxyModelQML::QSortFilterProxyModelQML(QObject *parent)
23+UnitySortFilterProxyModelQML::UnitySortFilterProxyModelQML(QObject *parent)
2424 : QSortFilterProxyModel(parent)
2525 , m_invertMatch(false)
2626{
@@ -32,7 +32,7 @@ QSortFilterProxyModelQML::QSortFilterProxyModelQML(QObject *parent)
3232/*
3333 * Enter row index of filtered/sorted model, returns row index of source model
3434 */
35−int QSortFilterProxyModelQML::mapRowToSource(int row)
35+int UnitySortFilterProxyModelQML::mapRowToSource(int row)
3636{
3737 if (sourceModel() == nullptr)
3838 return -1;
@@ -40,13 +40,13 @@ int QSortFilterProxyModelQML::mapRowToSource(int row)
4040 return QSortFilterProxyModel::mapToSource(index(row, 0)).row();
4141}
4242
43−QHash<int, QByteArray> QSortFilterProxyModelQML::roleNames() const
43+QHash<int, QByteArray> UnitySortFilterProxyModelQML::roleNames() const
4444{
4545 return sourceModel() ? sourceModel()->roleNames() : QHash<int, QByteArray>();
4646}
4747
4848void
49−QSortFilterProxyModelQML::setModel(QAbstractItemModel *itemModel)
49+UnitySortFilterProxyModelQML::setModel(QAbstractItemModel *itemModel)
5050{
5151 if (itemModel == nullptr) {
5252 return;
@@ -69,7 +69,7 @@ QSortFilterProxyModelQML::setModel(QAbstractItemModel *itemModel)
6969}
7070
7171QVariantMap
72−QSortFilterProxyModelQML::get(int row)
72+UnitySortFilterProxyModelQML::get(int row)
7373{
7474 QVariantMap res;
7575 const QHash<int, QByteArray> roles = roleNames();
@@ -81,7 +81,7 @@ QSortFilterProxyModelQML::get(int row)
8181}
8282
8383QVariant
84−QSortFilterProxyModelQML::data(int row, int role)
84+UnitySortFilterProxyModelQML::data(int row, int role)
8585{
8686 if (sourceModel() == nullptr) {
8787 return QVariant();
@@ -91,7 +91,7 @@ QSortFilterProxyModelQML::data(int row, int role)
9191}
9292
9393int
94−QSortFilterProxyModelQML::totalCount() const
94+UnitySortFilterProxyModelQML::totalCount() const
9595{
9696 if (sourceModel() != nullptr) {
9797 return sourceModel()->rowCount();
@@ -101,19 +101,19 @@ QSortFilterProxyModelQML::totalCount() const
101101}
102102
103103int
104−QSortFilterProxyModelQML::count()
104+UnitySortFilterProxyModelQML::count()
105105{
106106 return rowCount();
107107}
108108
109109bool
110−QSortFilterProxyModelQML::invertMatch() const
110+UnitySortFilterProxyModelQML::invertMatch() const
111111{
112112 return m_invertMatch;
113113}
114114
115115void
116−QSortFilterProxyModelQML::setInvertMatch(bool invertMatch)
116+UnitySortFilterProxyModelQML::setInvertMatch(bool invertMatch)
117117{
118118 if (invertMatch != m_invertMatch) {
119119 m_invertMatch = invertMatch;
@@ -123,7 +123,7 @@ QSortFilterProxyModelQML::setInvertMatch(bool invertMatch)
123123}
124124
125125bool
126−QSortFilterProxyModelQML::filterAcceptsRow(int sourceRow,
126+UnitySortFilterProxyModelQML::filterAcceptsRow(int sourceRow,
127127 const QModelIndex &sourceParent) const
128128{
129129 // If there's no regexp set, always accept all rows indepenently of the invertMatch setting
@@ -136,7 +136,7 @@ QSortFilterProxyModelQML::filterAcceptsRow(int sourceRow,
136136}
137137
138138int
139−QSortFilterProxyModelQML::findFirst(int role, const QVariant& value) const
139+UnitySortFilterProxyModelQML::findFirst(int role, const QVariant& value) const
140140{
141141 QModelIndexList matches = match(index(0, 0), role, value, 1, Qt::MatchExactly);
142142 if (!matches.isEmpty()) {
@@ -147,7 +147,7 @@ QSortFilterProxyModelQML::findFirst(int role, const QVariant& value) const
147147}
148148
149149int
150−QSortFilterProxyModelQML::mapFromSource(int row)
150+UnitySortFilterProxyModelQML::mapFromSource(int row)
151151{
152152 if (sourceModel() != nullptr) {
153153 return QSortFilterProxyModel::mapFromSource(sourceModel()->index(row, 0)).row();
@@ -157,7 +157,7 @@ QSortFilterProxyModelQML::mapFromSource(int row)
157157}
158158
159159int
160−QSortFilterProxyModelQML::mapToSource(int row)
160+UnitySortFilterProxyModelQML::mapToSource(int row)
161161{
162162 if (sourceModel() != nullptr) {
163163 return QSortFilterProxyModel::mapToSource(index(row, 0)).row();
plugins/Utils/qsortfilterproxymodelqml.h → plugins/Utils/unitysortfilterproxymodelqml.hrenamed+5−5
@@ -14,12 +14,12 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−#ifndef QSORTFILTERPROXYMODELQML_H
18−#define QSORTFILTERPROXYMODELQML_H
17+#ifndef UNITYSORTFILTERPROXYMODELQML_H
18+#define UNITYSORTFILTERPROXYMODELQML_H
1919
2020#include <QSortFilterProxyModel>
2121
22−class QSortFilterProxyModelQML : public QSortFilterProxyModel
22+class UnitySortFilterProxyModelQML : public QSortFilterProxyModel
2323{
2424 Q_OBJECT
2525
@@ -29,7 +29,7 @@ class QSortFilterProxyModelQML : public QSortFilterProxyModel
2929 Q_PROPERTY(bool invertMatch READ invertMatch WRITE setInvertMatch NOTIFY invertMatchChanged)
3030
3131public:
32− explicit QSortFilterProxyModelQML(QObject *parent = 0);
32+ explicit UnitySortFilterProxyModelQML(QObject *parent = 0);
3333
3434 Q_INVOKABLE QVariantMap get(int row); // Use with caution, it can be slow to query all the roles
3535 Q_INVOKABLE QVariant data(int row, int role);
@@ -60,4 +60,4 @@ private:
6060 bool m_invertMatch;
6161};
6262
63−#endif // QSORTFILTERPROXYMODELQML_H
63+#endif // UNITYSORTFILTERPROXYMODELQML_H
po/am.po+96−93
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-12-10 10:55+0100\n"
11−"PO-Revision-Date: 2014-11-06 00:53+0000\n"
11+"PO-Revision-Date: 2014-12-27 19:44+0000\n"
1212"Last-Translator: samson <Unknown>\n"
1313"Language-Team: Amharic <am@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2014-12-13 07:10+0000\n"
18+"X-Launchpad-Export-Date: 2014-12-28 06:07+0000\n"
1919"X-Generator: Launchpad (build 17286)\n"
2020
2121#: plugins/LightDM/Greeter.cpp:130
@@ -23,11 +23,11 @@ msgid "Password: "
2323msgstr "የ መግቢያ ቃል: "
2424
2525#: plugins/Unity/Launcher/launcheritem.cpp:45
26−#: plugins/Unity/Launcher/launcheritem.cpp:100
26+#: plugins/Unity/Launcher/launcheritem.cpp:91
2727msgid "Pin shortcut"
2828msgstr "አቋራጭ ማጣበቂያ"
2929
30−#: plugins/Unity/Launcher/launcheritem.cpp:100
30+#: plugins/Unity/Launcher/launcheritem.cpp:91
3131msgid "Unpin shortcut"
3232msgstr "አቋራጭ መለያያ"
3333
@@ -50,45 +50,45 @@ msgid_plural "Please wait %1 minutes and then try again…"
5050msgstr[0] "እባክዎን ይቆዩ %1 ደቂቃ እና ከዛ እንደ ገና ይምክሩ…"
5151msgstr[1] "እባክዎን ይቆዩ %1 ደቂቃዎች እና ከዛ እንደ ገና ይምክሩ…"
5252
53−#: qml/Components/Dialogs.qml:70
53+#: qml/Components/Dialogs.qml:74
5454msgid "Log out"
5555msgstr "መውጫ"
5656
57−#: qml/Components/Dialogs.qml:71
57+#: qml/Components/Dialogs.qml:75
5858msgid "Are you sure you want to log out?"
5959msgstr "በእርግጥ መውጣት ይፈልጋሉ?"
6060
61−#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
62−#: qml/Components/Dialogs.qml:122
61+#: qml/Components/Dialogs.qml:77 qml/Components/Dialogs.qml:101
62+#: qml/Components/Dialogs.qml:126
6363msgid "No"
6464msgstr "አይ"
6565
66−#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
67−#: qml/Components/Dialogs.qml:129
66+#: qml/Components/Dialogs.qml:84 qml/Components/Dialogs.qml:108
67+#: qml/Components/Dialogs.qml:133
6868msgid "Yes"
6969msgstr "አዎ"
7070
71−#: qml/Components/Dialogs.qml:94
71+#: qml/Components/Dialogs.qml:98
7272msgid "Shut down"
7373msgstr "ማጥፊያ"
7474
75−#: qml/Components/Dialogs.qml:95
75+#: qml/Components/Dialogs.qml:99
7676msgid "Are you sure you want to shut down?"
7777msgstr "በእርግጥ ማጥፋት ይፈልጋሉ?"
7878
79−#: qml/Components/Dialogs.qml:119
79+#: qml/Components/Dialogs.qml:123
8080msgid "Reboot"
8181msgstr "እንደገና ማስነሻ"
8282
83−#: qml/Components/Dialogs.qml:120
83+#: qml/Components/Dialogs.qml:124
8484msgid "Are you sure you want to reboot?"
8585msgstr "በእርግጥ እንደገና ማስነሳት ይፈልጋሉ?"
8686
87−#: qml/Components/Dialogs.qml:144
87+#: qml/Components/Dialogs.qml:148
8888msgid "Power"
8989msgstr "ሐይል"
9090
91−#: qml/Components/Dialogs.qml:145
91+#: qml/Components/Dialogs.qml:149
9292msgid ""
9393"Are you sure you would like\n"
9494"to power off?"
@@ -96,15 +96,15 @@ msgstr ""
9696"በእርግጥ ሐይሉን ማጥፋት\n"
9797"ይፈልጋሉ?"
9898
99−#: qml/Components/Dialogs.qml:147
99+#: qml/Components/Dialogs.qml:151
100100msgid "Power off"
101101msgstr "ማጥፊያ"
102102
103−#: qml/Components/Dialogs.qml:157
103+#: qml/Components/Dialogs.qml:161
104104msgid "Restart"
105105msgstr "እንደገና ማስጀመሪያ"
106106
107−#: qml/Components/Dialogs.qml:167
107+#: qml/Components/Dialogs.qml:171
108108msgid "Cancel"
109109msgstr "መሰረዣ"
110110
@@ -112,87 +112,87 @@ msgstr "መሰረዣ"
112112msgid "Skip intro"
113113msgstr "መግቢያውን መዝለያ"
114114
115−#: qml/Components/EdgeDemo.qml:125
115+#: qml/Components/EdgeDemo.qml:112
116116msgid "Right edge"
117117msgstr "የቀኝ ጠርዝ"
118118
119−#: qml/Components/EdgeDemo.qml:126
119+#: qml/Components/EdgeDemo.qml:113
120120msgid "Try swiping from the right edge to unlock the phone"
121121msgstr "ስልኩን ለመክፈት ከ ቀኝ ጠርዝ በኩል ወደ ግራ ይጥረጉ"
122122
123−#: qml/Components/EdgeDemo.qml:157
123+#: qml/Components/EdgeDemo.qml:144
124124msgid "Top edge"
125125msgstr "የላይ ጠርዝ"
126126
127−#: qml/Components/EdgeDemo.qml:158
127+#: qml/Components/EdgeDemo.qml:145
128128msgid "Try swiping from the top edge to access the indicators"
129129msgstr "ጠቋሚዎች ጋር ለመድረስ ከ ላይ ጠርዝ በኩል ወደ ታች ይጥረጉ"
130130
131−#: qml/Components/EdgeDemo.qml:183
131+#: qml/Components/EdgeDemo.qml:170
132132msgid "Close"
133133msgstr "መዝጊያ"
134134
135−#: qml/Components/EdgeDemo.qml:184
135+#: qml/Components/EdgeDemo.qml:171
136136msgid "Swipe up again to close the settings screen"
137137msgstr "የማሰናጃውን መመልከቻ ለመዝጋት እንደገና ወደ ላይ ይጥረጉ"
138138
139−#: qml/Components/EdgeDemo.qml:214
139+#: qml/Components/EdgeDemo.qml:201
140140msgid "Left edge"
141141msgstr "የግራ ጠርዝ"
142142
143−#: qml/Components/EdgeDemo.qml:215
143+#: qml/Components/EdgeDemo.qml:202
144144msgid "Swipe from the left to reveal the launcher for quick access to apps"
145145msgstr "ከ ግራ በኩል ወደ ቀኝ ይጥረጉ በፍጥነት መተግበሪያዎች ጋር ለመድረስ እና ለማስጀመር"
146146
147−#: qml/Components/EdgeDemo.qml:242
147+#: qml/Components/EdgeDemo.qml:229
148148msgid "Well done"
149149msgstr "ጥሩ አድረገዋል"
150150
151−#: qml/Components/EdgeDemo.qml:243
151+#: qml/Components/EdgeDemo.qml:230
152152msgid ""
153153"You have now mastered the edge gestures and can start using the "
154154"phone<br><br>Tap on the screen to start"
155155msgstr ""
156156"አሁን የ ጠርዝ እንቅስቃሴን አውቀዋል እና መጀመር ይችላሉ ስልኩን መጠቀም <br><br>መመልከቻውን መታ ያድርጉ ለመጀመር"
157157
158−#: qml/Components/Lockscreen.qml:238
158+#: qml/Components/Lockscreen.qml:223
159159msgid "Return to Call"
160160msgstr "ወደ ጥሪ መመለሻ"
161161
162−#: qml/Components/Lockscreen.qml:238
162+#: qml/Components/Lockscreen.qml:223
163163msgid "Emergency Call"
164164msgstr "የ ድንገተኛ ጥሪ"
165165
166−#: qml/Components/Lockscreen.qml:270
166+#: qml/Components/Lockscreen.qml:255
167167msgid "OK"
168168msgstr "እሺ"
169169
170−#: qml/Dash/GenericScopeView.qml:431 qml/Dash/GenericScopeView.qml:588
170+#: qml/Dash/GenericScopeView.qml:434 qml/Dash/GenericScopeView.qml:591
171171msgid "See less"
172172msgstr "አነስተኛ መመልከቻ"
173173
174−#: qml/Dash/GenericScopeView.qml:431
174+#: qml/Dash/GenericScopeView.qml:434
175175msgid "See all"
176176msgstr "ሁሉንም መመልከቻ"
177177
178−#: qml/Dash/GenericScopeView.qml:493 qml/Dash/PageHeader.qml:267
178+#: qml/Dash/GenericScopeView.qml:496 qml/Dash/PageHeader.qml:268
179179#: qml/Panel/SearchIndicator.qml:27
180180msgid "Search"
181181msgstr "መፈለጊያ"
182182
183−#: qml/Dash/PageHeader.qml:260
183+#: qml/Dash/PageHeader.qml:261
184184msgid "Store"
185185msgstr "ማስቀመጫ"
186186
187−#: qml/Dash/PageHeader.qml:277
187+#: qml/Dash/PageHeader.qml:278
188188msgid "Settings"
189189msgstr "ማሰናጃ"
190190
191−#: qml/Dash/PageHeader.qml:284
191+#: qml/Dash/PageHeader.qml:285
192192msgid "Remove from Favorites"
193193msgstr "ከምወዳቸው ማስወገጃ"
194194
195−#: qml/Dash/PageHeader.qml:284
195+#: qml/Dash/PageHeader.qml:285
196196msgid "Add to Favorites"
197197msgstr "ወደምወዳቸው መጨመሪያ"
198198
@@ -226,15 +226,15 @@ msgstr "ይልቀቁ ለማነቃቃት…"
226226
227227#: qml/Dash/ScopesList.qml:63
228228msgid "Manage"
229−msgstr ""
229+msgstr "አስተዳዳሪ"
230230
231231#: qml/Dash/ScopesList.qml:107
232232msgid "Home"
233−msgstr ""
233+msgstr "ቤት"
234234
235235#: qml/Dash/ScopesList.qml:108
236236msgid "Also installed"
237−msgstr ""
237+msgstr "እንዲሁም የተገጠሙ"
238238
239239#: qml/Greeter/Greeter.qml:174
240240msgid "Unlock"
@@ -288,49 +288,49 @@ msgstr "ሲም መክፈቻ"
288288msgid "Roaming"
289289msgstr "ማዘዋወሪያ"
290290
291−#: qml/Shell.qml:367
291+#: qml/Shell.qml:402
292292#, qt-format
293293msgid "Enter %1"
294294msgstr "ማስገቢያ %1"
295295
296−#: qml/Shell.qml:368 qml/Wizard/Pages/passwd-set.qml:60
296+#: qml/Shell.qml:394
297297msgid "Enter passphrase"
298298msgstr "የ ማለፊያ ሀረግ ያስገቡ"
299299
300−#: qml/Shell.qml:369
300+#: qml/Shell.qml:398
301301msgid "Enter passcode"
302302msgstr "የ ማለፊያ ኮድ ያስገቡ"
303303
304−#: qml/Shell.qml:370
304+#: qml/Shell.qml:403
305305#, qt-format
306306msgid "Sorry, incorrect %1"
307307msgstr "አዝናለሁ: የተሳሳተ%1"
308308
309−#: qml/Shell.qml:371
309+#: qml/Shell.qml:395
310310msgid "Sorry, incorrect passphrase"
311311msgstr "አዝናለሁ የተሳሳተ የማለፊያ ሐረግ"
312312
313−#: qml/Shell.qml:372
313+#: qml/Shell.qml:396
314314msgid "Please re-enter"
315315msgstr "እባክዎን እንደገና-ያስገቡ"
316316
317−#: qml/Shell.qml:373
317+#: qml/Shell.qml:399
318318msgid "Sorry, incorrect passcode"
319319msgstr "አዝናለሁ የተሳሳተ የማለፊያ ኮድ"
320320
321−#: qml/Shell.qml:467 qml/Wizard/Pages/passwd-confirm.qml:53
321+#: qml/Shell.qml:444
322322msgid "Sorry, incorrect passphrase."
323323msgstr "አዝናለሁ የተሳሳተ የማለፊያ ሐረግ"
324324
325−#: qml/Shell.qml:468 qml/Wizard/Pages/passwd-confirm.qml:54
325+#: qml/Shell.qml:445
326326msgid "Sorry, incorrect passcode."
327327msgstr "አዝናለሁ የተሳሳተ የማለፊያ ኮድ"
328328
329−#: qml/Shell.qml:469
329+#: qml/Shell.qml:446
330330msgid "This will be your last attempt."
331331msgstr "ይህ የመጨረሻ ሙከራዎ ነው"
332332
333−#: qml/Shell.qml:471
333+#: qml/Shell.qml:448
334334msgid ""
335335"If passphrase is entered incorrectly, your phone will conduct a factory "
336336"reset and all personal data will be deleted."
@@ -338,7 +338,7 @@ msgstr ""
338338"የተሳሳተ የማለፊያ ሐረግ ካስገቡ የ እርስዎ ስልክ ወደ ነበረበት ወደ ፋክቶሪው ዘዴ ይመለሳል: እና የ ግል ዳታ በሙሉ "
339339"ይጠፋል"
340340
341−#: qml/Shell.qml:472
341+#: qml/Shell.qml:449
342342msgid ""
343343"If passcode is entered incorrectly, your phone will conduct a factory reset "
344344"and all personal data will be deleted."
@@ -348,180 +348,183 @@ msgstr ""
348348
349349#: qml/Wizard/Page.qml:89
350350msgid "Back"
351−msgstr ""
351+msgstr "ወደ ኋላ"
352352
353353#: qml/Wizard/Pages/10-welcome.qml:27
354354msgid "Hi!"
355−msgstr ""
355+msgstr "ሰላም"
356356
357357#: qml/Wizard/Pages/10-welcome.qml:44
358358msgid "Welcome to your Ubuntu phone."
359−msgstr ""
359+msgstr "እንኳን ደህና መጡ ወደ እርስዎ ኡቡንቱ ስልክ"
360360
361361#: qml/Wizard/Pages/10-welcome.qml:52
362362msgid "Let’s get started."
363−msgstr ""
363+msgstr "ስራ እንጀምር"
364364
365365#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:128
366366#: qml/Wizard/Pages/40-wifi.qml:197 qml/Wizard/Pages/50-location.qml:131
367367#: qml/Wizard/Pages/60-reporting.qml:50 qml/Wizard/Pages/passwd-confirm.qml:82
368368#: qml/Wizard/Pages/passwd-set.qml:90
369369msgid "Continue"
370−msgstr ""
370+msgstr "ይቀጥሉ"
371371
372372#: qml/Wizard/Pages/20-sim.qml:25
373373msgid "Add a SIM card and restart your device"
374−msgstr ""
374+msgstr "የ ሲም ካርድ ይጨምሩ እና አካሉን እንደገና ያስነሱ"
375375
376376#: qml/Wizard/Pages/20-sim.qml:55
377377msgid "Without it, you won’t be able to make calls or use text messaging."
378−msgstr ""
378+msgstr "ያለ እሱ ጥሪ መፈጸም ወይንም የ ጽሁፍ መልእክት መላክ አይችሉም"
379379
380380#: qml/Wizard/Pages/20-sim.qml:69 qml/Wizard/Pages/40-wifi.qml:197
381381msgid "Skip"
382−msgstr ""
382+msgstr "መዝለያ"
383383
384384#: qml/Wizard/Pages/30-passwd-type.qml:39
385385msgid "Lock security"
386−msgstr ""
386+msgstr "ደህንነት መቆለፊያ"
387387
388388#: qml/Wizard/Pages/30-passwd-type.qml:74
389389msgid "Please select how you’d like to unlock your phone."
390−msgstr ""
390+msgstr "እባክዎን የ እርስዎን ስልክ እንዴት እንደሚከፍቱ ይምረጡ"
391391
392392#: qml/Wizard/Pages/30-passwd-type.qml:97
393393msgid "Swipe"
394−msgstr ""
394+msgstr "መጥረጊያ"
395395
396396#: qml/Wizard/Pages/30-passwd-type.qml:98
397397msgid "No security"
398−msgstr ""
398+msgstr "ደህንነት አልተገኘም"
399399
400400#: qml/Wizard/Pages/30-passwd-type.qml:100
401401msgid "Passcode"
402−msgstr ""
402+msgstr "ማለፊያ ኮድ"
403403
404404#: qml/Wizard/Pages/30-passwd-type.qml:101
405405msgid "4 digits only"
406−msgstr ""
406+msgstr "4 ዲጂትስ ብቻ"
407407
408408#: qml/Wizard/Pages/30-passwd-type.qml:103
409409msgid "Passphrase"
410−msgstr ""
410+msgstr "ማለፊያ ሐረግ"
411411
412412#: qml/Wizard/Pages/30-passwd-type.qml:104
413413msgid "Numbers and letters"
414−msgstr ""
414+msgstr "ቁጥሮች እና ፊደሎች"
415415
416416#: qml/Wizard/Pages/40-wifi.qml:28
417417msgid "Connect to Wi‑Fi"
418−msgstr ""
418+msgstr "ወደ ዋይ‑ፋይ መገናኛ"
419419
420420#: qml/Wizard/Pages/40-wifi.qml:147
421421msgid "Available networks…"
422−msgstr ""
422+msgstr "ዝግጁ ኔትዎርኮች…"
423423
424424#: qml/Wizard/Pages/40-wifi.qml:148
425425msgid "No available networks."
426−msgstr ""
426+msgstr "ዝግጁ ኔትዎርኮች አልተገኙም"
427427
428428#: qml/Wizard/Pages/50-location.qml:27
429429msgid "Location"
430−msgstr ""
430+msgstr "አካባቢ"
431431
432432#: qml/Wizard/Pages/50-location.qml:62
433433msgid "Let the phone detect your location:"
434−msgstr ""
434+msgstr "እባክዎን እርስዎ ያሉበትን አካባቢ ስልኩ እራሱ ይፈልግ:"
435435
436436#: qml/Wizard/Pages/50-location.qml:69
437437msgid "Using GPS only (less accurate)"
438−msgstr ""
438+msgstr "ጂፒኤስን ብቻ መጠቀሚያ(በጣም ቅርብ)"
439439
440440#: qml/Wizard/Pages/50-location.qml:86
441441msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
442−msgstr ""
442+msgstr "ይጠቀሙ ጂፒኤስ ግልጽ ያልሆነ ዋይ-ፋይ እና ተንቀሳቃሽ ኔትዎርክ መረጃ (ይመከራሉ)"
443443
444444#. TRANSLATORS: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
445445#: qml/Wizard/Pages/50-location.qml:103
446446msgid ""
447447"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
448448"conditions</a>."
449−msgstr ""
449+msgstr "ይህን ምርጫ በመምረጥ ተስማምቻለሁ ከ Nokia HERE <a href='#'>ውሎች እና ሁኔታዎች ጋር</a>."
450450
451451#: qml/Wizard/Pages/50-location.qml:112
452452msgid "Not at all"
453−msgstr ""
453+msgstr "አይደለም"
454454
455455#: qml/Wizard/Pages/50-location.qml:124
456456msgid "You can change your mind later in <b>System Settings</b>."
457−msgstr ""
457+msgstr "እርስዎ በኋላ መቀየር ይችላሉ ከ <b>ስርአት ማሰናጃዎች</b>."
458458
459459#: qml/Wizard/Pages/60-reporting.qml:24
460460msgid "Improving your experience"
461−msgstr ""
461+msgstr "የ እርስዎን ልምምድ ማሻሻያ"
462462
463463#: qml/Wizard/Pages/60-reporting.qml:36
464464msgid ""
465465"Your phone is set up to automatically report errors to Canonical and its "
466466"partners, the makers of the operating system."
467467msgstr ""
468+"የ እርስዎ ስልክ ራሱ በራሱ የ ስህተት መግለጫዎች ወደ Canonical and its partners, የ መስሪያ ስርአት "
469+"አምራቾች"
468470
469471#: qml/Wizard/Pages/60-reporting.qml:43
470472msgid ""
471473"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
472474"Privacy</b>"
473475msgstr ""
476+"ይህን ግልጋሎት ማሰናከል ይችላሉ ከ <b>ስርአት ማሰናጃዎች</b> under <b>Security &amp; Privacy</b>"
474477
475478#: qml/Wizard/Pages/80-finished.qml:24
476479msgid "All done"
477−msgstr ""
480+msgstr "ሁሉም ተፈጽሟል"
478481
479482#: qml/Wizard/Pages/80-finished.qml:39
480483msgid "Nice work!"
481−msgstr ""
484+msgstr "ጥሩ ሰርተዋል!"
482485
483486#: qml/Wizard/Pages/80-finished.qml:46
484487msgid "Your phone is now ready to use."
485−msgstr ""
488+msgstr "ስልኩ አሁን ለመጠቀም ዝግጁ ነው"
486489
487490#: qml/Wizard/Pages/80-finished.qml:53
488491msgid "Finish"
489−msgstr ""
492+msgstr "መጨረሻ"
490493
491494#: qml/Wizard/Pages/here-terms.qml:27
492495msgid "Terms & Conditions"
493−msgstr ""
496+msgstr "ውሎች & ሁኔታዎች"
494497
495498#: qml/Wizard/Pages/passwd-confirm.qml:49
496499msgid "Confirm passphrase"
497−msgstr ""
500+msgstr "የ ማለፊያ ሐረግ ማረጋገጫ"
498501
499502#: qml/Wizard/Pages/passwd-confirm.qml:50
500503msgid "Confirm passcode"
501−msgstr ""
504+msgstr "የማለፊያ ኮድ ማረጋገጫ"
502505
503506#: qml/Wizard/Pages/passwd-confirm.qml:53
504507#: qml/Wizard/Pages/passwd-confirm.qml:54
505508msgid "Please try again."
506−msgstr ""
509+msgstr "እባክዎን እንደገና ይሞክሩ"
507510
508511#: qml/Wizard/Pages/passwd-set.qml:61
509512msgid "Choose your passcode"
510−msgstr ""
513+msgstr "የ እርስዎን የማለፊያ ኮድ ይምረጡ"
511514
512515#: qml/Wizard/Pages/passwd-set.qml:68
513516msgid "Passphrase must be 4 characters long"
514−msgstr ""
517+msgstr "የ ማለፊያ ሀረግ ቢያንስ 4 ባህሪዎች መሆን አለበት"
515518
516519#: qml/Wizard/StackButton.qml:39
517520#, qt-format
518521msgid "〈 %1"
519−msgstr ""
522+msgstr "〈 %1"
520523
521524#: qml/Wizard/StackButton.qml:42
522525#, qt-format
523526msgid "%1 〉"
524−msgstr ""
527+msgstr "%1 〉"
525528
526529#~ msgid "Type or say a command"
527530#~ msgstr "ትእዛዝ ይናገሩ ወይንም ይጻፉ"
po/br.po+1−1
@@ -15,7 +15,7 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2014-12-16 07:34+0000\n"
18+"X-Launchpad-Export-Date: 2014-12-17 07:06+0000\n"
1919"X-Generator: Launchpad (build 17286)\n"
2020
2121#: plugins/LightDM/Greeter.cpp:130
po/hu.po+61−61
@@ -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: 2014-12-10 10:55+0100\n"
11−"PO-Revision-Date: 2014-12-15 15:26+0000\n"
11+"PO-Revision-Date: 2014-12-21 15:13+0000\n"
1212"Last-Translator: Richard Somlói <ricsipontaz@gmail.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"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-12-16 07:34+0000\n"
18+"X-Launchpad-Export-Date: 2014-12-22 07:05+0000\n"
1919"X-Generator: Launchpad (build 17286)\n"
2020
2121#: plugins/LightDM/Greeter.cpp:130
@@ -23,11 +23,11 @@ msgid "Password: "
2323msgstr "Jelszó: "
2424
2525#: plugins/Unity/Launcher/launcheritem.cpp:45
26−#: plugins/Unity/Launcher/launcheritem.cpp:100
26+#: plugins/Unity/Launcher/launcheritem.cpp:91
2727msgid "Pin shortcut"
2828msgstr "Indító rögzítése"
2929
30−#: plugins/Unity/Launcher/launcheritem.cpp:100
30+#: plugins/Unity/Launcher/launcheritem.cpp:91
3131msgid "Unpin shortcut"
3232msgstr "Indító feloldása"
3333
@@ -47,48 +47,48 @@ msgstr "A túl sok hibás jelkód próbálkozás miatt le lett zárva az eszköz
4747#, qt-format
4848msgid "Please wait %1 minute and then try again…"
4949msgid_plural "Please wait %1 minutes and then try again…"
50−msgstr[0] "Kérjük várjon %1 percet és próbálja újra…"
51−msgstr[1] "Kérjük várjon %1 percet és próbálja újra…"
50+msgstr[0] "Várjon %1 percet és próbálja újra…"
51+msgstr[1] "Várjon %1 percet és próbálja újra…"
5252
53−#: qml/Components/Dialogs.qml:70
53+#: qml/Components/Dialogs.qml:74
5454msgid "Log out"
5555msgstr "Kijelentkezés"
5656
57−#: qml/Components/Dialogs.qml:71
57+#: qml/Components/Dialogs.qml:75
5858msgid "Are you sure you want to log out?"
5959msgstr "Biztos benne, hogy kijelentkezik?"
6060
61−#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
62−#: qml/Components/Dialogs.qml:122
61+#: qml/Components/Dialogs.qml:77 qml/Components/Dialogs.qml:101
62+#: qml/Components/Dialogs.qml:126
6363msgid "No"
6464msgstr "Nem"
6565
66−#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
67−#: qml/Components/Dialogs.qml:129
66+#: qml/Components/Dialogs.qml:84 qml/Components/Dialogs.qml:108
67+#: qml/Components/Dialogs.qml:133
6868msgid "Yes"
6969msgstr "Igen"
7070
71−#: qml/Components/Dialogs.qml:94
71+#: qml/Components/Dialogs.qml:98
7272msgid "Shut down"
7373msgstr "Leállítás"
7474
75−#: qml/Components/Dialogs.qml:95
75+#: qml/Components/Dialogs.qml:99
7676msgid "Are you sure you want to shut down?"
7777msgstr "Biztosan le szeretné állítani?"
7878
79−#: qml/Components/Dialogs.qml:119
79+#: qml/Components/Dialogs.qml:123
8080msgid "Reboot"
8181msgstr "Újraindítás"
8282
83−#: qml/Components/Dialogs.qml:120
83+#: qml/Components/Dialogs.qml:124
8484msgid "Are you sure you want to reboot?"
8585msgstr "Biztosan újra szeretné indítani?"
8686
87−#: qml/Components/Dialogs.qml:144
87+#: qml/Components/Dialogs.qml:148
8888msgid "Power"
8989msgstr "Kikapcsolás"
9090
91−#: qml/Components/Dialogs.qml:145
91+#: qml/Components/Dialogs.qml:149
9292msgid ""
9393"Are you sure you would like\n"
9494"to power off?"
@@ -96,15 +96,15 @@ msgstr ""
9696"Biztos benne, hogy ki\n"
9797"szeretné kapcsolni?"
9898
99−#: qml/Components/Dialogs.qml:147
99+#: qml/Components/Dialogs.qml:151
100100msgid "Power off"
101101msgstr "Kikapcsolás"
102102
103−#: qml/Components/Dialogs.qml:157
103+#: qml/Components/Dialogs.qml:161
104104msgid "Restart"
105105msgstr "Újraindítás"
106106
107−#: qml/Components/Dialogs.qml:167
107+#: qml/Components/Dialogs.qml:171
108108msgid "Cancel"
109109msgstr "Mégse"
110110
@@ -112,45 +112,45 @@ msgstr "Mégse"
112112msgid "Skip intro"
113113msgstr "A bemutató kihagyása"
114114
115−#: qml/Components/EdgeDemo.qml:125
115+#: qml/Components/EdgeDemo.qml:112
116116msgid "Right edge"
117117msgstr "Jobb szél"
118118
119−#: qml/Components/EdgeDemo.qml:126
119+#: qml/Components/EdgeDemo.qml:113
120120msgid "Try swiping from the right edge to unlock the phone"
121121msgstr "A telefon feloldásához csúsztassa ujját a jobb szélről"
122122
123−#: qml/Components/EdgeDemo.qml:157
123+#: qml/Components/EdgeDemo.qml:144
124124msgid "Top edge"
125125msgstr "Felső szél"
126126
127−#: qml/Components/EdgeDemo.qml:158
127+#: qml/Components/EdgeDemo.qml:145
128128msgid "Try swiping from the top edge to access the indicators"
129129msgstr "Az állapotmenük eléréséhez csúsztassa ujját a felső szélről"
130130
131−#: qml/Components/EdgeDemo.qml:183
131+#: qml/Components/EdgeDemo.qml:170
132132msgid "Close"
133133msgstr "Bezárás"
134134
135−#: qml/Components/EdgeDemo.qml:184
135+#: qml/Components/EdgeDemo.qml:171
136136msgid "Swipe up again to close the settings screen"
137137msgstr "A beállítások bezárásához csúsztassa ujját újra felfelé"
138138
139−#: qml/Components/EdgeDemo.qml:214
139+#: qml/Components/EdgeDemo.qml:201
140140msgid "Left edge"
141141msgstr "Bal szél"
142142
143−#: qml/Components/EdgeDemo.qml:215
143+#: qml/Components/EdgeDemo.qml:202
144144msgid "Swipe from the left to reveal the launcher for quick access to apps"
145145msgstr ""
146146"Csúsztassa ujját a bal szélről az indítón található alkalmazások gyors "
147147"eléréséhez"
148148
149−#: qml/Components/EdgeDemo.qml:242
149+#: qml/Components/EdgeDemo.qml:229
150150msgid "Well done"
151151msgstr "Rendben"
152152
153−#: qml/Components/EdgeDemo.qml:243
153+#: qml/Components/EdgeDemo.qml:230
154154msgid ""
155155"You have now mastered the edge gestures and can start using the "
156156"phone<br><br>Tap on the screen to start"
@@ -158,44 +158,44 @@ msgstr ""
158158"Elsajátította a gesztusokat, és megkezdheti a telefon "
159159"használatát.<br><br>Koppintson a képernyőre a kezdéshez."
160160
161−#: qml/Components/Lockscreen.qml:238
161+#: qml/Components/Lockscreen.qml:223
162162msgid "Return to Call"
163163msgstr "Vissza a híváshoz"
164164
165−#: qml/Components/Lockscreen.qml:238
165+#: qml/Components/Lockscreen.qml:223
166166msgid "Emergency Call"
167167msgstr "Vészhívás"
168168
169−#: qml/Components/Lockscreen.qml:270
169+#: qml/Components/Lockscreen.qml:255
170170msgid "OK"
171171msgstr "Ok"
172172
173−#: qml/Dash/GenericScopeView.qml:431 qml/Dash/GenericScopeView.qml:588
173+#: qml/Dash/GenericScopeView.qml:434 qml/Dash/GenericScopeView.qml:591
174174msgid "See less"
175175msgstr "Kevesebb"
176176
177−#: qml/Dash/GenericScopeView.qml:431
177+#: qml/Dash/GenericScopeView.qml:434
178178msgid "See all"
179179msgstr "Összes megtekintése"
180180
181−#: qml/Dash/GenericScopeView.qml:493 qml/Dash/PageHeader.qml:267
181+#: qml/Dash/GenericScopeView.qml:496 qml/Dash/PageHeader.qml:268
182182#: qml/Panel/SearchIndicator.qml:27
183183msgid "Search"
184184msgstr "Keresés"
185185
186−#: qml/Dash/PageHeader.qml:260
186+#: qml/Dash/PageHeader.qml:261
187187msgid "Store"
188188msgstr "Áruház"
189189
190−#: qml/Dash/PageHeader.qml:277
190+#: qml/Dash/PageHeader.qml:278
191191msgid "Settings"
192192msgstr "Beállítások"
193193
194−#: qml/Dash/PageHeader.qml:284
194+#: qml/Dash/PageHeader.qml:285
195195msgid "Remove from Favorites"
196196msgstr "Eltávolítás a kedvencek közül"
197197
198−#: qml/Dash/PageHeader.qml:284
198+#: qml/Dash/PageHeader.qml:285
199199msgid "Add to Favorites"
200200msgstr "Hozzáadás a kedvencekhez"
201201
@@ -229,11 +229,11 @@ msgstr "Engedje el a frissítéshez…"
229229
230230#: qml/Dash/ScopesList.qml:63
231231msgid "Manage"
232−msgstr ""
232+msgstr "Kezelés"
233233
234234#: qml/Dash/ScopesList.qml:107
235235msgid "Home"
236−msgstr ""
236+msgstr "Kezdőlapon"
237237
238238#: qml/Dash/ScopesList.qml:108
239239msgid "Also installed"
@@ -291,49 +291,49 @@ msgstr "SIM feloldása"
291291msgid "Roaming"
292292msgstr "Barangolás"
293293
294−#: qml/Shell.qml:367
294+#: qml/Shell.qml:402
295295#, qt-format
296296msgid "Enter %1"
297297msgstr "Adja meg: %1"
298298
299−#: qml/Shell.qml:368 qml/Wizard/Pages/passwd-set.qml:60
299+#: qml/Shell.qml:394
300300msgid "Enter passphrase"
301301msgstr "Jelmondat megadása"
302302
303−#: qml/Shell.qml:369
303+#: qml/Shell.qml:398
304304msgid "Enter passcode"
305305msgstr "Jelkód megadása"
306306
307−#: qml/Shell.qml:370
307+#: qml/Shell.qml:403
308308#, qt-format
309309msgid "Sorry, incorrect %1"
310−msgstr "Sajnáljuk, helytelen %1"
310+msgstr "Sajnálom, helytelen %1"
311311
312−#: qml/Shell.qml:371
312+#: qml/Shell.qml:395
313313msgid "Sorry, incorrect passphrase"
314−msgstr "Sajnáljuk, helytelen jelmondat"
314+msgstr "Sajnálom, helytelen jelmondat"
315315
316−#: qml/Shell.qml:372
316+#: qml/Shell.qml:396
317317msgid "Please re-enter"
318−msgstr "Kérjük próbálja újra"
318+msgstr "Próbálja újra"
319319
320−#: qml/Shell.qml:373
320+#: qml/Shell.qml:399
321321msgid "Sorry, incorrect passcode"
322−msgstr "Sajnáljuk, helytelen jelkód"
322+msgstr "Sajnálom, helytelen jelkód"
323323
324−#: qml/Shell.qml:467 qml/Wizard/Pages/passwd-confirm.qml:53
324+#: qml/Shell.qml:444
325325msgid "Sorry, incorrect passphrase."
326−msgstr "Sajnáljuk, helytelen jelmondat."
326+msgstr "Sajnálom, helytelen jelmondat."
327327
328−#: qml/Shell.qml:468 qml/Wizard/Pages/passwd-confirm.qml:54
328+#: qml/Shell.qml:445
329329msgid "Sorry, incorrect passcode."
330−msgstr "Sajnáljuk, helytelen jelkód."
330+msgstr "Sajnálom, helytelen jelkód."
331331
332−#: qml/Shell.qml:469
332+#: qml/Shell.qml:446
333333msgid "This will be your last attempt."
334334msgstr "Ez az utolsó próbálkozási lehetősége."
335335
336−#: qml/Shell.qml:471
336+#: qml/Shell.qml:448
337337msgid ""
338338"If passphrase is entered incorrectly, your phone will conduct a factory "
339339"reset and all personal data will be deleted."
@@ -341,7 +341,7 @@ msgstr ""
341341"Ha helytelen jelmondatot ad meg, a telefonja visszaállítja a gyári "
342342"beállításokat és törli minden személyes adatát."
343343
344−#: qml/Shell.qml:472
344+#: qml/Shell.qml:449
345345msgid ""
346346"If passcode is entered incorrectly, your phone will conduct a factory reset "
347347"and all personal data will be deleted."
po/ro.po+101−90
@@ -8,7 +8,7 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-12-10 10:55+0100\n"
11−"PO-Revision-Date: 2014-11-18 12:09+0000\n"
11+"PO-Revision-Date: 2015-01-07 11:11+0000\n"
1212"Last-Translator: Marian Vasile <marianvasile1972@gmail.com>\n"
1313"Language-Team: Romanian <ro@li.org>\n"
1414"MIME-Version: 1.0\n"
@@ -16,19 +16,19 @@ msgstr ""
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=3; plural=(n == 1 ? 0: (((n % 100 > 19) || ((n % 100 "
1818"== 0) && (n != 0))) ? 2: 1));\n"
19−"X-Launchpad-Export-Date: 2014-12-13 07:11+0000\n"
20−"X-Generator: Launchpad (build 17286)\n"
19+"X-Launchpad-Export-Date: 2015-01-08 07:10+0000\n"
20+"X-Generator: Launchpad (build 17298)\n"
2121
2222#: plugins/LightDM/Greeter.cpp:130
2323msgid "Password: "
2424msgstr "Parolă: "
2525
2626#: plugins/Unity/Launcher/launcheritem.cpp:45
27−#: plugins/Unity/Launcher/launcheritem.cpp:100
27+#: plugins/Unity/Launcher/launcheritem.cpp:91
2828msgid "Pin shortcut"
2929msgstr "Fixează scurtătura"
3030
31−#: plugins/Unity/Launcher/launcheritem.cpp:100
31+#: plugins/Unity/Launcher/launcheritem.cpp:91
3232msgid "Unpin shortcut"
3333msgstr "Eliberează scurtătura"
3434
@@ -55,45 +55,45 @@ msgstr[0] "Așteptați %1 minut și apoi încercați din nou..."
5555msgstr[1] "Așteptați %1 minute și apoi încercați din nou..."
5656msgstr[2] "Așteptați %1 de minute și apoi încercați din nou..."
5757
58−#: qml/Components/Dialogs.qml:70
58+#: qml/Components/Dialogs.qml:74
5959msgid "Log out"
6060msgstr "Închide sesiunea"
6161
62−#: qml/Components/Dialogs.qml:71
62+#: qml/Components/Dialogs.qml:75
6363msgid "Are you sure you want to log out?"
6464msgstr "Sunteți sigur că doriți să închideți sesiunea?"
6565
66−#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
67−#: qml/Components/Dialogs.qml:122
66+#: qml/Components/Dialogs.qml:77 qml/Components/Dialogs.qml:101
67+#: qml/Components/Dialogs.qml:126
6868msgid "No"
6969msgstr "Nu"
7070
71−#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
72−#: qml/Components/Dialogs.qml:129
71+#: qml/Components/Dialogs.qml:84 qml/Components/Dialogs.qml:108
72+#: qml/Components/Dialogs.qml:133
7373msgid "Yes"
7474msgstr "Da"
7575
76−#: qml/Components/Dialogs.qml:94
76+#: qml/Components/Dialogs.qml:98
7777msgid "Shut down"
7878msgstr "Închideți"
7979
80−#: qml/Components/Dialogs.qml:95
80+#: qml/Components/Dialogs.qml:99
8181msgid "Are you sure you want to shut down?"
8282msgstr "Sunteți sigur că doriți să închideți?"
8383
84−#: qml/Components/Dialogs.qml:119
84+#: qml/Components/Dialogs.qml:123
8585msgid "Reboot"
8686msgstr "Repornire"
8787
88−#: qml/Components/Dialogs.qml:120
88+#: qml/Components/Dialogs.qml:124
8989msgid "Are you sure you want to reboot?"
9090msgstr "Sunteți sigur că doriți să reporniți?"
9191
92−#: qml/Components/Dialogs.qml:144
92+#: qml/Components/Dialogs.qml:148
9393msgid "Power"
9494msgstr "Alimentare"
9595
96−#: qml/Components/Dialogs.qml:145
96+#: qml/Components/Dialogs.qml:149
9797msgid ""
9898"Are you sure you would like\n"
9999"to power off?"
@@ -101,15 +101,15 @@ msgstr ""
101101"Sunteți sigur că doriți să\n"
102102"opriți alimentarea?"
103103
104−#: qml/Components/Dialogs.qml:147
104+#: qml/Components/Dialogs.qml:151
105105msgid "Power off"
106106msgstr "Oprire"
107107
108−#: qml/Components/Dialogs.qml:157
108+#: qml/Components/Dialogs.qml:161
109109msgid "Restart"
110110msgstr "Repornire"
111111
112−#: qml/Components/Dialogs.qml:167
112+#: qml/Components/Dialogs.qml:171
113113msgid "Cancel"
114114msgstr "Anulează"
115115
@@ -117,46 +117,46 @@ msgstr "Anulează"
117117msgid "Skip intro"
118118msgstr "Sari peste introducere"
119119
120−#: qml/Components/EdgeDemo.qml:125
120+#: qml/Components/EdgeDemo.qml:112
121121msgid "Right edge"
122122msgstr "Marginea din dreapta"
123123
124−#: qml/Components/EdgeDemo.qml:126
124+#: qml/Components/EdgeDemo.qml:113
125125msgid "Try swiping from the right edge to unlock the phone"
126126msgstr "Glisați de la dreapta spre stânga pentru a debloca telefonul"
127127
128−#: qml/Components/EdgeDemo.qml:157
128+#: qml/Components/EdgeDemo.qml:144
129129msgid "Top edge"
130130msgstr "Marginea de sus"
131131
132−#: qml/Components/EdgeDemo.qml:158
132+#: qml/Components/EdgeDemo.qml:145
133133msgid "Try swiping from the top edge to access the indicators"
134134msgstr ""
135135"Glisați de la marginea de sus a ecranului pentru a accesa indicatorii"
136136
137−#: qml/Components/EdgeDemo.qml:183
137+#: qml/Components/EdgeDemo.qml:170
138138msgid "Close"
139139msgstr "Închide"
140140
141−#: qml/Components/EdgeDemo.qml:184
141+#: qml/Components/EdgeDemo.qml:171
142142msgid "Swipe up again to close the settings screen"
143143msgstr "Glisați în sus din nou pentru a închide ecranul configurărilor"
144144
145−#: qml/Components/EdgeDemo.qml:214
145+#: qml/Components/EdgeDemo.qml:201
146146msgid "Left edge"
147147msgstr "Marginea din stânga"
148148
149−#: qml/Components/EdgeDemo.qml:215
149+#: qml/Components/EdgeDemo.qml:202
150150msgid "Swipe from the left to reveal the launcher for quick access to apps"
151151msgstr ""
152152"Glisați din stânga ecranului pentru a afișa lansatorul care oferă acces "
153153"rapid la aplicații"
154154
155−#: qml/Components/EdgeDemo.qml:242
155+#: qml/Components/EdgeDemo.qml:229
156156msgid "Well done"
157157msgstr "Felicitări"
158158
159−#: qml/Components/EdgeDemo.qml:243
159+#: qml/Components/EdgeDemo.qml:230
160160msgid ""
161161"You have now mastered the edge gestures and can start using the "
162162"phone<br><br>Tap on the screen to start"
@@ -164,44 +164,44 @@ msgstr ""
164164"De acum stăpâniți gesturile de control și puteți începe să utilizați "
165165"telefonul<br><br>Atingeți ecranul pentru a începe"
166166
167−#: qml/Components/Lockscreen.qml:238
167+#: qml/Components/Lockscreen.qml:223
168168msgid "Return to Call"
169169msgstr "Reveniți la funcția de apelare"
170170
171−#: qml/Components/Lockscreen.qml:238
171+#: qml/Components/Lockscreen.qml:223
172172msgid "Emergency Call"
173173msgstr "Apel de urgență"
174174
175−#: qml/Components/Lockscreen.qml:270
175+#: qml/Components/Lockscreen.qml:255
176176msgid "OK"
177177msgstr "În regulă"
178178
179−#: qml/Dash/GenericScopeView.qml:431 qml/Dash/GenericScopeView.qml:588
179+#: qml/Dash/GenericScopeView.qml:434 qml/Dash/GenericScopeView.qml:591
180180msgid "See less"
181181msgstr "Afișează mai puține"
182182
183−#: qml/Dash/GenericScopeView.qml:431
183+#: qml/Dash/GenericScopeView.qml:434
184184msgid "See all"
185185msgstr "Afișează tot"
186186
187−#: qml/Dash/GenericScopeView.qml:493 qml/Dash/PageHeader.qml:267
187+#: qml/Dash/GenericScopeView.qml:496 qml/Dash/PageHeader.qml:268
188188#: qml/Panel/SearchIndicator.qml:27
189189msgid "Search"
190190msgstr "Căutare"
191191
192−#: qml/Dash/PageHeader.qml:260
192+#: qml/Dash/PageHeader.qml:261
193193msgid "Store"
194194msgstr "Magazin"
195195
196−#: qml/Dash/PageHeader.qml:277
196+#: qml/Dash/PageHeader.qml:278
197197msgid "Settings"
198198msgstr "Configurări"
199199
200−#: qml/Dash/PageHeader.qml:284
200+#: qml/Dash/PageHeader.qml:285
201201msgid "Remove from Favorites"
202202msgstr "Șterge din favorite"
203203
204−#: qml/Dash/PageHeader.qml:284
204+#: qml/Dash/PageHeader.qml:285
205205msgid "Add to Favorites"
206206msgstr "Adaugă la favorite"
207207
@@ -235,15 +235,15 @@ msgstr "Eliberați pentru a actualiza..."
235235
236236#: qml/Dash/ScopesList.qml:63
237237msgid "Manage"
238−msgstr ""
238+msgstr "Administrați"
239239
240240#: qml/Dash/ScopesList.qml:107
241241msgid "Home"
242−msgstr ""
242+msgstr "Acasă"
243243
244244#: qml/Dash/ScopesList.qml:108
245245msgid "Also installed"
246−msgstr ""
246+msgstr "Alte programe instalate"
247247
248248#: qml/Greeter/Greeter.qml:174
249249msgid "Unlock"
@@ -297,49 +297,49 @@ msgstr "Deblocare SIM"
297297msgid "Roaming"
298298msgstr "Roaming"
299299
300−#: qml/Shell.qml:367
300+#: qml/Shell.qml:402
301301#, qt-format
302302msgid "Enter %1"
303303msgstr "Introducere %1"
304304
305−#: qml/Shell.qml:368 qml/Wizard/Pages/passwd-set.qml:60
305+#: qml/Shell.qml:394
306306msgid "Enter passphrase"
307307msgstr "Introduceți fraza parolă"
308308
309−#: qml/Shell.qml:369
309+#: qml/Shell.qml:398
310310msgid "Enter passcode"
311311msgstr "Introduceți parola"
312312
313−#: qml/Shell.qml:370
313+#: qml/Shell.qml:403
314314#, qt-format
315315msgid "Sorry, incorrect %1"
316316msgstr "%1 incorectă"
317317
318−#: qml/Shell.qml:371
318+#: qml/Shell.qml:395
319319msgid "Sorry, incorrect passphrase"
320320msgstr "Frază secretă incorectă"
321321
322−#: qml/Shell.qml:372
322+#: qml/Shell.qml:396
323323msgid "Please re-enter"
324324msgstr "Introduceți din nou"
325325
326−#: qml/Shell.qml:373
326+#: qml/Shell.qml:399
327327msgid "Sorry, incorrect passcode"
328328msgstr "Parolă incorectă"
329329
330−#: qml/Shell.qml:467 qml/Wizard/Pages/passwd-confirm.qml:53
330+#: qml/Shell.qml:444
331331msgid "Sorry, incorrect passphrase."
332332msgstr "Frază parolă greșită"
333333
334−#: qml/Shell.qml:468 qml/Wizard/Pages/passwd-confirm.qml:54
334+#: qml/Shell.qml:445
335335msgid "Sorry, incorrect passcode."
336336msgstr "Parolă greșită"
337337
338−#: qml/Shell.qml:469
338+#: qml/Shell.qml:446
339339msgid "This will be your last attempt."
340340msgstr "Aceasta va fi ultima încercare"
341341
342−#: qml/Shell.qml:471
342+#: qml/Shell.qml:448
343343msgid ""
344344"If passphrase is entered incorrectly, your phone will conduct a factory "
345345"reset and all personal data will be deleted."
@@ -348,7 +348,7 @@ msgstr ""
348348"configurările inițiale, ale fabricantului, iar toate datele personale vor fi "
349349"șterse."
350350
351−#: qml/Shell.qml:472
351+#: qml/Shell.qml:449
352352msgid ""
353353"If passcode is entered incorrectly, your phone will conduct a factory reset "
354354"and all personal data will be deleted."
@@ -359,98 +359,101 @@ msgstr ""
359359
360360#: qml/Wizard/Page.qml:89
361361msgid "Back"
362−msgstr ""
362+msgstr "Înapoi"
363363
364364#: qml/Wizard/Pages/10-welcome.qml:27
365365msgid "Hi!"
366−msgstr ""
366+msgstr "Salut!"
367367
368368#: qml/Wizard/Pages/10-welcome.qml:44
369369msgid "Welcome to your Ubuntu phone."
370−msgstr ""
370+msgstr "Bun venit! Acesta este telefonul dumneavoastră Ubuntu."
371371
372372#: qml/Wizard/Pages/10-welcome.qml:52
373373msgid "Let’s get started."
374−msgstr ""
374+msgstr "Să începem."
375375
376376#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:128
377377#: qml/Wizard/Pages/40-wifi.qml:197 qml/Wizard/Pages/50-location.qml:131
378378#: qml/Wizard/Pages/60-reporting.qml:50 qml/Wizard/Pages/passwd-confirm.qml:82
379379#: qml/Wizard/Pages/passwd-set.qml:90
380380msgid "Continue"
381−msgstr ""
381+msgstr "Continuare"
382382
383383#: qml/Wizard/Pages/20-sim.qml:25
384384msgid "Add a SIM card and restart your device"
385−msgstr ""
385+msgstr "Adăugați un card SIM și reporniți dispozitivul dumneavoastră"
386386
387387#: qml/Wizard/Pages/20-sim.qml:55
388388msgid "Without it, you won’t be able to make calls or use text messaging."
389389msgstr ""
390+"Fără acesta, nu veți putea efectua apeluri sau utiliza mesajele text."
390391
391392#: qml/Wizard/Pages/20-sim.qml:69 qml/Wizard/Pages/40-wifi.qml:197
392393msgid "Skip"
393−msgstr ""
394+msgstr "Se omite"
394395
395396#: qml/Wizard/Pages/30-passwd-type.qml:39
396397msgid "Lock security"
397−msgstr ""
398+msgstr "Blocare de securitate"
398399
399400#: qml/Wizard/Pages/30-passwd-type.qml:74
400401msgid "Please select how you’d like to unlock your phone."
401−msgstr ""
402+msgstr "Alegeți cum doriți să vă deblocați telefonul."
402403
403404#: qml/Wizard/Pages/30-passwd-type.qml:97
404405msgid "Swipe"
405−msgstr ""
406+msgstr "Glisare"
406407
407408#: qml/Wizard/Pages/30-passwd-type.qml:98
408409msgid "No security"
409−msgstr ""
410+msgstr "Fară securitate"
410411
411412#: qml/Wizard/Pages/30-passwd-type.qml:100
412413msgid "Passcode"
413−msgstr ""
414+msgstr "Cod de acces"
414415
415416#: qml/Wizard/Pages/30-passwd-type.qml:101
416417msgid "4 digits only"
417−msgstr ""
418+msgstr "Doar 4 caractere"
418419
419420#: qml/Wizard/Pages/30-passwd-type.qml:103
420421msgid "Passphrase"
421−msgstr ""
422+msgstr "Frază parolă"
422423
423424#: qml/Wizard/Pages/30-passwd-type.qml:104
424425msgid "Numbers and letters"
425−msgstr ""
426+msgstr "Numere și litere"
426427
427428#: qml/Wizard/Pages/40-wifi.qml:28
428429msgid "Connect to Wi‑Fi"
429−msgstr ""
430+msgstr "Conectare la Wi-Fi"
430431
431432#: qml/Wizard/Pages/40-wifi.qml:147
432433msgid "Available networks…"
433−msgstr ""
434+msgstr "Rețele disponibile..."
434435
435436#: qml/Wizard/Pages/40-wifi.qml:148
436437msgid "No available networks."
437−msgstr ""
438+msgstr "Nu sunt rețele disponibile."
438439
439440#: qml/Wizard/Pages/50-location.qml:27
440441msgid "Location"
441−msgstr ""
442+msgstr "Loc"
442443
443444#: qml/Wizard/Pages/50-location.qml:62
444445msgid "Let the phone detect your location:"
445−msgstr ""
446+msgstr "Permiteți telefonului să detecteze locul în care vă aflați:"
446447
447448#: qml/Wizard/Pages/50-location.qml:69
448449msgid "Using GPS only (less accurate)"
449−msgstr ""
450+msgstr "Utilizând numai GPS (mai puțin precis)"
450451
451452#: qml/Wizard/Pages/50-location.qml:86
452453msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
453454msgstr ""
455+"Utilizând GPS, rețelele fără fir în modul anonim și informațiile furnizate "
456+"de rețeaua celulară (recomandat)"
454457
455458#. TRANSLATORS: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
456459#: qml/Wizard/Pages/50-location.qml:103
@@ -458,81 +461,89 @@ msgid ""
458461"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
459462"conditions</a>."
460463msgstr ""
464+"Prin selectarea acestei opțiuni sunteți de acord cu <a href='#'>termenii și "
465+"condițiile</a> Nokia HERE."
461466
462467#: qml/Wizard/Pages/50-location.qml:112
463468msgid "Not at all"
464−msgstr ""
469+msgstr "Deloc"
465470
466471#: qml/Wizard/Pages/50-location.qml:124
467472msgid "You can change your mind later in <b>System Settings</b>."
468473msgstr ""
474+"Puteți să modificați opțiunea utilizând <b>Configurări de sistem</b>."
469475
470476#: qml/Wizard/Pages/60-reporting.qml:24
471477msgid "Improving your experience"
472−msgstr ""
478+msgstr "Îmbunătățirea experienței în utilizare"
473479
474480#: qml/Wizard/Pages/60-reporting.qml:36
475481msgid ""
476482"Your phone is set up to automatically report errors to Canonical and its "
477483"partners, the makers of the operating system."
478484msgstr ""
485+"Telefonul dumneavoastră este configurat să trimită în mod automat rapoarte "
486+"de erori către Canonical și partenerii săi, producătorii sistemului de "
487+"operare."
479488
480489#: qml/Wizard/Pages/60-reporting.qml:43
481490msgid ""
482491"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
483492"Privacy</b>"
484493msgstr ""
494+"Acest comportament poate fi dezactivat din <b>Configurări de sistem</b> "
495+"ramura <b>Securitate și confidențialitate</b>"
485496
486497#: qml/Wizard/Pages/80-finished.qml:24
487498msgid "All done"
488−msgstr ""
499+msgstr "Efectuat"
489500
490501#: qml/Wizard/Pages/80-finished.qml:39
491502msgid "Nice work!"
492−msgstr ""
503+msgstr "Bună treabă!"
493504
494505#: qml/Wizard/Pages/80-finished.qml:46
495506msgid "Your phone is now ready to use."
496−msgstr ""
507+msgstr "Telefonul dumneavoastră este gata de utilizare."
497508
498509#: qml/Wizard/Pages/80-finished.qml:53
499510msgid "Finish"
500−msgstr ""
511+msgstr "Sfârșit"
501512
502513#: qml/Wizard/Pages/here-terms.qml:27
503514msgid "Terms & Conditions"
504−msgstr ""
515+msgstr "Termeni și condiții"
505516
506517#: qml/Wizard/Pages/passwd-confirm.qml:49
507518msgid "Confirm passphrase"
508−msgstr ""
519+msgstr "Confirmați frază parolă"
509520
510521#: qml/Wizard/Pages/passwd-confirm.qml:50
511522msgid "Confirm passcode"
512−msgstr ""
523+msgstr "Confirmați codul de acces"
513524
514525#: qml/Wizard/Pages/passwd-confirm.qml:53
515526#: qml/Wizard/Pages/passwd-confirm.qml:54
516527msgid "Please try again."
517−msgstr ""
528+msgstr "Vă rugăm să încercați din nou."
518529
519530#: qml/Wizard/Pages/passwd-set.qml:61
520531msgid "Choose your passcode"
521−msgstr ""
532+msgstr "Alegeți codul dumneavoastră de acces"
522533
523534#: qml/Wizard/Pages/passwd-set.qml:68
524535msgid "Passphrase must be 4 characters long"
525−msgstr ""
536+msgstr "Codul de acces trebuie să conțină 4 caractere"
526537
527538#: qml/Wizard/StackButton.qml:39
528539#, qt-format
529540msgid "〈 %1"
530−msgstr ""
541+msgstr "〈 %1"
531542
532543#: qml/Wizard/StackButton.qml:42
533544#, qt-format
534545msgid "%1 〉"
535−msgstr ""
546+msgstr "%1 〉"
536547
537548#~ msgid "Confirm"
538549#~ msgstr "Confirmați"
qml/Dash/Dash.qml+4−10
@@ -36,9 +36,8 @@ Showable {
3636 dashContent.setCurrentScopeAtIndex(index, animate, isSwipe)
3737 // Close dash overview and nested temp scopes in it
3838 if (bottomEdgeController.progress != 0) {
39− bottomEdgeController.enableAnimation = window.active && !scopesOverview.showingNonFavoriteScope;
39+ bottomEdgeController.enableAnimation = window.active;
4040 bottomEdgeController.progress = 0;
41− scopesOverview.closeTempScope();
4241 }
4342 // Close normal temp scopes (e.g. App Store)
4443 if (scopeItem.scope) {
@@ -335,28 +334,23 @@ Showable {
335334 height: units.gu(2)
336335
337336 onSceneDistanceChanged: {
338− if (status == DirectionalDragArea.Recognized && initialSceneDistance != -1) {
337+ if (status == DirectionalDragArea.Recognized) {
339338 bottomEdgeController.enableAnimation = false;
340− var deltaDistance = sceneDistance - initialSceneDistance;
341− bottomEdgeController.progress = Math.max(0, Math.min(1, deltaDistance / fullMovement));
339+ bottomEdgeController.progress = Math.max(0, Math.min(1, sceneDistance / fullMovement));
342340 }
343341 }
344342
345343 property int previousStatus: -1
346344 property int currentStatus: DirectionalDragArea.WaitingForTouch
347− property real initialSceneDistance: -1
348345
349346 onStatusChanged: {
350347 previousStatus = currentStatus;
351348 currentStatus = status;
352349
353− if (status == DirectionalDragArea.Recognized) {
354− initialSceneDistance = sceneDistance;
355− } else if (status == DirectionalDragArea.WaitingForTouch &&
350+ if (status == DirectionalDragArea.WaitingForTouch &&
356351 previousStatus == DirectionalDragArea.Recognized) {
357352 bottomEdgeController.enableAnimation = true;
358353 bottomEdgeController.progress = (bottomEdgeController.progress > 0.2) ? 1 : 0;
359− initialSceneDistance = -1;
360354 }
361355 }
362356 }
qml/Dash/DashContent.qml+2−2
@@ -113,7 +113,7 @@ Item {
113113 objectName: "dashContentList"
114114
115115 interactive: !dashContent.forceNonInteractive && dashContent.scopes.loaded && currentItem
116− && !currentItem.moving && !currentItem.navigationShown && !currentItem.subPageShown
116+ && !currentItem.moving && !currentItem.navigationDisableParentInteractive && !currentItem.subPageShown
117117 anchors.fill: parent
118118 orientation: ListView.Horizontal
119119 boundsBehavior: Flickable.DragAndOvershootBounds
@@ -175,7 +175,7 @@ Item {
175175 objectName: "scopeLoader" + index
176176
177177 readonly property bool moving: item ? item.moving : false
178− readonly property bool navigationShown: item ? item.navigationShown : false
178+ readonly property bool navigationDisableParentInteractive: item ? item.navigationDisableParentInteractive : false
179179 readonly property bool subPageShown: item ? item.subPageShown : false
180180 readonly property var categoryView: item ? item.categoryView : null
181181 readonly property var theScope: scope
qml/Dash/DashNavigation.qml+4
@@ -33,6 +33,10 @@ Item {
3333 if (altNavigationButton.showList) return altNavigationButton.listView;
3434 return null;
3535 }
36+ readonly property bool disableParentInteractive: {
37+ return navigationButton.showList || altNavigationButton.showList ||
38+ navigationButton.inverseMousePressed || altNavigationButton.inverseMousePressed;
39+ }
3640
3741 // FIXME this is only here for highlight purposes (see Background.qml, too)
3842 readonly property var background: backgroundItem
qml/Dash/DashNavigationButton.qml+2
@@ -31,6 +31,7 @@ AbstractButton {
3131 // Used by parent
3232 readonly property var currentNavigation: scope && scope[hasNavigation] ? getNavigation(scope[currentNavigationId]) : null
3333 readonly property alias listView: navigationListView
34+ readonly property bool inverseMousePressed: inverseMouseArea.pressed
3435 property bool showList: false
3536
3637 // Internal
@@ -210,6 +211,7 @@ AbstractButton {
210211 onCurrentNavigationChanged: setNewNavigation();
211212
212213 InverseMouseArea {
214+ id: inverseMouseArea
213215 anchors.fill: navigationListView
214216 enabled: root.showList
215217 onPressed: root.showList = false
qml/Dash/GenericScopeView.qml+3−3
@@ -25,10 +25,10 @@ import "../Components/ListItems" as ListItems
2525FocusScope {
2626 id: scopeView
2727
28− readonly property bool navigationShown: pageHeaderLoader.item ? pageHeaderLoader.item.bottomItem[0].openList : false
28+ readonly property bool navigationDisableParentInteractive: pageHeaderLoader.item ? pageHeaderLoader.item.bottomItem[0].disableParentInteractive : false
2929 property bool forceNonInteractive: false
3030 property var scope: null
31− property SortFilterProxyModel categories: categoryFilter
31+ property UnitySortFilterProxyModel categories: categoryFilter
3232 property bool isCurrent: false
3333 property alias moving: categoryView.moving
3434 property bool hasBackAction: false
@@ -106,7 +106,7 @@ FocusScope {
106106 value: isCurrent && !subPageLoader.open
107107 }
108108
109− SortFilterProxyModel {
109+ UnitySortFilterProxyModel {
110110 id: categoryFilter
111111 model: scope ? scope.categories : null
112112 dynamicSortFilter: true
qml/Dash/ScopesList.qml+1
@@ -65,6 +65,7 @@ Item {
6565 objectName: "pageHeader"
6666 title: i18n.tr("Manage")
6767 width: parent.width
68+ clip: true
6869 showBackButton: true
6970 backIsClose: root.state == "edit"
7071 storeEntryEnabled: root.state == "browse"
qml/Greeter/Clock.qml+1−1
@@ -53,7 +53,7 @@ Item {
5353 menuObjectPath: clock.visible ? "/com/canonical/indicator/datetime/phone" : ""
5454 }
5555
56− Indicators.RootActionState {
56+ Indicators.ModelActionRootState {
5757 menu: timeModel.model
5858 onUpdated: {
5959 if (timeLabel.text != rightLabel) {
qml/Greeter/Infographics.qml+9−7
@@ -127,7 +127,7 @@ Item {
127127
128128 index: model.index
129129 count: pastCircles.count
130− radius: parent.width / 2
130+ radius: dataCircle.width / 2
131131 halfSize: pastCircle.width / 2
132132 posOffset: 0.0
133133
@@ -187,7 +187,7 @@ Item {
187187
188188 index: model.index
189189 count: presentCircles.count
190− radius: parent.width / 2
190+ radius: dataCircle.width / 2
191191 halfSize: presentCircle.width / 2
192192 posOffset: 0.0
193193
@@ -255,14 +255,16 @@ Item {
255255 interval: animDuration * 0.5; running: false; repeat: true
256256 onTriggered: {
257257 if (dotCounter < dots.count) {
258− var nextDot = dots.itemAt(dotCounter++)
259− nextDot.unlockAnimation.start()
258+ var nextDot = dots.itemAt(dotCounter);
259+ if (nextDot) {
260+ nextDot.unlockAnimation.start();
261+ if (++dotCounter == Math.round(dots.count / 2)) {
262+ circleChangeAnimTimer.startFromBeginning();
263+ }
264+ }
260265 } else {
261266 stop()
262267 }
263− if (dotCounter == Math.round(dots.count / 2)) {
264− circleChangeAnimTimer.startFromBeginning()
265− }
266268 }
267269
268270 function startFromBeginning() {
qml/Notifications/Notifications.qml+1−1
@@ -29,7 +29,7 @@ ListView {
2929 property real margin
3030 property bool useModal: snapDecisionProxyModel.count > 0
3131
32− SortFilterProxyModel {
32+ UnitySortFilterProxyModel {
3333 id: snapDecisionProxyModel
3434 objectName: "snapDecisionProxyModel"
3535
qml/Panel/IndicatorItem.qml−8
@@ -45,14 +45,6 @@ IndicatorDelegate {
4545 onClicked: parent.clicked()
4646 }
4747
48− // FIXME: For now we will enable led indicator support only for messaging indicator
49− // in the future we should export a led API insted of doing that,
50− Loader {
51− id: indicatorLed
52− // only load source Component if the icons contains the new message icon
53− source: (root.icons && (String(root.icons).indexOf("indicator-messages-new") != -1)) ? Qt.resolvedUrl("Indicators/IndicatorsLight.qml") : ""
54− }
55−
5648 Item {
5749 id: mainItems
5850 anchors.centerIn: parent
qml/Panel/Indicators/IndicatorBase.qml+1−1
@@ -40,7 +40,7 @@ Item {
4040 menuObjectPath: indicatorItem.menuObjectPath
4141 }
4242
43− RootActionState {
43+ ModelActionRootState {
4444 id: rootAction
4545 menu: menuModel ? menuModel : null
4646 onUpdated: indicatorItem.rootActionStateChanged()
qml/Panel/Indicators/IndicatorsLight.qml+19−1
@@ -20,16 +20,34 @@
2020import QtQuick 2.0
2121import Powerd 0.1
2222import Lights 0.1
23+import QMenuModel 0.1 as QMenuModel
24+import Unity.Indicators 0.1 as Indicators
2325
2426QtObject {
2527 id: root
2628
29+ property var _actionGroup: QMenuModel.QDBusActionGroup {
30+ busType: 1
31+ busName: "com.canonical.indicator.messages"
32+ objectPath: "/com/canonical/indicator/messages"
33+ }
34+
35+ property var _rootState: Indicators.ActionRootState {
36+ actionGroup: _actionGroup
37+ actionName: "messages"
38+ Component.onCompleted: actionGroup.start()
39+
40+ property bool hasMessages: valid && (String(icons).indexOf("indicator-messages-new") != -1)
41+ }
42+
2743 Component.onDestruction: Lights.state = Lights.Off
2844
2945 // QtObject does not have children
3046 property var _binding: Binding {
3147 target: Lights
3248 property: "state"
33− value: (Powerd.status === Powerd.Off) ? Lights.On : Lights.Off
49+ value: {
50+ return (Powerd.status === Powerd.Off && _rootState.hasMessages) ? Lights.On : Lights.Off
51+ }
3452 }
3553}
qml/Panel/Indicators/VisibleIndicators.qml+2−2
@@ -22,13 +22,13 @@ import Unity.Indicators 0.1 as Indicators
2222import Utils 0.1
2323
2424Item {
25− property SortFilterProxyModel model: filterModel
25+ property UnitySortFilterProxyModel model: filterModel
2626
2727 function initialise(profile) {
2828 indicatorsModel.load(profile);
2929 }
3030
31− SortFilterProxyModel {
31+ UnitySortFilterProxyModel {
3232 id: filterModel
3333 filterRole: Indicators.IndicatorsModelRole.IsVisible
3434 filterRegExp: RegExp("^true$")
qml/Panel/IndicatorsMenu.qml+5
@@ -18,6 +18,7 @@ import QtQuick 2.2
1818import Ubuntu.Components 1.1
1919import Ubuntu.Gestures 0.1
2020import "../Components"
21+import "Indicators"
2122
2223Showable {
2324 id: root
@@ -60,6 +61,10 @@ Showable {
6061 onUnitProgressChanged: d.updateState()
6162 clip: root.partiallyOpened
6263
64+ IndicatorsLight {
65+ id: indicatorLights
66+ }
67+
6368 // eater
6469 MouseArea {
6570 anchors.fill: parent
qml/Shell.qml+21−3
@@ -326,7 +326,7 @@ Item {
326326 id: inputMethod
327327 objectName: "inputMethod"
328328 anchors { fill: parent; topMargin: panel.panelHeight }
329− z: notifications.useModal || panel.indicators.shown ? overlay.z + 1 : overlay.z - 1
329+ z: notifications.useModal || panel.indicators.shown || wizard.active ? overlay.z + 1 : overlay.z - 1
330330 }
331331
332332 Connections {
@@ -403,7 +403,7 @@ Item {
403403
404404 function maybeShow() {
405405 if (!shell.forcedUnlock) {
406− show()
406+ showNow();
407407 }
408408 }
409409
@@ -597,6 +597,15 @@ Item {
597597 enabled = true;
598598 }
599599
600+ Timer {
601+ // See powerConnection for why this is useful
602+ id: showGreeterDelayed
603+ interval: 1
604+ onTriggered: {
605+ greeter.showNow();
606+ }
607+ }
608+
600609 onShownChanged: {
601610 if (shown) {
602611 // Disable everything so that user can't swipe greeter or
@@ -671,7 +680,16 @@ Item {
671680 onStatusChanged: {
672681 if (Powerd.status === Powerd.Off && reason !== Powerd.Proximity &&
673682 !callManager.hasCalls && !tutorial.running) {
674− greeter.showNow()
683+ // We don't want to simply call greeter.showNow() here, because
684+ // that will take too long. Qt will delay button event
685+ // handling until the greeter is done loading and may think the
686+ // user held down the power button the whole time, leading to a
687+ // power dialog being shown. Instead, delay showing the
688+ // greeter until we've finished handling the event. We could
689+ // make the greeter load asynchronously instead, but that
690+ // introduces a whole host of timing issues, especially with
691+ // its animations. So this is simpler.
692+ showGreeterDelayed.start();
675693 }
676694 }
677695 }
src/main.cpp−6
@@ -147,12 +147,6 @@ Load the testability driver");
147147 view->setSource(source);
148148 QObject::connect(view->engine(), SIGNAL(quit()), application, SLOT(quit()));
149149
150− if (!isMirServer && qEnvironmentVariableIsSet("UNITY_MIR_EMITS_SIGSTOP")) {
151− // Emit SIGSTOP as expected by upstart, under Mir it's qtmir that will raise it.
152− // see http://upstart.ubuntu.com/cookbook/#expect-stop
153− raise(SIGSTOP);
154− }
155−
156150 if (isMirServer || parser.isSet(fullscreenOption)) {
157151 view->showFullScreen();
158152 } else {
tests/autopilot/unity8/shell/emulators/create_interactive_notification.py−1
@@ -88,7 +88,6 @@ if __name__ == '__main__':
8888 action_id,
8989 action_label,
9090 action_callback,
91− None,
9291 None
9392 )
9493
tests/autopilot/unity8/shell/emulators/edges_demo.pynew file+140
@@ -0,0 +1,140 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+#
3+# Unity Autopilot Test Suite
4+# Copyright (C) 2014 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License as published by
8+# the Free Software Foundation, either version 3 of the License, or
9+# (at your option) any later version.
10+#
11+# This program is distributed in the hope that it will be useful,
12+# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+# GNU General Public License for more details.
15+#
16+# You should have received a copy of the GNU General Public License
17+# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+#
19+
20+import logging
21+import time
22+
23+import ubuntuuitoolkit
24+
25+import autopilot
26+from autopilot import introspection
27+
28+
29+logger = logging.getLogger(__name__)
30+
31+
32+class RightEdgeDemoOverlay(
33+ ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
34+
35+ @classmethod
36+ def validate_dbus_object(cls, path, state):
37+ name = introspection.get_classname_from_path(path)
38+ if name == b'EdgeDemoOverlay':
39+ if state['edge'][1] == 'right':
40+ return True
41+ return False
42+
43+ @autopilot.logging.log_action(logger.info)
44+ def swipe(self):
45+ """Swipe to the left to complete this demo step."""
46+ x, y, width, height = self.globalRect
47+ start_x = x + width
48+ stop_x = x
49+ start_y = stop_y = y + height // 2
50+ self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
51+ return self.get_root_instance().wait_select_single(
52+ edge='top', active=True)
53+
54+
55+class TopEdgeDemoOverlay(
56+ ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
57+
58+ @classmethod
59+ def validate_dbus_object(cls, path, state):
60+ name = introspection.get_classname_from_path(path)
61+ if name == b'EdgeDemoOverlay':
62+ if state['edge'][1] == 'top':
63+ return True
64+ return False
65+
66+ @autopilot.logging.log_action(logger.info)
67+ def swipe(self):
68+ """Swipe to the bottom to complete this demo step."""
69+ x, y, width, height = self.globalRect
70+ start_x = stop_x = x + width // 2
71+ start_y = y
72+ stop_y = y + height
73+ self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
74+ return self.get_root_instance().wait_select_single(
75+ edge='bottom', active=True)
76+
77+
78+class BottomEdgeDemoOverlay(
79+ ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
80+
81+ @classmethod
82+ def validate_dbus_object(cls, path, state):
83+ name = introspection.get_classname_from_path(path)
84+ if name == b'EdgeDemoOverlay':
85+ if state['edge'][1] == 'bottom':
86+ return True
87+ return False
88+
89+ @autopilot.logging.log_action(logger.info)
90+ def swipe(self):
91+ """Swipe to the top to complete this demo step."""
92+ x, y, width, height = self.globalRect
93+ start_x = stop_x = x + width // 2
94+ start_y = y + height
95+ stop_y = y
96+ self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
97+ return self.get_root_instance().wait_select_single(
98+ edge='left', active=True)
99+
100+
101+class LeftEdgeDemoOverlay(
102+ ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
103+
104+ @classmethod
105+ def validate_dbus_object(cls, path, state):
106+ name = introspection.get_classname_from_path(path)
107+ if name == b'EdgeDemoOverlay':
108+ if state['edge'][1] == 'left':
109+ return True
110+ return False
111+
112+ @autopilot.logging.log_action(logger.info)
113+ def swipe(self):
114+ """Swipe to the right to complete this demo step."""
115+ x, y, width, height = self.globalRect
116+ start_x = x
117+ stop_x = x + width
118+ start_y = stop_y = y + height // 2
119+ self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
120+ return self.get_root_instance().wait_select_single(
121+ edge='none', active=True)
122+
123+
124+class FinalEdgeDemoOverlay(
125+ ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
126+
127+ @classmethod
128+ def validate_dbus_object(cls, path, state):
129+ name = introspection.get_classname_from_path(path)
130+ if name == b'EdgeDemoOverlay':
131+ if state['edge'][1] == 'none':
132+ return True
133+ return False
134+
135+ @autopilot.logging.log_action(logger.info)
136+ def tap_to_start(self):
137+ """Tap to finish the demo and start using the Ubuntu Touch."""
138+ time.sleep(1)
139+ self.pointing_device.click_object(self)
140+ self.shown.wait_for(False)
tests/autopilot/unity8/shell/fixture_setup.py+38
@@ -20,6 +20,7 @@
2020"""Set up and clean up fixtures for the Unity acceptance tests."""
2121
2222import os
23+import subprocess
2324import sysconfig
2425
2526import fixtures
@@ -51,3 +52,40 @@ class FakeScopes(fixtures.Fixture):
5152 'Expected library path does not exists: %s.' % (
5253 ld_library_path))
5354 return ld_library_path
55+
56+
57+class EdgesDemo(fixtures.Fixture):
58+
59+ def __init__(self, enable):
60+ super().__init__()
61+ self.enable = enable
62+
63+ def setUp(self):
64+ super().setUp()
65+ original_state = self._is_edges_demo_enabled()
66+ if self.enable != original_state:
67+ self.addCleanup(self._set_edges_demo, original_state)
68+ self._set_edges_demo(self.enable)
69+
70+ def _is_edges_demo_enabled(self):
71+ command = [
72+ 'dbus-send', '--system', '--print-reply',
73+ '--dest=org.freedesktop.Accounts',
74+ '/org/freedesktop/Accounts/User32011',
75+ 'org.freedesktop.DBus.Properties.Get',
76+ 'string:com.canonical.unity.AccountsService',
77+ 'string:demo-edges'
78+ ]
79+ output = subprocess.check_output(command, universal_newlines=True)
80+ return True if output.count('true') else False
81+
82+ def _set_edges_demo(self, value):
83+ value_string = 'true' if value else 'false'
84+ command = [
85+ 'dbus-send', '--system', '--print-reply',
86+ '--dest=com.canonical.PropertyService',
87+ '/com/canonical/PropertyService',
88+ 'com.canonical.PropertyService.SetProperty',
89+ 'string:edge', 'boolean:{}'.format(value_string)
90+ ]
91+ subprocess.check_output(command)
tests/autopilot/unity8/shell/tests/test_edges_demo.pynew file+52
@@ -0,0 +1,52 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+#
3+# Unity Autopilot Test Suite
4+# Copyright (C) 2014 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License as published by
8+# the Free Software Foundation, either version 3 of the License, or
9+# (at your option) any later version.
10+#
11+# This program is distributed in the hope that it will be useful,
12+# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+# GNU General Public License for more details.
15+#
16+# You should have received a copy of the GNU General Public License
17+# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+#
19+
20+from autopilot.matchers import Eventually
21+from testtools.matchers import Equals
22+
23+from unity8.shell import (
24+ fixture_setup,
25+ tests
26+)
27+# unused import to load the edge emulators custom proxy objects.
28+from unity8.shell.emulators import edges_demo # NOQA
29+
30+
31+class EdgesDemoTestCase(tests.UnityTestCase):
32+
33+ def setUp(self):
34+ super().setUp()
35+ self._qml_mock_enabled = False
36+ self._data_dirs_mock_enabled = False
37+ self._lightdm_mock_type = False
38+
39+ self.useFixture(fixture_setup.EdgesDemo(True))
40+ self.unity = self.launch_unity()
41+
42+ def test_complete_edge_demo(self):
43+ edge_demo = self.unity.select_single('EdgeDemo')
44+ self.assertThat(edge_demo.running, Eventually(Equals(True)))
45+ right_edge_overlay = self.unity.wait_select_single(
46+ edge='right', active=True)
47+ top_edge_overlay = right_edge_overlay.swipe()
48+ bottom_edge_overlay = top_edge_overlay.swipe()
49+ left_edge_overlay = bottom_edge_overlay.swipe()
50+ final_overlay = left_edge_overlay.swipe()
51+ final_overlay.tap_to_start()
52+ self.assertThat(edge_demo.running, Eventually(Equals(False)))
tests/mocks/CMakeLists.txt+1
@@ -32,6 +32,7 @@ add_subdirectory(AccountsService)
3232add_subdirectory(GSettings.1.0)
3333add_subdirectory(libusermetrics)
3434add_subdirectory(LightDM)
35+add_subdirectory(Lights)
3536add_subdirectory(MeeGo)
3637add_subdirectory(Powerd)
3738add_subdirectory(QMenuModel)
tests/mocks/LightDM/CMakeLists.txt+1−1
@@ -24,7 +24,7 @@ set(QMLPLUGIN_SRC
2424 ${CMAKE_SOURCE_DIR}/plugins/LightDM/Greeter.cpp
2525 ${CMAKE_SOURCE_DIR}/plugins/LightDM/plugin.cpp
2626 ${CMAKE_SOURCE_DIR}/plugins/LightDM/UsersModel.cpp
27− ${CMAKE_SOURCE_DIR}/plugins/Utils/qsortfilterproxymodelqml.cpp
27+ ${CMAKE_SOURCE_DIR}/plugins/Utils/unitysortfilterproxymodelqml.cpp
2828 )
2929
3030add_library(MockLightDM-qml MODULE
tests/mocks/LightDM/Greeter.cpp+6
@@ -129,6 +129,12 @@ void Greeter::authenticate(const QString &username)
129129 d->authenticated = false;
130130 d->authenticationUser = username;
131131 d->twoFactorDone = false;
132+ QTimer::singleShot(0, this, SLOT(delayedAuthentication()));
133+}
134+
135+void Greeter::delayedAuthentication()
136+{
137+ Q_D(Greeter);
132138 d->handleAuthenticate();
133139}
134140
tests/mocks/LightDM/Greeter.h+3
@@ -99,6 +99,9 @@ Q_SIGNALS:
9999protected:
100100 void sendAuthenticationComplete();
101101
102+private Q_SLOTS:
103+ void delayedAuthentication();
104+
102105private:
103106 GreeterPrivate *d_ptr;
104107 Q_DECLARE_PRIVATE(Greeter)
tests/mocks/Lights/CMakeLists.txtnew file+8
@@ -0,0 +1,8 @@
1+add_library(MockLights-qml MODULE
2+ plugin.cpp
3+ Lights.cpp
4+ )
5+
6+qt5_use_modules(MockLights-qml Qml Gui)
7+
8+add_unity8_mock(Lights 0.1 Lights TARGETS MockLights-qml)
tests/mocks/Lights/Lights.cppnew file+84
@@ -0,0 +1,84 @@
1+/*
2+ * Copyright (C) 2014 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 "Lights.h"
18+
19+#include <QDebug>
20+
21+Lights::Lights(QObject* parent)
22+ : QObject(parent),
23+ m_color("blue"),
24+ m_state(Lights::Off),
25+ m_onMs(1000),
26+ m_offMs(3000)
27+{
28+}
29+
30+Lights::~Lights()
31+{
32+}
33+
34+void Lights::setState(Lights::State newState)
35+{
36+ if (m_state != newState) {
37+ m_state = newState;
38+ Q_EMIT stateChanged(m_state);
39+ }
40+}
41+
42+Lights::State Lights::state() const
43+{
44+ return m_state;
45+}
46+
47+void Lights::setColor(const QColor &color)
48+{
49+ if (m_color != color) {
50+ m_color = color;
51+ Q_EMIT colorChanged(m_color);
52+ }
53+}
54+
55+QColor Lights::color() const
56+{
57+ return m_color;
58+}
59+
60+int Lights::onMillisec() const
61+{
62+ return m_onMs;
63+}
64+
65+void Lights::setOnMillisec(int onMs)
66+{
67+ if (m_onMs != onMs) {
68+ m_onMs = onMs;
69+ Q_EMIT onMillisecChanged(m_onMs);
70+ }
71+}
72+
73+int Lights::offMillisec() const
74+{
75+ return m_offMs;
76+}
77+
78+void Lights::setOffMillisec(int offMs)
79+{
80+ if (m_offMs != offMs) {
81+ m_offMs = offMs;
82+ Q_EMIT offMillisecChanged(m_offMs);
83+ }
84+}
tests/mocks/Lights/Lights.hnew file+66
@@ -0,0 +1,66 @@
1+/*
2+ * Copyright (C) 2014 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+#ifndef UNITY_MOCK_LIGHTS_H
18+#define UNITY_MOCK_LIGHTS_H
19+
20+#include <QtCore/QObject>
21+#include <QtGui/QColor>
22+
23+class Lights: public QObject
24+{
25+ Q_OBJECT
26+ Q_ENUMS(State)
27+ Q_PROPERTY(State state READ state WRITE setState NOTIFY stateChanged)
28+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
29+ Q_PROPERTY(int onMillisec READ onMillisec WRITE setOnMillisec NOTIFY onMillisecChanged)
30+ Q_PROPERTY(int offMillisec READ offMillisec WRITE setOffMillisec NOTIFY offMillisecChanged)
31+
32+public:
33+ enum State {
34+ Off,
35+ On,
36+ };
37+
38+ explicit Lights(QObject *parent = 0);
39+ ~Lights();
40+
41+ void setState(State newState);
42+ State state() const;
43+
44+ void setColor(const QColor &color);
45+ QColor color() const;
46+
47+ int onMillisec() const;
48+ void setOnMillisec(int onMs);
49+
50+ int offMillisec() const;
51+ void setOffMillisec(int offMs);
52+
53+Q_SIGNALS:
54+ void stateChanged(State newState);
55+ void colorChanged(const QColor &color);
56+ void onMillisecChanged(int onMs);
57+ void offMillisecChanged(int offMs);
58+
59+private:
60+ QColor m_color;
61+ State m_state;
62+ int m_onMs;
63+ int m_offMs;
64+};
65+
66+#endif
tests/mocks/Lights/Lights.qmltypesnew file+45
@@ -0,0 +1,45 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Lights 0.1 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "Lights"
12+ prototype: "QObject"
13+ exports: ["Lights/Lights 0.1"]
14+ isCreatable: false
15+ isSingleton: true
16+ exportMetaObjectRevisions: [0]
17+ Enum {
18+ name: "State"
19+ values: {
20+ "Off": 0,
21+ "On": 1
22+ }
23+ }
24+ Property { name: "state"; type: "State" }
25+ Property { name: "color"; type: "QColor" }
26+ Property { name: "onMillisec"; type: "int" }
27+ Property { name: "offMillisec"; type: "int" }
28+ Signal {
29+ name: "stateChanged"
30+ Parameter { name: "newState"; type: "State" }
31+ }
32+ Signal {
33+ name: "colorChanged"
34+ Parameter { name: "color"; type: "QColor" }
35+ }
36+ Signal {
37+ name: "onMillisecChanged"
38+ Parameter { name: "onMs"; type: "int" }
39+ }
40+ Signal {
41+ name: "offMillisecChanged"
42+ Parameter { name: "offMs"; type: "int" }
43+ }
44+ }
45+}
tests/mocks/Lights/plugin.cppnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2012,2013 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 "plugin.h"
18+#include "Lights.h"
19+
20+#include <QtQml/qqml.h>
21+
22+static QObject *lights_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
23+{
24+ Q_UNUSED(engine)
25+ Q_UNUSED(scriptEngine)
26+ return new Lights();
27+}
28+
29+void PowerdPlugin::registerTypes(const char *uri)
30+{
31+ Q_ASSERT(uri == QLatin1String("Lights"));
32+ qmlRegisterSingletonType<Lights>(uri, 0, 1, "Lights", lights_provider);
33+}
tests/mocks/Lights/plugin.hnew file+32
@@ -0,0 +1,32 @@
1+/*
2+ * Copyright (C) 2012,2013 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+#ifndef MOCK_POWER_PLUGIN_H
18+#define MOCK_POWER_PLUGIN_H
19+
20+#include <QtQml/QQmlEngine>
21+#include <QtQml/QQmlExtensionPlugin>
22+
23+class PowerdPlugin : public QQmlExtensionPlugin
24+{
25+ Q_OBJECT
26+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
27+
28+public:
29+ void registerTypes(const char *uri);
30+};
31+
32+#endif
tests/mocks/Lights/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module Lights
2+plugin MockLights-qml
3+typeinfo Lights.qmltypes
tests/mocks/QMenuModel/CMakeLists.txt+1
@@ -4,6 +4,7 @@ include_directories(
44)
55
66set(QMenuModelQml_SOURCES
7+ actiondata.h
78 actionstateparser.cpp
89 dbus-enums.h
910 plugin.cpp
tests/mocks/QMenuModel/QDBusActionGroup.qml+20−67
@@ -19,81 +19,34 @@
1919
2020import QtQuick 2.0
2121import Ubuntu.Settings.Menus 0.1 as Menus
22+import QMenuModel 0.1
2223
2324QtObject {
2425 id: actionGroup
2526 property int busType
2627 property string busName
2728 property string objectPath
29+ property var actions: ActionData ? ActionData.data : undefined
30+
31+ signal dataChanged
32+
2833 function start() {}
34+
2935 function action(actionName) {
30− switch (actionName) {
31− case "transfer-state.queued":
32− return {
33− 'valid': true,
34− 'state': {
35− 'state': Menus.TransferState.Queued,
36− 'percent': 0.0
37− }
38− }
39− case "transfer-state.running":
40− return {
41− 'valid': true,
42− 'state': {
43− 'state': Menus.TransferState.Running,
44− 'seconds-left': 100,
45− 'percent': 0.1
46− }
47− }
48− case "transfer-state.paused":
49− return {
50− 'valid': true,
51− 'state': {
52− 'state': Menus.TransferState.Paused,
53− 'seconds-left': 100,
54− 'percent': 0.5
55− }
56− }
57− case "transfer-state.cancelled":
58− return {
59− 'valid': true,
60− 'state': {
61− 'state': Menus.TransferState.Canceled,
62− 'percent': 0.4
63− }
64− }
65− case "transfer-state.finished": return {
66− 'valid': true,
67− 'state': {
68− 'state': Menus.TransferState.Finished,
69− 'seconds-left': 0,
70− 'percent': 1.0
71− }
72− }
73− case "transfer-state.error":
74− return {
75− 'valid': true,
76− 'state': {
77− 'state': Menus.TransferState.Error,
78− 'seconds-left': 100,
79− 'percent': 0.0
80− }
81− }
82− case "gps-detection-enabled":
83− case "location-detection-enabled":
84− return Qt.createQmlObject("
85−import QtQuick 2.3
86−QtObject {
87− property bool valid: true
88− property bool state: false
89− function activate() {
90− state = !state;
91− }
92−}", actionGroup);
93− default:
94− break;
95− }
36+ return Qt.createQmlObject("
37+ import QtQuick 2.3
38+ import QMenuModel 0.1
39+
40+ QtObject {
41+ signal activated
42+
43+ property string actionName: \"" + actionName + "\"
44+ property bool valid: ActionData.data[actionName] != undefined ? ActionData.data[actionName].valid : false
45+ property var state: ActionData.data[actionName] != undefined ? ActionData.data[actionName].state : undefined
9646
97− return null;
47+ function activate() {
48+ activated();
49+ }
50+ }", actionGroup);
9851 }
9952}
tests/mocks/QMenuModel/actiondata.hnew file+52
@@ -0,0 +1,52 @@
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+ * Authors: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+#ifndef ACTIONDATA_H
20+#define ACTIONDATA_H
21+
22+#include <QObject>
23+#include <QVariant>
24+
25+typedef struct _GVariant GVariant;
26+
27+class Q_DECL_EXPORT ActionData : public QObject
28+{
29+ Q_OBJECT
30+ Q_PROPERTY(QVariant data READ data WRITE setData NOTIFY dataChanged)
31+public:
32+ ActionData(QObject* parent = 0)
33+ : QObject(parent)
34+ {}
35+
36+ QVariant data() const { return m_data; }
37+ void setData(const QVariant& data)
38+ {
39+ if (m_data != data) {
40+ m_data = data;
41+ Q_EMIT dataChanged();
42+ }
43+ }
44+
45+Q_SIGNALS:
46+ void dataChanged();
47+
48+private:
49+ QVariant m_data;
50+};
51+
52+#endif // ACTIONDATA_H
tests/mocks/QMenuModel/plugin.cpp+10
@@ -18,11 +18,19 @@
1818
1919#include "plugin.h"
2020#include "unitymenumodel.h"
21+#include "actiondata.h"
2122#include "actionstateparser.h"
2223#include "dbus-enums.h"
2324
2425#include <QtQml/qqml.h>
2526
27+static QObject* actionDataSingleton(QQmlEngine* engine, QJSEngine* scriptEngine)
28+{
29+ Q_UNUSED(engine);
30+ Q_UNUSED(scriptEngine);
31+ return new ActionData;
32+}
33+
2634void QMenuModelPlugin::registerTypes(const char *uri)
2735{
2836 Q_ASSERT(uri == QLatin1String("QMenuModel"));
@@ -30,4 +38,6 @@ void QMenuModelPlugin::registerTypes(const char *uri)
3038 "DBus is only a namespace");
3139 qmlRegisterType<UnityMenuModel>(uri, 0, 1, "UnityMenuModel");
3240 qmlRegisterType<ActionStateParser>(uri, 0, 1, "ActionStateParser");
41+
42+ qmlRegisterSingletonType<ActionData>(uri, 0, 1, "ActionData", actionDataSingleton);
3343}
tests/mocks/Unity/Indicators/ActionRootState.qmlnew file+46
@@ -0,0 +1,46 @@
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+QtObject {
23+ property var actionGroup
24+ property var actionName
25+
26+ property var action: actionGroup ? actionGroup.actions[actionName] : undefined
27+ property var state: action && action.hasOwnProperty("state") ? action.state : undefined
28+
29+ property bool valid: action && action.hasOwnProperty("valid") ? action.valid : false
30+ property string title: state && state.hasOwnProperty("title") ? state["title"] : ""
31+ property string leftLabel: state && state.hasOwnProperty("pre-label") ? state["pre-label"] : ""
32+ property string rightLabel: state && state.hasOwnProperty("label") ? state["label"] : ""
33+ property var icons: state && state.hasOwnProperty("icons") ? state["icons"] : []
34+ property string accessibleName: state && state.hasOwnProperty("accessible-desc") ? state["accessible-desc"] : ""
35+ property bool visible: state && state.hasOwnProperty("visible") ? state["visible"] : true
36+
37+ signal updated
38+
39+ onValidChanged: updated()
40+ onTitleChanged: updated()
41+ onLeftLabelChanged: updated()
42+ onRightLabelChanged: updated()
43+ onIconsChanged: updated()
44+ onAccessibleNameChanged: updated()
45+ onVisibleChanged: updated()
46+}
tests/mocks/Unity/Indicators/RootActionState.qml → tests/mocks/Unity/Indicators/ModelActionRootState.qmlrenamed

The content is the same.

tests/mocks/Unity/Indicators/qmldir+2−1
@@ -2,5 +2,6 @@ module Unity.Indicators
22plugin IndicatorsFakeQml
33typeinfo Indicators.qmltypes
44
5+ActionRootState 0.1 ActionRootState.qml
56IndicatorsModel 0.1 IndicatorsModel.qml
6−RootActionState 0.1 RootActionState.qml
7+ModelActionRootState 0.1 ModelActionRootState.qml
tests/plugins/LightDM/CMakeLists.txt+4−8
@@ -1,8 +1,8 @@
1−add_executable(test-lightdm-dbus
1+add_executable(GreeterDBusTestExec
22 dbus.cpp
33 ${CMAKE_SOURCE_DIR}/plugins/LightDM/Greeter.cpp
44 )
5−qt5_use_modules(test-lightdm-dbus Core DBus Quick Test)
5+qt5_use_modules(GreeterDBusTestExec Core DBus Quick Test)
66
77include_directories(
88 ${CMAKE_CURRENT_BINARY_DIR}
@@ -11,15 +11,11 @@ include_directories(
1111 ${LIBLIGHTDM_INCLUDE_DIRS}
1212 )
1313
14−add_dependencies(test-lightdm-dbus MockLightDM-full)
15−target_link_libraries(test-lightdm-dbus
14+target_link_libraries(GreeterDBusTestExec
1615 -L${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full
1716 -llightdm-qt5-2
1817 )
1918
2019add_definitions(-DCURRENT_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
2120
22−add_custom_target(testLightDMDBus xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum dbus-launch env QML2_IMPORT_PATH=${CMAKE_BINARY_DIR}/tests/mocks LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full ${CMAKE_CURRENT_BINARY_DIR}/test-lightdm-dbus)
23−add_dependencies(testLightDMDBus test-lightdm-dbus)
24−
25−add_dependencies(qmluitests testLightDMDBus)
21+add_binary_qml_test(GreeterDBus "${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full" MockLightDM-full "QML2_IMPORT_PATH=${CMAKE_BINARY_DIR}/tests/mocks")
tests/plugins/LightDM/dbus.cpp+11−2
@@ -16,6 +16,7 @@
1616
1717#include "Greeter.h"
1818
19+#include <QCoreApplication>
1920#include <QDBusInterface>
2021#include <QDBusReply>
2122#include <QSignalSpy>
@@ -149,9 +150,11 @@ private Q_SLOTS:
149150 QVERIFY(dbusList->property("EntryIsLocked").toBool());
150151
151152 greeter->authenticate("no-password");
153+ QCoreApplication::processEvents(); // wait for auth to finish
152154 QVERIFY(!dbusList->property("EntryIsLocked").toBool());
153155
154156 greeter->authenticate("has-password");
157+ QCoreApplication::processEvents(); // wait for auth to finish
155158 QVERIFY(dbusList->property("EntryIsLocked").toBool());
156159 }
157160
@@ -159,10 +162,16 @@ private Q_SLOTS:
159162 {
160163 QSignalSpy spy(this, SIGNAL(PropertiesChangedRelay(QString, QVariantMap, QStringList)));
161164 greeter->authenticate("no-password");
165+
166+ // Two property changed signals will be emitted, one for the IsLocked
167+ // property, one for the ActiveEntry; the first will be IsLocked.
162168 spy.wait();
169+ if (spy.count() < 2) {
170+ spy.wait();
171+ }
172+ QCOMPARE(spy.count(), 2);
163173
164− QCOMPARE(spy.count(), 2); // once for locked, once for user; first will be locked mode
165− QList<QVariant> arguments = spy.takeFirst();
174+ QList<QVariant> arguments = spy.takeLast();
166175 QVERIFY(arguments.at(0).toString() == "com.canonical.UnityGreeter.List");
167176 QVERIFY(arguments.at(1).toMap().contains("EntryIsLocked"));
168177 QVERIFY(arguments.at(1).toMap()["EntryIsLocked"] == false);
tests/plugins/Unity/Indicators/rootactionstatetest.cpp+4−4
@@ -17,7 +17,7 @@
1717 * Nick Dedekind <nick.dedekind@canonical.com>
1818 */
1919
20−#include "rootactionstate.h"
20+#include "modelactionrootstate.h"
2121
2222#include <unitymenumodel.h>
2323#include <QtTest>
@@ -32,7 +32,7 @@ private Q_SLOTS:
3232 {
3333 UnityMenuModel* menuModel = new UnityMenuModel();
3434 ActionStateParser* originalParser = menuModel->actionStateParser();
35− RootActionState* rootState = new RootActionState();
35+ ModelActionRootState* rootState = new ModelActionRootState();
3636
3737 rootState->setMenu(menuModel);
3838
@@ -44,7 +44,7 @@ private Q_SLOTS:
4444 void testDeleteUnityMenuModel()
4545 {
4646 UnityMenuModel* menuModel = new UnityMenuModel();
47− RootActionState* rootState = new RootActionState();
47+ ModelActionRootState* rootState = new ModelActionRootState();
4848
4949 rootState->setMenu(menuModel);
5050
@@ -77,7 +77,7 @@ private Q_SLOTS:
7777
7878 GVariant* params = g_variant_builder_end (&builderParams);
7979
80− RootActionState rootState;
80+ RootStateParser rootState;
8181 QVariant result = rootState.toQVariant(params);
8282 g_variant_unref(params);
8383
tests/plugins/Utils/CMakeLists.txt+1−1
@@ -23,7 +23,7 @@ endmacro(run_tests)
2323
2424run_tests(
2525 qlimitproxymodeltest
26− qsortfilterproxymodeltest
26+ unitysortfilterproxymodeltest
2727 timeformattertest
2828 )
2929
tests/plugins/Utils/qsortfilterproxymodeltest.cpp → tests/plugins/Utils/unitysortfilterproxymodeltest.cpprenamed+14−14
@@ -18,7 +18,7 @@
1818 */
1919
2020// local
21−#include "qsortfilterproxymodelqml.h"
21+#include "unitysortfilterproxymodelqml.h"
2222#include "modeltest.h"
2323
2424// Qt
@@ -91,7 +91,7 @@ private:
9191 QHash<int, QByteArray> m_roles;
9292};
9393
94−class QSortFilterProxyModelTest : public QObject
94+class UnitySortFilterProxyModelTest : public QObject
9595{
9696 Q_OBJECT
9797
@@ -103,7 +103,7 @@ private Q_SLOTS:
103103
104104 void testRoleNamesSetAfter()
105105 {
106− QSortFilterProxyModelQML proxy;
106+ UnitySortFilterProxyModelQML proxy;
107107 MockListModel model;
108108 QHash<int, QByteArray> roles;
109109
@@ -117,7 +117,7 @@ private Q_SLOTS:
117117
118118 void testRoleNamesSetBefore()
119119 {
120− QSortFilterProxyModelQML proxy;
120+ UnitySortFilterProxyModelQML proxy;
121121 MockListModel model;
122122 QHash<int, QByteArray> roles;
123123
@@ -131,7 +131,7 @@ private Q_SLOTS:
131131
132132 void testCountSetAfter()
133133 {
134− QSortFilterProxyModelQML proxy;
134+ UnitySortFilterProxyModelQML proxy;
135135 MockListModel model;
136136 model.insertRows(0, 5);
137137
@@ -144,7 +144,7 @@ private Q_SLOTS:
144144
145145 void testCountInsert()
146146 {
147− QSortFilterProxyModelQML proxy;
147+ UnitySortFilterProxyModelQML proxy;
148148 MockListModel model;
149149
150150 proxy.setModel(&model);
@@ -158,7 +158,7 @@ private Q_SLOTS:
158158
159159 void testCountRemove()
160160 {
161− QSortFilterProxyModelQML proxy;
161+ UnitySortFilterProxyModelQML proxy;
162162 MockListModel model;
163163 model.insertRows(0, 5);
164164
@@ -173,7 +173,7 @@ private Q_SLOTS:
173173 }
174174
175175 void testInvertMatch() {
176− QSortFilterProxyModelQML proxy;
176+ UnitySortFilterProxyModelQML proxy;
177177 MockListModel model;
178178
179179 proxy.setModel(&model);
@@ -215,7 +215,7 @@ private Q_SLOTS:
215215 }
216216
217217 void testNestedProxyRoleNames() {
218− QSortFilterProxyModelQML proxy1, proxy2;
218+ UnitySortFilterProxyModelQML proxy1, proxy2;
219219 MockListModel model;
220220 QHash<int, QByteArray> roles;
221221 roles[0] = "role0";
@@ -229,7 +229,7 @@ private Q_SLOTS:
229229 }
230230
231231 void testModelTest() {
232− QSortFilterProxyModelQML proxy;
232+ UnitySortFilterProxyModelQML proxy;
233233 MockListModel model;
234234
235235 proxy.setModel(&model);
@@ -246,7 +246,7 @@ private Q_SLOTS:
246246 }
247247
248248 void testModelChanged() {
249− QSortFilterProxyModelQML proxy;
249+ UnitySortFilterProxyModelQML proxy;
250250 MockListModel model, model2;
251251
252252 QSignalSpy spyOnModelChanged(&proxy, SIGNAL(modelChanged()));
@@ -265,7 +265,7 @@ private Q_SLOTS:
265265 }
266266
267267 void testData() {
268− QSortFilterProxyModelQML proxy;
268+ UnitySortFilterProxyModelQML proxy;
269269 MockListModel model, model2;
270270
271271 QStringList rows;
@@ -285,6 +285,6 @@ private Q_SLOTS:
285285 }
286286};
287287
288−QTEST_GUILESS_MAIN(QSortFilterProxyModelTest)
288+QTEST_GUILESS_MAIN(UnitySortFilterProxyModelTest)
289289
290−#include "qsortfilterproxymodeltest.moc"
290+#include "unitysortfilterproxymodeltest.moc"
tests/qmltests/CMakeLists.txt+1
@@ -78,6 +78,7 @@ add_qml_test(Panel IndicatorsMenu ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DI
7878add_qml_test(Panel MenuContent ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
7979add_qml_test(Panel Panel ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
8080add_qml_test(Panel SearchIndicator)
81+add_qml_test(Panel/Indicators IndicatorsLight ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
8182# These MenuItemFactory tests need the test/mocks/ to come before plugins/
8283add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
8384add_qml_test(Panel/Indicators MessageMenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
tests/qmltests/Components/tst_Carousel.qml+5−5
@@ -274,20 +274,20 @@ Item {
274274
275275 spy.signalName = "clicked";
276276 spy.target = carouselItem;
277− mouseClick(carouselItem, carouselItem.width / 2, carouselItem.height / 2);
277+ mouseClick(carouselItem);
278278 tryCompare(carouselList, "moving", false);
279279 tryCompare(carouselItem, "explicitlyScaled", true);
280− mouseClick(carouselItem, carouselItem.width / 2, carouselItem.height / 2);
280+ mouseClick(carouselItem);
281281 spy.wait();
282282
283283 spy.signalName = "pressAndHold";
284284 spy.target = carouselItem;
285− mouseClick(carouselItem, carouselItem.width / 2, carouselItem.height / 2);
285+ mouseClick(carouselItem);
286286 tryCompare(carouselList, "moving", false);
287287 tryCompare(carouselItem, "explicitlyScaled", true);
288− mousePress(carouselItem, carouselItem.width / 2, carouselItem.height / 2);
288+ mousePress(carouselItem);
289289 spy.wait();
290− mouseRelease(carouselItem, carouselItem.width / 2, carouselItem.height / 2);
290+ mouseRelease(carouselItem);
291291 }
292292 }
293293}
tests/qmltests/Components/tst_Lockscreen.qml+1−1
@@ -421,7 +421,7 @@ Rectangle {
421421 signalSpy.clear();
422422
423423 var okButton = findChild(root, "infoPopupOkButton");
424− mouseClick(okButton, okButton.width / 2, okButton.height / 2);
424+ mouseClick(okButton);
425425
426426 tryCompareFunction(function() { return findChild(root, "infoPopup") === null}, true);
427427
tests/qmltests/Components/tst_ResponsiveVerticalJournal.qml+1−1
@@ -79,7 +79,7 @@ Item {
7979 ListElement { name: "U" }
8080 }
8181
82− SortFilterProxyModel {
82+ UnitySortFilterProxyModel {
8383 id: wrappedFakeModel
8484 model: fakeModel
8585 }
tests/qmltests/Dash/Previews/tst_PreviewActions.qml+3−3
@@ -104,7 +104,7 @@ Rectangle {
104104 var button = findChild(root, "button" + id);
105105 verify(button != null);
106106 spy.target = target;
107− mouseClick(button, button.width / 2, button.height / 2);
107+ mouseClick(button);
108108 compare(spy.count, 1);
109109 compare(spy.signalArguments[0][0], target.widgetId);
110110 compare(spy.signalArguments[0][1], id);
@@ -137,11 +137,11 @@ Rectangle {
137137 var buttonColumn = findChild(root, "buttonColumn");
138138 verify(button != null);
139139 var twoActionsY = twoActions.y
140− mouseClick(button, button.width / 2, button.height / 2);
140+ mouseClick(button);
141141 tryCompareFunction(function () { return twoActions.y <= twoActionsY; }, false);
142142 tryCompare(buttonColumn, "height", buttonColumn.implicitHeight);
143143 checkButtonPressSignal(buttonAndCombo, data.id, data.buttonNumber);
144− mouseClick(button, button.width / 2, button.height / 2);
144+ mouseClick(button);
145145 tryCompare(twoActions, "y", twoActionsY);
146146 }
147147 }
tests/qmltests/Dash/Previews/tst_PreviewAudioPlayback.qml+5−5
@@ -131,7 +131,7 @@ Rectangle {
131131 compare(track2ProgressBar.visible, false);
132132
133133 // Playing track 0 should make progress bar 0 visible
134− mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2);
134+ mouseClick(track0PlayButton);
135135
136136 tryCompare(audio, "playbackState", Audio.PlayingState);
137137 checkPlayerSource(0);
@@ -141,18 +141,18 @@ Rectangle {
141141 tryCompare(track2ProgressBar, "visible", false);
142142
143143 // Clicking the button again should pause it. The progress bar should stay visible
144− mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2);
144+ mouseClick(track0PlayButton);
145145 tryCompare(audio, "playbackState", Audio.PausedState);
146146 checkPlayerSource(0);
147147 tryCompare(track0ProgressBar, "visible", true);
148148
149149 // Continue playback
150− mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2);
150+ mouseClick(track0PlayButton);
151151 tryCompare(audio, "playbackState", Audio.PlayingState);
152152 checkPlayerSource(0);
153153
154154 // Playing track 1 should make progress bar 1 visible and hide progress bar 0 again
155− mouseClick(track1PlayButton, track1PlayButton.width / 2, track1PlayButton.height / 2);
155+ mouseClick(track1PlayButton);
156156
157157 tryCompare(audio, "playbackState", Audio.PlayingState);
158158 checkPlayerSource(1);
@@ -162,7 +162,7 @@ Rectangle {
162162 tryCompare(track2ProgressBar, "visible", false);
163163
164164 // Playing track 2 should make progress bar 1 visible and hide progress bar 0 again
165− mouseClick(track2PlayButton, track2PlayButton.width / 2, track2PlayButton.height / 2);
165+ mouseClick(track2PlayButton);
166166
167167 tryCompare(audio, "playbackState", Audio.PlayingState);
168168 checkPlayerSource(2);
tests/qmltests/Dash/Previews/tst_PreviewExpandable.qml+2−2
@@ -85,7 +85,7 @@ Rectangle {
8585
8686 function test_expand_collapse() {
8787 var expandButton = findChild(previewExpandable, "expandButton")
88− mouseClick(expandButton, expandButton.width / 2, expandButton.height / 2);
88+ mouseClick(expandButton);
8989
9090 var repeater = findChild(previewExpandable, "repeater")
9191 compare(repeater.count, 4)
@@ -99,7 +99,7 @@ Rectangle {
9999 compare (repeater.itemAt(2).expanded, true);
100100 compare (repeater.itemAt(3).expanded, true);
101101
102− mouseClick(expandButton, expandButton.width / 2, expandButton.height / 2);
102+ mouseClick(expandButton);
103103
104104 checkInitialState();
105105 }
tests/qmltests/Dash/Previews/tst_PreviewImageGallery.qml+6−6
@@ -67,23 +67,23 @@ Rectangle {
6767
6868 function test_overlayOpenClose() {
6969 var image0 = findChild(imageGallery, "previewImage0");
70− mouseClick(image0, image0.width / 2, image0.height / 2);
70+ mouseClick(image0);
7171 tryCompare(overlay, "visible", true);
7272 tryCompare(overlay, "scale", 1.0);
7373 tryCompare(overlayCloseButton, "visible", true);
74− mouseClick(overlayCloseButton, overlayCloseButton.width / 2, overlayCloseButton.height / 2);
74+ mouseClick(overlayCloseButton);
7575 tryCompare(overlay, "visible", false);
7676 }
7777
7878 function test_overlayShowHideHeader() {
7979 var image0 = findChild(imageGallery, "previewImage0");
80− mouseClick(image0, image0.width / 2, image0.height / 2);
80+ mouseClick(image0);
8181 tryCompare(overlay, "visible", true);
8282 tryCompare(overlay, "scale", 1.0);
8383 tryCompare(overlayCloseButton, "visible", true);
84− mouseClick(overlay, overlay.width / 2, overlay.height / 2);
84+ mouseClick(overlay);
8585 tryCompare(overlayCloseButton, "visible", false);
86− mouseClick(overlay, overlay.width / 2, overlay.height / 2);
86+ mouseClick(overlay);
8787 tryCompare(overlayCloseButton, "visible", true);
8888 }
8989
@@ -97,7 +97,7 @@ Rectangle {
9797
9898 function test_overlayOpenCorrectImage(data) {
9999 var image = findChild(imageGallery, "previewImage" + data.index);
100− mouseClick(image, image.width / 2, image.height / 2);
100+ mouseClick(image);
101101 tryCompare(overlay, "visible", true);
102102 tryCompare(overlay, "scale", 1.0);
103103 tryCompare(overlayListView, "currentIndex", data.index);
tests/qmltests/Dash/Previews/tst_PreviewPayments.qml+5−5
@@ -84,7 +84,7 @@ Rectangle {
8484 var button = findChild(previewPayments, "paymentButton");
8585 verify(button, "Button not found.");
8686
87− mouseClick(button, button.width / 2, button.height / 2);
87+ mouseClick(button);
8888
8989 paymentClient.process();
9090 spy.wait();
@@ -107,7 +107,7 @@ Rectangle {
107107 tryCompare(button, "visible", true);
108108 tryCompare(button, "opacity", 1);
109109
110− mouseClick(button, button.width / 2, button.height / 2);
110+ mouseClick(button);
111111
112112 paymentClient.process();
113113 spy.wait();
@@ -130,7 +130,7 @@ Rectangle {
130130 tryCompare(button, "visible", true);
131131 tryCompare(button, "opacity", 1);
132132
133− mouseClick(button, button.width / 2, button.height / 2);
133+ mouseClick(button);
134134
135135 tryCompare(progress, "visible", true);
136136 tryCompare(progress, "opacity", 1);
@@ -154,7 +154,7 @@ Rectangle {
154154 var button = findChild(previewPayments, "paymentButton");
155155 verify(button, "Button not found.");
156156
157− mouseClick(button, button.width / 2, button.height / 2);
157+ mouseClick(button);
158158
159159 paymentClient.process();
160160 spy.wait();
@@ -175,7 +175,7 @@ Rectangle {
175175 verify(button, "Button not found.");
176176 verify(progress, "Progress not found.");
177177
178− mouseClick(button, button.width / 2, button.height / 2);
178+ mouseClick(button);
179179
180180 tryCompare(progress, "visible", true);
181181 tryCompare(progress, "opacity", 1);
tests/qmltests/Dash/Previews/tst_PreviewRatingDisplay.qml+1−1
@@ -118,7 +118,7 @@ Rectangle {
118118 compare(rating.value, reviewsModel1["reviews"][1]["rating"]);
119119
120120 // Tap on first star
121− mouseClick(rating, 0, 0);
121+ mouseClick(rating);
122122 compare(rating.value, reviewsModel1["reviews"][1]["rating"]);
123123 }
124124 }
tests/qmltests/Dash/Previews/tst_PreviewRatingInput.qml+2−2
@@ -139,7 +139,7 @@ Rectangle {
139139 verify(reviewTextArea.visible === true);
140140
141141 reviewTextArea.text = data.inputText;
142− mouseClick(submitButton, submitButton.width / 2, submitButton.height / 2);
142+ mouseClick(submitButton);
143143 switch (data.widgetData["required"]) {
144144 case "rating": {
145145 if (rating.visible === false || data.inputRating < 0) {
@@ -187,7 +187,7 @@ Rectangle {
187187 if (data.inputRating > 0) rating.value = data.inputRating;
188188 if (data.inputText !== "") {
189189 reviewTextArea.text = data.inputText;
190− mouseClick(submitButton, submitButton.width / 2, submitButton.height / 2);
190+ mouseClick(submitButton);
191191 }
192192
193193 compare(spy.count, 1);
tests/qmltests/Dash/Previews/tst_PreviewZoomableImage.qml+2−2
@@ -72,11 +72,11 @@ Rectangle {
7272
7373 function test_zoomableImageOpenClose() {
7474 var overlayCloseButton = findChild(overlay, "overlayCloseButton");
75− mouseClick(lazyImage, lazyImage.width / 2, lazyImage.height / 2);
75+ mouseClick(lazyImage);
7676 tryCompare(overlay, "visible", true);
7777 tryCompare(overlay, "scale", 1.0);
7878 tryCompare(overlayCloseButton, "visible", true);
79− mouseClick(overlayCloseButton, overlayCloseButton.width / 2, overlayCloseButton.height / 2);
79+ mouseClick(overlayCloseButton);
8080 tryCompare(overlay, "visible", false);
8181 }
8282 }
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingBoolean.qml+2−2
@@ -49,12 +49,12 @@ Rectangle {
4949
5050 function test_updated() {
5151 var control = findChild(scopeSetting, "control");
52− mouseClick(control, control.width / 2, control.height / 2);
52+ mouseClick(control);
5353 spy.wait();
5454 compare(spy.signalArguments[0][0], false);
5555
5656 spy.clear();
57− mouseClick(scopeSetting, scopeSetting.width / 2, scopeSetting.height / 2);
57+ mouseClick(scopeSetting);
5858 spy.wait();
5959 compare(spy.signalArguments[0][0], true);
6060 }
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingNumber.qml+3−3
@@ -57,7 +57,7 @@ Rectangle {
5757 }
5858
5959 function test_updated_on_unfocus() {
60− mouseClick(control, control.width / 2, control.height / 2);
60+ mouseClick(control);
6161 control.selectAll();
6262 control.cut();
6363 control.insert(0, newNumber);
@@ -67,7 +67,7 @@ Rectangle {
6767 }
6868
6969 function test_updated_on_accepted() {
70− mouseClick(control, control.width / 2, control.height / 2);
70+ mouseClick(control);
7171 control.selectAll();
7272 control.cut();
7373 control.insert(0, newNumber);
@@ -86,7 +86,7 @@ Rectangle {
8686 }
8787
8888 function test_unacceptable_input() {
89− mouseClick(control, control.width / 2, control.height / 2);
89+ mouseClick(control);
9090 control.selectAll();
9191 control.cut();
9292 control.insert(0, "not valid");
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingString.qml+2−2
@@ -57,7 +57,7 @@ Rectangle {
5757 }
5858
5959 function test_updated_on_unfocus() {
60− mouseClick(control, control.width / 2, control.height / 2);
60+ mouseClick(control);
6161 control.selectAll();
6262 control.cut();
6363 control.insert(0, newText);
@@ -67,7 +67,7 @@ Rectangle {
6767 }
6868
6969 function test_updated_on_accepted() {
70− mouseClick(control, control.width / 2, control.height / 2);
70+ mouseClick(control);
7171 control.selectAll();
7272 control.cut();
7373 control.insert(0, newText);
tests/qmltests/Dash/tst_Card.qml+2−2
@@ -539,9 +539,9 @@ Rectangle {
539539 var touchdown = findChild(card, "touchdown");
540540
541541 compare(touchdown.visible, false);
542− mousePress(card, card.width/2, card.height/2);
542+ mousePress(card);
543543 compare(touchdown.visible, true);
544− mouseRelease(card, card.width/2, card.height/2);
544+ mouseRelease(card);
545545 compare(touchdown.visible, false);
546546 }
547547
tests/qmltests/Dash/tst_Dash.qml+42−25
@@ -89,8 +89,8 @@ Item {
8989 // Go back
9090 var scopesList = findChild(dash, "scopesList");
9191 var scopesListPageHeader = findChild(scopesList, "pageHeader");
92− var backButton = findChild(findChild(scopesListPageHeader, "innerPageHeader"), "backButton");
93− mouseClick(backButton, 0, 0);
92+ var backButton = findChild(findChild(scopesListPageHeader, "innerPageHeader"), "customBackButton");
93+ mouseClick(backButton);
9494 tryCompare(bottomEdgeController, "progress", 0);
9595 }
9696
@@ -106,7 +106,7 @@ Item {
106106 tryCompare(favScopesListCategoryList, "currentIndex", 0);
107107
108108 // Click in first item
109− mouseClick(favScopesListCategoryList.currentItem, 0, 0);
109+ mouseClick(favScopesListCategoryList.currentItem);
110110
111111 // Make sure animation went back
112112 tryCompare(bottomEdgeController, "progress", 0);
@@ -128,7 +128,7 @@ Item {
128128
129129 // Click in second item
130130 favScopesListCategoryList.currentIndex = 1;
131− mouseClick(favScopesListCategoryList.currentItem, 0, 0);
131+ mouseClick(favScopesListCategoryList.currentItem);
132132
133133 // Make sure animation went back
134134 tryCompare(bottomEdgeController, "progress", 0);
@@ -148,7 +148,7 @@ Item {
148148 tryCompare(nonfavScopesListCategoryList, "currentIndex", 0);
149149
150150 // Click on a non favorite scope
151− mouseClick(nonfavScopesListCategoryList.currentItem, 0, 0);
151+ mouseClick(nonfavScopesListCategoryList.currentItem);
152152
153153 // Check the bottom edge (manage dash) is disabled from temp scope
154154 var overviewDragHandle = findChild(dash, "overviewDragHandle");
@@ -164,8 +164,8 @@ Item {
164164
165165 // Go back
166166 var dashTempScopeItemHeader = findChild(dashTempScopeItem, "scopePageHeader");
167− var backButton = findChild(findChild(dashTempScopeItemHeader, "innerPageHeader"), "backButton");
168− mouseClick(backButton, 0, 0);
167+ var backButton = findChild(findChild(dashTempScopeItemHeader, "innerPageHeader"), "customBackButton");
168+ mouseClick(backButton);
169169
170170 // Check temp scope is gone
171171 tryCompare(dashTempScopeItem, "x", dash.width);
@@ -189,7 +189,7 @@ Item {
189189 var scopesList = findChild(dash, "scopesList");
190190 var scopesListPageHeader = findChild(scopesList, "pageHeader");
191191 var searchButton = findChild(scopesListPageHeader, "search_header_button");
192− mouseClick(searchButton, 0, 0);
192+ mouseClick(searchButton);
193193
194194 // Type something
195195 keyClick(Qt.Key_H);
@@ -201,7 +201,7 @@ Item {
201201 var cardTempScope = findChild(dashCategorysearchA, "delegate2");
202202
203203 waitForRendering(cardTempScope);
204− mouseClick(cardTempScope, cardTempScope.width / 2, cardTempScope.height / 2);
204+ mouseClick(cardTempScope);
205205
206206 // Check the bottom edge (overview) is disabled from temp scope
207207 var overviewDragHandle = findChild(dash, "overviewDragHandle");
@@ -217,8 +217,8 @@ Item {
217217
218218 // Go back
219219 var dashTempScopeItemHeader = findChild(dashTempScopeItem, "scopePageHeader");
220− var backButton = findChild(findChild(dashTempScopeItemHeader, "innerPageHeader"), "backButton");
221− mouseClick(backButton, 0, 0);
220+ var backButton = findChild(findChild(dashTempScopeItemHeader, "innerPageHeader"), "customBackButton");
221+ mouseClick(backButton);
222222
223223 // Check temp scope is gone
224224 tryCompare(dashTempScopeItem, "x", dash.width);
@@ -243,8 +243,8 @@ Item {
243243 // Go back
244244 var scopesList = findChild(dash, "scopesList");
245245 var scopesListPageHeader = findChild(scopesList, "pageHeader");
246− var backButton = findChild(findChild(scopesListPageHeader, "innerPageHeader"), "backButton");
247− mouseClick(backButton, 0, 0);
246+ var backButton = findChild(findChild(scopesListPageHeader, "innerPageHeader"), "customBackButton");
247+ mouseClick(backButton);
248248 tryCompare(bottomEdgeController, "progress", 0);
249249 }
250250
@@ -272,7 +272,7 @@ Item {
272272 var scopeLoader0 = findChild(dashContent, "scopeLoader0");
273273 var dashCategory0 = findChild(scopeLoader0, "dashCategory0");
274274 var delegate0 = findChild(dashCategory0, "delegate0");
275− mouseClick(delegate0, delegate0.width / 2, delegate0.height / 2);
275+ mouseClick(delegate0);
276276
277277 tryCompare(dashContent, "subPageShown", true)
278278 waitForRendering(dash);
@@ -320,7 +320,7 @@ Item {
320320 // Click on the store
321321 var scopesListPageHeader = findChild(scopesList, "pageHeader");
322322 var searchButton = findChild(scopesListPageHeader, "store_header_button");
323− mouseClick(searchButton, 0, 0);
323+ mouseClick(searchButton);
324324
325325 spy.wait();
326326 compare(spy.signalArguments[0][0], "scope://com.canonical.scopes.clickstore");
@@ -345,9 +345,9 @@ Item {
345345 // Enter edit mode
346346 var scopesList = findChild(dash, "scopesList");
347347 var clickScope = findChild(favScopesListCategoryList, "delegateclickscope");
348− mousePress(clickScope, 0, 0);
348+ mousePress(clickScope);
349349 tryCompare(scopesList, "state", "edit");
350− mouseRelease(clickScope, 0, 0);
350+ mouseRelease(clickScope);
351351
352352 var starArea = findChild(clickScope, "starArea");
353353 touchFlick(starArea, 0, 0, 0, -units.gu(10));
@@ -355,9 +355,9 @@ Item {
355355 // Exit edit mode and go back
356356 var scopesList = findChild(dash, "scopesList");
357357 var scopesListPageHeader = findChild(scopesList, "pageHeader");
358− var backButton = findChild(findChild(scopesListPageHeader, "innerPageHeader"), "backButton");
359− mouseClick(backButton, 0, 0);
360− mouseClick(backButton, 0, 0);
358+ var backButton = findChild(findChild(scopesListPageHeader, "innerPageHeader"), "customBackButton");
359+ mouseClick(backButton);
360+ mouseClick(backButton);
361361 tryCompare(bottomEdgeController, "progress", 0);
362362
363363 tryCompare(dashContentList, "currentIndex", 0);
@@ -387,9 +387,9 @@ Item {
387387 // Enter edit mode
388388 var scopesList = findChild(dash, "scopesList");
389389 var clickScope = findChild(favScopesListCategoryList, "delegateclickscope");
390− mousePress(clickScope, 0, 0);
390+ mousePress(clickScope);
391391 tryCompare(scopesList, "state", "edit");
392− mouseRelease(clickScope, 0, 0);
392+ mouseRelease(clickScope);
393393
394394 var starArea = findChild(clickScope, "starArea");
395395 touchFlick(starArea, 0, 0, 0, -units.gu(10));
@@ -400,16 +400,33 @@ Item {
400400 // Exit edit mode
401401 var scopesList = findChild(dash, "scopesList");
402402 var scopesListPageHeader = findChild(scopesList, "pageHeader");
403− var backButton = findChild(findChild(scopesListPageHeader, "innerPageHeader"), "backButton");
404− mouseClick(backButton, 0, 0);
403+ var backButton = findChild(findChild(scopesListPageHeader, "innerPageHeader"), "customBackButton");
404+ mouseClick(backButton);
405405
406406 // Click on third scope
407407 var mockScope5 = findChild(favScopesListCategoryList, "delegateMockScope5");
408408 waitForRendering(mockScope5)
409− mouseClick(mockScope5, 0, 0);
409+ mouseClick(mockScope5);
410410 tryCompare(bottomEdgeController, "progress", 0);
411411 tryCompare(dashContentList, "currentIndex", 2);
412412 compare(dashContentList.currentItem.scopeId, "MockScope5");
413413 }
414+
415+ function test_manage_dash_close_dashCommunicator() {
416+ var dashContentList = findChild(dash, "dashContentList");
417+ compare(dashContentList.currentIndex, 0);
418+ compare(dashContentList.currentItem.scopeId, "MockScope1");
419+
420+ // Show the manage dash
421+ touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, units.gu(2));
422+ var bottomEdgeController = findInvisibleChild(dash, "bottomEdgeController");
423+ tryCompare(bottomEdgeController, "progress", 1);
424+
425+ var dashCommunicatorService = findInvisibleChild(dash, "dashCommunicatorService");
426+ dashCommunicatorService.mockSetCurrentScope(1, true, false);
427+
428+ tryCompare(bottomEdgeController, "progress", 0);
429+ tryCompare(dashContentList, "currentIndex", 1)
430+ }
414431 }
415432}
tests/qmltests/Dash/tst_DashContent.qml+48−27
@@ -288,7 +288,7 @@ Item {
288288 var dashNavigationButton = findChild(dashContentList.currentItem, "navigationButton");
289289 compare(dashNavigationButton.showList, false);
290290 waitForRendering(dashNavigationButton);
291− mouseClick(dashNavigationButton, dashNavigationButton.width / 2, dashNavigationButton.height / 2);
291+ mouseClick(dashNavigationButton);
292292 compare(dashNavigationButton.showList, true);
293293
294294 var navigationListView = findChild(dashNavigationButton, "navigationListView");
@@ -304,30 +304,30 @@ Item {
304304 compare(allButton.visible, false);
305305
306306 var navigation = findChild(dashNavigationButton, "navigation0child3");
307− mouseClick(navigation, 0, 0);
307+ mouseClick(navigation);
308308 compare(dashNavigationButton.showList, false);
309309 tryCompare(dashNavigationButton.currentNavigation, "navigationId", "middle3");
310310 tryCompare(navigationListView.currentItem.navigation, "navigationId", "root");
311311
312− mouseClick(dashNavigationButton, 0, 0);
312+ mouseClick(dashNavigationButton);
313313 compare(dashNavigationButton.showList, true);
314314 waitForRendering(navigationListView);
315315 waitForRendering(navigationListView.currentItem);
316316 compare(allButton.visible, true);
317317
318− mouseClick(allButton, 0, 0);
318+ mouseClick(allButton);
319319 compare(dashNavigationButton.showList, false);
320320 tryCompare(dashNavigationButton.currentNavigation, "navigationId", "root");
321321 tryCompare(navigationListView.currentItem.navigation, "navigationId", "root");
322322
323− mouseClick(dashNavigationButton, 0, 0);
323+ mouseClick(dashNavigationButton);
324324 compare(dashNavigationButton.showList, true);
325325 waitForRendering(navigationListView);
326326 waitForRendering(navigationListView.currentItem);
327327 compare(allButton.visible, false);
328328
329329 navigation = findChild(dashNavigationButton, "navigation0child2");
330− mouseClick(navigation, 0, 0);
330+ mouseClick(navigation);
331331 compare(dashNavigationButton.showList, true);
332332 tryCompare(dashNavigationButton.currentNavigation, "navigationId", "middle2");
333333 tryCompare(navigationListView.currentItem.navigation, "navigationId", "middle2");
@@ -340,12 +340,12 @@ Item {
340340
341341 tryCompare(navigationListView, "contentX", navigationList1.x);
342342 waitForRendering(navigationListView);
343− mouseClick(allButton, 0, 0);
343+ mouseClick(allButton);
344344 compare(dashNavigationButton.showList, false);
345345 tryCompare(dashNavigationButton.currentNavigation, "navigationId", "middle2");
346346 tryCompare(navigationListView.currentItem.navigation, "navigationId", "middle2");
347347
348− mouseClick(dashNavigationButton, 0, 0);
348+ mouseClick(dashNavigationButton);
349349 compare(dashNavigationButton.showList, true);
350350 waitForRendering(navigationListView);
351351 waitForRendering(navigationListView.currentItem);
@@ -354,47 +354,47 @@ Item {
354354
355355 tryCompare(navigationList1.navigation, "loaded", true);
356356 navigation = findChild(dashNavigationButton, "navigation1child2");
357− mouseClick(navigation, 0, 0);
357+ mouseClick(navigation);
358358 compare(dashNavigationButton.showList, false);
359359 tryCompare(dashNavigationButton.currentNavigation, "navigationId", "childmiddle22");
360360 tryCompare(navigationListView.currentItem.navigation, "navigationId", "middle2");
361361
362− mouseClick(dashNavigationButton, 0, 0);
362+ mouseClick(dashNavigationButton);
363363 compare(dashNavigationButton.showList, true);
364364 waitForRendering(navigationListView);
365365 waitForRendering(navigationListView.currentItem);
366366
367367 tryCompare(navigationList1.navigation, "loaded", true);
368368 navigation = findChild(dashNavigationButton, "navigation1child3");
369− mouseClick(navigation, 0, 0);
369+ mouseClick(navigation);
370370 compare(dashNavigationButton.showList, false);
371371 tryCompare(dashNavigationButton.currentNavigation, "navigationId", "childmiddle23");
372372 tryCompare(navigationListView.currentItem.navigation, "navigationId", "middle2");
373373
374− mouseClick(dashNavigationButton, 0, 0);
374+ mouseClick(dashNavigationButton);
375375 compare(dashNavigationButton.showList, true);
376376 waitForRendering(navigationListView);
377377 waitForRendering(navigationListView.currentItem);
378− mouseClick(backButton, 0, 0);
378+ mouseClick(backButton);
379379
380380 tryCompare(dashNavigationButton.currentNavigation, "navigationId", "root");
381381 tryCompare(navigationListView.currentItem.navigation, "navigationId", "root");
382382 compare(dashNavigationButton.showList, true);
383− mouseClick(dashNavigationButton, 0, 0);
383+ mouseClick(dashNavigationButton);
384384 compare(dashNavigationButton.showList, false);
385385
386− mouseClick(dashNavigationButton, 0, 0);
386+ mouseClick(dashNavigationButton);
387387 compare(dashNavigationButton.showList, true);
388388 tryCompare(navigationListView.currentItem.navigation, "loaded", true);
389389 navigation = findChild(dashNavigationButton, "navigation0child2");
390− mouseClick(navigation, 0, 0);
390+ mouseClick(navigation);
391391 compare(dashNavigationButton.showList, true);
392392 navigationList1 = findChild(dashNavigationButton, "navigation1");
393393 compare(navigationList1.navigation.loaded, false);
394394 tryCompare(dashNavigationButton.currentNavigation, "navigationId", "middle2");
395395 allButton = findChild(navigationList1, "allButton");
396396 tryCompare(dashNavigationButton.currentNavigation, "navigationId", "middle2");
397− mouseClick(allButton, 0, 0);
397+ mouseClick(allButton);
398398 tryCompare(dashNavigationButton.currentNavigation, "navigationId", "middle2");
399399 }
400400
@@ -408,7 +408,7 @@ Item {
408408
409409 compare(dashNavigationButton.showList, false);
410410 waitForRendering(dashNavigationButton);
411− mouseClick(dashNavigationButton, 0, 0);
411+ mouseClick(dashNavigationButton);
412412 compare(dashNavigationButton.showList, true);
413413
414414 var navigationListView = findChild(dashNavigationButton, "navigationListView");
@@ -429,24 +429,24 @@ Item {
429429 compare(backButton.visible, false);
430430
431431 var navigation = findChild(dashNavigationButton, "navigation0child3");
432− mouseClick(navigation, 0, 0);
432+ mouseClick(navigation);
433433 compare(dashNavigationButton.showList, false);
434434 tryCompare(dashNavigationButton.currentNavigation, "navigationId", "altrootChild3");
435435 tryCompare(navigationListView.currentItem.navigation, "navigationId", "altroot");
436436
437− mouseClick(dashNavigationButton, 0, 0);
437+ mouseClick(dashNavigationButton);
438438 compare(dashNavigationButton.showList, true);
439439 waitForRendering(navigationListView);
440440 waitForRendering(navigationListView.currentItem);
441441 compare(allButton.visible, false);
442442
443443 navigation = findChild(dashNavigationButton, "navigation0child2");
444− mouseClick(navigation, 0, 0);
444+ mouseClick(navigation);
445445 compare(dashNavigationButton.showList, false);
446446 tryCompare(dashNavigationButton.currentNavigation, "navigationId", "altrootChild2");
447447 tryCompare(navigationListView.currentItem.navigation, "navigationId", "altroot");
448448
449− mouseClick(dashNavigationButton, 0, 0);
449+ mouseClick(dashNavigationButton);
450450 compare(dashNavigationButton.showList, true);
451451 waitForRendering(navigationListView);
452452 waitForRendering(navigationListView.currentItem);
@@ -454,7 +454,7 @@ Item {
454454
455455 compare(navigationListView.count, 1, "There should be no second-level navigation");
456456
457− mouseClick(dashNavigationButton, 0, 0);
457+ mouseClick(dashNavigationButton);
458458 compare(dashNavigationButton.showList, false);
459459 }
460460
@@ -474,7 +474,7 @@ Item {
474474 compare(dashNavigationButton.showList, false);
475475 compare(dashAltNavigationButton.showList, false);
476476
477− mouseClick(dashNavigation, 0, 0);
477+ mouseClick(dashAltNavigationButton);
478478 compare(dashNavigationButton.showList, false);
479479 compare(dashAltNavigationButton.showList, true);
480480
@@ -487,24 +487,45 @@ Item {
487487 var blackRect = findChild(dashNavigation, "blackRect");
488488 tryCompare(blackRect, "opacity", 0.5);
489489
490− mouseClick(dashNavigation, dashNavigationButton.x, 0);
490+ mouseClick(dashNavigationButton);
491491 compare(dashNavigationButton.showList, false);
492492 compare(dashAltNavigationButton.showList, false);
493493
494494 tryCompare(navigationListView, "visible", false);
495495
496− mouseClick(dashNavigation, dashNavigationButton.x, 0);
496+ mouseClick(dashNavigationButton);
497497 compare(dashNavigationButton.showList, true);
498498 compare(dashAltNavigationButton.showList, false);
499499
500500 navigationListView = findChild(dashNavigationButton, "navigationListView");
501501 tryCompare(navigationListView.currentItem.navigation, "loaded", true);
502502
503− mouseClick(dashNavigation, 0, 0);
503+ mouseClick(dashAltNavigationButton);
504504 compare(dashNavigationButton.showList, false);
505505 compare(dashAltNavigationButton.showList, false);
506506 }
507507
508+ function test_navigationsSwipeToNextScope() {
509+ var dashContentList = findChild(dashContent, "dashContentList");
510+ tryCompareFunction(function() { return findChild(dashContentList.currentItem, "dashNavigation") != null; }, true);
511+ var dashNavigation = findChild(dashContentList.currentItem, "dashNavigation");
512+ tryCompare(dashNavigation, "visible", true);
513+ var dashNavigationButton = findChild(dashContentList.currentItem, "altNavigationButton");
514+ verify(dashNavigationButton, "Can't find navigation button");
515+
516+ compare(dashNavigationButton.showList, false);
517+ waitForRendering(dashNavigationButton);
518+ mouseClick(dashNavigationButton, 0, 0);
519+ compare(dashNavigationButton.showList, true);
520+
521+ mouseFlick(dashNavigationButton, dashNavigationButton.width - units.gu(1), units.gu(1), units.gu(1), units.gu(1));
522+ compare(dashNavigationButton.showList, false);
523+
524+ var dashContentList = findChild(dashContent, "dashContentList");
525+ expectFail("", "should not change the parent list.");
526+ tryCompare(dashContentList, "currentIndex", 1);
527+ }
528+
508529 function test_searchHint() {
509530 var dashContentList = findChild(dashContent, "dashContentList");
510531 verify(dashContentList !== null);
tests/qmltests/Dash/tst_GenericScopeView.qml+26−26
@@ -163,12 +163,12 @@ Item {
163163 verify(!category.expanded);
164164
165165 var initialHeight = category.height;
166− mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
166+ mouseClick(seeAll);
167167 verify(category.expanded);
168168 tryCompare(category, "height", category.item.expandedHeight + seeAll.height);
169169
170170 waitForRendering(seeAll);
171− mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
171+ mouseClick(seeAll);
172172 verify(!category.expanded);
173173 }
174174
@@ -186,17 +186,17 @@ Item {
186186 verify(category2.expandable);
187187 verify(!category2.expanded);
188188
189− mouseClick(seeAll2, seeAll2.width / 2, seeAll2.height / 2);
189+ mouseClick(seeAll2);
190190 tryCompare(category2, "expanded", true);
191191
192192 categoryListView.positionAtBeginning();
193193
194194 var category0 = findChild(genericScopeView, "dashCategory0")
195195 var seeAll0 = findChild(category0, "seeAll")
196− mouseClick(seeAll0, seeAll0.width / 2, seeAll0.height / 2);
196+ mouseClick(seeAll0);
197197 tryCompare(category0, "expanded", true);
198198 tryCompare(category2, "expanded", false);
199− mouseClick(seeAll0, seeAll0.width / 2, seeAll0.height / 2);
199+ mouseClick(seeAll0);
200200 tryCompare(category0, "expanded", false);
201201 tryCompare(category2, "expanded", false);
202202 }
@@ -208,7 +208,7 @@ Item {
208208 spy.target = genericScopeView.scope;
209209 spy.signalName = "performQuery";
210210
211− mouseClick(header, header.width / 2, header.height / 2);
211+ mouseClick(header);
212212
213213 spy.wait();
214214 compare(spy.signalArguments[0][0], genericScopeView.scope.categories.data(1, Categories.RoleHeaderLink));
@@ -248,13 +248,13 @@ Item {
248248 categoryListView.contentY = units.gu(20);
249249 var seeAll = findChild(category, "seeAll");
250250 var floatingSeeLess = findChild(genericScopeView, "floatingSeeLess");
251− mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
251+ mouseClick(seeAll);
252252 tryCompare(category, "expanded", true);
253253 tryCompareFunction(function() {
254254 return category.item.height + floatingSeeLess.height ==
255255 genericScopeView.height - category.item.displayMarginBeginning - category.item.displayMarginEnd;
256256 }, true);
257− mouseClick(floatingSeeLess, floatingSeeLess.width / 2, floatingSeeLess.height / 2);
257+ mouseClick(floatingSeeLess);
258258 tryCompare(category, "expanded", false);
259259 }
260260
@@ -295,7 +295,7 @@ Item {
295295 true);
296296 var tile = findChild(findChild(genericScopeView, "dashCategory"+category), "delegate"+delegate);
297297 waitForRendering(tile);
298− mouseClick(tile, tile.width / 2, tile.height / 2);
298+ mouseClick(tile);
299299 tryCompare(testCase.subPageLoader, "open", true);
300300 tryCompare(testCase.subPageLoader, "x", 0);
301301 tryCompare(findChild(genericScopeView, "categoryListView"), "visible", false);
@@ -340,15 +340,15 @@ Item {
340340 tryCompare(testCase.subPageLoader, "open", false);
341341 tryCompare(testCase.subPageLoader, "visible", false);
342342
343− mouseClick(tile, tile.width / 2, tile.height / 2);
343+ mouseClick(tile);
344344
345345 tryCompare(testCase.subPageLoader, "open", false);
346346 tryCompare(testCase.subPageLoader, "visible", false);
347347
348− mousePress(tile, tile.width / 2, tile.height / 2);
348+ mousePress(tile);
349349 tryCompare(testCase.subPageLoader, "open", false);
350350 tryCompare(testCase.subPageLoader, "visible", false);
351− mouseRelease(tile, tile.width / 2, tile.height / 2);
351+ mouseRelease(tile);
352352 }
353353
354354 function test_showPreviewCarousel() {
@@ -359,18 +359,18 @@ Item {
359359 var tile = findChild(category, "carouselDelegate1");
360360 verify(tile, "Could not find delegate");
361361
362− mouseClick(tile, tile.width / 2, tile.height / 2);
362+ mouseClick(tile);
363363 tryCompare(tile, "explicitlyScaled", true);
364− mouseClick(tile, tile.width / 2, tile.height / 2);
364+ mouseClick(tile);
365365 tryCompare(testCase.subPageLoader, "open", true);
366366 tryCompare(testCase.subPageLoader, "x", 0);
367367
368368 closePreview();
369369
370− mousePress(tile, tile.width / 2, tile.height / 2);
370+ mousePress(tile);
371371 tryCompare(testCase.subPageLoader, "open", true);
372372 tryCompare(testCase.subPageLoader, "x", 0);
373− mouseRelease(tile, tile.width / 2, tile.height / 2);
373+ mouseRelease(tile);
374374
375375 closePreview();
376376 }
@@ -383,16 +383,16 @@ Item {
383383 var tile = findChild(category, "delegate1");
384384 verify(tile, "Could not find delegate");
385385
386− mouseClick(tile, tile.width / 2, tile.height / 2);
386+ mouseClick(tile);
387387 tryCompare(testCase.subPageLoader, "open", true);
388388 tryCompare(testCase.subPageLoader, "x", 0);
389389
390390 closePreview();
391391
392− mousePress(tile, tile.width / 2, tile.height / 2);
392+ mousePress(tile);
393393 tryCompare(testCase.subPageLoader, "open", true);
394394 tryCompare(testCase.subPageLoader, "x", 0);
395− mouseRelease(tile, tile.width / 2, tile.height / 2);
395+ mouseRelease(tile);
396396
397397 closePreview();
398398 }
@@ -429,7 +429,7 @@ Item {
429429 tryCompare(testCase.subPageLoader, "open", false);
430430 tryCompare(testCase.subPageLoader, "visible", false);
431431 var settings = findChild(innerHeader, "settings_header_button");
432− mouseClick(settings, settings.width / 2, settings.height / 2);
432+ mouseClick(settings);
433433 tryCompare(testCase.subPageLoader, "open", true);
434434 tryCompareFunction(function() { return (String(subPageLoader.source)).indexOf("ScopeSettingsPage.qml") != -1; }, true);
435435 tryCompare(genericScopeView, "subPageShown", true);
@@ -496,7 +496,7 @@ Item {
496496 verify(category0.expandable);
497497 verify(!category0.expanded);
498498
499− mouseClick(seeAll0, seeAll0.width / 2, seeAll0.height / 2);
499+ mouseClick(seeAll0);
500500 verify(category0.expanded);
501501 tryCompare(category0, "height", category0.item.expandedHeight + seeAll0.height);
502502 tryCompare(genericScopeView.categoryView, "contentY", units.gu(14));
@@ -509,7 +509,7 @@ Item {
509509 verify(category1.expandable);
510510 verify(!category1.expanded);
511511
512− mouseClick(seeAll1, seeAll1.width / 2, seeAll1.height / 2);
512+ mouseClick(seeAll1);
513513 verify(!category0.expanded);
514514 verify(category1.expanded);
515515 tryCompare(category1, "height", category1.item.expandedHeight + seeAll1.height);
@@ -539,7 +539,7 @@ Item {
539539 verify(category0.expandable);
540540 verify(!category0.expanded);
541541
542− mouseClick(seeAll0, seeAll0.width / 2, seeAll0.height / 2);
542+ mouseClick(seeAll0);
543543 verify(category0.expanded);
544544 tryCompare(category0, "height", category0.item.expandedHeight + seeAll0.height);
545545
@@ -550,7 +550,7 @@ Item {
550550 verify(category1.expandable);
551551 verify(!category1.expanded);
552552
553− mouseClick(seeAll1, seeAll1.width / 2, seeAll1.height / 2);
553+ mouseClick(seeAll1);
554554 verify(!category0.expanded);
555555 verify(category1.expanded);
556556 tryCompare(category1, "height", category1.item.expandedHeight + seeAll1.height);
@@ -578,7 +578,7 @@ Item {
578578 expectFail("Apps", "Click scope should not have a favorite button");
579579 var favoriteAction = findChild(innerHeader, "favorite_header_button");
580580 verify(favoriteAction, "Could not find the favorite action.");
581− mouseClick(favoriteAction, favoriteAction.width / 2, favoriteAction.height / 2);
581+ mouseClick(favoriteAction);
582582
583583 tryCompare(genericScopeView.scope, "favorite", !data.favorite);
584584
@@ -629,7 +629,7 @@ Item {
629629 var touchdown = findChild(item0, "touchdown");
630630
631631 compare(touchdown.visible, false);
632− mouseClick(item0, item0.width / 2, item0.height / 2);
632+ mouseClick(item0);
633633 compare(touchdown.visible, false);
634634
635635 cardTool.template["non-interactive"] = false;
tests/qmltests/Dash/tst_PageHeader.qml+1−1
@@ -157,7 +157,7 @@ Item {
157157 var recentSearches = findChild(headerContainer.popover, "recentSearches");
158158 verify(recentSearches, "Could not find recent searches in the popover");
159159 waitForRendering(recentSearches);
160− mouseClick(recentSearches.itemAt(0), 0, 0);
160+ mouseClick(recentSearches.itemAt(0));
161161
162162 compare(pageHeader.searchQuery, "Search2");
163163 tryCompareFunction(function() { return headerContainer.popover === null; }, true);
tests/qmltests/Dash/tst_PreviewListView.qml+2−2
@@ -73,7 +73,7 @@ Rectangle {
7373
7474 function test_notProcessing() {
7575 expectFail("", "processingMouseArea should not receive the click.");
76− mouseClick(listView, listView.width / 2, listView.height / 2);
76+ mouseClick(listView);
7777 clickedSpy.wait();
7878 }
7979
@@ -83,7 +83,7 @@ Rectangle {
8383
8484 tryCompare(listView, "processing", true);
8585
86− mouseClick(listView, listView.width / 2, listView.height / 2);
86+ mouseClick(listView);
8787 clickedSpy.wait();
8888 }
8989
tests/qmltests/Launcher/tst_Launcher.qml+8−8
@@ -154,7 +154,7 @@ Item {
154154 dragLauncherIntoView()
155155
156156 // tapping on the center of the screen should dismiss the launcher
157− mouseClick(launcher, launcher.width/2, launcher.height/2)
157+ mouseClick(launcher)
158158
159159 // should eventually get fully retracted (hidden)
160160 tryCompare(panel, "x", -launcher.panelWidth, 1000)
@@ -175,7 +175,7 @@ Item {
175175
176176 verify(appIcon != undefined)
177177
178− mouseClick(appIcon, appIcon.width/2, appIcon.height/2)
178+ mouseClick(appIcon)
179179
180180 tryCompare(launcher, "lastSelectedApplication",
181181 "dialer-app")
@@ -194,7 +194,7 @@ Item {
194194 var dashIcon = findChild(launcher, "dashItem")
195195 verify(dashIcon != undefined)
196196
197− mouseClick(dashIcon, dashIcon.width/2, dashIcon.height/2)
197+ mouseClick(dashIcon)
198198
199199 tryCompare(launcher, "showDashHome_count", 1)
200200
@@ -413,7 +413,7 @@ Item {
413413 compare(quickListShape.visible, false)
414414
415415 // Doing longpress
416− mousePress(draggedItem, draggedItem.width / 2, draggedItem.height / 2)
416+ mousePress(draggedItem)
417417 tryCompare(fakeDragItem, "visible", true) // Wait longpress happening
418418 tryCompare(quickListShape, "visible", true)
419419
@@ -448,7 +448,7 @@ Item {
448448 }
449449
450450 // Doing longpress
451− mousePress(draggedItem, draggedItem.width / 2, draggedItem.height / 2);
451+ mousePress(draggedItem);
452452 tryCompare(quickListShape, "opacity", 0.96);
453453 mouseRelease(draggedItem);
454454
@@ -481,7 +481,7 @@ Item {
481481 tryCompare(quickListShape, "visible", false)
482482
483483 // Doing longpress
484− mousePress(clickedItem, clickedItem.width / 2, clickedItem.height / 2)
484+ mousePress(clickedItem)
485485 tryCompare(clickedItem, "itemOpacity", 0) // Wait for longpress to happen
486486 verify(quickListShape.visible, "QuickList must be visible")
487487
@@ -492,7 +492,7 @@ Item {
492492 signalSpy.clear();
493493 signalSpy.signalName = "quickListTriggered"
494494
495− mouseClick(quickListEntry, quickListEntry.width / 2, quickListEntry.height / 2)
495+ mouseClick(quickListEntry)
496496
497497 if (data.clickable) {
498498 // QuickList needs to be closed when some clickable item is clicked
@@ -524,7 +524,7 @@ Item {
524524 tryCompare(quickList, "state", "")
525525
526526 // Doing longpress
527− mousePress(clickedItem, clickedItem.width / 2, clickedItem.height / 2)
527+ mousePress(clickedItem)
528528 tryCompare(clickedItem, "itemOpacity", 0) // Wait for longpress to happen
529529 verify(quickList, "state", "open")
530530
tests/qmltests/Notifications/tst_Notifications.qml+6−6
@@ -547,7 +547,7 @@ Item {
547547 compare(valueLabel.visible, data.valueLabelVisible, "value-label visibility is incorrect")
548548
549549 // test input does not fall through
550− mouseClick(notification, notification.width / 2, notification.height / 2)
550+ mouseClick(notification)
551551 if(data.type == Notification.Interactive) {
552552 actionSpy.wait()
553553 compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id for interactive action")
@@ -568,7 +568,7 @@ Item {
568568
569569 // only test the left/cancel-button if two actions have been passed in
570570 if (data.actions.length == 2) {
571− tryCompareFunction(function() { mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2); return actionSpy.signalArguments.length > 0; }, true);
571+ tryCompareFunction(function() { mouseClick(buttonCancel); return actionSpy.signalArguments.length > 0; }, true);
572572 compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
573573 actionSpy.clear()
574574 }
@@ -577,7 +577,7 @@ Item {
577577 verify(buttonAccept.color === data.buttonTinted ? "#3fb24f" : "#dddddd", "button has the wrong color-tint")
578578
579579 // click the positive/right button
580− tryCompareFunction(function() { mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2); return actionSpy.signalArguments.length > 0; }, true);
580+ tryCompareFunction(function() { mouseClick(buttonAccept); return actionSpy.signalArguments.length > 0; }, true);
581581 compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id positive action")
582582 actionSpy.clear()
583583 waitForRendering (notification)
@@ -592,19 +592,19 @@ Item {
592592
593593 // try clicking on choices in expanded comboList
594594 var choiceButton1 = findChild(notification, "notify_button3")
595− tryCompareFunction(function() { mouseClick(choiceButton1, choiceButton1.width / 2, choiceButton1.height / 2); return actionSpy.signalArguments.length > 0; }, true);
595+ tryCompareFunction(function() { mouseClick(choiceButton1); return actionSpy.signalArguments.length > 0; }, true);
596596 compare(actionSpy.signalArguments[0][0], data.actions[3]["id"], "got wrong id choice action 1")
597597 actionSpy.clear()
598598
599599 var choiceButton2 = findChild(notification, "notify_button4")
600− tryCompareFunction(function() { mouseClick(choiceButton2, choiceButton2.width / 2, choiceButton2.height / 2); return actionSpy.signalArguments.length > 0; }, true);
600+ tryCompareFunction(function() { mouseClick(choiceButton2); return actionSpy.signalArguments.length > 0; }, true);
601601 compare(actionSpy.signalArguments[0][0], data.actions[4]["id"], "got wrong id choice action 2")
602602 actionSpy.clear()
603603
604604 // click to collapse
605605 //tryCompareFunction(function() { mouseClick(comboButton, comboButton.width - comboButton.__styleInstance.dropDownWidth / 2, comboButton.height / 2); return comboButton.expanded == false; }, true);
606606 } else {
607− mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
607+ mouseClick(buttonCancel)
608608 compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
609609 }
610610 }
tests/qmltests/Notifications/tst_OptionToggle.qml+7−7
@@ -223,7 +223,7 @@ Row {
223223 }
224224
225225 // test input does not fall through
226− mouseClick(notification, notification.width / 2, notification.height / 2)
226+ mouseClick(notification)
227227 if(data.type == Notification.Interactive) {
228228 actionSpy.wait()
229229 compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id for interactive action")
@@ -244,7 +244,7 @@ Row {
244244
245245 // only test the left/cancel-button if two actions have been passed in
246246 if (data.actions.length == 2) {
247− tryCompareFunction(function() { mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2); return actionSpy.signalArguments.length > 0; }, true);
247+ tryCompareFunction(function() { mouseClick(buttonCancel); return actionSpy.signalArguments.length > 0; }, true);
248248 compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
249249 actionSpy.clear()
250250 }
@@ -253,7 +253,7 @@ Row {
253253 verify(buttonAccept.color === data.buttonTinted ? "#3fb24f" : "#dddddd", "button has the wrong color-tint")
254254
255255 // click the positive/right button
256− tryCompareFunction(function() { mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2); return actionSpy.signalArguments.length > 0; }, true);
256+ tryCompareFunction(function() { mouseClick(buttonAccept); return actionSpy.signalArguments.length > 0; }, true);
257257 compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id positive action")
258258 actionSpy.clear()
259259 waitForRendering(notification)
@@ -264,20 +264,20 @@ Row {
264264 tryCompareFunction(function() { return optionToggle.expanded == false; }, true);
265265
266266 // click to expand
267− tryCompareFunction(function() { mouseClick(optionToggle, optionToggle.width / 2, optionToggle.height / 2); return optionToggle.expanded == true; }, true);
267+ tryCompareFunction(function() { mouseClick(optionToggle); return optionToggle.expanded == true; }, true);
268268
269269 // try clicking on choices in expanded comboList
270270 var choiceButton1 = findChild(notification, "notify_button3")
271− tryCompareFunction(function() { mouseClick(choiceButton1, choiceButton1.width / 2, choiceButton1.height / 2); return actionSpy.signalArguments.length > 0; }, true);
271+ tryCompareFunction(function() { mouseClick(choiceButton1); return actionSpy.signalArguments.length > 0; }, true);
272272 compare(actionSpy.signalArguments[0][0], data.actions[3]["id"], "got wrong id choice action 1")
273273 actionSpy.clear()
274274
275275 var choiceButton2 = findChild(notification, "notify_button4")
276− tryCompareFunction(function() { mouseClick(choiceButton2, choiceButton2.width / 2, choiceButton2.height / 2); return actionSpy.signalArguments.length > 0; }, true);
276+ tryCompareFunction(function() { mouseClick(choiceButton2); return actionSpy.signalArguments.length > 0; }, true);
277277 compare(actionSpy.signalArguments[0][0], data.actions[4]["id"], "got wrong id choice action 2")
278278 actionSpy.clear()
279279 } else {
280− mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
280+ mouseClick(buttonCancel)
281281 compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
282282 }
283283 }
tests/qmltests/Notifications/tst_SwipeToAct.qml+1−1
@@ -240,7 +240,7 @@ Item {
240240 }
241241
242242 // test input does not fall through
243− mouseClick(notification, notification.width / 2, notification.height / 2)
243+ mouseClick(notification)
244244 if(data.type == Notification.Interactive) {
245245 actionSpy.wait()
246246 compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id for interactive action")
tests/qmltests/Notifications/tst_VisualSnapDecisionsQueue.qml+2−2
@@ -214,7 +214,7 @@ Row {
214214
215215 // click/tap on each snap-decision and verify only one is in expanded-state at any time
216216 for (var index = 0; index < snap_decision.length; index++) {
217− mouseClick(snap_decision[index], snap_decision[index].width / 2, snap_decision[index].height / 2)
217+ mouseClick(snap_decision[index])
218218 for (var kindex = 0; kindex < snap_decision.length; kindex++) {
219219 if (kindex == index) {
220220 compare(snap_decision[kindex].state, "expanded", "state of "+ kindex + ".snap-decision is not expanded");
@@ -227,7 +227,7 @@ Row {
227227 // remove top-most and verify one of the remaining ones is still getting expanded
228228
229229 // make first snap-decision expand
230− mouseClick(snap_decision[0], snap_decision[0].width / 2, snap_decision[0].height / 2);
230+ mouseClick(snap_decision[0]);
231231
232232 for (var index = 1; index < snap_decision.length; index++) {
233233 removeTopMostNotification();
tests/qmltests/Panel/Indicators/tst_IndicatorsLight.qmlnew file+129
@@ -0,0 +1,129 @@
1+/*
2+ * Copyright 2014 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 QtQuick.Layouts 1.1
19+import Unity.Test 0.1 as UT
20+import Unity.Indicators 0.1 as Indicators
21+import Ubuntu.Components 1.1
22+import Powerd 0.1
23+import Lights 0.1
24+import QMenuModel 0.1
25+import "../../../../qml/Panel/Indicators"
26+
27+Item {
28+ id: root
29+ width: units.gu(30)
30+ height: units.gu(30)
31+
32+ property var newMessage: {
33+ "messages" : {
34+ 'valid': true,
35+ 'state': {
36+ 'icons': [ 'indicator-messages-new' ]
37+ }
38+ }
39+ };
40+ property var noNewMessage: {
41+ "messages" : {
42+ 'valid': true,
43+ 'state': {
44+ 'icons': [ 'indicator-messages' ]
45+ }
46+ }
47+ };
48+
49+ Component {
50+ id: light
51+ IndicatorsLight {}
52+ }
53+
54+ Loader {
55+ id: loader
56+ sourceComponent: light
57+ }
58+
59+ Component.onCompleted: {
60+ ActionData.data = newMessage;
61+ Powerd.status = Powerd.On
62+ }
63+
64+ RowLayout {
65+ anchors.fill: parent
66+ anchors.margins: units.gu(1)
67+
68+ Item {
69+ Layout.fillWidth: true
70+ Layout.fillHeight: true
71+
72+ Rectangle {
73+ width: units.gu(4)
74+ height: width
75+ radius: width / 2
76+ anchors.centerIn: parent
77+
78+ color: Lights.state === Lights.On ? Lights.color : "transparent"
79+
80+ border.color: "black"
81+ border.width: 1
82+ }
83+ }
84+
85+ ColumnLayout {
86+ Layout.alignment: Qt.AlignTop
87+ Layout.fillWidth: false
88+ Layout.preferredWidth: units.gu(15)
89+
90+ Button {
91+ Layout.fillWidth: true
92+ text: Powerd.status === Powerd.On ? "Power Off" : "Power On"
93+ onClicked: {
94+ if (Powerd.status === Powerd.On) Powerd.status = Powerd.Off;
95+ else Powerd.status = Powerd.On;
96+ }
97+ }
98+ }
99+ }
100+
101+ UT.UnityTestCase {
102+ name: "IndicatorsLight"
103+ when: windowShown
104+
105+ function init() {
106+ // reload
107+ ActionData.data = noNewMessage;
108+ loader.sourceComponent = undefined;
109+ loader.sourceComponent = light;
110+ Powerd.status = Powerd.On
111+ }
112+
113+ function test_LightsStatus_data() {
114+ return [
115+ { tag: "Powerd.On with No Message", powerd: Powerd.On, actionData: noNewMessage, expected: Lights.Off },
116+ { tag: "Powerd.Off with No Message", powerd: Powerd.Off, actionData: noNewMessage, expected: Lights.Off },
117+ { tag: "Powerd.On with New Message", powerd: Powerd.On, actionData: newMessage, expected: Lights.Off },
118+ { tag: "Powerd.Off with New Message", powerd: Powerd.Off, actionData: newMessage, expected: Lights.On },
119+ ]
120+ }
121+
122+ function test_LightsStatus(data) {
123+ Powerd.status = data.powerd;
124+ ActionData.data = data.actionData;
125+
126+ compare(Lights.state, data.expected, "Light does not match expected value");
127+ }
128+ }
129+}
tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml+52−1
@@ -17,6 +17,7 @@
1717import QtQuick 2.0
1818import QtTest 1.0
1919import Unity.Test 0.1 as UT
20+import Ubuntu.Settings.Menus 0.1 as Menus
2021import QMenuModel 0.1
2122import Utils 0.1 as Utils
2223import "../../../../qml/Panel/Indicators"
@@ -448,9 +449,59 @@ Item {
448449 }
449450
450451 function test_create_transferMenu(data) {
452+ ActionData.data = {
453+ "transfer-state.queued": {
454+ 'valid': true,
455+ 'state': {
456+ 'state': Menus.TransferState.Queued,
457+ 'percent': data.progress
458+ }
459+ },
460+ "transfer-state.running": {
461+ 'valid': true,
462+ 'state': {
463+ 'state': Menus.TransferState.Running,
464+ 'seconds-left': 100,
465+ 'percent': data.progress
466+ }
467+ },
468+ "transfer-state.paused": {
469+ 'valid': true,
470+ 'state': {
471+ 'state': Menus.TransferState.Paused,
472+ 'seconds-left': 100,
473+ 'percent': data.progress
474+ }
475+ },
476+ "transfer-state.cancelled": {
477+ 'valid': true,
478+ 'state': {
479+ 'state': Menus.TransferState.Canceled,
480+ 'percent': data.progress
481+ }
482+ },
483+ "transfer-state.finished": {
484+ 'valid': true,
485+ 'state': {
486+ 'state': Menus.TransferState.Finished,
487+ 'seconds-left': 0,
488+ 'percent': data.progress
489+ }
490+ },
491+ "transfer-state.error": {
492+ 'valid': true,
493+ 'state': {
494+ 'state': Menus.TransferState.Error,
495+ 'seconds-left': 100,
496+ 'percent': data.progress
497+ }
498+ }
499+ };
500+
451501 menuData.type = "com.canonical.indicator.transfer";
452502 menuData.label = data.label;
453503 menuData.sensitive = data.enabled;
504+ menuData.isToggled = data.active;
454505 menuData.icon = data.icon;
455506 menuData.ext = {
456507 'xCanonicalUid': data.tag
@@ -464,7 +515,7 @@ Item {
464515 compare(loader.item.text, data.label, "Label does not match data");
465516 compare(loader.item.iconSource, data.icon, "Icon does not match data");
466517 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
467− compare(loader.item.progress, data.progress, "Icon does not match data");
518+ compare(loader.item.progress, data.progress, "Progress does not match data");
468519 compare(loader.item.active, data.active, "Active does not match data");
469520 compare(loader.item.stateText, data.stateText, "State text does not match data");
470521 }
tests/qmltests/Panel/tst_IndicatorsBar.qml+1−1
@@ -197,7 +197,7 @@ IndicatorTest {
197197 if (indicatorsBar.mapFromItem(dataItem, dataItem.width/2, dataItem.height/2).x < 0) {
198198 skip("Out of bounds");
199199 }
200− mouseClick(dataItem, dataItem.width/2, dataItem.height/2);
200+ mouseClick(dataItem);
201201 verify(dataItem.selected === true);
202202 }
203203
tests/qmltests/Stages/tst_PhoneStage.qml+2
@@ -205,6 +205,7 @@ Item {
205205
206206 if (data.targetPhase == 2) {
207207 var app2 = findChild(spreadView, "appDelegate2");
208+ tryCompare(app2, "swipeToCloseEnabled", true);
208209 mouseClick(app2, units.gu(1), units.gu(1));
209210 }
210211
@@ -249,6 +250,7 @@ Item {
249250 }
250251
251252 console.log("clicking app", data.index, "(", appId, ")")
253+ tryCompare(tile, "swipeToCloseEnabled", true);
252254 mouseClick(spreadView, tile.mapToItem(spreadView).x + units.gu(1), spreadView.height / 2)
253255 tryCompare(ApplicationManager, "focusedApplicationId", appId);
254256 tryCompare(spreadView, "phase", 0);
tests/qmltests/Wizard/tst_Wizard.qml+36−12
@@ -18,6 +18,7 @@ import QtQuick 2.3
1818import QtTest 1.0
1919import AccountsService 0.1
2020import MeeGo.QOfono 0.2
21+import QMenuModel 0.1
2122import Ubuntu.Components 1.1
2223import Ubuntu.SystemSettings.SecurityPrivacy 1.0
2324import Unity.Test 0.1 as UT
@@ -58,6 +59,16 @@ Item {
5859 signalName: "setSecurityCalled"
5960 }
6061
62+ SignalSpy {
63+ id: activateLocationSpy
64+ signalName: "activated"
65+ }
66+
67+ SignalSpy {
68+ id: activateGPSSpy
69+ signalName: "activated"
70+ }
71+
6172 function setup() {
6273 AccountsService.hereEnabled = false;
6374 AccountsService.hereLicensePath = Qt.resolvedUrl("licenses");
@@ -68,6 +79,19 @@ Item {
6879
6980 updateSessionLanguageSpy.clear();
7081 setSecuritySpy.clear();
82+ activateLocationSpy.clear();
83+ activateGPSSpy.clear();
84+
85+ ActionData.data = {
86+ "location-detection-enabled": {
87+ 'valid': true,
88+ 'state': false
89+ },
90+ "gps-detection-enabled": {
91+ 'valid': true,
92+ 'state': false
93+ }
94+ };
7195 }
7296
7397 Component.onCompleted: {
@@ -360,8 +384,8 @@ Item {
360384 var nopeCheck = findChild(page, "nopeCheck");
361385
362386 var locationActionGroup = findInvisibleChild(page, "locationActionGroup");
363− tryCompare(locationActionGroup.location, "state", false);
364− tryCompare(locationActionGroup.gps, "state", false);
387+ activateLocationSpy.target = locationActionGroup.location;
388+ activateGPSSpy.target = locationActionGroup.gps;
365389
366390 tap(gpsCheck);
367391 tryCompare(gpsCheck, "checked", true);
@@ -370,8 +394,8 @@ Item {
370394
371395 tap(findChild(page, "forwardButton"));
372396 tryCompare(AccountsService, "hereEnabled", false);
373− tryCompare(locationActionGroup.location, "state", true);
374− tryCompare(locationActionGroup.gps, "state", true);
397+ tryCompare(activateLocationSpy, "count", 1)
398+ tryCompare(activateGPSSpy, "count", 1)
375399 }
376400
377401 function test_locationNope() {
@@ -381,8 +405,8 @@ Item {
381405 var nopeCheck = findChild(page, "nopeCheck");
382406
383407 var locationActionGroup = findInvisibleChild(page, "locationActionGroup");
384− tryCompare(locationActionGroup.location, "state", false);
385− tryCompare(locationActionGroup.gps, "state", false);
408+ activateLocationSpy.target = locationActionGroup.location;
409+ activateGPSSpy.target = locationActionGroup.gps;
386410
387411 tap(nopeCheck);
388412 tryCompare(gpsCheck, "checked", false);
@@ -391,8 +415,8 @@ Item {
391415
392416 tap(findChild(page, "forwardButton"));
393417 tryCompare(AccountsService, "hereEnabled", false);
394− tryCompare(locationActionGroup.location, "state", false);
395− tryCompare(locationActionGroup.gps, "state", false);
418+ tryCompare(activateLocationSpy, "count", 0)
419+ tryCompare(activateGPSSpy, "count", 0)
396420 }
397421
398422 function test_locationHere() {
@@ -402,8 +426,8 @@ Item {
402426 var nopeCheck = findChild(page, "nopeCheck");
403427
404428 var locationActionGroup = findInvisibleChild(page, "locationActionGroup");
405− tryCompare(locationActionGroup.location, "state", false);
406− tryCompare(locationActionGroup.gps, "state", false);
429+ activateLocationSpy.target = locationActionGroup.location;
430+ activateGPSSpy.target = locationActionGroup.gps;
407431
408432 // no tap because HERE is the default
409433 tryCompare(gpsCheck, "checked", false);
@@ -412,8 +436,8 @@ Item {
412436
413437 tap(findChild(page, "forwardButton"));
414438 tryCompare(AccountsService, "hereEnabled", true);
415− tryCompare(locationActionGroup.location, "state", true);
416− tryCompare(locationActionGroup.gps, "state", true);
439+ tryCompare(activateLocationSpy, "count", 1)
440+ tryCompare(activateGPSSpy, "count", 1)
417441 }
418442
419443 function test_locationHereTerms() {
tests/qmltests/tst_Shell.qml+3−3
@@ -222,7 +222,7 @@ Item {
222222
223223 notifications.model = mockNotificationsModel;
224224
225− // FIXME: Hack: SortFilterProxyModelQML doesn't work with QML ListModels which we use
225+ // FIXME: Hack: UnitySortFilterProxyModelQML doesn't work with QML ListModels which we use
226226 // for mocking here (RoleType can't be found in the QML model). As we only need to show
227227 // one SnapDecision lets just disable the filtering and make appear any notification as a
228228 // SnapDecision.
@@ -245,7 +245,7 @@ Item {
245245
246246 // Clicking the button should dismiss the notification and return focus
247247 var buttonAccept = findChild(notification, "notify_button0");
248− mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2);
248+ mouseClick(buttonAccept);
249249
250250 // Make sure we're back to normal
251251 tryCompare(app.session.surface, "activeFocus", true);
@@ -463,7 +463,7 @@ Item {
463463 var launcher = findChild(shell, "launcherPanel")
464464 tryCompareFunction(function() {return launcher.x === 0 || launcher.x === -launcher.width;}, true);
465465 if (launcher.x === 0) {
466− mouseClick(shell, shell.width / 2, shell.height / 2)
466+ mouseClick(shell)
467467 }
468468 tryCompare(launcher, "x", -launcher.width)
469469
tests/qmltests/tst_ShellWithPin.qml+31
@@ -116,6 +116,12 @@ Item {
116116 signalName: "resettingDevice"
117117 }
118118
119+ SignalSpy {
120+ id: promptSpy
121+ target: LightDM.Greeter
122+ signalName: "showPrompt"
123+ }
124+
119125 Telephony.CallEntry {
120126 id: phoneCall
121127 phoneNumber: "+447812221111"
@@ -472,5 +478,30 @@ Item {
472478
473479 }
474480
481+ /* We had a bug (1395075) where if a user kept swiping as the greeter
482+ loaded, they would be able to get into the session before the
483+ lockscreen appeared. Make sure that doesn't happen. */
484+ function test_earlyDisable() {
485+ // Kill current shell
486+ shellLoader.itemDestroyed = false;
487+ shellLoader.active = false;
488+ tryCompare(shellLoader, "itemDestroyed", true);
489+ LightDM.Greeter.authenticate(""); // reset greeter
490+
491+ // Create new shell
492+ promptSpy.clear();
493+ shellLoader.active = true;
494+ tryCompareFunction(function() {return shell !== null}, true);
495+
496+ // Confirm that we start disabled
497+ compare(promptSpy.count, 0);
498+ verify(!shell.enabled);
499+
500+ // And that we only become enabled once the lockscreen is up
501+ tryCompare(shell, "enabled", true);
502+ verify(promptSpy.count > 0);
503+ var lockscreen = findChild(shell, "lockscreen");
504+ verify(lockscreen.shown);
505+ }
475506 }
476507}
tests/qmltests/tst_TabletShell.qml+1−1
@@ -211,7 +211,7 @@ Row {
211211 tryCompare(passwordMouseArea, "enabled", isButton)
212212
213213 var passwordInput = findChild(shell, "passwordInput")
214− mouseClick(passwordInput, passwordInput.width / 2, passwordInput.height / 2)
214+ mouseClick(passwordInput)
215215 }
216216
217217 function confirmLoggedIn(loggedIn) {
tests/utils/modules/Unity/Test/UnityTestCase.qml+71
@@ -37,6 +37,67 @@ TestCase {
3737 this.getCurrentTimeMs = function() {return this.currentTimeMs}
3838 }
3939
40+ function mouseClick(item, x, y, button, modifiers, delay) {
41+ if (button === undefined)
42+ button = Qt.LeftButton;
43+ if (modifiers === undefined)
44+ modifiers = Qt.NoModifier;
45+ if (delay === undefined)
46+ delay = -1;
47+ if (x === undefined)
48+ x = item.width / 2;
49+ if (y === undefined)
50+ y = item.height / 2;
51+ if (!qtest_events.mouseClick(item, x, y, button, modifiers, delay))
52+ qtest_fail("window not shown", 2);
53+ }
54+
55+ function mouseDoubleClick(item, x, y, button, modifiers, delay) {
56+ if (button === undefined)
57+ button = Qt.LeftButton;
58+ if (modifiers === undefined)
59+ modifiers = Qt.NoModifier;
60+ if (delay === undefined)
61+ delay = -1;
62+ if (x === undefined)
63+ x = item.width / 2;
64+ if (y === undefined)
65+ y = item.height / 2;
66+ if (!qtest_events.mouseDoubleClick(item, x, y, button, modifiers, delay))
67+ qtest_fail("window not shown", 2)
68+ }
69+
70+ function mousePress(item, x, y, button, modifiers, delay) {
71+ if (button === undefined)
72+ button = Qt.LeftButton;
73+ if (modifiers === undefined)
74+ modifiers = Qt.NoModifier;
75+ if (delay === undefined)
76+ delay = -1;
77+ if (x === undefined)
78+ x = item.width / 2;
79+ if (y === undefined)
80+ y = item.height / 2;
81+ if (!qtest_events.mousePress(item, x, y, button, modifiers, delay))
82+ qtest_fail("window not shown", 2)
83+ }
84+
85+ function mouseRelease(item, x, y, button, modifiers, delay) {
86+ if (button === undefined)
87+ button = Qt.LeftButton;
88+ if (modifiers === undefined)
89+ modifiers = Qt.NoModifier;
90+ if (delay === undefined)
91+ delay = -1;
92+ if (x === undefined)
93+ x = item.width / 2;
94+ if (y === undefined)
95+ y = item.height / 2;
96+ if (!qtest_events.mouseRelease(item, x, y, button, modifiers, delay))
97+ qtest_fail("window not shown", 2)
98+ }
99+
100+
40101 // Flickable won't recognise a single mouse move as dragging the flickable.
41102 // Use 5 steps because it's what
42103 // Qt uses in QQuickViewTestUtil::flick
@@ -381,4 +442,14 @@ TestCase {
381442 }
382443 }
383444 }
445+
446+ // TODO This function can be removed altogether once we use Qt 5.5 which has the same feature
447+ function waitForRendering(item, timeout) {
448+ if (timeout === undefined)
449+ timeout = 5000;
450+ if (!item)
451+ qtest_fail("No item given to waitForRendering", 1);
452+ return qtest_results.waitForRendering(item, timeout);
453+ }
454+
384455}