on xenial help sign in
Make qmltests compile again
commit553eef831b54ef0f5b05fa2036040309f6c810a5 authorMichal Hruby <michal.mhr@gmail.com> dateFri 28 Jun 2013, 18:59 (13 years ago) parent0a01fee
6 files changed+399−90
tests/qmltests/plugins/Unity/CMakeLists.txt+2−3 tests/qmltests/plugins/Unity/fake_categories.cpp+178 tests/qmltests/plugins/Unity/fake_categories.h+69 tests/qmltests/plugins/Unity/fake_scope.cpp+104−73 tests/qmltests/plugins/Unity/fake_scope.h+43−11 tests/qmltests/plugins/Unity/fake_unity_plugin.cpp+3−3
tests/qmltests/plugins/Unity/CMakeLists.txt+2−3
@@ -19,11 +19,10 @@ include_directories(
1919add_definitions(-DQT_NO_KEYWORDS)
2020
2121set(UnityQML_SOURCES
22− ${CMAKE_SOURCE_DIR}/plugins/Unity/categories.cpp
23− ${CMAKE_SOURCE_DIR}/plugins/Unity/categoryfilter.cpp
24− ${CMAKE_SOURCE_DIR}/plugins/Utils/qsortfilterproxymodelqml.cpp
22+ ${CMAKE_SOURCE_DIR}/plugins/Unity/categoryresults.cpp
2523 fake_scope.cpp
2624 fake_scopes.cpp
25+ fake_categories.cpp
2726 fake_unity_plugin.cpp
2827 fake_launchermodel.cpp
2928)
tests/qmltests/plugins/Unity/fake_categories.cppnew file+178
@@ -0,0 +1,178 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+// self
20+#include "fake_categories.h"
21+
22+// local
23+#include "categoryresults.h"
24+
25+#define CATEGORY_COLUMN 2
26+
27+Categories::Categories(QObject* parent)
28+ : DeeListModel(parent)
29+{
30+ // FIXME: need to clean up unused filters on countChanged
31+ m_roles[Categories::RoleId] = "id";
32+ m_roles[Categories::RoleName] = "name";
33+ m_roles[Categories::RoleIcon] = "icon";
34+ m_roles[Categories::RoleRenderer] = "renderer";
35+ m_roles[Categories::RoleContentType] = "content_type";
36+ m_roles[Categories::RoleHints] = "hints";
37+ m_roles[Categories::RoleResults] = "results";
38+ m_roles[Categories::RoleCount] = "count";
39+
40+ // TODO This should not be needed but accumulatting the count changes
41+ // makes the visualization more stable and also makes crashes on fast
42+ // change of the search term harder to reproduce
43+ m_timer.setSingleShot(true);
44+ m_timer.setInterval(50);
45+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(onEmitCountChanged()));
46+}
47+
48+DeeListModel*
49+Categories::getFilter(int index) const
50+{
51+ if (!m_filters.contains(index)) {
52+ auto results = new CategoryResults ();
53+ results->setCategoryIndex(index);
54+ connect(results, SIGNAL(countChanged()), this, SLOT(onCountChanged()));
55+
56+ unsigned cat_index = static_cast<unsigned>(index);
57+ auto model = getResultsForCategory(cat_index);
58+ results->setModel(model);
59+
60+ m_filters.insert(index, results);
61+ }
62+
63+ return m_filters[index];
64+}
65+
66+void
67+Categories::onCountChanged()
68+{
69+ DeeListModel* filter = qobject_cast<DeeListModel*>(sender());
70+ if (filter) {
71+ m_timerFilters << filter;
72+ m_timer.start();
73+ }
74+}
75+
76+void
77+Categories::onEmitCountChanged()
78+{
79+ QVector<int> roles;
80+ roles.append(Categories::RoleCount);
81+ Q_FOREACH(DeeListModel* results, m_timerFilters) {
82+ auto cat_results = qobject_cast<CategoryResults*>(results);
83+ QModelIndex changedIndex = index(cat_results->categoryIndex());
84+ Q_EMIT dataChanged(changedIndex, changedIndex, roles);
85+ }
86+ m_timerFilters.clear();
87+}
88+
89+QHash<int, QByteArray>
90+Categories::roleNames() const
91+{
92+ return m_roles;
93+}
94+
95+void Categories::setResultModel(DeeModel* model)
96+{
97+ // FIXME: should ref it
98+ m_dee_results = model;
99+}
100+
101+
102+static void category_filter_map_func (DeeModel* orig_model,
103+ DeeFilterModel* filter_model,
104+ gpointer user_data)
105+{
106+ DeeModelIter* iter;
107+ DeeModelIter* end;
108+ unsigned index = GPOINTER_TO_UINT(user_data);
109+
110+ iter = dee_model_get_first_iter(orig_model);
111+ end = dee_model_get_last_iter(orig_model);
112+ while (iter != end) {
113+ unsigned category_index = dee_model_get_uint32(orig_model, iter, CATEGORY_COLUMN);
114+ if (index == category_index) {
115+ dee_filter_model_append_iter(filter_model, iter);
116+ }
117+ iter = dee_model_next(orig_model, iter);
118+ }
119+}
120+
121+static gboolean category_filter_notify_func (DeeModel* orig_model,
122+ DeeModelIter* orig_iter,
123+ DeeFilterModel* filter_model,
124+ gpointer user_data)
125+{
126+ unsigned index = GPOINTER_TO_UINT(user_data);
127+ unsigned category_index = dee_model_get_uint32(orig_model, orig_iter, CATEGORY_COLUMN);
128+
129+ if (index != category_index)
130+ return FALSE;
131+
132+ dee_filter_model_insert_iter_with_original_order(filter_model, orig_iter);
133+ return TRUE;
134+}
135+
136+DeeModel* Categories::getResultsForCategory(unsigned cat_index) const
137+{
138+ DeeFilter filter;
139+ filter.map_func = category_filter_map_func;
140+ filter.map_notify = category_filter_notify_func;
141+ filter.destroy = nullptr;
142+ filter.userdata = GUINT_TO_POINTER(cat_index);
143+
144+ DeeModel* filtered_model = dee_filter_model_new(m_dee_results, &filter);
145+ return filtered_model;
146+}
147+
148+QVariant
149+Categories::data(const QModelIndex& index, int role) const
150+{
151+ if (!index.isValid()) {
152+ return QVariant();
153+ }
154+
155+ switch (role) {
156+ case RoleId:
157+ return QVariant::fromValue(index.row());
158+ case RoleName:
159+ return DeeListModel::data(index, 1); //DISPLAY_NAME
160+ case RoleIcon:
161+ return DeeListModel::data(index, 2); //ICON_HINT
162+ case RoleRenderer:
163+ return DeeListModel::data(index, 3); //RENDERER_NAME
164+ case RoleContentType:
165+ {
166+ auto hints = DeeListModel::data(index, 4).toHash();
167+ return hints.contains("content-type") ? hints["content-type"] : QVariant(QString("default"));
168+ }
169+ case RoleHints:
170+ return DeeListModel::data(index, 4); //HINTS
171+ case RoleResults:
172+ return QVariant::fromValue(getFilter(index.row()));
173+ case RoleCount:
174+ return QVariant::fromValue(getFilter(index.row())->rowCount());
175+ default:
176+ return QVariant();
177+ }
178+}
tests/qmltests/plugins/Unity/fake_categories.hnew file+69
@@ -0,0 +1,69 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef FAKE_CATEGORIES_H
18+#define FAKE_CATEGORIES_H
19+
20+// Qt
21+#include <QObject>
22+#include <QSet>
23+#include <QTimer>
24+
25+#include <dee.h>
26+#include <deelistmodel.h>
27+
28+class Categories : public DeeListModel
29+{
30+ Q_OBJECT
31+
32+ Q_ENUMS(Roles)
33+
34+public:
35+ Categories(QObject* parent = 0);
36+ enum Roles {
37+ RoleId,
38+ RoleName,
39+ RoleIcon,
40+ RoleRenderer,
41+ RoleContentType,
42+ RoleHints,
43+ RoleResults,
44+ RoleCount
45+ };
46+
47+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
48+
49+ QHash<int, QByteArray> roleNames() const;
50+
51+ /* setters */
52+ void setResultModel(DeeModel* model);
53+
54+private Q_SLOTS:
55+ void onCountChanged();
56+ void onEmitCountChanged();
57+
58+private:
59+ DeeModel* getResultsForCategory(unsigned index) const;
60+ DeeListModel* getFilter(int index) const;
61+
62+ DeeModel* m_dee_results;
63+ QTimer m_timer;
64+ QSet<DeeListModel*> m_timerFilters;
65+ QHash<int, QByteArray> m_roles;
66+ mutable QMap<int, DeeListModel*> m_filters;
67+};
68+
69+#endif // FAKE_CATEGORIES_H
tests/qmltests/plugins/Unity/fake_scope.cpp+104−73
@@ -26,32 +26,29 @@ static DeeModel* create_results_model(unsigned category_count, unsigned result_c
2626// TODO: Implement remaining pieces
2727
2828Scope::Scope(QObject* parent)
29−: QObject(parent),
30− m_visible(false),
31− m_categories(new Categories(this)),
32− m_results(new DeeListModel(this))
29+ : QObject(parent)
30+ , m_visible(false)
31+ , m_categories(new Categories(this))
32+ , m_results(new DeeListModel(this))
3333{
34+ DeeModel* results_model = create_results_model(4, 30);
35+ m_categories->setResultModel(results_model);
3436 m_categories->setModel(create_categories_model(4));
35− m_results->setModel(create_results_model(4, 30));
36−
37− m_categories->setResultModel(m_results);
37+ m_results->setModel(results_model);
3838}
3939
40−Scope::Scope(QString const& id,
41− QString const& name,
42− bool visible,
43− QObject* parent)
44−: QObject(parent),
45− m_id(id),
46− m_name(name),
47− m_visible(visible),
48− m_categories(new Categories(this)),
49− m_results(new DeeListModel(this))
40+Scope::Scope(QString const& id, QString const& name, bool visible, QObject* parent)
41+ : QObject(parent)
42+ , m_id(id)
43+ , m_name(name)
44+ , m_visible(visible)
45+ , m_categories(new Categories(this))
46+ , m_results(new DeeListModel(this))
5047{
48+ DeeModel* results_model = create_results_model(4, 30);
49+ m_categories->setResultModel(results_model);
5150 m_categories->setModel(create_categories_model(4));
52− m_results->setModel(create_results_model(4, 30));
53−
54− m_categories->setResultModel(m_results);
51+ m_results->setModel(results_model);
5552}
5653
5754QString Scope::id() const {
@@ -66,6 +63,42 @@ QString Scope::searchQuery() const {
6663 return m_searchQuery;
6764}
6865
66+QString Scope::iconHint() const {
67+ return m_iconHint;
68+}
69+
70+QString Scope::description() const {
71+ return m_description;
72+}
73+
74+QString Scope::searchHint() const {
75+ return QString("");
76+}
77+
78+QString Scope::shortcut() const {
79+ return QString("");
80+}
81+
82+bool Scope::connected() const {
83+ return true;
84+}
85+
86+Categories* Scope::categories() const {
87+ return m_categories;
88+}
89+
90+QString Scope::noResultsHint() const {
91+ return m_noResultsHint;
92+}
93+
94+QString Scope::formFactor() const {
95+ return m_formFactor;
96+}
97+
98+bool Scope::visible() const {
99+ return m_visible;
100+}
101+
69102void Scope::setName(const QString &str) {
70103 if (str != m_name) {
71104 m_name = str;
@@ -76,45 +109,47 @@ void Scope::setName(const QString &str) {
76109void Scope::setSearchQuery(const QString &str) {
77110 if (str != m_searchQuery) {
78111 m_searchQuery = str;
79− Q_EMIT searchQueryChanged(m_searchQuery);
112+ Q_EMIT searchQueryChanged();
80113 }
81114}
82115
83−bool Scope::visible() const {
84− return m_visible;
116+void Scope::setFormFactor(const QString &str) {
117+ if (str != m_formFactor) {
118+ m_formFactor = str;
119+ Q_EMIT formFactorChanged();
120+ }
85121}
86122
87−Categories* Scope::categories() const {
88− return m_categories;
123+void Scope::setNoResultsHint(const QString& str) {
124+ if (str != m_noResultsHint) {
125+ m_noResultsHint = str;
126+ Q_EMIT noResultsHintChanged();
127+ }
89128}
90129
91130static const gchar * categories_model_schema[] = {
92− "s", //ID
93− "s", // DISPLAY_NAME
94− "s", // ICON_HINT
95− "s", // RENDERER_NAME
96− "a{sv}" // HINTS
131+ "s", //ID
132+ "s", // DISPLAY_NAME
133+ "s", // ICON_HINT
134+ "s", // RENDERER_NAME
135+ "a{sv}" // HINTS
97136};
98137
99138
100139DeeModel* create_categories_model(unsigned category_count) {
101140 DeeModel* category_model = dee_sequence_model_new();
102141 dee_model_set_schema_full(category_model, categories_model_schema, G_N_ELEMENTS(categories_model_schema));
103−
104− GVariantBuilder b;
105− g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
106− GVariant *hints = g_variant_builder_end(&b);
142+ GVariant* hints = g_variant_new_array(g_variant_type_element(G_VARIANT_TYPE_VARDICT), NULL, 0);
107143
108144 for(unsigned i = 0; i < category_count; ++i)
109145 {
110− dee_model_append(category_model,
111− std::to_string(i).c_str(),
112− ("Category "+std::to_string(i)).c_str(),
113− "gtk-apply",
114− "grid",
115− hints);
146+ dee_model_append(category_model,
147+ std::to_string(i).c_str(),
148+ ("Category "+std::to_string(i)).c_str(),
149+ "gtk-apply",
150+ "grid",
151+ hints);
116152 }
117− g_variant_unref(hints);
118153 return category_model;
119154}
120155
@@ -122,48 +157,44 @@ DeeModel* create_categories_model(unsigned category_count) {
122157/* Schema that is used in the DeeModel representing
123158 the results */
124159static const gchar * results_model_schema[] = {
125− "s", // URI
126− "s", // ICON_HINT
127− "u", // CATEGORY
128− "u", // RESULT_TYPE
129− "s", // MIMETYPE
130− "s", // TITLE
131− "s", // COMMENT
132− "s", // DND_URI
133− "a{sv}" // METADATA
160+ "s", // URI
161+ "s", // ICON_HINT
162+ "u", // CATEGORY
163+ "u", // RESULT_TYPE
164+ "s", // MIMETYPE
165+ "s", // TITLE
166+ "s", // COMMENT
167+ "s", // DND_URI
168+ "a{sv}" // METADATA
134169};
135170
136171static const gchar * icons[] = {
137− "Applications.png",
138− "Home.png",
139− "Music.png",
140− "People.png",
141− "Videos.png",
172+ "Applications.png",
173+ "Home.png",
174+ "Music.png",
175+ "People.png",
176+ "Videos.png",
142177};
143178
144179DeeModel* create_results_model(unsigned category_count, unsigned result_count) {
145180 DeeModel* results_model = dee_sequence_model_new();
146181 dee_model_set_schema_full(results_model, results_model_schema, G_N_ELEMENTS(results_model_schema));
147−
148− GVariantBuilder b;
149− g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
150− GVariant *hints = g_variant_builder_end(&b);
182+ GVariant* hints = g_variant_new_array(g_variant_type_element(G_VARIANT_TYPE_VARDICT), NULL, 0);
151183
152184 for(unsigned i = 0; i < result_count; ++i)
153185 {
154− unsigned category = i % category_count;
155−
156− dee_model_append(results_model,
157− ("uri://result."+std::to_string(i)).c_str(),
158− (shellAppDirectory() + "Dash/graphics/scopeIcons/" + (icons[i%G_N_ELEMENTS(icons)])).toLatin1().data(),
159− category,
160− 0,
161− "application/x-desktop",
162− ("Title."+std::to_string(i)).c_str(),
163− ("Comment."+std::to_string(i)).c_str(),
164− ("uri://result."+std::to_string(i)).c_str(),
165− hints);
186+ unsigned category = i % category_count;
187+
188+ dee_model_append(results_model,
189+ ("uri://result."+std::to_string(i)).c_str(),
190+ (shellAppDirectory() + "Dash/graphics/scopeIcons/" + (icons[i%G_N_ELEMENTS(icons)])).toLatin1().data(),
191+ category,
192+ 0,
193+ "application/x-desktop",
194+ ("Title."+std::to_string(i)).c_str(),
195+ ("Comment."+std::to_string(i)).c_str(),
196+ ("uri://result."+std::to_string(i)).c_str(),
197+ hints);
166198 }
167− g_variant_unref(hints);
168199 return results_model;
169− }
200+}
tests/qmltests/plugins/Unity/fake_scope.h+43−11
@@ -19,43 +19,75 @@
1919
2020// Qt
2121#include <QObject>
22−#include "categories.h"
22+#include "fake_categories.h"
2323
2424class Scope : public QObject
2525{
2626 Q_OBJECT
27+
2728 Q_PROPERTY(QString id READ id NOTIFY idChanged)
28− Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
29− Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
29+ Q_PROPERTY(QString name READ name NOTIFY nameChanged)
30+ Q_PROPERTY(QString iconHint READ iconHint NOTIFY iconHintChanged)
31+ Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
32+ Q_PROPERTY(QString searchHint READ searchHint NOTIFY searchHintChanged)
3033 Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
34+ Q_PROPERTY(QString shortcut READ shortcut NOTIFY shortcutChanged)
35+ Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
3136 Q_PROPERTY(Categories* categories READ categories NOTIFY categoriesChanged)
3237
38+ Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
39+ Q_PROPERTY(QString noResultsHint READ noResultsHint WRITE setNoResultsHint NOTIFY noResultsHintChanged)
40+ Q_PROPERTY(QString formFactor READ formFactor WRITE setFormFactor NOTIFY formFactorChanged)
41+
3342public:
3443 Scope(QObject* parent = 0);
3544 Scope(QString const& id, QString const& name, bool visible, QObject* parent = 0);
3645
46+ /* getters */
3747 QString id() const;
3848 QString name() const;
39− QString searchQuery() const;
49+ QString iconHint() const;
50+ QString description() const;
51+ QString searchHint() const;
4052 bool visible() const;
41−
42− void setName(const QString &str);
43− void setSearchQuery(const QString &str);
44−
53+ QString shortcut() const;
54+ bool connected() const;
4555 Categories* categories() const;
56+ QString searchQuery() const;
57+ QString noResultsHint() const;
58+ QString formFactor() const;
59+
60+ /* setters */
61+ void setName(const QString& name);
62+ void setSearchQuery(const QString& search_query);
63+ void setNoResultsHint(const QString& hint);
64+ void setFormFactor(const QString& form_factor);
4665
4766Q_SIGNALS:
48− void idChanged(QString);
49− void nameChanged(QString);
50− void searchQueryChanged(QString);
67+ void idChanged(const QString&);
68+ void nameChanged(const QString&);
69+ void iconHintChanged(const QString&);
70+ void descriptionChanged(const QString&);
71+ void searchHintChanged(const QString&);
5172 void visibleChanged(bool);
73+ void shortcutChanged(const QString&);
74+ void connectedChanged(bool);
5275 void categoriesChanged();
76+ void searchFinished(const QString&);
77+ void searchQueryChanged();
78+ void noResultsHintChanged();
79+ void formFactorChanged();
5380
5481private:
5582 QString m_id;
83+ QString m_iconHint;
84+ QString m_description;
5685 QString m_name;
5786 QString m_searchQuery;
87+ QString m_noResultsHint;
88+ QString m_formFactor;
5889 bool m_visible;
90+
5991 Categories* m_categories;
6092 DeeListModel* m_results;
6193};
tests/qmltests/plugins/Unity/fake_unity_plugin.cpp+3−3
@@ -21,8 +21,8 @@
2121
2222// local
2323#include "fake_scopes.h"
24−#include "categories.h"
25−#include "categoryfilter.h"
24+#include "fake_categories.h"
25+#include "categoryresults.h"
2626#include "fake_launchermodel.h"
2727
2828// External
@@ -40,7 +40,7 @@ void FakeUnityPlugin::registerTypes(const char *uri)
4040 qmlRegisterType<Scopes>(uri, 0, 1, "Scopes");
4141 qmlRegisterType<Scope>(uri, 0, 1, "Scope");
4242 qmlRegisterType<Categories>(uri, 0, 1, "Categories");
43− qmlRegisterType<CategoryFilter>(uri, 0, 1, "CategoryFilter");
43+ qmlRegisterType<CategoryResults>(uri, 0, 1, "CategoryResults");
4444 qmlRegisterType<LauncherModel>(uri, 0, 1, "LauncherModel");
4545 qmlRegisterUncreatableType<LauncherItem>(uri, 0, 1, "LauncherItem", "Can't create");
4646}