Merge lp:~unity-team/unity-scopes-shell/sort-order into lp:unity-scopes-shell

Proposed by Michal Hruby
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
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.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
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

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
147. By Michal Hruby

Update for the latest interface

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
148. By Michal Hruby

Update tests

149. By Michal Hruby

Merge with drop-appid branch

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
150. By Michal Hruby

Implement refresh method

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
151. By Michal Hruby

Reset filter state on non-empty queries

152. By Michal Hruby

Merge trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Pete Woods (pete-woods) wrote :

Conflicts with trunk

153. By Michal Hruby

Merge trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Pete Woods (pete-woods) :
review: Needs Information
Revision history for this message
Michal Hruby (mhr3) :
Revision history for this message
Pete Woods (pete-woods) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/changelog'
--- debian/changelog 2014-08-05 16:42:48 +0000
+++ debian/changelog 2014-08-06 08:35:31 +0000
@@ -1,3 +1,9 @@
1unity-scopes-shell (0.5.3-0ubuntu1) UNRELEASED; urgency=medium
2
3 * Implemented shell interface version 4
4
5 -- Michal Hruby <michal.hruby@canonical.com> Fri, 01 Aug 2014 11:08:43 +0100
6
1unity-scopes-shell (0.5.2+14.10.20140805.1-0ubuntu1) utopic; urgency=low7unity-scopes-shell (0.5.2+14.10.20140805.1-0ubuntu1) utopic; urgency=low
28
3 [ Pete Woods ]9 [ Pete Woods ]
410
=== modified file 'debian/control'
--- debian/control 2014-08-01 10:25:41 +0000
+++ debian/control 2014-08-06 08:35:31 +0000
@@ -3,7 +3,7 @@
3Section: libs3Section: libs
4Build-Depends: cmake,4Build-Depends: cmake,
5 debhelper (>= 9),5 debhelper (>= 9),
6 libunity-api-dev (>= 7.87),6 libunity-api-dev (>= 7.88),
7 libunity-scopes-dev (>= 0.6.0~),7 libunity-scopes-dev (>= 0.6.0~),
8 libgsettings-qt-dev (>= 0.1),8 libgsettings-qt-dev (>= 0.1),
9 libqtdbustest1-dev (>= 0.2),9 libqtdbustest1-dev (>= 0.2),
@@ -34,8 +34,7 @@
34Provides: unity-scopes-impl,34Provides: unity-scopes-impl,
35 unity-scopes-impl-0,35 unity-scopes-impl-0,
36 unity-scopes-impl-1,36 unity-scopes-impl-1,
37 unity-scopes-impl-2,37 unity-scopes-impl-4,
38 unity-scopes-impl-3,
39Breaks: unity8-private (<< 7.84)38Breaks: unity8-private (<< 7.84)
40Replaces: unity8-private (<< 7.84)39Replaces: unity8-private (<< 7.84)
41Description: QML plugin for Scopes40Description: QML plugin for Scopes
4241
=== modified file 'src/Unity/CMakeLists.txt'
--- src/Unity/CMakeLists.txt 2014-08-01 10:25:41 +0000
+++ src/Unity/CMakeLists.txt 2014-08-06 08:35:31 +0000
@@ -2,7 +2,7 @@
2include(Plugins)2include(Plugins)
33
4# Dependencies4# Dependencies
5pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=3)5pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=4)
6pkg_check_modules(SCOPESLIB REQUIRED libunity-scopes>=0.6.0)6pkg_check_modules(SCOPESLIB REQUIRED libunity-scopes>=0.6.0)
7pkg_check_modules(GSETTINGSQT REQUIRED gsettings-qt)7pkg_check_modules(GSETTINGSQT REQUIRED gsettings-qt)
8pkg_check_modules(U1DB REQUIRED libu1db-qt5)8pkg_check_modules(U1DB REQUIRED libu1db-qt5)
@@ -41,7 +41,7 @@
41 # We need these headers here so moc runs and we get the moc-stuff41 # We need these headers here so moc runs and we get the moc-stuff
42 # compiled in, otherwise we miss some symbols42 # compiled in, otherwise we miss some symbols
43 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/CategoriesInterface.h43 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/CategoriesInterface.h
44 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/DepartmentInterface.h44 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/NavigationInterface.h
45 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewModelInterface.h45 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewModelInterface.h
46 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewStackInterface.h46 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewStackInterface.h
47 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewWidgetModelInterface.h47 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewWidgetModelInterface.h
4848
=== modified file 'src/Unity/collectors.cpp'
--- src/Unity/collectors.cpp 2014-08-01 10:34:32 +0000
+++ src/Unity/collectors.cpp 2014-08-06 08:35:31 +0000
@@ -93,7 +93,19 @@
93 m_rootDepartment = department;93 m_rootDepartment = department;
94 }94 }
9595
96 Status collect(QList<scopes::CategorisedResult::SPtr>& out_results, scopes::Department::SCPtr& out_rootDepartment)96 void setSortOrder(scopes::OptionSelectorFilter::SCPtr const& sortOrder)
97 {
98 QMutexLocker locker(&m_mutex);
99 m_sortOrderFilter = sortOrder;
100 }
101
102 void setFilterState(scopes::FilterState const& state)
103 {
104 QMutexLocker locker(&m_mutex);
105 m_filterState = state;
106 }
107
108 Status collect(QList<scopes::CategorisedResult::SPtr>& out_results, scopes::Department::SCPtr& out_rootDepartment, scopes::OptionSelectorFilter::SCPtr& out_sortOrder, scopes::FilterState& out_filterState)
97 {109 {
98 Status status;110 Status status;
99111
@@ -106,12 +118,17 @@
106 m_results.swap(out_results);118 m_results.swap(out_results);
107 out_rootDepartment = m_rootDepartment;119 out_rootDepartment = m_rootDepartment;
108120
121 out_sortOrder = m_sortOrderFilter;
122 out_filterState = m_filterState;
123
109 return status;124 return status;
110 }125 }
111126
112private:127private:
113 QList<scopes::CategorisedResult::SPtr> m_results;128 QList<scopes::CategorisedResult::SPtr> m_results;
114 scopes::Department::SCPtr m_rootDepartment;129 scopes::Department::SCPtr m_rootDepartment;
130 scopes::OptionSelectorFilter::SCPtr m_sortOrderFilter;
131 scopes::FilterState m_filterState;
115};132};
116133
117class PreviewDataCollector: public CollectorBase134class PreviewDataCollector: public CollectorBase
@@ -222,10 +239,10 @@
222 return m_collector->msecsSinceStart();239 return m_collector->msecsSinceStart();
223}240}
224241
225CollectorBase::Status PushEvent::collectSearchResults(QList<scopes::CategorisedResult::SPtr>& out_results, scopes::Department::SCPtr& rootDepartment)242CollectorBase::Status PushEvent::collectSearchResults(QList<scopes::CategorisedResult::SPtr>& out_results, scopes::Department::SCPtr& rootDepartment, scopes::OptionSelectorFilter::SCPtr& sortOrder, scopes::FilterState& filterState)
226{243{
227 auto collector = std::dynamic_pointer_cast<SearchDataCollector>(m_collector);244 auto collector = std::dynamic_pointer_cast<SearchDataCollector>(m_collector);
228 return collector->collect(out_results, rootDepartment);245 return collector->collect(out_results, rootDepartment, sortOrder, filterState);
229}246}
230247
231CollectorBase::Status PushEvent::collectPreviewData(scopes::ColumnLayoutList& out_columns, scopes::PreviewWidgetList& out_widgets, QHash<QString, QVariant>& out_data)248CollectorBase::Status PushEvent::collectPreviewData(scopes::ColumnLayoutList& out_columns, scopes::PreviewWidgetList& out_widgets, QHash<QString, QVariant>& out_data)
@@ -287,6 +304,23 @@
287 m_collector->setDepartment(department);304 m_collector->setDepartment(department);
288}305}
289306
307void SearchResultReceiver::push(scopes::Filters const& filters, scopes::FilterState const& state)
308{
309 for (auto it = filters.begin(); it != filters.end(); ++it) {
310 scopes::FilterBase::SCPtr filter = *it;
311 if (filter->display_hints() == scopes::FilterBase::DisplayHints::Primary) {
312 scopes::OptionSelectorFilter::SCPtr option_filter = std::dynamic_pointer_cast<const scopes::OptionSelectorFilter>(filter);
313 if (!option_filter) {
314 continue;
315 } else {
316 m_collector->setSortOrder(option_filter);
317 break;
318 }
319 }
320 }
321 m_collector->setFilterState(state);
322}
323
290// this might be called from any thread (might be main, might be any other thread)324// this might be called from any thread (might be main, might be any other thread)
291void SearchResultReceiver::finished(scopes::CompletionDetails const& details)325void SearchResultReceiver::finished(scopes::CompletionDetails const& details)
292{326{
293327
=== modified file 'src/Unity/collectors.h'
--- src/Unity/collectors.h 2014-08-01 10:34:32 +0000
+++ src/Unity/collectors.h 2014-08-06 08:35:31 +0000
@@ -27,12 +27,15 @@
27#include <QElapsedTimer>27#include <QElapsedTimer>
2828
29#include <unity/scopes/ActivationListenerBase.h>29#include <unity/scopes/ActivationListenerBase.h>
30#include <unity/scopes/SearchListenerBase.h>30#include <unity/scopes/ActivationResponse.h>
31#include <unity/scopes/CategorisedResult.h>
32#include <unity/scopes/FilterBase.h>
33#include <unity/scopes/FilterState.h>
34#include <unity/scopes/OptionSelectorFilter.h>
31#include <unity/scopes/PreviewListenerBase.h>35#include <unity/scopes/PreviewListenerBase.h>
32#include <unity/scopes/CategorisedResult.h>36#include <unity/scopes/PreviewWidget.h>
33#include <unity/scopes/QueryCtrl.h>37#include <unity/scopes/QueryCtrl.h>
34#include <unity/scopes/PreviewWidget.h>38#include <unity/scopes/SearchListenerBase.h>
35#include <unity/scopes/ActivationResponse.h>
3639
37namespace scopes_ng40namespace scopes_ng
38{41{
@@ -73,7 +76,7 @@
73 PushEvent(Type event_type, std::shared_ptr<CollectorBase> collector);76 PushEvent(Type event_type, std::shared_ptr<CollectorBase> collector);
74 Type type();77 Type type();
7578
76 CollectorBase::Status collectSearchResults(QList<std::shared_ptr<unity::scopes::CategorisedResult>>& out_results, unity::scopes::Department::SCPtr& out_rootDepartment);79 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);
77 CollectorBase::Status collectPreviewData(unity::scopes::ColumnLayoutList& out_columns, unity::scopes::PreviewWidgetList& out_widgets, QHash<QString, QVariant>& out_data);80 CollectorBase::Status collectPreviewData(unity::scopes::ColumnLayoutList& out_columns, unity::scopes::PreviewWidgetList& out_widgets, QHash<QString, QVariant>& out_data);
78 CollectorBase::Status collectActivationResponse(std::shared_ptr<unity::scopes::ActivationResponse>& out_response, std::shared_ptr<unity::scopes::Result>& out_result);81 CollectorBase::Status collectActivationResponse(std::shared_ptr<unity::scopes::ActivationResponse>& out_response, std::shared_ptr<unity::scopes::Result>& out_result);
7982
@@ -105,6 +108,7 @@
105public:108public:
106 virtual void push(unity::scopes::CategorisedResult result) override;109 virtual void push(unity::scopes::CategorisedResult result) override;
107 virtual void push(unity::scopes::Department::SCPtr const& department) override;110 virtual void push(unity::scopes::Department::SCPtr const& department) override;
111 virtual void push(unity::scopes::Filters const& filters, unity::scopes::FilterState const& state) override;
108 virtual void finished(unity::scopes::CompletionDetails const& details) override;112 virtual void finished(unity::scopes::CompletionDetails const& details) override;
109113
110 SearchResultReceiver(QObject* receiver);114 SearchResultReceiver(QObject* receiver);
111115
=== modified file 'src/Unity/department.cpp'
--- src/Unity/department.cpp 2014-06-12 11:34:44 +0000
+++ src/Unity/department.cpp 2014-08-06 08:35:31 +0000
@@ -19,16 +19,22 @@
1919
20#include "department.h"20#include "department.h"
2121
22#include <unity/scopes/OptionSelectorFilter.h>
23
22namespace scopes_ng24namespace scopes_ng
23{25{
2426
25using namespace unity;27using namespace unity;
2628
27Department::Department(QObject* parent) :29Department::Department(QObject* parent) :
28 unity::shell::scopes::DepartmentInterface(parent),30 unity::shell::scopes::NavigationInterface(parent),
29 m_loaded(false),31 m_loaded(false), m_isRoot(false), m_hidden(false), m_isFilter(false)
30 m_isRoot(false)32{
31{33}
34
35void Department::setScopeId(QString const& scopeId)
36{
37 m_scopeId = scopeId;
32}38}
3339
34void Department::loadFromDepartmentNode(DepartmentNode* treeNode)40void Department::loadFromDepartmentNode(DepartmentNode* treeNode)
@@ -37,14 +43,17 @@
37 qWarning("Tried to set null DepartmentNode!");43 qWarning("Tried to set null DepartmentNode!");
38 return;44 return;
39 }45 }
40 m_departmentId = treeNode->id();46 m_navigationId = treeNode->id();
47 m_filterId = treeNode->filterId();
41 m_label = treeNode->label();48 m_label = treeNode->label();
42 m_allLabel = treeNode->allLabel();49 m_allLabel = treeNode->allLabel();
43 m_loaded = !treeNode->isLeaf() && treeNode->childCount() > 0;50 m_loaded = !treeNode->isLeaf() && treeNode->childCount() > 0;
44 m_isRoot = treeNode->isRoot();51 m_isRoot = treeNode->isRoot();
52 m_hidden = treeNode->hidden();
53 m_isFilter = treeNode->isFilter();
4554
46 DepartmentNode* parentNode = treeNode->parent();55 DepartmentNode* parentNode = treeNode->parent();
47 m_parentDepartmentId = parentNode ? parentNode->id() : "";56 m_parentNavigationId = parentNode ? parentNode->id() : "";
48 m_parentLabel = parentNode ? parentNode->label() : "";57 m_parentLabel = parentNode ? parentNode->label() : "";
4958
50 beginResetModel();59 beginResetModel();
@@ -61,14 +70,15 @@
6170
62 endResetModel();71 endResetModel();
6372
64 Q_EMIT departmentIdChanged();73 Q_EMIT navigationIdChanged();
65 Q_EMIT labelChanged();74 Q_EMIT labelChanged();
66 Q_EMIT allLabelChanged();75 Q_EMIT allLabelChanged();
67 Q_EMIT parentDepartmentIdChanged();76 Q_EMIT parentNavigationIdChanged();
68 Q_EMIT parentLabelChanged();77 Q_EMIT parentLabelChanged();
69 Q_EMIT loadedChanged();78 Q_EMIT loadedChanged();
70 Q_EMIT countChanged();79 Q_EMIT countChanged();
71 Q_EMIT isRootChanged();80 Q_EMIT isRootChanged();
81 Q_EMIT hiddenChanged();
72}82}
7383
74void Department::markSubdepartmentActive(QString const& subdepartmentId)84void Department::markSubdepartmentActive(QString const& subdepartmentId)
@@ -100,7 +110,7 @@
100{110{
101 SubdepartmentData* data = m_subdepartments[index.row()].data();111 SubdepartmentData* data = m_subdepartments[index.row()].data();
102 switch (role) {112 switch (role) {
103 case RoleDepartmentId: return data->id;113 case RoleNavigationId: return data->id;
104 case RoleLabel: return data->label;114 case RoleLabel: return data->label;
105 case RoleHasChildren: return data->hasChildren;115 case RoleHasChildren: return data->hasChildren;
106 case RoleIsActive: return data->isActive;116 case RoleIsActive: return data->isActive;
@@ -114,9 +124,9 @@
114 return m_subdepartments.size();124 return m_subdepartments.size();
115}125}
116126
117QString Department::departmentId() const127QString Department::navigationId() const
118{128{
119 return m_departmentId;129 return m_navigationId;
120}130}
121131
122QString Department::label() const132QString Department::label() const
@@ -129,9 +139,9 @@
129 return m_allLabel;139 return m_allLabel;
130}140}
131141
132QString Department::parentDepartmentId() const142QString Department::parentNavigationId() const
133{143{
134 return m_parentDepartmentId;144 return m_parentNavigationId;
135}145}
136146
137QString Department::parentLabel() const147QString Department::parentLabel() const
@@ -149,6 +159,11 @@
149 return m_isRoot;159 return m_isRoot;
150}160}
151161
162bool Department::hidden() const
163{
164 return m_hidden;
165}
166
152int Department::count() const167int Department::count() const
153{168{
154 return rowCount();169 return rowCount();
155170
=== modified file 'src/Unity/department.h'
--- src/Unity/department.h 2014-06-12 11:34:44 +0000
+++ src/Unity/department.h 2014-08-06 08:35:31 +0000
@@ -21,7 +21,7 @@
21#ifndef NG_DEPARTMENT_H21#ifndef NG_DEPARTMENT_H
22#define NG_DEPARTMENT_H22#define NG_DEPARTMENT_H
2323
24#include <unity/shell/scopes/DepartmentInterface.h>24#include <unity/shell/scopes/NavigationInterface.h>
2525
26#include <QString>26#include <QString>
27#include <QSharedPointer>27#include <QSharedPointer>
@@ -44,37 +44,43 @@
44 bool isActive;44 bool isActive;
45};45};
4646
47class Q_DECL_EXPORT Department : public unity::shell::scopes::DepartmentInterface47class Q_DECL_EXPORT Department : public unity::shell::scopes::NavigationInterface
48{48{
49 Q_OBJECT49 Q_OBJECT
5050
51public:51public:
52 explicit Department(QObject* parent = 0);52 explicit Department(QObject* parent = 0);
53 void setScopeId(QString const& scopeId);
53 void loadFromDepartmentNode(DepartmentNode* treeNode);54 void loadFromDepartmentNode(DepartmentNode* treeNode);
54 void markSubdepartmentActive(QString const& subdepartmentId);55 void markSubdepartmentActive(QString const& subdepartmentId);
5556
56 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;57 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
57 int rowCount(const QModelIndex& parent = QModelIndex()) const override;58 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
5859
59 QString departmentId() const override;60 QString navigationId() const override;
60 QString label() const override;61 QString label() const override;
61 QString allLabel() const override;62 QString allLabel() const override;
62 QString parentDepartmentId() const override;63 QString parentNavigationId() const override;
63 QString parentLabel() const override;64 QString parentLabel() const override;
64 bool loaded() const override;65 bool loaded() const override;
65 bool isRoot() const override;66 bool isRoot() const override;
67 bool hidden() const override;
66 int count() const override;68 int count() const override;
6769
68Q_SIGNALS:70Q_SIGNALS:
6971
70private:72private:
71 QString m_departmentId;73 QString m_navigationId;
74 QString m_scopeId;
75 QString m_filterId;
72 QString m_label;76 QString m_label;
73 QString m_allLabel;77 QString m_allLabel;
74 QString m_parentDepartmentId;78 QString m_parentNavigationId;
75 QString m_parentLabel;79 QString m_parentLabel;
76 bool m_loaded;80 bool m_loaded;
77 bool m_isRoot;81 bool m_isRoot;
82 bool m_hidden;
83 bool m_isFilter;
7884
79 QList<QSharedPointer<SubdepartmentData>> m_subdepartments;85 QList<QSharedPointer<SubdepartmentData>> m_subdepartments;
80};86};
8187
=== modified file 'src/Unity/departmentnode.cpp'
--- src/Unity/departmentnode.cpp 2014-05-28 07:04:50 +0000
+++ src/Unity/departmentnode.cpp 2014-08-06 08:35:31 +0000
@@ -24,7 +24,11 @@
2424
25using namespace unity;25using namespace unity;
2626
27DepartmentNode::DepartmentNode(DepartmentNode* parent) : m_parent(parent), m_isRoot(false)27DepartmentNode::DepartmentNode(DepartmentNode* parent)
28 : m_parent(parent)
29 , m_isRoot(false)
30 , m_hidden(false)
31 , m_isFilter(false)
28{32{
29}33}
3034
@@ -39,6 +43,8 @@
39 m_label = QString::fromStdString(dep->label());43 m_label = QString::fromStdString(dep->label());
40 m_allLabel = QString::fromStdString(dep->alternate_label());44 m_allLabel = QString::fromStdString(dep->alternate_label());
41 m_hasSubdepartments = dep->has_subdepartments();45 m_hasSubdepartments = dep->has_subdepartments();
46 m_hidden = false;
47 m_isFilter = false;
4248
43 clearChildren();49 clearChildren();
4450
@@ -50,6 +56,41 @@
50 }56 }
51}57}
5258
59void DepartmentNode::initializeForFilter(scopes::OptionSelectorFilter::SCPtr const& filter)
60{
61 auto children = filter->options();
62 m_id = QString(""); // this is root (which we shouldn't show really)
63 m_filterId = QString::fromStdString(filter->id());
64 m_label = QString::fromStdString(filter->label());
65 m_allLabel = QString();
66 m_hasSubdepartments = !children.empty();
67 m_isRoot = true;
68 m_hidden = true;
69 m_isFilter = true;
70
71 clearChildren();
72
73 for (auto it = children.begin(); it != children.end(); ++it) {
74 DepartmentNode* subdep = new DepartmentNode(this);
75 subdep->initializeForFilterOption(*it, m_filterId);
76 this->appendChild(subdep);
77 }
78}
79
80void DepartmentNode::initializeForFilterOption(scopes::FilterOption::SCPtr const& option, QString const& filterId)
81{
82 m_id = QString::fromStdString(option->id());
83 m_filterId = filterId;
84 m_label = QString::fromStdString(option->label());
85 m_allLabel = QString();
86 m_hasSubdepartments = false;
87 m_isRoot = false;
88 m_hidden = false;
89 m_isFilter = true;
90
91 clearChildren();
92}
93
53void DepartmentNode::setIsRoot(bool isRoot)94void DepartmentNode::setIsRoot(bool isRoot)
54{95{
55 m_isRoot = isRoot;96 m_isRoot = isRoot;
@@ -60,6 +101,16 @@
60 return m_isRoot;101 return m_isRoot;
61}102}
62103
104bool DepartmentNode::hidden() const
105{
106 return m_hidden;
107}
108
109bool DepartmentNode::isFilter() const
110{
111 return m_isFilter;
112}
113
63DepartmentNode* DepartmentNode::findNodeById(QString const& id)114DepartmentNode* DepartmentNode::findNodeById(QString const& id)
64{115{
65 if (id == m_id) return this;116 if (id == m_id) return this;
@@ -87,6 +138,11 @@
87 return m_allLabel;138 return m_allLabel;
88}139}
89140
141QString DepartmentNode::filterId() const
142{
143 return m_filterId;
144}
145
90bool DepartmentNode::hasSubdepartments() const146bool DepartmentNode::hasSubdepartments() const
91{147{
92 return m_hasSubdepartments;148 return m_hasSubdepartments;
93149
=== modified file 'src/Unity/departmentnode.h'
--- src/Unity/departmentnode.h 2014-05-28 07:04:50 +0000
+++ src/Unity/departmentnode.h 2014-08-06 08:35:31 +0000
@@ -38,6 +38,7 @@
38 ~DepartmentNode();38 ~DepartmentNode();
3939
40 void initializeForDepartment(unity::scopes::Department::SCPtr const& dep);40 void initializeForDepartment(unity::scopes::Department::SCPtr const& dep);
41 void initializeForFilter(unity::scopes::OptionSelectorFilter::SCPtr const& filter);
41 DepartmentNode* findNodeById(QString const& id);42 DepartmentNode* findNodeById(QString const& id);
4243
43 QString id() const;44 QString id() const;
@@ -45,6 +46,8 @@
45 QString allLabel() const;46 QString allLabel() const;
46 bool hasSubdepartments() const;47 bool hasSubdepartments() const;
47 bool isRoot() const;48 bool isRoot() const;
49 bool hidden() const;
50 bool isFilter() const;
4851
49 void setIsRoot(bool isRoot);52 void setIsRoot(bool isRoot);
5053
@@ -53,17 +56,22 @@
53 bool isLeaf() const;56 bool isLeaf() const;
54 QList<DepartmentNode*> childNodes() const;57 QList<DepartmentNode*> childNodes() const;
55 DepartmentNode* parent() const;58 DepartmentNode* parent() const;
59 QString filterId() const;
5660
57private:61private:
58 void clearChildren();62 void clearChildren();
63 void initializeForFilterOption(unity::scopes::FilterOption::SCPtr const&, QString const&);
5964
60 DepartmentNode* m_parent;65 DepartmentNode* m_parent;
61 QList<DepartmentNode*> m_children;66 QList<DepartmentNode*> m_children;
62 QString m_id;67 QString m_id;
63 QString m_label;68 QString m_label;
64 QString m_allLabel;69 QString m_allLabel;
70 QString m_filterId;
65 bool m_hasSubdepartments;71 bool m_hasSubdepartments;
66 bool m_isRoot;72 bool m_isRoot;
73 bool m_hidden;
74 bool m_isFilter;
67};75};
6876
69} // namespace scopes_ng77} // namespace scopes_ng
7078
=== modified file 'src/Unity/overviewscope.cpp'
--- src/Unity/overviewscope.cpp 2014-07-23 12:32:48 +0000
+++ src/Unity/overviewscope.cpp 2014-08-06 08:35:31 +0000
@@ -96,11 +96,6 @@
96 return QString("scopes");96 return QString("scopes");
97}97}
9898
99bool OverviewScope::visible() const
100{
101 return false;
102}
103
104scopes::ScopeProxy OverviewScope::proxy_for_result(scopes::Result::SPtr const& result) const99scopes::ScopeProxy OverviewScope::proxy_for_result(scopes::Result::SPtr const& result) const
105{100{
106 try {101 try {
107102
=== modified file 'src/Unity/overviewscope.h'
--- src/Unity/overviewscope.h 2014-07-18 17:10:39 +0000
+++ src/Unity/overviewscope.h 2014-08-06 08:35:31 +0000
@@ -35,7 +35,6 @@
3535
36 /* getters */36 /* getters */
37 QString id() const override;37 QString id() const override;
38 bool visible() const override;
3938
40 void dispatchSearch() override;39 void dispatchSearch() override;
4140
4241
=== modified file 'src/Unity/plugin.cpp'
--- src/Unity/plugin.cpp 2014-06-11 17:08:34 +0000
+++ src/Unity/plugin.cpp 2014-08-06 08:35:31 +0000
@@ -41,7 +41,7 @@
41 // new Scopes classes41 // new Scopes classes
42 qmlRegisterType<scopes_ng::Scopes>(uri, 0, 2, "Scopes");42 qmlRegisterType<scopes_ng::Scopes>(uri, 0, 2, "Scopes");
43 qmlRegisterUncreatableType<unity::shell::scopes::ScopeInterface>(uri, 0, 2, "Scope", "Can't create Scope object in QML. Get them from Scopes instance.");43 qmlRegisterUncreatableType<unity::shell::scopes::ScopeInterface>(uri, 0, 2, "Scope", "Can't create Scope object in QML. Get them from Scopes instance.");
44 qmlRegisterUncreatableType<unity::shell::scopes::DepartmentInterface>(uri, 0, 2, "Department", "Can't create Department object in QML. Get them from Scope instance.");44 qmlRegisterUncreatableType<unity::shell::scopes::NavigationInterface>(uri, 0, 2, "Navigation", "Can't create Navigation object in QML. Get them from Scope instance.");
45 qmlRegisterUncreatableType<unity::shell::scopes::CategoriesInterface>(uri, 0, 2, "Categories", "Can't create Categories object in QML. Get them from Scope instance.");45 qmlRegisterUncreatableType<unity::shell::scopes::CategoriesInterface>(uri, 0, 2, "Categories", "Can't create Categories object in QML. Get them from Scope instance.");
46 qmlRegisterUncreatableType<unity::shell::scopes::SettingsModelInterface>(uri, 0, 2, "Settings", "Can't create Settings object in QML. Get them from Scope instance.");46 qmlRegisterUncreatableType<unity::shell::scopes::SettingsModelInterface>(uri, 0, 2, "Settings", "Can't create Settings object in QML. Get them from Scope instance.");
47 qmlRegisterUncreatableType<scopes_ng::ResultsModel>(uri, 0, 2, "ResultsModel", "Can't create new ResultsModel in QML. Get them from Categories instance.");47 qmlRegisterUncreatableType<scopes_ng::ResultsModel>(uri, 0, 2, "ResultsModel", "Can't create new ResultsModel in QML. Get them from Categories instance.");
4848
=== modified file 'src/Unity/scope.cpp'
--- src/Unity/scope.cpp 2014-08-05 16:24:32 +0000
+++ src/Unity/scope.cpp 2014-08-06 08:35:31 +0000
@@ -47,6 +47,8 @@
47#include <libintl.h>47#include <libintl.h>
4848
49#include <unity/scopes/ListenerBase.h>49#include <unity/scopes/ListenerBase.h>
50#include <unity/scopes/CannedQuery.h>
51#include <unity/scopes/OptionSelectorFilter.h>
50#include <unity/scopes/CategorisedResult.h>52#include <unity/scopes/CategorisedResult.h>
51#include <unity/scopes/QueryCtrl.h>53#include <unity/scopes/QueryCtrl.h>
52#include <unity/scopes/PreviewWidget.h>54#include <unity/scopes/PreviewWidget.h>
@@ -70,9 +72,11 @@
70 , m_searchInProgress(false)72 , m_searchInProgress(false)
71 , m_resultsDirty(false)73 , m_resultsDirty(false)
72 , m_delayedClear(false)74 , m_delayedClear(false)
73 , m_hasDepartments(false)75 , m_hasNavigation(false)
76 , m_hasAltNavigation(false)
74 , m_searchController(new CollectionController)77 , m_searchController(new CollectionController)
75 , m_activationController(new CollectionController)78 , m_activationController(new CollectionController)
79 , m_status(Status::Okay)
76{80{
77 m_categories.reset(new Categories(this));81 m_categories.reset(new Categories(this));
7882
@@ -99,13 +103,17 @@
99 CollectorBase::Status status;103 CollectorBase::Status status;
100 QList<std::shared_ptr<scopes::CategorisedResult>> results;104 QList<std::shared_ptr<scopes::CategorisedResult>> results;
101 scopes::Department::SCPtr rootDepartment;105 scopes::Department::SCPtr rootDepartment;
106 scopes::OptionSelectorFilter::SCPtr sortOrderFilter;
107 scopes::FilterState filterState;
102108
103 status = pushEvent->collectSearchResults(results, rootDepartment);109 status = pushEvent->collectSearchResults(results, rootDepartment, sortOrderFilter, filterState);
104 if (status == CollectorBase::Status::CANCELLED) {110 if (status == CollectorBase::Status::CANCELLED) {
105 return;111 return;
106 }112 }
107113
108 m_rootDepartment = rootDepartment;114 m_rootDepartment = rootDepartment;
115 m_sortOrderFilter = sortOrderFilter;
116 m_receivedFilterState = filterState;
109117
110 if (m_cachedResults.empty()) {118 if (m_cachedResults.empty()) {
111 m_cachedResults.swap(results);119 m_cachedResults.swap(results);
@@ -126,6 +134,7 @@
126 flushUpdates();134 flushUpdates();
127135
128 setSearchInProgress(false);136 setSearchInProgress(false);
137 setStatus(status == CollectorBase::Status::FINISHED ? Status::Okay : Status::Unknown);
129138
130 // Don't schedule a refresh if the query suffered an error139 // Don't schedule a refresh if the query suffered an error
131 if (status == CollectorBase::Status::FINISHED) {140 if (status == CollectorBase::Status::FINISHED) {
@@ -226,9 +235,13 @@
226 }235 }
227236
228 if (scope != nullptr) {237 if (scope != nullptr) {
229 // TODO: change filters?238 scope->setCurrentNavigationId(departmentId);
230 scope->setCurrentDepartmentId(departmentId);239 scope->setFilterState(query.filter_state());
231 scope->setSearchQuery(searchString);240 scope->setSearchQuery(searchString);
241 // FIXME: implement better way to do multiple changes to search props and dispatch single search
242 if (!scope->searchInProgress()) {
243 scope->invalidateResults();
244 }
232 if (scope != this) Q_EMIT gotoScope(scopeId);245 if (scope != this) Q_EMIT gotoScope(scopeId);
233 } else {246 } else {
234 // create temp dash page247 // create temp dash page
@@ -237,7 +250,8 @@
237 scope = new scopes_ng::Scope(this);250 scope = new scopes_ng::Scope(this);
238 scope->setScopeData(*meta_sptr);251 scope->setScopeData(*meta_sptr);
239 scope->setScopesInstance(m_scopesInstance);252 scope->setScopesInstance(m_scopesInstance);
240 scope->setCurrentDepartmentId(departmentId);253 scope->setCurrentNavigationId(departmentId);
254 scope->setFilterState(query.filter_state());
241 scope->setSearchQuery(searchString);255 scope->setSearchQuery(searchString);
242 m_tempScopes.insert(scope);256 m_tempScopes.insert(scope);
243 Q_EMIT openScope(scope);257 Q_EMIT openScope(scope);
@@ -263,6 +277,9 @@
263 m_clearTimer.stop();277 m_clearTimer.stop();
264 }278 }
265279
280 if (m_status != Status::Okay) {
281 setStatus(Status::Okay);
282 }
266 processResultSet(m_cachedResults); // clears the result list283 processResultSet(m_cachedResults); // clears the result list
267284
268 // process departments285 // process departments
@@ -289,25 +306,7 @@
289 m_departmentTree->setIsRoot(true);306 m_departmentTree->setIsRoot(true);
290307
291 // update corresponding models308 // update corresponding models
292 QString activeDepartment(m_currentDepartmentId);309 updateNavigationModels(m_departmentTree.data(), m_departmentModels, m_currentNavigationId);
293 node = m_departmentTree->findNodeById(activeDepartment);
294 DepartmentNode* parentNode = nullptr;
295 if (node != nullptr) {
296 auto it = m_departmentModels.find(activeDepartment);
297 while (it != m_departmentModels.end() && it.key() == activeDepartment) {
298 it.value()->loadFromDepartmentNode(node);
299 ++it;
300 }
301 // if this node is a leaf, we need to update models for the parent
302 parentNode = node->isLeaf() ? node->parent() : nullptr;
303 }
304 if (parentNode != nullptr) {
305 auto it = m_departmentModels.find(parentNode->id());
306 while (it != m_departmentModels.end() && it.key() == parentNode->id()) {
307 it.value()->markSubdepartmentActive(activeDepartment);
308 ++it;
309 }
310 }
311 } else {310 } else {
312 m_departmentTree.reset(new DepartmentNode);311 m_departmentTree.reset(new DepartmentNode);
313 m_departmentTree->initializeForDepartment(m_rootDepartment);312 m_departmentTree->initializeForDepartment(m_rootDepartment);
@@ -320,17 +319,80 @@
320 m_lastRootDepartment = m_rootDepartment;319 m_lastRootDepartment = m_rootDepartment;
321320
322 bool containsDepartments = m_rootDepartment.get() != nullptr;321 bool containsDepartments = m_rootDepartment.get() != nullptr;
323 // design decision - no departments when doing searches322 // design decision - no navigation when doing searches
324 containsDepartments &= m_searchQuery.isEmpty();323 containsDepartments &= m_searchQuery.isEmpty();
325324
326 if (containsDepartments != m_hasDepartments) {325 if (containsDepartments != m_hasNavigation) {
327 m_hasDepartments = containsDepartments;326 m_hasNavigation = containsDepartments;
328 Q_EMIT hasDepartmentsChanged();327 Q_EMIT hasNavigationChanged();
329 }328 }
330329
331 if (!containsDepartments && !m_currentDepartmentId.isEmpty()) {330 if (!containsDepartments && !m_currentNavigationId.isEmpty()) {
332 m_currentDepartmentId = "";331 m_currentNavigationId = "";
333 Q_EMIT currentDepartmentIdChanged();332 Q_EMIT currentNavigationIdChanged();
333 }
334
335 // process the alt navigation (sort order filter)
336 QString currentAltNav(m_currentAltNavigationId);
337
338 if (m_sortOrderFilter && m_sortOrderFilter != m_lastSortOrderFilter) {
339 // build the nodes
340 m_altNavTree.reset(new DepartmentNode);
341 m_altNavTree->initializeForFilter(m_sortOrderFilter);
342
343 if (m_sortOrderFilter->has_active_option(m_receivedFilterState)) {
344 auto active_options = m_sortOrderFilter->active_options(m_receivedFilterState);
345 scopes::FilterOption::SCPtr active_option = *active_options.begin();
346 if (active_option) {
347 currentAltNav = QString::fromStdString(active_option->id());
348 }
349 }
350 }
351
352 m_lastSortOrderFilter = m_sortOrderFilter;
353
354 bool containsAltNav = m_sortOrderFilter.get() != nullptr;
355 // design decision - no navigation when doing searches
356 containsAltNav &= m_searchQuery.isEmpty();
357
358 if (containsAltNav != m_hasAltNavigation) {
359 m_hasAltNavigation = containsAltNav;
360 Q_EMIT hasAltNavigationChanged();
361 }
362
363 if (!containsAltNav && !m_currentAltNavigationId.isEmpty()) {
364 m_currentAltNavigationId = "";
365 Q_EMIT currentAltNavigationIdChanged();
366 }
367
368 if (containsAltNav && currentAltNav != m_currentAltNavigationId) {
369 m_currentAltNavigationId = currentAltNav;
370 Q_EMIT currentAltNavigationIdChanged();
371
372 // update the alt navigation models
373 updateNavigationModels(m_altNavTree.data(), m_altNavModels, m_currentAltNavigationId);
374 }
375}
376
377void Scope::updateNavigationModels(DepartmentNode* rootNode, QMultiMap<QString, Department*>& navigationModels, QString const& activeNavigation)
378{
379 DepartmentNode* parentNode = nullptr;
380 DepartmentNode* node = rootNode->findNodeById(activeNavigation);
381 if (node != nullptr) {
382 auto it = navigationModels.find(activeNavigation);
383 while (it != navigationModels.end() && it.key() == activeNavigation) {
384 it.value()->loadFromDepartmentNode(node);
385 ++it;
386 }
387 // if this node is a leaf, we need to update models for the parent
388 parentNode = node->isLeaf() ? node->parent() : nullptr;
389 }
390 if (parentNode != nullptr) {
391 auto it = navigationModels.find(parentNode->id());
392 while (it != navigationModels.end() && it.key() == parentNode->id()) {
393 it.value()->markSubdepartmentActive(activeNavigation);
394 ++it;
395 }
334 }396 }
335}397}
336398
@@ -494,12 +556,25 @@
494 }556 }
495}557}
496558
497void Scope::setCurrentDepartmentId(QString const& id)559void Scope::setStatus(shell::scopes::ScopeInterface::Status status)
498{560{
499 if (m_currentDepartmentId != id) {561 if (m_status != status) {
500 m_currentDepartmentId = id;562 m_status = status;
501 Q_EMIT currentDepartmentIdChanged();563 Q_EMIT statusChanged();
502 }564 }
565}
566
567void Scope::setCurrentNavigationId(QString const& id)
568{
569 if (m_currentNavigationId != id) {
570 m_currentNavigationId = id;
571 Q_EMIT currentNavigationIdChanged();
572 }
573}
574
575void Scope::setFilterState(scopes::FilterState const& filterState)
576{
577 m_filterState = filterState;
503}578}
504579
505void Scope::dispatchSearch()580void Scope::dispatchSearch()
@@ -554,7 +629,7 @@
554 scopes::SearchListenerBase::SPtr listener(new SearchResultReceiver(this));629 scopes::SearchListenerBase::SPtr listener(new SearchResultReceiver(this));
555 m_searchController->setListener(listener);630 m_searchController->setListener(listener);
556 try {631 try {
557 scopes::QueryCtrlProxy controller = m_proxy->search(m_searchQuery.toStdString(), m_currentDepartmentId.toStdString(), scopes::FilterState(), meta, listener);632 scopes::QueryCtrlProxy controller = m_proxy->search(m_searchQuery.toStdString(), m_currentNavigationId.toStdString(), m_filterState, meta, listener);
558 m_searchController->setController(controller);633 m_searchController->setController(controller);
559 } catch (std::exception& e) {634 } catch (std::exception& e) {
560 qWarning("Caught an error from create_query(): %s", e.what());635 qWarning("Caught an error from create_query(): %s", e.what());
@@ -652,9 +727,13 @@
652 return m_searchInProgress;727 return m_searchInProgress;
653}728}
654729
655bool Scope::visible() const730unity::shell::scopes::ScopeInterface::Status Scope::status() const
656{731{
657 // FIXME: get from scope config732 return m_status;
733}
734
735bool Scope::favorite() const
736{
658 return true;737 return true;
659}738}
660739
@@ -689,42 +768,86 @@
689}768}
690*/769*/
691770
692unity::shell::scopes::DepartmentInterface* Scope::getDepartment(QString const& departmentId)771unity::shell::scopes::NavigationInterface* Scope::getNavigation(QString const& navId)
693{772{
694 if (!m_departmentTree) return nullptr;773 if (!m_departmentTree) return nullptr;
695774
696 DepartmentNode* node = m_departmentTree->findNodeById(departmentId);775 DepartmentNode* node = m_departmentTree->findNodeById(navId);
697 if (!node) return nullptr;776 if (!node) return nullptr;
698777
699 Department* departmentModel = new Department;778 Department* navModel = new Department;
700 departmentModel->loadFromDepartmentNode(node);779 navModel->setScopeId(this->id());
701780 navModel->loadFromDepartmentNode(node);
702 m_departmentModels.insert(departmentId, departmentModel);781 navModel->markSubdepartmentActive(m_currentNavigationId);
703 m_inverseDepartments.insert(departmentModel, departmentId);782
704 QObject::connect(departmentModel, &QObject::destroyed, this, &Scope::departmentModelDestroyed);783 // sharing m_inverseDepartments with getAltNavigation
705784 m_departmentModels.insert(navId, navModel);
706 return departmentModel;785 m_inverseDepartments.insert(navModel, navId);
786 QObject::connect(navModel, &QObject::destroyed, this, &Scope::departmentModelDestroyed);
787
788 return navModel;
789}
790
791unity::shell::scopes::NavigationInterface* Scope::getAltNavigation(QString const& navId)
792{
793 if (!m_altNavTree) return nullptr;
794
795 DepartmentNode* node = m_altNavTree->findNodeById(navId);
796 if (!node) return nullptr;
797
798 Department* navModel = new Department;
799 navModel->setScopeId(this->id());
800 navModel->loadFromDepartmentNode(node);
801 navModel->markSubdepartmentActive(m_currentAltNavigationId);
802
803 // sharing m_inverseDepartments with getNavigation
804 m_altNavModels.insert(navId, navModel);
805 m_inverseDepartments.insert(navModel, navId);
806 QObject::connect(navModel, &QObject::destroyed, this, &Scope::departmentModelDestroyed);
807
808 return navModel;
809}
810
811QString Scope::buildQuery(QString const& scopeId, QString const& searchQuery, QString const& departmentId, QString const& primaryFilterId, QString const& primaryOptionId)
812{
813 scopes::CannedQuery q(scopeId.toStdString());
814 q.set_query_string(searchQuery.toStdString());
815 q.set_department_id(departmentId.toStdString());
816
817 if (!primaryFilterId.isEmpty() && !primaryOptionId.isEmpty()) {
818 scopes::FilterState filter_state;
819 scopes::OptionSelectorFilter::update_state(filter_state, primaryFilterId.toStdString(), primaryOptionId.toStdString(), true);
820 q.set_filter_state(filter_state);
821 }
822
823 return QString::fromStdString(q.to_uri());
824}
825
826void Scope::setNavigationState(QString const& navId, bool altNavigation)
827{
828 QString primaryFilterId;
829 if (m_sortOrderFilter) {
830 primaryFilterId = QString::fromStdString(m_sortOrderFilter->id());
831 }
832 if (!altNavigation) {
833 // switch current department id
834 performQuery(buildQuery(id(), m_searchQuery, navId, primaryFilterId, m_currentAltNavigationId));
835 } else {
836 // switch current primary filter
837 performQuery(buildQuery(id(), m_searchQuery, m_currentNavigationId, primaryFilterId, navId));
838 }
707}839}
708840
709void Scope::departmentModelDestroyed(QObject* obj)841void Scope::departmentModelDestroyed(QObject* obj)
710{842{
711 scopes_ng::Department* department = reinterpret_cast<scopes_ng::Department*>(obj);843 scopes_ng::Department* navigation = reinterpret_cast<scopes_ng::Department*>(obj);
712844
713 auto it = m_inverseDepartments.find(department);845 auto it = m_inverseDepartments.find(navigation);
714 if (it == m_inverseDepartments.end()) return;846 if (it == m_inverseDepartments.end()) return;
715847
716 m_departmentModels.remove(it.value(), department);848 m_departmentModels.remove(it.value(), navigation);
717 m_inverseDepartments.erase(it);849 m_altNavModels.remove(it.value(), navigation);
718}850 m_inverseDepartments.erase(it);
719
720void Scope::loadDepartment(QString const& departmentId)
721{
722 if (departmentId != m_currentDepartmentId) {
723 m_currentDepartmentId = departmentId;
724 Q_EMIT currentDepartmentIdChanged();
725
726 dispatchSearch();
727 }
728}851}
729852
730void Scope::performQuery(QString const& cannedQuery)853void Scope::performQuery(QString const& cannedQuery)
@@ -737,6 +860,12 @@
737 }860 }
738}861}
739862
863void Scope::refresh()
864{
865 // shell has to specifically call this, maybe we should ignore the active flag here and just call dispatchSearch
866 invalidateResults();
867}
868
740QString Scope::searchQuery() const869QString Scope::searchQuery() const
741{870{
742 return m_searchQuery;871 return m_searchQuery;
@@ -757,14 +886,24 @@
757 return m_isActive;886 return m_isActive;
758}887}
759888
760QString Scope::currentDepartmentId() const889QString Scope::currentNavigationId() const
761{890{
762 return m_currentDepartmentId;891 return m_currentNavigationId;
763}892}
764893
765bool Scope::hasDepartments() const894bool Scope::hasNavigation() const
766{895{
767 return m_hasDepartments;896 return m_hasNavigation;
897}
898
899QString Scope::currentAltNavigationId() const
900{
901 return m_currentAltNavigationId;
902}
903
904bool Scope::hasAltNavigation() const
905{
906 return m_hasAltNavigation;
768}907}
769908
770QVariantMap Scope::customizations() const909QVariantMap Scope::customizations() const
@@ -783,6 +922,11 @@
783 if (m_searchQuery.isNull() || search_query != m_searchQuery) {922 if (m_searchQuery.isNull() || search_query != m_searchQuery) {
784 m_searchQuery = search_query;923 m_searchQuery = search_query;
785924
925 // atm only empty query can have a filter state
926 if (!m_searchQuery.isEmpty()) {
927 m_filterState = scopes::FilterState();
928 }
929
786 // FIXME: use a timeout930 // FIXME: use a timeout
787 invalidateResults();931 invalidateResults();
788932
@@ -828,6 +972,13 @@
828 }972 }
829}973}
830974
975void Scope::setFavorite(const bool value)
976{
977 Q_UNUSED(value);
978
979 qWarning("Unimplemented: %s", __func__);
980}
981
831void Scope::activate(QVariant const& result_var)982void Scope::activate(QVariant const& result_var)
832{983{
833 if (!result_var.canConvert<std::shared_ptr<scopes::Result>>()) {984 if (!result_var.canConvert<std::shared_ptr<scopes::Result>>()) {
834985
=== modified file 'src/Unity/scope.h'
--- src/Unity/scope.h 2014-07-31 11:08:50 +0000
+++ src/Unity/scope.h 2014-08-06 08:35:31 +0000
@@ -116,17 +116,20 @@
116 QString iconHint() const override;116 QString iconHint() const override;
117 QString description() const override;117 QString description() const override;
118 QString searchHint() const override;118 QString searchHint() const override;
119 bool visible() const override;119 bool favorite() const override;
120 QString shortcut() const override;120 QString shortcut() const override;
121 bool searchInProgress() const override;121 bool searchInProgress() const override;
122 unity::shell::scopes::ScopeInterface::Status status() const override;
122 unity::shell::scopes::CategoriesInterface* categories() const override;123 unity::shell::scopes::CategoriesInterface* categories() const override;
123 unity::shell::scopes::SettingsModelInterface* settings() const override;124 unity::shell::scopes::SettingsModelInterface* settings() const override;
124 QString searchQuery() const override;125 QString searchQuery() const override;
125 QString noResultsHint() const override;126 QString noResultsHint() const override;
126 QString formFactor() const override;127 QString formFactor() const override;
127 bool isActive() const override;128 bool isActive() const override;
128 QString currentDepartmentId() const override;129 QString currentNavigationId() const override;
129 bool hasDepartments() const override;130 bool hasNavigation() const override;
131 QString currentAltNavigationId() const override;
132 bool hasAltNavigation() const override;
130 QVariantMap customizations() const override;133 QVariantMap customizations() const override;
131134
132 /* setters */135 /* setters */
@@ -134,14 +137,17 @@
134 void setNoResultsHint(const QString& hint) override;137 void setNoResultsHint(const QString& hint) override;
135 void setFormFactor(const QString& form_factor) override;138 void setFormFactor(const QString& form_factor) override;
136 void setActive(const bool) override;139 void setActive(const bool) override;
140 void setFavorite(const bool) override;
137141
138 Q_INVOKABLE void activate(QVariant const& result) override;142 Q_INVOKABLE void activate(QVariant const& result) override;
139 Q_INVOKABLE unity::shell::scopes::PreviewStackInterface* preview(QVariant const& result) override;143 Q_INVOKABLE unity::shell::scopes::PreviewStackInterface* preview(QVariant const& result) override;
140 Q_INVOKABLE void cancelActivation() override;144 Q_INVOKABLE void cancelActivation() override;
141 Q_INVOKABLE void closeScope(unity::shell::scopes::ScopeInterface* scope) override;145 Q_INVOKABLE void closeScope(unity::shell::scopes::ScopeInterface* scope) override;
142 Q_INVOKABLE unity::shell::scopes::DepartmentInterface* getDepartment(QString const& id) override;146 Q_INVOKABLE unity::shell::scopes::NavigationInterface* getNavigation(QString const& id) override;
143 Q_INVOKABLE void loadDepartment(QString const& id) override;147 Q_INVOKABLE unity::shell::scopes::NavigationInterface* getAltNavigation(QString const& id) override;
148 Q_INVOKABLE void setNavigationState(QString const& navId, bool altNavigation) override;
144 Q_INVOKABLE void performQuery(QString const& cannedQuery) override;149 Q_INVOKABLE void performQuery(QString const& cannedQuery) override;
150 Q_INVOKABLE void refresh() override;
145151
146 void setScopeData(unity::scopes::ScopeMetadata const& data);152 void setScopeData(unity::scopes::ScopeMetadata const& data);
147 void handleActivation(std::shared_ptr<unity::scopes::ActivationResponse> const&, unity::scopes::Result::SPtr const&);153 void handleActivation(std::shared_ptr<unity::scopes::ActivationResponse> const&, unity::scopes::Result::SPtr const&);
@@ -164,6 +170,7 @@
164170
165protected:171protected:
166 void setSearchInProgress(bool searchInProgress);172 void setSearchInProgress(bool searchInProgress);
173 void setStatus(unity::shell::scopes::ScopeInterface::Status status);
167 void invalidateLastSearch();174 void invalidateLastSearch();
168 virtual void dispatchSearch();175 virtual void dispatchSearch();
169176
@@ -173,9 +180,12 @@
173 QPointer<Scopes> m_scopesInstance;180 QPointer<Scopes> m_scopesInstance;
174181
175private:182private:
183 static void updateNavigationModels(DepartmentNode* rootNode, QMultiMap<QString, Department*>& navigationModels, QString const& activeNavigation);
184 static QString buildQuery(QString const& scopeId, QString const& searchQuery, QString const& departmentId, QString const& primaryFilterId, QString const& primaryOptionId);
176 void setScopesInstance(Scopes*);185 void setScopesInstance(Scopes*);
177 void startTtlTimer();186 void startTtlTimer();
178 void setCurrentDepartmentId(QString const& id);187 void setCurrentNavigationId(QString const& id);
188 void setFilterState(unity::scopes::FilterState const& filterState);
179 void processSearchChunk(PushEvent* pushEvent);189 void processSearchChunk(PushEvent* pushEvent);
180 void executeCannedQuery(unity::scopes::CannedQuery const& query, bool allowDelayedActivation);190 void executeCannedQuery(unity::scopes::CannedQuery const& query, bool allowDelayedActivation);
181191
@@ -187,13 +197,15 @@
187 QString m_searchQuery;197 QString m_searchQuery;
188 QString m_noResultsHint;198 QString m_noResultsHint;
189 QString m_formFactor;199 QString m_formFactor;
190 QString m_currentDepartmentId;200 QString m_currentNavigationId;
201 QString m_currentAltNavigationId;
191 QVariantMap m_customizations;202 QVariantMap m_customizations;
192 bool m_isActive;203 bool m_isActive;
193 bool m_searchInProgress;204 bool m_searchInProgress;
194 bool m_resultsDirty;205 bool m_resultsDirty;
195 bool m_delayedClear;206 bool m_delayedClear;
196 bool m_hasDepartments;207 bool m_hasNavigation;
208 bool m_hasAltNavigation;
197209
198 std::unique_ptr<CollectionController> m_searchController;210 std::unique_ptr<CollectionController> m_searchController;
199 std::unique_ptr<CollectionController> m_activationController;211 std::unique_ptr<CollectionController> m_activationController;
@@ -202,15 +214,22 @@
202 std::shared_ptr<unity::scopes::ActivationResponse> m_delayedActivation;214 std::shared_ptr<unity::scopes::ActivationResponse> m_delayedActivation;
203 unity::scopes::Department::SCPtr m_rootDepartment;215 unity::scopes::Department::SCPtr m_rootDepartment;
204 unity::scopes::Department::SCPtr m_lastRootDepartment;216 unity::scopes::Department::SCPtr m_lastRootDepartment;
217 unity::scopes::OptionSelectorFilter::SCPtr m_sortOrderFilter;
218 unity::scopes::OptionSelectorFilter::SCPtr m_lastSortOrderFilter;
219 unity::scopes::FilterState m_filterState;
220 unity::scopes::FilterState m_receivedFilterState;
221 unity::shell::scopes::ScopeInterface::Status m_status;
205 QGSettings* m_settings;222 QGSettings* m_settings;
206 QScopedPointer<SettingsModel> m_settingsModel;223 QScopedPointer<SettingsModel> m_settingsModel;
207 QSharedPointer<DepartmentNode> m_departmentTree;224 QSharedPointer<DepartmentNode> m_departmentTree;
225 QSharedPointer<DepartmentNode> m_altNavTree;
208 QTimer m_aggregatorTimer;226 QTimer m_aggregatorTimer;
209 QTimer m_clearTimer;227 QTimer m_clearTimer;
210 QTimer m_invalidateTimer;228 QTimer m_invalidateTimer;
211 QList<std::shared_ptr<unity::scopes::CategorisedResult>> m_cachedResults;229 QList<std::shared_ptr<unity::scopes::CategorisedResult>> m_cachedResults;
212 QSet<unity::shell::scopes::ScopeInterface*> m_tempScopes;230 QSet<unity::shell::scopes::ScopeInterface*> m_tempScopes;
213 QMultiMap<QString, Department*> m_departmentModels;231 QMultiMap<QString, Department*> m_departmentModels;
232 QMultiMap<QString, Department*> m_altNavModels;
214 QMap<Department*, QString> m_inverseDepartments;233 QMap<Department*, QString> m_inverseDepartments;
215 QMetaObject::Connection m_metadataConnection;234 QMetaObject::Connection m_metadataConnection;
216 LocationService::Ptr m_locationService;235 LocationService::Ptr m_locationService;
217236
=== modified file 'src/Unity/scopes.cpp'
--- src/Unity/scopes.cpp 2014-07-31 11:08:50 +0000
+++ src/Unity/scopes.cpp 2014-08-06 08:35:31 +0000
@@ -130,6 +130,11 @@
130 return m_scopes.count();130 return m_scopes.count();
131}131}
132132
133int Scopes::count() const
134{
135 return m_scopes.count();
136}
137
133void Scopes::populateScopes()138void Scopes::populateScopes()
134{139{
135 auto thread = new ScopeListWorker;140 auto thread = new ScopeListWorker;
@@ -198,6 +203,7 @@
198203
199 m_loaded = true;204 m_loaded = true;
200 Q_EMIT loadedChanged();205 Q_EMIT loadedChanged();
206 Q_EMIT countChanged();
201 Q_EMIT overviewScopeChanged();207 Q_EMIT overviewScopeChanged();
202 Q_EMIT metadataRefreshed();208 Q_EMIT metadataRefreshed();
203209
@@ -249,8 +255,6 @@
249 return QVariant::fromValue(scope);255 return QVariant::fromValue(scope);
250 case Scopes::RoleId:256 case Scopes::RoleId:
251 return QString(scope->id());257 return QString(scope->id());
252 case Scopes::RoleVisible:
253 return QVariant::fromValue(scope->visible());
254 case Scopes::RoleTitle:258 case Scopes::RoleTitle:
255 return QString(scope->name());259 return QString(scope->name());
256 default:260 default:
257261
=== modified file 'src/Unity/scopes.h'
--- src/Unity/scopes.h 2014-07-31 11:08:50 +0000
+++ src/Unity/scopes.h 2014-08-06 08:35:31 +0000
@@ -62,6 +62,7 @@
62 void refreshScopeMetadata();62 void refreshScopeMetadata();
6363
64 bool loaded() const override;64 bool loaded() const override;
65 int count() const override;
65 unity::shell::scopes::ScopeInterface* overviewScope() const override;66 unity::shell::scopes::ScopeInterface* overviewScope() const override;
6667
67 LocationService::Ptr locationService() const;68 LocationService::Ptr locationService() const;
6869
=== modified file 'tests/data/CMakeLists.txt'
--- tests/data/CMakeLists.txt 2014-07-22 13:49:50 +0000
+++ tests/data/CMakeLists.txt 2014-08-06 08:35:31 +0000
@@ -1,5 +1,6 @@
1add_subdirectory(mock-scope)1add_subdirectory(mock-scope)
2add_subdirectory(mock-scope-departments)2add_subdirectory(mock-scope-departments)
3add_subdirectory(mock-scope-double-nav)
3add_subdirectory(mock-scope-ttl)4add_subdirectory(mock-scope-ttl)
4add_subdirectory(scopes)5add_subdirectory(scopes)
56
67
=== added directory 'tests/data/mock-scope-double-nav'
=== added file 'tests/data/mock-scope-double-nav/CMakeLists.txt'
--- tests/data/mock-scope-double-nav/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ tests/data/mock-scope-double-nav/CMakeLists.txt 2014-08-06 08:35:31 +0000
@@ -0,0 +1,16 @@
1include(FindPkgConfig)
2pkg_check_modules(SCOPESLIB REQUIRED libunity-scopes>=0.4.0)
3
4set(SCOPES_BIN_DIR ${SCOPESLIB_LIBDIR})
5
6include_directories(${SCOPESLIB_INCLUDE_DIRS})
7include_directories(${CMAKE_CURRENT_BINARY_DIR})
8
9set(SCOPE_SOURCES
10 mock-scope-double-nav.cpp
11 )
12
13add_library(mock-scope-double-nav MODULE ${SCOPE_SOURCES})
14target_link_libraries(mock-scope-double-nav ${SCOPESLIB_LDFLAGS})
15
16configure_file(mock-scope-double-nav.ini.in mock-scope-double-nav.ini)
017
=== added file 'tests/data/mock-scope-double-nav/mock-scope-double-nav.cpp'
--- tests/data/mock-scope-double-nav/mock-scope-double-nav.cpp 1970-01-01 00:00:00 +0000
+++ tests/data/mock-scope-double-nav/mock-scope-double-nav.cpp 2014-08-06 08:35:31 +0000
@@ -0,0 +1,214 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Pete Woods <pete.woods@canonical.com>
17 */
18
19#include <unity/scopes/CategorisedResult.h>
20#include <unity/scopes/OptionSelectorFilter.h>
21#include <unity/scopes/ScopeBase.h>
22#include <unity/scopes/SearchReply.h>
23
24#include <iostream>
25#include <thread>
26#include <atomic>
27#include <sstream>
28
29#define EXPORT __attribute__ ((visibility ("default")))
30
31using namespace std;
32using namespace unity::scopes;
33
34class MyQuery : public SearchQueryBase
35{
36public:
37 MyQuery(CannedQuery const& query, SearchMetadata const& metadata) :
38 SearchQueryBase(query, metadata),
39 department_id_(query.department_id())
40 {
41 }
42
43 ~MyQuery()
44 {
45 }
46
47 virtual void cancelled() override
48 {
49 }
50
51 static Department::SPtr create_root_dep(CannedQuery const& query)
52 {
53 Department::SPtr child_dep;
54 Department::SPtr root_dep;
55 root_dep = Department::create("", query, "All departments");
56
57 child_dep = Department::create("books", query, "Books");
58 child_dep->set_has_subdepartments();
59 root_dep->add_subdepartment(child_dep);
60
61 child_dep = Department::create("movies", query, "Movies, TV, Music");
62 child_dep->set_has_subdepartments();
63 root_dep->add_subdepartment(child_dep);
64
65 child_dep = Department::create("electronics", query, "Electronics");
66 child_dep->set_has_subdepartments();
67 root_dep->add_subdepartment(child_dep);
68
69 child_dep = Department::create("home", query, "Home, Garden & DIY");
70 child_dep->set_has_subdepartments();
71 root_dep->add_subdepartment(child_dep);
72
73 child_dep = Department::create("toys", query, "Toys, Children & Baby");
74 child_dep->set_has_subdepartments();
75 root_dep->add_subdepartment(child_dep);
76
77 return root_dep;
78 }
79
80 static Department::SPtr get_department_by_id(Department::SPtr root_dep, std::string const& dep_id)
81 {
82 auto children = root_dep->subdepartments();
83 for (auto it = children.begin(); it != children.end(); ++it)
84 {
85 if ((*it)->id() == dep_id) return const_pointer_cast<Department>(*it);
86 }
87 return Department::SPtr();
88 }
89
90 virtual void run(SearchReplyProxy const& reply) override
91 {
92 Department::SPtr child_dep;
93 Department::SPtr root_dep;
94 Department::SPtr active_dep;
95
96 root_dep = create_root_dep(query());
97
98 if (department_id_.compare(0, 5, "books") == 0)
99 {
100 active_dep = get_department_by_id(root_dep, "books");
101 child_dep = Department::create("books-kindle", query(), "Kindle Books");
102 active_dep->add_subdepartment(child_dep);
103
104 child_dep = Department::create("books-study", query(), "Books for Study");
105 active_dep->add_subdepartment(child_dep);
106
107 child_dep = Department::create("books-audio", query(), "Audiobooks");
108 active_dep->add_subdepartment(child_dep);
109 }
110
111 if (department_id_.compare(0, 4, "home") == 0)
112 {
113 active_dep = get_department_by_id(root_dep, "home");
114 child_dep = Department::create("home-garden", query(), "Garden & Outdoors");
115 active_dep->add_subdepartment(child_dep);
116
117 child_dep = Department::create("home-furniture", query(), "Homeware & Furniture");
118 active_dep->add_subdepartment(child_dep);
119
120 child_dep = Department::create("home-kitchen", query(), "Kitchen & Dining");
121 active_dep->add_subdepartment(child_dep);
122 }
123
124 if (department_id_.compare(0, 4, "toys") == 0)
125 {
126 active_dep = get_department_by_id(root_dep, "toys");
127 child_dep = Department::create("toys-games", query(), "Toys & Games");
128 active_dep->add_subdepartment(child_dep);
129
130 child_dep = Department::create("toys-baby", query(), "Baby");
131 active_dep->add_subdepartment(child_dep);
132 }
133
134 // provide only partial tree for this leaf
135 if (department_id_ == "toys-games")
136 {
137 root_dep = Department::create("", query(), "All departments");
138 child_dep = Department::create("toys", query(), "Toys, Children & Baby");
139 root_dep->add_subdepartment(child_dep);
140 active_dep = Department::create("toys-games", query(), "Toys & Games");
141 child_dep->add_subdepartment(active_dep);
142 }
143
144 reply->register_departments(root_dep);
145
146 // add sort order filter
147 OptionSelectorFilter::UPtr sort_order_filter = OptionSelectorFilter::create("sort-order", "Sort Order");
148 sort_order_filter->set_display_hints(FilterBase::Primary);
149 sort_order_filter->add_option("featured", "Featured");
150 sort_order_filter->add_option("top", "Most popular");
151 sort_order_filter->add_option("best", "Best sellers");
152 Filters filters;
153 filters.push_back(std::move(sort_order_filter));
154
155 FilterState state;
156 FilterState initial_filter_state(query().filter_state());
157 if (initial_filter_state.has_filter("sort-order")) {
158 state = initial_filter_state;
159 } else {
160 // default option
161 OptionSelectorFilter::update_state(state, "sort-order", "featured", true);
162 }
163
164 reply->push(filters, state);
165
166 auto cat1 = reply->register_category("cat1", "Category 1", "");
167 CategorisedResult res1(cat1);
168 res1.set_uri("test:uri");
169 res1.set_title("result for: \"" + query().query_string() + "\"");
170 reply->push(res1);
171 }
172
173protected:
174 string department_id_;
175};
176
177class MyScope : public ScopeBase
178{
179public:
180 MyScope()
181 {
182 }
183
184 virtual SearchQueryBase::UPtr search(CannedQuery const& q, SearchMetadata const& metadata) override
185 {
186 return SearchQueryBase::UPtr(new MyQuery(q, metadata));
187 }
188
189 virtual PreviewQueryBase::UPtr preview(Result const&, ActionMetadata const&) override
190 {
191 return nullptr;
192 }
193};
194
195extern "C"
196{
197
198 EXPORT
199 unity::scopes::ScopeBase*
200 // cppcheck-suppress unusedFunction
201 UNITY_SCOPE_CREATE_FUNCTION()
202 {
203 return new MyScope;
204 }
205
206 EXPORT
207 void
208 // cppcheck-suppress unusedFunction
209 UNITY_SCOPE_DESTROY_FUNCTION(unity::scopes::ScopeBase* scope_base)
210 {
211 delete scope_base;
212 }
213
214}
0215
=== added file 'tests/data/mock-scope-double-nav/mock-scope-double-nav.ini.in'
--- tests/data/mock-scope-double-nav/mock-scope-double-nav.ini.in 1970-01-01 00:00:00 +0000
+++ tests/data/mock-scope-double-nav/mock-scope-double-nav.ini.in 2014-08-06 08:35:31 +0000
@@ -0,0 +1,8 @@
1[ScopeConfig]
2DisplayName = mock-double-nav.DisplayName
3Description = mock-double-nav.Description
4Art = /mock-double-nav.Art
5Icon = /mock-double-nav.Icon
6SearchHint = mock-double-nav.SearchHint
7HotKey = mock-double-nav.HotKey
8Author = mock-double-nav.Author
09
=== modified file 'tests/departmentstest.cpp'
--- tests/departmentstest.cpp 2014-07-18 16:35:52 +0000
+++ tests/departmentstest.cpp 2014-08-06 08:35:31 +0000
@@ -48,6 +48,7 @@
48private:48private:
49 QScopedPointer<Scopes> m_scopes;49 QScopedPointer<Scopes> m_scopes;
50 Scope* m_scope;50 Scope* m_scope;
51 Scope* m_scope_navs;
51 QScopedPointer<RegistrySpawner> m_registry;52 QScopedPointer<RegistrySpawner> m_registry;
5253
53private Q_SLOTS:54private Q_SLOTS:
@@ -78,6 +79,10 @@
78 m_scope = qobject_cast<scopes_ng::Scope*>(m_scopes->getScope(QString("mock-scope-departments")));79 m_scope = qobject_cast<scopes_ng::Scope*>(m_scopes->getScope(QString("mock-scope-departments")));
79 QVERIFY(m_scope != nullptr);80 QVERIFY(m_scope != nullptr);
80 m_scope->setActive(true);81 m_scope->setActive(true);
82
83 m_scope_navs = qobject_cast<scopes_ng::Scope*>(m_scopes->getScope(QString("mock-scope-double-nav")));
84 QVERIFY(m_scope_navs != nullptr);
85 m_scope_navs->setActive(true);
81 }86 }
8287
83 void cleanup()88 void cleanup()
@@ -90,37 +95,40 @@
90 {95 {
91 performSearch(m_scope, QString("foo"));96 performSearch(m_scope, QString("foo"));
9297
93 QCOMPARE(m_scope->hasDepartments(), false);98 QCOMPARE(m_scope->hasNavigation(), false);
99 QCOMPARE(m_scope->hasAltNavigation(), false);
94 }100 }
95101
96 void testRootDepartment()102 void testRootDepartment()
97 {103 {
98 performSearch(m_scope, QString(""));104 performSearch(m_scope, QString(""));
99105
100 QCOMPARE(m_scope->hasDepartments(), true);106 QCOMPARE(m_scope->hasNavigation(), true);
101 QCOMPARE(m_scope->currentDepartmentId(), QString(""));107 QCOMPARE(m_scope->hasAltNavigation(), false);
102 QScopedPointer<DepartmentInterface> departmentModel(m_scope->getDepartment(m_scope->currentDepartmentId()));108 QCOMPARE(m_scope->currentNavigationId(), QString(""));
109 QScopedPointer<NavigationInterface> departmentModel(m_scope->getNavigation(m_scope->currentNavigationId()));
103 QVERIFY(departmentModel != nullptr);110 QVERIFY(departmentModel != nullptr);
104111
105 QVERIFY(departmentModel->departmentId().isEmpty());112 QVERIFY(departmentModel->navigationId().isEmpty());
106 QCOMPARE(departmentModel->label(), QString("All departments"));113 QCOMPARE(departmentModel->label(), QString("All departments"));
107 QCOMPARE(departmentModel->allLabel(), QString(""));114 QCOMPARE(departmentModel->allLabel(), QString(""));
108 QCOMPARE(departmentModel->parentDepartmentId(), QString());115 QCOMPARE(departmentModel->parentNavigationId(), QString());
109 QCOMPARE(departmentModel->parentLabel(), QString());116 QCOMPARE(departmentModel->parentLabel(), QString());
110 QCOMPARE(departmentModel->loaded(), true);117 QCOMPARE(departmentModel->loaded(), true);
111 QCOMPARE(departmentModel->isRoot(), true);118 QCOMPARE(departmentModel->isRoot(), true);
119 QCOMPARE(departmentModel->hidden(), false);
112120
113 QCOMPARE(departmentModel->rowCount(), 5);121 QCOMPARE(departmentModel->rowCount(), 5);
114 QModelIndex idx;122 QModelIndex idx;
115123
116 idx = departmentModel->index(0);124 idx = departmentModel->index(0);
117 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleDepartmentId), QVariant(QString("books")));125 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleNavigationId), QVariant(QString("books")));
118 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleLabel), QVariant(QString("Books")));126 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleLabel), QVariant(QString("Books")));
119 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleHasChildren), QVariant(true));127 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleHasChildren), QVariant(true));
120 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleIsActive), QVariant(false));128 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleIsActive), QVariant(false));
121129
122 idx = departmentModel->index(4);130 idx = departmentModel->index(4);
123 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleDepartmentId), QVariant(QString("toys")));131 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleNavigationId), QVariant(QString("toys")));
124 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleLabel), QVariant(QString("Toys, Children & Baby")));132 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleLabel), QVariant(QString("Toys, Children & Baby")));
125 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleHasChildren), QVariant(true));133 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleHasChildren), QVariant(true));
126 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleIsActive), QVariant(false));134 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleIsActive), QVariant(false));
@@ -130,23 +138,23 @@
130 {138 {
131 performSearch(m_scope, QString(""));139 performSearch(m_scope, QString(""));
132140
133 QCOMPARE(m_scope->currentDepartmentId(), QString(""));141 QCOMPARE(m_scope->currentNavigationId(), QString(""));
134 QScopedPointer<DepartmentInterface> departmentModel(m_scope->getDepartment(QString("toys")));142 QScopedPointer<NavigationInterface> departmentModel(m_scope->getNavigation(QString("toys")));
135 QVERIFY(departmentModel != nullptr);143 QVERIFY(departmentModel != nullptr);
136144
137 QSignalSpy spy(departmentModel.data(), SIGNAL(loadedChanged()));145 QSignalSpy spy(departmentModel.data(), SIGNAL(loadedChanged()));
138146
139 QCOMPARE(departmentModel->departmentId(), QString("toys"));147 QCOMPARE(departmentModel->navigationId(), QString("toys"));
140 QCOMPARE(departmentModel->label(), QString("Toys, Children & Baby"));148 QCOMPARE(departmentModel->label(), QString("Toys, Children & Baby"));
141 QCOMPARE(departmentModel->allLabel(), QString(""));149 QCOMPARE(departmentModel->allLabel(), QString(""));
142 QCOMPARE(departmentModel->parentDepartmentId(), QString(""));150 QCOMPARE(departmentModel->parentNavigationId(), QString(""));
143 QCOMPARE(departmentModel->parentLabel(), QString("All departments"));151 QCOMPARE(departmentModel->parentLabel(), QString("All departments"));
144 QCOMPARE(departmentModel->loaded(), false);152 QCOMPARE(departmentModel->loaded(), false);
145 QCOMPARE(departmentModel->isRoot(), false);153 QCOMPARE(departmentModel->isRoot(), false);
146154
147 QCOMPARE(departmentModel->rowCount(), 0);155 QCOMPARE(departmentModel->rowCount(), 0);
148156
149 m_scope->loadDepartment(QString("toys"));157 m_scope->setNavigationState(departmentModel->navigationId(), false);
150 QVERIFY(spy.wait());158 QVERIFY(spy.wait());
151159
152 QCOMPARE(departmentModel->rowCount(), 2);160 QCOMPARE(departmentModel->rowCount(), 2);
@@ -158,16 +166,18 @@
158 {166 {
159 performSearch(m_scope, QString(""));167 performSearch(m_scope, QString(""));
160168
161 QCOMPARE(m_scope->currentDepartmentId(), QString(""));169 QCOMPARE(m_scope->currentNavigationId(), QString(""));
162 QSignalSpy spy(m_scope, SIGNAL(searchInProgressChanged()));170 QSignalSpy spy(m_scope, SIGNAL(searchInProgressChanged()));
163 m_scope->loadDepartment(QString("books"));171 QScopedPointer<NavigationInterface> navModel(m_scope->getNavigation(QString("books")));
172 m_scope->setNavigationState(navModel->navigationId(), false);
164 QVERIFY(spy.wait());173 QVERIFY(spy.wait());
165 QCOMPARE(m_scope->searchInProgress(), false);174 QCOMPARE(m_scope->searchInProgress(), false);
166 QScopedPointer<DepartmentInterface> departmentModel(m_scope->getDepartment(QString("books")));175 QScopedPointer<NavigationInterface> departmentModel(m_scope->getNavigation(QString("books")));
167 QCOMPARE(departmentModel->isRoot(), false);176 QCOMPARE(departmentModel->isRoot(), false);
168177
178 navModel.reset(m_scope->getNavigation(QString("books-audio")));
169 // this is a leaf department, so activating it should update the parent model179 // this is a leaf department, so activating it should update the parent model
170 m_scope->loadDepartment(QString("books-audio"));180 m_scope->setNavigationState(navModel->navigationId(), false);
171 QVERIFY(spy.wait());181 QVERIFY(spy.wait());
172 QCOMPARE(m_scope->searchInProgress(), false);182 QCOMPARE(m_scope->searchInProgress(), false);
173 QCOMPARE(departmentModel->isRoot(), false);183 QCOMPARE(departmentModel->isRoot(), false);
@@ -175,7 +185,7 @@
175 bool foundAudiobooks = false;185 bool foundAudiobooks = false;
176 for (int i = 0; i < departmentModel->rowCount(); i++) {186 for (int i = 0; i < departmentModel->rowCount(); i++) {
177 QModelIndex idx(departmentModel->index(i));187 QModelIndex idx(departmentModel->index(i));
178 QVariant data = departmentModel->data(idx, Department::Roles::RoleDepartmentId);188 QVariant data = departmentModel->data(idx, Department::Roles::RoleNavigationId);
179 if (data.toString() == QString("books-audio")) {189 if (data.toString() == QString("books-audio")) {
180 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleIsActive).toBool(), true);190 QCOMPARE(departmentModel->data(idx, Department::Roles::RoleIsActive).toBool(), true);
181 foundAudiobooks = true;191 foundAudiobooks = true;
@@ -188,16 +198,17 @@
188 {198 {
189 performSearch(m_scope, QString(""));199 performSearch(m_scope, QString(""));
190200
191 QCOMPARE(m_scope->currentDepartmentId(), QString(""));201 QCOMPARE(m_scope->currentNavigationId(), QString(""));
192 QSignalSpy spy(m_scope, SIGNAL(searchInProgressChanged()));202 QSignalSpy spy(m_scope, SIGNAL(searchInProgressChanged()));
193 m_scope->loadDepartment(QString("books"));203 QScopedPointer<NavigationInterface> navModel(m_scope->getNavigation(QString("books")));
204 m_scope->setNavigationState(navModel->navigationId(), false);
194 QVERIFY(spy.wait());205 QVERIFY(spy.wait());
195 QCOMPARE(m_scope->searchInProgress(), false);206 QCOMPARE(m_scope->searchInProgress(), false);
196 QScopedPointer<DepartmentInterface> departmentModel(m_scope->getDepartment(QString("books")));207 QScopedPointer<NavigationInterface> departmentModel(m_scope->getNavigation(QString("books")));
197 QCOMPARE(departmentModel->isRoot(), false);208 QCOMPARE(departmentModel->isRoot(), false);
198209
199 // get the root again without actually loading the department210 // get the root again without actually loading the department
200 departmentModel.reset(m_scope->getDepartment(departmentModel->parentDepartmentId()));211 departmentModel.reset(m_scope->getNavigation(departmentModel->parentNavigationId()));
201 QCOMPARE(departmentModel->isRoot(), true);212 QCOMPARE(departmentModel->isRoot(), true);
202 QEXPECT_FAIL("", "We have the department in cache, to it kind of is loaded", Continue);213 QEXPECT_FAIL("", "We have the department in cache, to it kind of is loaded", Continue);
203 QCOMPARE(departmentModel->loaded(), false);214 QCOMPARE(departmentModel->loaded(), false);
@@ -205,32 +216,98 @@
205216
206 void testIncompleteTreeOnLeaf()217 void testIncompleteTreeOnLeaf()
207 {218 {
208 QScopedPointer<DepartmentInterface> departmentModel;219 QScopedPointer<NavigationInterface> navModel;
220 QScopedPointer<NavigationInterface> departmentModel;
209 performSearch(m_scope, QString(""));221 performSearch(m_scope, QString(""));
210222
211 QCOMPARE(m_scope->currentDepartmentId(), QString(""));223 QCOMPARE(m_scope->currentNavigationId(), QString(""));
212 QCOMPARE(m_scope->hasDepartments(), true);224 QCOMPARE(m_scope->hasNavigation(), true);
213225
214 QSignalSpy spy(m_scope, SIGNAL(searchInProgressChanged()));226 QSignalSpy spy(m_scope, SIGNAL(searchInProgressChanged()));
215 m_scope->loadDepartment(QString("toys"));227 navModel.reset(m_scope->getNavigation(QString("toys")));
228 m_scope->setNavigationState(navModel->navigationId(), false);
216 QVERIFY(spy.wait());229 QVERIFY(spy.wait());
217 QCOMPARE(m_scope->searchInProgress(), false);230 QCOMPARE(m_scope->searchInProgress(), false);
218231
219 departmentModel.reset(m_scope->getDepartment(QString("toys")));232 departmentModel.reset(m_scope->getNavigation(QString("toys")));
220 QCOMPARE(departmentModel->isRoot(), false);233 QCOMPARE(departmentModel->isRoot(), false);
221 QCOMPARE(departmentModel->rowCount(), 2);234 QCOMPARE(departmentModel->rowCount(), 2);
222235
223 m_scope->loadDepartment(QString("toys-games"));236 navModel.reset(m_scope->getNavigation(QString("toys-games")));
237 m_scope->setNavigationState(navModel->navigationId(), false);
224 QVERIFY(spy.wait());238 QVERIFY(spy.wait());
225 QCOMPARE(m_scope->searchInProgress(), false);239 QCOMPARE(m_scope->searchInProgress(), false);
226240
227 // after getting the parent department model, it should still have241 // after getting the parent department model, it should still have
228 // all the leaves, even though the leaf served just itself242 // all the leaves, even though the leaf served just itself
229 departmentModel.reset(m_scope->getDepartment(QString("toys")));243 departmentModel.reset(m_scope->getNavigation(QString("toys")));
230 QCOMPARE(departmentModel->isRoot(), false);244 QCOMPARE(departmentModel->isRoot(), false);
231 QCOMPARE(departmentModel->rowCount(), 2);245 QCOMPARE(departmentModel->rowCount(), 2);
232 }246 }
233247
248 void testDoubleNavigation()
249 {
250 performSearch(m_scope_navs, QString(""));
251
252 QCOMPARE(m_scope_navs->hasNavigation(), true);
253 QCOMPARE(m_scope_navs->hasAltNavigation(), true);
254 QCOMPARE(m_scope_navs->currentNavigationId(), QString(""));
255 QCOMPARE(m_scope_navs->currentAltNavigationId(), QString("featured"));
256 QScopedPointer<NavigationInterface> departmentModel(m_scope_navs->getNavigation(m_scope_navs->currentNavigationId()));
257 QVERIFY(departmentModel != nullptr);
258
259 QVERIFY(!m_scope_navs->currentAltNavigationId().isEmpty());
260 QScopedPointer<NavigationInterface> sortOrderModel(m_scope_navs->getAltNavigation(""));
261 QVERIFY(sortOrderModel != nullptr);
262
263 QCOMPARE(sortOrderModel->navigationId(), QString(""));
264 QCOMPARE(sortOrderModel->label(), QString("Sort Order"));
265 QCOMPARE(sortOrderModel->allLabel(), QString(""));
266 QCOMPARE(sortOrderModel->parentNavigationId(), QString());
267 QCOMPARE(sortOrderModel->parentLabel(), QString());
268 QCOMPARE(sortOrderModel->loaded(), true);
269 QCOMPARE(sortOrderModel->isRoot(), true);
270 QCOMPARE(sortOrderModel->hidden(), true);
271
272 QCOMPARE(sortOrderModel->rowCount(), 3);
273 QModelIndex idx;
274
275 idx = sortOrderModel->index(0);
276 QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleNavigationId), QVariant(QString("featured")));
277 QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleLabel), QVariant(QString("Featured")));
278 QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleHasChildren), QVariant(false));
279 QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleIsActive), QVariant(true));
280
281 idx = sortOrderModel->index(2);
282 QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleNavigationId), QVariant(QString("best")));
283 QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleLabel), QVariant(QString("Best sellers")));
284 QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleHasChildren), QVariant(false));
285 QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleIsActive), QVariant(false));
286 }
287
288 void testDoubleNavChangeActive()
289 {
290 performSearch(m_scope_navs, QString(""));
291
292 QCOMPARE(m_scope_navs->currentAltNavigationId(), QString("featured"));
293 QScopedPointer<NavigationInterface> sortOrderModel(m_scope_navs->getAltNavigation(""));
294 QVERIFY(sortOrderModel != nullptr);
295 QCOMPARE(sortOrderModel->loaded(), true);
296 QCOMPARE(sortOrderModel->rowCount(), 3);
297
298 QModelIndex idx(sortOrderModel->index(1));
299 QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleNavigationId), QVariant(QString("top")));
300 QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleIsActive), QVariant(false));
301
302 // perform a query for the other navigation
303 QSignalSpy spy(m_scope_navs, SIGNAL(searchInProgressChanged()));
304 m_scope_navs->setNavigationState("top", true);
305 QVERIFY(spy.wait());
306
307 // the model should be updated
308 QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleNavigationId), QVariant(QString("top")));
309 QCOMPARE(sortOrderModel->data(idx, Department::Roles::RoleIsActive), QVariant(true));
310 }
234};311};
235312
236QTEST_GUILESS_MAIN(DepartmentsTest)313QTEST_GUILESS_MAIN(DepartmentsTest)
237314
=== modified file 'tests/previewtest.cpp'
--- tests/previewtest.cpp 2014-08-05 12:10:41 +0000
+++ tests/previewtest.cpp 2014-08-06 08:35:31 +0000
@@ -67,14 +67,14 @@
67 QVERIFY(spy.wait());67 QVERIFY(spy.wait());
68 QCOMPARE(m_scopes->loaded(), true);68 QCOMPARE(m_scopes->loaded(), true);
69 // should have at least one scope now69 // should have at least one scope now
70 QCOMPARE(m_scopes->rowCount(), 4);70 QVERIFY(m_scopes->rowCount() > 1);
7171
72 QVariant scope_var = m_scopes->data(m_scopes->index(0), Scopes::Roles::RoleScope);72 QVariant scope_var = m_scopes->data(m_scopes->index(0), Scopes::Roles::RoleScope);
73 QVERIFY(scope_var.canConvert<Scope*>());73 QVERIFY(scope_var.canConvert<Scope*>());
7474
75 // get scope proxy75 // get scope proxy
76 m_scope = scope_var.value<Scope*>();76 m_scope = m_scopes->getScopeById("mock-scope");
77 QCOMPARE(m_scope->id(), QString("mock-scope"));77 QVERIFY(m_scope != nullptr);
78 m_scope->setActive(true);78 m_scope->setActive(true);
79 }79 }
8080
8181
=== modified file 'tests/resultstest.cpp'
--- tests/resultstest.cpp 2014-07-31 13:04:20 +0000
+++ tests/resultstest.cpp 2014-08-06 08:35:31 +0000
@@ -112,15 +112,15 @@
112 QVERIFY(spy.wait());112 QVERIFY(spy.wait());
113 QCOMPARE(m_scopes->loaded(), true);113 QCOMPARE(m_scopes->loaded(), true);
114 // should have at least one scope now114 // should have at least one scope now
115 QCOMPARE(m_scopes->rowCount(), 4);115 QVERIFY(m_scopes->rowCount() > 1);
116116
117 // get scope proxy117 // get scope proxy
118 m_scope = qobject_cast<scopes_ng::Scope*>(m_scopes->getScope(QString("mock-scope")));118 m_scope = qobject_cast<scopes_ng::Scope*>(m_scopes->getScopeById(QString("mock-scope")));
119 QVERIFY(m_scope != nullptr);119 QVERIFY(m_scope != nullptr);
120 m_scope->setActive(true);120 m_scope->setActive(true);
121121
122 // get scope proxy for TTL scope122 // get scope proxy for TTL scope
123 m_scope_ttl = qobject_cast<scopes_ng::Scope*>(m_scopes->getScope(QString("mock-scope-ttl")));123 m_scope_ttl = qobject_cast<scopes_ng::Scope*>(m_scopes->getScopeById(QString("mock-scope-ttl")));
124 QVERIFY(m_scope != nullptr);124 QVERIFY(m_scope != nullptr);
125 m_scope_ttl->setActive(true);125 m_scope_ttl->setActive(true);
126 }126 }
@@ -177,7 +177,6 @@
177 QCOMPARE(m_scope->description(), QString("mock.Description"));177 QCOMPARE(m_scope->description(), QString("mock.Description"));
178 QCOMPARE(m_scope->searchHint(), QString("mock.SearchHint"));178 QCOMPARE(m_scope->searchHint(), QString("mock.SearchHint"));
179 QCOMPARE(m_scope->shortcut(), QString("mock.HotKey"));179 QCOMPARE(m_scope->shortcut(), QString("mock.HotKey"));
180 QCOMPARE(m_scope->visible(), true);
181 QCOMPARE(m_scope->searchQuery(), QString());180 QCOMPARE(m_scope->searchQuery(), QString());
182181
183 QVariantMap customizations(m_scope->customizations());182 QVariantMap customizations(m_scope->customizations());
@@ -199,7 +198,6 @@
199 QCOMPARE(m_scope_ttl->description(), QString("mock-ttl.Description"));198 QCOMPARE(m_scope_ttl->description(), QString("mock-ttl.Description"));
200 QCOMPARE(m_scope_ttl->searchHint(), QString());199 QCOMPARE(m_scope_ttl->searchHint(), QString());
201 QCOMPARE(m_scope_ttl->shortcut(), QString());200 QCOMPARE(m_scope_ttl->shortcut(), QString());
202 QCOMPARE(m_scope_ttl->visible(), true);
203 QCOMPARE(m_scope_ttl->searchQuery(), QString());201 QCOMPARE(m_scope_ttl->searchQuery(), QString());
204 }202 }
205203
206204
=== modified file 'tests/settingsendtoendtest.cpp'
--- tests/settingsendtoendtest.cpp 2014-08-05 16:41:02 +0000
+++ tests/settingsendtoendtest.cpp 2014-08-06 08:35:31 +0000
@@ -61,10 +61,10 @@
61 QVERIFY(spy.wait());61 QVERIFY(spy.wait());
62 QCOMPARE(m_scopes->loaded(), true);62 QCOMPARE(m_scopes->loaded(), true);
63 // should have at least one scope now63 // should have at least one scope now
64 QCOMPARE(m_scopes->rowCount(), 4);64 QVERIFY(m_scopes->rowCount() > 1);
6565
66 // get scope proxy66 // get scope proxy
67 m_scope = qobject_cast<scopes_ng::Scope*>(m_scopes->getScope(QString("mock-scope")));67 m_scope = m_scopes->getScopeById("mock-scope");
68 QVERIFY(m_scope != nullptr);68 QVERIFY(m_scope != nullptr);
69 m_scope->setActive(true);69 m_scope->setActive(true);
70 }70 }

Subscribers

People subscribed via source and target branches

to all changes: