Merge lp:~unity-team/unity-scopes-shell/sort-order into lp:unity-scopes-shell
- sort-order
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Pete Woods |
Approved revision: | 153 |
Merged at revision: | 123 |
Proposed branch: | lp:~unity-team/unity-scopes-shell/sort-order |
Merge into: | lp:unity-scopes-shell |
Diff against target: |
1749 lines (+780/-169) 24 files modified
debian/changelog (+6/-0) debian/control (+2/-3) src/Unity/CMakeLists.txt (+2/-2) src/Unity/collectors.cpp (+37/-3) src/Unity/collectors.h (+9/-5) src/Unity/department.cpp (+28/-13) src/Unity/department.h (+12/-6) src/Unity/departmentnode.cpp (+57/-1) src/Unity/departmentnode.h (+8/-0) src/Unity/overviewscope.cpp (+0/-5) src/Unity/overviewscope.h (+0/-1) src/Unity/plugin.cpp (+1/-1) src/Unity/scope.cpp (+231/-80) src/Unity/scope.h (+27/-8) src/Unity/scopes.cpp (+6/-2) src/Unity/scopes.h (+1/-0) tests/data/CMakeLists.txt (+1/-0) tests/data/mock-scope-double-nav/CMakeLists.txt (+16/-0) tests/data/mock-scope-double-nav/mock-scope-double-nav.cpp (+214/-0) tests/data/mock-scope-double-nav/mock-scope-double-nav.ini.in (+8/-0) tests/departmentstest.cpp (+106/-29) tests/previewtest.cpp (+3/-3) tests/resultstest.cpp (+3/-5) tests/settingsendtoendtest.cpp (+2/-2) |
To merge this branch: | bzr merge lp:~unity-team/unity-scopes-shell/sort-order |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Pete Woods (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Review via email: mp+229190@code.launchpad.net |
Commit message
Implemented alt navigation as per shell interface v4.
Description of the change
Implemented alt navigation as per shell interface v4.
PS Jenkins bot (ps-jenkins) wrote : | # |
- 145. By Michal Hruby
-
Drop support for impl-2 and 3, as the interfaces changed
- 146. By Michal Hruby
-
Compile with very latest unity-api
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:146
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 147. By Michal Hruby
-
Update for the latest interface
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:147
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 148. By Michal Hruby
-
Update tests
- 149. By Michal Hruby
-
Merge with drop-appid branch
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:149
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 150. By Michal Hruby
-
Implement refresh method
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:150
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 151. By Michal Hruby
-
Reset filter state on non-empty queries
- 152. By Michal Hruby
-
Merge trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:152
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Pete Woods (pete-woods) wrote : | # |
Conflicts with trunk
- 153. By Michal Hruby
-
Merge trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:153
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Pete Woods (pete-woods) : | # |
Michal Hruby (mhr3) : | # |
Pete Woods (pete-woods) : | # |
Preview Diff
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2014-08-05 16:42:48 +0000 |
3 | +++ debian/changelog 2014-08-06 08:35:31 +0000 |
4 | @@ -1,3 +1,9 @@ |
5 | +unity-scopes-shell (0.5.3-0ubuntu1) UNRELEASED; urgency=medium |
6 | + |
7 | + * Implemented shell interface version 4 |
8 | + |
9 | + -- Michal Hruby <michal.hruby@canonical.com> Fri, 01 Aug 2014 11:08:43 +0100 |
10 | + |
11 | unity-scopes-shell (0.5.2+14.10.20140805.1-0ubuntu1) utopic; urgency=low |
12 | |
13 | [ Pete Woods ] |
14 | |
15 | === modified file 'debian/control' |
16 | --- debian/control 2014-08-01 10:25:41 +0000 |
17 | +++ debian/control 2014-08-06 08:35:31 +0000 |
18 | @@ -3,7 +3,7 @@ |
19 | Section: libs |
20 | Build-Depends: cmake, |
21 | debhelper (>= 9), |
22 | - libunity-api-dev (>= 7.87), |
23 | + libunity-api-dev (>= 7.88), |
24 | libunity-scopes-dev (>= 0.6.0~), |
25 | libgsettings-qt-dev (>= 0.1), |
26 | libqtdbustest1-dev (>= 0.2), |
27 | @@ -34,8 +34,7 @@ |
28 | Provides: unity-scopes-impl, |
29 | unity-scopes-impl-0, |
30 | unity-scopes-impl-1, |
31 | - unity-scopes-impl-2, |
32 | - unity-scopes-impl-3, |
33 | + unity-scopes-impl-4, |
34 | Breaks: unity8-private (<< 7.84) |
35 | Replaces: unity8-private (<< 7.84) |
36 | Description: QML plugin for Scopes |
37 | |
38 | === modified file 'src/Unity/CMakeLists.txt' |
39 | --- src/Unity/CMakeLists.txt 2014-08-01 10:25:41 +0000 |
40 | +++ src/Unity/CMakeLists.txt 2014-08-06 08:35:31 +0000 |
41 | @@ -2,7 +2,7 @@ |
42 | include(Plugins) |
43 | |
44 | # Dependencies |
45 | -pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=3) |
46 | +pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=4) |
47 | pkg_check_modules(SCOPESLIB REQUIRED libunity-scopes>=0.6.0) |
48 | pkg_check_modules(GSETTINGSQT REQUIRED gsettings-qt) |
49 | pkg_check_modules(U1DB REQUIRED libu1db-qt5) |
50 | @@ -41,7 +41,7 @@ |
51 | # We need these headers here so moc runs and we get the moc-stuff |
52 | # compiled in, otherwise we miss some symbols |
53 | ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/CategoriesInterface.h |
54 | - ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/DepartmentInterface.h |
55 | + ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/NavigationInterface.h |
56 | ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewModelInterface.h |
57 | ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewStackInterface.h |
58 | ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewWidgetModelInterface.h |
59 | |
60 | === modified file 'src/Unity/collectors.cpp' |
61 | --- src/Unity/collectors.cpp 2014-08-01 10:34:32 +0000 |
62 | +++ src/Unity/collectors.cpp 2014-08-06 08:35:31 +0000 |
63 | @@ -93,7 +93,19 @@ |
64 | m_rootDepartment = department; |
65 | } |
66 | |
67 | - Status collect(QList<scopes::CategorisedResult::SPtr>& out_results, scopes::Department::SCPtr& out_rootDepartment) |
68 | + void setSortOrder(scopes::OptionSelectorFilter::SCPtr const& sortOrder) |
69 | + { |
70 | + QMutexLocker locker(&m_mutex); |
71 | + m_sortOrderFilter = sortOrder; |
72 | + } |
73 | + |
74 | + void setFilterState(scopes::FilterState const& state) |
75 | + { |
76 | + QMutexLocker locker(&m_mutex); |
77 | + m_filterState = state; |
78 | + } |
79 | + |
80 | + Status collect(QList<scopes::CategorisedResult::SPtr>& out_results, scopes::Department::SCPtr& out_rootDepartment, scopes::OptionSelectorFilter::SCPtr& out_sortOrder, scopes::FilterState& out_filterState) |
81 | { |
82 | Status status; |
83 | |
84 | @@ -106,12 +118,17 @@ |
85 | m_results.swap(out_results); |
86 | out_rootDepartment = m_rootDepartment; |
87 | |
88 | + out_sortOrder = m_sortOrderFilter; |
89 | + out_filterState = m_filterState; |
90 | + |
91 | return status; |
92 | } |
93 | |
94 | private: |
95 | QList<scopes::CategorisedResult::SPtr> m_results; |
96 | scopes::Department::SCPtr m_rootDepartment; |
97 | + scopes::OptionSelectorFilter::SCPtr m_sortOrderFilter; |
98 | + scopes::FilterState m_filterState; |
99 | }; |
100 | |
101 | class PreviewDataCollector: public CollectorBase |
102 | @@ -222,10 +239,10 @@ |
103 | return m_collector->msecsSinceStart(); |
104 | } |
105 | |
106 | -CollectorBase::Status PushEvent::collectSearchResults(QList<scopes::CategorisedResult::SPtr>& out_results, scopes::Department::SCPtr& rootDepartment) |
107 | +CollectorBase::Status PushEvent::collectSearchResults(QList<scopes::CategorisedResult::SPtr>& out_results, scopes::Department::SCPtr& rootDepartment, scopes::OptionSelectorFilter::SCPtr& sortOrder, scopes::FilterState& filterState) |
108 | { |
109 | auto collector = std::dynamic_pointer_cast<SearchDataCollector>(m_collector); |
110 | - return collector->collect(out_results, rootDepartment); |
111 | + return collector->collect(out_results, rootDepartment, sortOrder, filterState); |
112 | } |
113 | |
114 | CollectorBase::Status PushEvent::collectPreviewData(scopes::ColumnLayoutList& out_columns, scopes::PreviewWidgetList& out_widgets, QHash<QString, QVariant>& out_data) |
115 | @@ -287,6 +304,23 @@ |
116 | m_collector->setDepartment(department); |
117 | } |
118 | |
119 | +void SearchResultReceiver::push(scopes::Filters const& filters, scopes::FilterState const& state) |
120 | +{ |
121 | + for (auto it = filters.begin(); it != filters.end(); ++it) { |
122 | + scopes::FilterBase::SCPtr filter = *it; |
123 | + if (filter->display_hints() == scopes::FilterBase::DisplayHints::Primary) { |
124 | + scopes::OptionSelectorFilter::SCPtr option_filter = std::dynamic_pointer_cast<const scopes::OptionSelectorFilter>(filter); |
125 | + if (!option_filter) { |
126 | + continue; |
127 | + } else { |
128 | + m_collector->setSortOrder(option_filter); |
129 | + break; |
130 | + } |
131 | + } |
132 | + } |
133 | + m_collector->setFilterState(state); |
134 | +} |
135 | + |
136 | // this might be called from any thread (might be main, might be any other thread) |
137 | void SearchResultReceiver::finished(scopes::CompletionDetails const& details) |
138 | { |
139 | |
140 | === modified file 'src/Unity/collectors.h' |
141 | --- src/Unity/collectors.h 2014-08-01 10:34:32 +0000 |
142 | +++ src/Unity/collectors.h 2014-08-06 08:35:31 +0000 |
143 | @@ -27,12 +27,15 @@ |
144 | #include <QElapsedTimer> |
145 | |
146 | #include <unity/scopes/ActivationListenerBase.h> |
147 | -#include <unity/scopes/SearchListenerBase.h> |
148 | +#include <unity/scopes/ActivationResponse.h> |
149 | +#include <unity/scopes/CategorisedResult.h> |
150 | +#include <unity/scopes/FilterBase.h> |
151 | +#include <unity/scopes/FilterState.h> |
152 | +#include <unity/scopes/OptionSelectorFilter.h> |
153 | #include <unity/scopes/PreviewListenerBase.h> |
154 | -#include <unity/scopes/CategorisedResult.h> |
155 | +#include <unity/scopes/PreviewWidget.h> |
156 | #include <unity/scopes/QueryCtrl.h> |
157 | -#include <unity/scopes/PreviewWidget.h> |
158 | -#include <unity/scopes/ActivationResponse.h> |
159 | +#include <unity/scopes/SearchListenerBase.h> |
160 | |
161 | namespace scopes_ng |
162 | { |
163 | @@ -73,7 +76,7 @@ |
164 | PushEvent(Type event_type, std::shared_ptr<CollectorBase> collector); |
165 | Type type(); |
166 | |
167 | - CollectorBase::Status collectSearchResults(QList<std::shared_ptr<unity::scopes::CategorisedResult>>& out_results, unity::scopes::Department::SCPtr& out_rootDepartment); |
168 | + CollectorBase::Status collectSearchResults(QList<std::shared_ptr<unity::scopes::CategorisedResult>>& out_results, unity::scopes::Department::SCPtr& out_rootDepartment, unity::scopes::OptionSelectorFilter::SCPtr& out_sortOrder, unity::scopes::FilterState& out_filterState); |
169 | CollectorBase::Status collectPreviewData(unity::scopes::ColumnLayoutList& out_columns, unity::scopes::PreviewWidgetList& out_widgets, QHash<QString, QVariant>& out_data); |
170 | CollectorBase::Status collectActivationResponse(std::shared_ptr<unity::scopes::ActivationResponse>& out_response, std::shared_ptr<unity::scopes::Result>& out_result); |
171 | |
172 | @@ -105,6 +108,7 @@ |
173 | public: |
174 | virtual void push(unity::scopes::CategorisedResult result) override; |
175 | virtual void push(unity::scopes::Department::SCPtr const& department) override; |
176 | + virtual void push(unity::scopes::Filters const& filters, unity::scopes::FilterState const& state) override; |
177 | virtual void finished(unity::scopes::CompletionDetails const& details) override; |
178 | |
179 | SearchResultReceiver(QObject* receiver); |
180 | |
181 | === modified file 'src/Unity/department.cpp' |
182 | --- src/Unity/department.cpp 2014-06-12 11:34:44 +0000 |
183 | +++ src/Unity/department.cpp 2014-08-06 08:35:31 +0000 |
184 | @@ -19,16 +19,22 @@ |
185 | |
186 | #include "department.h" |
187 | |
188 | +#include <unity/scopes/OptionSelectorFilter.h> |
189 | + |
190 | namespace scopes_ng |
191 | { |
192 | |
193 | using namespace unity; |
194 | |
195 | Department::Department(QObject* parent) : |
196 | - unity::shell::scopes::DepartmentInterface(parent), |
197 | - m_loaded(false), |
198 | - m_isRoot(false) |
199 | -{ |
200 | + unity::shell::scopes::NavigationInterface(parent), |
201 | + m_loaded(false), m_isRoot(false), m_hidden(false), m_isFilter(false) |
202 | +{ |
203 | +} |
204 | + |
205 | +void Department::setScopeId(QString const& scopeId) |
206 | +{ |
207 | + m_scopeId = scopeId; |
208 | } |
209 | |
210 | void Department::loadFromDepartmentNode(DepartmentNode* treeNode) |
211 | @@ -37,14 +43,17 @@ |
212 | qWarning("Tried to set null DepartmentNode!"); |
213 | return; |
214 | } |
215 | - m_departmentId = treeNode->id(); |
216 | + m_navigationId = treeNode->id(); |
217 | + m_filterId = treeNode->filterId(); |
218 | m_label = treeNode->label(); |
219 | m_allLabel = treeNode->allLabel(); |
220 | m_loaded = !treeNode->isLeaf() && treeNode->childCount() > 0; |
221 | m_isRoot = treeNode->isRoot(); |
222 | + m_hidden = treeNode->hidden(); |
223 | + m_isFilter = treeNode->isFilter(); |
224 | |
225 | DepartmentNode* parentNode = treeNode->parent(); |
226 | - m_parentDepartmentId = parentNode ? parentNode->id() : ""; |
227 | + m_parentNavigationId = parentNode ? parentNode->id() : ""; |
228 | m_parentLabel = parentNode ? parentNode->label() : ""; |
229 | |
230 | beginResetModel(); |
231 | @@ -61,14 +70,15 @@ |
232 | |
233 | endResetModel(); |
234 | |
235 | - Q_EMIT departmentIdChanged(); |
236 | + Q_EMIT navigationIdChanged(); |
237 | Q_EMIT labelChanged(); |
238 | Q_EMIT allLabelChanged(); |
239 | - Q_EMIT parentDepartmentIdChanged(); |
240 | + Q_EMIT parentNavigationIdChanged(); |
241 | Q_EMIT parentLabelChanged(); |
242 | Q_EMIT loadedChanged(); |
243 | Q_EMIT countChanged(); |
244 | Q_EMIT isRootChanged(); |
245 | + Q_EMIT hiddenChanged(); |
246 | } |
247 | |
248 | void Department::markSubdepartmentActive(QString const& subdepartmentId) |
249 | @@ -100,7 +110,7 @@ |
250 | { |
251 | SubdepartmentData* data = m_subdepartments[index.row()].data(); |
252 | switch (role) { |
253 | - case RoleDepartmentId: return data->id; |
254 | + case RoleNavigationId: return data->id; |
255 | case RoleLabel: return data->label; |
256 | case RoleHasChildren: return data->hasChildren; |
257 | case RoleIsActive: return data->isActive; |
258 | @@ -114,9 +124,9 @@ |
259 | return m_subdepartments.size(); |
260 | } |
261 | |
262 | -QString Department::departmentId() const |
263 | +QString Department::navigationId() const |
264 | { |
265 | - return m_departmentId; |
266 | + return m_navigationId; |
267 | } |
268 | |
269 | QString Department::label() const |
270 | @@ -129,9 +139,9 @@ |
271 | return m_allLabel; |
272 | } |
273 | |
274 | -QString Department::parentDepartmentId() const |
275 | +QString Department::parentNavigationId() const |
276 | { |
277 | - return m_parentDepartmentId; |
278 | + return m_parentNavigationId; |
279 | } |
280 | |
281 | QString Department::parentLabel() const |
282 | @@ -149,6 +159,11 @@ |
283 | return m_isRoot; |
284 | } |
285 | |
286 | +bool Department::hidden() const |
287 | +{ |
288 | + return m_hidden; |
289 | +} |
290 | + |
291 | int Department::count() const |
292 | { |
293 | return rowCount(); |
294 | |
295 | === modified file 'src/Unity/department.h' |
296 | --- src/Unity/department.h 2014-06-12 11:34:44 +0000 |
297 | +++ src/Unity/department.h 2014-08-06 08:35:31 +0000 |
298 | @@ -21,7 +21,7 @@ |
299 | #ifndef NG_DEPARTMENT_H |
300 | #define NG_DEPARTMENT_H |
301 | |
302 | -#include <unity/shell/scopes/DepartmentInterface.h> |
303 | +#include <unity/shell/scopes/NavigationInterface.h> |
304 | |
305 | #include <QString> |
306 | #include <QSharedPointer> |
307 | @@ -44,37 +44,43 @@ |
308 | bool isActive; |
309 | }; |
310 | |
311 | -class Q_DECL_EXPORT Department : public unity::shell::scopes::DepartmentInterface |
312 | +class Q_DECL_EXPORT Department : public unity::shell::scopes::NavigationInterface |
313 | { |
314 | Q_OBJECT |
315 | |
316 | public: |
317 | explicit Department(QObject* parent = 0); |
318 | + void setScopeId(QString const& scopeId); |
319 | void loadFromDepartmentNode(DepartmentNode* treeNode); |
320 | void markSubdepartmentActive(QString const& subdepartmentId); |
321 | |
322 | QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; |
323 | int rowCount(const QModelIndex& parent = QModelIndex()) const override; |
324 | |
325 | - QString departmentId() const override; |
326 | + QString navigationId() const override; |
327 | QString label() const override; |
328 | QString allLabel() const override; |
329 | - QString parentDepartmentId() const override; |
330 | + QString parentNavigationId() const override; |
331 | QString parentLabel() const override; |
332 | bool loaded() const override; |
333 | bool isRoot() const override; |
334 | + bool hidden() const override; |
335 | int count() const override; |
336 | |
337 | Q_SIGNALS: |
338 | |
339 | private: |
340 | - QString m_departmentId; |
341 | + QString m_navigationId; |
342 | + QString m_scopeId; |
343 | + QString m_filterId; |
344 | QString m_label; |
345 | QString m_allLabel; |
346 | - QString m_parentDepartmentId; |
347 | + QString m_parentNavigationId; |
348 | QString m_parentLabel; |
349 | bool m_loaded; |
350 | bool m_isRoot; |
351 | + bool m_hidden; |
352 | + bool m_isFilter; |
353 | |
354 | QList<QSharedPointer<SubdepartmentData>> m_subdepartments; |
355 | }; |
356 | |
357 | === modified file 'src/Unity/departmentnode.cpp' |
358 | --- src/Unity/departmentnode.cpp 2014-05-28 07:04:50 +0000 |
359 | +++ src/Unity/departmentnode.cpp 2014-08-06 08:35:31 +0000 |
360 | @@ -24,7 +24,11 @@ |
361 | |
362 | using namespace unity; |
363 | |
364 | -DepartmentNode::DepartmentNode(DepartmentNode* parent) : m_parent(parent), m_isRoot(false) |
365 | +DepartmentNode::DepartmentNode(DepartmentNode* parent) |
366 | + : m_parent(parent) |
367 | + , m_isRoot(false) |
368 | + , m_hidden(false) |
369 | + , m_isFilter(false) |
370 | { |
371 | } |
372 | |
373 | @@ -39,6 +43,8 @@ |
374 | m_label = QString::fromStdString(dep->label()); |
375 | m_allLabel = QString::fromStdString(dep->alternate_label()); |
376 | m_hasSubdepartments = dep->has_subdepartments(); |
377 | + m_hidden = false; |
378 | + m_isFilter = false; |
379 | |
380 | clearChildren(); |
381 | |
382 | @@ -50,6 +56,41 @@ |
383 | } |
384 | } |
385 | |
386 | +void DepartmentNode::initializeForFilter(scopes::OptionSelectorFilter::SCPtr const& filter) |
387 | +{ |
388 | + auto children = filter->options(); |
389 | + m_id = QString(""); // this is root (which we shouldn't show really) |
390 | + m_filterId = QString::fromStdString(filter->id()); |
391 | + m_label = QString::fromStdString(filter->label()); |
392 | + m_allLabel = QString(); |
393 | + m_hasSubdepartments = !children.empty(); |
394 | + m_isRoot = true; |
395 | + m_hidden = true; |
396 | + m_isFilter = true; |
397 | + |
398 | + clearChildren(); |
399 | + |
400 | + for (auto it = children.begin(); it != children.end(); ++it) { |
401 | + DepartmentNode* subdep = new DepartmentNode(this); |
402 | + subdep->initializeForFilterOption(*it, m_filterId); |
403 | + this->appendChild(subdep); |
404 | + } |
405 | +} |
406 | + |
407 | +void DepartmentNode::initializeForFilterOption(scopes::FilterOption::SCPtr const& option, QString const& filterId) |
408 | +{ |
409 | + m_id = QString::fromStdString(option->id()); |
410 | + m_filterId = filterId; |
411 | + m_label = QString::fromStdString(option->label()); |
412 | + m_allLabel = QString(); |
413 | + m_hasSubdepartments = false; |
414 | + m_isRoot = false; |
415 | + m_hidden = false; |
416 | + m_isFilter = true; |
417 | + |
418 | + clearChildren(); |
419 | +} |
420 | + |
421 | void DepartmentNode::setIsRoot(bool isRoot) |
422 | { |
423 | m_isRoot = isRoot; |
424 | @@ -60,6 +101,16 @@ |
425 | return m_isRoot; |
426 | } |
427 | |
428 | +bool DepartmentNode::hidden() const |
429 | +{ |
430 | + return m_hidden; |
431 | +} |
432 | + |
433 | +bool DepartmentNode::isFilter() const |
434 | +{ |
435 | + return m_isFilter; |
436 | +} |
437 | + |
438 | DepartmentNode* DepartmentNode::findNodeById(QString const& id) |
439 | { |
440 | if (id == m_id) return this; |
441 | @@ -87,6 +138,11 @@ |
442 | return m_allLabel; |
443 | } |
444 | |
445 | +QString DepartmentNode::filterId() const |
446 | +{ |
447 | + return m_filterId; |
448 | +} |
449 | + |
450 | bool DepartmentNode::hasSubdepartments() const |
451 | { |
452 | return m_hasSubdepartments; |
453 | |
454 | === modified file 'src/Unity/departmentnode.h' |
455 | --- src/Unity/departmentnode.h 2014-05-28 07:04:50 +0000 |
456 | +++ src/Unity/departmentnode.h 2014-08-06 08:35:31 +0000 |
457 | @@ -38,6 +38,7 @@ |
458 | ~DepartmentNode(); |
459 | |
460 | void initializeForDepartment(unity::scopes::Department::SCPtr const& dep); |
461 | + void initializeForFilter(unity::scopes::OptionSelectorFilter::SCPtr const& filter); |
462 | DepartmentNode* findNodeById(QString const& id); |
463 | |
464 | QString id() const; |
465 | @@ -45,6 +46,8 @@ |
466 | QString allLabel() const; |
467 | bool hasSubdepartments() const; |
468 | bool isRoot() const; |
469 | + bool hidden() const; |
470 | + bool isFilter() const; |
471 | |
472 | void setIsRoot(bool isRoot); |
473 | |
474 | @@ -53,17 +56,22 @@ |
475 | bool isLeaf() const; |
476 | QList<DepartmentNode*> childNodes() const; |
477 | DepartmentNode* parent() const; |
478 | + QString filterId() const; |
479 | |
480 | private: |
481 | void clearChildren(); |
482 | + void initializeForFilterOption(unity::scopes::FilterOption::SCPtr const&, QString const&); |
483 | |
484 | DepartmentNode* m_parent; |
485 | QList<DepartmentNode*> m_children; |
486 | QString m_id; |
487 | QString m_label; |
488 | QString m_allLabel; |
489 | + QString m_filterId; |
490 | bool m_hasSubdepartments; |
491 | bool m_isRoot; |
492 | + bool m_hidden; |
493 | + bool m_isFilter; |
494 | }; |
495 | |
496 | } // namespace scopes_ng |
497 | |
498 | === modified file 'src/Unity/overviewscope.cpp' |
499 | --- src/Unity/overviewscope.cpp 2014-07-23 12:32:48 +0000 |
500 | +++ src/Unity/overviewscope.cpp 2014-08-06 08:35:31 +0000 |
501 | @@ -96,11 +96,6 @@ |
502 | return QString("scopes"); |
503 | } |
504 | |
505 | -bool OverviewScope::visible() const |
506 | -{ |
507 | - return false; |
508 | -} |
509 | - |
510 | scopes::ScopeProxy OverviewScope::proxy_for_result(scopes::Result::SPtr const& result) const |
511 | { |
512 | try { |
513 | |
514 | === modified file 'src/Unity/overviewscope.h' |
515 | --- src/Unity/overviewscope.h 2014-07-18 17:10:39 +0000 |
516 | +++ src/Unity/overviewscope.h 2014-08-06 08:35:31 +0000 |
517 | @@ -35,7 +35,6 @@ |
518 | |
519 | /* getters */ |
520 | QString id() const override; |
521 | - bool visible() const override; |
522 | |
523 | void dispatchSearch() override; |
524 | |
525 | |
526 | === modified file 'src/Unity/plugin.cpp' |
527 | --- src/Unity/plugin.cpp 2014-06-11 17:08:34 +0000 |
528 | +++ src/Unity/plugin.cpp 2014-08-06 08:35:31 +0000 |
529 | @@ -41,7 +41,7 @@ |
530 | // new Scopes classes |
531 | qmlRegisterType<scopes_ng::Scopes>(uri, 0, 2, "Scopes"); |
532 | qmlRegisterUncreatableType<unity::shell::scopes::ScopeInterface>(uri, 0, 2, "Scope", "Can't create Scope object in QML. Get them from Scopes instance."); |
533 | - qmlRegisterUncreatableType<unity::shell::scopes::DepartmentInterface>(uri, 0, 2, "Department", "Can't create Department object in QML. Get them from Scope instance."); |
534 | + qmlRegisterUncreatableType<unity::shell::scopes::NavigationInterface>(uri, 0, 2, "Navigation", "Can't create Navigation object in QML. Get them from Scope instance."); |
535 | qmlRegisterUncreatableType<unity::shell::scopes::CategoriesInterface>(uri, 0, 2, "Categories", "Can't create Categories object in QML. Get them from Scope instance."); |
536 | qmlRegisterUncreatableType<unity::shell::scopes::SettingsModelInterface>(uri, 0, 2, "Settings", "Can't create Settings object in QML. Get them from Scope instance."); |
537 | qmlRegisterUncreatableType<scopes_ng::ResultsModel>(uri, 0, 2, "ResultsModel", "Can't create new ResultsModel in QML. Get them from Categories instance."); |
538 | |
539 | === modified file 'src/Unity/scope.cpp' |
540 | --- src/Unity/scope.cpp 2014-08-05 16:24:32 +0000 |
541 | +++ src/Unity/scope.cpp 2014-08-06 08:35:31 +0000 |
542 | @@ -47,6 +47,8 @@ |
543 | #include <libintl.h> |
544 | |
545 | #include <unity/scopes/ListenerBase.h> |
546 | +#include <unity/scopes/CannedQuery.h> |
547 | +#include <unity/scopes/OptionSelectorFilter.h> |
548 | #include <unity/scopes/CategorisedResult.h> |
549 | #include <unity/scopes/QueryCtrl.h> |
550 | #include <unity/scopes/PreviewWidget.h> |
551 | @@ -70,9 +72,11 @@ |
552 | , m_searchInProgress(false) |
553 | , m_resultsDirty(false) |
554 | , m_delayedClear(false) |
555 | - , m_hasDepartments(false) |
556 | + , m_hasNavigation(false) |
557 | + , m_hasAltNavigation(false) |
558 | , m_searchController(new CollectionController) |
559 | , m_activationController(new CollectionController) |
560 | + , m_status(Status::Okay) |
561 | { |
562 | m_categories.reset(new Categories(this)); |
563 | |
564 | @@ -99,13 +103,17 @@ |
565 | CollectorBase::Status status; |
566 | QList<std::shared_ptr<scopes::CategorisedResult>> results; |
567 | scopes::Department::SCPtr rootDepartment; |
568 | + scopes::OptionSelectorFilter::SCPtr sortOrderFilter; |
569 | + scopes::FilterState filterState; |
570 | |
571 | - status = pushEvent->collectSearchResults(results, rootDepartment); |
572 | + status = pushEvent->collectSearchResults(results, rootDepartment, sortOrderFilter, filterState); |
573 | if (status == CollectorBase::Status::CANCELLED) { |
574 | return; |
575 | } |
576 | |
577 | m_rootDepartment = rootDepartment; |
578 | + m_sortOrderFilter = sortOrderFilter; |
579 | + m_receivedFilterState = filterState; |
580 | |
581 | if (m_cachedResults.empty()) { |
582 | m_cachedResults.swap(results); |
583 | @@ -126,6 +134,7 @@ |
584 | flushUpdates(); |
585 | |
586 | setSearchInProgress(false); |
587 | + setStatus(status == CollectorBase::Status::FINISHED ? Status::Okay : Status::Unknown); |
588 | |
589 | // Don't schedule a refresh if the query suffered an error |
590 | if (status == CollectorBase::Status::FINISHED) { |
591 | @@ -226,9 +235,13 @@ |
592 | } |
593 | |
594 | if (scope != nullptr) { |
595 | - // TODO: change filters? |
596 | - scope->setCurrentDepartmentId(departmentId); |
597 | + scope->setCurrentNavigationId(departmentId); |
598 | + scope->setFilterState(query.filter_state()); |
599 | scope->setSearchQuery(searchString); |
600 | + // FIXME: implement better way to do multiple changes to search props and dispatch single search |
601 | + if (!scope->searchInProgress()) { |
602 | + scope->invalidateResults(); |
603 | + } |
604 | if (scope != this) Q_EMIT gotoScope(scopeId); |
605 | } else { |
606 | // create temp dash page |
607 | @@ -237,7 +250,8 @@ |
608 | scope = new scopes_ng::Scope(this); |
609 | scope->setScopeData(*meta_sptr); |
610 | scope->setScopesInstance(m_scopesInstance); |
611 | - scope->setCurrentDepartmentId(departmentId); |
612 | + scope->setCurrentNavigationId(departmentId); |
613 | + scope->setFilterState(query.filter_state()); |
614 | scope->setSearchQuery(searchString); |
615 | m_tempScopes.insert(scope); |
616 | Q_EMIT openScope(scope); |
617 | @@ -263,6 +277,9 @@ |
618 | m_clearTimer.stop(); |
619 | } |
620 | |
621 | + if (m_status != Status::Okay) { |
622 | + setStatus(Status::Okay); |
623 | + } |
624 | processResultSet(m_cachedResults); // clears the result list |
625 | |
626 | // process departments |
627 | @@ -289,25 +306,7 @@ |
628 | m_departmentTree->setIsRoot(true); |
629 | |
630 | // update corresponding models |
631 | - QString activeDepartment(m_currentDepartmentId); |
632 | - node = m_departmentTree->findNodeById(activeDepartment); |
633 | - DepartmentNode* parentNode = nullptr; |
634 | - if (node != nullptr) { |
635 | - auto it = m_departmentModels.find(activeDepartment); |
636 | - while (it != m_departmentModels.end() && it.key() == activeDepartment) { |
637 | - it.value()->loadFromDepartmentNode(node); |
638 | - ++it; |
639 | - } |
640 | - // if this node is a leaf, we need to update models for the parent |
641 | - parentNode = node->isLeaf() ? node->parent() : nullptr; |
642 | - } |
643 | - if (parentNode != nullptr) { |
644 | - auto it = m_departmentModels.find(parentNode->id()); |
645 | - while (it != m_departmentModels.end() && it.key() == parentNode->id()) { |
646 | - it.value()->markSubdepartmentActive(activeDepartment); |
647 | - ++it; |
648 | - } |
649 | - } |
650 | + updateNavigationModels(m_departmentTree.data(), m_departmentModels, m_currentNavigationId); |
651 | } else { |
652 | m_departmentTree.reset(new DepartmentNode); |
653 | m_departmentTree->initializeForDepartment(m_rootDepartment); |
654 | @@ -320,17 +319,80 @@ |
655 | m_lastRootDepartment = m_rootDepartment; |
656 | |
657 | bool containsDepartments = m_rootDepartment.get() != nullptr; |
658 | - // design decision - no departments when doing searches |
659 | + // design decision - no navigation when doing searches |
660 | containsDepartments &= m_searchQuery.isEmpty(); |
661 | |
662 | - if (containsDepartments != m_hasDepartments) { |
663 | - m_hasDepartments = containsDepartments; |
664 | - Q_EMIT hasDepartmentsChanged(); |
665 | - } |
666 | - |
667 | - if (!containsDepartments && !m_currentDepartmentId.isEmpty()) { |
668 | - m_currentDepartmentId = ""; |
669 | - Q_EMIT currentDepartmentIdChanged(); |
670 | + if (containsDepartments != m_hasNavigation) { |
671 | + m_hasNavigation = containsDepartments; |
672 | + Q_EMIT hasNavigationChanged(); |
673 | + } |
674 | + |
675 | + if (!containsDepartments && !m_currentNavigationId.isEmpty()) { |
676 | + m_currentNavigationId = ""; |
677 | + Q_EMIT currentNavigationIdChanged(); |
678 | + } |
679 | + |
680 | + // process the alt navigation (sort order filter) |
681 | + QString currentAltNav(m_currentAltNavigationId); |
682 | + |
683 | + if (m_sortOrderFilter && m_sortOrderFilter != m_lastSortOrderFilter) { |
684 | + // build the nodes |
685 | + m_altNavTree.reset(new DepartmentNode); |
686 | + m_altNavTree->initializeForFilter(m_sortOrderFilter); |
687 | + |
688 | + if (m_sortOrderFilter->has_active_option(m_receivedFilterState)) { |
689 | + auto active_options = m_sortOrderFilter->active_options(m_receivedFilterState); |
690 | + scopes::FilterOption::SCPtr active_option = *active_options.begin(); |
691 | + if (active_option) { |
692 | + currentAltNav = QString::fromStdString(active_option->id()); |
693 | + } |
694 | + } |
695 | + } |
696 | + |
697 | + m_lastSortOrderFilter = m_sortOrderFilter; |
698 | + |
699 | + bool containsAltNav = m_sortOrderFilter.get() != nullptr; |
700 | + // design decision - no navigation when doing searches |
701 | + containsAltNav &= m_searchQuery.isEmpty(); |
702 | + |
703 | + if (containsAltNav != m_hasAltNavigation) { |
704 | + m_hasAltNavigation = containsAltNav; |
705 | + Q_EMIT hasAltNavigationChanged(); |
706 | + } |
707 | + |
708 | + if (!containsAltNav && !m_currentAltNavigationId.isEmpty()) { |
709 | + m_currentAltNavigationId = ""; |
710 | + Q_EMIT currentAltNavigationIdChanged(); |
711 | + } |
712 | + |
713 | + if (containsAltNav && currentAltNav != m_currentAltNavigationId) { |
714 | + m_currentAltNavigationId = currentAltNav; |
715 | + Q_EMIT currentAltNavigationIdChanged(); |
716 | + |
717 | + // update the alt navigation models |
718 | + updateNavigationModels(m_altNavTree.data(), m_altNavModels, m_currentAltNavigationId); |
719 | + } |
720 | +} |
721 | + |
722 | +void Scope::updateNavigationModels(DepartmentNode* rootNode, QMultiMap<QString, Department*>& navigationModels, QString const& activeNavigation) |
723 | +{ |
724 | + DepartmentNode* parentNode = nullptr; |
725 | + DepartmentNode* node = rootNode->findNodeById(activeNavigation); |
726 | + if (node != nullptr) { |
727 | + auto it = navigationModels.find(activeNavigation); |
728 | + while (it != navigationModels.end() && it.key() == activeNavigation) { |
729 | + it.value()->loadFromDepartmentNode(node); |
730 | + ++it; |
731 | + } |
732 | + // if this node is a leaf, we need to update models for the parent |
733 | + parentNode = node->isLeaf() ? node->parent() : nullptr; |
734 | + } |
735 | + if (parentNode != nullptr) { |
736 | + auto it = navigationModels.find(parentNode->id()); |
737 | + while (it != navigationModels.end() && it.key() == parentNode->id()) { |
738 | + it.value()->markSubdepartmentActive(activeNavigation); |
739 | + ++it; |
740 | + } |
741 | } |
742 | } |
743 | |
744 | @@ -494,12 +556,25 @@ |
745 | } |
746 | } |
747 | |
748 | -void Scope::setCurrentDepartmentId(QString const& id) |
749 | -{ |
750 | - if (m_currentDepartmentId != id) { |
751 | - m_currentDepartmentId = id; |
752 | - Q_EMIT currentDepartmentIdChanged(); |
753 | - } |
754 | +void Scope::setStatus(shell::scopes::ScopeInterface::Status status) |
755 | +{ |
756 | + if (m_status != status) { |
757 | + m_status = status; |
758 | + Q_EMIT statusChanged(); |
759 | + } |
760 | +} |
761 | + |
762 | +void Scope::setCurrentNavigationId(QString const& id) |
763 | +{ |
764 | + if (m_currentNavigationId != id) { |
765 | + m_currentNavigationId = id; |
766 | + Q_EMIT currentNavigationIdChanged(); |
767 | + } |
768 | +} |
769 | + |
770 | +void Scope::setFilterState(scopes::FilterState const& filterState) |
771 | +{ |
772 | + m_filterState = filterState; |
773 | } |
774 | |
775 | void Scope::dispatchSearch() |
776 | @@ -554,7 +629,7 @@ |
777 | scopes::SearchListenerBase::SPtr listener(new SearchResultReceiver(this)); |
778 | m_searchController->setListener(listener); |
779 | try { |
780 | - scopes::QueryCtrlProxy controller = m_proxy->search(m_searchQuery.toStdString(), m_currentDepartmentId.toStdString(), scopes::FilterState(), meta, listener); |
781 | + scopes::QueryCtrlProxy controller = m_proxy->search(m_searchQuery.toStdString(), m_currentNavigationId.toStdString(), m_filterState, meta, listener); |
782 | m_searchController->setController(controller); |
783 | } catch (std::exception& e) { |
784 | qWarning("Caught an error from create_query(): %s", e.what()); |
785 | @@ -652,9 +727,13 @@ |
786 | return m_searchInProgress; |
787 | } |
788 | |
789 | -bool Scope::visible() const |
790 | -{ |
791 | - // FIXME: get from scope config |
792 | +unity::shell::scopes::ScopeInterface::Status Scope::status() const |
793 | +{ |
794 | + return m_status; |
795 | +} |
796 | + |
797 | +bool Scope::favorite() const |
798 | +{ |
799 | return true; |
800 | } |
801 | |
802 | @@ -689,42 +768,86 @@ |
803 | } |
804 | */ |
805 | |
806 | -unity::shell::scopes::DepartmentInterface* Scope::getDepartment(QString const& departmentId) |
807 | +unity::shell::scopes::NavigationInterface* Scope::getNavigation(QString const& navId) |
808 | { |
809 | if (!m_departmentTree) return nullptr; |
810 | |
811 | - DepartmentNode* node = m_departmentTree->findNodeById(departmentId); |
812 | - if (!node) return nullptr; |
813 | - |
814 | - Department* departmentModel = new Department; |
815 | - departmentModel->loadFromDepartmentNode(node); |
816 | - |
817 | - m_departmentModels.insert(departmentId, departmentModel); |
818 | - m_inverseDepartments.insert(departmentModel, departmentId); |
819 | - QObject::connect(departmentModel, &QObject::destroyed, this, &Scope::departmentModelDestroyed); |
820 | - |
821 | - return departmentModel; |
822 | + DepartmentNode* node = m_departmentTree->findNodeById(navId); |
823 | + if (!node) return nullptr; |
824 | + |
825 | + Department* navModel = new Department; |
826 | + navModel->setScopeId(this->id()); |
827 | + navModel->loadFromDepartmentNode(node); |
828 | + navModel->markSubdepartmentActive(m_currentNavigationId); |
829 | + |
830 | + // sharing m_inverseDepartments with getAltNavigation |
831 | + m_departmentModels.insert(navId, navModel); |
832 | + m_inverseDepartments.insert(navModel, navId); |
833 | + QObject::connect(navModel, &QObject::destroyed, this, &Scope::departmentModelDestroyed); |
834 | + |
835 | + return navModel; |
836 | +} |
837 | + |
838 | +unity::shell::scopes::NavigationInterface* Scope::getAltNavigation(QString const& navId) |
839 | +{ |
840 | + if (!m_altNavTree) return nullptr; |
841 | + |
842 | + DepartmentNode* node = m_altNavTree->findNodeById(navId); |
843 | + if (!node) return nullptr; |
844 | + |
845 | + Department* navModel = new Department; |
846 | + navModel->setScopeId(this->id()); |
847 | + navModel->loadFromDepartmentNode(node); |
848 | + navModel->markSubdepartmentActive(m_currentAltNavigationId); |
849 | + |
850 | + // sharing m_inverseDepartments with getNavigation |
851 | + m_altNavModels.insert(navId, navModel); |
852 | + m_inverseDepartments.insert(navModel, navId); |
853 | + QObject::connect(navModel, &QObject::destroyed, this, &Scope::departmentModelDestroyed); |
854 | + |
855 | + return navModel; |
856 | +} |
857 | + |
858 | +QString Scope::buildQuery(QString const& scopeId, QString const& searchQuery, QString const& departmentId, QString const& primaryFilterId, QString const& primaryOptionId) |
859 | +{ |
860 | + scopes::CannedQuery q(scopeId.toStdString()); |
861 | + q.set_query_string(searchQuery.toStdString()); |
862 | + q.set_department_id(departmentId.toStdString()); |
863 | + |
864 | + if (!primaryFilterId.isEmpty() && !primaryOptionId.isEmpty()) { |
865 | + scopes::FilterState filter_state; |
866 | + scopes::OptionSelectorFilter::update_state(filter_state, primaryFilterId.toStdString(), primaryOptionId.toStdString(), true); |
867 | + q.set_filter_state(filter_state); |
868 | + } |
869 | + |
870 | + return QString::fromStdString(q.to_uri()); |
871 | +} |
872 | + |
873 | +void Scope::setNavigationState(QString const& navId, bool altNavigation) |
874 | +{ |
875 | + QString primaryFilterId; |
876 | + if (m_sortOrderFilter) { |
877 | + primaryFilterId = QString::fromStdString(m_sortOrderFilter->id()); |
878 | + } |
879 | + if (!altNavigation) { |
880 | + // switch current department id |
881 | + performQuery(buildQuery(id(), m_searchQuery, navId, primaryFilterId, m_currentAltNavigationId)); |
882 | + } else { |
883 | + // switch current primary filter |
884 | + performQuery(buildQuery(id(), m_searchQuery, m_currentNavigationId, primaryFilterId, navId)); |
885 | + } |
886 | } |
887 | |
888 | void Scope::departmentModelDestroyed(QObject* obj) |
889 | { |
890 | - scopes_ng::Department* department = reinterpret_cast<scopes_ng::Department*>(obj); |
891 | - |
892 | - auto it = m_inverseDepartments.find(department); |
893 | - if (it == m_inverseDepartments.end()) return; |
894 | - |
895 | - m_departmentModels.remove(it.value(), department); |
896 | - m_inverseDepartments.erase(it); |
897 | -} |
898 | - |
899 | -void Scope::loadDepartment(QString const& departmentId) |
900 | -{ |
901 | - if (departmentId != m_currentDepartmentId) { |
902 | - m_currentDepartmentId = departmentId; |
903 | - Q_EMIT currentDepartmentIdChanged(); |
904 | - |
905 | - dispatchSearch(); |
906 | - } |
907 | + scopes_ng::Department* navigation = reinterpret_cast<scopes_ng::Department*>(obj); |
908 | + |
909 | + auto it = m_inverseDepartments.find(navigation); |
910 | + if (it == m_inverseDepartments.end()) return; |
911 | + |
912 | + m_departmentModels.remove(it.value(), navigation); |
913 | + m_altNavModels.remove(it.value(), navigation); |
914 | + m_inverseDepartments.erase(it); |
915 | } |
916 | |
917 | void Scope::performQuery(QString const& cannedQuery) |
918 | @@ -737,6 +860,12 @@ |
919 | } |
920 | } |
921 | |
922 | +void Scope::refresh() |
923 | +{ |
924 | + // shell has to specifically call this, maybe we should ignore the active flag here and just call dispatchSearch |
925 | + invalidateResults(); |
926 | +} |
927 | + |
928 | QString Scope::searchQuery() const |
929 | { |
930 | return m_searchQuery; |
931 | @@ -757,14 +886,24 @@ |
932 | return m_isActive; |
933 | } |
934 | |
935 | -QString Scope::currentDepartmentId() const |
936 | -{ |
937 | - return m_currentDepartmentId; |
938 | -} |
939 | - |
940 | -bool Scope::hasDepartments() const |
941 | -{ |
942 | - return m_hasDepartments; |
943 | +QString Scope::currentNavigationId() const |
944 | +{ |
945 | + return m_currentNavigationId; |
946 | +} |
947 | + |
948 | +bool Scope::hasNavigation() const |
949 | +{ |
950 | + return m_hasNavigation; |
951 | +} |
952 | + |
953 | +QString Scope::currentAltNavigationId() const |
954 | +{ |
955 | + return m_currentAltNavigationId; |
956 | +} |
957 | + |
958 | +bool Scope::hasAltNavigation() const |
959 | +{ |
960 | + return m_hasAltNavigation; |
961 | } |
962 | |
963 | QVariantMap Scope::customizations() const |
964 | @@ -783,6 +922,11 @@ |
965 | if (m_searchQuery.isNull() || search_query != m_searchQuery) { |
966 | m_searchQuery = search_query; |
967 | |
968 | + // atm only empty query can have a filter state |
969 | + if (!m_searchQuery.isEmpty()) { |
970 | + m_filterState = scopes::FilterState(); |
971 | + } |
972 | + |
973 | // FIXME: use a timeout |
974 | invalidateResults(); |
975 | |
976 | @@ -828,6 +972,13 @@ |
977 | } |
978 | } |
979 | |
980 | +void Scope::setFavorite(const bool value) |
981 | +{ |
982 | + Q_UNUSED(value); |
983 | + |
984 | + qWarning("Unimplemented: %s", __func__); |
985 | +} |
986 | + |
987 | void Scope::activate(QVariant const& result_var) |
988 | { |
989 | if (!result_var.canConvert<std::shared_ptr<scopes::Result>>()) { |
990 | |
991 | === modified file 'src/Unity/scope.h' |
992 | --- src/Unity/scope.h 2014-07-31 11:08:50 +0000 |
993 | +++ src/Unity/scope.h 2014-08-06 08:35:31 +0000 |
994 | @@ -116,17 +116,20 @@ |
995 | QString iconHint() const override; |
996 | QString description() const override; |
997 | QString searchHint() const override; |
998 | - bool visible() const override; |
999 | + bool favorite() const override; |
1000 | QString shortcut() const override; |
1001 | bool searchInProgress() const override; |
1002 | + unity::shell::scopes::ScopeInterface::Status status() const override; |
1003 | unity::shell::scopes::CategoriesInterface* categories() const override; |
1004 | unity::shell::scopes::SettingsModelInterface* settings() const override; |
1005 | QString searchQuery() const override; |
1006 | QString noResultsHint() const override; |
1007 | QString formFactor() const override; |
1008 | bool isActive() const override; |
1009 | - QString currentDepartmentId() const override; |
1010 | - bool hasDepartments() const override; |
1011 | + QString currentNavigationId() const override; |
1012 | + bool hasNavigation() const override; |
1013 | + QString currentAltNavigationId() const override; |
1014 | + bool hasAltNavigation() const override; |
1015 | QVariantMap customizations() const override; |
1016 | |
1017 | /* setters */ |
1018 | @@ -134,14 +137,17 @@ |
1019 | void setNoResultsHint(const QString& hint) override; |
1020 | void setFormFactor(const QString& form_factor) override; |
1021 | void setActive(const bool) override; |
1022 | + void setFavorite(const bool) override; |
1023 | |
1024 | Q_INVOKABLE void activate(QVariant const& result) override; |
1025 | Q_INVOKABLE unity::shell::scopes::PreviewStackInterface* preview(QVariant const& result) override; |
1026 | Q_INVOKABLE void cancelActivation() override; |
1027 | Q_INVOKABLE void closeScope(unity::shell::scopes::ScopeInterface* scope) override; |
1028 | - Q_INVOKABLE unity::shell::scopes::DepartmentInterface* getDepartment(QString const& id) override; |
1029 | - Q_INVOKABLE void loadDepartment(QString const& id) override; |
1030 | + Q_INVOKABLE unity::shell::scopes::NavigationInterface* getNavigation(QString const& id) override; |
1031 | + Q_INVOKABLE unity::shell::scopes::NavigationInterface* getAltNavigation(QString const& id) override; |
1032 | + Q_INVOKABLE void setNavigationState(QString const& navId, bool altNavigation) override; |
1033 | Q_INVOKABLE void performQuery(QString const& cannedQuery) override; |
1034 | + Q_INVOKABLE void refresh() override; |
1035 | |
1036 | void setScopeData(unity::scopes::ScopeMetadata const& data); |
1037 | void handleActivation(std::shared_ptr<unity::scopes::ActivationResponse> const&, unity::scopes::Result::SPtr const&); |
1038 | @@ -164,6 +170,7 @@ |
1039 | |
1040 | protected: |
1041 | void setSearchInProgress(bool searchInProgress); |
1042 | + void setStatus(unity::shell::scopes::ScopeInterface::Status status); |
1043 | void invalidateLastSearch(); |
1044 | virtual void dispatchSearch(); |
1045 | |
1046 | @@ -173,9 +180,12 @@ |
1047 | QPointer<Scopes> m_scopesInstance; |
1048 | |
1049 | private: |
1050 | + static void updateNavigationModels(DepartmentNode* rootNode, QMultiMap<QString, Department*>& navigationModels, QString const& activeNavigation); |
1051 | + static QString buildQuery(QString const& scopeId, QString const& searchQuery, QString const& departmentId, QString const& primaryFilterId, QString const& primaryOptionId); |
1052 | void setScopesInstance(Scopes*); |
1053 | void startTtlTimer(); |
1054 | - void setCurrentDepartmentId(QString const& id); |
1055 | + void setCurrentNavigationId(QString const& id); |
1056 | + void setFilterState(unity::scopes::FilterState const& filterState); |
1057 | void processSearchChunk(PushEvent* pushEvent); |
1058 | void executeCannedQuery(unity::scopes::CannedQuery const& query, bool allowDelayedActivation); |
1059 | |
1060 | @@ -187,13 +197,15 @@ |
1061 | QString m_searchQuery; |
1062 | QString m_noResultsHint; |
1063 | QString m_formFactor; |
1064 | - QString m_currentDepartmentId; |
1065 | + QString m_currentNavigationId; |
1066 | + QString m_currentAltNavigationId; |
1067 | QVariantMap m_customizations; |
1068 | bool m_isActive; |
1069 | bool m_searchInProgress; |
1070 | bool m_resultsDirty; |
1071 | bool m_delayedClear; |
1072 | - bool m_hasDepartments; |
1073 | + bool m_hasNavigation; |
1074 | + bool m_hasAltNavigation; |
1075 | |
1076 | std::unique_ptr<CollectionController> m_searchController; |
1077 | std::unique_ptr<CollectionController> m_activationController; |
1078 | @@ -202,15 +214,22 @@ |
1079 | std::shared_ptr<unity::scopes::ActivationResponse> m_delayedActivation; |
1080 | unity::scopes::Department::SCPtr m_rootDepartment; |
1081 | unity::scopes::Department::SCPtr m_lastRootDepartment; |
1082 | + unity::scopes::OptionSelectorFilter::SCPtr m_sortOrderFilter; |
1083 | + unity::scopes::OptionSelectorFilter::SCPtr m_lastSortOrderFilter; |
1084 | + unity::scopes::FilterState m_filterState; |
1085 | + unity::scopes::FilterState m_receivedFilterState; |
1086 | + unity::shell::scopes::ScopeInterface::Status m_status; |
1087 | QGSettings* m_settings; |
1088 | QScopedPointer<SettingsModel> m_settingsModel; |
1089 | QSharedPointer<DepartmentNode> m_departmentTree; |
1090 | + QSharedPointer<DepartmentNode> m_altNavTree; |
1091 | QTimer m_aggregatorTimer; |
1092 | QTimer m_clearTimer; |
1093 | QTimer m_invalidateTimer; |
1094 | QList<std::shared_ptr<unity::scopes::CategorisedResult>> m_cachedResults; |
1095 | QSet<unity::shell::scopes::ScopeInterface*> m_tempScopes; |
1096 | QMultiMap<QString, Department*> m_departmentModels; |
1097 | + QMultiMap<QString, Department*> m_altNavModels; |
1098 | QMap<Department*, QString> m_inverseDepartments; |
1099 | QMetaObject::Connection m_metadataConnection; |
1100 | LocationService::Ptr m_locationService; |
1101 | |
1102 | === modified file 'src/Unity/scopes.cpp' |
1103 | --- src/Unity/scopes.cpp 2014-07-31 11:08:50 +0000 |
1104 | +++ src/Unity/scopes.cpp 2014-08-06 08:35:31 +0000 |
1105 | @@ -130,6 +130,11 @@ |
1106 | return m_scopes.count(); |
1107 | } |
1108 | |
1109 | +int Scopes::count() const |
1110 | +{ |
1111 | + return m_scopes.count(); |
1112 | +} |
1113 | + |
1114 | void Scopes::populateScopes() |
1115 | { |
1116 | auto thread = new ScopeListWorker; |
1117 | @@ -198,6 +203,7 @@ |
1118 | |
1119 | m_loaded = true; |
1120 | Q_EMIT loadedChanged(); |
1121 | + Q_EMIT countChanged(); |
1122 | Q_EMIT overviewScopeChanged(); |
1123 | Q_EMIT metadataRefreshed(); |
1124 | |
1125 | @@ -249,8 +255,6 @@ |
1126 | return QVariant::fromValue(scope); |
1127 | case Scopes::RoleId: |
1128 | return QString(scope->id()); |
1129 | - case Scopes::RoleVisible: |
1130 | - return QVariant::fromValue(scope->visible()); |
1131 | case Scopes::RoleTitle: |
1132 | return QString(scope->name()); |
1133 | default: |
1134 | |
1135 | === modified file 'src/Unity/scopes.h' |
1136 | --- src/Unity/scopes.h 2014-07-31 11:08:50 +0000 |
1137 | +++ src/Unity/scopes.h 2014-08-06 08:35:31 +0000 |
1138 | @@ -62,6 +62,7 @@ |
1139 | void refreshScopeMetadata(); |
1140 | |
1141 | bool loaded() const override; |
1142 | + int count() const override; |
1143 | unity::shell::scopes::ScopeInterface* overviewScope() const override; |
1144 | |
1145 | LocationService::Ptr locationService() const; |
1146 | |
1147 | === modified file 'tests/data/CMakeLists.txt' |
1148 | --- tests/data/CMakeLists.txt 2014-07-22 13:49:50 +0000 |
1149 | +++ tests/data/CMakeLists.txt 2014-08-06 08:35:31 +0000 |
1150 | @@ -1,5 +1,6 @@ |
1151 | add_subdirectory(mock-scope) |
1152 | add_subdirectory(mock-scope-departments) |
1153 | +add_subdirectory(mock-scope-double-nav) |
1154 | add_subdirectory(mock-scope-ttl) |
1155 | add_subdirectory(scopes) |
1156 | |
1157 | |
1158 | === added directory 'tests/data/mock-scope-double-nav' |
1159 | === added file 'tests/data/mock-scope-double-nav/CMakeLists.txt' |
1160 | --- tests/data/mock-scope-double-nav/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1161 | +++ tests/data/mock-scope-double-nav/CMakeLists.txt 2014-08-06 08:35:31 +0000 |
1162 | @@ -0,0 +1,16 @@ |
1163 | +include(FindPkgConfig) |
1164 | +pkg_check_modules(SCOPESLIB REQUIRED libunity-scopes>=0.4.0) |
1165 | + |
1166 | +set(SCOPES_BIN_DIR ${SCOPESLIB_LIBDIR}) |
1167 | + |
1168 | +include_directories(${SCOPESLIB_INCLUDE_DIRS}) |
1169 | +include_directories(${CMAKE_CURRENT_BINARY_DIR}) |
1170 | + |
1171 | +set(SCOPE_SOURCES |
1172 | + mock-scope-double-nav.cpp |
1173 | + ) |
1174 | + |
1175 | +add_library(mock-scope-double-nav MODULE ${SCOPE_SOURCES}) |
1176 | +target_link_libraries(mock-scope-double-nav ${SCOPESLIB_LDFLAGS}) |
1177 | + |
1178 | +configure_file(mock-scope-double-nav.ini.in mock-scope-double-nav.ini) |
1179 | |
1180 | === added file 'tests/data/mock-scope-double-nav/mock-scope-double-nav.cpp' |
1181 | --- tests/data/mock-scope-double-nav/mock-scope-double-nav.cpp 1970-01-01 00:00:00 +0000 |
1182 | +++ tests/data/mock-scope-double-nav/mock-scope-double-nav.cpp 2014-08-06 08:35:31 +0000 |
1183 | @@ -0,0 +1,214 @@ |
1184 | +/* |
1185 | + * Copyright (C) 2014 Canonical Ltd |
1186 | + * |
1187 | + * This program is free software: you can redistribute it and/or modify |
1188 | + * it under the terms of the GNU Lesser General Public License version 3 as |
1189 | + * published by the Free Software Foundation. |
1190 | + * |
1191 | + * This program is distributed in the hope that it will be useful, |
1192 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1193 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1194 | + * GNU Lesser General Public License for more details. |
1195 | + * |
1196 | + * You should have received a copy of the GNU Lesser General Public License |
1197 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1198 | + * |
1199 | + * Authored by: Pete Woods <pete.woods@canonical.com> |
1200 | + */ |
1201 | + |
1202 | +#include <unity/scopes/CategorisedResult.h> |
1203 | +#include <unity/scopes/OptionSelectorFilter.h> |
1204 | +#include <unity/scopes/ScopeBase.h> |
1205 | +#include <unity/scopes/SearchReply.h> |
1206 | + |
1207 | +#include <iostream> |
1208 | +#include <thread> |
1209 | +#include <atomic> |
1210 | +#include <sstream> |
1211 | + |
1212 | +#define EXPORT __attribute__ ((visibility ("default"))) |
1213 | + |
1214 | +using namespace std; |
1215 | +using namespace unity::scopes; |
1216 | + |
1217 | +class MyQuery : public SearchQueryBase |
1218 | +{ |
1219 | +public: |
1220 | + MyQuery(CannedQuery const& query, SearchMetadata const& metadata) : |
1221 | + SearchQueryBase(query, metadata), |
1222 | + department_id_(query.department_id()) |
1223 | + { |
1224 | + } |
1225 | + |
1226 | + ~MyQuery() |
1227 | + { |
1228 | + } |
1229 | + |
1230 | + virtual void cancelled() override |
1231 | + { |
1232 | + } |
1233 | + |
1234 | + static Department::SPtr create_root_dep(CannedQuery const& query) |
1235 | + { |
1236 | + Department::SPtr child_dep; |
1237 | + Department::SPtr root_dep; |
1238 | + root_dep = Department::create("", query, "All departments"); |
1239 | + |
1240 | + child_dep = Department::create("books", query, "Books"); |
1241 | + child_dep->set_has_subdepartments(); |
1242 | + root_dep->add_subdepartment(child_dep); |
1243 | + |
1244 | + child_dep = Department::create("movies", query, "Movies, TV, Music"); |
1245 | + child_dep->set_has_subdepartments(); |
1246 | + root_dep->add_subdepartment(child_dep); |
1247 | + |
1248 | + child_dep = Department::create("electronics", query, "Electronics"); |
1249 | + child_dep->set_has_subdepartments(); |
1250 | + root_dep->add_subdepartment(child_dep); |
1251 | + |
1252 | + child_dep = Department::create("home", query, "Home, Garden & DIY"); |
1253 | + child_dep->set_has_subdepartments(); |
1254 | + root_dep->add_subdepartment(child_dep); |
1255 | + |
1256 | + child_dep = Department::create("toys", query, "Toys, Children & Baby"); |
1257 | + child_dep->set_has_subdepartments(); |
1258 | + root_dep->add_subdepartment(child_dep); |
1259 | + |
1260 | + return root_dep; |
1261 | + } |
1262 | + |
1263 | + static Department::SPtr get_department_by_id(Department::SPtr root_dep, std::string const& dep_id) |
1264 | + { |
1265 | + auto children = root_dep->subdepartments(); |
1266 | + for (auto it = children.begin(); it != children.end(); ++it) |
1267 | + { |
1268 | + if ((*it)->id() == dep_id) return const_pointer_cast<Department>(*it); |
1269 | + } |
1270 | + return Department::SPtr(); |
1271 | + } |
1272 | + |
1273 | + virtual void run(SearchReplyProxy const& reply) override |
1274 | + { |
1275 | + Department::SPtr child_dep; |
1276 | + Department::SPtr root_dep; |
1277 | + Department::SPtr active_dep; |
1278 | + |
1279 | + root_dep = create_root_dep(query()); |
1280 | + |
1281 | + if (department_id_.compare(0, 5, "books") == 0) |
1282 | + { |
1283 | + active_dep = get_department_by_id(root_dep, "books"); |
1284 | + child_dep = Department::create("books-kindle", query(), "Kindle Books"); |
1285 | + active_dep->add_subdepartment(child_dep); |
1286 | + |
1287 | + child_dep = Department::create("books-study", query(), "Books for Study"); |
1288 | + active_dep->add_subdepartment(child_dep); |
1289 | + |
1290 | + child_dep = Department::create("books-audio", query(), "Audiobooks"); |
1291 | + active_dep->add_subdepartment(child_dep); |
1292 | + } |
1293 | + |
1294 | + if (department_id_.compare(0, 4, "home") == 0) |
1295 | + { |
1296 | + active_dep = get_department_by_id(root_dep, "home"); |
1297 | + child_dep = Department::create("home-garden", query(), "Garden & Outdoors"); |
1298 | + active_dep->add_subdepartment(child_dep); |
1299 | + |
1300 | + child_dep = Department::create("home-furniture", query(), "Homeware & Furniture"); |
1301 | + active_dep->add_subdepartment(child_dep); |
1302 | + |
1303 | + child_dep = Department::create("home-kitchen", query(), "Kitchen & Dining"); |
1304 | + active_dep->add_subdepartment(child_dep); |
1305 | + } |
1306 | + |
1307 | + if (department_id_.compare(0, 4, "toys") == 0) |
1308 | + { |
1309 | + active_dep = get_department_by_id(root_dep, "toys"); |
1310 | + child_dep = Department::create("toys-games", query(), "Toys & Games"); |
1311 | + active_dep->add_subdepartment(child_dep); |
1312 | + |
1313 | + child_dep = Department::create("toys-baby", query(), "Baby"); |
1314 | + active_dep->add_subdepartment(child_dep); |
1315 | + } |
1316 | + |
1317 | + // provide only partial tree for this leaf |
1318 | + if (department_id_ == "toys-games") |
1319 | + { |
1320 | + root_dep = Department::create("", query(), "All departments"); |
1321 | + child_dep = Department::create("toys", query(), "Toys, Children & Baby"); |
1322 | + root_dep->add_subdepartment(child_dep); |
1323 | + active_dep = Department::create("toys-games", query(), "Toys & Games"); |
1324 | + child_dep->add_subdepartment(active_dep); |
1325 | + } |
1326 | + |
1327 | + reply->register_departments(root_dep); |
1328 | + |
1329 | + // add sort order filter |
1330 | + OptionSelectorFilter::UPtr sort_order_filter = OptionSelectorFilter::create("sort-order", "Sort Order"); |
1331 | + sort_order_filter->set_display_hints(FilterBase::Primary); |
1332 | + sort_order_filter->add_option("featured", "Featured"); |
1333 | + sort_order_filter->add_option("top", "Most popular"); |
1334 | + sort_order_filter->add_option("best", "Best sellers"); |
1335 | + Filters filters; |
1336 | + filters.push_back(std::move(sort_order_filter)); |
1337 | + |
1338 | + FilterState state; |
1339 | + FilterState initial_filter_state(query().filter_state()); |
1340 | + if (initial_filter_state.has_filter("sort-order")) { |
1341 | + state = initial_filter_state; |
1342 | + } else { |
1343 | + // default option |
1344 | + OptionSelectorFilter::update_state(state, "sort-order", "featured", true); |
1345 | + } |
1346 | + |
1347 | + reply->push(filters, state); |
1348 | + |
1349 | + auto cat1 = reply->register_category("cat1", "Category 1", ""); |
1350 | + CategorisedResult res1(cat1); |
1351 | + res1.set_uri("test:uri"); |
1352 | + res1.set_title("result for: \"" + query().query_string() + "\""); |
1353 | + reply->push(res1); |
1354 | + } |
1355 | + |
1356 | +protected: |
1357 | + string department_id_; |
1358 | +}; |
1359 | + |
1360 | +class MyScope : public ScopeBase |
1361 | +{ |
1362 | +public: |
1363 | + MyScope() |
1364 | + { |
1365 | + } |
1366 | + |
1367 | + virtual SearchQueryBase::UPtr search(CannedQuery const& q, SearchMetadata const& metadata) override |
1368 | + { |
1369 | + return SearchQueryBase::UPtr(new MyQuery(q, metadata)); |
1370 | + } |
1371 | + |
1372 | + virtual PreviewQueryBase::UPtr preview(Result const&, ActionMetadata const&) override |
1373 | + { |
1374 | + return nullptr; |
1375 | + } |
1376 | +}; |
1377 | + |
1378 | +extern "C" |
1379 | +{ |
1380 | + |
1381 | + EXPORT |
1382 | + unity::scopes::ScopeBase* |
1383 | + // cppcheck-suppress unusedFunction |
1384 | + UNITY_SCOPE_CREATE_FUNCTION() |
1385 | + { |
1386 | + return new MyScope; |
1387 | + } |
1388 | + |
1389 | + EXPORT |
1390 | + void |
1391 | + // cppcheck-suppress unusedFunction |
1392 | + UNITY_SCOPE_DESTROY_FUNCTION(unity::scopes::ScopeBase* scope_base) |
1393 | + { |
1394 | + delete scope_base; |
1395 | + } |
1396 | + |
1397 | +} |
1398 | |
1399 | === added file 'tests/data/mock-scope-double-nav/mock-scope-double-nav.ini.in' |
1400 | --- tests/data/mock-scope-double-nav/mock-scope-double-nav.ini.in 1970-01-01 00:00:00 +0000 |
1401 | +++ tests/data/mock-scope-double-nav/mock-scope-double-nav.ini.in 2014-08-06 08:35:31 +0000 |
1402 | @@ -0,0 +1,8 @@ |
1403 | +[ScopeConfig] |
1404 | +DisplayName = mock-double-nav.DisplayName |
1405 | +Description = mock-double-nav.Description |
1406 | +Art = /mock-double-nav.Art |
1407 | +Icon = /mock-double-nav.Icon |
1408 | +SearchHint = mock-double-nav.SearchHint |
1409 | +HotKey = mock-double-nav.HotKey |
1410 | +Author = mock-double-nav.Author |
1411 | |
1412 | === modified file 'tests/departmentstest.cpp' |
1413 | --- tests/departmentstest.cpp 2014-07-18 16:35:52 +0000 |
1414 | +++ tests/departmentstest.cpp 2014-08-06 08:35:31 +0000 |
1415 | @@ -48,6 +48,7 @@ |
1416 | private: |
1417 | QScopedPointer<Scopes> m_scopes; |
1418 | Scope* m_scope; |
1419 | + Scope* m_scope_navs; |
1420 | QScopedPointer<RegistrySpawner> m_registry; |
1421 | |
1422 | private Q_SLOTS: |
1423 | @@ -78,6 +79,10 @@ |
1424 | m_scope = qobject_cast<scopes_ng::Scope*>(m_scopes->getScope(QString("mock-scope-departments"))); |
1425 | QVERIFY(m_scope != nullptr); |
1426 | m_scope->setActive(true); |
1427 | + |
1428 | + m_scope_navs = qobject_cast<scopes_ng::Scope*>(m_scopes->getScope(QString("mock-scope-double-nav"))); |
1429 | + QVERIFY(m_scope_navs != nullptr); |
1430 | + m_scope_navs->setActive(true); |
1431 | } |
1432 | |
1433 | void cleanup() |
1434 | @@ -90,37 +95,40 @@ |
1435 | { |
1436 | performSearch(m_scope, QString("foo")); |
1437 | |
1438 | - QCOMPARE(m_scope->hasDepartments(), false); |
1439 | + QCOMPARE(m_scope->hasNavigation(), false); |
1440 | + QCOMPARE(m_scope->hasAltNavigation(), false); |
1441 | } |
1442 | |
1443 | void testRootDepartment() |
1444 | { |
1445 | performSearch(m_scope, QString("")); |
1446 | |
1447 | - QCOMPARE(m_scope->hasDepartments(), true); |
1448 | - QCOMPARE(m_scope->currentDepartmentId(), QString("")); |
1449 | - QScopedPointer<DepartmentInterface> departmentModel(m_scope->getDepartment(m_scope->currentDepartmentId())); |
1450 | + QCOMPARE(m_scope->hasNavigation(), true); |
1451 | + QCOMPARE(m_scope->hasAltNavigation(), false); |
1452 | + QCOMPARE(m_scope->currentNavigationId(), QString("")); |
1453 | + QScopedPointer<NavigationInterface> departmentModel(m_scope->getNavigation(m_scope->currentNavigationId())); |
1454 | QVERIFY(departmentModel != nullptr); |
1455 | |
1456 | - QVERIFY(departmentModel->departmentId().isEmpty()); |
1457 | + QVERIFY(departmentModel->navigationId().isEmpty()); |
1458 | QCOMPARE(departmentModel->label(), QString("All departments")); |
1459 | QCOMPARE(departmentModel->allLabel(), QString("")); |
1460 | - QCOMPARE(departmentModel->parentDepartmentId(), QString()); |
1461 | + QCOMPARE(departmentModel->parentNavigationId(), QString()); |
1462 | QCOMPARE(departmentModel->parentLabel(), QString()); |
1463 | QCOMPARE(departmentModel->loaded(), true); |
1464 | QCOMPARE(departmentModel->isRoot(), true); |
1465 | + QCOMPARE(departmentModel->hidden(), false); |
1466 | |
1467 | QCOMPARE(departmentModel->rowCount(), 5); |
1468 | QModelIndex idx; |
1469 | |
1470 | idx = departmentModel->index(0); |
1471 | - QCOMPARE(departmentModel->data(idx, Department::Roles::RoleDepartmentId), QVariant(QString("books"))); |
1472 | + QCOMPARE(departmentModel->data(idx, Department::Roles::RoleNavigationId), QVariant(QString("books"))); |
1473 | QCOMPARE(departmentModel->data(idx, Department::Roles::RoleLabel), QVariant(QString("Books"))); |
1474 | QCOMPARE(departmentModel->data(idx, Department::Roles::RoleHasChildren), QVariant(true)); |
1475 | QCOMPARE(departmentModel->data(idx, Department::Roles::RoleIsActive), QVariant(false)); |
1476 | |
1477 | idx = departmentModel->index(4); |
1478 | - QCOMPARE(departmentModel->data(idx, Department::Roles::RoleDepartmentId), QVariant(QString("toys"))); |
1479 | + QCOMPARE(departmentModel->data(idx, Department::Roles::RoleNavigationId), QVariant(QString("toys"))); |
1480 | QCOMPARE(departmentModel->data(idx, Department::Roles::RoleLabel), QVariant(QString("Toys, Children & Baby"))); |
1481 | QCOMPARE(departmentModel->data(idx, Department::Roles::RoleHasChildren), QVariant(true)); |
1482 | QCOMPARE(departmentModel->data(idx, Department::Roles::RoleIsActive), QVariant(false)); |
1483 | @@ -130,23 +138,23 @@ |
1484 | { |
1485 | performSearch(m_scope, QString("")); |
1486 | |
1487 | - QCOMPARE(m_scope->currentDepartmentId(), QString("")); |
1488 | - QScopedPointer<DepartmentInterface> departmentModel(m_scope->getDepartment(QString("toys"))); |
1489 | + QCOMPARE(m_scope->currentNavigationId(), QString("")); |
1490 | + QScopedPointer<NavigationInterface> departmentModel(m_scope->getNavigation(QString("toys"))); |
1491 | QVERIFY(departmentModel != nullptr); |
1492 | |
1493 | QSignalSpy spy(departmentModel.data(), SIGNAL(loadedChanged())); |
1494 | |
1495 | - QCOMPARE(departmentModel->departmentId(), QString("toys")); |
1496 | + QCOMPARE(departmentModel->navigationId(), QString("toys")); |
1497 | QCOMPARE(departmentModel->label(), QString("Toys, Children & Baby")); |
1498 | QCOMPARE(departmentModel->allLabel(), QString("")); |
1499 | - QCOMPARE(departmentModel->parentDepartmentId(), QString("")); |
1500 | + QCOMPARE(departmentModel->parentNavigationId(), QString("")); |
1501 | QCOMPARE(departmentModel->parentLabel(), QString("All departments")); |
1502 | QCOMPARE(departmentModel->loaded(), false); |
1503 | QCOMPARE(departmentModel->isRoot(), false); |
1504 | |
1505 | QCOMPARE(departmentModel->rowCount(), 0); |
1506 | |
1507 | - m_scope->loadDepartment(QString("toys")); |
1508 | + m_scope->setNavigationState(departmentModel->navigationId(), false); |
1509 | QVERIFY(spy.wait()); |
1510 | |
1511 | QCOMPARE(departmentModel->rowCount(), 2); |
1512 | @@ -158,16 +166,18 @@ |
1513 | { |
1514 | performSearch(m_scope, QString("")); |
1515 | |
1516 | - QCOMPARE(m_scope->currentDepartmentId(), QString("")); |
1517 | + QCOMPARE(m_scope->currentNavigationId(), QString("")); |
1518 | QSignalSpy spy(m_scope, SIGNAL(searchInProgressChanged())); |
1519 | - m_scope->loadDepartment(QString("books")); |
1520 | + QScopedPointer<NavigationInterface> navModel(m_scope->getNavigation(QString("books"))); |
1521 | + m_scope->setNavigationState(navModel->navigationId(), false); |
1522 | QVERIFY(spy.wait()); |
1523 | QCOMPARE(m_scope->searchInProgress(), false); |
1524 | - QScopedPointer<DepartmentInterface> departmentModel(m_scope->getDepartment(QString("books"))); |
1525 | + QScopedPointer<NavigationInterface> departmentModel(m_scope->getNavigation(QString("books"))); |
1526 | QCOMPARE(departmentModel->isRoot(), false); |
1527 | |
1528 | + navModel.reset(m_scope->getNavigation(QString("books-audio"))); |
1529 | // this is a leaf department, so activating it should update the parent model |
1530 | - m_scope->loadDepartment(QString("books-audio")); |
1531 | + m_scope->setNavigationState(navModel->navigationId(), false); |
1532 | QVERIFY(spy.wait()); |
1533 | QCOMPARE(m_scope->searchInProgress(), false); |
1534 | QCOMPARE(departmentModel->isRoot(), false); |
1535 | @@ -175,7 +185,7 @@ |
1536 | bool foundAudiobooks = false; |
1537 | for (int i = 0; i < departmentModel->rowCount(); i++) { |
1538 | QModelIndex idx(departmentModel->index(i)); |
1539 | - QVariant data = departmentModel->data(idx, Department::Roles::RoleDepartmentId); |
1540 | + QVariant data = departmentModel->data(idx, Department::Roles::RoleNavigationId); |
1541 | if (data.toString() == QString("books-audio")) { |
1542 | QCOMPARE(departmentModel->data(idx, Department::Roles::RoleIsActive).toBool(), true); |
1543 | foundAudiobooks = true; |
1544 | @@ -188,16 +198,17 @@ |
1545 | { |
1546 | performSearch(m_scope, QString("")); |
1547 | |
1548 | - QCOMPARE(m_scope->currentDepartmentId(), QString("")); |
1549 | + QCOMPARE(m_scope->currentNavigationId(), QString("")); |
1550 | QSignalSpy spy(m_scope, SIGNAL(searchInProgressChanged())); |
1551 | - m_scope->loadDepartment(QString("books")); |
1552 | + QScopedPointer<NavigationInterface> navModel(m_scope->getNavigation(QString("books"))); |
1553 | + m_scope->setNavigationState(navModel->navigationId(), false); |
1554 | QVERIFY(spy.wait()); |
1555 | QCOMPARE(m_scope->searchInProgress(), false); |
1556 | - QScopedPointer<DepartmentInterface> departmentModel(m_scope->getDepartment(QString("books"))); |
1557 | + QScopedPointer<NavigationInterface> departmentModel(m_scope->getNavigation(QString("books"))); |
1558 | QCOMPARE(departmentModel->isRoot(), false); |
1559 | |
1560 | // get the root again without actually loading the department |
1561 | - departmentModel.reset(m_scope->getDepartment(departmentModel->parentDepartmentId())); |
1562 | + departmentModel.reset(m_scope->getNavigation(departmentModel->parentNavigationId())); |
1563 | QCOMPARE(departmentModel->isRoot(), true); |
1564 | QEXPECT_FAIL("", "We have the department in cache, to it kind of is loaded", Continue); |
1565 | QCOMPARE(departmentModel->loaded(), false); |
1566 | @@ -205,32 +216,98 @@ |
1567 | |
1568 | void testIncompleteTreeOnLeaf() |
1569 | { |
1570 | - QScopedPointer<DepartmentInterface> departmentModel; |
1571 | + QScopedPointer<NavigationInterface> navModel; |
1572 | + QScopedPointer<NavigationInterface> departmentModel; |
1573 | performSearch(m_scope, QString("")); |
1574 | |
1575 | - QCOMPARE(m_scope->currentDepartmentId(), QString("")); |
1576 | - QCOMPARE(m_scope->hasDepartments(), true); |
1577 | + QCOMPARE(m_scope->currentNavigationId(), QString("")); |
1578 | + QCOMPARE(m_scope->hasNavigation(), true); |
1579 | |
1580 | QSignalSpy spy(m_scope, SIGNAL(searchInProgressChanged())); |
1581 | - m_scope->loadDepartment(QString("toys")); |
1582 | + navModel.reset(m_scope->getNavigation(QString("toys"))); |
1583 | + m_scope->setNavigationState(navModel->navigationId(), false); |
1584 | QVERIFY(spy.wait()); |
1585 | QCOMPARE(m_scope->searchInProgress(), false); |
1586 | |
1587 | - departmentModel.reset(m_scope->getDepartment(QString("toys"))); |
1588 | + departmentModel.reset(m_scope->getNavigation(QString("toys"))); |
1589 | QCOMPARE(departmentModel->isRoot(), false); |
1590 | QCOMPARE(departmentModel->rowCount(), 2); |
1591 | |
1592 | - m_scope->loadDepartment(QString("toys-games")); |
1593 | + navModel.reset(m_scope->getNavigation(QString("toys-games"))); |
1594 | + m_scope->setNavigationState(navModel->navigationId(), false); |
1595 | QVERIFY(spy.wait()); |
1596 | QCOMPARE(m_scope->searchInProgress(), false); |
1597 | |
1598 | // after getting the parent department model, it should still have |
1599 | // all the leaves, even though the leaf served just itself |
1600 | - departmentModel.reset(m_scope->getDepartment(QString("toys"))); |
1601 | + departmentModel.reset(m_scope->getNavigation(QString("toys"))); |
1602 | QCOMPARE(departmentModel->isRoot(), false); |
1603 | QCOMPARE(departmentModel->rowCount(), 2); |
1604 | } |
1605 | |
1606 | + void testDoubleNavigation() |
1607 | + { |
1608 | + performSearch(m_scope_navs, QString("")); |
1609 | + |
1610 | + QCOMPARE(m_scope_navs->hasNavigation(), true); |
1611 | + QCOMPARE(m_scope_navs->hasAltNavigation(), true); |
1612 | + QCOMPARE(m_scope_navs->currentNavigationId(), QString("")); |
1613 | + QCOMPARE(m_scope_navs->currentAltNavigationId(), QString("featured")); |
1614 | + QScopedPointer<NavigationInterface> departmentModel(m_scope_navs->getNavigation(m_scope_navs->currentNavigationId())); |
1615 | + QVERIFY(departmentModel != nullptr); |
1616 | + |
1617 | + QVERIFY(!m_scope_navs->currentAltNavigationId().isEmpty()); |
1618 | + QScopedPointer<NavigationInterface> sortOrderModel(m_scope_navs->getAltNavigation("")); |
1619 | + QVERIFY(sortOrderModel != nullptr); |
1620 | + |
1621 | + QCOMPARE(sortOrderModel->navigationId(), QString("")); |
1622 | + QCOMPARE(sortOrderModel->label(), QString("Sort Order")); |
1623 | + QCOMPARE(sortOrderModel->allLabel(), QString("")); |
1624 | + QCOMPARE(sortOrderModel->parentNavigationId(), QString()); |
1625 | + QCOMPARE(sortOrderModel->parentLabel(), QString()); |
1626 | + QCOMPARE(sortOrderModel->loaded(), true); |
1627 | + QCOMPARE(sortOrderModel->isRoot(), true); |
1628 | + QCOMPARE(sortOrderModel->hidden(), true); |
1629 | + |
1630 | + QCOMPARE(sortOrderModel->rowCount(), 3); |
1631 | + QModelIndex idx; |
1632 | + |
1633 | + idx = sortOrderModel->index(0); |
1634 | + QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleNavigationId), QVariant(QString("featured"))); |
1635 | + QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleLabel), QVariant(QString("Featured"))); |
1636 | + QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleHasChildren), QVariant(false)); |
1637 | + QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleIsActive), QVariant(true)); |
1638 | + |
1639 | + idx = sortOrderModel->index(2); |
1640 | + QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleNavigationId), QVariant(QString("best"))); |
1641 | + QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleLabel), QVariant(QString("Best sellers"))); |
1642 | + QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleHasChildren), QVariant(false)); |
1643 | + QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleIsActive), QVariant(false)); |
1644 | + } |
1645 | + |
1646 | + void testDoubleNavChangeActive() |
1647 | + { |
1648 | + performSearch(m_scope_navs, QString("")); |
1649 | + |
1650 | + QCOMPARE(m_scope_navs->currentAltNavigationId(), QString("featured")); |
1651 | + QScopedPointer<NavigationInterface> sortOrderModel(m_scope_navs->getAltNavigation("")); |
1652 | + QVERIFY(sortOrderModel != nullptr); |
1653 | + QCOMPARE(sortOrderModel->loaded(), true); |
1654 | + QCOMPARE(sortOrderModel->rowCount(), 3); |
1655 | + |
1656 | + QModelIndex idx(sortOrderModel->index(1)); |
1657 | + QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleNavigationId), QVariant(QString("top"))); |
1658 | + QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleIsActive), QVariant(false)); |
1659 | + |
1660 | + // perform a query for the other navigation |
1661 | + QSignalSpy spy(m_scope_navs, SIGNAL(searchInProgressChanged())); |
1662 | + m_scope_navs->setNavigationState("top", true); |
1663 | + QVERIFY(spy.wait()); |
1664 | + |
1665 | + // the model should be updated |
1666 | + QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleNavigationId), QVariant(QString("top"))); |
1667 | + QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleIsActive), QVariant(true)); |
1668 | + } |
1669 | }; |
1670 | |
1671 | QTEST_GUILESS_MAIN(DepartmentsTest) |
1672 | |
1673 | === modified file 'tests/previewtest.cpp' |
1674 | --- tests/previewtest.cpp 2014-08-05 12:10:41 +0000 |
1675 | +++ tests/previewtest.cpp 2014-08-06 08:35:31 +0000 |
1676 | @@ -67,14 +67,14 @@ |
1677 | QVERIFY(spy.wait()); |
1678 | QCOMPARE(m_scopes->loaded(), true); |
1679 | // should have at least one scope now |
1680 | - QCOMPARE(m_scopes->rowCount(), 4); |
1681 | + QVERIFY(m_scopes->rowCount() > 1); |
1682 | |
1683 | QVariant scope_var = m_scopes->data(m_scopes->index(0), Scopes::Roles::RoleScope); |
1684 | QVERIFY(scope_var.canConvert<Scope*>()); |
1685 | |
1686 | // get scope proxy |
1687 | - m_scope = scope_var.value<Scope*>(); |
1688 | - QCOMPARE(m_scope->id(), QString("mock-scope")); |
1689 | + m_scope = m_scopes->getScopeById("mock-scope"); |
1690 | + QVERIFY(m_scope != nullptr); |
1691 | m_scope->setActive(true); |
1692 | } |
1693 | |
1694 | |
1695 | === modified file 'tests/resultstest.cpp' |
1696 | --- tests/resultstest.cpp 2014-07-31 13:04:20 +0000 |
1697 | +++ tests/resultstest.cpp 2014-08-06 08:35:31 +0000 |
1698 | @@ -112,15 +112,15 @@ |
1699 | QVERIFY(spy.wait()); |
1700 | QCOMPARE(m_scopes->loaded(), true); |
1701 | // should have at least one scope now |
1702 | - QCOMPARE(m_scopes->rowCount(), 4); |
1703 | + QVERIFY(m_scopes->rowCount() > 1); |
1704 | |
1705 | // get scope proxy |
1706 | - m_scope = qobject_cast<scopes_ng::Scope*>(m_scopes->getScope(QString("mock-scope"))); |
1707 | + m_scope = qobject_cast<scopes_ng::Scope*>(m_scopes->getScopeById(QString("mock-scope"))); |
1708 | QVERIFY(m_scope != nullptr); |
1709 | m_scope->setActive(true); |
1710 | |
1711 | // get scope proxy for TTL scope |
1712 | - m_scope_ttl = qobject_cast<scopes_ng::Scope*>(m_scopes->getScope(QString("mock-scope-ttl"))); |
1713 | + m_scope_ttl = qobject_cast<scopes_ng::Scope*>(m_scopes->getScopeById(QString("mock-scope-ttl"))); |
1714 | QVERIFY(m_scope != nullptr); |
1715 | m_scope_ttl->setActive(true); |
1716 | } |
1717 | @@ -177,7 +177,6 @@ |
1718 | QCOMPARE(m_scope->description(), QString("mock.Description")); |
1719 | QCOMPARE(m_scope->searchHint(), QString("mock.SearchHint")); |
1720 | QCOMPARE(m_scope->shortcut(), QString("mock.HotKey")); |
1721 | - QCOMPARE(m_scope->visible(), true); |
1722 | QCOMPARE(m_scope->searchQuery(), QString()); |
1723 | |
1724 | QVariantMap customizations(m_scope->customizations()); |
1725 | @@ -199,7 +198,6 @@ |
1726 | QCOMPARE(m_scope_ttl->description(), QString("mock-ttl.Description")); |
1727 | QCOMPARE(m_scope_ttl->searchHint(), QString()); |
1728 | QCOMPARE(m_scope_ttl->shortcut(), QString()); |
1729 | - QCOMPARE(m_scope_ttl->visible(), true); |
1730 | QCOMPARE(m_scope_ttl->searchQuery(), QString()); |
1731 | } |
1732 | |
1733 | |
1734 | === modified file 'tests/settingsendtoendtest.cpp' |
1735 | --- tests/settingsendtoendtest.cpp 2014-08-05 16:41:02 +0000 |
1736 | +++ tests/settingsendtoendtest.cpp 2014-08-06 08:35:31 +0000 |
1737 | @@ -61,10 +61,10 @@ |
1738 | QVERIFY(spy.wait()); |
1739 | QCOMPARE(m_scopes->loaded(), true); |
1740 | // should have at least one scope now |
1741 | - QCOMPARE(m_scopes->rowCount(), 4); |
1742 | + QVERIFY(m_scopes->rowCount() > 1); |
1743 | |
1744 | // get scope proxy |
1745 | - m_scope = qobject_cast<scopes_ng::Scope*>(m_scopes->getScope(QString("mock-scope"))); |
1746 | + m_scope = m_scopes->getScopeById("mock-scope"); |
1747 | QVERIFY(m_scope != nullptr); |
1748 | m_scope->setActive(true); |
1749 | } |
FAILED: Continuous integration, rev:144 jenkins. qa.ubuntu. com/job/ unity-scopes- shell-ci/ 179/ jenkins. qa.ubuntu. com/job/ unity-scopes- shell-utopic- amd64-ci/ 76/console jenkins. qa.ubuntu. com/job/ unity-scopes- shell-utopic- armhf-ci/ 76/console jenkins. qa.ubuntu. com/job/ unity-scopes- shell-utopic- i386-ci/ 76/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/ 179/rebuild
http://