Merge lp:~unity-team/unity-scopes-shell/overview into lp:unity-scopes-shell
- overview
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Michal Hruby |
Approved revision: | 132 |
Merged at revision: | 113 |
Proposed branch: | lp:~unity-team/unity-scopes-shell/overview |
Merge into: | lp:unity-scopes-shell |
Diff against target: |
1668 lines (+1114/-52) 29 files modified
debian/changelog (+6/-0) debian/control (+2/-1) src/Unity/CMakeLists.txt (+4/-1) src/Unity/categories.cpp (+20/-14) src/Unity/categories.h (+3/-2) src/Unity/overviewcategories.cpp (+144/-0) src/Unity/overviewcategories.h (+62/-0) src/Unity/overviewresults.cpp (+183/-0) src/Unity/overviewresults.h (+62/-0) src/Unity/overviewscope.cpp (+133/-0) src/Unity/overviewscope.h (+52/-0) src/Unity/previewstack.cpp (+3/-2) src/Unity/resultsmodel.cpp (+20/-0) src/Unity/resultsmodel.h (+6/-0) src/Unity/scope.cpp (+34/-8) src/Unity/scope.h (+11/-5) src/Unity/scopes.cpp (+38/-1) src/Unity/scopes.h (+6/-0) tests/CMakeLists.txt (+5/-4) tests/data/CMakeLists.txt (+1/-0) tests/data/mock-scope-ttl/mock-scope-ttl.ini.in (+0/-3) tests/data/mock-scope/mock-scope.cpp (+2/-2) tests/data/scopes/CMakeLists.txt (+8/-0) tests/data/scopes/scopes.cpp (+132/-0) tests/data/scopes/scopes.ini.in (+8/-0) tests/overviewtest.cpp (+148/-0) tests/previewtest.cpp (+2/-2) tests/resultstest.cpp (+13/-3) tests/test-utils.h (+6/-4) |
To merge this branch: | bzr merge lp:~unity-team/unity-scopes-shell/overview |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Pete Woods (community) | Approve | ||
Albert Astals Cid (community) | functional | Approve | |
Review via email: mp+227745@code.launchpad.net |
Commit message
Implement support for the scopes overview.
Description of the change
Implement support for the scopes overview.
PS Jenkins bot (ps-jenkins) wrote : | # |
- 124. By Michal Hruby
-
Added missing file
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:124
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 125. By Michal Hruby
-
Pretend we're the scopes scope, so server recommendations work
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:125
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 126. By Michal Hruby
-
Bump dep on libunity-api
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:126
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
Been using it with my unity8 branch and can't find nothing wrong.
Pete Woods (pete-woods) wrote : | # |
The code changes look good to me.
- 127. By Michal Hruby
-
Merge trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:127
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 128. By Michal Hruby
-
Fix tests
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:128
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 129. By Michal Hruby
-
Merge trunk
- 130. By Michal Hruby
-
Fix up things
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:130
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 131. By Michal Hruby
-
Fix tests
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:131
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 132. By Michal Hruby
-
Merge the catch branch
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:132
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2014-07-28 15:27:16 +0000 |
3 | +++ debian/changelog 2014-07-31 13:04:48 +0000 |
4 | @@ -1,3 +1,9 @@ |
5 | +unity-scopes-shell (0.5.2-0ubuntu1) UNRELEASED; urgency=medium |
6 | + |
7 | + * Specialized implementation of scopes overview |
8 | + |
9 | + -- Michal Hruby <michal.hruby@canonical.com> Wed, 16 Jul 2014 18:18:08 +0100 |
10 | + |
11 | unity-scopes-shell (0.5.0+14.10.20140728.1-0ubuntu1) utopic; urgency=low |
12 | |
13 | [ Pete Woods ] |
14 | |
15 | === modified file 'debian/control' |
16 | --- debian/control 2014-07-28 15:20:34 +0000 |
17 | +++ debian/control 2014-07-31 13:04:48 +0000 |
18 | @@ -3,7 +3,7 @@ |
19 | Section: libs |
20 | Build-Depends: cmake, |
21 | debhelper (>= 9), |
22 | - libunity-api-dev (>= 7.85), |
23 | + libunity-api-dev (>= 7.87), |
24 | libunity-scopes-dev (>= 0.5.3~), |
25 | libgsettings-qt-dev (>= 0.1), |
26 | libqtdbustest1-dev (>= 0.2), |
27 | @@ -35,6 +35,7 @@ |
28 | unity-scopes-impl-0, |
29 | unity-scopes-impl-1, |
30 | unity-scopes-impl-2, |
31 | + unity-scopes-impl-3, |
32 | Breaks: unity8-private (<< 7.84) |
33 | Replaces: unity8-private (<< 7.84) |
34 | Description: QML plugin for Scopes |
35 | |
36 | === modified file 'src/Unity/CMakeLists.txt' |
37 | --- src/Unity/CMakeLists.txt 2014-07-25 15:30:02 +0000 |
38 | +++ src/Unity/CMakeLists.txt 2014-07-31 13:04:48 +0000 |
39 | @@ -2,7 +2,7 @@ |
40 | include(Plugins) |
41 | |
42 | # Dependencies |
43 | -pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=2) |
44 | +pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=3) |
45 | pkg_check_modules(SCOPESLIB REQUIRED libunity-scopes>=0.5.3) |
46 | pkg_check_modules(GSETTINGSQT REQUIRED gsettings-qt) |
47 | pkg_check_modules(U1DB REQUIRED libu1db-qt5) |
48 | @@ -24,6 +24,9 @@ |
49 | departmentnode.cpp |
50 | geoip.cpp |
51 | locationservice.cpp |
52 | + overviewcategories.cpp |
53 | + overviewresults.cpp |
54 | + overviewscope.cpp |
55 | previewmodel.cpp |
56 | previewstack.cpp |
57 | previewwidgetmodel.cpp |
58 | |
59 | === modified file 'src/Unity/categories.cpp' |
60 | --- src/Unity/categories.cpp 2014-07-24 15:21:23 +0000 |
61 | +++ src/Unity/categories.cpp 2014-07-31 13:04:48 +0000 |
62 | @@ -39,7 +39,7 @@ |
63 | namespace scopes_ng { |
64 | |
65 | // FIXME: this should be in a common place |
66 | -#define CATEGORY_JSON_DEFAULTS R"({"schema-version":1,"template": {"category-layout":"grid","card-layout":"vertical","card-size":"small","overlay-mode":null,"collapsed-rows":2}, "components": { "title":null, "art": { "aspect-ratio":1.0, "fill-mode":"crop" }, "subtitle":null, "mascot":null, "emblem":null, "summary":null, "attributes": { "max-count":2 }, "background":null }, "resources":{}})" |
67 | +#define CATEGORY_JSON_DEFAULTS R"({"schema-version":1,"template": {"category-layout":"grid","card-layout":"vertical","card-size":"small","overlay-mode":null,"collapsed-rows":2}, "components": { "title":null, "art": { "aspect-ratio":1.0, "fill-mode":"crop" }, "subtitle":null, "mascot":null, "emblem":null, "summary":null, "attributes": { "max-count":2 }, "background":null, "overlay-color":null }, "resources":{}})" |
68 | |
69 | class CategoryData |
70 | { |
71 | @@ -219,19 +219,6 @@ |
72 | return m_isSpecial; |
73 | } |
74 | |
75 | -private: |
76 | - static QJsonValue* DEFAULTS; |
77 | - scopes::Category::SCPtr m_category; |
78 | - QString m_catId; |
79 | - QString m_catTitle; |
80 | - QString m_catIcon; |
81 | - std::string m_rawTemplate; |
82 | - QJsonValue m_rendererTemplate; |
83 | - QJsonValue m_components; |
84 | - ResultsModel* m_resultsModel; |
85 | - QPointer<QObject> m_countObject; |
86 | - bool m_isSpecial; |
87 | - |
88 | static bool parseTemplate(std::string const& raw_template, QJsonValue* renderer, QJsonValue* components) |
89 | { |
90 | // lazy init of the defaults |
91 | @@ -265,6 +252,19 @@ |
92 | return true; |
93 | } |
94 | |
95 | +private: |
96 | + static QJsonValue* DEFAULTS; |
97 | + scopes::Category::SCPtr m_category; |
98 | + QString m_catId; |
99 | + QString m_catTitle; |
100 | + QString m_catIcon; |
101 | + std::string m_rawTemplate; |
102 | + QJsonValue m_rendererTemplate; |
103 | + QJsonValue m_components; |
104 | + ResultsModel* m_resultsModel; |
105 | + QPointer<QObject> m_countObject; |
106 | + bool m_isSpecial; |
107 | + |
108 | static QJsonValue mergeOverrides(QJsonValue const& defaultVal, QJsonValue const& overrideVal) |
109 | { |
110 | if (overrideVal.isObject() && defaultVal.isObject()) { |
111 | @@ -440,6 +440,12 @@ |
112 | dataChanged(changeStart, changeEnd, roles); |
113 | } |
114 | |
115 | + |
116 | +bool Categories::parseTemplate(std::string const& raw_template, QJsonValue* renderer, QJsonValue* components) |
117 | +{ |
118 | + return CategoryData::parseTemplate(raw_template, renderer, components); |
119 | +} |
120 | + |
121 | bool Categories::overrideCategoryJson(QString const& categoryId, QString const& json) |
122 | { |
123 | int idx = getCategoryIndex(categoryId); |
124 | |
125 | === modified file 'src/Unity/categories.h' |
126 | --- src/Unity/categories.h 2014-05-13 13:59:41 +0000 |
127 | +++ src/Unity/categories.h 2014-07-31 13:04:48 +0000 |
128 | @@ -24,9 +24,8 @@ |
129 | |
130 | #include <unity/shell/scopes/CategoriesInterface.h> |
131 | |
132 | -#include <QSet> |
133 | -#include <QTimer> |
134 | #include <QSharedPointer> |
135 | +#include <QJsonValue> |
136 | |
137 | #include <unity/scopes/Category.h> |
138 | |
139 | @@ -55,6 +54,8 @@ |
140 | void updateResultCount(ResultsModel* resultsModel); |
141 | void clearAll(); |
142 | |
143 | + static bool parseTemplate(std::string const& raw_template, QJsonValue* renderer, QJsonValue* components); |
144 | + |
145 | private Q_SLOTS: |
146 | void countChanged(); |
147 | |
148 | |
149 | === added file 'src/Unity/overviewcategories.cpp' |
150 | --- src/Unity/overviewcategories.cpp 1970-01-01 00:00:00 +0000 |
151 | +++ src/Unity/overviewcategories.cpp 2014-07-31 13:04:48 +0000 |
152 | @@ -0,0 +1,144 @@ |
153 | +/* |
154 | + * Copyright (C) 2013 Canonical, Ltd. |
155 | + * |
156 | + * Authors: |
157 | + * Michał Sawicz <michal.sawicz@canonical.com> |
158 | + * Michal Hruby <michal.hruby@canonical.com> |
159 | + * |
160 | + * This program is free software; you can redistribute it and/or modify |
161 | + * it under the terms of the GNU General Public License as published by |
162 | + * the Free Software Foundation; version 3. |
163 | + * |
164 | + * This program is distributed in the hope that it will be useful, |
165 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
166 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
167 | + * GNU General Public License for more details. |
168 | + * |
169 | + * You should have received a copy of the GNU General Public License |
170 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
171 | + */ |
172 | + |
173 | +// self |
174 | +#include "overviewcategories.h" |
175 | + |
176 | +// local |
177 | +#include "overviewresults.h" |
178 | +#include "utils.h" |
179 | + |
180 | +namespace scopes_ng |
181 | +{ |
182 | + |
183 | +#define CATEGORY_JSON R"({"schema-version":1,"template": {"category-layout":"grid","card-size":"small","overlay":true}, "components": { "title":"title", "art": {"field":"art", "aspect-ratio": 0.5}, "overlay-color": "overlay-color"}})" |
184 | + |
185 | +struct ScopesCategoryData |
186 | +{ |
187 | + QString categoryId; |
188 | + QString rawTemplate; |
189 | + QVariant rendererVar; |
190 | + QVariant componentsVar; |
191 | + |
192 | + ScopesCategoryData(QString const& id, QString const& jsonTemplate): categoryId(id), rawTemplate(jsonTemplate) |
193 | + { |
194 | + QJsonValue rendererTemplate; |
195 | + QJsonValue components; |
196 | + |
197 | + Categories::parseTemplate(jsonTemplate.toStdString(), &rendererTemplate, &components); |
198 | + rendererVar = rendererTemplate.toVariant(); |
199 | + componentsVar = components.toVariant(); |
200 | + } |
201 | +}; |
202 | + |
203 | +OverviewCategories::OverviewCategories(QObject* parent) |
204 | + : scopes_ng::Categories(parent) |
205 | + , m_isSurfacing(true) |
206 | +{ |
207 | + m_allScopes.reset(new OverviewResultsModel(this)); |
208 | + m_favouriteScopes.reset(new OverviewResultsModel(this)); |
209 | + |
210 | + m_surfaceCategories.append(QSharedPointer<ScopesCategoryData>(new ScopesCategoryData("favorites", CATEGORY_JSON))); |
211 | + m_surfaceCategories.append(QSharedPointer<ScopesCategoryData>(new ScopesCategoryData("all", CATEGORY_JSON))); |
212 | +} |
213 | + |
214 | +OverviewCategories::~OverviewCategories() |
215 | +{ |
216 | +} |
217 | + |
218 | +void OverviewCategories::setSurfacingMode(bool surfacingMode) |
219 | +{ |
220 | + if (m_isSurfacing != surfacingMode) { |
221 | + beginResetModel(); |
222 | + m_isSurfacing = surfacingMode; |
223 | + endResetModel(); |
224 | + } |
225 | +} |
226 | + |
227 | +void OverviewCategories::setAllScopes(const QList<unity::scopes::ScopeMetadata::SPtr>& scopes) |
228 | +{ |
229 | + m_allScopes->setResults(scopes); |
230 | + |
231 | + if (!m_isSurfacing) return; |
232 | + |
233 | + QVector<int> roles; |
234 | + roles.append(RoleCount); |
235 | + |
236 | + QModelIndex changedIndex(index(1)); |
237 | + dataChanged(changedIndex, changedIndex, roles); |
238 | +} |
239 | + |
240 | +void OverviewCategories::setFavouriteScopes(const QList<unity::scopes::ScopeMetadata::SPtr>& scopes) |
241 | +{ |
242 | + m_favouriteScopes->setResults(scopes); |
243 | + |
244 | + if (!m_isSurfacing) return; |
245 | + |
246 | + QVector<int> roles; |
247 | + roles.append(RoleCount); |
248 | + |
249 | + QModelIndex changedIndex(index(0)); |
250 | + dataChanged(changedIndex, changedIndex, roles); |
251 | +} |
252 | + |
253 | +int OverviewCategories::rowCount(const QModelIndex& parent) const |
254 | +{ |
255 | + if (m_isSurfacing) { |
256 | + return m_surfaceCategories.size(); |
257 | + } else { |
258 | + return Categories::rowCount(parent); |
259 | + } |
260 | +} |
261 | + |
262 | +QVariant |
263 | +OverviewCategories::data(const QModelIndex& index, int role) const |
264 | +{ |
265 | + if (!m_isSurfacing) { |
266 | + return Categories::data(index, role); |
267 | + } |
268 | + |
269 | + ScopesCategoryData* catData = m_surfaceCategories.at(index.row()).data(); |
270 | + OverviewResultsModel* results = index.row() == 0 ? m_favouriteScopes.data() : m_allScopes.data(); |
271 | + |
272 | + switch (role) { |
273 | + case RoleCategoryId: |
274 | + return catData->categoryId; |
275 | + case RoleName: |
276 | + return QVariant(); |
277 | + case RoleIcon: |
278 | + return QVariant(); |
279 | + case RoleRawRendererTemplate: |
280 | + return catData->rawTemplate; |
281 | + case RoleRenderer: |
282 | + return catData->rendererVar; |
283 | + case RoleComponents: |
284 | + return catData->componentsVar; |
285 | + case RoleHeaderLink: |
286 | + return QVariant(); |
287 | + case RoleResults: |
288 | + return QVariant::fromValue(results); |
289 | + case RoleCount: |
290 | + return QVariant(results->rowCount()); |
291 | + default: |
292 | + return QVariant(); |
293 | + } |
294 | +} |
295 | + |
296 | +} // namespace scopes_ng |
297 | |
298 | === added file 'src/Unity/overviewcategories.h' |
299 | --- src/Unity/overviewcategories.h 1970-01-01 00:00:00 +0000 |
300 | +++ src/Unity/overviewcategories.h 2014-07-31 13:04:48 +0000 |
301 | @@ -0,0 +1,62 @@ |
302 | +/* |
303 | + * Copyright (C) 2014 Canonical, Ltd. |
304 | + * |
305 | + * Authors: |
306 | + * Michal Hruby <michal.hruby@canonical.com> |
307 | + * |
308 | + * This program is free software; you can redistribute it and/or modify |
309 | + * it under the terms of the GNU General Public License as published by |
310 | + * the Free Software Foundation; version 3. |
311 | + * |
312 | + * This program is distributed in the hope that it will be useful, |
313 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
314 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
315 | + * GNU General Public License for more details. |
316 | + * |
317 | + * You should have received a copy of the GNU General Public License |
318 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
319 | + */ |
320 | + |
321 | + |
322 | +#ifndef NG_OVERVIEW_CATEGORIES_H |
323 | +#define NG_OVERVIEW_CATEGORIES_H |
324 | + |
325 | +#include <unity/scopes/ScopeMetadata.h> |
326 | + |
327 | +#include "categories.h" |
328 | + |
329 | +namespace scopes_ng |
330 | +{ |
331 | + |
332 | +class ScopesCategoryData; |
333 | +class OverviewResultsModel; |
334 | + |
335 | +class Q_DECL_EXPORT OverviewCategories : public scopes_ng::Categories |
336 | +{ |
337 | + Q_OBJECT |
338 | + |
339 | +public: |
340 | + explicit OverviewCategories(QObject* parent = 0); |
341 | + virtual ~OverviewCategories(); |
342 | + |
343 | + void setSurfacingMode(bool isSurfacing); |
344 | + |
345 | + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; |
346 | + int rowCount(const QModelIndex& parent = QModelIndex()) const override; |
347 | + |
348 | + void setAllScopes(const QList<unity::scopes::ScopeMetadata::SPtr>& scopes); |
349 | + void setFavouriteScopes(const QList<unity::scopes::ScopeMetadata::SPtr>& scopes); |
350 | + |
351 | +private: |
352 | + bool m_isSurfacing; |
353 | + |
354 | + QList<QSharedPointer<ScopesCategoryData>> m_surfaceCategories; |
355 | + QScopedPointer<OverviewResultsModel> m_allScopes; |
356 | + QScopedPointer<OverviewResultsModel> m_favouriteScopes; |
357 | +}; |
358 | + |
359 | +} // namespace scopes_ng |
360 | + |
361 | +Q_DECLARE_METATYPE(scopes_ng::OverviewCategories*) |
362 | + |
363 | +#endif // NG_OVERVIEW_CATEGORIES_H |
364 | |
365 | === added file 'src/Unity/overviewresults.cpp' |
366 | --- src/Unity/overviewresults.cpp 1970-01-01 00:00:00 +0000 |
367 | +++ src/Unity/overviewresults.cpp 2014-07-31 13:04:48 +0000 |
368 | @@ -0,0 +1,183 @@ |
369 | +/* |
370 | + * Copyright (C) 2014 Canonical, Ltd. |
371 | + * |
372 | + * Authors: |
373 | + * Michal Hruby <michal.hruby@canonical.com> |
374 | + * |
375 | + * This program is free software; you can redistribute it and/or modify |
376 | + * it under the terms of the GNU General Public License as published by |
377 | + * the Free Software Foundation; version 3. |
378 | + * |
379 | + * This program is distributed in the hope that it will be useful, |
380 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
381 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
382 | + * GNU General Public License for more details. |
383 | + * |
384 | + * You should have received a copy of the GNU General Public License |
385 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
386 | + */ |
387 | + |
388 | +// self |
389 | +#include "overviewresults.h" |
390 | + |
391 | +// local |
392 | +#include "resultsmodel.h" |
393 | +#include "utils.h" |
394 | + |
395 | +#include <unity/scopes/Result.h> |
396 | + |
397 | +namespace scopes_ng { |
398 | + |
399 | +using namespace unity; |
400 | + |
401 | +class FakeResult: public scopes::Result |
402 | +{ |
403 | +public: |
404 | + FakeResult(scopes::ScopeMetadata const& metadata): Result(map_for_meta(metadata)) {} |
405 | + |
406 | +private: |
407 | + // HACK: we need to create a fake result understood by the scopes scope, so it can create a proper preview |
408 | + static scopes::VariantMap map_for_meta(scopes::ScopeMetadata const& metadata) |
409 | + { |
410 | + scopes::VariantMap map; |
411 | + scopes::VariantMap internal; |
412 | + scopes::VariantMap attrs; |
413 | + |
414 | + internal["origin"] = "scopes"; |
415 | + map["internal"] = internal; |
416 | + |
417 | + attrs["title"] = metadata.display_name(); |
418 | + try { |
419 | + attrs["art"] = metadata.art(); |
420 | + } catch (...) {} |
421 | + try { |
422 | + attrs["icon"] = metadata.icon(); |
423 | + } catch (...) {} |
424 | + attrs["description"] = metadata.description(); |
425 | + attrs["uri"] = scopes::CannedQuery(metadata.scope_id()).to_uri(); |
426 | + map["attrs"] = attrs; |
427 | + |
428 | + return map; |
429 | + } |
430 | +}; |
431 | + |
432 | +OverviewResultsModel::OverviewResultsModel(QObject* parent) |
433 | + : unity::shell::scopes::ResultsModelInterface(parent) |
434 | +{ |
435 | +} |
436 | + |
437 | +void OverviewResultsModel::setResults(const QList<unity::scopes::ScopeMetadata::SPtr>& results) |
438 | +{ |
439 | + beginResetModel(); |
440 | + m_results = results; |
441 | + endResetModel(); |
442 | +} |
443 | + |
444 | +QString OverviewResultsModel::categoryId() const |
445 | +{ |
446 | + return QString(); |
447 | +} |
448 | + |
449 | +void OverviewResultsModel::setCategoryId(const QString& id) |
450 | +{ |
451 | + Q_UNUSED(id); |
452 | +} |
453 | + |
454 | +int OverviewResultsModel::rowCount(const QModelIndex& parent) const |
455 | +{ |
456 | + Q_UNUSED(parent); |
457 | + |
458 | + return m_results.count(); |
459 | +} |
460 | + |
461 | +int OverviewResultsModel::count() const |
462 | +{ |
463 | + return m_results.count(); |
464 | +} |
465 | + |
466 | +int OverviewResultsModel::scopeIndex(const QString& scopeId) const |
467 | +{ |
468 | + std::string id(scopeId.toStdString()); |
469 | + |
470 | + for (int i = 0; i < m_results.size(); i++) { |
471 | + if (m_results.at(i)->scope_id() == id) return i; |
472 | + } |
473 | + |
474 | + return -1; |
475 | +} |
476 | + |
477 | +QHash<int, QByteArray> OverviewResultsModel::roleNames() const |
478 | +{ |
479 | + QHash<int, QByteArray> roles(unity::shell::scopes::ResultsModelInterface::roleNames()); |
480 | + roles.insert(ExtraRoles::RoleScopeId, "scopeId"); |
481 | + |
482 | + return roles; |
483 | +} |
484 | + |
485 | +QVariant |
486 | +OverviewResultsModel::data(const QModelIndex& index, int role) const |
487 | +{ |
488 | + scopes::ScopeMetadata* metadata = m_results.at(index.row()).get(); |
489 | + |
490 | + switch (role) { |
491 | + case RoleUri: { |
492 | + scopes::CannedQuery q(metadata->scope_id()); |
493 | + return QString::fromStdString(q.to_uri()); |
494 | + } |
495 | + case RoleCategoryId: |
496 | + return QVariant(); |
497 | + case RoleDndUri: |
498 | + return data(index, RoleUri); |
499 | + case RoleResult: { |
500 | + scopes::Result::SPtr result(new FakeResult(*metadata)); |
501 | + return QVariant::fromValue(result); |
502 | + } |
503 | + case RoleTitle: |
504 | + return QString::fromStdString(metadata->display_name()); |
505 | + case RoleArt: { |
506 | + std::string art; |
507 | + try { |
508 | + art = metadata->icon(); |
509 | + } catch (...) { |
510 | + try { |
511 | + art = metadata->art(); |
512 | + } catch (...) { |
513 | + // no icon, oh well |
514 | + } |
515 | + } |
516 | + return QString::fromStdString(art); |
517 | + } |
518 | + case RoleSubtitle: |
519 | + return QVariant(); |
520 | + case RoleMascot: |
521 | + return QVariant(); |
522 | + case RoleEmblem: |
523 | + return QVariant(); |
524 | + case RoleAttributes: |
525 | + return QVariant(); |
526 | + case RoleSummary: |
527 | + return QVariant(); |
528 | + case RoleBackground: |
529 | + return QVariant(); |
530 | + case RoleOverlayColor: { |
531 | + try { |
532 | + std::string color; |
533 | + auto attrs = metadata->appearance_attributes(); |
534 | + auto it = attrs.find("logo-overlay-color"); |
535 | + if (it != attrs.end()) { |
536 | + color = it->second.get_string(); |
537 | + return QString::fromStdString(color); |
538 | + } |
539 | + } catch (...) { |
540 | + // silently ignore |
541 | + } |
542 | + return QVariant(); |
543 | + } |
544 | + case RoleScopeId: |
545 | + return QString::fromStdString(metadata->scope_id()); |
546 | + default: |
547 | + return QVariant(); |
548 | + } |
549 | +} |
550 | + |
551 | +} // namespace scopes_ng |
552 | |
553 | === added file 'src/Unity/overviewresults.h' |
554 | --- src/Unity/overviewresults.h 1970-01-01 00:00:00 +0000 |
555 | +++ src/Unity/overviewresults.h 2014-07-31 13:04:48 +0000 |
556 | @@ -0,0 +1,62 @@ |
557 | +/* |
558 | + * Copyright (C) 2014 Canonical, Ltd. |
559 | + * |
560 | + * Authors: |
561 | + * Michal Hruby <michal.hruby@canonical.com> |
562 | + * |
563 | + * This program is free software; you can redistribute it and/or modify |
564 | + * it under the terms of the GNU General Public License as published by |
565 | + * the Free Software Foundation; version 3. |
566 | + * |
567 | + * This program is distributed in the hope that it will be useful, |
568 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
569 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
570 | + * GNU General Public License for more details. |
571 | + * |
572 | + * You should have received a copy of the GNU General Public License |
573 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
574 | + */ |
575 | + |
576 | + |
577 | +#ifndef NG_OVERVIEW_RESULTS_H |
578 | +#define NG_OVERVIEW_RESULTS_H |
579 | + |
580 | +#include <unity/shell/scopes/ResultsModelInterface.h> |
581 | +#include <unity/scopes/ScopeMetadata.h> |
582 | + |
583 | +#include <QHash> |
584 | + |
585 | +namespace scopes_ng { |
586 | + |
587 | +class Q_DECL_EXPORT OverviewResultsModel : public unity::shell::scopes::ResultsModelInterface |
588 | +{ |
589 | + Q_OBJECT |
590 | + |
591 | +public: |
592 | + enum ExtraRoles { |
593 | + RoleScopeId = unity::shell::scopes::ResultsModelInterface::Roles::RoleBackground + 100 |
594 | + }; |
595 | + |
596 | + explicit OverviewResultsModel(QObject* parent = 0); |
597 | + |
598 | + void setResults(const QList<unity::scopes::ScopeMetadata::SPtr>& results); |
599 | + |
600 | + int rowCount(const QModelIndex& parent = QModelIndex()) const override; |
601 | + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; |
602 | + |
603 | + int count() const override; |
604 | + |
605 | + QString categoryId() const override; |
606 | + void setCategoryId(QString const& id) override; |
607 | + |
608 | + QHash<int, QByteArray> roleNames() const override; |
609 | + |
610 | + Q_INVOKABLE int scopeIndex(const QString& scopeId) const; |
611 | + |
612 | +private: |
613 | + QList<unity::scopes::ScopeMetadata::SPtr> m_results; |
614 | +}; |
615 | + |
616 | +} // namespace scopes_ng |
617 | + |
618 | +#endif // NG_OVERVIEW_RESULTS_H |
619 | |
620 | === added file 'src/Unity/overviewscope.cpp' |
621 | --- src/Unity/overviewscope.cpp 1970-01-01 00:00:00 +0000 |
622 | +++ src/Unity/overviewscope.cpp 2014-07-31 13:04:48 +0000 |
623 | @@ -0,0 +1,133 @@ |
624 | +/* |
625 | + * Copyright (C) 2014 Canonical, Ltd. |
626 | + * |
627 | + * Authors: |
628 | + * Michal Hruby <michal.hruby@canonical.com> |
629 | + * |
630 | + * This program is free software; you can redistribute it and/or modify |
631 | + * it under the terms of the GNU General Public License as published by |
632 | + * the Free Software Foundation; version 3. |
633 | + * |
634 | + * This program is distributed in the hope that it will be useful, |
635 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
636 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
637 | + * GNU General Public License for more details. |
638 | + * |
639 | + * You should have received a copy of the GNU General Public License |
640 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
641 | + */ |
642 | + |
643 | +// Self |
644 | +#include "overviewscope.h" |
645 | + |
646 | +// local |
647 | +#include "overviewcategories.h" |
648 | +#include "scopes.h" |
649 | +#include "utils.h" |
650 | + |
651 | +// Qt |
652 | +#include <QScopedPointer> |
653 | + |
654 | +namespace scopes_ng |
655 | +{ |
656 | + |
657 | +using namespace unity; |
658 | + |
659 | +OverviewScope::OverviewScope(QObject *parent) : scopes_ng::Scope(parent) |
660 | +{ |
661 | + m_categories.reset(new OverviewCategories(this)); |
662 | + |
663 | + QObject::connect(m_scopesInstance.data(), &Scopes::metadataRefreshed, this, &OverviewScope::metadataChanged); |
664 | +} |
665 | + |
666 | +OverviewScope::~OverviewScope() |
667 | +{ |
668 | +} |
669 | + |
670 | +struct ScopeInfo { |
671 | + scopes::ScopeMetadata::SPtr data; |
672 | + QString name; |
673 | + |
674 | + ScopeInfo(scopes::ScopeMetadata::SPtr const& data_): |
675 | + data(data_), name(QString::fromStdString(data->display_name())) {} |
676 | +}; |
677 | + |
678 | +bool operator<(ScopeInfo const& first, ScopeInfo const& second) |
679 | +{ |
680 | + return first.name.compare(second.name, Qt::CaseInsensitive) < 0; |
681 | +} |
682 | + |
683 | +void OverviewScope::metadataChanged() |
684 | +{ |
685 | + OverviewCategories* categories = qobject_cast<OverviewCategories*>(m_categories.data()); |
686 | + if (!categories) { |
687 | + qWarning("Unable to cast m_categories to OverviewCategories"); |
688 | + return; |
689 | + } |
690 | + |
691 | + QMap<QString, scopes::ScopeMetadata::SPtr> allMetadata = m_scopesInstance->getAllMetadata(); |
692 | + QList<scopes::ScopeMetadata::SPtr> favourites; |
693 | + Q_FOREACH(QString id, m_scopesInstance->getFavoriteIds()) { |
694 | + auto it = allMetadata.find(id); |
695 | + if (it != allMetadata.end()) { |
696 | + favourites.append(it.value()); |
697 | + } |
698 | + } |
699 | + |
700 | + QList<ScopeInfo> scopes; |
701 | + Q_FOREACH(scopes::ScopeMetadata::SPtr const& metadata, allMetadata.values()) { |
702 | + if (metadata->invisible()) continue; |
703 | + scopes.append(ScopeInfo(metadata)); |
704 | + } |
705 | + qSort(scopes.begin(), scopes.end()); |
706 | + |
707 | + QList<scopes::ScopeMetadata::SPtr> allScopes; |
708 | + Q_FOREACH(ScopeInfo const& info, scopes) { |
709 | + allScopes << info.data; |
710 | + } |
711 | + |
712 | + // FIXME: filter invisible scopes? |
713 | + categories->setAllScopes(allScopes); |
714 | + categories->setFavouriteScopes(favourites); |
715 | +} |
716 | + |
717 | +QString OverviewScope::id() const |
718 | +{ |
719 | + return QString("scopes"); |
720 | +} |
721 | + |
722 | +bool OverviewScope::visible() const |
723 | +{ |
724 | + return false; |
725 | +} |
726 | + |
727 | +scopes::ScopeProxy OverviewScope::proxy_for_result(scopes::Result::SPtr const& result) const |
728 | +{ |
729 | + try { |
730 | + return result->target_scope_proxy(); |
731 | + } catch (...) { |
732 | + // our fake results don't have a proxy associated, return the default one |
733 | + return proxy(); |
734 | + } |
735 | +} |
736 | + |
737 | +void OverviewScope::dispatchSearch() |
738 | +{ |
739 | + OverviewCategories* categories = qobject_cast<OverviewCategories*>(m_categories.data()); |
740 | + if (!categories) { |
741 | + qWarning("Unable to cast m_categories to OverviewCategories"); |
742 | + return; |
743 | + } |
744 | + |
745 | + if (searchQuery().isEmpty()) { |
746 | + setSearchInProgress(true); |
747 | + invalidateLastSearch(); |
748 | + categories->setSurfacingMode(true); |
749 | + setSearchInProgress(false); |
750 | + } else { |
751 | + categories->setSurfacingMode(false); |
752 | + Scope::dispatchSearch(); |
753 | + } |
754 | +} |
755 | + |
756 | +} // namespace scopes_ng |
757 | |
758 | === added file 'src/Unity/overviewscope.h' |
759 | --- src/Unity/overviewscope.h 1970-01-01 00:00:00 +0000 |
760 | +++ src/Unity/overviewscope.h 2014-07-31 13:04:48 +0000 |
761 | @@ -0,0 +1,52 @@ |
762 | +/* |
763 | + * Copyright (C) 2014 Canonical, Ltd. |
764 | + * |
765 | + * Authors: |
766 | + * Michal Hruby <michal.hruby@canonical.com> |
767 | + * |
768 | + * This program is free software; you can redistribute it and/or modify |
769 | + * it under the terms of the GNU General Public License as published by |
770 | + * the Free Software Foundation; version 3. |
771 | + * |
772 | + * This program is distributed in the hope that it will be useful, |
773 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
774 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
775 | + * GNU General Public License for more details. |
776 | + * |
777 | + * You should have received a copy of the GNU General Public License |
778 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
779 | + */ |
780 | + |
781 | +#ifndef NG_OVERVIEW_SCOPE_H |
782 | +#define NG_OVERVIEW_SCOPE_H |
783 | + |
784 | +#include "scope.h" |
785 | + |
786 | +namespace scopes_ng |
787 | +{ |
788 | + |
789 | +class Q_DECL_EXPORT OverviewScope : public scopes_ng::Scope |
790 | +{ |
791 | + Q_OBJECT |
792 | + |
793 | +public: |
794 | + explicit OverviewScope(QObject *parent = 0); |
795 | + virtual ~OverviewScope(); |
796 | + |
797 | + /* getters */ |
798 | + QString id() const override; |
799 | + bool visible() const override; |
800 | + |
801 | + void dispatchSearch() override; |
802 | + |
803 | + unity::scopes::ScopeProxy proxy_for_result(unity::scopes::Result::SPtr const& result) const override; |
804 | + |
805 | +private Q_SLOTS: |
806 | + void metadataChanged(); |
807 | +}; |
808 | + |
809 | +} // namespace scopes_ng |
810 | + |
811 | +Q_DECLARE_METATYPE(scopes_ng::OverviewScope*) |
812 | + |
813 | +#endif // NG_OVERVIEW_SCOPE_H |
814 | |
815 | === modified file 'src/Unity/previewstack.cpp' |
816 | --- src/Unity/previewstack.cpp 2014-05-19 09:58:14 +0000 |
817 | +++ src/Unity/previewstack.cpp 2014-07-31 13:04:48 +0000 |
818 | @@ -112,7 +112,7 @@ |
819 | // TODO: figure out if the result can produce a preview without sending a request to the scope |
820 | // if (m_previewedResult->has_early_preview()) { ... } |
821 | try { |
822 | - auto proxy = m_previewedResult->target_scope_proxy(); |
823 | + auto proxy = m_associatedScope ? m_associatedScope->proxy_for_result(m_previewedResult) : m_previewedResult->target_scope_proxy(); |
824 | |
825 | QString formFactor(m_associatedScope ? m_associatedScope->formFactor() : "phone"); |
826 | scopes::ActionMetadata metadata(QLocale::system().name().toStdString(), formFactor.toStdString()); |
827 | @@ -153,7 +153,8 @@ |
828 | } |
829 | |
830 | try { |
831 | - auto proxy = m_previewedResult->target_scope_proxy(); |
832 | + auto proxy = m_associatedScope ? m_associatedScope->proxy_for_result(m_previewedResult) : m_previewedResult->target_scope_proxy(); |
833 | + |
834 | QString formFactor(m_associatedScope ? m_associatedScope->formFactor() : "phone"); |
835 | scopes::ActionMetadata metadata(QLocale::system().name().toStdString(), formFactor.toStdString()); |
836 | metadata.set_scope_data(qVariantToScopeVariant(data)); |
837 | |
838 | === modified file 'src/Unity/resultsmodel.cpp' |
839 | --- src/Unity/resultsmodel.cpp 2014-07-24 15:21:23 +0000 |
840 | +++ src/Unity/resultsmodel.cpp 2014-07-31 13:04:48 +0000 |
841 | @@ -167,6 +167,14 @@ |
842 | return attributes; |
843 | } |
844 | |
845 | +QHash<int, QByteArray> ResultsModel::roleNames() const |
846 | +{ |
847 | + QHash<int, QByteArray> roles(unity::shell::scopes::ResultsModelInterface::roleNames()); |
848 | + roles.insert(ExtraRoles::RoleScopeId, "scopeId"); |
849 | + |
850 | + return roles; |
851 | +} |
852 | + |
853 | QVariant |
854 | ResultsModel::data(const QModelIndex& index, int role) const |
855 | { |
856 | @@ -217,6 +225,18 @@ |
857 | } |
858 | return backgroundUriToVariant(backgroundVariant.toString()); |
859 | } |
860 | + case RoleOverlayColor: |
861 | + return componentValue(result, "overlay-color"); |
862 | + case RoleScopeId: |
863 | + if (result->uri().compare(0, 8, "scope://") == 0) { |
864 | + try { |
865 | + scopes::CannedQuery q(scopes::CannedQuery::from_uri(result->uri())); |
866 | + return QString::fromStdString(q.scope_id()); |
867 | + } catch (...) { |
868 | + // silently ignore and return "undefined" |
869 | + } |
870 | + } |
871 | + return QVariant(); |
872 | default: |
873 | return QVariant(); |
874 | } |
875 | |
876 | === modified file 'src/Unity/resultsmodel.h' |
877 | --- src/Unity/resultsmodel.h 2014-07-24 15:21:23 +0000 |
878 | +++ src/Unity/resultsmodel.h 2014-07-31 13:04:48 +0000 |
879 | @@ -35,6 +35,10 @@ |
880 | Q_OBJECT |
881 | |
882 | public: |
883 | + enum ExtraRoles { |
884 | + RoleScopeId = unity::shell::scopes::ResultsModelInterface::Roles::RoleBackground + 100 |
885 | + }; |
886 | + |
887 | explicit ResultsModel(QObject* parent = 0); |
888 | |
889 | int rowCount(const QModelIndex& parent = QModelIndex()) const override; |
890 | @@ -52,6 +56,8 @@ |
891 | void setComponentsMapping(QHash<QString, QString> const& mapping); |
892 | void setMaxAtrributesCount(int count); |
893 | |
894 | + QHash<int, QByteArray> roleNames() const override; |
895 | + |
896 | private: |
897 | QVariant componentValue(unity::scopes::CategorisedResult const* result, std::string const& fieldName) const; |
898 | QVariant attributesValue(unity::scopes::CategorisedResult const* result) const; |
899 | |
900 | === modified file 'src/Unity/scope.cpp' |
901 | --- src/Unity/scope.cpp 2014-07-25 15:30:02 +0000 |
902 | +++ src/Unity/scope.cpp 2014-07-31 13:04:48 +0000 |
903 | @@ -74,7 +74,7 @@ |
904 | , m_searchController(new CollectionController) |
905 | , m_activationController(new CollectionController) |
906 | { |
907 | - m_categories = new Categories(this); |
908 | + m_categories.reset(new Categories(this)); |
909 | |
910 | m_settings = QGSettings::isSchemaInstalled("com.canonical.Unity.Lenses") ? new QGSettings("com.canonical.Unity.Lenses", QByteArray(), this) : nullptr; |
911 | QObject::connect(m_settings, &QGSettings::changed, this, &Scope::internetFlagChanged); |
912 | @@ -216,13 +216,20 @@ |
913 | QString scopeId(QString::fromStdString(query.scope_id())); |
914 | QString searchString(QString::fromStdString(query.query_string())); |
915 | QString departmentId(QString::fromStdString(query.department_id())); |
916 | - // figure out if this scope is already favourited |
917 | - Scope* scope = m_scopesInstance->getScopeById(scopeId); |
918 | + |
919 | + Scope* scope = nullptr; |
920 | + if (scopeId == id()) { |
921 | + scope = this; |
922 | + } else { |
923 | + // figure out if this scope is already favourited |
924 | + scope = m_scopesInstance->getScopeById(scopeId); |
925 | + } |
926 | + |
927 | if (scope != nullptr) { |
928 | // TODO: change filters? |
929 | scope->setCurrentDepartmentId(departmentId); |
930 | scope->setSearchQuery(searchString); |
931 | - Q_EMIT gotoScope(scopeId); |
932 | + if (scope != this) Q_EMIT gotoScope(scopeId); |
933 | } else { |
934 | // create temp dash page |
935 | auto meta_sptr = m_scopesInstance->getCachedMetadata(scopeId); |
936 | @@ -405,7 +412,7 @@ |
937 | Q_FOREACH(scopes::Category::SCPtr const& category, categories) { |
938 | ResultsModel* category_model = m_categories->lookupCategory(category->id()); |
939 | if (category_model == nullptr) { |
940 | - category_model = new ResultsModel(m_categories); |
941 | + category_model = new ResultsModel(m_categories.data()); |
942 | category_model->setCategoryId(QString::fromStdString(category->id())); |
943 | category_model->addResults(category_results[category->id()]); |
944 | m_categories->registerCategory(category, category_model); |
945 | @@ -418,6 +425,16 @@ |
946 | } |
947 | } |
948 | |
949 | +scopes::ScopeProxy Scope::proxy() const |
950 | +{ |
951 | + return m_proxy; |
952 | +} |
953 | + |
954 | +scopes::ScopeProxy Scope::proxy_for_result(scopes::Result::SPtr const& result) const |
955 | +{ |
956 | + return result->target_scope_proxy(); |
957 | +} |
958 | + |
959 | void Scope::invalidateLastSearch() |
960 | { |
961 | m_searchController->invalidate(); |
962 | @@ -608,7 +625,16 @@ |
963 | |
964 | QString Scope::searchHint() const |
965 | { |
966 | - return QString::fromStdString(m_scopeMetadata ? m_scopeMetadata->search_hint() : ""); |
967 | + std::string search_hint; |
968 | + try { |
969 | + if (m_scopeMetadata) { |
970 | + search_hint = m_scopeMetadata->search_hint(); |
971 | + } |
972 | + } catch (...) { |
973 | + // throws if the value isn't set, safe to ignore |
974 | + } |
975 | + |
976 | + return QString::fromStdString(search_hint); |
977 | } |
978 | |
979 | bool Scope::searchInProgress() const |
980 | @@ -638,7 +664,7 @@ |
981 | |
982 | unity::shell::scopes::CategoriesInterface* Scope::categories() const |
983 | { |
984 | - return m_categories; |
985 | + return m_categories.data(); |
986 | } |
987 | |
988 | unity::shell::scopes::SettingsModelInterface* Scope::settings() const |
989 | @@ -813,7 +839,7 @@ |
990 | scopes::ActivationListenerBase::SPtr listener(new ActivationReceiver(this, result)); |
991 | m_activationController->setListener(listener); |
992 | |
993 | - auto proxy = result->target_scope_proxy(); |
994 | + auto proxy = proxy_for_result(result); |
995 | unity::scopes::ActionMetadata metadata(QLocale::system().name().toStdString(), m_formFactor.toStdString()); |
996 | scopes::QueryCtrlProxy controller = proxy->activate(*(result.get()), metadata, listener); |
997 | m_activationController->setController(controller); |
998 | |
999 | === modified file 'src/Unity/scope.h' |
1000 | --- src/Unity/scope.h 2014-07-20 17:14:37 +0000 |
1001 | +++ src/Unity/scope.h 2014-07-31 13:04:48 +0000 |
1002 | @@ -148,6 +148,7 @@ |
1003 | void activateUri(QString const& uri); |
1004 | |
1005 | bool resultsDirty() const; |
1006 | + virtual unity::scopes::ScopeProxy proxy_for_result(unity::scopes::Result::SPtr const& result) const; |
1007 | |
1008 | public Q_SLOTS: |
1009 | void invalidateResults(); |
1010 | @@ -161,17 +162,24 @@ |
1011 | void internetFlagChanged(QString const& key); |
1012 | void departmentModelDestroyed(QObject* obj); |
1013 | |
1014 | +protected: |
1015 | + void setSearchInProgress(bool searchInProgress); |
1016 | + void invalidateLastSearch(); |
1017 | + virtual void dispatchSearch(); |
1018 | + |
1019 | + unity::scopes::ScopeProxy proxy() const; |
1020 | + |
1021 | + QScopedPointer<Categories> m_categories; |
1022 | + QPointer<Scopes> m_scopesInstance; |
1023 | + |
1024 | private: |
1025 | void setScopesInstance(Scopes*); |
1026 | void startTtlTimer(); |
1027 | - void setSearchInProgress(bool searchInProgress); |
1028 | void setCurrentDepartmentId(QString const& id); |
1029 | void processSearchChunk(PushEvent* pushEvent); |
1030 | void executeCannedQuery(unity::scopes::CannedQuery const& query, bool allowDelayedActivation); |
1031 | |
1032 | void processResultSet(QList<std::shared_ptr<unity::scopes::CategorisedResult>>& result_set); |
1033 | - void dispatchSearch(); |
1034 | - void invalidateLastSearch(); |
1035 | |
1036 | static unity::scopes::Department::SCPtr findDepartmentById(unity::scopes::Department::SCPtr const& root, std::string const& id); |
1037 | static unity::scopes::Department::SCPtr findUpdateNode(DepartmentNode* node, unity::scopes::Department::SCPtr const& scopeNode); |
1038 | @@ -195,7 +203,6 @@ |
1039 | unity::scopes::Department::SCPtr m_rootDepartment; |
1040 | unity::scopes::Department::SCPtr m_lastRootDepartment; |
1041 | QGSettings* m_settings; |
1042 | - Categories* m_categories; |
1043 | QScopedPointer<SettingsModel> m_settingsModel; |
1044 | QSharedPointer<DepartmentNode> m_departmentTree; |
1045 | QTimer m_aggregatorTimer; |
1046 | @@ -205,7 +212,6 @@ |
1047 | QSet<unity::shell::scopes::ScopeInterface*> m_tempScopes; |
1048 | QMultiMap<QString, Department*> m_departmentModels; |
1049 | QMap<Department*, QString> m_inverseDepartments; |
1050 | - QPointer<Scopes> m_scopesInstance; |
1051 | QMetaObject::Connection m_metadataConnection; |
1052 | LocationService::Ptr m_locationService; |
1053 | }; |
1054 | |
1055 | === modified file 'src/Unity/scopes.cpp' |
1056 | --- src/Unity/scopes.cpp 2014-07-24 13:17:30 +0000 |
1057 | +++ src/Unity/scopes.cpp 2014-07-31 13:04:48 +0000 |
1058 | @@ -22,6 +22,7 @@ |
1059 | |
1060 | // Local |
1061 | #include "scope.h" |
1062 | +#include "overviewscope.h" |
1063 | #include "ubuntulocationservice.h" |
1064 | |
1065 | // Qt |
1066 | @@ -39,6 +40,8 @@ |
1067 | |
1068 | using namespace unity; |
1069 | |
1070 | +#define SCOPES_SCOPE_ID "scopes" |
1071 | + |
1072 | void ScopeListWorker::run() |
1073 | { |
1074 | try |
1075 | @@ -90,6 +93,7 @@ |
1076 | |
1077 | Scopes::Scopes(QObject *parent) |
1078 | : unity::shell::scopes::ScopesInterface(parent) |
1079 | + , m_overviewScope(nullptr) |
1080 | , m_listThread(nullptr) |
1081 | , m_loaded(false) |
1082 | , m_priv(new Priv()) |
1083 | @@ -107,6 +111,7 @@ |
1084 | |
1085 | QDBusConnection::sessionBus().connect(QString(), QString("/com/canonical/unity/scopes"), QString("com.canonical.unity.scopes"), QString("InvalidateResults"), this, SLOT(invalidateScopeResults(QString))); |
1086 | |
1087 | + m_overviewScope = new OverviewScope(this); |
1088 | m_locationService.reset(new UbuntuLocationService()); |
1089 | } |
1090 | |
1091 | @@ -147,7 +152,7 @@ |
1092 | new core::ScopedConnection( |
1093 | m_scopesRuntime->registry()->set_list_update_callback( |
1094 | std::bind(&Scopes::Priv::safeInvalidateScopeResults, |
1095 | - m_priv.get(), "scopes")))); |
1096 | + m_priv.get(), SCOPES_SCOPE_ID)))); |
1097 | |
1098 | // FIXME: use a dconf setting for this |
1099 | QByteArray enabledScopes = qgetenv("UNITY_SCOPES_LIST"); |
1100 | @@ -174,6 +179,16 @@ |
1101 | } |
1102 | } |
1103 | |
1104 | + // HACK! deal with the overview scope |
1105 | + { |
1106 | + auto it = scopes.find(SCOPES_SCOPE_ID); |
1107 | + if (it != scopes.end()) { |
1108 | + m_overviewScope->setScopeData(it->second); |
1109 | + } else { |
1110 | + qWarning("Unable to add overview scope, can't find with ID: \"%s\"", SCOPES_SCOPE_ID); |
1111 | + } |
1112 | + } |
1113 | + |
1114 | // cache all the metadata |
1115 | for (auto it = scopes.begin(); it != scopes.end(); ++it) { |
1116 | m_cachedMetadata[QString::fromStdString(it->first)] = std::make_shared<unity::scopes::ScopeMetadata>(it->second); |
1117 | @@ -183,6 +198,7 @@ |
1118 | |
1119 | m_loaded = true; |
1120 | Q_EMIT loadedChanged(); |
1121 | + Q_EMIT overviewScopeChanged(); |
1122 | Q_EMIT metadataRefreshed(); |
1123 | |
1124 | m_listThread = nullptr; |
1125 | @@ -266,6 +282,22 @@ |
1126 | return nullptr; |
1127 | } |
1128 | |
1129 | +QStringList Scopes::getFavoriteIds() const |
1130 | +{ |
1131 | + QStringList ids; |
1132 | + |
1133 | + Q_FOREACH(Scope* scope, m_scopes) { |
1134 | + ids << scope->id(); |
1135 | + } |
1136 | + |
1137 | + return ids; |
1138 | +} |
1139 | + |
1140 | +QMap<QString, unity::scopes::ScopeMetadata::SPtr> Scopes::getAllMetadata() const |
1141 | +{ |
1142 | + return m_cachedMetadata; |
1143 | +} |
1144 | + |
1145 | scopes::ScopeMetadata::SPtr Scopes::getCachedMetadata(QString const& scopeId) const |
1146 | { |
1147 | auto it = m_cachedMetadata.constFind(scopeId); |
1148 | @@ -290,6 +322,11 @@ |
1149 | } |
1150 | } |
1151 | |
1152 | +unity::shell::scopes::ScopeInterface* Scopes::overviewScope() const |
1153 | +{ |
1154 | + return m_loaded ? m_overviewScope : nullptr; |
1155 | +} |
1156 | + |
1157 | bool Scopes::loaded() const |
1158 | { |
1159 | return m_loaded; |
1160 | |
1161 | === modified file 'src/Unity/scopes.h' |
1162 | --- src/Unity/scopes.h 2014-07-16 15:32:25 +0000 |
1163 | +++ src/Unity/scopes.h 2014-07-31 13:04:48 +0000 |
1164 | @@ -27,6 +27,7 @@ |
1165 | // Qt |
1166 | #include <QList> |
1167 | #include <QThread> |
1168 | +#include <QStringList> |
1169 | #include <QSharedPointer> |
1170 | |
1171 | #include <unity/scopes/Runtime.h> |
1172 | @@ -55,9 +56,13 @@ |
1173 | |
1174 | Scope* getScopeById(QString const& scopeId) const; |
1175 | unity::scopes::ScopeMetadata::SPtr getCachedMetadata(QString const& scopeId) const; |
1176 | + QMap<QString, unity::scopes::ScopeMetadata::SPtr> getAllMetadata() const; |
1177 | + QStringList getFavoriteIds() const; |
1178 | + |
1179 | void refreshScopeMetadata(); |
1180 | |
1181 | bool loaded() const override; |
1182 | + unity::shell::scopes::ScopeInterface* overviewScope() const override; |
1183 | |
1184 | LocationService::Ptr locationService() const; |
1185 | |
1186 | @@ -76,6 +81,7 @@ |
1187 | |
1188 | QList<Scope*> m_scopes; |
1189 | QMap<QString, unity::scopes::ScopeMetadata::SPtr> m_cachedMetadata; |
1190 | + Scope* m_overviewScope; |
1191 | QThread* m_listThread; |
1192 | bool m_loaded; |
1193 | |
1194 | |
1195 | === modified file 'tests/CMakeLists.txt' |
1196 | --- tests/CMakeLists.txt 2014-07-25 15:30:02 +0000 |
1197 | +++ tests/CMakeLists.txt 2014-07-31 13:04:48 +0000 |
1198 | @@ -1,4 +1,4 @@ |
1199 | -pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=1) |
1200 | +pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=3) |
1201 | pkg_check_modules(SCOPESLIB REQUIRED libunity-scopes>=0.5.3) |
1202 | pkg_check_modules(GSETTINGSQT REQUIRED gsettings-qt) |
1203 | pkg_check_modules(QTDBUSTEST REQUIRED libqtdbustest-1>=0.2 REQUIRED) |
1204 | @@ -57,11 +57,12 @@ |
1205 | |
1206 | run_tests( |
1207 | departmentstest |
1208 | + locationtest |
1209 | + overviewtest |
1210 | + previewtest |
1211 | resultstest |
1212 | - previewtest |
1213 | - locationtest |
1214 | + settingstest |
1215 | utilstest |
1216 | - settingstest |
1217 | ) |
1218 | |
1219 | qt5_use_modules(settingstestExec Sql) |
1220 | |
1221 | === modified file 'tests/data/CMakeLists.txt' |
1222 | --- tests/data/CMakeLists.txt 2014-06-02 14:36:07 +0000 |
1223 | +++ tests/data/CMakeLists.txt 2014-07-31 13:04:48 +0000 |
1224 | @@ -1,6 +1,7 @@ |
1225 | add_subdirectory(mock-scope) |
1226 | add_subdirectory(mock-scope-departments) |
1227 | add_subdirectory(mock-scope-ttl) |
1228 | +add_subdirectory(scopes) |
1229 | |
1230 | configure_file(Runtime.ini.in Runtime.ini @ONLY) |
1231 | configure_file(Registry.ini.in Registry.ini @ONLY) |
1232 | |
1233 | === modified file 'tests/data/mock-scope-ttl/mock-scope-ttl.ini.in' |
1234 | --- tests/data/mock-scope-ttl/mock-scope-ttl.ini.in 2014-05-15 08:21:45 +0000 |
1235 | +++ tests/data/mock-scope-ttl/mock-scope-ttl.ini.in 2014-07-31 13:04:48 +0000 |
1236 | @@ -1,9 +1,6 @@ |
1237 | [ScopeConfig] |
1238 | DisplayName = mock-ttl.DisplayName |
1239 | Description = mock-ttl.Description |
1240 | -Art = /mock-ttl.Art |
1241 | Icon = /mock-ttl.Icon |
1242 | -SearchHint = mock-ttl.SearchHint |
1243 | -HotKey = mock-ttl.HotKey |
1244 | Author = mock-ttl.Author |
1245 | ResultsTtlType = Small |
1246 | |
1247 | === modified file 'tests/data/mock-scope/mock-scope.cpp' |
1248 | --- tests/data/mock-scope/mock-scope.cpp 2014-07-24 15:21:23 +0000 |
1249 | +++ tests/data/mock-scope/mock-scope.cpp 2014-07-31 13:04:48 +0000 |
1250 | @@ -143,7 +143,7 @@ |
1251 | CategorisedResult res(cat); |
1252 | res.set_uri("test:perform-query"); |
1253 | res.set_title("result for: \"" + query_ + "\""); |
1254 | - res["scope-id"] = "mock-scope"; |
1255 | + res["scope-id"] = "mock-scope-ttl"; |
1256 | res.set_intercept_activation(); |
1257 | reply->push(res); |
1258 | } |
1259 | @@ -163,7 +163,7 @@ |
1260 | CategoryRenderer minimal_rndr(R"({"schema-version": 1, "components": {"title": "title"}})"); |
1261 | auto cat = reply->register_category("cat1", "Category 1", "", minimal_rndr); |
1262 | CategorisedResult res(cat); |
1263 | - res.set_uri("scope://mock-scope?q=next-scope-uri"); |
1264 | + res.set_uri("scope://mock-scope?q=next-scope-query"); |
1265 | res.set_title("result for: \"" + query_ + "\""); |
1266 | reply->push(res); |
1267 | } |
1268 | |
1269 | === added directory 'tests/data/scopes' |
1270 | === added file 'tests/data/scopes/CMakeLists.txt' |
1271 | --- tests/data/scopes/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1272 | +++ tests/data/scopes/CMakeLists.txt 2014-07-31 13:04:48 +0000 |
1273 | @@ -0,0 +1,8 @@ |
1274 | +pkg_check_modules(SCOPESLIB REQUIRED libunity-scopes>=0.5.0) |
1275 | + |
1276 | +include_directories(${SCOPESLIB_INCLUDE_DIRS}) |
1277 | + |
1278 | +add_library(scopes MODULE scopes.cpp) |
1279 | +target_link_libraries(scopes ${SCOPESLIB_LDFLAGS}) |
1280 | + |
1281 | +configure_file(scopes.ini.in scopes.ini) |
1282 | |
1283 | === added file 'tests/data/scopes/scopes.cpp' |
1284 | --- tests/data/scopes/scopes.cpp 1970-01-01 00:00:00 +0000 |
1285 | +++ tests/data/scopes/scopes.cpp 2014-07-31 13:04:48 +0000 |
1286 | @@ -0,0 +1,132 @@ |
1287 | +/* |
1288 | + * Copyright (C) 2013 Canonical, Ltd. |
1289 | + * |
1290 | + * This program is free software; you can redistribute it and/or modify |
1291 | + * it under the terms of the GNU General Public License as published by |
1292 | + * the Free Software Foundation; version 3. |
1293 | + * |
1294 | + * This program is distributed in the hope that it will be useful, |
1295 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1296 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1297 | + * GNU General Public License for more details. |
1298 | + * |
1299 | + * You should have received a copy of the GNU General Public License |
1300 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1301 | + * |
1302 | + * Authors: |
1303 | + * Michal Hruby <michal.hruby@canonical.com> |
1304 | + */ |
1305 | + |
1306 | +#include <unity-scopes.h> |
1307 | + |
1308 | +#include <iostream> |
1309 | + |
1310 | +#define EXPORT __attribute__ ((visibility ("default"))) |
1311 | + |
1312 | +using namespace std; |
1313 | +using namespace unity::scopes; |
1314 | + |
1315 | +// Example scope A: replies synchronously to a query. (Replies are returned before returning from the run() method.) |
1316 | + |
1317 | +class MyQuery : public SearchQueryBase |
1318 | +{ |
1319 | +public: |
1320 | + MyQuery(CannedQuery const& query, SearchMetadata const& metadata) : |
1321 | + SearchQueryBase(query, metadata), |
1322 | + query_(query.query_string()) |
1323 | + { |
1324 | + } |
1325 | + |
1326 | + ~MyQuery() noexcept |
1327 | + { |
1328 | + } |
1329 | + |
1330 | + virtual void cancelled() override |
1331 | + { |
1332 | + } |
1333 | + |
1334 | + virtual void run(SearchReplyProxy const& reply) override |
1335 | + { |
1336 | + CategoryRenderer minimal_rndr(R"({"schema-version": 1, "components": {"title": "title"}})"); |
1337 | + auto cat = reply->register_category("cat1", "Category 1", "", minimal_rndr); |
1338 | + CategorisedResult res(cat); |
1339 | + res.set_uri("test:uri"); |
1340 | + res.set_title("result for: \"" + query_ + "\""); |
1341 | + res.set_art("art"); |
1342 | + res.set_dnd_uri("test:dnd_uri"); |
1343 | + reply->push(res); |
1344 | + } |
1345 | + |
1346 | +private: |
1347 | + string query_; |
1348 | +}; |
1349 | + |
1350 | +class MyPreview : public PreviewQueryBase |
1351 | +{ |
1352 | +public: |
1353 | + MyPreview(Result const& result, ActionMetadata const& metadata) : |
1354 | + PreviewQueryBase(result, metadata), |
1355 | + scope_data_(metadata.scope_data()) |
1356 | + { |
1357 | + } |
1358 | + |
1359 | + ~MyPreview() noexcept |
1360 | + { |
1361 | + } |
1362 | + |
1363 | + virtual void cancelled() override |
1364 | + { |
1365 | + } |
1366 | + |
1367 | + virtual void run(PreviewReplyProxy const& reply) override |
1368 | + { |
1369 | + PreviewWidgetList widgets; |
1370 | + PreviewWidget w1(R"({"id": "hdr", "type": "header", "components": {"title": "title", "subtitle": "uri"}})"); |
1371 | + PreviewWidget w2(R"({"id": "img", "type": "image", "components": {"source": "art"}, "zoomable": false})"); |
1372 | + widgets.push_back(w1); |
1373 | + widgets.push_back(w2); |
1374 | + reply->push(widgets); |
1375 | + } |
1376 | + |
1377 | +private: |
1378 | + Variant scope_data_; |
1379 | +}; |
1380 | + |
1381 | +class MyScope : public ScopeBase |
1382 | +{ |
1383 | +public: |
1384 | + virtual SearchQueryBase::UPtr search(CannedQuery const& q, SearchMetadata const& metadata) override |
1385 | + { |
1386 | + SearchQueryBase::UPtr query(new MyQuery(q, metadata)); |
1387 | + cout << "scope-A: created query: \"" << q.query_string() << "\"" << endl; |
1388 | + return query; |
1389 | + } |
1390 | + |
1391 | + virtual PreviewQueryBase::UPtr preview(Result const& result, ActionMetadata const& metadata) override |
1392 | + { |
1393 | + PreviewQueryBase::UPtr query(new MyPreview(result, metadata)); |
1394 | + cout << "scope-A: created preview query: \"" << result.uri() << "\"" << endl; |
1395 | + return query; |
1396 | + } |
1397 | +}; |
1398 | + |
1399 | +extern "C" |
1400 | +{ |
1401 | + |
1402 | + EXPORT |
1403 | + unity::scopes::ScopeBase* |
1404 | + // cppcheck-suppress unusedFunction |
1405 | + UNITY_SCOPE_CREATE_FUNCTION() |
1406 | + { |
1407 | + return new MyScope; |
1408 | + } |
1409 | + |
1410 | + EXPORT |
1411 | + void |
1412 | + // cppcheck-suppress unusedFunction |
1413 | + UNITY_SCOPE_DESTROY_FUNCTION(unity::scopes::ScopeBase* scope_base) |
1414 | + { |
1415 | + delete scope_base; |
1416 | + } |
1417 | + |
1418 | +} |
1419 | |
1420 | === added file 'tests/data/scopes/scopes.ini.in' |
1421 | --- tests/data/scopes/scopes.ini.in 1970-01-01 00:00:00 +0000 |
1422 | +++ tests/data/scopes/scopes.ini.in 2014-07-31 13:04:48 +0000 |
1423 | @@ -0,0 +1,8 @@ |
1424 | +[ScopeConfig] |
1425 | +DisplayName = mock.scopes.DisplayName |
1426 | +Description = mock.scopes.Description |
1427 | +Art = /mock.Art |
1428 | +Icon = /mock.Icon |
1429 | +SearchHint = mock.SearchHint |
1430 | +HotKey = mock.HotKey |
1431 | +Author = mock.Author |
1432 | |
1433 | === added file 'tests/overviewtest.cpp' |
1434 | --- tests/overviewtest.cpp 1970-01-01 00:00:00 +0000 |
1435 | +++ tests/overviewtest.cpp 2014-07-31 13:04:48 +0000 |
1436 | @@ -0,0 +1,148 @@ |
1437 | +/* |
1438 | + * Copyright (C) 2013-2014 Canonical, Ltd. |
1439 | + * |
1440 | + * This program is free software; you can redistribute it and/or modify |
1441 | + * it under the terms of the GNU General Public License as published by |
1442 | + * the Free Software Foundation; version 3. |
1443 | + * |
1444 | + * This program is distributed in the hope that it will be useful, |
1445 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1446 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1447 | + * GNU General Public License for more details. |
1448 | + * |
1449 | + * You should have received a copy of the GNU General Public License |
1450 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1451 | + * |
1452 | + * Authors: |
1453 | + * Michal Hruby <michal.hruby@canonical.com> |
1454 | + */ |
1455 | + |
1456 | +#include <QObject> |
1457 | +#include <QTest> |
1458 | +#include <QJsonValue> |
1459 | +#include <QJsonObject> |
1460 | +#include <QThread> |
1461 | +#include <QScopedPointer> |
1462 | +#include <QSignalSpy> |
1463 | +#include <QVariantList> |
1464 | + |
1465 | +#include <scopes.h> |
1466 | +#include <scope.h> |
1467 | +#include <categories.h> |
1468 | +#include <overviewresults.h> |
1469 | +#include <previewmodel.h> |
1470 | +#include <previewstack.h> |
1471 | +#include <previewwidgetmodel.h> |
1472 | + |
1473 | +#include "registry-spawner.h" |
1474 | +#include "test-utils.h" |
1475 | + |
1476 | +using namespace scopes_ng; |
1477 | + |
1478 | +class OverviewTest : public QObject |
1479 | +{ |
1480 | + Q_OBJECT |
1481 | +private: |
1482 | + QScopedPointer<Scopes> m_scopes; |
1483 | + Scope* m_scope; |
1484 | + QScopedPointer<RegistrySpawner> m_registry; |
1485 | + |
1486 | +private Q_SLOTS: |
1487 | + void initTestCase() |
1488 | + { |
1489 | + m_registry.reset(new RegistrySpawner); |
1490 | + } |
1491 | + |
1492 | + void cleanupTestCase() |
1493 | + { |
1494 | + m_registry.reset(); |
1495 | + } |
1496 | + |
1497 | + void init() |
1498 | + { |
1499 | + m_scopes.reset(new Scopes(nullptr)); |
1500 | + // no scopes on startup |
1501 | + QCOMPARE(m_scopes->rowCount(), 0); |
1502 | + QCOMPARE(m_scopes->loaded(), false); |
1503 | + QSignalSpy spy(m_scopes.data(), SIGNAL(loadedChanged())); |
1504 | + // wait till the registry spawns |
1505 | + QVERIFY(spy.wait()); |
1506 | + QCOMPARE(m_scopes->loaded(), true); |
1507 | + |
1508 | + // get scope proxy |
1509 | + m_scope = qobject_cast<scopes_ng::Scope*>(m_scopes->overviewScope()); |
1510 | + QVERIFY(m_scope != nullptr); |
1511 | + m_scope->setActive(true); |
1512 | + } |
1513 | + |
1514 | + void cleanup() |
1515 | + { |
1516 | + m_scopes.reset(); |
1517 | + m_scope = nullptr; |
1518 | + } |
1519 | + |
1520 | + void testScopeProperties() |
1521 | + { |
1522 | + QCOMPARE(m_scope->id(), QString("scopes")); |
1523 | + QCOMPARE(m_scope->name(), QString("mock.scopes.DisplayName")); |
1524 | + QCOMPARE(m_scope->iconHint(), QString("/mock.Icon")); |
1525 | + QCOMPARE(m_scope->description(), QString("mock.scopes.Description")); |
1526 | + QCOMPARE(m_scope->searchHint(), QString("mock.SearchHint")); |
1527 | + QCOMPARE(m_scope->shortcut(), QString("mock.HotKey")); |
1528 | + QCOMPARE(m_scope->searchQuery(), QString()); |
1529 | + |
1530 | + QCOMPARE(m_scope->isActive(), true); |
1531 | + m_scope->setActive(false); |
1532 | + QCOMPARE(m_scope->isActive(), false); |
1533 | + } |
1534 | + |
1535 | + void testSurfacingQuery() |
1536 | + { |
1537 | + performSearch(m_scope, QString("")); |
1538 | + |
1539 | + // ensure categories have > 0 rows |
1540 | + auto categories = m_scope->categories(); |
1541 | + QVERIFY(categories->rowCount() > 0); |
1542 | + QCOMPARE(categories->data(categories->index(0), Categories::Roles::RoleCategoryId), QVariant(QString("favorites"))); |
1543 | + QCOMPARE(categories->data(categories->index(1), Categories::Roles::RoleCategoryId), QVariant(QString("all"))); |
1544 | + |
1545 | + QVariant results_var = categories->data(categories->index(0), Categories::Roles::RoleResults); |
1546 | + QVERIFY(results_var.canConvert<OverviewResultsModel*>()); |
1547 | + OverviewResultsModel* results = results_var.value<OverviewResultsModel*>(); |
1548 | + QVERIFY(results->rowCount() > 0); |
1549 | + } |
1550 | + |
1551 | + void testPreview() |
1552 | + { |
1553 | + performSearch(m_scope, QString("")); |
1554 | + |
1555 | + // get a result from the model |
1556 | + auto categories = m_scope->categories(); |
1557 | + QVERIFY(categories->rowCount() > 0); |
1558 | + QVariant results_var = categories->data(categories->index(0), Categories::Roles::RoleResults); |
1559 | + QVERIFY(results_var.canConvert<OverviewResultsModel*>()); |
1560 | + OverviewResultsModel* results = results_var.value<OverviewResultsModel*>(); |
1561 | + auto result_var = results->data(results->index(0), ResultsModel::RoleResult); |
1562 | + QCOMPARE(result_var.isNull(), false); |
1563 | + auto result = result_var.value<std::shared_ptr<unity::scopes::Result>>(); |
1564 | + QVERIFY(result != nullptr); |
1565 | + |
1566 | + // and try to preview it |
1567 | + QScopedPointer<PreviewStack> preview_stack(static_cast<PreviewStack*>(m_scope->preview(QVariant::fromValue(result)))); |
1568 | + QCOMPARE(preview_stack->rowCount(), 1); |
1569 | + QCOMPARE(preview_stack->widgetColumnCount(), 1); |
1570 | + auto preview_var = preview_stack->data(preview_stack->index(0), PreviewStack::RolePreviewModel); |
1571 | + auto preview_model = preview_stack->getPreviewModel(0); |
1572 | + QCOMPARE(preview_model, preview_var.value<scopes_ng::PreviewModel*>()); |
1573 | + QCOMPARE(preview_model->widgetColumnCount(), 1); |
1574 | + QTRY_COMPARE(preview_model->loaded(), true); |
1575 | + |
1576 | + auto preview_widgets = preview_model->data(preview_model->index(0), PreviewModel::RoleColumnModel).value<scopes_ng::PreviewWidgetModel*>(); |
1577 | + QVERIFY(!preview_widgets->roleNames().isEmpty()); |
1578 | + QCOMPARE(preview_widgets->rowCount(), 2); |
1579 | + } |
1580 | + |
1581 | +}; |
1582 | + |
1583 | +QTEST_GUILESS_MAIN(OverviewTest) |
1584 | +#include <overviewtest.moc> |
1585 | |
1586 | === modified file 'tests/previewtest.cpp' |
1587 | --- tests/previewtest.cpp 2014-07-18 16:35:52 +0000 |
1588 | +++ tests/previewtest.cpp 2014-07-31 13:04:48 +0000 |
1589 | @@ -66,8 +66,8 @@ |
1590 | // wait till the registry spawns |
1591 | QVERIFY(spy.wait()); |
1592 | QCOMPARE(m_scopes->loaded(), true); |
1593 | - // should have one scope now |
1594 | - QCOMPARE(m_scopes->rowCount(), 3); |
1595 | + // should have at least one scope now |
1596 | + QCOMPARE(m_scopes->rowCount(), 4); |
1597 | |
1598 | QVariant scope_var = m_scopes->data(m_scopes->index(0), Scopes::Roles::RoleScope); |
1599 | QVERIFY(scope_var.canConvert<Scope*>()); |
1600 | |
1601 | === modified file 'tests/resultstest.cpp' |
1602 | --- tests/resultstest.cpp 2014-07-18 16:35:52 +0000 |
1603 | +++ tests/resultstest.cpp 2014-07-31 13:04:48 +0000 |
1604 | @@ -111,8 +111,8 @@ |
1605 | // wait till the registry spawns |
1606 | QVERIFY(spy.wait()); |
1607 | QCOMPARE(m_scopes->loaded(), true); |
1608 | - // should have one scope now |
1609 | - QCOMPARE(m_scopes->rowCount(), 3); |
1610 | + // should have at least one scope now |
1611 | + QCOMPARE(m_scopes->rowCount(), 4); |
1612 | |
1613 | // get scope proxy |
1614 | m_scope = qobject_cast<scopes_ng::Scope*>(m_scopes->getScope(QString("mock-scope"))); |
1615 | @@ -192,6 +192,15 @@ |
1616 | QCOMPARE(m_scope->isActive(), true); |
1617 | m_scope->setActive(false); |
1618 | QCOMPARE(m_scope->isActive(), false); |
1619 | + |
1620 | + QCOMPARE(m_scope_ttl->id(), QString("mock-scope-ttl")); |
1621 | + QCOMPARE(m_scope_ttl->name(), QString("mock-ttl.DisplayName")); |
1622 | + QCOMPARE(m_scope_ttl->iconHint(), QString("/mock-ttl.Icon")); |
1623 | + QCOMPARE(m_scope_ttl->description(), QString("mock-ttl.Description")); |
1624 | + QCOMPARE(m_scope_ttl->searchHint(), QString()); |
1625 | + QCOMPARE(m_scope_ttl->shortcut(), QString()); |
1626 | + QCOMPARE(m_scope_ttl->visible(), true); |
1627 | + QCOMPARE(m_scope_ttl->searchQuery(), QString()); |
1628 | } |
1629 | |
1630 | void testCategoryQuery() |
1631 | @@ -649,13 +658,14 @@ |
1632 | unity::scopes::Result::SPtr result; |
1633 | QVERIFY(getFirstResult(m_scope, result)); |
1634 | |
1635 | - QSignalSpy spy(m_scope, SIGNAL(gotoScope(QString))); |
1636 | + QSignalSpy spy(m_scope, SIGNAL(searchQueryChanged())); |
1637 | m_scope->activate(QVariant::fromValue(result)); |
1638 | // this is likely to be invoked synchronously |
1639 | if (spy.count() == 0) { |
1640 | QVERIFY(spy.wait()); |
1641 | } |
1642 | QVERIFY(spy.count() > 0); |
1643 | + QCOMPARE(m_scope->searchQuery(), QString("next-scope-query")); |
1644 | } |
1645 | |
1646 | }; |
1647 | |
1648 | === modified file 'tests/test-utils.h' |
1649 | --- tests/test-utils.h 2014-05-22 08:03:59 +0000 |
1650 | +++ tests/test-utils.h 2014-07-31 13:04:48 +0000 |
1651 | @@ -64,12 +64,14 @@ |
1652 | void performSearch(Scope* scope, QString const& searchString) |
1653 | { |
1654 | QCOMPARE(scope->searchInProgress(), false); |
1655 | + QSignalSpy spy(scope, SIGNAL(searchInProgressChanged())); |
1656 | // perform a search |
1657 | scope->setSearchQuery(searchString); |
1658 | - QCOMPARE(scope->searchInProgress(), true); |
1659 | - // wait for the search to finish |
1660 | - QSignalSpy spy(scope, SIGNAL(searchInProgressChanged())); |
1661 | - QVERIFY(spy.wait()); |
1662 | + QVERIFY(scope->searchInProgress() || spy.count() > 1); |
1663 | + if (scope->searchInProgress()) { |
1664 | + // wait for the search to finish |
1665 | + QVERIFY(spy.wait()); |
1666 | + } |
1667 | QCOMPARE(scope->searchInProgress(), false); |
1668 | } |
1669 |
FAILED: Continuous integration, rev:123 jenkins. qa.ubuntu. com/job/ unity-scopes- shell-ci/ 147/ jenkins. qa.ubuntu. com/job/ unity-scopes- shell-utopic- amd64-ci/ 44/console jenkins. qa.ubuntu. com/job/ unity-scopes- shell-utopic- armhf-ci/ 44/console jenkins. qa.ubuntu. com/job/ unity-scopes- shell-utopic- i386-ci/ 44/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity- scopes- shell-ci/ 147/rebuild
http://