on xenial help sign in
Fix giant merge mess.
8daa47eJosh Arenson
CMakeLists.txt+4−1
@@ -57,7 +57,10 @@ find_package(Qt5DBus 5.4 REQUIRED)
57find_package(Qt5Concurrent 5.4 REQUIRED)
57find_package(Qt5Concurrent 5.4 REQUIRED)
58find_package(Qt5Sql 5.4 REQUIRED)
58find_package(Qt5Sql 5.4 REQUIRED)
59
59
60−pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=12)
60+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=13)
61+pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
62+pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
63+pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
61
64
62# Standard install paths
65# Standard install paths
63include(GNUInstallDirs)
66include(GNUInstallDirs)
data/unity8.conf+4−2
@@ -44,7 +44,11 @@ pre-start script
44 fi
44 fi
45
45
46 initctl set-env --global MIR_SERVER_PROMPT_FILE=1
46 initctl set-env --global MIR_SERVER_PROMPT_FILE=1
47+end script
48+
49+exec ${BINARY:-unity8} $ARGS
47
50
51+post-start script
48 initctl emit --no-wait indicator-services-start
52 initctl emit --no-wait indicator-services-start
49
53
50 # Disable Qt's stuttering 'touch compression' to fix scrolling smoothness
54 # Disable Qt's stuttering 'touch compression' to fix scrolling smoothness
@@ -58,8 +62,6 @@ pre-start script
58 # initctl set-env MIR_SERVER_NBUFFERS=2
62 # initctl set-env MIR_SERVER_NBUFFERS=2
59end script
63end script
60
64
61−exec ${BINARY:-unity8} $ARGS
62−
63post-stop script
65post-stop script
64 initctl set-env --global MIR_SOCKET=$UNITY_MIR_SOCKET
66 initctl set-env --global MIR_SOCKET=$UNITY_MIR_SOCKET
65 initctl unset-env --global UNITY_MIR_SOCKET
67 initctl unset-env --global UNITY_MIR_SOCKET
debian/changelog+155
@@ -1,3 +1,158 @@
1+unity8 (8.11+16.04.20160216.1-0ubuntu1) xenial; urgency=medium
2+
3+ [ Albert Astals Cid ]
4+ * Make the audio previews create a playlist (LP: #1540477)
5+
6+ [ CI Train Bot ]
7+ * Resync trunk. added: po/aa.po
8+ * Update translation template
9+
10+ -- Pawel Stolowski <ci-train-bot@canonical.com> Tue, 16 Feb 2016 03:24:46 +0000
11+
12+unity8 (8.11+16.04.20160212-0ubuntu1) xenial; urgency=medium
13+
14+ [ Albert Astals Cid ]
15+ * Do not use components in card creator generated code
16+ * Forward the makesurevisible signal from the inner preview widget
17+ * Make fallback also be fallback when the image is empty and not only
18+ on error (LP: #1531913)
19+ * Make the artShapeSize assignment be updated when using dynamic grid
20+ units
21+ * Visual improvements to the dash audio play cards
22+ * We don't use the unity-scope-scopes anymore (LP: #1439172)
23+
24+ [ Andrea Cimitan ]
25+ * only request a bigger image if zoomable widget data property is
26+ true, otherwise just leave the screen size (LP: #1536814)
27+
28+ [ CI Train Bot ]
29+ * Update translation template
30+
31+ [ Daniel d'Andrada ]
32+ * Set initial surface size (LP: #1532974)
33+
34+ [ Daniel d'Andrada, Michał Sawicz ]
35+ * Window Size Hints
36+
37+ [ Florian Boucault ]
38+ * Splash screen: delay showing the ActivityIndicator by 2 seconds.
39+
40+ [ Lukáš Tinkl ]
41+ * Replace the word "phone" with a more generic term "device" in the
42+ welcome wizard (LP: #1294732, #1543527)
43+
44+ [ Michael Terry ]
45+ * Have the tablet greeter set appropriate OSK hints if the user has a
46+ passcode instead of a passphrase. (LP: #1544173)
47+
48+ [ Michael Zanetti ]
49+ * Don't eat mouse events in the edgebarrer
50+
51+ [ Michał Sawicz ]
52+ * Bump unity-api dependencies
53+
54+ [ Nick Dedekind ]
55+ * Added support for secondary indicator actions (LP: #1398888)
56+ * Remove zombie if they're not animated. (LP: #1534541)
57+ * Removed unused panel resources
58+
59+ [ Ted Gould ]
60+ * Start the indicators after Unity8 starts instead of before
61+
62+ -- Michał Sawicz <michal.sawicz@canonical.com> Fri, 12 Feb 2016 00:12:41 +0000
63+
64+unity8 (8.11+16.04.20160208-0ubuntu1) xenial; urgency=medium
65+
66+ [ Albert Astals Cid ]
67+ * LVWPH: Reset to initial values when list is empty (LP: #1540490)
68+ * Make LazyImage qmltest less flaky on CI
69+
70+ [ Andrea Cimitan ]
71+ * Make LazyImage qmltest less flaky on CI
72+
73+ [ CI Train Bot ]
74+ * Resync trunk.
75+ * Update translation template
76+
77+ [ Michael Terry ]
78+ * Display the current user's real name on the tablet lockscreen. (LP:
79+ #1536714)
80+
81+ -- Michał Sawicz <michal.sawicz@canonical.com> Mon, 08 Feb 2016 09:38:00 +0000
82+
83+unity8 (8.11+16.04.20160129-0ubuntu1) xenial; urgency=medium
84+
85+ [ Albert Astals Cid ]
86+ * Audio Preview Button: Don't gain focus on press (LP: #1517830)
87+ * Better attempt at sanitization
88+ * Better looking application scopes for wide screens
89+ * Call printSettings correctly
90+ * Card test: Limit the precision we ask for doubles to be equal
91+ * Convert while into tryCompareFunction
92+ * Do not use the same filepath parameter for all the card creator
93+ createQmlObject calls (LP: #1536379)
94+ * Fix some test shells being unstable in the armhf builders
95+ * Make revealByEdgePush more stable
96+ * More reliable compares
97+ * Move the mouse over the bfb before waiting for rendering
98+ * Remove the DDAs constrains for every test
99+ * Set the background source size to the max we'll need + new
100+ background (LP: #1539011)
101+
102+ [ Andrea Cimitan ]
103+ * Dynamically change click scope card size according to size (LP:
104+ #1536745)
105+ * Should fix lazyimage test failures on fast machines
106+
107+ [ CI Train Bot ]
108+ * Fix card tests on the phone
109+ * Update translation template
110+
111+ [ Daniel d'Andrada ]
112+ * Desktop stage rotates only to follow screen orientation (LP:
113+ #1515977)
114+
115+ [ Lukáš Tinkl ]
116+ * Hide/reveal the mouse pointer on touch/mouse events renamed:
117+ plugins/Utils/HomeKeyWatcher.cpp =>
118+ plugins/Utils/WindowInputMonitor.cpp plugins/Utils/HomeKeyWatcher.h
119+ => plugins/Utils/WindowInputMonitor.h
120+ tests/mocks/Utils/HomeKeyWatcher.qml =>
121+ tests/mocks/Utils/WindowInputMonitor.qml
122+ tests/plugins/Utils/HomeKeyWatcherTest.cpp =>
123+ tests/plugins/Utils/WindowInputMonitorTest.cpp
124+
125+ [ Michael Terry ]
126+ * Synchronize the mouse-cursor-speed and touchpad-cursor-speed
127+ properties with USC. (LP: #1536383)
128+
129+ [ Michael Zanetti ]
130+ * Add InputMethod to secondary screen
131+ * Add a virtual Touchpad while external screen is connected
132+ * Make big tablets switch to windowed mode by plugging a kbd only (LP:
133+ #1535399)
134+ * Prevent alt key presses from being dispatched to the app on alt+tab
135+ (LP: #1532862)
136+
137+ [ Michał Sawicz ]
138+ * Make qmluitests.sh more robust and allow parallel test execution
139+ * Skip SessionBackendTest::testLogin1Capabilities until we talk to a
140+ mock instead (LP: #1532112, #1532113)
141+
142+ -- Michał Sawicz <michal.sawicz@canonical.com> Fri, 29 Jan 2016 11:53:27 +0000
143+
144+unity8 (8.11+16.04.20160122-0ubuntu1) xenial; urgency=medium
145+
146+ [ Albert Astals Cid ]
147+ * Fix bug #1536296 added: tests/plugins/Dash/cardcreator/10.tst (LP:
148+ #1536296)
149+ * Fix card tests on the phone
150+
151+ [ CI Train Bot ]
152+ * Update translation template
153+
154+ -- Michał Sawicz <michal.sawicz@canonical.com> Fri, 22 Jan 2016 16:56:04 +0000
155+
1unity8 (8.11+16.04.20160111.1-0ubuntu1) xenial; urgency=medium
156unity8 (8.11+16.04.20160111.1-0ubuntu1) xenial; urgency=medium
2
157
3 [ Albert Astals Cid ]
158 [ Albert Astals Cid ]
debian/control+4−4
@@ -30,7 +30,7 @@ Build-Depends: cmake,
30 libqt5xmlpatterns5-dev,
30 libqt5xmlpatterns5-dev,
31 libsystemsettings-dev,
31 libsystemsettings-dev,
32 libudev-dev,
32 libudev-dev,
33− libunity-api-dev (>= 7.105),
33+ libunity-api-dev (>= 7.106),
34 libusermetricsoutput1-dev,
34 libusermetricsoutput1-dev,
35# Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
35# Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
36 libx11-dev[!armhf],
36 libx11-dev[!armhf],
@@ -126,7 +126,6 @@ Depends: dmz-cursor-theme,
126 ${shlibs:Depends},
126 ${shlibs:Depends},
127Recommends: unity-scope-click,
127Recommends: unity-scope-click,
128 unity-scope-mediascanner2,
128 unity-scope-mediascanner2,
129− unity-scope-scopes,
130Breaks: indicator-network (<< 0.5.1+14.10.20141014),
129Breaks: indicator-network (<< 0.5.1+14.10.20141014),
131 ubuntu-touch-session (<< 0.107),
130 ubuntu-touch-session (<< 0.107),
132 unity8-greeter (<< 7.89),
131 unity8-greeter (<< 7.89),
@@ -144,7 +143,7 @@ Depends: qml-module-qtquick-layouts,
144 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1627) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1627),
143 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1627) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1627),
145 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
144 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
146 ubuntu-thumbnailer-impl-0,
145 ubuntu-thumbnailer-impl-0,
147− unity-application-impl-12,
146+ unity-application-impl-13,
148 unity-notifications-impl-3,
147 unity-notifications-impl-3,
149 unity-plugin-scopes | unity-scopes-impl,
148 unity-plugin-scopes | unity-scopes-impl,
150 unity-scopes-impl-9,
149 unity-scopes-impl-9,
@@ -191,6 +190,7 @@ Depends: ${misc:Depends},
191 ${shlibs:Depends},
190 ${shlibs:Depends},
192Provides: unity-application-impl,
191Provides: unity-application-impl,
193 unity-application-impl-12,
192 unity-application-impl-12,
193+ unity-application-impl-13,
194Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1)
194Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1)
195Description: Fake environment for running Unity 8 shell
195Description: Fake environment for running Unity 8 shell
196 Provides fake implementations of some QML modules used by Unity 8 shell
196 Provides fake implementations of some QML modules used by Unity 8 shell
@@ -200,7 +200,7 @@ Package: unity8-private
200Architecture: any
200Architecture: any
201Multi-Arch: same
201Multi-Arch: same
202Pre-Depends: ${misc:Pre-Depends},
202Pre-Depends: ${misc:Pre-Depends},
203−Depends: accountsservice-ubuntu-schemas (>= 0.0.3),
203+Depends: accountsservice-ubuntu-schemas (>= 0.0.5),
204 gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
204 gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
205 libhardware2,
205 libhardware2,
206 pay-service,
206 pay-service,
debian/tests/autopilot.shnew file+13
@@ -0,0 +1,13 @@
1+#!/bin/sh
2+
3+# log all commands and abort on error
4+set -xe
5+
6+if [ ! -f /system/build.prop ]; then
7+ echo "WARNING: Skipping autopilot test, will only run on devices at the moment."
8+ exit 0
9+fi
10+
11+initctl --session stop unity8
12+autopilot3 run --verbose --format xml --output "${ADT_ARTIFACTS}/unity8.xml" unity8
13+initctl --session start unity8
debian/tests/control+5
@@ -3,3 +3,8 @@ Restrictions: allow-stderr
3Depends: @,
3Depends: @,
4 @builddeps@,
4 @builddeps@,
5 xvfb,
5 xvfb,
6+
7+Tests: autopilot.sh
8+Restrictions: allow-stderr,
9+ isolation-machine,
10+Depends: unity8-autopilot,
debian/tests/qmluitests.sh+4−2
@@ -1,5 +1,8 @@
1#!/bin/sh
1#!/bin/sh
2
2
3+# log all commands and abort on error
4+set -xe
5+
3SHELL_QML_PATH=$(pkg-config --variable=plugindir unity-shell-api)
6SHELL_QML_PATH=$(pkg-config --variable=plugindir unity-shell-api)
4UNITY_SOURCE_DIR=$(readlink -f $(dirname $(readlink -f $0))/../..)
7UNITY_SOURCE_DIR=$(readlink -f $(dirname $(readlink -f $0))/../..)
5
8
@@ -15,5 +18,4 @@ dh_auto_build --parallel -- -C tests/utils
15
18
16export UNITY_SOURCE_DIR
19export UNITY_SOURCE_DIR
17
20
18−# FIXME: --parallel here causes some failures
19−dh_auto_build -- -k xvfballtests
21+dh_auto_build --parallel -- -k xvfballtests
debian/unity8-private.install+1
@@ -12,6 +12,7 @@ usr/lib/*/unity8/qml/ScreenGrabber
12usr/lib/*/unity8/qml/SessionBroadcast
12usr/lib/*/unity8/qml/SessionBroadcast
13usr/lib/*/unity8/qml/Ubuntu
13usr/lib/*/unity8/qml/Ubuntu
14usr/lib/*/unity8/qml/Unity
14usr/lib/*/unity8/qml/Unity
15+usr/lib/*/unity8/qml/UInput
15usr/lib/*/unity8/qml/Utils
16usr/lib/*/unity8/qml/Utils
16usr/lib/*/unity8/qml/Wizard
17usr/lib/*/unity8/qml/Wizard
17usr/share/accountsservice/interfaces
18usr/share/accountsservice/interfaces
plugins/AccountsService/AccountsService.cpp+61
@@ -19,6 +19,7 @@
19#include "AccountsService.h"
19#include "AccountsService.h"
20#include "AccountsServiceDBusAdaptor.h"
20#include "AccountsServiceDBusAdaptor.h"
21
21
22+#include <QDBusInterface>
22#include <QFile>
23#include <QFile>
23#include <QStringList>
24#include <QStringList>
24#include <QDebug>
25#include <QDebug>
@@ -35,6 +36,11 @@ AccountsService::AccountsService(QObject* parent, const QString &user)
35 m_hereEnabled(false),
36 m_hereEnabled(false),
36 m_hereLicensePath() // null means not set yet
37 m_hereLicensePath() // null means not set yet
37{
38{
39+ m_unityInput = new QDBusInterface(QStringLiteral("com.canonical.Unity.Input"),
40+ QStringLiteral("/com/canonical/Unity/Input"),
41+ QStringLiteral("com.canonical.Unity.Input"),
42+ QDBusConnection::SM_BUSNAME(), this);
43+
38 connect(m_service, &AccountsServiceDBusAdaptor::propertiesChanged, this, &AccountsService::onPropertiesChanged);
44 connect(m_service, &AccountsServiceDBusAdaptor::propertiesChanged, this, &AccountsService::onPropertiesChanged);
39 connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged, this, &AccountsService::onMaybeChanged);
45 connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged, this, &AccountsService::onMaybeChanged);
40
46
@@ -58,6 +64,8 @@ void AccountsService::setUser(const QString &user)
58 updateEnableLauncherWhileLocked(false);
64 updateEnableLauncherWhileLocked(false);
59 updateEnableIndicatorsWhileLocked(false);
65 updateEnableIndicatorsWhileLocked(false);
60 updateBackgroundFile(false);
66 updateBackgroundFile(false);
67+ updateMouseCursorSpeed();
68+ updateTouchpadCursorSpeed();
61 updateStatsWelcomeScreen(false);
69 updateStatsWelcomeScreen(false);
62 updatePasswordDisplayHint(false);
70 updatePasswordDisplayHint(false);
63 updateFailedLogins(false);
71 updateFailedLogins(false);
@@ -246,6 +254,52 @@ void AccountsService::updateBackgroundFile(bool async)
246 }
254 }
247}
255}
248
256
257+void AccountsService::updateMouseCursorSpeed()
258+{
259+ QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
260+ QStringLiteral("com.ubuntu.AccountsService.Input"),
261+ QStringLiteral("MouseCursorSpeed"));
262+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
263+
264+ connect(watcher, &QDBusPendingCallWatcher::finished,
265+ this, [this](QDBusPendingCallWatcher* watcher) {
266+
267+ QDBusPendingReply<QVariant> reply = *watcher;
268+ watcher->deleteLater();
269+ if (reply.isError()) {
270+ qWarning() << "Failed to get 'MouseCursorSpeed' property - " << reply.error().message();
271+ return;
272+ }
273+
274+ // Merely proxy this along to USC. We don't care about keeping a copy
275+ // or exporting it internally.
276+ m_unityInput->asyncCall(QStringLiteral("setMouseCursorSpeed"), reply.value());
277+ });
278+}
279+
280+void AccountsService::updateTouchpadCursorSpeed()
281+{
282+ QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
283+ QStringLiteral("com.ubuntu.AccountsService.Input"),
284+ QStringLiteral("TouchpadCursorSpeed"));
285+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
286+
287+ connect(watcher, &QDBusPendingCallWatcher::finished,
288+ this, [this](QDBusPendingCallWatcher* watcher) {
289+
290+ QDBusPendingReply<QVariant> reply = *watcher;
291+ watcher->deleteLater();
292+ if (reply.isError()) {
293+ qWarning() << "Failed to get 'TouchpadCursorSpeed' property - " << reply.error().message();
294+ return;
295+ }
296+
297+ // Merely proxy this along to USC. We don't care about keeping a copy
298+ // or exporting it internally.
299+ m_unityInput->asyncCall(QStringLiteral("setTouchpadCursorSpeed"), reply.value());
300+ });
301+}
302+
249void AccountsService::updateStatsWelcomeScreen(bool async)
303void AccountsService::updateStatsWelcomeScreen(bool async)
250{
304{
251 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
305 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
@@ -423,6 +477,13 @@ void AccountsService::onPropertiesChanged(const QString &user, const QString &in
423 if (changed.contains(QStringLiteral("FailedLogins"))) {
477 if (changed.contains(QStringLiteral("FailedLogins"))) {
424 updateFailedLogins();
478 updateFailedLogins();
425 }
479 }
480+ } else if (interface == QLatin1String("com.ubuntu.AccountsService.Input")) {
481+ if (changed.contains(QStringLiteral("MouseCursorSpeed"))) {
482+ updateMouseCursorSpeed();
483+ }
484+ if (changed.contains(QStringLiteral("TouchpadCursorSpeed"))) {
485+ updateTouchpadCursorSpeed();
486+ }
426 } else if (interface == QLatin1String("com.ubuntu.touch.AccountsService.SecurityPrivacy")) {
487 } else if (interface == QLatin1String("com.ubuntu.touch.AccountsService.SecurityPrivacy")) {
427 if (changed.contains(QStringLiteral("StatsWelcomeScreen"))) {
488 if (changed.contains(QStringLiteral("StatsWelcomeScreen"))) {
428 updateStatsWelcomeScreen();
489 updateStatsWelcomeScreen();
plugins/AccountsService/AccountsService.h+4
@@ -23,6 +23,7 @@
23#include <QString>
23#include <QString>
24
24
25class AccountsServiceDBusAdaptor;
25class AccountsServiceDBusAdaptor;
26+class QDBusInterface;
26
27
27class AccountsService: public QObject
28class AccountsService: public QObject
28{
29{
@@ -112,6 +113,8 @@ private:
112 void updateEnableLauncherWhileLocked(bool async = true);
113 void updateEnableLauncherWhileLocked(bool async = true);
113 void updateEnableIndicatorsWhileLocked(bool async = true);
114 void updateEnableIndicatorsWhileLocked(bool async = true);
114 void updateBackgroundFile(bool async = true);
115 void updateBackgroundFile(bool async = true);
116+ void updateMouseCursorSpeed();
117+ void updateTouchpadCursorSpeed();
115 void updateStatsWelcomeScreen(bool async = true);
118 void updateStatsWelcomeScreen(bool async = true);
116 void updatePasswordDisplayHint(bool async = true);
119 void updatePasswordDisplayHint(bool async = true);
117 void updateFailedLogins(bool async = true);
120 void updateFailedLogins(bool async = true);
@@ -119,6 +122,7 @@ private:
119 void updateHereLicensePath(bool async = true);
122 void updateHereLicensePath(bool async = true);
120
123
121 AccountsServiceDBusAdaptor *m_service;
124 AccountsServiceDBusAdaptor *m_service;
125+ QDBusInterface *m_unityInput;
122 QString m_user;
126 QString m_user;
123 bool m_demoEdges;
127 bool m_demoEdges;
124 bool m_enableLauncherWhileLocked;
128 bool m_enableLauncherWhileLocked;
plugins/CMakeLists.txt+1
@@ -22,6 +22,7 @@ add_subdirectory(Powerd)
22add_subdirectory(SessionBroadcast)
22add_subdirectory(SessionBroadcast)
23add_subdirectory(ScreenGrabber)
23add_subdirectory(ScreenGrabber)
24add_subdirectory(Ubuntu)
24add_subdirectory(Ubuntu)
25+add_subdirectory(UInput)
25add_subdirectory(Unity)
26add_subdirectory(Unity)
26add_subdirectory(Utils)
27add_subdirectory(Utils)
27add_subdirectory(Wizard)
28add_subdirectory(Wizard)
plugins/Cursor/MousePointer.cpp+4
@@ -42,6 +42,10 @@ void MousePointer::handleMouseEvent(ulong timestamp, QPointF movement, Qt::Mouse
42 return;
42 return;
43 }
43 }
44
44
45+ if (!movement.isNull()) {
46+ Q_EMIT mouseMoved();
47+ }
48+
45 qreal newX = x() + movement.x();
49 qreal newX = x() + movement.x();
46 if (newX < 0) {
50 if (newX < 0) {
47 Q_EMIT pushedLeftBoundary(qAbs(newX), buttons);
51 Q_EMIT pushedLeftBoundary(qAbs(newX), buttons);
plugins/Cursor/MousePointer.h+1
@@ -48,6 +48,7 @@ public Q_SLOTS:
48Q_SIGNALS:
48Q_SIGNALS:
49 void pushedLeftBoundary(qreal amount, Qt::MouseButtons buttons);
49 void pushedLeftBoundary(qreal amount, Qt::MouseButtons buttons);
50 void pushedRightBoundary(qreal amount, Qt::MouseButtons buttons);
50 void pushedRightBoundary(qreal amount, Qt::MouseButtons buttons);
51+ void mouseMoved();
51
52
52protected:
53protected:
53 void itemChange(ItemChange change, const ItemChangeData &value) override;
54 void itemChange(ItemChange change, const ItemChangeData &value) override;
plugins/Dash/CardCreator.js+81−28
@@ -16,9 +16,9 @@
16
16
17.pragma library
17.pragma library
18
18
19−// %1 is the template["card-background"] string
19+// %1 is the template["card-background"]["elements"][0]
20−// %2 is the template["card-background"]["elements"][0]
20+// %2 is the template["card-background"]["elements"][1]
21−// %3 is the template["card-background"]["elements"][1]
21+// %3 is the template["card-background"] string
22var kBackgroundLoaderCode = 'Loader {\n\
22var kBackgroundLoaderCode = 'Loader {\n\
23 id: backgroundLoader; \n\
23 id: backgroundLoader; \n\
24 objectName: "backgroundLoader"; \n\
24 objectName: "backgroundLoader"; \n\
@@ -46,14 +46,14 @@ var kBackgroundLoaderCode = 'Loader {\n\
46 objectName: "backgroundImage"; \n\
46 objectName: "backgroundImage"; \n\
47 source: { \n\
47 source: { \n\
48 if (cardData && typeof cardData["background"] === "string") return cardData["background"]; \n\
48 if (cardData && typeof cardData["background"] === "string") return cardData["background"]; \n\
49− else return "%1"; \n\
49+ else return %3; \n\
50 } \n\
50 } \n\
51 } \n\
51 } \n\
52 function getColor(index) { \n\
52 function getColor(index) { \n\
53 if (cardData && typeof cardData["background"] === "object" \n\
53 if (cardData && typeof cardData["background"] === "object" \n\
54 && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) { \n\
54 && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) { \n\
55 return cardData["background"]["elements"][index]; \n\
55 return cardData["background"]["elements"][index]; \n\
56− } else return index === 0 ? %2 : %3; \n\
56+ } else return index === 0 ? %1 : %2; \n\
57 } \n\
57 } \n\
58 } \n\
58 } \n\
59 }\n';
59 }\n';
@@ -61,6 +61,10 @@ var kBackgroundLoaderCode = 'Loader {\n\
61// %1 is used as anchors of artShapeHolder
61// %1 is used as anchors of artShapeHolder
62// %2 is used as image width
62// %2 is used as image width
63// %3 is used as image height
63// %3 is used as image height
64+// %4 is used for artShapeSource.hideSource and inner Loader visible
65+// %5 is used as aspect ratio fallback
66+// %6 is injected as code to artImage
67+// %7 is used as image fallback
64var kArtShapeHolderCode = 'Item { \n\
68var kArtShapeHolderCode = 'Item { \n\
65 id: artShapeHolder; \n\
69 id: artShapeHolder; \n\
66 height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\
70 height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\
@@ -69,13 +73,13 @@ var kArtShapeHolderCode = 'Item { \n\
69 Loader { \n\
73 Loader { \n\
70 id: artShapeLoader; \n\
74 id: artShapeLoader; \n\
71 objectName: "artShapeLoader"; \n\
75 objectName: "artShapeLoader"; \n\
72− active: cardData && cardData["art"] || false; \n\
76+ readonly property string cardArt: cardData && cardData["art"] || %7; \n\
77+ active: cardArt != ""; \n\
73 asynchronous: root.asynchronous; \n\
78 asynchronous: root.asynchronous; \n\
74 visible: status == Loader.Ready; \n\
79 visible: status == Loader.Ready; \n\
75 sourceComponent: Item { \n\
80 sourceComponent: Item { \n\
76 id: artShape; \n\
81 id: artShape; \n\
77 objectName: "artShape"; \n\
82 objectName: "artShape"; \n\
78− readonly property bool doShapeItem: components["art"]["conciergeMode"] !== true; \n\
79 visible: image.status == Image.Ready; \n\
83 visible: image.status == Image.Ready; \n\
80 readonly property alias image: artImage; \n\
84 readonly property alias image: artImage; \n\
81 ShaderEffectSource { \n\
85 ShaderEffectSource { \n\
@@ -84,11 +88,11 @@ var kArtShapeHolderCode = 'Item { \n\
84 anchors.centerIn: parent; \n\
88 anchors.centerIn: parent; \n\
85 width: 1; \n\
89 width: 1; \n\
86 height: 1; \n\
90 height: 1; \n\
87− hideSource: doShapeItem; \n\
91+ hideSource: %4; \n\
88 } \n\
92 } \n\
89 Loader { \n\
93 Loader { \n\
90 anchors.fill: parent; \n\
94 anchors.fill: parent; \n\
91− visible: artShape.doShapeItem; \n\
95+ visible: %4; \n\
92 sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent; \n\
96 sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent; \n\
93 Component { \n\
97 Component { \n\
94 id: artShapeShapeComponent; \n\
98 id: artShapeShapeComponent; \n\
@@ -112,7 +116,7 @@ var kArtShapeHolderCode = 'Item { \n\
112 } \n\
116 } \n\
113 } \n\
117 } \n\
114 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; \n\
118 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; \n\
115− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1; \n\
119+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : %5; \n\
116 Component.onCompleted: { updateWidthHeightBindings(); } \n\
120 Component.onCompleted: { updateWidthHeightBindings(); } \n\
117 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); } \n\
121 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); } \n\
118 function updateWidthHeightBindings() { \n\
122 function updateWidthHeightBindings() { \n\
@@ -127,10 +131,11 @@ var kArtShapeHolderCode = 'Item { \n\
127 CroppedImageMinimumSourceSize { \n\
131 CroppedImageMinimumSourceSize { \n\
128 id: artImage; \n\
132 id: artImage; \n\
129 objectName: "artImage"; \n\
133 objectName: "artImage"; \n\
130− source: cardData && cardData["art"] || ""; \n\
134+ source: artShapeLoader.cardArt; \n\
131 asynchronous: root.asynchronous; \n\
135 asynchronous: root.asynchronous; \n\
132 width: %2; \n\
136 width: %2; \n\
133 height: %3; \n\
137 height: %3; \n\
138+ %6 \n\
134 } \n\
139 } \n\
135 } \n\
140 } \n\
136 } \n\
141 } \n\
@@ -150,11 +155,20 @@ var kAudioButtonCode = 'AbstractButton { \n\
150 visible: parent.pressed; \n\
155 visible: parent.pressed; \n\
151 radius: "medium"; \n\
156 radius: "medium"; \n\
152 } \n\
157 } \n\
158+ Rectangle { \n\
159+ color: Qt.rgba(0, 0, 0, 0.5); \n\
160+ anchors.centerIn: parent; \n\
161+ width: parent.width * 0.5; \n\
162+ height: width; \n\
163+ radius: width / 2; \n\
164+ } \n\
153 Icon { \n\
165 Icon { \n\
154− anchors.fill: parent; \n\
166+ anchors.centerIn: parent; \n\
155− anchors.margins: parent.height > units.gu(5) ? units.gu(2) : 0; \n\
167+ width: parent.width * 0.3; \n\
168+ height: width; \n\
156 opacity: 0.9; \n\
169 opacity: 0.9; \n\
157 name: DashAudioPlayer.playing && AudioUrlComparer.compare(parent.source, DashAudioPlayer.currentSource) ? "media-playback-pause" : "media-playback-start"; \n\
170 name: DashAudioPlayer.playing && AudioUrlComparer.compare(parent.source, DashAudioPlayer.currentSource) ? "media-playback-pause" : "media-playback-start"; \n\
171+ color: "white"; \n\
158 } \n\
172 } \n\
159 onClicked: { \n\
173 onClicked: { \n\
160 if (AudioUrlComparer.compare(source, DashAudioPlayer.currentSource)) { \n\
174 if (AudioUrlComparer.compare(source, DashAudioPlayer.currentSource)) { \n\
@@ -242,16 +256,19 @@ var kMascotShapeLoaderCode = 'Loader { \n\
242
256
243// %1 is used as anchors of mascotImage
257// %1 is used as anchors of mascotImage
244// %2 is used as visible of mascotImage
258// %2 is used as visible of mascotImage
259+// %3 is injected as code to mascotImage
260+// %4 is used as fallback image
245var kMascotImageCode = 'CroppedImageMinimumSourceSize { \n\
261var kMascotImageCode = 'CroppedImageMinimumSourceSize { \n\
246 id: mascotImage; \n\
262 id: mascotImage; \n\
247 objectName: "mascotImage"; \n\
263 objectName: "mascotImage"; \n\
248 anchors { %1 } \n\
264 anchors { %1 } \n\
249− source: cardData && cardData["mascot"] || ""; \n\
265+ source: cardData && cardData["mascot"] || %4; \n\
250 width: units.gu(6); \n\
266 width: units.gu(6); \n\
251 height: units.gu(5.625); \n\
267 height: units.gu(5.625); \n\
252 horizontalAlignment: Image.AlignHCenter; \n\
268 horizontalAlignment: Image.AlignHCenter; \n\
253 verticalAlignment: Image.AlignVCenter; \n\
269 verticalAlignment: Image.AlignVCenter; \n\
254 visible: %2; \n\
270 visible: %2; \n\
271+ %3 \n\
255 }\n';
272 }\n';
256
273
257// %1 is used as anchors of titleLabel
274// %1 is used as anchors of titleLabel
@@ -369,6 +386,18 @@ var kAudioProgressBarCode = 'CardAudioProgress { \n\
369 color: %3; \n\
386 color: %3; \n\
370 }';
387 }';
371
388
389+function sanitizeColor(colorString) {
390+ if (colorString !== undefined) {
391+ if (colorString.match(/^[#a-z0-9]*$/i) === null) {
392+ // This is not the perfect regexp for color
393+ // but what we're trying to do here is just protect
394+ // against injection so it's ok
395+ return "";
396+ }
397+ }
398+ return colorString;
399+}
400+
372function cardString(template, components) {
401function cardString(template, components) {
373 var code;
402 var code;
374
403
@@ -376,7 +405,6 @@ function cardString(template, components) {
376
405
377 code = 'AbstractButton { \n\
406 code = 'AbstractButton { \n\
378 id: root; \n\
407 id: root; \n\
379− property var components; \n\
380 property var cardData; \n\
408 property var cardData; \n\
381 property string artShapeStyle: "inset"; \n\
409 property string artShapeStyle: "inset"; \n\
382 property string backgroundShapeStyle: "inset"; \n\
410 property string backgroundShapeStyle: "inset"; \n\
@@ -394,7 +422,8 @@ function cardString(template, components) {
394
422
395 var hasArt = components["art"] && components["art"]["field"] || false;
423 var hasArt = components["art"] && components["art"]["field"] || false;
396 var hasSummary = components["summary"] || false;
424 var hasSummary = components["summary"] || false;
425+ var isConciergeMode = components["art"] && components["art"]["conciergeMode"] || false;
397− var artAndSummary = hasArt && hasSummary && components["art"]["conciergeMode"] !== true;
426+ var artAndSummary = hasArt && hasSummary && !isConciergeMode;
398 var isHorizontal = template["card-layout"] === "horizontal";
427 var isHorizontal = template["card-layout"] === "horizontal";
399 var hasBackground = (!isHorizontal && (template["card-background"] || components["background"] || artAndSummary)) ||
428 var hasBackground = (!isHorizontal && (template["card-background"] || components["background"] || artAndSummary)) ||
400 (hasSummary && (template["card-background"] || components["background"]));
429 (hasSummary && (template["card-background"] || components["background"]));
@@ -420,18 +449,26 @@ function cardString(template, components) {
420 }
449 }
421
450
422 if (hasBackground) {
451 if (hasBackground) {
452+ var templateCardBackground;
423− var templateCardBackground = (template && typeof template["card-background"] === "string") ? template["card-background"] : "";
453+ if (template && typeof template["card-background"] === "string") {
454+ templateCardBackground = 'decodeURI("' + encodeURI(template["card-background"]) + '")';
455+ } else {
456+ templateCardBackground = '""';
457+ }
458+
424 var backgroundElements0;
459 var backgroundElements0;
425 var backgroundElements1;
460 var backgroundElements1;
426 if (template && typeof template["card-background"] === "object" && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
461 if (template && typeof template["card-background"] === "object" && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
427− if (template["card-background"]["elements"][0] !== undefined) {
462+ var element0 = sanitizeColor(template["card-background"]["elements"][0]);
463+ var element1 = sanitizeColor(template["card-background"]["elements"][1]);
464+ if (element0 !== undefined) {
428− backgroundElements0 = '"%1"'.arg(template["card-background"]["elements"][0]);
465+ backgroundElements0 = '"%1"'.arg(element0);
429 }
466 }
430− if (template["card-background"]["elements"][1] !== undefined) {
467+ if (element1 !== undefined) {
431− backgroundElements1 = '"%1"'.arg(template["card-background"]["elements"][1]);
468+ backgroundElements1 = '"%1"'.arg(element1);
432 }
469 }
433 }
470 }
434− code += kBackgroundLoaderCode.arg(templateCardBackground).arg(backgroundElements0).arg(backgroundElements1);
471+ code += kBackgroundLoaderCode.arg(backgroundElements0).arg(backgroundElements1).arg(templateCardBackground);
435 }
472 }
436
473
437 if (hasArt) {
474 if (hasArt) {
@@ -456,11 +493,21 @@ function cardString(template, components) {
456 heightCode = 'width / artShape.aspect';
493 heightCode = 'width / artShape.aspect';
457 }
494 }
458
495
459− code += kArtShapeHolderCode.arg(artAnchors).arg(widthCode).arg(heightCode);
496+ var aspectRatio = components["art"] && components["art"]["aspect-ratio"] || 1;
497+ if (isNaN(aspectRatio)) {
498+ aspectRatio = 1;
499+ }
460 var fallback = components["art"] && components["art"]["fallback"] || "";
500 var fallback = components["art"] && components["art"]["fallback"] || "";
501+ fallback = encodeURI(fallback);
502+ var fallbackStatusCode = "";
503+ var fallbackURICode = '""';
461 if (fallback !== "") {
504 if (fallback !== "") {
462− code += 'Connections { target: artShapeLoader.item ? artShapeLoader.item.image : null; onStatusChanged: if (artShapeLoader.item.image.status === Image.Error) artShapeLoader.item.image.source = "%1"; } \n'.arg(fallback);
505+ // fallbackStatusCode has %6 in it because we want to substitute it for fallbackURICode
506+ // which in kArtShapeHolderCode is %7
507+ fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %7;';
508+ fallbackURICode = 'decodeURI("%1")'.arg(fallback);
463 }
509 }
510+ code += kArtShapeHolderCode.arg(artAnchors).arg(widthCode).arg(heightCode).arg(isConciergeMode ? "false" : "true").arg(aspectRatio).arg(fallbackStatusCode).arg(fallbackURICode);
464 } else {
511 } else {
465 code += 'readonly property size artShapeSize: Qt.size(-1, -1);\n'
512 code += 'readonly property size artShapeSize: Qt.size(-1, -1);\n'
466 }
513 }
@@ -552,11 +599,17 @@ function cardString(template, components) {
552 }
599 }
553
600
554 var mascotImageVisible = useMascotShape ? 'false' : 'showHeader';
601 var mascotImageVisible = useMascotShape ? 'false' : 'showHeader';
555− mascotCode = kMascotImageCode.arg(mascotAnchors).arg(mascotImageVisible);
556 var fallback = components["mascot"] && components["mascot"]["fallback"] || "";
602 var fallback = components["mascot"] && components["mascot"]["fallback"] || "";
603+ fallback = encodeURI(fallback);
604+ var fallbackStatusCode = "";
605+ var fallbackURICode = '""';
557 if (fallback !== "") {
606 if (fallback !== "") {
607+ // fallbackStatusCode has %4 in it because we want to substitute it for fallbackURICode
608+ // which in kMascotImageCode is %4
558− code += 'Connections { target: mascotImage; onStatusChanged: if (mascotImage.status === Image.Error) mascotImage.source = "%1"; } \n'.arg(fallback);
609+ fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %4;';
610+ fallbackURICode = 'decodeURI("%1")'.arg(fallback);
559 }
611 }
612+ mascotCode = kMascotImageCode.arg(mascotAnchors).arg(mascotImageVisible).arg(fallbackStatusCode).arg(fallbackURICode);
560 }
613 }
561
614
562 var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white")';
615 var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white")';
@@ -801,7 +854,7 @@ function cardString(template, components) {
801 return code;
854 return code;
802}
855}
803
856
804−function createCardComponent(parent, template, components) {
857+function createCardComponent(parent, template, components, identifier) {
805 var imports = 'import QtQuick 2.4; \n\
858 var imports = 'import QtQuick 2.4; \n\
806 import Ubuntu.Components 1.3; \n\
859 import Ubuntu.Components 1.3; \n\
807 import Ubuntu.Settings.Components 0.1; \n\
860 import Ubuntu.Settings.Components 0.1; \n\
@@ -811,7 +864,7 @@ function createCardComponent(parent, template, components) {
811 var code = imports + 'Component {\n' + card + '}\n';
864 var code = imports + 'Component {\n' + card + '}\n';
812
865
813 try {
866 try {
814− return Qt.createQmlObject(code, parent, "createCardComponent");
867+ return Qt.createQmlObject(code, parent, identifier);
815 } catch (e) {
868 } catch (e) {
816 console.error("ERROR: Invalid component created.");
869 console.error("ERROR: Invalid component created.");
817 console.error("Template:");
870 console.error("Template:");
plugins/Dash/CardCreatorCache.qml+1−1
@@ -32,7 +32,7 @@ QtObject {
32 var allString = tString + cString;
32 var allString = tString + cString;
33 var component = cache[allString];
33 var component = cache[allString];
34 if (component === undefined) {
34 if (component === undefined) {
35− component = CardCreator.createCardComponent(root, template, components);
35+ component = CardCreator.createCardComponent(root, template, components, allString);
36 cache[allString] = component;
36 cache[allString] = component;
37 }
37 }
38 return component;
38 return component;
plugins/Dash/listviewwithpageheader.cpp+18−9
@@ -219,13 +219,7 @@ void ListViewWithPageHeader::setDelegate(QQmlComponent *delegate)
219 Q_FOREACH(ListItem *item, m_visibleItems)
219 Q_FOREACH(ListItem *item, m_visibleItems)
220 releaseItem(item);
220 releaseItem(item);
221 m_visibleItems.clear();
221 m_visibleItems.clear();
222− m_firstVisibleIndex = -1;
222+ initializeValuesForEmptyList();
223− adjustMinYExtent();
224− setContentY(0);
225− m_clipItem->setY(0);
226− if (m_topSectionItem) {
227− QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
228− }
229
223
230 m_delegateModel->setDelegate(delegate);
224 m_delegateModel->setDelegate(delegate);
231
225
@@ -236,6 +230,17 @@ void ListViewWithPageHeader::setDelegate(QQmlComponent *delegate)
236 }
230 }
237}
231}
238
232
233+void ListViewWithPageHeader::initializeValuesForEmptyList()
234+{
235+ m_firstVisibleIndex = -1;
236+ adjustMinYExtent();
237+ setContentY(0);
238+ m_clipItem->setY(0);
239+ if (m_topSectionItem) {
240+ QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
241+ }
242+}
243+
239QQuickItem *ListViewWithPageHeader::header() const
244QQuickItem *ListViewWithPageHeader::header() const
240{
245{
241 return m_headerItem;
246 return m_headerItem;
@@ -835,7 +840,7 @@ bool ListViewWithPageHeader::removeNonVisibleItems(qreal bufferFrom, qreal buffe
835 }
840 }
836 }
841 }
837 if (!foundVisible) {
842 if (!foundVisible) {
838− m_firstVisibleIndex = -1;
843+ initializeValuesForEmptyList();
839 }
844 }
840 if (m_firstVisibleIndex != oldFirstVisibleIndex) {
845 if (m_firstVisibleIndex != oldFirstVisibleIndex) {
841 adjustMinYExtent();
846 adjustMinYExtent();
@@ -1092,7 +1097,11 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
1092 }
1097 }
1093
1098
1094 if (m_firstVisibleIndex != oldFirstVisibleIndex) {
1099 if (m_firstVisibleIndex != oldFirstVisibleIndex) {
1100+ if (m_visibleItems.isEmpty()) {
1101+ initializeValuesForEmptyList();
1102+ } else {
1095− adjustMinYExtent();
1103+ adjustMinYExtent();
1104+ }
1096 }
1105 }
1097
1106
1098 for (int i = 0; i < m_visibleItems.count(); ++i) {
1107 for (int i = 0; i < m_visibleItems.count(); ++i) {
plugins/Dash/listviewwithpageheader.h+1
@@ -168,6 +168,7 @@ private:
168 QQuickItem *getSectionItem(int modelIndex, bool alreadyInserted);
168 QQuickItem *getSectionItem(int modelIndex, bool alreadyInserted);
169 QQuickItem *getSectionItem(const QString &sectionText);
169 QQuickItem *getSectionItem(const QString &sectionText);
170 void updateSectionItem(int modelIndex);
170 void updateSectionItem(int modelIndex);
171+ void initializeValuesForEmptyList();
171
172
172 QQmlDelegateModel *m_delegateModel;
173 QQmlDelegateModel *m_delegateModel;
173
174
plugins/LightDM/CMakeLists.txt+1−1
@@ -7,7 +7,7 @@ include_directories(
7 ${CMAKE_CURRENT_SOURCE_DIR}
7 ${CMAKE_CURRENT_SOURCE_DIR}
8 ${CMAKE_CURRENT_BINARY_DIR}
8 ${CMAKE_CURRENT_BINARY_DIR}
9 ${CMAKE_SOURCE_DIR}/plugins/Utils
9 ${CMAKE_SOURCE_DIR}/plugins/Utils
10− ${LIBLIGHTDM_INCLUDE_DIRS}
10+ ${CMAKE_BINARY_DIR}/tests/mocks/LightDM/IntegratedLightDM
11 ${libunity8-private_SOURCE_DIR}
11 ${libunity8-private_SOURCE_DIR}
12 ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
12 ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
13)
13)
plugins/LightDM/FullLightDM/CMakeLists.txt+2−5
@@ -2,15 +2,12 @@ pkg_check_modules(LIBLIGHTDM REQUIRED liblightdm-qt5-3)
2
2
3set(PLUGIN_CLASSNAME "FullLightDM")
3set(PLUGIN_CLASSNAME "FullLightDM")
4
4
5−# Written to source dir as thats where add_unity8_plugin expects it
6−configure_file(../qmldir.in ${CMAKE_CURRENT_SOURCE_DIR}/qmldir)
7−
8add_definitions(-DFULL_LIGHTDM)
5add_definitions(-DFULL_LIGHTDM)
9
6
10include_directories(
7include_directories(
8+ ../
11 ${LIBLIGHTDM_INCLUDE_DIRS}
9 ${LIBLIGHTDM_INCLUDE_DIRS}
12− ${CMAKE_CURRENT_BINARY_DIR}
13−)
10+ )
14
11
15foreach(source_file ${QMLPLUGIN_SRC})
12foreach(source_file ${QMLPLUGIN_SRC})
16 list(APPEND RELATIVE_QMLPLUGIN_SRC ../${source_file})
13 list(APPEND RELATIVE_QMLPLUGIN_SRC ../${source_file})
plugins/LightDM/FullLightDM/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module LightDM.FullLightDM
2+plugin FullLightDM-qml
3+typeinfo FullLightDM.qmltypes
plugins/LightDM/IntegratedLightDM/CMakeLists.txt+6−6
@@ -1,15 +1,15 @@
1set(PLUGIN_CLASSNAME "IntegratedLightDM")
1set(PLUGIN_CLASSNAME "IntegratedLightDM")
2
2
3−# Written to source dir as thats where add_unity8_plugin expects it
4−configure_file(../qmldir.in ${CMAKE_CURRENT_SOURCE_DIR}/qmldir)
5−
6add_definitions(-DINTEGRATED_LIGHTDM)
3add_definitions(-DINTEGRATED_LIGHTDM)
7
4
5+foreach(include_directory ${QMLPLUGIN_INCLUDES})
6+ list(APPEND RELATIVE_QMLPLUGIN_INCLUDES ../${include_directory})
7+endforeach()
8+
8include_directories(
9include_directories(
9− ${libunity8-private_SOURCE_DIR}
10+ ../
10 ${CMAKE_SOURCE_DIR}/tests/mocks/LightDM/IntegratedLightDM
11 ${CMAKE_SOURCE_DIR}/tests/mocks/LightDM/IntegratedLightDM
11− ${CMAKE_BINARY_DIR}/tests/mocks/LightDM/IntegratedLightDM
12−)
12+ )
13
13
14foreach(source_file ${QMLPLUGIN_SRC})
14foreach(source_file ${QMLPLUGIN_SRC})
15 list(APPEND RELATIVE_QMLPLUGIN_SRC ../${source_file})
15 list(APPEND RELATIVE_QMLPLUGIN_SRC ../${source_file})
plugins/LightDM/IntegratedLightDM/liblightdm/CMakeLists.txt+3
@@ -15,14 +15,17 @@ add_library(MockLightDM-demo-shared SHARED ${LibLightDM_SOURCES})
15
15
16include_directories(
16include_directories(
17 ${CMAKE_CURRENT_BINARY_DIR}
17 ${CMAKE_CURRENT_BINARY_DIR}
18+ ${GLIB_INCLUDE_DIRS}
18 ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
19 ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
19)
20)
20
21
21target_link_libraries(integratedLightDM
22target_link_libraries(integratedLightDM
23+ ${GLIB_LIBRARIES}
22 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
24 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
23 -lpam
25 -lpam
24)
26)
25target_link_libraries(MockLightDM-demo-shared
27target_link_libraries(MockLightDM-demo-shared
28+ ${GLIB_LIBRARIES}
26 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
29 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
27 -lpam
30 -lpam
28)
31)
plugins/LightDM/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp+23−7
@@ -18,6 +18,7 @@
18
18
19#include "UsersModelPrivate.h"
19#include "UsersModelPrivate.h"
20
20
21+#include <glib.h>
21#include <QDir>
22#include <QDir>
22#include <QSettings>
23#include <QSettings>
23#include <QStringList>
24#include <QStringList>
@@ -28,14 +29,29 @@ namespace QLightDM
28UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
29UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
29 : q_ptr(parent)
30 : q_ptr(parent)
30{
31{
31− QSettings settings(QDir::homePath() + "/.unity8-greeter-demo", QSettings::NativeFormat);
32+ QFileInfo demoFile(QDir::homePath() + "/.unity8-greeter-demo");
32− QStringList users = settings.value(QStringLiteral("users"), QStringList() << qgetenv("USER")).toStringList();
33+ QString currentUser = g_get_user_name();
33
34
35+ if (demoFile.exists()) {
36+ QSettings settings(demoFile.filePath(), QSettings::NativeFormat);
37+ QStringList users = settings.value(QStringLiteral("users"), QStringList() << currentUser).toStringList();
38+
34− entries.reserve(users.count());
39+ entries.reserve(users.count());
35− Q_FOREACH(const QString &user, users)
40+ Q_FOREACH(const QString &user, users)
36− {
41+ {
37− QString name = settings.value(user + "/name", user).toString();
42+ QString name = settings.value(user + "/name", user).toString();
38− entries.append({user, name, 0, 0, false, false, 0, 0});
43+ entries.append({user, name, 0, 0, false, false, 0, 0});
44+ }
45+ } else {
46+ // If we were using the actual liblightdm, we could just ask it
47+ // for the user's real name. But we aren't. We *should* ask
48+ // AccountsService for the real name, like liblightdm does internally,
49+ // but this is close enough since AS and passwd are always in sync.
50+ QString realName = QString::fromUtf8(g_get_real_name()); // gets name from passwd entry
51+ if (realName == QStringLiteral("Unknown")) { // glib doesn't translate this string
52+ realName.clear();
53+ }
54+ entries.append({currentUser, realName, 0, 0, false, false, 0, 0});
39 }
55 }
40}
56}
41
57
plugins/LightDM/IntegratedLightDM/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module LightDM.IntegratedLightDM
2+plugin IntegratedLightDM-qml
3+typeinfo IntegratedLightDM.qmltypes
plugins/LightDM/qmldir.indeleted−3
@@ -1,3 +0,0 @@
1−module LightDM.@PLUGIN_CLASSNAME@
2−plugin @PLUGIN_CLASSNAME@-qml
3−typeinfo @PLUGIN_CLASSNAME@.qmltypes
plugins/Powerd/CMakeLists.txt−2
@@ -1,5 +1,3 @@
1−pkg_search_module(GIO REQUIRED gio-2.0)
2−
3include_directories(
1include_directories(
4 ${GIO_INCLUDE_DIRS}
2 ${GIO_INCLUDE_DIRS}
5)
3)
plugins/UInput/CMakeLists.txtnew file+7
@@ -0,0 +1,7 @@
1+add_library(UInput-qml MODULE
2+ plugin.cpp
3+ uinput.cpp
4+)
5+
6+qt5_use_modules(UInput-qml Qml)
7+add_unity8_plugin(UInput 0.1 UInput TARGETS UInput-qml)
plugins/UInput/UInput.qmltypesnew file+44
@@ -0,0 +1,44 @@
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 UInput 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "UInput"
12+ prototype: "QObject"
13+ exports: ["UInput/UInput 0.1"]
14+ exportMetaObjectRevisions: [0]
15+ Enum {
16+ name: "Button"
17+ values: {
18+ "ButtonLeft": 0,
19+ "ButtonRight": 1,
20+ "ButtonMiddle": 2
21+ }
22+ }
23+ Method { name: "createMouse" }
24+ Method { name: "removeMouse" }
25+ Method {
26+ name: "moveMouse"
27+ Parameter { name: "dx"; type: "int" }
28+ Parameter { name: "dy"; type: "int" }
29+ }
30+ Method {
31+ name: "pressMouse"
32+ Parameter { name: "button"; type: "Button" }
33+ }
34+ Method {
35+ name: "releaseMouse"
36+ Parameter { name: "button"; type: "Button" }
37+ }
38+ Method {
39+ name: "scrollMouse"
40+ Parameter { name: "dh"; type: "int" }
41+ Parameter { name: "dv"; type: "int" }
42+ }
43+ }
44+}
plugins/UInput/plugin.cppnew file+26
@@ -0,0 +1,26 @@
1+/*
2+ * Copyright (C) 2015 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "plugin.h"
18+#include "uinput.h"
19+
20+#include <QtQml/qqml.h>
21+
22+void UInputPlugin::registerTypes(const char *uri)
23+{
24+ Q_ASSERT(uri == QLatin1String("UInput"));
25+ qmlRegisterType<UInput>(uri, 0, 1, "UInput");
26+}
plugins/UInput/plugin.hnew file+32
@@ -0,0 +1,32 @@
1+/*
2+ * Copyright (C) 2015 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 UINPUT_PLUGIN_H
18+#define UINPUT_PLUGIN_H
19+
20+#include <QtQml/QQmlEngine>
21+#include <QtQml/QQmlExtensionPlugin>
22+
23+class UInputPlugin : 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) override;
30+};
31+
32+#endif
plugins/UInput/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module UInput
2+plugin UInput-qml
3+typeinfo UInput.qmltypes
plugins/UInput/uinput.cppnew file+182
@@ -0,0 +1,182 @@
1+/*
2+ * Copyright (C) 2015 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "uinput.h"
18+
19+#include <QFile>
20+#include <QDebug>
21+#include <QDateTime>
22+
23+#include <unistd.h>
24+#include <time.h>
25+
26+UInput::UInput(QObject *parent) :
27+ QObject(parent)
28+{
29+ m_devName = QByteArrayLiteral("unity8-simulated-mouse");
30+ m_uinput.setFileName(QStringLiteral("/dev/uinput"));
31+
32+ memset(&m_uinput_mouse_dev, 0, sizeof(m_uinput_mouse_dev));
33+ m_uinput_mouse_dev.id.bustype = BUS_USB;
34+ m_uinput_mouse_dev.id.version = 1;
35+ strncpy(m_uinput_mouse_dev.name, m_devName.constData(), m_devName.length());
36+}
37+
38+UInput::~UInput()
39+{
40+ if (m_mouseCreated) {
41+ removeMouse();
42+ }
43+}
44+
45+void UInput::createMouse()
46+{
47+ if (m_mouseCreated) {
48+ qDebug() << "Already have a virtual device. Not creating another one.";
49+ return;
50+ }
51+
52+ if (!m_uinput.isOpen() && !m_uinput.open(QFile::WriteOnly)) {
53+ return;
54+ }
55+
56+ ioctl(m_uinput.handle(), UI_SET_EVBIT, EV_REL);
57+ ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_X);
58+ ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_Y);
59+ ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_HWHEEL);
60+ ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_WHEEL);
61+
62+ ioctl(m_uinput.handle(), UI_SET_EVBIT, EV_KEY);
63+ ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_MOUSE);
64+ ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_LEFT);
65+ ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_MIDDLE);
66+ ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_RIGHT);
67+ ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_FORWARD);
68+ ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_BACK);
69+
70+ ioctl(m_uinput.handle(), UI_SET_EVBIT, EV_SYN);
71+
72+ int len = write(m_uinput.handle(), &m_uinput_mouse_dev, sizeof(m_uinput_mouse_dev));
73+ if (len <= 0) {
74+ qWarning() << "Failed to write to uinput. Cannot create virtual uinput mouse.";
75+ return;
76+ }
77+
78+ int err = ioctl(m_uinput.handle(), UI_DEV_CREATE);
79+ if (err != 0) {
80+ qWarning() << "Cannot create virtual uinput device. Create ioctl failed:" << err;
81+ return;
82+ }
83+ m_mouseCreated = true;
84+ qDebug() << "Virtual uinput mouse device created.";
85+}
86+
87+void UInput::removeMouse()
88+{
89+ if (!m_mouseCreated) {
90+ return;
91+ }
92+
93+ if (!m_uinput.isOpen() && !m_uinput.open(QFile::WriteOnly)) {
94+ qWarning() << "cannot open uinput... ";
95+ return;
96+ }
97+
98+ int err = ioctl(m_uinput.handle(), UI_DEV_DESTROY);
99+ if (err != 0) {
100+ qWarning() << "Failed to destroy virtual uinput device. Destroy ioctl failed:" << err;
101+ } else {
102+ qDebug() << "Virtual uinput mouse device removed.";
103+ }
104+ m_uinput.close();
105+ m_mouseCreated = false;
106+}
107+
108+void UInput::moveMouse(int dx, int dy)
109+{
110+ struct input_event event;
111+ memset(&event, 0, sizeof(event));
112+ clock_gettime(CLOCK_MONOTONIC, (timespec*)&event.time);
113+ event.type = EV_REL;
114+ event.code = REL_X;
115+ event.value = dx;
116+ write(m_uinput.handle(), &event, sizeof(event));
117+
118+ event.code = REL_Y;
119+ event.value = dy;
120+ write(m_uinput.handle(), &event, sizeof(event));
121+
122+ event.type = EV_SYN;
123+ event.code = SYN_REPORT;
124+ event.value = 0;
125+ write(m_uinput.handle(), &event, sizeof(event));
126+}
127+
128+void UInput::pressMouse(Button button)
129+{
130+ injectMouse(button, 1);
131+}
132+
133+void UInput::releaseMouse(Button button)
134+{
135+ injectMouse(button, 0);
136+}
137+
138+void UInput::scrollMouse(int dh, int dv)
139+{
140+ struct input_event event;
141+ memset(&event, 0, sizeof(event));
142+ clock_gettime(CLOCK_MONOTONIC, (timespec*)&event.time);
143+ event.type = EV_REL;
144+ event.code = REL_HWHEEL;
145+ event.value = dh;
146+ write(m_uinput.handle(), &event, sizeof(event));
147+
148+ event.code = REL_WHEEL;
149+ event.value = dv;
150+ write(m_uinput.handle(), &event, sizeof(event));
151+
152+ event.type = EV_SYN;
153+ event.code = SYN_REPORT;
154+ event.value = 0;
155+ write(m_uinput.handle(), &event, sizeof(event));
156+}
157+
158+void UInput::injectMouse(Button button, int down)
159+{
160+ struct input_event event;
161+ memset(&event, 0, sizeof(event));
162+ clock_gettime(CLOCK_MONOTONIC, (timespec*)&event.time);
163+ event.type = EV_KEY;
164+ switch (button) {
165+ case ButtonLeft:
166+ event.code = BTN_LEFT;
167+ break;
168+ case ButtonRight:
169+ event.code = BTN_RIGHT;
170+ break;
171+ case ButtonMiddle:
172+ event.code = BTN_MIDDLE;
173+ break;
174+ }
175+ event.value = down;
176+ write(m_uinput.handle(), &event, sizeof(event));
177+
178+ event.type = EV_SYN;
179+ event.code = SYN_REPORT;
180+ event.value = 0;
181+ write(m_uinput.handle(), &event, sizeof(event));
182+}
plugins/UInput/uinput.hnew file+61
@@ -0,0 +1,61 @@
1+/*
2+ * Copyright (C) 2015 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+
18+#ifndef UINPUT_H
19+#define UINPUT_H
20+
21+#include <QObject>
22+#include <QFile>
23+
24+#include <linux/uinput.h>
25+
26+
27+class UInput : public QObject
28+{
29+ Q_OBJECT
30+ Q_ENUMS(Button)
31+
32+public:
33+ enum Button {
34+ ButtonLeft,
35+ ButtonRight,
36+ ButtonMiddle
37+ };
38+
39+ explicit UInput(QObject *parent = nullptr);
40+ ~UInput();
41+
42+ Q_INVOKABLE void createMouse();
43+ Q_INVOKABLE void removeMouse();
44+
45+ Q_INVOKABLE void moveMouse(int dx, int dy);
46+ Q_INVOKABLE void pressMouse(Button button);
47+ Q_INVOKABLE void releaseMouse(Button button);
48+ Q_INVOKABLE void scrollMouse(int dh, int dv);
49+
50+private:
51+ void injectMouse(Button button, int down);
52+
53+private:
54+ QFile m_uinput;
55+ uinput_user_dev m_uinput_mouse_dev;
56+ QByteArray m_devName;
57+
58+ bool m_mouseCreated = false;
59+};
60+
61+#endif // UINPUT_H
plugins/Unity/Indicators/CMakeLists.txt−4
@@ -1,9 +1,5 @@
1project(IndicatorsQml)
1project(IndicatorsQml)
2
2
3−pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
4−pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
5−pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
6−
7find_package(Qt5Core REQUIRED)
3find_package(Qt5Core REQUIRED)
8find_package(Qt5Quick REQUIRED)
4find_package(Qt5Quick REQUIRED)
9
5
plugins/Unity/Indicators/modelactionrootstate.cpp+76−1
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright 2013 Canonical Ltd.
2+ * Copyright 2013-2016 Canonical Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
5 * it under the terms of the GNU Lesser General Public License as published by
@@ -32,6 +32,7 @@ extern "C" {
32ModelActionRootState::ModelActionRootState(QObject *parent)
32ModelActionRootState::ModelActionRootState(QObject *parent)
33 : RootStateObject(parent),
33 : RootStateObject(parent),
34 m_menu(nullptr)
34 m_menu(nullptr)
35+ , m_reentryGuard(false)
35{
36{
36}
37}
37
38
@@ -62,6 +63,7 @@ void ModelActionRootState::setMenu(UnityMenuModel* menu)
62 connect(m_menu, &UnityMenuModel::destroyed, this, &ModelActionRootState::reset);
63 connect(m_menu, &UnityMenuModel::destroyed, this, &ModelActionRootState::reset);
63 }
64 }
64 updateActionState();
65 updateActionState();
66+ updateOtherActions();
65 Q_EMIT menuChanged();
67 Q_EMIT menuChanged();
66
68
67 if (wasValid != valid())
69 if (wasValid != valid())
@@ -69,6 +71,21 @@ void ModelActionRootState::setMenu(UnityMenuModel* menu)
69 }
71 }
70}
72}
71
73
74+QString ModelActionRootState::secondaryAction() const
75+{
76+ return m_secondaryAction;
77+}
78+
79+QString ModelActionRootState::scrollAction() const
80+{
81+ return m_scrollAction;
82+}
83+
84+QString ModelActionRootState::submenuAction() const
85+{
86+ return m_submenuAction;
87+}
88+
72bool ModelActionRootState::valid() const
89bool ModelActionRootState::valid() const
73{
90{
74 return !currentState().empty();
91 return !currentState().empty();
@@ -79,6 +96,7 @@ void ModelActionRootState::onModelRowsAdded(const QModelIndex& parent, int start
79 Q_UNUSED(parent);
96 Q_UNUSED(parent);
80 if (start == 0 && end >= 0) {
97 if (start == 0 && end >= 0) {
81 updateActionState();
98 updateActionState();
99+ updateOtherActions();
82 }
100 }
83}
101}
84
102
@@ -87,6 +105,7 @@ void ModelActionRootState::onModelRowsRemoved(const QModelIndex& parent, int sta
87 Q_UNUSED(parent);
105 Q_UNUSED(parent);
88 if (start == 0 && end >= 0) {
106 if (start == 0 && end >= 0) {
89 updateActionState();
107 updateActionState();
108+ updateOtherActions();
90 }
109 }
91}
110}
92
111
@@ -99,6 +118,7 @@ void ModelActionRootState::onModelDataChanged(const QModelIndex& topLeft, const
99
118
100 if (topLeft.row() <= 0 && bottomRight.row() >= 0) {
119 if (topLeft.row() <= 0 && bottomRight.row() >= 0) {
101 updateActionState();
120 updateActionState();
121+ updateOtherActions();
102 }
122 }
103}
123}
104
124
@@ -108,10 +128,15 @@ void ModelActionRootState::reset()
108
128
109 Q_EMIT menuChanged();
129 Q_EMIT menuChanged();
110 setCurrentState(QVariantMap());
130 setCurrentState(QVariantMap());
131+
132+ updateOtherActions();
111}
133}
112
134
113void ModelActionRootState::updateActionState()
135void ModelActionRootState::updateActionState()
114{
136{
137+ if (m_reentryGuard) return;
138+ m_reentryGuard = true;
139+
115 if (m_menu && m_menu->rowCount() > 0) {
140 if (m_menu && m_menu->rowCount() > 0) {
116 ActionStateParser* oldParser = m_menu->actionStateParser();
141 ActionStateParser* oldParser = m_menu->actionStateParser();
117 m_menu->setActionStateParser(&m_parser);
142 m_menu->setActionStateParser(&m_parser);
@@ -126,4 +151,54 @@ void ModelActionRootState::updateActionState()
126 }
151 }
127 // else if m_menu->rowCount() == 0, let's leave existing cache in place
152 // else if m_menu->rowCount() == 0, let's leave existing cache in place
128 // until the new menu comes in, to avoid flashing the UI empty for a moment
153 // until the new menu comes in, to avoid flashing the UI empty for a moment
154+
155+ m_reentryGuard = false;
156+}
157+
158+void ModelActionRootState::updateOtherActions()
159+{
160+ if (m_reentryGuard) return;
161+ m_reentryGuard = true;
162+
163+ if (m_menu && m_menu->rowCount() > 0) {
164+ QVariantMap map;
165+ map[QStringLiteral("submenu-action")] = QStringLiteral("string");
166+ map[QStringLiteral("x-canonical-scroll-action")] = QStringLiteral("string");
167+ map[QStringLiteral("x-canonical-secondary-action")] = QStringLiteral("string");
168+ m_menu->loadExtendedAttributes(0, map);
169+ QVariantMap extMap = m_menu->get(0, "ext").toMap();
170+
171+ QString secondaryAction = extMap.value(QStringLiteral("xCanonicalSecondaryAction")).toString();
172+ if (m_secondaryAction != secondaryAction) {
173+ m_secondaryAction = secondaryAction;
174+ Q_EMIT secondaryActionChanged();
175+ }
176+
177+ QString scrollAction = extMap.value(QStringLiteral("xCanonicalScrollAction")).toString();
178+ if (m_scrollAction != scrollAction) {
179+ m_scrollAction = scrollAction;
180+ Q_EMIT scrollActionChanged();
181+ }
182+
183+ QString submenuAction = extMap.value(QStringLiteral("submenuAction")).toString();
184+ if (m_submenuAction != submenuAction) {
185+ m_submenuAction = submenuAction;
186+ Q_EMIT submenuActionChanged();
187+ }
188+ } else {
189+ if (!m_secondaryAction.isEmpty()) {
190+ m_secondaryAction.clear();
191+ Q_EMIT secondaryActionChanged();
192+ }
193+ if (!m_scrollAction.isEmpty()) {
194+ m_scrollAction.clear();
195+ Q_EMIT scrollActionChanged();
196+ }
197+ if (!m_submenuAction.isEmpty()) {
198+ m_submenuAction.clear();
199+ Q_EMIT submenuActionChanged();
200+ }
201+ }
202+
203+ m_reentryGuard = false;
129}
204}
plugins/Unity/Indicators/modelactionrootstate.h+15−4
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright 2013 Canonical Ltd.
2+ * Copyright 2013-2016 Canonical Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
5 * it under the terms of the GNU Lesser General Public License as published by
@@ -30,6 +30,9 @@ class UNITYINDICATORS_EXPORT ModelActionRootState : public RootStateObject
30{
30{
31 Q_OBJECT
31 Q_OBJECT
32 Q_PROPERTY(UnityMenuModel* menu READ menu WRITE setMenu NOTIFY menuChanged)
32 Q_PROPERTY(UnityMenuModel* menu READ menu WRITE setMenu NOTIFY menuChanged)
33+ Q_PROPERTY(QString secondaryAction READ secondaryAction NOTIFY secondaryActionChanged)
34+ Q_PROPERTY(QString scrollAction READ scrollAction NOTIFY scrollActionChanged)
35+ Q_PROPERTY(QString submenuAction READ submenuAction NOTIFY submenuActionChanged)
33public:
36public:
34 ModelActionRootState(QObject *parent = 0);
37 ModelActionRootState(QObject *parent = 0);
35 virtual ~ModelActionRootState();
38 virtual ~ModelActionRootState();
@@ -37,14 +40,17 @@ public:
37 UnityMenuModel* menu() const;
40 UnityMenuModel* menu() const;
38 void setMenu(UnityMenuModel* menu);
41 void setMenu(UnityMenuModel* menu);
39
42
40− int index() const;
43+ QString secondaryAction() const;
41− void setIndex(int index);
44+ QString scrollAction() const;
45+ QString submenuAction() const;
42
46
43 bool valid() const override;
47 bool valid() const override;
44
48
45Q_SIGNALS:
49Q_SIGNALS:
46 void menuChanged();
50 void menuChanged();
47− void indexChanged();
51+ void secondaryActionChanged();
52+ void scrollActionChanged();
53+ void submenuActionChanged();
48
54
49private Q_SLOTS:
55private Q_SLOTS:
50 void onModelRowsAdded(const QModelIndex& parent, int start, int end);
56 void onModelRowsAdded(const QModelIndex& parent, int start, int end);
@@ -54,8 +60,13 @@ private Q_SLOTS:
54
60
55private:
61private:
56 void updateActionState();
62 void updateActionState();
63+ void updateOtherActions();
57
64
58 UnityMenuModel* m_menu;
65 UnityMenuModel* m_menu;
66+ QString m_secondaryAction;
67+ QString m_scrollAction;
68+ QString m_submenuAction;
69+ bool m_reentryGuard;
59};
70};
60
71
61#endif // MODELACTIONROOTSTATE_H
72#endif // MODELACTIONROOTSTATE_H
plugins/Unity/Session/CMakeLists.txt−2
@@ -1,5 +1,3 @@
1−pkg_search_module(GIO REQUIRED gio-2.0)
2−
3include_directories(
1include_directories(
4 ${CMAKE_CURRENT_SOURCE_DIR}
2 ${CMAKE_CURRENT_SOURCE_DIR}
5 ${CMAKE_CURRENT_BINARY_DIR}
3 ${CMAKE_CURRENT_BINARY_DIR}
plugins/Utils/CMakeLists.txt+2−3
@@ -1,5 +1,3 @@
1−pkg_search_module(GIO REQUIRED gio-2.0)
2−
3include_directories(
1include_directories(
4 ${CMAKE_CURRENT_SOURCE_DIR}
2 ${CMAKE_CURRENT_SOURCE_DIR}
5 ${CMAKE_CURRENT_BINARY_DIR}
3 ${CMAKE_CURRENT_BINARY_DIR}
@@ -13,7 +11,7 @@ set(QMLPLUGIN_SRC
13 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
11 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
14 applicationsfiltermodel.cpp
12 applicationsfiltermodel.cpp
15 constants.cpp
13 constants.cpp
16− HomeKeyWatcher.cpp
14+ WindowInputMonitor.cpp
17 inputwatcher.cpp
15 inputwatcher.cpp
18 qlimitproxymodelqml.cpp
16 qlimitproxymodelqml.cpp
19 unitysortfilterproxymodelqml.cpp
17 unitysortfilterproxymodelqml.cpp
@@ -24,6 +22,7 @@ set(QMLPLUGIN_SRC
24 easingcurve.cpp
22 easingcurve.cpp
25 windowstatestorage.cpp
23 windowstatestorage.cpp
26 timezoneFormatter.cpp
24 timezoneFormatter.cpp
25+ inputeventgenerator.cpp
27 plugin.cpp
26 plugin.cpp
28 )
27 )
29
28
plugins/Utils/EdgeBarrierSettings.qml+1−1
@@ -35,7 +35,7 @@ QtObject {
35
35
36 property Timer printSettingsTimer: Timer {
36 property Timer printSettingsTimer: Timer {
37 interval: 1
37 interval: 1
38− onTriggered: printSettings();
38+ onTriggered: d.printSettings();
39 }
39 }
40 function printSettings() {
40 function printSettings() {
41 console.log("EdgeBarrierSettings: min="+(minPushThreshold/units.gu(1))+"gu("+minPushThreshold+"px)"
41 console.log("EdgeBarrierSettings: min="+(minPushThreshold/units.gu(1))+"gu("+minPushThreshold+"px)"
plugins/Utils/HomeKeyWatcher.hdeleted−74
@@ -1,74 +0,0 @@
1−/*
2− * Copyright (C) 2015 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_HOMEKEYWATCHER_H
18−#define UNITY_HOMEKEYWATCHER_H
19−
20−#include <QQuickItem>
21−#include <QPointer>
22−
23−#include "Timer.h"
24−#include "ElapsedTimer.h"
25−
26−/*
27− Signals when the home key seems to be have been intentionally tapped.
28−
29− It only says the home key has been activated if it has been tapped in isolation,
30− that is, without being accompanied by touches on the screen. Home key taps that
31− happen along with (or immediately after, or immediately before) touches on the
32− screen are considered to have happened unintentionally and are thus ignored.
33−
34− Rationale being that it's easy to accidentally hit the home key while performing
35− a swipe from a screen edge, for instance. That's particularly the case when the
36− home key is a capacitive key.
37− */
38−class HomeKeyWatcher : public QQuickItem
39−{
40− Q_OBJECT
41−public:
42−
43− HomeKeyWatcher(QQuickItem *parent = 0);
44−
45− // for testing
46− HomeKeyWatcher(UnityUtil::AbstractTimer *timer,
47− UnityUtil::AbstractElapsedTimer *elapsedTimer,
48− QQuickItem *parent = 0);
49−
50− virtual ~HomeKeyWatcher();
51−
52− bool eventFilter(QObject *watched, QEvent *event) override;
53−
54− void update(QEvent *event);
55−
56− const qint64 msecsWithoutTouches = 150;
57−
58−Q_SIGNALS:
59− // Emitted when the home key has been intentionally tapped
60− void activated();
61−
62−private Q_SLOTS:
63− void setupFilterOnWindow(QQuickWindow *window);
64− void emitActivatedIfNoTouchesAround();
65−
66−private:
67− QPointer<QQuickWindow> m_filteredWindow;
68− bool m_windowBeingTouched;
69− bool m_homeKeyPressed;
70− UnityUtil::AbstractElapsedTimer *m_windowLastTouchedTimer;
71− UnityUtil::AbstractTimer *m_activationTimer;
72−};
73−
74−#endif // UNITY_HOMEKEYWATCHER_H
plugins/Utils/HomeKeyWatcher.cpp → plugins/Utils/WindowInputMonitor.cpprenamed+19−12
@@ -14,18 +14,18 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−#include "HomeKeyWatcher.h"
17+#include "WindowInputMonitor.h"
18
18
19#include <QQuickWindow>
19#include <QQuickWindow>
20
20
21using namespace UnityUtil;
21using namespace UnityUtil;
22
22
23−HomeKeyWatcher::HomeKeyWatcher(QQuickItem *parent)
23+WindowInputMonitor::WindowInputMonitor(QQuickItem *parent)
24− : HomeKeyWatcher(new Timer, new ElapsedTimer, parent)
24+ : WindowInputMonitor(new Timer, new ElapsedTimer, parent)
25{
25{
26}
26}
27
27
28−HomeKeyWatcher::HomeKeyWatcher(UnityUtil::AbstractTimer *timer,
28+WindowInputMonitor::WindowInputMonitor(UnityUtil::AbstractTimer *timer,
29 UnityUtil::AbstractElapsedTimer *elapsedTimer,
29 UnityUtil::AbstractElapsedTimer *elapsedTimer,
30 QQuickItem *parent)
30 QQuickItem *parent)
31 : QQuickItem(parent)
31 : QQuickItem(parent)
@@ -37,20 +37,20 @@ HomeKeyWatcher::HomeKeyWatcher(UnityUtil::AbstractTimer *timer,
37 m_windowLastTouchedTimer->start();
37 m_windowLastTouchedTimer->start();
38
38
39 connect(this, &QQuickItem::windowChanged,
39 connect(this, &QQuickItem::windowChanged,
40− this, &HomeKeyWatcher::setupFilterOnWindow);
40+ this, &WindowInputMonitor::setupFilterOnWindow);
41
41
42 connect(m_activationTimer, &UnityUtil::AbstractTimer::timeout,
42 connect(m_activationTimer, &UnityUtil::AbstractTimer::timeout,
43− this, &HomeKeyWatcher::emitActivatedIfNoTouchesAround);
43+ this, &WindowInputMonitor::emitActivatedIfNoTouchesAround);
44 m_activationTimer->setInterval(msecsWithoutTouches);
44 m_activationTimer->setInterval(msecsWithoutTouches);
45}
45}
46
46
47−HomeKeyWatcher::~HomeKeyWatcher()
47+WindowInputMonitor::~WindowInputMonitor()
48{
48{
49 delete m_windowLastTouchedTimer;
49 delete m_windowLastTouchedTimer;
50 delete m_activationTimer;
50 delete m_activationTimer;
51}
51}
52
52
53−bool HomeKeyWatcher::eventFilter(QObject *watched, QEvent *event)
53+bool WindowInputMonitor::eventFilter(QObject *watched, QEvent *event)
54{
54{
55 Q_ASSERT(!m_filteredWindow.isNull());
55 Q_ASSERT(!m_filteredWindow.isNull());
56 Q_ASSERT(watched == static_cast<QObject*>(m_filteredWindow.data()));
56 Q_ASSERT(watched == static_cast<QObject*>(m_filteredWindow.data()));
@@ -62,7 +62,7 @@ bool HomeKeyWatcher::eventFilter(QObject *watched, QEvent *event)
62 return false;
62 return false;
63}
63}
64
64
65−void HomeKeyWatcher::update(QEvent *event)
65+void WindowInputMonitor::update(QEvent *event)
66{
66{
67 if (event->type() == QEvent::KeyPress) {
67 if (event->type() == QEvent::KeyPress) {
68 QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
68 QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
@@ -86,15 +86,22 @@ void HomeKeyWatcher::update(QEvent *event)
86
86
87 m_activationTimer->stop();
87 m_activationTimer->stop();
88 m_windowBeingTouched = true;
88 m_windowBeingTouched = true;
89+ Q_EMIT touchBegun();
89
90
90 } else if (event->type() == QEvent::TouchEnd) {
91 } else if (event->type() == QEvent::TouchEnd) {
91
92
92 m_windowBeingTouched = false;
93 m_windowBeingTouched = false;
93 m_windowLastTouchedTimer->start();
94 m_windowLastTouchedTimer->start();
95+
96+ QTouchEvent * touchEv = static_cast<QTouchEvent *>(event);
97+ if (touchEv && !touchEv->touchPoints().isEmpty()) {
98+ const QPointF pos = touchEv->touchPoints().last().screenPos();
99+ Q_EMIT touchEnded(pos);
100+ }
94 }
101 }
95}
102}
96
103
97−void HomeKeyWatcher::setupFilterOnWindow(QQuickWindow *window)
104+void WindowInputMonitor::setupFilterOnWindow(QQuickWindow *window)
98{
105{
99 if (!m_filteredWindow.isNull()) {
106 if (!m_filteredWindow.isNull()) {
100 m_filteredWindow->removeEventFilter(this);
107 m_filteredWindow->removeEventFilter(this);
@@ -107,10 +114,10 @@ void HomeKeyWatcher::setupFilterOnWindow(QQuickWindow *window)
107 }
114 }
108}
115}
109
116
110−void HomeKeyWatcher::emitActivatedIfNoTouchesAround()
117+void WindowInputMonitor::emitActivatedIfNoTouchesAround()
111{
118{
112 if (!m_homeKeyPressed && !m_windowBeingTouched &&
119 if (!m_homeKeyPressed && !m_windowBeingTouched &&
113 (m_windowLastTouchedTimer->elapsed() > msecsWithoutTouches)) {
120 (m_windowLastTouchedTimer->elapsed() > msecsWithoutTouches)) {
114− Q_EMIT activated();
121+ Q_EMIT homeKeyActivated();
115 }
122 }
116}
123}
plugins/Utils/WindowInputMonitor.hnew file+91
@@ -0,0 +1,91 @@
1+/*
2+ * Copyright (C) 2015 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_WINDOWINPUTMONITOR_H
18+#define UNITY_WINDOWINPUTMONITOR_H
19+
20+#include <QQuickItem>
21+#include <QPointer>
22+
23+#include "Timer.h"
24+#include "ElapsedTimer.h"
25+
26+/**
27+ * Monitors input events received by the window holding this item and the Home (Win aka Super_L)
28+ * key presses.
29+ *
30+ * Additionally, this class monitors for generic touch events on the screen, to
31+ * help with hiding/revealing the mouse pointer.
32+ */
33+class WindowInputMonitor : public QQuickItem
34+{
35+ Q_OBJECT
36+public:
37+
38+ WindowInputMonitor(QQuickItem *parent = 0);
39+
40+ // for testing
41+ WindowInputMonitor(UnityUtil::AbstractTimer *timer,
42+ UnityUtil::AbstractElapsedTimer *elapsedTimer,
43+ QQuickItem *parent = 0);
44+
45+ virtual ~WindowInputMonitor();
46+
47+ bool eventFilter(QObject *watched, QEvent *event) override;
48+
49+ void update(QEvent *event);
50+
51+ const qint64 msecsWithoutTouches = 150;
52+
53+Q_SIGNALS:
54+ /**
55+ * Emitted when the home key has been intentionally tapped
56+ *
57+ * It only says the home key has been activated if it has been tapped in isolation,
58+ * that is, without being accompanied by touches on the screen. Home key taps that
59+ * happen along with (or immediately after, or immediately before) touches on the
60+ * screen are considered to have happened unintentionally and are thus ignored.
61+ *
62+ * Rationale being that it's easy to accidentally hit the home key while performing
63+ * a swipe from a screen edge, for instance. That's particularly the case when the
64+ * home key is a capacitive key.
65+ */
66+ void homeKeyActivated();
67+
68+ /**
69+ * Emitted when a touch begin event is detected
70+ */
71+ void touchBegun();
72+
73+ /**
74+ * Emitted when a touch end event is detected
75+ * @param pos the position in screen coordinates
76+ */
77+ void touchEnded(const QPointF &pos);
78+
79+private Q_SLOTS:
80+ void setupFilterOnWindow(QQuickWindow *window);
81+ void emitActivatedIfNoTouchesAround();
82+
83+private:
84+ QPointer<QQuickWindow> m_filteredWindow;
85+ bool m_windowBeingTouched;
86+ bool m_homeKeyPressed;
87+ UnityUtil::AbstractElapsedTimer *m_windowLastTouchedTimer;
88+ UnityUtil::AbstractTimer *m_activationTimer;
89+};
90+
91+#endif // UNITY_WINDOWINPUTMONITOR_H
plugins/Utils/inputeventgenerator.cppnew file+34
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (C) 2016 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 "inputeventgenerator.h"
18+
19+#include <QQuickWindow>
20+#include <QDebug>
21+#include <QDateTime>
22+
23+InputEventGenerator::InputEventGenerator(QQuickItem *parent)
24+ : QQuickItem(parent)
25+{
26+}
27+
28+void InputEventGenerator::generateKeyEvent(Qt::Key key, bool pressed, Qt::KeyboardModifiers modifiers, quint64 timestamp, quint32 nativeScanCode, const QString &text)
29+{
30+ QEvent::Type type = pressed ? QEvent::KeyPress : QEvent::KeyRelease;
31+ QKeyEvent ev(type, key, modifiers, nativeScanCode, 0, 0, text);
32+ ev.setTimestamp(timestamp);
33+ QCoreApplication::sendEvent(window(), &ev);
34+}
plugins/Utils/inputeventgenerator.hnew file+40
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright (C) 2016 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 INPUTEVENTGENERATOR_H
18+#define INPUTEVENTGENERATOR_H
19+
20+#include <QQuickItem>
21+#include <QPointer>
22+#include <QDateTime>
23+
24+/**
25+ * \brief This class allows injecting Key events into the scene it lives in.
26+ */
27+class InputEventGenerator : public QQuickItem
28+{
29+ Q_OBJECT
30+public:
31+ InputEventGenerator(QQuickItem *parent = 0);
32+
33+ /**
34+ * Generate and post and event to the scene. The key event will be sent to the scene the Generator
35+ * lives in and it will be dispatched through the regular event/focus queue.
36+ */
37+ Q_INVOKABLE void generateKeyEvent(Qt::Key key, bool pressed, Qt::KeyboardModifiers modifiers = Qt::NoModifier, quint64 timestamp = QDateTime::currentMSecsSinceEpoch(), quint32 nativeScanCode = 0, const QString &text = QString());
38+};
39+
40+#endif // INPUTEVENTGENERATOR_H
plugins/Utils/plugin.cpp+4−2
@@ -25,7 +25,7 @@
25// local
25// local
26#include "activefocuslogger.h"
26#include "activefocuslogger.h"
27#include "easingcurve.h"
27#include "easingcurve.h"
28−#include "HomeKeyWatcher.h"
28+#include "WindowInputMonitor.h"
29#include "inputwatcher.h"
29#include "inputwatcher.h"
30#include "qlimitproxymodelqml.h"
30#include "qlimitproxymodelqml.h"
31#include "unitysortfilterproxymodelqml.h"
31#include "unitysortfilterproxymodelqml.h"
@@ -36,6 +36,7 @@
36#include "constants.h"
36#include "constants.h"
37#include "timezoneFormatter.h"
37#include "timezoneFormatter.h"
38#include "applicationsfiltermodel.h"
38#include "applicationsfiltermodel.h"
39+#include "inputeventgenerator.h"
39
40
40static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
41static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
41{
42{
@@ -54,7 +55,7 @@ static QObject *createConstants(QQmlEngine *engine, QJSEngine *scriptEngine)
54void UtilsPlugin::registerTypes(const char *uri)
55void UtilsPlugin::registerTypes(const char *uri)
55{
56{
56 Q_ASSERT(uri == QLatin1String("Utils"));
57 Q_ASSERT(uri == QLatin1String("Utils"));
57− qmlRegisterType<HomeKeyWatcher>(uri, 0, 1, "HomeKeyWatcher");
58+ qmlRegisterType<WindowInputMonitor>(uri, 0, 1, "WindowInputMonitor");
58 qmlRegisterType<QAbstractItemModel>();
59 qmlRegisterType<QAbstractItemModel>();
59 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
60 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
60 qmlRegisterType<UnitySortFilterProxyModelQML>(uri, 0, 1, "UnitySortFilterProxyModel");
61 qmlRegisterType<UnitySortFilterProxyModelQML>(uri, 0, 1, "UnitySortFilterProxyModel");
@@ -68,6 +69,7 @@ void UtilsPlugin::registerTypes(const char *uri)
68 [](QQmlEngine*, QJSEngine*) -> QObject* { return new TimezoneFormatter; });
69 [](QQmlEngine*, QJSEngine*) -> QObject* { return new TimezoneFormatter; });
69 qmlRegisterType<ActiveFocusLogger>(uri, 0, 1, "ActiveFocusLogger");
70 qmlRegisterType<ActiveFocusLogger>(uri, 0, 1, "ActiveFocusLogger");
70 qmlRegisterType<ApplicationsFilterModel>(uri, 0, 1, "ApplicationsFilterModel");
71 qmlRegisterType<ApplicationsFilterModel>(uri, 0, 1, "ApplicationsFilterModel");
72+ qmlRegisterType<InputEventGenerator>(uri, 0, 1, "InputEventGenerator");
71}
73}
72
74
73void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
75void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
po/aa.ponew file+667
@@ -0,0 +1,667 @@
1+# Afar translation for unity8
2+# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
3+# This file is distributed under the same license as the unity8 package.
4+# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
5+#
6+msgid ""
7+msgstr ""
8+"Project-Id-Version: unity8\n"
9+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"POT-Creation-Date: 2016-02-16 03:29+0000\n"
11+"PO-Revision-Date: 2016-02-12 10:18+0000\n"
12+"Last-Translator: Charif AYFARAH <ayfarah@ymail.com>\n"
13+"Language-Team: Afar <aa@li.org>\n"
14+"MIME-Version: 1.0\n"
15+"Content-Type: text/plain; charset=UTF-8\n"
16+"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
18+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
19+"X-Generator: Launchpad (build 17925)\n"
20+
21+#: plugins/IntegratedLightDM/Greeter.cpp:112
22+msgid "Password: "
23+msgstr "Cuumita "
24+
25+#: plugins/Unity/Launcher/launcheritem.cpp:47
26+#: plugins/Unity/Launcher/launcheritem.cpp:106
27+msgid "Pin shortcut"
28+msgstr ""
29+
30+#: plugins/Unity/Launcher/launcheritem.cpp:52
31+msgid "Quit"
32+msgstr "Kat"
33+
34+#: plugins/Unity/Launcher/launcheritem.cpp:106
35+msgid "Unpin shortcut"
36+msgstr ""
37+
38+#: qml/Components/DelayedLockscreen.qml:49
39+msgid "Device Locked"
40+msgstr ""
41+
42+#: qml/Components/DelayedLockscreen.qml:64
43+msgid "You have been locked out due to too many failed passphrase attempts."
44+msgstr ""
45+
46+#: qml/Components/DelayedLockscreen.qml:65
47+msgid "You have been locked out due to too many failed passcode attempts."
48+msgstr ""
49+
50+#: qml/Components/DelayedLockscreen.qml:74
51+#, qt-format
52+msgid "Please wait %1 minute and then try again…"
53+msgid_plural "Please wait %1 minutes and then try again…"
54+msgstr[0] "Maganak %1 minit qambaalaay, kaadu gabbat"
55+msgstr[1] "Maganak %1 minit qambaalaay, kaadu gabbat"
56+
57+#: qml/Components/Dialogs.qml:144
58+msgctxt "Title: Lock/Log out dialog"
59+msgid "Log out"
60+msgstr "Eweq"
61+
62+#: qml/Components/Dialogs.qml:145
63+msgid "Are you sure you want to log out?"
64+msgstr ""
65+
66+#: qml/Components/Dialogs.qml:147
67+msgctxt "Button: Lock the system"
68+msgid "Lock"
69+msgstr "Koflis"
70+
71+#: qml/Components/Dialogs.qml:154
72+msgctxt "Button: Log out from the system"
73+msgid "Log Out"
74+msgstr "Eweq"
75+
76+#: qml/Components/Dialogs.qml:161 qml/Components/Dialogs.qml:194
77+#: qml/Components/Dialogs.qml:253
78+msgid "Cancel"
79+msgstr "Bayis"
80+
81+#: qml/Components/Dialogs.qml:173
82+msgctxt "Title: Reboot/Shut down dialog"
83+msgid "Shut down"
84+msgstr "Bargus"
85+
86+#: qml/Components/Dialogs.qml:174
87+msgid "Are you sure you want to shut down?"
88+msgstr "Bargussuh digga maay litoo?"
89+
90+#: qml/Components/Dialogs.qml:176
91+msgctxt "Button: Reboot the system"
92+msgid "Reboot"
93+msgstr "Wadir-ugus"
94+
95+#: qml/Components/Dialogs.qml:185
96+msgctxt "Button: Shut down the system"
97+msgid "Shut down"
98+msgstr "Bargus"
99+
100+#: qml/Components/Dialogs.qml:207
101+msgctxt "Title: Reboot dialog"
102+msgid "Reboot"
103+msgstr "Wadir-ugus"
104+
105+#: qml/Components/Dialogs.qml:208
106+msgid "Are you sure you want to reboot?"
107+msgstr "Wadir-ugussuh digga maay litoo?"
108+
109+#: qml/Components/Dialogs.qml:210
110+msgid "No"
111+msgstr "Maleey"
112+
113+#: qml/Components/Dialogs.qml:217
114+msgid "Yes"
115+msgstr "Yeey"
116+
117+#: qml/Components/Dialogs.qml:232
118+msgctxt "Title: Power off/Restart dialog"
119+msgid "Power"
120+msgstr "Cayla"
121+
122+#: qml/Components/Dialogs.qml:233
123+msgid ""
124+"Are you sure you would like\n"
125+"to power off?"
126+msgstr "Timmi haytuh digga maay litoo?"
127+
128+#: qml/Components/Dialogs.qml:235
129+msgctxt "Button: Power off the system"
130+msgid "Power off"
131+msgstr "Timmi hayis"
132+
133+#: qml/Components/Dialogs.qml:244
134+msgctxt "Button: Restart the system"
135+msgid "Restart"
136+msgstr "Wadir-qimbis"
137+
138+#: qml/Components/Lockscreen.qml:245
139+msgid "Return to Call"
140+msgstr "Seecol gacis"
141+
142+#: qml/Components/Lockscreen.qml:245
143+msgid "Emergency Call"
144+msgstr ""
145+
146+#: qml/Components/Lockscreen.qml:277
147+msgid "OK"
148+msgstr "Hayya"
149+
150+#: qml/Components/ModeSwitchWarningDialog.qml:32
151+msgid "Apps may have unsaved data:"
152+msgstr ""
153+
154+#: qml/Components/ModeSwitchWarningDialog.qml:57
155+msgid "Re-dock, save your work and close these apps to continue."
156+msgstr ""
157+
158+#: qml/Components/ModeSwitchWarningDialog.qml:63
159+msgid "Or force close now (unsaved data will be lost)."
160+msgstr ""
161+
162+#: qml/Components/ModeSwitchWarningDialog.qml:75
163+msgid "OK, I will reconnect"
164+msgstr ""
165+
166+#: qml/Components/ModeSwitchWarningDialog.qml:76
167+msgid "Reconnect now!"
168+msgstr ""
169+
170+#: qml/Components/ModeSwitchWarningDialog.qml:88
171+msgid "Close all"
172+msgstr "Inkih alif"
173+
174+#: qml/Dash/DashPageHeader.qml:266
175+msgctxt "Button: Open the Ubuntu Store"
176+msgid "Store"
177+msgstr ""
178+
179+#: qml/Dash/DashPageHeader.qml:273
180+msgctxt "Button: Start a search in the current dash scope"
181+msgid "Search"
182+msgstr "Goranto"
183+
184+#: qml/Dash/DashPageHeader.qml:283
185+msgctxt "Button: Show the current dash scope settings"
186+msgid "Settings"
187+msgstr "Massosu"
188+
189+#: qml/Dash/DashPageHeader.qml:290
190+msgid "Remove from Favorites"
191+msgstr ""
192+
193+#: qml/Dash/DashPageHeader.qml:290
194+msgid "Add to Favorites"
195+msgstr ""
196+
197+#: qml/Dash/GenericScopeView.qml:587 qml/Dash/GenericScopeView.qml:745
198+msgid "See less"
199+msgstr ""
200+
201+#: qml/Dash/GenericScopeView.qml:587
202+msgid "See all"
203+msgstr ""
204+
205+#: qml/Dash/GenericScopeView.qml:649
206+msgctxt "Label: Hint for dash search line edit"
207+msgid "Search"
208+msgstr "Goranto"
209+
210+#: qml/Dash/Previews/PreviewActionCombo.qml:35
211+msgid "More..."
212+msgstr ""
213+
214+#: qml/Dash/Previews/PreviewActionCombo.qml:35
215+msgid "Less..."
216+msgstr ""
217+
218+#: qml/Dash/Previews/PreviewCommentInput.qml:68
219+#: qml/Dash/Previews/PreviewRatingInput.qml:174
220+msgid "Send"
221+msgstr "Rub"
222+
223+#: qml/Dash/Previews/PreviewRatingInput.qml:84
224+msgid "Rate this"
225+msgstr ""
226+
227+#: qml/Dash/Previews/PreviewRatingInput.qml:129
228+msgid "Add a review"
229+msgstr ""
230+
231+#: qml/Dash/Previews/PreviewSharing.qml:50
232+msgid "Preview Share Item"
233+msgstr ""
234+
235+#: qml/Dash/PullToRefreshScopeStyle.qml:55
236+msgid "Pull to refresh…"
237+msgstr ""
238+
239+#: qml/Dash/PullToRefreshScopeStyle.qml:60
240+msgid "Release to refresh…"
241+msgstr ""
242+
243+#: qml/Dash/ScopeSettings/ScopeSettingBoolean.qml:43
244+msgid "Enable location data"
245+msgstr ""
246+
247+#: qml/Dash/ScopesList.qml:67
248+msgid "Manage"
249+msgstr ""
250+
251+#: qml/Dash/ScopesList.qml:113
252+msgid "Home"
253+msgstr "Dabqi"
254+
255+#: qml/Dash/ScopesList.qml:114
256+msgid "Also installed"
257+msgstr ""
258+
259+#: qml/DisabledScreenNotice.qml:87
260+msgid ""
261+"Your device is now connected to an external display. Use this screen as a "
262+"touch pad to interact with the mouse."
263+msgstr ""
264+
265+#: qml/Greeter/CoverPage.qml:107
266+msgid "Unlock"
267+msgstr ""
268+
269+#: qml/Greeter/LoginList.qml:239
270+msgid "Retry"
271+msgstr "Qagis"
272+
273+#: qml/Greeter/LoginList.qml:240
274+msgid "Tap to unlock"
275+msgstr ""
276+
277+#: qml/Greeter/NarrowView.qml:54 qml/Wizard/Pages/passwd-confirm.qml:53
278+msgid "Sorry, incorrect passphrase."
279+msgstr ""
280+
281+#: qml/Greeter/NarrowView.qml:55 qml/Wizard/Pages/passwd-confirm.qml:54
282+msgid "Sorry, incorrect passcode."
283+msgstr ""
284+
285+#: qml/Greeter/NarrowView.qml:56
286+msgid "This will be your last attempt."
287+msgstr ""
288+
289+#: qml/Greeter/NarrowView.qml:58
290+msgid ""
291+"If passphrase is entered incorrectly, your phone will conduct a factory "
292+"reset and all personal data will be deleted."
293+msgstr ""
294+
295+#: qml/Greeter/NarrowView.qml:59
296+msgid ""
297+"If passcode is entered incorrectly, your phone will conduct a factory reset "
298+"and all personal data will be deleted."
299+msgstr ""
300+
301+#: qml/Greeter/NarrowView.qml:116
302+#, qt-format
303+msgid "Enter %1"
304+msgstr "%1 culus"
305+
306+#: qml/Greeter/NarrowView.qml:117 qml/Wizard/Pages/passwd-set.qml:60
307+msgid "Enter passphrase"
308+msgstr "Tatur-maxco culus"
309+
310+#: qml/Greeter/NarrowView.qml:118
311+msgid "Enter passcode"
312+msgstr "Tatur-mudenta culus"
313+
314+#: qml/Greeter/NarrowView.qml:119
315+#, qt-format
316+msgid "Sorry, incorrect %1"
317+msgstr ""
318+
319+#: qml/Greeter/NarrowView.qml:120
320+msgid "Sorry, incorrect passphrase"
321+msgstr ""
322+
323+#: qml/Greeter/NarrowView.qml:121
324+msgctxt "passphrase"
325+msgid "Please re-enter"
326+msgstr ""
327+
328+#: qml/Greeter/NarrowView.qml:122
329+msgid "Sorry, incorrect passcode"
330+msgstr ""
331+
332+#: qml/Notifications/NotificationMenuItemFactory.qml:129
333+msgid "Show password"
334+msgstr "Cuumita uybulluy"
335+
336+#: qml/Panel/ActiveCallHint.qml:79
337+msgid "Tap to return to call..."
338+msgstr ""
339+
340+#: qml/Panel/ActiveCallHint.qml:92
341+msgid "Conference"
342+msgstr "Koboxu"
343+
344+#: qml/Panel/Indicators/MenuItemFactory.qml:753
345+msgid "Nothing is playing"
346+msgstr ""
347+
348+#: qml/Panel/Indicators/MenuItemFactory.qml:882
349+#, qt-format
350+msgid "%1 hour"
351+msgid_plural "%1 hours"
352+msgstr[0] "%1 saaqata"
353+msgstr[1] "%1 saaqata"
354+
355+#: qml/Panel/Indicators/MenuItemFactory.qml:886
356+#, qt-format
357+msgid "%1 minute"
358+msgid_plural "%1 minutes"
359+msgstr[0] "%1 miniti"
360+msgstr[1] "%1 miniti"
361+
362+#: qml/Panel/Indicators/MenuItemFactory.qml:891
363+#, qt-format
364+msgid "%1 second"
365+msgid_plural "%1 seconds"
366+msgstr[0] "%1 nammayye"
367+msgstr[1] "%1 nammayye"
368+
369+#: qml/Panel/Indicators/MenuItemFactory.qml:894
370+msgid "0 seconds"
371+msgstr "0 nammayye"
372+
373+#. Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
374+#: qml/Panel/Indicators/MenuItemFactory.qml:896
375+#, qt-format
376+msgid "%1 remaining"
377+msgstr "%1 raaqe"
378+
379+#: qml/Panel/Indicators/MenuItemFactory.qml:902
380+msgid "In queue…"
381+msgstr ""
382+
383+#: qml/Panel/Indicators/MenuItemFactory.qml:906
384+msgid "Downloading"
385+msgstr "Qulluumah"
386+
387+#: qml/Panel/Indicators/MenuItemFactory.qml:908
388+msgid "Paused, tap to resume"
389+msgstr ""
390+
391+#: qml/Panel/Indicators/MenuItemFactory.qml:910
392+msgid "Canceled"
393+msgstr "Bayteh"
394+
395+#: qml/Panel/Indicators/MenuItemFactory.qml:912
396+msgid "Finished"
397+msgstr "Duudumteh"
398+
399+#: qml/Panel/Indicators/MenuItemFactory.qml:914
400+msgid "Failed, tap to retry"
401+msgstr ""
402+
403+#: qml/Panel/Indicators/MessageMenuItemFactory.qml:155
404+#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
405+msgctxt "Button: Send a reply message"
406+msgid "Send"
407+msgstr "Rub"
408+
409+#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
410+msgctxt "Label: Hint in message indicator line edit"
411+msgid "Reply"
412+msgstr ""
413+
414+#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
415+msgctxt "Button: Call back on phone"
416+msgid "Call back"
417+msgstr ""
418+
419+#: qml/Panel/Indicators/ModemInfoItem.qml:105
420+msgid "Unlock SIM"
421+msgstr ""
422+
423+#: qml/Panel/Indicators/RoamingIndication.qml:27
424+msgid "Roaming"
425+msgstr ""
426+
427+#: qml/Tutorial/TutorialBottom.qml:28
428+msgid "Open special menus"
429+msgstr ""
430+
431+#: qml/Tutorial/TutorialBottom.qml:29
432+msgid "Swipe up from the bottom edge."
433+msgstr ""
434+
435+#: qml/Tutorial/TutorialBottomFinish.qml:24
436+msgid "This action does different things for different apps"
437+msgstr ""
438+
439+#: qml/Tutorial/TutorialBottomFinish.qml:25
440+msgid "Tap here to finish."
441+msgstr ""
442+
443+#: qml/Tutorial/TutorialContent.qml:80 qml/Tutorial/TutorialLeftFinish.qml:25
444+#: qml/Tutorial/TutorialRight.qml:144
445+msgid "Tap here to continue."
446+msgstr ""
447+
448+#: qml/Tutorial/TutorialLeft.qml:26
449+msgid "Open the launcher"
450+msgstr ""
451+
452+#: qml/Tutorial/TutorialLeft.qml:27
453+msgid "Short swipe from the left edge."
454+msgstr ""
455+
456+#: qml/Tutorial/TutorialLeftFinish.qml:24
457+msgid "These are the shortcuts to favorite apps"
458+msgstr ""
459+
460+#: qml/Tutorial/TutorialPage.qml:178
461+msgid "You almost got it!"
462+msgstr ""
463+
464+#: qml/Tutorial/TutorialPage.qml:195
465+msgid "Try again."
466+msgstr ""
467+
468+#: qml/Tutorial/TutorialRight.qml:31
469+msgid "To view open apps"
470+msgstr ""
471+
472+#: qml/Tutorial/TutorialRight.qml:32
473+msgid "Long swipe from the right edge."
474+msgstr ""
475+
476+#: qml/Tutorial/TutorialRight.qml:122
477+msgid "View all your running tasks."
478+msgstr ""
479+
480+#: qml/Wizard/Page.qml:89
481+msgctxt "Button: Go back one page in the Wizard"
482+msgid "Back"
483+msgstr "Derre"
484+
485+#: qml/Wizard/Pages/10-welcome.qml:27
486+msgid "Hi!"
487+msgstr "Nagaale!"
488+
489+#: qml/Wizard/Pages/10-welcome.qml:44
490+msgid "Welcome to your Ubuntu device."
491+msgstr ""
492+
493+#: qml/Wizard/Pages/10-welcome.qml:52
494+msgid "Let’s get started."
495+msgstr "Hayya qimbisnay."
496+
497+#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:133
498+#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
499+#: qml/Wizard/Pages/60-reporting.qml:60 qml/Wizard/Pages/passwd-confirm.qml:82
500+#: qml/Wizard/Pages/passwd-set.qml:90
501+msgid "Continue"
502+msgstr "Tatur"
503+
504+#: qml/Wizard/Pages/20-sim.qml:25
505+msgid "Add a SIM card and restart your device"
506+msgstr ""
507+
508+#: qml/Wizard/Pages/20-sim.qml:59
509+msgid "Without it, you won’t be able to make calls or use text messaging."
510+msgstr ""
511+
512+#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
513+msgid "Skip"
514+msgstr "Kaqit"
515+
516+#: qml/Wizard/Pages/30-passwd-type.qml:39
517+msgid "Lock security"
518+msgstr ""
519+
520+#: qml/Wizard/Pages/30-passwd-type.qml:79
521+msgid "Please select how you’d like to unlock your device."
522+msgstr ""
523+
524+#: qml/Wizard/Pages/30-passwd-type.qml:102
525+msgctxt "Label: Type of security method"
526+msgid "Swipe"
527+msgstr "Uysuttuc"
528+
529+#: qml/Wizard/Pages/30-passwd-type.qml:103
530+msgctxt "Label: Description of security method"
531+msgid "No security"
532+msgstr ""
533+
534+#: qml/Wizard/Pages/30-passwd-type.qml:105
535+msgctxt "Label: Type of security method"
536+msgid "Passcode"
537+msgstr ""
538+
539+#: qml/Wizard/Pages/30-passwd-type.qml:106
540+msgctxt "Label: Description of security method"
541+msgid "4 digits only"
542+msgstr ""
543+
544+#: qml/Wizard/Pages/30-passwd-type.qml:108
545+msgctxt "Label: Type of security method"
546+msgid "Passphrase"
547+msgstr ""
548+
549+#: qml/Wizard/Pages/30-passwd-type.qml:109
550+msgctxt "Label: Description of security method"
551+msgid "Numbers and letters"
552+msgstr ""
553+
554+#: qml/Wizard/Pages/40-wifi.qml:29
555+msgid "Connect to Wi‑Fi"
556+msgstr ""
557+
558+#: qml/Wizard/Pages/40-wifi.qml:168
559+msgid "Available networks…"
560+msgstr ""
561+
562+#: qml/Wizard/Pages/40-wifi.qml:169
563+msgid "No available networks."
564+msgstr ""
565+
566+#: qml/Wizard/Pages/50-location.qml:27
567+msgid "Location"
568+msgstr ""
569+
570+#: qml/Wizard/Pages/50-location.qml:62
571+msgid "Let the phone detect your location:"
572+msgstr ""
573+
574+#: qml/Wizard/Pages/50-location.qml:69
575+msgid "Using GPS only (less accurate)"
576+msgstr ""
577+
578+#: qml/Wizard/Pages/50-location.qml:86
579+msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
580+msgstr ""
581+
582+#. Translators: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
583+#: qml/Wizard/Pages/50-location.qml:103
584+msgid ""
585+"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
586+"conditions</a>."
587+msgstr ""
588+
589+#: qml/Wizard/Pages/50-location.qml:112
590+msgid "Not at all"
591+msgstr ""
592+
593+#: qml/Wizard/Pages/50-location.qml:124
594+msgid "You can change your mind later in <b>System Settings</b>."
595+msgstr ""
596+
597+#: qml/Wizard/Pages/60-reporting.qml:26
598+msgid "Improving your experience"
599+msgstr ""
600+
601+#: qml/Wizard/Pages/60-reporting.qml:46
602+msgid ""
603+"Your phone is set up to automatically report errors to Canonical and its "
604+"partners, the makers of the operating system."
605+msgstr ""
606+
607+#: qml/Wizard/Pages/60-reporting.qml:53
608+msgid ""
609+"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
610+"Privacy</b>"
611+msgstr ""
612+
613+#: qml/Wizard/Pages/80-finished.qml:24
614+msgid "All done"
615+msgstr ""
616+
617+#: qml/Wizard/Pages/80-finished.qml:39
618+msgid "Nice work!"
619+msgstr ""
620+
621+#: qml/Wizard/Pages/80-finished.qml:46
622+msgid "Your device is now ready to use."
623+msgstr ""
624+
625+#: qml/Wizard/Pages/80-finished.qml:53
626+msgid "Finish"
627+msgstr ""
628+
629+#: qml/Wizard/Pages/here-terms.qml:27
630+msgid "Terms & Conditions"
631+msgstr ""
632+
633+#: qml/Wizard/Pages/passwd-confirm.qml:49
634+msgid "Confirm passphrase"
635+msgstr ""
636+
637+#: qml/Wizard/Pages/passwd-confirm.qml:50
638+msgid "Confirm passcode"
639+msgstr ""
640+
641+#: qml/Wizard/Pages/passwd-confirm.qml:53
642+#: qml/Wizard/Pages/passwd-confirm.qml:54
643+msgid "Please try again."
644+msgstr ""
645+
646+#: qml/Wizard/Pages/passwd-set.qml:61
647+msgid "Choose your passcode"
648+msgstr ""
649+
650+#: qml/Wizard/Pages/passwd-set.qml:68
651+msgid "Passphrase must be 4 characters long"
652+msgstr ""
653+
654+#. Translators: This is the arrow for "Back" buttons
655+#: qml/Wizard/StackButton.qml:39
656+#, qt-format
657+msgid "〈 %1"
658+msgstr ""
659+
660+#. Translators: This is the arrow for "Forward" buttons
661+#: qml/Wizard/StackButton.qml:42
662+#, qt-format
663+msgid "%1 〉"
664+msgstr ""
665+
666+#~ msgid "Welcome to your Ubuntu phone."
667+#~ msgstr "Ubuntu Telefoonul arcib"
po/am.po+17−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n > 1;\n"
18"Plural-Forms: nplurals=2; plural=n > 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -671,6 +671,21 @@ msgstr "〈 %1"
671msgid "%1 〉"
671msgid "%1 〉"
672msgstr "%1 〉"
672msgstr "%1 〉"
673
673
674+#~ msgid ""
675+#~ "Your device is now connected to an external display. Use this screen as a "
676+#~ "touch pad to interact with the mouse."
677+#~ msgstr ""
678+#~ "የ እርስዎ አካል አሁን ከ ውጪ ማሳያ ጋር ተገናኝቷል: ይህን መመልከቻ እንደ ተችፓድ ከ አይጥ ጋር ተባብሮ ይሰራል"
679+
680+#~ msgid "Welcome to your Ubuntu device."
681+#~ msgstr "እንኳን ድህና መጡ ወደ ኡቡንቱ"
682+
683+#~ msgid "Please select how you’d like to unlock your device."
684+#~ msgstr "እባክዎን የ እርስዎን አካል እንዴት እንደሚከፈት ይምረጡ"
685+
686+#~ msgid "Your device is now ready to use."
687+#~ msgstr "የ እርስዎ አካል አሁን ዝግጁ ነው"
688+
674#~ msgid "Top edge"
689#~ msgid "Top edge"
675#~ msgstr "የላይ ጠርዝ"
690#~ msgstr "የላይ ጠርዝ"
676
691
po/ar.po+2−2
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n % 100 >= "
18"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n % 100 >= "
19"3 && n % 100 <= 10 ? 3 : n % 100 >= 11 && n % 100 <= 99 ? 4 : 5;\n"
19"3 && n % 100 <= 10 ? 3 : n % 100 >= 11 && n % 100 <= 99 ? 4 : 5;\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
po/ast.po+13−11
@@ -8,7 +8,7 @@ msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: \n"
9"Report-Msgid-Bugs-To: \n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
11−"PO-Revision-Date: 2015-10-06 12:07+0000\n"
11+"PO-Revision-Date: 2016-02-19 19:39+0000\n"
12"Last-Translator: Xuacu Saturio <xuacusk8@gmail.com>\n"
12"Last-Translator: Xuacu Saturio <xuacusk8@gmail.com>\n"
13"Language-Team: Asturian <ast@li.org>\n"
13"Language-Team: Asturian <ast@li.org>\n"
14"Language: ast\n"
14"Language: ast\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -152,27 +152,29 @@ msgstr "Aceutar"
152
152
153#: qml/Components/ModeSwitchWarningDialog.qml:32
153#: qml/Components/ModeSwitchWarningDialog.qml:32
154msgid "Apps may have unsaved data:"
154msgid "Apps may have unsaved data:"
155−msgstr ""
155+msgstr "Apps que pueden tener datos sin guardar:"
156
156
157#: qml/Components/ModeSwitchWarningDialog.qml:57
157#: qml/Components/ModeSwitchWarningDialog.qml:57
158msgid "Re-dock, save your work and close these apps to continue."
158msgid "Re-dock, save your work and close these apps to continue."
159msgstr ""
159msgstr ""
160+"Pa siguir coneuta nuevamente'l preséu, guarda'l trabayu y zarra estes "
161+"aplicaciones."
160
162
161#: qml/Components/ModeSwitchWarningDialog.qml:63
163#: qml/Components/ModeSwitchWarningDialog.qml:63
162msgid "Or force close now (unsaved data will be lost)."
164msgid "Or force close now (unsaved data will be lost)."
163−msgstr ""
165+msgstr "O fuerza salir agora (perderás tolos datos sin guardar)."
164
166
165#: qml/Components/ModeSwitchWarningDialog.qml:75
167#: qml/Components/ModeSwitchWarningDialog.qml:75
166msgid "OK, I will reconnect"
168msgid "OK, I will reconnect"
167−msgstr ""
169+msgstr "D'alcuerdu, reconeutaré"
168
170
169#: qml/Components/ModeSwitchWarningDialog.qml:76
171#: qml/Components/ModeSwitchWarningDialog.qml:76
170msgid "Reconnect now!"
172msgid "Reconnect now!"
171−msgstr ""
173+msgstr "Reconeutar agora."
172
174
173#: qml/Components/ModeSwitchWarningDialog.qml:88
175#: qml/Components/ModeSwitchWarningDialog.qml:88
174msgid "Close all"
176msgid "Close all"
175−msgstr ""
177+msgstr "Zarrar too"
176
178
177#: qml/Dash/DashPageHeader.qml:266
179#: qml/Dash/DashPageHeader.qml:266
178msgctxt "Button: Open the Ubuntu Store"
180msgctxt "Button: Open the Ubuntu Store"
@@ -233,7 +235,7 @@ msgstr "Amestar una reseña"
233
235
234#: qml/Dash/Previews/PreviewSharing.qml:50
236#: qml/Dash/Previews/PreviewSharing.qml:50
235msgid "Preview Share Item"
237msgid "Preview Share Item"
236−msgstr ""
238+msgstr "Entever l'elementu compartíu"
237
239
238#: qml/Dash/PullToRefreshScopeStyle.qml:55
240#: qml/Dash/PullToRefreshScopeStyle.qml:55
239msgid "Pull to refresh…"
241msgid "Pull to refresh…"
@@ -409,7 +411,7 @@ msgstr "Falló, toca pa reintentar"
409#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
411#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
410msgctxt "Button: Send a reply message"
412msgctxt "Button: Send a reply message"
411msgid "Send"
413msgid "Send"
412−msgstr ""
414+msgstr "Unviar"
413
415
414#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
416#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
415msgctxt "Label: Hint in message indicator line edit"
417msgctxt "Label: Hint in message indicator line edit"
@@ -419,7 +421,7 @@ msgstr "Responder"
419#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
421#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
420msgctxt "Button: Call back on phone"
422msgctxt "Button: Call back on phone"
421msgid "Call back"
423msgid "Call back"
422−msgstr ""
424+msgstr "Devolver llamada"
423
425
424#: qml/Panel/Indicators/ModemInfoItem.qml:105
426#: qml/Panel/Indicators/ModemInfoItem.qml:105
425msgid "Unlock SIM"
427msgid "Unlock SIM"
po/az.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/be.po+3−3
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
18"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
19"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
@@ -237,7 +237,7 @@ msgstr "Дадаць рэцэнзію"
237
237
238#: qml/Dash/Previews/PreviewSharing.qml:50
238#: qml/Dash/Previews/PreviewSharing.qml:50
239msgid "Preview Share Item"
239msgid "Preview Share Item"
240−msgstr "Падзяліцца праглядаймым"
240+msgstr "Праглядзець элемент"
241
241
242#: qml/Dash/PullToRefreshScopeStyle.qml:55
242#: qml/Dash/PullToRefreshScopeStyle.qml:55
243msgid "Pull to refresh…"
243msgid "Pull to refresh…"
po/bg.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/bn.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/br.po+28−10
@@ -8,7 +8,7 @@ msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: \n"
9"Report-Msgid-Bugs-To: \n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
11−"PO-Revision-Date: 2015-10-05 06:47+0000\n"
11+"PO-Revision-Date: 2016-02-22 12:29+0000\n"
12"Last-Translator: Fohanno Thierry <thierry.fohanno@ofis-bzh.org>\n"
12"Last-Translator: Fohanno Thierry <thierry.fohanno@ofis-bzh.org>\n"
13"Language-Team: Breton <br@li.org>\n"
13"Language-Team: Breton <br@li.org>\n"
14"Language: br\n"
14"Language: br\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n > 1;\n"
18"Plural-Forms: nplurals=2; plural=n > 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -156,27 +156,29 @@ msgstr "Mat eo"
156
156
157#: qml/Components/ModeSwitchWarningDialog.qml:32
157#: qml/Components/ModeSwitchWarningDialog.qml:32
158msgid "Apps may have unsaved data:"
158msgid "Apps may have unsaved data:"
159−msgstr ""
159+msgstr "Roadennoù ha n'int ket enrollet a c'hall bezañ gant an arloadoù :"
160
160
161#: qml/Components/ModeSwitchWarningDialog.qml:57
161#: qml/Components/ModeSwitchWarningDialog.qml:57
162msgid "Re-dock, save your work and close these apps to continue."
162msgid "Re-dock, save your work and close these apps to continue."
163msgstr ""
163msgstr ""
164+"Adlugit, enrollit ho labour ha serrit an arloadoù-mañ evit kenderc'hel."
164
165
165#: qml/Components/ModeSwitchWarningDialog.qml:63
166#: qml/Components/ModeSwitchWarningDialog.qml:63
166msgid "Or force close now (unsaved data will be lost)."
167msgid "Or force close now (unsaved data will be lost)."
167msgstr ""
168msgstr ""
169+"Pe rediañ da serriñ bremañ (kollet e vo ar roadennoù n'int ket bet enrollet)."
168
170
169#: qml/Components/ModeSwitchWarningDialog.qml:75
171#: qml/Components/ModeSwitchWarningDialog.qml:75
170msgid "OK, I will reconnect"
172msgid "OK, I will reconnect"
171−msgstr ""
173+msgstr "Mat eo, ez an da adkevreañ"
172
174
173#: qml/Components/ModeSwitchWarningDialog.qml:76
175#: qml/Components/ModeSwitchWarningDialog.qml:76
174msgid "Reconnect now!"
176msgid "Reconnect now!"
175−msgstr ""
177+msgstr "Adkevreañ bremañ !"
176
178
177#: qml/Components/ModeSwitchWarningDialog.qml:88
179#: qml/Components/ModeSwitchWarningDialog.qml:88
178msgid "Close all"
180msgid "Close all"
179−msgstr ""
181+msgstr "Serriñ pep tra"
180
182
181#: qml/Dash/DashPageHeader.qml:266
183#: qml/Dash/DashPageHeader.qml:266
182msgctxt "Button: Open the Ubuntu Store"
184msgctxt "Button: Open the Ubuntu Store"
@@ -237,7 +239,7 @@ msgstr "Ouzhpennañ un ali"
237
239
238#: qml/Dash/Previews/PreviewSharing.qml:50
240#: qml/Dash/Previews/PreviewSharing.qml:50
239msgid "Preview Share Item"
241msgid "Preview Share Item"
240−msgstr ""
242+msgstr "Rakwelet an elfenn lodet"
241
243
242#: qml/Dash/PullToRefreshScopeStyle.qml:55
244#: qml/Dash/PullToRefreshScopeStyle.qml:55
243msgid "Pull to refresh…"
245msgid "Pull to refresh…"
@@ -413,7 +415,7 @@ msgstr "C'hwitet, touchit evit adkregiñ"
413#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
415#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
414msgctxt "Button: Send a reply message"
416msgctxt "Button: Send a reply message"
415msgid "Send"
417msgid "Send"
416−msgstr ""
418+msgstr "Kas"
417
419
418#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
420#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
419msgctxt "Label: Hint in message indicator line edit"
421msgctxt "Label: Hint in message indicator line edit"
@@ -423,7 +425,7 @@ msgstr "Respont"
423#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
425#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
424msgctxt "Button: Call back on phone"
426msgctxt "Button: Call back on phone"
425msgid "Call back"
427msgid "Call back"
426−msgstr ""
428+msgstr "Gervel en-dro"
427
429
428#: qml/Panel/Indicators/ModemInfoItem.qml:105
430#: qml/Panel/Indicators/ModemInfoItem.qml:105
429msgid "Unlock SIM"
431msgid "Unlock SIM"
@@ -678,6 +680,22 @@ msgstr "〈 %1"
678msgid "%1 〉"
680msgid "%1 〉"
679msgstr "%1 〉"
681msgstr "%1 〉"
680
682
683+#~ msgid ""
684+#~ "Your device is now connected to an external display. Use this screen as a "
685+#~ "touch pad to interact with the mouse."
686+#~ msgstr ""
687+#~ "N'eo ket kevreet ho penveg ouzh un diskwel diavaez. Implijit ar skramm-"
688+#~ "mañ da douch evit ober gant al logodenn."
689+
690+#~ msgid "Welcome to your Ubuntu device."
691+#~ msgstr "Donemat en ho penveg Ubuntu"
692+
693+#~ msgid "Please select how you’d like to unlock your device."
694+#~ msgstr "Diuzit penaos e fell deoc'h dibrennañ ho penveg, mar plij."
695+
696+#~ msgid "Your device is now ready to use."
697+#~ msgstr "Prest eo ho penveg da vezañ implijet bremañ."
698+
681#~ msgid "Close"
699#~ msgid "Close"
682#~ msgstr "Serriñ"
700#~ msgstr "Serriñ"
683
701
po/bs.po+2−2
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
18"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
po/ca.po+11−9
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -156,27 +156,29 @@ msgstr "D'acord"
156
156
157#: qml/Components/ModeSwitchWarningDialog.qml:32
157#: qml/Components/ModeSwitchWarningDialog.qml:32
158msgid "Apps may have unsaved data:"
158msgid "Apps may have unsaved data:"
159−msgstr ""
159+msgstr "Pot ser que aquestes aplicacions no hagin desat les dades:"
160
160
161#: qml/Components/ModeSwitchWarningDialog.qml:57
161#: qml/Components/ModeSwitchWarningDialog.qml:57
162msgid "Re-dock, save your work and close these apps to continue."
162msgid "Re-dock, save your work and close these apps to continue."
163msgstr ""
163msgstr ""
164+"Torneu a connectar, deseu la feina i tanqueu aquestes aplicacions per "
165+"continuar."
164
166
165#: qml/Components/ModeSwitchWarningDialog.qml:63
167#: qml/Components/ModeSwitchWarningDialog.qml:63
166msgid "Or force close now (unsaved data will be lost)."
168msgid "Or force close now (unsaved data will be lost)."
167−msgstr ""
169+msgstr "O força el tancament (les dades no desades es perdran)."
168
170
169#: qml/Components/ModeSwitchWarningDialog.qml:75
171#: qml/Components/ModeSwitchWarningDialog.qml:75
170msgid "OK, I will reconnect"
172msgid "OK, I will reconnect"
171−msgstr ""
173+msgstr "D'acord, tornaré a connectar"
172
174
173#: qml/Components/ModeSwitchWarningDialog.qml:76
175#: qml/Components/ModeSwitchWarningDialog.qml:76
174msgid "Reconnect now!"
176msgid "Reconnect now!"
175−msgstr ""
177+msgstr "Torna a connectar"
176
178
177#: qml/Components/ModeSwitchWarningDialog.qml:88
179#: qml/Components/ModeSwitchWarningDialog.qml:88
178msgid "Close all"
180msgid "Close all"
179−msgstr ""
181+msgstr "Tanca-ho tot"
180
182
181#: qml/Dash/DashPageHeader.qml:266
183#: qml/Dash/DashPageHeader.qml:266
182msgctxt "Button: Open the Ubuntu Store"
184msgctxt "Button: Open the Ubuntu Store"
@@ -415,7 +417,7 @@ msgstr "Ha fallat, feu un toc per tornar-ho a intentar"
415#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
417#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
416msgctxt "Button: Send a reply message"
418msgctxt "Button: Send a reply message"
417msgid "Send"
419msgid "Send"
418−msgstr ""
420+msgstr "Envia"
419
421
420#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
422#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
421msgctxt "Label: Hint in message indicator line edit"
423msgctxt "Label: Hint in message indicator line edit"
@@ -425,7 +427,7 @@ msgstr "Respon"
425#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
427#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
426msgctxt "Button: Call back on phone"
428msgctxt "Button: Call back on phone"
427msgid "Call back"
429msgid "Call back"
428−msgstr ""
430+msgstr "Retorna la trucada"
429
431
430#: qml/Panel/Indicators/ModemInfoItem.qml:105
432#: qml/Panel/Indicators/ModemInfoItem.qml:105
431msgid "Unlock SIM"
433msgid "Unlock SIM"
po/ca@valencia.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/ce.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/ckb.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/cs.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
18"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/cy.po+2−2
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=4; plural=n==1 ? 0 : n==2 ? 1 : (n != 8 && n != 11) ? "
18"Plural-Forms: nplurals=4; plural=n==1 ? 0 : n==2 ? 1 : (n != 8 && n != 11) ? "
19"2 : 3;\n"
19"2 : 3;\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
po/da.po+2−2
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Type: text/plain; charset=UTF-8\n"
18"Content-Transfer-Encoding: 8bit\n"
18"Content-Transfer-Encoding: 8bit\n"
19"Plural-Forms: nplurals=2; plural=n != 1;\n"
19"Plural-Forms: nplurals=2; plural=n != 1;\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
po/de.po+20−4
@@ -8,16 +8,16 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: \n"
9"Report-Msgid-Bugs-To: \n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
11−"PO-Revision-Date: 2015-07-24 18:03+0000\n"
11+"PO-Revision-Date: 2016-02-17 19:16+0000\n"
12−"Last-Translator: Torsten Franz <Unknown>\n"
12+"Last-Translator: schuko24 <gerdsaenger@t-online.de>\n"
13"Language-Team: German <de@li.org>\n"
13"Language-Team: German <de@li.org>\n"
14"Language: de\n"
14"Language: de\n"
15"MIME-Version: 1.0\n"
15"MIME-Version: 1.0\n"
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -682,6 +682,22 @@ msgstr "〈 %1"
682msgid "%1 〉"
682msgid "%1 〉"
683msgstr "%1 〉"
683msgstr "%1 〉"
684
684
685+#~ msgid ""
686+#~ "Your device is now connected to an external display. Use this screen as a "
687+#~ "touch pad to interact with the mouse."
688+#~ msgstr ""
689+#~ "Ihr Gerät ist nun mit einer externen Anzeige verbunden. Benutzen Sie "
690+#~ "diesen Bildschirm als Touchpad zur Steuerung des Mauszeigers."
691+
692+#~ msgid "Welcome to your Ubuntu device."
693+#~ msgstr "Willkommen auf Ihrem Ubuntu-Gerät."
694+
695+#~ msgid "Please select how you’d like to unlock your device."
696+#~ msgstr "Bitte wählen Sie, wie Sie dieses Gerät entsperren möchten."
697+
698+#~ msgid "Your device is now ready to use."
699+#~ msgstr "Ihr Gerät ist nun einsatzbereit."
700+
685#~ msgid "Confirm"
701#~ msgid "Confirm"
686#~ msgstr "Bestätigen"
702#~ msgstr "Bestätigen"
687
703
po/el.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/en_AU.po+21−14
@@ -8,7 +8,7 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: \n"
9"Report-Msgid-Bugs-To: \n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
11−"PO-Revision-Date: 2015-07-12 07:17+0000\n"
11+"PO-Revision-Date: 2016-02-12 23:22+0000\n"
12"Last-Translator: Jared Norris <jarednorris@ubuntu.com>\n"
12"Last-Translator: Jared Norris <jarednorris@ubuntu.com>\n"
13"Language-Team: English (Australia) <en_AU@li.org>\n"
13"Language-Team: English (Australia) <en_AU@li.org>\n"
14"Language: \n"
14"Language: \n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -30,7 +30,7 @@ msgstr "Pin shortcut"
30
30
31#: plugins/Unity/Launcher/launcheritem.cpp:52
31#: plugins/Unity/Launcher/launcheritem.cpp:52
32msgid "Quit"
32msgid "Quit"
33−msgstr ""
33+msgstr "Quit"
34
34
35#: plugins/Unity/Launcher/launcheritem.cpp:106
35#: plugins/Unity/Launcher/launcheritem.cpp:106
36msgid "Unpin shortcut"
36msgid "Unpin shortcut"
@@ -152,27 +152,27 @@ msgstr "OK"
152
152
153#: qml/Components/ModeSwitchWarningDialog.qml:32
153#: qml/Components/ModeSwitchWarningDialog.qml:32
154msgid "Apps may have unsaved data:"
154msgid "Apps may have unsaved data:"
155−msgstr ""
155+msgstr "Apps may have unsaved data:"
156
156
157#: qml/Components/ModeSwitchWarningDialog.qml:57
157#: qml/Components/ModeSwitchWarningDialog.qml:57
158msgid "Re-dock, save your work and close these apps to continue."
158msgid "Re-dock, save your work and close these apps to continue."
159−msgstr ""
159+msgstr "Re-dock, save your work and close these apps to continue."
160
160
161#: qml/Components/ModeSwitchWarningDialog.qml:63
161#: qml/Components/ModeSwitchWarningDialog.qml:63
162msgid "Or force close now (unsaved data will be lost)."
162msgid "Or force close now (unsaved data will be lost)."
163−msgstr ""
163+msgstr "Or force close now (unsaved data will be lost)."
164
164
165#: qml/Components/ModeSwitchWarningDialog.qml:75
165#: qml/Components/ModeSwitchWarningDialog.qml:75
166msgid "OK, I will reconnect"
166msgid "OK, I will reconnect"
167−msgstr ""
167+msgstr "OK, I will reconnect"
168
168
169#: qml/Components/ModeSwitchWarningDialog.qml:76
169#: qml/Components/ModeSwitchWarningDialog.qml:76
170msgid "Reconnect now!"
170msgid "Reconnect now!"
171−msgstr ""
171+msgstr "Reconnect now!"
172
172
173#: qml/Components/ModeSwitchWarningDialog.qml:88
173#: qml/Components/ModeSwitchWarningDialog.qml:88
174msgid "Close all"
174msgid "Close all"
175−msgstr ""
175+msgstr "Close all"
176
176
177#: qml/Dash/DashPageHeader.qml:266
177#: qml/Dash/DashPageHeader.qml:266
178msgctxt "Button: Open the Ubuntu Store"
178msgctxt "Button: Open the Ubuntu Store"
@@ -233,7 +233,7 @@ msgstr "Add a review"
233
233
234#: qml/Dash/Previews/PreviewSharing.qml:50
234#: qml/Dash/Previews/PreviewSharing.qml:50
235msgid "Preview Share Item"
235msgid "Preview Share Item"
236−msgstr ""
236+msgstr "Preview Share Item"
237
237
238#: qml/Dash/PullToRefreshScopeStyle.qml:55
238#: qml/Dash/PullToRefreshScopeStyle.qml:55
239msgid "Pull to refresh…"
239msgid "Pull to refresh…"
@@ -328,7 +328,7 @@ msgstr "Sorry, incorrect passphrase"
328#: qml/Greeter/NarrowView.qml:121
328#: qml/Greeter/NarrowView.qml:121
329msgctxt "passphrase"
329msgctxt "passphrase"
330msgid "Please re-enter"
330msgid "Please re-enter"
331−msgstr ""
331+msgstr "Please re-enter"
332
332
333#: qml/Greeter/NarrowView.qml:122
333#: qml/Greeter/NarrowView.qml:122
334msgid "Sorry, incorrect passcode"
334msgid "Sorry, incorrect passcode"
@@ -409,7 +409,7 @@ msgstr "Failed, tap to retry"
409#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
409#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
410msgctxt "Button: Send a reply message"
410msgctxt "Button: Send a reply message"
411msgid "Send"
411msgid "Send"
412−msgstr ""
412+msgstr "Send"
413
413
414#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
414#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
415msgctxt "Label: Hint in message indicator line edit"
415msgctxt "Label: Hint in message indicator line edit"
@@ -419,7 +419,7 @@ msgstr "Reply"
419#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
419#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
420msgctxt "Button: Call back on phone"
420msgctxt "Button: Call back on phone"
421msgid "Call back"
421msgid "Call back"
422−msgstr ""
422+msgstr "Call back"
423
423
424#: qml/Panel/Indicators/ModemInfoItem.qml:105
424#: qml/Panel/Indicators/ModemInfoItem.qml:105
425msgid "Unlock SIM"
425msgid "Unlock SIM"
@@ -674,6 +674,13 @@ msgstr "〈 %1"
674msgid "%1 〉"
674msgid "%1 〉"
675msgstr "%1 〉"
675msgstr "%1 〉"
676
676
677+#~ msgid ""
678+#~ "Your device is now connected to an external display. Use this screen as a "
679+#~ "touch pad to interact with the mouse."
680+#~ msgstr ""
681+#~ "Your device is now connected to an external display. Use this screen as a "
682+#~ "touch pad to interact with the mouse."
683+
677#~ msgid "Confirm"
684#~ msgid "Confirm"
678#~ msgstr "Confirm"
685#~ msgstr "Confirm"
679
686
po/en_GB.po+18−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -674,6 +674,22 @@ msgstr "〈 %1"
674msgid "%1 〉"
674msgid "%1 〉"
675msgstr "%1 〉"
675msgstr "%1 〉"
676
676
677+#~ msgid ""
678+#~ "Your device is now connected to an external display. Use this screen as a "
679+#~ "touch pad to interact with the mouse."
680+#~ msgstr ""
681+#~ "Your device is now connected to an external display. Use this screen as a "
682+#~ "touch pad to interact with the mouse."
683+
684+#~ msgid "Welcome to your Ubuntu device."
685+#~ msgstr "Welcome to your Ubuntu device."
686+
687+#~ msgid "Please select how you’d like to unlock your device."
688+#~ msgstr "Please select how you would like to unlock your device."
689+
690+#~ msgid "Your device is now ready to use."
691+#~ msgstr "Your device is now ready to use."
692+
677#~ msgid "Confirm"
693#~ msgid "Confirm"
678#~ msgstr "Confirm"
694#~ msgstr "Confirm"
679
695
po/eo.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/es.po+18−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-16 05:38+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -680,6 +680,22 @@ msgstr "〈 %1"
680msgid "%1 〉"
680msgid "%1 〉"
681msgstr "%1 〉"
681msgstr "%1 〉"
682
682
683+#~ msgid ""
684+#~ "Your device is now connected to an external display. Use this screen as a "
685+#~ "touch pad to interact with the mouse."
686+#~ msgstr ""
687+#~ "Ahora está conectado a una pantalla externa. Utilice esta pantalla como "
688+#~ "dispositivo táctil para controlar el ratón."
689+
690+#~ msgid "Welcome to your Ubuntu device."
691+#~ msgstr "Bienvenido a su dispositivo Ubuntu."
692+
693+#~ msgid "Please select how you’d like to unlock your device."
694+#~ msgstr "Por favor, seleccione cómo desea desbloquear el dispositivo."
695+
696+#~ msgid "Your device is now ready to use."
697+#~ msgstr "El dispositivo ya está listo."
698+
683#~ msgid "Confirm"
699#~ msgid "Confirm"
684#~ msgstr "Confirmar"
700#~ msgstr "Confirmar"
685
701
po/eu.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/fa.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/fi.po+18−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -678,6 +678,22 @@ msgstr "〈 %1"
678msgid "%1 〉"
678msgid "%1 〉"
679msgstr "%1 〉"
679msgstr "%1 〉"
680
680
681+#~ msgid ""
682+#~ "Your device is now connected to an external display. Use this screen as a "
683+#~ "touch pad to interact with the mouse."
684+#~ msgstr ""
685+#~ "Laitteesi on nyt yhdistetty erilliseen näyttöön. Käytä tätä näyttöä "
686+#~ "kosketuslevynä vaikuttaaksesi hiiren toimintaan."
687+
688+#~ msgid "Welcome to your Ubuntu device."
689+#~ msgstr "Tervetuloa Ubuntu-laitteesi pariin."
690+
691+#~ msgid "Please select how you’d like to unlock your device."
692+#~ msgstr "Valitse kuinka haluat avata laitteen lukituksen."
693+
694+#~ msgid "Your device is now ready to use."
695+#~ msgstr "Laitteesi on nyt valmis käytettäväksi."
696+
681#~ msgid "Confirm"
697#~ msgid "Confirm"
682#~ msgstr "Hyväksy"
698#~ msgstr "Hyväksy"
683
699
po/fo.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/fr.po+22−4
@@ -8,16 +8,16 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: \n"
9"Report-Msgid-Bugs-To: \n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
11−"PO-Revision-Date: 2015-11-07 19:43+0000\n"
11+"PO-Revision-Date: 2016-02-28 17:22+0000\n"
12−"Last-Translator: Jean-Marc <Unknown>\n"
12+"Last-Translator: Anne <anneonyme017@gmail.com>\n"
13"Language-Team: French <fr@li.org>\n"
13"Language-Team: French <fr@li.org>\n"
14"Language: fr\n"
14"Language: fr\n"
15"MIME-Version: 1.0\n"
15"MIME-Version: 1.0\n"
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n > 1;\n"
18"Plural-Forms: nplurals=2; plural=n > 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-29 05:58+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -690,6 +690,24 @@ msgstr "〈 %1"
690msgid "%1 〉"
690msgid "%1 〉"
691msgstr "%1 〉"
691msgstr "%1 〉"
692
692
693+#~ msgid ""
694+#~ "Your device is now connected to an external display. Use this screen as a "
695+#~ "touch pad to interact with the mouse."
696+#~ msgstr ""
697+#~ "Votre appareil est maintenant connecté à un affichage externe. Utilisez "
698+#~ "cet écran comme un pavé tactile pour interagir avec la souris."
699+
700+#~ msgid "Welcome to your Ubuntu device."
701+#~ msgstr "Bienvenue sur votre appareil Ubuntu."
702+
703+#~ msgid "Please select how you’d like to unlock your device."
704+#~ msgstr ""
705+#~ "Veuillez sélectionner la façon dont vous souhaitez déverrouiller votre "
706+#~ "appareil."
707+
708+#~ msgid "Your device is now ready to use."
709+#~ msgstr "Votre appareil est maintenant prêt à être utilisé."
710+
693#~ msgid "Skip intro"
711#~ msgid "Skip intro"
694#~ msgstr "Passer l'intro"
712#~ msgstr "Passer l'intro"
695
713
po/ga.po+135−119
@@ -8,7 +8,7 @@ msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: \n"
9"Report-Msgid-Bugs-To: \n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
11−"PO-Revision-Date: 2015-12-17 16:56+0000\n"
11+"PO-Revision-Date: 2016-01-25 11:33+0000\n"
12"Last-Translator: Joshua Kiley <Unknown>\n"
12"Last-Translator: Joshua Kiley <Unknown>\n"
13"Language-Team: Irish <ga@li.org>\n"
13"Language-Team: Irish <ga@li.org>\n"
14"Language: ga\n"
14"Language: ga\n"
@@ -16,44 +16,45 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;\n"
18"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
24−msgstr "Focal Faire: "
24+msgstr "Pasfhocal "
25
25
26#: plugins/Unity/Launcher/launcheritem.cpp:47
26#: plugins/Unity/Launcher/launcheritem.cpp:47
27#: plugins/Unity/Launcher/launcheritem.cpp:106
27#: plugins/Unity/Launcher/launcheritem.cpp:106
28msgid "Pin shortcut"
28msgid "Pin shortcut"
29−msgstr ""
29+msgstr "Cruthaigh Aicearra Leis An Bharra"
30
30
31#: plugins/Unity/Launcher/launcheritem.cpp:52
31#: plugins/Unity/Launcher/launcheritem.cpp:52
32msgid "Quit"
32msgid "Quit"
33−msgstr "Scoir"
33+msgstr "Éirigh as"
34
34
35#: plugins/Unity/Launcher/launcheritem.cpp:106
35#: plugins/Unity/Launcher/launcheritem.cpp:106
36msgid "Unpin shortcut"
36msgid "Unpin shortcut"
37−msgstr ""
37+msgstr "Bain Aicearra Den Bharra"
38
38
39#: qml/Components/DelayedLockscreen.qml:49
39#: qml/Components/DelayedLockscreen.qml:49
40msgid "Device Locked"
40msgid "Device Locked"
41−msgstr ""
41+msgstr "Faoi Ghlas"
42
42
43#: qml/Components/DelayedLockscreen.qml:64
43#: qml/Components/DelayedLockscreen.qml:64
44msgid "You have been locked out due to too many failed passphrase attempts."
44msgid "You have been locked out due to too many failed passphrase attempts."
45−msgstr ""
45+msgstr "Tá tú dúnta amach ceal an iomarca drochiarrachtaí pasfhocail."
46
46
47#: qml/Components/DelayedLockscreen.qml:65
47#: qml/Components/DelayedLockscreen.qml:65
48msgid "You have been locked out due to too many failed passcode attempts."
48msgid "You have been locked out due to too many failed passcode attempts."
49−msgstr ""
49+msgstr "Tá tú dúnta amach ceal an iomarca drochiarrachtaí cóid."
50
50
51#: qml/Components/DelayedLockscreen.qml:74
51#: qml/Components/DelayedLockscreen.qml:74
52#, qt-format
52#, qt-format
53msgid "Please wait %1 minute and then try again…"
53msgid "Please wait %1 minute and then try again…"
54msgid_plural "Please wait %1 minutes and then try again…"
54msgid_plural "Please wait %1 minutes and then try again…"
55−msgstr[0] ""
55+msgstr[0] "Fan %1 nóiméad agus bain triail as arís, le do thoil."
56−msgstr[1] ""
56+msgstr[1] "Fan %1 nóiméad agus bain triail as arís, le do thoil."
57+msgstr[2] "Fan %1 nóiméad agus bain triail as arís, le do thoil."
57
58
58#: qml/Components/Dialogs.qml:144
59#: qml/Components/Dialogs.qml:144
59msgctxt "Title: Lock/Log out dialog"
60msgctxt "Title: Lock/Log out dialog"
@@ -62,12 +63,12 @@ msgstr "Logáil Amach"
62
63
63#: qml/Components/Dialogs.qml:145
64#: qml/Components/Dialogs.qml:145
64msgid "Are you sure you want to log out?"
65msgid "Are you sure you want to log out?"
65−msgstr ""
66+msgstr "An bhfuil tú cinnte gur mhaith leat lógáil amach?"
66
67
67#: qml/Components/Dialogs.qml:147
68#: qml/Components/Dialogs.qml:147
68msgctxt "Button: Lock the system"
69msgctxt "Button: Lock the system"
69msgid "Lock"
70msgid "Lock"
70−msgstr "Glasáil"
71+msgstr "Cuir Faoi Ghlas"
71
72
72#: qml/Components/Dialogs.qml:154
73#: qml/Components/Dialogs.qml:154
73msgctxt "Button: Log out from the system"
74msgctxt "Button: Log out from the system"
@@ -86,7 +87,7 @@ msgstr "Múch"
86
87
87#: qml/Components/Dialogs.qml:174
88#: qml/Components/Dialogs.qml:174
88msgid "Are you sure you want to shut down?"
89msgid "Are you sure you want to shut down?"
89−msgstr ""
90+msgstr "Cinnte gur mhaith leat an gléas a mhúchadh?"
90
91
91#: qml/Components/Dialogs.qml:176
92#: qml/Components/Dialogs.qml:176
92msgctxt "Button: Reboot the system"
93msgctxt "Button: Reboot the system"
@@ -105,7 +106,7 @@ msgstr "Atosaigh"
105
106
106#: qml/Components/Dialogs.qml:208
107#: qml/Components/Dialogs.qml:208
107msgid "Are you sure you want to reboot?"
108msgid "Are you sure you want to reboot?"
108−msgstr ""
109+msgstr "Cinnte gur mhaith leat atosú?"
109
110
110#: qml/Components/Dialogs.qml:210
111#: qml/Components/Dialogs.qml:210
111msgid "No"
112msgid "No"
@@ -113,18 +114,18 @@ msgstr "Níl"
113
114
114#: qml/Components/Dialogs.qml:217
115#: qml/Components/Dialogs.qml:217
115msgid "Yes"
116msgid "Yes"
116−msgstr "Tá Go Maith"
117+msgstr "Tá"
117
118
118#: qml/Components/Dialogs.qml:232
119#: qml/Components/Dialogs.qml:232
119msgctxt "Title: Power off/Restart dialog"
120msgctxt "Title: Power off/Restart dialog"
120msgid "Power"
121msgid "Power"
121−msgstr "Cumhacht"
122+msgstr "Múch an chumhacht"
122
123
123#: qml/Components/Dialogs.qml:233
124#: qml/Components/Dialogs.qml:233
124msgid ""
125msgid ""
125"Are you sure you would like\n"
126"Are you sure you would like\n"
126"to power off?"
127"to power off?"
127−msgstr ""
128+msgstr "Cinnte gur mhaith leat an chumhacht a mhúchadh?"
128
129
129#: qml/Components/Dialogs.qml:235
130#: qml/Components/Dialogs.qml:235
130msgctxt "Button: Power off the system"
131msgctxt "Button: Power off the system"
@@ -138,11 +139,11 @@ msgstr "Atosaigh"
138
139
139#: qml/Components/Lockscreen.qml:245
140#: qml/Components/Lockscreen.qml:245
140msgid "Return to Call"
141msgid "Return to Call"
141−msgstr ""
142+msgstr "Fill ar an Ghlaoch"
142
143
143#: qml/Components/Lockscreen.qml:245
144#: qml/Components/Lockscreen.qml:245
144msgid "Emergency Call"
145msgid "Emergency Call"
145−msgstr ""
146+msgstr "Glaoch Éigeandála"
146
147
147#: qml/Components/Lockscreen.qml:277
148#: qml/Components/Lockscreen.qml:277
148msgid "OK"
149msgid "OK"
@@ -150,11 +151,13 @@ msgstr "Tá Go Maith"
150
151
151#: qml/Components/ModeSwitchWarningDialog.qml:32
152#: qml/Components/ModeSwitchWarningDialog.qml:32
152msgid "Apps may have unsaved data:"
153msgid "Apps may have unsaved data:"
153−msgstr ""
154+msgstr "Seans go mbeidh sonraí gan sábháil ag aipeanna:"
154
155
155#: qml/Components/ModeSwitchWarningDialog.qml:57
156#: qml/Components/ModeSwitchWarningDialog.qml:57
156msgid "Re-dock, save your work and close these apps to continue."
157msgid "Re-dock, save your work and close these apps to continue."
157msgstr ""
158msgstr ""
159+"Cuir sa leaba nasctha, sabhail do chuid oibre agus dún na haipeanna seo chun "
160+"leanúínt ar aghaidh."
158
161
159#: qml/Components/ModeSwitchWarningDialog.qml:63
162#: qml/Components/ModeSwitchWarningDialog.qml:63
160msgid "Or force close now (unsaved data will be lost)."
163msgid "Or force close now (unsaved data will be lost)."
@@ -162,11 +165,11 @@ msgstr ""
162
165
163#: qml/Components/ModeSwitchWarningDialog.qml:75
166#: qml/Components/ModeSwitchWarningDialog.qml:75
164msgid "OK, I will reconnect"
167msgid "OK, I will reconnect"
165−msgstr ""
168+msgstr "Go maith, athcheanglóidh mé."
166
169
167#: qml/Components/ModeSwitchWarningDialog.qml:76
170#: qml/Components/ModeSwitchWarningDialog.qml:76
168msgid "Reconnect now!"
171msgid "Reconnect now!"
169−msgstr ""
172+msgstr "Athnasc anois!"
170
173
171#: qml/Components/ModeSwitchWarningDialog.qml:88
174#: qml/Components/ModeSwitchWarningDialog.qml:88
172msgid "Close all"
175msgid "Close all"
@@ -185,7 +188,7 @@ msgstr "Cuardach"
185#: qml/Dash/DashPageHeader.qml:283
188#: qml/Dash/DashPageHeader.qml:283
186msgctxt "Button: Show the current dash scope settings"
189msgctxt "Button: Show the current dash scope settings"
187msgid "Settings"
190msgid "Settings"
188−msgstr ""
191+msgstr "Socruithe"
189
192
190#: qml/Dash/DashPageHeader.qml:290
193#: qml/Dash/DashPageHeader.qml:290
191msgid "Remove from Favorites"
194msgid "Remove from Favorites"
@@ -197,16 +200,16 @@ msgstr "Cuir le Ceanáin"
197
200
198#: qml/Dash/GenericScopeView.qml:576 qml/Dash/GenericScopeView.qml:734
201#: qml/Dash/GenericScopeView.qml:576 qml/Dash/GenericScopeView.qml:734
199msgid "See less"
202msgid "See less"
200−msgstr "Fheiceáil Níos Lú"
203+msgstr "Taispeáin níos lú"
201
204
202#: qml/Dash/GenericScopeView.qml:576
205#: qml/Dash/GenericScopeView.qml:576
203msgid "See all"
206msgid "See all"
204−msgstr ""
207+msgstr "Taispeáin gach rud"
205
208
206#: qml/Dash/GenericScopeView.qml:638
209#: qml/Dash/GenericScopeView.qml:638
207msgctxt "Label: Hint for dash search line edit"
210msgctxt "Label: Hint for dash search line edit"
208msgid "Search"
211msgid "Search"
209−msgstr ""
212+msgstr "Cuardach"
210
213
211#: qml/Dash/Previews/PreviewActionCombo.qml:35
214#: qml/Dash/Previews/PreviewActionCombo.qml:35
212msgid "More..."
215msgid "More..."
@@ -214,7 +217,7 @@ msgstr "Tuilleadh..."
214
217
215#: qml/Dash/Previews/PreviewActionCombo.qml:35
218#: qml/Dash/Previews/PreviewActionCombo.qml:35
216msgid "Less..."
219msgid "Less..."
217−msgstr ""
220+msgstr "Níos lú..."
218
221
219#: qml/Dash/Previews/PreviewCommentInput.qml:68
222#: qml/Dash/Previews/PreviewCommentInput.qml:68
220#: qml/Dash/Previews/PreviewRatingInput.qml:174
223#: qml/Dash/Previews/PreviewRatingInput.qml:174
@@ -223,31 +226,31 @@ msgstr "Seol"
223
226
224#: qml/Dash/Previews/PreviewRatingInput.qml:84
227#: qml/Dash/Previews/PreviewRatingInput.qml:84
225msgid "Rate this"
228msgid "Rate this"
226−msgstr ""
229+msgstr "Grádaigh é seo"
227
230
228#: qml/Dash/Previews/PreviewRatingInput.qml:129
231#: qml/Dash/Previews/PreviewRatingInput.qml:129
229msgid "Add a review"
232msgid "Add a review"
230−msgstr ""
233+msgstr "Cuir léirmheas leis"
231
234
232#: qml/Dash/Previews/PreviewSharing.qml:50
235#: qml/Dash/Previews/PreviewSharing.qml:50
233msgid "Preview Share Item"
236msgid "Preview Share Item"
234−msgstr ""
237+msgstr "Réamhthaispeántas Rud Le Chéile"
235
238
236#: qml/Dash/PullToRefreshScopeStyle.qml:55
239#: qml/Dash/PullToRefreshScopeStyle.qml:55
237msgid "Pull to refresh…"
240msgid "Pull to refresh…"
238−msgstr ""
241+msgstr "Tarraing le hathnuachan..."
239
242
240#: qml/Dash/PullToRefreshScopeStyle.qml:60
243#: qml/Dash/PullToRefreshScopeStyle.qml:60
241msgid "Release to refresh…"
244msgid "Release to refresh…"
242−msgstr ""
245+msgstr "Scaoil le hathnuachan..."
243
246
244#: qml/Dash/ScopeSettings/ScopeSettingBoolean.qml:43
247#: qml/Dash/ScopeSettings/ScopeSettingBoolean.qml:43
245msgid "Enable location data"
248msgid "Enable location data"
246−msgstr ""
249+msgstr "Ceadaigh logshonraí"
247
250
248#: qml/Dash/ScopesList.qml:67
251#: qml/Dash/ScopesList.qml:67
249msgid "Manage"
252msgid "Manage"
250−msgstr ""
253+msgstr "Bainistigh"
251
254
252#: qml/Dash/ScopesList.qml:113
255#: qml/Dash/ScopesList.qml:113
253msgid "Home"
256msgid "Home"
@@ -263,111 +266,118 @@ msgstr ""
263
266
264#: qml/Greeter/CoverPage.qml:107
267#: qml/Greeter/CoverPage.qml:107
265msgid "Unlock"
268msgid "Unlock"
266−msgstr "Díghlasáil"
269+msgstr "Oscail"
267
270
268#: qml/Greeter/LoginList.qml:236
271#: qml/Greeter/LoginList.qml:236
269msgid "Retry"
272msgid "Retry"
270−msgstr ""
273+msgstr "Bain triail as arís"
271
274
272#: qml/Greeter/LoginList.qml:237
275#: qml/Greeter/LoginList.qml:237
273msgid "Tap to unlock"
276msgid "Tap to unlock"
274−msgstr ""
277+msgstr "Cnag le hoscail"
275
278
276#: qml/Greeter/NarrowView.qml:54 qml/Wizard/Pages/passwd-confirm.qml:53
279#: qml/Greeter/NarrowView.qml:54 qml/Wizard/Pages/passwd-confirm.qml:53
277msgid "Sorry, incorrect passphrase."
280msgid "Sorry, incorrect passphrase."
278−msgstr ""
281+msgstr "Pasfhocal míchruinn"
279
282
280#: qml/Greeter/NarrowView.qml:55 qml/Wizard/Pages/passwd-confirm.qml:54
283#: qml/Greeter/NarrowView.qml:55 qml/Wizard/Pages/passwd-confirm.qml:54
281msgid "Sorry, incorrect passcode."
284msgid "Sorry, incorrect passcode."
282−msgstr ""
285+msgstr "Códfhocal míchruinn"
283
286
284#: qml/Greeter/NarrowView.qml:56
287#: qml/Greeter/NarrowView.qml:56
285msgid "This will be your last attempt."
288msgid "This will be your last attempt."
286−msgstr ""
289+msgstr "Iarracht dheireanach."
287
290
288#: qml/Greeter/NarrowView.qml:58
291#: qml/Greeter/NarrowView.qml:58
289msgid ""
292msgid ""
290"If passphrase is entered incorrectly, your phone will conduct a factory "
293"If passphrase is entered incorrectly, your phone will conduct a factory "
291"reset and all personal data will be deleted."
294"reset and all personal data will be deleted."
292msgstr ""
295msgstr ""
296+"Más mbíonn pasfhocal mícheart agat arís, déanann do guthan monarchan "
297+"athshocrú agus beidh do shonraí pearsanta scriosadh."
293
298
294#: qml/Greeter/NarrowView.qml:59
299#: qml/Greeter/NarrowView.qml:59
295msgid ""
300msgid ""
296"If passcode is entered incorrectly, your phone will conduct a factory reset "
301"If passcode is entered incorrectly, your phone will conduct a factory reset "
297"and all personal data will be deleted."
302"and all personal data will be deleted."
298msgstr ""
303msgstr ""
304+"Más mbíonn paschód mícheart agat arís, déanann do guthan monarchan athshocrú "
305+"agus beidh do shonraí pearsanta scriosadh."
299
306
300#: qml/Greeter/NarrowView.qml:116
307#: qml/Greeter/NarrowView.qml:116
301#, qt-format
308#, qt-format
302msgid "Enter %1"
309msgid "Enter %1"
303−msgstr ""
310+msgstr "Cuir isteach %1"
304
311
305#: qml/Greeter/NarrowView.qml:117 qml/Wizard/Pages/passwd-set.qml:60
312#: qml/Greeter/NarrowView.qml:117 qml/Wizard/Pages/passwd-set.qml:60
306msgid "Enter passphrase"
313msgid "Enter passphrase"
307−msgstr ""
314+msgstr "Cuir pasfhrása isteach"
308
315
309#: qml/Greeter/NarrowView.qml:118
316#: qml/Greeter/NarrowView.qml:118
310msgid "Enter passcode"
317msgid "Enter passcode"
311−msgstr ""
318+msgstr "Cuir paschód isteach"
312
319
313#: qml/Greeter/NarrowView.qml:119
320#: qml/Greeter/NarrowView.qml:119
314#, qt-format
321#, qt-format
315msgid "Sorry, incorrect %1"
322msgid "Sorry, incorrect %1"
316−msgstr ""
323+msgstr "Míchruinn, mo léan %1"
317
324
318#: qml/Greeter/NarrowView.qml:120
325#: qml/Greeter/NarrowView.qml:120
319msgid "Sorry, incorrect passphrase"
326msgid "Sorry, incorrect passphrase"
320−msgstr ""
327+msgstr "Códfhrása míchruinn, mo léan."
321
328
322#: qml/Greeter/NarrowView.qml:121
329#: qml/Greeter/NarrowView.qml:121
323msgctxt "passphrase"
330msgctxt "passphrase"
324msgid "Please re-enter"
331msgid "Please re-enter"
325−msgstr ""
332+msgstr "Cuir isteach é arís, le do thoil"
326
333
327#: qml/Greeter/NarrowView.qml:122
334#: qml/Greeter/NarrowView.qml:122
328msgid "Sorry, incorrect passcode"
335msgid "Sorry, incorrect passcode"
329−msgstr ""
336+msgstr "Paschód míchruinn, mo léan"
330
337
331#: qml/Notifications/NotificationMenuItemFactory.qml:129
338#: qml/Notifications/NotificationMenuItemFactory.qml:129
332msgid "Show password"
339msgid "Show password"
333−msgstr ""
340+msgstr "Taispeáin pasfhocal"
334
341
335#: qml/Panel/ActiveCallHint.qml:79
342#: qml/Panel/ActiveCallHint.qml:79
336msgid "Tap to return to call..."
343msgid "Tap to return to call..."
337−msgstr ""
344+msgstr "Tapáil chun filleadh ar an nglaoch..."
338
345
339#: qml/Panel/ActiveCallHint.qml:92
346#: qml/Panel/ActiveCallHint.qml:92
340msgid "Conference"
347msgid "Conference"
341−msgstr ""
348+msgstr "Glaoch comhdhála"
342
349
343#: qml/Panel/Indicators/MenuItemFactory.qml:753
350#: qml/Panel/Indicators/MenuItemFactory.qml:753
344msgid "Nothing is playing"
351msgid "Nothing is playing"
345−msgstr ""
352+msgstr "Tada á chasadh"
346
353
347#: qml/Panel/Indicators/MenuItemFactory.qml:882
354#: qml/Panel/Indicators/MenuItemFactory.qml:882
348#, qt-format
355#, qt-format
349msgid "%1 hour"
356msgid "%1 hour"
350msgid_plural "%1 hours"
357msgid_plural "%1 hours"
351−msgstr[0] ""
358+msgstr[0] "%1 uair"
352−msgstr[1] ""
359+msgstr[1] "%1 uair"
360+msgstr[2] "%1 uair"
353
361
354#: qml/Panel/Indicators/MenuItemFactory.qml:886
362#: qml/Panel/Indicators/MenuItemFactory.qml:886
355#, qt-format
363#, qt-format
356msgid "%1 minute"
364msgid "%1 minute"
357msgid_plural "%1 minutes"
365msgid_plural "%1 minutes"
358−msgstr[0] ""
366+msgstr[0] "%1 nóiméad"
359−msgstr[1] ""
367+msgstr[1] "%1 nóiméad"
368+msgstr[2] "%1 nóiméad"
360
369
361#: qml/Panel/Indicators/MenuItemFactory.qml:891
370#: qml/Panel/Indicators/MenuItemFactory.qml:891
362#, qt-format
371#, qt-format
363msgid "%1 second"
372msgid "%1 second"
364msgid_plural "%1 seconds"
373msgid_plural "%1 seconds"
365−msgstr[0] ""
374+msgstr[0] "%1 soicind"
366−msgstr[1] ""
375+msgstr[1] "%1 soicind"
376+msgstr[2] "%1 soicind"
367
377
368#: qml/Panel/Indicators/MenuItemFactory.qml:894
378#: qml/Panel/Indicators/MenuItemFactory.qml:894
369msgid "0 seconds"
379msgid "0 seconds"
370−msgstr ""
380+msgstr "%1 soicind"
371
381
372#. Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
382#. Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
373#: qml/Panel/Indicators/MenuItemFactory.qml:896
383#: qml/Panel/Indicators/MenuItemFactory.qml:896
@@ -377,206 +387,206 @@ msgstr ""
377
387
378#: qml/Panel/Indicators/MenuItemFactory.qml:902
388#: qml/Panel/Indicators/MenuItemFactory.qml:902
379msgid "In queue…"
389msgid "In queue…"
380−msgstr ""
390+msgstr "Ag fanacht a scuaine..."
381
391
382#: qml/Panel/Indicators/MenuItemFactory.qml:906
392#: qml/Panel/Indicators/MenuItemFactory.qml:906
383msgid "Downloading"
393msgid "Downloading"
384−msgstr ""
394+msgstr "Íoslódáil"
385
395
386#: qml/Panel/Indicators/MenuItemFactory.qml:908
396#: qml/Panel/Indicators/MenuItemFactory.qml:908
387msgid "Paused, tap to resume"
397msgid "Paused, tap to resume"
388−msgstr ""
398+msgstr "Sos, tapáill chun leanúint ar aghaidhdh"
389
399
390#: qml/Panel/Indicators/MenuItemFactory.qml:910
400#: qml/Panel/Indicators/MenuItemFactory.qml:910
391msgid "Canceled"
401msgid "Canceled"
392−msgstr ""
402+msgstr "Curtha Ar Ceal"
393
403
394#: qml/Panel/Indicators/MenuItemFactory.qml:912
404#: qml/Panel/Indicators/MenuItemFactory.qml:912
395msgid "Finished"
405msgid "Finished"
396−msgstr ""
406+msgstr "Críochnaithe"
397
407
398#: qml/Panel/Indicators/MenuItemFactory.qml:914
408#: qml/Panel/Indicators/MenuItemFactory.qml:914
399msgid "Failed, tap to retry"
409msgid "Failed, tap to retry"
400−msgstr ""
410+msgstr "Tá teipthe ort, tapáil chun triail eile a bhaint as"
401
411
402#: qml/Panel/Indicators/MessageMenuItemFactory.qml:155
412#: qml/Panel/Indicators/MessageMenuItemFactory.qml:155
403#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
413#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
404msgctxt "Button: Send a reply message"
414msgctxt "Button: Send a reply message"
405msgid "Send"
415msgid "Send"
406−msgstr ""
416+msgstr "Seol"
407
417
408#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
418#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
409msgctxt "Label: Hint in message indicator line edit"
419msgctxt "Label: Hint in message indicator line edit"
410msgid "Reply"
420msgid "Reply"
411−msgstr ""
421+msgstr "Freagra"
412
422
413#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
423#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
414msgctxt "Button: Call back on phone"
424msgctxt "Button: Call back on phone"
415msgid "Call back"
425msgid "Call back"
416−msgstr ""
426+msgstr "Glaoch Ar Ais"
417
427
418#: qml/Panel/Indicators/ModemInfoItem.qml:105
428#: qml/Panel/Indicators/ModemInfoItem.qml:105
419msgid "Unlock SIM"
429msgid "Unlock SIM"
420−msgstr ""
430+msgstr "Díghlasail an SIM"
421
431
422#: qml/Panel/Indicators/RoamingIndication.qml:27
432#: qml/Panel/Indicators/RoamingIndication.qml:27
423msgid "Roaming"
433msgid "Roaming"
424−msgstr ""
434+msgstr "Fánaíocht"
425
435
426#: qml/Tutorial/TutorialBottom.qml:28
436#: qml/Tutorial/TutorialBottom.qml:28
427msgid "Open special menus"
437msgid "Open special menus"
428−msgstr ""
438+msgstr "Oscail Roghchláir Speisialta"
429
439
430#: qml/Tutorial/TutorialBottom.qml:29
440#: qml/Tutorial/TutorialBottom.qml:29
431msgid "Swipe up from the bottom edge."
441msgid "Swipe up from the bottom edge."
432−msgstr ""
442+msgstr "Cuimil anuas ón bhunlíne."
433
443
434#: qml/Tutorial/TutorialBottomFinish.qml:24
444#: qml/Tutorial/TutorialBottomFinish.qml:24
435msgid "This action does different things for different apps"
445msgid "This action does different things for different apps"
436−msgstr ""
446+msgstr "Baineann feidhm ar leith leis seo i dtaca le haipeanna éagsúla"
437
447
438#: qml/Tutorial/TutorialBottomFinish.qml:25
448#: qml/Tutorial/TutorialBottomFinish.qml:25
439msgid "Tap here to finish."
449msgid "Tap here to finish."
440−msgstr ""
450+msgstr "Tapáil anseo chun críochnú."
441
451
442#: qml/Tutorial/TutorialContent.qml:80 qml/Tutorial/TutorialLeftFinish.qml:25
452#: qml/Tutorial/TutorialContent.qml:80 qml/Tutorial/TutorialLeftFinish.qml:25
443#: qml/Tutorial/TutorialRight.qml:144
453#: qml/Tutorial/TutorialRight.qml:144
444msgid "Tap here to continue."
454msgid "Tap here to continue."
445−msgstr ""
455+msgstr "Tapáil anseo chun leanúint ar aghaidh."
446
456
447#: qml/Tutorial/TutorialLeft.qml:26
457#: qml/Tutorial/TutorialLeft.qml:26
448msgid "Open the launcher"
458msgid "Open the launcher"
449−msgstr ""
459+msgstr "Oscail an lainseálaí"
450
460
451#: qml/Tutorial/TutorialLeft.qml:27
461#: qml/Tutorial/TutorialLeft.qml:27
452msgid "Short swipe from the left edge."
462msgid "Short swipe from the left edge."
453−msgstr ""
463+msgstr "Cuimil ghearr ón taobh clé."
454
464
455#: qml/Tutorial/TutorialLeftFinish.qml:24
465#: qml/Tutorial/TutorialLeftFinish.qml:24
456msgid "These are the shortcuts to favorite apps"
466msgid "These are the shortcuts to favorite apps"
457−msgstr ""
467+msgstr "Is iad seo na haicearrái i gcomhair na n-aipeanna is fearr leat"
458
468
459#: qml/Tutorial/TutorialPage.qml:178
469#: qml/Tutorial/TutorialPage.qml:178
460msgid "You almost got it!"
470msgid "You almost got it!"
461−msgstr ""
471+msgstr "D'éirigh leat beagnach!"
462
472
463#: qml/Tutorial/TutorialPage.qml:195
473#: qml/Tutorial/TutorialPage.qml:195
464msgid "Try again."
474msgid "Try again."
465−msgstr ""
475+msgstr "Bain triail as arís."
466
476
467#: qml/Tutorial/TutorialRight.qml:31
477#: qml/Tutorial/TutorialRight.qml:31
468msgid "To view open apps"
478msgid "To view open apps"
469−msgstr ""
479+msgstr "Chun féachaint oscail aipeanna"
470
480
471#: qml/Tutorial/TutorialRight.qml:32
481#: qml/Tutorial/TutorialRight.qml:32
472msgid "Long swipe from the right edge."
482msgid "Long swipe from the right edge."
473−msgstr ""
483+msgstr "Cuimil fhada ó taobh clé."
474
484
475#: qml/Tutorial/TutorialRight.qml:122
485#: qml/Tutorial/TutorialRight.qml:122
476msgid "View all your running tasks."
486msgid "View all your running tasks."
477−msgstr ""
487+msgstr "Féach ar do thascanna reatha."
478
488
479#: qml/Wizard/Page.qml:89
489#: qml/Wizard/Page.qml:89
480msgctxt "Button: Go back one page in the Wizard"
490msgctxt "Button: Go back one page in the Wizard"
481msgid "Back"
491msgid "Back"
482−msgstr ""
492+msgstr "Ar ais"
483
493
484#: qml/Wizard/Pages/10-welcome.qml:27
494#: qml/Wizard/Pages/10-welcome.qml:27
485msgid "Hi!"
495msgid "Hi!"
486−msgstr ""
496+msgstr "Dia duit!"
487
497
488#: qml/Wizard/Pages/10-welcome.qml:44
498#: qml/Wizard/Pages/10-welcome.qml:44
489msgid "Welcome to your Ubuntu phone."
499msgid "Welcome to your Ubuntu phone."
490−msgstr ""
500+msgstr "Tá fáilte romhat chuig do fhón Ubuntu."
491
501
492#: qml/Wizard/Pages/10-welcome.qml:52
502#: qml/Wizard/Pages/10-welcome.qml:52
493msgid "Let’s get started."
503msgid "Let’s get started."
494−msgstr ""
504+msgstr "Tosaímis"
495
505
496#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:133
506#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:133
497#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
507#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
498#: qml/Wizard/Pages/60-reporting.qml:60 qml/Wizard/Pages/passwd-confirm.qml:82
508#: qml/Wizard/Pages/60-reporting.qml:60 qml/Wizard/Pages/passwd-confirm.qml:82
499#: qml/Wizard/Pages/passwd-set.qml:90
509#: qml/Wizard/Pages/passwd-set.qml:90
500msgid "Continue"
510msgid "Continue"
501−msgstr ""
511+msgstr "Ar aghaidh leat (go dtí an chéad lch eile)"
502
512
503#: qml/Wizard/Pages/20-sim.qml:25
513#: qml/Wizard/Pages/20-sim.qml:25
504msgid "Add a SIM card and restart your device"
514msgid "Add a SIM card and restart your device"
505−msgstr ""
515+msgstr "Cuir cárta SIM isteach agus atosaigh an fearas"
506
516
507#: qml/Wizard/Pages/20-sim.qml:59
517#: qml/Wizard/Pages/20-sim.qml:59
508msgid "Without it, you won’t be able to make calls or use text messaging."
518msgid "Without it, you won’t be able to make calls or use text messaging."
509−msgstr ""
519+msgstr "Gan é, ní bheifeá ábalta glaoch a dhéanamh nó téasc a sheoladh."
510
520
511#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
521#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
512msgid "Skip"
522msgid "Skip"
513−msgstr ""
523+msgstr "Scipeáil"
514
524
515#: qml/Wizard/Pages/30-passwd-type.qml:39
525#: qml/Wizard/Pages/30-passwd-type.qml:39
516msgid "Lock security"
526msgid "Lock security"
517−msgstr ""
527+msgstr "Slándáil ghlasála"
518
528
519#: qml/Wizard/Pages/30-passwd-type.qml:79
529#: qml/Wizard/Pages/30-passwd-type.qml:79
520msgid "Please select how you’d like to unlock your phone."
530msgid "Please select how you’d like to unlock your phone."
521−msgstr ""
531+msgstr "Roghnaigh conas ar mhaith leat do fhón a díghlasáil"
522
532
523#: qml/Wizard/Pages/30-passwd-type.qml:102
533#: qml/Wizard/Pages/30-passwd-type.qml:102
524msgctxt "Label: Type of security method"
534msgctxt "Label: Type of security method"
525msgid "Swipe"
535msgid "Swipe"
526−msgstr ""
536+msgstr "Cuimil"
527
537
528#: qml/Wizard/Pages/30-passwd-type.qml:103
538#: qml/Wizard/Pages/30-passwd-type.qml:103
529msgctxt "Label: Description of security method"
539msgctxt "Label: Description of security method"
530msgid "No security"
540msgid "No security"
531−msgstr ""
541+msgstr "Gan slándáil"
532
542
533#: qml/Wizard/Pages/30-passwd-type.qml:105
543#: qml/Wizard/Pages/30-passwd-type.qml:105
534msgctxt "Label: Type of security method"
544msgctxt "Label: Type of security method"
535msgid "Passcode"
545msgid "Passcode"
536−msgstr ""
546+msgstr "Paschód"
537
547
538#: qml/Wizard/Pages/30-passwd-type.qml:106
548#: qml/Wizard/Pages/30-passwd-type.qml:106
539msgctxt "Label: Description of security method"
549msgctxt "Label: Description of security method"
540msgid "4 digits only"
550msgid "4 digits only"
541−msgstr ""
551+msgstr "Ceithre dhigit amháin"
542
552
543#: qml/Wizard/Pages/30-passwd-type.qml:108
553#: qml/Wizard/Pages/30-passwd-type.qml:108
544msgctxt "Label: Type of security method"
554msgctxt "Label: Type of security method"
545msgid "Passphrase"
555msgid "Passphrase"
546−msgstr ""
556+msgstr "Pasfhrása"
547
557
548#: qml/Wizard/Pages/30-passwd-type.qml:109
558#: qml/Wizard/Pages/30-passwd-type.qml:109
549msgctxt "Label: Description of security method"
559msgctxt "Label: Description of security method"
550msgid "Numbers and letters"
560msgid "Numbers and letters"
551−msgstr ""
561+msgstr "Litreacha agus uimhreacha"
552
562
553#: qml/Wizard/Pages/40-wifi.qml:29
563#: qml/Wizard/Pages/40-wifi.qml:29
554msgid "Connect to Wi‑Fi"
564msgid "Connect to Wi‑Fi"
555−msgstr ""
565+msgstr "Ceangail le Wi-Fi"
556
566
557#: qml/Wizard/Pages/40-wifi.qml:168
567#: qml/Wizard/Pages/40-wifi.qml:168
558msgid "Available networks…"
568msgid "Available networks…"
559−msgstr ""
569+msgstr "Gréasáin ar fáil..."
560
570
561#: qml/Wizard/Pages/40-wifi.qml:169
571#: qml/Wizard/Pages/40-wifi.qml:169
562msgid "No available networks."
572msgid "No available networks."
563−msgstr ""
573+msgstr "Níl aon ghréasáin ar fáil."
564
574
565#: qml/Wizard/Pages/50-location.qml:27
575#: qml/Wizard/Pages/50-location.qml:27
566msgid "Location"
576msgid "Location"
567−msgstr ""
577+msgstr "Suíomh reatha"
568
578
569#: qml/Wizard/Pages/50-location.qml:62
579#: qml/Wizard/Pages/50-location.qml:62
570msgid "Let the phone detect your location:"
580msgid "Let the phone detect your location:"
571−msgstr ""
581+msgstr "Lig an fón do shuíomh reatha a aimsiú:"
572
582
573#: qml/Wizard/Pages/50-location.qml:69
583#: qml/Wizard/Pages/50-location.qml:69
574msgid "Using GPS only (less accurate)"
584msgid "Using GPS only (less accurate)"
575−msgstr ""
585+msgstr "Úsáid GPS amháín (easpa cruinnis)"
576
586
577#: qml/Wizard/Pages/50-location.qml:86
587#: qml/Wizard/Pages/50-location.qml:86
578msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
588msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
579−msgstr ""
589+msgstr "Úsáid GPS, gan ainm WIFI agus líonra ceallach eolas (moltar)"
580
590
581#. Translators: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
591#. Translators: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
582#: qml/Wizard/Pages/50-location.qml:103
592#: qml/Wizard/Pages/50-location.qml:103
@@ -584,67 +594,73 @@ msgid ""
584"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
594"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
585"conditions</a>."
595"conditions</a>."
586msgstr ""
596msgstr ""
597+"Má ghlacann tú leis an rogha seo glacann tú leis na <a href='#'>téarmaí agus "
598+"coinníollacha</a> a bhaineann le Nokia HERE."
587
599
588#: qml/Wizard/Pages/50-location.qml:112
600#: qml/Wizard/Pages/50-location.qml:112
589msgid "Not at all"
601msgid "Not at all"
590−msgstr ""
602+msgstr "In aon chor"
591
603
592#: qml/Wizard/Pages/50-location.qml:124
604#: qml/Wizard/Pages/50-location.qml:124
593msgid "You can change your mind later in <b>System Settings</b>."
605msgid "You can change your mind later in <b>System Settings</b>."
594−msgstr ""
606+msgstr "Is féidir do chinneadh a athrú níos déanaí sna <b>Socruithe Córais</b>"
595
607
596#: qml/Wizard/Pages/60-reporting.qml:26
608#: qml/Wizard/Pages/60-reporting.qml:26
597msgid "Improving your experience"
609msgid "Improving your experience"
598−msgstr ""
610+msgstr "Ag cur le do thaitneamh agus leis an tairbhe"
599
611
600#: qml/Wizard/Pages/60-reporting.qml:46
612#: qml/Wizard/Pages/60-reporting.qml:46
601msgid ""
613msgid ""
602"Your phone is set up to automatically report errors to Canonical and its "
614"Your phone is set up to automatically report errors to Canonical and its "
603"partners, the makers of the operating system."
615"partners, the makers of the operating system."
604msgstr ""
616msgstr ""
617+"Cuireann do fhón earráidí in iúl go huathoibríoch do Chanonical agus a "
618+"chomhpháirithe, lucht déanta an chórais oibre."
605
619
606#: qml/Wizard/Pages/60-reporting.qml:53
620#: qml/Wizard/Pages/60-reporting.qml:53
607msgid ""
621msgid ""
608"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
622"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
609"Privacy</b>"
623"Privacy</b>"
610msgstr ""
624msgstr ""
625+"Is féidir é seo a mhúchadh sna Socruithe Córais faoi Shlándáil agus "
626+"Príobháideachas"
611
627
612#: qml/Wizard/Pages/80-finished.qml:24
628#: qml/Wizard/Pages/80-finished.qml:24
613msgid "All done"
629msgid "All done"
614−msgstr ""
630+msgstr "Déanta"
615
631
616#: qml/Wizard/Pages/80-finished.qml:39
632#: qml/Wizard/Pages/80-finished.qml:39
617msgid "Nice work!"
633msgid "Nice work!"
618−msgstr ""
634+msgstr "D'éirigh leat!"
619
635
620#: qml/Wizard/Pages/80-finished.qml:46
636#: qml/Wizard/Pages/80-finished.qml:46
621msgid "Your phone is now ready to use."
637msgid "Your phone is now ready to use."
622−msgstr ""
638+msgstr "Tá do fhón reidh le húsáid anois."
623
639
624#: qml/Wizard/Pages/80-finished.qml:53
640#: qml/Wizard/Pages/80-finished.qml:53
625msgid "Finish"
641msgid "Finish"
626−msgstr ""
642+msgstr "Críoch"
627
643
628#: qml/Wizard/Pages/here-terms.qml:27
644#: qml/Wizard/Pages/here-terms.qml:27
629msgid "Terms & Conditions"
645msgid "Terms & Conditions"
630−msgstr ""
646+msgstr "Téarmaí agus Coinníollacha"
631
647
632#: qml/Wizard/Pages/passwd-confirm.qml:49
648#: qml/Wizard/Pages/passwd-confirm.qml:49
633msgid "Confirm passphrase"
649msgid "Confirm passphrase"
634−msgstr ""
650+msgstr "Deimhnigh pasfhrása"
635
651
636#: qml/Wizard/Pages/passwd-confirm.qml:50
652#: qml/Wizard/Pages/passwd-confirm.qml:50
637msgid "Confirm passcode"
653msgid "Confirm passcode"
638−msgstr ""
654+msgstr "Deimhnigh paschód"
639
655
640#: qml/Wizard/Pages/passwd-confirm.qml:53
656#: qml/Wizard/Pages/passwd-confirm.qml:53
641#: qml/Wizard/Pages/passwd-confirm.qml:54
657#: qml/Wizard/Pages/passwd-confirm.qml:54
642msgid "Please try again."
658msgid "Please try again."
643−msgstr ""
659+msgstr "Bain trial as arís."
644
660
645#: qml/Wizard/Pages/passwd-set.qml:61
661#: qml/Wizard/Pages/passwd-set.qml:61
646msgid "Choose your passcode"
662msgid "Choose your passcode"
647−msgstr ""
663+msgstr "Roghnaigh do phaschód"
648
664
649#: qml/Wizard/Pages/passwd-set.qml:68
665#: qml/Wizard/Pages/passwd-set.qml:68
650msgid "Passphrase must be 4 characters long"
666msgid "Passphrase must be 4 characters long"
po/gd.po+20−2
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : "
18"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : "
19"(n > 2 && n < 20) ? 2 : 3;\n"
19"(n > 2 && n < 20) ? 2 : 3;\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
@@ -698,6 +698,24 @@ msgstr "〈 %1"
698msgid "%1 〉"
698msgid "%1 〉"
699msgstr "%1 〉"
699msgstr "%1 〉"
700
700
701+#~ msgid ""
702+#~ "Your device is now connected to an external display. Use this screen as a "
703+#~ "touch pad to interact with the mouse."
704+#~ msgstr ""
705+#~ "Tha an t-uidheam agad air a cheangal ri uidheam-taisbeanaidh air an taobh "
706+#~ "a-muigh a-nis. Cleachd an sgrìn seo 'na phada-suathaidh gus gnìomh "
707+#~ "luchaige a dhèanamh."
708+
709+#~ msgid "Welcome to your Ubuntu device."
710+#~ msgstr "Fàilte dhan uidheam Ubuntu agad."
711+
712+#~ msgid "Please select how you’d like to unlock your device."
713+#~ msgstr ""
714+#~ "Tagh an dòigh sa tha thu airson a' ghlas a thoirt far an uidheam agad."
715+
716+#~ msgid "Your device is now ready to use."
717+#~ msgstr "Tha an t-uidheam agad ullamh a-nis."
718+
701#~ msgid "Skip intro"
719#~ msgid "Skip intro"
702#~ msgstr "Gearr leum thairis air an ro-ràdh"
720#~ msgstr "Gearr leum thairis air an ro-ràdh"
703
721
po/gl.po+18−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-16 05:38+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -674,6 +674,22 @@ msgstr "〈 %1"
674msgid "%1 〉"
674msgid "%1 〉"
675msgstr "%1 〉"
675msgstr "%1 〉"
676
676
677+#~ msgid ""
678+#~ "Your device is now connected to an external display. Use this screen as a "
679+#~ "touch pad to interact with the mouse."
680+#~ msgstr ""
681+#~ "O dispositivo está agora conectado a unha pantalla externa. Use esta "
682+#~ "pantalla como área táctil para interactuar co rato."
683+
684+#~ msgid "Welcome to your Ubuntu device."
685+#~ msgstr "Benvido/a ao seu dispositivo Ubuntu."
686+
687+#~ msgid "Please select how you’d like to unlock your device."
688+#~ msgstr "Seleccione o xeito de desbloquear o dispositivo."
689+
690+#~ msgid "Your device is now ready to use."
691+#~ msgstr "O dispositivo xa está listo para o seu uso."
692+
677#~ msgid "Confirm"
693#~ msgid "Confirm"
678#~ msgstr "Confirmar"
694#~ msgstr "Confirmar"
679
695
po/gv.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : (n == 2 ? 1 : 2);\n"
18"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : (n == 2 ? 1 : 2);\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/he.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/hi.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/hr.po+19−2
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
18"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
@@ -159,6 +159,7 @@ msgstr "Aplikacija možda ima nespremljene podatke:"
159#: qml/Components/ModeSwitchWarningDialog.qml:57
159#: qml/Components/ModeSwitchWarningDialog.qml:57
160msgid "Re-dock, save your work and close these apps to continue."
160msgid "Re-dock, save your work and close these apps to continue."
161msgstr ""
161msgstr ""
162+"Za nastavak ponovno povežite, spremite svoj rad i zatvorite te aplikacije."
162
163
163#: qml/Components/ModeSwitchWarningDialog.qml:63
164#: qml/Components/ModeSwitchWarningDialog.qml:63
164msgid "Or force close now (unsaved data will be lost)."
165msgid "Or force close now (unsaved data will be lost)."
@@ -680,6 +681,22 @@ msgstr "〈 %1"
680msgid "%1 〉"
681msgid "%1 〉"
681msgstr "%1 〉"
682msgstr "%1 〉"
682
683
684+#~ msgid ""
685+#~ "Your device is now connected to an external display. Use this screen as a "
686+#~ "touch pad to interact with the mouse."
687+#~ msgstr ""
688+#~ "Vaš uređaj je sada povezan s vanjskim zaslonom. Koristite ovaj uređaj kao "
689+#~ "touchpad za interakciju s mišem."
690+
691+#~ msgid "Welcome to your Ubuntu device."
692+#~ msgstr "Dobrodošli u svoj Ubuntu uređaj."
693+
694+#~ msgid "Please select how you’d like to unlock your device."
695+#~ msgstr "Odaberite kako želite otključavati svoj uređaj."
696+
697+#~ msgid "Your device is now ready to use."
698+#~ msgstr "Vaš uređaj je sada spreman za upotrebu."
699+
683#~ msgid "Confirm"
700#~ msgid "Confirm"
684#~ msgstr "Potvrdi"
701#~ msgstr "Potvrdi"
685
702
po/hu.po+19−3
@@ -8,7 +8,7 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: \n"
9"Report-Msgid-Bugs-To: \n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
11−"PO-Revision-Date: 2015-12-30 09:49+0000\n"
11+"PO-Revision-Date: 2016-02-16 07:23+0000\n"
12"Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
12"Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
14"Language: hu\n"
14"Language: hu\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -678,6 +678,22 @@ msgstr "〈 %1"
678msgid "%1 〉"
678msgid "%1 〉"
679msgstr "%1 〉"
679msgstr "%1 〉"
680
680
681+#~ msgid ""
682+#~ "Your device is now connected to an external display. Use this screen as a "
683+#~ "touch pad to interact with the mouse."
684+#~ msgstr ""
685+#~ "Egy külső kijelzőhöz csatlakoztatta a készülékét. A telefon kijelzőjén "
686+#~ "tett ujjmozdulatokkal mozgathatja az egeret."
687+
688+#~ msgid "Welcome to your Ubuntu device."
689+#~ msgstr "Köszönti az Ubuntus eszköze."
690+
691+#~ msgid "Please select how you’d like to unlock your device."
692+#~ msgstr "Válassza ki, hogy milyen módon szeretné feloldani az eszközét."
693+
694+#~ msgid "Your device is now ready to use."
695+#~ msgstr "Az eszköze készen áll a használatra."
696+
681#~ msgid "Confirm"
697#~ msgid "Confirm"
682#~ msgstr "Megerősítés"
698#~ msgstr "Megerősítés"
683
699
po/hy.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/ia.po+12−12
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -30,7 +30,7 @@ msgstr "Via-breve a pin"
30
30
31#: plugins/Unity/Launcher/launcheritem.cpp:52
31#: plugins/Unity/Launcher/launcheritem.cpp:52
32msgid "Quit"
32msgid "Quit"
33−msgstr ""
33+msgstr "Quitar"
34
34
35#: plugins/Unity/Launcher/launcheritem.cpp:106
35#: plugins/Unity/Launcher/launcheritem.cpp:106
36msgid "Unpin shortcut"
36msgid "Unpin shortcut"
@@ -154,27 +154,27 @@ msgstr "OK"
154
154
155#: qml/Components/ModeSwitchWarningDialog.qml:32
155#: qml/Components/ModeSwitchWarningDialog.qml:32
156msgid "Apps may have unsaved data:"
156msgid "Apps may have unsaved data:"
157−msgstr ""
157+msgstr "Le applicationes pote haber datos non salvate:"
158
158
159#: qml/Components/ModeSwitchWarningDialog.qml:57
159#: qml/Components/ModeSwitchWarningDialog.qml:57
160msgid "Re-dock, save your work and close these apps to continue."
160msgid "Re-dock, save your work and close these apps to continue."
161−msgstr ""
161+msgstr "Re-connecte, salva tu labor e claude iste applicationes pro continuar."
162
162
163#: qml/Components/ModeSwitchWarningDialog.qml:63
163#: qml/Components/ModeSwitchWarningDialog.qml:63
164msgid "Or force close now (unsaved data will be lost)."
164msgid "Or force close now (unsaved data will be lost)."
165−msgstr ""
165+msgstr "O fortia clauder nunc (le datos non salveguardate essera perdite)."
166
166
167#: qml/Components/ModeSwitchWarningDialog.qml:75
167#: qml/Components/ModeSwitchWarningDialog.qml:75
168msgid "OK, I will reconnect"
168msgid "OK, I will reconnect"
169−msgstr ""
169+msgstr "OK, io va reconnecter"
170
170
171#: qml/Components/ModeSwitchWarningDialog.qml:76
171#: qml/Components/ModeSwitchWarningDialog.qml:76
172msgid "Reconnect now!"
172msgid "Reconnect now!"
173−msgstr ""
173+msgstr "Reconnecter nunc!"
174
174
175#: qml/Components/ModeSwitchWarningDialog.qml:88
175#: qml/Components/ModeSwitchWarningDialog.qml:88
176msgid "Close all"
176msgid "Close all"
177−msgstr ""
177+msgstr "Clauder toto"
178
178
179#: qml/Dash/DashPageHeader.qml:266
179#: qml/Dash/DashPageHeader.qml:266
180msgctxt "Button: Open the Ubuntu Store"
180msgctxt "Button: Open the Ubuntu Store"
@@ -235,7 +235,7 @@ msgstr "Adder un revision"
235
235
236#: qml/Dash/Previews/PreviewSharing.qml:50
236#: qml/Dash/Previews/PreviewSharing.qml:50
237msgid "Preview Share Item"
237msgid "Preview Share Item"
238−msgstr ""
238+msgstr "Elemento compartite de vista preliminar"
239
239
240#: qml/Dash/PullToRefreshScopeStyle.qml:55
240#: qml/Dash/PullToRefreshScopeStyle.qml:55
241msgid "Pull to refresh…"
241msgid "Pull to refresh…"
@@ -411,7 +411,7 @@ msgstr "Fallite, colpar pro re-provar"
411#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
411#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
412msgctxt "Button: Send a reply message"
412msgctxt "Button: Send a reply message"
413msgid "Send"
413msgid "Send"
414−msgstr ""
414+msgstr "Inviar"
415
415
416#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
416#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
417msgctxt "Label: Hint in message indicator line edit"
417msgctxt "Label: Hint in message indicator line edit"
@@ -421,7 +421,7 @@ msgstr "Responde"
421#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
421#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
422msgctxt "Button: Call back on phone"
422msgctxt "Button: Call back on phone"
423msgid "Call back"
423msgid "Call back"
424−msgstr ""
424+msgstr "Appellar retro"
425
425
426#: qml/Panel/Indicators/ModemInfoItem.qml:105
426#: qml/Panel/Indicators/ModemInfoItem.qml:105
427msgid "Unlock SIM"
427msgid "Unlock SIM"
po/id.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/is.po+2−2
@@ -18,8 +18,8 @@ msgstr ""
18"Content-Type: text/plain; charset=UTF-8\n"
18"Content-Type: text/plain; charset=UTF-8\n"
19"Content-Transfer-Encoding: 8bit\n"
19"Content-Transfer-Encoding: 8bit\n"
20"Plural-Forms: nplurals=2; plural=n != 1;\n"
20"Plural-Forms: nplurals=2; plural=n != 1;\n"
21−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
21+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
22−"X-Generator: Launchpad (build 17886)\n"
22+"X-Generator: Launchpad (build 17925)\n"
23
23
24#: plugins/IntegratedLightDM/Greeter.cpp:112
24#: plugins/IntegratedLightDM/Greeter.cpp:112
25msgid "Password: "
25msgid "Password: "
po/it.po+12−10
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -156,27 +156,29 @@ msgstr "OK"
156
156
157#: qml/Components/ModeSwitchWarningDialog.qml:32
157#: qml/Components/ModeSwitchWarningDialog.qml:32
158msgid "Apps may have unsaved data:"
158msgid "Apps may have unsaved data:"
159−msgstr ""
159+msgstr "Le app potrebbero contenere dati non salvati:"
160
160
161#: qml/Components/ModeSwitchWarningDialog.qml:57
161#: qml/Components/ModeSwitchWarningDialog.qml:57
162msgid "Re-dock, save your work and close these apps to continue."
162msgid "Re-dock, save your work and close these apps to continue."
163msgstr ""
163msgstr ""
164+"Collegare nuovamente il dispositivo, salvare il lavoro e chiudere queste app "
165+"per continuare."
164
166
165#: qml/Components/ModeSwitchWarningDialog.qml:63
167#: qml/Components/ModeSwitchWarningDialog.qml:63
166msgid "Or force close now (unsaved data will be lost)."
168msgid "Or force close now (unsaved data will be lost)."
167−msgstr ""
169+msgstr "Oppure forzare la chiusura ora (i dati non salvati verranno persi)."
168
170
169#: qml/Components/ModeSwitchWarningDialog.qml:75
171#: qml/Components/ModeSwitchWarningDialog.qml:75
170msgid "OK, I will reconnect"
172msgid "OK, I will reconnect"
171−msgstr ""
173+msgstr "Ok, collegherò il dispositivo"
172
174
173#: qml/Components/ModeSwitchWarningDialog.qml:76
175#: qml/Components/ModeSwitchWarningDialog.qml:76
174msgid "Reconnect now!"
176msgid "Reconnect now!"
175−msgstr ""
177+msgstr "Collegare ora."
176
178
177#: qml/Components/ModeSwitchWarningDialog.qml:88
179#: qml/Components/ModeSwitchWarningDialog.qml:88
178msgid "Close all"
180msgid "Close all"
179−msgstr ""
181+msgstr "Chiudi tutto"
180
182
181#: qml/Dash/DashPageHeader.qml:266
183#: qml/Dash/DashPageHeader.qml:266
182msgctxt "Button: Open the Ubuntu Store"
184msgctxt "Button: Open the Ubuntu Store"
@@ -237,7 +239,7 @@ msgstr "Aggiungi una recensione"
237
239
238#: qml/Dash/Previews/PreviewSharing.qml:50
240#: qml/Dash/Previews/PreviewSharing.qml:50
239msgid "Preview Share Item"
241msgid "Preview Share Item"
240−msgstr ""
242+msgstr "Anteprima elementi da condividere"
241
243
242#: qml/Dash/PullToRefreshScopeStyle.qml:55
244#: qml/Dash/PullToRefreshScopeStyle.qml:55
243msgid "Pull to refresh…"
245msgid "Pull to refresh…"
@@ -413,7 +415,7 @@ msgstr "Non riuscito. Tocca per riprovare"
413#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
415#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
414msgctxt "Button: Send a reply message"
416msgctxt "Button: Send a reply message"
415msgid "Send"
417msgid "Send"
416−msgstr ""
418+msgstr "Invia"
417
419
418#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
420#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
419msgctxt "Label: Hint in message indicator line edit"
421msgctxt "Label: Hint in message indicator line edit"
@@ -423,7 +425,7 @@ msgstr "Rispondi"
423#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
425#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
424msgctxt "Button: Call back on phone"
426msgctxt "Button: Call back on phone"
425msgid "Call back"
427msgid "Call back"
426−msgstr ""
428+msgstr "Richiama"
427
429
428#: qml/Panel/Indicators/ModemInfoItem.qml:105
430#: qml/Panel/Indicators/ModemInfoItem.qml:105
429msgid "Unlock SIM"
431msgid "Unlock SIM"
po/ja.po+10−10
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -30,7 +30,7 @@ msgstr "ショートカットを追加する"
30
30
31#: plugins/Unity/Launcher/launcheritem.cpp:52
31#: plugins/Unity/Launcher/launcheritem.cpp:52
32msgid "Quit"
32msgid "Quit"
33−msgstr ""
33+msgstr "終了"
34
34
35#: plugins/Unity/Launcher/launcheritem.cpp:106
35#: plugins/Unity/Launcher/launcheritem.cpp:106
36msgid "Unpin shortcut"
36msgid "Unpin shortcut"
@@ -57,7 +57,7 @@ msgstr[0] "%1 分待ってからやり直してください…"
57#: qml/Components/Dialogs.qml:144
57#: qml/Components/Dialogs.qml:144
58msgctxt "Title: Lock/Log out dialog"
58msgctxt "Title: Lock/Log out dialog"
59msgid "Log out"
59msgid "Log out"
60−msgstr ""
60+msgstr "ログアウト"
61
61
62#: qml/Components/Dialogs.qml:145
62#: qml/Components/Dialogs.qml:145
63msgid "Are you sure you want to log out?"
63msgid "Are you sure you want to log out?"
@@ -66,12 +66,12 @@ msgstr "本当にログアウトしますか?"
66#: qml/Components/Dialogs.qml:147
66#: qml/Components/Dialogs.qml:147
67msgctxt "Button: Lock the system"
67msgctxt "Button: Lock the system"
68msgid "Lock"
68msgid "Lock"
69−msgstr ""
69+msgstr "ロック"
70
70
71#: qml/Components/Dialogs.qml:154
71#: qml/Components/Dialogs.qml:154
72msgctxt "Button: Log out from the system"
72msgctxt "Button: Log out from the system"
73msgid "Log Out"
73msgid "Log Out"
74−msgstr ""
74+msgstr "ログアウト"
75
75
76#: qml/Components/Dialogs.qml:161 qml/Components/Dialogs.qml:194
76#: qml/Components/Dialogs.qml:161 qml/Components/Dialogs.qml:194
77#: qml/Components/Dialogs.qml:253
77#: qml/Components/Dialogs.qml:253
@@ -81,7 +81,7 @@ msgstr "キャンセル"
81#: qml/Components/Dialogs.qml:173
81#: qml/Components/Dialogs.qml:173
82msgctxt "Title: Reboot/Shut down dialog"
82msgctxt "Title: Reboot/Shut down dialog"
83msgid "Shut down"
83msgid "Shut down"
84−msgstr ""
84+msgstr "シャットダウン"
85
85
86#: qml/Components/Dialogs.qml:174
86#: qml/Components/Dialogs.qml:174
87msgid "Are you sure you want to shut down?"
87msgid "Are you sure you want to shut down?"
@@ -90,17 +90,17 @@ msgstr "本当にシャットダウンしますか?"
90#: qml/Components/Dialogs.qml:176
90#: qml/Components/Dialogs.qml:176
91msgctxt "Button: Reboot the system"
91msgctxt "Button: Reboot the system"
92msgid "Reboot"
92msgid "Reboot"
93−msgstr ""
93+msgstr "再起動"
94
94
95#: qml/Components/Dialogs.qml:185
95#: qml/Components/Dialogs.qml:185
96msgctxt "Button: Shut down the system"
96msgctxt "Button: Shut down the system"
97msgid "Shut down"
97msgid "Shut down"
98−msgstr ""
98+msgstr "シャットダウン"
99
99
100#: qml/Components/Dialogs.qml:207
100#: qml/Components/Dialogs.qml:207
101msgctxt "Title: Reboot dialog"
101msgctxt "Title: Reboot dialog"
102msgid "Reboot"
102msgid "Reboot"
103−msgstr ""
103+msgstr "再起動"
104
104
105#: qml/Components/Dialogs.qml:208
105#: qml/Components/Dialogs.qml:208
106msgid "Are you sure you want to reboot?"
106msgid "Are you sure you want to reboot?"
po/km.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/kn.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/ko.po+18−11
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -149,27 +149,27 @@ msgstr "확인"
149
149
150#: qml/Components/ModeSwitchWarningDialog.qml:32
150#: qml/Components/ModeSwitchWarningDialog.qml:32
151msgid "Apps may have unsaved data:"
151msgid "Apps may have unsaved data:"
152−msgstr ""
152+msgstr "프로그램에 저장하지 않은 데이터가 있을 때:"
153
153
154#: qml/Components/ModeSwitchWarningDialog.qml:57
154#: qml/Components/ModeSwitchWarningDialog.qml:57
155msgid "Re-dock, save your work and close these apps to continue."
155msgid "Re-dock, save your work and close these apps to continue."
156−msgstr ""
156+msgstr "다시 도킹해 작업을 저장하고 프로그램을 닫은 후 계속합니다."
157
157
158#: qml/Components/ModeSwitchWarningDialog.qml:63
158#: qml/Components/ModeSwitchWarningDialog.qml:63
159msgid "Or force close now (unsaved data will be lost)."
159msgid "Or force close now (unsaved data will be lost)."
160−msgstr ""
160+msgstr "강제로 지금 끝냅니다.(저장하지 않은 데이터를 잃게 됩니다.)"
161
161
162#: qml/Components/ModeSwitchWarningDialog.qml:75
162#: qml/Components/ModeSwitchWarningDialog.qml:75
163msgid "OK, I will reconnect"
163msgid "OK, I will reconnect"
164−msgstr ""
164+msgstr "다시 접속합니다."
165
165
166#: qml/Components/ModeSwitchWarningDialog.qml:76
166#: qml/Components/ModeSwitchWarningDialog.qml:76
167msgid "Reconnect now!"
167msgid "Reconnect now!"
168−msgstr ""
168+msgstr "지급 다시 접속!"
169
169
170#: qml/Components/ModeSwitchWarningDialog.qml:88
170#: qml/Components/ModeSwitchWarningDialog.qml:88
171msgid "Close all"
171msgid "Close all"
172−msgstr ""
172+msgstr "모두 닫기"
173
173
174#: qml/Dash/DashPageHeader.qml:266
174#: qml/Dash/DashPageHeader.qml:266
175msgctxt "Button: Open the Ubuntu Store"
175msgctxt "Button: Open the Ubuntu Store"
@@ -230,7 +230,7 @@ msgstr "평가 추가"
230
230
231#: qml/Dash/Previews/PreviewSharing.qml:50
231#: qml/Dash/Previews/PreviewSharing.qml:50
232msgid "Preview Share Item"
232msgid "Preview Share Item"
233−msgstr ""
233+msgstr "공유 항목 미리 보기"
234
234
235#: qml/Dash/PullToRefreshScopeStyle.qml:55
235#: qml/Dash/PullToRefreshScopeStyle.qml:55
236msgid "Pull to refresh…"
236msgid "Pull to refresh…"
@@ -403,7 +403,7 @@ msgstr "실패, 두드리면 다시 시도합니다."
403#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
403#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
404msgctxt "Button: Send a reply message"
404msgctxt "Button: Send a reply message"
405msgid "Send"
405msgid "Send"
406−msgstr ""
406+msgstr "보내기"
407
407
408#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
408#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
409msgctxt "Label: Hint in message indicator line edit"
409msgctxt "Label: Hint in message indicator line edit"
@@ -413,7 +413,7 @@ msgstr "답신"
413#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
413#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
414msgctxt "Button: Call back on phone"
414msgctxt "Button: Call back on phone"
415msgid "Call back"
415msgid "Call back"
416−msgstr ""
416+msgstr "부재중 번호로 전화"
417
417
418#: qml/Panel/Indicators/ModemInfoItem.qml:105
418#: qml/Panel/Indicators/ModemInfoItem.qml:105
419msgid "Unlock SIM"
419msgid "Unlock SIM"
@@ -667,6 +667,13 @@ msgstr "〈 %1"
667msgid "%1 〉"
667msgid "%1 〉"
668msgstr "%1 〉"
668msgstr "%1 〉"
669
669
670+#~ msgid ""
671+#~ "Your device is now connected to an external display. Use this screen as a "
672+#~ "touch pad to interact with the mouse."
673+#~ msgstr ""
674+#~ "장치를 외부 디스플레이와 연결햇습니다. 이 화면을 마우스와 상호작용 하는 터"
675+#~ "치 패드로 사용합니다."
676+
670#~ msgid "Search"
677#~ msgid "Search"
671#~ msgstr "검색"
678#~ msgstr "검색"
672
679
po/ku.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/ky.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/lo.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/lt.po+2−2
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n"
18"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n"
19"%100<10 || n%100>=20) ? 1 : 2;\n"
19"%100<10 || n%100>=20) ? 1 : 2;\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
po/lv.po+2−2
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Type: text/plain; charset=UTF-8\n"
18"Content-Transfer-Encoding: 8bit\n"
18"Content-Transfer-Encoding: 8bit\n"
19"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
19"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
po/ml.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/mr.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/ms.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/my.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/nb.po+14−12
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -30,7 +30,7 @@ msgstr "Fest snarvei"
30
30
31#: plugins/Unity/Launcher/launcheritem.cpp:52
31#: plugins/Unity/Launcher/launcheritem.cpp:52
32msgid "Quit"
32msgid "Quit"
33−msgstr ""
33+msgstr "Avslutt"
34
34
35#: plugins/Unity/Launcher/launcheritem.cpp:106
35#: plugins/Unity/Launcher/launcheritem.cpp:106
36msgid "Unpin shortcut"
36msgid "Unpin shortcut"
@@ -154,27 +154,29 @@ msgstr "OK"
154
154
155#: qml/Components/ModeSwitchWarningDialog.qml:32
155#: qml/Components/ModeSwitchWarningDialog.qml:32
156msgid "Apps may have unsaved data:"
156msgid "Apps may have unsaved data:"
157−msgstr ""
157+msgstr "Programmer kan ha ulagrede data:"
158
158
159#: qml/Components/ModeSwitchWarningDialog.qml:57
159#: qml/Components/ModeSwitchWarningDialog.qml:57
160msgid "Re-dock, save your work and close these apps to continue."
160msgid "Re-dock, save your work and close these apps to continue."
161msgstr ""
161msgstr ""
162+"Koble enheten til en stasjon, lagre arbeidet ditt og lukk disse programmene "
163+"for å fortsette."
162
164
163#: qml/Components/ModeSwitchWarningDialog.qml:63
165#: qml/Components/ModeSwitchWarningDialog.qml:63
164msgid "Or force close now (unsaved data will be lost)."
166msgid "Or force close now (unsaved data will be lost)."
165−msgstr ""
167+msgstr "Eller tving avslutning nå (ulagrede data går tapt)."
166
168
167#: qml/Components/ModeSwitchWarningDialog.qml:75
169#: qml/Components/ModeSwitchWarningDialog.qml:75
168msgid "OK, I will reconnect"
170msgid "OK, I will reconnect"
169−msgstr ""
171+msgstr "OK, jeg skal koble til"
170
172
171#: qml/Components/ModeSwitchWarningDialog.qml:76
173#: qml/Components/ModeSwitchWarningDialog.qml:76
172msgid "Reconnect now!"
174msgid "Reconnect now!"
173−msgstr ""
175+msgstr "Koble til nå!"
174
176
175#: qml/Components/ModeSwitchWarningDialog.qml:88
177#: qml/Components/ModeSwitchWarningDialog.qml:88
176msgid "Close all"
178msgid "Close all"
177−msgstr ""
179+msgstr "Lukk alle"
178
180
179#: qml/Dash/DashPageHeader.qml:266
181#: qml/Dash/DashPageHeader.qml:266
180msgctxt "Button: Open the Ubuntu Store"
182msgctxt "Button: Open the Ubuntu Store"
@@ -235,7 +237,7 @@ msgstr "Skriv en anmeldelse"
235
237
236#: qml/Dash/Previews/PreviewSharing.qml:50
238#: qml/Dash/Previews/PreviewSharing.qml:50
237msgid "Preview Share Item"
239msgid "Preview Share Item"
238−msgstr ""
240+msgstr "Forhåndsvis delingselement"
239
241
240#: qml/Dash/PullToRefreshScopeStyle.qml:55
242#: qml/Dash/PullToRefreshScopeStyle.qml:55
241msgid "Pull to refresh…"
243msgid "Pull to refresh…"
@@ -330,7 +332,7 @@ msgstr "Feil passordfrase"
330#: qml/Greeter/NarrowView.qml:121
332#: qml/Greeter/NarrowView.qml:121
331msgctxt "passphrase"
333msgctxt "passphrase"
332msgid "Please re-enter"
334msgid "Please re-enter"
333−msgstr ""
335+msgstr "Skriv inn på nytt"
334
336
335#: qml/Greeter/NarrowView.qml:122
337#: qml/Greeter/NarrowView.qml:122
336msgid "Sorry, incorrect passcode"
338msgid "Sorry, incorrect passcode"
@@ -411,7 +413,7 @@ msgstr "Feilet. Trykk for å prøve på nytt"
411#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
413#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
412msgctxt "Button: Send a reply message"
414msgctxt "Button: Send a reply message"
413msgid "Send"
415msgid "Send"
414−msgstr ""
416+msgstr "Send"
415
417
416#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
418#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
417msgctxt "Label: Hint in message indicator line edit"
419msgctxt "Label: Hint in message indicator line edit"
@@ -421,7 +423,7 @@ msgstr "Svar"
421#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
423#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
422msgctxt "Button: Call back on phone"
424msgctxt "Button: Call back on phone"
423msgid "Call back"
425msgid "Call back"
424−msgstr ""
426+msgstr "Ring tilbake"
425
427
426#: qml/Panel/Indicators/ModemInfoItem.qml:105
428#: qml/Panel/Indicators/ModemInfoItem.qml:105
427msgid "Unlock SIM"
429msgid "Unlock SIM"
po/ne.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/nl.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/nn.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/oc.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n > 1;\n"
18"Plural-Forms: nplurals=2; plural=n > 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/or.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n!=1;\n"
18"Plural-Forms: nplurals=2; plural=n!=1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/pa.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/pl.po+20−2
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
18"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
19"|| n%100>=20) ? 1 : 2;\n"
19"|| n%100>=20) ? 1 : 2;\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
@@ -157,6 +157,8 @@ msgstr "Programy mogące mieć niezapisane dane:"
157#: qml/Components/ModeSwitchWarningDialog.qml:57
157#: qml/Components/ModeSwitchWarningDialog.qml:57
158msgid "Re-dock, save your work and close these apps to continue."
158msgid "Re-dock, save your work and close these apps to continue."
159msgstr ""
159msgstr ""
160+"Aby kontynuować, dodaj ponownie do doku, zapisz swoją pracę i zamknij te "
161+"programy."
160
162
161#: qml/Components/ModeSwitchWarningDialog.qml:63
163#: qml/Components/ModeSwitchWarningDialog.qml:63
162msgid "Or force close now (unsaved data will be lost)."
164msgid "Or force close now (unsaved data will be lost)."
@@ -678,6 +680,22 @@ msgstr "〈 %1"
678msgid "%1 〉"
680msgid "%1 〉"
679msgstr "%1 〉"
681msgstr "%1 〉"
680
682
683+#~ msgid ""
684+#~ "Your device is now connected to an external display. Use this screen as a "
685+#~ "touch pad to interact with the mouse."
686+#~ msgstr ""
687+#~ "Twoje urządzenie jest teraz podłączone do zewnętrznego wyświetlacza. Użyj "
688+#~ "tego ekranu jako panelu dotykowego do interakcji z myszą."
689+
690+#~ msgid "Welcome to your Ubuntu device."
691+#~ msgstr "Witaj w swoim urządzeniu Ubuntu."
692+
693+#~ msgid "Please select how you’d like to unlock your device."
694+#~ msgstr "Prosimy wybrać sposób, w jaki chcesz odblokować swoje urządzenie."
695+
696+#~ msgid "Your device is now ready to use."
697+#~ msgstr "Twoje urządzenie jest już gotowe do użytku."
698+
681#~ msgid "Confirm"
699#~ msgid "Confirm"
682#~ msgstr "Potwierdź"
700#~ msgstr "Potwierdź"
683
701
po/pt.po+22−6
@@ -8,7 +8,7 @@ msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: \n"
9"Report-Msgid-Bugs-To: \n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
11−"PO-Revision-Date: 2015-12-20 09:20+0000\n"
11+"PO-Revision-Date: 2016-02-18 01:11+0000\n"
12"Last-Translator: Ivo Xavier <ivofernandes12@gmail.com>\n"
12"Last-Translator: Ivo Xavier <ivofernandes12@gmail.com>\n"
13"Language-Team: Portuguese <pt@li.org>\n"
13"Language-Team: Portuguese <pt@li.org>\n"
14"Language: pt\n"
14"Language: pt\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -144,7 +144,7 @@ msgstr "Reiniciar"
144
144
145#: qml/Components/Lockscreen.qml:245
145#: qml/Components/Lockscreen.qml:245
146msgid "Return to Call"
146msgid "Return to Call"
147−msgstr "Volte para chamada"
147+msgstr "Volte para a chamada"
148
148
149#: qml/Components/Lockscreen.qml:245
149#: qml/Components/Lockscreen.qml:245
150msgid "Emergency Call"
150msgid "Emergency Call"
@@ -176,7 +176,7 @@ msgstr "Volte a ligar agora!"
176
176
177#: qml/Components/ModeSwitchWarningDialog.qml:88
177#: qml/Components/ModeSwitchWarningDialog.qml:88
178msgid "Close all"
178msgid "Close all"
179−msgstr ""
179+msgstr "Fechar tudo"
180
180
181#: qml/Dash/DashPageHeader.qml:266
181#: qml/Dash/DashPageHeader.qml:266
182msgctxt "Button: Open the Ubuntu Store"
182msgctxt "Button: Open the Ubuntu Store"
@@ -344,7 +344,7 @@ msgstr "Mostrar palavra-passe"
344
344
345#: qml/Panel/ActiveCallHint.qml:79
345#: qml/Panel/ActiveCallHint.qml:79
346msgid "Tap to return to call..."
346msgid "Tap to return to call..."
347−msgstr "Toque para voltar a chamar..."
347+msgstr "Toque para voltar à chamada..."
348
348
349#: qml/Panel/ActiveCallHint.qml:92
349#: qml/Panel/ActiveCallHint.qml:92
350msgid "Conference"
350msgid "Conference"
@@ -679,6 +679,22 @@ msgstr "〈 %1"
679msgid "%1 〉"
679msgid "%1 〉"
680msgstr "%1 〉"
680msgstr "%1 〉"
681
681
682+#~ msgid ""
683+#~ "Your device is now connected to an external display. Use this screen as a "
684+#~ "touch pad to interact with the mouse."
685+#~ msgstr ""
686+#~ "O dispositivo está ligado a um ecrã externo. Utilize o ecrã como touchpad "
687+#~ "para manipular o ponteiro do rato."
688+
689+#~ msgid "Welcome to your Ubuntu device."
690+#~ msgstr "Bem-vindo ao seu dispositivo Ubuntu."
691+
692+#~ msgid "Please select how you’d like to unlock your device."
693+#~ msgstr "Escolha como quer desbloquear o seu dispositivo."
694+
695+#~ msgid "Your device is now ready to use."
696+#~ msgstr "O seu dispositivo está pronto."
697+
682#~ msgid "Top edge"
698#~ msgid "Top edge"
683#~ msgstr "Margem superior"
699#~ msgstr "Margem superior"
684
700
po/pt_BR.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n > 1;\n"
18"Plural-Forms: nplurals=2; plural=n > 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/ro.po+2−2
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=3; plural=(n == 1 ? 0: (((n % 100 > 19) || ((n % 100 "
18"Plural-Forms: nplurals=3; plural=(n == 1 ? 0: (((n % 100 > 19) || ((n % 100 "
19"== 0) && (n != 0))) ? 2: 1));\n"
19"== 0) && (n != 0))) ? 2: 1));\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
po/ru.po+2−2
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
18"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
po/shn.po+29−29
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: \n"
9"Report-Msgid-Bugs-To: \n"
10−"POT-Creation-Date: 2015-12-08 15:42+0000\n"
10+"POT-Creation-Date: 2016-01-11 17:43+0000\n"
11"PO-Revision-Date: 2015-11-10 12:09+0000\n"
11"PO-Revision-Date: 2015-11-10 12:09+0000\n"
12"Last-Translator: Rockworld <sumoisrock@gmail.com>\n"
12"Last-Translator: Rockworld <sumoisrock@gmail.com>\n"
13"Language-Team: Shan <shn@li.org>\n"
13"Language-Team: Shan <shn@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=(n == 1) ? 0 : 1;\n"
18"Plural-Forms: nplurals=2; plural=(n == 1) ? 0 : 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -172,26 +172,26 @@ msgstr ""
172msgid "Close all"
172msgid "Close all"
173msgstr ""
173msgstr ""
174
174
175−#: qml/Dash/DashPageHeader.qml:265
175+#: qml/Dash/DashPageHeader.qml:266
176msgctxt "Button: Open the Ubuntu Store"
176msgctxt "Button: Open the Ubuntu Store"
177msgid "Store"
177msgid "Store"
178msgstr ""
178msgstr ""
179
179
180−#: qml/Dash/DashPageHeader.qml:272
180+#: qml/Dash/DashPageHeader.qml:273
181msgctxt "Button: Start a search in the current dash scope"
181msgctxt "Button: Start a search in the current dash scope"
182msgid "Search"
182msgid "Search"
183msgstr ""
183msgstr ""
184
184
185−#: qml/Dash/DashPageHeader.qml:282
185+#: qml/Dash/DashPageHeader.qml:283
186msgctxt "Button: Show the current dash scope settings"
186msgctxt "Button: Show the current dash scope settings"
187msgid "Settings"
187msgid "Settings"
188msgstr ""
188msgstr ""
189
189
190−#: qml/Dash/DashPageHeader.qml:289
190+#: qml/Dash/DashPageHeader.qml:290
191msgid "Remove from Favorites"
191msgid "Remove from Favorites"
192msgstr ""
192msgstr ""
193
193
194−#: qml/Dash/DashPageHeader.qml:289
194+#: qml/Dash/DashPageHeader.qml:290
195msgid "Add to Favorites"
195msgid "Add to Favorites"
196msgstr ""
196msgstr ""
197
197
@@ -229,7 +229,7 @@ msgstr ""
229msgid "Add a review"
229msgid "Add a review"
230msgstr ""
230msgstr ""
231
231
232−#: qml/Dash/Previews/PreviewSharing.qml:51
232+#: qml/Dash/Previews/PreviewSharing.qml:50
233msgid "Preview Share Item"
233msgid "Preview Share Item"
234msgstr ""
234msgstr ""
235
235
@@ -340,62 +340,62 @@ msgstr ""
340msgid "Conference"
340msgid "Conference"
341msgstr ""
341msgstr ""
342
342
343−#: qml/Panel/Indicators/MenuItemFactory.qml:731
343+#: qml/Panel/Indicators/MenuItemFactory.qml:753
344msgid "Nothing is playing"
344msgid "Nothing is playing"
345msgstr ""
345msgstr ""
346
346
347−#: qml/Panel/Indicators/MenuItemFactory.qml:860
347+#: qml/Panel/Indicators/MenuItemFactory.qml:882
348#, qt-format
348#, qt-format
349msgid "%1 hour"
349msgid "%1 hour"
350msgid_plural "%1 hours"
350msgid_plural "%1 hours"
351msgstr[0] ""
351msgstr[0] ""
352msgstr[1] ""
352msgstr[1] ""
353
353
354−#: qml/Panel/Indicators/MenuItemFactory.qml:864
354+#: qml/Panel/Indicators/MenuItemFactory.qml:886
355#, qt-format
355#, qt-format
356msgid "%1 minute"
356msgid "%1 minute"
357msgid_plural "%1 minutes"
357msgid_plural "%1 minutes"
358msgstr[0] ""
358msgstr[0] ""
359msgstr[1] ""
359msgstr[1] ""
360
360
361−#: qml/Panel/Indicators/MenuItemFactory.qml:869
361+#: qml/Panel/Indicators/MenuItemFactory.qml:891
362#, qt-format
362#, qt-format
363msgid "%1 second"
363msgid "%1 second"
364msgid_plural "%1 seconds"
364msgid_plural "%1 seconds"
365msgstr[0] ""
365msgstr[0] ""
366msgstr[1] ""
366msgstr[1] ""
367
367
368−#: qml/Panel/Indicators/MenuItemFactory.qml:872
368+#: qml/Panel/Indicators/MenuItemFactory.qml:894
369msgid "0 seconds"
369msgid "0 seconds"
370msgstr ""
370msgstr ""
371
371
372#. Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
372#. Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
373−#: qml/Panel/Indicators/MenuItemFactory.qml:874
373+#: qml/Panel/Indicators/MenuItemFactory.qml:896
374#, qt-format
374#, qt-format
375msgid "%1 remaining"
375msgid "%1 remaining"
376msgstr ""
376msgstr ""
377
377
378−#: qml/Panel/Indicators/MenuItemFactory.qml:880
378+#: qml/Panel/Indicators/MenuItemFactory.qml:902
379msgid "In queue…"
379msgid "In queue…"
380msgstr ""
380msgstr ""
381
381
382−#: qml/Panel/Indicators/MenuItemFactory.qml:884
382+#: qml/Panel/Indicators/MenuItemFactory.qml:906
383msgid "Downloading"
383msgid "Downloading"
384msgstr ""
384msgstr ""
385
385
386−#: qml/Panel/Indicators/MenuItemFactory.qml:886
386+#: qml/Panel/Indicators/MenuItemFactory.qml:908
387msgid "Paused, tap to resume"
387msgid "Paused, tap to resume"
388msgstr ""
388msgstr ""
389
389
390−#: qml/Panel/Indicators/MenuItemFactory.qml:888
390+#: qml/Panel/Indicators/MenuItemFactory.qml:910
391msgid "Canceled"
391msgid "Canceled"
392msgstr ""
392msgstr ""
393
393
394−#: qml/Panel/Indicators/MenuItemFactory.qml:890
394+#: qml/Panel/Indicators/MenuItemFactory.qml:912
395msgid "Finished"
395msgid "Finished"
396msgstr ""
396msgstr ""
397
397
398−#: qml/Panel/Indicators/MenuItemFactory.qml:892
398+#: qml/Panel/Indicators/MenuItemFactory.qml:914
399msgid "Failed, tap to retry"
399msgid "Failed, tap to retry"
400msgstr ""
400msgstr ""
401
401
@@ -493,7 +493,7 @@ msgstr ""
493msgid "Let’s get started."
493msgid "Let’s get started."
494msgstr ""
494msgstr ""
495
495
496−#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:128
496+#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:133
497#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
497#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
498#: qml/Wizard/Pages/60-reporting.qml:60 qml/Wizard/Pages/passwd-confirm.qml:82
498#: qml/Wizard/Pages/60-reporting.qml:60 qml/Wizard/Pages/passwd-confirm.qml:82
499#: qml/Wizard/Pages/passwd-set.qml:90
499#: qml/Wizard/Pages/passwd-set.qml:90
@@ -516,36 +516,36 @@ msgstr ""
516msgid "Lock security"
516msgid "Lock security"
517msgstr ""
517msgstr ""
518
518
519−#: qml/Wizard/Pages/30-passwd-type.qml:74
519+#: qml/Wizard/Pages/30-passwd-type.qml:79
520msgid "Please select how you’d like to unlock your phone."
520msgid "Please select how you’d like to unlock your phone."
521msgstr ""
521msgstr ""
522
522
523−#: qml/Wizard/Pages/30-passwd-type.qml:97
523+#: qml/Wizard/Pages/30-passwd-type.qml:102
524msgctxt "Label: Type of security method"
524msgctxt "Label: Type of security method"
525msgid "Swipe"
525msgid "Swipe"
526msgstr ""
526msgstr ""
527
527
528−#: qml/Wizard/Pages/30-passwd-type.qml:98
528+#: qml/Wizard/Pages/30-passwd-type.qml:103
529msgctxt "Label: Description of security method"
529msgctxt "Label: Description of security method"
530msgid "No security"
530msgid "No security"
531msgstr ""
531msgstr ""
532
532
533−#: qml/Wizard/Pages/30-passwd-type.qml:100
533+#: qml/Wizard/Pages/30-passwd-type.qml:105
534msgctxt "Label: Type of security method"
534msgctxt "Label: Type of security method"
535msgid "Passcode"
535msgid "Passcode"
536msgstr ""
536msgstr ""
537
537
538−#: qml/Wizard/Pages/30-passwd-type.qml:101
538+#: qml/Wizard/Pages/30-passwd-type.qml:106
539msgctxt "Label: Description of security method"
539msgctxt "Label: Description of security method"
540msgid "4 digits only"
540msgid "4 digits only"
541msgstr ""
541msgstr ""
542
542
543−#: qml/Wizard/Pages/30-passwd-type.qml:103
543+#: qml/Wizard/Pages/30-passwd-type.qml:108
544msgctxt "Label: Type of security method"
544msgctxt "Label: Type of security method"
545msgid "Passphrase"
545msgid "Passphrase"
546msgstr ""
546msgstr ""
547
547
548−#: qml/Wizard/Pages/30-passwd-type.qml:104
548+#: qml/Wizard/Pages/30-passwd-type.qml:109
549msgctxt "Label: Description of security method"
549msgctxt "Label: Description of security method"
550msgid "Numbers and letters"
550msgid "Numbers and letters"
551msgstr ""
551msgstr ""
po/si.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/sk.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
18"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/sl.po+54−15
@@ -8,8 +8,8 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: \n"
9"Report-Msgid-Bugs-To: \n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
11−"PO-Revision-Date: 2015-07-06 21:10+0000\n"
11+"PO-Revision-Date: 2016-01-31 18:34+0000\n"
12−"Last-Translator: Sasa Batistic <Unknown>\n"
12+"Last-Translator: Bernard Banko <Unknown>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
14"Language: sl\n"
14"Language: sl\n"
15"MIME-Version: 1.0\n"
15"MIME-Version: 1.0\n"
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n"
18"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n"
19"%100==4 ? 3 : 0);\n"
19"%100==4 ? 3 : 0);\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
@@ -31,7 +31,7 @@ msgstr "Pripni bližnjico"
31
31
32#: plugins/Unity/Launcher/launcheritem.cpp:52
32#: plugins/Unity/Launcher/launcheritem.cpp:52
33msgid "Quit"
33msgid "Quit"
34−msgstr ""
34+msgstr "Končaj"
35
35
36#: plugins/Unity/Launcher/launcheritem.cpp:106
36#: plugins/Unity/Launcher/launcheritem.cpp:106
37msgid "Unpin shortcut"
37msgid "Unpin shortcut"
@@ -151,31 +151,33 @@ msgstr "Klic v sili"
151
151
152#: qml/Components/Lockscreen.qml:277
152#: qml/Components/Lockscreen.qml:277
153msgid "OK"
153msgid "OK"
154−msgstr "V REDU"
154+msgstr "V redu"
155
155
156#: qml/Components/ModeSwitchWarningDialog.qml:32
156#: qml/Components/ModeSwitchWarningDialog.qml:32
157msgid "Apps may have unsaved data:"
157msgid "Apps may have unsaved data:"
158−msgstr ""
158+msgstr "Programi morda niso shranili podatkov:"
159
159
160#: qml/Components/ModeSwitchWarningDialog.qml:57
160#: qml/Components/ModeSwitchWarningDialog.qml:57
161msgid "Re-dock, save your work and close these apps to continue."
161msgid "Re-dock, save your work and close these apps to continue."
162msgstr ""
162msgstr ""
163+"Za nadaljevanje ponovno usidrajte, shranite svoje delo in zaprite te "
164+"programe."
163
165
164#: qml/Components/ModeSwitchWarningDialog.qml:63
166#: qml/Components/ModeSwitchWarningDialog.qml:63
165msgid "Or force close now (unsaved data will be lost)."
167msgid "Or force close now (unsaved data will be lost)."
166−msgstr ""
168+msgstr "Prisilno zapri sedaj (neshranjeni podatki bodo izgubljeni)."
167
169
168#: qml/Components/ModeSwitchWarningDialog.qml:75
170#: qml/Components/ModeSwitchWarningDialog.qml:75
169msgid "OK, I will reconnect"
171msgid "OK, I will reconnect"
170−msgstr ""
172+msgstr "V redu, bom ponovno priključil"
171
173
172#: qml/Components/ModeSwitchWarningDialog.qml:76
174#: qml/Components/ModeSwitchWarningDialog.qml:76
173msgid "Reconnect now!"
175msgid "Reconnect now!"
174−msgstr ""
176+msgstr "Ponovno priključi sedaj!"
175
177
176#: qml/Components/ModeSwitchWarningDialog.qml:88
178#: qml/Components/ModeSwitchWarningDialog.qml:88
177msgid "Close all"
179msgid "Close all"
178−msgstr ""
180+msgstr "Zapri vse"
179
181
180#: qml/Dash/DashPageHeader.qml:266
182#: qml/Dash/DashPageHeader.qml:266
181msgctxt "Button: Open the Ubuntu Store"
183msgctxt "Button: Open the Ubuntu Store"
@@ -236,7 +238,7 @@ msgstr "Dodaj oceno"
236
238
237#: qml/Dash/Previews/PreviewSharing.qml:50
239#: qml/Dash/Previews/PreviewSharing.qml:50
238msgid "Preview Share Item"
240msgid "Preview Share Item"
239−msgstr ""
241+msgstr "Preglej deljeno"
240
242
241#: qml/Dash/PullToRefreshScopeStyle.qml:55
243#: qml/Dash/PullToRefreshScopeStyle.qml:55
242msgid "Pull to refresh…"
244msgid "Pull to refresh…"
@@ -331,7 +333,7 @@ msgstr "Oprostite, napačno šifrirno reklo"
331#: qml/Greeter/NarrowView.qml:121
333#: qml/Greeter/NarrowView.qml:121
332msgctxt "passphrase"
334msgctxt "passphrase"
333msgid "Please re-enter"
335msgid "Please re-enter"
334−msgstr ""
336+msgstr "Ponovno vnesite"
335
337
336#: qml/Greeter/NarrowView.qml:122
338#: qml/Greeter/NarrowView.qml:122
337msgid "Sorry, incorrect passcode"
339msgid "Sorry, incorrect passcode"
@@ -418,7 +420,7 @@ msgstr "Spodletelo, tapnite za ponovni poskus"
418#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
420#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
419msgctxt "Button: Send a reply message"
421msgctxt "Button: Send a reply message"
420msgid "Send"
422msgid "Send"
421−msgstr ""
423+msgstr "Pošlji"
422
424
423#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
425#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
424msgctxt "Label: Hint in message indicator line edit"
426msgctxt "Label: Hint in message indicator line edit"
@@ -428,7 +430,7 @@ msgstr "Odgovor"
428#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
430#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
429msgctxt "Button: Call back on phone"
431msgctxt "Button: Call back on phone"
430msgid "Call back"
432msgid "Call back"
431−msgstr ""
433+msgstr "Pokliči nazaj"
432
434
433#: qml/Panel/Indicators/ModemInfoItem.qml:105
435#: qml/Panel/Indicators/ModemInfoItem.qml:105
434msgid "Unlock SIM"
436msgid "Unlock SIM"
@@ -685,6 +687,13 @@ msgstr "〈 %1"
685msgid "%1 〉"
687msgid "%1 〉"
686msgstr "%1 〉"
688msgstr "%1 〉"
687
689
690+#~ msgid ""
691+#~ "Your device is now connected to an external display. Use this screen as a "
692+#~ "touch pad to interact with the mouse."
693+#~ msgstr ""
694+#~ "Vaša naprava je sedaj priključena na zunanji zaslon. Ta zaslon pa lahko "
695+#~ "uporabite kot sledilno ploščico za nadzor kazalke."
696+
688#~ msgid "Confirm"
697#~ msgid "Confirm"
689#~ msgstr "Potrdi"
698#~ msgstr "Potrdi"
690
699
@@ -777,3 +786,33 @@ msgstr "%1 〉"
777
786
778#~ msgid "Please re-enter"
787#~ msgid "Please re-enter"
779#~ msgstr "Ponovno vnesite"
788#~ msgstr "Ponovno vnesite"
789+
790+#~ msgid "%a %H:%M"
791+#~ msgstr "%a %H:%M"
792+
793+#~ msgid "%a %l:%M %p"
794+#~ msgstr "%a %l:%M %p"
795+
796+#~ msgid "Tomorrow %l:%M %p"
797+#~ msgstr "Jutri %l:%M %p"
798+
799+#~ msgid "%l:%M %p"
800+#~ msgstr "%l:%M %p"
801+
802+#~ msgid "Yesterday %l:%M %p"
803+#~ msgstr "Včeraj %l:%M %p"
804+
805+#~ msgid "%H:%M"
806+#~ msgstr "%H:%M"
807+
808+#~ msgid "Yesterday %H:%M"
809+#~ msgstr "Včeraj %H:%M"
810+
811+#~ msgid "Tomorrow %H:%M"
812+#~ msgstr "Jutri %H:%M"
813+
814+#~ msgid "%a %d %b %H:%M"
815+#~ msgstr "%a %d %b %H:%M"
816+
817+#~ msgid "%a %d %b %l:%M %p"
818+#~ msgstr "%a %d %b %l:%M %p"
po/sq.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:53+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/sr.po+10−3
@@ -9,7 +9,7 @@ msgstr ""
9"Project-Id-Version: unity\n"
9"Project-Id-Version: unity\n"
10"Report-Msgid-Bugs-To: \n"
10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2016-01-11 17:43+0000\n"
11"POT-Creation-Date: 2016-01-11 17:43+0000\n"
12−"PO-Revision-Date: 2015-12-09 20:16+0000\n"
12+"PO-Revision-Date: 2016-02-10 21:21+0000\n"
13"Last-Translator: Bojan Bogdanović <Unknown>\n"
13"Last-Translator: Bojan Bogdanović <Unknown>\n"
14"Language-Team: српски <xfce4@xfce4.org>\n"
14"Language-Team: српски <xfce4@xfce4.org>\n"
15"Language: sr\n"
15"Language: sr\n"
@@ -18,8 +18,8 @@ msgstr ""
18"Content-Transfer-Encoding: 8bit\n"
18"Content-Transfer-Encoding: 8bit\n"
19"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
20"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
20"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
21−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
21+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
22−"X-Generator: Launchpad (build 17886)\n"
22+"X-Generator: Launchpad (build 17925)\n"
23
23
24#: plugins/IntegratedLightDM/Greeter.cpp:112
24#: plugins/IntegratedLightDM/Greeter.cpp:112
25msgid "Password: "
25msgid "Password: "
@@ -682,6 +682,13 @@ msgstr "〈 %1"
682msgid "%1 〉"
682msgid "%1 〉"
683msgstr "%1 〉"
683msgstr "%1 〉"
684
684
685+#~ msgid ""
686+#~ "Your device is now connected to an external display. Use this screen as a "
687+#~ "touch pad to interact with the mouse."
688+#~ msgstr ""
689+#~ "Ваш уређај је сада повезан на спољњи монитор. Користите овај екран као "
690+#~ "додирну плочу да остварите интеракцију са мишем."
691+
685#~ msgid "Confirm"
692#~ msgid "Confirm"
686#~ msgstr "Потврди"
693#~ msgstr "Потврди"
687
694
po/sv.po+18−11
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -152,27 +152,27 @@ msgstr "OK"
152
152
153#: qml/Components/ModeSwitchWarningDialog.qml:32
153#: qml/Components/ModeSwitchWarningDialog.qml:32
154msgid "Apps may have unsaved data:"
154msgid "Apps may have unsaved data:"
155−msgstr ""
155+msgstr "Program kan ha osparad data:"
156
156
157#: qml/Components/ModeSwitchWarningDialog.qml:57
157#: qml/Components/ModeSwitchWarningDialog.qml:57
158msgid "Re-dock, save your work and close these apps to continue."
158msgid "Re-dock, save your work and close these apps to continue."
159−msgstr ""
159+msgstr "Docka om, spara ditt arbete och stäng dessa program för att fortsätta."
160
160
161#: qml/Components/ModeSwitchWarningDialog.qml:63
161#: qml/Components/ModeSwitchWarningDialog.qml:63
162msgid "Or force close now (unsaved data will be lost)."
162msgid "Or force close now (unsaved data will be lost)."
163−msgstr ""
163+msgstr "Eller tvinga avstängning nu (osparad data kommer att gå förlorad)."
164
164
165#: qml/Components/ModeSwitchWarningDialog.qml:75
165#: qml/Components/ModeSwitchWarningDialog.qml:75
166msgid "OK, I will reconnect"
166msgid "OK, I will reconnect"
167−msgstr ""
167+msgstr "OK, jag kommer att återansluta"
168
168
169#: qml/Components/ModeSwitchWarningDialog.qml:76
169#: qml/Components/ModeSwitchWarningDialog.qml:76
170msgid "Reconnect now!"
170msgid "Reconnect now!"
171−msgstr ""
171+msgstr "Återanslut nu!"
172
172
173#: qml/Components/ModeSwitchWarningDialog.qml:88
173#: qml/Components/ModeSwitchWarningDialog.qml:88
174msgid "Close all"
174msgid "Close all"
175−msgstr ""
175+msgstr "Stäng alla"
176
176
177#: qml/Dash/DashPageHeader.qml:266
177#: qml/Dash/DashPageHeader.qml:266
178msgctxt "Button: Open the Ubuntu Store"
178msgctxt "Button: Open the Ubuntu Store"
@@ -233,7 +233,7 @@ msgstr "Lägg till en recension"
233
233
234#: qml/Dash/Previews/PreviewSharing.qml:50
234#: qml/Dash/Previews/PreviewSharing.qml:50
235msgid "Preview Share Item"
235msgid "Preview Share Item"
236−msgstr ""
236+msgstr "Premiärvisa objektet dela"
237
237
238#: qml/Dash/PullToRefreshScopeStyle.qml:55
238#: qml/Dash/PullToRefreshScopeStyle.qml:55
239msgid "Pull to refresh…"
239msgid "Pull to refresh…"
@@ -409,7 +409,7 @@ msgstr "Misslyckades, tryck för att försöka igen"
409#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
409#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
410msgctxt "Button: Send a reply message"
410msgctxt "Button: Send a reply message"
411msgid "Send"
411msgid "Send"
412−msgstr ""
412+msgstr "Skicka"
413
413
414#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
414#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
415msgctxt "Label: Hint in message indicator line edit"
415msgctxt "Label: Hint in message indicator line edit"
@@ -419,7 +419,7 @@ msgstr "Svara"
419#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
419#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
420msgctxt "Button: Call back on phone"
420msgctxt "Button: Call back on phone"
421msgid "Call back"
421msgid "Call back"
422−msgstr ""
422+msgstr "Ring upp"
423
423
424#: qml/Panel/Indicators/ModemInfoItem.qml:105
424#: qml/Panel/Indicators/ModemInfoItem.qml:105
425msgid "Unlock SIM"
425msgid "Unlock SIM"
@@ -674,6 +674,13 @@ msgstr "〈 %1"
674msgid "%1 〉"
674msgid "%1 〉"
675msgstr "%1 〉"
675msgstr "%1 〉"
676
676
677+#~ msgid ""
678+#~ "Your device is now connected to an external display. Use this screen as a "
679+#~ "touch pad to interact with the mouse."
680+#~ msgstr ""
681+#~ "Din enhet är nu ansluten till en extern display. Använd denna skärm som "
682+#~ "en styrplatta för att interagera med musen."
683+
677#~ msgid "Top edge"
684#~ msgid "Top edge"
678#~ msgstr "Överkant"
685#~ msgstr "Överkant"
679
686
po/sw.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/ta.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/te.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/th.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/tr.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/ug.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/uk.po+18−2
@@ -17,8 +17,8 @@ msgstr ""
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
18"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
20−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21−"X-Generator: Launchpad (build 17886)\n"
21+"X-Generator: Launchpad (build 17925)\n"
22
22
23#: plugins/IntegratedLightDM/Greeter.cpp:112
23#: plugins/IntegratedLightDM/Greeter.cpp:112
24msgid "Password: "
24msgid "Password: "
@@ -687,6 +687,22 @@ msgstr "〈 %1"
687msgid "%1 〉"
687msgid "%1 〉"
688msgstr "%1 〉"
688msgstr "%1 〉"
689
689
690+#~ msgid ""
691+#~ "Your device is now connected to an external display. Use this screen as a "
692+#~ "touch pad to interact with the mouse."
693+#~ msgstr ""
694+#~ "Ваш пристрій з’єднано із зовнішнім дисплеєм. Скористайтеся його екраном "
695+#~ "як сенсорною панеллю для імітації роботи із мишею."
696+
697+#~ msgid "Welcome to your Ubuntu device."
698+#~ msgstr "Вітаємо у вашому пристрої Ubuntu."
699+
700+#~ msgid "Please select how you’d like to unlock your device."
701+#~ msgstr "Будь ласка, виберіть спосіб розблокування вашого пристрою."
702+
703+#~ msgid "Your device is now ready to use."
704+#~ msgstr "Пристрій готовий до використання."
705+
690#~ msgid "Confirm"
706#~ msgid "Confirm"
691#~ msgstr "Підтвердити"
707#~ msgstr "Підтвердити"
692
708
po/unity8.pot+13−11
@@ -8,7 +8,7 @@ msgid ""
8msgstr ""
8msgstr ""
9"Project-Id-Version: unity8\n"
9"Project-Id-Version: unity8\n"
10"Report-Msgid-Bugs-To: \n"
10"Report-Msgid-Bugs-To: \n"
11−"POT-Creation-Date: 2016-01-11 17:43+0000\n"
11+"POT-Creation-Date: 2016-02-16 03:29+0000\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -194,15 +194,15 @@ msgstr ""
194msgid "Add to Favorites"
194msgid "Add to Favorites"
195msgstr ""
195msgstr ""
196
196
197−#: qml/Dash/GenericScopeView.qml:576 qml/Dash/GenericScopeView.qml:734
197+#: qml/Dash/GenericScopeView.qml:587 qml/Dash/GenericScopeView.qml:745
198msgid "See less"
198msgid "See less"
199msgstr ""
199msgstr ""
200
200
201−#: qml/Dash/GenericScopeView.qml:576
201+#: qml/Dash/GenericScopeView.qml:587
202msgid "See all"
202msgid "See all"
203msgstr ""
203msgstr ""
204
204
205−#: qml/Dash/GenericScopeView.qml:638
205+#: qml/Dash/GenericScopeView.qml:649
206msgctxt "Label: Hint for dash search line edit"
206msgctxt "Label: Hint for dash search line edit"
207msgid "Search"
207msgid "Search"
208msgstr ""
208msgstr ""
@@ -256,19 +256,21 @@ msgstr ""
256msgid "Also installed"
256msgid "Also installed"
257msgstr ""
257msgstr ""
258
258
259−#: qml/DisabledScreenNotice.qml:42
259+#: qml/DisabledScreenNotice.qml:87
260+msgid ""
260−msgid "Your device is now connected to an external display."
261+"Your device is now connected to an external display. Use this screen as a "
262+"touch pad to interact with the mouse."
261msgstr ""
263msgstr ""
262
264
263#: qml/Greeter/CoverPage.qml:107
265#: qml/Greeter/CoverPage.qml:107
264msgid "Unlock"
266msgid "Unlock"
265msgstr ""
267msgstr ""
266
268
267−#: qml/Greeter/LoginList.qml:236
269+#: qml/Greeter/LoginList.qml:239
268msgid "Retry"
270msgid "Retry"
269msgstr ""
271msgstr ""
270
272
271−#: qml/Greeter/LoginList.qml:237
273+#: qml/Greeter/LoginList.qml:240
272msgid "Tap to unlock"
274msgid "Tap to unlock"
273msgstr ""
275msgstr ""
274
276
@@ -485,7 +487,7 @@ msgid "Hi!"
485msgstr ""
487msgstr ""
486
488
487#: qml/Wizard/Pages/10-welcome.qml:44
489#: qml/Wizard/Pages/10-welcome.qml:44
488−msgid "Welcome to your Ubuntu phone."
490+msgid "Welcome to your Ubuntu device."
489msgstr ""
491msgstr ""
490
492
491#: qml/Wizard/Pages/10-welcome.qml:52
493#: qml/Wizard/Pages/10-welcome.qml:52
@@ -516,7 +518,7 @@ msgid "Lock security"
516msgstr ""
518msgstr ""
517
519
518#: qml/Wizard/Pages/30-passwd-type.qml:79
520#: qml/Wizard/Pages/30-passwd-type.qml:79
519−msgid "Please select how you’d like to unlock your phone."
521+msgid "Please select how you’d like to unlock your device."
520msgstr ""
522msgstr ""
521
523
522#: qml/Wizard/Pages/30-passwd-type.qml:102
524#: qml/Wizard/Pages/30-passwd-type.qml:102
@@ -617,7 +619,7 @@ msgid "Nice work!"
617msgstr ""
619msgstr ""
618
620
619#: qml/Wizard/Pages/80-finished.qml:46
621#: qml/Wizard/Pages/80-finished.qml:46
620−msgid "Your phone is now ready to use."
622+msgid "Your device is now ready to use."
621msgstr ""
623msgstr ""
622
624
623#: qml/Wizard/Pages/80-finished.qml:53
625#: qml/Wizard/Pages/80-finished.qml:53
po/ur.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/uz.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/vi.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/wo.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n > 1;\n"
18"Plural-Forms: nplurals=2; plural=n > 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/xh.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/zh_CN.po+17−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -663,6 +663,21 @@ msgstr "〈 %1"
663msgid "%1 〉"
663msgid "%1 〉"
664msgstr "%1 〉"
664msgstr "%1 〉"
665
665
666+#~ msgid ""
667+#~ "Your device is now connected to an external display. Use this screen as a "
668+#~ "touch pad to interact with the mouse."
669+#~ msgstr ""
670+#~ "你的设备现已连接上了一个外接显示。将这个屏幕作为触控板使用,可与鼠标互动。"
671+
672+#~ msgid "Welcome to your Ubuntu device."
673+#~ msgstr "欢迎使用您的Ubuntu设备。"
674+
675+#~ msgid "Please select how you’d like to unlock your device."
676+#~ msgstr "请选择你偏好的设备解锁方式。"
677+
678+#~ msgid "Your device is now ready to use."
679+#~ msgstr "您的设备已就绪。"
680+
666#~ msgid "Confirm"
681#~ msgid "Confirm"
667#~ msgstr "确认"
682#~ msgstr "确认"
668
683
po/zh_HK.po+2−2
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
po/zh_TW.po+13−4
@@ -8,7 +8,7 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: \n"
9"Report-Msgid-Bugs-To: \n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
10"POT-Creation-Date: 2016-01-11 17:43+0000\n"
11−"PO-Revision-Date: 2015-07-31 09:29+0000\n"
11+"PO-Revision-Date: 2016-02-24 04:40+0000\n"
12"Last-Translator: Po-Hsu Lin <po-hsu.lin@canonical.com>\n"
12"Last-Translator: Po-Hsu Lin <po-hsu.lin@canonical.com>\n"
13"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
13"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
14"Language: zh_TW\n"
14"Language: zh_TW\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19−"X-Launchpad-Export-Date: 2016-01-14 05:54+0000\n"
19+"X-Launchpad-Export-Date: 2016-02-25 05:23+0000\n"
20−"X-Generator: Launchpad (build 17886)\n"
20+"X-Generator: Launchpad (build 17925)\n"
21
21
22#: plugins/IntegratedLightDM/Greeter.cpp:112
22#: plugins/IntegratedLightDM/Greeter.cpp:112
23msgid "Password: "
23msgid "Password: "
@@ -399,7 +399,7 @@ msgstr "失敗,點按可重試"
399#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
399#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
400msgctxt "Button: Send a reply message"
400msgctxt "Button: Send a reply message"
401msgid "Send"
401msgid "Send"
402−msgstr ""
402+msgstr "傳送"
403
403
404#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
404#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
405msgctxt "Label: Hint in message indicator line edit"
405msgctxt "Label: Hint in message indicator line edit"
@@ -660,6 +660,15 @@ msgstr "〈 %1"
660msgid "%1 〉"
660msgid "%1 〉"
661msgstr "%1 〉"
661msgstr "%1 〉"
662
662
663+#~ msgid "Welcome to your Ubuntu device."
664+#~ msgstr "歡迎使用您的 Ubuntu 裝置"
665+
666+#~ msgid "Please select how you’d like to unlock your device."
667+#~ msgstr "請選擇您想要的裝置解鎖方式。"
668+
669+#~ msgid "Your device is now ready to use."
670+#~ msgstr "您的裝置已準備就緒。"
671+
663#~ msgid "Confirm"
672#~ msgid "Confirm"
664#~ msgstr "確認"
673#~ msgstr "確認"
665
674
qml/Components/EdgeBarrierController.qml+2
@@ -30,6 +30,8 @@ MouseArea {
30 // Should trigger the action associated with this edge
30 // Should trigger the action associated with this edge
31 signal passed()
31 signal passed()
32
32
33+ onPressed: mouse.accepted = false;
34+
33 function push(amount) {
35 function push(amount) {
34 if (!root._containsMouse) {
36 if (!root._containsMouse) {
35 return;
37 return;
qml/Components/InputMethod.qml+1−1
@@ -59,7 +59,7 @@ Item {
59 }
59 }
60
60
61 state: {
61 state: {
62− if (surfaceItem.surface && surfaceItem.surfaceState != Mir.MinimizedState) {
62+ if (surfaceItem.surface && surfaceItem.surfaceState != Mir.MinimizedState && root.enabled) {
63 return "shown";
63 return "shown";
64 } else {
64 } else {
65 return "hidden";
65 return "hidden";
qml/Components/PhysicalKeysMapper.qml+32−2
@@ -16,6 +16,7 @@
16
16
17import QtQuick 2.4
17import QtQuick 2.4
18import Powerd 0.1
18import Powerd 0.1
19+import Utils 0.1
19
20
20/*!
21/*!
21 \brief A mapper for the physical keys on the device
22 \brief A mapper for the physical keys on the device
@@ -59,9 +60,24 @@ Item {
59 property bool altTabPressed: false
60 property bool altTabPressed: false
60
61
61 property var powerButtonPressStart: 0
62 property var powerButtonPressStart: 0
63+
64+ // We need to eat ALT presses until we know what they're for (Alt+Tab or going to the app?)
65+ // Once we know if an ALT keypress is for the app, we need to re-inject the pressed event for it
66+ // but we must only do that once.
67+ property bool altPressInjected: false
68+ }
69+
70+ InputEventGenerator {
71+ id: inputEventGenerator
62 }
72 }
63
73
64 function onKeyPressed(event, currentEventTimestamp) {
74 function onKeyPressed(event, currentEventTimestamp) {
75+ if (d.altPressed && !d.altTabPressed && event.key !== Qt.Key_Tab && event.key !== Qt.Key_Alt && !d.altPressInjected) {
76+ // ALT is pressed and another key that is not Tab has been received. Re-inject the alt pressed event
77+ d.altPressInjected = true;
78+ inputEventGenerator.generateKeyEvent(Qt.Key_Alt, true, Qt.NoModifier, currentEventTimestamp - 1, 56);
79+ }
80+
65 if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
81 if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
66 if (event.isAutoRepeat) {
82 if (event.isAutoRepeat) {
67 if (d.powerButtonPressStart > 0
83 if (d.powerButtonPressStart > 0
@@ -97,7 +113,12 @@ Item {
97 d.volumeUpKeyPressed = true;
113 d.volumeUpKeyPressed = true;
98 }
114 }
99 } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
115 } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
116+ if (!d.altPressed || event.isAutoRepeat) {
117+ // Only eat it if it's the first time we receive alt pressed (or if it's the autorepeat of the first press)
100− d.altPressed = true;
118+ d.altPressed = true;
119+ event.accepted = true;
120+ d.altPressInjected = false;
121+ }
101 } else if (event.key == Qt.Key_Tab) {
122 } else if (event.key == Qt.Key_Tab) {
102 if (d.altPressed && !d.altTabPressed) {
123 if (d.altPressed && !d.altTabPressed) {
103 d.altTabPressed = true;
124 d.altTabPressed = true;
@@ -119,10 +140,19 @@ Item {
119 d.volumeUpKeyPressed = false;
140 d.volumeUpKeyPressed = false;
120 if (!d.volumeDownKeyPressed) d.ignoreVolumeEvents = false;
141 if (!d.volumeDownKeyPressed) d.ignoreVolumeEvents = false;
121 } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
142 } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
122− d.altPressed = false;
123 if (d.altTabPressed) {
143 if (d.altTabPressed) {
124 d.altTabPressed = false;
144 d.altTabPressed = false;
125 event.accepted = true;
145 event.accepted = true;
146+ } else if (d.altPressed && !d.altPressInjected) {
147+ // Alt was released but nothing else. Let's inject a pressed event and also forward the release.
148+ d.altPressInjected = true;
149+ inputEventGenerator.generateKeyEvent(Qt.Key_Alt, true, Qt.AltModifer, currentEventTimestamp, 56);
150+ d.altPressInjected = false;
151+ }
152+ d.altPressed = false;
153+ } else if (event.key == Qt.Key_Tab) {
154+ if (d.altTabPressed) {
155+ event.accepted = true;
126 }
156 }
127 }
157 }
128 }
158 }
qml/Components/ResponsiveGridView.qml+2−4
@@ -18,12 +18,10 @@ import QtQuick 2.4
18import Ubuntu.Components 1.3
18import Ubuntu.Components 1.3
19
19
20/*
20/*
21− Essentially a GridView where you can specify the maximum number of columns it can have.
21+ Essentially a GridView
22 */
22 */
23Item {
23Item {
24 property int minimumHorizontalSpacing: units.gu(0.5)
24 property int minimumHorizontalSpacing: units.gu(0.5)
25− // property int minimumNumberOfColumns: 2 // FIXME: not implemented
26− property int maximumNumberOfColumns: 6
27 readonly property int columns: gridView.columns
25 readonly property int columns: gridView.columns
28 property alias verticalSpacing: gridView.verticalSpacing
26 property alias verticalSpacing: gridView.verticalSpacing
29 readonly property alias margins: gridView.margin
27 readonly property alias margins: gridView.margin
@@ -81,7 +79,7 @@ Item {
81 }
79 }
82
80
83 property real allocatableHorizontalSpace: parent.width - columns * delegateWidth
81 property real allocatableHorizontalSpace: parent.width - columns * delegateWidth
84− property int columns: Math.min(columnsForSpacing(minimumHorizontalSpacing), maximumNumberOfColumns)
82+ property int columns: columnsForSpacing(minimumHorizontalSpacing)
85 property real horizontalSpacing: spacingForColumns(columns)
83 property real horizontalSpacing: spacingForColumns(columns)
86 property real verticalSpacing: horizontalSpacing
84 property real verticalSpacing: horizontalSpacing
87 property int margin: allocatableHorizontalSpace - columns * horizontalSpacing
85 property int margin: allocatableHorizontalSpace - columns * horizontalSpacing
qml/Components/VirtualTouchPad.qmlnew file+138
@@ -0,0 +1,138 @@
1+/*
2+ * Copyright (C) 2015 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.4
18+import Ubuntu.Components 1.3
19+import UInput 0.1
20+
21+Item {
22+ property var uinput: UInput {
23+ Component.onCompleted: createMouse();
24+ Component.onDestruction: removeMouse();
25+ }
26+
27+ readonly property bool pressed: point1.pressed || point2.pressed
28+
29+ MultiPointTouchArea {
30+ objectName: "touchPadArea"
31+ anchors.fill: parent
32+
33+ // FIXME: Once we have Qt DPR support, this should be Qt.styleHints.startDragDistance
34+ readonly property int clickThreshold: units.gu(1.5)
35+ property bool isClick: false
36+ property bool isDoubleClick: false
37+ property bool isDrag: false
38+
39+ onPressed: {
40+ // If double-tapping *really* fast, it could happen that we end up having only point2 pressed
41+ // Make sure we check for both combos, only point1 or only point2
42+ if (((point1.pressed && !point2.pressed) || (!point1.pressed && point2.pressed))
43+ && clickTimer.running) {
44+ clickTimer.stop();
45+ uinput.pressMouse(UInput.ButtonLeft)
46+ isDoubleClick = true;
47+ }
48+ isClick = true;
49+ }
50+
51+ onUpdated: {
52+ switch (touchPoints.length) {
53+ case 1:
54+ moveMouse(touchPoints);
55+ return;
56+ case 2:
57+ scroll(touchPoints);
58+ return;
59+ }
60+ }
61+
62+ onReleased: {
63+ if (isDoubleClick || isDrag) {
64+ uinput.releaseMouse(UInput.ButtonLeft)
65+ isDoubleClick = false;
66+ }
67+ if (isClick) {
68+ clickTimer.scheduleClick(point1.pressed ? UInput.ButtonRight : UInput.ButtonLeft)
69+ }
70+ isClick = false;
71+ isDrag = false;
72+ }
73+
74+ Timer {
75+ id: clickTimer
76+ repeat: false
77+ interval: 200
78+ property int button: UInput.ButtonLeft
79+ onTriggered: {
80+ uinput.pressMouse(button);
81+ uinput.releaseMouse(button);
82+ }
83+ function scheduleClick(button) {
84+ clickTimer.button = button;
85+ clickTimer.start();
86+ }
87+ }
88+
89+ function moveMouse(touchPoints) {
90+ var tp = touchPoints[0];
91+ if (isClick &&
92+ (Math.abs(tp.x - tp.startX) > clickThreshold ||
93+ Math.abs(tp.y - tp.startY) > clickThreshold)) {
94+ isClick = false;
95+ isDrag = true;
96+ }
97+
98+ uinput.moveMouse(tp.x - tp.previousX, tp.y - tp.previousY);
99+ }
100+
101+ function scroll(touchPoints) {
102+ var dh = 0;
103+ var dv = 0;
104+ var tp = touchPoints[0];
105+ if (isClick &&
106+ (Math.abs(tp.x - tp.startX) > clickThreshold ||
107+ Math.abs(tp.y - tp.startY) > clickThreshold)) {
108+ isClick = false;
109+ }
110+ dh += tp.x - tp.previousX;
111+ dv += tp.y - tp.previousY;
112+
113+ tp = touchPoints[1];
114+ if (isClick &&
115+ (Math.abs(tp.x - tp.startX) > clickThreshold ||
116+ Math.abs(tp.y - tp.startY) > clickThreshold)) {
117+ isClick = false;
118+ }
119+ dh += tp.x - tp.previousX;
120+ dv += tp.y - tp.previousY;
121+
122+ // As we added up the movement of the two fingers, let's divide it again by 2
123+ dh /= 2;
124+ dv /= 2;
125+
126+ uinput.scrollMouse(dh, dv);
127+ }
128+
129+ touchPoints: [
130+ TouchPoint {
131+ id: point1
132+ },
133+ TouchPoint {
134+ id: point2
135+ }
136+ ]
137+ }
138+}
qml/Components/VolumeControl.qml+1−6
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013-2015 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -28,10 +28,6 @@ Item {
28 readonly property int stepDown: -1
28 readonly property int stepDown: -1
29
29
30 property var indicators // passed from Shell.qml
30 property var indicators // passed from Shell.qml
31− readonly property bool showNotification: indicators && indicators.fullyOpened && indicators.currentIndicator === "indicator-sound"
32− onShowNotificationChanged: { // disallow the volume notification when using the slider, lpbug#1484126
33− actionGroup.indicatorsAction.updateState(root.showNotification);
34− }
35
31
36 GlobalShortcut {
32 GlobalShortcut {
37 id: muteShortcut
33 id: muteShortcut
@@ -47,7 +43,6 @@ Item {
47
43
48 property variant actionObject: action("volume")
44 property variant actionObject: action("volume")
49 property variant muteActionObject: indicators.indicatorsModel.profile === "desktop" ? action("mute") : action("silent-mode")
45 property variant muteActionObject: indicators.indicatorsModel.profile === "desktop" ? action("mute") : action("silent-mode")
50− property variant indicatorsAction: action("indicator-shown")
51 }
46 }
52
47
53 function volumeUp() {
48 function volumeUp() {
qml/Components/ZoomableImage.qml+1−1
@@ -65,7 +65,7 @@ Item {
65 anchors.fill: parent
65 anchors.fill: parent
66 fillMode: Image.PreserveAspectFit
66 fillMode: Image.PreserveAspectFit
67
67
68− readonly property int sourceSizeMultiplier: 3
68+ readonly property int sourceSizeMultiplier: root.zoomable ? 3 : 1
69
69
70 sourceSize.width: root.width * sourceSizeMultiplier <= root.height * sourceSizeMultiplier ? root.width * sourceSizeMultiplier : 0
70 sourceSize.width: root.width * sourceSizeMultiplier <= root.height * sourceSizeMultiplier ? root.width * sourceSizeMultiplier : 0
71 sourceSize.height: root.height * sourceSizeMultiplier <= root.width * sourceSizeMultiplier ? root.height * sourceSizeMultiplier : 0
71 sourceSize.height: root.height * sourceSizeMultiplier <= root.width * sourceSizeMultiplier ? root.height * sourceSizeMultiplier : 0
qml/Dash/CardCarousel.qml−1
@@ -64,7 +64,6 @@ DashRenderer {
64 item.fixedHeaderHeight = Qt.binding(function() { return carousel.headerHeight; });
64 item.fixedHeaderHeight = Qt.binding(function() { return carousel.headerHeight; });
65 item.height = Qt.binding(function() { return cardTool.cardHeight; });
65 item.height = Qt.binding(function() { return cardTool.cardHeight; });
66 item.cardData = Qt.binding(function() { return model; });
66 item.cardData = Qt.binding(function() { return model; });
67− item.components = Qt.binding(function() { return cardTool.components; });
68 item.fontScale = Qt.binding(function() { return carousel.fontScale; });
67 item.fontScale = Qt.binding(function() { return carousel.fontScale; });
69 item.showHeader = Qt.binding(function() { return loader.explicitlyScaled; });
68 item.showHeader = Qt.binding(function() { return loader.explicitlyScaled; });
70 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
69 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
qml/Dash/CardGrid.qml+3−2
@@ -20,12 +20,14 @@ import "../Components"
20DashRenderer {
20DashRenderer {
21 id: root
21 id: root
22
22
23+ readonly property real defaultMinimumHorizontalSpacing: units.gu(1)
23 readonly property int collapsedRows: {
24 readonly property int collapsedRows: {
24 if (!cardTool || !cardTool.template || typeof cardTool.template["collapsed-rows"] != "number") return 2;
25 if (!cardTool || !cardTool.template || typeof cardTool.template["collapsed-rows"] != "number") return 2;
25 return cardTool.template["collapsed-rows"];
26 return cardTool.template["collapsed-rows"];
26 }
27 }
27 property string artShapeStyle: "inset";
28 property string artShapeStyle: "inset";
28 property string backgroundShapeStyle: "inset";
29 property string backgroundShapeStyle: "inset";
30+ property alias minimumHorizontalSpacing: grid.minimumHorizontalSpacing
29
31
30 expandedHeight: grid.totalContentHeight
32 expandedHeight: grid.totalContentHeight
31 collapsedHeight: Math.min(grid.contentHeightForRows(collapsedRows, grid.cellHeight), expandedHeight)
33 collapsedHeight: Math.min(grid.contentHeightForRows(collapsedRows, grid.cellHeight), expandedHeight)
@@ -45,7 +47,7 @@ DashRenderer {
45 ResponsiveGridView {
47 ResponsiveGridView {
46 id: grid
48 id: grid
47 anchors.fill: parent
49 anchors.fill: parent
48− minimumHorizontalSpacing: units.gu(1)
50+ minimumHorizontalSpacing: root.defaultMinimumHorizontalSpacing
49 delegateWidth: cardTool.cardWidth
51 delegateWidth: cardTool.cardWidth
50 delegateHeight: cardTool.cardHeight
52 delegateHeight: cardTool.cardHeight
51 verticalSpacing: units.gu(1)
53 verticalSpacing: units.gu(1)
@@ -68,7 +70,6 @@ DashRenderer {
68 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
70 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
69 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
71 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
70 item.cardData = Qt.binding(function() { return model; });
72 item.cardData = Qt.binding(function() { return model; });
71− item.components = Qt.binding(function() { return cardTool.components; });
72 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
73 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
73 item.scopeStyle = root.scopeStyle;
74 item.scopeStyle = root.scopeStyle;
74 item.artShapeStyle = root.artShapeStyle;
75 item.artShapeStyle = root.artShapeStyle;
qml/Dash/CardHorizontalList.qml−1
@@ -53,7 +53,6 @@ DashRenderer {
53 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
53 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
54 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
54 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
55 item.cardData = Qt.binding(function() { return model; });
55 item.cardData = Qt.binding(function() { return model; });
56− item.components = Qt.binding(function() { return cardTool.components; });
57 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
56 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
58 item.scopeStyle = root.scopeStyle;
57 item.scopeStyle = root.scopeStyle;
59 }
58 }
qml/Dash/CardTool.qml−1
@@ -220,7 +220,6 @@ Item {
220 onLoaded: {
220 onLoaded: {
221 item.objectName = "cardToolCard";
221 item.objectName = "cardToolCard";
222 item.asynchronous = false;
222 item.asynchronous = false;
223− item.components = Qt.binding(function() { return cardTool.components; });
224 item.width = Qt.binding(function() { return cardTool.cardWidth !== -1 ? cardTool.cardWidth : item.implicitWidth; });
223 item.width = Qt.binding(function() { return cardTool.cardWidth !== -1 ? cardTool.cardWidth : item.implicitWidth; });
225 item.height = Qt.binding(function() { return cardTool.cardHeight !== -1 ? cardTool.cardHeight : item.implicitHeight; });
224 item.height = Qt.binding(function() { return cardTool.cardHeight !== -1 ? cardTool.cardHeight : item.implicitHeight; });
226 }
225 }
qml/Dash/CardVerticalJournal.qml−1
@@ -72,7 +72,6 @@ DashRenderer {
72 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
72 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
73 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
73 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
74 item.cardData = Qt.binding(function() { return model; });
74 item.cardData = Qt.binding(function() { return model; });
75− item.components = Qt.binding(function() { return cardTool.components; });
76 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
75 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
77 item.scopeStyle = root.scopeStyle;
76 item.scopeStyle = root.scopeStyle;
78 }
77 }
qml/Dash/DashBackground.qml+6−2
@@ -15,12 +15,16 @@
15 */
15 */
16
16
17import QtQuick 2.4
17import QtQuick 2.4
18+import QtQuick.Window 2.2
19+import Ubuntu.Thumbnailer 0.1
18
20
19Image {
21Image {
20− source: anchors.fill.width > anchors.fill.height ? "graphics/paper_landscape.png" : "graphics/paper_portrait.png"
22+ source: "image://thumbnailer/" + Qt.resolvedUrl("graphics/paper.png")
21 fillMode: Image.PreserveAspectCrop
23 fillMode: Image.PreserveAspectCrop
22 horizontalAlignment: Image.AlignRight
24 horizontalAlignment: Image.AlignRight
23 verticalAlignment: Image.AlignTop
25 verticalAlignment: Image.AlignTop
26+ // avoid CPU scaling when window size changes
27+ readonly property int maxSize: Math.max(Screen.width, Screen.height)
24− sourceSize.width: anchors.fill.width
28+ sourceSize.width: maxSize
25 sourceSize.height: 0
29 sourceSize.height: 0
26}
30}
qml/Dash/GenericScopeView.qml+20−9
@@ -360,17 +360,10 @@ FocusScope {
360 baseItem.expand(shouldExpand, false /*animate*/);
360 baseItem.expand(shouldExpand, false /*animate*/);
361 }
361 }
362 updateRanges();
362 updateRanges();
363+ clickScopeSizingHacks();
363 if (scope && scope.id === "clickscope") {
364 if (scope && scope.id === "clickscope") {
364 if (categoryId === "predefined" || categoryId === "local") {
365 if (categoryId === "predefined" || categoryId === "local") {
365− // Yeah, hackish :/
366− if (scopeView.width > units.gu(45)) {
367− if (scopeView.width >= units.gu(70)) {
368− cardTool.cardWidth = units.gu(9);
369− } else {
370− cardTool.cardWidth = units.gu(10);
371− }
372− }
373− cardTool.artShapeSize = Qt.size(units.gu(8), units.gu(7.5));
366+ cardTool.artShapeSize = Qt.binding(function() { return Qt.size(units.gu(8), units.gu(7.5)) });
374 item.artShapeStyle = "icon";
367 item.artShapeStyle = "icon";
375 } else {
368 } else {
376 // Should be ubuntu store icon
369 // Should be ubuntu store icon
@@ -387,6 +380,23 @@ FocusScope {
387 }
380 }
388 }
381 }
389
382
383+ function clickScopeSizingHacks() {
384+ if (scope && scope.id === "clickscope" &&
385+ (categoryId === "predefined" || categoryId === "local")) {
386+ // Yeah, hackish :/
387+ if (scopeView.width > units.gu(45)) {
388+ if (scopeView.width >= units.gu(70)) {
389+ cardTool.cardWidth = units.gu(11);
390+ item.minimumHorizontalSpacing = units.gu(5);
391+ return;
392+ } else {
393+ cardTool.cardWidth = units.gu(10);
394+ }
395+ }
396+ item.minimumHorizontalSpacing = item.defaultMinimumHorizontalSpacing;
397+ }
398+ }
399+
390 Connections {
400 Connections {
391 target: rendererLoader.item
401 target: rendererLoader.item
392 onClicked: { // (int index, var result, var item, var itemModel)
402 onClicked: { // (int index, var result, var item, var itemModel)
@@ -416,6 +426,7 @@ FocusScope {
416 target: scopeView
426 target: scopeView
417 onIsCurrentChanged: rendererLoader.updateRanges();
427 onIsCurrentChanged: rendererLoader.updateRanges();
418 onVisibleToParentChanged: rendererLoader.updateRanges();
428 onVisibleToParentChanged: rendererLoader.updateRanges();
429+ onWidthChanged: rendererLoader.clickScopeSizingHacks();
419 }
430 }
420 Connections {
431 Connections {
421 target: holdingList
432 target: holdingList
qml/Dash/Previews/PreviewAudioPlayback.qml+6−1
@@ -71,6 +71,7 @@ PreviewWidget {
71 width: trackRow.column1Width
71 width: trackRow.column1Width
72 height: width
72 height: width
73 iconSource: DashAudioPlayer.playing && trackItem.isPlayingItem ? "image://theme/media-playback-pause" : "image://theme/media-playback-start"
73 iconSource: DashAudioPlayer.playing && trackItem.isPlayingItem ? "image://theme/media-playback-pause" : "image://theme/media-playback-start"
74+ activeFocusOnPress: false
74
75
75 // Can't be "transparent" or "#00xxxxxx" as the button optimizes away the surrounding shape
76 // Can't be "transparent" or "#00xxxxxx" as the button optimizes away the surrounding shape
76 // FIXME when this is resolved: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1251685
77 // FIXME when this is resolved: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1251685
@@ -84,7 +85,11 @@ PreviewWidget {
84 DashAudioPlayer.play();
85 DashAudioPlayer.play();
85 }
86 }
86 } else {
87 } else {
88+ var playlist = [];
89+ for (var i = 0; i < trackRepeater.count; ++i) {
90+ playlist.push(trackRepeater.itemAt(i).sourceUrl);
91+ }
87− DashAudioPlayer.playSource(sourceUrl);
92+ DashAudioPlayer.playSource(sourceUrl, playlist);
88 }
93 }
89 }
94 }
90 }
95 }
qml/Dash/Previews/PreviewHeader.qml+1−1
@@ -35,7 +35,7 @@ PreviewWidget {
35 Item {
35 Item {
36 id: headerRoot
36 id: headerRoot
37 objectName: "innerPreviewHeader"
37 objectName: "innerPreviewHeader"
38− readonly property url mascot: root.widgetData["mascot"] || ""
38+ readonly property url mascot: root.widgetData["mascot"] || fallback
39 readonly property url fallback: root.widgetData["fallback"] || ""
39 readonly property url fallback: root.widgetData["fallback"] || ""
40 readonly property string title: root.widgetData["title"] || ""
40 readonly property string title: root.widgetData["title"] || ""
41 readonly property string subtitle: root.widgetData["subtitle"] || ""
41 readonly property string subtitle: root.widgetData["subtitle"] || ""
qml/Dash/Previews/PreviewImageGallery.qml+2−2
@@ -59,7 +59,7 @@ PreviewWidget {
59 top: parent.top
59 top: parent.top
60 bottom: parent.bottom
60 bottom: parent.bottom
61 }
61 }
62− source: modelData ? modelData : ""
62+ source: modelData || root.widgetData["fallback"] || ""
63 scaleTo: "height"
63 scaleTo: "height"
64 initialWidth: units.gu(13)
64 initialWidth: units.gu(13)
65 pressed: mouseArea.pressed
65 pressed: mouseArea.pressed
@@ -128,7 +128,7 @@ PreviewWidget {
128 bottom: parent.bottom
128 bottom: parent.bottom
129 }
129 }
130 width: overlay.width
130 width: overlay.width
131− source: modelData ? modelData : ""
131+ source: modelData || root.widgetData["fallback"] || ""
132 fillMode: Image.PreserveAspectFit
132 fillMode: Image.PreserveAspectFit
133 sourceSize { width: screenshot.width; height: screenshot.height }
133 sourceSize { width: screenshot.width; height: screenshot.height }
134
134
qml/Dash/Previews/PreviewRatingEdit.qml+1
@@ -75,6 +75,7 @@ PreviewWidget {
75 reviewText: widgetData["review"]
75 reviewText: widgetData["review"]
76
76
77 onTriggered: root.triggered(widgetId, actionId, data);
77 onTriggered: root.triggered(widgetId, actionId, data);
78+ onMakeSureVisible: root.makeSureVisible(item);
78 }
79 }
79
80
80}
81}
qml/Dash/Previews/PreviewZoomableImage.qml+2−2
@@ -42,7 +42,7 @@ PreviewWidget {
42 right: parent.right
42 right: parent.right
43 }
43 }
44 scaleTo: "width"
44 scaleTo: "width"
45− source: widgetData["source"]
45+ source: widgetData["source"] || widgetData["fallback"] || ""
46 asynchronous: true
46 asynchronous: true
47 useUbuntuShape: false
47 useUbuntuShape: false
48 pressed: mouseArea.pressed
48 pressed: mouseArea.pressed
@@ -86,7 +86,7 @@ PreviewWidget {
86
86
87 delegate: ZoomableImage {
87 delegate: ZoomableImage {
88 anchors.fill: parent
88 anchors.fill: parent
89− source: widgetData["source"]
89+ source: widgetData["source"] || widgetData["fallback"] || ""
90 zoomable: widgetData["zoomable"] ? widgetData["zoomable"] : false
90 zoomable: widgetData["zoomable"] ? widgetData["zoomable"] : false
91 // If modelData would change after failing to load it would not be
91 // If modelData would change after failing to load it would not be
92 // reloaded since the source binding is destroyed by the source = fallback
92 // reloaded since the source binding is destroyed by the source = fallback
qml/Dash/graphics/paper.pngnew file

Binary file not shown.

qml/Dash/graphics/paper_landscape@27.pngdeleted

Binary file not shown.

qml/Dash/graphics/paper_portrait@27.pngdeleted

Binary file not shown.

qml/DisabledScreenNotice.qml+72−19
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2016 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -15,35 +15,88 @@
15 */
15 */
16
16
17import QtQuick 2.4
17import QtQuick 2.4
18+import QtQuick.Layouts 1.1
18import Ubuntu.Components 1.3
19import Ubuntu.Components 1.3
20+import QtQuick.Window 2.2
19import "Components"
21import "Components"
20
22
21−Image {
23+Item {
22 id: root
24 id: root
23
25
26+ property bool infoNoteDisplayed: true
27+
24 WallpaperResolver {
28 WallpaperResolver {
25 width: root.width
29 width: root.width
26 id: wallpaperResolver
30 id: wallpaperResolver
27 }
31 }
28
32
29− source: wallpaperResolver.background
33+ Item {
34+ id: contentContainer
35+ anchors.centerIn: parent
36+ height: rotation == 90 || rotation == 270 ? parent.width : parent.height
37+ width: rotation == 90 || rotation == 270 ? parent.height : parent.width
30
38
31− UbuntuShape {
39+ rotation: {
32− anchors.fill: text
40+ switch (Screen.orientation) {
33− anchors.margins: -units.gu(2)
41+ case Qt.PortraitOrientation:
34− backgroundColor: "black"
42+ return 0;
35− opacity: 0.4
43+ case Qt.LandscapeOrientation:
44+ return 270;
45+ case Qt.InvertedPortraitOrientation:
46+ return 180;
47+ case Qt.InvertedLandscapeOrientation:
48+ return 90;
36− }
49+ }
50+ }
51+ transformOrigin: Item.Center
37
52
53+ VirtualTouchPad {
54+ anchors.fill: parent
55+
56+ onPressedChanged: {
57+ if (pressed && infoNoteDisplayed) {
58+ infoNoteDisplayed = false;
59+ }
60+ }
61+ }
62+
63+ Image {
64+ anchors.fill: parent
65+ source: wallpaperResolver.background
66+ }
67+
68+ Item {
69+ objectName: "infoNoticeArea"
70+ anchors.fill: parent
71+ opacity: infoNoteDisplayed ? 1 : 0
72+ visible: opacity > 0
73+ Behavior on opacity {
74+ UbuntuNumberAnimation { }
75+ }
76+
77+ Rectangle {
78+ anchors.fill: parent
79+ color: "black"
80+ opacity: 0.4
81+ }
82+
38− Label {
83+ Label {
39− id: text
84+ id: text
40− anchors.centerIn: parent
85+ anchors.centerIn: parent
41− width: parent.width / 2
86+ width: parent.width - units.gu(8)
42− text: i18n.tr("Your device is now connected to an external display.")
87+ text: i18n.tr("Your device is now connected to an external display. Use this screen as a touch pad to interact with the mouse.")
43− color: "white"
88+ color: "white"
44− horizontalAlignment: Text.AlignHCenter
89+ horizontalAlignment: Text.AlignHCenter
45− verticalAlignment: Text.AlignVCenter
90+ verticalAlignment: Text.AlignVCenter
46− fontSize: "x-large"
91+ fontSize: "x-large"
47− wrapMode: Text.Wrap
92+ wrapMode: Text.Wrap
93+ }
94+ }
95+
96+ InputMethod {
97+ id: inputMethod
98+ objectName: "inputMethod"
99+ anchors.fill: parent
100+ }
48 }
101 }
49}
102}
qml/Greeter/Greeter.qml+2−1
@@ -288,6 +288,7 @@ Showable {
288 onSelected: {
288 onSelected: {
289 d.selectUser(index, true);
289 d.selectUser(index, true);
290 }
290 }
291+ onPromptlessLogin: d.login();
291 onResponded: {
292 onResponded: {
292 if (root.locked) {
293 if (root.locked) {
293 LightDMService.greeter.respond(response);
294 LightDMService.greeter.respond(response);
@@ -410,8 +411,8 @@ Showable {
410
411
411 if (LightDMService.greeter.authenticated) {
412 if (LightDMService.greeter.authenticated) {
412 AccountsService.failedLogins = 0;
413 AccountsService.failedLogins = 0;
413− d.login();
414 if (!LightDMService.greeter.promptless) {
414 if (!LightDMService.greeter.promptless) {
415+ d.login();
415 loader.item.hide();
416 loader.item.hide();
416 }
417 }
417 } else {
418 } else {
qml/Greeter/LoginList.qml+6−2
@@ -23,6 +23,7 @@ Item {
23 id: root
23 id: root
24
24
25 property alias model: userList.model
25 property alias model: userList.model
26+ property bool alphanumeric: true
26 property int currentIndex
27 property int currentIndex
27 property bool locked
28 property bool locked
28
29
@@ -36,13 +37,13 @@ Item {
36 readonly property string currentUser: userList.currentItem.username
37 readonly property string currentUser: userList.currentItem.username
37 property bool wasPrompted: false
38 property bool wasPrompted: false
38
39
40+ signal loginListSessionChanged(string session)
41+ signal promptlessLogin()
39 signal responded(string response)
42 signal responded(string response)
40 signal selected(int index)
43 signal selected(int index)
41 signal sessionChooserButtonClicked()
44 signal sessionChooserButtonClicked()
42− signal loginListSessionChanged(string session)
43
45
44 onCurrentSessionChanged: loginListSessionChanged(currentSession)
46 onCurrentSessionChanged: loginListSessionChanged(currentSession)
45−
46 function tryToUnlock() {
47 function tryToUnlock() {
47 if (wasPrompted) {
48 if (wasPrompted) {
48 passwordInput.forceActiveFocus();
49 passwordInput.forceActiveFocus();
@@ -50,6 +51,7 @@ Item {
50 if (root.locked) {
51 if (root.locked) {
51 root.selected(currentIndex);
52 root.selected(currentIndex);
52 } else {
53 } else {
54+ promptlessLogin();
53 root.responded("");
55 root.responded("");
54 }
56 }
55 }
57 }
@@ -277,6 +279,8 @@ Item {
277 width: parent.width - anchors.margins * 2
279 width: parent.width - anchors.margins * 2
278 opacity: userList.movingInternally ? 0 : 1
280 opacity: userList.movingInternally ? 0 : 1
279
281
282+ inputMethodHints: root.alphanumeric ? Qt.ImhNone : Qt.ImhDigitsOnly
283+
280 property string promptText
284 property string promptText
281 placeholderText: root.wasPrompted ? promptText
285 placeholderText: root.wasPrompted ? promptText
282 : (root.locked ? i18n.tr("Retry")
286 : (root.locked ? i18n.tr("Retry")
qml/Greeter/WideView.qml+2
@@ -41,6 +41,7 @@ FocusScope {
41 // so that it can be replaced in tests with a mock object
41 // so that it can be replaced in tests with a mock object
42 property var inputMethod: Qt.inputMethod
42 property var inputMethod: Qt.inputMethod
43
43
44+ signal promptlessLogin()
44 signal selected(int index)
45 signal selected(int index)
45 signal responded(string response)
46 signal responded(string response)
46 signal tease()
47 signal tease()
@@ -207,6 +208,7 @@ FocusScope {
207 loginAreaLoader.currentSession = loginAreaLoader.item.currentSession
208 loginAreaLoader.currentSession = loginAreaLoader.item.currentSession
208 }
209 }
209 }
210 }
211+ onPromptlessLogin: root.promptlessLogin()
210
212
211 onSessionChooserButtonClicked: loginListShown = false;
213 onSessionChooserButtonClicked: loginListShown = false;
212 ignoreUnknownSignals: true
214 ignoreUnknownSignals: true
qml/Launcher/Launcher.qml+18−19
@@ -51,9 +51,9 @@ Item {
51
51
52 onStateChanged: {
52 onStateChanged: {
53 if (state == "") {
53 if (state == "") {
54− dismissTimer.stop()
54+ panel.dismissTimer.stop()
55 } else {
55 } else {
56− dismissTimer.restart()
56+ panel.dismissTimer.restart()
57 }
57 }
58 }
58 }
59
59
@@ -96,21 +96,6 @@ Item {
96 property string mode: "teasing"
96 property string mode: "teasing"
97 }
97 }
98
98
99− Timer {
100− id: dismissTimer
101− objectName: "dismissTimer"
102− interval: 500
103− onTriggered: {
104− if (root.autohideEnabled) {
105− if (!panel.preventHiding) {
106− root.state = ""
107− } else {
108− dismissTimer.restart()
109− }
110− }
111− }
112− }
113−
114 // Because the animation on x is disabled while dragging
99 // Because the animation on x is disabled while dragging
115 // switching state directly in the drag handlers would not animate
100 // switching state directly in the drag handlers would not animate
116 // the completion of the hide/reveal gesture. Lets update the state
101 // the completion of the hide/reveal gesture. Lets update the state
@@ -238,6 +223,20 @@ Item {
238 visible: root.x > 0 || x > -width || dragArea.pressed
223 visible: root.x > 0 || x > -width || dragArea.pressed
239 model: LauncherModel
224 model: LauncherModel
240
225
226+ property var dismissTimer: Timer { interval: 500 }
227+ Connections {
228+ target: panel.dismissTimer
229+ onTriggered: {
230+ if (root.autohideEnabled) {
231+ if (!panel.preventHiding) {
232+ root.state = ""
233+ } else {
234+ panel.dismissTimer.restart()
235+ }
236+ }
237+ }
238+ }
239+
241 property bool animate: true
240 property bool animate: true
242
241
243 onApplicationSelected: {
242 onApplicationSelected: {
@@ -250,8 +249,8 @@ Item {
250 }
249 }
251
250
252 onPreventHidingChanged: {
251 onPreventHidingChanged: {
253− if (dismissTimer.running) {
252+ if (panel.dismissTimer.running) {
254− dismissTimer.restart();
253+ panel.dismissTimer.restart();
255 }
254 }
256 }
255 }
257
256
qml/OrientedShell.qml+28−14
@@ -18,6 +18,7 @@ import QtQuick 2.4
18import QtQuick.Window 2.2
18import QtQuick.Window 2.2
19import Unity.InputInfo 0.1
19import Unity.InputInfo 0.1
20import Unity.Session 0.1
20import Unity.Session 0.1
21+import Unity.Screens 0.1
21import GSettings 1.0
22import GSettings 1.0
22import "Components"
23import "Components"
23import "Rotation"
24import "Rotation"
@@ -78,6 +79,15 @@ Rectangle {
78 deviceFilter: InputInfo.Keyboard
79 deviceFilter: InputInfo.Keyboard
79 }
80 }
80
81
82+ InputDeviceModel {
83+ id: touchScreensModel
84+ deviceFilter: InputInfo.TouchScreen
85+ }
86+
87+ Screens {
88+ id: screens
89+ }
90+
81 property int orientation
91 property int orientation
82 onPhysicalOrientationChanged: {
92 onPhysicalOrientationChanged: {
83 if (!orientationLocked) {
93 if (!orientationLocked) {
@@ -97,8 +107,7 @@ Rectangle {
97 }
107 }
98 // We need to manually update this on startup as the binding
108 // We need to manually update this on startup as the binding
99 // below doesn't seem to have any effect at that stage
109 // below doesn't seem to have any effect at that stage
100− oskSettings.stayHidden = keyboardsModel.count > 0
101− oskSettings.disableHeight = shell.usageScenario == "desktop"
110+ oskSettings.disableHeight = !shell.oskEnabled || shell.usageScenario == "desktop"
102 }
111 }
103
112
104 // we must rotate to a supported orientation regardless of shell's preference
113 // we must rotate to a supported orientation regardless of shell's preference
@@ -106,17 +115,10 @@ Rectangle {
106 (shell.orientation & supportedOrientations) === 0 ? true
115 (shell.orientation & supportedOrientations) === 0 ? true
107 : shell.orientationChangesEnabled
116 : shell.orientationChangesEnabled
108
117
109−
110− Binding {
111− target: oskSettings
112− property: "stayHidden"
113− value: keyboardsModel.count > 0
114− }
115−
116 Binding {
118 Binding {
117 target: oskSettings
119 target: oskSettings
118 property: "disableHeight"
120 property: "disableHeight"
119− value: shell.usageScenario == "desktop"
121+ value: !shell.oskEnabled || shell.usageScenario == "desktop"
120 }
122 }
121
123
122 readonly property int supportedOrientations: shell.supportedOrientations
124 readonly property int supportedOrientations: shell.supportedOrientations
@@ -189,6 +191,11 @@ Rectangle {
189 nativeHeight: root.height
191 nativeHeight: root.height
190 mode: applicationArguments.mode
192 mode: applicationArguments.mode
191 hasMouse: miceModel.count + touchPadModel.count > 0
193 hasMouse: miceModel.count + touchPadModel.count > 0
194+ // TODO: Factor in if the current screen is a touch screen and if the user wants to
195+ // have multiple keyboards around. For now we only enable one keyboard at a time
196+ // thus hiding it here if there is a physical one around or if we have a second
197+ // screen (the virtual touchpad & osk on the phone) attached.
198+ oskEnabled: keyboardsModel.count === 0 && screens.count === 1
192
199
193 // TODO: Factor in the connected input devices (eg: physical keyboard, mouse, touchscreen),
200 // TODO: Factor in the connected input devices (eg: physical keyboard, mouse, touchscreen),
194 // what's the output device (eg: big TV, desktop monitor, phone display), etc.
201 // what's the output device (eg: big TV, desktop monitor, phone display), etc.
@@ -202,11 +209,18 @@ Rectangle {
202 return "tablet";
209 return "tablet";
203 }
210 }
204 } else { // automatic
211 } else { // automatic
212+ var longEdgeWidth = Math.max(root.width, root.height)
213+ if (longEdgeWidth > units.gu(120)) {
205− if (miceModel.count + touchPadModel.count > 0) {
214+ if (keyboardsModel.count + miceModel.count + touchPadModel.count > 0) {
206− return "desktop";
215+ return "desktop";
207− } else {
216+ }
208− return deviceConfiguration.category;
217+ } else if (longEdgeWidth > units.gu(90)){
218+ if (miceModel.count + touchPadModel.count > 0) {
219+ return "desktop";
220+ }
209 }
221 }
222+
223+ return deviceConfiguration.category;
210 }
224 }
211 }
225 }
212
226
qml/Panel/IndicatorItem.qml+57−7
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright 2013-2014 Canonical Ltd.
2+ * Copyright 2013-2016 Canonical Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
5 * it under the terms of the GNU Lesser General Public License as published by
@@ -17,6 +17,7 @@
17import QtQuick 2.4
17import QtQuick 2.4
18import Ubuntu.Components 1.3
18import Ubuntu.Components 1.3
19import Ubuntu.Settings.Components 0.1
19import Ubuntu.Settings.Components 0.1
20+import QMenuModel 0.1
20import "Indicators"
21import "Indicators"
21
22
22IndicatorDelegate {
23IndicatorDelegate {
@@ -36,13 +37,24 @@ IndicatorDelegate {
36 return "#ffffff";
37 return "#ffffff";
37 }
38 }
38
39
39− signal clicked()
40−
41 implicitWidth: mainItems.width
40 implicitWidth: mainItems.width
42
41
43 MouseArea {
42 MouseArea {
43+ readonly property int stepUp: 1
44+ readonly property int stepDown: -1
45+
44 anchors.fill: parent
46 anchors.fill: parent
47+ acceptedButtons: Qt.MiddleButton
45− onClicked: parent.clicked()
48+ onClicked: {
49+ if ((!expanded || selected) && secondaryAction.valid) {
50+ secondaryAction.activate();
51+ }
52+ }
53+ onWheel: {
54+ if ((!expanded || selected) && scrollAction.valid) {
55+ scrollAction.activate(wheel.angleDelta.y > 0 ? stepUp : stepDown);
56+ }
57+ }
46 }
58 }
47
59
48 Item {
60 Item {
@@ -152,9 +164,6 @@ IndicatorDelegate {
152 }
164 }
153
165
154 StateGroup {
166 StateGroup {
155− id: d
156− property bool useFallbackIcon: false
157−
158 states: [
167 states: [
159 State {
168 State {
160 name: "minimised"
169 name: "minimised"
@@ -251,4 +260,45 @@ IndicatorDelegate {
251 rightLabel = rootActionState.rightLabel ? rootActionState.rightLabel : "";
260 rightLabel = rootActionState.rightLabel ? rootActionState.rightLabel : "";
252 icons = rootActionState.icons;
261 icons = rootActionState.icons;
253 }
262 }
263+
264+ QtObject {
265+ id: d
266+
267+ property bool useFallbackIcon: false
268+ property var shouldIndicatorBeShown: undefined
269+
270+ onShouldIndicatorBeShownChanged: {
271+ if (shouldIndicatorBeShown !== undefined) {
272+ submenuAction.changeState(shouldIndicatorBeShown);
273+ }
274+ }
275+ }
276+
277+ UnityMenuAction {
278+ id: secondaryAction
279+ model: menuModel
280+ index: 0
281+ name: rootActionState.secondaryAction
282+ }
283+
284+ UnityMenuAction {
285+ id: scrollAction
286+ model: menuModel
287+ index: 0
288+ name: rootActionState.scrollAction
289+ }
290+
291+ UnityMenuAction {
292+ id: submenuAction
293+ model: menuModel
294+ index: 0
295+ name: rootActionState.submenuAction
296+ }
297+
298+ Binding {
299+ target: d
300+ property: "shouldIndicatorBeShown"
301+ when: submenuAction.valid
302+ value: root.selected && root.expanded
303+ }
254}
304}
qml/Panel/graphics/Battery@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Bluetooth@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Clock@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Location@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Messages@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Network@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Sound@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Sync@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/System@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Time@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/VerticalDivider@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/handle@12.pngdeleted

Binary file not shown.

qml/Panel/graphics/handle@12.scideleted−5
@@ -1,5 +0,0 @@
1−border.left: 0
2−border.top: 1
3−border.bottom: 0
4−border.right: 0
5−source: handle@12.png
qml/Panel/graphics/search@12.pngdeleted

Binary file not shown.

qml/Panel/graphics/time_and_date@18.pngdeleted

Binary file not shown.

qml/Shell.qml+15−6
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013-2015 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@ Item {
56 property bool beingResized
56 property bool beingResized
57 property string usageScenario: "phone" // supported values: "phone", "tablet" or "desktop"
57 property string usageScenario: "phone" // supported values: "phone", "tablet" or "desktop"
58 property string mode: "full-greeter"
58 property string mode: "full-greeter"
59− property bool cursorVisible: false
59+ property alias oskEnabled: inputMethod.enabled
60 function updateFocusedAppOrientation() {
60 function updateFocusedAppOrientation() {
61 applicationsDisplayLoader.item.updateFocusedAppOrientation();
61 applicationsDisplayLoader.item.updateFocusedAppOrientation();
62 }
62 }
@@ -84,8 +84,8 @@ Item {
84 return Qt.PrimaryOrientation;
84 return Qt.PrimaryOrientation;
85 } else if (greeter && greeter.shown) {
85 } else if (greeter && greeter.shown) {
86 return Qt.PrimaryOrientation;
86 return Qt.PrimaryOrientation;
87− } else if (mainApp) {
87+ } else if (applicationsDisplayLoader.item) {
88− return shell.orientations.map(mainApp.supportedOrientations);
88+ return shell.orientations.map(applicationsDisplayLoader.item.supportedOrientations);
89 } else {
89 } else {
90 // we just don't care
90 // we just don't care
91 return Qt.PortraitOrientation
91 return Qt.PortraitOrientation
@@ -175,8 +175,15 @@ Item {
175 Keys.onReleased: physicalKeysMapper.onKeyReleased(event, currentEventTimestamp);
175 Keys.onReleased: physicalKeysMapper.onKeyReleased(event, currentEventTimestamp);
176 }
176 }
177
177
178− HomeKeyWatcher {
178+ WindowInputMonitor {
179− onActivated: { launcher.fadeOut(); shell.showHome(); }
179+ onHomeKeyActivated: { launcher.fadeOut(); shell.showHome(); }
180+ onTouchBegun: { cursor.opacity = 0; }
181+ onTouchEnded: {
182+ // move the (hidden) cursor to the last known touch position
183+ var mappedCoords = mapFromItem(null, pos.x, pos.y);
184+ cursor.x = mappedCoords.x;
185+ cursor.y = mappedCoords.y;
186+ }
180 }
187 }
181
188
182 Item {
189 Item {
@@ -676,6 +683,8 @@ Item {
676 applicationsDisplayLoader.item.pushRightEdge(amount);
683 applicationsDisplayLoader.item.pushRightEdge(amount);
677 }
684 }
678 }
685 }
686+
687+ onMouseMoved: { cursor.opacity = 1; }
679 }
688 }
680
689
681 Rectangle {
690 Rectangle {
qml/Stages/AbstractStage.qml+5−1
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2015-2016 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -44,6 +44,10 @@ Rectangle {
44 property var mainApp: null
44 property var mainApp: null
45 property int mainAppWindowOrientationAngle
45 property int mainAppWindowOrientationAngle
46 property bool orientationChangesEnabled
46 property bool orientationChangesEnabled
47+ property int supportedOrientations: Qt.PortraitOrientation
48+ | Qt.LandscapeOrientation
49+ | Qt.InvertedPortraitOrientation
50+ | Qt.InvertedLandscapeOrientation
47
51
48 // Shared code for use in stage implementations
52 // Shared code for use in stage implementations
49 GSettings {
53 GSettings {
qml/Stages/ApplicationWindow.qml+14−1
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright 2014-2015 Canonical Ltd.
2+ * Copyright 2014-2016 Canonical Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
5 * it under the terms of the GNU Lesser General Public License as published by
@@ -37,6 +37,13 @@ FocusScope {
37 property int requestedWidth: -1
37 property int requestedWidth: -1
38 property int requestedHeight: -1
38 property int requestedHeight: -1
39
39
40+ readonly property int minimumWidth: sessionContainer.surface ? sessionContainer.surface.minimumWidth : 0
41+ readonly property int minimumHeight: sessionContainer.surface ? sessionContainer.surface.minimumHeight : 0
42+ readonly property int maximumWidth: sessionContainer.surface ? sessionContainer.surface.maximumWidth : 0
43+ readonly property int maximumHeight: sessionContainer.surface ? sessionContainer.surface.maximumHeight : 0
44+ readonly property int widthIncrement: sessionContainer.surface ? sessionContainer.surface.widthIncrement : 0
45+ readonly property int heightIncrement: sessionContainer.surface ? sessionContainer.surface.heightIncrement : 0
46+
40 QtObject {
47 QtObject {
41 id: d
48 id: d
42
49
@@ -82,6 +89,12 @@ FocusScope {
82 property bool surfaceOldEnoughToBeResized: false
89 property bool surfaceOldEnoughToBeResized: false
83 }
90 }
84
91
92+ Binding {
93+ target: root.application
94+ property: "initialSurfaceSize"
95+ value: Qt.size(root.requestedWidth, root.requestedHeight)
96+ }
97+
85 Timer {
98 Timer {
86 id: surfaceInitTimer
99 id: surfaceInitTimer
87 interval: 100
100 interval: 100
qml/Stages/DecoratedWindow.qml+7
@@ -39,6 +39,13 @@ FocusScope {
39 property alias requestedWidth: applicationWindow.requestedWidth
39 property alias requestedWidth: applicationWindow.requestedWidth
40 property real requestedHeight
40 property real requestedHeight
41
41
42+ property alias minimumWidth: applicationWindow.minimumWidth
43+ readonly property int minimumHeight: (root.decorationShown ? decoration.height : 0) + applicationWindow.minimumHeight
44+ property alias maximumWidth: applicationWindow.maximumWidth
45+ readonly property int maximumHeight: (root.decorationShown ? decoration.height : 0) + applicationWindow.maximumHeight
46+ property alias widthIncrement: applicationWindow.widthIncrement
47+ property alias heightIncrement: applicationWindow.heightIncrement
48+
42 signal close()
49 signal close()
43 signal maximize()
50 signal maximize()
44 signal minimize()
51 signal minimize()
qml/Stages/DesktopStage.qml+12−1
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2014-2015 Canonical, Ltd.
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -40,6 +40,11 @@ AbstractStage {
40 ? ApplicationManager.findApplication(ApplicationManager.focusedApplicationId)
40 ? ApplicationManager.findApplication(ApplicationManager.focusedApplicationId)
41 : null
41 : null
42
42
43+ // application windows never rotate independently
44+ mainAppWindowOrientationAngle: shellOrientationAngle
45+
46+ orientationChangesEnabled: true
47+
43 Connections {
48 Connections {
44 target: ApplicationManager
49 target: ApplicationManager
45 onApplicationAdded: {
50 onApplicationAdded: {
@@ -251,6 +256,12 @@ AbstractStage {
251 height: decoratedWindow.height
256 height: decoratedWindow.height
252 property alias requestedWidth: decoratedWindow.requestedWidth
257 property alias requestedWidth: decoratedWindow.requestedWidth
253 property alias requestedHeight: decoratedWindow.requestedHeight
258 property alias requestedHeight: decoratedWindow.requestedHeight
259+ property alias minimumWidth: decoratedWindow.minimumWidth
260+ property alias minimumHeight: decoratedWindow.minimumHeight
261+ property alias maximumWidth: decoratedWindow.maximumWidth
262+ property alias maximumHeight: decoratedWindow.maximumHeight
263+ property alias widthIncrement: decoratedWindow.widthIncrement
264+ property alias heightIncrement: decoratedWindow.heightIncrement
254
265
255 QtObject {
266 QtObject {
256 id: appDelegatePrivate
267 id: appDelegatePrivate
qml/Stages/PhoneStage.qml+5−1
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2014-2015 Canonical, Ltd.
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -83,6 +83,10 @@ AbstractStage {
83 && !(priv.focusedAppDelegate && priv.focusedAppDelegate.xBehavior.running)
83 && !(priv.focusedAppDelegate && priv.focusedAppDelegate.xBehavior.running)
84 && spreadView.phase === 0
84 && spreadView.phase === 0
85
85
86+ supportedOrientations: mainApp ? mainApp.supportedOrientations
87+ : (Qt.PortraitOrientation | Qt.LandscapeOrientation
88+ | Qt.InvertedPortraitOrientation | Qt.InvertedLandscapeOrientation)
89+
86 // How far left the stage has been dragged
90 // How far left the stage has been dragged
87 readonly property real dragProgress: spreadRepeater.count > 0 ? -spreadRepeater.itemAt(0).xTranslate : 0
91 readonly property real dragProgress: spreadRepeater.count > 0 ? -spreadRepeater.itemAt(0).xTranslate : 0
88
92
qml/Stages/SessionContainer.qml+2
@@ -152,6 +152,8 @@ FocusScope {
152 popped.completed.connect(function() { root.session.release(); } );
152 popped.completed.connect(function() { root.session.release(); } );
153 popped.end();
153 popped.end();
154 d.animations = tmp;
154 d.animations = tmp;
155+ } else {
156+ root.session.release();
155 }
157 }
156 }
158 }
157
159
qml/Stages/Splash.qml+7−2
@@ -138,15 +138,20 @@ Item {
138 visible: d.showIcon
138 visible: d.showIcon
139 }
139 }
140
140
141+ Timer {
142+ interval: 2000
143+ onTriggered: spinner.running = true
144+ running: true
145+ }
146+
141 ActivityIndicator {
147 ActivityIndicator {
148+ id: spinner
142 anchors.centerIn: header.visible ? parent : undefined
149 anchors.centerIn: header.visible ? parent : undefined
143 anchors.verticalCenterOffset: header.visible ? header.height / 2 : 0
150 anchors.verticalCenterOffset: header.visible ? header.height / 2 : 0
144
151
145 anchors.horizontalCenter: header.visible ? undefined : parent.horizontalCenter
152 anchors.horizontalCenter: header.visible ? undefined : parent.horizontalCenter
146 anchors.bottom: header.visible ? undefined : parent.bottom
153 anchors.bottom: header.visible ? undefined : parent.bottom
147 anchors.bottomMargin: header.visible ? 0 : units.gu(12)
154 anchors.bottomMargin: header.visible ? 0 : units.gu(12)
148−
149− running: true
150 }
155 }
151
156
152 MouseArea {
157 MouseArea {
qml/Stages/TabletStage.qml+5−1
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2014-2015 Canonical, Ltd.
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -72,6 +72,10 @@ AbstractStage {
72
72
73 orientationChangesEnabled: priv.mainAppOrientationChangesEnabled
73 orientationChangesEnabled: priv.mainAppOrientationChangesEnabled
74
74
75+ supportedOrientations: mainApp ? mainApp.supportedOrientations
76+ : (Qt.PortraitOrientation | Qt.LandscapeOrientation
77+ | Qt.InvertedPortraitOrientation | Qt.InvertedLandscapeOrientation)
78+
75 onWidthChanged: {
79 onWidthChanged: {
76 spreadView.selectedIndex = -1;
80 spreadView.selectedIndex = -1;
77 spreadView.phase = 0;
81 spreadView.phase = 0;
qml/Stages/WindowResizeArea.qml+95−16
@@ -72,8 +72,8 @@ MouseArea {
72 var windowGeometry = windowStateStorage.getGeometry(root.windowId,
72 var windowGeometry = windowStateStorage.getGeometry(root.windowId,
73 Qt.rect(target.x, target.y, defaultWidth, defaultHeight));
73 Qt.rect(target.x, target.y, defaultWidth, defaultHeight));
74
74
75− target.requestedWidth = Math.min(Math.max(windowGeometry.width, minWidth), screenWidth);
75+ target.requestedWidth = Math.min(Math.max(windowGeometry.width, d.minimumWidth), screenWidth);
76− target.requestedHeight = Math.min(Math.max(windowGeometry.height, minHeight), root.screenHeight - PanelState.panelHeight);
76+ target.requestedHeight = Math.min(Math.max(windowGeometry.height, d.minimumHeight), root.screenHeight - PanelState.panelHeight);
77 target.x = Math.max(Math.min(windowGeometry.x, root.screenWidth - target.requestedWidth), 0)
77 target.x = Math.max(Math.min(windowGeometry.x, root.screenWidth - target.requestedWidth), 0)
78 target.y = Math.max(Math.min(windowGeometry.y, root.screenHeight - target.requestedHeight), PanelState.panelHeight)
78 target.y = Math.max(Math.min(windowGeometry.y, root.screenHeight - target.requestedHeight), PanelState.panelHeight)
79
79
@@ -91,6 +91,65 @@ MouseArea {
91
91
92 QtObject {
92 QtObject {
93 id: d
93 id: d
94+
95+ readonly property int maxSafeInt: 2147483647
96+ readonly property int maxSizeIncrement: units.gu(40)
97+
98+ readonly property int minimumWidth: root.target ? Math.max(root.minWidth, root.target.minimumWidth) : root.minWidth
99+ onMinimumWidthChanged: {
100+ if (target.requestedWidth < minimumWidth) {
101+ target.requestedWidth = minimumWidth;
102+ }
103+ }
104+ readonly property int minimumHeight: root.target ? Math.max(root.minHeight, root.target.minimumHeight) : root.minHeight
105+ onMinimumHeightChanged: {
106+ if (target.requestedHeight < minimumHeight) {
107+ target.requestedHeight = minimumHeight;
108+ }
109+ }
110+ readonly property int maximumWidth: root.target && root.target.maximumWidth >= minimumWidth && root.target.maximumWidth > 0
111+ ? root.target.maximumWidth : maxSafeInt
112+ onMaximumWidthChanged: {
113+ if (target.requestedWidth > maximumWidth) {
114+ target.requestedWidth = maximumWidth;
115+ }
116+ }
117+ readonly property int maximumHeight: root.target && root.target.maximumHeight >= minimumHeight && root.target.maximumHeight > 0
118+ ? root.target.maximumHeight : maxSafeInt
119+ onMaximumHeightChanged: {
120+ if (target.requestedHeight > maximumHeight) {
121+ target.requestedHeight = maximumHeight;
122+ }
123+ }
124+ readonly property int widthIncrement: {
125+ if (!root.target) {
126+ return 1;
127+ }
128+ if (root.target.widthIncrement > 0) {
129+ if (root.target.widthIncrement < maxSizeIncrement) {
130+ return root.target.widthIncrement;
131+ } else {
132+ return maxSizeIncrement;
133+ }
134+ } else {
135+ return 1;
136+ }
137+ }
138+ readonly property int heightIncrement: {
139+ if (!root.target) {
140+ return 1;
141+ }
142+ if (root.target.heightIncrement > 0) {
143+ if (root.target.heightIncrement < maxSizeIncrement) {
144+ return root.target.heightIncrement;
145+ } else {
146+ return maxSizeIncrement;
147+ }
148+ } else {
149+ return 1;
150+ }
151+ }
152+
94 property bool leftBorder: false
153 property bool leftBorder: false
95 property bool rightBorder: false
154 property bool rightBorder: false
96 property bool topBorder: false
155 property bool topBorder: false
@@ -209,38 +268,58 @@ MouseArea {
209
268
210 var pos = mapToItem(target.parent, mouse.x, mouse.y);
269 var pos = mapToItem(target.parent, mouse.x, mouse.y);
211
270
212− var deltaX = pos.x - d.startMousePosX;
271+ var deltaX = Math.floor((pos.x - d.startMousePosX) / d.widthIncrement) * d.widthIncrement;
213− var deltaY = pos.y - d.startMousePosY;
272+ var deltaY = Math.floor((pos.y - d.startMousePosY) / d.heightIncrement) * d.heightIncrement;
214
273
215 if (d.leftBorder) {
274 if (d.leftBorder) {
216 var newTargetX = d.startX + deltaX;
275 var newTargetX = d.startX + deltaX;
217− if (target.x + target.width > newTargetX + minWidth) {
276+ var rightBorderX = target.x + target.width;
218− target.requestedWidth = target.x + target.width - newTargetX;
277+ if (rightBorderX > newTargetX + d.minimumWidth) {
278+ if (rightBorderX < newTargetX + d.maximumWidth) {
279+ target.requestedWidth = rightBorderX - newTargetX;
280+ } else {
281+ target.requestedWidth = d.maximumWidth;
282+ }
219 } else {
283 } else {
220− target.requestedWidth = minWidth;
284+ target.requestedWidth = d.minimumWidth;
221 }
285 }
222
286
223 } else if (d.rightBorder) {
287 } else if (d.rightBorder) {
224− if (d.startWidth + deltaX >= minWidth) {
288+ var newWidth = d.startWidth + deltaX;
289+ if (newWidth > d.minimumWidth) {
290+ if (newWidth < d.maximumWidth) {
225− target.requestedWidth = d.startWidth + deltaX;
291+ target.requestedWidth = newWidth;
292+ } else {
293+ target.requestedWidth = d.maximumWidth;
294+ }
226 } else {
295 } else {
227− target.requestedWidth = minWidth;
296+ target.requestedWidth = d.minimumWidth;
228 }
297 }
229 }
298 }
230
299
231 if (d.topBorder) {
300 if (d.topBorder) {
232 var newTargetY = d.startY + deltaY;
301 var newTargetY = d.startY + deltaY;
233− if (target.y + target.height > newTargetY + minHeight) {
302+ var bottomBorderY = target.y + target.height;
234− target.requestedHeight = target.y + target.height - newTargetY;
303+ if (bottomBorderY > newTargetY + d.minimumHeight) {
304+ if (bottomBorderY < newTargetY + d.maximumHeight) {
305+ target.requestedHeight = bottomBorderY - newTargetY;
306+ } else {
307+ target.requestedHeight = d.maximumHeight;
308+ }
235 } else {
309 } else {
236− target.requestedHeight = minHeight;
310+ target.requestedHeight = d.minimumHeight;
237 }
311 }
238
312
239 } else if (d.bottomBorder) {
313 } else if (d.bottomBorder) {
240− if (d.startHeight + deltaY >= minHeight) {
314+ var newHeight = d.startHeight + deltaY;
315+ if (newHeight > d.minimumHeight) {
316+ if (newHeight < d.maximumHeight) {
241− target.requestedHeight = d.startHeight + deltaY;
317+ target.requestedHeight = newHeight;
318+ } else {
319+ target.requestedHeight = d.maximumHeight;
320+ }
242 } else {
321 } else {
243− target.requestedHeight = minHeight;
322+ target.requestedHeight = d.minimumHeight;
244 }
323 }
245 }
324 }
246 }
325 }
qml/Wizard/Pages/10-welcome.qml+1−1
@@ -41,7 +41,7 @@ LocalComponents.Page {
41 anchors.left: parent.left
41 anchors.left: parent.left
42 anchors.right: parent.right
42 anchors.right: parent.right
43 wrapMode: Text.Wrap
43 wrapMode: Text.Wrap
44− text: i18n.tr("Welcome to your Ubuntu phone.")
44+ text: i18n.tr("Welcome to your Ubuntu device.")
45 }
45 }
46
46
47 Label {
47 Label {
qml/Wizard/Pages/30-passwd-type.qml+1−1
@@ -76,7 +76,7 @@ LocalComponents.Page {
76 anchors.left: parent.left
76 anchors.left: parent.left
77 anchors.right: parent.right
77 anchors.right: parent.right
78 wrapMode: Text.Wrap
78 wrapMode: Text.Wrap
79− text: i18n.tr("Please select how you’d like to unlock your phone.")
79+ text: i18n.tr("Please select how you’d like to unlock your device.")
80 }
80 }
81
81
82 ItemSelector {
82 ItemSelector {
qml/Wizard/Pages/80-finished.qml+1−1
@@ -43,7 +43,7 @@ LocalComponents.Page {
43 anchors.left: parent.left
43 anchors.left: parent.left
44 anchors.right: parent.right
44 anchors.right: parent.right
45 wrapMode: Text.Wrap
45 wrapMode: Text.Wrap
46− text: i18n.tr("Your phone is now ready to use.")
46+ text: i18n.tr("Your device is now ready to use.")
47 }
47 }
48 }
48 }
49
49
src/ShellApplication.cpp+7−5
@@ -112,13 +112,15 @@ ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
112 }
112 }
113
113
114 if (parser.mode().compare("greeter") == 0) {
114 if (parser.mode().compare("greeter") == 0) {
115+ QSize primaryScreenSize = this->primaryScreen()->size();
116+ m_shellView->setHeight(primaryScreenSize.height());
117+ m_shellView->setWidth(primaryScreenSize.width());
118+ m_shellView->show();
119+ m_shellView->requestActivate();
115− QString upstartCmd = "/sbin/initctl emit --no-wait unity8-greeter-started";
120+ if (!QProcess::startDetached("/sbin/initctl emit --no-wait unity8-greeter-started")) {
116− if (!QProcess::startDetached(upstartCmd)) {
117 qDebug() << "Unable to send unity8-greeter-started event to Upstart";
121 qDebug() << "Unable to send unity8-greeter-started event to Upstart";
118 }
122 }
119− }
120−
121− if (isMirServer || parser.hasFullscreen()) {
123+ } else if (isMirServer || parser.hasFullscreen()) {
122 m_shellView->showFullScreen();
124 m_shellView->showFullScreen();
123 } else {
125 } else {
124 m_shellView->show();
126 m_shellView->show();
tests/mocks/CMakeLists.txt+1
@@ -43,6 +43,7 @@ add_subdirectory(Unity)
43add_subdirectory(QtMultimedia)
43add_subdirectory(QtMultimedia)
44add_subdirectory(Wizard)
44add_subdirectory(Wizard)
45add_subdirectory(Utils)
45add_subdirectory(Utils)
46+add_subdirectory(UInput)
46
47
47install(
48install(
48 DIRECTORY data
49 DIRECTORY data
tests/mocks/Cursor/Cursor.qml+1
@@ -19,4 +19,5 @@ import QtQuick 2.4
19Item {
19Item {
20 signal pushedLeftBoundary(real amount, int buttons)
20 signal pushedLeftBoundary(real amount, int buttons)
21 signal pushedRightBoundary(real amount, int buttons)
21 signal pushedRightBoundary(real amount, int buttons)
22+ signal mouseMoved()
22}
23}
tests/mocks/UInput/CMakeLists.txtnew file+7
@@ -0,0 +1,7 @@
1+add_library(FakeUInput-qml MODULE
2+ plugin.cpp
3+ mockuinput.cpp
4+)
5+
6+qt5_use_modules(FakeUInput-qml Qml)
7+add_unity8_mock(UInput 0.1 UInput TARGETS FakeUInput-qml)
tests/mocks/UInput/mockuinput.cppnew file+73
@@ -0,0 +1,73 @@
1+/*
2+ * Copyright (C) 2015 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+
18+#include "mockuinput.h"
19+
20+#include <QFile>
21+#include <QDebug>
22+#include <QDateTime>
23+
24+#include <unistd.h>
25+
26+MockUInput::MockUInput(QObject *parent) :
27+ QObject(parent)
28+{
29+}
30+
31+MockUInput::~MockUInput()
32+{
33+}
34+
35+void MockUInput::createMouse()
36+{
37+ if (m_mouseCreated) {
38+ qDebug() << "Already have a virtual device. Not creating another one.";
39+ return;
40+ }
41+ m_mouseCreated = true;
42+ Q_EMIT mouseCreated();
43+}
44+
45+void MockUInput::removeMouse()
46+{
47+ if (!m_mouseCreated) {
48+ return;
49+ }
50+ qDebug() << "Virtual uinput mouse device removed.";
51+ m_mouseCreated = false;
52+ Q_EMIT mouseRemoved();
53+}
54+
55+void MockUInput::moveMouse(int dx, int dy)
56+{
57+ Q_EMIT mouseMoved(dx, dy);
58+}
59+
60+void MockUInput::pressMouse(Button button)
61+{
62+ Q_EMIT mousePressed(button);
63+}
64+
65+void MockUInput::releaseMouse(Button button)
66+{
67+ Q_EMIT mouseReleased(button);
68+}
69+
70+void MockUInput::scrollMouse(int dh, int dv)
71+{
72+ Q_EMIT mouseScrolled(dh, dv);
73+}
tests/mocks/UInput/mockuinput.hnew file+63
@@ -0,0 +1,63 @@
1+/*
2+ * Copyright (C) 2015 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+
18+#ifndef MOCKUINPUT_H
19+#define MOCKUINPUT_H
20+
21+#include <QObject>
22+#include <QFile>
23+
24+#include <linux/uinput.h>
25+
26+
27+class MockUInput : public QObject
28+{
29+ Q_OBJECT
30+ Q_ENUMS(Button)
31+
32+public:
33+ enum Button {
34+ ButtonLeft,
35+ ButtonRight,
36+ ButtonMiddle
37+ };
38+
39+ explicit MockUInput(QObject *parent = nullptr);
40+ ~MockUInput();
41+
42+ Q_INVOKABLE void createMouse();
43+ Q_INVOKABLE void removeMouse();
44+
45+ Q_INVOKABLE void moveMouse(int dx, int dy);
46+ Q_INVOKABLE void pressMouse(Button button);
47+ Q_INVOKABLE void releaseMouse(Button button);
48+ Q_INVOKABLE void scrollMouse(int dh, int dv);
49+
50+Q_SIGNALS:
51+ // for testing
52+ void mouseCreated();
53+ void mouseRemoved();
54+ void mouseMoved(int dx, int dy);
55+ void mousePressed(Button button);
56+ void mouseReleased(Button button);
57+ void mouseScrolled(int dh, int dv);
58+
59+private:
60+ bool m_mouseCreated = false;
61+};
62+
63+#endif // MOCKUINPUT_H
tests/mocks/UInput/plugin.cppnew file+26
@@ -0,0 +1,26 @@
1+/*
2+ * Copyright (C) 2015 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "plugin.h"
18+#include "mockuinput.h"
19+
20+#include <QtQml/qqml.h>
21+
22+void MockUInputPlugin::registerTypes(const char *uri)
23+{
24+ Q_ASSERT(uri == QLatin1String("UInput"));
25+ qmlRegisterType<MockUInput>(uri, 0, 1, "UInput");
26+}
tests/mocks/UInput/plugin.hnew file+32
@@ -0,0 +1,32 @@
1+/*
2+ * Copyright (C) 2015 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 MOCKUINPUT_PLUGIN_H
18+#define MOCKUINPUT_PLUGIN_H
19+
20+#include <QtQml/QQmlEngine>
21+#include <QtQml/QQmlExtensionPlugin>
22+
23+class MockUInputPlugin : 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) override;
30+};
31+
32+#endif
tests/mocks/UInput/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module UInput
2+plugin FakeUInput-qml
tests/mocks/Unity/Application/ApplicationInfo.cpp+14−1
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013-2015 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -278,3 +278,16 @@ void ApplicationInfo::setExemptFromLifecycle(bool exemptFromLifecycle)
278 Q_EMIT exemptFromLifecycleChanged(m_exemptFromLifecycle);
278 Q_EMIT exemptFromLifecycleChanged(m_exemptFromLifecycle);
279 }
279 }
280}
280}
281+
282+QSize ApplicationInfo::initialSurfaceSize() const
283+{
284+ return m_initialSurfaceSize;
285+}
286+
287+void ApplicationInfo::setInitialSurfaceSize(const QSize &size)
288+{
289+ if (size != m_initialSurfaceSize) {
290+ m_initialSurfaceSize = size;
291+ Q_EMIT initialSurfaceSizeChanged(m_initialSurfaceSize);
292+ }
293+}
tests/mocks/Unity/Application/ApplicationInfo.h+4−1
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013-2015 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -95,6 +95,8 @@ public:
95 bool exemptFromLifecycle() const override;
95 bool exemptFromLifecycle() const override;
96 void setExemptFromLifecycle(bool) override;
96 void setExemptFromLifecycle(bool) override;
97
97
98+ QSize initialSurfaceSize() const override;
99+ void setInitialSurfaceSize(const QSize &size) override;
98public:
100public:
99 void setSession(Session* session);
101 void setSession(Session* session);
100 Session* session() const { return m_session; }
102 Session* session() const { return m_session; }
@@ -129,6 +131,7 @@ private:
129 RequestedState m_requestedState;
131 RequestedState m_requestedState;
130 bool m_isTouchApp;
132 bool m_isTouchApp;
131 bool m_exemptFromLifecycle;
133 bool m_exemptFromLifecycle;
134+ QSize m_initialSurfaceSize;
132
135
133 bool m_manualSurfaceCreation;
136 bool m_manualSurfaceCreation;
134};
137};
tests/mocks/Unity/Application/ApplicationTestInterface.cpp+4−4
@@ -36,7 +36,7 @@ ApplicationTestInterface::ApplicationTestInterface(QObject* parent)
36 connection.registerObject("/com/canonical/Unity8/Mocks", parent);
36 connection.registerObject("/com/canonical/Unity8/Mocks", parent);
37}
37}
38
38
39−Session* ApplicationTestInterface::addChildSession(Session* existingSession, const QString& surfaceImage)
39+Session* ApplicationTestInterface::addChildSession(Session* existingSession, const QString& surfaceImage, bool addSurface)
40{
40{
41 if (!existingSession) return nullptr;
41 if (!existingSession) return nullptr;
42
42
@@ -49,7 +49,7 @@ Session* ApplicationTestInterface::addChildSession(Session* existingSession, con
49 .arg(existingSession->childSessions()->count()),
49 .arg(existingSession->childSessions()->count()),
50 screenshotUrl);
50 screenshotUrl);
51 existingSession->addChildSession(session);
51 existingSession->addChildSession(session);
52− session->createSurface();
52+ if (addSurface) session->createSurface();
53
53
54 return session;
54 return session;
55}
55}
@@ -70,7 +70,7 @@ void ApplicationTestInterface::removeSurface(MirSurface* existingSurface)
70 existingSurface->setLive(false);
70 existingSurface->setLive(false);
71}
71}
72
72
73−quint32 ApplicationTestInterface::addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage)
73+quint32 ApplicationTestInterface::addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage, bool addSurface)
74{
74{
75 qDebug() << "ApplicationTestInterface::addChildSession to " << appId;
75 qDebug() << "ApplicationTestInterface::addChildSession to " << appId;
76
76
@@ -100,7 +100,7 @@ quint32 ApplicationTestInterface::addChildSession(const QString& appId, quint32
100 .arg(parentSession->childSessions()->count()),
100 .arg(parentSession->childSessions()->count()),
101 screenshotUrl);
101 screenshotUrl);
102 parentSession->addChildSession(session);
102 parentSession->addChildSession(session);
103− session->createSurface();
103+ if (addSurface) { session->createSurface(); }
104 m_childSessions[sessionId] = session;
104 m_childSessions[sessionId] = session;
105
105
106 return sessionId;
106 return sessionId;
tests/mocks/Unity/Application/ApplicationTestInterface.h+2−2
@@ -30,12 +30,12 @@ class ApplicationTestInterface : public QDBusAbstractAdaptor
30public:
30public:
31 ApplicationTestInterface(QObject* parent = 0);
31 ApplicationTestInterface(QObject* parent = 0);
32
32
33− Q_INVOKABLE Session* addChildSession(Session* existingSession, const QString& surfaceImage);
33+ Q_INVOKABLE Session* addChildSession(Session* existingSession, const QString& surfaceImage, bool addSurface);
34 Q_INVOKABLE void removeSession(Session* existingSession);
34 Q_INVOKABLE void removeSession(Session* existingSession);
35 Q_INVOKABLE void removeSurface(MirSurface* existingSurface);
35 Q_INVOKABLE void removeSurface(MirSurface* existingSurface);
36
36
37public Q_SLOTS:
37public Q_SLOTS:
38− quint32 addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage);
38+ quint32 addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage, bool addSurface);
39 void removeSession(quint32 sessionId);
39 void removeSession(quint32 sessionId);
40
40
41private:
41private:
tests/mocks/Unity/Application/MirSurface.cpp+48
@@ -266,3 +266,51 @@ void MirSurface::setSlowToResize(bool value)
266 }
266 }
267 }
267 }
268}
268}
269+
270+void MirSurface::setMinimumWidth(int value)
271+{
272+ if (value != m_minimumWidth) {
273+ m_minimumWidth = value;
274+ Q_EMIT minimumWidthChanged(m_minimumWidth);
275+ }
276+}
277+
278+void MirSurface::setMaximumWidth(int value)
279+{
280+ if (value != m_maximumWidth) {
281+ m_maximumWidth = value;
282+ Q_EMIT maximumWidthChanged(m_maximumWidth);
283+ }
284+}
285+
286+void MirSurface::setMinimumHeight(int value)
287+{
288+ if (value != m_minimumHeight) {
289+ m_minimumHeight = value;
290+ Q_EMIT minimumHeightChanged(m_minimumHeight);
291+ }
292+}
293+
294+void MirSurface::setMaximumHeight(int value)
295+{
296+ if (value != m_maximumHeight) {
297+ m_maximumHeight = value;
298+ Q_EMIT maximumHeightChanged(m_maximumHeight);
299+ }
300+}
301+
302+void MirSurface::setWidthIncrement(int value)
303+{
304+ if (value != m_widthIncrement) {
305+ m_widthIncrement = value;
306+ Q_EMIT widthIncrementChanged(m_widthIncrement);
307+ }
308+}
309+
310+void MirSurface::setHeightIncrement(int value)
311+{
312+ if (value != m_heightIncrement) {
313+ m_heightIncrement = value;
314+ Q_EMIT heightIncrementChanged(m_heightIncrement);
315+ }
316+}
tests/mocks/Unity/Application/MirSurface.h+21
@@ -66,6 +66,13 @@ public:
66 Mir::OrientationAngle orientationAngle() const override;
66 Mir::OrientationAngle orientationAngle() const override;
67 void setOrientationAngle(Mir::OrientationAngle) override;
67 void setOrientationAngle(Mir::OrientationAngle) override;
68
68
69+ int minimumWidth() const override { return m_minimumWidth; }
70+ int minimumHeight() const override { return m_minimumHeight; }
71+ int maximumWidth() const override { return m_maximumWidth; }
72+ int maximumHeight() const override { return m_maximumHeight; }
73+ int widthIncrement() const override { return m_widthIncrement; }
74+ int heightIncrement() const override { return m_heightIncrement; }
75+
69 ////
76 ////
70 // API for tests
77 // API for tests
71
78
@@ -82,6 +89,13 @@ public:
82 bool isSlowToResize() const;
89 bool isSlowToResize() const;
83 void setSlowToResize(bool value);
90 void setSlowToResize(bool value);
84
91
92+ Q_INVOKABLE void setMinimumWidth(int);
93+ Q_INVOKABLE void setMaximumWidth(int);
94+ Q_INVOKABLE void setMinimumHeight(int);
95+ Q_INVOKABLE void setMaximumHeight(int);
96+ Q_INVOKABLE void setWidthIncrement(int);
97+ Q_INVOKABLE void setHeightIncrement(int);
98+
85 /////
99 /////
86 // internal mock stuff
100 // internal mock stuff
87
101
@@ -125,6 +139,13 @@ private:
125 int m_width;
139 int m_width;
126 int m_height;
140 int m_height;
127
141
142+ int m_minimumWidth{0};
143+ int m_minimumHeight{0};
144+ int m_maximumWidth{0};
145+ int m_maximumHeight{0};
146+ int m_widthIncrement{0};
147+ int m_heightIncrement{0};
148+
128 bool m_slowToResize;
149 bool m_slowToResize;
129 QTimer m_delayedResizeTimer;
150 QTimer m_delayedResizeTimer;
130 QSize m_delayedResize;
151 QSize m_delayedResize;
tests/mocks/Unity/Application/MirSurfaceItem.cpp+6
@@ -37,6 +37,8 @@ MirSurfaceItem::MirSurfaceItem(QQuickItem *parent)
37 , m_surfaceHeight(0)
37 , m_surfaceHeight(0)
38 , m_touchPressCount(0)
38 , m_touchPressCount(0)
39 , m_touchReleaseCount(0)
39 , m_touchReleaseCount(0)
40+ , m_mousePressCount(0)
41+ , m_mouseReleaseCount(0)
40{
42{
41// qDebug() << "MirSurfaceItem::MirSurfaceItem() " << (void*)(this) << name();
43// qDebug() << "MirSurfaceItem::MirSurfaceItem() " << (void*)(this) << name();
42 setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton |
44 setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton |
@@ -165,6 +167,8 @@ void MirSurfaceItem::touchEvent(QTouchEvent * event)
165
167
166void MirSurfaceItem::mousePressEvent(QMouseEvent * event)
168void MirSurfaceItem::mousePressEvent(QMouseEvent * event)
167{
169{
170+ m_mousePressCount++;
171+ Q_EMIT mousePressCountChanged(m_mousePressCount);
168 event->accept();
172 event->accept();
169}
173}
170
174
@@ -175,6 +179,8 @@ void MirSurfaceItem::mouseMoveEvent(QMouseEvent * event)
175
179
176void MirSurfaceItem::mouseReleaseEvent(QMouseEvent * event)
180void MirSurfaceItem::mouseReleaseEvent(QMouseEvent * event)
177{
181{
182+ m_mouseReleaseCount++;
183+ Q_EMIT mouseReleaseCountChanged(m_mouseReleaseCount);
178 event->accept();
184 event->accept();
179}
185}
180
186
tests/mocks/Unity/Application/MirSurfaceItem.h+14
@@ -36,6 +36,10 @@ class MirSurfaceItem : public unity::shell::application::MirSurfaceItemInterface
36 Q_PROPERTY(int touchReleaseCount READ touchReleaseCount WRITE setTouchReleaseCount
36 Q_PROPERTY(int touchReleaseCount READ touchReleaseCount WRITE setTouchReleaseCount
37 NOTIFY touchReleaseCountChanged DESIGNABLE false)
37 NOTIFY touchReleaseCountChanged DESIGNABLE false)
38
38
39+ Q_PROPERTY(int mousePressCount READ mousePressCount WRITE setMousePressCount
40+ NOTIFY mousePressCountChanged)
41+ Q_PROPERTY(int mouseReleaseCount READ mouseReleaseCount WRITE setMouseReleaseCount
42+ NOTIFY mouseReleaseCountChanged)
39public:
43public:
40 explicit MirSurfaceItem(QQuickItem *parent = 0);
44 explicit MirSurfaceItem(QQuickItem *parent = 0);
41 ~MirSurfaceItem();
45 ~MirSurfaceItem();
@@ -76,9 +80,17 @@ public:
76 int touchReleaseCount() const { return m_touchReleaseCount; }
80 int touchReleaseCount() const { return m_touchReleaseCount; }
77 void setTouchReleaseCount(int count) { m_touchReleaseCount = count; Q_EMIT touchReleaseCountChanged(count); }
81 void setTouchReleaseCount(int count) { m_touchReleaseCount = count; Q_EMIT touchReleaseCountChanged(count); }
78
82
83+ int mousePressCount() const { return m_mousePressCount; }
84+ void setMousePressCount(int count) { m_mousePressCount = count; Q_EMIT mousePressCountChanged(count); }
85+
86+ int mouseReleaseCount() const { return m_mouseReleaseCount; }
87+ void setMouseReleaseCount(int count) { m_mouseReleaseCount = count; Q_EMIT mouseReleaseCountChanged(count); }
88+
79Q_SIGNALS:
89Q_SIGNALS:
80 void touchPressCountChanged(int count);
90 void touchPressCountChanged(int count);
81 void touchReleaseCountChanged(int count);
91 void touchReleaseCountChanged(int count);
92+ void mousePressCountChanged(int count);
93+ void mouseReleaseCountChanged(int count);
82
94
83protected:
95protected:
84 void touchEvent(QTouchEvent * event) override;
96 void touchEvent(QTouchEvent * event) override;
@@ -109,6 +121,8 @@ private:
109
121
110 int m_touchPressCount;
122 int m_touchPressCount;
111 int m_touchReleaseCount;
123 int m_touchReleaseCount;
124+ int m_mousePressCount;
125+ int m_mouseReleaseCount;
112
126
113 FillMode m_fillMode{Stretch};
127 FillMode m_fillMode{Stretch};
114
128
tests/mocks/Unity/Application/SurfaceManager.cpp+56
@@ -46,6 +46,14 @@ MirSurface *SurfaceManager::createSurface(const QString& name,
46 MirSurface* surface = qobject_cast<MirSurface*>(obj);
46 MirSurface* surface = qobject_cast<MirSurface*>(obj);
47 Q_EMIT surfaceDestroyed(surface);
47 Q_EMIT surfaceDestroyed(surface);
48 });
48 });
49+
50+ surface->setMinimumWidth(m_newSurfaceMinimumWidth);
51+ surface->setMaximumWidth(m_newSurfaceMaximumWidth);
52+ surface->setMinimumHeight(m_newSurfaceMinimumHeight);
53+ surface->setMaximumHeight(m_newSurfaceMaximumHeight);
54+ surface->setWidthIncrement(m_newSurfaceWidthIncrement);
55+ surface->setHeightIncrement(m_newSurfaceHeightIncrement);
56+
49 Q_EMIT surfaceCreated(surface);
57 Q_EMIT surfaceCreated(surface);
50 return surface;
58 return surface;
51}
59}
@@ -62,3 +70,51 @@ MirSurface *SurfaceManager::inputMethodSurface()
62 }
70 }
63 return m_virtualKeyboard;
71 return m_virtualKeyboard;
64}
72}
73+
74+void SurfaceManager::setNewSurfaceMinimumWidth(int value)
75+{
76+ if (m_newSurfaceMinimumWidth != value) {
77+ m_newSurfaceMinimumWidth = value;
78+ Q_EMIT newSurfaceMinimumWidthChanged(m_newSurfaceMinimumWidth);
79+ }
80+}
81+
82+void SurfaceManager::setNewSurfaceMaximumWidth(int value)
83+{
84+ if (m_newSurfaceMaximumWidth != value) {
85+ m_newSurfaceMaximumWidth = value;
86+ Q_EMIT newSurfaceMaximumWidthChanged(m_newSurfaceMaximumWidth);
87+ }
88+}
89+
90+void SurfaceManager::setNewSurfaceMinimumHeight(int value)
91+{
92+ if (m_newSurfaceMinimumHeight != value) {
93+ m_newSurfaceMinimumHeight = value;
94+ Q_EMIT newSurfaceMinimumHeightChanged(m_newSurfaceMinimumHeight);
95+ }
96+}
97+
98+void SurfaceManager::setNewSurfaceMaximumHeight(int value)
99+{
100+ if (m_newSurfaceMaximumHeight != value) {
101+ m_newSurfaceMaximumHeight = value;
102+ Q_EMIT newSurfaceMaximumHeightChanged(m_newSurfaceMaximumHeight);
103+ }
104+}
105+
106+void SurfaceManager::setNewSurfaceWidthIncrement(int value)
107+{
108+ if (m_newSurfaceWidthIncrement != value) {
109+ m_newSurfaceWidthIncrement = value;
110+ Q_EMIT newSurfaceWidthIncrementChanged(m_newSurfaceWidthIncrement);
111+ }
112+}
113+
114+void SurfaceManager::setNewSurfaceHeightIncrement(int value)
115+{
116+ if (m_newSurfaceHeightIncrement != value) {
117+ m_newSurfaceHeightIncrement = value;
118+ Q_EMIT newSurfaceHeightIncrementChanged(m_newSurfaceHeightIncrement);
119+ }
120+}
tests/mocks/Unity/Application/SurfaceManager.h+40
@@ -25,6 +25,14 @@
25class SurfaceManager : public QObject
25class SurfaceManager : public QObject
26{
26{
27 Q_OBJECT
27 Q_OBJECT
28+
29+ Q_PROPERTY(int newSurfaceMinimumWidth READ newSurfaceMinimumWidth WRITE setNewSurfaceMinimumWidth NOTIFY newSurfaceMinimumWidthChanged)
30+ Q_PROPERTY(int newSurfaceMaximumWidth READ newSurfaceMaximumWidth WRITE setNewSurfaceMaximumWidth NOTIFY newSurfaceMaximumWidthChanged)
31+ Q_PROPERTY(int newSurfaceMinimumHeight READ newSurfaceMinimumHeight WRITE setNewSurfaceMinimumHeight NOTIFY newSurfaceMinimumHeightChanged)
32+ Q_PROPERTY(int newSurfaceMaximumHeight READ newSurfaceMaximumHeight WRITE setNewSurfaceMaximumHeight NOTIFY newSurfaceMaximumHeightChanged)
33+ Q_PROPERTY(int newSurfaceWidthIncrement READ newSurfaceWidthIncrement WRITE setNewSurfaceWidthIncrement NOTIFY newSurfaceWidthIncrementChanged)
34+ Q_PROPERTY(int newSurfaceHeightIncrement READ newSurfaceHeightIncrement WRITE setNewSurfaceHeightIncrement NOTIFY newSurfaceHeightIncrementChanged)
35+
28public:
36public:
29 explicit SurfaceManager(QObject *parent = 0);
37 explicit SurfaceManager(QObject *parent = 0);
30
38
@@ -38,14 +46,46 @@ public:
38 // To be used in the tests
46 // To be used in the tests
39 Q_INVOKABLE MirSurface* inputMethodSurface();
47 Q_INVOKABLE MirSurface* inputMethodSurface();
40
48
49+ int newSurfaceMinimumWidth() const { return m_newSurfaceMinimumWidth; }
50+ void setNewSurfaceMinimumWidth(int value);
51+
52+ int newSurfaceMaximumWidth() const { return m_newSurfaceMaximumWidth; }
53+ void setNewSurfaceMaximumWidth(int value);
54+
55+ int newSurfaceMinimumHeight() const { return m_newSurfaceMinimumHeight; }
56+ void setNewSurfaceMinimumHeight(int value);
57+
58+ int newSurfaceMaximumHeight() const { return m_newSurfaceMaximumHeight; }
59+ void setNewSurfaceMaximumHeight(int value);
60+
61+ int newSurfaceWidthIncrement() const { return m_newSurfaceWidthIncrement; }
62+ void setNewSurfaceWidthIncrement(int);
63+
64+ int newSurfaceHeightIncrement() const { return m_newSurfaceHeightIncrement; }
65+ void setNewSurfaceHeightIncrement(int);
66+
41Q_SIGNALS:
67Q_SIGNALS:
42 void countChanged();
68 void countChanged();
43 void surfaceCreated(MirSurface *surface);
69 void surfaceCreated(MirSurface *surface);
44 void surfaceDestroyed(MirSurface*surface);
70 void surfaceDestroyed(MirSurface*surface);
45
71
72+ void newSurfaceMinimumWidthChanged(int value);
73+ void newSurfaceMaximumWidthChanged(int value);
74+ void newSurfaceMinimumHeightChanged(int value);
75+ void newSurfaceMaximumHeightChanged(int value);
76+ void newSurfaceWidthIncrementChanged(int value);
77+ void newSurfaceHeightIncrementChanged(int value);
78+
46private:
79private:
47 static SurfaceManager *the_surface_manager;
80 static SurfaceManager *the_surface_manager;
48 VirtualKeyboard *m_virtualKeyboard;
81 VirtualKeyboard *m_virtualKeyboard;
82+
83+ int m_newSurfaceMinimumWidth{0};
84+ int m_newSurfaceMaximumWidth{0};
85+ int m_newSurfaceMinimumHeight{0};
86+ int m_newSurfaceMaximumHeight{0};
87+ int m_newSurfaceWidthIncrement{1};
88+ int m_newSurfaceHeightIncrement{1};
49};
89};
50
90
51#endif // SURFACEMANAGER_H
91#endif // SURFACEMANAGER_H
tests/mocks/Unity/CMakeLists.txt+1
@@ -5,6 +5,7 @@ add_subdirectory(InputInfo)
5add_subdirectory(Launcher)
5add_subdirectory(Launcher)
6add_subdirectory(Notifications)
6add_subdirectory(Notifications)
7add_subdirectory(DashCommunicator)
7add_subdirectory(DashCommunicator)
8+add_subdirectory(Screens)
8
9
9pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
10pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
10pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=9)
11pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=9)
tests/mocks/Unity/Indicators/ModelActionRootState.qml+11−1
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright 2013 Canonical Ltd.
2+ * Copyright 2013-2016 Canonical Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
5 * it under the terms of the GNU Lesser General Public License as published by
@@ -30,10 +30,20 @@ Item {
30 property bool indicatorVisible: cachedState && cachedState.hasOwnProperty("visible") ? cachedState["visible"] : true
30 property bool indicatorVisible: cachedState && cachedState.hasOwnProperty("visible") ? cachedState["visible"] : true
31
31
32 property var cachedState: menu ? menu.get(0, "actionState") : undefined
32 property var cachedState: menu ? menu.get(0, "actionState") : undefined
33+ property string submenuAction: {
34+ if (!menu) return "";
35+ var ext = menu.get(0, "ext");
36+ var submenuVar = ext ? ext["submenu-action"] : undefined;
37+ return submenuVar ? submenuVar : ""
38+ }
33 Connections {
39 Connections {
34 target: menu
40 target: menu
35 onModelDataChanged: {
41 onModelDataChanged: {
36 cachedState = menu.get(0, "actionState");
42 cachedState = menu.get(0, "actionState");
43+
44+ var ext = menu.get(0, "ext");
45+ var submenuVar = ext ? ext["submenu-action"] : undefined;
46+ submenuAction = submenuVar ? submenuVar : ""
37 }
47 }
38 }
48 }
39
49
tests/mocks/Unity/Screens/CMakeLists.txtnew file+14
@@ -0,0 +1,14 @@
1+include_directories(
2+ ${CMAKE_CURRENT_SOURCE_DIR}
3+)
4+
5+set(MockScreens_SOURCES
6+ plugin.cpp
7+ screens.cpp
8+)
9+
10+add_library(MockScreensPlugin MODULE ${MockScreens_SOURCES})
11+
12+qt5_use_modules(MockScreensPlugin Gui Qml)
13+
14+add_unity8_mock(Unity.Screens 0.1 Unity/Screens TARGETS MockScreensPlugin)
tests/mocks/Unity/Screens/plugin.cppnew file+29
@@ -0,0 +1,29 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * 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 "plugin.h"
18+#include "screens.h"
19+
20+#include <QScreen>
21+
22+void UnityScreensPlugin::registerTypes(const char* uri)
23+{
24+ Q_ASSERT(QLatin1String(uri) == QLatin1String("Unity.Screens"));
25+
26+ qRegisterMetaType<QScreen*>("QScreen*");
27+
28+ qmlRegisterType<Screens>(uri, 0, 1, "Screens");
29+}
tests/mocks/Unity/Screens/plugin.hnew file+25
@@ -0,0 +1,25 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * 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 <QQmlExtensionPlugin>
18+#include <QtQml/qqml.h>
19+
20+class UnityScreensPlugin : public QQmlExtensionPlugin {
21+ Q_OBJECT
22+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
23+public:
24+ virtual void registerTypes(const char* uri);
25+};
tests/mocks/Unity/Screens/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module Unity.Screens
2+plugin MockScreensPlugin
tests/mocks/Unity/Screens/screens.cppnew file+71
@@ -0,0 +1,71 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * 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 "screens.h"
18+
19+// Qt
20+#include <QGuiApplication>
21+#include <QScreen>
22+#include <QDebug>
23+
24+Q_DECLARE_METATYPE(QScreen*)
25+
26+Screens::Screens(QObject *parent) :
27+ QAbstractListModel(parent)
28+{
29+ // start with one screen attached
30+ m_screenList.append(new Screen());
31+}
32+
33+Screens::~Screens()
34+{
35+ qDeleteAll(m_screenList);
36+ m_screenList.clear();
37+}
38+
39+QHash<int, QByteArray> Screens::roleNames() const
40+{
41+ QHash<int, QByteArray> roles;
42+ roles[ScreenRole] = "screen";
43+ roles[OutputTypeRole] = "outputType";
44+ return roles;
45+}
46+
47+QVariant Screens::data(const QModelIndex &index, int role) const
48+{
49+ if (!index.isValid() || index.row() >= m_screenList.size()) {
50+ return QVariant();
51+ }
52+
53+ switch(role) {
54+ case ScreenRole:
55+ return QVariant::fromValue(m_screenList.at(index.row())->qScreen);
56+ case OutputTypeRole:
57+ return m_screenList.at(index.row())->outputTypes;
58+ }
59+
60+ return QVariant();
61+}
62+
63+int Screens::rowCount(const QModelIndex &) const
64+{
65+ return count();
66+}
67+
68+int Screens::count() const
69+{
70+ return m_screenList.size();
71+}
tests/mocks/Unity/Screens/screens.hnew file+82
@@ -0,0 +1,82 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * 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 SCREENS_H
18+#define SCREENS_H
19+
20+#include <QAbstractListModel>
21+#include <QScreen>
22+
23+class Screen;
24+
25+class Screens : public QAbstractListModel
26+{
27+ Q_OBJECT
28+ Q_ENUMS(OutputTypes)
29+
30+ Q_PROPERTY(int count READ count NOTIFY countChanged)
31+
32+public:
33+ enum ItemRoles {
34+ ScreenRole = Qt::UserRole + 1,
35+ OutputTypeRole
36+ };
37+
38+ enum OutputTypes {
39+ Unknown,
40+ VGA,
41+ DVII,
42+ DVID,
43+ DVIA,
44+ Composite,
45+ SVideo,
46+ LVDS,
47+ Component,
48+ NinePinDIN,
49+ DisplayPort,
50+ HDMIA,
51+ HDMIB,
52+ TV,
53+ EDP
54+ };
55+
56+ explicit Screens(QObject *parent = 0);
57+ virtual ~Screens() noexcept;
58+
59+ /* QAbstractItemModel */
60+ QHash<int, QByteArray> roleNames() const override;
61+ QVariant data(const QModelIndex &index, int role = ScreenRole) const override;
62+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
63+
64+ int count() const;
65+
66+Q_SIGNALS:
67+ void countChanged();
68+ void screenAdded(QScreen *screen);
69+ void screenRemoved(QScreen *screen);
70+
71+private:
72+ QList<Screen *> m_screenList;
73+};
74+
75+class Screen
76+{
77+public:
78+ Screens::OutputTypes outputTypes = Screens::Unknown;
79+ QScreen *qScreen = nullptr;
80+};
81+
82+#endif // SCREENS_H
tests/mocks/Unity/fake_categories.cpp+1−1
@@ -141,7 +141,7 @@ ResultsModel* Categories::resultModel(int row) const
141 ResultsModel *result = m_resultsModels[row];
141 ResultsModel *result = m_resultsModels[row];
142 if (!result) {
142 if (!result) {
143 Categories *that = const_cast<Categories*>(this);
143 Categories *that = const_cast<Categories*>(this);
144− result = new ResultsModel(15, row, that);
144+ result = new ResultsModel(25, row, that);
145 m_resultsModels[row] = result;
145 m_resultsModels[row] = result;
146 }
146 }
147 return result;
147 return result;
tests/mocks/Utils/CMakeLists.txt+1−2
@@ -1,5 +1,3 @@
1−pkg_search_module(GIO REQUIRED gio-2.0)
2−
3include_directories(
1include_directories(
4 ${CMAKE_CURRENT_SOURCE_DIR}
2 ${CMAKE_CURRENT_SOURCE_DIR}
5 ${CMAKE_CURRENT_BINARY_DIR}
3 ${CMAKE_CURRENT_BINARY_DIR}
@@ -19,6 +17,7 @@ set(QMLPLUGIN_SRC
19 ${CMAKE_SOURCE_DIR}/plugins/Utils/easingcurve.cpp
17 ${CMAKE_SOURCE_DIR}/plugins/Utils/easingcurve.cpp
20 ${CMAKE_SOURCE_DIR}/plugins/Utils/inputwatcher.cpp
18 ${CMAKE_SOURCE_DIR}/plugins/Utils/inputwatcher.cpp
21 ${CMAKE_SOURCE_DIR}/plugins/Utils/applicationsfiltermodel.cpp
19 ${CMAKE_SOURCE_DIR}/plugins/Utils/applicationsfiltermodel.cpp
20+ ${CMAKE_SOURCE_DIR}/plugins/Utils/inputeventgenerator.cpp
22 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
21 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
23 constants.cpp
22 constants.cpp
24 plugin.cpp
23 plugin.cpp
tests/mocks/Utils/HomeKeyWatcher.qml → tests/mocks/Utils/WindowInputMonitor.qmlrenamed+3−1
@@ -17,5 +17,7 @@
17import QtQuick 2.4
17import QtQuick 2.4
18
18
19QtObject {
19QtObject {
20− signal activated()
20+ signal homeKeyActivated()
21+ signal touchBegun()
22+ signal touchEnded(point pos)
21}
23}
tests/mocks/Utils/plugin.cpp+2
@@ -36,6 +36,7 @@
36#include <windowscreenshotprovider.h>
36#include <windowscreenshotprovider.h>
37#include <easingcurve.h>
37#include <easingcurve.h>
38#include <applicationsfiltermodel.h>
38#include <applicationsfiltermodel.h>
39+#include <inputeventgenerator.h>
39
40
40static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
41static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
41{
42{
@@ -65,6 +66,7 @@ void FakeUtilsPlugin::registerTypes(const char *uri)
65 qmlRegisterSingletonType<Constants>(uri, 0, 1, "Constants", createConstants);
66 qmlRegisterSingletonType<Constants>(uri, 0, 1, "Constants", createConstants);
66 qmlRegisterType<ActiveFocusLogger>(uri, 0, 1, "ActiveFocusLogger");
67 qmlRegisterType<ActiveFocusLogger>(uri, 0, 1, "ActiveFocusLogger");
67 qmlRegisterType<ApplicationsFilterModel>(uri, 0, 1, "ApplicationsFilterModel");
68 qmlRegisterType<ApplicationsFilterModel>(uri, 0, 1, "ApplicationsFilterModel");
69+ qmlRegisterType<InputEventGenerator>(uri, 0, 1, "InputEventGenerator");
68}
70}
69
71
70void FakeUtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
72void FakeUtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
tests/mocks/Utils/qmldir+1−1
@@ -2,5 +2,5 @@ module Utils
2plugin FakeUtils-qml
2plugin FakeUtils-qml
3typeinfo Utils.qmltypes
3typeinfo Utils.qmltypes
4Style 0.1 Style.js
4Style 0.1 Style.js
5−HomeKeyWatcher 0.1 HomeKeyWatcher.qml
5+WindowInputMonitor 0.1 WindowInputMonitor.qml
6singleton EdgeBarrierSettings 0.1 EdgeBarrierSettings.qml
6singleton EdgeBarrierSettings 0.1 EdgeBarrierSettings.qml
tests/mocks/indicator-service/CMakeLists.txt−1
@@ -1,5 +1,4 @@
1project(mock-indicator-service)
1project(mock-indicator-service)
2−pkg_search_module(GIO REQUIRED gio-2.0)
3
2
4set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
3set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
5
4
tests/plugins/Dash/cardcreator/1.res+6−7
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var components;
4 property var cardData;
3 property var cardData;
5 property string artShapeStyle: "inset";
4 property string artShapeStyle: "inset";
6 property string backgroundShapeStyle: "inset";
5 property string backgroundShapeStyle: "inset";
@@ -24,13 +23,13 @@ Item {
24 Loader {
23 Loader {
25 id: artShapeLoader;
24 id: artShapeLoader;
26 objectName: "artShapeLoader";
25 objectName: "artShapeLoader";
27− active: cardData && cardData["art"] || false;
26+ readonly property string cardArt: cardData && cardData["art"] || "";
27+ active: cardArt != "";
28 asynchronous: root.asynchronous;
28 asynchronous: root.asynchronous;
29 visible: status == Loader.Ready;
29 visible: status == Loader.Ready;
30 sourceComponent: Item {
30 sourceComponent: Item {
31 id: artShape;
31 id: artShape;
32 objectName: "artShape";
32 objectName: "artShape";
33− readonly property bool doShapeItem: components["art"]["conciergeMode"] !== true;
34 visible: image.status == Image.Ready;
33 visible: image.status == Image.Ready;
35 readonly property alias image: artImage;
34 readonly property alias image: artImage;
36 ShaderEffectSource {
35 ShaderEffectSource {
@@ -39,11 +38,11 @@ Item {
39 anchors.centerIn: parent;
38 anchors.centerIn: parent;
40 width: 1;
39 width: 1;
41 height: 1;
40 height: 1;
42− hideSource: doShapeItem;
41+ hideSource: true;
43 }
42 }
44 Loader {
43 Loader {
45 anchors.fill: parent;
44 anchors.fill: parent;
46− visible: artShape.doShapeItem;
45+ visible: true;
47 sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent;
46 sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent;
48 Component {
47 Component {
49 id: artShapeShapeComponent;
48 id: artShapeShapeComponent;
@@ -67,7 +66,7 @@ Item {
67 }
66 }
68 }
67 }
69 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
68 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
70− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
69+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : 1.6;
71 Component.onCompleted: { updateWidthHeightBindings(); }
70 Component.onCompleted: { updateWidthHeightBindings(); }
72 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
71 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
73 function updateWidthHeightBindings() {
72 function updateWidthHeightBindings() {
@@ -82,7 +81,7 @@ Item {
82 CroppedImageMinimumSourceSize {
81 CroppedImageMinimumSourceSize {
83 id: artImage;
82 id: artImage;
84 objectName: "artImage";
83 objectName: "artImage";
85− source: cardData && cardData["art"] || "";
84+ source: artShapeLoader.cardArt;
86 asynchronous: root.asynchronous;
85 asynchronous: root.asynchronous;
87 width: root.width;
86 width: root.width;
88 height: width / artShape.aspect;
87 height: width / artShape.aspect;
tests/plugins/Dash/cardcreator/10.resnew file+141
@@ -0,0 +1,141 @@
1+AbstractButton {
2+ id: root;
3+ property var cardData;
4+ property string artShapeStyle: "inset";
5+ property string backgroundShapeStyle: "inset";
6+ property real fontScale: 1.0;
7+ property var scopeStyle: null;
8+ property int titleAlignment: Text.AlignLeft;
9+ property int fixedHeaderHeight: -1;
10+ property size fixedArtShapeSize: Qt.size(-1, -1);
11+ readonly property string title: cardData && cardData["title"] || "";
12+ property bool asynchronous: true;
13+ property bool showHeader: true;
14+ implicitWidth: childrenRect.width;
15+ enabled: true;
16+
17+Loader {
18+ id: backgroundLoader;
19+ objectName: "backgroundLoader";
20+ anchors.fill: parent;
21+ asynchronous: root.asynchronous;
22+ visible: status == Loader.Ready;
23+ sourceComponent: UbuntuShape {
24+ objectName: "background";
25+ radius: "medium";
26+ aspect: {
27+ switch (root.backgroundShapeStyle) {
28+ case "inset": return UbuntuShape.Inset;
29+ case "shadow": return UbuntuShape.DropShadow;
30+ default:
31+ case "flat": return UbuntuShape.Flat;
32+ }
33+ }
34+ backgroundColor: getColor(0) || "white";
35+ secondaryBackgroundColor: getColor(1) || backgroundColor;
36+ backgroundMode: UbuntuShape.VerticalGradient;
37+ anchors.fill: parent;
38+ source: backgroundImage.source ? backgroundImage : null;
39+ property real luminance: Style.luminance(backgroundColor);
40+ property Image backgroundImage: Image {
41+ objectName: "backgroundImage";
42+ source: {
43+ if (cardData && typeof cardData["background"] === "string") return cardData["background"];
44+ else return "";
45+ }
46+ }
47+ function getColor(index) {
48+ if (cardData && typeof cardData["background"] === "object"
49+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
50+ return cardData["background"]["elements"][index];
51+ } else return index === 0 ? "" : "";
52+ }
53+ }
54+ }
55+readonly property size artShapeSize: Qt.size(-1, -1);
56+readonly property int headerHeight: row.height;
57+Row {
58+ id: row;
59+ objectName: "outerRow";
60+ property real margins: units.gu(1);
61+ spacing: margins;
62+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
63+ anchors { top: parent.top;
64+ topMargin: units.gu(1);
65+left: parent.left;
66+ }
67+ anchors.right: parent.right;
68+ anchors.margins: margins;
69+ anchors.rightMargin: 0;
70+ data: [
71+ CroppedImageMinimumSourceSize {
72+ id: mascotImage;
73+ objectName: "mascotImage";
74+ anchors { verticalCenter: parent.verticalCenter; }
75+ source: cardData && cardData["mascot"] || "";
76+ width: units.gu(6);
77+ height: units.gu(5.625);
78+ horizontalAlignment: Image.AlignHCenter;
79+ verticalAlignment: Image.AlignVCenter;
80+ visible: showHeader;
81+
82+ }
83+,Item {
84+ id: headerTitleContainer;
85+ anchors { verticalCenter: parent.verticalCenter; }
86+ width: parent.width - x;
87+ implicitHeight: titleLabel.height + subtitleLabel.height;
88+ data: [
89+ Label {
90+ id: titleLabel;
91+ objectName: "titleLabel";
92+ anchors { right: parent.right;
93+rightMargin: units.gu(1);
94+left: parent.left;
95+ top: parent.top; }
96+ elide: Text.ElideRight;
97+ fontSize: "small";
98+ wrapMode: Text.Wrap;
99+ maximumLineCount: 2;
100+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
101+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
102+ visible: showHeader ;
103+ width: undefined;
104+ text: root.title;
105+ font.weight: cardData && cardData["subtitle"] ? Font.DemiBold : Font.Normal;
106+ horizontalAlignment: root.titleAlignment;
107+ }
108+,Label {
109+ id: subtitleLabel;
110+ objectName: "subtitleLabel";
111+ anchors { right: parent.right;
112+ left: parent.left;
113+rightMargin: units.gu(1);
114+top: titleLabel.bottom;
115+ }
116+ anchors.topMargin: units.dp(2);
117+ elide: Text.ElideRight;
118+ maximumLineCount: 1;
119+ fontSize: "x-small";
120+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
121+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
122+ visible: titleLabel.visible && titleLabel.text;
123+ text: cardData && cardData["subtitle"] || "";
124+ font.weight: Font.Light;
125+ }
126+
127+ ]
128+ }
129+
130+ ]
131+ }
132+UbuntuShape {
133+ id: touchdown;
134+ objectName: "touchdown";
135+ anchors { fill: backgroundLoader }
136+ visible: root.artShapeStyle != "shadow" && root.artShapeStyle != "icon" && root.pressed;
137+ radius: "medium";
138+ borderSource: "radius_pressed.sci"
139+ }
140+implicitHeight: row.y + row.height + units.gu(1);
141+}
tests/plugins/Dash/cardcreator/10.tstnew file+3
@@ -0,0 +1,3 @@
1+template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2, "card-background": { "type": "color", "elements": [ "\\", ": 3; } Item { } function moo () { \"" ] } }
2+components: {"art":{"aspect-ratio":1},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"},"attributes":{}}
3+result: 10.res
tests/plugins/Dash/cardcreator/11.resnew file+216
@@ -0,0 +1,216 @@
1+AbstractButton {
2+ id: root;
3+ property var cardData;
4+ property string artShapeStyle: "inset";
5+ property string backgroundShapeStyle: "inset";
6+ property real fontScale: 1.0;
7+ property var scopeStyle: null;
8+ property int titleAlignment: Text.AlignLeft;
9+ property int fixedHeaderHeight: -1;
10+ property size fixedArtShapeSize: Qt.size(-1, -1);
11+ readonly property string title: cardData && cardData["title"] || "";
12+ property bool asynchronous: true;
13+ property bool showHeader: true;
14+ implicitWidth: childrenRect.width;
15+ enabled: true;
16+
17+Loader {
18+ id: backgroundLoader;
19+ objectName: "backgroundLoader";
20+ anchors.fill: parent;
21+ asynchronous: root.asynchronous;
22+ visible: status == Loader.Ready;
23+ sourceComponent: UbuntuShape {
24+ objectName: "background";
25+ radius: "medium";
26+ aspect: {
27+ switch (root.backgroundShapeStyle) {
28+ case "inset": return UbuntuShape.Inset;
29+ case "shadow": return UbuntuShape.DropShadow;
30+ default:
31+ case "flat": return UbuntuShape.Flat;
32+ }
33+ }
34+ backgroundColor: getColor(0) || "white";
35+ secondaryBackgroundColor: getColor(1) || backgroundColor;
36+ backgroundMode: UbuntuShape.VerticalGradient;
37+ anchors.fill: parent;
38+ source: backgroundImage.source ? backgroundImage : null;
39+ property real luminance: Style.luminance(backgroundColor);
40+ property Image backgroundImage: Image {
41+ objectName: "backgroundImage";
42+ source: {
43+ if (cardData && typeof cardData["background"] === "string") return cardData["background"];
44+ else return "";
45+ }
46+ }
47+ function getColor(index) {
48+ if (cardData && typeof cardData["background"] === "object"
49+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
50+ return cardData["background"]["elements"][index];
51+ } else return index === 0 ? "#E9E9E9" : undefined;
52+ }
53+ }
54+ }
55+readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
56+Item {
57+ id: artShapeHolder;
58+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
59+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
60+ anchors { horizontalCenter: parent.horizontalCenter; }
61+ Loader {
62+ id: artShapeLoader;
63+ objectName: "artShapeLoader";
64+ readonly property string cardArt: cardData && cardData["art"] || decodeURI("%5C");
65+ active: cardArt != "";
66+ asynchronous: root.asynchronous;
67+ visible: status == Loader.Ready;
68+ sourceComponent: Item {
69+ id: artShape;
70+ objectName: "artShape";
71+ visible: image.status == Image.Ready;
72+ readonly property alias image: artImage;
73+ ShaderEffectSource {
74+ id: artShapeSource;
75+ sourceItem: artImage;
76+ anchors.centerIn: parent;
77+ width: 1;
78+ height: 1;
79+ hideSource: true;
80+ }
81+ Loader {
82+ anchors.fill: parent;
83+ visible: true;
84+ sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent;
85+ Component {
86+ id: artShapeShapeComponent;
87+ UbuntuShape {
88+ source: artShapeSource;
89+ sourceFillMode: UbuntuShape.PreserveAspectCrop;
90+ radius: "medium";
91+ aspect: {
92+ switch (root.artShapeStyle) {
93+ case "inset": return UbuntuShape.Inset;
94+ case "shadow": return UbuntuShape.DropShadow;
95+ default:
96+ case "flat": return UbuntuShape.Flat;
97+ }
98+ }
99+ }
100+ }
101+ Component {
102+ id: artShapeIconComponent;
103+ ProportionalShape { source: artShapeSource; aspect: UbuntuShape.DropShadow; }
104+ }
105+ }
106+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
107+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : 1;
108+ Component.onCompleted: { updateWidthHeightBindings(); }
109+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
110+ function updateWidthHeightBindings() {
111+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
112+ width = root.fixedArtShapeSize.width;
113+ height = root.fixedArtShapeSize.height;
114+ } else {
115+ width = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.width });
116+ height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height });
117+ }
118+ }
119+ CroppedImageMinimumSourceSize {
120+ id: artImage;
121+ objectName: "artImage";
122+ source: artShapeLoader.cardArt;
123+ asynchronous: root.asynchronous;
124+ width: root.width;
125+ height: width / artShape.aspect;
126+ onStatusChanged: if (status === Image.Error) source = decodeURI("%5C");
127+ }
128+ }
129+ }
130+ }
131+readonly property int headerHeight: row.height;
132+Row {
133+ id: row;
134+ objectName: "outerRow";
135+ property real margins: units.gu(1);
136+ spacing: margins;
137+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
138+ anchors { top: artShapeHolder.bottom;
139+ topMargin: units.gu(1);
140+left: parent.left;
141+ }
142+ anchors.right: parent.right;
143+ anchors.margins: margins;
144+ anchors.rightMargin: 0;
145+ data: [
146+ CroppedImageMinimumSourceSize {
147+ id: mascotImage;
148+ objectName: "mascotImage";
149+ anchors { verticalCenter: parent.verticalCenter; }
150+ source: cardData && cardData["mascot"] || decodeURI("%22");
151+ width: units.gu(6);
152+ height: units.gu(5.625);
153+ horizontalAlignment: Image.AlignHCenter;
154+ verticalAlignment: Image.AlignVCenter;
155+ visible: showHeader;
156+ onStatusChanged: if (status === Image.Error) source = decodeURI("%22");
157+ }
158+,Item {
159+ id: headerTitleContainer;
160+ anchors { verticalCenter: parent.verticalCenter; }
161+ width: parent.width - x;
162+ implicitHeight: titleLabel.height + subtitleLabel.height;
163+ data: [
164+ Label {
165+ id: titleLabel;
166+ objectName: "titleLabel";
167+ anchors { right: parent.right;
168+rightMargin: units.gu(1);
169+left: parent.left;
170+ top: parent.top; }
171+ elide: Text.ElideRight;
172+ fontSize: "small";
173+ wrapMode: Text.Wrap;
174+ maximumLineCount: 2;
175+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
176+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
177+ visible: showHeader ;
178+ width: undefined;
179+ text: root.title;
180+ font.weight: cardData && cardData["subtitle"] ? Font.DemiBold : Font.Normal;
181+ horizontalAlignment: root.titleAlignment;
182+ }
183+,Label {
184+ id: subtitleLabel;
185+ objectName: "subtitleLabel";
186+ anchors { right: parent.right;
187+ left: parent.left;
188+rightMargin: units.gu(1);
189+top: titleLabel.bottom;
190+ }
191+ anchors.topMargin: units.dp(2);
192+ elide: Text.ElideRight;
193+ maximumLineCount: 1;
194+ fontSize: "x-small";
195+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
196+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
197+ visible: titleLabel.visible && titleLabel.text;
198+ text: cardData && cardData["subtitle"] || "";
199+ font.weight: Font.Light;
200+ }
201+
202+ ]
203+ }
204+
205+ ]
206+ }
207+UbuntuShape {
208+ id: touchdown;
209+ objectName: "touchdown";
210+ anchors { fill: backgroundLoader }
211+ visible: root.artShapeStyle != "shadow" && root.artShapeStyle != "icon" && root.pressed;
212+ radius: "medium";
213+ borderSource: "radius_pressed.sci"
214+ }
215+implicitHeight: row.y + row.height + units.gu(1);
216+}
tests/plugins/Dash/cardcreator/11.tstnew file+3
@@ -0,0 +1,3 @@
1+template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2 }
2+components: {"art":{"aspect-ratio":1,"field":"art","fallback":"\\"},"background":{"field":"background"},"mascot":{"field":"icon","fallback":"\""},"subtitle":{"field":"author"},"title":{"field":"title"},"attributes":{}}
3+result: 11.res
tests/plugins/Dash/cardcreator/2.res−1
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var components;
4 property var cardData;
3 property var cardData;
5 property string artShapeStyle: "inset";
4 property string artShapeStyle: "inset";
6 property string backgroundShapeStyle: "inset";
5 property string backgroundShapeStyle: "inset";
tests/plugins/Dash/cardcreator/3.res+7−7
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var components;
4 property var cardData;
3 property var cardData;
5 property string artShapeStyle: "inset";
4 property string artShapeStyle: "inset";
6 property string backgroundShapeStyle: "inset";
5 property string backgroundShapeStyle: "inset";
@@ -24,13 +23,13 @@ Item {
24 Loader {
23 Loader {
25 id: artShapeLoader;
24 id: artShapeLoader;
26 objectName: "artShapeLoader";
25 objectName: "artShapeLoader";
27− active: cardData && cardData["art"] || false;
26+ readonly property string cardArt: cardData && cardData["art"] || decodeURI("IHAVE%5C%22ESCAPED%5C%22QUOTES%5C%22");
27+ active: cardArt != "";
28 asynchronous: root.asynchronous;
28 asynchronous: root.asynchronous;
29 visible: status == Loader.Ready;
29 visible: status == Loader.Ready;
30 sourceComponent: Item {
30 sourceComponent: Item {
31 id: artShape;
31 id: artShape;
32 objectName: "artShape";
32 objectName: "artShape";
33− readonly property bool doShapeItem: components["art"]["conciergeMode"] !== true;
34 visible: image.status == Image.Ready;
33 visible: image.status == Image.Ready;
35 readonly property alias image: artImage;
34 readonly property alias image: artImage;
36 ShaderEffectSource {
35 ShaderEffectSource {
@@ -39,11 +38,11 @@ Item {
39 anchors.centerIn: parent;
38 anchors.centerIn: parent;
40 width: 1;
39 width: 1;
41 height: 1;
40 height: 1;
42− hideSource: doShapeItem;
41+ hideSource: true;
43 }
42 }
44 Loader {
43 Loader {
45 anchors.fill: parent;
44 anchors.fill: parent;
46− visible: artShape.doShapeItem;
45+ visible: true;
47 sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent;
46 sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent;
48 Component {
47 Component {
49 id: artShapeShapeComponent;
48 id: artShapeShapeComponent;
@@ -67,7 +66,7 @@ Item {
67 }
66 }
68 }
67 }
69 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
68 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
70− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
69+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : 0.75;
71 Component.onCompleted: { updateWidthHeightBindings(); }
70 Component.onCompleted: { updateWidthHeightBindings(); }
72 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
71 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
73 function updateWidthHeightBindings() {
72 function updateWidthHeightBindings() {
@@ -82,10 +81,11 @@ Item {
82 CroppedImageMinimumSourceSize {
81 CroppedImageMinimumSourceSize {
83 id: artImage;
82 id: artImage;
84 objectName: "artImage";
83 objectName: "artImage";
85− source: cardData && cardData["art"] || "";
84+ source: artShapeLoader.cardArt;
86 asynchronous: root.asynchronous;
85 asynchronous: root.asynchronous;
87 width: root.width;
86 width: root.width;
88 height: width / artShape.aspect;
87 height: width / artShape.aspect;
88+ onStatusChanged: if (status === Image.Error) source = decodeURI("IHAVE%5C%22ESCAPED%5C%22QUOTES%5C%22");
89 }
89 }
90 }
90 }
91 }
91 }
tests/plugins/Dash/cardcreator/3.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":0.75,"field":"art"},"subtitle":{"field":"price"},"title":{"field":"title"},"attributes":{}}
2+components: {"art":{"aspect-ratio":0.75,"field":"art","fallback":"IHAVE\\\"ESCAPED\\\"QUOTES\\\""},"subtitle":{"field":"price"},"title":{"field":"title"},"attributes":{}}
3result: 3.res
3result: 3.res
tests/plugins/Dash/cardcreator/4.res−1
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var components;
4 property var cardData;
3 property var cardData;
5 property string artShapeStyle: "inset";
4 property string artShapeStyle: "inset";
6 property string backgroundShapeStyle: "inset";
5 property string backgroundShapeStyle: "inset";
tests/plugins/Dash/cardcreator/5.res+6−7
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var components;
4 property var cardData;
3 property var cardData;
5 property string artShapeStyle: "inset";
4 property string artShapeStyle: "inset";
6 property string backgroundShapeStyle: "inset";
5 property string backgroundShapeStyle: "inset";
@@ -24,13 +23,13 @@ Item {
24 Loader {
23 Loader {
25 id: artShapeLoader;
24 id: artShapeLoader;
26 objectName: "artShapeLoader";
25 objectName: "artShapeLoader";
27− active: cardData && cardData["art"] || false;
26+ readonly property string cardArt: cardData && cardData["art"] || "";
27+ active: cardArt != "";
28 asynchronous: root.asynchronous;
28 asynchronous: root.asynchronous;
29 visible: status == Loader.Ready;
29 visible: status == Loader.Ready;
30 sourceComponent: Item {
30 sourceComponent: Item {
31 id: artShape;
31 id: artShape;
32 objectName: "artShape";
32 objectName: "artShape";
33− readonly property bool doShapeItem: components["art"]["conciergeMode"] !== true;
34 visible: image.status == Image.Ready;
33 visible: image.status == Image.Ready;
35 readonly property alias image: artImage;
34 readonly property alias image: artImage;
36 ShaderEffectSource {
35 ShaderEffectSource {
@@ -39,11 +38,11 @@ Item {
39 anchors.centerIn: parent;
38 anchors.centerIn: parent;
40 width: 1;
39 width: 1;
41 height: 1;
40 height: 1;
42− hideSource: doShapeItem;
41+ hideSource: false;
43 }
42 }
44 Loader {
43 Loader {
45 anchors.fill: parent;
44 anchors.fill: parent;
46− visible: artShape.doShapeItem;
45+ visible: false;
47 sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent;
46 sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent;
48 Component {
47 Component {
49 id: artShapeShapeComponent;
48 id: artShapeShapeComponent;
@@ -67,7 +66,7 @@ Item {
67 }
66 }
68 }
67 }
69 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
68 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
70− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
69+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : 1;
71 Component.onCompleted: { updateWidthHeightBindings(); }
70 Component.onCompleted: { updateWidthHeightBindings(); }
72 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
71 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
73 function updateWidthHeightBindings() {
72 function updateWidthHeightBindings() {
@@ -82,7 +81,7 @@ Item {
82 CroppedImageMinimumSourceSize {
81 CroppedImageMinimumSourceSize {
83 id: artImage;
82 id: artImage;
84 objectName: "artImage";
83 objectName: "artImage";
85− source: cardData && cardData["art"] || "";
84+ source: artShapeLoader.cardArt;
86 asynchronous: root.asynchronous;
85 asynchronous: root.asynchronous;
87 width: root.width;
86 width: root.width;
88 height: width / artShape.aspect;
87 height: width / artShape.aspect;
tests/plugins/Dash/cardcreator/5.tst+1−1
@@ -1,3 +1,3 @@
1template: {"non-interactive":true,"card-layout":"vertical","card-size":"medium","category-layout":"carousel","collapsed-rows":2,"overlay":true}
1template: {"non-interactive":true,"card-layout":"vertical","card-size":"medium","category-layout":"carousel","collapsed-rows":2,"overlay":true}
2−components: {"art":{"aspect-ratio":1,"field":"art"},"subtitle":{"field":"artist"},"title":{"field":"title"},"attributes":{}}
2+components: {"art":{"aspect-ratio":1,"field":"art","conciergeMode":true},"subtitle":{"field":"artist"},"title":{"field":"title"},"attributes":{}}
3result: 5.res
3result: 5.res
tests/plugins/Dash/cardcreator/6.res+1−2
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var components;
4 property var cardData;
3 property var cardData;
5 property string artShapeStyle: "inset";
4 property string artShapeStyle: "inset";
6 property string backgroundShapeStyle: "inset";
5 property string backgroundShapeStyle: "inset";
@@ -42,7 +41,7 @@ Loader {
42 objectName: "backgroundImage";
41 objectName: "backgroundImage";
43 source: {
42 source: {
44 if (cardData && typeof cardData["background"] === "string") return cardData["background"];
43 if (cardData && typeof cardData["background"] === "string") return cardData["background"];
45− else return "http://assets.ubuntu.com/sites/ubuntu/latest/u/img/logos/logo-ubuntu-grey.png";
44+ else return decodeURI("http://assets.ubuntu.com/sites/ubuntu/latest/u/img/logos/logo-ubuntu-grey.png");
46 }
45 }
47 }
46 }
48 function getColor(index) {
47 function getColor(index) {
tests/plugins/Dash/cardcreator/7.res−1
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var components;
4 property var cardData;
3 property var cardData;
5 property string artShapeStyle: "inset";
4 property string artShapeStyle: "inset";
6 property string backgroundShapeStyle: "inset";
5 property string backgroundShapeStyle: "inset";
tests/plugins/Dash/cardcreator/8.res+1−2
@@ -1,7 +1,6 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var components;
3+ property var cardData;
4− property var cardData;
5 property string artShapeStyle: "inset";
4 property string artShapeStyle: "inset";
6 property string backgroundShapeStyle: "inset";
5 property string backgroundShapeStyle: "inset";
7 property real fontScale: 1.0;
6 property real fontScale: 1.0;
tests/plugins/Dash/cardcreator/9.res+12−4
@@ -1,9 +1,8 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var components;
4 property var cardData;
3 property var cardData;
5 property string artShapeStyle: "inset";
4 property string artShapeStyle: "inset";
6− property string backgroundShapeStyle: "inset";
5+ property string backgroundShapeStyle: "inset";
7 property real fontScale: 1.0;
6 property real fontScale: 1.0;
8 property var scopeStyle: null;
7 property var scopeStyle: null;
9 property int titleAlignment: Text.AlignLeft;
8 property int titleAlignment: Text.AlignLeft;
@@ -80,11 +79,20 @@ CardAudioProgress {
80 visible: parent.pressed;
79 visible: parent.pressed;
81 radius: "medium";
80 radius: "medium";
82 }
81 }
82+ Rectangle {
83+ color: Qt.rgba(0, 0, 0, 0.5);
84+ anchors.centerIn: parent;
85+ width: parent.width * 0.5;
86+ height: width;
87+ radius: width / 2;
88+ }
83 Icon {
89 Icon {
84− anchors.fill: parent;
90+ anchors.centerIn: parent;
85− anchors.margins: parent.height > units.gu(5) ? units.gu(2) : 0;
91+ width: parent.width * 0.3;
92+ height: width;
86 opacity: 0.9;
93 opacity: 0.9;
87 name: DashAudioPlayer.playing && AudioUrlComparer.compare(parent.source, DashAudioPlayer.currentSource) ? "media-playback-pause" : "media-playback-start";
94 name: DashAudioPlayer.playing && AudioUrlComparer.compare(parent.source, DashAudioPlayer.currentSource) ? "media-playback-pause" : "media-playback-start";
95+ color: "white";
88 }
96 }
89 onClicked: {
97 onClicked: {
90 if (AudioUrlComparer.compare(source, DashAudioPlayer.currentSource)) {
98 if (AudioUrlComparer.compare(source, DashAudioPlayer.currentSource)) {
tests/plugins/Dash/cardcreatortest.cpp+1
@@ -64,6 +64,7 @@ private Q_SLOTS:
64 QVERIFY(lines[0].startsWith(templateString));
64 QVERIFY(lines[0].startsWith(templateString));
65 QVERIFY(lines[1].startsWith(componentsString));
65 QVERIFY(lines[1].startsWith(componentsString));
66 QVERIFY(lines[2].startsWith(resultString));
66 QVERIFY(lines[2].startsWith(resultString));
67+
67 const QString templateJSON = lines[0].mid(templateString.length());
68 const QString templateJSON = lines[0].mid(templateString.length());
68 const QString componentsJSON = lines[1].mid(componentsString.length());
69 const QString componentsJSON = lines[1].mid(componentsString.length());
69 const QString resultFileName = lines[2].mid(resultString.length());
70 const QString resultFileName = lines[2].mid(resultString.length());
tests/plugins/Dash/listviewwithpageheadertest.cpp+23
@@ -1954,6 +1954,29 @@ private Q_SLOTS:
1954 QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1954 QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1955 }
1955 }
1956
1956
1957+ void testBug1540490()
1958+ {
1959+ lvwph->header()->setImplicitHeight(150);
1960+ verifyItem(0, 150., 150., false);
1961+
1962+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 3), Q_ARG(QVariant, 3));
1963+ model->setProperty(0, "size", 400);
1964+ model->setProperty(1, "size", 600);
1965+ model->setProperty(2, "size", 300);
1966+
1967+ scrollToBottom();
1968+ changeContentY(-200);
1969+
1970+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 1), Q_ARG(QVariant, 2));
1971+ model->setProperty(0, "size", 100);
1972+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 1));
1973+ lvwph->header()->setImplicitHeight(50);
1974+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 200));
1975+
1976+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 1);
1977+ verifyItem(0, 50., 200., false);
1978+ }
1979+
1957private:
1980private:
1958 QQuickView *view;
1981 QQuickView *view;
1959 ListViewWithPageHeader *lvwph;
1982 ListViewWithPageHeader *lvwph;
tests/plugins/Dash/listviewwithpageheadertest.qml−1
@@ -85,7 +85,6 @@ Rectangle {
85 pageHeader: Rectangle {
85 pageHeader: Rectangle {
86 color: "transparent"
86 color: "transparent"
87 width: parent.width
87 width: parent.width
88− height: 50
89 implicitHeight: 50
88 implicitHeight: 50
90 Text {
89 Text {
91 anchors.fill: parent
90 anchors.fill: parent
tests/plugins/Unity/Indicators/CMakeLists.txt−4
@@ -1,7 +1,3 @@
1−pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
2−pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
3−pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
4−
5set(INDICATORS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../plugins/Unity/Indicators)
1set(INDICATORS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../plugins/Unity/Indicators)
6set(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
2set(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
7
3
tests/plugins/Unity/Launcher/launchermodeltest.cpp+2
@@ -61,6 +61,8 @@ public:
61 bool isTouchApp() const override { return true; }
61 bool isTouchApp() const override { return true; }
62 bool exemptFromLifecycle() const override { return false; }
62 bool exemptFromLifecycle() const override { return false; }
63 void setExemptFromLifecycle(bool) override {}
63 void setExemptFromLifecycle(bool) override {}
64+ QSize initialSurfaceSize() const override { return QSize(); }
65+ void setInitialSurfaceSize(const QSize &) override {}
64
66
65 // Methods used for mocking (not in the interface)
67 // Methods used for mocking (not in the interface)
66 void setFocused(bool focused) { m_focused = focused; Q_EMIT focusedChanged(focused); }
68 void setFocused(bool focused) { m_focused = focused; Q_EMIT focusedChanged(focused); }
tests/plugins/Unity/Session/sessionbackendtest.cpp+1
@@ -149,6 +149,7 @@ private Q_SLOTS:
149 }
149 }
150
150
151 void testLogin1Capabilities() {
151 void testLogin1Capabilities() {
152+ QSKIP("This test talks to real logind backend, it will fail depending on how the machine is set up");
152 DBusUnitySessionService dbusUnitySessionService;
153 DBusUnitySessionService dbusUnitySessionService;
153 QDBusInterface login1face("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus());
154 QDBusInterface login1face("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus());
154 QCoreApplication::processEvents(); // to let the services register on DBus
155 QCoreApplication::processEvents(); // to let the services register on DBus
tests/plugins/Utils/CMakeLists.txt+1−1
@@ -7,7 +7,7 @@ include_directories(
7foreach(util_test
7foreach(util_test
8 QLimitProxyModel
8 QLimitProxyModel
9 UnitySortFilterProxyModel
9 UnitySortFilterProxyModel
10− HomeKeyWatcher
10+ WindowInputMonitor
11)
11)
12 add_executable(${util_test}TestExec ${util_test}Test.cpp ModelTest.cpp)
12 add_executable(${util_test}TestExec ${util_test}Test.cpp ModelTest.cpp)
13 qt5_use_modules(${util_test}TestExec Test Core Qml)
13 qt5_use_modules(${util_test}TestExec Test Core Qml)
tests/plugins/Utils/HomeKeyWatcherTest.cpp → tests/plugins/Utils/WindowInputMonitorTest.cpprenamed+14−14
@@ -14,7 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−#include "HomeKeyWatcher.h"
17+#include "WindowInputMonitor.h"
18
18
19#include <QTest>
19#include <QTest>
20#include <QSignalSpy>
20#include <QSignalSpy>
@@ -71,7 +71,7 @@ public:
71
71
72using namespace UnityUtil;
72using namespace UnityUtil;
73
73
74−class HomeKeyWatcherTest : public QObject {
74+class WindowInputMonitorTest : public QObject {
75 Q_OBJECT
75 Q_OBJECT
76private Q_SLOTS:
76private Q_SLOTS:
77 void init(); // called right before each and every test function is executed
77 void init(); // called right before each and every test function is executed
@@ -88,25 +88,25 @@ private:
88 FakeTimerFactory *m_fakeTimerFactory;
88 FakeTimerFactory *m_fakeTimerFactory;
89};
89};
90
90
91−void HomeKeyWatcherTest::init()
91+void WindowInputMonitorTest::init()
92{
92{
93 m_fakeTimerFactory = new FakeTimerFactory;
93 m_fakeTimerFactory = new FakeTimerFactory;
94}
94}
95
95
96−void HomeKeyWatcherTest::cleanup()
96+void WindowInputMonitorTest::cleanup()
97{
97{
98 delete m_fakeTimerFactory;
98 delete m_fakeTimerFactory;
99 m_fakeTimerFactory = nullptr;
99 m_fakeTimerFactory = nullptr;
100}
100}
101
101
102
102
103−void HomeKeyWatcherTest::passTime(qint64 timeSpanMs)
103+void WindowInputMonitorTest::passTime(qint64 timeSpanMs)
104{
104{
105 qint64 finalTime = FakeElapsedTimer::msecsSinceEpoch + timeSpanMs;
105 qint64 finalTime = FakeElapsedTimer::msecsSinceEpoch + timeSpanMs;
106 m_fakeTimerFactory->updateTime(finalTime);
106 m_fakeTimerFactory->updateTime(finalTime);
107}
107}
108
108
109−void HomeKeyWatcherTest::touchTapTouch_data()
109+void WindowInputMonitorTest::touchTapTouch_data()
110{
110{
111 QTest::addColumn<int>("silenceBeforeTap");
111 QTest::addColumn<int>("silenceBeforeTap");
112 QTest::addColumn<int>("tapDuration");
112 QTest::addColumn<int>("tapDuration");
@@ -121,14 +121,14 @@ void HomeKeyWatcherTest::touchTapTouch_data()
121 QTest::newRow("isolated long press") << 1000 << 200 << 1000 << 0;
121 QTest::newRow("isolated long press") << 1000 << 200 << 1000 << 0;
122}
122}
123
123
124−void HomeKeyWatcherTest::touchTapTouch()
124+void WindowInputMonitorTest::touchTapTouch()
125{
125{
126 QFETCH(int, silenceBeforeTap);
126 QFETCH(int, silenceBeforeTap);
127 QFETCH(int, tapDuration);
127 QFETCH(int, tapDuration);
128 QFETCH(int, silenceAfterTap);
128 QFETCH(int, silenceAfterTap);
129 QFETCH(int, expectedActivatedCount);
129 QFETCH(int, expectedActivatedCount);
130− HomeKeyWatcher homeKeyWatcher(m_fakeTimerFactory->create(), new FakeElapsedTimer);
130+ WindowInputMonitor homeKeyWatcher(m_fakeTimerFactory->create(), new FakeElapsedTimer);
131− QSignalSpy activatedSpy(&homeKeyWatcher, &HomeKeyWatcher::activated);
131+ QSignalSpy activatedSpy(&homeKeyWatcher, &WindowInputMonitor::homeKeyActivated);
132 QVERIFY(activatedSpy.isValid());
132 QVERIFY(activatedSpy.isValid());
133
133
134 {
134 {
@@ -186,10 +186,10 @@ void HomeKeyWatcherTest::touchTapTouch()
186 QCOMPARE(activatedSpy.count(), expectedActivatedCount);
186 QCOMPARE(activatedSpy.count(), expectedActivatedCount);
187}
187}
188
188
189−void HomeKeyWatcherTest::tapWhileTouching()
189+void WindowInputMonitorTest::tapWhileTouching()
190{
190{
191− HomeKeyWatcher homeKeyWatcher(m_fakeTimerFactory->create(), new FakeElapsedTimer);
191+ WindowInputMonitor homeKeyWatcher(m_fakeTimerFactory->create(), new FakeElapsedTimer);
192− QSignalSpy activatedSpy(&homeKeyWatcher, &HomeKeyWatcher::activated);
192+ QSignalSpy activatedSpy(&homeKeyWatcher, &WindowInputMonitor::homeKeyActivated);
193 QVERIFY(activatedSpy.isValid());
193 QVERIFY(activatedSpy.isValid());
194
194
195 {
195 {
@@ -318,6 +318,6 @@ AbstractTimer *FakeTimerFactory::create(QObject *parent)
318 return fakeTimer;
318 return fakeTimer;
319}
319}
320
320
321−QTEST_GUILESS_MAIN(HomeKeyWatcherTest)
321+QTEST_GUILESS_MAIN(WindowInputMonitorTest)
322
322
323−#include "HomeKeyWatcherTest.moc"
323+#include "WindowInputMonitorTest.moc"
tests/qmltests/CMakeLists.txt+2−1
@@ -12,11 +12,12 @@ add_unity8_qmltest(Components DraggingArea)
12add_unity8_qmltest(Components LazyImage)
12add_unity8_qmltest(Components LazyImage)
13add_unity8_qmltest(Components Lockscreen)
13add_unity8_qmltest(Components Lockscreen)
14add_unity8_qmltest(Components ModeSwitchWarningDialog)
14add_unity8_qmltest(Components ModeSwitchWarningDialog)
15−add_unity8_qmlunittest(Components PhysicalKeysMapper)
15+add_unity8_qmltest(Components PhysicalKeysMapper)
16add_unity8_qmltest(Components Rating)
16add_unity8_qmltest(Components Rating)
17add_unity8_qmltest(Components ResponsiveGridView)
17add_unity8_qmltest(Components ResponsiveGridView)
18add_unity8_qmltest(Components ResponsiveVerticalJournal)
18add_unity8_qmltest(Components ResponsiveVerticalJournal)
19add_unity8_qmltest(Components Showable)
19add_unity8_qmltest(Components Showable)
20+add_unity8_qmltest(Components VirtualTouchPad)
20add_unity8_qmltest(Components WallpaperResolver)
21add_unity8_qmltest(Components WallpaperResolver)
21add_unity8_qmltest(Components ZoomableImage)
22add_unity8_qmltest(Components ZoomableImage)
22add_unity8_qmltest(Dash Dash)
23add_unity8_qmltest(Dash Dash)
tests/qmltests/Components/tst_LazyImage.qml+27−8
@@ -112,6 +112,11 @@ Rectangle {
112 }
112 }
113 }
113 }
114
114
115+ SignalSpy {
116+ id: signalSpy
117+ signalName: "runningChanged"
118+ }
119+
115 UT.UnityTestCase {
120 UT.UnityTestCase {
116 name: "LazyImage"
121 name: "LazyImage"
117 when: windowShown
122 when: windowShown
@@ -123,6 +128,18 @@ Rectangle {
123 tryCompare(lazy2, "height", units.gu(10));
128 tryCompare(lazy2, "height", units.gu(10));
124 controls3.blank();
129 controls3.blank();
125 tryCompare(lazy3, "width", units.gu(10));
130 tryCompare(lazy3, "width", units.gu(10));
131+
132+ tryCompare(lazy1, "state", "default");
133+ var transition = findChildIn(lazy1, "transitions", "genericTransition");
134+ tryCompare(transition, "running", false);
135+
136+ tryCompare(lazy2, "state", "default");
137+ transition = findChildIn(lazy2, "transitions", "genericTransition");
138+ tryCompare(transition, "running", false);
139+
140+ tryCompare(lazy3, "state", "default");
141+ transition = findChildIn(lazy3, "transitions", "genericTransition");
142+ tryCompare(transition, "running", false);
126 }
143 }
127
144
128 function test_lazyimage_data() {
145 function test_lazyimage_data() {
@@ -131,32 +148,34 @@ Rectangle {
131 {tag: "Unbound Wide", image: lazy1, func: controls1.wide, transition: "readyTransition", width: 160, height: 80, imageWidth: 160, imageHeight: 80, initialWidth: units.gu(10), initialHeight: units.gu(10)},
148 {tag: "Unbound Wide", image: lazy1, func: controls1.wide, transition: "readyTransition", width: 160, height: 80, imageWidth: 160, imageHeight: 80, initialWidth: units.gu(10), initialHeight: units.gu(10)},
132 {tag: "Unbound Square", image: lazy1, func: controls1.square, transition: "readyTransition", width: 160, height: 160, imageWidth: 160, imageHeight: 160, initialWidth: units.gu(10), initialHeight: units.gu(10)},
149 {tag: "Unbound Square", image: lazy1, func: controls1.square, transition: "readyTransition", width: 160, height: 160, imageWidth: 160, imageHeight: 160, initialWidth: units.gu(10), initialHeight: units.gu(10)},
133 {tag: "Unbound Portrait", image: lazy1, func: controls1.portrait, transition: "readyTransition", width: 80, height: 160, imageWidth: 80, imageHeight: 160, initialWidth: units.gu(10), initialHeight: units.gu(10)},
150 {tag: "Unbound Portrait", image: lazy1, func: controls1.portrait, transition: "readyTransition", width: 80, height: 160, imageWidth: 80, imageHeight: 160, initialWidth: units.gu(10), initialHeight: units.gu(10)},
134− {tag: "Unbound Bad path", image: lazy1, func: controls1.badpath, transition: "genericTransition", width: units.gu(10), height: units.gu(10), imageWidth: units.gu(10), imageHeight: units.gu(10), initialWidth: units.gu(10), initialHeight: units.gu(10), placeholder: true, error: true},
151+ {tag: "Unbound Bad path", image: lazy1, func: controls1.badpath, transition: "genericTransition", state: "error", width: units.gu(10), height: units.gu(10), imageWidth: units.gu(10), imageHeight: units.gu(10), initialWidth: units.gu(10), initialHeight: units.gu(10), placeholder: true, error: true},
135 {tag: "Width-bound Blank", image: lazy2, func: controls2.blank, width: units.gu(30), height: units.gu(10), imageWidth: units.gu(30), imageHeight: units.gu(10), initialWidth: units.gu(30), initialHeight: units.gu(10), placeholder: true},
152 {tag: "Width-bound Blank", image: lazy2, func: controls2.blank, width: units.gu(30), height: units.gu(10), imageWidth: units.gu(30), imageHeight: units.gu(10), initialWidth: units.gu(30), initialHeight: units.gu(10), placeholder: true},
136 {tag: "Width-bound Wide", image: lazy2, func: controls2.wide, transition: "readyTransition", width: units.gu(30), height: units.gu(15), imageWidth: units.gu(30), imageHeight: units.gu(15), initialWidth: units.gu(30), initialHeight: units.gu(10)},
153 {tag: "Width-bound Wide", image: lazy2, func: controls2.wide, transition: "readyTransition", width: units.gu(30), height: units.gu(15), imageWidth: units.gu(30), imageHeight: units.gu(15), initialWidth: units.gu(30), initialHeight: units.gu(10)},
137 {tag: "Width-bound Square", image: lazy2, func: controls2.square, transition: "readyTransition", width: units.gu(30), height: units.gu(30), imageWidth: units.gu(30), imageHeight: units.gu(30), initialWidth: units.gu(30), initialHeight: units.gu(10)},
154 {tag: "Width-bound Square", image: lazy2, func: controls2.square, transition: "readyTransition", width: units.gu(30), height: units.gu(30), imageWidth: units.gu(30), imageHeight: units.gu(30), initialWidth: units.gu(30), initialHeight: units.gu(10)},
138 {tag: "Width-bound Portrait", image: lazy2, func: controls2.portrait, transition: "readyTransition", width: units.gu(30), height: units.gu(60), imageWidth: units.gu(30), imageHeight: units.gu(60), initialWidth: units.gu(30), initialHeight: units.gu(10)},
155 {tag: "Width-bound Portrait", image: lazy2, func: controls2.portrait, transition: "readyTransition", width: units.gu(30), height: units.gu(60), imageWidth: units.gu(30), imageHeight: units.gu(60), initialWidth: units.gu(30), initialHeight: units.gu(10)},
139− {tag: "Width-bound Bad path", image: lazy2, func: controls2.badpath, transition: "genericTransition", width: units.gu(30), height: units.gu(10), imageWidth: units.gu(30), imageHeight: units.gu(10), initialWidth: units.gu(30), initialHeight: units.gu(10), placeholder: true, error: true},
156+ {tag: "Width-bound Bad path", image: lazy2, func: controls2.badpath, transition: "genericTransition", state: "error", width: units.gu(30), height: units.gu(10), imageWidth: units.gu(30), imageHeight: units.gu(10), initialWidth: units.gu(30), initialHeight: units.gu(10), placeholder: true, error: true},
140 {tag: "Height-bound Blank", image: lazy3, func: controls3.blank, width: units.gu(10), height: units.gu(12), imageWidth: units.gu(10), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12), placeholder: true},
157 {tag: "Height-bound Blank", image: lazy3, func: controls3.blank, width: units.gu(10), height: units.gu(12), imageWidth: units.gu(10), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12), placeholder: true},
141 {tag: "Height-bound Wide", image: lazy3, func: controls3.wide, transition: "readyTransition", width: units.gu(24), height: units.gu(12), imageWidth: units.gu(24), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12)},
158 {tag: "Height-bound Wide", image: lazy3, func: controls3.wide, transition: "readyTransition", width: units.gu(24), height: units.gu(12), imageWidth: units.gu(24), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12)},
142 {tag: "Height-bound Square", image: lazy3, func: controls3.square, transition: "readyTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12)},
159 {tag: "Height-bound Square", image: lazy3, func: controls3.square, transition: "readyTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12)},
143 {tag: "Height-bound Portrait", image: lazy3, func: controls3.portrait, transition: "readyTransition", width: units.gu(6), height: units.gu(12), imageWidth: units.gu(6), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12)},
160 {tag: "Height-bound Portrait", image: lazy3, func: controls3.portrait, transition: "readyTransition", width: units.gu(6), height: units.gu(12), imageWidth: units.gu(6), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12)},
144− {tag: "Height-bound Bad path", image: lazy3, func: controls3.badpath, transition: "genericTransition", width: units.gu(10), height: units.gu(12), imageWidth: units.gu(10), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12), placeholder: true, error: true},
161+ {tag: "Height-bound Bad path", image: lazy3, func: controls3.badpath, transition: "genericTransition", state: "error", width: units.gu(10), height: units.gu(12), imageWidth: units.gu(10), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12), placeholder: true, error: true},
145 {tag: "Fit Blank", image: lazy4, func: controls4.blank, width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(12), initialWidth: units.gu(12), initialHeight: units.gu(12), placeholder: true},
162 {tag: "Fit Blank", image: lazy4, func: controls4.blank, width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(12), initialWidth: units.gu(12), initialHeight: units.gu(12), placeholder: true},
146 {tag: "Fit Wide", image: lazy4, func: controls4.wide, transition: "readyTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(6), initialWidth: units.gu(12), initialHeight: units.gu(12)},
163 {tag: "Fit Wide", image: lazy4, func: controls4.wide, transition: "readyTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(6), initialWidth: units.gu(12), initialHeight: units.gu(12)},
147 {tag: "Fit Square", image: lazy4, func: controls4.square, transition: "readyTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(12), initialWidth: units.gu(12), initialHeight: units.gu(12)},
164 {tag: "Fit Square", image: lazy4, func: controls4.square, transition: "readyTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(12), initialWidth: units.gu(12), initialHeight: units.gu(12)},
148 {tag: "Fit Portrait", image: lazy4, func: controls4.portrait, transition: "readyTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(6), imageHeight: units.gu(12), initialWidth: units.gu(12), initialHeight: units.gu(12)},
165 {tag: "Fit Portrait", image: lazy4, func: controls4.portrait, transition: "readyTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(6), imageHeight: units.gu(12), initialWidth: units.gu(12), initialHeight: units.gu(12)},
149− {tag: "Fit Bad path", image: lazy4, func: controls4.badpath, transition: "genericTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(12), initialWidth: units.gu(12), initialHeight: units.gu(12), placeholder: true, error: true},
166+ {tag: "Fit Bad path", image: lazy4, func: controls4.badpath, transition: "genericTransition", state: "error", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(12), initialWidth: units.gu(12), initialHeight: units.gu(12), placeholder: true, error: true},
150 ]
167 ]
151 }
168 }
152
169
153 function test_lazyimage(data) {
170 function test_lazyimage(data) {
171+ var transition = findChildIn(data.image, "transitions", data.transition);
172+ signalSpy.target = transition;
173+ signalSpy.clear();
174+
154 data.func();
175 data.func();
155
176
156 if (data.transition) {
177 if (data.transition) {
157− // wait for the transition to complete
178+ tryCompare(data.image, "state", data.state ? data.state : "ready");
158− var transition = findChildIn(data.image, "transitions", data.transition);
159− tryCompare(transition, "running", true);
160 tryCompare(transition, "running", false);
179 tryCompare(transition, "running", false);
161 }
180 }
162
181
@@ -185,7 +204,7 @@ Rectangle {
185
204
186 // check the error image
205 // check the error image
187 var error = findChild(data.image, "errorImage");
206 var error = findChild(data.image, "errorImage");
188− compare(error.visible, data.error ? true : false);
207+ tryCompare(error, "visible", data.error ? true : false);
189 }
208 }
190 }
209 }
191}
210}
tests/qmltests/Components/tst_PhysicalKeysMapper.qml+136−62
@@ -18,12 +18,19 @@ import QtQuick 2.4
18import QtTest 1.0
18import QtTest 1.0
19import "../../../qml/Components"
19import "../../../qml/Components"
20import Powerd 0.1
20import Powerd 0.1
21+import Utils 0.1
21
22
22−TestCase {
23+Item {
23− name: "PhysicalKeysMapper"
24+ width: 100
25+ height: 100
24
26
25 property var physicalKeysMapper: loader.item
27 property var physicalKeysMapper: loader.item
26
28
29+ WindowKeysFilter {
30+ Keys.onPressed: physicalKeysMapper.onKeyPressed(event, currentEventTimestamp);
31+ Keys.onReleased: physicalKeysMapper.onKeyReleased(event, currentEventTimestamp);
32+ }
33+
27 Loader {
34 Loader {
28 // Using a Loader here to make sure mapper state is coherent
35 // Using a Loader here to make sure mapper state is coherent
29 // regardless of unmatched KeyPress and KeyRelease events
36 // regardless of unmatched KeyPress and KeyRelease events
@@ -32,6 +39,21 @@ TestCase {
32 sourceComponent: PhysicalKeysMapper { }
39 sourceComponent: PhysicalKeysMapper { }
33 }
40 }
34
41
42+ Item {
43+ id: inputCatcher
44+ focus: true
45+
46+ property var pressedKeys: []
47+ property var releasedKeys: []
48+
49+ Keys.onPressed: {
50+ inputCatcher.pressedKeys.push(event.key);
51+ }
52+ Keys.onReleased: {
53+ inputCatcher.releasedKeys.push(event.key);
54+ }
55+ }
56+
35 SignalSpy {
57 SignalSpy {
36 id: powerSpy
58 id: powerSpy
37 target: physicalKeysMapper
59 target: physicalKeysMapper
@@ -44,65 +66,117 @@ TestCase {
44 signalName: "screenshotTriggered"
66 signalName: "screenshotTriggered"
45 }
67 }
46
68
69+ TestCase {
70+ name: "PhysicalKeysMapper"
71+ when: windowShown
72+
47− function init() {
73+ function init() {
48− Powerd.setStatus(Powerd.On, Powerd.Unknown);
74+ Powerd.setStatus(Powerd.On, Powerd.Unknown);
49− loader.active = true;
75+ loader.active = true;
50− tryCompare(loader.status == Loader.Ready);
76+ tryCompare(loader.status == Loader.Ready);
77+ inputCatcher.pressedKeys = [];
78+ inputCatcher.releasedKeys = [];
51− }
79+ }
52−
80+
53− function cleanup() {
81+ function cleanup() {
54− loader.active = false;
82+ loader.active = false;
55− powerSpy.clear();
83+ powerSpy.clear();
56− screenshotSpy.clear();
84+ screenshotSpy.clear();
57− }
85+ }
58−
86+
59− function test_powerKeyLongPressed_data() {
87+ function test_powerKeyLongPressed_data() {
60− return [
88+ return [
61− { tag: "screenOn", status: Powerd.On },
89+ { tag: "screenOn", status: Powerd.On },
62− { tag: "screenOff", status: Powerd.Off },
90+ { tag: "screenOff", status: Powerd.Off },
63− ];
91+ ];
64− }
92+ }
65−
93+
66− function test_powerKeyLongPressed(data) {
94+ function test_powerKeyLongPressed(data) {
67− Powerd.setStatus(data.status, Powerd.Unknown);
95+ Powerd.setStatus(data.status, Powerd.Unknown);
68− physicalKeysMapper.powerKeyLongPressTime = 500;
96+ physicalKeysMapper.powerKeyLongPressTime = 500;
69−
97+
70− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: false }, 100);
98+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: false }, 100);
71−
99+
72− // After the first key press the screen is always on
100+ // After the first key press the screen is always on
73− // and the rest of keypresses are auto repeat
101+ // and the rest of keypresses are auto repeat
74− Powerd.setStatus(Powerd.On, Powerd.Unknown);
102+ Powerd.setStatus(Powerd.On, Powerd.Unknown);
75−
103+
76− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 300);
104+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 300);
77− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 400);
105+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 400);
78− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 500);
106+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 500);
79− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 599);
107+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 599);
80−
108+
81− // powerKeyLongPressed should not have been emitted yet.
109+ // powerKeyLongPressed should not have been emitted yet.
82− compare(powerSpy.count, 0);
110+ compare(powerSpy.count, 0);
83−
111+
84− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 600);
112+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 600);
85−
113+
86− compare(powerSpy.count, 1);
114+ compare(powerSpy.count, 1);
87−
115+
88− // Confirm we only emit once
116+ // Confirm we only emit once
89− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 601);
117+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 601);
90− compare(powerSpy.count, 1);
118+ compare(powerSpy.count, 1);
91− }
119+ }
92−
120+
93− function test_screenshotButtons_data() {
121+ function test_screenshotButtons_data() {
94− return [
122+ return [
95− { tag: "UpFirst", first: Qt.Key_VolumeUp, second: Qt.Key_VolumeDown },
123+ { tag: "UpFirst", first: Qt.Key_VolumeUp, second: Qt.Key_VolumeDown },
96− { tag: "DownFirst", first: Qt.Key_VolumeDown, second: Qt.Key_VolumeUp },
124+ { tag: "DownFirst", first: Qt.Key_VolumeDown, second: Qt.Key_VolumeUp },
97− ];
125+ ];
98− }
126+ }
99−
127+
100− function test_screenshotButtons(data) {
128+ function test_screenshotButtons(data) {
101− physicalKeysMapper.onKeyPressed({ key: data.first });
129+ physicalKeysMapper.onKeyPressed({ key: data.first });
102− physicalKeysMapper.onKeyPressed({ key: data.second });
130+ physicalKeysMapper.onKeyPressed({ key: data.second });
103− screenshotSpy.wait();
131+ screenshotSpy.wait();
104− physicalKeysMapper.onKeyReleased({ key: data.first });
132+ physicalKeysMapper.onKeyReleased({ key: data.first });
105− physicalKeysMapper.onKeyReleased({ key: data.second });
133+ physicalKeysMapper.onKeyReleased({ key: data.second });
106− compare(screenshotSpy.count, 1);
134+ compare(screenshotSpy.count, 1);
135+ }
136+
137+ function test_altIsDispatchedOnRelease() {
138+ // Press alt, make sure it does *not* end up in inputCatcher (aka, the focused app)
139+ keyPress(Qt.Key_Alt, Qt.NoModifier)
140+ compare(inputCatcher.pressedKeys.length, 0);
141+ // Now release alt. It should cause the previous Alt press to be dispatched along with the release
142+ keyRelease(Qt.Key_Alt, Qt.NoModifier);
143+ compare(inputCatcher.pressedKeys.length, 1);
144+ compare(inputCatcher.pressedKeys[0], Qt.Key_Alt);
145+ compare(inputCatcher.releasedKeys.length, 1);
146+ compare(inputCatcher.releasedKeys[0], Qt.Key_Alt);
147+ }
148+
149+ function test_altIsNotDispatchedOnAltTab() {
150+ // Press alt, make sure it does *not* end up in inputCatcher (aka, the focused app)
151+ inputCatcher.pressedKeys = [];
152+ keyPress(Qt.Key_Alt, Qt.NoModifier)
153+ compare(inputCatcher.pressedKeys.length, 0);
154+ // Now also press tab. As this should trigger the spread, neither of them should end up in the app
155+ keyPress(Qt.Key_Tab, Qt.NoModifier)
156+ compare(inputCatcher.pressedKeys.length, 0);
157+
158+ // Also the release events should not be dispatched to the app
159+ keyRelease(Qt.Key_Tab, Qt.NoModifier);
160+ keyRelease(Qt.Key_Alt, Qt.NoModifier);
161+ compare(inputCatcher.pressedKeys.length, 0);
162+ compare(inputCatcher.releasedKeys.length, 0);
163+ }
164+
165+ function test_altComboIsDispatched() {
166+ inputCatcher.pressedKeys = [];
167+ // Press alt, make sure it does *not* yet end up in inputCatcher (aka, the focused app)
168+ keyPress(Qt.Key_Alt, Qt.NoModifier)
169+ compare(inputCatcher.pressedKeys.length, 0);
170+ // Now press F in order to opening the File menu (Alt+F), now the app should get the full combo
171+ keyPress(Qt.Key_F, Qt.NoModifier)
172+ compare(inputCatcher.pressedKeys.length, 2);
173+ compare(inputCatcher.pressedKeys[0], Qt.Key_Alt);
174+ compare(inputCatcher.pressedKeys[1], Qt.Key_F);
175+
176+ // release them both, both are supposed to end up in the app
177+ keyRelease(Qt.Key_F, Qt.NoModifier);
178+ keyRelease(Qt.Key_Alt, Qt.NoModifier);
179+ compare(inputCatcher.releasedKeys.length, 2);
180+ }
107 }
181 }
108}
182}
tests/qmltests/Components/tst_ResponsiveGridView.qml−36
@@ -32,12 +32,6 @@ Item {
32 height: parent.height
32 height: parent.height
33 anchors.top: parent.top
33 anchors.top: parent.top
34 anchors.right: parent.right
34 anchors.right: parent.right
35− ListItem.ValueSelector {
36− id: maxColumnsSelector
37− text: "maximumNumberOfColumns"
38− values: [2,4,8,13,1000]
39− selectedIndex: 1
40− }
41 ListItem.ValueSelector {
35 ListItem.ValueSelector {
42 id: minHSpacingSelector
36 id: minHSpacingSelector
43 text: "minHorizontalSpacing"
37 text: "minHorizontalSpacing"
@@ -86,8 +80,6 @@ Item {
86 minimumHorizontalSpacing:
80 minimumHorizontalSpacing:
87 minHSpacingSelector.values[minHSpacingSelector.selectedIndex]
81 minHSpacingSelector.values[minHSpacingSelector.selectedIndex]
88 verticalSpacing: units.gu(2)
82 verticalSpacing: units.gu(2)
89− maximumNumberOfColumns:
90− maxColumnsSelector.values[maxColumnsSelector.selectedIndex]
91 delegateWidth: units.gu(6)
83 delegateWidth: units.gu(6)
92 delegateHeight: units.gu(6)
84 delegateHeight: units.gu(6)
93
85
@@ -123,31 +115,6 @@ Item {
123 name: "ResponsiveGridView"
115 name: "ResponsiveGridView"
124 when: windowShown
116 when: windowShown
125
117
126− function test_maximumNumberOfColumns_data() {
127− var data = new Array()
128−
129− data.push({selectedIndex: 0, maxColumnCount:2, columnCount: 2})
130− data.push({selectedIndex: 1, maxColumnCount:4, columnCount: 4})
131− data.push({selectedIndex: 2, maxColumnCount:8, columnCount: 8})
132− data.push({selectedIndex: 4, maxColumnCount:1000, columnCount: 13})
133−
134− return data
135− }
136−
137− /* Change ResponsiveGridView's maximumNumberOfColumns property and check
138− that the resulting number of columns matches expectations */
139− function test_maximumNumberOfColumns(data) {
140− minHSpacingSelector.selectedIndex = 0
141−
142− // sanity checks
143− compare(maxColumnsSelector.values[data.selectedIndex], data.maxColumnCount)
144− compare(minHSpacingSelector.values[0], 0)
145−
146− maxColumnsSelector.selectedIndex = data.selectedIndex
147− tryCompareFunction(countGridDelegatesOnFirstRow, data.columnCount);
148− compare(grid.columns, data.columnCount)
149− }
150−
151 function test_minimumHorizontalSpacing_data() {
118 function test_minimumHorizontalSpacing_data() {
152 var data = new Array()
119 var data = new Array()
153
120
@@ -162,10 +129,7 @@ Item {
162 /* Change ResponsiveGridView's minimumHorizontalSpacing property and check
129 /* Change ResponsiveGridView's minimumHorizontalSpacing property and check
163 that the resulting number of columns matches expectations */
130 that the resulting number of columns matches expectations */
164 function test_minimumHorizontalSpacing(data) {
131 function test_minimumHorizontalSpacing(data) {
165− maxColumnsSelector.selectedIndex = 4
166−
167 // sanity checks
132 // sanity checks
168− compare(maxColumnsSelector.values[4], 1000)
169 compare(minHSpacingSelector.values[data.selectedIndex], data.minHSpacing)
133 compare(minHSpacingSelector.values[data.selectedIndex], data.minHSpacing)
170
134
171 minHSpacingSelector.selectedIndex = data.selectedIndex
135 minHSpacingSelector.selectedIndex = data.selectedIndex
tests/qmltests/Components/tst_VirtualTouchPad.qmlnew file+143
@@ -0,0 +1,143 @@
1+/*
2+ * Copyright (C) 2015 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.4
18+import QtTest 1.0
19+import Unity.Test 0.1
20+import UInput 0.1
21+import "../../../qml/Components"
22+
23+
24+Item {
25+ id: root
26+ width: units.gu(70)
27+ height: units.gu(70)
28+
29+ VirtualTouchPad {
30+ id: touchScreenPad
31+ anchors.fill: parent
32+ }
33+
34+ SignalSpy {
35+ id: mouseEventSpy1
36+ target: touchScreenPad.uinput
37+ }
38+ SignalSpy {
39+ id: mouseEventSpy2
40+ target: touchScreenPad.uinput
41+ }
42+
43+ UnityTestCase {
44+ id: testCase
45+ name: "VirtualTouchPad"
46+ when: windowShown
47+
48+ function init() {
49+ mouseEventSpy1.clear();
50+ mouseEventSpy2.clear();
51+ }
52+
53+ function test_click() {
54+ mouseEventSpy1.signalName = "mousePressed"
55+ mouseEventSpy2.signalName = "mouseReleased"
56+
57+ var touchPadArea = findChild(touchScreenPad, "touchPadArea");
58+
59+ tap(touchPadArea)
60+ tryCompare(mouseEventSpy1, "count", 1)
61+ tryCompare(mouseEventSpy2, "count", 1)
62+ }
63+
64+ function test_doubleClick() {
65+ mouseEventSpy1.signalName = "mousePressed"
66+ mouseEventSpy2.signalName = "mouseReleased"
67+
68+ var touchPadArea = findChild(touchScreenPad, "touchPadArea");
69+
70+ tap(touchPadArea)
71+ tap(touchPadArea)
72+
73+ tryCompare(mouseEventSpy1, "count", 2)
74+ tryCompare(mouseEventSpy2, "count", 2)
75+ }
76+
77+ function test_move() {
78+ mouseEventSpy1.signalName = "mouseMoved"
79+
80+ var touchPadArea = findChild(touchScreenPad, "touchPadArea");
81+
82+ var moveDiff = units.gu(2);
83+ var moveSteps = 5;
84+
85+ touchFlick(touchPadArea, units.gu(1), units.gu(1), units.gu(1) + moveDiff, units.gu(1) + moveDiff, true, true, 10, moveSteps)
86+
87+ tryCompare(mouseEventSpy1, "count", moveSteps)
88+ var movedX = 0;
89+ var movedY = 0
90+ for (var i = 0; i < 5; i++) {
91+ movedX += mouseEventSpy1.signalArguments[i][0]
92+ movedY += mouseEventSpy1.signalArguments[i][1]
93+ }
94+ compare(movedX, moveDiff)
95+ compare(movedY, moveDiff)
96+ }
97+
98+ function test_doubleTapAndHoldToDrag() {
99+ mouseEventSpy1.signalName = "mousePressed"
100+ mouseEventSpy2.signalName = "mouseReleased"
101+
102+ var touchPadArea = findChild(touchScreenPad, "touchPadArea");
103+
104+ mouseClick(touchPadArea)
105+ mousePress(touchPadArea)
106+ mouseMove(touchPadArea, touchPadArea.width / 4, touchPadArea.height / 4)
107+
108+ tryCompare(mouseEventSpy1, "count", 1)
109+ tryCompare(mouseEventSpy2, "count", 0)
110+ mouseRelease(touchPadArea)
111+ tryCompare(mouseEventSpy2, "count", 1)
112+ }
113+
114+ function test_twoFingerScroll() {
115+ var touchPadArea = findChild(touchScreenPad, "touchPadArea");
116+
117+ mouseEventSpy1.signalName = "mouseScrolled"
118+
119+ var startX = touchPadArea.width / 2;
120+ var startY = touchPadArea.height / 2;
121+
122+ var startX1 = startX - units.gu(1);
123+ var startX2 = startX + units.gu(1);
124+
125+ var event = touchEvent(touchPadArea)
126+ event.press(0, startX1, startY)
127+ event.press(1, startX2, startY);
128+ event.commit()
129+
130+ for (var i = 0; i < 10; i++) {
131+ event.move(0, startX1, startY + units.gu(i))
132+ event.move(1, startX2, startY + units.gu(i));
133+ event.commit();
134+
135+ tryCompare(mouseEventSpy1, "count", i + 1);
136+ }
137+
138+ event.release(0, startX1, startY + units.gu(11))
139+ event.release(1, startX2, startY + units.gu(11));
140+ event.commit();
141+ }
142+ }
143+}
tests/qmltests/Components/tst_ZoomableImage.qml+8−5
@@ -73,7 +73,10 @@ Rectangle {
73 tryCompareFunction(function() { return get_filename(imageRenderer.source.toString()) === get_filename(widgetData1["source"]); }, true);
73 tryCompareFunction(function() { return get_filename(imageRenderer.source.toString()) === get_filename(widgetData1["source"]); }, true);
74 waitForRendering(zoomableImage);
74 waitForRendering(zoomableImage);
75 tryCompare(zoomableImage, "imageStatus", Image.Ready);
75 tryCompare(zoomableImage, "imageStatus", Image.Ready);
76− compare (signalSpy.count, 1);
76+ compare(signalSpy.count, 1);
77+ compare(imageRenderer.sourceSize.width, root.width);
78+ zoomableImage.zoomable = true;
79+ compare(imageRenderer.sourceSize.width, root.width*3);
77 }
80 }
78
81
79 function get_filename(a) {
82 function get_filename(a) {
@@ -138,14 +141,14 @@ Rectangle {
138 var imageRenderer = findChild(zoomableImage, "imageRenderer");
141 var imageRenderer = findChild(zoomableImage, "imageRenderer");
139 var flickable = findChild(zoomableImage, "flickable");
142 var flickable = findChild(zoomableImage, "flickable");
140
143
141− signalSpy.signalName = "onScaleChanged";
142− signalSpy.target = image;
143− signalSpy.clear();
144−
145 zoomableImage.source = data.source;
144 zoomableImage.source = data.source;
146 zoomableImage.zoomable = data.zoomable;
145 zoomableImage.zoomable = data.zoomable;
147 waitForRendering(zoomableImage);
146 waitForRendering(zoomableImage);
148
147
148+ signalSpy.signalName = "onScaleChanged";
149+ signalSpy.target = image;
150+ signalSpy.clear();
151+
149 tryCompare(zoomableImage, "imageStatus", Image.Ready);
152 tryCompare(zoomableImage, "imageStatus", Image.Ready);
150 tryCompareFunction(function() { return get_filename(imageRenderer.source.toString()) === get_filename(data.source); }, true);
153 tryCompareFunction(function() { return get_filename(imageRenderer.source.toString()) === get_filename(data.source); }, true);
151 waitForRendering(image);
154 waitForRendering(image);
tests/qmltests/Dash/Previews/tst_Preview.qml+5−6
@@ -121,15 +121,14 @@ Rectangle {
121 var moreLessButton = findChild(widget, "moreLessButton");
121 var moreLessButton = findChild(widget, "moreLessButton");
122 mouseClick(moreLessButton);
122 mouseClick(moreLessButton);
123
123
124− // Make sure the combo is growing
125− tryCompareFunction(function () { return widget.height > 2 * initialWidgetHeight; }, true);
126−
127 // Wait for the combo to stop growing
124 // Wait for the combo to stop growing
128− tryCompareFunction(function () { var currentWidgetHeight = widget.height; wait(200); return currentWidgetHeight === widget.height;}, true);
125+ tryCompare(widget, "height", units.gu(15));
129
126
130 // Make sure the combo bottom is on the viewport
127 // Make sure the combo bottom is on the viewport
128+ tryCompareFunction(function () {
131− var bottomLeft = preview.mapFromItem(widget, 0, widget.height);
129+ var bottomLeft = preview.mapFromItem(widget, 0, widget.height);
132− verify(bottomLeft.y <= preview.height);
130+ return bottomLeft.y <= preview.height
131+ }, true);
133 }
132 }
134 }
133 }
135}
134}
tests/qmltests/Dash/Previews/tst_PreviewAudioPlayback.qml+12−3
@@ -100,13 +100,17 @@ Rectangle {
100 }
100 }
101 }
101 }
102
102
103− function checkPlayerSource(index) {
103+ function checkPlayerUrls(modelFilename, playerUrl) {
104− var modelFilename = previewAudioPlayback.widgetData["tracks"][index]["source"].replace(/^.*[\\\/]/, '');
104+ var modelFilename = modelFilename.replace(/^.*[\\\/]/, '');
105− var playerFilename = DashAudioPlayer.currentSource.toString().replace(/^.*[\\\/]/, '');
105+ var playerFilename = playerUrl.toString().replace(/^.*[\\\/]/, '');
106
106
107 compare(modelFilename, playerFilename, "Player source is not set correctly.");
107 compare(modelFilename, playerFilename, "Player source is not set correctly.");
108 }
108 }
109
109
110+ function checkPlayerSource(index) {
111+ checkPlayerUrls(previewAudioPlayback.widgetData["tracks"][index]["source"], DashAudioPlayer.currentSource);
112+ }
113+
110 function test_playback() {
114 function test_playback() {
111 previewAudioPlayback.widgetData = tracksModel2;
115 previewAudioPlayback.widgetData = tracksModel2;
112 waitForRendering(previewAudioPlayback);
116 waitForRendering(previewAudioPlayback);
@@ -157,6 +161,11 @@ Rectangle {
157 tryCompare(audio, "playbackState", Audio.PlayingState);
161 tryCompare(audio, "playbackState", Audio.PlayingState);
158 checkPlayerSource(1);
162 checkPlayerSource(1);
159
163
164+ // Check the playlist is song 0, 1, 2
165+ checkPlayerUrls(tracksModel2["tracks"][0].source, audio.playlist.itemSource(0));
166+ checkPlayerUrls(tracksModel2["tracks"][1].source, audio.playlist.itemSource(1));
167+ checkPlayerUrls(tracksModel2["tracks"][2].source, audio.playlist.itemSource(2));
168+
160 tryCompare(track0ProgressBar, "visible", false);
169 tryCompare(track0ProgressBar, "visible", false);
161 tryCompare(track1ProgressBar, "visible", true);
170 tryCompare(track1ProgressBar, "visible", true);
162 tryCompare(track2ProgressBar, "visible", false);
171 tryCompare(track2ProgressBar, "visible", false);
tests/qmltests/Dash/Previews/tst_PreviewHeader.qml+15
@@ -54,6 +54,14 @@ Rectangle {
54 "attributes": [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}]
54 "attributes": [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}]
55 }
55 }
56
56
57+ property var emptyfallbackheaderjson: {
58+ "title": "THE TITLE",
59+ "subtitle": "Something catchy",
60+ "mascot": "",
61+ "fallback": "../graphics/play_button.png",
62+ "attributes": [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}]
63+ }
64+
57 PreviewHeader {
65 PreviewHeader {
58 id: previewHeader
66 id: previewHeader
59 widgetData: headerjson
67 widgetData: headerjson
@@ -150,6 +158,13 @@ Rectangle {
150 var mascot = findChild(previewHeader, "mascotShape");
158 var mascot = findChild(previewHeader, "mascotShape");
151 tryCompare(mascot, "visible", true);
159 tryCompare(mascot, "visible", true);
152 tryCompare(mascot.source, "status", Image.Ready);
160 tryCompare(mascot.source, "status", Image.Ready);
161+
162+ previewHeader.widgetData = {};
163+ previewHeader.widgetData = emptyfallbackheaderjson;
164+ tryCompareFunction(function() { return findChild(previewHeader, "mascotShape") != null }, true);
165+ var mascot = findChild(previewHeader, "mascotShape");
166+ tryCompare(mascot, "visible", true);
167+ tryCompare(mascot.source, "status", Image.Ready);
153 }
168 }
154 }
169 }
155}
170}
tests/qmltests/Dash/Previews/tst_PreviewImageGallery.qml+19
@@ -48,6 +48,16 @@ Rectangle {
48 , "fallback": "../../../tests/graphics/clock@18.png"
48 , "fallback": "../../../tests/graphics/clock@18.png"
49 }
49 }
50
50
51+ property var sourcesModelEmptyWithFallback: {
52+ "sources": [
53+ "../../graphics/phone_background.jpg",
54+ "../../graphics/tablet_background.jpg",
55+ "../../../tests/graphics/clock@18.png",
56+ ""
57+ ]
58+ , "fallback": "../../../tests/graphics/clock@18.png"
59+ }
60+
51 PreviewImageGallery {
61 PreviewImageGallery {
52 id: imageGallery
62 id: imageGallery
53 width: parent.width
63 width: parent.width
@@ -123,5 +133,14 @@ Rectangle {
123 image3 = findChild(imageGallery, "previewImage3");
133 image3 = findChild(imageGallery, "previewImage3");
124 tryCompare(image3, "state", "ready");
134 tryCompare(image3, "state", "ready");
125 }
135 }
136+
137+ function test_empty_fallback() {
138+ var image3 = findChild(imageGallery, "previewImage3");
139+ tryCompare(image3, "state", "error");
140+ imageGallery.widgetData = sourcesModel0;
141+ imageGallery.widgetData = sourcesModelEmptyWithFallback;
142+ image3 = findChild(imageGallery, "previewImage3");
143+ tryCompare(image3, "state", "ready");
144+ }
126 }
145 }
127}
146}
tests/qmltests/Dash/Previews/tst_PreviewZoomableImage.qml+12
@@ -39,6 +39,11 @@ Rectangle {
39 "fallback": "../../graphics/phone_background.jpg"
39 "fallback": "../../graphics/phone_background.jpg"
40 }
40 }
41
41
42+ property var widgetData3: {
43+ "source": "",
44+ "fallback": "../../graphics/phone_background.jpg"
45+ }
46+
42 Loader {
47 Loader {
43 id: loader
48 id: loader
44 width: parent.width
49 width: parent.width
@@ -100,5 +105,12 @@ Rectangle {
100 waitForRendering(lazyImage);
105 waitForRendering(lazyImage);
101 tryCompare(lazyImage, "state", "ready");
106 tryCompare(lazyImage, "state", "ready");
102 }
107 }
108+
109+ function test_emptyfallback() {
110+ zoomableImage.widgetData = widgetData3;
111+ waitForRendering(zoomableImage);
112+ waitForRendering(lazyImage);
113+ tryCompare(lazyImage, "state", "ready");
114+ }
103 }
115 }
104}
116}
tests/qmltests/Dash/tst_Card.qml+22−6
@@ -130,7 +130,6 @@ Rectangle {
130 sourceComponent: cardTool.cardComponent
130 sourceComponent: cardTool.cardComponent
131 clip: true
131 clip: true
132 onLoaded: {
132 onLoaded: {
133− item.components = Qt.binding(function() { return cardTool.components; });
134 item.cardData = Qt.binding(function() { return Helpers.mapData(dataArea.text, cardTool.components, dataError); });
133 item.cardData = Qt.binding(function() { return Helpers.mapData(dataArea.text, cardTool.components, dataError); });
135 item.width = Qt.binding(function() { return cardTool.cardWidth || item.implicitWidth; });
134 item.width = Qt.binding(function() { return cardTool.cardWidth || item.implicitWidth; });
136 item.height = Qt.binding(function() { return cardTool.cardHeight || item.implicitHeight; });
135 item.height = Qt.binding(function() { return cardTool.cardHeight || item.implicitHeight; });
@@ -232,6 +231,7 @@ Rectangle {
232 function init() {
231 function init() {
233 cardTool.components = Qt.binding(function() { return Helpers.update(JSON.parse(Helpers.defaultLayout), Helpers.tryParse(layoutArea.text, layoutError))['components']; });
232 cardTool.components = Qt.binding(function() { return Helpers.update(JSON.parse(Helpers.defaultLayout), Helpers.tryParse(layoutArea.text, layoutError))['components']; });
234 loader.visible = true;
233 loader.visible = true;
234+ waitForRendering(card);
235 }
235 }
236
236
237 function cleanup() {
237 function cleanup() {
@@ -306,8 +306,8 @@ Rectangle {
306 { tag: "Medium", width: units.gu(18), fill: Image.PreserveAspectCrop, index: 0 },
306 { tag: "Medium", width: units.gu(18), fill: Image.PreserveAspectCrop, index: 0 },
307 { tag: "Small", width: units.gu(12), index: 1 },
307 { tag: "Small", width: units.gu(12), index: 1 },
308 { tag: "Large", width: units.gu(38), index: 2 },
308 { tag: "Large", width: units.gu(38), index: 2 },
309− { tag: "Wide", height: units.gu(19), size: "large", index: 3 },
309+ { tag: "Wide", height: function() { return units.gu(19) }, size: "large", index: 3 },
310− { tag: "Tall", height: units.gu(38) / 0.7, size: "large", width: units.gu(38), index: 4 },
310+ { tag: "Tall", height: function() { return units.gu(38) / 0.7 }, size: "large", width: units.gu(38), index: 4 },
311 { tag: "VerticalWidth", width: function() { return headerRow.width + units.gu(1) }, index: 0 },
311 { tag: "VerticalWidth", width: function() { return headerRow.width + units.gu(1) }, index: 0 },
312 { tag: "HorizontalHeight", height: function() { return headerRow.height + units.gu(1) * 2 }, index: 5 },
312 { tag: "HorizontalHeight", height: function() { return headerRow.height + units.gu(1) * 2 }, index: 5 },
313 { tag: "HorizontalWidth", width: function() { return headerRow.x - units.gu(1) }, index: 5 },
313 { tag: "HorizontalWidth", width: function() { return headerRow.x - units.gu(1) }, index: 5 },
@@ -336,9 +336,7 @@ Rectangle {
336 }
336 }
337
337
338 if (data.hasOwnProperty("height")) {
338 if (data.hasOwnProperty("height")) {
339− if (typeof data.height === "function") {
340− tryCompareFunction(function() { return art.height === data.height() }, true);
339+ tryCompareFunction(function() { return art.height.toFixed(2) === data.height().toFixed(2) }, true);
341− } else tryCompare(art, "height", data.height);
342 }
340 }
343
341
344 if (data.hasOwnProperty("fill")) {
342 if (data.hasOwnProperty("fill")) {
@@ -477,6 +475,15 @@ Rectangle {
477 card.cardDataChanged();
475 card.cardDataChanged();
478 waitForRendering(card);
476 waitForRendering(card);
479 tryCompare(art, "visible", true);
477 tryCompare(art, "visible", true);
478+ compare(artImage.source, Qt.resolvedUrl("artwork/emblem.png"));
479+
480+ cardTool.components["art"]["fallback"] = Qt.resolvedUrl("artwork/checkers.png");
481+ cardTool.componentsChanged();
482+ card.cardData["art"] = "";
483+ card.cardDataChanged();
484+ waitForRendering(card);
485+ tryCompare(art, "visible", true);
486+ compare(artImage.source, Qt.resolvedUrl("artwork/checkers.png"));
480
487
481 card.cardData["mascot"] = "somethingbroken2";
488 card.cardData["mascot"] = "somethingbroken2";
482 card.cardDataChanged();
489 card.cardDataChanged();
@@ -488,6 +495,15 @@ Rectangle {
488 card.cardDataChanged();
495 card.cardDataChanged();
489 waitForRendering(card);
496 waitForRendering(card);
490 tryCompare(mascotImage, "status", Image.Ready);
497 tryCompare(mascotImage, "status", Image.Ready);
498+ compare(mascotImage.source, Qt.resolvedUrl("artwork/emblem.png"));
499+
500+ cardTool.components["mascot"] = {"fallback": Qt.resolvedUrl("artwork/checkers.png")};
501+ cardTool.componentsChanged();
502+ card.cardData["mascot"] = "";
503+ card.cardDataChanged();
504+ waitForRendering(card);
505+ tryCompare(mascotImage, "status", Image.Ready);
506+ compare(mascotImage.source, Qt.resolvedUrl("artwork/checkers.png"));
491 }
507 }
492
508
493 function test_font_weights_data() {
509 function test_font_weights_data() {
tests/qmltests/Dash/tst_CardBenchmark.qml−2
@@ -61,8 +61,6 @@ Rectangle {
61 item.width = Qt.binding(function() { return cardTool.cardWidth || implicitWidth; });
61 item.width = Qt.binding(function() { return cardTool.cardWidth || implicitWidth; });
62 item.height = Qt.binding(function() { return cardTool.cardHeight || implicitHeight; });
62 item.height = Qt.binding(function() { return cardTool.cardHeight || implicitHeight; });
63 item.cardData = Qt.binding(function() { return Helpers.mapData(root.cardData, cardTool.components); });
63 item.cardData = Qt.binding(function() { return Helpers.mapData(root.cardData, cardTool.components); });
64− item.template = Qt.binding(function() { return cardTool.template; });
65− item.components = Qt.binding(function() { return cardTool.components; });
66 }
64 }
67 }
65 }
68 }
66 }
tests/qmltests/Dash/tst_GenericScopeView.qml+30−9
@@ -107,11 +107,12 @@ Item {
107 {
107 {
108 var categoryListView = findChild(genericScopeView, "categoryListView");
108 var categoryListView = findChild(genericScopeView, "categoryListView");
109 waitForRendering(categoryListView);
109 waitForRendering(categoryListView);
110− while (!categoryListView.atYEnd) {
110+ tryCompareFunction(function() {
111− mouseFlick(genericScopeView, genericScopeView.width/2, genericScopeView.height - units.gu(8),
111+ mouseFlick(genericScopeView, genericScopeView.width/2, genericScopeView.height - units.gu(8),
112− genericScopeView.width/2, genericScopeView.y)
112+ genericScopeView.width/2, genericScopeView.y)
113− tryCompare(categoryListView, "moving", false);
113+ tryCompare(categoryListView, "moving", false);
114− }
114+ return categoryListView.atYEnd;
115+ }, true);
115 }
116 }
116
117
117 function test_isActive() {
118 function test_isActive() {
@@ -238,7 +239,7 @@ Item {
238
239
239 openPreview(4, 0);
240 openPreview(4, 0);
240
241
241− compare(testCase.subPageLoader.count, 12, "There should only be 12 items in preview.");
242+ compare(testCase.subPageLoader.count, 16, "There should only be 16 items in preview.");
242
243
243 closePreview();
244 closePreview();
244 }
245 }
@@ -413,7 +414,7 @@ Item {
413 var previewListViewList = findChild(subPageLoader.item, "listView");
414 var previewListViewList = findChild(subPageLoader.item, "listView");
414
415
415 // flick to the next previews
416 // flick to the next previews
416− tryCompare(testCase.subPageLoader, "count", 15);
417+ tryCompare(testCase.subPageLoader, "count", 25);
417 for (var i = 1; i < testCase.subPageLoader.count; ++i) {
418 for (var i = 1; i < testCase.subPageLoader.count; ++i) {
418 mouseFlick(testCase.subPageLoader.item, testCase.subPageLoader.width - units.gu(1),
419 mouseFlick(testCase.subPageLoader.item, testCase.subPageLoader.width - units.gu(1),
419 testCase.subPageLoader.height / 2,
420 testCase.subPageLoader.height / 2,
@@ -487,7 +488,7 @@ Item {
487 mockScope.setName("Mock Scope");
488 mockScope.setName("Mock Scope");
488 mockScope.categories.setCount(2);
489 mockScope.categories.setCount(2);
489 mockScope.categories.resultModel(0).setResultCount(50);
490 mockScope.categories.resultModel(0).setResultCount(50);
490− mockScope.categories.resultModel(1).setResultCount(15);
491+ mockScope.categories.resultModel(1).setResultCount(25);
491 mockScope.categories.setLayout(0, "grid");
492 mockScope.categories.setLayout(0, "grid");
492 mockScope.categories.setLayout(1, "grid");
493 mockScope.categories.setLayout(1, "grid");
493 mockScope.categories.setHeaderLink(0, "");
494 mockScope.categories.setHeaderLink(0, "");
@@ -529,7 +530,7 @@ Item {
529 mockScope.setId("mockScope");
530 mockScope.setId("mockScope");
530 mockScope.setName("Mock Scope");
531 mockScope.setName("Mock Scope");
531 mockScope.categories.setCount(2);
532 mockScope.categories.setCount(2);
532− mockScope.categories.resultModel(0).setResultCount(15);
533+ mockScope.categories.resultModel(0).setResultCount(25);
533 mockScope.categories.resultModel(1).setResultCount(50);
534 mockScope.categories.resultModel(1).setResultCount(50);
534 mockScope.categories.setLayout(0, "grid");
535 mockScope.categories.setLayout(0, "grid");
535 mockScope.categories.setLayout(1, "grid");
536 mockScope.categories.setLayout(1, "grid");
@@ -666,6 +667,26 @@ Item {
666 var shape = findChildsByType(artShapeLoader, "UCUbuntuShape");
667 var shape = findChildsByType(artShapeLoader, "UCUbuntuShape");
667 compare(shape.borderSource, undefined);
668 compare(shape.borderSource, undefined);
668 }
669 }
670+
671+ function test_clickScopeSizing() {
672+ genericScopeView.scope = scopes.getScopeFromAll("clickscope");
673+ waitForRendering(genericScopeView);
674+
675+ var categoryListView = findChild(genericScopeView, "categoryListView");
676+ waitForRendering(categoryListView);
677+
678+ var categorypredefined = findChild(categoryListView, "dashCategorypredefined");
679+ waitForRendering(categorypredefined);
680+
681+ var cardTool = findChild(categorypredefined, "cardTool");
682+
683+ compare(cardTool.cardWidth, units.gu(11));
684+ shell.width = units.gu(46);
685+ waitForRendering(genericScopeView);
686+ compare(cardTool.cardWidth, units.gu(10));
687+
688+ shell.width = units.gu(120)
689+ }
669 }
690 }
670 }
691 }
671}
692}
tests/qmltests/Greeter/tst_WideView.qml+11
@@ -619,5 +619,16 @@ Item {
619
619
620 tryCompare(loginList, "height", view.height);
620 tryCompare(loginList, "height", view.height);
621 }
621 }
622+
623+ function test_alphanumeric() {
624+ var passwordInput = findChild(view, "passwordInput");
625+
626+ verify(view.alphanumeric);
627+ compare(passwordInput.inputMethodHints, Qt.ImhNone);
628+ view.alphanumeric = false;
629+ compare(passwordInput.inputMethodHints, Qt.ImhDigitsOnly);
630+ view.alphanumeric = true;
631+ compare(passwordInput.inputMethodHints, Qt.ImhNone);
632+ }
622 }
633 }
623}
634}
tests/qmltests/Launcher/tst_Launcher.qml+26
@@ -159,6 +159,20 @@ Item {
159 target: LauncherModel
159 target: LauncherModel
160 }
160 }
161
161
162+ Item {
163+ id: fakeDismissTimer
164+ property bool running: false
165+ signal triggered
166+
167+ function stop() {
168+ running = false;
169+ }
170+
171+ function restart() {
172+ running = true;
173+ }
174+ }
175+
162 UnityTestCase {
176 UnityTestCase {
163 id: testCase
177 id: testCase
164 name: "Launcher"
178 name: "Launcher"
@@ -177,6 +191,11 @@ Item {
177 launcherLoader.active = true;
191 launcherLoader.active = true;
178 }
192 }
179 function init() {
193 function init() {
194+ var panel = findChild(launcher, "launcherPanel");
195+ verify(!!panel);
196+
197+ panel.dismissTimer = fakeDismissTimer;
198+
180 // Make sure we don't start the test with the mouse hovering the launcher
199 // Make sure we don't start the test with the mouse hovering the launcher
181 mouseMove(root, root.width, root.height / 2);
200 mouseMove(root, root.width, root.height / 2);
182
201
@@ -195,6 +214,8 @@ Item {
195
214
196 // Now do check that snapping is in fact enabled
215 // Now do check that snapping is in fact enabled
197 compare(listView.snapMode, ListView.SnapToItem, "Snapping is not enabled");
216 compare(listView.snapMode, ListView.SnapToItem, "Snapping is not enabled");
217+
218+ removeTimeConstraintsFromDirectionalDragAreas(root);
198 }
219 }
199
220
200 function dragLauncherIntoView() {
221 function dragLauncherIntoView() {
@@ -895,6 +916,11 @@ Item {
895 // Now move the mouse away and make sure it hides in less than a second
916 // Now move the mouse away and make sure it hides in less than a second
896 mouseMove(root, root.width, root.height / 2)
917 mouseMove(root, root.width, root.height / 2)
897
918
919+ // trigger the hide timer
920+ compare(fakeDismissTimer.running, true);
921+ fakeDismissTimer.triggered();
922+ tryCompare(panel, "x", 0);
923+
898 tryCompare(launcher, "state", "", 1000, "Launcher didn't hide after moving mouse away from it");
924 tryCompare(launcher, "state", "", 1000, "Launcher didn't hide after moving mouse away from it");
899 waitUntilLauncherDisappears();
925 waitUntilLauncherDisappears();
900 }
926 }
tests/qmltests/Stages/RecursingChildSessionControl.qml+3−3
@@ -88,7 +88,7 @@ ColumnLayout {
88
88
89 CheckBox {
89 CheckBox {
90 id: _surfaceCheckbox;
90 id: _surfaceCheckbox;
91− checked: false;
91+ checked: root.session.lastSurface ? true : false
92 activeFocusOnPress: false
92 activeFocusOnPress: false
93 enabled: root.session
93 enabled: root.session
94 onCheckedChanged: {
94 onCheckedChanged: {
@@ -101,7 +101,7 @@ ColumnLayout {
101
101
102 Connections {
102 Connections {
103 target: root.session ? root.session : null
103 target: root.session ? root.session : null
104− onSurfaceChanged: {
104+ onLastSurfaceChanged: {
105 surfaceCheckbox.checked = root.session.lastSurface !== null
105 surfaceCheckbox.checked = root.session.lastSurface !== null
106 }
106 }
107 }
107 }
@@ -137,7 +137,7 @@ ColumnLayout {
137 text: "Add Child"
137 text: "Add Child"
138 onClicked: {
138 onClicked: {
139 var screenshot = Math.round(Math.random()*100 % (screenshotIds.length-1));
139 var screenshot = Math.round(Math.random()*100 % (screenshotIds.length-1));
140− var session = ApplicationTest.addChildSession(root.session, root.screenshotIds[screenshot]);
140+ var session = ApplicationTest.addChildSession(root.session, root.screenshotIds[screenshot], true);
141 }
141 }
142 }
142 }
143 }
143 }
tests/qmltests/Stages/SizeHintField.qmlnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright 2015 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.4
18+import QtQuick.Layouts 1.1
19+import Ubuntu.Components 1.3
20+
21+Row {
22+ property alias text: label.text
23+ property alias value: field.text
24+ spacing: units.gu(1)
25+ Label {
26+ id: label
27+ color: "black"; anchors.verticalCenter: parent.verticalCenter
28+ }
29+ TextField {
30+ id: field
31+ text: ""; width: units.gu(8); hasClearButton: false; maximumLength: 6; inputMask: "d00000"
32+ }
33+}
tests/qmltests/Stages/SurfaceManagerControls.qmlnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2015 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.4
18+import Ubuntu.Components 1.3
19+import Unity.Application 0.1
20+
21+Column {
22+ id: root
23+ property color textColor: "black"
24+
25+ Label {text: "Size hints for new surface:"; color: root.textColor; font.bold: true}
26+
27+ SurfaceManagerField { text: "min width"; propertyName: "newSurfaceMinimumWidth"; textColor: root.textColor }
28+ SurfaceManagerField { text: "max width"; propertyName: "newSurfaceMaximumWidth"; textColor: root.textColor }
29+ SurfaceManagerField { text: "min height"; propertyName: "newSurfaceMinimumHeight"; textColor: root.textColor }
30+ SurfaceManagerField { text: "max height"; propertyName: "newSurfaceMaximumHeight"; textColor: root.textColor }
31+ SurfaceManagerField { text: "width increment"; propertyName: "newSurfaceWidthIncrement"; textColor: root.textColor }
32+ SurfaceManagerField { text: "height increment"; propertyName: "newSurfaceHeightIncrement"; textColor: root.textColor }
33+}
tests/qmltests/Stages/SurfaceManagerField.qmlnew file+40
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright (C) 2015 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.4
18+import Ubuntu.Components 1.3
19+import Unity.Application 0.1
20+
21+Row {
22+ id: root
23+ property alias textColor: label.color
24+ property alias text: label.text
25+ property string propertyName
26+
27+ Label {id: label; anchors.verticalCenter: parent.verticalCenter}
28+ TextField {
29+ width: units.gu(10); hasClearButton: false; maximumLength: 6
30+ inputMask: "d00000"
31+ text: ""
32+ onTextChanged: {
33+ if (text.length > 0) {
34+ SurfaceManager[root.propertyName] = parseInt(text);
35+ } else {
36+ SurfaceManager[root.propertyName] = 0;
37+ }
38+ }
39+ }
40+}
tests/qmltests/Stages/tst_DesktopStage.qml+30−24
@@ -89,36 +89,42 @@ Item {
89 right: parent.right
89 right: parent.right
90 }
90 }
91
91
92− Column {
92+ Flickable {
93− anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
93+ anchors.fill: parent
94+ contentHeight: controlsColumn.height
95+ Column {
96+ id: controlsColumn
94− spacing: units.gu(1)
97+ spacing: units.gu(1)
95−
98+
96− Button {
99+ Button {
97− color: "white"
100+ color: "white"
98− text: "Make surface slow to resize"
101+ text: "Make surface slow to resize"
99− activeFocusOnPress: false
102+ activeFocusOnPress: false
100− onClicked: {
103+ onClicked: {
101− if (ApplicationManager.focusedApplicationId) {
104+ if (ApplicationManager.focusedApplicationId) {
102− var surface = ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).session.lastSurface;
105+ var surface = ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).session.lastSurface;
103− surface.slowToResize = true;
106+ surface.slowToResize = true;
107+ }
104 }
108 }
105 }
109 }
106− }
107
110
108− EdgeBarrierControls {
111+ EdgeBarrierControls {
109− id: edgeBarrierControls
112+ id: edgeBarrierControls
110− text: "Drag here to pull out spread"
113+ text: "Drag here to pull out spread"
111− backgroundColor: "blue"
114+ backgroundColor: "blue"
112− onDragged: { desktopStageLoader.item.pushRightEdge(amount); }
115+ onDragged: { desktopStageLoader.item.pushRightEdge(amount); }
113− }
116+ }
114
117
115− Divider {}
118+ Divider {}
116
119
117− Repeater {
120+ Repeater {
118− model: ApplicationManager.availableApplications
121+ model: ApplicationManager.availableApplications
119− ApplicationCheckBox {
122+ ApplicationCheckBox {
120− appId: modelData
123+ appId: modelData
124+ }
121 }
125 }
126+
127+ SurfaceManagerControls { textColor: "white" }
122 }
128 }
123 }
129 }
124 }
130 }
tests/qmltests/Stages/tst_SessionContainer.qml+27−5
@@ -155,7 +155,8 @@ Rectangle {
155 var sessions = [];
155 var sessions = [];
156 for (i = 0; i < data.count; i++) {
156 for (i = 0; i < data.count; i++) {
157 var session = ApplicationTest.addChildSession(sessionContainer.session,
157 var session = ApplicationTest.addChildSession(sessionContainer.session,
158− "gallery");
158+ "gallery",
159+ true);
159 session.createSurface();
160 session.createSurface();
160 sessionContainer.session.addChildSession(session);
161 sessionContainer.session.addChildSession(session);
161 compare(sessionContainer.childSessions.count(), i+1);
162 compare(sessionContainer.childSessions.count(), i+1);
@@ -180,7 +181,7 @@ Rectangle {
180 // 3 sessions should cover all edge cases
181 // 3 sessions should cover all edge cases
181 for(i = 0; i < 3; i++) {
182 for(i = 0; i < 3; i++) {
182 var a_session = ApplicationTest.addChildSession(
183 var a_session = ApplicationTest.addChildSession(
183− sessionContainer.session, "gallery"
184+ sessionContainer.session, "gallery", true
184 )
185 )
185
186
186 a_session.createSurface();
187 a_session.createSurface();
@@ -226,7 +227,8 @@ Rectangle {
226 var container = sessionContainer;
227 var container = sessionContainer;
227 for (i = 0; i < data.depth; i++) {
228 for (i = 0; i < data.depth; i++) {
228 var session = ApplicationTest.addChildSession(lastSession,
229 var session = ApplicationTest.addChildSession(lastSession,
229− "gallery");
230+ "gallery",
231+ true);
230 session.createSurface();
232 session.createSurface();
231 lastSession.addChildSession(session);
233 lastSession.addChildSession(session);
232 compare(container.childSessions.count(), 1);
234 compare(container.childSessions.count(), 1);
@@ -250,7 +252,8 @@ Rectangle {
250 var sessionContainer = sessionContainerLoader.item;
252 var sessionContainer = sessionContainerLoader.item;
251
253
252 var session = ApplicationTest.addChildSession(sessionContainer.session,
254 var session = ApplicationTest.addChildSession(sessionContainer.session,
253− "gallery");
255+ "gallery",
256+ true);
254 session.createSurface();
257 session.createSurface();
255 sessionContainer.session.addChildSession(session);
258 sessionContainer.session.addChildSession(session);
256
259
@@ -288,7 +291,8 @@ Rectangle {
288 var sessionContainer = sessionContainerLoader.item;
291 var sessionContainer = sessionContainerLoader.item;
289
292
290 var session = ApplicationTest.addChildSession(sessionContainer.session,
293 var session = ApplicationTest.addChildSession(sessionContainer.session,
291− "gallery");
294+ "gallery",
295+ true);
292
296
293 var delegate = findChild(sessionContainer, "childDelegate0");
297 var delegate = findChild(sessionContainer, "childDelegate0");
294 var childContainer = findChild(delegate, "sessionContainer");
298 var childContainer = findChild(delegate, "sessionContainer");
@@ -304,6 +308,24 @@ Rectangle {
304 tryCompareFunction(function() { return isContainerAnimating(childContainer); }, true);
308 tryCompareFunction(function() { return isContainerAnimating(childContainer); }, true);
305 // wait for animation to end
309 // wait for animation to end
306 tryCompareFunction(function() { return isContainerAnimating(childContainer); }, false);
310 tryCompareFunction(function() { return isContainerAnimating(childContainer); }, false);
311+
312+ tryCompareFunction(function() { return sessionContainer.childSessions.count() }, 0);
313+ }
314+
315+ function test_childSessionsRemovedOnStopWhenNotLive() {
316+ sessionCheckbox.checked = true;
317+ var sessionContainer = sessionContainerLoader.item;
318+
319+ var session = ApplicationTest.addChildSession(sessionContainer.session,
320+ "gallery",
321+ false);
322+
323+ var delegate = findChild(sessionContainer, "childDelegate0");
324+ var childContainer = findChild(delegate, "sessionContainer");
325+
326+ ApplicationTest.removeSession(session);
327+
328+ tryCompareFunction(function() { return sessionContainer.childSessions.count() }, 0);
307 }
329 }
308 }
330 }
309}
331}
tests/qmltests/Stages/tst_WindowResizeArea.qml+225−30
@@ -28,7 +28,7 @@ import Unity.Application 0.1
28Item {
28Item {
29 id: root
29 id: root
30 height: units.gu(60)
30 height: units.gu(60)
31− width: units.gu(60)
31+ width: units.gu(85)
32
32
33 Binding {
33 Binding {
34 target: PanelState
34 target: PanelState
@@ -41,14 +41,20 @@ Item {
41
41
42 Item {
42 Item {
43 id: fakeWindow
43 id: fakeWindow
44− property alias minWidth: windowResizeArea.minWidth
44+ property alias resizeAreaMinWidth: windowResizeArea.minWidth
45− property alias minHeight: windowResizeArea.minHeight
45+ property alias resizeAreaMinHeight: windowResizeArea.minHeight
46 x: units.gu(20)
46 x: units.gu(20)
47 y: units.gu(20)
47 y: units.gu(20)
48 width: requestedWidth
48 width: requestedWidth
49 height: requestedHeight
49 height: requestedHeight
50 property real requestedWidth
50 property real requestedWidth
51 property real requestedHeight
51 property real requestedHeight
52+ property real minimumWidth: 0
53+ property real minimumHeight: 0
54+ property real maximumWidth: 0
55+ property real maximumHeight: 0
56+ property real widthIncrement: 0
57+ property real heightIncrement: 0
52 state: "normal"
58 state: "normal"
53
59
54 function maximize() {
60 function maximize() {
@@ -80,6 +86,10 @@ Item {
80 anchors.fill: parent
86 anchors.fill: parent
81 hoverEnabled: true
87 hoverEnabled: true
82 }
88 }
89+ Text {
90+ text: parent.width + "x" + parent.height
91+ color: "white"
92+ }
83 }
93 }
84 }
94 }
85 }
95 }
@@ -90,27 +100,107 @@ Item {
90 active: windowLoaderCheckbox.checked
100 active: windowLoaderCheckbox.checked
91 }
101 }
92
102
103+ Rectangle {
104+ anchors.right: parent.right
105+ anchors.top: parent.top
106+ anchors.bottom: parent.bottom
107+ width: units.gu(25)
108+ color: "lightgrey"
93− Column {
109+ Column {
110+ width: parent.width
111+ spacing: units.gu(1)
94− MouseTouchEmulationCheckbox {
112+ MouseTouchEmulationCheckbox {
95− checked: false
113+ checked: false
96− color: "black"
114+ color: "black"
97− }
115+ }
98− RowLayout {
116+ RowLayout {
99− Layout.fillWidth: true
117+ Layout.fillWidth: true
100− CheckBox {
118+ CheckBox {
101− id: windowLoaderCheckbox
119+ id: windowLoaderCheckbox
102− checked: true
120+ checked: true
103− activeFocusOnPress: false
121+ activeFocusOnPress: false
122+ }
123+ Label {
124+ color: "black"
125+ text: "Window loader active"
126+ anchors.verticalCenter: parent.verticalCenter
127+ }
104 }
128 }
105 Label {
129 Label {
106− id: label
130+ color: "black"; font.bold: true
131+ text: "Size Hints:"
132+ }
133+ SizeHintField { id: minWidthText; text: "min width" }
134+ SizeHintField { id: maxWidthText; text: "max width" }
135+ SizeHintField { id: minHeightText; text: "min height" }
136+ SizeHintField { id: maxHeightText; text: "max height" }
137+ SizeHintField { id: widthIncrText; text: "width incr" }
138+ SizeHintField { id: heightIncrText; text: "height incr" }
139+ Button {
107 color: "black"
140 color: "black"
108− text: "Window loader active"
141+ anchors.horizontalCenter: parent.horizontalCenter
109− anchors.verticalCenter: parent.verticalCenter
142+ text: "Apply"
143+ onClicked: {
144+ var value = parseInt(minWidthText.value);
145+ if (isNaN(value)) {
146+ windowLoader.item.minimumWidth = 0;
147+ } else {
148+ windowLoader.item.resizeAreaMinWidth = 1; // get it out of the way
149+ windowLoader.item.minimumWidth = value;
150+ }
151+
152+ value = parseInt(maxWidthText.value);
153+ if (isNaN(value)) {
154+ windowLoader.item.maximumWidth = 0;
155+ } else {
156+ windowLoader.item.maximumWidth = value;
157+ }
158+
159+ value = parseInt(minHeightText.value);
160+ if (isNaN(value)) {
161+ windowLoader.item.minimumHeight = 0;
162+ } else {
163+ windowLoader.item.resizeAreaMinHeight = 1; // get it out of the way
164+ windowLoader.item.minimumHeight = value;
165+ }
166+
167+ value = parseInt(maxHeightText.value);
168+ if (isNaN(value)) {
169+ windowLoader.item.maximumHeight = 0;
170+ } else {
171+ windowLoader.item.maximumHeight = value;
172+ }
173+
174+ value = parseInt(widthIncrText.value);
175+ if (isNaN(value)) {
176+ windowLoader.item.widthIncrement = 0;
177+ } else {
178+ windowLoader.item.widthIncrement = value;
179+ }
180+
181+ value = parseInt(heightIncrText.value);
182+ if (isNaN(value)) {
183+ windowLoader.item.heightIncrement = 0;
184+ } else {
185+ windowLoader.item.heightIncrement = value;
186+ }
187+ }
110 }
188 }
111 }
189 }
112 }
190 }
113
191
192+ SignalSpy {
193+ id: windowRequestedWidthSpy
194+ target: windowLoader.item
195+ signalName: "onRequestedWidthChanged"
196+ }
197+
198+ SignalSpy {
199+ id: windowRequestedHeightSpy
200+ target: windowLoader.item
201+ signalName: "onRequestedHeightChanged"
202+ }
203+
114 UnityTestCase {
204 UnityTestCase {
115 name: "WindowResizeArea"
205 name: "WindowResizeArea"
116 when: windowShown
206 when: windowShown
@@ -122,6 +212,18 @@ Item {
122 fakeWindow.y = units.gu(20)
212 fakeWindow.y = units.gu(20)
123 fakeWindow.requestedWidth = units.gu(20)
213 fakeWindow.requestedWidth = units.gu(20)
124 fakeWindow.requestedHeight = units.gu(20)
214 fakeWindow.requestedHeight = units.gu(20)
215+ fakeWindow.resizeAreaMinWidth = units.gu(15);
216+ fakeWindow.resizeAreaMinHeight = units.gu(10);
217+ fakeWindow.minimumWidth = 0;
218+ fakeWindow.minimumHeight = 0;
219+ fakeWindow.maximumWidth = 0;
220+ fakeWindow.maximumHeight = 0;
221+ fakeWindow.widthIncrement = 0;
222+ fakeWindow.heightIncrement = 0;
223+
224+ // Our test window resizes instantly
225+ compare(fakeWindow.width, fakeWindow.requestedWidth);
226+ compare(fakeWindow.height, fakeWindow.requestedHeight);
125 }
227 }
126
228
127 function test_resizeWindowRightBottom_data() {
229 function test_resizeWindowRightBottom_data() {
@@ -143,8 +245,8 @@ Item {
143 var startDragY = initialWindowY + initialWindowHeight + 1
245 var startDragY = initialWindowY + initialWindowHeight + 1
144 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
246 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
145
247
146− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + data.dx, fakeWindow.minWidth));
248+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + data.dx, fakeWindow.resizeAreaMinWidth));
147− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + data.dy, fakeWindow.minHeight));
249+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + data.dy, fakeWindow.resizeAreaMinHeight));
148
250
149 compare(fakeWindow.x, initialWindowX);
251 compare(fakeWindow.x, initialWindowX);
150 compare(fakeWindow.y, initialWindowY);
252 compare(fakeWindow.y, initialWindowY);
@@ -169,11 +271,11 @@ Item {
169 var startDragY = initialWindowY - 1
271 var startDragY = initialWindowY - 1
170 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
272 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
171
273
172− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - data.dx, fakeWindow.minWidth));
274+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - data.dx, fakeWindow.resizeAreaMinWidth));
173− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - data.dy, fakeWindow.minHeight));
275+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - data.dy, fakeWindow.resizeAreaMinHeight));
174
276
175− var maxMoveX = initialWindowWidth - fakeWindow.minWidth;
277+ var maxMoveX = initialWindowWidth - fakeWindow.resizeAreaMinWidth;
176− var maxMoveY = initialWindowHeight - fakeWindow.minHeight;
278+ var maxMoveY = initialWindowHeight - fakeWindow.resizeAreaMinHeight;
177 compare(fakeWindow.x, Math.min(initialWindowX + data.dx, initialWindowX + maxMoveX));
279 compare(fakeWindow.x, Math.min(initialWindowX + data.dx, initialWindowX + maxMoveX));
178 compare(fakeWindow.y, Math.min(initialWindowY + data.dy, initialWindowY + maxMoveY));
280 compare(fakeWindow.y, Math.min(initialWindowY + data.dy, initialWindowY + maxMoveY));
179 }
281 }
@@ -189,8 +291,8 @@ Item {
189 var startDragY = initialWindowY + initialWindowHeight + 1
291 var startDragY = initialWindowY + initialWindowHeight + 1
190 mouseFlick(root, startDragX, startDragY, startDragX + resizeDelta, startDragY + resizeDelta, true, true, units.gu(.5), 10);
292 mouseFlick(root, startDragX, startDragY, startDragX + resizeDelta, startDragY + resizeDelta, true, true, units.gu(.5), 10);
191
293
192− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.minWidth));
294+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.resizeAreaMinWidth));
193− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.minHeight));
295+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.resizeAreaMinHeight));
194
296
195 // This will destroy the window and recreate it
297 // This will destroy the window and recreate it
196 windowLoader.active = false;
298 windowLoader.active = false;
@@ -198,8 +300,8 @@ Item {
198 windowLoader.active = true;
300 windowLoader.active = true;
199
301
200 // Make sure its size is again the same as before
302 // Make sure its size is again the same as before
201− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.minWidth));
303+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.resizeAreaMinWidth));
202− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.minHeight));
304+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.resizeAreaMinHeight));
203 }
305 }
204
306
205 // This tests if dragging smaller than minSize and then larger again, will keep the edge sticking
307 // This tests if dragging smaller than minSize and then larger again, will keep the edge sticking
@@ -220,8 +322,8 @@ Item {
220 var startDragX = initialWindowX + data.startX
322 var startDragX = initialWindowX + data.startX
221 var startDragY = initialWindowY + data.startY
323 var startDragY = initialWindowY + data.startY
222 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, false, units.gu(.05), 10);
324 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, false, units.gu(.05), 10);
223− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - Math.abs(data.dx), fakeWindow.minWidth));
325+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - Math.abs(data.dx), fakeWindow.resizeAreaMinWidth));
224− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - Math.abs(data.dy), fakeWindow.minHeight));
326+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - Math.abs(data.dy), fakeWindow.resizeAreaMinHeight));
225 mouseFlick(root, startDragX + data.dx, startDragY + data.dy, startDragX, startDragY, false, true, units.gu(.05), 10);
327 mouseFlick(root, startDragX + data.dx, startDragY + data.dy, startDragX, startDragY, false, true, units.gu(.05), 10);
226 tryCompare(fakeWindow, "width", initialWindowWidth);
328 tryCompare(fakeWindow, "width", initialWindowWidth);
227 tryCompare(fakeWindow, "height", initialWindowHeight);
329 tryCompare(fakeWindow, "height", initialWindowHeight);
@@ -257,7 +359,6 @@ Item {
257 fakeWindow.state = "normal"
359 fakeWindow.state = "normal"
258 }
360 }
259
361
260−
261 function test_restoreMovesIntoBounds_data() {
362 function test_restoreMovesIntoBounds_data() {
262 return [
363 return [
263 {tag: "left off", x: -units.gu(5), y: units.gu(5), w: units.gu(10), h: units.gu(10)},
364 {tag: "left off", x: -units.gu(5), y: units.gu(5), w: units.gu(10), h: units.gu(10)},
@@ -290,5 +391,99 @@ Item {
290
391
291 waitForRendering(root)
392 waitForRendering(root)
292 }
393 }
394+
395+ /*
396+ Tests that even though you dragged the window bottom right corner continously (ie,
397+ through multiple intermediate steps), its (requested) width and height changed only
398+ once. And, furthermore, its dimensions increased by a multiple of its size (width
399+ and height) increment value.
400+ */
401+ function test_sizeIncrement() {
402+ var initialWindowX = fakeWindow.x;
403+ var initialWindowY = fakeWindow.y;
404+ var initialWindowWidth = fakeWindow.width
405+ var initialWindowHeight = fakeWindow.height
406+
407+ fakeWindow.widthIncrement = 70;
408+ fakeWindow.heightIncrement = 70;
409+
410+ var startDragX = initialWindowX + initialWindowWidth + 1
411+ var startDragY = initialWindowY + initialWindowHeight + 1
412+ var deltaX = 100;
413+ var deltaY = 100;
414+
415+ windowRequestedWidthSpy.clear();
416+ verify(windowRequestedWidthSpy.valid);
417+
418+ windowRequestedHeightSpy.clear();
419+ verify(windowRequestedHeightSpy.valid);
420+
421+ mouseFlick(root, startDragX, startDragY, startDragX + deltaX, startDragY + deltaY, true, true, units.gu(.5), 10);
422+
423+ compare(windowRequestedWidthSpy.count, 1);
424+ compare(fakeWindow.width, initialWindowWidth + fakeWindow.widthIncrement);
425+ compare(windowRequestedHeightSpy.count, 1);
426+ compare(fakeWindow.height, initialWindowHeight + fakeWindow.heightIncrement);
427+ }
428+
429+ /*
430+ Tests that when dragging a window border you cannot make it bigger than its maximum size
431+ */
432+ function test_maximumSize() {
433+ fakeWindow.x = units.gu(1);
434+ fakeWindow.y = units.gu(1);
435+ fakeWindow.resizeAreaMinWidth = 1; // so it does not interfere with anything
436+ fakeWindow.resizeAreaMinHeight = 1; // so it does not interfere with anything
437+ fakeWindow.requestedWidth = units.gu(10);
438+ fakeWindow.requestedHeight = units.gu(10);
439+
440+ fakeWindow.maximumWidth = units.gu(20);
441+ fakeWindow.maximumHeight = units.gu(20);
442+
443+ // Our test window resizes instantly
444+ compare(fakeWindow.width, fakeWindow.requestedWidth);
445+ compare(fakeWindow.height, fakeWindow.requestedHeight);
446+
447+ var startDragX = fakeWindow.width + 1
448+ var startDragY = fakeWindow.height + 1
449+ var endDragX = (fakeWindow.maximumWidth * 2) + 1;
450+ var endDragY = (fakeWindow.maximumHeight * 2) + 1;
451+
452+ mouseFlick(fakeWindow, startDragX, startDragY, endDragX, endDragY,
453+ true/*pressMouse*/, true/*releaseMouse*/, units.gu(.5)/*speed*/, 20/*iterations*/);
454+
455+ compare(fakeWindow.requestedWidth, fakeWindow.maximumWidth);
456+ compare(fakeWindow.requestedHeight, fakeWindow.maximumHeight);
457+ }
458+
459+ /*
460+ Tests that when dragging a window border you cannot make it smaller than its minimum size
461+ */
462+ function test_minimumSize() {
463+ fakeWindow.x = units.gu(1);
464+ fakeWindow.y = units.gu(1);
465+ fakeWindow.resizeAreaMinWidth = 1; // so it does not interfere with anything
466+ fakeWindow.resizeAreaMinHeight = 1; // so it does not interfere with anything
467+ fakeWindow.requestedWidth = units.gu(20);
468+ fakeWindow.requestedHeight = units.gu(20);
469+
470+ fakeWindow.minimumWidth = units.gu(10);
471+ fakeWindow.minimumHeight = units.gu(10);
472+
473+ // Our test window resizes instantly
474+ compare(fakeWindow.width, fakeWindow.requestedWidth);
475+ compare(fakeWindow.height, fakeWindow.requestedHeight);
476+
477+ var startDragX = fakeWindow.width + 1
478+ var startDragY = fakeWindow.height + 1
479+ var endDragX = (fakeWindow.minimumWidth * 0.5) + 1;
480+ var endDragY = (fakeWindow.minimumHeight * 0.5) + 1;
481+
482+ mouseFlick(fakeWindow, startDragX, startDragY, endDragX, endDragY,
483+ true/*pressMouse*/, true/*releaseMouse*/, units.gu(.5)/*speed*/, 20/*iterations*/);
484+
485+ compare(fakeWindow.requestedWidth, fakeWindow.minimumWidth);
486+ compare(fakeWindow.requestedHeight, fakeWindow.minimumHeight);
487+ }
293 }
488 }
294}
489}
tests/qmltests/tst_DisabledScreenNotice.qml+10−2
@@ -19,13 +19,13 @@ import QtTest 1.0
19import Unity.Test 0.1
19import Unity.Test 0.1
20import "../../qml"
20import "../../qml"
21
21
22−
23Item {
22Item {
24 id: root
23 id: root
25− width: units.gu(70)
24+ width: units.gu(40)
26 height: units.gu(70)
25 height: units.gu(70)
27
26
28 DisabledScreenNotice {
27 DisabledScreenNotice {
28+ id: touchScreenPad
29 anchors.fill: parent
29 anchors.fill: parent
30 }
30 }
31
31
@@ -33,5 +33,13 @@ Item {
33 id: testCase
33 id: testCase
34 name: "DisabledScreenNotice"
34 name: "DisabledScreenNotice"
35 when: windowShown
35 when: windowShown
36+
37+ function test_mouseAreaHidesOnFirstTap() {
38+ var noticeArea = findChild(touchScreenPad, "infoNoticeArea")
39+ print("noticeArea", noticeArea.visible)
40+ compare(noticeArea.visible, true)
41+ tap(root)
42+ tryCompare(noticeArea, "visible", false)
43+ }
36 }
44 }
37}
45}
tests/qmltests/tst_OrientedShell.qml+110−27
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2015-2016 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@ import Ubuntu.Components 1.3
21import Ubuntu.Components.ListItems 1.3 as ListItem
21import Ubuntu.Components.ListItems 1.3 as ListItem
22import Unity.Application 0.1
22import Unity.Application 0.1
23import Unity.Test 0.1
23import Unity.Test 0.1
24−import LightDM.IntegratedLightDM 0.1 as LightDM
24+import IntegratedLightDM 0.1 as LightDM
25import Powerd 0.1
25import Powerd 0.1
26import Unity.InputInfo 0.1
26import Unity.InputInfo 0.1
27
27
@@ -292,6 +292,9 @@ Rectangle {
292 activeFocusOnPress: false
292 activeFocusOnPress: false
293 text: "Usage Mode"
293 text: "Usage Mode"
294 model: ["Staged", "Windowed", "Automatic"]
294 model: ["Staged", "Windowed", "Automatic"]
295+ function selectStaged() {selectedIndex = 0;}
296+ function selectWindowed() {selectedIndex = 1;}
297+ function selectAutomatic() {selectedIndex = 2;}
295 }
298 }
296 MouseTouchEmulationCheckbox {
299 MouseTouchEmulationCheckbox {
297 checked: true
300 checked: true
@@ -393,7 +396,7 @@ Rectangle {
393 activeFocusOnPress: false
396 activeFocusOnPress: false
394 property string prevDevName: "mako"
397 property string prevDevName: "mako"
395 onClicked: {
398 onClicked: {
396− usageModeSelector.selectedIndex = 2; // "Automatic"
399+ usageModeSelector.selectAutomatic();
397
400
398 if (applicationArguments.deviceName === "desktop") {
401 if (applicationArguments.deviceName === "desktop") {
399 applicationArguments.deviceName = prevDevName;
402 applicationArguments.deviceName = prevDevName;
@@ -457,6 +460,8 @@ Rectangle {
457 signalSpy.signalName = "";
460 signalSpy.signalName = "";
458
461
459 LightDM.Greeter.authenticate(""); // reset greeter
462 LightDM.Greeter.authenticate(""); // reset greeter
463+
464+ usageModeSelector.selectStaged();
460 }
465 }
461
466
462 function cleanup() {
467 function cleanup() {
@@ -996,37 +1001,58 @@ Rectangle {
996 tryCompare(shell, "transformRotationAngle", 0);
1001 tryCompare(shell, "transformRotationAngle", 0);
997 }
1002 }
998
1003
1004+ function test_attachRemoveInputDevices_data() {
1005+ return [
1006+ { tag: "small screen, no devices", screenWidth: units.gu(50), mouse: false, kbd: false, expectedMode: "phone", oskExpected: true },
1007+ { tag: "medium screen, no devices", screenWidth: units.gu(100), mouse: false, kbd: false, expectedMode: "phone", oskExpected: true },
1008+ { tag: "big screen, no devices", screenWidth: units.gu(200), mouse: false, kbd: false, expectedMode: "phone", oskExpected: true },
1009+ { tag: "small screen, mouse", screenWidth: units.gu(50), mouse: true, kbd: false, expectedMode: "phone", oskExpected: true },
1010+ { tag: "medium screen, mouse", screenWidth: units.gu(100), mouse: true, kbd: false, expectedMode: "desktop", oskExpected: true },
1011+ { tag: "big screen, mouse", screenWidth: units.gu(200), mouse: true, kbd: false, expectedMode: "desktop", oskExpected: true },
1012+ { tag: "small screen, kbd", screenWidth: units.gu(50), mouse: false, kbd: true, expectedMode: "phone", oskExpected: false },
1013+ { tag: "medium screen, kbd", screenWidth: units.gu(100), mouse: false, kbd: true, expectedMode: "phone", oskExpected: false },
1014+ { tag: "big screen, kbd", screenWidth: units.gu(200), mouse: false, kbd: true, expectedMode: "desktop", oskExpected: false },
1015+ { tag: "small screen, mouse & kbd", screenWidth: units.gu(50), mouse: true, kbd: true, expectedMode: "phone", oskExpected: false },
1016+ { tag: "medium screen, mouse & kbd", screenWidth: units.gu(100), mouse: true, kbd: true, expectedMode: "desktop", oskExpected: false },
1017+ { tag: "big screen, mouse & kbd", screenWidth: units.gu(200), mouse: true, kbd: true, expectedMode: "desktop", oskExpected: false },
1018+ ]
1019+ }
1020+
999− function test_attachRemoveInputDevices() {
1021+ function test_attachRemoveInputDevices(data) {
1000− usageModeSelector.selectedIndex = 2;
1022+ usageModeSelector.selectAutomatic();
1001 tryCompare(mockUnity8Settings, "usageMode", "Automatic")
1023 tryCompare(mockUnity8Settings, "usageMode", "Automatic")
1002
1024
1003 loadShell("mako")
1025 loadShell("mako")
1004 var shell = findChild(orientedShell, "shell");
1026 var shell = findChild(orientedShell, "shell");
1027+ var inputMethod = findChild(shell, "inputMethod");
1005
1028
1006− tryCompare(shell, "usageScenario", "phone");
1029+ var oldWidth = orientedShellLoader.width;
1007− tryCompare(mockOskSettings, "stayHidden", false);
1030+ orientedShellLoader.width = data.screenWidth;
1008
1031
1009− MockInputDeviceBackend.addMockDevice("/kbd0", InputInfo.Keyboard);
1010 tryCompare(shell, "usageScenario", "phone");
1032 tryCompare(shell, "usageScenario", "phone");
1011− tryCompare(mockOskSettings, "stayHidden", true);
1033+ tryCompare(inputMethod, "enabled", true);
1012−
1034+ tryCompare(mockOskSettings, "disableHeight", false);
1013− MockInputDeviceBackend.addMockDevice("/mouse0", InputInfo.Mouse);
1014− tryCompare(shell, "usageScenario", "desktop");
1015− tryCompare(mockOskSettings, "stayHidden", true);
1016
1035
1036+ if (data.kbd) {
1017− MockInputDeviceBackend.removeDevice("/kbd0");
1037+ MockInputDeviceBackend.addMockDevice("/kbd0", InputInfo.Keyboard);
1018− tryCompare(shell, "usageScenario", "desktop");
1038+ }
1019− tryCompare(mockOskSettings, "stayHidden", false);
1039+ if (data.mouse) {
1040+ MockInputDeviceBackend.addMockDevice("/mouse0", InputInfo.Mouse);
1041+ }
1020
1042
1021− MockInputDeviceBackend.removeDevice("/mouse0");
1022− tryCompare(shell, "usageScenario", "phone");
1043+ tryCompare(shell, "usageScenario", data.expectedMode);
1044+ tryCompare(inputMethod, "enabled", data.oskExpected);
1023− tryCompare(mockOskSettings, "stayHidden", false);
1045+ tryCompare(mockOskSettings, "disableHeight", data.expectedMode == "desktop" || data.kbd);
1024
1046
1047+ if (data.kbd) {
1025− MockInputDeviceBackend.addMockDevice("/touchpad0", InputInfo.TouchPad);
1048+ MockInputDeviceBackend.removeDevice("/kbd0");
1026− tryCompare(shell, "usageScenario", "desktop");
1049+ }
1050+ if (data.mouse) {
1051+ MockInputDeviceBackend.removeDevice("/mouse0");
1052+ }
1027
1053
1028− MockInputDeviceBackend.removeDevice("/touchpad0");
1054+ // Restore width
1029− tryCompare(shell, "usageScenario", "phone");
1055+ orientedShellLoader.width = oldWidth;
1030 }
1056 }
1031
1057
1032 /*
1058 /*
@@ -1140,6 +1166,61 @@ Rectangle {
1140 tryCompare(shell, "transformRotationAngle" , 0);
1166 tryCompare(shell, "transformRotationAngle" , 0);
1141 }
1167 }
1142
1168
1169+ /*
1170+ Regression test for https://launchpad.net/bugs/1515977
1171+
1172+ Preconditions:
1173+ UI in Desktop mode and landscape
1174+
1175+ Steps:
1176+ - Launch a portrait-only application
1177+
1178+ Expected outcome:
1179+ - Shell stays in landscape
1180+
1181+ Buggy outcome:
1182+ - Shell would rotate to portrait as the newly-focused app doesn't support landscape
1183+ */
1184+ function test_portraitOnlyAppInLandscapeDesktop_data() {
1185+ return [
1186+ {tag: "mako", deviceName: "mako"},
1187+ {tag: "manta", deviceName: "manta"},
1188+ {tag: "flo", deviceName: "flo"}
1189+ ];
1190+ }
1191+ function test_portraitOnlyAppInLandscapeDesktop(data) {
1192+ loadShell(data.deviceName);
1193+
1194+ ////
1195+ // setup preconditions (put shell in Desktop mode and landscape)
1196+
1197+ usageModeSelector.selectWindowed();
1198+
1199+ orientedShell.physicalOrientation = orientedShell.orientations.landscape;
1200+ waitUntilShellIsInOrientation(orientedShell.orientations.landscape);
1201+ waitForRotationAnimationsToFinish();
1202+
1203+ ////
1204+ // Launch a portrait-only application
1205+
1206+ var dialerApp = ApplicationManager.startApplication("dialer-app");
1207+ verify(dialerApp);
1208+
1209+ // ensure the mock dialer-app is as we expect
1210+ compare(dialerApp.rotatesWindowContents, false);
1211+ compare(dialerApp.supportedOrientations, Qt.PortraitOrientation | Qt.InvertedPortraitOrientation);
1212+
1213+ waitUntilAppSurfaceShowsUp("dialer-app");
1214+ waitUntilAppWindowCanRotate("dialer-app");
1215+ verify(isAppSurfaceFocused("dialer-app"));
1216+
1217+ ////
1218+ // check outcome (shell should stay in landscape)
1219+
1220+ waitForRotationAnimationsToFinish();
1221+ compare(shell.orientation, orientedShell.orientations.landscape);
1222+ }
1223+
1143 // angle - rotation angle in degrees clockwise, relative to the primary orientation.
1224 // angle - rotation angle in degrees clockwise, relative to the primary orientation.
1144 function rotateTo(angle) {
1225 function rotateTo(angle) {
1145 switch (angle) {
1226 switch (angle) {
@@ -1158,7 +1239,10 @@ Rectangle {
1158 default:
1239 default:
1159 verify(false);
1240 verify(false);
1160 }
1241 }
1242+ waitForRotationAnimationsToFinish();
1243+ }
1161
1244
1245+ function waitForRotationAnimationsToFinish() {
1162 var rotationStates = findInvisibleChild(orientedShell, "rotationStates");
1246 var rotationStates = findInvisibleChild(orientedShell, "rotationStates");
1163 verify(rotationStates.d);
1247 verify(rotationStates.d);
1164 verify(rotationStates.d.stateUpdateTimer);
1248 verify(rotationStates.d.stateUpdateTimer);
@@ -1340,11 +1424,10 @@ Rectangle {
1340 var greeter = findChild(shell, "greeter");
1424 var greeter = findChild(shell, "greeter");
1341 verify(greeter);
1425 verify(greeter);
1342
1426
1343− var greeterViewLoader = findChild(greeter, "loader").item;
1427+ var loginList = findChild(greeter, "loginList");
1344− var loginAreaLoader = findChild(greeterViewLoader, "loginAreaLoader");
1345 // Only present in WideView
1428 // Only present in WideView
1346− if (loginAreaLoader) {
1429+ if (loginList) {
1347− var userList = findChild(loginAreaLoader.item, "userList");
1430+ var userList = findChild(loginList, "userList");
1348 verify(userList);
1431 verify(userList);
1349 tryCompare(userList, "movingInternally", false);
1432 tryCompare(userList, "movingInternally", false);
1350 }
1433 }
tests/qmltests/tst_Shell.qml+78−10
@@ -18,7 +18,7 @@ import QtQuick 2.4
18import QtTest 1.0
18import QtTest 1.0
19import AccountsService 0.1
19import AccountsService 0.1
20import GSettings 1.0
20import GSettings 1.0
21−import LightDM.IntegratedLightDM 0.1 as LightDM
21+import IntegratedLightDM 0.1 as LightDM
22import Ubuntu.Components 1.3
22import Ubuntu.Components 1.3
23import Ubuntu.Components.ListItems 1.3 as ListItem
23import Ubuntu.Components.ListItems 1.3 as ListItem
24import Ubuntu.Telephony 0.1 as Telephony
24import Ubuntu.Telephony 0.1 as Telephony
@@ -49,6 +49,11 @@ Rectangle {
49 shellLoader.active = true;
49 shellLoader.active = true;
50 }
50 }
51
51
52+ MouseArea {
53+ id: clickThroughCatcher
54+ anchors.fill: shellContainer
55+ }
56+
52 Item {
57 Item {
53 id: shellContainer
58 id: shellContainer
54 anchors.left: root.left
59 anchors.left: root.left
@@ -291,11 +296,31 @@ Rectangle {
291 signalName: "applicationRemoved"
296 signalName: "applicationRemoved"
292 }
297 }
293
298
299+ SignalSpy {
300+ id: clickThroughSpy
301+ target: clickThroughCatcher
302+ signalName: "clicked"
303+ }
304+
294 Telephony.CallEntry {
305 Telephony.CallEntry {
295 id: phoneCall
306 id: phoneCall
296 phoneNumber: "+447812221111"
307 phoneNumber: "+447812221111"
297 }
308 }
298
309
310+ Item {
311+ id: fakeDismissTimer
312+ property bool running: false
313+ signal triggered
314+
315+ function stop() {
316+ running = false;
317+ }
318+
319+ function restart() {
320+ running = true;
321+ }
322+ }
323+
299 UnityTestCase {
324 UnityTestCase {
300 id: testCase
325 id: testCase
301 name: "Shell"
326 name: "Shell"
@@ -333,6 +358,11 @@ Rectangle {
333 var launcher = findChild(shell, "launcher");
358 var launcher = findChild(shell, "launcher");
334 launcherShowDashHomeSpy.target = launcher;
359 launcherShowDashHomeSpy.target = launcher;
335
360
361+ var panel = findChild(launcher, "launcherPanel");
362+ verify(!!panel);
363+
364+ panel.dismissTimer = fakeDismissTimer;
365+
336 waitForGreeterToStabilize();
366 waitForGreeterToStabilize();
337 }
367 }
338
368
@@ -355,11 +385,10 @@ Rectangle {
355 var greeter = findChild(shell, "greeter");
385 var greeter = findChild(shell, "greeter");
356 verify(greeter);
386 verify(greeter);
357
387
358− var greeterViewLoader = findChild(greeter, "loader").item
388+ var loginList = findChild(greeter, "loginList");
359− var loginAreaLoader = findChild(greeterViewLoader, "loginAreaLoader");
360 // Only present in WideView
389 // Only present in WideView
361− if (loginAreaLoader) {
390+ if (loginList) {
362− var userList = findChild(loginAreaLoader, "userList");
391+ var userList = findChild(loginList, "userList");
363 verify(userList);
392 verify(userList);
364 tryCompare(userList, "movingInternally", false);
393 tryCompare(userList, "movingInternally", false);
365 }
394 }
@@ -632,7 +661,6 @@ Rectangle {
632 // again before interacting with it otherwise any
661 // again before interacting with it otherwise any
633 // DirectionalDragAreas in there won't be easily fooled by
662 // DirectionalDragAreas in there won't be easily fooled by
634 // fake swipes.
663 // fake swipes.
635− removeTimeConstraintsFromDirectionalDragAreas(greeter);
636 swipeAwayGreeter();
664 swipeAwayGreeter();
637
665
638 compare(mainApp.requestedState, ApplicationInfoInterface.RequestedRunning);
666 compare(mainApp.requestedState, ApplicationInfoInterface.RequestedRunning);
@@ -642,6 +670,7 @@ Rectangle {
642 function swipeAwayGreeter() {
670 function swipeAwayGreeter() {
643 var greeter = findChild(shell, "greeter");
671 var greeter = findChild(shell, "greeter");
644 tryCompare(greeter, "fullyShown", true);
672 tryCompare(greeter, "fullyShown", true);
673+ removeTimeConstraintsFromDirectionalDragAreas(greeter);
645
674
646 var touchX = shell.width - (shell.edgeSize / 2);
675 var touchX = shell.width - (shell.edgeSize / 2);
647 var touchY = shell.height / 2;
676 var touchY = shell.height / 2;
@@ -1241,10 +1270,6 @@ Rectangle {
1241
1270
1242 var launcher = findChild(shell, "launcher");
1271 var launcher = findChild(shell, "launcher");
1243
1272
1244− // ensure the launcher dimissal timer never gets triggered during the test run
1245− var dismissTimer = findInvisibleChild(launcher, "dismissTimer");
1246− dismissTimer.interval = 60 * 60 * 1000;
1247−
1248 dragLauncherIntoView();
1273 dragLauncherIntoView();
1249
1274
1250 // Emulate a tap with a finger, where the touch position drifts during the tap.
1275 // Emulate a tap with a finger, where the touch position drifts during the tap.
@@ -1732,6 +1757,7 @@ Rectangle {
1732
1757
1733 revealLauncherByEdgePushWithMouse();
1758 revealLauncherByEdgePushWithMouse();
1734 tryCompare(launcher, "x", 0);
1759 tryCompare(launcher, "x", 0);
1760+ mouseMove(bfb, bfb.width / 2, bfb.height / 2)
1735 waitForRendering(shell)
1761 waitForRendering(shell)
1736
1762
1737 mouseClick(bfb, bfb.width / 2, bfb.height / 2)
1763 mouseClick(bfb, bfb.width / 2, bfb.height / 2)
@@ -1962,5 +1988,47 @@ Rectangle {
1962 compare(ApplicationManager.findApplication("libreoffice") === null, true);
1988 compare(ApplicationManager.findApplication("libreoffice") === null, true);
1963 }
1989 }
1964 }
1990 }
1991+
1992+ function test_inputEventsOnEdgesEndUpInAppSurface_data() {
1993+ return [
1994+ { tag: "phone", repeaterName: "spreadRepeater" },
1995+ { tag: "tablet", repeaterName: "spreadRepeater" },
1996+ { tag: "desktop", repeaterName: "appRepeater" },
1997+ ]
1998+ }
1999+
2000+ function test_inputEventsOnEdgesEndUpInAppSurface(data) {
2001+ loadShell(data.tag);
2002+ shell.usageScenario = data.tag;
2003+ waitForRendering(shell);
2004+ swipeAwayGreeter();
2005+
2006+ // Let's open a fullscreen app
2007+ var app = ApplicationManager.startApplication("camera-app");
2008+ waitUntilAppWindowIsFullyLoaded(app);
2009+
2010+ var appRepeater = findChild(shell, data.repeaterName);
2011+ var topmostAppDelegate = appRepeater.itemAt(0);
2012+ verify(topmostAppDelegate);
2013+
2014+ var topmostSurfaceItem = findChild(topmostAppDelegate, "surfaceItem");
2015+ verify(topmostSurfaceItem);
2016+
2017+ mouseClick(shell, 1, shell.height / 2);
2018+ compare(topmostSurfaceItem.mousePressCount, 1);
2019+ compare(topmostSurfaceItem.mouseReleaseCount, 1);
2020+
2021+ mouseClick(shell, shell.width - 1, shell.height / 2);
2022+ compare(topmostSurfaceItem.mousePressCount, 2);
2023+ compare(topmostSurfaceItem.mouseReleaseCount, 2);
2024+
2025+ tap(shell, 1, shell.height / 2);
2026+ compare(topmostSurfaceItem.touchPressCount, 1);
2027+ compare(topmostSurfaceItem.touchReleaseCount, 1);
2028+
2029+ tap(shell, shell.width - 1, shell.height / 2);
2030+ compare(topmostSurfaceItem.touchPressCount, 2);
2031+ compare(topmostSurfaceItem.touchReleaseCount, 2);
2032+ }
1965 }
2033 }
1966}
2034}
tests/qmltests/tst_ShellWithPin.qml+19−5
@@ -128,6 +128,20 @@ Item {
128 phoneNumber: "+447812221111"
128 phoneNumber: "+447812221111"
129 }
129 }
130
130
131+ Item {
132+ id: fakeDismissTimer
133+ property bool running: false
134+ signal triggered
135+
136+ function stop() {
137+ running = false;
138+ }
139+
140+ function restart() {
141+ running = true;
142+ }
143+ }
144+
131 UT.UnityTestCase {
145 UT.UnityTestCase {
132 id: testCase
146 id: testCase
133 name: "ShellWithPin"
147 name: "ShellWithPin"
@@ -143,6 +157,11 @@ Item {
143 waitForLockscreen()
157 waitForLockscreen()
144 greeter.failedLoginsDelayAttempts = -1;
158 greeter.failedLoginsDelayAttempts = -1;
145 greeter.maxFailedLogins = -1;
159 greeter.maxFailedLogins = -1;
160+
161+ var launcher = findChild(shell, "launcher");
162+ var panel = findChild(launcher, "launcherPanel");
163+ verify(!!panel);
164+ panel.dismissTimer = fakeDismissTimer;
146 }
165 }
147
166
148 function cleanup() {
167 function cleanup() {
@@ -565,11 +584,6 @@ Item {
565 tryCompare(coverPage, "showProgress", 1);
584 tryCompare(coverPage, "showProgress", 1);
566
585
567 var launcher = testCase.findChild(shell, "launcher")
586 var launcher = testCase.findChild(shell, "launcher")
568− {
569− var dismissTimer = testCase.findInvisibleChild(launcher, "dismissTimer");
570− // effectively disable the dismiss timer
571− dismissTimer.interval = 24 * 60 * 60 * 1000 // 24 hours
572− }
573 var launcherPanel = testCase.findChild(launcher, "launcherPanel");
587 var launcherPanel = testCase.findChild(launcher, "launcherPanel");
574
588
575 var toX = shell.width * 0.45;
589 var toX = shell.width * 0.45;