on xenial help sign in
Merge trunk
e2c239fGerry Boland
Shell.qml+5
@@ -95,6 +95,11 @@ FocusScope {
95 greeter.hide();
95 greeter.hide();
96 shell.activateApplication(desktopFile);
96 shell.activateApplication(desktopFile);
97 }
97 }
98+
99+ onMainStageFocusedApplicationChanged: {
100+ var app = applicationManager.mainStageFocusedApplication
101+ LauncherModel.applicationFocused(app.desktopFile);
102+ }
98 }
103 }
99
104
100 function activateApplication(desktopFile, argument) {
105 function activateApplication(desktopFile, argument) {
plugins/Unity/Launcher/backend/launcherbackend.cpp+36−4
@@ -25,6 +25,7 @@
25#include <QDBusArgument>
25#include <QDBusArgument>
26#include <QFileInfo>
26#include <QFileInfo>
27#include <QGSettings>
27#include <QGSettings>
28+#include <QDebug>
28
29
29class LauncherBackendItem
30class LauncherBackendItem
30{
31{
@@ -73,6 +74,19 @@ void LauncherBackend::setStoredApplications(const QStringList &appIds)
73 }
74 }
74 }
75 }
75 m_storedApps = appIds;
76 m_storedApps = appIds;
77+ Q_FOREACH(const QString &appId, appIds) {
78+ if (!m_itemCache.contains(appId)) {
79+ QString df = findDesktopFile(appId);
80+ if (!df.isEmpty()) {
81+ LauncherBackendItem *item = parseDesktopFile(df);
82+ m_itemCache.insert(appId, item);
83+ } else {
84+ // Cannot find any data for that app... ignoring it.
85+ qWarning() << "cannot find desktop file for" << appId << ". discarding app.";
86+ m_storedApps.removeAll(appId);
87+ }
88+ }
89+ }
76 syncToAccounts();
90 syncToAccounts();
77}
91}
78
92
@@ -199,7 +213,7 @@ void LauncherBackend::syncFromAccounts()
199
213
200 m_storedApps.clear();
214 m_storedApps.clear();
201
215
202− if (m_accounts && m_user.isEmpty()) {
216+ if (m_accounts && !m_user.isEmpty()) {
203 QVariant variant = m_accounts->getUserProperty(m_user, "launcher-items");
217 QVariant variant = m_accounts->getUserProperty(m_user, "launcher-items");
204 apps = qdbus_cast<QList<QVariantMap>>(variant.value<QDBusArgument>());
218 apps = qdbus_cast<QList<QVariantMap>>(variant.value<QDBusArgument>());
205 defaults = isDefaultsItem(apps);
219 defaults = isDefaultsItem(apps);
@@ -248,14 +262,32 @@ QString LauncherBackend::findDesktopFile(const QString &appId) const
248 int dashPos = -1;
262 int dashPos = -1;
249 QString helper = appId;
263 QString helper = appId;
250
264
265+ QStringList searchDirs;
266+ searchDirs << "/usr/share/applications";
267+
268+// FIXME: Right now the appId can be (or rather is) a full path
269+// to a .desktop file. This will change in the future.
270+// Once the ApplicationManager has been switched over to use appIds,
271+// remove this chop() and enable the ifdef to only search the current
272+// working dir for testing. Also, this is the place to add the search
273+// paths for click apps in the next step.
274+ if (helper.endsWith(".desktop")) {
275+ helper.chop(8);
276+ }
277+//#ifdef LAUNCHER_TESTING
278+ searchDirs << "";
279+//#endif
280+
251 do {
281 do {
252 if (dashPos != -1) {
282 if (dashPos != -1) {
253 helper = helper.replace(dashPos, 1, '/');
283 helper = helper.replace(dashPos, 1, '/');
254 }
284 }
255
285
286+ Q_FOREACH(const QString &searchDir, searchDirs) {
256− QFileInfo fileInfo(QDir("/usr/share/applications"), helper);
287+ QFileInfo fileInfo(QDir(searchDir), helper + ".desktop");
257− if (fileInfo.exists()) {
288+ if (fileInfo.exists()) {
258− return fileInfo.absoluteFilePath();
289+ return fileInfo.absoluteFilePath();
290+ }
259 }
291 }
260
292
261 dashPos = helper.indexOf("-");
293 dashPos = helper.indexOf("-");
plugins/Unity/Launcher/launchermodel.cpp+37
@@ -191,6 +191,43 @@ void LauncherModel::setUser(const QString &username)
191 m_backend->setUser(username);
191 m_backend->setUser(username);
192}
192}
193
193
194+void LauncherModel::applicationFocused(const QString &appId)
195+{
196+ int index = findApplication(appId);
197+
198+ if (index >= 0) {
199+ // TODO: Mark application as focued
200+ } else {
201+ // Add app to recent apps
202+ QString desktopFile = m_backend->desktopFile(appId);
203+ QString appName = m_backend->displayName(appId);
204+ QString icon = m_backend->icon(appId);
205+
206+ LauncherItem *item = new LauncherItem(appId, desktopFile, appName, icon);
207+ item->setRecent(true);
208+ beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
209+ m_list.append(item);
210+ endInsertRows();
211+
212+ // Clean up old recent apps
213+ QList<int> recentAppIndices;
214+ for (int i = 0; i < m_list.count(); ++i) {
215+ if (m_list.at(i)->recent()) {
216+ recentAppIndices << i;
217+ }
218+ }
219+ int run = 0;
220+ while (recentAppIndices.count() > 5) {
221+ beginRemoveRows(QModelIndex(), recentAppIndices.first() - run, recentAppIndices.first() - run);
222+ m_list.takeAt(recentAppIndices.first() - run)->deleteLater();
223+ endRemoveRows();
224+ recentAppIndices.takeFirst();
225+ ++run;
226+ }
227+ storeAppList();
228+ }
229+}
230+
194void LauncherModel::storeAppList()
231void LauncherModel::storeAppList()
195{
232{
196 QStringList appIds;
233 QStringList appIds;
plugins/Unity/Launcher/launchermodel.h+1
@@ -49,6 +49,7 @@ public:
49 Q_INVOKABLE void requestRemove(const QString &appId);
49 Q_INVOKABLE void requestRemove(const QString &appId);
50 Q_INVOKABLE void quickListActionInvoked(const QString &appId, int actionIndex);
50 Q_INVOKABLE void quickListActionInvoked(const QString &appId, int actionIndex);
51 Q_INVOKABLE void setUser(const QString &username);
51 Q_INVOKABLE void setUser(const QString &username);
52+ Q_INVOKABLE void applicationFocused(const QString &appId);
52
53
53private:
54private:
54 void storeAppList();
55 void storeAppList();
po/es.po+24−22
@@ -8,15 +8,15 @@ 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: 2013-08-27 13:36-0400\n"
10"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11−"PO-Revision-Date: 2013-07-08 07:25+0000\n"
11+"PO-Revision-Date: 2013-09-04 22:12+0000\n"
12"Last-Translator: Adolfo Jayme Barrientos <fitoschido@gmail.com>\n"
12"Last-Translator: Adolfo Jayme Barrientos <fitoschido@gmail.com>\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"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-08-30 05:37+0000\n"
18+"X-Launchpad-Export-Date: 2013-09-05 05:35+0000\n"
19−"X-Generator: Launchpad (build 16750)\n"
19+"X-Generator: Launchpad (build 16758)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -88,47 +88,49 @@ msgstr "YouTube"
88
88
89#: Components/EdgeDemoOverlay.qml:145
89#: Components/EdgeDemoOverlay.qml:145
90msgid "Skip intro"
90msgid "Skip intro"
91−msgstr ""
91+msgstr "Omitir la introducción"
92
92
93#: Components/EdgeDemo.qml:98
93#: Components/EdgeDemo.qml:98
94msgid "Right edge"
94msgid "Right edge"
95−msgstr ""
95+msgstr "Borde derecho"
96
96
97#: Components/EdgeDemo.qml:99
97#: Components/EdgeDemo.qml:99
98msgid "Try swiping from the right edge to unlock the phone"
98msgid "Try swiping from the right edge to unlock the phone"
99−msgstr ""
99+msgstr "Deslice el dedo desde el borde derecho para desbloquear el teléfono"
100
100
101#: Components/EdgeDemo.qml:135
101#: Components/EdgeDemo.qml:135
102msgid "Top edge"
102msgid "Top edge"
103−msgstr ""
103+msgstr "Borde superior"
104
104
105#: Components/EdgeDemo.qml:136
105#: Components/EdgeDemo.qml:136
106msgid "Try swiping from the top edge to access the indicators"
106msgid "Try swiping from the top edge to access the indicators"
107−msgstr ""
107+msgstr "Deslice el dedo desde el borde superior para acceder a los menús"
108
108
109#: Components/EdgeDemo.qml:161
109#: Components/EdgeDemo.qml:161
110msgid "Close"
110msgid "Close"
111−msgstr ""
111+msgstr "Cerrar"
112
112
113#: Components/EdgeDemo.qml:162
113#: Components/EdgeDemo.qml:162
114msgid "Swipe up again to close the settings screen"
114msgid "Swipe up again to close the settings screen"
115−msgstr ""
115+msgstr "Deslice hacia arriba para cerrar la pantalla de configuración"
116
116
117#: Components/EdgeDemo.qml:189
117#: Components/EdgeDemo.qml:189
118msgid "Left edge"
118msgid "Left edge"
119−msgstr ""
119+msgstr "Borde izquierdo"
120
120
121#: Components/EdgeDemo.qml:190
121#: Components/EdgeDemo.qml:190
122msgid "Swipe from the left to reveal the launcher for quick access to apps"
122msgid "Swipe from the left to reveal the launcher for quick access to apps"
123msgstr ""
123msgstr ""
124+"Deslice el dedo desde la izquierda para mostrar el lanzador y acceder "
125+"rápidamente a las aplicaciones"
124
126
125#: Components/EdgeDemo.qml:217
127#: Components/EdgeDemo.qml:217
126msgid "Well done"
128msgid "Well done"
127−msgstr ""
129+msgstr "Bien hecho"
128
130
129#: Components/EdgeDemo.qml:218
131#: Components/EdgeDemo.qml:218
130msgid "You have now mastered the edge gestures and can start using the phone"
132msgid "You have now mastered the edge gestures and can start using the phone"
131−msgstr ""
133+msgstr "Ahora domina el uso de gestos de los bordes. Puede usar el teléfono"
132
134
133#: Components/PageHeader.qml:298
135#: Components/PageHeader.qml:298
134msgid "Recent searches"
136msgid "Recent searches"
@@ -138,35 +140,35 @@ msgstr "Búsquedas recientes"
138#: Dash/Apps/AppInfo.qml:73
140#: Dash/Apps/AppInfo.qml:73
139#, qt-format
141#, qt-format
140msgid "(%1)"
142msgid "(%1)"
141−msgstr ""
143+msgstr "(%1)"
142
144
143#. TRANSLATORS: Number of persons who wrote reviews for this app
145#. TRANSLATORS: Number of persons who wrote reviews for this app
144#: Dash/Apps/AppInfo.qml:85
146#: Dash/Apps/AppInfo.qml:85
145#, qt-format
147#, qt-format
146msgid "%1 review"
148msgid "%1 review"
147msgid_plural "%1 reviews"
149msgid_plural "%1 reviews"
148−msgstr[0] ""
150+msgstr[0] "%1 reseña"
149−msgstr[1] ""
151+msgstr[1] "%1 reseñas"
150
152
151#: Dash/Apps/AppPreview.qml:175
153#: Dash/Apps/AppPreview.qml:175
152msgid "Rate this"
154msgid "Rate this"
153−msgstr ""
155+msgstr "Valorar esto"
154
156
155#: Dash/Apps/AppReviews.qml:72
157#: Dash/Apps/AppReviews.qml:72
156msgid "Add a review"
158msgid "Add a review"
157−msgstr ""
159+msgstr "Añadir una reseña"
158
160
159#: Dash/Apps/AppReviews.qml:84
161#: Dash/Apps/AppReviews.qml:84
160msgid "Review"
162msgid "Review"
161−msgstr ""
163+msgstr "Reseñar"
162
164
163#: Dash/Apps/AppReviews.qml:118
165#: Dash/Apps/AppReviews.qml:118
164msgid "Send"
166msgid "Send"
165−msgstr ""
167+msgstr "Enviar"
166
168
167#: Dash/Apps/AppReviews.qml:136
169#: Dash/Apps/AppReviews.qml:136
168msgid "Comments:"
170msgid "Comments:"
169−msgstr ""
171+msgstr "Comentarios:"
170
172
171#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
173#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
172msgid "Featured"
174msgid "Featured"
@@ -210,7 +212,7 @@ msgstr "Autor:"
210
212
211#: Greeter/Lockscreen.qml:134
213#: Greeter/Lockscreen.qml:134
212msgid "Emergency Call"
214msgid "Emergency Call"
213−msgstr ""
215+msgstr "Llamada de emergencia"
214
216
215#: Greeter/PassphraseLockscreen.qml:59
217#: Greeter/PassphraseLockscreen.qml:59
216#, qt-format
218#, qt-format
tests/mocks/Unity/Launcher/MockLauncherModel.cpp+5
@@ -180,3 +180,8 @@ void MockLauncherModel::setUser(const QString &username)
180 Q_UNUSED(username)
180 Q_UNUSED(username)
181 // TODO: implement this...
181 // TODO: implement this...
182}
182}
183+
184+void MockLauncherModel::applicationFocused(const QString &appId)
185+{
186+ Q_UNUSED(appId)
187+}
tests/mocks/Unity/Launcher/MockLauncherModel.h+1
@@ -44,6 +44,7 @@ public:
44 Q_INVOKABLE void requestRemove(const QString &appId);
44 Q_INVOKABLE void requestRemove(const QString &appId);
45 Q_INVOKABLE void quickListActionInvoked(const QString &appId, int actionIndex);
45 Q_INVOKABLE void quickListActionInvoked(const QString &appId, int actionIndex);
46 Q_INVOKABLE void setUser(const QString &username);
46 Q_INVOKABLE void setUser(const QString &username);
47+ Q_INVOKABLE void applicationFocused(const QString &appId);
47
48
48Q_SIGNALS:
49Q_SIGNALS:
49 void quickListTriggered(const QString &appId, int index);
50 void quickListTriggered(const QString &appId, int index);
tests/plugins/Unity/Launcher/CMakeLists.txt+10
@@ -10,6 +10,7 @@ include_directories(
10
10
11add_definitions(-DSM_BUSNAME=sessionBus)
11add_definitions(-DSM_BUSNAME=sessionBus)
12add_definitions(-DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}")
12add_definitions(-DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}")
13+add_definitions(-DLAUNCHER_TESTING)
13
14
14set(testCommand ${CMAKE_CURRENT_BINARY_DIR}/launcherbackendtestExec
15set(testCommand ${CMAKE_CURRENT_BINARY_DIR}/launcherbackendtestExec
15 -o ${CMAKE_BINARY_DIR}/launcherbackendtest.xml,xunitxml
16 -o ${CMAKE_BINARY_DIR}/launcherbackendtest.xml,xunitxml
@@ -24,3 +25,12 @@ add_executable(launcherbackendtestExec
24 )
25 )
25target_link_libraries(launcherbackendtestExec ${GSETTINGS_QT_LDFLAGS})
26target_link_libraries(launcherbackendtestExec ${GSETTINGS_QT_LDFLAGS})
26qt5_use_modules(launcherbackendtestExec Test Core DBus)
27qt5_use_modules(launcherbackendtestExec Test Core DBus)
28+
29+# copy .desktop files into build directory for shadow builds
30+file(GLOB DESKTOP_FILES *.desktop)
31+
32+foreach(DESKTOP_FILE ${DESKTOP_FILES})
33+ file(COPY "${DESKTOP_FILE}"
34+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
35+ )
36+endforeach()
tests/plugins/Unity/Launcher/launcherbackendtest.cpp+14−15
@@ -20,7 +20,6 @@
20#include "launcherbackend.h"
20#include "launcherbackend.h"
21
21
22#include <QtTest>
22#include <QtTest>
23−#include <QDebug>
24
23
25class LauncherBackendTest : public QObject
24class LauncherBackendTest : public QObject
26{
25{
@@ -31,29 +30,29 @@ private Q_SLOTS:
31 {
30 {
32 LauncherBackend backend(false);
31 LauncherBackend backend(false);
33
32
34− backend.setStoredApplications(QStringList() << "relative.path" << "/full/path");
33+ backend.setStoredApplications(QStringList() << "rel-icon.desktop" << "abs-icon" << "invalid");
35− QCOMPARE(backend.storedApplications(), QStringList() << "relative.path" << "/full/path");
34+ QCOMPARE(backend.storedApplications(), QStringList() << "rel-icon.desktop" << "abs-icon");
36 }
35 }
37
36
38 void testPinning()
37 void testPinning()
39 {
38 {
40 LauncherBackend backend(false);
39 LauncherBackend backend(false);
41
40
42− backend.setStoredApplications(QStringList() << "one" << "two");
41+ backend.setStoredApplications(QStringList() << "rel-icon" << "abs-icon");
43− QCOMPARE(backend.isPinned("one"), false);
42+ QCOMPARE(backend.isPinned("rel-icon"), false);
44− QCOMPARE(backend.isPinned("two"), false);
43+ QCOMPARE(backend.isPinned("abs-icon"), false);
45
44
46− backend.setPinned("two", true);
45+ backend.setPinned("rel-icon", true);
47− QCOMPARE(backend.isPinned("two"), true);
46+ QCOMPARE(backend.isPinned("rel-icon"), true);
48
47
49− backend.setStoredApplications(QStringList() << "one" << "two" << "three");
48+ backend.setStoredApplications(QStringList() << "rel-icon" << "abs-icon" << "no-name");
50− QCOMPARE(backend.isPinned("two"), true);
49+ QCOMPARE(backend.isPinned("rel-icon"), true);
51− QCOMPARE(backend.isPinned("three"), false);
50+ QCOMPARE(backend.isPinned("no-name"), false);
52
51
53− backend.setPinned("three", true);
52+ backend.setPinned("no-name", true);
54− backend.setStoredApplications(QStringList() << "one" << "two");
53+ backend.setStoredApplications(QStringList() << "rel-icon" << "abs-icon");
55− QCOMPARE(backend.isPinned("two"), true);
54+ QCOMPARE(backend.isPinned("rel-icon"), true);
56− QCOMPARE(backend.isPinned("three"), false); // doesn't exist anymore!
55+ QCOMPARE(backend.isPinned("no-name"), false); // doesn't exist anymore!
57 }
56 }
58};
57};
59
58