on xenial help sign in
Merge from trunk
f2f6907Michael Terry
Components/VolumeControl.qml+5−20
@@ -21,37 +21,22 @@ Item {
21 id: root
21 id: root
22 objectName: "volumeControl"
22 objectName: "volumeControl"
23 visible: false
23 visible: false
24− property int volume
25
24
26 QDBusActionGroup {
25 QDBusActionGroup {
27 id: actionGroup
26 id: actionGroup
28 busType: 1
27 busType: 1
29− busName: "com.canonical.settings.sound"
28+ busName: "com.canonical.indicator.sound"
30− objectPath: "/com/canonical/settings/sound"
29+ objectPath: "/com/canonical/indicator/sound"
31
30
32− property variant actionObject: action("volume")
31+ property variant actionObject: action("scroll")
33− property variant serverVolume: actionObject.valid ? actionObject.state: 0
34− }
35−
36− Binding {
37− target: root
38− property: "volume"
39− value: actionGroup.serverVolume * 100
40− }
41−
42− onVolumeChanged: {
43− if (actionGroup.serverVolume != volume) {
44− var targetVolume = Math.min(1, Math.max(0, volume / 100));
45− actionGroup.actionObject.updateState(targetVolume);
46− }
47 }
32 }
48
33
49 function volumeUp() {
34 function volumeUp() {
50− actionGroup.actionObject.updateState(Math.min(1, volume/100 + 0.10));
35+ actionGroup.actionObject.activate(1);
51 }
36 }
52
37
53 function volumeDown() {
38 function volumeDown() {
54− actionGroup.actionObject.updateState(Math.max(0, volume/100 - 0.10));
39+ actionGroup.actionObject.activate(-1);
55 }
40 }
56
41
57 Component.onCompleted: actionGroup.start()
42 Component.onCompleted: actionGroup.start()
Dash/GenericScopeView.qml+4−1
@@ -21,10 +21,11 @@ import "../Components/ListItems" as ListItems
21
21
22ScopeView {
22ScopeView {
23 id: scopeView
23 id: scopeView
24− property alias previewShown: previewLoader.onScreen
24+ readonly property alias previewShown: previewLoader.onScreen
25
25
26 onIsCurrentChanged: {
26 onIsCurrentChanged: {
27 pageHeader.resetSearch();
27 pageHeader.resetSearch();
28+ previewLoader.open = false;
28 }
29 }
29
30
30 onMovementStarted: categoryView.showHeader()
31 onMovementStarted: categoryView.showHeader()
@@ -179,6 +180,7 @@ ScopeView {
179 case "grid": {
180 case "grid": {
180 switch (contentType) {
181 switch (contentType) {
181 case "video": return "Generic/GenericFilterGridPotrait.qml";
182 case "video": return "Generic/GenericFilterGridPotrait.qml";
183+ case "music": return "Music/MusicFilterGrid.qml";
182 default: return "Generic/GenericFilterGrid.qml";
184 default: return "Generic/GenericFilterGrid.qml";
183 }
185 }
184 }
186 }
@@ -246,6 +248,7 @@ ScopeView {
246 }
248 }
247
249
248 Loader {
250 Loader {
251+ objectName: "previewLoader"
249 id: previewLoader
252 id: previewLoader
250 property var previewData
253 property var previewData
251 height: effect.bottomGapPx - effect.topGapPx
254 height: effect.bottomGapPx - effect.topGapPx
MouseTouchAdaptor.cpp+29−12
@@ -39,24 +39,16 @@ Qt::MouseButton translateMouseButton(xcb_button_t detail)
39} // end of anonymous namespace
39} // end of anonymous namespace
40
40
41MouseTouchAdaptor::MouseTouchAdaptor()
41MouseTouchAdaptor::MouseTouchAdaptor()
42− : m_targetWindow(0)
43− , m_leftButtonIsPressed(false)
42+ : m_leftButtonIsPressed(false)
44{
43{
45 m_touchDevice = new QTouchDevice;
44 m_touchDevice = new QTouchDevice;
46 m_touchDevice->setType(QTouchDevice::TouchScreen);
45 m_touchDevice->setType(QTouchDevice::TouchScreen);
47 QWindowSystemInterface::registerTouchDevice(m_touchDevice);
46 QWindowSystemInterface::registerTouchDevice(m_touchDevice);
48}
47}
49
48
50−void MouseTouchAdaptor::setTargetWindow(QWindow *window)
51−{
52− m_targetWindow = window;
53−}
54−
55bool MouseTouchAdaptor::nativeEventFilter(const QByteArray & eventType,
49bool MouseTouchAdaptor::nativeEventFilter(const QByteArray & eventType,
56 void * message, long * /*result*/)
50 void * message, long * /*result*/)
57{
51{
58− Q_ASSERT(m_targetWindow);
59−
60 if (eventType != "xcb_generic_event_t") {
52 if (eventType != "xcb_generic_event_t") {
61 // wrong backend.
53 // wrong backend.
62 qWarning("MouseTouchAdaptor: XCB backend not in use. Adaptor inoperative!");
54 qWarning("MouseTouchAdaptor: XCB backend not in use. Adaptor inoperative!");
@@ -91,7 +83,9 @@ bool MouseTouchAdaptor::handleButtonPress(xcb_button_press_event_t *pressEvent)
91
83
92 QPoint windowPos(pressEvent->event_x, pressEvent->event_y);
84 QPoint windowPos(pressEvent->event_x, pressEvent->event_y);
93
85
86+ QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(pressEvent->event));
87+
94− QTouchEventSequence touchEvent = QTest::touchEvent(m_targetWindow, m_touchDevice,
88+ QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
95 false /* autoCommit */);
89 false /* autoCommit */);
96 touchEvent.press(0 /* touchId */, windowPos);
90 touchEvent.press(0 /* touchId */, windowPos);
97 touchEvent.commit(false /* processEvents */);
91 touchEvent.commit(false /* processEvents */);
@@ -110,7 +104,9 @@ bool MouseTouchAdaptor::handleButtonRelease(xcb_button_release_event_t *releaseE
110
104
111 QPoint windowPos(releaseEvent->event_x, releaseEvent->event_y);
105 QPoint windowPos(releaseEvent->event_x, releaseEvent->event_y);
112
106
107+ QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(releaseEvent->event));
108+
113− QTouchEventSequence touchEvent = QTest::touchEvent(m_targetWindow, m_touchDevice,
109+ QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
114 false /* autoCommit */);
110 false /* autoCommit */);
115 touchEvent.release(0 /* touchId */, windowPos);
111 touchEvent.release(0 /* touchId */, windowPos);
116 touchEvent.commit(false /* processEvents */);
112 touchEvent.commit(false /* processEvents */);
@@ -127,10 +123,31 @@ bool MouseTouchAdaptor::handleMotionNotify(xcb_motion_notify_event_t *event)
127
123
128 QPoint windowPos(event->event_x, event->event_y);
124 QPoint windowPos(event->event_x, event->event_y);
129
125
126+ QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(event->event));
127+
130− QTouchEventSequence touchEvent = QTest::touchEvent(m_targetWindow, m_touchDevice,
128+ QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
131 false /* autoCommit */);
129 false /* autoCommit */);
132 touchEvent.move(0 /* touchId */, windowPos);
130 touchEvent.move(0 /* touchId */, windowPos);
133 touchEvent.commit(false /* processEvents */);
131 touchEvent.commit(false /* processEvents */);
134
132
135 return true;
133 return true;
136}
134}
135+
136+QWindow *MouseTouchAdaptor::findQWindowWithXWindowID(WId windowId)
137+{
138+ QWindowList windowList = QGuiApplication::topLevelWindows();
139+ QWindow *foundWindow = nullptr;
140+
141+ int i = 0;
142+ while (!foundWindow && i < windowList.count()) {
143+ QWindow *window = windowList[i];
144+ if (window->winId() == windowId) {
145+ foundWindow = window;
146+ } else {
147+ ++i;
148+ }
149+ }
150+
151+ Q_ASSERT(foundWindow);
152+ return foundWindow;
153+}
MouseTouchAdaptor.h+2−5
@@ -20,11 +20,11 @@
20#define MOUSE_TOUCH_ADAPTOR_H
20#define MOUSE_TOUCH_ADAPTOR_H
21
21
22#include <QtCore/QAbstractNativeEventFilter>
22#include <QtCore/QAbstractNativeEventFilter>
23+#include <QWindow>
23#include <xcb/xcb.h>
24#include <xcb/xcb.h>
24
25
25class QMouseEvent;
26class QMouseEvent;
26class QTouchDevice;
27class QTouchDevice;
27−class QWindow;
28
28
29// Transforms QMouseEvents into single-finger QTouchEvents.
29// Transforms QMouseEvents into single-finger QTouchEvents.
30class MouseTouchAdaptor : public QAbstractNativeEventFilter {
30class MouseTouchAdaptor : public QAbstractNativeEventFilter {
@@ -32,9 +32,6 @@ class MouseTouchAdaptor : public QAbstractNativeEventFilter {
32public:
32public:
33 MouseTouchAdaptor();
33 MouseTouchAdaptor();
34
34
35− // The window that will receive the generated QTouchEvents
36− void setTargetWindow(QWindow *window);
37−
38 // Filters mouse events and posts the equivalent QTouchEvents.
35 // Filters mouse events and posts the equivalent QTouchEvents.
39 virtual bool nativeEventFilter(const QByteArray & eventType, void *message, long *result);
36 virtual bool nativeEventFilter(const QByteArray & eventType, void *message, long *result);
40
37
@@ -43,8 +40,8 @@ private:
43 bool handleButtonPress(xcb_button_press_event_t *pressEvent);
40 bool handleButtonPress(xcb_button_press_event_t *pressEvent);
44 bool handleButtonRelease(xcb_button_release_event_t *releaseEvent);
41 bool handleButtonRelease(xcb_button_release_event_t *releaseEvent);
45 bool handleMotionNotify(xcb_motion_notify_event_t *event);
42 bool handleMotionNotify(xcb_motion_notify_event_t *event);
43+ QWindow *findQWindowWithXWindowID(WId windowId);
46
44
47− QWindow *m_targetWindow;
48 QTouchDevice *m_touchDevice;
45 QTouchDevice *m_touchDevice;
49 bool m_leftButtonIsPressed;
46 bool m_leftButtonIsPressed;
50};
47};
Shell.qml+20−10
@@ -23,6 +23,7 @@ import Ubuntu.Gestures 0.1
23import Unity.Launcher 0.1
23import Unity.Launcher 0.1
24import LightDM 0.1 as LightDM
24import LightDM 0.1 as LightDM
25import Powerd 0.1
25import Powerd 0.1
26+import SessionBroadcast 0.1
26import "Dash"
27import "Dash"
27import "Greeter"
28import "Greeter"
28import "Launcher"
29import "Launcher"
@@ -83,6 +84,8 @@ FocusScope {
83
84
84 readonly property bool applicationFocused: !!applicationManager.mainStageFocusedApplication
85 readonly property bool applicationFocused: !!applicationManager.mainStageFocusedApplication
85 || !!applicationManager.sideStageFocusedApplication
86 || !!applicationManager.sideStageFocusedApplication
87+ // Used for autopilot testing.
88+ readonly property string currentFocusedAppId: ApplicationManager.focusedApplicationId
86
89
87 readonly property bool fullscreenMode: {
90 readonly property bool fullscreenMode: {
88 if (greeter.shown || lockscreen.shown) {
91 if (greeter.shown || lockscreen.shown) {
@@ -545,6 +548,17 @@ FocusScope {
545 }
548 }
546 }
549 }
547
550
551+ function showHome() {
552+ greeter.hide()
553+ // Animate if moving between application and dash
554+ if (!stages.shown) {
555+ dash.setCurrentScope("home.scope", true, false)
556+ } else {
557+ dash.setCurrentScope("home.scope", false, false)
558+ }
559+ stages.hide()
560+ }
561+
548 Item {
562 Item {
549 id: overlay
563 id: overlay
550
564
@@ -632,16 +646,7 @@ FocusScope {
632 width: parent.width
646 width: parent.width
633 dragAreaWidth: shell.edgeSize
647 dragAreaWidth: shell.edgeSize
634 available: (!greeter.shown || greeter.narrowMode) && edgeDemo.launcherEnabled
648 available: (!greeter.shown || greeter.narrowMode) && edgeDemo.launcherEnabled
635− onDashItemSelected: {
649+ onDashItemSelected: showHome()
636− greeter.hide()
637− // Animate if moving between application and dash
638− if (!stages.shown) {
639− dash.setCurrentScope("home.scope", true, false)
640− } else {
641− dash.setCurrentScope("home.scope", false, false)
642− }
643− stages.hide();
644− }
645 onDash: {
650 onDash: {
646 if (stages.shown) {
651 if (stages.shown) {
647 dash.setCurrentScope("applications.scope", true, false)
652 dash.setCurrentScope("applications.scope", true, false)
@@ -749,4 +754,9 @@ FocusScope {
749 indicators: panel.indicators
754 indicators: panel.indicators
750 underlay: underlay
755 underlay: underlay
751 }
756 }
757+
758+ Connections {
759+ target: SessionBroadcast
760+ onShowHome: showHome()
761+ }
752}
762}
debian/unity8-private.install+1
@@ -3,6 +3,7 @@ usr/lib/*/unity8/qml/HudClient
3usr/lib/*/unity8/qml/LightDM
3usr/lib/*/unity8/qml/LightDM
4usr/lib/*/unity8/qml/ListViewWithPageHeader
4usr/lib/*/unity8/qml/ListViewWithPageHeader
5usr/lib/*/unity8/qml/Powerd
5usr/lib/*/unity8/qml/Powerd
6+usr/lib/*/unity8/qml/SessionBroadcast
6usr/lib/*/unity8/qml/Ubuntu
7usr/lib/*/unity8/qml/Ubuntu
7usr/lib/*/unity8/qml/Unity
8usr/lib/*/unity8/qml/Unity
8usr/lib/*/unity8/qml/Utils
9usr/lib/*/unity8/qml/Utils
main.cpp−1
@@ -144,7 +144,6 @@ int startShell(int argc, const char** argv, void* server)
144 MouseTouchAdaptor *mouseTouchAdaptor = 0;
144 MouseTouchAdaptor *mouseTouchAdaptor = 0;
145 if (args.contains(QLatin1String("-mousetouch"))) {
145 if (args.contains(QLatin1String("-mousetouch"))) {
146 mouseTouchAdaptor = new MouseTouchAdaptor;
146 mouseTouchAdaptor = new MouseTouchAdaptor;
147− mouseTouchAdaptor->setTargetWindow(view);
148 application->installNativeEventFilter(mouseTouchAdaptor);
147 application->installNativeEventFilter(mouseTouchAdaptor);
149 }
148 }
150
149
plugins/CMakeLists.txt+1
@@ -3,6 +3,7 @@ add_subdirectory(HudClient)
3add_subdirectory(LightDM)
3add_subdirectory(LightDM)
4add_subdirectory(ListViewWithPageHeader)
4add_subdirectory(ListViewWithPageHeader)
5add_subdirectory(Powerd)
5add_subdirectory(Powerd)
6+add_subdirectory(SessionBroadcast)
6add_subdirectory(Ubuntu)
7add_subdirectory(Ubuntu)
7add_subdirectory(Unity)
8add_subdirectory(Unity)
8add_subdirectory(Utils)
9add_subdirectory(Utils)
plugins/SessionBroadcast/CMakeLists.txtnew file+13
@@ -0,0 +1,13 @@
1+include(Plugins)
2+
3+add_definitions(-DSM_BUSNAME=systemBus)
4+
5+add_library(SessionBroadcast-qml MODULE
6+ SessionBroadcast.cpp
7+ plugin.cpp
8+ )
9+
10+qt5_use_modules(SessionBroadcast-qml DBus Qml)
11+
12+export_qmlfiles(SessionBroadcast SessionBroadcast)
13+export_qmlplugin(SessionBroadcast 0.1 SessionBroadcast TARGETS SessionBroadcast-qml)
plugins/SessionBroadcast/SessionBroadcast.cppnew file+41
@@ -0,0 +1,41 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#include "SessionBroadcast.h"
20+#include <QDBusConnection>
21+
22+SessionBroadcast::SessionBroadcast(QObject* parent)
23+ : QObject(parent)
24+{
25+ auto connection = QDBusConnection::SM_BUSNAME();
26+
27+ connection.connect("com.canonical.Unity.Greeter.Broadcast",
28+ "/com/canonical/Unity/Greeter/Broadcast",
29+ "com.canonical.Unity.Greeter.Broadcast",
30+ "ShowHome",
31+ this,
32+ SLOT(onShowHome(const QString &)));
33+}
34+
35+void SessionBroadcast::onShowHome(const QString &username)
36+{
37+ // Only listen to requests meant for us
38+ if (username == qgetenv("USER")) {
39+ Q_EMIT showHome();
40+ }
41+}
plugins/SessionBroadcast/SessionBroadcast.hnew file+41
@@ -0,0 +1,41 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#ifndef UNITY_SESSIONBROADCAST_H
20+#define UNITY_SESSIONBROADCAST_H
21+
22+#include <QObject>
23+#include <QString>
24+
25+class QDBusInterface;
26+
27+class SessionBroadcast: public QObject
28+{
29+ Q_OBJECT
30+
31+public:
32+ explicit SessionBroadcast(QObject *parent = 0);
33+
34+Q_SIGNALS:
35+ void showHome();
36+
37+private Q_SLOTS:
38+ void onShowHome(const QString &username);
39+};
40+
41+#endif
plugins/SessionBroadcast/plugin.cppnew file+35
@@ -0,0 +1,35 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#include "plugin.h"
20+#include "SessionBroadcast.h"
21+
22+#include <QtQml>
23+
24+static QObject *broadcast_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
25+{
26+ Q_UNUSED(engine)
27+ Q_UNUSED(scriptEngine)
28+ return new SessionBroadcast();
29+}
30+
31+void SessionBroadcastPlugin::registerTypes(const char *uri)
32+{
33+ Q_ASSERT(uri == QLatin1String("SessionBroadcast"));
34+ qmlRegisterSingletonType<SessionBroadcast>(uri, 0, 1, "SessionBroadcast", broadcast_provider);
35+}
plugins/SessionBroadcast/plugin.hnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#ifndef UNITY_SESSIONBROADCAST_PLUGIN_H
20+#define UNITY_SESSIONBROADCAST_PLUGIN_H
21+
22+#include <QQmlExtensionPlugin>
23+
24+class SessionBroadcastPlugin : public QQmlExtensionPlugin
25+{
26+ Q_OBJECT
27+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
28+
29+public:
30+ void registerTypes(const char *uri);
31+};
32+
33+#endif
plugins/SessionBroadcast/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module SessionBroadcast
2+plugin SessionBroadcast-qml
3+typeinfo plugin.qmltypes
plugins/Unity/Launcher/launchermodel.cpp+12−3
@@ -115,9 +115,11 @@ void LauncherModel::move(int oldIndex, int newIndex)
115 m_list.move(oldIndex, newIndex);
115 m_list.move(oldIndex, newIndex);
116 endMoveRows();
116 endMoveRows();
117
117
118− storeAppList();
118+ if (!m_list.at(newIndex)->pinned()) {
119−
120− pin(m_list.at(newIndex)->appId());
119+ pin(m_list.at(newIndex)->appId());
120+ } else {
121+ storeAppList();
122+ }
121}
123}
122
124
123void LauncherModel::pin(const QString &appId, int index)
125void LauncherModel::pin(const QString &appId, int index)
@@ -146,6 +148,8 @@ void LauncherModel::pin(const QString &appId, int index)
146 m_list.insert(index, item);
148 m_list.insert(index, item);
147 endInsertRows();
149 endInsertRows();
148 }
150 }
151+
152+ storeAppList();
149}
153}
150
154
151void LauncherModel::requestRemove(const QString &appId)
155void LauncherModel::requestRemove(const QString &appId)
@@ -155,6 +159,11 @@ void LauncherModel::requestRemove(const QString &appId)
155 return;
159 return;
156 }
160 }
157
161
162+ if (m_appManager->findApplication(appId)) {
163+ m_list.at(index)->setPinned(false);
164+ return;
165+ }
166+
158 beginRemoveRows(QModelIndex(), index, index);
167 beginRemoveRows(QModelIndex(), index, index);
159 m_list.takeAt(index)->deleteLater();
168 m_list.takeAt(index)->deleteLater();
160 endRemoveRows();
169 endRemoveRows();
po/is.ponew file+256
@@ -0,0 +1,256 @@
1+# Icelandic translation for unity8
2+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
3+# This file is distributed under the same license as the unity8 package.
4+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
5+#
6+msgid ""
7+msgstr ""
8+"Project-Id-Version: unity8\n"
9+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11+"PO-Revision-Date: 2013-09-18 16:22+0000\n"
12+"Last-Translator: Andri Thorlacius <Unknown>\n"
13+"Language-Team: Icelandic <is@li.org>\n"
14+"MIME-Version: 1.0\n"
15+"Content-Type: text/plain; charset=UTF-8\n"
16+"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
18+"X-Launchpad-Export-Date: 2013-09-19 05:14+0000\n"
19+"X-Generator: Launchpad (build 16765)\n"
20+
21+#: Applications/applications.js:23
22+msgid "Phone"
23+msgstr "Sími"
24+
25+#: Applications/applications.js:29
26+msgid "Camera"
27+msgstr "Myndavél"
28+
29+#: Applications/applications.js:35
30+msgid "Gallery"
31+msgstr "Myndasafn"
32+
33+#: Applications/applications.js:40
34+msgid "Facebook"
35+msgstr "Facebook"
36+
37+#: Applications/applications.js:46
38+msgid "Browser"
39+msgstr "Vafri"
40+
41+#: Applications/applications.js:51
42+msgid "Twitter"
43+msgstr "Twitter"
44+
45+#: Applications/applications.js:57
46+msgid "GMail"
47+msgstr "GMail"
48+
49+#: Applications/applications.js:62
50+msgid "Weather"
51+msgstr "Veður"
52+
53+#: Applications/applications.js:68
54+msgid "Notepad"
55+msgstr "Skrifblokk"
56+
57+#: Applications/applications.js:74
58+msgid "Calendar"
59+msgstr "Dagatal"
60+
61+#: Applications/applications.js:80
62+msgid "Media Player"
63+msgstr "Margmiðlunarspilari"
64+
65+#: Applications/applications.js:86
66+msgid "Evernote"
67+msgstr "Evernote"
68+
69+#: Applications/applications.js:91
70+msgid "Map"
71+msgstr "Kort"
72+
73+#: Applications/applications.js:96
74+msgid "Pinterest"
75+msgstr "Pinterest"
76+
77+#: Applications/applications.js:101
78+msgid "SoundCloud"
79+msgstr "SoundCloud"
80+
81+#: Applications/applications.js:106
82+msgid "Wikipedia"
83+msgstr "Wikipedia"
84+
85+#: Applications/applications.js:111
86+msgid "YouTube"
87+msgstr "YouTube"
88+
89+#: Components/EdgeDemoOverlay.qml:145
90+msgid "Skip intro"
91+msgstr "Hoppa yfir kynningu"
92+
93+#: Components/EdgeDemo.qml:98
94+msgid "Right edge"
95+msgstr "Hægri brún"
96+
97+#: Components/EdgeDemo.qml:99
98+msgid "Try swiping from the right edge to unlock the phone"
99+msgstr ""
100+"Prufaðu að renna puttanum frá hægri brúninni til að aflæsa símanum þínum."
101+
102+#: Components/EdgeDemo.qml:135
103+msgid "Top edge"
104+msgstr "Efri brún"
105+
106+#: Components/EdgeDemo.qml:136
107+msgid "Try swiping from the top edge to access the indicators"
108+msgstr ""
109+
110+#: Components/EdgeDemo.qml:161
111+msgid "Close"
112+msgstr "Loka"
113+
114+#: Components/EdgeDemo.qml:162
115+msgid "Swipe up again to close the settings screen"
116+msgstr ""
117+
118+#: Components/EdgeDemo.qml:189
119+msgid "Left edge"
120+msgstr "Vinstri brún"
121+
122+#: Components/EdgeDemo.qml:190
123+msgid "Swipe from the left to reveal the launcher for quick access to apps"
124+msgstr ""
125+
126+#: Components/EdgeDemo.qml:217
127+msgid "Well done"
128+msgstr "Vel gert"
129+
130+#: Components/EdgeDemo.qml:218
131+msgid "You have now mastered the edge gestures and can start using the phone"
132+msgstr ""
133+
134+#: Components/PageHeader.qml:298
135+msgid "Recent searches"
136+msgstr "Nýlegar leitir"
137+
138+#. TRANSLATORS: Number of persons who rated this app
139+#: Dash/Apps/AppInfo.qml:73
140+#, qt-format
141+msgid "(%1)"
142+msgstr "(%1)"
143+
144+#. TRANSLATORS: Number of persons who wrote reviews for this app
145+#: Dash/Apps/AppInfo.qml:85
146+#, qt-format
147+msgid "%1 review"
148+msgid_plural "%1 reviews"
149+msgstr[0] "%1 ummæli"
150+msgstr[1] "%1 ummæli"
151+
152+#: Dash/Apps/AppPreview.qml:175
153+msgid "Rate this"
154+msgstr "Gefa þessu einkunn"
155+
156+#: Dash/Apps/AppReviews.qml:72
157+msgid "Add a review"
158+msgstr "Gefa umsögn"
159+
160+#: Dash/Apps/AppReviews.qml:84
161+msgid "Review"
162+msgstr "Umsögn"
163+
164+#: Dash/Apps/AppReviews.qml:118
165+msgid "Send"
166+msgstr "Senda"
167+
168+#: Dash/Apps/AppReviews.qml:136
169+msgid "Comments:"
170+msgstr "Athugasemdir:"
171+
172+#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
173+msgid "Featured"
174+msgstr "Efst á baugi"
175+
176+#: Dash/DashMusic.qml:28 Dash/DashVideos.qml:29
177+msgid "Recent"
178+msgstr "Nýlegt"
179+
180+#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
181+msgid "New Releases"
182+msgstr "Nýjar Útgáfur"
183+
184+#: Dash/DashMusic.qml:30
185+msgid "Top Charting"
186+msgstr "Topp Listi"
187+
188+#: Dash/DashMusic.qml:91
189+msgid "Music"
190+msgstr "Tónlist"
191+
192+#: Dash/DashVideos.qml:31
193+msgid "Popular Online"
194+msgstr "Vinsælt á Netinu"
195+
196+#: Dash/DashVideos.qml:146
197+msgid "Videos"
198+msgstr "Myndbönd"
199+
200+#: Dash/Video/VideoPreview.qml:130
201+msgid "Directed by:"
202+msgstr "Leikstýrt af:"
203+
204+#: Dash/Video/VideoPreview.qml:153
205+msgid "Starring:"
206+msgstr "Meðal leikara eru:"
207+
208+#: Dash/Video/VideoPreview.qml:176
209+msgid "Author:"
210+msgstr "Höfundur:"
211+
212+#: Greeter/Lockscreen.qml:134
213+msgid "Emergency Call"
214+msgstr "Neyðarsímtal"
215+
216+#: Greeter/PassphraseLockscreen.qml:59
217+#, qt-format
218+msgid "Hello %1"
219+msgstr "Hæ %1"
220+
221+#: Greeter/PassphraseLockscreen.qml:59
222+msgid "Hello"
223+msgstr "Hæ"
224+
225+#: Hud/HudParametrizedActionsPage.qml:132
226+msgid "Confirm"
227+msgstr "Staðfesta"
228+
229+#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
230+msgid "Type or say a command"
231+msgstr "Skrifaðu eða segðu eitthvað"
232+
233+#: Hud/Hud.qml:84
234+msgid "Loading. Please Wait..."
235+msgstr "Hleð. Vinsamlegast Bíðið..."
236+
237+#: Hud/Hud.qml:89
238+msgid "Speak Now..."
239+msgstr "Talaðu Núna..."
240+
241+#: Hud/Hud.qml:94
242+msgid "Speaking..."
243+msgstr "Tala..."
244+
245+#: Panel/SearchIndicator.qml:27
246+msgid "Search"
247+msgstr "Leita"
248+
249+#: plugins/Unity/scope.cpp:317
250+msgid "Sorry, there is nothing that matches your search."
251+msgstr "Því miður, það var ekkert sem passaði við leitarorðið þitt."
252+
253+#: Shell.qml:429
254+#, qt-format
255+msgid "Please enter %1"
256+msgstr ""
tests/autopilot/unity8/application_lifecycle/__init__.pynew file+20
@@ -0,0 +1,20 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+#
3+# Unity Autopilot Test Suite
4+# Copyright (C) 2013 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License as published by
8+# the Free Software Foundation, either version 3 of the License, or
9+# (at your option) any later version.
10+#
11+# This program is distributed in the hope that it will be useful,
12+# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+# GNU General Public License for more details.
15+#
16+# You should have received a copy of the GNU General Public License
17+# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+#
19+
20+"""Tests for the application lifecycle base package."""
tests/autopilot/unity8/application_lifecycle/tests/__init__.pynew file

