on xenial help sign in
merge trunk
45b5bf0Michael Zanetti
debian/changelog+54
@@ -1,3 +1,57 @@
1+unity8 (8.00+14.10.20140908.1-0ubuntu1) utopic; urgency=low
2+
3+ [ Michał Sawicz ]
4+ * Use a single white pixel instead of the heavier checkers image.
5+ * Add support to unlock-device for the new adbd coming down the
6+ pipeline. Also fix autopilot tests and run scripts for that.
7+ * Make LVWPH non interactive while on header animation
8+ * Improve references to scope/scopeStyle in PreviewListView and
9+ PageHeader, add tests.
10+
11+ [ Nick Dedekind ]
12+ * Support for nested prompt session. (LP: #1358388)
13+
14+ [ Albert Astals ]
15+ * Remove unused hasAttributes variable
16+ * Disable dash overview if in temp scope preview
17+ * Block mouse events under scope overview bottombar (LP: #1362206)
18+ * Fix regression in focus handling due to SDK change
19+ * Fix warning 'Background.qml:81:21: Unable to assign bool to QUrl'
20+ * Fix launcher internationalization
21+ * Make swipe and home button press in the launcher dismiss the
22+ overview
23+ * GSV: Use proper variable since altnav renames
24+ * Fix some "Cannot read property 'luminance' of null" warnings
25+ * Make LVWPH non interactive while on header animation
26+
27+ [ Mirco Müller ]
28+ * Implemented the needed visual updates on notifications requested by
29+ Design for RTM. (LP: #1348092)
30+
31+ [ Michael Terry ]
32+ * Don't show greeter when screen turns off during a call, even if
33+ proximity sensor isn't active. (LP: #1347001)
34+ * Add support to unlock-device for the new adbd coming down the
35+ pipeline. Also fix autopilot tests and run scripts for that.
36+
37+ [ Michael Zanetti ]
38+ * open the application when clicking on the title entry in the
39+ quicklist (LP: #1336380)
40+ * Don't animate x while dragging apps from the left edge (LP:
41+ #1360105)
42+
43+ [ Diego Sarmentero ]
44+ * Reset button state on cancel (LP: #1362622)
45+
46+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 08 Sep 2014 14:16:42 +0000
47+
48+unity8 (8.00+14.10.20140903.1-0ubuntu1) utopic; urgency=low
49+
50+ [ Nick Dedekind ]
51+ * Support for nested prompt session. (LP: #1358388)
52+
53+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 03 Sep 2014 07:58:49 +0000
54+
1unity8 (8.00+14.10.20140828.1-0ubuntu1) utopic; urgency=low
55unity8 (8.00+14.10.20140828.1-0ubuntu1) utopic; urgency=low
2
56
3 [ Michael Terry ]
57 [ Michael Terry ]
debian/control+1−1
@@ -85,7 +85,7 @@ Depends: gsettings-desktop-schemas,
85 qmenumodel-qml (>= 0.2.8),
85 qmenumodel-qml (>= 0.2.8),
86 qml-module-qtquick-xmllistmodel,
86 qml-module-qtquick-xmllistmodel,
87 qtdeclarative5-gsettings1.0,
87 qtdeclarative5-gsettings1.0,
88− qtdeclarative5-qtmir-plugin (>= 0.4.1),
88+ qtdeclarative5-qtmir-plugin (>= 0.4.3),
89 qtdeclarative5-ubuntu-telephony0.1,
89 qtdeclarative5-ubuntu-telephony0.1,
90 unity-launcher-impl-4,
90 unity-launcher-impl-4,
91 unity8-common (= ${source:Version}),
91 unity8-common (= ${source:Version}),
plugins/AccountsService/AccountsService.qmltypes+1
@@ -26,5 +26,6 @@ Module {
26 Property { name: "backgroundFile"; type: "string"; isReadonly: true }
26 Property { name: "backgroundFile"; type: "string"; isReadonly: true }
27 Property { name: "statsWelcomeScreen"; type: "bool"; isReadonly: true }
27 Property { name: "statsWelcomeScreen"; type: "bool"; isReadonly: true }
28 Property { name: "passwordDisplayHint"; type: "PasswordDisplayHint"; isReadonly: true }
28 Property { name: "passwordDisplayHint"; type: "PasswordDisplayHint"; isReadonly: true }
29+ Property { name: "failedLogins"; type: "uint" }
29 }
30 }
30}
31}
plugins/Dash/CardCreator.js+2−2
@@ -440,14 +440,14 @@ function cardString(template, components) {
440 mascotCode = kMascotImageCode.arg(mascotAnchors).arg(mascotImageVisible);
440 mascotCode = kMascotImageCode.arg(mascotAnchors).arg(mascotImageVisible);
441 }
441 }
442
442
443− var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white")';
443+ 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")';
444
444
445 var hasTitleContainer = hasTitle && (hasEmblem || (hasMascot && (hasSubtitle || hasAttributes)));
445 var hasTitleContainer = hasTitle && (hasEmblem || (hasMascot && (hasSubtitle || hasAttributes)));
446 var titleSubtitleCode = '';
446 var titleSubtitleCode = '';
447 if (hasTitle) {
447 if (hasTitle) {
448 var titleColor;
448 var titleColor;
449 if (headerAsOverlay) {
449 if (headerAsOverlay) {
450− titleColor = 'root.scopeStyle ? root.scopeStyle.getTextColor(overlayLoader.item.luminance) : (overlayLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white")';
450+ titleColor = 'root.scopeStyle && overlayLoader.item ? root.scopeStyle.getTextColor(overlayLoader.item.luminance) : (overlayLoader.item && overlayLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white")';
451 } else if (hasSummary) {
451 } else if (hasSummary) {
452 titleColor = 'summary.color';
452 titleColor = 'summary.color';
453 } else if (hasBackground) {
453 } else if (hasBackground) {
plugins/Dash/listviewwithpageheader.cpp+7−4
@@ -172,7 +172,7 @@ ListViewWithPageHeader::ListViewWithPageHeader()
172 connect(this, SIGNAL(contentWidthChanged()), this, SLOT(onContentWidthChanged()));
172 connect(this, SIGNAL(contentWidthChanged()), this, SLOT(onContentWidthChanged()));
173 connect(this, SIGNAL(contentHeightChanged()), this, SLOT(onContentHeightChanged()));
173 connect(this, SIGNAL(contentHeightChanged()), this, SLOT(onContentHeightChanged()));
174 connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged()));
174 connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged()));
175− connect(m_contentYAnimation, SIGNAL(stopped()), this, SLOT(onShowHeaderAnimationFinished()));
175+ connect(m_contentYAnimation, SIGNAL(runningChanged(bool)), this, SLOT(contentYAnimationRunningChanged(bool)));
176
176
177 setFlickableDirection(VerticalFlick);
177 setFlickableDirection(VerticalFlick);
178}
178}
@@ -1056,10 +1056,13 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
1056 m_contentHeightDirty = true;
1056 m_contentHeightDirty = true;
1057}
1057}
1058
1058
1059−void ListViewWithPageHeader::onShowHeaderAnimationFinished()
1059+void ListViewWithPageHeader::contentYAnimationRunningChanged(bool running)
1060{
1060{
1061+ setInteractive(!running);
1062+ if (!running) {
1061− m_contentHeightDirty = true;
1063+ m_contentHeightDirty = true;
1062− polish();
1064+ polish();
1065+ }
1063}
1066}
1064
1067
1065void ListViewWithPageHeader::itemGeometryChanged(QQuickItem * /*item*/, const QRectF &newGeometry, const QRectF &oldGeometry)
1068void ListViewWithPageHeader::itemGeometryChanged(QQuickItem * /*item*/, const QRectF &newGeometry, const QRectF &oldGeometry)
plugins/Dash/listviewwithpageheader.h+1−1
@@ -118,7 +118,7 @@ private Q_SLOTS:
118 void onContentWidthChanged();
118 void onContentWidthChanged();
119 void onHeightChanged();
119 void onHeightChanged();
120 void onModelUpdated(const QQmlChangeSet &changeSet, bool reset);
120 void onModelUpdated(const QQmlChangeSet &changeSet, bool reset);
121− void onShowHeaderAnimationFinished();
121+ void contentYAnimationRunningChanged(bool running);
122
122
123private:
123private:
124 class ListItem
124 class ListItem
plugins/LightDM/LightDM.qmltypes+2
@@ -27,6 +27,7 @@ Module {
27 name: "showPrompt"
27 name: "showPrompt"
28 Parameter { name: "text"; type: "string" }
28 Parameter { name: "text"; type: "string" }
29 Parameter { name: "isSecret"; type: "bool" }
29 Parameter { name: "isSecret"; type: "bool" }
30+ Parameter { name: "isDefaultPrompt"; type: "bool" }
30 }
31 }
31 Signal { name: "authenticationComplete" }
32 Signal { name: "authenticationComplete" }
32 Signal {
33 Signal {
@@ -34,6 +35,7 @@ Module {
34 Parameter { name: "user"; type: "string" }
35 Parameter { name: "user"; type: "string" }
35 }
36 }
36 Signal { name: "isActiveChanged" }
37 Signal { name: "isActiveChanged" }
38+ Signal { name: "isAuthenticatedChanged" }
37 Signal { name: "showGreeter" }
39 Signal { name: "showGreeter" }
38 Signal {
40 Signal {
39 name: "requestAuthenticationUser"
41 name: "requestAuthenticationUser"
plugins/Powerd/Powerd.cpp+16−2
@@ -39,7 +39,8 @@ void dimTimeoutChanged(GSettings *settings, const gchar *key, QDBusInterface *un
39
39
40Powerd::Powerd(QObject* parent)
40Powerd::Powerd(QObject* parent)
41 : QObject(parent),
41 : QObject(parent),
42− unityScreen(nullptr)
42+ unityScreen(nullptr),
43+ cachedStatus(Status::On)
43{
44{
44 unityScreen = new QDBusInterface("com.canonical.Unity.Screen",
45 unityScreen = new QDBusInterface("com.canonical.Unity.Screen",
45 "/com/canonical/Unity/Screen",
46 "/com/canonical/Unity/Screen",
@@ -51,7 +52,7 @@ Powerd::Powerd(QObject* parent)
51 "com.canonical.Unity.Screen",
52 "com.canonical.Unity.Screen",
52 "DisplayPowerStateChange",
53 "DisplayPowerStateChange",
53 this,
54 this,
54− SIGNAL(displayPowerStateChange(int, int)));
55+ SLOT(handleDisplayPowerStateChange(int, int)));
55
56
56 systemSettings = g_settings_new("com.ubuntu.touch.system");
57 systemSettings = g_settings_new("com.ubuntu.touch.system");
57 g_signal_connect(systemSettings, "changed::auto-brightness", G_CALLBACK(autoBrightnessChanged), unityScreen);
58 g_signal_connect(systemSettings, "changed::auto-brightness", G_CALLBACK(autoBrightnessChanged), unityScreen);
@@ -67,3 +68,16 @@ Powerd::~Powerd()
67 g_signal_handlers_disconnect_by_data(systemSettings, unityScreen);
68 g_signal_handlers_disconnect_by_data(systemSettings, unityScreen);
68 g_object_unref(systemSettings);
69 g_object_unref(systemSettings);
69}
70}
71+
72+Powerd::Status Powerd::status() const
73+{
74+ return cachedStatus;
75+}
76+
77+void Powerd::handleDisplayPowerStateChange(int status, int reason)
78+{
79+ if (cachedStatus != (Status)status) {
80+ cachedStatus = (Status)status;
81+ Q_EMIT statusChanged((DisplayStateChangeReason)reason);
82+ }
83+}
plugins/Powerd/Powerd.h+8−1
@@ -29,6 +29,7 @@ class Powerd: public QObject
29 Q_OBJECT
29 Q_OBJECT
30 Q_ENUMS(Status)
30 Q_ENUMS(Status)
31 Q_ENUMS(DisplayStateChangeReason)
31 Q_ENUMS(DisplayStateChangeReason)
32+ Q_PROPERTY(Status status READ status NOTIFY statusChanged)
32
33
33public:
34public:
34 enum DisplayStateChangeReason {
35 enum DisplayStateChangeReason {
@@ -46,12 +47,18 @@ public:
46 explicit Powerd(QObject *parent = 0);
47 explicit Powerd(QObject *parent = 0);
47 ~Powerd();
48 ~Powerd();
48
49
50+ Status status() const;
51+
49Q_SIGNALS:
52Q_SIGNALS:
50− void displayPowerStateChange(int status, int reason);
53+ void statusChanged(DisplayStateChangeReason reason);
54+
55+private Q_SLOTS:
56+ void handleDisplayPowerStateChange(int status, int reason);
51
57
52private:
58private:
53 QDBusInterface *unityScreen;
59 QDBusInterface *unityScreen;
54 GSettings *systemSettings;
60 GSettings *systemSettings;
61+ Status cachedStatus;
55};
62};
56
63
57#endif
64#endif
plugins/Powerd/Powerd.qmltypes+3−3
@@ -30,10 +30,10 @@ Module {
30 "On": 1
30 "On": 1
31 }
31 }
32 }
32 }
33+ Property { name: "status"; type: "Status"; isReadonly: true }
33 Signal {
34 Signal {
34− name: "displayPowerStateChange"
35+ name: "statusChanged"
35− Parameter { name: "status"; type: "int" }
36− Parameter { name: "reason"; type: "int" }
36+ Parameter { name: "reason"; type: "DisplayStateChangeReason" }
37 }
37 }
38 }
38 }
39}
39}
plugins/Ubuntu/SystemImage/SystemImage.qmltypes+2
@@ -11,6 +11,8 @@ Module {
11 name: "SystemImage"
11 name: "SystemImage"
12 prototype: "QObject"
12 prototype: "QObject"
13 exports: ["Ubuntu.SystemImage/SystemImage 0.1"]
13 exports: ["Ubuntu.SystemImage/SystemImage 0.1"]
14+ isCreatable: false
15+ isSingleton: true
14 exportMetaObjectRevisions: [0]
16 exportMetaObjectRevisions: [0]
15 Method { name: "factoryReset" }
17 Method { name: "factoryReset" }
16 }
18 }
plugins/Unity/DashCommunicator/dashcommunicator.cpp+2−2
@@ -31,7 +31,7 @@ DashCommunicator::~DashCommunicator()
31}
31}
32
32
33
33
34−void DashCommunicator::setCurrentScope(const QString &scopeId, bool animate, bool reset)
34+void DashCommunicator::setCurrentScope(const QString &scopeId, bool animate, bool isSwipe)
35{
35{
36 QDBusConnection connection = QDBusConnection::sessionBus();
36 QDBusConnection connection = QDBusConnection::sessionBus();
37 QDBusInterface dashIface ("com.canonical.UnityDash",
37 QDBusInterface dashIface ("com.canonical.UnityDash",
@@ -39,5 +39,5 @@ void DashCommunicator::setCurrentScope(const QString &scopeId, bool animate, boo
39 "",
39 "",
40 connection);
40 connection);
41
41
42− dashIface.call("SetCurrentScope", scopeId, animate, reset);
42+ dashIface.call("SetCurrentScope", scopeId, animate, isSwipe);
43}
43}
plugins/Unity/DashCommunicator/dashcommunicator.h+1−1
@@ -29,7 +29,7 @@ public:
29 ~DashCommunicator();
29 ~DashCommunicator();
30
30
31public Q_SLOTS:
31public Q_SLOTS:
32− void setCurrentScope(const QString &scopeId, bool animate, bool reset);
32+ void setCurrentScope(const QString &scopeId, bool animate, bool isSwipe);
33};
33};
34
34
35#endif
35#endif
plugins/Unity/DashCommunicator/dashcommunicatorservice.h+1−1
@@ -29,7 +29,7 @@ public:
29 ~DashCommunicatorService();
29 ~DashCommunicatorService();
30
30
31Q_SIGNALS:
31Q_SIGNALS:
32− void setCurrentScopeRequested(const QString &scopeId, bool animate, bool reset);
32+ void setCurrentScopeRequested(const QString &scopeId, bool animate, bool isSwipe);
33
33
34private:
34private:
35 DBusDashCommunicatorService *m_dbusService;
35 DBusDashCommunicatorService *m_dbusService;
plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.cpp+2−2
@@ -33,7 +33,7 @@ DBusDashCommunicatorService::~DBusDashCommunicatorService()
33{
33{
34}
34}
35
35
36−void DBusDashCommunicatorService::SetCurrentScope(const QString &scopeId, bool animate, bool reset)
36+void DBusDashCommunicatorService::SetCurrentScope(const QString &scopeId, bool animate, bool isSwipe)
37{
37{
38− Q_EMIT setCurrentScopeRequested(scopeId, animate, reset);
38+ Q_EMIT setCurrentScopeRequested(scopeId, animate, isSwipe);
39}
39}
plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.h+2−2
@@ -29,10 +29,10 @@ public:
29 ~DBusDashCommunicatorService();
29 ~DBusDashCommunicatorService();
30
30
31Q_SIGNALS:
31Q_SIGNALS:
32− void setCurrentScopeRequested(const QString &scopeId, bool animate, bool reset);
32+ void setCurrentScopeRequested(const QString &scopeId, bool animate, bool isSwipe);
33
33
34public Q_SLOTS:
34public Q_SLOTS:
35− Q_SCRIPTABLE void SetCurrentScope(const QString &scopeId, bool animate, bool reset);
35+ Q_SCRIPTABLE void SetCurrentScope(const QString &scopeId, bool animate, bool isSwipe);
36
36
37};
37};
38
38
plugins/Unity/Indicators/Indicators.qmltypes+6−4
@@ -219,12 +219,14 @@ Module {
219 Method {
219 Method {
220 name: "model"
220 name: "model"
221 type: "UnityMenuModel*"
221 type: "UnityMenuModel*"
222− Parameter { name: "path"; type: "string" }
222+ Parameter { name: "bus"; type: "QByteArray" }
223+ Parameter { name: "path"; type: "QByteArray" }
224+ Parameter { name: "actions"; type: "QVariantMap" }
223 }
225 }
224 Method {
226 Method {
225− name: "registerModel"
227+ name: "contains"
228+ type: "bool"
226− Parameter { name: "path"; type: "string" }
229+ Parameter { name: "path"; type: "QByteArray" }
227− Parameter { name: "menuModel"; type: "UnityMenuModel"; isPointer: true }
228 }
230 }
229 }
231 }
230 Component {
232 Component {
plugins/Unity/Launcher/CMakeLists.txt+1−1
@@ -32,6 +32,6 @@ add_library(UnityLauncher-qml MODULE
32
32
33target_link_libraries(UnityLauncher-qml ${GSETTINGS_QT_LDFLAGS})
33target_link_libraries(UnityLauncher-qml ${GSETTINGS_QT_LDFLAGS})
34
34
35−qt5_use_modules(UnityLauncher-qml DBus Qml)
35+qt5_use_modules(UnityLauncher-qml DBus Qml Gui)
36
36
37add_unity8_plugin(Unity.Launcher 0.1 Unity/Launcher TARGETS UnityLauncher-qml)
37add_unity8_plugin(Unity.Launcher 0.1 Unity/Launcher TARGETS UnityLauncher-qml)
plugins/Unity/Launcher/launcheritem.cpp+1
@@ -37,6 +37,7 @@ LauncherItem::LauncherItem(const QString &appId, const QString &name, const QStr
37 m_quickList(new QuickListModel(this))
37 m_quickList(new QuickListModel(this))
38{
38{
39 QuickListEntry nameAction;
39 QuickListEntry nameAction;
40+ nameAction.setActionId("launch_item");
40 nameAction.setText(m_name);
41 nameAction.setText(m_name);
41 m_quickList->appendAction(nameAction);
42 m_quickList->appendAction(nameAction);
42 QuickListEntry pinningAction;
43 QuickListEntry pinningAction;
plugins/Unity/Launcher/launchermodel.cpp+3
@@ -25,6 +25,7 @@
25
25
26#include <unity/shell/application/ApplicationInfoInterface.h>
26#include <unity/shell/application/ApplicationInfoInterface.h>
27
27
28+#include <QDesktopServices>
28#include <QDebug>
29#include <QDebug>
29
30
30using namespace unity::shell::application;
31using namespace unity::shell::application;
@@ -210,6 +211,8 @@ void LauncherModel::quickListActionInvoked(const QString &appId, int actionIndex
210 } else {
211 } else {
211 pin(appId);
212 pin(appId);
212 }
213 }
214+ } else if (actionId == "launch_item") {
215+ QDesktopServices::openUrl(getUrlForAppId(appId));
213
216
214 // Nope, we don't know this action, let the backend forward it to the application
217 // Nope, we don't know this action, let the backend forward it to the application
215 } else {
218 } else {
po/am.po+18−13
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
11−"PO-Revision-Date: 2014-08-30 14:40+0000\n"
11+"PO-Revision-Date: 2014-09-02 01:51+0000\n"
12"Last-Translator: samson <Unknown>\n"
12"Last-Translator: samson <Unknown>\n"
13"Language-Team: Amharic <am@li.org>\n"
13"Language-Team: Amharic <am@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-08-31 07:30+0000\n"
17+"X-Launchpad-Export-Date: 2014-09-03 07:05+0000\n"
18−"X-Generator: Launchpad (build 17176)\n"
18+"X-Generator: Launchpad (build 17196)\n"
19
19
20#: plugins/LightDM/Greeter.cpp:130
20#: plugins/LightDM/Greeter.cpp:130
21msgid "Password: "
21msgid "Password: "
@@ -129,6 +129,7 @@ msgid ""
129"You have now mastered the edge gestures and can start using the "
129"You have now mastered the edge gestures and can start using the "
130"phone<br><br>Tap on the screen to start"
130"phone<br><br>Tap on the screen to start"
131msgstr ""
131msgstr ""
132+"አሁን የ ጠርዝ እንቅስቃሴን አውቀዋል እና መጀመር ይችላሉ ስልኩን መጠቀም <br><br>መመልከቻውን መታ ያድርጉ ለመጀመር"
132
133
133#: qml/Components/Lockscreen.qml:167
134#: qml/Components/Lockscreen.qml:167
134msgid "Please wait"
135msgid "Please wait"
@@ -202,7 +203,7 @@ msgstr "መላኪያ"
202
203
203#: qml/Dash/ScopesOverview.qml:201
204#: qml/Dash/ScopesOverview.qml:201
204msgid "Manage Dash"
205msgid "Manage Dash"
205−msgstr ""
206+msgstr "የ ዳሽ አስተዳዳሪ"
206
207
207#: qml/Dash/ScopesOverview.qml:417
208#: qml/Dash/ScopesOverview.qml:417
208msgid "Done"
209msgid "Done"
@@ -250,11 +251,11 @@ msgstr "የመግቢያ ቃል ማሳያ"
250
251
251#: qml/Notifications/NotificationMenuItemFactory.qml:120
252#: qml/Notifications/NotificationMenuItemFactory.qml:120
252msgid "Enter SIM PIN"
253msgid "Enter SIM PIN"
253−msgstr ""
254+msgstr "ሲም ፒን ያስገቡ"
254
255
255#: qml/Notifications/NotificationMenuItemFactory.qml:121
256#: qml/Notifications/NotificationMenuItemFactory.qml:121
256msgid "Sorry, incorrect PIN"
257msgid "Sorry, incorrect PIN"
257−msgstr ""
258+msgstr "አዝናለሁ የተሳሳተ ፒን"
258
259
259#: qml/Panel/ActiveCallHint.qml:77
260#: qml/Panel/ActiveCallHint.qml:77
260msgid "Tap to return to call..."
261msgid "Tap to return to call..."
@@ -290,11 +291,11 @@ msgstr "አልተቻለም: እንደገና ለመሞከር መታ ያድርጉ"
290
291
291#: qml/Panel/Indicators/ModemInfoItem.qml:105
292#: qml/Panel/Indicators/ModemInfoItem.qml:105
292msgid "Unlock SIM"
293msgid "Unlock SIM"
293−msgstr ""
294+msgstr "ሲም መክፈቻ"
294
295
295#: qml/Panel/Indicators/RoamingIndication.qml:27
296#: qml/Panel/Indicators/RoamingIndication.qml:27
296msgid "Roaming"
297msgid "Roaming"
297−msgstr ""
298+msgstr "ማዘዋወሪያ"
298
299
299#: qml/Shell.qml:279
300#: qml/Shell.qml:279
300msgid "Enter your passphrase"
301msgid "Enter your passphrase"
@@ -302,15 +303,15 @@ msgstr "የማለፊያ ሐረግ ያስገቡ"
302
303
303#: qml/Shell.qml:280
304#: qml/Shell.qml:280
304msgid "Sorry, incorrect passphrase"
305msgid "Sorry, incorrect passphrase"
305−msgstr ""
306+msgstr "አዝናለሁ የተሳሳተ የማለፊያ ሐረግ"
306
307
307#: qml/Shell.qml:282
308#: qml/Shell.qml:282
308msgid "Enter your passcode"
309msgid "Enter your passcode"
309−msgstr ""
310+msgstr "የ እርስዎን የማለፊያ ኮድ ያስገቡ"
310
311
311#: qml/Shell.qml:283
312#: qml/Shell.qml:283
312msgid "Sorry, incorrect passcode"
313msgid "Sorry, incorrect passcode"
313−msgstr ""
314+msgstr "አዝናለሁ የተሳሳተ የማለፊያ ኮድ"
314
315
315#: qml/Shell.qml:286
316#: qml/Shell.qml:286
316#, qt-format
317#, qt-format
@@ -324,11 +325,11 @@ msgstr "አዝናለሁ: የተሳሳተ%1"
324
325
325#: qml/Shell.qml:323
326#: qml/Shell.qml:323
326msgid "Sorry, incorrect passphrase."
327msgid "Sorry, incorrect passphrase."
327−msgstr ""
328+msgstr "አዝናለሁ የተሳሳተ የማለፊያ ሐረግ"
328
329
329#: qml/Shell.qml:324
330#: qml/Shell.qml:324
330msgid "Sorry, incorrect passcode."
331msgid "Sorry, incorrect passcode."
331−msgstr ""
332+msgstr "አዝናለሁ የተሳሳተ የማለፊያ ኮድ"
332
333
333#: qml/Shell.qml:325
334#: qml/Shell.qml:325
334msgid "This will be your last attempt."
335msgid "This will be your last attempt."
@@ -339,9 +340,13 @@ msgid ""
339"If passphrase is entered incorrectly, your phone will conduct a factory "
340"If passphrase is entered incorrectly, your phone will conduct a factory "
340"reset and all personal data will be deleted."
341"reset and all personal data will be deleted."
341msgstr ""
342msgstr ""
343+"የተሳሳተ የማለፊያ ሐረግ ካስገቡ የ እርስዎ ስልክ ወደ ነበረበት ወደ ፋክቶሪው ዘዴ ይመለሳል: እና የ ግል ዳታ በሙሉ "
344+"ይጠፋል"
342
345
343#: qml/Shell.qml:328
346#: qml/Shell.qml:328
344msgid ""
347msgid ""
345"If passcode is entered incorrectly, your phone will conduct a factory reset "
348"If passcode is entered incorrectly, your phone will conduct a factory reset "
346"and all personal data will be deleted."
349"and all personal data will be deleted."
347msgstr ""
350msgstr ""
351+"የተሳሳተ የማለፊያ ኮድ ካስገቡ የ እርስዎ ስልክ ወደ ነበረበት ወደ ፋክቶሪው ዘዴ ይመለሳል: እና የ ግል ዳታ በሙሉ "
352+"ይጠፋል"
po/ast.po+62−55
@@ -8,18 +8,18 @@ msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
11−"PO-Revision-Date: 2014-07-25 16:51+0000\n"
11+"PO-Revision-Date: 2014-08-31 12:51+0000\n"
12"Last-Translator: ivarela <ivarela@ubuntu.com>\n"
12"Last-Translator: ivarela <ivarela@ubuntu.com>\n"
13"Language-Team: Asturian <ast@li.org>\n"
13"Language-Team: Asturian <ast@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-08-28 06:29+0000\n"
17+"X-Launchpad-Export-Date: 2014-09-01 07:33+0000\n"
18−"X-Generator: Launchpad (build 17174)\n"
18+"X-Generator: Launchpad (build 17176)\n"
19
19
20−#: plugins/LightDM/Greeter.cpp:129
20+#: plugins/LightDM/Greeter.cpp:130
21msgid "Password: "
21msgid "Password: "
22−msgstr ""
22+msgstr "Contraseña: "
23
23
24#: plugins/Unity/Launcher/launcheritem.cpp:43
24#: plugins/Unity/Launcher/launcheritem.cpp:43
25#: plugins/Unity/Launcher/launcheritem.cpp:73
25#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -32,55 +32,57 @@ msgstr "Desanclar"
32
32
33#: qml/Components/Dialogs.qml:70
33#: qml/Components/Dialogs.qml:70
34msgid "Log out"
34msgid "Log out"
35−msgstr ""
35+msgstr "Zarrar sesión"
36
36
37#: qml/Components/Dialogs.qml:71
37#: qml/Components/Dialogs.qml:71
38msgid "Are you sure you want to log out?"
38msgid "Are you sure you want to log out?"
39−msgstr ""
39+msgstr "De xuru que quies zarrar la sesión?"
40
40
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
42#: qml/Components/Dialogs.qml:122
42#: qml/Components/Dialogs.qml:122
43msgid "No"
43msgid "No"
44−msgstr ""
44+msgstr "Non"
45
45
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
47#: qml/Components/Dialogs.qml:129
47#: qml/Components/Dialogs.qml:129
48msgid "Yes"
48msgid "Yes"
49−msgstr ""
49+msgstr "Sí"
50
50
51#: qml/Components/Dialogs.qml:94
51#: qml/Components/Dialogs.qml:94
52msgid "Shut down"
52msgid "Shut down"
53−msgstr ""
53+msgstr "Apagar"
54
54
55#: qml/Components/Dialogs.qml:95
55#: qml/Components/Dialogs.qml:95
56msgid "Are you sure you want to shut down?"
56msgid "Are you sure you want to shut down?"
57−msgstr ""
57+msgstr "De xuru que quies apagar?"
58
58
59#: qml/Components/Dialogs.qml:119
59#: qml/Components/Dialogs.qml:119
60msgid "Reboot"
60msgid "Reboot"
61−msgstr ""
61+msgstr "Reaniciar"
62
62
63#: qml/Components/Dialogs.qml:120
63#: qml/Components/Dialogs.qml:120
64msgid "Are you sure you want to reboot?"
64msgid "Are you sure you want to reboot?"
65−msgstr ""
65+msgstr "De xuru que quies reaniciar?"
66
66
67#: qml/Components/Dialogs.qml:144
67#: qml/Components/Dialogs.qml:144
68msgid "Power"
68msgid "Power"
69−msgstr ""
69+msgstr "Enerxía"
70
70
71#: qml/Components/Dialogs.qml:145
71#: qml/Components/Dialogs.qml:145
72msgid ""
72msgid ""
73"Are you sure you would like\n"
73"Are you sure you would like\n"
74"to power off?"
74"to power off?"
75msgstr ""
75msgstr ""
76+"De xuru que quies\n"
77+"apagar?"
76
78
77−#: qml/Components/Dialogs.qml:144
79+#: qml/Components/Dialogs.qml:147
78msgid "Power off"
80msgid "Power off"
79−msgstr ""
81+msgstr "Apagar"
80
82
81−#: qml/Components/Dialogs.qml:162
83+#: qml/Components/Dialogs.qml:157
82msgid "Cancel"
84msgid "Cancel"
83−msgstr ""
85+msgstr "Encaboxar"
84
86
85#: qml/Components/EdgeDemoOverlay.qml:151
87#: qml/Components/EdgeDemoOverlay.qml:151
86msgid "Skip intro"
88msgid "Skip intro"
@@ -134,11 +136,11 @@ msgstr ""
134
136
135#: qml/Components/Lockscreen.qml:167
137#: qml/Components/Lockscreen.qml:167
136msgid "Please wait"
138msgid "Please wait"
137−msgstr ""
139+msgstr "Espera un segundu"
138
140
139#: qml/Components/Lockscreen.qml:172
141#: qml/Components/Lockscreen.qml:172
140msgid "Too many incorrect attempts"
142msgid "Too many incorrect attempts"
141−msgstr ""
143+msgstr "Munchos intentos incorreutos"
142
144
143#: qml/Components/Lockscreen.qml:206
145#: qml/Components/Lockscreen.qml:206
144msgid "Emergency Call"
146msgid "Emergency Call"
@@ -165,21 +167,22 @@ msgstr "Ver menos"
165msgid "See all"
167msgid "See all"
166msgstr "Ver too"
168msgstr "Ver too"
167
169
168−#: qml/Dash/GenericScopeView.qml:424 qml/Panel/SearchIndicator.qml:27
170+#: qml/Dash/GenericScopeView.qml:424 qml/Dash/PageHeader.qml:260
171+#: qml/Panel/SearchIndicator.qml:27
169msgid "Search"
172msgid "Search"
170msgstr "Guetar"
173msgstr "Guetar"
171
174
172#: qml/Dash/PageHeader.qml:270
175#: qml/Dash/PageHeader.qml:270
173msgid "Settings"
176msgid "Settings"
174−msgstr ""
177+msgstr "Axustes"
175
178
176#: qml/Dash/PageHeader.qml:279
179#: qml/Dash/PageHeader.qml:279
177msgid "Remove from Favorites"
180msgid "Remove from Favorites"
178−msgstr ""
181+msgstr "Desaniciar de favoritos"
179
182
180#: qml/Dash/PageHeader.qml:279
183#: qml/Dash/PageHeader.qml:279
181msgid "Add to Favorites"
184msgid "Add to Favorites"
182−msgstr ""
185+msgstr "Amestar a favoritos"
183
186
184#: qml/Dash/Previews/PreviewActionCombo.qml:34
187#: qml/Dash/Previews/PreviewActionCombo.qml:34
185msgid "More..."
188msgid "More..."
@@ -203,29 +206,29 @@ msgstr "Unviar"
203
206
204#: qml/Dash/ScopesOverview.qml:201
207#: qml/Dash/ScopesOverview.qml:201
205msgid "Manage Dash"
208msgid "Manage Dash"
206−msgstr ""
209+msgstr "Xestionar tableru"
207
210
208−#: qml/Dash/ScopesOverview.qml:408
211+#: qml/Dash/ScopesOverview.qml:417
209msgid "Done"
212msgid "Done"
210−msgstr ""
213+msgstr "Fecho"
211
214
212−#: qml/Dash/ScopesOverview.qml:434
215+#: qml/Dash/ScopesOverview.qml:443
213msgid "Store"
216msgid "Store"
214−msgstr ""
217+msgstr "Tienda"
215
218
216#: qml/Dash/ScopesOverviewTab.qml:36
219#: qml/Dash/ScopesOverviewTab.qml:36
217msgid "Favorites"
220msgid "Favorites"
218−msgstr ""
221+msgstr "Favoritos"
219
222
220#: qml/Dash/ScopesOverviewTab.qml:54
223#: qml/Dash/ScopesOverviewTab.qml:54
221msgid "All"
224msgid "All"
222−msgstr ""
225+msgstr "Too"
223
226
224#: qml/Greeter/Greeter.qml:157
227#: qml/Greeter/Greeter.qml:157
225msgid "Swipe to unlock"
228msgid "Swipe to unlock"
226msgstr "Esliza pa desbloquiar"
229msgstr "Esliza pa desbloquiar"
227
230
228−#: qml/Hud/HudParametrizedActionsPage.qml:132
231+#: qml/Hud/HudParametrizedActionsPage.qml:139
229msgid "Confirm"
232msgid "Confirm"
230msgstr "Confirmar"
233msgstr "Confirmar"
231
234
@@ -251,11 +254,11 @@ msgstr "Amosar contraseña"
251
254
252#: qml/Notifications/NotificationMenuItemFactory.qml:120
255#: qml/Notifications/NotificationMenuItemFactory.qml:120
253msgid "Enter SIM PIN"
256msgid "Enter SIM PIN"
254−msgstr ""
257+msgstr "Escribi'l PIN de la SIM"
255
258
256−#: qml/Notifications/NotificationMenuItemFactory.qml:121 qml/Shell.qml:270
259+#: qml/Notifications/NotificationMenuItemFactory.qml:121
257msgid "Sorry, incorrect PIN"
260msgid "Sorry, incorrect PIN"
258−msgstr ""
261+msgstr "PIN incorreutu"
259
262
260#: qml/Panel/ActiveCallHint.qml:77
263#: qml/Panel/ActiveCallHint.qml:77
261msgid "Tap to return to call..."
264msgid "Tap to return to call..."
@@ -291,58 +294,62 @@ msgstr "Falló, toca pa reintentar"
291
294
292#: qml/Panel/Indicators/ModemInfoItem.qml:105
295#: qml/Panel/Indicators/ModemInfoItem.qml:105
293msgid "Unlock SIM"
296msgid "Unlock SIM"
294−msgstr ""
297+msgstr "Desbloquiar SIM"
295
298
296#: qml/Panel/Indicators/RoamingIndication.qml:27
299#: qml/Panel/Indicators/RoamingIndication.qml:27
297msgid "Roaming"
300msgid "Roaming"
298−msgstr ""
301+msgstr "Roaming"
299
302
300−#: qml/Shell.qml:266
303+#: qml/Shell.qml:279
301msgid "Enter your passphrase"
304msgid "Enter your passphrase"
302−msgstr ""
305+msgstr "Introduz contraseña"
303
306
304−#: qml/Shell.qml:267
307+#: qml/Shell.qml:280
305msgid "Sorry, incorrect passphrase"
308msgid "Sorry, incorrect passphrase"
306−msgstr ""
309+msgstr "Sentímoslo, contraseña incorreuta"
307
310
308#: qml/Shell.qml:282
311#: qml/Shell.qml:282
309msgid "Enter your passcode"
312msgid "Enter your passcode"
310−msgstr ""
313+msgstr "Introduz códigu de pasu"
311
314
312#: qml/Shell.qml:283
315#: qml/Shell.qml:283
313msgid "Sorry, incorrect passcode"
316msgid "Sorry, incorrect passcode"
314−msgstr ""
317+msgstr "Sentímoslo, códigu de pasu incorreutu"
315
318
316−#: qml/Shell.qml:273
319+#: qml/Shell.qml:286
317#, qt-format
320#, qt-format
318msgid "Enter your %1"
321msgid "Enter your %1"
319−msgstr ""
322+msgstr "Introduz %1"
320
323
321−#: qml/Shell.qml:274
324+#: qml/Shell.qml:287
322#, qt-format
325#, qt-format
323msgid "Sorry, incorrect %1"
326msgid "Sorry, incorrect %1"
324−msgstr ""
327+msgstr "Sentímoslo, %1 incorreutu"
325
328
326−#: qml/Shell.qml:310
329+#: qml/Shell.qml:323
327msgid "Sorry, incorrect passphrase."
330msgid "Sorry, incorrect passphrase."
328−msgstr ""
331+msgstr "Fras de pasu incorreuta"
329
332
330−#: qml/Shell.qml:311
333+#: qml/Shell.qml:324
331msgid "Sorry, incorrect passcode."
334msgid "Sorry, incorrect passcode."
332−msgstr ""
335+msgstr "Códigu de pasu incorreutu"
333
336
334−#: qml/Shell.qml:312
337+#: qml/Shell.qml:325
335msgid "This will be your last attempt."
338msgid "This will be your last attempt."
336−msgstr ""
339+msgstr "Esti ye'l caberu intentu."
337
340
338−#: qml/Shell.qml:314
341+#: qml/Shell.qml:327
339msgid ""
342msgid ""
340"If passphrase is entered incorrectly, your phone will conduct a factory "
343"If passphrase is entered incorrectly, your phone will conduct a factory "
341"reset and all personal data will be deleted."
344"reset and all personal data will be deleted."
342msgstr ""
345msgstr ""
346+"Si s'inxerta la fras incorreutamente, el teléfonu va volver a la "
347+"configuración de fábrica y van perdese tolos datos personales."
343
348
344−#: qml/Shell.qml:315
349+#: qml/Shell.qml:328
345msgid ""
350msgid ""
346"If passcode is entered incorrectly, your phone will conduct a factory reset "
351"If passcode is entered incorrectly, your phone will conduct a factory reset "
347"and all personal data will be deleted."
352"and all personal data will be deleted."
348msgstr ""
353msgstr ""
354+"Si s'inxerta'l códigu incorreutamente, el teléfonu va volver a la "
355+"configuración de fábrica y van perdese tolos datos personales."
po/az.po+56−64
@@ -8,18 +8,18 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
11−"PO-Revision-Date: 2014-08-26 22:12+0000\n"
11+"PO-Revision-Date: 2014-09-03 16:39+0000\n"
12−"Last-Translator: Turan Mahmudov <turan.mahmudov@gmail.com>\n"
12+"Last-Translator: Nicat Məmmədov <n1c4t97@gmail.com>\n"
13"Language-Team: Azerbaijani <az@li.org>\n"
13"Language-Team: Azerbaijani <az@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-08-28 06:29+0000\n"
17+"X-Launchpad-Export-Date: 2014-09-04 08:35+0000\n"
18−"X-Generator: Launchpad (build 17174)\n"
18+"X-Generator: Launchpad (build 17196)\n"
19
19
20−#: plugins/LightDM/Greeter.cpp:129
20+#: plugins/LightDM/Greeter.cpp:130
21msgid "Password: "
21msgid "Password: "
22−msgstr "Parol: "
22+msgstr "Şifrә: "
23
23
24#: plugins/Unity/Launcher/launcheritem.cpp:43
24#: plugins/Unity/Launcher/launcheritem.cpp:43
25#: plugins/Unity/Launcher/launcheritem.cpp:73
25#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -32,37 +32,37 @@ msgstr "Açma qısayolu"
32
32
33#: qml/Components/Dialogs.qml:70
33#: qml/Components/Dialogs.qml:70
34msgid "Log out"
34msgid "Log out"
35−msgstr ""
35+msgstr "Çıxış"
36
36
37#: qml/Components/Dialogs.qml:71
37#: qml/Components/Dialogs.qml:71
38msgid "Are you sure you want to log out?"
38msgid "Are you sure you want to log out?"
39−msgstr ""
39+msgstr "Çıxmaq istәdiyinizdәn әminsiniz?"
40
40
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
42#: qml/Components/Dialogs.qml:122
42#: qml/Components/Dialogs.qml:122
43msgid "No"
43msgid "No"
44−msgstr ""
44+msgstr "Yox"
45
45
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
47#: qml/Components/Dialogs.qml:129
47#: qml/Components/Dialogs.qml:129
48msgid "Yes"
48msgid "Yes"
49−msgstr ""
49+msgstr "Hə"
50
50
51#: qml/Components/Dialogs.qml:94
51#: qml/Components/Dialogs.qml:94
52msgid "Shut down"
52msgid "Shut down"
53−msgstr ""
53+msgstr "Sistemi Söndür"
54
54
55#: qml/Components/Dialogs.qml:95
55#: qml/Components/Dialogs.qml:95
56msgid "Are you sure you want to shut down?"
56msgid "Are you sure you want to shut down?"
57−msgstr ""
57+msgstr "Sistemi söndürmәk istәdiyinizә әminsiniz?"
58
58
59#: qml/Components/Dialogs.qml:119
59#: qml/Components/Dialogs.qml:119
60msgid "Reboot"
60msgid "Reboot"
61−msgstr ""
61+msgstr "Yenidən yüklə"
62
62
63#: qml/Components/Dialogs.qml:120
63#: qml/Components/Dialogs.qml:120
64msgid "Are you sure you want to reboot?"
64msgid "Are you sure you want to reboot?"
65−msgstr ""
65+msgstr "Yenidәn başlatmaq istәdiyinizә әminsiniz?"
66
66
67#: qml/Components/Dialogs.qml:144
67#: qml/Components/Dialogs.qml:144
68msgid "Power"
68msgid "Power"
@@ -74,17 +74,17 @@ msgid ""
74"to power off?"
74"to power off?"
75msgstr ""
75msgstr ""
76
76
77−#: qml/Components/Dialogs.qml:144
77+#: qml/Components/Dialogs.qml:147
78msgid "Power off"
78msgid "Power off"
79msgstr "Söndür"
79msgstr "Söndür"
80
80
81−#: qml/Components/Dialogs.qml:162
81+#: qml/Components/Dialogs.qml:157
82msgid "Cancel"
82msgid "Cancel"
83msgstr "İmtina"
83msgstr "İmtina"
84
84
85#: qml/Components/EdgeDemoOverlay.qml:151
85#: qml/Components/EdgeDemoOverlay.qml:151
86msgid "Skip intro"
86msgid "Skip intro"
87−msgstr "Intro -nu keç"
87+msgstr "Tәqdimatı keç"
88
88
89#: qml/Components/EdgeDemo.qml:112
89#: qml/Components/EdgeDemo.qml:112
90msgid "Right edge"
90msgid "Right edge"
@@ -92,7 +92,7 @@ msgstr "Sağ Künc"
92
92
93#: qml/Components/EdgeDemo.qml:113
93#: qml/Components/EdgeDemo.qml:113
94msgid "Try swiping from the right edge to unlock the phone"
94msgid "Try swiping from the right edge to unlock the phone"
95−msgstr "Kilidi açmaq üçün sağ küncdən çəkin"
95+msgstr "Kilidi açmaq üçün sağ küncdən sürüşdürün"
96
96
97#: qml/Components/EdgeDemo.qml:144
97#: qml/Components/EdgeDemo.qml:144
98msgid "Top edge"
98msgid "Top edge"
@@ -100,7 +100,7 @@ msgstr "Yuxarı künc"
100
100
101#: qml/Components/EdgeDemo.qml:145
101#: qml/Components/EdgeDemo.qml:145
102msgid "Try swiping from the top edge to access the indicators"
102msgid "Try swiping from the top edge to access the indicators"
103−msgstr "Göstəricilərə keçid üçün yuxarı küncdən çəkin"
103+msgstr "Göstəriciləri görmәk üçün yuxarı küncdən sürüşdürün"
104
104
105#: qml/Components/EdgeDemo.qml:170
105#: qml/Components/EdgeDemo.qml:170
106msgid "Close"
106msgid "Close"
@@ -108,7 +108,7 @@ msgstr "Bağla"
108
108
109#: qml/Components/EdgeDemo.qml:171
109#: qml/Components/EdgeDemo.qml:171
110msgid "Swipe up again to close the settings screen"
110msgid "Swipe up again to close the settings screen"
111−msgstr "Nizamlamalar ekranını bağlamaq üçün yenidən yuxarı çəkin"
111+msgstr "Nizamlamalar ekranını bağlamaq üçün yenidən yuxarı sürüşdürün"
112
112
113#: qml/Components/EdgeDemo.qml:198
113#: qml/Components/EdgeDemo.qml:198
114msgid "Left edge"
114msgid "Left edge"
@@ -128,16 +128,16 @@ msgid ""
128"You have now mastered the edge gestures and can start using the "
128"You have now mastered the edge gestures and can start using the "
129"phone<br><br>Tap on the screen to start"
129"phone<br><br>Tap on the screen to start"
130msgstr ""
130msgstr ""
131−"Siz künc jestlərini mənimsəmisiniz və telefonu istifadə etməyə başlaya "
131+"Siz künc hәrәkәtlәrini öyrәndiniz və telefonu istifadə etməyə başlaya "
132"bilərsiniz.<br><br>Başlamaq üçün ekrana toxunun"
132"bilərsiniz.<br><br>Başlamaq üçün ekrana toxunun"
133
133
134#: qml/Components/Lockscreen.qml:167
134#: qml/Components/Lockscreen.qml:167
135msgid "Please wait"
135msgid "Please wait"
136−msgstr "Lütfən gözləyin"
136+msgstr "Xahiş edirik gözləyin"
137
137
138#: qml/Components/Lockscreen.qml:172
138#: qml/Components/Lockscreen.qml:172
139msgid "Too many incorrect attempts"
139msgid "Too many incorrect attempts"
140−msgstr "Çoxlu yanlış cəhd"
140+msgstr "Çoxlu yanlış cəhdlәr"
141
141
142#: qml/Components/Lockscreen.qml:206
142#: qml/Components/Lockscreen.qml:206
143msgid "Emergency Call"
143msgid "Emergency Call"
@@ -145,44 +145,45 @@ msgstr "Zərurət zəngi"
145
145
146#: qml/Components/Lockscreen.qml:226
146#: qml/Components/Lockscreen.qml:226
147msgid "OK"
147msgid "OK"
148−msgstr "ОК"
148+msgstr "Oldu"
149
149
150#: qml/Components/PassphraseLockscreen.qml:61
150#: qml/Components/PassphraseLockscreen.qml:61
151#, qt-format
151#, qt-format
152msgid "Hello %1"
152msgid "Hello %1"
153−msgstr "Xoş gördük %1"
153+msgstr "Salam %1"
154
154
155#: qml/Components/PassphraseLockscreen.qml:61
155#: qml/Components/PassphraseLockscreen.qml:61
156msgid "Hello"
156msgid "Hello"
157−msgstr "Xoş gördük"
157+msgstr "Salam"
158
158
159#: qml/Dash/GenericScopeView.qml:361
159#: qml/Dash/GenericScopeView.qml:361
160msgid "See less"
160msgid "See less"
161−msgstr "Daha az gör"
161+msgstr "Daha azını gör"
162
162
163#: qml/Dash/GenericScopeView.qml:361
163#: qml/Dash/GenericScopeView.qml:361
164msgid "See all"
164msgid "See all"
165msgstr "Hamısını gör"
165msgstr "Hamısını gör"
166
166
167−#: qml/Dash/GenericScopeView.qml:424 qml/Panel/SearchIndicator.qml:27
167+#: qml/Dash/GenericScopeView.qml:424 qml/Dash/PageHeader.qml:260
168+#: qml/Panel/SearchIndicator.qml:27
168msgid "Search"
169msgid "Search"
169msgstr "Axtar"
170msgstr "Axtar"
170
171
171#: qml/Dash/PageHeader.qml:270
172#: qml/Dash/PageHeader.qml:270
172msgid "Settings"
173msgid "Settings"
173−msgstr ""
174+msgstr "Tənzimləmələr"
174
175
175#: qml/Dash/PageHeader.qml:279
176#: qml/Dash/PageHeader.qml:279
176msgid "Remove from Favorites"
177msgid "Remove from Favorites"
177−msgstr ""
178+msgstr "Seçilmişlәrdәn çıxart"
178
179
179#: qml/Dash/PageHeader.qml:279
180#: qml/Dash/PageHeader.qml:279
180msgid "Add to Favorites"
181msgid "Add to Favorites"
181−msgstr ""
182+msgstr "Seçilmişlәrә әlavә et"
182
183
183#: qml/Dash/Previews/PreviewActionCombo.qml:34
184#: qml/Dash/Previews/PreviewActionCombo.qml:34
184msgid "More..."
185msgid "More..."
185−msgstr "Ətraflı..."
186+msgstr "Daha çox..."
186
187
187#: qml/Dash/Previews/PreviewActionCombo.qml:34
188#: qml/Dash/Previews/PreviewActionCombo.qml:34
188msgid "Less..."
189msgid "Less..."
@@ -190,7 +191,7 @@ msgstr "Az..."
190
191
191#: qml/Dash/Previews/PreviewRatingInput.qml:81
192#: qml/Dash/Previews/PreviewRatingInput.qml:81
192msgid "Rate this"
193msgid "Rate this"
193−msgstr "Qiymət ver"
194+msgstr "Qiymәtlәndir"
194
195
195#: qml/Dash/Previews/PreviewRatingInput.qml:126
196#: qml/Dash/Previews/PreviewRatingInput.qml:126
196msgid "Add a review"
197msgid "Add a review"
@@ -204,13 +205,13 @@ msgstr "Göndər"
204msgid "Manage Dash"
205msgid "Manage Dash"
205msgstr ""
206msgstr ""
206
207
207−#: qml/Dash/ScopesOverview.qml:408
208+#: qml/Dash/ScopesOverview.qml:417
208msgid "Done"
209msgid "Done"
209msgstr "Başa çatdı"
210msgstr "Başa çatdı"
210
211
211−#: qml/Dash/ScopesOverview.qml:434
212+#: qml/Dash/ScopesOverview.qml:443
212msgid "Store"
213msgid "Store"
213−msgstr "Saxla"
214+msgstr ""
214
215
215#: qml/Dash/ScopesOverviewTab.qml:36
216#: qml/Dash/ScopesOverviewTab.qml:36
216msgid "Favorites"
217msgid "Favorites"
@@ -224,13 +225,13 @@ msgstr "Hamısı"
224msgid "Swipe to unlock"
225msgid "Swipe to unlock"
225msgstr "Kilidi açmaq üçün sürüşdürün"
226msgstr "Kilidi açmaq üçün sürüşdürün"
226
227
227−#: qml/Hud/HudParametrizedActionsPage.qml:132
228+#: qml/Hud/HudParametrizedActionsPage.qml:139
228msgid "Confirm"
229msgid "Confirm"
229msgstr "Təsdiqlə"
230msgstr "Təsdiqlə"
230
231
231#: qml/Hud/Hud.qml:61 qml/Hud/Hud.qml:99 qml/Hud/Hud.qml:372
232#: qml/Hud/Hud.qml:61 qml/Hud/Hud.qml:99 qml/Hud/Hud.qml:372
232msgid "Type or say a command"
233msgid "Type or say a command"
233−msgstr "Əmri söyləyin və ya yazın"
234+msgstr "Bir әmr söyləyin və ya yazın"
234
235
235#: qml/Hud/Hud.qml:84
236#: qml/Hud/Hud.qml:84
236msgid "Loading. Please Wait..."
237msgid "Loading. Please Wait..."
@@ -246,15 +247,15 @@ msgstr "Danışır..."
246
247
247#: qml/Notifications/NotificationMenuItemFactory.qml:105
248#: qml/Notifications/NotificationMenuItemFactory.qml:105
248msgid "Show password"
249msgid "Show password"
249−msgstr "Parolu göstər"
250+msgstr "Şifrәni göstәr"
250
251
251#: qml/Notifications/NotificationMenuItemFactory.qml:120
252#: qml/Notifications/NotificationMenuItemFactory.qml:120
252msgid "Enter SIM PIN"
253msgid "Enter SIM PIN"
253msgstr "SIM PIN kodunuzu daxil edin"
254msgstr "SIM PIN kodunuzu daxil edin"
254
255
255−#: qml/Notifications/NotificationMenuItemFactory.qml:121 qml/Shell.qml:270
256+#: qml/Notifications/NotificationMenuItemFactory.qml:121
256msgid "Sorry, incorrect PIN"
257msgid "Sorry, incorrect PIN"
257−msgstr "Təəssüf ki, PIN yanlışdır"
258+msgstr "Bağışlayın, PIN yanlışdır"
258
259
259#: qml/Panel/ActiveCallHint.qml:77
260#: qml/Panel/ActiveCallHint.qml:77
260msgid "Tap to return to call..."
261msgid "Tap to return to call..."
@@ -274,7 +275,7 @@ msgstr "Endirilir"
274
275
275#: qml/Panel/Indicators/MenuItemFactory.qml:657
276#: qml/Panel/Indicators/MenuItemFactory.qml:657
276msgid "Paused, tap to resume"
277msgid "Paused, tap to resume"
277−msgstr "Saxlanıldı, davam etmək üçün toxunun"
278+msgstr "Dayandırıldı. Davam etmək üçün toxunun"
278
279
279#: qml/Panel/Indicators/MenuItemFactory.qml:659
280#: qml/Panel/Indicators/MenuItemFactory.qml:659
280msgid "Canceled"
281msgid "Canceled"
@@ -286,7 +287,7 @@ msgstr "Bitdi"
286
287
287#: qml/Panel/Indicators/MenuItemFactory.qml:663
288#: qml/Panel/Indicators/MenuItemFactory.qml:663
288msgid "Failed, tap to retry"
289msgid "Failed, tap to retry"
289−msgstr "Alınmadı, davam etmək üçün toxunun"
290+msgstr "Alınmadı. Yenidәn cәhd etmək üçün toxunun"
290
291
291#: qml/Panel/Indicators/ModemInfoItem.qml:105
292#: qml/Panel/Indicators/ModemInfoItem.qml:105
292msgid "Unlock SIM"
293msgid "Unlock SIM"
@@ -296,13 +297,13 @@ msgstr "SIM kilidini aç"
296msgid "Roaming"
297msgid "Roaming"
297msgstr "Rominq"
298msgstr "Rominq"
298
299
299−#: qml/Shell.qml:266
300+#: qml/Shell.qml:279
300msgid "Enter your passphrase"
301msgid "Enter your passphrase"
301msgstr "Açar sözünüzü daxil edin"
302msgstr "Açar sözünüzü daxil edin"
302
303
303−#: qml/Shell.qml:267
304+#: qml/Shell.qml:280
304msgid "Sorry, incorrect passphrase"
305msgid "Sorry, incorrect passphrase"
305−msgstr "Təəssüf ki, açar söz yanlışdır"
306+msgstr "Bağışlayın, açar söz yanlışdır"
306
307
307#: qml/Shell.qml:282
308#: qml/Shell.qml:282
308msgid "Enter your passcode"
309msgid "Enter your passcode"
@@ -312,29 +313,29 @@ msgstr ""
312msgid "Sorry, incorrect passcode"
313msgid "Sorry, incorrect passcode"
313msgstr ""
314msgstr ""
314
315
315−#: qml/Shell.qml:273
316+#: qml/Shell.qml:286
316#, qt-format
317#, qt-format
317msgid "Enter your %1"
318msgid "Enter your %1"
318msgstr "%1 daxil edin"
319msgstr "%1 daxil edin"
319
320
320−#: qml/Shell.qml:274
321+#: qml/Shell.qml:287
321#, qt-format
322#, qt-format
322msgid "Sorry, incorrect %1"
323msgid "Sorry, incorrect %1"
323−msgstr "Təəssüf ki, %1 yanlışdır"
324+msgstr "Bağışlayın, %1 yanlışdır"
324
325
325−#: qml/Shell.qml:310
326+#: qml/Shell.qml:323
326msgid "Sorry, incorrect passphrase."
327msgid "Sorry, incorrect passphrase."
327−msgstr "Təəssüf ki, açar söz yanlışdır."
328+msgstr "Bağışlayın, açar söz yanlışdır."
328
329
329−#: qml/Shell.qml:311
330+#: qml/Shell.qml:324
330msgid "Sorry, incorrect passcode."
331msgid "Sorry, incorrect passcode."
331msgstr "Təəssüf ki, açar kod yanlışdır."
332msgstr "Təəssüf ki, açar kod yanlışdır."
332
333
333−#: qml/Shell.qml:312
334+#: qml/Shell.qml:325
334msgid "This will be your last attempt."
335msgid "This will be your last attempt."
335msgstr "Bu sizin son cəhdiniz olacaq."
336msgstr "Bu sizin son cəhdiniz olacaq."
336
337
337−#: qml/Shell.qml:314
338+#: qml/Shell.qml:327
338msgid ""
339msgid ""
339"If passphrase is entered incorrectly, your phone will conduct a factory "
340"If passphrase is entered incorrectly, your phone will conduct a factory "
340"reset and all personal data will be deleted."
341"reset and all personal data will be deleted."
@@ -342,19 +343,10 @@ msgstr ""
342"Əgər açar söz yanlış daxil edilibsə, onda telefonunuz fabrika parametrlərinə "
343"Əgər açar söz yanlış daxil edilibsə, onda telefonunuz fabrika parametrlərinə "
343"geri qayıdacaq və bütün şəxsi məlumatlarınız silinəcək."
344"geri qayıdacaq və bütün şəxsi məlumatlarınız silinəcək."
344
345
345−#: qml/Shell.qml:315
346+#: qml/Shell.qml:328
346msgid ""
347msgid ""
347"If passcode is entered incorrectly, your phone will conduct a factory reset "
348"If passcode is entered incorrectly, your phone will conduct a factory reset "
348"and all personal data will be deleted."
349"and all personal data will be deleted."
349msgstr ""
350msgstr ""
350"Əgər açar kod yanlış daxil edilibsə, onda telefonunuz fabrika parametrlərinə "
351"Əgər açar kod yanlış daxil edilibsə, onda telefonunuz fabrika parametrlərinə "
351"geri qayıdacaq və bütün şəxsi məlumatlarınız silinəcək."
352"geri qayıdacaq və bütün şəxsi məlumatlarınız silinəcək."
352−
353−#~ msgid "Are you sure you would like to turn power off?"
354−#~ msgstr "Söndürmək istədiyinizə əminsiniz?"
355−
356−#~ msgid "Restart"
357−#~ msgstr "Yenidən Başlat"
358−
359−#~ msgid "Enter your PIN"
360−#~ msgstr "PIN kodunuzu daxil edin"
po/ca.po+39−45
@@ -8,16 +8,16 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
11−"PO-Revision-Date: 2014-08-27 14:23+0000\n"
11+"PO-Revision-Date: 2014-09-07 04:05+0000\n"
12"Last-Translator: David Planella <david.planella@ubuntu.com>\n"
12"Last-Translator: David Planella <david.planella@ubuntu.com>\n"
13"Language-Team: Catalan <ca@li.org>\n"
13"Language-Team: Catalan <ca@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-08-28 06:30+0000\n"
17+"X-Launchpad-Export-Date: 2014-09-08 06:58+0000\n"
18−"X-Generator: Launchpad (build 17174)\n"
18+"X-Generator: Launchpad (build 17196)\n"
19
19
20−#: plugins/LightDM/Greeter.cpp:129
20+#: plugins/LightDM/Greeter.cpp:130
21msgid "Password: "
21msgid "Password: "
22msgstr "Contrasenya: "
22msgstr "Contrasenya: "
23
23
@@ -32,53 +32,55 @@ msgstr "Desenganxa la drecera"
32
32
33#: qml/Components/Dialogs.qml:70
33#: qml/Components/Dialogs.qml:70
34msgid "Log out"
34msgid "Log out"
35−msgstr ""
35+msgstr "Surt"
36
36
37#: qml/Components/Dialogs.qml:71
37#: qml/Components/Dialogs.qml:71
38msgid "Are you sure you want to log out?"
38msgid "Are you sure you want to log out?"
39−msgstr ""
39+msgstr "Segur que voleu sortir?"
40
40
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
42#: qml/Components/Dialogs.qml:122
42#: qml/Components/Dialogs.qml:122
43msgid "No"
43msgid "No"
44−msgstr ""
44+msgstr "No"
45
45
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
47#: qml/Components/Dialogs.qml:129
47#: qml/Components/Dialogs.qml:129
48msgid "Yes"
48msgid "Yes"
49−msgstr ""
49+msgstr "Sí"
50
50
51#: qml/Components/Dialogs.qml:94
51#: qml/Components/Dialogs.qml:94
52msgid "Shut down"
52msgid "Shut down"
53−msgstr ""
53+msgstr "Apaga"
54
54
55#: qml/Components/Dialogs.qml:95
55#: qml/Components/Dialogs.qml:95
56msgid "Are you sure you want to shut down?"
56msgid "Are you sure you want to shut down?"
57−msgstr ""
57+msgstr "Segur que voleu apagar?"
58
58
59#: qml/Components/Dialogs.qml:119
59#: qml/Components/Dialogs.qml:119
60msgid "Reboot"
60msgid "Reboot"
61−msgstr ""
61+msgstr "Reinicia"
62
62
63#: qml/Components/Dialogs.qml:120
63#: qml/Components/Dialogs.qml:120
64msgid "Are you sure you want to reboot?"
64msgid "Are you sure you want to reboot?"
65−msgstr ""
65+msgstr "Segur que voleu reiniciar?"
66
66
67#: qml/Components/Dialogs.qml:144
67#: qml/Components/Dialogs.qml:144
68msgid "Power"
68msgid "Power"
69−msgstr ""
69+msgstr "Energia"
70
70
71#: qml/Components/Dialogs.qml:145
71#: qml/Components/Dialogs.qml:145
72msgid ""
72msgid ""
73"Are you sure you would like\n"
73"Are you sure you would like\n"
74"to power off?"
74"to power off?"
75msgstr ""
75msgstr ""
76+"Segur que voleu\n"
77+"apagar?"
76
78
77−#: qml/Components/Dialogs.qml:144
79+#: qml/Components/Dialogs.qml:147
78msgid "Power off"
80msgid "Power off"
79−msgstr "Apaga'l"
81+msgstr "Apaga"
80
82
81−#: qml/Components/Dialogs.qml:162
83+#: qml/Components/Dialogs.qml:157
82msgid "Cancel"
84msgid "Cancel"
83msgstr "Cancel·la"
85msgstr "Cancel·la"
84
86
@@ -169,21 +171,22 @@ msgstr "Mostra'n menys"
169msgid "See all"
171msgid "See all"
170msgstr "Mostra-ho tot"
172msgstr "Mostra-ho tot"
171
173
172−#: qml/Dash/GenericScopeView.qml:424 qml/Panel/SearchIndicator.qml:27
174+#: qml/Dash/GenericScopeView.qml:424 qml/Dash/PageHeader.qml:260
175+#: qml/Panel/SearchIndicator.qml:27
173msgid "Search"
176msgid "Search"
174msgstr "Cerca"
177msgstr "Cerca"
175
178
176#: qml/Dash/PageHeader.qml:270
179#: qml/Dash/PageHeader.qml:270
177msgid "Settings"
180msgid "Settings"
178−msgstr ""
181+msgstr "Paràmetres"
179
182
180#: qml/Dash/PageHeader.qml:279
183#: qml/Dash/PageHeader.qml:279
181msgid "Remove from Favorites"
184msgid "Remove from Favorites"
182−msgstr ""
185+msgstr "Suprimeix dels preferits"
183
186
184#: qml/Dash/PageHeader.qml:279
187#: qml/Dash/PageHeader.qml:279
185msgid "Add to Favorites"
188msgid "Add to Favorites"
186−msgstr ""
189+msgstr "Afegeix als preferits"
187
190
188#: qml/Dash/Previews/PreviewActionCombo.qml:34
191#: qml/Dash/Previews/PreviewActionCombo.qml:34
189msgid "More..."
192msgid "More..."
@@ -209,11 +212,11 @@ msgstr "Envia"
209msgid "Manage Dash"
212msgid "Manage Dash"
210msgstr "Gestiona el tauler"
213msgstr "Gestiona el tauler"
211
214
212−#: qml/Dash/ScopesOverview.qml:408
215+#: qml/Dash/ScopesOverview.qml:417
213msgid "Done"
216msgid "Done"
214msgstr "Fet"
217msgstr "Fet"
215
218
216−#: qml/Dash/ScopesOverview.qml:434
219+#: qml/Dash/ScopesOverview.qml:443
217msgid "Store"
220msgid "Store"
218msgstr "Botiga"
221msgstr "Botiga"
219
222
@@ -229,7 +232,7 @@ msgstr "Totes"
229msgid "Swipe to unlock"
232msgid "Swipe to unlock"
230msgstr "Feu lliscar el dit per desbloquejar"
233msgstr "Feu lliscar el dit per desbloquejar"
231
234
232−#: qml/Hud/HudParametrizedActionsPage.qml:132
235+#: qml/Hud/HudParametrizedActionsPage.qml:139
233msgid "Confirm"
236msgid "Confirm"
234msgstr "Confirma"
237msgstr "Confirma"
235
238
@@ -255,9 +258,9 @@ msgstr "Mostra la contrasenya"
255
258
256#: qml/Notifications/NotificationMenuItemFactory.qml:120
259#: qml/Notifications/NotificationMenuItemFactory.qml:120
257msgid "Enter SIM PIN"
260msgid "Enter SIM PIN"
258−msgstr "Introduïu el PIN de la tarjeta SIM"
261+msgstr "Introduïu el PIN de la targeta SIM"
259
262
260−#: qml/Notifications/NotificationMenuItemFactory.qml:121 qml/Shell.qml:270
263+#: qml/Notifications/NotificationMenuItemFactory.qml:121
261msgid "Sorry, incorrect PIN"
264msgid "Sorry, incorrect PIN"
262msgstr "El PIN no és correcte"
265msgstr "El PIN no és correcte"
263
266
@@ -301,45 +304,45 @@ msgstr "Desbloca la SIM"
301msgid "Roaming"
304msgid "Roaming"
302msgstr "Itinerància"
305msgstr "Itinerància"
303
306
304−#: qml/Shell.qml:266
307+#: qml/Shell.qml:279
305msgid "Enter your passphrase"
308msgid "Enter your passphrase"
306msgstr "Escriviu la contrasenya"
309msgstr "Escriviu la contrasenya"
307
310
308−#: qml/Shell.qml:267
311+#: qml/Shell.qml:280
309msgid "Sorry, incorrect passphrase"
312msgid "Sorry, incorrect passphrase"
310msgstr "La contrasenya no és correcta"
313msgstr "La contrasenya no és correcta"
311
314
312#: qml/Shell.qml:282
315#: qml/Shell.qml:282
313msgid "Enter your passcode"
316msgid "Enter your passcode"
314−msgstr ""
317+msgstr "Introduïu el codi d'accés"
315
318
316#: qml/Shell.qml:283
319#: qml/Shell.qml:283
317msgid "Sorry, incorrect passcode"
320msgid "Sorry, incorrect passcode"
318−msgstr ""
321+msgstr "El codi d'accés no és correcte"
319
322
320−#: qml/Shell.qml:273
323+#: qml/Shell.qml:286
321#, qt-format
324#, qt-format
322msgid "Enter your %1"
325msgid "Enter your %1"
323msgstr "Introduïu la %1"
326msgstr "Introduïu la %1"
324
327
325−#: qml/Shell.qml:274
328+#: qml/Shell.qml:287
326#, qt-format
329#, qt-format
327msgid "Sorry, incorrect %1"
330msgid "Sorry, incorrect %1"
328msgstr "Incorrecte (%1)"
331msgstr "Incorrecte (%1)"
329
332
330−#: qml/Shell.qml:310
333+#: qml/Shell.qml:323
331msgid "Sorry, incorrect passphrase."
334msgid "Sorry, incorrect passphrase."
332msgstr "La contrasenya és incorrecta"
335msgstr "La contrasenya és incorrecta"
333
336
334−#: qml/Shell.qml:311
337+#: qml/Shell.qml:324
335msgid "Sorry, incorrect passcode."
338msgid "Sorry, incorrect passcode."
336msgstr "La clau és incorrecta"
339msgstr "La clau és incorrecta"
337
340
338−#: qml/Shell.qml:312
341+#: qml/Shell.qml:325
339msgid "This will be your last attempt."
342msgid "This will be your last attempt."
340msgstr "Aquest serà el darrer intent."
343msgstr "Aquest serà el darrer intent."
341
344
342−#: qml/Shell.qml:314
345+#: qml/Shell.qml:327
343msgid ""
346msgid ""
344"If passphrase is entered incorrectly, your phone will conduct a factory "
347"If passphrase is entered incorrectly, your phone will conduct a factory "
345"reset and all personal data will be deleted."
348"reset and all personal data will be deleted."
@@ -348,19 +351,10 @@ msgstr ""
348"reinicialitzarà a l'estat de fàbrica i se suprimiran totes les dades "
351"reinicialitzarà a l'estat de fàbrica i se suprimiran totes les dades "
349"personals."
352"personals."
350
353
351−#: qml/Shell.qml:315
354+#: qml/Shell.qml:328
352msgid ""
355msgid ""
353"If passcode is entered incorrectly, your phone will conduct a factory reset "
356"If passcode is entered incorrectly, your phone will conduct a factory reset "
354"and all personal data will be deleted."
357"and all personal data will be deleted."
355msgstr ""
358msgstr ""
356"Si la clau s'introdueix de manera incorrecta, el telèfon es reinicialitzarà "
359"Si la clau s'introdueix de manera incorrecta, el telèfon es reinicialitzarà "
357"a l'estat de fàbrica i se suprimiran totes les dades personals."
360"a l'estat de fàbrica i se suprimiran totes les dades personals."
358−
359−#~ msgid "Are you sure you would like to turn power off?"
360−#~ msgstr "Segur que voleu apagar el dispositiu?"
361−
362−#~ msgid "Restart"
363−#~ msgstr "Reinicia'l"
364−
365−#~ msgid "Enter your PIN"
366−#~ msgstr "Escriviu el PIN"
po/de.po+7−7
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
11−"PO-Revision-Date: 2014-08-29 13:00+0000\n"
11+"PO-Revision-Date: 2014-09-04 15:02+0000\n"
12−"Last-Translator: Martin Pitt <martin.pitt@ubuntu.com>\n"
12+"Last-Translator: Niklas Wenzel <nikwen.developer@gmail.com>\n"
13"Language-Team: German <de@li.org>\n"
13"Language-Team: German <de@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-08-30 07:46+0000\n"
17+"X-Launchpad-Export-Date: 2014-09-05 07:50+0000\n"
18−"X-Generator: Launchpad (build 17176)\n"
18+"X-Generator: Launchpad (build 17196)\n"
19
19
20#: plugins/LightDM/Greeter.cpp:130
20#: plugins/LightDM/Greeter.cpp:130
21msgid "Password: "
21msgid "Password: "
@@ -36,7 +36,7 @@ msgstr "Abmelden"
36
36
37#: qml/Components/Dialogs.qml:71
37#: qml/Components/Dialogs.qml:71
38msgid "Are you sure you want to log out?"
38msgid "Are you sure you want to log out?"
39−msgstr "Sind Sie sicher dass Sie sich abmelden wollen?"
39+msgstr "Sind Sie sicher, dass Sie sich abmelden wollen?"
40
40
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
42#: qml/Components/Dialogs.qml:122
42#: qml/Components/Dialogs.qml:122
@@ -54,7 +54,7 @@ msgstr "Herunterfahren"
54
54
55#: qml/Components/Dialogs.qml:95
55#: qml/Components/Dialogs.qml:95
56msgid "Are you sure you want to shut down?"
56msgid "Are you sure you want to shut down?"
57−msgstr "Sind Sie sicher dass Sie ausschalten wollen?"
57+msgstr "Sind Sie sicher, dass Sie herunterfahren wollen?"
58
58
59#: qml/Components/Dialogs.qml:119
59#: qml/Components/Dialogs.qml:119
60msgid "Reboot"
60msgid "Reboot"
@@ -62,7 +62,7 @@ msgstr "Neustart"
62
62
63#: qml/Components/Dialogs.qml:120
63#: qml/Components/Dialogs.qml:120
64msgid "Are you sure you want to reboot?"
64msgid "Are you sure you want to reboot?"
65−msgstr "Sind Sie sicher dass Sie neu starten wollen?"
65+msgstr "Sind Sie sicher, dass Sie neu starten wollen?"
66
66
67#: qml/Components/Dialogs.qml:144
67#: qml/Components/Dialogs.qml:144
68msgid "Power"
68msgid "Power"
po/en_AU.po+37−43
@@ -8,16 +8,16 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
11−"PO-Revision-Date: 2014-08-27 09:59+0000\n"
11+"PO-Revision-Date: 2014-08-31 11:20+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"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-08-28 06:30+0000\n"
17+"X-Launchpad-Export-Date: 2014-09-01 07:33+0000\n"
18−"X-Generator: Launchpad (build 17174)\n"
18+"X-Generator: Launchpad (build 17176)\n"
19
19
20−#: plugins/LightDM/Greeter.cpp:129
20+#: plugins/LightDM/Greeter.cpp:130
21msgid "Password: "
21msgid "Password: "
22msgstr "Password: "
22msgstr "Password: "
23
23
@@ -32,53 +32,55 @@ msgstr "Unpin shortcut"
32
32
33#: qml/Components/Dialogs.qml:70
33#: qml/Components/Dialogs.qml:70
34msgid "Log out"
34msgid "Log out"
35−msgstr ""
35+msgstr "Log out"
36
36
37#: qml/Components/Dialogs.qml:71
37#: qml/Components/Dialogs.qml:71
38msgid "Are you sure you want to log out?"
38msgid "Are you sure you want to log out?"
39−msgstr ""
39+msgstr "Are you sure you want to log out?"
40
40
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
42#: qml/Components/Dialogs.qml:122
42#: qml/Components/Dialogs.qml:122
43msgid "No"
43msgid "No"
44−msgstr ""
44+msgstr "No"
45
45
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
47#: qml/Components/Dialogs.qml:129
47#: qml/Components/Dialogs.qml:129
48msgid "Yes"
48msgid "Yes"
49−msgstr ""
49+msgstr "Yes"
50
50
51#: qml/Components/Dialogs.qml:94
51#: qml/Components/Dialogs.qml:94
52msgid "Shut down"
52msgid "Shut down"
53−msgstr ""
53+msgstr "Shut down"
54
54
55#: qml/Components/Dialogs.qml:95
55#: qml/Components/Dialogs.qml:95
56msgid "Are you sure you want to shut down?"
56msgid "Are you sure you want to shut down?"
57−msgstr ""
57+msgstr "Are you sure you want to shut down?"
58
58
59#: qml/Components/Dialogs.qml:119
59#: qml/Components/Dialogs.qml:119
60msgid "Reboot"
60msgid "Reboot"
61−msgstr ""
61+msgstr "Reboot"
62
62
63#: qml/Components/Dialogs.qml:120
63#: qml/Components/Dialogs.qml:120
64msgid "Are you sure you want to reboot?"
64msgid "Are you sure you want to reboot?"
65−msgstr ""
65+msgstr "Are you sure you want to reboot?"
66
66
67#: qml/Components/Dialogs.qml:144
67#: qml/Components/Dialogs.qml:144
68msgid "Power"
68msgid "Power"
69−msgstr ""
69+msgstr "Power"
70
70
71#: qml/Components/Dialogs.qml:145
71#: qml/Components/Dialogs.qml:145
72msgid ""
72msgid ""
73"Are you sure you would like\n"
73"Are you sure you would like\n"
74"to power off?"
74"to power off?"
75msgstr ""
75msgstr ""
76+"Are you sure you would like\n"
77+"to power off?"
76
78
77−#: qml/Components/Dialogs.qml:144
79+#: qml/Components/Dialogs.qml:147
78msgid "Power off"
80msgid "Power off"
79msgstr "Power off"
81msgstr "Power off"
80
82
81−#: qml/Components/Dialogs.qml:162
83+#: qml/Components/Dialogs.qml:157
82msgid "Cancel"
84msgid "Cancel"
83msgstr "Cancel"
85msgstr "Cancel"
84
86
@@ -163,21 +165,22 @@ msgstr "See less"
163msgid "See all"
165msgid "See all"
164msgstr "See all"
166msgstr "See all"
165
167
166−#: qml/Dash/GenericScopeView.qml:424 qml/Panel/SearchIndicator.qml:27
168+#: qml/Dash/GenericScopeView.qml:424 qml/Dash/PageHeader.qml:260
169+#: qml/Panel/SearchIndicator.qml:27
167msgid "Search"
170msgid "Search"
168msgstr "Search"
171msgstr "Search"
169
172
170#: qml/Dash/PageHeader.qml:270
173#: qml/Dash/PageHeader.qml:270
171msgid "Settings"
174msgid "Settings"
172−msgstr ""
175+msgstr "Settings"
173
176
174#: qml/Dash/PageHeader.qml:279
177#: qml/Dash/PageHeader.qml:279
175msgid "Remove from Favorites"
178msgid "Remove from Favorites"
176−msgstr ""
179+msgstr "Remove from Favourites"
177
180
178#: qml/Dash/PageHeader.qml:279
181#: qml/Dash/PageHeader.qml:279
179msgid "Add to Favorites"
182msgid "Add to Favorites"
180−msgstr ""
183+msgstr "Add to Favourites"
181
184
182#: qml/Dash/Previews/PreviewActionCombo.qml:34
185#: qml/Dash/Previews/PreviewActionCombo.qml:34
183msgid "More..."
186msgid "More..."
@@ -203,11 +206,11 @@ msgstr "Send"
203msgid "Manage Dash"
206msgid "Manage Dash"
204msgstr "Manage Dash"
207msgstr "Manage Dash"
205
208
206−#: qml/Dash/ScopesOverview.qml:408
209+#: qml/Dash/ScopesOverview.qml:417
207msgid "Done"
210msgid "Done"
208msgstr "Done"
211msgstr "Done"
209
212
210−#: qml/Dash/ScopesOverview.qml:434
213+#: qml/Dash/ScopesOverview.qml:443
211msgid "Store"
214msgid "Store"
212msgstr "Store"
215msgstr "Store"
213
216
@@ -223,7 +226,7 @@ msgstr "All"
223msgid "Swipe to unlock"
226msgid "Swipe to unlock"
224msgstr "Swipe to unlock"
227msgstr "Swipe to unlock"
225
228
226−#: qml/Hud/HudParametrizedActionsPage.qml:132
229+#: qml/Hud/HudParametrizedActionsPage.qml:139
227msgid "Confirm"
230msgid "Confirm"
228msgstr "Confirm"
231msgstr "Confirm"
229
232
@@ -251,7 +254,7 @@ msgstr "Show password"
251msgid "Enter SIM PIN"
254msgid "Enter SIM PIN"
252msgstr "Enter SIM PIN"
255msgstr "Enter SIM PIN"
253
256
254−#: qml/Notifications/NotificationMenuItemFactory.qml:121 qml/Shell.qml:270
257+#: qml/Notifications/NotificationMenuItemFactory.qml:121
255msgid "Sorry, incorrect PIN"
258msgid "Sorry, incorrect PIN"
256msgstr "Sorry, incorrect PIN"
259msgstr "Sorry, incorrect PIN"
257
260
@@ -295,45 +298,45 @@ msgstr "Unlock SIM"
295msgid "Roaming"
298msgid "Roaming"
296msgstr "Roaming"
299msgstr "Roaming"
297
300
298−#: qml/Shell.qml:266
301+#: qml/Shell.qml:279
299msgid "Enter your passphrase"
302msgid "Enter your passphrase"
300msgstr "Enter your passphrase"
303msgstr "Enter your passphrase"
301
304
302−#: qml/Shell.qml:267
305+#: qml/Shell.qml:280
303msgid "Sorry, incorrect passphrase"
306msgid "Sorry, incorrect passphrase"
304msgstr "Sorry, incorrect passphrase"
307msgstr "Sorry, incorrect passphrase"
305
308
306#: qml/Shell.qml:282
309#: qml/Shell.qml:282
307msgid "Enter your passcode"
310msgid "Enter your passcode"
308−msgstr ""
311+msgstr "Enter your passcode"
309
312
310#: qml/Shell.qml:283
313#: qml/Shell.qml:283
311msgid "Sorry, incorrect passcode"
314msgid "Sorry, incorrect passcode"
312−msgstr ""
315+msgstr "Sorry, incorrect passcode"
313
316
314−#: qml/Shell.qml:273
317+#: qml/Shell.qml:286
315#, qt-format
318#, qt-format
316msgid "Enter your %1"
319msgid "Enter your %1"
317msgstr "Enter your %1"
320msgstr "Enter your %1"
318
321
319−#: qml/Shell.qml:274
322+#: qml/Shell.qml:287
320#, qt-format
323#, qt-format
321msgid "Sorry, incorrect %1"
324msgid "Sorry, incorrect %1"
322msgstr "Sorry, incorrect %1"
325msgstr "Sorry, incorrect %1"
323
326
324−#: qml/Shell.qml:310
327+#: qml/Shell.qml:323
325msgid "Sorry, incorrect passphrase."
328msgid "Sorry, incorrect passphrase."
326msgstr "Sorry, incorrect passphrase."
329msgstr "Sorry, incorrect passphrase."
327
330
328−#: qml/Shell.qml:311
331+#: qml/Shell.qml:324
329msgid "Sorry, incorrect passcode."
332msgid "Sorry, incorrect passcode."
330msgstr "Sorry, incorrect passcode."
333msgstr "Sorry, incorrect passcode."
331
334
332−#: qml/Shell.qml:312
335+#: qml/Shell.qml:325
333msgid "This will be your last attempt."
336msgid "This will be your last attempt."
334msgstr "This will be your last attempt."
337msgstr "This will be your last attempt."
335
338
336−#: qml/Shell.qml:314
339+#: qml/Shell.qml:327
337msgid ""
340msgid ""
338"If passphrase is entered incorrectly, your phone will conduct a factory "
341"If passphrase is entered incorrectly, your phone will conduct a factory "
339"reset and all personal data will be deleted."
342"reset and all personal data will be deleted."
@@ -341,19 +344,10 @@ msgstr ""
341"If passphrase is entered incorrectly, your phone will conduct a factory "
344"If passphrase is entered incorrectly, your phone will conduct a factory "
342"reset and all personal data will be deleted."
345"reset and all personal data will be deleted."
343
346
344−#: qml/Shell.qml:315
347+#: qml/Shell.qml:328
345msgid ""
348msgid ""
346"If passcode is entered incorrectly, your phone will conduct a factory reset "
349"If passcode is entered incorrectly, your phone will conduct a factory reset "
347"and all personal data will be deleted."
350"and all personal data will be deleted."
348msgstr ""
351msgstr ""
349"If passcode is entered incorrectly, your phone will conduct a factory reset "
352"If passcode is entered incorrectly, your phone will conduct a factory reset "
350"and all personal data will be deleted."
353"and all personal data will be deleted."
351−
352−#~ msgid "Are you sure you would like to turn power off?"
353−#~ msgstr "Are you sure you would like to turn power off?"
354−
355−#~ msgid "Restart"
356−#~ msgstr "Restart"
357−
358−#~ msgid "Enter your PIN"
359−#~ msgstr "Enter your PIN"
po/es.po+39−45
@@ -8,16 +8,16 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
11−"PO-Revision-Date: 2014-08-27 15:20+0000\n"
11+"PO-Revision-Date: 2014-09-02 08:16+0000\n"
12−"Last-Translator: Leo Arias <leo.arias@canonical.com>\n"
12+"Last-Translator: Víctor R. Ruiz <Unknown>\n"
13"Language-Team: Spanish <es@li.org>\n"
13"Language-Team: Spanish <es@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-08-28 06:30+0000\n"
17+"X-Launchpad-Export-Date: 2014-09-03 07:05+0000\n"
18−"X-Generator: Launchpad (build 17174)\n"
18+"X-Generator: Launchpad (build 17196)\n"
19
19
20−#: plugins/LightDM/Greeter.cpp:129
20+#: plugins/LightDM/Greeter.cpp:130
21msgid "Password: "
21msgid "Password: "
22msgstr "Contraseña: "
22msgstr "Contraseña: "
23
23
@@ -32,53 +32,55 @@ msgstr "Desanclar"
32
32
33#: qml/Components/Dialogs.qml:70
33#: qml/Components/Dialogs.qml:70
34msgid "Log out"
34msgid "Log out"
35−msgstr ""
35+msgstr "Cerrar la sesión"
36
36
37#: qml/Components/Dialogs.qml:71
37#: qml/Components/Dialogs.qml:71
38msgid "Are you sure you want to log out?"
38msgid "Are you sure you want to log out?"
39−msgstr ""
39+msgstr "̉¿Está seguro de que quiere cerrar la sesión?"
40
40
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
42#: qml/Components/Dialogs.qml:122
42#: qml/Components/Dialogs.qml:122
43msgid "No"
43msgid "No"
44−msgstr ""
44+msgstr "No"
45
45
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
47#: qml/Components/Dialogs.qml:129
47#: qml/Components/Dialogs.qml:129
48msgid "Yes"
48msgid "Yes"
49−msgstr ""
49+msgstr "Sí"
50
50
51#: qml/Components/Dialogs.qml:94
51#: qml/Components/Dialogs.qml:94
52msgid "Shut down"
52msgid "Shut down"
53−msgstr ""
53+msgstr "Apagar"
54
54
55#: qml/Components/Dialogs.qml:95
55#: qml/Components/Dialogs.qml:95
56msgid "Are you sure you want to shut down?"
56msgid "Are you sure you want to shut down?"
57−msgstr ""
57+msgstr "¿Está seguro de que quiere apagar?"
58
58
59#: qml/Components/Dialogs.qml:119
59#: qml/Components/Dialogs.qml:119
60msgid "Reboot"
60msgid "Reboot"
61−msgstr ""
61+msgstr "Reiniciar"
62
62
63#: qml/Components/Dialogs.qml:120
63#: qml/Components/Dialogs.qml:120
64msgid "Are you sure you want to reboot?"
64msgid "Are you sure you want to reboot?"
65−msgstr ""
65+msgstr "¿Esta seguro de que quiere reiniciar?"
66
66
67#: qml/Components/Dialogs.qml:144
67#: qml/Components/Dialogs.qml:144
68msgid "Power"
68msgid "Power"
69−msgstr ""
69+msgstr "Encendido"
70
70
71#: qml/Components/Dialogs.qml:145
71#: qml/Components/Dialogs.qml:145
72msgid ""
72msgid ""
73"Are you sure you would like\n"
73"Are you sure you would like\n"
74"to power off?"
74"to power off?"
75msgstr ""
75msgstr ""
76+"¿Está seguro de que quiere\n"
77+"apagar?"
76
78
77−#: qml/Components/Dialogs.qml:144
79+#: qml/Components/Dialogs.qml:147
78msgid "Power off"
80msgid "Power off"
79msgstr "Apagar"
81msgstr "Apagar"
80
82
81−#: qml/Components/Dialogs.qml:162
83+#: qml/Components/Dialogs.qml:157
82msgid "Cancel"
84msgid "Cancel"
83msgstr "Cancelar"
85msgstr "Cancelar"
84
86
@@ -166,21 +168,22 @@ msgstr "Ver menos"
166msgid "See all"
168msgid "See all"
167msgstr "Ver todo"
169msgstr "Ver todo"
168
170
169−#: qml/Dash/GenericScopeView.qml:424 qml/Panel/SearchIndicator.qml:27
171+#: qml/Dash/GenericScopeView.qml:424 qml/Dash/PageHeader.qml:260
172+#: qml/Panel/SearchIndicator.qml:27
170msgid "Search"
173msgid "Search"
171msgstr "Buscar"
174msgstr "Buscar"
172
175
173#: qml/Dash/PageHeader.qml:270
176#: qml/Dash/PageHeader.qml:270
174msgid "Settings"
177msgid "Settings"
175−msgstr ""
178+msgstr "Configuración"
176
179
177#: qml/Dash/PageHeader.qml:279
180#: qml/Dash/PageHeader.qml:279
178msgid "Remove from Favorites"
181msgid "Remove from Favorites"
179−msgstr ""
182+msgstr "Quitar de favoritos"
180
183
181#: qml/Dash/PageHeader.qml:279
184#: qml/Dash/PageHeader.qml:279
182msgid "Add to Favorites"
185msgid "Add to Favorites"
183−msgstr ""
186+msgstr "Añadir a favoritos"
184
187
185#: qml/Dash/Previews/PreviewActionCombo.qml:34
188#: qml/Dash/Previews/PreviewActionCombo.qml:34
186msgid "More..."
189msgid "More..."
@@ -206,11 +209,11 @@ msgstr "Enviar"
206msgid "Manage Dash"
209msgid "Manage Dash"
207msgstr "Gestionar tablero"
210msgstr "Gestionar tablero"
208
211
209−#: qml/Dash/ScopesOverview.qml:408
212+#: qml/Dash/ScopesOverview.qml:417
210msgid "Done"
213msgid "Done"
211msgstr "Hecho"
214msgstr "Hecho"
212
215
213−#: qml/Dash/ScopesOverview.qml:434
216+#: qml/Dash/ScopesOverview.qml:443
214msgid "Store"
217msgid "Store"
215msgstr "Tienda"
218msgstr "Tienda"
216
219
@@ -226,7 +229,7 @@ msgstr "Todo"
226msgid "Swipe to unlock"
229msgid "Swipe to unlock"
227msgstr "Deslice para desbloquear"
230msgstr "Deslice para desbloquear"
228
231
229−#: qml/Hud/HudParametrizedActionsPage.qml:132
232+#: qml/Hud/HudParametrizedActionsPage.qml:139
230msgid "Confirm"
233msgid "Confirm"
231msgstr "Confirmar"
234msgstr "Confirmar"
232
235
@@ -254,7 +257,7 @@ msgstr "Mostrar contraseña"
254msgid "Enter SIM PIN"
257msgid "Enter SIM PIN"
255msgstr "Escriba el PIN de la SIM"
258msgstr "Escriba el PIN de la SIM"
256
259
257−#: qml/Notifications/NotificationMenuItemFactory.qml:121 qml/Shell.qml:270
260+#: qml/Notifications/NotificationMenuItemFactory.qml:121
258msgid "Sorry, incorrect PIN"
261msgid "Sorry, incorrect PIN"
259msgstr "El PIN es incorrecto"
262msgstr "El PIN es incorrecto"
260
263
@@ -298,45 +301,45 @@ msgstr "Desbloquear SIM"
298msgid "Roaming"
301msgid "Roaming"
299msgstr "Itinerancia"
302msgstr "Itinerancia"
300
303
301−#: qml/Shell.qml:266
304+#: qml/Shell.qml:279
302msgid "Enter your passphrase"
305msgid "Enter your passphrase"
303msgstr "Introudzca su contraseña"
306msgstr "Introudzca su contraseña"
304
307
305−#: qml/Shell.qml:267
308+#: qml/Shell.qml:280
306msgid "Sorry, incorrect passphrase"
309msgid "Sorry, incorrect passphrase"
307msgstr "Lo sentimos, contraseña incorrecta"
310msgstr "Lo sentimos, contraseña incorrecta"
308
311
309#: qml/Shell.qml:282
312#: qml/Shell.qml:282
310msgid "Enter your passcode"
313msgid "Enter your passcode"
311−msgstr ""
314+msgstr "Escriba su código de acceso"
312
315
313#: qml/Shell.qml:283
316#: qml/Shell.qml:283
314msgid "Sorry, incorrect passcode"
317msgid "Sorry, incorrect passcode"
315−msgstr ""
318+msgstr "El código de acceso es incorrecto"
316
319
317−#: qml/Shell.qml:273
320+#: qml/Shell.qml:286
318#, qt-format
321#, qt-format
319msgid "Enter your %1"
322msgid "Enter your %1"
320msgstr "Introduzca su %1"
323msgstr "Introduzca su %1"
321
324
322−#: qml/Shell.qml:274
325+#: qml/Shell.qml:287
323#, qt-format
326#, qt-format
324msgid "Sorry, incorrect %1"
327msgid "Sorry, incorrect %1"
325msgstr "Lo sentimos, %1 incorrecto"
328msgstr "Lo sentimos, %1 incorrecto"
326
329
327−#: qml/Shell.qml:310
330+#: qml/Shell.qml:323
328msgid "Sorry, incorrect passphrase."
331msgid "Sorry, incorrect passphrase."
329msgstr "Frase de paso incorrecta"
332msgstr "Frase de paso incorrecta"
330
333
331−#: qml/Shell.qml:311
334+#: qml/Shell.qml:324
332msgid "Sorry, incorrect passcode."
335msgid "Sorry, incorrect passcode."
333−msgstr "Código de paso incorrecto"
336+msgstr "Código de acceso incorrecto."
334
337
335−#: qml/Shell.qml:312
338+#: qml/Shell.qml:325
336msgid "This will be your last attempt."
339msgid "This will be your last attempt."
337msgstr "Este será su último intento."
340msgstr "Este será su último intento."
338
341
339−#: qml/Shell.qml:314
342+#: qml/Shell.qml:327
340msgid ""
343msgid ""
341"If passphrase is entered incorrectly, your phone will conduct a factory "
344"If passphrase is entered incorrectly, your phone will conduct a factory "
342"reset and all personal data will be deleted."
345"reset and all personal data will be deleted."
@@ -344,19 +347,10 @@ msgstr ""
344"Si se introduce la frase incorrectamente, el teléfono volverá a la "
347"Si se introduce la frase incorrectamente, el teléfono volverá a la "
345"configuración de fábrica y se perderán todos los datos personales."
348"configuración de fábrica y se perderán todos los datos personales."
346
349
347−#: qml/Shell.qml:315
350+#: qml/Shell.qml:328
348msgid ""
351msgid ""
349"If passcode is entered incorrectly, your phone will conduct a factory reset "
352"If passcode is entered incorrectly, your phone will conduct a factory reset "
350"and all personal data will be deleted."
353"and all personal data will be deleted."
351msgstr ""
354msgstr ""
352"Si se introduce el código incorrectamente, el teléfono volverá a la "
355"Si se introduce el código incorrectamente, el teléfono volverá a la "
353"configuración de fábrica y se perderán todos los datos personales."
356"configuración de fábrica y se perderán todos los datos personales."
354−
355−#~ msgid "Restart"
356−#~ msgstr "Reiniciar"
357−
358−#~ msgid "Are you sure you would like to turn power off?"
359−#~ msgstr "¿Está seguro de que quiere apagarlo?"
360−
361−#~ msgid "Enter your PIN"
362−#~ msgstr "Escriba el PIN"
po/eu.po+61−56
@@ -8,18 +8,18 @@ msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
11−"PO-Revision-Date: 2014-08-06 22:51+0000\n"
11+"PO-Revision-Date: 2014-09-02 20:34+0000\n"
12"Last-Translator: Ibai Oihanguren Sala <Unknown>\n"
12"Last-Translator: Ibai Oihanguren Sala <Unknown>\n"
13"Language-Team: Basque <eu@li.org>\n"
13"Language-Team: Basque <eu@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-08-28 06:29+0000\n"
17+"X-Launchpad-Export-Date: 2014-09-03 07:05+0000\n"
18−"X-Generator: Launchpad (build 17174)\n"
18+"X-Generator: Launchpad (build 17196)\n"
19
19
20−#: plugins/LightDM/Greeter.cpp:129
20+#: plugins/LightDM/Greeter.cpp:130
21msgid "Password: "
21msgid "Password: "
22−msgstr ""
22+msgstr "Pasahitza: "
23
23
24#: plugins/Unity/Launcher/launcheritem.cpp:43
24#: plugins/Unity/Launcher/launcheritem.cpp:43
25#: plugins/Unity/Launcher/launcheritem.cpp:73
25#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -32,55 +32,55 @@ msgstr "Askatu lasterbidea"
32
32
33#: qml/Components/Dialogs.qml:70
33#: qml/Components/Dialogs.qml:70
34msgid "Log out"
34msgid "Log out"
35−msgstr ""
35+msgstr "Amaitu saioa"
36
36
37#: qml/Components/Dialogs.qml:71
37#: qml/Components/Dialogs.qml:71
38msgid "Are you sure you want to log out?"
38msgid "Are you sure you want to log out?"
39−msgstr ""
39+msgstr "Ziur saioa amaitu nahi duzula?"
40
40
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
42#: qml/Components/Dialogs.qml:122
42#: qml/Components/Dialogs.qml:122
43msgid "No"
43msgid "No"
44−msgstr ""
44+msgstr "Ez"
45
45
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
47#: qml/Components/Dialogs.qml:129
47#: qml/Components/Dialogs.qml:129
48msgid "Yes"
48msgid "Yes"
49−msgstr ""
49+msgstr "Bai"
50
50
51#: qml/Components/Dialogs.qml:94
51#: qml/Components/Dialogs.qml:94
52msgid "Shut down"
52msgid "Shut down"
53−msgstr ""
53+msgstr "Itzali"
54
54
55#: qml/Components/Dialogs.qml:95
55#: qml/Components/Dialogs.qml:95
56msgid "Are you sure you want to shut down?"
56msgid "Are you sure you want to shut down?"
57−msgstr ""
57+msgstr "Ziur itzali nahi duzula?"
58
58
59#: qml/Components/Dialogs.qml:119
59#: qml/Components/Dialogs.qml:119
60msgid "Reboot"
60msgid "Reboot"
61−msgstr ""
61+msgstr "Berrabiarazi"
62
62
63#: qml/Components/Dialogs.qml:120
63#: qml/Components/Dialogs.qml:120
64msgid "Are you sure you want to reboot?"
64msgid "Are you sure you want to reboot?"
65−msgstr ""
65+msgstr "Ziur berrabiarazi nahi duzula?"
66
66
67#: qml/Components/Dialogs.qml:144
67#: qml/Components/Dialogs.qml:144
68msgid "Power"
68msgid "Power"
69−msgstr ""
69+msgstr "Energia"
70
70
71#: qml/Components/Dialogs.qml:145
71#: qml/Components/Dialogs.qml:145
72msgid ""
72msgid ""
73"Are you sure you would like\n"
73"Are you sure you would like\n"
74"to power off?"
74"to power off?"
75−msgstr ""
75+msgstr "Ziur itzali nahi duzula?"
76
76
77−#: qml/Components/Dialogs.qml:144
77+#: qml/Components/Dialogs.qml:147
78msgid "Power off"
78msgid "Power off"
79−msgstr ""
79+msgstr "Itzali"
80
80
81−#: qml/Components/Dialogs.qml:162
81+#: qml/Components/Dialogs.qml:157
82msgid "Cancel"
82msgid "Cancel"
83−msgstr ""
83+msgstr "Utzi"
84
84
85#: qml/Components/EdgeDemoOverlay.qml:151
85#: qml/Components/EdgeDemoOverlay.qml:151
86msgid "Skip intro"
86msgid "Skip intro"
@@ -135,11 +135,11 @@ msgstr ""
135
135
136#: qml/Components/Lockscreen.qml:167
136#: qml/Components/Lockscreen.qml:167
137msgid "Please wait"
137msgid "Please wait"
138−msgstr ""
138+msgstr "Itxaron"
139
139
140#: qml/Components/Lockscreen.qml:172
140#: qml/Components/Lockscreen.qml:172
141msgid "Too many incorrect attempts"
141msgid "Too many incorrect attempts"
142−msgstr ""
142+msgstr "Okerreko saiakera gehiegi"
143
143
144#: qml/Components/Lockscreen.qml:206
144#: qml/Components/Lockscreen.qml:206
145msgid "Emergency Call"
145msgid "Emergency Call"
@@ -166,21 +166,22 @@ msgstr "Ikusi gutxiago"
166msgid "See all"
166msgid "See all"
167msgstr "Ikusi guztiak"
167msgstr "Ikusi guztiak"
168
168
169−#: qml/Dash/GenericScopeView.qml:424 qml/Panel/SearchIndicator.qml:27
169+#: qml/Dash/GenericScopeView.qml:424 qml/Dash/PageHeader.qml:260
170+#: qml/Panel/SearchIndicator.qml:27
170msgid "Search"
171msgid "Search"
171msgstr "Bilatu"
172msgstr "Bilatu"
172
173
173#: qml/Dash/PageHeader.qml:270
174#: qml/Dash/PageHeader.qml:270
174msgid "Settings"
175msgid "Settings"
175−msgstr ""
176+msgstr "Ezarpenak"
176
177
177#: qml/Dash/PageHeader.qml:279
178#: qml/Dash/PageHeader.qml:279
178msgid "Remove from Favorites"
179msgid "Remove from Favorites"
179−msgstr ""
180+msgstr "Kendu gogokoetatik"
180
181
181#: qml/Dash/PageHeader.qml:279
182#: qml/Dash/PageHeader.qml:279
182msgid "Add to Favorites"
183msgid "Add to Favorites"
183−msgstr ""
184+msgstr "Gehitu gogokoetara"
184
185
185#: qml/Dash/Previews/PreviewActionCombo.qml:34
186#: qml/Dash/Previews/PreviewActionCombo.qml:34
186msgid "More..."
187msgid "More..."
@@ -204,29 +205,29 @@ msgstr "Bidali"
204
205
205#: qml/Dash/ScopesOverview.qml:201
206#: qml/Dash/ScopesOverview.qml:201
206msgid "Manage Dash"
207msgid "Manage Dash"
207−msgstr ""
208+msgstr "Kudeatu abio-leihoa"
208
209
209−#: qml/Dash/ScopesOverview.qml:408
210+#: qml/Dash/ScopesOverview.qml:417
210msgid "Done"
211msgid "Done"
211−msgstr ""
212+msgstr "Eginda"
212
213
213−#: qml/Dash/ScopesOverview.qml:434
214+#: qml/Dash/ScopesOverview.qml:443
214msgid "Store"
215msgid "Store"
215−msgstr ""
216+msgstr "Denda"
216
217
217#: qml/Dash/ScopesOverviewTab.qml:36
218#: qml/Dash/ScopesOverviewTab.qml:36
218msgid "Favorites"
219msgid "Favorites"
219−msgstr ""
220+msgstr "Gogokoak"
220
221
221#: qml/Dash/ScopesOverviewTab.qml:54
222#: qml/Dash/ScopesOverviewTab.qml:54
222msgid "All"
223msgid "All"
223−msgstr ""
224+msgstr "Guztiak"
224
225
225#: qml/Greeter/Greeter.qml:157
226#: qml/Greeter/Greeter.qml:157
226msgid "Swipe to unlock"
227msgid "Swipe to unlock"
227msgstr "Pasatu hatza desblokeatzeko"
228msgstr "Pasatu hatza desblokeatzeko"
228
229
229−#: qml/Hud/HudParametrizedActionsPage.qml:132
230+#: qml/Hud/HudParametrizedActionsPage.qml:139
230msgid "Confirm"
231msgid "Confirm"
231msgstr "Baieztatu"
232msgstr "Baieztatu"
232
233
@@ -252,11 +253,11 @@ msgstr "Erakutsi pasahitza"
252
253
253#: qml/Notifications/NotificationMenuItemFactory.qml:120
254#: qml/Notifications/NotificationMenuItemFactory.qml:120
254msgid "Enter SIM PIN"
255msgid "Enter SIM PIN"
255−msgstr ""
256+msgstr "Sartu SIM PINa"
256
257
257−#: qml/Notifications/NotificationMenuItemFactory.qml:121 qml/Shell.qml:270
258+#: qml/Notifications/NotificationMenuItemFactory.qml:121
258msgid "Sorry, incorrect PIN"
259msgid "Sorry, incorrect PIN"
259−msgstr ""
260+msgstr "Sentitzen dugu, PINa okerrekoa da"
260
261
261#: qml/Panel/ActiveCallHint.qml:77
262#: qml/Panel/ActiveCallHint.qml:77
262msgid "Tap to return to call..."
263msgid "Tap to return to call..."
@@ -292,58 +293,62 @@ msgstr "Huts egin du, sakatu berriro saiatzeko"
292
293
293#: qml/Panel/Indicators/ModemInfoItem.qml:105
294#: qml/Panel/Indicators/ModemInfoItem.qml:105
294msgid "Unlock SIM"
295msgid "Unlock SIM"
295−msgstr ""
296+msgstr "Desblokeatu SIMa"
296
297
297#: qml/Panel/Indicators/RoamingIndication.qml:27
298#: qml/Panel/Indicators/RoamingIndication.qml:27
298msgid "Roaming"
299msgid "Roaming"
299−msgstr ""
300+msgstr "Ibiltaritza"
300
301
301−#: qml/Shell.qml:266
302+#: qml/Shell.qml:279
302msgid "Enter your passphrase"
303msgid "Enter your passphrase"
303−msgstr ""
304+msgstr "Sartu pasaesaldia"
304
305
305−#: qml/Shell.qml:267
306+#: qml/Shell.qml:280
306msgid "Sorry, incorrect passphrase"
307msgid "Sorry, incorrect passphrase"
307−msgstr ""
308+msgstr "Sentitzen dugu, pasaesaldia okerrekoa da"
308
309
309#: qml/Shell.qml:282
310#: qml/Shell.qml:282
310msgid "Enter your passcode"
311msgid "Enter your passcode"
311−msgstr ""
312+msgstr "Sartu pasakodea"
312
313
313#: qml/Shell.qml:283
314#: qml/Shell.qml:283
314msgid "Sorry, incorrect passcode"
315msgid "Sorry, incorrect passcode"
315−msgstr ""
316+msgstr "Sentitzen dugu, pasakodea okerrekoa da"
316
317
317−#: qml/Shell.qml:273
318+#: qml/Shell.qml:286
318#, qt-format
319#, qt-format
319msgid "Enter your %1"
320msgid "Enter your %1"
320−msgstr ""
321+msgstr "Sartu %1"
321
322
322−#: qml/Shell.qml:274
323+#: qml/Shell.qml:287
323#, qt-format
324#, qt-format
324msgid "Sorry, incorrect %1"
325msgid "Sorry, incorrect %1"
325−msgstr ""
326+msgstr "Sentitzen dugu, %1 okerrekoa da"
326
327
327−#: qml/Shell.qml:310
328+#: qml/Shell.qml:323
328msgid "Sorry, incorrect passphrase."
329msgid "Sorry, incorrect passphrase."
329−msgstr ""
330+msgstr "Sentitzen dugu, pasaesaldia okerrekoa da."
330
331
331−#: qml/Shell.qml:311
332+#: qml/Shell.qml:324
332msgid "Sorry, incorrect passcode."
333msgid "Sorry, incorrect passcode."
333−msgstr ""
334+msgstr "Sentitzen dugu, pasakodea okerrekoa da."
334
335
335−#: qml/Shell.qml:312
336+#: qml/Shell.qml:325
336msgid "This will be your last attempt."
337msgid "This will be your last attempt."
337−msgstr ""
338+msgstr "Hau duzu azken saiakera."
338
339
339−#: qml/Shell.qml:314
340+#: qml/Shell.qml:327
340msgid ""
341msgid ""
341"If passphrase is entered incorrectly, your phone will conduct a factory "
342"If passphrase is entered incorrectly, your phone will conduct a factory "
342"reset and all personal data will be deleted."
343"reset and all personal data will be deleted."
343msgstr ""
344msgstr ""
345+"Okerreko pasaesaldia sartzen baduzu, telefonoaren jatorrizko ezarpenak "
346+"berrezarri eta datu pertsonal guztiak ezabatuko dira."
344
347
345−#: qml/Shell.qml:315
348+#: qml/Shell.qml:328
346msgid ""
349msgid ""
347"If passcode is entered incorrectly, your phone will conduct a factory reset "
350"If passcode is entered incorrectly, your phone will conduct a factory reset "
348"and all personal data will be deleted."
351"and all personal data will be deleted."
349msgstr ""
352msgstr ""
353+"Okerreko pasakodea sartzen baduzu, telefonoaren jatorrizko ezarpenak "
354+"berrezarri eta datu pertsonal guztiak ezabatuko dira."
po/ja.po+37−42
@@ -8,16 +8,16 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
11−"PO-Revision-Date: 2014-08-18 15:03+0000\n"
11+"PO-Revision-Date: 2014-09-01 06:20+0000\n"
12"Last-Translator: Mitsuya Shibata <mty.shibata@gmail.com>\n"
12"Last-Translator: Mitsuya Shibata <mty.shibata@gmail.com>\n"
13"Language-Team: Japanese <ja@li.org>\n"
13"Language-Team: Japanese <ja@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-08-28 06:30+0000\n"
17+"X-Launchpad-Export-Date: 2014-09-02 07:20+0000\n"
18−"X-Generator: Launchpad (build 17174)\n"
18+"X-Generator: Launchpad (build 17192)\n"
19
19
20−#: plugins/LightDM/Greeter.cpp:129
20+#: plugins/LightDM/Greeter.cpp:130
21msgid "Password: "
21msgid "Password: "
22msgstr "パスワード: "
22msgstr "パスワード: "
23
23
@@ -32,7 +32,7 @@ msgstr "ショートカットを削除する"
32
32
33#: qml/Components/Dialogs.qml:70
33#: qml/Components/Dialogs.qml:70
34msgid "Log out"
34msgid "Log out"
35−msgstr ""
35+msgstr "ログアウト"
36
36
37#: qml/Components/Dialogs.qml:71
37#: qml/Components/Dialogs.qml:71
38msgid "Are you sure you want to log out?"
38msgid "Are you sure you want to log out?"
@@ -41,16 +41,16 @@ msgstr ""
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
41#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
42#: qml/Components/Dialogs.qml:122
42#: qml/Components/Dialogs.qml:122
43msgid "No"
43msgid "No"
44−msgstr ""
44+msgstr "いいえ"
45
45
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
46#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
47#: qml/Components/Dialogs.qml:129
47#: qml/Components/Dialogs.qml:129
48msgid "Yes"
48msgid "Yes"
49−msgstr ""
49+msgstr "はい"
50
50
51#: qml/Components/Dialogs.qml:94
51#: qml/Components/Dialogs.qml:94
52msgid "Shut down"
52msgid "Shut down"
53−msgstr ""
53+msgstr "シャットダウン"
54
54
55#: qml/Components/Dialogs.qml:95
55#: qml/Components/Dialogs.qml:95
56msgid "Are you sure you want to shut down?"
56msgid "Are you sure you want to shut down?"
@@ -58,7 +58,7 @@ msgstr ""
58
58
59#: qml/Components/Dialogs.qml:119
59#: qml/Components/Dialogs.qml:119
60msgid "Reboot"
60msgid "Reboot"
61−msgstr ""
61+msgstr "再起動"
62
62
63#: qml/Components/Dialogs.qml:120
63#: qml/Components/Dialogs.qml:120
64msgid "Are you sure you want to reboot?"
64msgid "Are you sure you want to reboot?"
@@ -74,11 +74,11 @@ msgid ""
74"to power off?"
74"to power off?"
75msgstr ""
75msgstr ""
76
76
77−#: qml/Components/Dialogs.qml:144
77+#: qml/Components/Dialogs.qml:147
78msgid "Power off"
78msgid "Power off"
79msgstr "電源を切る"
79msgstr "電源を切る"
80
80
81−#: qml/Components/Dialogs.qml:162
81+#: qml/Components/Dialogs.qml:157
82msgid "Cancel"
82msgid "Cancel"
83msgstr "キャンセル"
83msgstr "キャンセル"
84
84
@@ -156,27 +156,28 @@ msgstr "こんにちは"
156
156
157#: qml/Dash/GenericScopeView.qml:361
157#: qml/Dash/GenericScopeView.qml:361
158msgid "See less"
158msgid "See less"
159−msgstr ""
159+msgstr "隠す"
160
160
161#: qml/Dash/GenericScopeView.qml:361
161#: qml/Dash/GenericScopeView.qml:361
162msgid "See all"
162msgid "See all"
163msgstr "すべて表示する"
163msgstr "すべて表示する"
164
164
165−#: qml/Dash/GenericScopeView.qml:424 qml/Panel/SearchIndicator.qml:27
165+#: qml/Dash/GenericScopeView.qml:424 qml/Dash/PageHeader.qml:260
166+#: qml/Panel/SearchIndicator.qml:27
166msgid "Search"
167msgid "Search"
167msgstr "検索"
168msgstr "検索"
168
169
169#: qml/Dash/PageHeader.qml:270
170#: qml/Dash/PageHeader.qml:270
170msgid "Settings"
171msgid "Settings"
171−msgstr ""
172+msgstr "設定"
172
173
173#: qml/Dash/PageHeader.qml:279
174#: qml/Dash/PageHeader.qml:279
174msgid "Remove from Favorites"
175msgid "Remove from Favorites"
175−msgstr ""
176+msgstr "お気に入りから削除する"
176
177
177#: qml/Dash/PageHeader.qml:279
178#: qml/Dash/PageHeader.qml:279
178msgid "Add to Favorites"
179msgid "Add to Favorites"
179−msgstr ""
180+msgstr "お気に入りに追加する"
180
181
181#: qml/Dash/Previews/PreviewActionCombo.qml:34
182#: qml/Dash/Previews/PreviewActionCombo.qml:34
182msgid "More..."
183msgid "More..."
@@ -202,11 +203,11 @@ msgstr "送信"
202msgid "Manage Dash"
203msgid "Manage Dash"
203msgstr "Dashの管理"
204msgstr "Dashの管理"
204
205
205−#: qml/Dash/ScopesOverview.qml:408
206+#: qml/Dash/ScopesOverview.qml:417
206msgid "Done"
207msgid "Done"
207msgstr "完了"
208msgstr "完了"
208
209
209−#: qml/Dash/ScopesOverview.qml:434
210+#: qml/Dash/ScopesOverview.qml:443
210msgid "Store"
211msgid "Store"
211msgstr "保存"
212msgstr "保存"
212
213
@@ -222,7 +223,7 @@ msgstr "すべて"
222msgid "Swipe to unlock"
223msgid "Swipe to unlock"
223msgstr "スワイプしてロック解除"
224msgstr "スワイプしてロック解除"
224
225
225−#: qml/Hud/HudParametrizedActionsPage.qml:132
226+#: qml/Hud/HudParametrizedActionsPage.qml:139
226msgid "Confirm"
227msgid "Confirm"
227msgstr "確認"
228msgstr "確認"
228
229
@@ -250,7 +251,7 @@ msgstr "パスワードを表示"
250msgid "Enter SIM PIN"
251msgid "Enter SIM PIN"
251msgstr ""
252msgstr ""
252
253
253−#: qml/Notifications/NotificationMenuItemFactory.qml:121 qml/Shell.qml:270
254+#: qml/Notifications/NotificationMenuItemFactory.qml:121
254msgid "Sorry, incorrect PIN"
255msgid "Sorry, incorrect PIN"
255msgstr ""
256msgstr ""
256
257
@@ -260,11 +261,11 @@ msgstr "タップすると通話に戻ります..."
260
261
261#: qml/Panel/ActiveCallHint.qml:90
262#: qml/Panel/ActiveCallHint.qml:90
262msgid "Conference"
263msgid "Conference"
263−msgstr ""
264+msgstr "グループ通話"
264
265
265#: qml/Panel/Indicators/MenuItemFactory.qml:651
266#: qml/Panel/Indicators/MenuItemFactory.qml:651
266msgid "In queue…"
267msgid "In queue…"
267−msgstr ""
268+msgstr "開始待ち..."
268
269
269#: qml/Panel/Indicators/MenuItemFactory.qml:655
270#: qml/Panel/Indicators/MenuItemFactory.qml:655
270msgid "Downloading"
271msgid "Downloading"
@@ -276,11 +277,11 @@ msgstr "停止中、再開するにはタップしてください"
276
277
277#: qml/Panel/Indicators/MenuItemFactory.qml:659
278#: qml/Panel/Indicators/MenuItemFactory.qml:659
278msgid "Canceled"
279msgid "Canceled"
279−msgstr ""
280+msgstr "中止しました"
280
281
281#: qml/Panel/Indicators/MenuItemFactory.qml:661
282#: qml/Panel/Indicators/MenuItemFactory.qml:661
282msgid "Finished"
283msgid "Finished"
283−msgstr ""
284+msgstr "完了しました"
284
285
285#: qml/Panel/Indicators/MenuItemFactory.qml:663
286#: qml/Panel/Indicators/MenuItemFactory.qml:663
286msgid "Failed, tap to retry"
287msgid "Failed, tap to retry"
@@ -294,11 +295,11 @@ msgstr "SIMのアンロック"
294msgid "Roaming"
295msgid "Roaming"
295msgstr "ローミング"
296msgstr "ローミング"
296
297
297−#: qml/Shell.qml:266
298+#: qml/Shell.qml:279
298msgid "Enter your passphrase"
299msgid "Enter your passphrase"
299msgstr ""
300msgstr ""
300
301
301−#: qml/Shell.qml:267
302+#: qml/Shell.qml:280
302msgid "Sorry, incorrect passphrase"
303msgid "Sorry, incorrect passphrase"
303msgstr ""
304msgstr ""
304
305
@@ -308,44 +309,38 @@ msgstr ""
308
309
309#: qml/Shell.qml:283
310#: qml/Shell.qml:283
310msgid "Sorry, incorrect passcode"
311msgid "Sorry, incorrect passcode"
311−msgstr ""
312+msgstr "ごめんなさい、誤ったパスコードです"
312
313
313−#: qml/Shell.qml:273
314+#: qml/Shell.qml:286
314#, qt-format
315#, qt-format
315msgid "Enter your %1"
316msgid "Enter your %1"
316msgstr "%1を入力してください"
317msgstr "%1を入力してください"
317
318
318−#: qml/Shell.qml:274
319+#: qml/Shell.qml:287
319#, qt-format
320#, qt-format
320msgid "Sorry, incorrect %1"
321msgid "Sorry, incorrect %1"
321msgstr ""
322msgstr ""
322
323
323−#: qml/Shell.qml:310
324+#: qml/Shell.qml:323
324msgid "Sorry, incorrect passphrase."
325msgid "Sorry, incorrect passphrase."
325msgstr "パスフレーズが間違っています。"
326msgstr "パスフレーズが間違っています。"
326
327
327−#: qml/Shell.qml:311
328+#: qml/Shell.qml:324
328msgid "Sorry, incorrect passcode."
329msgid "Sorry, incorrect passcode."
329msgstr "パスコードが間違っています。"
330msgstr "パスコードが間違っています。"
330
331
331−#: qml/Shell.qml:312
332+#: qml/Shell.qml:325
332msgid "This will be your last attempt."
333msgid "This will be your last attempt."
333msgstr "これが最後のチャンスです。"
334msgstr "これが最後のチャンスです。"
334
335
335−#: qml/Shell.qml:314
336+#: qml/Shell.qml:327
336msgid ""
337msgid ""
337"If passphrase is entered incorrectly, your phone will conduct a factory "
338"If passphrase is entered incorrectly, your phone will conduct a factory "
338"reset and all personal data will be deleted."
339"reset and all personal data will be deleted."
339−msgstr ""
340+msgstr "パスフレーズが間違っている場合、ファクトリーリセットを実施し、すべての個人データは削除されます。"
340
341
341−#: qml/Shell.qml:315
342+#: qml/Shell.qml:328
342msgid ""
343msgid ""
343"If passcode is entered incorrectly, your phone will conduct a factory reset "
344"If passcode is entered incorrectly, your phone will conduct a factory reset "
344"and all personal data will be deleted."
345"and all personal data will be deleted."
345−msgstr ""
346+msgstr "パスコードが間違っている場合、ファクトリーリセットを実施し、すべての個人データは削除されます。"
346−
347−#~ msgid "Are you sure you would like to turn power off?"
348−#~ msgstr "本当に電源を切りますか?"
349−
350−#~ msgid "Restart"
351−#~ msgstr "再起動"
po/ro.po+7−7
@@ -8,13 +8,13 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
11−"PO-Revision-Date: 2014-08-29 17:49+0000\n"
11+"PO-Revision-Date: 2014-08-31 09:24+0000\n"
12"Last-Translator: Meriuță Cornel <meriutacornel@neacornel.eu>\n"
12"Last-Translator: Meriuță Cornel <meriutacornel@neacornel.eu>\n"
13"Language-Team: Romanian <ro@li.org>\n"
13"Language-Team: Romanian <ro@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-08-30 07:46+0000\n"
17+"X-Launchpad-Export-Date: 2014-09-01 07:33+0000\n"
18"X-Generator: Launchpad (build 17176)\n"
18"X-Generator: Launchpad (build 17176)\n"
19
19
20#: plugins/LightDM/Greeter.cpp:130
20#: plugins/LightDM/Greeter.cpp:130
@@ -259,7 +259,7 @@ msgstr "Introduceți codul PIN pentru SIM"
259
259
260#: qml/Notifications/NotificationMenuItemFactory.qml:121
260#: qml/Notifications/NotificationMenuItemFactory.qml:121
261msgid "Sorry, incorrect PIN"
261msgid "Sorry, incorrect PIN"
262−msgstr ""
262+msgstr "Cod PIN incorect"
263
263
264#: qml/Panel/ActiveCallHint.qml:77
264#: qml/Panel/ActiveCallHint.qml:77
265msgid "Tap to return to call..."
265msgid "Tap to return to call..."
@@ -307,15 +307,15 @@ msgstr "Introduceți fraza dumneavoastră secretă"
307
307
308#: qml/Shell.qml:280
308#: qml/Shell.qml:280
309msgid "Sorry, incorrect passphrase"
309msgid "Sorry, incorrect passphrase"
310−msgstr ""
310+msgstr "Frază secretă incorectă"
311
311
312#: qml/Shell.qml:282
312#: qml/Shell.qml:282
313msgid "Enter your passcode"
313msgid "Enter your passcode"
314−msgstr ""
314+msgstr "Introduceți parola"
315
315
316#: qml/Shell.qml:283
316#: qml/Shell.qml:283
317msgid "Sorry, incorrect passcode"
317msgid "Sorry, incorrect passcode"
318−msgstr ""
318+msgstr "Parolă incorectă"
319
319
320#: qml/Shell.qml:286
320#: qml/Shell.qml:286
321#, qt-format
321#, qt-format
@@ -325,7 +325,7 @@ msgstr "Introduceți %1"
325#: qml/Shell.qml:287
325#: qml/Shell.qml:287
326#, qt-format
326#, qt-format
327msgid "Sorry, incorrect %1"
327msgid "Sorry, incorrect %1"
328−msgstr ""
328+msgstr "%1 incorectă"
329
329
330#: qml/Shell.qml:323
330#: qml/Shell.qml:323
331msgid "Sorry, incorrect passphrase."
331msgid "Sorry, incorrect passphrase."
po/sv.po+56−52
@@ -8,17 +8,17 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
10"POT-Creation-Date: 2014-08-26 18:24+0200\n"
11−"PO-Revision-Date: 2014-08-14 18:22+0000\n"
11+"PO-Revision-Date: 2014-09-08 15:57+0000\n"
12−"Last-Translator: Erik Simmesgård <Unknown>\n"
12+"Last-Translator: Josef Andersson <Unknown>\n"
13"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
13"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-08-28 06:30+0000\n"
17+"X-Launchpad-Export-Date: 2014-09-10 08:02+0000\n"
18−"X-Generator: Launchpad (build 17174)\n"
18+"X-Generator: Launchpad (build 17196)\n"
19"Language: sv\n"
19"Language: sv\n"
20
20
21−#: plugins/LightDM/Greeter.cpp:129
21+#: plugins/LightDM/Greeter.cpp:130
22msgid "Password: "
22msgid "Password: "
23msgstr "Lösenord: "
23msgstr "Lösenord: "
24
24
@@ -33,53 +33,55 @@ msgstr "Släpp genväg"
33
33
34#: qml/Components/Dialogs.qml:70
34#: qml/Components/Dialogs.qml:70
35msgid "Log out"
35msgid "Log out"
36−msgstr ""
36+msgstr "Logga ut"
37
37
38#: qml/Components/Dialogs.qml:71
38#: qml/Components/Dialogs.qml:71
39msgid "Are you sure you want to log out?"
39msgid "Are you sure you want to log out?"
40−msgstr ""
40+msgstr "Är du säker på att du vill logga ut?"
41
41
42#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
42#: qml/Components/Dialogs.qml:73 qml/Components/Dialogs.qml:97
43#: qml/Components/Dialogs.qml:122
43#: qml/Components/Dialogs.qml:122
44msgid "No"
44msgid "No"
45−msgstr ""
45+msgstr "Nej"
46
46
47#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
47#: qml/Components/Dialogs.qml:80 qml/Components/Dialogs.qml:104
48#: qml/Components/Dialogs.qml:129
48#: qml/Components/Dialogs.qml:129
49msgid "Yes"
49msgid "Yes"
50−msgstr ""
50+msgstr "Ja"
51
51
52#: qml/Components/Dialogs.qml:94
52#: qml/Components/Dialogs.qml:94
53msgid "Shut down"
53msgid "Shut down"
54−msgstr ""
54+msgstr "Stäng av"
55
55
56#: qml/Components/Dialogs.qml:95
56#: qml/Components/Dialogs.qml:95
57msgid "Are you sure you want to shut down?"
57msgid "Are you sure you want to shut down?"
58−msgstr ""
58+msgstr "Är du säker på att du vill stänga av?"
59
59
60#: qml/Components/Dialogs.qml:119
60#: qml/Components/Dialogs.qml:119
61msgid "Reboot"
61msgid "Reboot"
62−msgstr ""
62+msgstr "Starta om"
63
63
64#: qml/Components/Dialogs.qml:120
64#: qml/Components/Dialogs.qml:120
65msgid "Are you sure you want to reboot?"
65msgid "Are you sure you want to reboot?"
66−msgstr ""
66+msgstr "Är du säker på att du vill starta om?"
67
67
68#: qml/Components/Dialogs.qml:144
68#: qml/Components/Dialogs.qml:144
69msgid "Power"
69msgid "Power"
70−msgstr ""
70+msgstr "Ström"
71
71
72#: qml/Components/Dialogs.qml:145
72#: qml/Components/Dialogs.qml:145
73msgid ""
73msgid ""
74"Are you sure you would like\n"
74"Are you sure you would like\n"
75"to power off?"
75"to power off?"
76msgstr ""
76msgstr ""
77+"Är du säker på att du vill \n"
78+"stänga av?"
77
79
78−#: qml/Components/Dialogs.qml:144
80+#: qml/Components/Dialogs.qml:147
79msgid "Power off"
81msgid "Power off"
80−msgstr ""
82+msgstr "Stäng av"
81
83
82−#: qml/Components/Dialogs.qml:162
84+#: qml/Components/Dialogs.qml:157
83msgid "Cancel"
85msgid "Cancel"
84msgstr "Avbryt"
86msgstr "Avbryt"
85
87
@@ -137,7 +139,7 @@ msgstr "Var god vänta"
137
139
138#: qml/Components/Lockscreen.qml:172
140#: qml/Components/Lockscreen.qml:172
139msgid "Too many incorrect attempts"
141msgid "Too many incorrect attempts"
140−msgstr ""
142+msgstr "För många felaktiga försök"
141
143
142#: qml/Components/Lockscreen.qml:206
144#: qml/Components/Lockscreen.qml:206
143msgid "Emergency Call"
145msgid "Emergency Call"
@@ -164,21 +166,22 @@ msgstr "Visa mindre"
164msgid "See all"
166msgid "See all"
165msgstr "Visa alla"
167msgstr "Visa alla"
166
168
167−#: qml/Dash/GenericScopeView.qml:424 qml/Panel/SearchIndicator.qml:27
169+#: qml/Dash/GenericScopeView.qml:424 qml/Dash/PageHeader.qml:260
170+#: qml/Panel/SearchIndicator.qml:27
168msgid "Search"
171msgid "Search"
169msgstr "Sök"
172msgstr "Sök"
170
173
171#: qml/Dash/PageHeader.qml:270
174#: qml/Dash/PageHeader.qml:270
172msgid "Settings"
175msgid "Settings"
173−msgstr ""
176+msgstr "Inställningar"
174
177
175#: qml/Dash/PageHeader.qml:279
178#: qml/Dash/PageHeader.qml:279
176msgid "Remove from Favorites"
179msgid "Remove from Favorites"
177−msgstr ""
180+msgstr "Ta bort från Favoriter"
178
181
179#: qml/Dash/PageHeader.qml:279
182#: qml/Dash/PageHeader.qml:279
180msgid "Add to Favorites"
183msgid "Add to Favorites"
181−msgstr ""
184+msgstr "Lägg till Favoriter"
182
185
183#: qml/Dash/Previews/PreviewActionCombo.qml:34
186#: qml/Dash/Previews/PreviewActionCombo.qml:34
184msgid "More..."
187msgid "More..."
@@ -202,15 +205,15 @@ msgstr "Skicka"
202
205
203#: qml/Dash/ScopesOverview.qml:201
206#: qml/Dash/ScopesOverview.qml:201
204msgid "Manage Dash"
207msgid "Manage Dash"
205−msgstr ""
208+msgstr "Hantera Dash"
206
209
207−#: qml/Dash/ScopesOverview.qml:408
210+#: qml/Dash/ScopesOverview.qml:417
208msgid "Done"
211msgid "Done"
209−msgstr ""
212+msgstr "Klar"
210
213
211−#: qml/Dash/ScopesOverview.qml:434
214+#: qml/Dash/ScopesOverview.qml:443
212msgid "Store"
215msgid "Store"
213−msgstr ""
216+msgstr "Butik"
214
217
215#: qml/Dash/ScopesOverviewTab.qml:36
218#: qml/Dash/ScopesOverviewTab.qml:36
216msgid "Favorites"
219msgid "Favorites"
@@ -218,13 +221,13 @@ msgstr "Favoriter"
218
221
219#: qml/Dash/ScopesOverviewTab.qml:54
222#: qml/Dash/ScopesOverviewTab.qml:54
220msgid "All"
223msgid "All"
221−msgstr ""
224+msgstr "Alla"
222
225
223#: qml/Greeter/Greeter.qml:157
226#: qml/Greeter/Greeter.qml:157
224msgid "Swipe to unlock"
227msgid "Swipe to unlock"
225msgstr "Svep för att låsa upp"
228msgstr "Svep för att låsa upp"
226
229
227−#: qml/Hud/HudParametrizedActionsPage.qml:132
230+#: qml/Hud/HudParametrizedActionsPage.qml:139
228msgid "Confirm"
231msgid "Confirm"
229msgstr "Bekräfta"
232msgstr "Bekräfta"
230
233
@@ -250,11 +253,11 @@ msgstr "Visa lösenord"
250
253
251#: qml/Notifications/NotificationMenuItemFactory.qml:120
254#: qml/Notifications/NotificationMenuItemFactory.qml:120
252msgid "Enter SIM PIN"
255msgid "Enter SIM PIN"
253−msgstr ""
256+msgstr "Ange SIM PIN-kod"
254
257
255−#: qml/Notifications/NotificationMenuItemFactory.qml:121 qml/Shell.qml:270
258+#: qml/Notifications/NotificationMenuItemFactory.qml:121
256msgid "Sorry, incorrect PIN"
259msgid "Sorry, incorrect PIN"
257−msgstr ""
260+msgstr "Felaktig PIN"
258
261
259#: qml/Panel/ActiveCallHint.qml:77
262#: qml/Panel/ActiveCallHint.qml:77
260msgid "Tap to return to call..."
263msgid "Tap to return to call..."
@@ -296,55 +299,56 @@ msgstr "Lås upp SIM-kort"
296msgid "Roaming"
299msgid "Roaming"
297msgstr "Roaming"
300msgstr "Roaming"
298
301
299−#: qml/Shell.qml:266
302+#: qml/Shell.qml:279
300msgid "Enter your passphrase"
303msgid "Enter your passphrase"
301−msgstr ""
304+msgstr "Ange din lösenfras"
302
305
303−#: qml/Shell.qml:267
306+#: qml/Shell.qml:280
304msgid "Sorry, incorrect passphrase"
307msgid "Sorry, incorrect passphrase"
305−msgstr ""
308+msgstr "Felaktig lösenfras"
306
309
307#: qml/Shell.qml:282
310#: qml/Shell.qml:282
308msgid "Enter your passcode"
311msgid "Enter your passcode"
309−msgstr ""
312+msgstr "Ange din lösenkod"
310
313
311#: qml/Shell.qml:283
314#: qml/Shell.qml:283
312msgid "Sorry, incorrect passcode"
315msgid "Sorry, incorrect passcode"
313−msgstr ""
316+msgstr "Felaktig lösenkod"
314
317
315−#: qml/Shell.qml:273
318+#: qml/Shell.qml:286
316#, qt-format
319#, qt-format
317msgid "Enter your %1"
320msgid "Enter your %1"
318msgstr "Skriv in din %1"
321msgstr "Skriv in din %1"
319
322
320−#: qml/Shell.qml:274
323+#: qml/Shell.qml:287
321#, qt-format
324#, qt-format
322msgid "Sorry, incorrect %1"
325msgid "Sorry, incorrect %1"
323−msgstr ""
326+msgstr "Felaktig %1"
324
327
325−#: qml/Shell.qml:310
328+#: qml/Shell.qml:323
326msgid "Sorry, incorrect passphrase."
329msgid "Sorry, incorrect passphrase."
327−msgstr ""
330+msgstr "Felaktig lösenfras."
328
331
329−#: qml/Shell.qml:311
332+#: qml/Shell.qml:324
330msgid "Sorry, incorrect passcode."
333msgid "Sorry, incorrect passcode."
331−msgstr ""
334+msgstr "Felaktig lösenkod."
332
335
333−#: qml/Shell.qml:312
336+#: qml/Shell.qml:325
334msgid "This will be your last attempt."
337msgid "This will be your last attempt."
335−msgstr ""
338+msgstr "Detta är ditt sista försök."
336
339
337−#: qml/Shell.qml:314
340+#: qml/Shell.qml:327
338msgid ""
341msgid ""
339"If passphrase is entered incorrectly, your phone will conduct a factory "
342"If passphrase is entered incorrectly, your phone will conduct a factory "
340"reset and all personal data will be deleted."
343"reset and all personal data will be deleted."
341msgstr ""
344msgstr ""
345+"Om lösenfrasen anges inkorrekt kommer telefonen att fabrikåterställas och "
346+"all personlig data kommer att tas bort."
342
347
343−#: qml/Shell.qml:315
348+#: qml/Shell.qml:328
344msgid ""
349msgid ""
345"If passcode is entered incorrectly, your phone will conduct a factory reset "
350"If passcode is entered incorrectly, your phone will conduct a factory reset "
346"and all personal data will be deleted."
351"and all personal data will be deleted."
347msgstr ""
352msgstr ""
348−
353+"Om lösenkoden anges felaktigt kommer telefonen att fabrikåterställas och all "
349−#~ msgid "Restart"
354+"personlig data kommer att tas bort."
350−#~ msgstr "Starta om"
qml/Components/Background.qml+1−1
@@ -78,7 +78,7 @@ Loader {
78 Image {
78 Image {
79 objectName: "image"
79 objectName: "image"
80
80
81− source: width > 0 && height > 0 && root.style
81+ source: width > 0 && height > 0 && root.style || ""
82
82
83 sourceSize.width: width
83 sourceSize.width: width
84 sourceSize.height: height
84 sourceSize.height: height
qml/Dash/CardTool.qml+7−10
@@ -169,19 +169,16 @@ Item {
169
169
170 Item {
170 Item {
171 id: attributesModel
171 id: attributesModel
172− property int numOfAttributes: 0
172+ property int numOfAttributes: {
173− property var model: []
174− property bool hasAttributes: {
175 var attributes = components["attributes"];
173 var attributes = components["attributes"];
176− var hasAttributesFlag = (attributes != undefined) && attributes["field"];
174+ if ((attributes != undefined) && attributes["field"]) {
177−
178− if (hasAttributesFlag) {
179 if (attributes["max-count"]) {
175 if (attributes["max-count"]) {
180− numOfAttributes = attributes["max-count"];
176+ return attributes["max-count"];
181 }
177 }
182 }
178 }
183− return hasAttributesFlag
179+ return 0;
184 }
180 }
181+ property var model: []
185
182
186 onNumOfAttributesChanged: {
183 onNumOfAttributesChanged: {
187 model = []
184 model = []
@@ -195,8 +192,8 @@ Item {
195 id: cardLoader
192 id: cardLoader
196 property var fields: ["art", "mascot", "title", "subtitle", "summary", "attributes"]
193 property var fields: ["art", "mascot", "title", "subtitle", "summary", "attributes"]
197 property var maxData: {
194 property var maxData: {
198− "art": Qt.resolvedUrl("graphics/checkers.png"),
195+ "art": Qt.resolvedUrl("graphics/pixel.png"),
199− "mascot": Qt.resolvedUrl("graphics/checkers.png"),
196+ "mascot": Qt.resolvedUrl("graphics/pixel.png"),
200 "title": "—\n—",
197 "title": "—\n—",
201 "subtitle": "—",
198 "subtitle": "—",
202 "summary": "—\n—\n—\n—\n—",
199 "summary": "—\n—\n—\n—\n—",
qml/Dash/Dash.qml+12−1
@@ -34,7 +34,17 @@ Showable {
34 DashCommunicatorService {
34 DashCommunicatorService {
35 objectName: "dashCommunicatorService"
35 objectName: "dashCommunicatorService"
36 onSetCurrentScopeRequested: {
36 onSetCurrentScopeRequested: {
37+ if (!isSwipe || !window.active || overviewController.progress != 0) {
38+ if (overviewController.progress != 0 && window.active) animate = false;
37− dash.setCurrentScope(scopeId, animate, reset)
39+ dash.setCurrentScope(scopeId, animate, isSwipe)
40+ if (overviewController.progress != 0) {
41+ if (window.active) {
42+ dashContentCache.scheduleUpdate();
43+ }
44+ overviewController.enableAnimation = window.active;
45+ overviewController.progress = 0;
46+ }
47+ }
38 }
48 }
39 }
49 }
40
50
@@ -344,6 +354,7 @@ Showable {
344 enabled: !dashContent.subPageShown &&
354 enabled: !dashContent.subPageShown &&
345 dashContent.currentScope &&
355 dashContent.currentScope &&
346 dashContent.currentScope.searchQuery == "" &&
356 dashContent.currentScope.searchQuery == "" &&
357+ !scopeItem.subPageShown &&
347 (overviewController.progress == 0 || dragging)
358 (overviewController.progress == 0 || dragging)
348
359
349 readonly property real fullMovement: units.gu(20)
360 readonly property real fullMovement: units.gu(20)
qml/Dash/GenericScopeView.qml+1−2
@@ -25,7 +25,7 @@ import "../Components/ListItems" as ListItems
25FocusScope {
25FocusScope {
26 id: scopeView
26 id: scopeView
27
27
28− readonly property bool navigationShown: pageHeaderLoader.item ? pageHeaderLoader.item.bottomItem[0].showList : false
28+ readonly property bool navigationShown: pageHeaderLoader.item ? pageHeaderLoader.item.bottomItem[0].openList : false
29 property var scope: null
29 property var scope: null
30 property SortFilterProxyModel categories: categoryFilter
30 property SortFilterProxyModel categories: categoryFilter
31 property bool isCurrent: false
31 property bool isCurrent: false
@@ -151,7 +151,6 @@ FocusScope {
151 model: scopeView.categories
151 model: scopeView.categories
152 forceNoClip: subPageLoader.open
152 forceNoClip: subPageLoader.open
153 pixelAligned: true
153 pixelAligned: true
154− interactive: !navigationShown
155
154
156 property Item expandedCategoryItem: null
155 property Item expandedCategoryItem: null
157
156
qml/Dash/PageHeader.qml+19−14
@@ -64,9 +64,12 @@ Item {
64 }
64 }
65 }
65 }
66
66
67− function closePopup() {
67+ function closePopup(keepFocus) {
68 if (headerContainer.popover != null) {
68 if (headerContainer.popover != null) {
69+ headerContainer.popover.unfocusOnDestruction = !keepFocus;
69 PopupUtils.close(headerContainer.popover);
70 PopupUtils.close(headerContainer.popover);
71+ } else if (!keepFocus) {
72+ unfocus();
70 }
73 }
71 }
74 }
72
75
@@ -74,11 +77,8 @@ Item {
74 if (searchHistory) {
77 if (searchHistory) {
75 searchHistory.addQuery(searchTextField.text);
78 searchHistory.addQuery(searchTextField.text);
76 }
79 }
77− if (!keepFocus) {
78− unfocus();
79− }
80 searchTextField.text = "";
80 searchTextField.text = "";
81− closePopup();
81+ closePopup(keepFocus);
82 }
82 }
83
83
84 function unfocus() {
84 function unfocus() {
@@ -102,7 +102,7 @@ Item {
102 }
102 }
103
103
104 function refreshLogo() {
104 function refreshLogo() {
105− if (scopeStyle ? scopeStyle.headerLogo != "" : false) {
105+ if (root.scopeStyle ? root.scopeStyle.headerLogo != "" : false) {
106 header.contents = imageComponent.createObject();
106 header.contents = imageComponent.createObject();
107 } else if (header.contents) {
107 } else if (header.contents) {
108 header.contents.destroy();
108 header.contents.destroy();
@@ -119,11 +119,10 @@ Item {
119 anchors { fill: parent; margins: units.gu(1); bottomMargin: units.gu(3) + bottomContainer.height }
119 anchors { fill: parent; margins: units.gu(1); bottomMargin: units.gu(3) + bottomContainer.height }
120 visible: headerContainer.showSearch
120 visible: headerContainer.showSearch
121 onPressed: {
121 onPressed: {
122− closePopup();
122+ closePopup(/* keepFocus */false);
123 if (!searchTextField.text) {
123 if (!searchTextField.text) {
124 headerContainer.showSearch = false;
124 headerContainer.showSearch = false;
125 }
125 }
126− searchTextField.focus = false;
127 mouse.accepted = false;
126 mouse.accepted = false;
128 }
127 }
129 }
128 }
@@ -228,7 +227,7 @@ Item {
228
227
229 onTextChanged: {
228 onTextChanged: {
230 if (text != "") {
229 if (text != "") {
231− closePopup();
230+ closePopup(/* keepFocus */true);
232 }
231 }
233 }
232 }
234 }
233 }
@@ -310,8 +309,13 @@ Item {
310 id: popover
309 id: popover
311 autoClose: false
310 autoClose: false
312
311
312+ property bool unfocusOnDestruction: false
313+
313 Component.onDestruction: {
314 Component.onDestruction: {
314 headerContainer.popover = null;
315 headerContainer.popover = null;
316+ if (unfocusOnDestruction) {
317+ root.unfocus();
318+ }
315 }
319 }
316
320
317 Column {
321 Column {
@@ -332,8 +336,7 @@ Item {
332 onClicked: {
336 onClicked: {
333 searchHistory.addQuery(text);
337 searchHistory.addQuery(text);
334 searchTextField.text = text;
338 searchTextField.text = text;
335− closePopup();
339+ closePopup(/* keepFocus */false);
336− unfocus();
337 }
340 }
338 }
341 }
339 }
342 }
@@ -350,7 +353,7 @@ Item {
350 bottom: bottomContainer.top
353 bottom: bottomContainer.top
351 }
354 }
352
355
353− color: scopeStyle ? scopeStyle.headerDividerColor : "#e0e0e0"
356+ color: root.scopeStyle ? root.scopeStyle.headerDividerColor : "#e0e0e0"
354
357
355 Rectangle {
358 Rectangle {
356 anchors {
359 anchors {
@@ -404,8 +407,10 @@ Item {
404 Qt.lighter(Qt.rgba(bottomItem.background.topColor.r,
407 Qt.lighter(Qt.rgba(bottomItem.background.topColor.r,
405 bottomItem.background.topColor.g,
408 bottomItem.background.topColor.g,
406 bottomItem.background.topColor.b, 1.0), 1.2);
409 bottomItem.background.topColor.b, 1.0), 1.2);
407− } else if (!bottomItem && scopeStyle) {
410+ } else if (!bottomItem && root.scopeStyle) {
408− Qt.lighter(Qt.rgba(scopeStyle.background.r, scopeStyle.background.g, scopeStyle.background.b, 1.0), 1.2);
411+ Qt.lighter(Qt.rgba(root.scopeStyle.background.r,
412+ root.scopeStyle.background.g,
413+ root.scopeStyle.background.b, 1.0), 1.2);
409 } else "#CCFFFFFF"
414 } else "#CCFFFFFF"
410 }
415 }
411 }
416 }
qml/Dash/PreviewListView.qml+2−2
@@ -44,7 +44,7 @@ Item {
44 id: header
44 id: header
45 objectName: "pageHeader"
45 objectName: "pageHeader"
46 width: parent.width
46 width: parent.width
47− title: scope ? scope.name : ""
47+ title: root.scope ? root.scope.name : ""
48 showBackButton: true
48 showBackButton: true
49 searchEntryEnabled: false
49 searchEntryEnabled: false
50 scopeStyle: root.scopeStyle
50 scopeStyle: root.scopeStyle
@@ -78,7 +78,7 @@ Item {
78 if (previewListView.currentItem && previewListView.currentItem.previewData !== undefined) {
78 if (previewListView.currentItem && previewListView.currentItem.previewData !== undefined) {
79 previewListView.currentItem.previewData.cancelAction();
79 previewListView.currentItem.previewData.cancelAction();
80 }
80 }
81− scope.cancelActivation();
81+ root.scope.cancelActivation();
82 model = undefined;
82 model = undefined;
83 }
83 }
84 }
84 }
qml/Dash/Previews/PreviewPayments.qml+2
@@ -49,6 +49,7 @@ PreviewWidget {
49
49
50 Payments {
50 Payments {
51 id: paymentClient
51 id: paymentClient
52+ objectName: "paymentClient"
52
53
53 property var source: widgetData["source"]
54 property var source: widgetData["source"]
54
55
@@ -59,6 +60,7 @@ PreviewWidget {
59 root.triggered(widgetId, "purchaseCompleted", source);
60 root.triggered(widgetId, "purchaseCompleted", source);
60 }
61 }
61 onPurchaseError: {
62 onPurchaseError: {
63+ paymentButton.opacity = 1;
62 root.triggered(widgetId, "purchaseError", source);
64 root.triggered(widgetId, "purchaseError", source);
63 }
65 }
64 }
66 }
qml/Dash/ScopesOverview.qml+6
@@ -386,6 +386,7 @@ Item {
386
386
387 Rectangle {
387 Rectangle {
388 id: bottomBar
388 id: bottomBar
389+ objectName: "bottomBar"
389 color: "black"
390 color: "black"
390 height: units.gu(8)
391 height: units.gu(8)
391 width: parent.width
392 width: parent.width
@@ -400,6 +401,11 @@ Item {
400 }
401 }
401 }
402 }
402
403
404+ MouseArea {
405+ // Just eat any other press since this parent is black opaque
406+ anchors.fill: parent
407+ }
408+
403 AbstractButton {
409 AbstractButton {
404 objectName: "scopesOverviewDoneButton"
410 objectName: "scopesOverviewDoneButton"
405 width: Math.max(label.width + units.gu(2), units.gu(10))
411 width: Math.max(label.width + units.gu(2), units.gu(10))
qml/Dash/graphics/checkers.pngdeleted

Binary file not shown.

qml/Dash/graphics/pixel.pngnew file

Binary file not shown.

qml/Notifications/Notification.qml+132−46
@@ -39,19 +39,17 @@ Item {
39 property bool fullscreen: false
39 property bool fullscreen: false
40 property int maxHeight
40 property int maxHeight
41 property int margins
41 property int margins
42− property Gradient greenGradient : Gradient {
42+ readonly property color red: "#fc4949"
43− GradientStop { position: 0.0; color: "#3fb24f" }
43+ readonly property color green: "#3fb24f"
44− GradientStop { position: 1.0; color: "#3fb24f" }
44+ readonly property color sdLightGrey: "#eaeaea"
45− }
45+ readonly property color sdDarkGrey: "#dddddd"
46− property Gradient darkgreyGradient: Gradient {
46+ readonly property color sdFontColor: "#5d5d5d"
47− GradientStop { position: 0.0; color: "#4d4745" }
47+ readonly property real contentSpacing: units.gu(2)
48− GradientStop { position: 1.0; color: "#4d4745" }
49− }
50
48
51 objectName: "background"
49 objectName: "background"
52− implicitHeight: type !== Notification.PlaceHolder ? (fullscreen ? maxHeight : contentColumn.height + contentColumn.spacing * 2) : 0
50+ implicitHeight: type !== Notification.PlaceHolder ? (fullscreen ? maxHeight : outterColumn.height + contentSpacing * 2) : 0
53
51
54− color: Qt.rgba(0.132, 0.117, 0.109, 0.97)
52+ color: type == Notification.SnapDecision ? sdLightGrey : Qt.rgba(0.132, 0.117, 0.109, 0.97)
55 opacity: 1 // FIXME: 1 because of LP: #1354406 workaround, has to be 0 really
53 opacity: 1 // FIXME: 1 because of LP: #1354406 workaround, has to be 0 really
56
54
57 state: {
55 state: {
@@ -107,7 +105,7 @@ Item {
107 states:[
105 states:[
108 State {
106 State {
109 name: "contracted"
107 name: "contracted"
110− PropertyChanges {target: notification; height: units.gu(8)}
108+ PropertyChanges {target: notification; height: units.gu(10)}
111 },
109 },
112 State {
110 State {
113 name: "expanded"
111 name: "expanded"
@@ -131,6 +129,7 @@ Item {
131 color: parent.color
129 color: parent.color
132 opacity: parent.opacity
130 opacity: parent.opacity
133 radius: "medium"
131 radius: "medium"
132+ borderSource: "none"
134 }
133 }
135
134
136 Rectangle {
135 Rectangle {
@@ -199,50 +198,41 @@ Item {
199 }
198 }
200
199
201 Column {
200 Column {
202− id: contentColumn
201+ id: outterColumn
203− objectName: "contentColumn"
204
202
205 anchors {
203 anchors {
206 left: parent.left
204 left: parent.left
207 right: parent.right
205 right: parent.right
208 top: parent.top
206 top: parent.top
209− margins: fullscreen ? 0 : spacing
207+ margins: 0
208+ topMargin: fullscreen ? 0 : units.gu(2)
210 }
209 }
211
210
212− spacing: units.gu(1)
211+ spacing: units.gu(2)
213
212
214 Row {
213 Row {
215 id: topRow
214 id: topRow
216
215
217− spacing: contentColumn.spacing
216+ spacing: contentSpacing
218 anchors {
217 anchors {
219 left: parent.left
218 left: parent.left
220 right: parent.right
219 right: parent.right
220+ margins: contentSpacing
221 }
221 }
222
222
223 ShapedIcon {
223 ShapedIcon {
224 id: icon
224 id: icon
225
225
226 objectName: "icon"
226 objectName: "icon"
227− width: units.gu(6)
227+ width: type == Notification.Ephemeral && !bodyLabel.visible ? units.gu(3) : units.gu(6)
228− height: units.gu(6)
228+ height: width
229 shaped: notification.hints["x-canonical-non-shaped-icon"] == "true" ? false : true
229 shaped: notification.hints["x-canonical-non-shaped-icon"] == "true" ? false : true
230 visible: iconSource !== undefined && iconSource != ""
230 visible: iconSource !== undefined && iconSource != ""
231− }
232−
233− Image {
234− id: secondaryIcon
235−
236− objectName: "secondaryIcon"
237− width: units.gu(2)
238− height: units.gu(2)
239− visible: source !== undefined && source != ""
240− fillMode: Image.PreserveAspectCrop
241− }
231+ }
242
232
243 Column {
233 Column {
244 id: labelColumn
234 id: labelColumn
245− width: parent.width - x
235+ width: secondaryIcon.visible ? parent.width - x - units.gu(4.5) : parent.width - x
246
236
247 anchors.verticalCenter: (icon.visible && !bodyLabel.visible) ? icon.verticalCenter : undefined
237 anchors.verticalCenter: (icon.visible && !bodyLabel.visible) ? icon.verticalCenter : undefined
248
238
@@ -255,8 +245,7 @@ Item {
255 right: parent.right
245 right: parent.right
256 }
246 }
257 fontSize: "medium"
247 fontSize: "medium"
258− font.bold: true
259− color: Theme.palette.selected.backgroundText
248+ color: type == Notification.SnapDecision ? sdFontColor : Theme.palette.selected.backgroundText
260 elide: Text.ElideRight
249 elide: Text.ElideRight
261 textFormat: Text.PlainText
250 textFormat: Text.PlainText
262 }
251 }
@@ -271,14 +260,27 @@ Item {
271 }
260 }
272 visible: body != ""
261 visible: body != ""
273 fontSize: "small"
262 fontSize: "small"
274− color: Theme.palette.selected.backgroundText
263+ color: type == Notification.SnapDecision ? sdFontColor : Theme.palette.selected.backgroundText
275− opacity: 0.6
276 wrapMode: Text.WordWrap
264 wrapMode: Text.WordWrap
277− maximumLineCount: 10
265+ maximumLineCount: 2
278 elide: Text.ElideRight
266 elide: Text.ElideRight
279 textFormat: Text.PlainText
267 textFormat: Text.PlainText
280 }
268 }
281 }
269 }
270+
271+ Image {
272+ id: secondaryIcon
273+
274+ objectName: "secondaryIcon"
275+ width: units.gu(3)
276+ height: units.gu(3)
277+ visible: status === Image.Ready
278+ fillMode: Image.PreserveAspectCrop
279+ }
280+ }
281+
282+ ListItem.ThinDivider {
283+ visible: type == Notification.SnapDecision
282 }
284 }
283
285
284 Column {
286 Column {
@@ -321,6 +323,74 @@ Item {
321 }
323 }
322 }
324 }
323
325
326+ Column {
327+ id: oneOverTwoCase
328+
329+ anchors {
330+ left: parent.left
331+ right: parent.right
332+ margins: contentSpacing
333+ }
334+
335+ spacing: contentSpacing
336+
337+ visible: notification.type == Notification.SnapDecision && oneOverTwoRepeaterTop.count == 3
338+
339+ Repeater {
340+ id: oneOverTwoRepeaterTop
341+
342+ model: notification.actions
343+ delegate: Loader {
344+ id: oneOverTwoLoaderTop
345+
346+ property string actionId: id
347+ property string actionLabel: label
348+
349+ Component {
350+ id: oneOverTwoButtonTop
351+
352+ Button {
353+ objectName: "notify_oot_button" + index
354+ width: oneOverTwoCase.width
355+ text: oneOverTwoLoaderTop.actionLabel
356+ color: notification.hints["x-canonical-private-affirmative-tint"] == "true" ? green : sdDarkGrey
357+ onClicked: notification.notification.invokeAction(oneOverTwoLoaderTop.actionId)
358+ }
359+ }
360+ sourceComponent: index == 0 ? oneOverTwoButtonTop : undefined
361+ }
362+ }
363+
364+ Row {
365+ spacing: contentSpacing
366+
367+ Repeater {
368+ id: oneOverTwoRepeaterBottom
369+
370+ model: notification.actions
371+ delegate: Loader {
372+ id: oneOverTwoLoaderBottom
373+
374+ property string actionId: id
375+ property string actionLabel: label
376+
377+ Component {
378+ id: oneOverTwoButtonBottom
379+
380+ Button {
381+ objectName: "notify_oot_button" + index
382+ width: oneOverTwoCase.width / 2 - spacing * 2
383+ text: oneOverTwoLoaderBottom.actionLabel
384+ color: index == 1 && notification.hints["x-canonical-private-rejection-tint"] == "true" ? red : sdDarkGrey
385+ onClicked: notification.notification.invokeAction(oneOverTwoLoaderBottom.actionId)
386+ }
387+ }
388+ sourceComponent: (index == 1 || index == 2) ? oneOverTwoButtonBottom : undefined
389+ }
390+ }
391+ }
392+ }
393+
324 Row {
394 Row {
325 id: buttonRow
395 id: buttonRow
326
396
@@ -328,9 +398,10 @@ Item {
328 anchors {
398 anchors {
329 left: parent.left
399 left: parent.left
330 right: parent.right
400 right: parent.right
401+ margins: contentSpacing
331 }
402 }
332− visible: notification.type == Notification.SnapDecision && actionRepeater.count > 0
403+ visible: notification.type == Notification.SnapDecision && actionRepeater.count > 0 && !oneOverTwoCase.visible
333− spacing: units.gu(1)
404+ spacing: units.gu(2)
334 layoutDirection: Qt.RightToLeft
405 layoutDirection: Qt.RightToLeft
335
406
336 Repeater {
407 Repeater {
@@ -347,10 +418,19 @@ Item {
347 id: actionButton
418 id: actionButton
348
419
349 Button {
420 Button {
350− objectName: "button" + index
421+ objectName: "notify_button" + index
351− width: buttonRow.width / 2 - spacing
422+ width: buttonRow.width / 2 - spacing*2
352 text: loader.actionLabel
423 text: loader.actionLabel
353− gradient: notification.hints["x-canonical-private-button-tint"] == "true" && index == 0 ? greenGradient : darkgreyGradient
424+ color: {
425+ var result = sdDarkGrey;
426+ if (index == 0 && notification.hints["x-canonical-private-affirmative-tint"] == "true") {
427+ result = green;
428+ }
429+ if (index == 1 && notification.hints["x-canonical-private-rejection-tint"] == "true") {
430+ result = red;
431+ }
432+ return result;
433+ }
354 onClicked: notification.notification.invokeAction(loader.actionId)
434 onClicked: notification.notification.invokeAction(loader.actionId)
355 }
435 }
356 }
436 }
@@ -362,10 +442,16 @@ Item {
362 ComboButton {
442 ComboButton {
363 id: comboButton
443 id: comboButton
364
444
365− objectName: "button2"
445+ objectName: "notify_button2"
366 width: parent.width
446 width: parent.width
447+ anchors {
448+ left: parent.left
449+ right: parent.right
450+ margins: contentSpacing
451+ }
452+
367− visible: notification.type == Notification.SnapDecision && actionRepeater.count > 3
453+ visible: notification.type == Notification.SnapDecision && actionRepeater.count > 3 && !oneOverTwoCase.visible
368− gradient: darkgreyGradient
454+ color: sdDarkGrey
369 onClicked: notification.notification.invokeAction(comboRepeater.itemAt(2).actionId)
455 onClicked: notification.notification.invokeAction(comboRepeater.itemAt(2).actionId)
370 expanded: false
456 expanded: false
371 expandedHeight: (comboRepeater.count - 2) * units.gu(4) + units.gu(.5)
457 expandedHeight: (comboRepeater.count - 2) * units.gu(4) + units.gu(.5)
@@ -399,7 +485,7 @@ Item {
399 MouseArea {
485 MouseArea {
400 id: comboInputArea
486 id: comboInputArea
401
487
402− objectName: "button" + index
488+ objectName: "notify_button" + index
403 width: comboButton.width
489 width: comboButton.width
404 height: comboIcon.height + units.gu(2)
490 height: comboIcon.height + units.gu(2)
405
491
@@ -421,7 +507,7 @@ Item {
421 }
507 }
422 width: units.gu(2)
508 width: units.gu(2)
423 height: units.gu(2)
509 height: units.gu(2)
424− color: "white"
510+ color: sdFontColor
425 name: splitLabel[2]
511 name: splitLabel[2]
426 }
512 }
427
513
@@ -434,7 +520,7 @@ Item {
434 verticalCenter: comboIcon.verticalCenter
520 verticalCenter: comboIcon.verticalCenter
435 }
521 }
436 fontSize: "small"
522 fontSize: "small"
437− color: "white"
523+ color: sdFontColor
438 text: splitLabel[3]
524 text: splitLabel[3]
439 }
525 }
440 }
526 }
qml/Notifications/NotificationMenuItemFactory.qml+4
@@ -55,6 +55,7 @@ Loader {
55 anchors {
55 anchors {
56 left: parent.left
56 left: parent.left
57 right: parent.right
57 right: parent.right
58+ margins: spacing
58 }
59 }
59
60
60 Component.onCompleted: {
61 Component.onCompleted: {
@@ -65,6 +66,7 @@ Loader {
65
66
66 Label {
67 Label {
67 text: menuData.label
68 text: menuData.label
69+ color: notification.sdFontColor
68 }
70 }
69
71
70 TextField {
72 TextField {
@@ -98,11 +100,13 @@ Loader {
98 id: checkBox
100 id: checkBox
99
101
100 checked: false
102 checked: false
103+ activeFocusOnPress: false
101 }
104 }
102
105
103 Label {
106 Label {
104 anchors.verticalCenter: checkBox.verticalCenter
107 anchors.verticalCenter: checkBox.verticalCenter
105 text: i18n.tr("Show password")
108 text: i18n.tr("Show password")
109+ color: notification.sdFontColor
106 }
110 }
107 }
111 }
108 }
112 }
qml/Notifications/Notifications.qml+1−1
@@ -33,7 +33,7 @@ ListView {
33 id: snapDecisionProxyModel
33 id: snapDecisionProxyModel
34
34
35 model: notificationList.model
35 model: notificationList.model
36− filterRole: UnityNotifications.ModelInterface.RoleType
36+ filterRole: UnityNotifications.ModelInterface != undefined ? UnityNotifications.ModelInterface.RoleType : 0
37 filterRegExp: RegExp(UnityNotifications.Notification.SnapDecision)
37 filterRegExp: RegExp(UnityNotifications.Notification.SnapDecision)
38 }
38 }
39
39
qml/Panel/Indicators/IndicatorsLight.qml+4−7
@@ -27,12 +27,9 @@ QtObject {
27 Component.onDestruction: Lights.state = Lights.Off
27 Component.onDestruction: Lights.state = Lights.Off
28
28
29 // QtObject does not have children
29 // QtObject does not have children
30− property var _connections: Connections {
30+ property var _binding: Binding {
31− id: powerConnection
32−
33− target: Powerd
31+ target: Lights
34− onDisplayPowerStateChange: {
32+ property: "state"
35− Lights.state = (status === Powerd.Off) ? Lights.On : Lights.Off
33+ value: (Powerd.status === Powerd.Off) ? Lights.On : Lights.Off
36− }
37 }
34 }
38}
35}
qml/Shell.qml+18−14
@@ -22,6 +22,7 @@ import Ubuntu.Components 0.1
22import Ubuntu.Components.Popups 1.0
22import Ubuntu.Components.Popups 1.0
23import Ubuntu.Gestures 0.1
23import Ubuntu.Gestures 0.1
24import Ubuntu.SystemImage 0.1
24import Ubuntu.SystemImage 0.1
25+import Ubuntu.Telephony 0.1 as Telephony
25import Unity.Connectivity 0.1
26import Unity.Connectivity 0.1
26import Unity.Launcher 0.1
27import Unity.Launcher 0.1
27import Utils 0.1
28import Utils 0.1
@@ -146,6 +147,7 @@ Item {
146 lockscreen.show();
147 lockscreen.show();
147 }
148 }
148 greeter.hide();
149 greeter.hide();
150+ launcher.hide();
149 }
151 }
150
152
151 onFocusedApplicationIdChanged: {
153 onFocusedApplicationIdChanged: {
@@ -164,6 +166,7 @@ Item {
164 // for an emergency call or accepted an incoming call.
166 // for an emergency call or accepted an incoming call.
165 setFakeActiveForApp(appId)
167 setFakeActiveForApp(appId)
166 }
168 }
169+ launcher.hide();
167 }
170 }
168 }
171 }
169
172
@@ -233,6 +236,15 @@ Item {
233 }
236 }
234 }
237 }
235 }
238 }
239+ Connections {
240+ target: SessionManager
241+ onSessionStopping: {
242+ if (!session.parentSession && !session.application) {
243+ // nothing is using it. delete it right away
244+ session.release();
245+ }
246+ }
247+ }
236
248
237 Lockscreen {
249 Lockscreen {
238 id: lockscreen
250 id: lockscreen
@@ -448,18 +460,9 @@ Item {
448 id: powerConnection
460 id: powerConnection
449 target: Powerd
461 target: Powerd
450
462
451− onDisplayPowerStateChange: {
463+ onStatusChanged: {
452− // We ignore any display-off signals when the proximity sensor
453− // is active. This usually indicates something like a phone call.
454− if (status == Powerd.Off && reason != Powerd.Proximity && !edgeDemo.running) {
464+ if (Powerd.status === Powerd.Off && !callManager.hasCalls && !edgeDemo.running) {
455− greeter.showNow();
465+ greeter.showNow()
456− }
457−
458− // No reason to chew demo CPU when user isn't watching
459− if (status == Powerd.Off) {
460− edgeDemo.paused = true;
461− } else if (status == Powerd.On) {
462− edgeDemo.paused = false;
463 }
466 }
464 }
467 }
465 }
468 }
@@ -535,7 +538,7 @@ Item {
535 onShowDashHome: showHome()
538 onShowDashHome: showHome()
536 onDash: showDash()
539 onDash: showDash()
537 onDashSwipeChanged: {
540 onDashSwipeChanged: {
538− if (dashSwipe && ApplicationManager.focusedApplicationId !== "unity8-dash") {
541+ if (dashSwipe) {
539 dash.setCurrentScope("clickscope", false, true)
542 dash.setCurrentScope("clickscope", false, true)
540 }
543 }
541 }
544 }
@@ -559,7 +562,7 @@ Item {
559 visible: notifications.useModal && !greeter.shown && (notifications.state == "narrow")
562 visible: notifications.useModal && !greeter.shown && (notifications.state == "narrow")
560 color: "#000000"
563 color: "#000000"
561 anchors.fill: parent
564 anchors.fill: parent
562− opacity: 0.5
565+ opacity: 0.9
563
566
564 MouseArea {
567 MouseArea {
565 anchors.fill: parent
568 anchors.fill: parent
@@ -622,6 +625,7 @@ Item {
622 EdgeDemo {
625 EdgeDemo {
623 id: edgeDemo
626 id: edgeDemo
624 z: alphaDisclaimerLabel.z + 10
627 z: alphaDisclaimerLabel.z + 10
628+ paused: Powerd.status === Powerd.Off // Saves power
625 greeter: greeter
629 greeter: greeter
626 launcher: launcher
630 launcher: launcher
627 indicators: panel.indicators
631 indicators: panel.indicators
qml/Stages/Animations/BaseSurfaceAnimation.qml → qml/Stages/Animations/BaseSessionAnimation.qmlrenamed+23−20
@@ -37,57 +37,60 @@ import QtQuick 2.0
37 */
37 */
38Item {
38Item {
39 id: base
39 id: base
40− property Item surface: null
40+ property var container
41+ objectName: "sessionAnimation"
41
42
42− // changes applied when state changes to "in"
43+ // changes applied when state changes to "from"
43− property list<QtObject> outChanges
44+ property list<QtObject> fromChanges
44− // transition animations when changing state to "in"
45+ // transition animations when changing state to "from"
45− property list<QtObject> outAnimations
46+ property list<QtObject> fromAnimations
46
47
47− // changes applied when state changes to "out"
48+ // changes applied when state changes to "to"
48− property list<QtObject> inChanges
49+ property list<QtObject> toChanges
49− // transition animations when changing state to "out"
50+ // transition animations when changing state to "to"
50− property list<QtObject> inAnimations
51+ property list<QtObject> toAnimations
51
52
52 function start() {
53 function start() {
53− // "prep" state forces outChanges without transition animations.
54+ // "prep" state forces toChanges without transition animations.
54 state = "prep"
55 state = "prep"
55− state = "in";
56+ state = "to";
56 }
57 }
57 function end() {
58 function end() {
58− state = "out";
59+ state = "from";
59 }
60 }
60
61
62+ signal completed()
63+
61 states: [
64 states: [
62 State {
65 State {
63 name: "baseAnimation"
66 name: "baseAnimation"
64− PropertyChanges { target: base.surface; anchors.fill: undefined }
67+ PropertyChanges { target: container; anchors.fill: undefined }
65 },
68 },
66
69
67 State {
70 State {
68 name: "prep"
71 name: "prep"
69 extend: "baseAnimation"
72 extend: "baseAnimation"
70− changes: outChanges
73+ changes: fromChanges
71 },
74 },
72 State {
75 State {
73− name: "out"
76+ name: "from"
74 extend: "prep"
77 extend: "prep"
75 },
78 },
76 State {
79 State {
77 name: "in"
80 name: "in"
78 extend: "baseAnimation"
81 extend: "baseAnimation"
79− changes: inChanges
82+ changes: toChanges
80 }
83 }
81 ]
84 ]
82
85
83 transitions: [
86 transitions: [
84 Transition {
87 Transition {
85− to: "out"
88+ to: "from"
86− animations: outAnimations
89+ animations: fromAnimations
87 },
90 },
88 Transition {
91 Transition {
89− to: "in"
92+ to: "to"
90− animations: inAnimations
93+ animations: toAnimations
91 }
94 }
92 ]
95 ]
93}
96}
qml/Stages/Animations/DarkenAndFadeInAnimation.qmldeleted−48
@@ -1,48 +0,0 @@
1−/*
2− * Copyright (C) 2014 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
19−
20−BaseSurfaceAnimation {
21− id: animation
22−
23− property Rectangle darkenItem: Rectangle {
24− parent: animation.surface.parent
25− anchors.fill: parent
26− color: Qt.rgba(0,0,0,0.0)
27− }
28−
29− outChanges: [ PropertyChanges { target: animation.surface; opacity: 0.0 } ]
30− outAnimations: [
31− SequentialAnimation {
32− UbuntuNumberAnimation { target: animation.surface; property: "opacity"; duration: UbuntuAnimation.FastDuration }
33− ColorAnimation { target: darkenItem; duration: UbuntuAnimation.FastDuration }
34− ScriptAction { script: { if (animation.parent.removing) animation.surface.release(); } }
35− }
36− ]
37−
38− inChanges: [
39− PropertyChanges { target: darkenItem; color: Qt.rgba(0,0,0,0.7) },
40− PropertyChanges { target: animation.surface; opacity: 1.0 }
41− ]
42− inAnimations: [
43− SequentialAnimation {
44− ColorAnimation { target: darkenItem; duration: UbuntuAnimation.FastDuration }
45− UbuntuNumberAnimation { target: animation.surface; property: "opacity"; duration: UbuntuAnimation.FastDuration }
46− }
47− ]
48−}
qml/Stages/Animations/SwipeFromBottomAnimation.qml+24−19
@@ -15,34 +15,39 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import Ubuntu.Components 1.1
18
19
19−BaseSurfaceAnimation {
20+BaseSessionAnimation {
20 id: animation
21 id: animation
21
22
23+ fromChanges: [
24+ AnchorChanges {
25+ target: container;
22− outChanges: [ AnchorChanges { target: animation.surface; anchors.top: animation.parent.bottom } ]
26+ anchors.top: container.parent.bottom
23− outAnimations: [
27+ }
28+ ]
29+ fromAnimations: [
24 SequentialAnimation {
30 SequentialAnimation {
31+ // clip so we don't go out of parent's bounds during spread
25− PropertyAction { target: animation.parent; property: "clip"; value: true }
32+ PropertyAction { target: container.parent; property: "clip"; value: true }
26− AnchorAnimation { easing.type: Easing.InOutQuad; duration: 400 }
33+ AnchorAnimation { easing: UbuntuAnimation.StandardEasing; duration: UbuntuAnimation.BriskDuration }
27− PropertyAction { target: animation.surface; property: "visible"; value: !animation.parent.removing }
28− PropertyAction { target: animation.parent; property: "clip"; value: false }
34+ PropertyAction { target: container.parent; property: "clip"; value: false }
29− ScriptAction { script: { if (animation.parent.removing) animation.surface.release(); } }
35+ ScriptAction { script: { animation.completed(); } }
30 }
36 }
31 ]
37 ]
32
38
33− inChanges: [
39+ toChanges: [
34 AnchorChanges {
40 AnchorChanges {
35− target: animation.surface;
41+ target: container;
36− anchors.top: animation.parent.top
42+ anchors.top: container.parent.top
37− anchors.right: undefined
38− anchors.bottom: undefined
39− anchors.left: undefined
40− } ]
43+ }
41− inAnimations: [
44+ ]
45+ toAnimations: [
42 SequentialAnimation {
46 SequentialAnimation {
47+ // clip so we don't go out of parent's bounds during spread
43− PropertyAction { target: animation.parent; property: "clip"; value: true }
48+ PropertyAction { target: container.parent; property: "clip"; value: true }
44− AnchorAnimation { easing.type: Easing.InOutQuad; duration: 400 }
49+ AnchorAnimation { easing: UbuntuAnimation.StandardEasing; duration: UbuntuAnimation.BriskDuration }
45− PropertyAction { target: animation.parent; property: "clip"; value: false }
50+ PropertyAction { target: container.parent; property: "clip"; value: false }
46 }
51 }
47 ]
52 ]
48}
53}
qml/Stages/Animations/SwipeUpAnimation.qmldeleted−49
@@ -1,49 +0,0 @@
1−/*
2− * Copyright (C) 2014 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−
19−BaseSurfaceAnimation {
20− id: animation
21−
22− outAnimations: [
23− SequentialAnimation {
24− PropertyAction { target: animation.parent; property: "clip"; value: true }
25− PropertyAction { target: animation.surface; property: "visible"; value: true }
26− AnchorAnimation { easing.type: Easing.InOutQuad; duration: 400 }
27− PropertyAction { target: animation.parent; property: "clip"; value: false }
28− ScriptAction { script: { if (animation.parent.removing) animation.surface.release(); } }
29− }
30− ]
31−
32− inChanges: [
33− AnchorChanges {
34− target: animation.surface;
35− anchors.top: undefined
36− anchors.right: undefined
37− anchors.bottom: animation.parent.top
38− anchors.left: undefined
39− }
40− ]
41− inAnimations: [
42− SequentialAnimation {
43− PropertyAction { target: animation.parent; property: "clip"; value: true }
44− AnchorAnimation { easing.type: Easing.InOutQuad; duration: 400 }
45− PropertyAction { target: animation.surface; property: "visible"; value: false}
46− PropertyAction { target: animation.parent; property: "clip"; value: false }
47− }
48− ]
49−}
qml/Stages/ApplicationWindow.qml+51−71
@@ -23,9 +23,9 @@ Item {
23
23
24 // to be read from outside
24 // to be read from outside
25 readonly property bool fullscreen: application ? application.fullscreen : false
25 readonly property bool fullscreen: application ? application.fullscreen : false
26+ property alias interactive: sessionContainer.interactive
26
27
27 // to be set from outside
28 // to be set from outside
28− property bool interactive: true
29 property QtObject application
29 property QtObject application
30
30
31 QtObject {
31 QtObject {
@@ -35,16 +35,14 @@ Item {
35 // (in order to avoid breaking qml binding due to a javascript exception)
35 // (in order to avoid breaking qml binding due to a javascript exception)
36 readonly property string name: root.application ? root.application.name : ""
36 readonly property string name: root.application ? root.application.name : ""
37 readonly property url icon: root.application ? root.application.icon : ""
37 readonly property url icon: root.application ? root.application.icon : ""
38− readonly property Item surface: root.application ? root.application.surface : null
39 readonly property int applicationState: root.application ? root.application.state : -1
38 readonly property int applicationState: root.application ? root.application.state : -1
40− readonly property var promptSurfaces: root.application ? root.application.promptSurfaces : null
41
39
42 // Whether the Application had a surface before but lost it.
40 // Whether the Application had a surface before but lost it.
43− property bool hadSurface: false
41+ property bool hadSurface: sessionContainer.surfaceContainer.hadSurface
44
42
45 property bool needToTakeScreenshot:
43 property bool needToTakeScreenshot:
46− d.surface && d.surfaceInitialized && screenshotImage.status === Image.Null
44+ sessionContainer.surface && d.surfaceInitialized && screenshotImage.status === Image.Null
47− && d.applicationState === ApplicationInfo.Stopped
45+ && d.applicationState === ApplicationInfoInterface.Stopped
48 onNeedToTakeScreenshotChanged: {
46 onNeedToTakeScreenshotChanged: {
49 if (needToTakeScreenshot) {
47 if (needToTakeScreenshot) {
50 screenshotImage.take();
48 screenshotImage.take();
@@ -55,12 +53,13 @@ Item {
55 // might show the UI accommodating due to surface resizes on startup.
53 // might show the UI accommodating due to surface resizes on startup.
56 // Remove this when possible
54 // Remove this when possible
57 property bool surfaceInitialized: false
55 property bool surfaceInitialized: false
58− onSurfaceChanged: {
56+
57+ function forceSurfaceActiveFocusIfReady() {
59− if (surface) {
58+ if (sessionContainer.surface !== null &&
60− surfaceInitTimer.start();
59+ sessionContainer.surface.focus &&
61− } else {
60+ sessionContainer.surface.parent === sessionContainer.surfaceContainer &&
62− hadSurface = true;
61+ sessionContainer.surface.enabled) {
63− surfaceInitialized = false;
62+ sessionContainer.surface.forceActiveFocus();
64 }
63 }
65 }
64 }
66 }
65 }
@@ -68,40 +67,16 @@ Item {
68 Timer {
67 Timer {
69 id: surfaceInitTimer
68 id: surfaceInitTimer
70 interval: 100
69 interval: 100
71− onTriggered: { if (d.surface) {d.surfaceInitialized = true;} }
70+ onTriggered: { if (sessionContainer.surface) {d.surfaceInitialized = true;} }
72 }
71 }
73
72
74− Binding {
75− target: d.surface
76− when: d.surface
77− property: "enabled"
78− value: root.interactive
79− }
80− Binding {
81− target: d.surface
82− when: d.surface
83− property: "focus"
84− value: root.interactive
85− }
86 Connections {
73 Connections {
87− target: d.surface
74+ target: sessionContainer.surface
88 // FIXME: I would rather not need to do this, but currently it doesn't get
75 // FIXME: I would rather not need to do this, but currently it doesn't get
89 // active focus without it and I don't know why.
76 // active focus without it and I don't know why.
90− onFocusChanged: forceSurfaceActiveFocusIfReady();
77+ onFocusChanged: d.forceSurfaceActiveFocusIfReady();
91− onParentChanged: forceSurfaceActiveFocusIfReady();
78+ onParentChanged: d.forceSurfaceActiveFocusIfReady();
92− onEnabledChanged: forceSurfaceActiveFocusIfReady();
79+ onEnabledChanged: d.forceSurfaceActiveFocusIfReady();
93− function forceSurfaceActiveFocusIfReady() {
94− if (d.surface.focus && d.surface.parent === surfaceContainer && d.surface.enabled) {
95− d.surface.forceActiveFocus();
96− }
97− }
98− }
99−
100− SurfaceContainer {
101− id: surfaceContainer
102− objectName: "surfaceContainer"
103− anchors.fill: parent
104− surface: d.surface
105 }
80 }
106
81
107 Image {
82 Image {
@@ -126,24 +101,23 @@ Item {
126 id: splashLoader
101 id: splashLoader
127 visible: active
102 visible: active
128 active: false
103 active: false
129− anchors.fill: surfaceContainer
104+ anchors.fill: parent
130 sourceComponent: Component {
105 sourceComponent: Component {
131 Splash { name: d.name; image: d.icon }
106 Splash { name: d.name; image: d.icon }
132 }
107 }
133 }
108 }
134
109
135− Repeater {
110+ SessionContainer {
136− model: d.promptSurfaces
111+ id: sessionContainer
137−
112+ session: application ? application.session : null
138− delegate: SurfaceContainer {
139− anchors {
113+ anchors.fill: parent
140− fill: surfaceContainer
141− }
142−
143− surface: modelData
144
114
145− Component.onCompleted: {
115+ onSurfaceChanged: {
146− animateIn();
116+ if (sessionContainer.surface) {
117+ surfaceInitTimer.start();
118+ d.forceSurfaceActiveFocusIfReady();
119+ } else {
120+ d.surfaceInitialized = false;
147 }
121 }
148 }
122 }
149 }
123 }
@@ -154,23 +128,23 @@ Item {
154 State {
128 State {
155 name: "void"
129 name: "void"
156 when:
130 when:
157− d.hadSurface && (!d.surface || !d.surfaceInitialized)
131+ d.hadSurface && (!sessionContainer.surface || !d.surfaceInitialized)
158 &&
132 &&
159 screenshotImage.status !== Image.Ready
133 screenshotImage.status !== Image.Ready
160 },
134 },
161 State {
135 State {
162 name: "splashScreen"
136 name: "splashScreen"
163 when:
137 when:
164− !d.hadSurface && (!d.surface || !d.surfaceInitialized)
138+ !d.hadSurface && (!sessionContainer.surface || !d.surfaceInitialized)
165 &&
139 &&
166 screenshotImage.status !== Image.Ready
140 screenshotImage.status !== Image.Ready
167 },
141 },
168 State {
142 State {
169 name: "surface"
143 name: "surface"
170 when:
144 when:
171− (d.surface && d.surfaceInitialized)
145+ (sessionContainer.surface && d.surfaceInitialized)
172 &&
146 &&
173− (d.applicationState !== ApplicationInfo.Stopped
147+ (d.applicationState !== ApplicationInfoInterface.Stopped
174 || screenshotImage.status !== Image.Ready)
148 || screenshotImage.status !== Image.Ready)
175 },
149 },
176 State {
150 State {
@@ -178,8 +152,8 @@ Item {
178 when:
152 when:
179 screenshotImage.status === Image.Ready
153 screenshotImage.status === Image.Ready
180 &&
154 &&
181− (d.applicationState === ApplicationInfo.Stopped
155+ (d.applicationState === ApplicationInfoInterface.Stopped
182− || !d.surface || !d.surfaceInitialized)
156+ || !sessionContainer.surface || !d.surfaceInitialized)
183 }
157 }
184 ]
158 ]
185
159
@@ -187,14 +161,18 @@ Item {
187 Transition {
161 Transition {
188 from: ""; to: "splashScreen"
162 from: ""; to: "splashScreen"
189 PropertyAction { target: splashLoader; property: "active"; value: true }
163 PropertyAction { target: splashLoader; property: "active"; value: true }
164+ PropertyAction { target: sessionContainer.surfaceContainer
165+ property: "visible"; value: false }
190 },
166 },
191 Transition {
167 Transition {
192 from: "splashScreen"; to: "surface"
168 from: "splashScreen"; to: "surface"
193 SequentialAnimation {
169 SequentialAnimation {
194− PropertyAction { target: surfaceContainer
170+ PropertyAction { target: sessionContainer.surfaceContainer
171+ property: "opacity"; value: 0.0 }
172+ PropertyAction { target: sessionContainer.surfaceContainer
195 property: "visible"; value: true }
173 property: "visible"; value: true }
196− UbuntuNumberAnimation { target: splashLoader; property: "opacity";
174+ UbuntuNumberAnimation { target: sessionContainer.surfaceContainer; property: "opacity";
197− from: 1.0; to: 0.0
175+ from: 0.0; to: 1.0
198 duration: UbuntuAnimation.BriskDuration }
176 duration: UbuntuAnimation.BriskDuration }
199 PropertyAction { target: splashLoader; property: "active"; value: false }
177 PropertyAction { target: splashLoader; property: "active"; value: false }
200 }
178 }
@@ -203,11 +181,13 @@ Item {
203 from: "surface"; to: "splashScreen"
181 from: "surface"; to: "splashScreen"
204 SequentialAnimation {
182 SequentialAnimation {
205 PropertyAction { target: splashLoader; property: "active"; value: true }
183 PropertyAction { target: splashLoader; property: "active"; value: true }
206− PropertyAction { target: surfaceContainer
184+ PropertyAction { target: sessionContainer.surfaceContainer
207 property: "visible"; value: true }
185 property: "visible"; value: true }
208 UbuntuNumberAnimation { target: splashLoader; property: "opacity";
186 UbuntuNumberAnimation { target: splashLoader; property: "opacity";
209 from: 0.0; to: 1.0
187 from: 0.0; to: 1.0
210 duration: UbuntuAnimation.BriskDuration }
188 duration: UbuntuAnimation.BriskDuration }
189+ PropertyAction { target: sessionContainer.surfaceContainer
190+ property: "visible"; value: false }
211 }
191 }
212 },
192 },
213 Transition {
193 Transition {
@@ -218,15 +198,15 @@ Item {
218 UbuntuNumberAnimation { target: screenshotImage; property: "opacity";
198 UbuntuNumberAnimation { target: screenshotImage; property: "opacity";
219 from: 0.0; to: 1.0
199 from: 0.0; to: 1.0
220 duration: UbuntuAnimation.BriskDuration }
200 duration: UbuntuAnimation.BriskDuration }
221− PropertyAction { target: surfaceContainer
201+ PropertyAction { target: sessionContainer.surfaceContainer
222 property: "visible"; value: false }
202 property: "visible"; value: false }
223− ScriptAction { script: { if (d.surface) { d.surface.release(); } } }
203+ ScriptAction { script: { if (sessionContainer.session) { sessionContainer.session.release(); } } }
224 }
204 }
225 },
205 },
226 Transition {
206 Transition {
227 from: "screenshot"; to: "surface"
207 from: "screenshot"; to: "surface"
228 SequentialAnimation {
208 SequentialAnimation {
229− PropertyAction { target: surfaceContainer
209+ PropertyAction { target: sessionContainer.surfaceContainer
230 property: "visible"; value: true }
210 property: "visible"; value: true }
231 UbuntuNumberAnimation { target: screenshotImage; property: "opacity";
211 UbuntuNumberAnimation { target: screenshotImage; property: "opacity";
232 from: 1.0; to: 0.0
212 from: 1.0; to: 0.0
@@ -238,16 +218,16 @@ Item {
238 Transition {
218 Transition {
239 from: "surface"; to: "void"
219 from: "surface"; to: "void"
240 SequentialAnimation {
220 SequentialAnimation {
241− PropertyAction { target: surfaceContainer; property: "visible"; value: false }
221+ PropertyAction { target: sessionContainer.surfaceContainer; property: "visible"; value: false }
242− ScriptAction { script: { if (d.surface) { d.surface.release(); } } }
222+ ScriptAction { script: { if (sessionContainer.session) { sessionContainer.session.release(); } } }
243 }
223 }
244 },
224 },
245 Transition {
225 Transition {
246 from: "void"; to: "surface"
226 from: "void"; to: "surface"
247 SequentialAnimation {
227 SequentialAnimation {
248− PropertyAction { target: surfaceContainer; property: "opacity"; value: 0.0 }
228+ PropertyAction { target: sessionContainer.surfaceContainer; property: "opacity"; value: 0.0 }
249− PropertyAction { target: surfaceContainer; property: "visible"; value: true }
229+ PropertyAction { target: sessionContainer.surfaceContainer; property: "visible"; value: true }
250− UbuntuNumberAnimation { target: surfaceContainer; property: "opacity";
230+ UbuntuNumberAnimation { target: sessionContainer.surfaceContainer; property: "opacity";
251 from: 0.0; to: 1.0
231 from: 0.0; to: 1.0
252 duration: UbuntuAnimation.BriskDuration }
232 duration: UbuntuAnimation.BriskDuration }
253 }
233 }
qml/Stages/PhoneStage.qml+6−1
@@ -44,6 +44,9 @@ Rectangle {
44 }
44 }
45
45
46 onInverseProgressChanged: {
46 onInverseProgressChanged: {
47+ // This can't be a simple binding because that would be triggered after this handler
48+ // while we need it active before doing the anition left/right
49+ priv.animateX = (inverseProgress == 0)
47 if (inverseProgress == 0 && priv.oldInverseProgress > 0) {
50 if (inverseProgress == 0 && priv.oldInverseProgress > 0) {
48 // left edge drag released. Minimum distance is given by design.
51 // left edge drag released. Minimum distance is given by design.
49 if (priv.oldInverseProgress > units.gu(22)) {
52 if (priv.oldInverseProgress > units.gu(22)) {
@@ -92,6 +95,7 @@ Rectangle {
92 property var focusedAppDelegate: null
95 property var focusedAppDelegate: null
93
96
94 property real oldInverseProgress: 0
97 property real oldInverseProgress: 0
98+ property bool animateX: true
95
99
96 onFocusedAppIdChanged: focusedAppDelegate = spreadRepeater.itemAt(0);
100 onFocusedAppIdChanged: focusedAppDelegate = spreadRepeater.itemAt(0);
97
101
@@ -311,7 +315,8 @@ Rectangle {
311 Behavior on x {
315 Behavior on x {
312 enabled: root.spreadEnabled &&
316 enabled: root.spreadEnabled &&
313 !spreadView.active &&
317 !spreadView.active &&
314− !snapAnimation.running
318+ !snapAnimation.running &&
319+ priv.animateX
315 UbuntuNumberAnimation {
320 UbuntuNumberAnimation {
316 duration: UbuntuAnimation.FastDuration
321 duration: UbuntuAnimation.FastDuration
317 onRunningChanged: {
322 onRunningChanged: {
qml/Stages/SessionContainer.qmlnew file+143
@@ -0,0 +1,143 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+*/
16+
17+import QtQuick 2.0
18+import "Animations"
19+
20+Item {
21+ id: root
22+ objectName: "sessionContainer"
23+ property QtObject session
24+ readonly property var childSessions: session ? session.childSessions : null
25+ readonly property alias surface: _surfaceContainer.surface
26+ property bool interactive: true
27+
28+ readonly property alias surfaceContainer: _surfaceContainer
29+ SurfaceContainer {
30+ id: _surfaceContainer
31+ anchors.fill: parent
32+ surface: session ? session.surface : null
33+ }
34+
35+ Binding {
36+ target: surfaceContainer.surface
37+ when: surfaceContainer.surface
38+ property: "enabled"
39+ value: root.interactive
40+ }
41+ Binding {
42+ target: surfaceContainer.surface
43+ when: surfaceContainer.surface
44+ property: "focus"
45+ value: root.interactive
46+ }
47+
48+ Repeater {
49+ model: root.childSessions
50+
51+ delegate: Loader {
52+ objectName: "childDelegate" + index
53+ anchors.fill: surfaceContainer
54+
55+ // Only way to do recursive qml items.
56+ source: Qt.resolvedUrl("SessionContainer.qml")
57+
58+ Binding {
59+ target: item; when: item
60+ property: "interactive"; value: root.interactive
61+ }
62+
63+ Binding {
64+ target: item; when: item
65+ property: "session"; value: modelData
66+ }
67+
68+ Binding {
69+ target: item; when: item
70+ property: "width"; value: root.width
71+ }
72+
73+ Binding {
74+ target: item; when: item
75+ property: "height"; value: root.height
76+ }
77+ }
78+ }
79+
80+ states: [
81+ State {
82+ name: "rootSession"
83+ when: root.session && !root.session.parentSession
84+ },
85+
86+ State {
87+ name: "childSession"
88+ when: root.session && root.session.parentSession !== null && root.session.live
89+ && !root.session.surface
90+ },
91+
92+ State {
93+ name: "childSessionReady"
94+ when: root.session && root.session.parentSession !== null && root.session.live
95+ && root.session.surface !== null
96+ },
97+
98+ State {
99+ name: "childSessionZombie"
100+ when: root.session && root.session.parentSession !== null && !root.session.live
101+ }
102+ ]
103+
104+ transitions: [
105+ Transition {
106+ to: "childSessionReady"
107+ ScriptAction { script: { if (!surfaceContainer.hadSurface) { animateIn(swipeFromBottom); } } }
108+ },
109+ Transition {
110+ to: "childSessionZombie"
111+ ScriptAction { script: { animateOut(); } }
112+ }
113+ ]
114+
115+ function animateIn(component) {
116+ var animation = component.createObject(root, { "container": root, });
117+ animation.start();
118+
119+ var tmp = d.animations;
120+ tmp.push(animation);
121+ d.animations = tmp;
122+ }
123+
124+ function animateOut() {
125+ if (d.animations.length > 0) {
126+ var tmp = d.animations;
127+ var popped = tmp.pop();
128+ popped.completed.connect(function() { root.session.release(); } );
129+ popped.end();
130+ d.animations = tmp;
131+ }
132+ }
133+
134+ Component {
135+ id: swipeFromBottom
136+ SwipeFromBottomAnimation {}
137+ }
138+
139+ QtObject {
140+ id: d
141+ property var animations: []
142+ }
143+}
qml/Stages/SurfaceContainer.qml+22−67
@@ -15,86 +15,41 @@
15*/
15*/
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18−import "Animations"
18+import Ubuntu.Components 1.1
19
19
20Item {
20Item {
21− id: container
21+ id: root
22+ objectName: "surfaceContainer"
22 property Item surface: null
23 property Item surface: null
23− property bool removing: false
24+ property bool hadSurface: false
24
25
25 onSurfaceChanged: {
26 onSurfaceChanged: {
26 if (surface) {
27 if (surface) {
27− surface.parent = container;
28+ surface.parent = root;
28− surface.z = 1;
29+ } else {
30+ hadSurface = true;
29 }
31 }
30 }
32 }
31 Binding {
33 Binding {
32 target: surface
34 target: surface
33− property: "anchors.fill"; value: container
35+ property: "anchors.fill"; value: root
34 }
36 }
35
37
36− Connections {
38+ states: [
37− target: surface
39+ State {
38− onRemoved: {
40+ name: "zombie"
39− container.removing = true;
41+ when: surface && !surface.live
40−
41− var childSurfaces = surface.childSurfaces;
42− for (var i=0; i<childSurfaces.length; i++) {
43− childSurfaces[i].removed();
44− }
45−
46− animateOut();
47 }
42 }
48− }
43+ ]
49−
44+ transitions: [
50− Repeater {
45+ Transition {
51− model: surface ? surface.childSurfaces : null
46+ from: ""; to: "zombie"
52−
47+ SequentialAnimation {
53− delegate: Loader {
48+ UbuntuNumberAnimation { target: surface; property: "opacity"; to: 0.0
54− z: 2
49+ duration: UbuntuAnimation.BriskDuration }
55− anchors {
50+ PropertyAction { target: surface; property: "visible"; value: false }
56− fill: container
51+ ScriptAction { script: { if (root.surface) { root.surface.release(); } } }
57− topMargin: container.surface.anchors.topMargin
58− rightMargin: container.surface.anchors.rightMargin
59− bottomMargin: container.surface.anchors.bottomMargin
60− leftMargin: container.surface.anchors.leftMargin
61 }
52 }
62−
63− // Only way to do recursive qml items.
64− source: Qt.resolvedUrl("SurfaceContainer.qml")
65− onLoaded: {
66− item.surface = modelData;
67− item.animateIn();
68− }
69− }
70− }
71−
72− function animateIn() {
73− var animation = swipeFromBottom.createObject(container, { "surface": container.surface });
74− animation.start();
75−
76− var tmp = d.animations;
77− tmp.push(animation);
78− d.animations = tmp;
79− }
80−
81− function animateOut() {
82− if (d.animations.length > 0) {
83− var tmp = d.animations;
84− var popped = tmp.pop();
85− popped.end();
86− d.animations = tmp;
87 }
53 }
88− }
54+ ]
89−
90− QtObject {
91− id: d
92− property var animations: []
93− property var currentAnimation: animations.length > 0 ? animations[animations.length-1] : undefined
94− }
95−
96− Component {
97− id: swipeFromBottom
98− SwipeFromBottomAnimation {}
99− }
100}
55}
qml/Stages/TabletStage.qml+5
@@ -36,6 +36,9 @@ Rectangle {
36 property real inverseProgress: 0 // This is the progress for left edge drags, in pixels.
36 property real inverseProgress: 0 // This is the progress for left edge drags, in pixels.
37
37
38 onInverseProgressChanged: {
38 onInverseProgressChanged: {
39+ // This can't be a simple binding because that would be triggered after this handler
40+ // while we need it active before doing the anition left/right
41+ spreadView.animateX = (inverseProgress == 0)
39 if (inverseProgress == 0 && priv.oldInverseProgress > 0) {
42 if (inverseProgress == 0 && priv.oldInverseProgress > 0) {
40 // left edge drag released. Minimum distance is given by design.
43 // left edge drag released. Minimum distance is given by design.
41 if (priv.oldInverseProgress > units.gu(22)) {
44 if (priv.oldInverseProgress > units.gu(22)) {
@@ -193,6 +196,8 @@ Rectangle {
193 property int draggedDelegateCount: 0
196 property int draggedDelegateCount: 0
194 property int closingIndex: -1
197 property int closingIndex: -1
195
198
199+ property bool animateX: true
200+
196 property bool sideStageDragging: sideStageDragHandle.dragging
201 property bool sideStageDragging: sideStageDragHandle.dragging
197 property real sideStageDragProgress: sideStageDragHandle.progress
202 property real sideStageDragProgress: sideStageDragHandle.progress
198
203
qml/Stages/TransformedTabletSpreadDelegate.qml+2−1
@@ -138,7 +138,8 @@ SpreadDelegate {
138 enabled: !spreadView.active &&
138 enabled: !spreadView.active &&
139 !snapAnimation.running &&
139 !snapAnimation.running &&
140 model.appId !== "unity8-dash" &&
140 model.appId !== "unity8-dash" &&
141− !spreadView.sideStageDragging
141+ !spreadView.sideStageDragging &&
142+ spreadView.animateX
142 UbuntuNumberAnimation {
143 UbuntuNumberAnimation {
143 duration: UbuntuAnimation.FastDuration
144 duration: UbuntuAnimation.FastDuration
144 }
145 }
run_on_device.sh+43−41
@@ -4,8 +4,8 @@ USER=phablet
4USER_ID=32011
4USER_ID=32011
5PACKAGE=unity8
5PACKAGE=unity8
6BINARY=unity8
6BINARY=unity8
7−TARGET_IP=${TARGET_IP-127.0.0.1}
7+TARGET_IP=127.0.0.1
8−TARGET_SSH_PORT=${TARGET_SSH_PORT-2222}
8+TARGET_SSH_PORT=2222
9TARGET_DEBUG_PORT=3768
9TARGET_DEBUG_PORT=3768
10RUN_OPTIONS=-qmljsdebugger=port:$TARGET_DEBUG_PORT
10RUN_OPTIONS=-qmljsdebugger=port:$TARGET_DEBUG_PORT
11SETUP=false
11SETUP=false
@@ -14,18 +14,23 @@ PINLOCK=false
14KEYLOCK=false
14KEYLOCK=false
15NUM_JOBS='$(( `grep -c ^processor /proc/cpuinfo` + 1 ))'
15NUM_JOBS='$(( `grep -c ^processor /proc/cpuinfo` + 1 ))'
16FLIPPED=false
16FLIPPED=false
17−CHROOT_PREFIX="/data/ubuntu"
18SSH_WAS_STARTED=0
17SSH_WAS_STARTED=0
19SSH_STARTED=0
18SSH_STARTED=0
19+PASSWORD=""
20+PASSFILE=""
20
21
21usage() {
22usage() {
22− echo "usage: run_on_device [OPTIONS]\n"
23+ echo "usage: run_on_device -a SUDO_PASSWORD [OPTIONS]"
24+ echo
23− echo "Script to setup a build environment for the shell and sync build and run it on the device\n"
25+ echo "Script to setup a build environment for the shell and sync build and run it on the device"
26+ echo
24 echo "OPTIONS:"
27 echo "OPTIONS:"
28+ echo " -a, --password The sudo password to use"
25− echo " -s, --setup Setup the build environment"
29+ echo " -s, --setup Setup the build environment"
30+ echo " -g, --gdb Run with gdb"
26− echo " -p, --pinlock Enable a PIN lock screen when running"
31+ echo " -p, --pinlock Enable a PIN lock screen when running"
27− echo " -k, --keylock Enable a Keyboard lock screen when running"
32+ echo " -k, --keylock Enable a Keyboard lock screen when running"
28− echo ""
33+ echo
29 echo "IMPORTANT:"
34 echo "IMPORTANT:"
30 echo " * Make sure to have networking setup on the device beforehand."
35 echo " * Make sure to have networking setup on the device beforehand."
31 echo " * Execute that script from a directory containing unity8 code."
36 echo " * Execute that script from a directory containing unity8 code."
@@ -34,7 +39,7 @@ usage() {
34
39
35start_ssh() {
40start_ssh() {
36 if [ $SSH_STARTED -eq 0 ]; then
41 if [ $SSH_STARTED -eq 0 ]; then
37− exec_with_adb initctl start ssh
42+ adb_sudo initctl start ssh
38 SSH_STARTED=1
43 SSH_STARTED=1
39 fi
44 fi
40}
45}
@@ -44,25 +49,13 @@ exec_with_ssh() {
44 ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -t $USER@$TARGET_IP -p $TARGET_SSH_PORT sudo -u $USER -i bash -ic \"$@\"
49 ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -t $USER@$TARGET_IP -p $TARGET_SSH_PORT sudo -u $USER -i bash -ic \"$@\"
45}
50}
46
51
47−exec_with_adb() {
52+adb_sudo() {
48− if $FLIPPED; then
53+ adb shell "SUDO_ASKPASS=${PASSFILE} sudo --askpass $@"
49− adb shell $@
50− else
51− adb shell chroot /data/ubuntu /usr/bin/env -i PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin "$@"
52− fi
53−}
54−
55−adb_root() {
56− adb root
57− adb wait-for-device
58}
54}
59
55
60install_ssh_key() {
56install_ssh_key() {
61− ssh-keygen -R $TARGET_IP
62− HOME_DIR="${CHROOT_PREFIX}/home/phablet"
57+ HOME_DIR="/home/phablet"
63 adb push ~/.ssh/id_rsa.pub $HOME_DIR/.ssh/authorized_keys
58 adb push ~/.ssh/id_rsa.pub $HOME_DIR/.ssh/authorized_keys
64− adb shell chown $USER_ID:$USER_ID $HOME_DIR/.ssh
65− adb shell chown $USER_ID:$USER_ID $HOME_DIR/.ssh/authorized_keys
66 adb shell chmod 700 $HOME_DIR/.ssh
59 adb shell chmod 700 $HOME_DIR/.ssh
67 adb shell chmod 600 $HOME_DIR/.ssh/authorized_keys
60 adb shell chmod 600 $HOME_DIR/.ssh/authorized_keys
68}
61}
@@ -73,8 +66,14 @@ setup_adb_forwarding() {
73}
66}
74
67
75install_dependencies() {
68install_dependencies() {
76− exec_with_adb apt-get update
69+ phablet-config writable-image --remotepassword ${PASSWORD} -p build-essential \
77− exec_with_adb apt-get -y --force-yes install build-essential rsync bzr ccache gdb ninja-build devscripts equivs unity-plugin-scopes
70+ -p rsync \
71+ -p bzr \
72+ -p ccache \
73+ -p gdb \
74+ -p ninja-build \
75+ -p devscripts \
76+ -p equivs
78}
77}
79
78
80sync_code() {
79sync_code() {
@@ -108,12 +107,13 @@ run() {
108 exec_with_ssh "start unity8"
107 exec_with_ssh "start unity8"
109}
108}
110
109
111−set -- `getopt -n$0 -u -a --longoptions="setup,gdb,pinlock,keylock,help" "sgpkh" "$@"`
110+set -- `getopt -n$0 -u -a --longoptions="password:,setup,gdb,pinlock,keylock,help" "a:sgpkh" "$@"`
112
111
113# FIXME: giving incorrect arguments does not call usage and exit
112# FIXME: giving incorrect arguments does not call usage and exit
114while [ $# -gt 0 ]
113while [ $# -gt 0 ]
115do
114do
116 case "$1" in
115 case "$1" in
116+ -a|--password) PASSWORD=$2;;
117 -s|--setup) SETUP=true;;
117 -s|--setup) SETUP=true;;
118 -g|--gdb) GDB=true;;
118 -g|--gdb) GDB=true;;
119 -p|--pinlock) PINLOCK=true;;
119 -p|--pinlock) PINLOCK=true;;
@@ -124,21 +124,21 @@ do
124 shift
124 shift
125done
125done
126
126
127+if [ -z "${PASSWORD}" ]; then
128+ echo "ERROR: You need to provide a sudo password..."
129+ echo
130+ usage
131+fi
127
132
128−adb_root
133+PASSFILE=$( adb shell "FILE=\`mktemp\`
129−[ "${TARGET_IP}" = "127.0.0.1" ] && setup_adb_forwarding
134+ echo \"#!/bin/sh\" > \$FILE
135+ echo \"echo \\\"${PASSWORD}\\\"\" >> \$FILE
136+ chmod +x \$FILE
137+ echo \$FILE" | tr -d '\r' )
130
138
131−if [ "`adb shell 'grep -q Ubuntu /etc/lsb-release 2> /dev/null && echo -n FLIPPED'`" = "FLIPPED" ]; then
139+setup_adb_forwarding
132− FLIPPED=true
133− CHROOT_PREFIX=""
134− if [ "${TARGET_IP}" != "127.0.0.1" ]; then
135− echo "ERROR: Flipped image detected, adb over TCP/IP isn't supported, yet :/"
136− echo "Unset TARGET_IP and try again."
137− exit 2
138− fi
139−fi
140
140
141−status_output=$(exec_with_adb initctl status ssh)
141+status_output=$(adb_sudo initctl status ssh)
142if [[ $status_output == "ssh start/running, process "* ]]; then
142if [[ $status_output == "ssh start/running, process "* ]]; then
143 SSH_WAS_STARTED=1
143 SSH_WAS_STARTED=1
144fi
144fi
@@ -158,6 +158,8 @@ else
158 run
158 run
159fi
159fi
160
160
161+adb shell "rm ${PASSFILE}"
162+
161if [ $SSH_WAS_STARTED -eq 0 ]; then
163if [ $SSH_WAS_STARTED -eq 0 ]; then
162− exec_with_adb initctl stop ssh
164+ adb_sudo initctl stop ssh
163fi
165fi
tests/autopilot/unity8/application_lifecycle/tests/test_application_lifecycle.py+4−2
@@ -97,7 +97,8 @@ class ApplicationLifecycleTests(tests.ApplicationLifeCycleTestCase):
97 self.assertThat(greeter.created, Eventually(Equals(True)))
97 self.assertThat(greeter.created, Eventually(Equals(True)))
98
98
99 application_name = self.launch_fake_app()
99 application_name = self.launch_fake_app()
100− self.assertThat(greeter.created, Eventually(Equals(False)))
100+ greeter.wait_swiped_away()
101+ process_helpers.unlock_unity()
101 self.assert_current_focused_application(application_name)
102 self.assert_current_focused_application(application_name)
102
103
103 def test_greeter_hides_on_app_focus(self):
104 def test_greeter_hides_on_app_focus(self):
@@ -113,7 +114,8 @@ class ApplicationLifecycleTests(tests.ApplicationLifeCycleTestCase):
113 self.assertThat(greeter.created, Eventually(Equals(True)))
114 self.assertThat(greeter.created, Eventually(Equals(True)))
114
115
115 self.launch_upstart_application(application_name)
116 self.launch_upstart_application(application_name)
116− self.assertThat(greeter.created, Eventually(Equals(False)))
117+ greeter.wait_swiped_away()
118+ process_helpers.unlock_unity()
117 self.assert_current_focused_application(application_name)
119 self.assert_current_focused_application(application_name)
118
120
119 def test_click_dash_icon_must_unfocus_application(self):
121 def test_click_dash_icon_must_unfocus_application(self):
tests/autopilot/unity8/process_helpers.py+12−17
@@ -20,6 +20,7 @@
20import logging
20import logging
21import subprocess
21import subprocess
22import sys
22import sys
23+import dbus
23
24
24# This has to work in both python 3 (ap 1.5) and py2 (ap legacy 1.4.1) so we
25# This has to work in both python 3 (ap 1.5) and py2 (ap legacy 1.4.1) so we
25# pick the correct location in each case. Remove the py2 branch once we no
26# pick the correct location in each case. Remove the py2 branch once we no
@@ -82,22 +83,16 @@ def unlock_unity(unity_proxy_obj=None):
82 if greeter.created is False:
83 if greeter.created is False:
83 raise RuntimeWarning("Greeter appears to be already unlocked.")
84 raise RuntimeWarning("Greeter appears to be already unlocked.")
84
85
85− # Because of potential input jerkiness under heavy load,
86+ bus = dbus.SessionBus()
86− # retry unlocking the greeter two times.
87+ dbus_proxy = bus.get_object("com.canonical.UnityGreeter", "/")
87− # https://bugs.launchpad.net/ubuntu/+bug/1260113
88−
89− retries = 3
90− while retries > 0:
91− try:
88+ try:
92− greeter.swipe()
89+ dbus_proxy.HideGreeter()
93− except AssertionError:
90+ except dbus.DBusException:
94− retries -= 1
95− if retries == 0:
96− raise
97− logger.info("Failed to unlock greeter, trying again...")
91+ logger.info("Failed to unlock greeter")
92+ raise
98− else:
93+ else:
94+ greeter.created.wait_for(False)
99− logger.info("Greeter unlocked, continuing.")
95+ logger.info("Greeter unlocked, continuing.")
100− break
101
96
102
97
103def lock_unity(unity_proxy_obj=None):
98def lock_unity(unity_proxy_obj=None):
@@ -198,7 +193,7 @@ def get_job_status(name):
198 ], universal_newlines=True)
193 ], universal_newlines=True)
199 except subprocess.CalledProcessError as error:
194 except subprocess.CalledProcessError as error:
200 raise JobError(
195 raise JobError(
201− "Unable to get {}'s status: {}".format(name, error)
196+ "Unable to get {}'s status: {}".format(name, error)
202 )
197 )
203
198
204
199
tests/autopilot/unity8/shell/emulators/greeter.py+4−1
@@ -25,6 +25,9 @@ from unity8.shell.emulators import UnityEmulatorBase
25class Greeter(UnityEmulatorBase):
25class Greeter(UnityEmulatorBase):
26 """An emulator that understands the greeter screen."""
26 """An emulator that understands the greeter screen."""
27
27
28+ def wait_swiped_away(self):
29+ self.showProgress.wait_for(0)
30+
28 def swipe(self):
31 def swipe(self):
29 """Swipe the greeter screen away."""
32 """Swipe the greeter screen away."""
30 self.created.wait_for(True)
33 self.created.wait_for(True)
@@ -37,7 +40,7 @@ class Greeter(UnityEmulatorBase):
37 stop_y = start_y
40 stop_y = start_y
38 self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
41 self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
39
42
40− self.showProgress.wait_for(0)
43+ self.wait_swiped_away()
41
44
42 def get_prompt(self):
45 def get_prompt(self):
43 return self.select_single(
46 return self.select_single(
tests/autopilot/unity8/shell/tests/test_lock_screen.py+8−9
@@ -20,7 +20,6 @@
20
20
21from __future__ import absolute_import
21from __future__ import absolute_import
22
22
23−from unity8.process_helpers import unlock_unity
24from unity8.shell import with_lightdm_mock
23from unity8.shell import with_lightdm_mock
25from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
24from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
26
25
@@ -45,11 +44,11 @@ class TestLockscreen(UnityTestCase):
45 @with_lightdm_mock("single-pin")
44 @with_lightdm_mock("single-pin")
46 def test_can_unlock_pin_screen(self):
45 def test_can_unlock_pin_screen(self):
47 """Must be able to unlock the PIN entry lock screen."""
46 """Must be able to unlock the PIN entry lock screen."""
48− unity_proxy = self.launch_unity()
47+ self.launch_unity()
49 greeter = self.main_window.get_greeter()
48 greeter = self.main_window.get_greeter()
50
49
51 if greeter.narrowMode:
50 if greeter.narrowMode:
52− unlock_unity(unity_proxy)
51+ greeter.swipe()
53 lockscreen = self._wait_for_lockscreen()
52 lockscreen = self._wait_for_lockscreen()
54 self.main_window.enter_pin_code("1234")
53 self.main_window.enter_pin_code("1234")
55 self.assertThat(lockscreen.shown, Eventually(Equals(False)))
54 self.assertThat(lockscreen.shown, Eventually(Equals(False)))
@@ -60,11 +59,11 @@ class TestLockscreen(UnityTestCase):
60 @with_lightdm_mock("single-passphrase")
59 @with_lightdm_mock("single-passphrase")
61 def test_can_unlock_passphrase_screen(self):
60 def test_can_unlock_passphrase_screen(self):
62 """Must be able to unlock the passphrase entry screen."""
61 """Must be able to unlock the passphrase entry screen."""
63− unity_proxy = self.launch_unity()
62+ self.launch_unity()
64 greeter = self.main_window.get_greeter()
63 greeter = self.main_window.get_greeter()
65
64
66 if greeter.narrowMode:
65 if greeter.narrowMode:
67− unlock_unity(unity_proxy)
66+ greeter.swipe()
68 lockscreen = self._wait_for_lockscreen()
67 lockscreen = self._wait_for_lockscreen()
69 self._enter_pin_passphrase("password")
68 self._enter_pin_passphrase("password")
70 self.assertThat(lockscreen.shown, Eventually(Equals(False)))
69 self.assertThat(lockscreen.shown, Eventually(Equals(False)))
@@ -75,11 +74,11 @@ class TestLockscreen(UnityTestCase):
75 @with_lightdm_mock("single-pin")
74 @with_lightdm_mock("single-pin")
76 def test_pin_screen_wrong_code(self):
75 def test_pin_screen_wrong_code(self):
77 """Entering the wrong pin code must not dismiss the lock screen."""
76 """Entering the wrong pin code must not dismiss the lock screen."""
78− unity_proxy = self.launch_unity()
77+ self.launch_unity()
79 greeter = self.main_window.get_greeter()
78 greeter = self.main_window.get_greeter()
80
79
81 if greeter.narrowMode:
80 if greeter.narrowMode:
82− unlock_unity(unity_proxy)
81+ greeter.swipe()
83 lockscreen = self._wait_for_lockscreen()
82 lockscreen = self._wait_for_lockscreen()
84 self.main_window.enter_pin_code("4321")
83 self.main_window.enter_pin_code("4321")
85 pinentryField = self.main_window.get_pinentryField()
84 pinentryField = self.main_window.get_pinentryField()
@@ -94,11 +93,11 @@ class TestLockscreen(UnityTestCase):
94 @with_lightdm_mock("single-passphrase")
93 @with_lightdm_mock("single-passphrase")
95 def test_passphrase_screen_wrong_password(self):
94 def test_passphrase_screen_wrong_password(self):
96 """Entering the wrong password must not dismiss the lock screen."""
95 """Entering the wrong password must not dismiss the lock screen."""
97− unity_proxy = self.launch_unity()
96+ self.launch_unity()
98 greeter = self.main_window.get_greeter()
97 greeter = self.main_window.get_greeter()
99
98
100 if greeter.narrowMode:
99 if greeter.narrowMode:
101− unlock_unity(unity_proxy)
100+ greeter.swipe()
102 lockscreen = self._wait_for_lockscreen()
101 lockscreen = self._wait_for_lockscreen()
103 self._enter_pin_passphrase("foobar")
102 self._enter_pin_passphrase("foobar")
104 pinentryField = self.main_window.get_pinentryField()
103 pinentryField = self.main_window.get_pinentryField()
tests/autopilot/unity8/shell/tests/test_notifications.py+61−97
@@ -135,10 +135,7 @@ class InteractiveNotificationBase(NotificationsBase):
135 actions = [("action_id", "dummy")]
135 actions = [("action_id", "dummy")]
136 hints = [
136 hints = [
137 ("x-canonical-switch-to-application", "true"),
137 ("x-canonical-switch-to-application", "true"),
138− (
139− "x-canonical-secondary-icon",
138+ ("x-canonical-secondary-icon","dialer")
140− self._get_icon_path('applicationIcons/dialer-app.png')
141− )
142 ]
139 ]
143
140
144 self._create_interactive_notification(
141 self._create_interactive_notification(
@@ -170,20 +167,19 @@ class InteractiveNotificationBase(NotificationsBase):
170 body = "Frank Zappa\n+44 (0)7736 027340"
167 body = "Frank Zappa\n+44 (0)7736 027340"
171 icon_path = self._get_icon_path('avatars/anna_olsson.png')
168 icon_path = self._get_icon_path('avatars/anna_olsson.png')
172 hints = [
169 hints = [
173− (
174− "x-canonical-secondary-icon",
170+ ("x-canonical-secondary-icon", "incoming-call"),
175− self._get_icon_path('applicationIcons/dialer-app.png')
176− ),
177 ("x-canonical-snap-decisions", "true"),
171 ("x-canonical-snap-decisions", "true"),
172+ ("x-canonical-private-affirmative-tint", "true"),
173+ ("x-canonical-private-rejection-tint", "true"),
178 ]
174 ]
179
175
180 actions = [
176 actions = [
181 ('action_accept', 'Hold + Answer'),
177 ('action_accept', 'Hold + Answer'),
182 ('action_decline_1', 'End + Answer'),
178 ('action_decline_1', 'End + Answer'),
183 ('action_decline_2', 'Decline'),
179 ('action_decline_2', 'Decline'),
184− ('action_decline_3', 'messages:I missed your call - can you call me now?'),
180+ ('action_decline_3', 'message:I missed your call - can you call me now?'),
185− ('action_decline_4', 'messages:I\'m running late. I\'m on my way.'),
181+ ('action_decline_4', 'message:I\'m running late. I\'m on my way.'),
186− ('action_decline_5', 'messages:I\'m busy at the moment. I\'ll call later.'),
182+ ('action_decline_5', 'message:I\'m busy at the moment. I\'ll call later.'),
187 ('action_decline_6', 'edit:Custom'),
183 ('action_decline_6', 'edit:Custom'),
188 ]
184 ]
189
185
@@ -204,13 +200,53 @@ class InteractiveNotificationBase(NotificationsBase):
204 notification.pointing_device.click_object(
200 notification.pointing_device.click_object(
205 notification.select_single(objectName="combobutton_dropdown"))
201 notification.select_single(objectName="combobutton_dropdown"))
206 self.assertThat(
202 self.assertThat(
207− notification.select_single(objectName="button2").expanded,
203+ notification.select_single(objectName="notify_button2").expanded,
208 Eventually(Equals(True)))
204 Eventually(Equals(True)))
209 time.sleep(2)
205 time.sleep(2)
210 notification.pointing_device.click_object(
206 notification.pointing_device.click_object(
211− notification.select_single(objectName="button4"))
207+ notification.select_single(objectName="notify_button4"))
212 self.assert_notification_action_id_was_called("action_decline_4")
208 self.assert_notification_action_id_was_called("action_decline_4")
213
209
210+
211+ def test_sd_one_over_two_layout(self):
212+ """Snap-decision with three actions should use one-over two button layout."""
213+ unity_proxy = self.launch_unity()
214+ unlock_unity(unity_proxy)
215+
216+ summary = "Theatre at Ferria Stadium"
217+ body = "at Ferria Stadium in Bilbao, Spain\n07578545317"
218+ hints = [
219+ ("x-canonical-snap-decisions", "true"),
220+ ("x-canonical-non-shaped-icon", "true"),
221+ ("x-canonical-private-affirmative-tint", "true")
222+ ]
223+
224+ actions = [
225+ ('action_accept', 'Ok'),
226+ ('action_decline_1', 'Snooze'),
227+ ('action_decline_2', 'View'),
228+ ]
229+
230+ self._create_interactive_notification(
231+ summary,
232+ body,
233+ None,
234+ "NORMAL",
235+ actions,
236+ hints
237+ )
238+
239+ # verify and interact with the triggered snap-decision notification
240+ notify_list = self._get_notifications_list()
241+ get_notification = lambda: notify_list.wait_select_single(
242+ 'Notification', objectName='notification1')
243+ notification = get_notification()
244+ self._assert_notification(
245+ notification, summary, body, False, False, 1.0)
246+ notification.pointing_device.click_object(
247+ notification.select_single(objectName="notify_oot_button0"))
248+ self.assert_notification_action_id_was_called("action_accept")
249+
214 def test_modal_sd_without_greeter(self):
250 def test_modal_sd_without_greeter(self):
215 """Snap-decision should block input to shell without greeter."""
251 """Snap-decision should block input to shell without greeter."""
216 unity_proxy = self.launch_unity()
252 unity_proxy = self.launch_unity()
@@ -222,6 +258,8 @@ class InteractiveNotificationBase(NotificationsBase):
222 hints = [
258 hints = [
223 ("x-canonical-snap-decisions", "true"),
259 ("x-canonical-snap-decisions", "true"),
224 ("x-canonical-non-shaped-icon", "true"),
260 ("x-canonical-non-shaped-icon", "true"),
261+ ("x-canonical-private-affirmative-tint", "true"),
262+ ("x-canonical-private-rejection-tint", "true"),
225 ]
263 ]
226
264
227 actions = [
265 actions = [
@@ -253,7 +291,7 @@ class InteractiveNotificationBase(NotificationsBase):
253 self._assert_notification(
291 self._assert_notification(
254 notification, summary, body, True, False, 1.0)
292 notification, summary, body, True, False, 1.0)
255 notification.pointing_device.click_object(
293 notification.pointing_device.click_object(
256− notification.select_single(objectName="button0"))
294+ notification.select_single(objectName="notify_button0"))
257 self.assert_notification_action_id_was_called("action_accept")
295 self.assert_notification_action_id_was_called("action_accept")
258
296
259 def test_modal_sd_with_greeter(self):
297 def test_modal_sd_with_greeter(self):
@@ -266,6 +304,8 @@ class InteractiveNotificationBase(NotificationsBase):
266 hints = [
304 hints = [
267 ("x-canonical-snap-decisions", "true"),
305 ("x-canonical-snap-decisions", "true"),
268 ("x-canonical-non-shaped-icon", "true"),
306 ("x-canonical-non-shaped-icon", "true"),
307+ ("x-canonical-private-affirmative-tint", "true"),
308+ ("x-canonical-private-rejection-tint", "true"),
269 ]
309 ]
270
310
271 actions = [
311 actions = [
@@ -296,7 +336,7 @@ class InteractiveNotificationBase(NotificationsBase):
296 self._assert_notification(
336 self._assert_notification(
297 notification, summary, body, True, False, 1.0)
337 notification, summary, body, True, False, 1.0)
298 notification.pointing_device.click_object(
338 notification.pointing_device.click_object(
299− notification.select_single(objectName="button0"))
339+ notification.select_single(objectName="notify_button0"))
300 self.assert_notification_action_id_was_called("action_accept")
340 self.assert_notification_action_id_was_called("action_accept")
301
341
302 def _create_interactive_notification(
342 def _create_interactive_notification(
@@ -438,10 +478,7 @@ class EphemeralNotificationsTests(NotificationsBase):
438 "join me and Anna?"
478 "join me and Anna?"
439 icon_path = self._get_icon_path('avatars/anna_olsson.png')
479 icon_path = self._get_icon_path('avatars/anna_olsson.png')
440 hints = [
480 hints = [
441− (
442− "x-canonical-secondary-icon",
481+ ("x-canonical-secondary-icon", "message")
443− self._get_icon_path('applicationIcons/dialer-app.png')
444− )
445 ]
482 ]
446
483
447 notification = shell.create_ephemeral_notification(
484 notification = shell.create_ephemeral_notification(
@@ -474,17 +511,13 @@ class EphemeralNotificationsTests(NotificationsBase):
474 notify_list = self._get_notifications_list()
511 notify_list = self._get_notifications_list()
475
512
476 summary = "Upload of image completed"
513 summary = "Upload of image completed"
477− hints = [
478− (
479− "x-canonical-secondary-icon",
480− self._get_icon_path('applicationIcons/facebook.png')
514+ icon_path = self._get_icon_path('applicationIcons/facebook.png')
481− )
515+ hints=[]
482− ]
483
516
484 notification = shell.create_ephemeral_notification(
517 notification = shell.create_ephemeral_notification(
485 summary,
518 summary,
486 None,
519 None,
487− None,
520+ icon_path,
488 hints,
521 hints,
489 "NORMAL",
522 "NORMAL",
490 )
523 )
@@ -497,8 +530,8 @@ class EphemeralNotificationsTests(NotificationsBase):
497 notification(),
530 notification(),
498 summary,
531 summary,
499 None,
532 None,
500− False,
501 True,
533 True,
534+ False,
502 1.0
535 1.0
503 )
536 )
504
537
@@ -683,7 +716,7 @@ class EphemeralNotificationsTests(NotificationsBase):
683 body = 'This bubble uses the icon-title-body layout with a ' \
716 body = 'This bubble uses the icon-title-body layout with a ' \
684 'secondary icon.'
717 'secondary icon.'
685 icon_path = self._get_icon_path('avatars/anna_olsson.png')
718 icon_path = self._get_icon_path('avatars/anna_olsson.png')
686− hint_icon = self._get_icon_path('applicationIcons/dialer-app.png')
719+ hint_icon = 'dialer'
687
720
688 notification = shell.create_ephemeral_notification(
721 notification = shell.create_ephemeral_notification(
689 summary,
722 summary,
@@ -718,72 +751,3 @@ class EphemeralNotificationsTests(NotificationsBase):
718 self.assertThat(get_notification, Eventually(NotEquals(None)))
751 self.assertThat(get_notification, Eventually(NotEquals(None)))
719 self._assert_notification(
752 self._assert_notification(
720 get_notification(), summary, body, False, False, 1.0)
753 get_notification(), summary, body, False, False, 1.0)
721−
722− def test_append_hint(self):
723− """Notification has to accumulate body-text using append-hint."""
724− unity_proxy = self.launch_unity()
725− unlock_unity(unity_proxy)
726−
727− notify_list = self._get_notifications_list()
728−
729− summary = 'Cole Raby'
730− body = 'Hey Bro Coly!'
731− icon_path = self._get_icon_path('avatars/amanda.png')
732− body_sum = body
733− notification = shell.create_ephemeral_notification(
734− summary,
735− body,
736− icon_path,
737− hints=[('x-canonical-append', 'true')]
738− )
739−
740− notification.show()
741−
742− get_notification = lambda: notify_list.wait_select_single(
743− 'Notification', objectName='notification1')
744−
745− notification = get_notification()
746− self._assert_notification(
747− notification,
748− summary,
749− body_sum,
750− True,
751− False,
752− 1.0
753− )
754−
755− bodies = [
756− 'What\'s up dude?',
757− 'Did you watch the air-race in Oshkosh last week?',
758− 'Phil owned the place like no one before him!',
759− 'Did really everything in the race work according to regulations?',
760− 'Somehow I think to remember Burt Williams did cut corners and '
761− 'was not punished for this.',
762− 'Hopefully the referees will watch the videos of the race.',
763− 'Burt could get fined with US$ 50000 for that rule-violation :)'
764− ]
765−
766− for new_body in bodies:
767− body = new_body
768− body_sum += '\n' + body
769− notification = shell.create_ephemeral_notification(
770− summary,
771− body,
772− icon_path,
773− hints=[('x-canonical-append', 'true')]
774− )
775− notification.show()
776−
777− get_notification = lambda: notify_list.wait_select_single(
778− 'Notification',
779− objectName='notification1'
780− )
781− notification = get_notification()
782− self._assert_notification(
783− notification,
784− summary,
785− body_sum,
786− True,
787− False,
788− 1.0
789− )
tests/mocks/AccountsService/AccountsService.qmltypes+1
@@ -26,5 +26,6 @@ Module {
26 Property { name: "backgroundFile"; type: "string" }
26 Property { name: "backgroundFile"; type: "string" }
27 Property { name: "statsWelcomeScreen"; type: "bool" }
27 Property { name: "statsWelcomeScreen"; type: "bool" }
28 Property { name: "passwordDisplayHint"; type: "PasswordDisplayHint"; isReadonly: true }
28 Property { name: "passwordDisplayHint"; type: "PasswordDisplayHint"; isReadonly: true }
29+ Property { name: "failedLogins"; type: "uint" }
29 }
30 }
30}
31}
tests/mocks/LightDM/LightDM.qmltypes+2
@@ -27,6 +27,7 @@ Module {
27 name: "showPrompt"
27 name: "showPrompt"
28 Parameter { name: "text"; type: "string" }
28 Parameter { name: "text"; type: "string" }
29 Parameter { name: "isSecret"; type: "bool" }
29 Parameter { name: "isSecret"; type: "bool" }
30+ Parameter { name: "isDefaultPrompt"; type: "bool" }
30 }
31 }
31 Signal { name: "authenticationComplete" }
32 Signal { name: "authenticationComplete" }
32 Signal {
33 Signal {
@@ -34,6 +35,7 @@ Module {
34 Parameter { name: "user"; type: "string" }
35 Parameter { name: "user"; type: "string" }
35 }
36 }
36 Signal { name: "isActiveChanged" }
37 Signal { name: "isActiveChanged" }
38+ Signal { name: "isAuthenticatedChanged" }
37 Signal { name: "showGreeter" }
39 Signal { name: "showGreeter" }
38 Signal {
40 Signal {
39 name: "requestAuthenticationUser"
41 name: "requestAuthenticationUser"
tests/mocks/Powerd/Powerd.cpp+15−1
@@ -19,6 +19,20 @@
19#include "Powerd.h"
19#include "Powerd.h"
20
20
21Powerd::Powerd(QObject* parent)
21Powerd::Powerd(QObject* parent)
22− : QObject(parent)
22+ : QObject(parent),
23+ m_status(Powerd::Status::On)
23{
24{
24}
25}
26+
27+void Powerd::setStatus(Powerd::Status status)
28+{
29+ if (m_status != status) {
30+ m_status = status;
31+ Q_EMIT statusChanged(DisplayStateChangeReason::Unknown);
32+ }
33+}
34+
35+Powerd::Status Powerd::status() const
36+{
37+ return m_status;
38+}
tests/mocks/Powerd/Powerd.h+8−1
@@ -26,6 +26,7 @@ class Powerd: public QObject
26 Q_OBJECT
26 Q_OBJECT
27 Q_ENUMS(Status)
27 Q_ENUMS(Status)
28 Q_ENUMS(DisplayStateChangeReason)
28 Q_ENUMS(DisplayStateChangeReason)
29+ Q_PROPERTY(Status status READ status WRITE setStatus NOTIFY statusChanged) // write only exists for tests
29
30
30public:
31public:
31 enum DisplayStateChangeReason {
32 enum DisplayStateChangeReason {
@@ -42,8 +43,14 @@ public:
42
43
43 explicit Powerd(QObject *parent = 0);
44 explicit Powerd(QObject *parent = 0);
44
45
46+ Status status() const;
47+ void setStatus(Status status);
48+
45Q_SIGNALS:
49Q_SIGNALS:
46− void displayPowerStateChange(int status, int reason);
50+ void statusChanged(DisplayStateChangeReason reason);
51+
52+private:
53+ Status m_status;
47};
54};
48
55
49#endif
56#endif
tests/mocks/Powerd/Powerd.qmltypes+3−3
@@ -30,10 +30,10 @@ Module {
30 "On": 1
30 "On": 1
31 }
31 }
32 }
32 }
33+ Property { name: "status"; type: "Status" }
33 Signal {
34 Signal {
34− name: "displayPowerStateChange"
35+ name: "statusChanged"
35− Parameter { name: "status"; type: "int" }
36− Parameter { name: "reason"; type: "int" }
36+ Parameter { name: "reason"; type: "DisplayStateChangeReason" }
37 }
37 }
38 }
38 }
39}
39}
tests/mocks/Ubuntu/Payments/MockPayments.cpp+10−7
@@ -77,13 +77,16 @@ void MockPayments::setStoreItemId(const QString &store_item_id)
77
77
78void MockPayments::start()
78void MockPayments::start()
79{
79{
80− if (!m_store_item_id.isEmpty()) {
80+ if (m_store_item_id.isEmpty()) {
81− if (m_store_item_id == "com.example.invalid") {
82− Q_EMIT purchaseError("Purchase failed.");
83− } else {
84− Q_EMIT purchaseCompleted();
85− }
86− } else {
87 Q_EMIT purchaseError("No item ID supplied.");
81 Q_EMIT purchaseError("No item ID supplied.");
88 }
82 }
89}
83}
84+
85+void MockPayments::process()
86+{
87+ if (m_store_item_id == "com.example.invalid") {
88+ Q_EMIT purchaseError("Purchase failed.");
89+ } else {
90+ Q_EMIT purchaseCompleted();
91+ }
92+}
tests/mocks/Ubuntu/Payments/MockPayments.h+1
@@ -41,6 +41,7 @@ public:
41 void setPrice(const double price);
41 void setPrice(const double price);
42 void setStoreItemId(const QString& store_item_id);
42 void setStoreItemId(const QString& store_item_id);
43 Q_INVOKABLE void start();
43 Q_INVOKABLE void start();
44+ Q_INVOKABLE void process(); // only available for testing
44
45
45Q_SIGNALS:
46Q_SIGNALS:
46 void currencyChanged(const QString& currency);
47 void currencyChanged(const QString& currency);
tests/mocks/Ubuntu/SystemImage/SystemImage.qmltypes+3−1
@@ -4,13 +4,15 @@ import QtQuick.tooling 1.1
4// It is used for QML tooling purposes only.
4// It is used for QML tooling purposes only.
5//
5//
6// This file was auto-generated by:
6// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Ubuntu.SystemImage 0.1 plugins'
7+// 'qmlplugindump -notrelocatable Ubuntu.SystemImage 0.1 tests/mocks'
8
8
9Module {
9Module {
10 Component {
10 Component {
11 name: "MockSystemImage"
11 name: "MockSystemImage"
12 prototype: "QObject"
12 prototype: "QObject"
13 exports: ["Ubuntu.SystemImage/SystemImage 0.1"]
13 exports: ["Ubuntu.SystemImage/SystemImage 0.1"]
14+ isCreatable: false
15+ isSingleton: true
14 exportMetaObjectRevisions: [0]
16 exportMetaObjectRevisions: [0]
15 Signal { name: "resettingDevice" }
17 Signal { name: "resettingDevice" }
16 Method { name: "factoryReset" }
18 Method { name: "factoryReset" }
tests/mocks/Unity/Application/Application.qmltypes+115−70
@@ -13,58 +13,24 @@ Module {
13 exports: ["Unity.Application/ApplicationInfo 0.1"]
13 exports: ["Unity.Application/ApplicationInfo 0.1"]
14 exportMetaObjectRevisions: [0]
14 exportMetaObjectRevisions: [0]
15 Property { name: "fullscreen"; type: "bool" }
15 Property { name: "fullscreen"; type: "bool" }
16− Property { name: "stage"; type: "Stage" }
17− Property { name: "surface"; type: "MirSurfaceItem"; isReadonly: true; isPointer: true }
16+ Property { name: "session"; type: "Session"; isReadonly: true; isPointer: true }
18− Property { name: "promptSurfaces"; type: "MirSurfaceItem"; isList: true; isReadonly: true }
17+ Property { name: "manualSurfaceCreation"; type: "bool" }
19− Property { name: "imageQml"; type: "string" }
20− Property { name: "windowQml"; type: "string" }
21− Signal {
22− name: "appIdChanged"
23− Parameter { type: "string" }
24− }
25− Signal {
26− name: "nameChanged"
27− Parameter { type: "string" }
28− }
29− Signal {
30− name: "commentChanged"
31− Parameter { type: "string" }
32− }
33− Signal {
34− name: "iconChanged"
35− Parameter { type: "QUrl" }
36− }
37 Signal {
18 Signal {
38− name: "stageChanged"
19+ name: "sessionChanged"
39− Parameter { type: "Stage" }
20+ Parameter { type: "Session"; isPointer: true }
40− }
41− Signal {
42− name: "stateChanged"
43− Parameter { type: "State" }
44− }
45− Signal {
46− name: "focusedChanged"
47− Parameter { type: "bool" }
48 }
21 }
49 Signal {
22 Signal {
50 name: "fullscreenChanged"
23 name: "fullscreenChanged"
51− Parameter { type: "bool" }
24+ Parameter { name: "value"; type: "bool" }
52− }
53− Signal {
54− name: "imageQmlChanged"
55− Parameter { type: "string" }
56− }
57− Signal {
58− name: "windowQmlChanged"
59− Parameter { type: "string" }
60 }
25 }
61 Signal {
26 Signal {
62− name: "screenshotChanged"
27+ name: "manualSurfaceCreationChanged"
63− Parameter { type: "QUrl" }
28+ Parameter { name: "value"; type: "bool" }
64 }
29 }
65− Signal {
30+ Method { name: "createSession" }
66− name: "surfaceChanged"
31+ Method {
67− Parameter { type: "MirSurfaceItem"; isPointer: true }
32+ name: "setState"
33+ Parameter { name: "value"; type: "State" }
68 }
34 }
69 }
35 }
70 Component {
36 Component {
@@ -198,17 +164,50 @@ Module {
198 type: "bool"
164 type: "bool"
199 Parameter { name: "appId"; type: "string" }
165 Parameter { name: "appId"; type: "string" }
200 }
166 }
167+ Method { name: "availableApplications"; type: "QStringList" }
201 Method {
168 Method {
202− name: "updateScreenshot"
169+ name: "add"
203− type: "bool"
170+ type: "ApplicationInfo*"
204 Parameter { name: "appId"; type: "string" }
171 Parameter { name: "appId"; type: "string" }
205 }
172 }
206− Method { name: "availableApplications"; type: "QStringList" }
173+ }
174+ Component {
175+ name: "ApplicationTestInterface"
176+ prototype: "QDBusAbstractAdaptor"
177+ exports: ["Unity.Application/ApplicationTest 0.1"]
178+ isCreatable: false
179+ isSingleton: true
180+ exportMetaObjectRevisions: [0]
181+ Method {
182+ name: "addChildSession"
183+ type: "uint"
184+ Parameter { name: "appId"; type: "string" }
185+ Parameter { name: "existingSessionId"; type: "uint" }
186+ Parameter { name: "surfaceImage"; type: "string" }
187+ }
188+ Method {
189+ name: "removeSession"
190+ Parameter { name: "sessionId"; type: "uint" }
191+ }
192+ Method {
193+ name: "addChildSession"
194+ type: "Session*"
195+ Parameter { name: "existingSession"; type: "Session"; isPointer: true }
196+ Parameter { name: "surfaceImage"; type: "string" }
197+ }
198+ Method {
199+ name: "removeSession"
200+ Parameter { name: "existingSession"; type: "Session"; isPointer: true }
201+ }
202+ Method {
203+ name: "removeSurface"
204+ Parameter { name: "existingSurface"; type: "MirSurfaceItem"; isPointer: true }
205+ }
207 }
206 }
208 Component {
207 Component {
209 name: "MirSurfaceItem"
208 name: "MirSurfaceItem"
210 defaultProperty: "data"
209 defaultProperty: "data"
211− prototype: "QQuickPaintedItem"
210+ prototype: "QQuickItem"
212 exports: ["Unity.Application/MirSurfaceItem 0.1"]
211 exports: ["Unity.Application/MirSurfaceItem 0.1"]
213 isCreatable: false
212 isCreatable: false
214 exportMetaObjectRevisions: [0]
213 exportMetaObjectRevisions: [0]
@@ -238,8 +237,7 @@ Module {
238 Property { name: "type"; type: "Type"; isReadonly: true }
237 Property { name: "type"; type: "Type"; isReadonly: true }
239 Property { name: "state"; type: "State"; isReadonly: true }
238 Property { name: "state"; type: "State"; isReadonly: true }
240 Property { name: "name"; type: "string"; isReadonly: true }
239 Property { name: "name"; type: "string"; isReadonly: true }
241− Property { name: "parentSurface"; type: "MirSurfaceItem"; isReadonly: true; isPointer: true }
240+ Property { name: "live"; type: "bool"; isReadonly: true }
242− Property { name: "childSurfaces"; type: "MirSurfaceItem"; isList: true; isReadonly: true }
243 Signal {
241 Signal {
244 name: "typeChanged"
242 name: "typeChanged"
245 Parameter { type: "Type" }
243 Parameter { type: "Type" }
@@ -249,22 +247,72 @@ Module {
249 Parameter { type: "State" }
247 Parameter { type: "State" }
250 }
248 }
251 Signal {
249 Signal {
252− name: "nameChanged"
250+ name: "liveChanged"
253− Parameter { type: "string" }
251+ Parameter { name: "live"; type: "bool" }
254− }
255− Signal {
256− name: "parentSurfaceChanged"
257− Parameter { type: "MirSurfaceItem"; isPointer: true }
258 }
252 }
259− Signal { name: "removed" }
260 Signal { name: "inputMethodRequested" }
253 Signal { name: "inputMethodRequested" }
261 Signal { name: "inputMethodDismissed" }
254 Signal { name: "inputMethodDismissed" }
255+ Signal { name: "deregister" }
262 Method {
256 Method {
263 name: "setState"
257 name: "setState"
264 Parameter { name: "newState"; type: "State" }
258 Parameter { name: "newState"; type: "State" }
265 }
259 }
266 Method { name: "release" }
260 Method { name: "release" }
267 }
261 }
262+ Component { name: "QDBusAbstractAdaptor"; prototype: "QObject" }
263+ Component {
264+ name: "Session"
265+ prototype: "QObject"
266+ exports: ["Unity.Application/Session 0.1"]
267+ isCreatable: false
268+ exportMetaObjectRevisions: [0]
269+ Property { name: "name"; type: "string"; isReadonly: true }
270+ Property { name: "surface"; type: "MirSurfaceItem"; isReadonly: true; isPointer: true }
271+ Property { name: "parentSession"; type: "Session"; isReadonly: true; isPointer: true }
272+ Property { name: "childSessions"; type: "SessionModel"; isReadonly: true; isPointer: true }
273+ Property { name: "live"; type: "bool"; isReadonly: true }
274+ Signal {
275+ name: "surfaceChanged"
276+ Parameter { type: "MirSurfaceItem"; isPointer: true }
277+ }
278+ Signal {
279+ name: "parentSessionChanged"
280+ Parameter { type: "Session"; isPointer: true }
281+ }
282+ Signal {
283+ name: "liveChanged"
284+ Parameter { name: "live"; type: "bool" }
285+ }
286+ Signal { name: "deregister" }
287+ Method { name: "createSurface" }
288+ Method { name: "release" }
289+ Method {
290+ name: "addChildSession"
291+ Parameter { name: "session"; type: "Session"; isPointer: true }
292+ }
293+ }
294+ Component {
295+ name: "SessionManager"
296+ prototype: "QObject"
297+ exports: ["Unity.Application/SessionManager 0.1"]
298+ isCreatable: false
299+ isSingleton: true
300+ exportMetaObjectRevisions: [0]
301+ Signal {
302+ name: "sessionStarting"
303+ Parameter { name: "session"; type: "Session"; isPointer: true }
304+ }
305+ Signal {
306+ name: "sessionStopping"
307+ Parameter { name: "session"; type: "Session"; isPointer: true }
308+ }
309+ Method {
310+ name: "createSession"
311+ type: "Session*"
312+ Parameter { name: "name"; type: "string" }
313+ Parameter { name: "screenshot"; type: "QUrl" }
314+ }
315+ }
268 Component {
316 Component {
269 name: "SurfaceManager"
317 name: "SurfaceManager"
270 prototype: "QObject"
318 prototype: "QObject"
@@ -281,6 +329,14 @@ Module {
281 name: "surfaceDestroyed"
329 name: "surfaceDestroyed"
282 Parameter { name: "surface"; type: "MirSurfaceItem"; isPointer: true }
330 Parameter { name: "surface"; type: "MirSurfaceItem"; isPointer: true }
283 }
331 }
332+ Method {
333+ name: "createSurface"
334+ type: "MirSurfaceItem*"
335+ Parameter { name: "name"; type: "string" }
336+ Parameter { name: "type"; type: "MirSurfaceItem::Type" }
337+ Parameter { name: "state"; type: "MirSurfaceItem::State" }
338+ Parameter { name: "screenshot"; type: "QUrl" }
339+ }
284 Method { name: "inputMethodSurface"; type: "MirSurfaceItem*" }
340 Method { name: "inputMethodSurface"; type: "MirSurfaceItem*" }
285 }
341 }
286 Component {
342 Component {
@@ -312,7 +368,6 @@ Module {
312 Property { name: "stage"; type: "Stage"; isReadonly: true }
368 Property { name: "stage"; type: "Stage"; isReadonly: true }
313 Property { name: "state"; type: "State"; isReadonly: true }
369 Property { name: "state"; type: "State"; isReadonly: true }
314 Property { name: "focused"; type: "bool"; isReadonly: true }
370 Property { name: "focused"; type: "bool"; isReadonly: true }
315− Property { name: "screenshot"; type: "QUrl"; isReadonly: true }
316 Signal {
371 Signal {
317 name: "nameChanged"
372 name: "nameChanged"
318 Parameter { name: "name"; type: "string" }
373 Parameter { name: "name"; type: "string" }
@@ -337,10 +392,6 @@ Module {
337 name: "focusedChanged"
392 name: "focusedChanged"
338 Parameter { name: "focused"; type: "bool" }
393 Parameter { name: "focused"; type: "bool" }
339 }
394 }
340− Signal {
341− name: "screenshotChanged"
342− Parameter { name: "screenshot"; type: "QUrl" }
343− }
344 }
395 }
345 Component {
396 Component {
346 name: "unity::shell::application::ApplicationManagerInterface"
397 name: "unity::shell::application::ApplicationManagerInterface"
@@ -357,8 +408,7 @@ Module {
357 "RoleIcon": 259,
408 "RoleIcon": 259,
358 "RoleStage": 260,
409 "RoleStage": 260,
359 "RoleState": 261,
410 "RoleState": 261,
360− "RoleFocused": 262,
411+ "RoleFocused": 262
361− "RoleScreenshot": 263
362 }
412 }
363 }
413 }
364 Property { name: "count"; type: "int"; isReadonly: true }
414 Property { name: "count"; type: "int"; isReadonly: true }
@@ -408,10 +458,5 @@ Module {
408 type: "bool"
458 type: "bool"
409 Parameter { name: "appId"; type: "string" }
459 Parameter { name: "appId"; type: "string" }
410 }
460 }
411− Method {
412− name: "updateScreenshot"
413− type: "bool"
414− Parameter { name: "appId"; type: "string" }
415− }
416 }
461 }
417}
462}
tests/mocks/Unity/Application/ApplicationDBusAdaptor.cppdeleted−81
@@ -1,81 +0,0 @@
1−/*
2− * Copyright (C) 2014 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−#include "ApplicationInfo.h"
18−#include "ApplicationDBusAdaptor.h"
19−#include "ApplicationManager.h"
20−#include "SurfaceManager.h"
21−#include "MirSurfaceItem.h"
22−
23−quint32 nextId = 0;
24−
25−ApplicationDBusAdaptor::ApplicationDBusAdaptor(ApplicationManager* applicationManager)
26− : QDBusAbstractAdaptor(applicationManager)
27− , m_applicationManager(applicationManager)
28−{
29−}
30−
31−MirSurfaceItem* topSurface(MirSurfaceItem* surface)
32−{
33− if (!surface)
34− return nullptr;
35−
36− MirSurfaceItem* child = nullptr;
37− Q_FOREACH (MirSurfaceItem *childSurface, surface->childSurfaceList()) {
38− child = topSurface(childSurface);
39− if (child) {
40− break;
41− }
42− }
43− return child ? child : surface;
44−}
45−
46−quint32 ApplicationDBusAdaptor::addPromptSurface(const QString &appId, const QString &surfaceImage)
47−{
48− qDebug() << "ApplicationDBusAdaptor::addPromptSurface to " << appId;
49−
50− ApplicationInfo* application = m_applicationManager->findApplication(appId);
51− if (!application) {
52− qDebug() << "ApplicationDBusAdaptor::addChildSurface - No application found for " << appId;
53− return 0;
54− }
55− quint32 surfaceId = ++nextId;
56− MirSurfaceItem* surface = new MirSurfaceItem(QString("%1-ChildSurface%2").arg(appId).arg(surfaceId),
57− MirSurfaceItem::Normal,
58− MirSurfaceItem::Maximized,
59− QUrl(surfaceImage));
60− m_childItems[surfaceId] = surface;
61−
62− if (application->promptSurfaceList().count() > 0) {
63− surface->setParentSurface(topSurface(application->promptSurfaceList()[0]));
64− } else {
65− application->addPromptSurface(surface);
66− }
67−
68− return surfaceId;
69−}
70−
71−void ApplicationDBusAdaptor::removeChildSurface(int surfaceId)
72−{
73− qDebug() << "ApplicationDBusAdaptor::removeChildSurface - " << surfaceId;
74−
75− if (!m_childItems.contains(surfaceId)) {
76− qDebug() << "ApplicationDBusAdaptor::removeChildSurface - No added surface for " << surfaceId;
77− return;
78− }
79− MirSurfaceItem* surface = m_childItems.take(surfaceId);
80− Q_EMIT surface->removed();
81−}
tests/mocks/Unity/Application/ApplicationInfo.cpp+36−85
@@ -15,8 +15,8 @@
15 */
15 */
16
16
17#include "ApplicationInfo.h"
17#include "ApplicationInfo.h"
18−#include "MirSurfaceItem.h"
18+#include "Session.h"
19−#include "SurfaceManager.h"
19+#include "SessionManager.h"
20
20
21#include <paths.h>
21#include <paths.h>
22
22
@@ -33,9 +33,8 @@ ApplicationInfo::ApplicationInfo(const QString &appId, QObject *parent)
33 , m_state(Starting)
33 , m_state(Starting)
34 , m_focused(false)
34 , m_focused(false)
35 , m_fullscreen(false)
35 , m_fullscreen(false)
36− , m_surface(0)
36+ , m_session(0)
37 , m_manualSurfaceCreation(false)
37 , m_manualSurfaceCreation(false)
38− , m_parentItem(0)
39{
38{
40}
39}
41
40
@@ -45,107 +44,50 @@ ApplicationInfo::ApplicationInfo(QObject *parent)
45 , m_state(Starting)
44 , m_state(Starting)
46 , m_focused(false)
45 , m_focused(false)
47 , m_fullscreen(false)
46 , m_fullscreen(false)
48− , m_surface(0)
47+ , m_session(0)
49 , m_manualSurfaceCreation(false)
48 , m_manualSurfaceCreation(false)
50− , m_parentItem(0)
51{
49{
52}
50}
53
51
54ApplicationInfo::~ApplicationInfo()
52ApplicationInfo::~ApplicationInfo()
55{
53{
56− if (m_surface) {
54+ delete m_session;
57− Q_EMIT SurfaceManager::singleton()->surfaceDestroyed(m_surface);
58− m_surface->deleteLater();
59− setSurface(nullptr);
60− }
61}
55}
62
56
63−void ApplicationInfo::createSurface()
57+void ApplicationInfo::createSession()
64{
58{
65− if (m_surface || state() == ApplicationInfo::Stopped) return;
59+ if (m_session || state() == ApplicationInfo::Stopped) { return; }
66
60
67 QUrl screenshotUrl = QString("file://%1").arg(m_screenshotFileName);
61 QUrl screenshotUrl = QString("file://%1").arg(m_screenshotFileName);
68−
62+ setSession(SessionManager::singleton()->createSession(appId(), screenshotUrl));
69− setSurface(new MirSurfaceItem(name(),
70− MirSurfaceItem::Normal,
71− fullscreen() ? MirSurfaceItem::Fullscreen : MirSurfaceItem::Maximized,
72− screenshotUrl));
73}
63}
74
64
75−void ApplicationInfo::setSurface(MirSurfaceItem* surface)
65+void ApplicationInfo::setSession(Session* session)
76{
66{
77− qDebug() << "Application::setSurface - appId=" << appId() << "surface=" << surface;
67+ qDebug() << "Application::setSession - appId=" << appId() << "session=" << session;
78− if (m_surface == surface)
68+ if (m_session == session)
79 return;
69 return;
80
70
81− if (m_surface) {
71+ if (m_session) {
82− m_surface->setApplication(nullptr);
72+ disconnect(this, 0, m_session, 0);
83− m_surface->setParent(nullptr);
84− SurfaceManager::singleton()->unregisterSurface(m_surface);
85− }
86−
87− m_surface = surface;
88−
89− if (m_surface) {
90− m_surface->setApplication(this);
73+ m_session->setApplication(nullptr);
91− m_surface->setParent(this);
74+ m_session->setParent(nullptr);
92− SurfaceManager::singleton()->registerSurface(m_surface);
75+ Q_EMIT m_session->deregister();
93 }
76 }
94
77
95− Q_EMIT surfaceChanged(m_surface);
78+ m_session = session;
96− SurfaceManager::singleton()->registerSurface(m_surface);
97−}
98
79
99−void ApplicationInfo::addPromptSurface(MirSurfaceItem* surface)
80+ if (m_session) {
100−{
81+ m_session->setApplication(this);
101− qDebug() << "ApplicationInfo::addPromptSurface " << surface->name() << " to " << name();
82+ m_session->setParent(this);
102− if (surface == m_surface || m_promptSurfaces.contains(surface)) return;
83+ SessionManager::singleton()->registerSession(m_session);
103
84
104− surface->setApplication(this);
85+ if (!m_manualSurfaceCreation) {
105− m_promptSurfaces.append(surface);
86+ QTimer::singleShot(500, m_session, SLOT(createSurface()));
106− Q_EMIT promptSurfacesChanged();
87+ }
107−}
108−
109−void ApplicationInfo::removeSurface(MirSurfaceItem* surface)
110−{
111− if (m_surface == surface) {
112− setSurface(nullptr);
113− } else if (m_promptSurfaces.contains(surface)) {
114− qDebug() << "Application::removeSurface " << surface->name() << " from " << name();
115−
116− m_promptSurfaces.removeAll(surface);
117− surface->setApplication(nullptr);
118−
119− Q_EMIT promptSurfacesChanged();
120 }
88 }
121−}
122
89
123−QList<MirSurfaceItem*> ApplicationInfo::promptSurfaceList() const
90+ Q_EMIT sessionChanged(m_session);
124−{
125− return m_promptSurfaces;
126−}
127−
128−QQmlListProperty<MirSurfaceItem> ApplicationInfo::promptSurfaces()
129−{
130− return QQmlListProperty<MirSurfaceItem>(this,
131− 0,
132− ApplicationInfo::promptSurfaceCount,
133− ApplicationInfo::promptSurfaceAt);
134−}
135−
136−int ApplicationInfo::promptSurfaceCount(QQmlListProperty<MirSurfaceItem> *prop)
137−{
138− ApplicationInfo *p = qobject_cast<ApplicationInfo*>(prop->object);
139− return p->m_promptSurfaces.count();
140−}
141−
142−MirSurfaceItem* ApplicationInfo::promptSurfaceAt(QQmlListProperty<MirSurfaceItem> *prop, int index)
143−{
144− ApplicationInfo *p = qobject_cast<ApplicationInfo*>(prop->object);
145−
146− if (index < 0 || index >= p->m_promptSurfaces.count())
147− return nullptr;
148− return p->m_promptSurfaces[index];
149}
91}
150
92
151void ApplicationInfo::setIconId(const QString &iconId)
93void ApplicationInfo::setIconId(const QString &iconId)
@@ -157,9 +99,18 @@ void ApplicationInfo::setIconId(const QString &iconId)
157
99
158void ApplicationInfo::setScreenshotId(const QString &screenshotId)
100void ApplicationInfo::setScreenshotId(const QString &screenshotId)
159{
101{
160− m_screenshotFileName = QString("%1/Dash/graphics/phone/screenshots/%2@12.png")
102+ QString screenshotFileName = QString("%1/Dash/graphics/phone/screenshots/%2@12.png")
161 .arg(qmlDirectory())
103 .arg(qmlDirectory())
162 .arg(screenshotId);
104 .arg(screenshotId);
105+
106+ if (screenshotFileName != m_screenshotFileName) {
107+ m_screenshotFileName = screenshotFileName;
108+
109+ QUrl screenshotUrl = QString("file://%1").arg(m_screenshotFileName);
110+ if (m_session) {
111+ m_session->setScreenshot(screenshotUrl);
112+ }
113+ }
163}
114}
164
115
165void ApplicationInfo::setName(const QString &value)
116void ApplicationInfo::setName(const QString &value)
@@ -193,7 +144,7 @@ void ApplicationInfo::setState(State value)
193 Q_EMIT stateChanged(value);
144 Q_EMIT stateChanged(value);
194
145
195 if (!m_manualSurfaceCreation && m_state == ApplicationInfo::Running) {
146 if (!m_manualSurfaceCreation && m_state == ApplicationInfo::Running) {
196− QTimer::singleShot(1000, this, SLOT(createSurface()));
147+ QTimer::singleShot(500, this, SLOT(createSession()));
197 }
148 }
198 }
149 }
199}
150}
tests/mocks/Unity/Application/ApplicationInfo.h+11−23
@@ -17,8 +17,10 @@
17#ifndef APPLICATION_H
17#ifndef APPLICATION_H
18#define APPLICATION_H
18#define APPLICATION_H
19
19
20+#include "SurfaceManager.h"
21+#include "MirSurfaceItemModel.h"
22+
20#include <QObject>
23#include <QObject>
21−#include <QQmlComponent>
22
24
23class QQuickItem;
25class QQuickItem;
24class MirSurfaceItem;
26class MirSurfaceItem;
@@ -32,8 +34,7 @@ class ApplicationInfo : public ApplicationInfoInterface {
32 Q_OBJECT
34 Q_OBJECT
33
35
34 Q_PROPERTY(bool fullscreen READ fullscreen WRITE setFullscreen NOTIFY fullscreenChanged)
36 Q_PROPERTY(bool fullscreen READ fullscreen WRITE setFullscreen NOTIFY fullscreenChanged)
35− Q_PROPERTY(MirSurfaceItem* surface READ surface NOTIFY surfaceChanged)
37+ Q_PROPERTY(Session* session READ session NOTIFY sessionChanged)
36− Q_PROPERTY(QQmlListProperty<MirSurfaceItem> promptSurfaces READ promptSurfaces NOTIFY promptSurfacesChanged DESIGNABLE false)
37
38
38 // Only exists in this fake implementation
39 // Only exists in this fake implementation
39
40
@@ -72,32 +73,23 @@ public:
72 void setFullscreen(bool value);
73 void setFullscreen(bool value);
73 bool fullscreen() const { return m_fullscreen; }
74 bool fullscreen() const { return m_fullscreen; }
74
75
75− void setSurface(MirSurfaceItem* surface);
76− MirSurfaceItem* surface() const { return m_surface; }
77−
78− void removeSurface(MirSurfaceItem* surface);
79−
80− void addPromptSurface(MirSurfaceItem* surface);
81− QList<MirSurfaceItem*> promptSurfaceList() const;
82− QQmlListProperty<MirSurfaceItem> promptSurfaces();
83−
84 bool manualSurfaceCreation() const { return m_manualSurfaceCreation; }
76 bool manualSurfaceCreation() const { return m_manualSurfaceCreation; }
85 void setManualSurfaceCreation(bool value);
77 void setManualSurfaceCreation(bool value);
86
78
79+public:
80+ void setSession(Session* session);
81+ Session* session() const { return m_session; }
82+
87Q_SIGNALS:
83Q_SIGNALS:
88− void surfaceChanged(MirSurfaceItem*);
84+ void sessionChanged(Session*);
89− void promptSurfacesChanged();
90 void fullscreenChanged(bool value);
85 void fullscreenChanged(bool value);
91 void manualSurfaceCreationChanged(bool value);
86 void manualSurfaceCreationChanged(bool value);
92
87
93public Q_SLOTS:
88public Q_SLOTS:
94− Q_INVOKABLE void createSurface();
89+ Q_INVOKABLE void createSession();
95
90
96private:
91private:
97− static int promptSurfaceCount(QQmlListProperty<MirSurfaceItem> *prop);
98− static MirSurfaceItem* promptSurfaceAt(QQmlListProperty<MirSurfaceItem> *prop, int index);
99 void setIcon(const QUrl &value);
92 void setIcon(const QUrl &value);
100− void setScreenshot(const QUrl &value);
101
93
102 QString m_screenshotFileName;
94 QString m_screenshotFileName;
103
95
@@ -108,15 +100,11 @@ private:
108 State m_state;
100 State m_state;
109 bool m_focused;
101 bool m_focused;
110 bool m_fullscreen;
102 bool m_fullscreen;
111− MirSurfaceItem* m_surface;
103+ Session* m_session;
112
104
113 bool m_manualSurfaceCreation;
105 bool m_manualSurfaceCreation;
114−
115− QQuickItem *m_parentItem;
116− QList<MirSurfaceItem*> m_promptSurfaces;
117};
106};
118
107
119Q_DECLARE_METATYPE(ApplicationInfo*)
108Q_DECLARE_METATYPE(ApplicationInfo*)
120−Q_DECLARE_METATYPE(QQmlListProperty<MirSurfaceItem>)
121
109
122#endif // APPLICATION_H
110#endif // APPLICATION_H
tests/mocks/Unity/Application/ApplicationManager.cpp+9−16
@@ -15,9 +15,9 @@
15 */
15 */
16
16
17#include "ApplicationManager.h"
17#include "ApplicationManager.h"
18−#include "ApplicationDBusAdaptor.h"
19#include "ApplicationInfo.h"
18#include "ApplicationInfo.h"
20−#include "MirSurfaceItem.h"
19+#include "Session.h"
20+#include "ApplicationTestInterface.h"
21
21
22#include <paths.h>
22#include <paths.h>
23
23
@@ -36,11 +36,6 @@ ApplicationManager *ApplicationManager::singleton()
36{
36{
37 if (!the_application_manager) {
37 if (!the_application_manager) {
38 the_application_manager = new ApplicationManager();
38 the_application_manager = new ApplicationManager();
39− new ApplicationDBusAdaptor(the_application_manager);
40−
41− QDBusConnection connection = QDBusConnection::sessionBus();
42− connection.registerService("com.canonical.Unity8");
43− connection.registerObject("/com/canonical/Unity8/Mocks", the_application_manager);
44 }
39 }
45 return the_application_manager;
40 return the_application_manager;
46}
41}
@@ -49,9 +44,8 @@ ApplicationManager::ApplicationManager(QObject *parent)
49 : ApplicationManagerInterface(parent)
44 : ApplicationManagerInterface(parent)
50 , m_suspended(false)
45 , m_suspended(false)
51{
46{
52− m_roleNames.insert(RoleSurface, "surface");
47+ m_roleNames.insert(RoleSession, "session");
53 m_roleNames.insert(RoleFullscreen, "fullscreen");
48 m_roleNames.insert(RoleFullscreen, "fullscreen");
54− m_roleNames.insert(RoleApplication, "application");
55
49
56 buildListOfAvailableApplications();
50 buildListOfAvailableApplications();
57
51
@@ -105,12 +99,10 @@ QVariant ApplicationManager::data(const QModelIndex& index, int role) const {
105 return app->state();
99 return app->state();
106 case RoleFocused:
100 case RoleFocused:
107 return app->focused();
101 return app->focused();
108− case RoleSurface:
102+ case RoleSession:
109− return QVariant::fromValue(app->surface());
103+ return QVariant::fromValue(app->session());
110 case RoleFullscreen:
104 case RoleFullscreen:
111 return app->fullscreen();
105 return app->fullscreen();
112− case RoleApplication:
113− return QVariant::fromValue(app);
114 default:
106 default:
115 return QVariant();
107 return QVariant();
116 }
108 }
@@ -154,10 +146,10 @@ void ApplicationManager::add(ApplicationInfo *application) {
154 Q_EMIT countChanged();
146 Q_EMIT countChanged();
155 if (count() == 1) Q_EMIT emptyChanged(isEmpty()); // was empty but not anymore
147 if (count() == 1) Q_EMIT emptyChanged(isEmpty()); // was empty but not anymore
156
148
157− connect(application, &ApplicationInfo::surfaceChanged, this, [application, this]() {
149+ connect(application, &ApplicationInfo::sessionChanged, this, [application, this]() {
158 QModelIndex appIndex = findIndex(application);
150 QModelIndex appIndex = findIndex(application);
159 if (!appIndex.isValid()) return;
151 if (!appIndex.isValid()) return;
160− Q_EMIT dataChanged(appIndex, appIndex, QVector<int>() << ApplicationManager::RoleSurface);
152+ Q_EMIT dataChanged(appIndex, appIndex, QVector<int>() << ApplicationManager::RoleSession);
161 });
153 });
162 connect(application, &ApplicationInfo::focusedChanged, this, [application, this]() {
154 connect(application, &ApplicationInfo::focusedChanged, this, [application, this]() {
163 QModelIndex appIndex = findIndex(application);
155 QModelIndex appIndex = findIndex(application);
@@ -181,7 +173,7 @@ void ApplicationManager::remove(ApplicationInfo *application) {
181 Q_EMIT countChanged();
173 Q_EMIT countChanged();
182 if (isEmpty()) Q_EMIT emptyChanged(isEmpty());
174 if (isEmpty()) Q_EMIT emptyChanged(isEmpty());
183 }
175 }
184− disconnect(application, 0, this, 0);
176+ application->disconnect(this);
185}
177}
186
178
187void ApplicationManager::move(int from, int to) {
179void ApplicationManager::move(int from, int to) {
@@ -464,6 +456,7 @@ void ApplicationManager::buildListOfAvailableApplications()
464 m_availableApplications.append(application);
456 m_availableApplications.append(application);
465}
457}
466
458
459+
467QStringList ApplicationManager::availableApplications()
460QStringList ApplicationManager::availableApplications()
468{
461{
469 QStringList appIds;
462 QStringList appIds;
tests/mocks/Unity/Application/ApplicationManager.h+1−2
@@ -52,9 +52,8 @@ class ApplicationManager : public ApplicationManagerInterface {
52 static ApplicationManager *singleton();
52 static ApplicationManager *singleton();
53
53
54 enum MoreRoles {
54 enum MoreRoles {
55− RoleSurface = RoleFocused+1,
55+ RoleSession = RoleFocused+1,
56 RoleFullscreen,
56 RoleFullscreen,
57− RoleApplication,
58 };
57 };
59 enum Role {
58 enum Role {
60 Dash, Default, Indicators, Notifications, Greeter, Launcher, OnScreenKeyboard,
59 Dash, Default, Indicators, Notifications, Greeter, Launcher, OnScreenKeyboard,
tests/mocks/Unity/Application/ApplicationTestInterface.cppnew file+117
@@ -0,0 +1,117 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "ApplicationInfo.h"
18+#include "ApplicationTestInterface.h"
19+#include "ApplicationManager.h"
20+#include "SessionManager.h"
21+#include "SurfaceManager.h"
22+#include "Session.h"
23+#include "MirSurfaceItem.h"
24+
25+#include <paths.h>
26+
27+#include <QtDBus/QtDBus>
28+
29+quint32 nextId = 0;
30+
31+ApplicationTestInterface::ApplicationTestInterface(QObject* parent)
32+ : QDBusAbstractAdaptor(parent)
33+{
34+ QDBusConnection connection = QDBusConnection::sessionBus();
35+ connection.registerService("com.canonical.Unity8");
36+ connection.registerObject("/com/canonical/Unity8/Mocks", parent);
37+}
38+
39+Session* ApplicationTestInterface::addChildSession(Session* existingSession, const QString& surfaceImage)
40+{
41+ if (!existingSession) return nullptr;
42+
43+ QUrl screenshotUrl = QString("file://%1/Dash/graphics/phone/screenshots/%2@12.png")
44+ .arg(qmlDirectory())
45+ .arg(surfaceImage);
46+
47+ Session* session = SessionManager::singleton()->createSession(
48+ QString("%1-Child%2").arg(existingSession->name())
49+ .arg(existingSession->childSessions()->count()),
50+ screenshotUrl);
51+ existingSession->addChildSession(session);
52+ session->createSurface();
53+
54+ return session;
55+}
56+
57+void ApplicationTestInterface::removeSession(Session* existingSession)
58+{
59+ qDebug() << "ApplicationTestInterface::removeSession - " << existingSession;
60+
61+ if (existingSession)
62+ existingSession->setLive(false);
63+}
64+
65+void ApplicationTestInterface::removeSurface(MirSurfaceItem* existingSurface)
66+{
67+ qDebug() << "ApplicationTestInterface::removeSurface - " << existingSurface;
68+
69+ if (existingSurface)
70+ existingSurface->setLive(false);
71+}
72+
73+quint32 ApplicationTestInterface::addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage)
74+{
75+ qDebug() << "ApplicationTestInterface::addChildSession to " << appId;
76+
77+ ApplicationInfo* application = ApplicationManager::singleton()->findApplication(appId);
78+ if (!application) {
79+ qDebug() << "ApplicationTestInterface::addChildSession - No application found for " << appId;
80+ return 0;
81+ }
82+
83+ Session* parentSession = nullptr;
84+ if (m_childSessions.contains(existingSessionId)) {
85+ parentSession = m_childSessions[existingSessionId];
86+ } else if (application->session()) {
87+ parentSession = application->session();
88+ } else {
89+ qDebug() << "ApplicationTestInterface::addChildSession - No session for " << appId << ":" << existingSessionId;
90+ return 0;
91+ }
92+
93+ QUrl screenshotUrl = QString("file://%1/Dash/graphics/phone/screenshots/%2@12.png")
94+ .arg(qmlDirectory())
95+ .arg(surfaceImage);
96+
97+ quint32 sessionId = ++nextId;
98+ Session* session = SessionManager::singleton()->createSession(
99+ QString("%1-Child%2").arg(parentSession->name())
100+ .arg(parentSession->childSessions()->count()),
101+ screenshotUrl);
102+ parentSession->addChildSession(session);
103+ session->createSurface();
104+ m_childSessions[sessionId] = session;
105+
106+ return sessionId;
107+}
108+
109+void ApplicationTestInterface::removeSession(quint32 sessionId)
110+{
111+ if (!m_childSessions.contains(sessionId)) {
112+ qDebug() << "ApplicationTestInterface::removeSession - No added session for " << sessionId;
113+ return;
114+ }
115+ Session* session = m_childSessions.take(sessionId);
116+ removeSession(session);
117+}
tests/mocks/Unity/Application/ApplicationDBusAdaptor.h → tests/mocks/Unity/Application/ApplicationTestInterface.hrenamed+13−11
@@ -14,30 +14,32 @@
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−#ifndef APPLICATIONDBUSADAPTOR_H
17+#ifndef APPLICATIONTESTINTERFACE_H
18−#define APPLICATIONDBUSADAPTOR_H
18+#define APPLICATIONTESTINTERFACE_H
19
19
20#include <QtDBus/QtDBus>
20#include <QtDBus/QtDBus>
21
21
22class ApplicationManager;
22class ApplicationManager;
23−class SurfaceManager;
23+class Session;
24class MirSurfaceItem;
24class MirSurfaceItem;
25
25
26−class ApplicationDBusAdaptor : public QDBusAbstractAdaptor
26+class ApplicationTestInterface : public QDBusAbstractAdaptor
27{
27{
28 Q_OBJECT
28 Q_OBJECT
29 Q_CLASSINFO("D-Bus Interface", "com.canonical.Unity8.Mocks.Application")
29 Q_CLASSINFO("D-Bus Interface", "com.canonical.Unity8.Mocks.Application")
30public:
30public:
31− ApplicationDBusAdaptor(ApplicationManager* applicationManager);
31+ ApplicationTestInterface(QObject* parent = 0);
32+
33+ Q_INVOKABLE Session* addChildSession(Session* existingSession, const QString& surfaceImage);
34+ Q_INVOKABLE void removeSession(Session* existingSession);
35+ Q_INVOKABLE void removeSurface(MirSurfaceItem* existingSurface);
32
36
33public Q_SLOTS:
37public Q_SLOTS:
34− quint32 addPromptSurface(const QString& appId, const QString& surfaceImage);
38+ quint32 addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage);
35− void removeChildSurface(int surfaceId);
39+ void removeSession(quint32 sessionId);
36
40
37private:
41private:
38− ApplicationManager* m_applicationManager;
42+ QHash<quint32, Session*> m_childSessions;
39−
40− QHash<quint32, MirSurfaceItem*> m_childItems;
41};
43};
42
44
43−#endif // APPLICATIONDBUSADAPTOR_H
45+#endif // APPLICATIONTESTINTERFACE_H
tests/mocks/Unity/Application/CMakeLists.txt+6−1
@@ -2,12 +2,17 @@ pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=3)
2
2
3set(FakeUnityApplicationQml_SOURCES
3set(FakeUnityApplicationQml_SOURCES
4 plugin.cpp
4 plugin.cpp
5− ApplicationDBusAdaptor.cpp
6 ApplicationInfo.cpp
5 ApplicationInfo.cpp
7 ApplicationManager.cpp
6 ApplicationManager.cpp
8 ApplicationScreenshotProvider.cpp
7 ApplicationScreenshotProvider.cpp
8+ ApplicationTestInterface.cpp
9 MirSurfaceItem.cpp
9 MirSurfaceItem.cpp
10+ MirSurfaceItemModel.h
11+ ObjectListModel.h
12+ Session.cpp
13+ SessionManager.cpp
10 SurfaceManager.cpp
14 SurfaceManager.cpp
15+ SessionModel.h
11 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
16 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
12 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
17 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
13)
18)
tests/mocks/Unity/Application/MirSurfaceItem.cpp+19−79
@@ -15,7 +15,7 @@
15 */
15 */
16
16
17#include "MirSurfaceItem.h"
17#include "MirSurfaceItem.h"
18−#include "ApplicationInfo.h"
18+#include "Session.h"
19
19
20#include <paths.h>
20#include <paths.h>
21
21
@@ -34,11 +34,11 @@ MirSurfaceItem::MirSurfaceItem(const QString& name,
34 const QString &qmlFilePath,
34 const QString &qmlFilePath,
35 QQuickItem *parent)
35 QQuickItem *parent)
36 : QQuickItem(parent)
36 : QQuickItem(parent)
37− , m_application(nullptr)
37+ , m_session(nullptr)
38 , m_name(name)
38 , m_name(name)
39 , m_type(type)
39 , m_type(type)
40 , m_state(state)
40 , m_state(state)
41− , m_parentSurface(nullptr)
41+ , m_live(true)
42 , m_qmlItem(nullptr)
42 , m_qmlItem(nullptr)
43 , m_screenshotUrl(screenshot)
43 , m_screenshotUrl(screenshot)
44{
44{
@@ -83,16 +83,9 @@ MirSurfaceItem::MirSurfaceItem(const QString& name,
83MirSurfaceItem::~MirSurfaceItem()
83MirSurfaceItem::~MirSurfaceItem()
84{
84{
85 qDebug() << "MirSurfaceItem::~MirSurfaceItem() " << name();
85 qDebug() << "MirSurfaceItem::~MirSurfaceItem() " << name();
86−
86+ if (m_session) {
87− QList<MirSurfaceItem*> children(m_children);
87+ m_session->setSurface(nullptr);
88− for (MirSurfaceItem* child : children) {
89− child->setParentSurface(nullptr);
90 }
88 }
91− if (m_parentSurface)
92− m_parentSurface->removeChildSurface(this);
93−
94− if (m_application)
95− m_application->removeSurface(this);
96}
89}
97
90
98void MirSurfaceItem::printComponentErrors()
91void MirSurfaceItem::printComponentErrors()
@@ -105,91 +98,38 @@ void MirSurfaceItem::printComponentErrors()
105
98
106void MirSurfaceItem::release()
99void MirSurfaceItem::release()
107{
100{
108− QList<MirSurfaceItem*> children(m_children);
101+ qDebug() << "MirSurfaceItem::release " << name();
109− for (MirSurfaceItem* child : children) {
110− child->release();
111− }
112− if (m_parentSurface) {
113− m_parentSurface->removeChildSurface(this);
114− }
115
102
116− if (m_application) {
103+ if (m_session) {
117− m_application->removeSurface(this);
104+ m_session->setSurface(nullptr);
118 }
105 }
119 if (!parent()) {
106 if (!parent()) {
120 deleteLater();
107 deleteLater();
121 }
108 }
122}
109}
123
110
124−void MirSurfaceItem::setApplication(ApplicationInfo* application)
111+void MirSurfaceItem::setSession(Session* session)
125{
112{
126− m_application = application;
113+ m_session = session;
127}
114}
128
115
129−void MirSurfaceItem::setParentSurface(MirSurfaceItem* surface)
116+void MirSurfaceItem::setScreenshot(const QUrl& screenshot)
130{
117{
131− if (m_parentSurface == surface || surface == this)
118+ m_screenshotUrl = screenshot;
132− return;
119+ if (m_qmlItem) {
133−
120+ QQmlProperty screenshotSource(m_qmlItem, "screenshotSource");
134− if (m_parentSurface) {
121+ screenshotSource.write(QVariant::fromValue(m_screenshotUrl));
135− m_parentSurface->removeChildSurface(this);
136− }
137−
138− m_parentSurface = surface;
139−
140− if (m_parentSurface) {
141− m_parentSurface->addChildSurface(this);
142 }
122 }
143− Q_EMIT parentSurfaceChanged(surface);
144}
123}
145
124
146−void MirSurfaceItem::addChildSurface(MirSurfaceItem* surface)
125+void MirSurfaceItem::setLive(bool live)
147{
126{
148− qDebug() << "MirSurfaceItem::addChildSurface " << surface->name() << " to " << name();
127+ if (m_live != live) {
149−
128+ m_live = live;
150− m_children.append(surface);
129+ Q_EMIT liveChanged(m_live);
151− Q_EMIT childSurfacesChanged();
152−}
153−
154−void MirSurfaceItem::removeChildSurface(MirSurfaceItem* surface)
155−{
156− qDebug() << "MirSurfaceItem::removeChildSurface " << surface->name() << " from " << name();
157−
158− if (m_children.contains(surface)) {
159− m_children.removeOne(surface);
160− Q_EMIT childSurfacesChanged();
161 }
130 }
162}
131}
163
132
164−QList<MirSurfaceItem*> MirSurfaceItem::childSurfaceList()
165−{
166− return m_children;
167−}
168−
169−QQmlListProperty<MirSurfaceItem> MirSurfaceItem::childSurfaces()
170−{
171− return QQmlListProperty<MirSurfaceItem>(this,
172− 0,
173− MirSurfaceItem::childSurfaceCount,
174− MirSurfaceItem::childSurfaceAt);
175−}
176−
177−int MirSurfaceItem::childSurfaceCount(QQmlListProperty<MirSurfaceItem> *prop)
178−{
179− MirSurfaceItem *p = qobject_cast<MirSurfaceItem*>(prop->object);
180− return p->m_children.count();
181−}
182−
183−MirSurfaceItem* MirSurfaceItem::childSurfaceAt(QQmlListProperty<MirSurfaceItem> *prop, int index)
184−{
185− MirSurfaceItem *p = qobject_cast<MirSurfaceItem*>(prop->object);
186−
187− if (index < 0 || index >= p->m_children.count())
188− return nullptr;
189− return p->m_children[index];
190−}
191−
192−
193void MirSurfaceItem::onQmlWantInputMethodChanged()
133void MirSurfaceItem::onQmlWantInputMethodChanged()
194{
134{
195 QQmlProperty prop(m_qmlItem, "wantInputMethod");
135 QQmlProperty prop(m_qmlItem, "wantInputMethod");
tests/mocks/Unity/Application/MirSurfaceItem.h+24−31
@@ -17,11 +17,12 @@
17#ifndef MIRSURFACEITEM_H
17#ifndef MIRSURFACEITEM_H
18#define MIRSURFACEITEM_H
18#define MIRSURFACEITEM_H
19
19
20+#include "MirSurfaceItemModel.h"
21+
20#include <QQuickItem>
22#include <QQuickItem>
21−#include <QQmlComponent>
22#include <QUrl>
23#include <QUrl>
23
24
24−class ApplicationInfo;
25+class Session;
25
26
26class MirSurfaceItem : public QQuickItem
27class MirSurfaceItem : public QQuickItem
27{
28{
@@ -31,9 +32,8 @@ class MirSurfaceItem : public QQuickItem
31
32
32 Q_PROPERTY(Type type READ type NOTIFY typeChanged)
33 Q_PROPERTY(Type type READ type NOTIFY typeChanged)
33 Q_PROPERTY(State state READ state NOTIFY stateChanged)
34 Q_PROPERTY(State state READ state NOTIFY stateChanged)
34− Q_PROPERTY(QString name READ name NOTIFY nameChanged)
35+ Q_PROPERTY(QString name READ name CONSTANT)
35− Q_PROPERTY(MirSurfaceItem* parentSurface READ parentSurface NOTIFY parentSurfaceChanged)
36+ Q_PROPERTY(bool live READ live NOTIFY liveChanged)
36− Q_PROPERTY(QQmlListProperty<MirSurfaceItem> childSurfaces READ childSurfaces NOTIFY childSurfacesChanged DESIGNABLE false)
37
37
38public:
38public:
39 enum Type {
39 enum Type {
@@ -56,24 +56,18 @@ public:
56 Fullscreen,
56 Fullscreen,
57 };
57 };
58
58
59− explicit MirSurfaceItem(const QString& name,
60− Type type,
61− State state,
62− const QUrl& screenshot,
63− const QString &qmlFilePath = QString(),
64− QQuickItem *parent = 0);
65 ~MirSurfaceItem();
59 ~MirSurfaceItem();
66
60
67 //getters
61 //getters
68− ApplicationInfo* application() const { return m_application; }
62+ Session* session() const { return m_session; }
69 Type type() const { return m_type; }
63 Type type() const { return m_type; }
70 State state() const { return m_state; }
64 State state() const { return m_state; }
71 QString name() const { return m_name; }
65 QString name() const { return m_name; }
72− MirSurfaceItem* parentSurface() const { return m_parentSurface; }
66+ bool live() const { return m_live; }
73− QList<MirSurfaceItem*> childSurfaceList();
74
67
75− void setApplication(ApplicationInfo* item);
68+ void setSession(Session* item);
76− void setParentSurface(MirSurfaceItem* item);
69+ void setScreenshot(const QUrl& screenshot);
70+ void setLive(bool live);
77
71
78 Q_INVOKABLE void setState(State newState);
72 Q_INVOKABLE void setState(State newState);
79 Q_INVOKABLE void release();
73 Q_INVOKABLE void release();
@@ -81,42 +75,41 @@ public:
81Q_SIGNALS:
75Q_SIGNALS:
82 void typeChanged(Type);
76 void typeChanged(Type);
83 void stateChanged(State);
77 void stateChanged(State);
84− void nameChanged(QString);
78+ void liveChanged(bool live);
85− void parentSurfaceChanged(MirSurfaceItem*);
86− void childSurfacesChanged();
87−
88− void removed();
89
79
90 void inputMethodRequested();
80 void inputMethodRequested();
91 void inputMethodDismissed();
81 void inputMethodDismissed();
92
82
83+ // internal mock use
84+ void deregister();
85+
93private Q_SLOTS:
86private Q_SLOTS:
94 void onFocusChanged();
87 void onFocusChanged();
95 void onComponentStatusChanged(QQmlComponent::Status status);
88 void onComponentStatusChanged(QQmlComponent::Status status);
96 void onQmlWantInputMethodChanged();
89 void onQmlWantInputMethodChanged();
97
90
98private:
91private:
99− void addChildSurface(MirSurfaceItem* surface);
92+ explicit MirSurfaceItem(const QString& name,
100− void removeChildSurface(MirSurfaceItem* surface);
93+ Type type,
101−
94+ State state,
102− QQmlListProperty<MirSurfaceItem> childSurfaces();
95+ const QUrl& screenshot,
103− static int childSurfaceCount(QQmlListProperty<MirSurfaceItem> *prop);
96+ const QString &qmlFilePath = QString(),
104− static MirSurfaceItem* childSurfaceAt(QQmlListProperty<MirSurfaceItem> *prop, int index);
97+ QQuickItem *parent = 0);
105
98
106 void createQmlContentItem();
99 void createQmlContentItem();
107 void printComponentErrors();
100 void printComponentErrors();
108
101
109− ApplicationInfo* m_application;
102+ Session* m_session;
110 const QString m_name;
103 const QString m_name;
111 const Type m_type;
104 const Type m_type;
112 State m_state;
105 State m_state;
113−
106+ bool m_live;
114− MirSurfaceItem* m_parentSurface;
115− QList<MirSurfaceItem*> m_children;
116
107
117 QQmlComponent *m_qmlContentComponent;
108 QQmlComponent *m_qmlContentComponent;
118 QQuickItem *m_qmlItem;
109 QQuickItem *m_qmlItem;
119 QUrl m_screenshotUrl;
110 QUrl m_screenshotUrl;
111+
112+ friend class SurfaceManager;
120};
113};
121
114
122Q_DECLARE_METATYPE(MirSurfaceItem*)
115Q_DECLARE_METATYPE(MirSurfaceItem*)
tests/mocks/Unity/Application/MirSurfaceItemModel.hnew file+35
@@ -0,0 +1,35 @@
1+/*
2+ * Copyright (C) 2014 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 MIRSURFACEITEMMODEL_H
18+#define MIRSURFACEITEMMODEL_H
19+
20+// Local
21+#include "ObjectListModel.h"
22+
23+class MirSurfaceItem;
24+class MirSurfaceItemModel: public ObjectListModel<MirSurfaceItem>
25+{
26+ Q_OBJECT
27+public:
28+ MirSurfaceItemModel(QObject *parent = 0): ObjectListModel(parent) {}
29+
30+ Q_INVOKABLE int count() const { return rowCount(); }
31+};
32+
33+Q_DECLARE_METATYPE(MirSurfaceItemModel*)
34+
35+#endif // MIRSURFACEITEMMODEL_H
tests/mocks/Unity/Application/ObjectListModel.hnew file+106
@@ -0,0 +1,106 @@
1+/*
2+ * Copyright (C) 2014 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 OBJECTLISTMODEL_H
18+#define OBJECTLISTMODEL_H
19+
20+// Qt
21+#include <QAbstractListModel>
22+
23+template<class TYPE>
24+class ObjectListModel : public QAbstractListModel
25+{
26+public:
27+ ObjectListModel(QObject *parent = 0)
28+ : QAbstractListModel(parent)
29+ {}
30+
31+ enum Roles {
32+ RoleModelData = Qt::UserRole,
33+ };
34+
35+ const QList<TYPE*>& list() const { return m_items; }
36+ bool contains(TYPE* item) const { return m_items.contains(item); }
37+
38+ void insert(uint index, TYPE* item)
39+ {
40+ index = qMin(index, (uint)m_items.count());
41+
42+ int existingIndex = m_items.indexOf(item);
43+ if (existingIndex != -1) {
44+ move(existingIndex, qMin(index, (uint)(m_items.count()-1)));
45+ } else {
46+ beginInsertRows(QModelIndex(), index, index);
47+ m_items.insert(index, item);
48+ endInsertRows();
49+ }
50+ }
51+
52+ void remove(TYPE* item)
53+ {
54+ int existingIndex = m_items.indexOf(item);
55+ if (existingIndex != -1) {
56+ beginRemoveRows(QModelIndex(), existingIndex, existingIndex);
57+ m_items.removeAt(existingIndex);
58+ endRemoveRows();
59+ }
60+ }
61+
62+ // from QAbstractItemModel
63+ int rowCount(const QModelIndex& = QModelIndex()) const override
64+ {
65+ return m_items.count();
66+ }
67+
68+ QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override
69+ {
70+ if (index.row() >= 0 && index.row() < m_items.count()) {
71+ if (role == RoleModelData) {
72+ TYPE *item = m_items.at(index.row());
73+ return QVariant::fromValue(item);
74+ }
75+ }
76+ return QVariant();
77+ }
78+
79+ QHash<int, QByteArray> roleNames() const
80+ {
81+ QHash<int, QByteArray> roleNames;
82+ roleNames.insert(RoleModelData, "modelData");
83+ return roleNames;
84+ }
85+
86+protected:
87+ void move(int from, int to)
88+ {
89+ if (from == to) return;
90+
91+ if (from >= 0 && from < m_items.size() && to >= 0 && to < m_items.size()) {
92+ QModelIndex parent;
93+ /* When moving an item down, the destination index needs to be incremented
94+ by one, as explained in the documentation:
95+ http://qt-project.org/doc/qt-5.0/qtcore/qabstractitemmodel.html#beginMoveRows */
96+
97+ beginMoveRows(parent, from, from, parent, to + (to > from ? 1 : 0));
98+ m_items.move(from, to);
99+ endMoveRows();
100+ }
101+ }
102+
103+ QList<TYPE*> m_items;
104+};
105+
106+#endif // OBJECTLISTMODEL_H
tests/mocks/Unity/Application/Session.cppnew file+174
@@ -0,0 +1,174 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "Session.h"
18+#include "ApplicationInfo.h"
19+#include "SessionManager.h"
20+#include "SurfaceManager.h"
21+
22+#include <QPainter>
23+#include <QQmlEngine>
24+#include <QTimer>
25+
26+Session::Session(const QString &name,
27+ const QUrl& screenshot,
28+ QObject *parent)
29+ : QObject(parent)
30+ , m_name(name)
31+ , m_live(true)
32+ , m_screenshot(screenshot)
33+ , m_application(nullptr)
34+ , m_surface(nullptr)
35+ , m_parentSession(nullptr)
36+ , m_children(new SessionModel(this))
37+{
38+ qDebug() << "Session::Session() " << this->name();
39+
40+ QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
41+}
42+
43+Session::~Session()
44+{
45+ qDebug() << "Session::~Session() " << name();
46+
47+ QList<Session*> children(m_children->list());
48+ for (Session* child : children) {
49+ delete child;
50+ }
51+ if (m_parentSession) {
52+ m_parentSession->removeChildSession(this);
53+ }
54+ if (m_application) {
55+ m_application->setSession(nullptr);
56+ }
57+ delete m_surface;
58+ delete m_children;
59+}
60+
61+void Session::release()
62+{
63+ qDebug() << "Session::release " << name();
64+
65+ if (m_parentSession) {
66+ m_parentSession->removeChildSession(this);
67+ }
68+ if (m_application) {
69+ m_application->setSession(nullptr);
70+ }
71+ if (!parent()) {
72+ deleteLater();
73+ }
74+}
75+
76+void Session::setApplication(ApplicationInfo* application)
77+{
78+ if (m_application == application)
79+ return;
80+
81+ m_application = application;
82+ Q_EMIT applicationChanged(application);
83+}
84+
85+void Session::setSurface(MirSurfaceItem* surface)
86+{
87+ qDebug() << "Session::setSurface - session=" << name() << "surface=" << surface;
88+ if (m_surface == surface)
89+ return;
90+
91+ if (m_surface) {
92+ m_surface->setSession(nullptr);
93+ m_surface->setParent(nullptr);
94+ Q_EMIT m_surface->deregister();
95+ }
96+
97+ m_surface = surface;
98+
99+ if (m_surface) {
100+ m_surface->setSession(this);
101+ m_surface->setParent(this);
102+ SurfaceManager::singleton()->registerSurface(m_surface);
103+ }
104+
105+ Q_EMIT surfaceChanged(m_surface);
106+}
107+
108+void Session::setScreenshot(const QUrl& screenshot)
109+{
110+ if (screenshot != m_screenshot) {
111+ m_screenshot = screenshot;
112+ if (m_surface) {
113+ m_surface->setScreenshot(m_screenshot);
114+ }
115+ }
116+}
117+
118+void Session::setLive(bool live)
119+{
120+ if (m_live != live) {
121+ m_live = live;
122+ Q_EMIT liveChanged(m_live);
123+ }
124+}
125+
126+void Session::setParentSession(Session* session)
127+{
128+ if (m_parentSession == session || session == this)
129+ return;
130+
131+ m_parentSession = session;
132+ Q_EMIT parentSessionChanged(session);
133+}
134+
135+void Session::createSurface()
136+{
137+ if (m_surface) return;
138+
139+ setSurface(SurfaceManager::singleton()->createSurface(name(),
140+ MirSurfaceItem::Normal,
141+ m_application && m_application->fullscreen() ? MirSurfaceItem::Fullscreen :
142+ MirSurfaceItem::Maximized,
143+ m_screenshot));
144+}
145+
146+void Session::addChildSession(Session* session)
147+{
148+ insertChildSession(m_children->rowCount(), session);
149+}
150+
151+void Session::insertChildSession(uint index, Session* session)
152+{
153+ qDebug() << "Session::insertChildSession - " << session->name() << " to " << name() << " @ " << index;
154+
155+ session->setParentSession(this);
156+ m_children->insert(index, session);
157+ SessionManager::singleton()->registerSession(session);
158+}
159+
160+void Session::removeChildSession(Session* session)
161+{
162+ qDebug() << "Session::removeChildSession - " << session->name() << " from " << name();
163+
164+ if (m_children->contains(session)) {
165+ m_children->remove(session);
166+ session->setParentSession(nullptr);
167+ Q_EMIT session->deregister();
168+ }
169+}
170+
171+SessionModel* Session::childSessions() const
172+{
173+ return m_children;
174+}
tests/mocks/Unity/Application/Session.hnew file+90
@@ -0,0 +1,90 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef SESSION_H
18+#define SESSION_H
19+
20+#include "SessionModel.h"
21+
22+#include <QQuickItem>
23+
24+class ApplicationInfo;
25+class MirSurfaceItem;
26+
27+class Session : public QObject
28+{
29+ Q_OBJECT
30+ Q_PROPERTY(QString name READ name CONSTANT)
31+ Q_PROPERTY(MirSurfaceItem* surface READ surface NOTIFY surfaceChanged)
32+ Q_PROPERTY(ApplicationInfo* application READ application NOTIFY applicationChanged)
33+ Q_PROPERTY(Session* parentSession READ parentSession NOTIFY parentSessionChanged DESIGNABLE false)
34+ Q_PROPERTY(SessionModel* childSessions READ childSessions DESIGNABLE false CONSTANT)
35+ Q_PROPERTY(bool live READ live NOTIFY liveChanged)
36+
37+public:
38+ explicit Session(const QString &name,
39+ const QUrl& screenshot,
40+ QObject *parent = 0);
41+ ~Session();
42+
43+ Q_INVOKABLE void release();
44+
45+ //getters
46+ QString name() const { return m_name; }
47+ bool live() const { return m_live; }
48+ ApplicationInfo* application() const { return m_application; }
49+ MirSurfaceItem* surface() const { return m_surface; }
50+ Session* parentSession() const { return m_parentSession; }
51+
52+ void setApplication(ApplicationInfo* item);
53+ void setSurface(MirSurfaceItem* surface);
54+ void setScreenshot(const QUrl& m_screenshot);
55+ void setLive(bool live);
56+
57+ Q_INVOKABLE void addChildSession(Session* session);
58+ void insertChildSession(uint index, Session* session);
59+ void removeChildSession(Session* session);
60+
61+Q_SIGNALS:
62+ void applicationChanged(ApplicationInfo*);
63+ void surfaceChanged(MirSurfaceItem*);
64+ void parentSessionChanged(Session*);
65+ void liveChanged(bool live);
66+
67+ // internal mock use
68+ void deregister();
69+
70+public Q_SLOTS:
71+ Q_INVOKABLE void createSurface();
72+
73+private:
74+ SessionModel* childSessions() const;
75+ void setParentSession(Session* session);
76+
77+ QString m_name;
78+ bool m_live;
79+ QUrl m_screenshot;
80+ ApplicationInfo* m_application;
81+ MirSurfaceItem* m_surface;
82+ Session* m_parentSession;
83+ SessionModel* m_children;
84+
85+ friend class ApplicationTestInterface;
86+};
87+
88+Q_DECLARE_METATYPE(Session*)
89+
90+#endif // SESSION_H
tests/mocks/Unity/Application/SessionManager.cppnew file+55
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "SessionManager.h"
18+
19+#include "Session.h"
20+
21+SessionManager *SessionManager::the_session_manager = nullptr;
22+
23+SessionManager *SessionManager::singleton()
24+{
25+ if (!the_session_manager) {
26+ the_session_manager = new SessionManager();
27+ }
28+ return the_session_manager;
29+}
30+
31+SessionManager::SessionManager(QObject *parent) :
32+ QObject(parent)
33+{
34+}
35+
36+
37+Session *SessionManager::createSession(const QString& name,
38+ const QUrl& screenshot)
39+{
40+ Session* session = new Session(name, screenshot);
41+ Q_EMIT sessionStarting(session);
42+ return session;
43+}
44+
45+void SessionManager::registerSession(Session *session)
46+{
47+ connect(session, &Session::deregister, this, [this] {
48+ Session* session = qobject_cast<Session*>(sender());
49+
50+ disconnect(session, 0, this, 0);
51+
52+ session->setLive(false);
53+ Q_EMIT sessionStopping(session);
54+ });
55+}
tests/mocks/Unity/Application/SessionManager.hnew file+44
@@ -0,0 +1,44 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef SESSIONMANAGER_H
18+#define SESSIONMANAGER_H
19+
20+#include <QObject>
21+
22+class Session;
23+
24+class SessionManager : public QObject
25+{
26+ Q_OBJECT
27+public:
28+ explicit SessionManager(QObject *parent = 0);
29+
30+ static SessionManager *singleton();
31+
32+ Q_INVOKABLE Session* createSession(const QString& name, const QUrl& screenshot);
33+
34+ void registerSession(Session *session);
35+
36+Q_SIGNALS:
37+ void sessionStarting(Session *session);
38+ void sessionStopping(Session *session);
39+
40+private:
41+ static SessionManager *the_session_manager;
42+};
43+
44+#endif // SESSIONMANAGER_H
tests/mocks/Unity/Application/SessionModel.hnew file+35
@@ -0,0 +1,35 @@
1+/*
2+ * Copyright (C) 2014 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 SESSIONMODEL_H
18+#define SESSIONMODEL_H
19+
20+// Local
21+#include "ObjectListModel.h"
22+
23+class Session;
24+class SessionModel: public ObjectListModel<Session>
25+{
26+ Q_OBJECT
27+public:
28+ SessionModel(QObject *parent = 0): ObjectListModel(parent) {}
29+
30+ Q_INVOKABLE int count() const { return rowCount(); }
31+};
32+
33+Q_DECLARE_METATYPE(SessionModel*)
34+
35+#endif // SESSIONMODEL_H
tests/mocks/Unity/Application/SurfaceManager.cpp+20−7
@@ -35,19 +35,32 @@ SurfaceManager::SurfaceManager(QObject *parent) :
35{
35{
36}
36}
37
37
38+MirSurfaceItem *SurfaceManager::createSurface(const QString& name,
39+ MirSurfaceItem::Type type,
40+ MirSurfaceItem::State state,
41+ const QUrl& screenshot)
42+{
43+ MirSurfaceItem* surface = new MirSurfaceItem(name,
44+ type,
45+ state,
46+ screenshot);
47+ Q_EMIT surfaceCreated(surface);
48+ return surface;
49+}
50+
38void SurfaceManager::registerSurface(MirSurfaceItem *surface)
51void SurfaceManager::registerSurface(MirSurfaceItem *surface)
39{
52{
53+ connect(surface, &MirSurfaceItem::deregister, this, [this] {
54+ MirSurfaceItem* surface = qobject_cast<MirSurfaceItem*>(sender());
55+ disconnect(surface, 0, this, 0);
56+
57+ surface->setLive(false);
58+ Q_EMIT surfaceDestroyed(surface);
59+ });
40 connect(surface, &MirSurfaceItem::inputMethodRequested,
60 connect(surface, &MirSurfaceItem::inputMethodRequested,
41 this, &SurfaceManager::showInputMethod);
61 this, &SurfaceManager::showInputMethod);
42 connect(surface, &MirSurfaceItem::inputMethodDismissed,
62 connect(surface, &MirSurfaceItem::inputMethodDismissed,
43 this, &SurfaceManager::hideInputMethod);
63 this, &SurfaceManager::hideInputMethod);
44− Q_EMIT surfaceCreated(surface);
45−}
46−
47−void SurfaceManager::unregisterSurface(MirSurfaceItem *surface)
48−{
49− disconnect(surface, 0, this, 0);
50− Q_EMIT surfaceDestroyed(surface);
51}
64}
52
65
53void SurfaceManager::showInputMethod()
66void SurfaceManager::showInputMethod()
tests/mocks/Unity/Application/SurfaceManager.h+6−2
@@ -19,7 +19,7 @@
19
19
20#include <QObject>
20#include <QObject>
21
21
22−class MirSurfaceItem;
22+#include "MirSurfaceItem.h"
23
23
24class SurfaceManager : public QObject
24class SurfaceManager : public QObject
25{
25{
@@ -29,9 +29,13 @@ public:
29
29
30 static SurfaceManager *singleton();
30 static SurfaceManager *singleton();
31
31
32+ Q_INVOKABLE MirSurfaceItem *createSurface(const QString& name,
33+ MirSurfaceItem::Type type,
34+ MirSurfaceItem::State state,
35+ const QUrl& screenshot);
36+
32 // Internal mock use
37 // Internal mock use
33 void registerSurface(MirSurfaceItem *surface);
38 void registerSurface(MirSurfaceItem *surface);
34− void unregisterSurface(MirSurfaceItem *surface);
35
39
36 // To be used in the tests
40 // To be used in the tests
37 Q_INVOKABLE MirSurfaceItem *inputMethodSurface();
41 Q_INVOKABLE MirSurfaceItem *inputMethodSurface();
tests/mocks/Unity/Application/plugin.cpp+37−4
@@ -18,8 +18,12 @@
18#include "ApplicationInfo.h"
18#include "ApplicationInfo.h"
19#include "ApplicationManager.h"
19#include "ApplicationManager.h"
20#include "ApplicationScreenshotProvider.h"
20#include "ApplicationScreenshotProvider.h"
21+#include "Session.h"
21#include "MirSurfaceItem.h"
22#include "MirSurfaceItem.h"
23+#include "MirSurfaceItemModel.h"
22#include "SurfaceManager.h"
24#include "SurfaceManager.h"
25+#include "SessionManager.h"
26+#include "ApplicationTestInterface.h"
23
27
24#include <qqml.h>
28#include <qqml.h>
25#include <QQmlEngine>
29#include <QQmlEngine>
@@ -36,18 +40,45 @@ static QObject* surfaceManagerSingleton(QQmlEngine* engine, QJSEngine* scriptEng
36 return SurfaceManager::singleton();
40 return SurfaceManager::singleton();
37}
41}
38
42
43+static QObject* sessionManagerSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
44+ Q_UNUSED(engine);
45+ Q_UNUSED(scriptEngine);
46+ return SessionManager::singleton();
47+}
48+
49+ApplicationTestInterface* s_appTestInterface = nullptr;
50+
51+static QObject* applicationTestInterface(QQmlEngine* engine, QJSEngine* scriptEngine) {
52+ Q_UNUSED(engine);
53+ Q_UNUSED(scriptEngine);
54+ if (!s_appTestInterface) {
55+ s_appTestInterface = new ApplicationTestInterface(engine);
56+ }
57+ return s_appTestInterface;
58+}
59+
39void FakeUnityApplicationQmlPlugin::registerTypes(const char *uri)
60void FakeUnityApplicationQmlPlugin::registerTypes(const char *uri)
40{
61{
62+ qRegisterMetaType<Session*>("Session*");
63+ qRegisterMetaType<ApplicationInfo*>("ApplicationInfo*");
64+ qRegisterMetaType<MirSurfaceItemModel*>("SessionModel*");
41 qRegisterMetaType<MirSurfaceItem*>("MirSurfaceItem*");
65 qRegisterMetaType<MirSurfaceItem*>("MirSurfaceItem*");
66+ qRegisterMetaType<MirSurfaceItemModel*>("MirSurfaceItemModel*");
42
67
43 qmlRegisterUncreatableType<unity::shell::application::ApplicationManagerInterface>(uri, 0, 1, "ApplicationManagerInterface", "Abstract interface. Cannot be created in QML");
68 qmlRegisterUncreatableType<unity::shell::application::ApplicationManagerInterface>(uri, 0, 1, "ApplicationManagerInterface", "Abstract interface. Cannot be created in QML");
44− qmlRegisterSingletonType<ApplicationManager>(uri, 0, 1, "ApplicationManager", applicationManagerSingleton);
45− qmlRegisterSingletonType<SurfaceManager>(uri, 0, 1, "SurfaceManager", surfaceManagerSingleton);
46−
47 qmlRegisterUncreatableType<unity::shell::application::ApplicationInfoInterface>(uri, 0, 1, "ApplicationInfoInterface", "Abstract interface. Cannot be created in QML");
69 qmlRegisterUncreatableType<unity::shell::application::ApplicationInfoInterface>(uri, 0, 1, "ApplicationInfoInterface", "Abstract interface. Cannot be created in QML");
70+ qmlRegisterUncreatableType<Session>(uri, 0, 1, "Session", "Session can't be instantiated from QML");
71+ qmlRegisterUncreatableType<MirSurfaceItem>(uri, 0, 1, "MirSurfaceItem", "MirSurfaceItem can't be instantiated from QML");
72+
48 qmlRegisterType<ApplicationInfo>(uri, 0, 1, "ApplicationInfo");
73 qmlRegisterType<ApplicationInfo>(uri, 0, 1, "ApplicationInfo");
49
74
50− qmlRegisterUncreatableType<MirSurfaceItem>(uri, 0, 1, "MirSurfaceItem", "MirSurfaceItem can't be instantiated from QML");
75+ qmlRegisterSingletonType<ApplicationManager>(uri, 0, 1, "ApplicationManager", applicationManagerSingleton);
76+ qmlRegisterSingletonType<SurfaceManager>(uri, 0, 1, "SurfaceManager", surfaceManagerSingleton);
77+ qmlRegisterSingletonType<SessionManager>(uri, 0, 1, "SessionManager", sessionManagerSingleton);
78+ qmlRegisterSingletonType<ApplicationTestInterface>(uri, 0, 1, "ApplicationTest", applicationTestInterface);
79+
80+ qRegisterMetaType<MirSurfaceItem::Type>("MirSurfaceItem::Type");
81+ qRegisterMetaType<MirSurfaceItem::State>("MirSurfaceItem::State");
51}
82}
52
83
53void FakeUnityApplicationQmlPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
84void FakeUnityApplicationQmlPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
@@ -55,4 +86,6 @@ void FakeUnityApplicationQmlPlugin::initializeEngine(QQmlEngine *engine, const c
55 QQmlExtensionPlugin::initializeEngine(engine, uri);
86 QQmlExtensionPlugin::initializeEngine(engine, uri);
56
87
57 engine->addImageProvider(QLatin1String("application"), new ApplicationScreenshotProvider(ApplicationManager::singleton()));
88 engine->addImageProvider(QLatin1String("application"), new ApplicationScreenshotProvider(ApplicationManager::singleton()));
89+ // make sure we initialise our test interface.
90+ applicationTestInterface(engine, nullptr);
58}
91}
tests/mocks/Unity/DashCommunicator/dashcommunicatorservice.cpp+2−2
@@ -27,7 +27,7 @@ DashCommunicatorService::~DashCommunicatorService()
27
27
28}
28}
29
29
30−void DashCommunicatorService::mockSetCurrentScope(const QString &scopeId, bool animate, bool reset)
30+void DashCommunicatorService::mockSetCurrentScope(const QString &scopeId, bool animate, bool isSwipe)
31{
31{
32− Q_EMIT setCurrentScopeRequested(scopeId, animate, reset);
32+ Q_EMIT setCurrentScopeRequested(scopeId, animate, isSwipe);
33}
33}
tests/mocks/Unity/DashCommunicator/dashcommunicatorservice.h+2−2
@@ -27,10 +27,10 @@ public:
27 ~DashCommunicatorService();
27 ~DashCommunicatorService();
28
28
29Q_SIGNALS:
29Q_SIGNALS:
30− void setCurrentScopeRequested(const QString &scopeId, bool animate, bool reset);
30+ void setCurrentScopeRequested(const QString &scopeId, bool animate, bool isSwipe);
31
31
32public Q_SLOTS:
32public Q_SLOTS:
33− void mockSetCurrentScope(const QString &scopeId, bool animate, bool reset);
33+ void mockSetCurrentScope(const QString &scopeId, bool animate, bool isSwipe);
34};
34};
35
35
36#endif // DBUSUNITYSESSIONSERVICE_H
36#endif // DBUSUNITYSESSIONSERVICE_H
tests/mocks/Unity/Indicators/Indicators.qmltypes+20
@@ -159,6 +159,26 @@ Module {
159 Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }
159 Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }
160 }
160 }
161 Component { name: "QIdentityProxyModel"; prototype: "QAbstractProxyModel" }
161 Component { name: "QIdentityProxyModel"; prototype: "QAbstractProxyModel" }
162+ Component {
163+ name: "UnityMenuModelCache"
164+ prototype: "QObject"
165+ exports: ["Unity.Indicators/UnityMenuModelCache 0.1"]
166+ isCreatable: false
167+ isSingleton: true
168+ exportMetaObjectRevisions: [0]
169+ Method {
170+ name: "model"
171+ type: "UnityMenuModel*"
172+ Parameter { name: "bus"; type: "QByteArray" }
173+ Parameter { name: "path"; type: "QByteArray" }
174+ Parameter { name: "actions"; type: "QVariantMap" }
175+ }
176+ Method {
177+ name: "contains"
178+ type: "bool"
179+ Parameter { name: "path"; type: "QByteArray" }
180+ }
181+ }
162 Component {
182 Component {
163 name: "UnityMenuModelStack"
183 name: "UnityMenuModelStack"
164 prototype: "QObject"
184 prototype: "QObject"
tests/mocks/Unity/Unity.qmltypes+30−2
@@ -36,6 +36,10 @@ Module {
36 prototype: "unity::shell::scopes::PreviewModelInterface"
36 prototype: "unity::shell::scopes::PreviewModelInterface"
37 exports: ["Unity/FakePreviewModel 0.2"]
37 exports: ["Unity/FakePreviewModel 0.2"]
38 exportMetaObjectRevisions: [0]
38 exportMetaObjectRevisions: [0]
39+ Method {
40+ name: "setLoaded"
41+ Parameter { type: "bool" }
42+ }
39 }
43 }
40 Component {
44 Component {
41 name: "PreviewStack"
45 name: "PreviewStack"
@@ -59,9 +63,9 @@ Module {
59 Component {
63 Component {
60 name: "ResultsModel"
64 name: "ResultsModel"
61 prototype: "unity::shell::scopes::ResultsModelInterface"
65 prototype: "unity::shell::scopes::ResultsModelInterface"
62− exports: ["Unity/ResultsModel 0.2"]
66+ exports: ["Unity/FakeResultsModel 0.2", "Unity/ResultsModel 0.2"]
63 isCreatable: false
67 isCreatable: false
64− exportMetaObjectRevisions: [0]
68+ exportMetaObjectRevisions: [0, 0]
65 }
69 }
66 Component {
70 Component {
67 name: "Scope"
71 name: "Scope"
@@ -134,7 +138,13 @@ Module {
134 }
138 }
135 Method { name: "clear" }
139 Method { name: "clear" }
136 Method { name: "load" }
140 Method { name: "load" }
141+ Method {
142+ name: "getScopeFromAll"
143+ type: "Scope*"
144+ Parameter { name: "scope_id"; type: "string" }
145+ }
137 }
146 }
147+ Component { name: "SettingsModel"; prototype: "unity::shell::scopes::SettingsModelInterface" }
138 Component {
148 Component {
139 name: "unity::shell::scopes::CategoriesInterface"
149 name: "unity::shell::scopes::CategoriesInterface"
140 prototype: "QAbstractListModel"
150 prototype: "QAbstractListModel"
@@ -402,4 +412,22 @@ Module {
402 Parameter { name: "scopeId"; type: "string" }
412 Parameter { name: "scopeId"; type: "string" }
403 }
413 }
404 }
414 }
415+ Component {
416+ name: "unity::shell::scopes::SettingsModelInterface"
417+ prototype: "QAbstractListModel"
418+ exports: ["Unity/SettingsModel 0.2"]
419+ isCreatable: false
420+ exportMetaObjectRevisions: [0]
421+ Enum {
422+ name: "Roles"
423+ values: {
424+ "RoleSettingId": 0,
425+ "RoleDisplayName": 1,
426+ "RoleType": 2,
427+ "RoleProperties": 3,
428+ "RoleValue": 4
429+ }
430+ }
431+ Property { name: "count"; type: "int"; isReadonly: true }
432+ }
405}
433}
tests/mocks/Unity/fake_scope.cpp+1−1
@@ -24,7 +24,7 @@
24#include "fake_scopes.h"
24#include "fake_scopes.h"
25#include "fake_settingsmodel.h"
25#include "fake_settingsmodel.h"
26
26
27−Scope::Scope(Scopes* parent) : Scope(QString(), QString(), false, parent)
27+Scope::Scope(Scopes* parent) : Scope("MockScope5", "Mock Scope", false, parent)
28{
28{
29}
29}
30
30
tests/plugins/Dash/cardcreator/2.res+2−2
@@ -94,7 +94,7 @@ Image {
94 wrapMode: Text.Wrap;
94 wrapMode: Text.Wrap;
95 maximumLineCount: 2;
95 maximumLineCount: 2;
96 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
96 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
97− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
97+ 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");
98 visible: showHeader ;
98 visible: showHeader ;
99 text: root.title;
99 text: root.title;
100 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
100 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
@@ -112,7 +112,7 @@ Image {
112 elide: Text.ElideRight;
112 elide: Text.ElideRight;
113 fontSize: "small";
113 fontSize: "small";
114 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
114 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
115− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
115+ 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");
116 visible: titleLabel.visible && titleLabel.text;
116 visible: titleLabel.visible && titleLabel.text;
117 text: cardData && cardData["subtitle"] || "";
117 text: cardData && cardData["subtitle"] || "";
118 font.weight: Font.Light;
118 font.weight: Font.Light;
tests/plugins/Dash/cardcreator/5.res+2−2
@@ -114,7 +114,7 @@ Label {
114 wrapMode: Text.Wrap;
114 wrapMode: Text.Wrap;
115 maximumLineCount: 2;
115 maximumLineCount: 2;
116 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
116 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
117− color: root.scopeStyle ? root.scopeStyle.getTextColor(overlayLoader.item.luminance) : (overlayLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
117+ color: root.scopeStyle && overlayLoader.item ? root.scopeStyle.getTextColor(overlayLoader.item.luminance) : (overlayLoader.item && overlayLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
118 visible: showHeader && overlayLoader.active;
118 visible: showHeader && overlayLoader.active;
119 text: root.title;
119 text: root.title;
120 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
120 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
@@ -133,7 +133,7 @@ Label {
133 elide: Text.ElideRight;
133 elide: Text.ElideRight;
134 fontSize: "small";
134 fontSize: "small";
135 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
135 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
136− color: root.scopeStyle ? root.scopeStyle.getTextColor(overlayLoader.item.luminance) : (overlayLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
136+ color: root.scopeStyle && overlayLoader.item ? root.scopeStyle.getTextColor(overlayLoader.item.luminance) : (overlayLoader.item && overlayLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
137 visible: titleLabel.visible && titleLabel.text;
137 visible: titleLabel.visible && titleLabel.text;
138 text: cardData && cardData["subtitle"] || "";
138 text: cardData && cardData["subtitle"] || "";
139 font.weight: Font.Light;
139 font.weight: Font.Light;
tests/plugins/Dash/cardcreator/6.res+3−3
@@ -70,7 +70,7 @@ Item {
70 wrapMode: Text.Wrap;
70 wrapMode: Text.Wrap;
71 maximumLineCount: 2;
71 maximumLineCount: 2;
72 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
72 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
73− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
73+ 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");
74 visible: showHeader ;
74 visible: showHeader ;
75 text: root.title;
75 text: root.title;
76 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
76 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
@@ -88,7 +88,7 @@ Item {
88 elide: Text.ElideRight;
88 elide: Text.ElideRight;
89 fontSize: "small";
89 fontSize: "small";
90 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
90 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
91− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
91+ 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");
92 visible: titleLabel.visible && titleLabel.text;
92 visible: titleLabel.visible && titleLabel.text;
93 text: cardData && cardData["subtitle"] || "";
93 text: cardData && cardData["subtitle"] || "";
94 font.weight: Font.Light;
94 font.weight: Font.Light;
@@ -103,7 +103,7 @@ Item {
103 rightMargin: units.gu(1);
103 rightMargin: units.gu(1);
104 }
104 }
105 source: cardData && cardData["emblem"] || "";
105 source: cardData && cardData["emblem"] || "";
106− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
106+ 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");
107 width: height;
107 width: height;
108 height: source != "" ? titleLabel.font.pixelSize : 0;
108 height: source != "" ? titleLabel.font.pixelSize : 0;
109 }
109 }
tests/plugins/Dash/cardcreator/7.res+3−3
@@ -95,7 +95,7 @@ Image {
95 wrapMode: Text.Wrap;
95 wrapMode: Text.Wrap;
96 maximumLineCount: 2;
96 maximumLineCount: 2;
97 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
97 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
98− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
98+ 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");
99 visible: showHeader ;
99 visible: showHeader ;
100 text: root.title;
100 text: root.title;
101 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
101 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
@@ -113,7 +113,7 @@ Image {
113 elide: Text.ElideRight;
113 elide: Text.ElideRight;
114 fontSize: "small";
114 fontSize: "small";
115 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
115 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
116− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
116+ 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");
117 visible: titleLabel.visible && titleLabel.text;
117 visible: titleLabel.visible && titleLabel.text;
118 text: cardData && cardData["subtitle"] || "";
118 text: cardData && cardData["subtitle"] || "";
119 font.weight: Font.Light;
119 font.weight: Font.Light;
@@ -127,7 +127,7 @@ Image {
127 rightMargin: units.gu(1);
127 rightMargin: units.gu(1);
128 top: subtitleLabel.bottom;
128 top: subtitleLabel.bottom;
129 }
129 }
130− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
130+ 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");
131 fontScale: root.fontScale;
131 fontScale: root.fontScale;
132 model: cardData && cardData["attributes"];
132 model: cardData && cardData["attributes"];
133 }
133 }
tests/plugins/Unity/Launcher/CMakeLists.txt+1−1
@@ -35,7 +35,7 @@ add_executable(launchermodeltestExec
35 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
35 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
36 )
36 )
37target_link_libraries(launchermodeltestExec ${GSETTINGS_QT_LDFLAGS})
37target_link_libraries(launchermodeltestExec ${GSETTINGS_QT_LDFLAGS})
38−qt5_use_modules(launchermodeltestExec Test Core DBus Xml)
38+qt5_use_modules(launchermodeltestExec Test Core DBus Xml Gui)
39
39
40# copy .desktop files into build directory for shadow builds
40# copy .desktop files into build directory for shadow builds
41file(GLOB DESKTOP_FILES *.desktop)
41file(GLOB DESKTOP_FILES *.desktop)
tests/qmltests/CMakeLists.txt+1
@@ -86,3 +86,4 @@ add_qml_test(Stages ApplicationWindow ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINAR
86add_qml_test(Stages PhoneStage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
86add_qml_test(Stages PhoneStage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
87add_qml_test(Stages SpreadDelegate ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
87add_qml_test(Stages SpreadDelegate ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
88add_qml_test(Stages SurfaceContainer ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
88add_qml_test(Stages SurfaceContainer ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
89+add_qml_test(Stages SessionContainer ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
tests/qmltests/Dash/Previews/tst_PreviewPayments.qml+49−9
@@ -48,19 +48,28 @@ Rectangle {
48 UT.UnityTestCase {
48 UT.UnityTestCase {
49 name: "PreviewPaymentsTest"
49 name: "PreviewPaymentsTest"
50 when: windowShown
50 when: windowShown
51+ property var paymentClient
52+
53+ function init()
54+ {
55+ paymentClient = findInvisibleChild(previewPayments, "paymentClient");
56+ verify(paymentClient, "Could not find the payment client object.");
57+ }
51
58
52 function cleanup()
59 function cleanup()
53 {
60 {
61+ paymentClient = null;
62+ previewPayments.widgetData = null;
54 spy.clear();
63 spy.clear();
55− var button = findChild(root, "paymentButton");
64+ var button = findChild(previewPayments, "paymentButton");
56 button.opacity = 1;
65 button.opacity = 1;
57 }
66 }
58
67
59 function test_purchase_text_display() {
68 function test_purchase_text_display() {
60 previewPayments.widgetData = jsonPurchase;
69 previewPayments.widgetData = jsonPurchase;
61
70
62− var button = findChild(root, "paymentButton");
71+ var button = findChild(previewPayments, "paymentButton");
63− verify(button != null, "Button not found.");
72+ verify(button, "Button not found.");
64 compare(button.text, "0.99USD");
73 compare(button.text, "0.99USD");
65 }
74 }
66
75
@@ -68,11 +77,12 @@ Rectangle {
68 // Exercise the purchaseCompleted signal here.
77 // Exercise the purchaseCompleted signal here.
69 previewPayments.widgetData = jsonPurchase;
78 previewPayments.widgetData = jsonPurchase;
70
79
71− var button = findChild(root, "paymentButton");
80+ var button = findChild(previewPayments, "paymentButton");
72− verify(button != null, "Button not found.");
81+ verify(button, "Button not found.");
73
82
74 mouseClick(button, button.width / 2, button.height / 2);
83 mouseClick(button, button.width / 2, button.height / 2);
75
84
85+ paymentClient.process();
76 spy.wait();
86 spy.wait();
77
87
78 var args = spy.signalArguments[0];
88 var args = spy.signalArguments[0];
@@ -85,8 +95,8 @@ Rectangle {
85 // Make sure the progress bar is shown.
95 // Make sure the progress bar is shown.
86 previewPayments.widgetData = jsonPurchase;
96 previewPayments.widgetData = jsonPurchase;
87
97
88− var button = findChild(root, "paymentButton");
98+ var button = findChild(previewPayments, "paymentButton");
89− var progress = findChild(root, "loadingBar");
99+ var progress = findChild(previewPayments, "loadingBar");
90
100
91 tryCompare(progress, "visible", false);
101 tryCompare(progress, "visible", false);
92 tryCompare(progress, "opacity", 0);
102 tryCompare(progress, "opacity", 0);
@@ -95,6 +105,7 @@ Rectangle {
95
105
96 mouseClick(button, button.width / 2, button.height / 2);
106 mouseClick(button, button.width / 2, button.height / 2);
97
107
108+ paymentClient.process();
98 spy.wait();
109 spy.wait();
99
110
100 tryCompare(progress, "visible", true);
111 tryCompare(progress, "visible", true);
@@ -103,16 +114,45 @@ Rectangle {
103 tryCompare(button, "opacity", 0);
114 tryCompare(button, "opacity", 0);
104 }
115 }
105
116
117+ function test_progress_show_cancel() {
118+ // Make sure the progress bar is shown.
119+ previewPayments.widgetData = jsonPurchaseError;
120+
121+ var button = findChild(previewPayments, "paymentButton");
122+ var progress = findChild(previewPayments, "loadingBar");
123+
124+ tryCompare(progress, "visible", false);
125+ tryCompare(progress, "opacity", 0);
126+ tryCompare(button, "visible", true);
127+ tryCompare(button, "opacity", 1);
128+
129+ mouseClick(button, button.width / 2, button.height / 2);
130+
131+ tryCompare(progress, "visible", true);
132+ tryCompare(progress, "opacity", 1);
133+ tryCompare(button, "visible", false);
134+ tryCompare(button, "opacity", 0);
135+
136+ paymentClient.process();
137+ spy.wait();
138+
139+ tryCompare(progress, "visible", false);
140+ tryCompare(progress, "opacity", 0);
141+ tryCompare(button, "visible", true);
142+ tryCompare(button, "opacity", 1);
143+ }
144+
106 function test_purchase_error() {
145 function test_purchase_error() {
107 // The mock Payments triggers an error when com.example.invalid is
146 // The mock Payments triggers an error when com.example.invalid is
108 // passed to it as store_item_id. Exercise it here
147 // passed to it as store_item_id. Exercise it here
109 previewPayments.widgetData = jsonPurchaseError;
148 previewPayments.widgetData = jsonPurchaseError;
110
149
111− var button = findChild(root, "paymentButton");
150+ var button = findChild(previewPayments, "paymentButton");
112− verify(button != null, "Button not found.");
151+ verify(button, "Button not found.");
113
152
114 mouseClick(button, button.width / 2, button.height / 2);
153 mouseClick(button, button.width / 2, button.height / 2);
115
154
155+ paymentClient.process();
116 spy.wait();
156 spy.wait();
117
157
118 var args = spy.signalArguments[0];
158 var args = spy.signalArguments[0];
tests/qmltests/Dash/tst_Dash.qml+9−2
@@ -189,6 +189,14 @@ Item {
189 var scopesOverviewAllView = findChild(dash, "scopesOverviewRepeaterChild1");
189 var scopesOverviewAllView = findChild(dash, "scopesOverviewRepeaterChild1");
190 tryCompare(scopesOverviewAllView, "enabled", true);
190 tryCompare(scopesOverviewAllView, "enabled", true);
191
191
192+ // Click in the middle of the black bar (nothing happens)
193+ var bottomBar = findChild(scopesOverview, "bottomBar");
194+ mouseClick(bottomBar, bottomBar.width / 2, bottomBar.height / 2);
195+ // Check temp scope is not there
196+ var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem");
197+ expectFailContinue("", "Clicking in the middle of bottom bar should not open a temp scope");
198+ tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope != null; }, true);
199+
192 // Click on a temp scope
200 // Click on a temp scope
193 var tempScopeCard = findChild(scopesOverviewAllView, "delegate1");
201 var tempScopeCard = findChild(scopesOverviewAllView, "delegate1");
194 mouseClick(tempScopeCard, 0, 0);
202 mouseClick(tempScopeCard, 0, 0);
@@ -198,7 +206,6 @@ Item {
198 compare(overviewDragHandle.enabled, false);
206 compare(overviewDragHandle.enabled, false);
199
207
200 // Check temp scope is there
208 // Check temp scope is there
201− var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem");
202 tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope != null; }, true);
209 tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope != null; }, true);
203 tryCompare(scopesOverviewTempScopeItem, "enabled", true);
210 tryCompare(scopesOverviewTempScopeItem, "enabled", true);
204
211
@@ -328,7 +335,7 @@ Item {
328 mouseFlick(dash, startX, startY, stopX, stopY);
335 mouseFlick(dash, startX, startY, stopX, stopY);
329 compare(dashContentList.currentIndex, 2, "Could not flick to scope id 2");
336 compare(dashContentList.currentIndex, 2, "Could not flick to scope id 2");
330 var dashCommunicatorService = findInvisibleChild(dash, "dashCommunicatorService");
337 var dashCommunicatorService = findInvisibleChild(dash, "dashCommunicatorService");
331− dashCommunicatorService.mockSetCurrentScope("clickscope", true, true);
338+ dashCommunicatorService.mockSetCurrentScope("clickscope", true, false);
332 tryCompare(dashContentList, "currentIndex", 1)
339 tryCompare(dashContentList, "currentIndex", 1)
333 }
340 }
334
341
tests/qmltests/Dash/tst_PreviewListView.qml+29−1
@@ -16,6 +16,7 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import QtTest 1.0
18import QtTest 1.0
19+import Ubuntu.Components 1.1
19import "../../../qml/Dash"
20import "../../../qml/Dash"
20import Unity.Test 0.1 as UT
21import Unity.Test 0.1 as UT
21import Unity 0.2 as Unity
22import Unity 0.2 as Unity
@@ -39,7 +40,9 @@ Rectangle {
39 id: listView
40 id: listView
40 anchors.fill: parent
41 anchors.fill: parent
41 scope: mockScope
42 scope: mockScope
42− scopeStyle: ScopeStyle { }
43+ scopeStyle: ScopeStyle {
44+ style: mockScope.customizations
45+ }
43 }
46 }
44
47
45 UT.UnityTestCase {
48 UT.UnityTestCase {
@@ -83,5 +86,30 @@ Rectangle {
83 mouseClick(listView, listView.width / 2, listView.height / 2);
86 mouseClick(listView, listView.width / 2, listView.height / 2);
84 clickedSpy.wait();
87 clickedSpy.wait();
85 }
88 }
89+
90+ function test_title() {
91+ var header = findChild(listView, "innerPageHeader");
92+ verify(header, "Could not find the preview header");
93+
94+ compare(header.title, "Mock Scope");
95+ }
96+
97+ function test_header_style() {
98+ var header = findChild(listView, "pageHeader");
99+ verify(header, "Could not find the header");
100+
101+ var innerHeader = findChild(header, "innerPageHeader");
102+ verify(innerHeader, "Could not find the inner header");
103+ verify(Qt.colorEqual(innerHeader.textColor, UbuntuColors.darkGrey),
104+ "Foreground color not equal: %1 != %2".arg(innerHeader.textColor).arg(UbuntuColors.darkGrey));
105+
106+ var background = findChild(header, "headerBackground");
107+ verify(background, "Could not find the background");
108+ compare(background.style, "gradient:///lightgrey/grey");
109+
110+ var image = findChild(header, "titleImage");
111+ verify(image, "Could not find the title image.");
112+ compare(image.source, Qt.resolvedUrl("../Dash/tst_PageHeader/logo-ubuntu-orange.svg"), "Title image has the wrong source");
113+ }
86 }
114 }
87}
115}
tests/qmltests/Notifications/tst_Notifications.qml+59−17
@@ -64,7 +64,7 @@ Row {
64 function addSnapDecisionNotification() {
64 function addSnapDecisionNotification() {
65 var n = {
65 var n = {
66 type: Notification.SnapDecision,
66 type: Notification.SnapDecision,
67− hints: {"x-canonical-private-button-tint": "true"},
67+ hints: {"x-canonical-private-affirmative-tint": "true"},
68 summary: "Tom Ato",
68 summary: "Tom Ato",
69 body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
69 body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
70 icon: "../graphics/avatars/funky.png",
70 icon: "../graphics/avatars/funky.png",
@@ -79,6 +79,22 @@ Row {
79 mockModel.append(n)
79 mockModel.append(n)
80 }
80 }
81
81
82+ function add2over1SnapDecisionNotification() {
83+ var n = {
84+ type: Notification.SnapDecision,
85+ hints: {"x-canonical-private-affirmative-tint": "true",},
86+ summary: "Theatre at Ferria Stadium",
87+ body: "at Ferria Stadium in Bilbao, Spain\n07578545317",
88+ icon: "",
89+ secondaryIcon: "",
90+ actions: [{ id: "ok_id", label: "Ok"},
91+ { id: "snooze_id", label: "Snooze"},
92+ { id: "view_id", label: "View"}]
93+ }
94+
95+ mockModel.append(n)
96+ }
97+
82 function addEphemeralNotification() {
98 function addEphemeralNotification() {
83 var n = {
99 var n = {
84 type: Notification.Ephemeral,
100 type: Notification.Ephemeral,
@@ -181,6 +197,12 @@ Row {
181 onClicked: addSnapDecisionNotification()
197 onClicked: addSnapDecisionNotification()
182 }
198 }
183
199
200+ Button {
201+ width: parent.width
202+ text: "add a 2over1 snap-decision"
203+ onClicked: add2over1SnapDecisionNotification()
204+ }
205+
184 Button {
206 Button {
185 width: parent.width
207 width: parent.width
186 text: "add an ephemeral"
208 text: "add an ephemeral"
@@ -229,7 +251,7 @@ Row {
229 {
251 {
230 tag: "Snap Decision with secondary icon and button-tint",
252 tag: "Snap Decision with secondary icon and button-tint",
231 type: Notification.SnapDecision,
253 type: Notification.SnapDecision,
232− hints: {"x-canonical-private-button-tint": "true"},
254+ hints: {"x-canonical-private-affirmative-tint": "true"},
233 summary: "Tom Ato",
255 summary: "Tom Ato",
234 body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
256 body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
235 icon: "../graphics/avatars/funky.png",
257 icon: "../graphics/avatars/funky.png",
@@ -249,10 +271,31 @@ Row {
249 buttonTinted: true,
271 buttonTinted: true,
250 hasSound: false
272 hasSound: false
251 },
273 },
274+ {
275+ tag: "2-over-1 Snap Decision with button-tint",
276+ type: Notification.SnapDecision,
277+ hints: {"x-canonical-private-affirmative-tint": "true"},
278+ summary: "Theatre at Ferria Stadium",
279+ body: "at Ferria Stadium in Bilbao, Spain\n07578545317",
280+ icon: "",
281+ secondaryIcon: "",
282+ actions: [{ id: "ok_id", label: "Ok"},
283+ { id: "snooze_id", label: "Snooze"},
284+ { id: "view_id", label: "View"}],
285+ summaryVisible: true,
286+ bodyVisible: true,
287+ iconVisible: false,
288+ shapedIcon: false,
289+ nonShapedIcon: false,
290+ secondaryIconVisible: false,
291+ buttonRowVisible: false,
292+ buttonTinted: true,
293+ hasSound: false
294+ },
252 {
295 {
253 tag: "Ephemeral notification - icon-summary layout",
296 tag: "Ephemeral notification - icon-summary layout",
254 type: Notification.Ephemeral,
297 type: Notification.Ephemeral,
255− hints: {"x-canonical-private-button-tint": "false"},
298+ hints: {"x-canonical-private-affirmative-tint": "false"},
256 summary: "Photo upload completed",
299 summary: "Photo upload completed",
257 body: "",
300 body: "",
258 icon: "",
301 icon: "",
@@ -271,7 +314,7 @@ Row {
271 {
314 {
272 tag: "Ephemeral notification - check suppression of secondary icon for icon-summary layout",
315 tag: "Ephemeral notification - check suppression of secondary icon for icon-summary layout",
273 type: Notification.Ephemeral,
316 type: Notification.Ephemeral,
274− hints: {"x-canonical-private-button-tint": "false",
317+ hints: {"x-canonical-private-affirmative-tint": "false",
275 "sound-file": "dummy.ogg",
318 "sound-file": "dummy.ogg",
276 "suppress-sound": "true"},
319 "suppress-sound": "true"},
277 summary: "New comment successfully published",
320 summary: "New comment successfully published",
@@ -293,7 +336,7 @@ Row {
293 {
336 {
294 tag: "Interactive notification",
337 tag: "Interactive notification",
295 type: Notification.Interactive,
338 type: Notification.Interactive,
296− hints: {"x-canonical-private-button-tint": "false",
339+ hints: {"x-canonical-private-affirmative-tint": "false",
297 "sound-file": "dummy.ogg"},
340 "sound-file": "dummy.ogg"},
298 summary: "Interactive notification",
341 summary: "Interactive notification",
299 body: "This is a notification that can be clicked",
342 body: "This is a notification that can be clicked",
@@ -313,7 +356,7 @@ Row {
313 {
356 {
314 tag: "Snap Decision without secondary icon and no button-tint",
357 tag: "Snap Decision without secondary icon and no button-tint",
315 type: Notification.SnapDecision,
358 type: Notification.SnapDecision,
316− hints: {"x-canonical-private-button-tint": "false",
359+ hints: {"x-canonical-private-affirmative-tint": "false",
317 "sound-file": "dummy.ogg"},
360 "sound-file": "dummy.ogg"},
318 summary: "Bro Coly",
361 summary: "Bro Coly",
319 body: "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
362 body: "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
@@ -334,7 +377,7 @@ Row {
334 {
377 {
335 tag: "Ephemeral notification",
378 tag: "Ephemeral notification",
336 type: Notification.Ephemeral,
379 type: Notification.Ephemeral,
337− hints: {"x-canonical-private-button-tint": "false",
380+ hints: {"x-canonical-private-affirmative-tint": "false",
338 "sound-file": "dummy.ogg"},
381 "sound-file": "dummy.ogg"},
339 summary: "Cole Raby",
382 summary: "Cole Raby",
340 body: "I did not expect it to be that late.",
383 body: "I did not expect it to be that late.",
@@ -354,9 +397,8 @@ Row {
354 {
397 {
355 tag: "Ephemeral notification with non-shaped icon",
398 tag: "Ephemeral notification with non-shaped icon",
356 type: Notification.Ephemeral,
399 type: Notification.Ephemeral,
357− hints: {"x-canonical-private-button-tint": "false",
400+ hints: {"x-canonical-private-affirmative-tint": "false",
358− "x-canonical-non-shaped-icon": "true",
401+ "x-canonical-non-shaped-icon": "true"},
359− "sound-file": "dummy.ogg"},
360 summary: "Contacts",
402 summary: "Contacts",
361 body: "Synchronised contacts-database with cloud-storage.",
403 body: "Synchronised contacts-database with cloud-storage.",
362 icon: "../graphics/applicationIcons/contacts-app.png",
404 icon: "../graphics/applicationIcons/contacts-app.png",
@@ -370,7 +412,7 @@ Row {
370 secondaryIconVisible: false,
412 secondaryIconVisible: false,
371 buttonRowVisible: false,
413 buttonRowVisible: false,
372 buttonTinted: false,
414 buttonTinted: false,
373− hasSound: true
415+ hasSound: false
374 }
416 }
375 ]
417 ]
376 }
418 }
@@ -437,8 +479,8 @@ Row {
437 tryCompare(audioItem, "playbackState", data.hasSound ? Audio.PlayingState : Audio.StoppedState)
479 tryCompare(audioItem, "playbackState", data.hasSound ? Audio.PlayingState : Audio.StoppedState)
438
480
439 if(data.buttonRowVisible) {
481 if(data.buttonRowVisible) {
440− var buttonCancel = findChild(buttonRow, "button1")
482+ var buttonCancel = findChild(buttonRow, "notify_button1")
441− var buttonAccept = findChild(buttonRow, "button0")
483+ var buttonAccept = findChild(buttonRow, "notify_button0")
442
484
443 // only test the left/cancel-button if two actions have been passed in
485 // only test the left/cancel-button if two actions have been passed in
444 if (data.actions.length == 2) {
486 if (data.actions.length == 2) {
@@ -448,7 +490,7 @@ Row {
448 }
490 }
449
491
450 // check the tinting of the positive/right button
492 // check the tinting of the positive/right button
451− verify(buttonAccept.gradient === data.buttonTinted ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient, "button has the wrong color-tint")
493+ verify(buttonAccept.color === data.buttonTinted ? "#3fb24f" : "#dddddd", "button has the wrong color-tint")
452
494
453 // click the positive/right button
495 // click the positive/right button
454 tryCompareFunction(function() { mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2); return actionSpy.signalArguments.length > 0; }, true);
496 tryCompareFunction(function() { mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2); return actionSpy.signalArguments.length > 0; }, true);
@@ -458,19 +500,19 @@ Row {
458
500
459 // check if there's a ComboButton created due to more actions being passed
501 // check if there's a ComboButton created due to more actions being passed
460 if (data.actions.length > 2) {
502 if (data.actions.length > 2) {
461− var comboButton = findChild(notification, "button2")
503+ var comboButton = findChild(notification, "notify_button2")
462 tryCompareFunction(function() { return comboButton.expanded == false; }, true);
504 tryCompareFunction(function() { return comboButton.expanded == false; }, true);
463
505
464 // click to expand
506 // click to expand
465 tryCompareFunction(function() { mouseClick(comboButton, comboButton.width - comboButton.__styleInstance.dropDownWidth / 2, comboButton.height / 2); return comboButton.expanded == true; }, true);
507 tryCompareFunction(function() { mouseClick(comboButton, comboButton.width - comboButton.__styleInstance.dropDownWidth / 2, comboButton.height / 2); return comboButton.expanded == true; }, true);
466
508
467 // try clicking on choices in expanded comboList
509 // try clicking on choices in expanded comboList
468− var choiceButton1 = findChild(notification, "button3")
510+ var choiceButton1 = findChild(notification, "notify_button3")
469 tryCompareFunction(function() { mouseClick(choiceButton1, choiceButton1.width / 2, choiceButton1.height / 2); return actionSpy.signalArguments.length > 0; }, true);
511 tryCompareFunction(function() { mouseClick(choiceButton1, choiceButton1.width / 2, choiceButton1.height / 2); return actionSpy.signalArguments.length > 0; }, true);
470 compare(actionSpy.signalArguments[0][0], data.actions[3]["id"], "got wrong id choice action 1")
512 compare(actionSpy.signalArguments[0][0], data.actions[3]["id"], "got wrong id choice action 1")
471 actionSpy.clear()
513 actionSpy.clear()
472
514
473− var choiceButton2 = findChild(notification, "button4")
515+ var choiceButton2 = findChild(notification, "notify_button4")
474 tryCompareFunction(function() { mouseClick(choiceButton2, choiceButton2.width / 2, choiceButton2.height / 2); return actionSpy.signalArguments.length > 0; }, true);
516 tryCompareFunction(function() { mouseClick(choiceButton2, choiceButton2.width / 2, choiceButton2.height / 2); return actionSpy.signalArguments.length > 0; }, true);
475 compare(actionSpy.signalArguments[0][0], data.actions[4]["id"], "got wrong id choice action 2")
517 compare(actionSpy.signalArguments[0][0], data.actions[4]["id"], "got wrong id choice action 2")
476 actionSpy.clear()
518 actionSpy.clear()
tests/qmltests/Panel/tst_ActiveCallHint.qml+1−1
@@ -97,7 +97,7 @@ Item {
97 var application = ApplicationManager.startApplication("dialer-app");
97 var application = ApplicationManager.startApplication("dialer-app");
98 ApplicationManager.focusApplication("dialer-app");
98 ApplicationManager.focusApplication("dialer-app");
99 tryCompare(ApplicationManager, "focusedApplicationId", "dialer-app");
99 tryCompare(ApplicationManager, "focusedApplicationId", "dialer-app");
100− tryCompare(application, "state", ApplicationInfo.Running);
100+ tryCompare(application, "state", ApplicationInfoInterface.Running);
101
101
102 if (!data.focused) { ApplicationManager.unfocusCurrentApplication(); }
102 if (!data.focused) { ApplicationManager.unfocusCurrentApplication(); }
103 }
103 }
tests/qmltests/Stages/RecursingChildSessionControl.qmlnew file+142
@@ -0,0 +1,142 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.1
18+import QtQuick.Layouts 1.1
19+import Ubuntu.Components 0.1
20+import Unity.Application 0.1
21+
22+ColumnLayout {
23+ id: root
24+
25+ property var session
26+ property var childSessions: session ? session.childSessions : 0
27+ property bool removable: false
28+ property alias surfaceCheckbox: _surfaceCheckbox
29+
30+ property var screenshotIds: [ "gallery", "map", "facebook", "camera", "browser", "music", "twitter"]
31+
32+ onSessionChanged: {
33+ if (!session) surfaceCheckbox.checked = false;
34+ }
35+
36+ Column {
37+ id: column
38+ Layout.fillWidth: true
39+ visible: repeater.count
40+ spacing: units.gu(1)
41+
42+ Repeater {
43+ id: repeater
44+ model: root.childSessions
45+ delegate: Rectangle {
46+ border {
47+ color: "black"
48+ width: 1
49+ }
50+ anchors {
51+ left: column.left
52+ right: column.right
53+ leftMargin: units.gu(1)
54+ rightMargin: units.gu(1)
55+ }
56+ height: loader.height
57+
58+ Rectangle {
59+ anchors.fill: parent
60+ color: Qt.rgba(Math.random(), Math.random(), Math.random(), 0.4 )
61+ }
62+
63+ Loader {
64+ id: loader
65+ visible: status == Loader.Ready
66+ source: Qt.resolvedUrl("RecursingChildSessionControl.qml")
67+
68+ anchors {
69+ left: parent.left
70+ right: parent.right
71+ }
72+
73+ onLoaded: {
74+ item.session = modelData;
75+ item.removable = true;
76+ }
77+ }
78+ }
79+ }
80+ }
81+
82+ ColumnLayout {
83+ Layout.fillWidth: true
84+ spacing: units.gu(1)
85+
86+ RowLayout {
87+ Layout.fillWidth: true
88+
89+ CheckBox {
90+ id: _surfaceCheckbox;
91+ checked: false;
92+ enabled: root.session
93+ onCheckedChanged: {
94+ if (checked) {
95+ root.session.createSurface();
96+ } else if (root.session.surface) {
97+ ApplicationTest.removeSurface(root.session.surface);
98+ }
99+ }
100+
101+ Connections {
102+ target: root.session ? root.session : null
103+ onSurfaceChanged: {
104+ surfaceCheckbox.checked = root.session.surface !== null
105+ }
106+ }
107+ }
108+
109+ Label {
110+ text: "Surface"
111+ anchors.verticalCenter: parent.verticalCenter
112+ }
113+ }
114+
115+ RowLayout {
116+ id: buttonLayout
117+
118+ Button {
119+ enabled: root.session
120+ text: removable ? "Remove" : "Release"
121+ onClicked: {
122+ if (removable) {
123+ // release the surface first. simulates mir app closing
124+ if (root.session.surface) ApplicationTest.removeSurface(root.session.surface);
125+ ApplicationTest.removeSession(root.session);
126+ } else {
127+ root.session.release();
128+ }
129+ }
130+ }
131+
132+ Button {
133+ enabled: root.session !== null
134+ text: "Add Child"
135+ onClicked: {
136+ var screenshot = Math.round(Math.random()*100 % (screenshotIds.length-1));
137+ var session = ApplicationTest.addChildSession(root.session, root.screenshotIds[screenshot]);
138+ }
139+ }
140+ }
141+ }
142+}
tests/qmltests/Stages/tst_ApplicationWindow.qml+99−47
@@ -14,7 +14,8 @@
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−import QtQuick 2.0
17+import QtQuick 2.1
18+import QtQuick.Layouts 1.1
18import QtTest 1.0
19import QtTest 1.0
19import Unity.Test 0.1 as UT
20import Unity.Test 0.1 as UT
20import ".."
21import ".."
@@ -32,14 +33,15 @@ Rectangle {
32 Component.onCompleted: {
33 Component.onCompleted: {
33 root.fakeApplication = ApplicationManager.add("gallery-app");
34 root.fakeApplication = ApplicationManager.add("gallery-app");
34 root.fakeApplication.manualSurfaceCreation = true;
35 root.fakeApplication.manualSurfaceCreation = true;
35− root.fakeApplication.setState(ApplicationInfo.Starting);
36+ root.fakeApplication.setState(ApplicationInfoInterface.Starting);
36 }
37 }
37 property QtObject fakeApplication: null
38 property QtObject fakeApplication: null
39+ readonly property var fakeSession: fakeApplication ? fakeApplication.session : null
38
40
39 Connections {
41 Connections {
40 target: fakeApplication
42 target: fakeApplication
41− onSurfaceChanged: {
43+ onSessionChanged: {
42− surfaceCheckbox.checked = fakeApplication.surface !== null;
44+ sessionCheckbox.checked = fakeApplication.session !== null
43 }
45 }
44 }
46 }
45
47
@@ -50,15 +52,20 @@ Rectangle {
50 application: fakeApplication
52 application: fakeApplication
51 }
53 }
52 }
54 }
53− Loader {
55+ FocusScope {
54− id: applicationWindowLoader
56+ id: appFocus
55 anchors {
57 anchors {
56 top: parent.top
58 top: parent.top
57 bottom: parent.bottom
59 bottom: parent.bottom
58 left: parent.left
60 left: parent.left
59 }
61 }
60 width: units.gu(40)
62 width: units.gu(40)
63+
64+ Loader {
65+ id: applicationWindowLoader
66+ anchors.fill: parent
61− sourceComponent: applicationWindowComponent
67+ sourceComponent: applicationWindowComponent
68+ }
62 }
69 }
63
70
64 Rectangle {
71 Rectangle {
@@ -66,30 +73,55 @@ Rectangle {
66 anchors {
73 anchors {
67 top: parent.top
74 top: parent.top
68 bottom: parent.bottom
75 bottom: parent.bottom
69− left: applicationWindowLoader.right
76+ left: appFocus.right
70 right: parent.right
77 right: parent.right
71 }
78 }
72
79
73− Column {
80+ ColumnLayout {
74 anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
81 anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
75 spacing: units.gu(1)
82 spacing: units.gu(1)
76− Row {
83+
77− anchors { left: parent.left; right: parent.right }
84+ RowLayout {
85+ Layout.fillWidth: true
86+
78 CheckBox {
87 CheckBox {
79− id: surfaceCheckbox; checked: false
88+ id: sessionCheckbox; checked: false
80 onCheckedChanged: {
89 onCheckedChanged: {
81 if (applicationWindowLoader.status !== Loader.Ready)
90 if (applicationWindowLoader.status !== Loader.Ready)
82 return;
91 return;
83
92
84− if (checked && !fakeApplication.surface) {
93+ if (checked && !fakeApplication.session) {
85− fakeApplication.createSurface();
94+ fakeApplication.createSession();
86− } else if (!checked && fakeApplication.surface) {
95+ } else if (!checked && fakeApplication.session) {
87− fakeApplication.surface.release();
96+ fakeApplication.session.release();
88 }
97 }
89 }
98 }
90 }
99 }
91− Label { text: "Surface" }
100+ Label {
101+ text: "Session"
102+ anchors.verticalCenter: parent.verticalCenter
103+ }
92 }
104 }
105+
106+ Rectangle {
107+ border {
108+ color: "black"
109+ width: 1
110+ }
111+ anchors {
112+ left: parent.left
113+ right: parent.right
114+ }
115+ Layout.preferredHeight: sessionControl.height
116+
117+ RecursingChildSessionControl {
118+ id: sessionControl
119+ anchors { left: parent.left; right: parent.right; }
120+
121+ session: fakeSession
122+ }
123+ }
124+
93 ListItem.ItemSelector {
125 ListItem.ItemSelector {
94 id: appStateSelector
126 id: appStateSelector
95 anchors { left: parent.left; right: parent.right }
127 anchors { left: parent.left; right: parent.right }
@@ -100,13 +132,13 @@ Rectangle {
100 "Stopped"]
132 "Stopped"]
101 property int selectedApplicationState: {
133 property int selectedApplicationState: {
102 if (model[selectedIndex] === "Starting") {
134 if (model[selectedIndex] === "Starting") {
103− return ApplicationInfo.Starting;
135+ return ApplicationInfoInterface.Starting;
104 } else if (model[selectedIndex] === "Running") {
136 } else if (model[selectedIndex] === "Running") {
105− return ApplicationInfo.Running;
137+ return ApplicationInfoInterface.Running;
106 } else if (model[selectedIndex] === "Suspended") {
138 } else if (model[selectedIndex] === "Suspended") {
107− return ApplicationInfo.Suspended;
139+ return ApplicationInfoInterface.Suspended;
108 } else {
140 } else {
109− return ApplicationInfo.Stopped;
141+ return ApplicationInfoInterface.Stopped;
110 }
142 }
111 }
143 }
112 onSelectedApplicationStateChanged: {
144 onSelectedApplicationStateChanged: {
@@ -114,6 +146,7 @@ Rectangle {
114 fakeApplication.setState(selectedApplicationState);
146 fakeApplication.setState(selectedApplicationState);
115 }
147 }
116 }
148 }
149+
117 }
150 }
118 }
151 }
119
152
@@ -123,10 +156,10 @@ Rectangle {
123 when: windowShown
156 when: windowShown
124
157
125 // just to make them shorter
158 // just to make them shorter
126− property int appStarting: ApplicationInfo.Starting
159+ property int appStarting: ApplicationInfoInterface.Starting
127− property int appRunning: ApplicationInfo.Running
160+ property int appRunning: ApplicationInfoInterface.Running
128− property int appSuspended: ApplicationInfo.Suspended
161+ property int appSuspended: ApplicationInfoInterface.Suspended
129− property int appStopped: ApplicationInfo.Stopped
162+ property int appStopped: ApplicationInfoInterface.Stopped
130
163
131 function setApplicationState(appState) {
164 function setApplicationState(appState) {
132 switch (appState) {
165 switch (appState) {
@@ -170,6 +203,14 @@ Rectangle {
170 findInterestingApplicationWindowChildren();
203 findInterestingApplicationWindowChildren();
171 }
204 }
172
205
206+ function initSession() {
207+ sessionCheckbox.checked = true;
208+ sessionControl.surfaceCheckbox.checked = true;
209+ }
210+ function cleanupSession() {
211+ sessionCheckbox.checked = false;
212+ }
213+
173 function cleanup() {
214 function cleanup() {
174 forgetApplicationWindowChildren();
215 forgetApplicationWindowChildren();
175
216
@@ -177,10 +218,10 @@ Rectangle {
177 applicationWindowLoader.active = false;
218 applicationWindowLoader.active = false;
178
219
179 appStateSelector.selectedIndex = 0;
220 appStateSelector.selectedIndex = 0;
180− surfaceCheckbox.checked = false;
221+ cleanupSession();
181
222
182− if (fakeApplication.surface)
223+ if (fakeApplication.session)
183− fakeApplication.surface.release();
224+ fakeApplication.session.release();
184
225
185 applicationWindowLoader.active = true;
226 applicationWindowLoader.active = true;
186 }
227 }
@@ -197,7 +238,7 @@ Rectangle {
197 verify(stateGroup.state === "splashScreen");
238 verify(stateGroup.state === "splashScreen");
198
239
199 if (data.swapInitOrder) {
240 if (data.swapInitOrder) {
200− surfaceCheckbox.checked = true;
241+ initSession();
201 } else {
242 } else {
202 setApplicationState(appRunning);
243 setApplicationState(appRunning);
203 }
244 }
@@ -207,14 +248,14 @@ Rectangle {
207 if (data.swapInitOrder) {
248 if (data.swapInitOrder) {
208 setApplicationState(appRunning);
249 setApplicationState(appRunning);
209 } else {
250 } else {
210− surfaceCheckbox.checked = true;
251+ initSession();
211 }
252 }
212
253
213 tryCompare(stateGroup, "state", "surface");
254 tryCompare(stateGroup, "state", "surface");
214 }
255 }
215
256
216 function test_suspendedAppShowsSurface() {
257 function test_suspendedAppShowsSurface() {
217− surfaceCheckbox.checked = true;
258+ initSession();
218 setApplicationState(appRunning);
259 setApplicationState(appRunning);
219
260
220 tryCompare(stateGroup, "state", "surface");
261 tryCompare(stateGroup, "state", "surface");
@@ -228,7 +269,7 @@ Rectangle {
228 }
269 }
229
270
230 function test_killedAppShowsScreenshot() {
271 function test_killedAppShowsScreenshot() {
231− surfaceCheckbox.checked = true;
272+ initSession();
232 setApplicationState(appRunning);
273 setApplicationState(appRunning);
233 tryCompare(stateGroup, "state", "surface");
274 tryCompare(stateGroup, "state", "surface");
234
275
@@ -241,13 +282,13 @@ Rectangle {
241 setApplicationState(appStopped);
282 setApplicationState(appStopped);
242
283
243 tryCompare(stateGroup, "state", "screenshot");
284 tryCompare(stateGroup, "state", "screenshot");
244− tryCompare(fakeApplication, "surface", null);
285+ tryCompare(fakeApplication, "session", null);
245 }
286 }
246
287
247 function test_restartApp() {
288 function test_restartApp() {
248 var screenshotImage = findChild(applicationWindowLoader.item, "screenshotImage");
289 var screenshotImage = findChild(applicationWindowLoader.item, "screenshotImage");
249
290
250− surfaceCheckbox.checked = true;
291+ initSession();
251 setApplicationState(appRunning);
292 setApplicationState(appRunning);
252 tryCompare(stateGroup, "state", "surface");
293 tryCompare(stateGroup, "state", "surface");
253 waitUntilTransitionsEnd();
294 waitUntilTransitionsEnd();
@@ -259,28 +300,28 @@ Rectangle {
259
300
260 tryCompare(stateGroup, "state", "screenshot");
301 tryCompare(stateGroup, "state", "screenshot");
261 waitUntilTransitionsEnd();
302 waitUntilTransitionsEnd();
262− tryCompare(fakeApplication, "surface", null);
303+ tryCompare(fakeApplication, "session", null);
263
304
264 // and restart it
305 // and restart it
265 setApplicationState(appStarting);
306 setApplicationState(appStarting);
266
307
267 waitUntilTransitionsEnd();
308 waitUntilTransitionsEnd();
268 verify(stateGroup.state === "screenshot");
309 verify(stateGroup.state === "screenshot");
269− verify(fakeApplication.surface === null);
310+ verify(fakeSession === null);
270
311
271 setApplicationState(appRunning);
312 setApplicationState(appRunning);
272
313
273 waitUntilTransitionsEnd();
314 waitUntilTransitionsEnd();
274 verify(stateGroup.state === "screenshot");
315 verify(stateGroup.state === "screenshot");
275
316
276− surfaceCheckbox.checked = true;
317+ initSession();
277
318
278 tryCompare(stateGroup, "state", "surface");
319 tryCompare(stateGroup, "state", "surface");
279 tryCompare(screenshotImage, "status", Image.Null);
320 tryCompare(screenshotImage, "status", Image.Null);
280 }
321 }
281
322
282 function test_appCrashed() {
323 function test_appCrashed() {
283− surfaceCheckbox.checked = true;
324+ initSession();
284 setApplicationState(appRunning);
325 setApplicationState(appRunning);
285 tryCompare(stateGroup, "state", "surface");
326 tryCompare(stateGroup, "state", "surface");
286 waitUntilTransitionsEnd();
327 waitUntilTransitionsEnd();
@@ -289,39 +330,39 @@ Rectangle {
289 setApplicationState(appStopped);
330 setApplicationState(appStopped);
290
331
291 tryCompare(stateGroup, "state", "screenshot");
332 tryCompare(stateGroup, "state", "screenshot");
292− tryCompare(fakeApplication, "surface", null);
333+ tryCompare(fakeApplication, "session", null);
293 }
334 }
294
335
295 function test_keepSurfaceWhileInvisible() {
336 function test_keepSurfaceWhileInvisible() {
296− surfaceCheckbox.checked = true;
337+ initSession();
297 setApplicationState(appRunning);
338 setApplicationState(appRunning);
298 tryCompare(stateGroup, "state", "surface");
339 tryCompare(stateGroup, "state", "surface");
299 waitUntilTransitionsEnd();
340 waitUntilTransitionsEnd();
300− verify(fakeApplication.surface !== null);
341+ verify(fakeSession.surface !== null);
301
342
302 applicationWindowLoader.item.visible = false;
343 applicationWindowLoader.item.visible = false;
303
344
304 waitUntilTransitionsEnd();
345 waitUntilTransitionsEnd();
305 verify(stateGroup.state === "surface");
346 verify(stateGroup.state === "surface");
306− verify(fakeApplication.surface !== null);
347+ verify(fakeSession.surface !== null);
307
348
308 applicationWindowLoader.item.visible = true;
349 applicationWindowLoader.item.visible = true;
309
350
310 waitUntilTransitionsEnd();
351 waitUntilTransitionsEnd();
311 verify(stateGroup.state === "surface");
352 verify(stateGroup.state === "surface");
312− verify(fakeApplication.surface !== null);
353+ verify(fakeSession.surface !== null);
313 }
354 }
314
355
315 function test_touchesReachSurfaceWhenItsShown() {
356 function test_touchesReachSurfaceWhenItsShown() {
316 setApplicationState(appRunning);
357 setApplicationState(appRunning);
317− surfaceCheckbox.checked = true;
358+ initSession();
318
359
319 tryCompare(stateGroup, "state", "surface");
360 tryCompare(stateGroup, "state", "surface");
320
361
321 waitUntilTransitionsEnd();
362 waitUntilTransitionsEnd();
322
363
323 // Because doing stuff in C++ is a PITA we keep the counter in the interal qml impl.
364 // Because doing stuff in C++ is a PITA we keep the counter in the interal qml impl.
324− var fakeSurface = findChild(fakeApplication.surface, "fakeSurfaceQML");
365+ var fakeSurface = findChild(fakeSession.surface, "fakeSurfaceQML");
325 fakeSurface.touchPressCount = 0;
366 fakeSurface.touchPressCount = 0;
326 fakeSurface.touchReleaseCount = 0;
367 fakeSurface.touchReleaseCount = 0;
327
368
@@ -333,14 +374,25 @@ Rectangle {
333 }
374 }
334
375
335 function test_showNothingOnSuddenSurfaceLoss() {
376 function test_showNothingOnSuddenSurfaceLoss() {
336− surfaceCheckbox.checked = true;
377+ initSession();
337 setApplicationState(appRunning);
378 setApplicationState(appRunning);
338 tryCompare(stateGroup, "state", "surface");
379 tryCompare(stateGroup, "state", "surface");
339 waitUntilTransitionsEnd();
380 waitUntilTransitionsEnd();
340
381
341− surfaceCheckbox.checked = false;
382+ cleanupSession();
342
383
343 verify(stateGroup.state === "void");
384 verify(stateGroup.state === "void");
344 }
385 }
386+
387+ // should be forcing active focus when interactive changes,
388+ // which will cause a FocusScope higher in the object hierarchy tp be given the focus
389+ function test_forceActiveFocusFollowsInterative() {
390+ fakeApplication.createSession();
391+ applicationWindowLoader.item.interactive = false;
392+ applicationWindowLoader.item.interactive = true;
393+ fakeSession.createSurface();
394+
395+ compare(appFocus.focus, true);
396+ }
345 }
397 }
346}
398}
tests/qmltests/Stages/tst_PhoneStage.qml+1−1
@@ -64,7 +64,7 @@ Item {
64 anchors { left: parent.left; right: parent.right }
64 anchors { left: parent.left; right: parent.right }
65 text: "Stop Selected"
65 text: "Stop Selected"
66 onClicked: {
66 onClicked: {
67− ApplicationManager.get(appList.selectedAppIndex).setState(ApplicationInfo.Stopped);
67+ ApplicationManager.get(appList.selectedAppIndex).setState(ApplicationInfoInterface.Stopped);
68 }
68 }
69 }
69 }
70 }
70 }
tests/qmltests/Stages/tst_SessionContainer.qmlnew file+267
@@ -0,0 +1,267 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.1
18+import QtQuick.Layouts 1.1
19+import QtTest 1.0
20+import Unity.Test 0.1 as UT
21+import Ubuntu.Components 0.1
22+import Unity.Application 0.1
23+import "../../../qml/Stages"
24+
25+Rectangle {
26+ color: "red"
27+ id: root
28+ width: units.gu(80)
29+ height: units.gu(70)
30+
31+ Connections {
32+ target: sessionContainerLoader.status === Loader.Ready ? sessionContainerLoader.item : null
33+ onSessionChanged: {
34+ sessionCheckbox.checked = sessionContainerLoader.item.session !== null
35+ }
36+ }
37+
38+ Component {
39+ id: sessionContainerComponent
40+
41+ SessionContainer {
42+ id: sessionContainer
43+ anchors.fill: parent
44+ }
45+ }
46+
47+ Loader {
48+ id: sessionContainerLoader
49+ anchors {
50+ top: parent.top
51+ bottom: parent.bottom
52+ left: parent.left
53+ }
54+ width: units.gu(40)
55+ sourceComponent: sessionContainerComponent
56+ }
57+
58+ Rectangle {
59+ color: "white"
60+ anchors {
61+ top: parent.top
62+ bottom: parent.bottom
63+ left: sessionContainerLoader.right
64+ right: parent.right
65+ }
66+
67+ ColumnLayout {
68+ anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
69+ spacing: units.gu(1)
70+
71+ RowLayout {
72+ Layout.fillWidth: true
73+
74+ CheckBox {
75+ id: sessionCheckbox;
76+ checked: false;
77+ onCheckedChanged: {
78+ if (sessionContainerLoader.status !== Loader.Ready)
79+ return;
80+
81+ if (checked) {
82+ var fakeSession = SessionManager.createSession("music-player", Qt.resolvedUrl("../Dash/artwork/music-player-design.png"));
83+ sessionContainerLoader.item.session = fakeSession;
84+ fakeSession.createSurface();
85+ } else {
86+ sessionContainerLoader.item.session.release();
87+ }
88+ }
89+ }
90+
91+ Label {
92+ text: "session"
93+ anchors.verticalCenter: parent.verticalCenter
94+ }
95+ }
96+
97+ Rectangle {
98+ border {
99+ color: "black"
100+ width: 1
101+ }
102+ anchors {
103+ left: parent.left
104+ right: parent.right
105+ }
106+ Layout.preferredHeight: sessionChildrenControl.height
107+
108+ RecursingChildSessionControl {
109+ id: sessionChildrenControl
110+ anchors { left: parent.left; right: parent.right; }
111+
112+ session: sessionContainerLoader.item ? sessionContainerLoader.item.session : null
113+ }
114+ }
115+ }
116+ }
117+
118+ SignalSpy {
119+ id: sessionSpy
120+ target: SessionManager
121+ signalName: "sessionStopping"
122+ }
123+
124+ UT.UnityTestCase {
125+ id: testCase
126+ name: "SessionContainer"
127+
128+ function init() {
129+ // reload our test subject to get it in a fresh state once again
130+ sessionContainerLoader.active = false;
131+ sessionCheckbox.checked = false;
132+ sessionContainerLoader.active = true;
133+
134+ tryCompare(sessionContainerLoader.item, "session", null);
135+ sessionSpy.clear();
136+ }
137+
138+ when: windowShown
139+
140+ function test_addChildSession_data() {
141+ return [ { tag: "count=1", count: 1 },
142+ { tag: "count=4", count: 4 } ];
143+ }
144+
145+ function test_addChildSession(data) {
146+ sessionCheckbox.checked = true;
147+ var sessionContainer = sessionContainerLoader.item;
148+ compare(sessionContainer.childSessions.count(), 0);
149+
150+ var i;
151+ var sessions = [];
152+ for (i = 0; i < data.count; i++) {
153+ var session = ApplicationTest.addChildSession(sessionContainer.session,
154+ "gallery");
155+ session.createSurface();
156+ sessionContainer.session.addChildSession(session);
157+ compare(sessionContainer.childSessions.count(), i+1);
158+
159+ sessions.push(session);
160+ }
161+
162+ for (i = data.count-1; i >= 0; i--) {
163+ ApplicationTest.removeSession(sessions[i]);
164+ tryCompareFunction(function() { return sessionContainer.childSessions.count(); }, i);
165+ }
166+ tryCompare(sessionSpy, "count", data.count);
167+ }
168+
169+ function test_nestedChildSessions_data() {
170+ return [ { tag: "depth=2", depth: 2 },
171+ { tag: "depth=8", depth: 8 }
172+ ];
173+ }
174+
175+ function test_nestedChildSessions(data) {
176+ sessionCheckbox.checked = true;
177+ var sessionContainer = sessionContainerLoader.item;
178+ compare(sessionContainer.childSessions.count(), 0);
179+
180+ var i;
181+ var sessions = [];
182+ var lastSession = sessionContainer.session;
183+ var delegate;
184+ var container = sessionContainer;
185+ for (i = 0; i < data.depth; i++) {
186+ var session = ApplicationTest.addChildSession(lastSession,
187+ "gallery");
188+ session.createSurface();
189+ lastSession.addChildSession(session);
190+ compare(container.childSessions.count(), 1);
191+ sessions.push(session);
192+
193+ delegate = findChild(container, "childDelegate0");
194+ container = findChild(delegate, "sessionContainer");
195+ lastSession = session;
196+ }
197+
198+ for (i = data.depth-1; i >= 0; i--) {
199+ ApplicationTest.removeSession(sessions[i]);
200+ }
201+
202+ tryCompareFunction(function() { return sessionContainer.childSessions.count(); }, 0);
203+ tryCompare(sessionSpy, "count", data.depth);
204+ }
205+
206+ function test_childrenAdjustForParentSize() {
207+ sessionCheckbox.checked = true;
208+ var sessionContainer = sessionContainerLoader.item;
209+
210+ var session = ApplicationTest.addChildSession(sessionContainer.session,
211+ "gallery");
212+ session.createSurface();
213+ sessionContainer.session.addChildSession(session);
214+
215+ var delegate = findChild(sessionContainer, "childDelegate0");
216+ var childContainer = findChild(delegate, "sessionContainer");
217+
218+ tryCompareFunction(function() { return childContainer.height === sessionContainer.height; }, true);
219+ tryCompareFunction(function() { return childContainer.width === sessionContainer.width; }, true);
220+ tryCompareFunction(function() { return childContainer.x === 0; }, true);
221+ tryCompareFunction(function() { return childContainer.y === 0; }, true);
222+
223+ sessionContainer.anchors.margins = units.gu(2);
224+
225+ tryCompareFunction(function() { return childContainer.height === sessionContainer.height; }, true);
226+ tryCompareFunction(function() { return childContainer.width === sessionContainer.width; }, true);
227+ tryCompareFunction(function() { return childContainer.x === 0; }, true);
228+ tryCompareFunction(function() { return childContainer.y === 0; }, true);
229+ }
230+
231+ function isContainerAnimating(container) {
232+ var animation = findInvisibleChild(container, "sessionAnimation");
233+ if (!animation) return false;
234+
235+ var animating = false;
236+ for (var i = 0; i < animation.transitions.length; ++i) {
237+ if (animation.transitions[i].running) {
238+ return true;
239+ }
240+ }
241+ return false;
242+ }
243+
244+ function test_childrenAnimate() {
245+ sessionCheckbox.checked = true;
246+ var sessionContainer = sessionContainerLoader.item;
247+
248+ var session = ApplicationTest.addChildSession(sessionContainer.session,
249+ "gallery");
250+
251+ var delegate = findChild(sessionContainer, "childDelegate0");
252+ var childContainer = findChild(delegate, "sessionContainer");
253+
254+ // wait for animation to begin
255+ tryCompareFunction(function() { return isContainerAnimating(childContainer); }, true);
256+ // wait for animation to end
257+ tryCompareFunction(function() { return isContainerAnimating(childContainer); }, false);
258+
259+ ApplicationTest.removeSession(session);
260+
261+ // wait for animation to begin
262+ tryCompareFunction(function() { return isContainerAnimating(childContainer); }, true);
263+ // wait for animation to end
264+ tryCompareFunction(function() { return isContainerAnimating(childContainer); }, false);
265+ }
266+ }
267+}
tests/qmltests/Stages/tst_SurfaceContainer.qml+28−43
@@ -28,43 +28,6 @@ Rectangle {
28 width: units.gu(70)
28 width: units.gu(70)
29 height: units.gu(70)
29 height: units.gu(70)
30
30
31− Component {
32− id: fakeSurfaceComponent
33− Rectangle {
34− color: "green"
35−
36− Rectangle {
37− color: "blue"
38− anchors.fill: parent
39− anchors.margins: units.gu(2)
40− Text {
41− anchors.fill: parent
42− text: "Surface"
43− color: "green"
44− font.bold: true
45− fontSizeMode: Text.Fit
46− minimumPixelSize: 10; font.pixelSize: 200
47− verticalAlignment: Text.AlignVCenter
48− }
49− }
50−
51− width: units.gu(1)
52− height: units.gu(1)
53−
54− property int type: MirSurfaceItem.Normal
55− property int state: MirSurfaceItem.Restored
56− property string name: "Fake Surface"
57− property Item parentSurface: null
58− property list<Item> childSurfaces
59− function release() {}
60− signal removed();
61− }
62− }
63−
64− Item {
65− id: tempSurfaceHolder
66− }
67−
68 Component {
31 Component {
69 id: surfaceContainerComponent
32 id: surfaceContainerComponent
70 SurfaceContainer {
33 SurfaceContainer {
@@ -98,19 +61,20 @@ Rectangle {
98 Row {
61 Row {
99 anchors { left: parent.left; right: parent.right }
62 anchors { left: parent.left; right: parent.right }
100 CheckBox {
63 CheckBox {
101− id: surfaceCheckbox; checked: false;
64+ id: surfaceCheckbox;
65+ checked: false;
102 onCheckedChanged: {
66 onCheckedChanged: {
103 if (surfaceContainerLoader.status !== Loader.Ready)
67 if (surfaceContainerLoader.status !== Loader.Ready)
104 return;
68 return;
105
69
106 if (checked) {
70 if (checked) {
107− var fakeSurface = fakeSurfaceComponent.createObject(tempSurfaceHolder);
71+ var fakeSurface = SurfaceManager.createSurface("fake-surface",
72+ MirSurfaceItem.Normal,
73+ MirSurfaceItem.Restored,
74+ Qt.resolvedUrl("../Dash/artwork/music-player-design.png"));
108 surfaceContainerLoader.item.surface = fakeSurface;
75 surfaceContainerLoader.item.surface = fakeSurface;
109 } else {
76 } else {
110− var fakeSurface = surfaceContainerLoader.item.surface;
77+ ApplicationTest.removeSurface(surfaceContainerLoader.item.surface);
111− surfaceContainerLoader.item.surface = null;
112− fakeSurface.parent = null;
113− fakeSurface.destroy();
114 }
78 }
115 }
79 }
116 }
80 }
@@ -124,6 +88,12 @@ Rectangle {
124 }
88 }
125 }
89 }
126
90
91+ SignalSpy {
92+ id: surfaceSpy
93+ target: SurfaceManager
94+ signalName: "surfaceDestroyed"
95+ }
96+
127 UT.UnityTestCase {
97 UT.UnityTestCase {
128 id: testCase
98 id: testCase
129 name: "SurfaceContainer"
99 name: "SurfaceContainer"
@@ -134,6 +104,9 @@ Rectangle {
134 surfaceContainerLoader.active = false;
104 surfaceContainerLoader.active = false;
135 surfaceCheckbox.checked = false;
105 surfaceCheckbox.checked = false;
136 surfaceContainerLoader.active = true;
106 surfaceContainerLoader.active = true;
107+
108+ tryCompare(surfaceContainerLoader.item, "surface", null);
109+ surfaceSpy.clear();
137 }
110 }
138
111
139 /*
112 /*
@@ -150,5 +123,17 @@ Rectangle {
150 compare(fakeSurface.width, surfaceContainerLoader.item.width);
123 compare(fakeSurface.width, surfaceContainerLoader.item.width);
151 compare(fakeSurface.height, surfaceContainerLoader.item.height);
124 compare(fakeSurface.height, surfaceContainerLoader.item.height);
152 }
125 }
126+
127+ function test_animateRemoval() {
128+ surfaceCheckbox.checked = true;
129+ var surfaceContainer = surfaceContainerLoader.item;
130+
131+ verify(surfaceContainer.surface !== null);
132+
133+ ApplicationTest.removeSurface(surfaceContainer.surface);
134+
135+ compare(surfaceContainer.state, "zombie");
136+ tryCompare(surfaceContainer, "surface", null);
137+ }
153 }
138 }
154}
139}
tests/qmltests/tst_Shell.qml+23−16
@@ -21,6 +21,7 @@ import QtQuick 2.0
21import QtTest 1.0
21import QtTest 1.0
22import GSettings 1.0
22import GSettings 1.0
23import LightDM 0.1 as LightDM
23import LightDM 0.1 as LightDM
24+import Ubuntu.Telephony 0.1 as Telephony
24import Unity.Application 0.1
25import Unity.Application 0.1
25import Unity.Connectivity 0.1
26import Unity.Connectivity 0.1
26import Unity.Test 0.1 as UT
27import Unity.Test 0.1 as UT
@@ -74,6 +75,11 @@ Item {
74 signalName: "unlockingAllModems"
75 signalName: "unlockingAllModems"
75 }
76 }
76
77
78+ Telephony.CallEntry {
79+ id: phoneCall
80+ phoneNumber: "+447812221111"
81+ }
82+
77 UT.UnityTestCase {
83 UT.UnityTestCase {
78 name: "Shell"
84 name: "Shell"
79 when: windowShown
85 when: windowShown
@@ -144,29 +150,30 @@ Item {
144 verify(mainAppId != "");
150 verify(mainAppId != "");
145 var mainApp = ApplicationManager.findApplication(mainAppId);
151 var mainApp = ApplicationManager.findApplication(mainAppId);
146 verify(mainApp);
152 verify(mainApp);
147− tryCompare(mainApp, "state", ApplicationInfo.Running);
153+ tryCompare(mainApp, "state", ApplicationInfoInterface.Running);
148
154
149− // Try to suspend while proximity is engaged...
155+ // Suspend while call is active...
156+ callManager.foregroundCall = phoneCall;
150− Powerd.displayPowerStateChange(Powerd.Off, Powerd.Proximity);
157+ Powerd.status = Powerd.Off;
151 tryCompare(greeter, "showProgress", 0);
158 tryCompare(greeter, "showProgress", 0);
152
159
153− // Now really suspend
160+ // Now try again after ending call
154− print("suspending")
161+ callManager.foregroundCall = null;
162+ Powerd.status = Powerd.On;
155− Powerd.displayPowerStateChange(Powerd.Off, 0);
163+ Powerd.status = Powerd.Off;
156− print("done suspending")
157 tryCompare(greeter, "showProgress", 1);
164 tryCompare(greeter, "showProgress", 1);
158
165
159 tryCompare(ApplicationManager, "suspended", true);
166 tryCompare(ApplicationManager, "suspended", true);
160− compare(mainApp.state, ApplicationInfo.Suspended);
167+ compare(mainApp.state, ApplicationInfoInterface.Suspended);
161
168
162 // And wake up
169 // And wake up
163− Powerd.displayPowerStateChange(Powerd.On, 0);
170+ Powerd.status = Powerd.On;
164 tryCompare(greeter, "showProgress", 1);
171 tryCompare(greeter, "showProgress", 1);
165
172
166 // Swipe away greeter to focus app
173 // Swipe away greeter to focus app
167 swipeAwayGreeter();
174 swipeAwayGreeter();
168 tryCompare(ApplicationManager, "suspended", false);
175 tryCompare(ApplicationManager, "suspended", false);
169− compare(mainApp.state, ApplicationInfo.Running);
176+ compare(mainApp.state, ApplicationInfoInterface.Running);
170 tryCompare(ApplicationManager, "focusedApplicationId", mainAppId);
177 tryCompare(ApplicationManager, "focusedApplicationId", mainAppId);
171 }
178 }
172
179
@@ -237,9 +244,9 @@ Item {
237 function test_surfaceLosesFocusWhilePanelIsOpen() {
244 function test_surfaceLosesFocusWhilePanelIsOpen() {
238 var app = ApplicationManager.startApplication("dialer-app");
245 var app = ApplicationManager.startApplication("dialer-app");
239 // wait until the app is fully loaded (ie, real surface replaces splash screen)
246 // wait until the app is fully loaded (ie, real surface replaces splash screen)
240− tryCompareFunction(function() { return app.surface != null }, true);
247+ tryCompareFunction(function() { return app.session !== null && app.session.surface !== null }, true);
241
248
242− tryCompare(app.surface, "focus", true);
249+ tryCompare(app.session.surface, "focus", true);
243
250
244 // Drag the indicators panel half-open
251 // Drag the indicators panel half-open
245 var touchX = shell.width / 2;
252 var touchX = shell.width / 2;
@@ -250,7 +257,7 @@ Item {
250 true /* beginTouch */, false /* endTouch */);
257 true /* beginTouch */, false /* endTouch */);
251 verify(indicators.partiallyOpened);
258 verify(indicators.partiallyOpened);
252
259
253− tryCompare(app.surface, "focus", false);
260+ tryCompare(app.session.surface, "focus", false);
254
261
255 // And finish getting it open
262 // And finish getting it open
256 touchFlick(indicators,
263 touchFlick(indicators,
@@ -259,11 +266,11 @@ Item {
259 false /* beginTouch */, true /* endTouch */);
266 false /* beginTouch */, true /* endTouch */);
260 tryCompare(indicators, "fullyOpened", true);
267 tryCompare(indicators, "fullyOpened", true);
261
268
262− tryCompare(app.surface, "focus", false);
269+ tryCompare(app.session.surface, "focus", false);
263
270
264 dragToCloseIndicatorsPanel();
271 dragToCloseIndicatorsPanel();
265
272
266− tryCompare(app.surface, "focus", true);
273+ tryCompare(app.session.surface, "focus", true);
267 }
274 }
268
275
269 // Wait for the whole UI to settle down
276 // Wait for the whole UI to settle down
@@ -361,7 +368,7 @@ Item {
361
368
362 var app = ApplicationManager.startApplication("dialer-app");
369 var app = ApplicationManager.startApplication("dialer-app");
363 // wait until the app is fully loaded (ie, real surface replaces splash screen)
370 // wait until the app is fully loaded (ie, real surface replaces splash screen)
364− tryCompareFunction(function() { return app.surface != null }, true);
371+ tryCompareFunction(function() { return app.session !== null && app.session.surface !== null }, true);
365
372
366 // Minimize the application we just launched
373 // Minimize the application we just launched
367 swipeFromLeftEdge(units.gu(26) + 1);
374 swipeFromLeftEdge(units.gu(26) + 1);
tools/unlock-device+4−5
@@ -19,13 +19,12 @@ done
19
19
20eval "$WAIT_COMMAND"
20eval "$WAIT_COMMAND"
21
21
22−# Force a sleep of twenty no matter what, since we may need to wait for unity8
22+# Force a sleep no matter what, since we may need to wait for unity8
23# to finish coming up (it's hard to tell when the greeter is actually rendered)
23# to finish coming up (it's hard to tell when the greeter is actually rendered)
24−sleep 20
24+sleep 30
25
25
26+# We need to go through sudo to get a proper environment for dbus set up
26−GDBUS_CMD="gdbus call --session --dest com.canonical.UnityGreeter --object-path / --method com.canonical.UnityGreeter.HideGreeter && echo Greeter unlocked"
27+UNLOCK_OUTPUT=$(adb shell "gdbus call --session --dest com.canonical.UnityGreeter --object-path / --method com.canonical.UnityGreeter.HideGreeter && echo Greeter unlocked" 2>&1)
27−
28−UNLOCK_OUTPUT=$(adb shell "if [ \"\$(id -u)\" = 0 ]; then sudo -u phablet -i $GDBUS_CMD; else $GDBUS_CMD; fi" 2>&1)
29if echo "$UNLOCK_OUTPUT" | grep 'Greeter unlocked' >/dev/null; then
28if echo "$UNLOCK_OUTPUT" | grep 'Greeter unlocked' >/dev/null; then
30 echo "I: Unlock passed"
29 echo "I: Unlock passed"
31 exit 0
30 exit 0