No changes to the content.

tests/autopilot/unity8/application_lifecycle/tests/test_application_lifecycle.pynew file+136
@@ -0,0 +1,136 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+#
3+# Unity Autopilot Test Suite
4+# Copyright (C) 2013 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License as published by
8+# the Free Software Foundation, either version 3 of the License, or
9+# (at your option) any later version.
10+#
11+# This program is distributed in the hope that it will be useful,
12+# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+# GNU General Public License for more details.
15+#
16+# You should have received a copy of the GNU General Public License
17+# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+#
19+
20+"""Tests for the application lifecycle."""
21+
22+from __future__ import absolute_import
23+
24+from unity8.shell import disable_qml_mocking
25+from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
26+
27+from autopilot.matchers import Eventually
28+from autopilot.platform import model
29+from testtools.matchers import Equals, NotEquals
30+
31+import logging
32+
33+logger = logging.getLogger(__name__)
34+
35+
36+class ApplicationLifecycleTests(UnityTestCase):
37+
38+ scenarios = _get_device_emulation_scenarios()
39+
40+ def setUp(self):
41+ super(ApplicationLifecycleTests, self).setUp()
42+ if model() == "Desktop":
43+ self.skipTest("Test cannot be run on the desktop.")
44+
45+ def swipe_screen_from_right(self):
46+ qml_view = self.main_window.get_qml_view()
47+ width = qml_view.width
48+ height = qml_view.height
49+ start_x = width
50+ start_y = int(height/2)
51+ end_x = int(width/2)
52+ end_y = start_y
53+
54+ logger.info("Swiping screen from the right edge")
55+ self.touch.drag(start_x, start_y, end_x, end_y)
56+
57+ def _get_current_focused_app_id(self):
58+ return self._proxy.select_single("Shell").currentFocusedAppId
59+
60+ def _launch_app(self, app_name):
61+ """Launches the application *app_name*
62+
63+ Assumes that the desktop file resides at:
64+ /usr/share/applications/{app_name}.desktop
65+
66+ """
67+ desktop_file = "--desktop_file_hint="\
68+ "/usr/share/applications/{app_name}.desktop".format(
69+ app_name=app_name
70+ )
71+ return self.launch_test_application(
72+ app_name,
73+ desktop_file,
74+ "--stage_hint=main_stage",
75+ app_type='qt'
76+ )
77+
78+ @disable_qml_mocking
79+ def test_can_launch_application(self):
80+ """Must be able to launch an application."""
81+ self.launch_unity()
82+ self.main_window.get_greeter().swipe()
83+
84+ app = self._launch_app("messaging-app")
85+
86+ self.assertThat(app, NotEquals(None))
87+ self.assertThat(
88+ self._get_current_focused_app_id(),
89+ Eventually(Equals("messaging-app"))
90+ )
91+
92+ @disable_qml_mocking
93+ def test_can_launch_multiple_applications(self):
94+ """A second application launched must be focused."""
95+ self.launch_unity()
96+ self.main_window.get_greeter().swipe()
97+
98+ self._launch_app("messaging-app")
99+ self.assertThat(
100+ self._get_current_focused_app_id(),
101+ Eventually(Equals("messaging-app"))
102+ )
103+
104+ self._launch_app("address-book-app")
105+ self.assertThat(
106+ self._get_current_focused_app_id(),
107+ Eventually(Equals("address-book-app"))
108+ )
109+
110+ @disable_qml_mocking
111+ def test_app_moves_from_unfocused_to_focused(self):
112+ """An application that is in the unfocused state must be able to be
113+ brought back to the focused state.
114+
115+ """
116+ self.launch_unity()
117+ self.main_window.get_greeter().swipe()
118+
119+ self._launch_app("messaging-app")
120+ self.assertThat(
121+ self._get_current_focused_app_id(),
122+ Eventually(Equals("messaging-app"))
123+ )
124+
125+ self._launch_app("address-book-app")
126+ self.assertThat(
127+ self._get_current_focused_app_id(),
128+ Eventually(Equals("address-book-app"))
129+ )
130+
131+ self.swipe_screen_from_right()
132+
133+ self.assertThat(
134+ self._get_current_focused_app_id(),
135+ Eventually(Equals("messaging-app"))
136+ )
tests/autopilot/unity8/shell/__init__.py+10
@@ -36,3 +36,13 @@ def with_lightdm_mock(mock_type):
36 return fn(*args, **kwargs)
36 return fn(*args, **kwargs)
37 return wrapper
37 return wrapper
38 return with_lightdm_mock_internal
38 return with_lightdm_mock_internal
39+
40+
41+def disable_qml_mocking(fn):
42+ """Simple decorator that disables the QML mocks from being loaded."""
43+ @wraps(fn)
44+ def wrapper(*args, **kwargs):
45+ tests_self = args[0]
46+ tests_self._qml_mock_enabled = False
47+ return fn(*args, **kwargs)
48+ return wrapper
tests/autopilot/unity8/shell/tests/__init__.py+4−1
@@ -86,6 +86,7 @@ class UnityTestCase(AutopilotTestCase):
86
86
87 self._proxy = None
87 self._proxy = None
88 self._lightdm_mock_type = None
88 self._lightdm_mock_type = None
89+ self._qml_mock_enabled = True
89 self.touch = Touch.create()
90 self.touch = Touch.create()
90 self._setup_display_details()
91 self._setup_display_details()
91
92
@@ -160,7 +161,9 @@ class UnityTestCase(AutopilotTestCase):
160
161
161 if self._lightdm_mock_type is None:
162 if self._lightdm_mock_type is None:
162 self.patch_lightdm_mock()
163 self.patch_lightdm_mock()
164+
165+ if self._qml_mock_enabled:
163− self._setup_extra_mock_environment_patch()
166+ self._setup_extra_mock_environment_patch()
164
167
165 app_proxy = self.launch_test_application(
168 app_proxy = self.launch_test_application(
166 binary_path,
169 binary_path,
tests/plugins/Unity/Launcher/launchermodeltest.cpp+61−2
@@ -62,7 +62,14 @@ public:
62 return QString();
62 return QString();
63 }
63 }
64 unity::shell::application::ApplicationInfoInterface *get(int index) const { return m_list.at(index); }
64 unity::shell::application::ApplicationInfoInterface *get(int index) const { return m_list.at(index); }
65− unity::shell::application::ApplicationInfoInterface *findApplication(const QString &) const { return nullptr; }
65+ unity::shell::application::ApplicationInfoInterface *findApplication(const QString &appId) const {
66+ Q_FOREACH(MockApp* app, m_list) {
67+ if (app->appId() == appId) {
68+ return app;
69+ }
70+ }
71+ return nullptr;
72+ }
66 unity::shell::application::ApplicationInfoInterface *startApplication(const QString &, const QStringList &) { return nullptr; }
73 unity::shell::application::ApplicationInfoInterface *startApplication(const QString &, const QStringList &) { return nullptr; }
67 bool stopApplication(const QString &) { return false; }
74 bool stopApplication(const QString &) { return false; }
68 bool focusApplication(const QString &appId) {
75 bool focusApplication(const QString &appId) {
@@ -151,9 +158,54 @@ private Q_SLOTS:
151 QCOMPARE(launcherModel->get(1)->pinned(), false);
158 QCOMPARE(launcherModel->get(1)->pinned(), false);
152 }
159 }
153
160
161+ void testRemove_data() {
162+
163+ QTest::addColumn<bool>("pinned");
164+ QTest::addColumn<bool>("running");
165+
166+ QTest::newRow("non-pinned, running") << false << true;
167+ QTest::newRow("pinned, running") << true << false;
168+ QTest::newRow("pinned, non-running") << true << false;
169+ }
170+
154 void testRemove() {
171 void testRemove() {
172+ QFETCH(bool, pinned);
173+ QFETCH(bool, running);
174+
175+ // In the beginning we always have two items
155 QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
176 QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
177+
178+ // pin one if required
179+ if (pinned) {
180+ launcherModel->pin(launcherModel->get(1)->appId());
181+ }
182+
183+ // stop it if required
184+ if (!running) {
185+ appManager->removeApplication(1);
186+ }
187+
188+ // Now remove it
156− launcherModel->requestRemove(launcherModel->get(0)->appId());
189+ launcherModel->requestRemove(launcherModel->get(1)->appId());
190+
191+ if (running) {
192+ // both apps are running, both apps must still be here
193+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
194+
195+ // Item must be unpinned now
196+ QCOMPARE(launcherModel->get(1)->pinned(), false);
197+
198+ } else if (pinned) {
199+ // Item 1 must go away, item 0 is here to stay
200+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
201+ }
202+
203+ // done our checks. now stop the app if was still running
204+ if (running) {
205+ appManager->removeApplication(1);
206+ }
207+
208+ // It needs to go away in any case now
157 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
209 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
158 }
210 }
159
211
@@ -181,6 +233,13 @@ private Q_SLOTS:
181
233
182 // quicklist needs to transform to remove item. trigger it and check it item goes away
234 // quicklist needs to transform to remove item. trigger it and check it item goes away
183 launcherModel->quickListActionInvoked(launcherModel->get(0)->appId(), pinActionIndex);
235 launcherModel->quickListActionInvoked(launcherModel->get(0)->appId(), pinActionIndex);
236+ QCOMPARE(launcherModel->get(0)->pinned(), false);
237+
238+ // still needs to be here as the app is still here
239+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
240+ // close the app
241+ appManager->removeApplication(0);
242+ // Now it needs to go away
184 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
243 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
185 }
244 }
186
245
tests/qmltests/Dash/tst_DashContent.qml+1−1
@@ -106,7 +106,7 @@ Item {
106 contentEndReachedSpy.clear()
106 contentEndReachedSpy.clear()
107 clear_scope_status();
107 clear_scope_status();
108
108
109− // clear, wait for dahs to empty and load scopes.
109+ // clear, wait for dash to empty and load scopes.
110 var dashContentList = findChild(dashContent, "dashContentList");
110 var dashContentList = findChild(dashContent, "dashContentList");
111 verify(dashContentList != undefined)
111 verify(dashContentList != undefined)
112 scopesModel.clear();
112 scopesModel.clear();
tests/qmltests/Dash/tst_GenericScopeView.qml+3
@@ -44,10 +44,13 @@ Item {
44
44
45 function test_isCurrent() {
45 function test_isCurrent() {
46 var pageHeader = findChild(genericScopeView, "pageHeader");
46 var pageHeader = findChild(genericScopeView, "pageHeader");
47+ var previewLoader = findChild(genericScopeView, "previewLoader");
47 genericScopeView.isCurrent = true
48 genericScopeView.isCurrent = true
48 pageHeader.searchQuery = "test"
49 pageHeader.searchQuery = "test"
50+ previewLoader.open = true
49 genericScopeView.isCurrent = false
51 genericScopeView.isCurrent = false
50 tryCompare(pageHeader, "searchQuery", "")
52 tryCompare(pageHeader, "searchQuery", "")
53+ tryCompare(genericScopeView, "previewShown", false);
51 }
54 }
52 }
55 }
53 }
56 }
tests/uqmlscene/main.cpp−2
@@ -497,8 +497,6 @@ int main(int argc, char ** argv)
497 }
497 }
498
498
499 if (window) {
499 if (window) {
500− mouseTouchAdaptor.setTargetWindow(window);
501−
502 QSurfaceFormat surfaceFormat = window->requestedFormat();
500 QSurfaceFormat surfaceFormat = window->requestedFormat();
503 if (options.multisample)
501 if (options.multisample)
504 surfaceFormat.setSamples(16);
502 surfaceFormat.setSamples(16);