on xenial help sign in
Update fake/mock plugins so that "./run --fake" works well again

- You can now see the thumbnails of the fake running applications once again. - You no longer get hundreds of warnings due to icons not found.

commit040db367b3d91a5fa0b1c7eb2a892b7706597284 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateMon 2 Sep 2013, 17:34 (13 years ago) parenta81cbd7
10 files changed+373−21
tests/mocks/Unity/CMakeLists.txt+2 tests/mocks/Unity/fake_applications_scope.cpp+68 tests/mocks/Unity/fake_applications_scope.h+33 tests/mocks/Unity/fake_categories.cpp+84−9 tests/mocks/Unity/fake_categories.h+6−1 tests/mocks/Unity/fake_preview.cpp+66 tests/mocks/Unity/fake_preview.h+62 tests/mocks/Unity/fake_scope.cpp+33−9 tests/mocks/Unity/fake_scope.h+15−1 tests/mocks/Unity/fake_scopes.cpp+4−1
tests/mocks/Unity/CMakeLists.txt+2
@@ -17,6 +17,8 @@ add_definitions(-DQT_NO_KEYWORDS)
1717
1818set(UnityQML_SOURCES
1919 ${CMAKE_SOURCE_DIR}/plugins/Unity/categoryresults.cpp
20+ fake_applications_scope.cpp
21+ fake_preview.cpp
2022 fake_scope.cpp
2123 fake_scopes.cpp
2224 fake_categories.cpp
tests/mocks/Unity/fake_applications_scope.cppnew file+68
@@ -0,0 +1,68 @@
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+#include "fake_applications_scope.h"
18+
19+static const gchar * categories_model_schema[] = {
20+ "s", //ID
21+ "s", // DISPLAY_NAME
22+ "s", // ICON_HINT
23+ "s", // RENDERER_NAME
24+ "a{sv}" // HINTS
25+};
26+
27+ApplicationsScope::ApplicationsScope(bool visible, QObject* parent)
28+ : Scope(parent)
29+{
30+ m_id = "applications.scope";
31+ m_name = "Applications";
32+ m_visible = visible;
33+ m_categories->setModel(createCategoriesModel());
34+}
35+
36+DeeModel* ApplicationsScope::createCategoriesModel()
37+{
38+ DeeModel* category_model = dee_sequence_model_new();
39+ dee_model_set_schema_full(category_model, categories_model_schema, G_N_ELEMENTS(categories_model_schema));
40+ GVariant* hints = g_variant_new_array(g_variant_type_element(G_VARIANT_TYPE_VARDICT), NULL, 0);
41+
42+ GVariant* children[1];
43+ children[0] = g_variant_new_dict_entry(g_variant_new_string("content-type"),
44+ g_variant_new_variant(g_variant_new_string("apps")));
45+ GVariant* recentHints = g_variant_new_array(g_variant_type_element(G_VARIANT_TYPE_VARDICT), children, 1);
46+ dee_model_append(category_model,
47+ "recent",
48+ "Recent",
49+ "gtk-apply",
50+ "special",
51+ recentHints);
52+
53+ dee_model_append(category_model,
54+ "installed",
55+ "Installed",
56+ "gtk-apply",
57+ "grid",
58+ hints);
59+
60+ dee_model_append(category_model,
61+ "suggested",
62+ "Suggested",
63+ "gtk-apply",
64+ "grid",
65+ hints);
66+
67+ return category_model;
68+}
tests/mocks/Unity/fake_applications_scope.hnew file+33
@@ -0,0 +1,33 @@
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_APPLICATIONS_SCOPE_H
18+#define FAKE_APPLICATIONS_SCOPE_H
19+
20+#include "fake_scope.h"
21+
22+class ApplicationsScope : public Scope
23+{
24+ Q_OBJECT
25+
26+public:
27+ ApplicationsScope(bool visible, QObject* parent = 0);
28+
29+private:
30+ DeeModel* createCategoriesModel();
31+};
32+
33+#endif // FAKE_APPLICATIONS_SCOPE_H
tests/mocks/Unity/fake_categories.cpp+84−9
@@ -24,11 +24,20 @@
2424
2525#define CATEGORY_COLUMN 2
2626
27+// TODO: use something from libunity once it's public
28+enum CategoryColumn {
29+ ID,
30+ DISPLAY_NAME,
31+ ICON_HINT,
32+ RENDERER_NAME,
33+ HINTS
34+};
35+
2736Categories::Categories(QObject* parent)
2837 : DeeListModel(parent)
2938{
3039 // FIXME: need to clean up unused filters on countChanged
31− m_roles[Categories::RoleId] = "id";
40+ m_roles[Categories::RoleCategoryId] = "categoryId";
3241 m_roles[Categories::RoleName] = "name";
3342 m_roles[Categories::RoleIcon] = "icon";
3443 m_roles[Categories::RoleRenderer] = "renderer";
@@ -74,6 +83,25 @@ Categories::onCountChanged()
7483 }
7584}
7685
86+void Categories::onRowCountChanged()
87+{
88+ QAbstractItemModel* model = qobject_cast<QAbstractItemModel*>(sender());
89+ // find the corresponding category index
90+ for (auto iter = m_overriddenCategories.begin(); iter != m_overriddenCategories.end(); ++iter) {
91+ if (iter.value() == model) {
92+ for (int i = 0; i < rowCount(); i++) {
93+ auto id = data(index(i), RoleCategoryId).toString();
94+ if (id != iter.key()) continue;
95+ QVector<int> roles;
96+ roles.append(RoleCount);
97+ QModelIndex changedIndex = index(i);
98+ Q_EMIT dataChanged(changedIndex, changedIndex, roles);
99+ break;
100+ }
101+ }
102+ }
103+}
104+
77105void
78106Categories::onEmitCountChanged()
79107{
@@ -93,6 +121,41 @@ Categories::roleNames() const
93121 return m_roles;
94122}
95123
124+void Categories::onOverrideModelDestroyed()
125+{
126+ QObject* model = sender();
127+ auto iter = m_overriddenCategories.begin();
128+ while (iter != m_overriddenCategories.end()) {
129+ if (iter.value() == model) {
130+ iter = m_overriddenCategories.erase(iter);
131+ continue;
132+ }
133+ ++iter;
134+ }
135+}
136+
137+void Categories::overrideResults(const QString& categoryId, QAbstractItemModel* model)
138+{
139+ m_overriddenCategories[categoryId] = model;
140+ // watch the model
141+ connect(model, &QObject::destroyed, this, &Categories::onOverrideModelDestroyed);
142+ connect(model, &QAbstractItemModel::rowsInserted, this, &Categories::onRowCountChanged);
143+ connect(model, &QAbstractItemModel::rowsRemoved, this, &Categories::onRowCountChanged);
144+ connect(model, &QAbstractItemModel::modelReset, this, &Categories::onRowCountChanged);
145+
146+ // emit the dataChanged signal if the category is already in the model
147+ for (int i = 0; i < rowCount(); i++) {
148+ auto id = data(index(i), RoleCategoryId).toString();
149+ if (id != categoryId) continue;
150+ QVector<int> roles;
151+ roles.append(RoleCount);
152+ roles.append(RoleResults);
153+ QModelIndex changedIndex = index(i);
154+ Q_EMIT dataChanged(changedIndex, changedIndex, roles);
155+ break;
156+ }
157+}
158+
96159void Categories::setResultModel(DeeModel* model)
97160{
98161 // FIXME: should ref it
@@ -154,24 +217,36 @@ Categories::data(const QModelIndex& index, int role) const
154217 }
155218
156219 switch (role) {
157− case RoleId:
158− return DeeListModel::data(index, 0); //ID
220+ case RoleCategoryId:
221+ return DeeListModel::data(index, CategoryColumn::ID);
159222 case RoleName:
160− return DeeListModel::data(index, 1); //DISPLAY_NAME
223+ return DeeListModel::data(index, CategoryColumn::DISPLAY_NAME);
161224 case RoleIcon:
162− return DeeListModel::data(index, 2); //ICON_HINT
225+ return DeeListModel::data(index, CategoryColumn::ICON_HINT);
163226 case RoleRenderer:
164− return DeeListModel::data(index, 3); //RENDERER_NAME
227+ return DeeListModel::data(index, CategoryColumn::RENDERER_NAME);
165228 case RoleContentType:
166229 {
167− auto hints = DeeListModel::data(index, 4).toHash();
168− return hints.contains("content-type") ? hints["content-type"] : QVariant(QString("default"));
230+ auto hints = DeeListModel::data(index, CategoryColumn::HINTS).toHash();
231+ return hints.contains("content-type") ? hints["content-type"] : QVariant(QString("default"));
169232 }
170233 case RoleHints:
171− return DeeListModel::data(index, 4); //HINTS
234+ return DeeListModel::data(index, CategoryColumn::HINTS);
172235 case RoleResults:
236+ if (m_overriddenCategories.size() > 0)
237+ {
238+ auto id = DeeListModel::data(index, CategoryColumn::ID).toString();
239+ if (m_overriddenCategories.find(id) != m_overriddenCategories.end())
240+ return QVariant::fromValue(m_overriddenCategories[id]);
241+ }
173242 return QVariant::fromValue(getFilter(index.row()));
174243 case RoleCount:
244+ if (m_overriddenCategories.size() > 0)
245+ {
246+ auto id = DeeListModel::data(index, CategoryColumn::ID).toString();
247+ if (m_overriddenCategories.find(id) != m_overriddenCategories.end())
248+ return QVariant::fromValue(m_overriddenCategories[id]->rowCount());
249+ }
175250 return QVariant::fromValue(getFilter(index.row())->rowCount());
176251 case RoleCategoryIndex:
177252 return QVariant::fromValue(index.row());
tests/mocks/Unity/fake_categories.h+6−1
@@ -34,7 +34,7 @@ class Categories : public DeeListModel
3434public:
3535 Categories(QObject* parent = 0);
3636 enum Roles {
37− RoleId,
37+ RoleCategoryId,
3838 RoleName,
3939 RoleIcon,
4040 RoleRenderer,
@@ -45,6 +45,8 @@ public:
4545 RoleCategoryIndex
4646 };
4747
48+ Q_INVOKABLE void overrideResults(const QString& categoryId, QAbstractItemModel* model);
49+
4850 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
4951
5052 QHash<int, QByteArray> roleNames() const;
@@ -54,7 +56,9 @@ public:
5456
5557private Q_SLOTS:
5658 void onCountChanged();
59+ void onRowCountChanged();
5760 void onEmitCountChanged();
61+ void onOverrideModelDestroyed();
5862
5963private:
6064 DeeModel* getResultsForCategory(unsigned index) const;
@@ -64,6 +68,7 @@ private:
6468 QTimer m_timer;
6569 QSet<DeeListModel*> m_timerFilters;
6670 QHash<int, QByteArray> m_roles;
71+ QMap<QString, QAbstractItemModel*> m_overriddenCategories;
6772 mutable QMap<int, DeeListModel*> m_filters;
6873};
6974
tests/mocks/Unity/fake_preview.cppnew file+66
@@ -0,0 +1,66 @@
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+#include "fake_preview.h"
18+
19+QString Preview::rendererName() const
20+{
21+ return "foo";
22+}
23+
24+QString Preview::title() const
25+{
26+ return "Title";
27+}
28+
29+QString Preview::subtitle() const
30+{
31+ return "Subtitle";
32+}
33+
34+QString Preview::description() const
35+{
36+ return "Description";
37+}
38+
39+QVariant Preview::actions()
40+{
41+ return QVariant();
42+}
43+
44+QVariant Preview::infoHints()
45+{
46+ return QVariant();
47+}
48+
49+QVariantMap Preview::infoHintsHash() const
50+{
51+ return QVariantMap();
52+}
53+
54+QString Preview::image() const
55+{
56+ return "";
57+}
58+
59+QString Preview::imageSourceUri() const
60+{
61+ return "";
62+}
63+
64+void Preview::execute(const QString& actionId, const QHash<QString, QVariant>& hints)
65+{
66+}
tests/mocks/Unity/fake_preview.hnew file+62
@@ -0,0 +1,62 @@
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_PREVIEW_H
18+#define FAKE_PREVIEW_H
19+
20+// Qt
21+#include <QObject>
22+#include <QString>
23+#include <QMetaType>
24+#include <QList>
25+#include <QVariantMap>
26+
27+class Q_DECL_EXPORT Preview : public QObject
28+{
29+ Q_OBJECT
30+
31+ Q_PROPERTY(QString rendererName READ rendererName NOTIFY previewChanged)
32+ Q_PROPERTY(QString title READ title NOTIFY previewChanged)
33+ Q_PROPERTY(QString subtitle READ subtitle NOTIFY previewChanged)
34+ Q_PROPERTY(QString description READ description NOTIFY previewChanged)
35+ Q_PROPERTY(QVariant actions READ actions NOTIFY previewChanged)
36+ Q_PROPERTY(QVariant infoHints READ infoHints NOTIFY previewChanged)
37+ Q_PROPERTY(QVariantMap infoMap READ infoHintsHash NOTIFY previewChanged)
38+ Q_PROPERTY(QString image READ image NOTIFY previewChanged)
39+ Q_PROPERTY(QString imageSourceUri READ imageSourceUri NOTIFY previewChanged)
40+
41+public:
42+ explicit Preview(QObject *parent = 0);
43+
44+ QString rendererName() const;
45+ QString title() const;
46+ QString subtitle() const;
47+ QString description() const;
48+ QVariant actions();
49+ QVariant infoHints();
50+ QVariantMap infoHintsHash() const;
51+ QString image() const;
52+ QString imageSourceUri() const;
53+
54+ Q_INVOKABLE void execute(const QString& actionId, const QHash<QString, QVariant>& hints);
55+
56+Q_SIGNALS:
57+ void previewChanged();
58+};
59+
60+Q_DECLARE_METATYPE(Preview *)
61+
62+#endif // FAKE_PREVIEW_H
tests/mocks/Unity/fake_scope.cpp+33−9
@@ -20,6 +20,8 @@
2020#include <dee.h>
2121#include "paths.h"
2222
23+#include "fake_preview.h"
24+
2325static DeeModel* create_categories_model(unsigned category_count);
2426static DeeModel* create_results_model(unsigned category_count, unsigned result_count);
2527
@@ -127,6 +129,36 @@ void Scope::setNoResultsHint(const QString& str) {
127129 }
128130}
129131
132+void Scope::activate(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
133+ const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
134+ const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata)
135+{
136+ Q_UNUSED(uri);
137+ Q_UNUSED(icon_hint);
138+ Q_UNUSED(category);
139+ Q_UNUSED(result_type);
140+ Q_UNUSED(mimetype);
141+ Q_UNUSED(title);
142+ Q_UNUSED(comment);
143+ Q_UNUSED(dnd_uri);
144+ Q_UNUSED(metadata);
145+}
146+
147+void Scope::preview(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
148+ const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
149+ const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata)
150+{
151+ Q_UNUSED(uri);
152+ Q_UNUSED(icon_hint);
153+ Q_UNUSED(category);
154+ Q_UNUSED(result_type);
155+ Q_UNUSED(mimetype);
156+ Q_UNUSED(title);
157+ Q_UNUSED(comment);
158+ Q_UNUSED(dnd_uri);
159+ Q_UNUSED(metadata);
160+}
161+
130162static const gchar * categories_model_schema[] = {
131163 "s", //ID
132164 "s", // DISPLAY_NAME
@@ -168,14 +200,6 @@ static const gchar * results_model_schema[] = {
168200 "a{sv}" // METADATA
169201};
170202
171−static const gchar * icons[] = {
172− "Applications.png",
173− "Home.png",
174− "Music.png",
175− "People.png",
176− "Videos.png",
177−};
178−
179203DeeModel* create_results_model(unsigned category_count, unsigned result_count) {
180204 DeeModel* results_model = dee_sequence_model_new();
181205 dee_model_set_schema_full(results_model, results_model_schema, G_N_ELEMENTS(results_model_schema));
@@ -187,7 +211,7 @@ DeeModel* create_results_model(unsigned category_count, unsigned result_count) {
187211
188212 dee_model_append(results_model,
189213 ("uri://result."+std::to_string(i)).c_str(),
190− (shellAppDirectory() + "Dash/graphics/scopeIcons/" + (icons[i%G_N_ELEMENTS(icons)])).toLatin1().data(),
214+ (shellAppDirectory() + "graphics/applicationIcons/dash.png").toLatin1().data(),
191215 category,
192216 0,
193217 "application/x-desktop",
tests/mocks/Unity/fake_scope.h+15−1
@@ -21,6 +21,8 @@
2121#include <QObject>
2222#include "fake_categories.h"
2323
24+class Preview;
25+
2426class Scope : public QObject
2527{
2628 Q_OBJECT
@@ -63,6 +65,13 @@ public:
6365 void setNoResultsHint(const QString& hint);
6466 void setFormFactor(const QString& form_factor);
6567
68+ Q_INVOKABLE void activate(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
69+ const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
70+ const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata);
71+ Q_INVOKABLE void preview(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
72+ const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
73+ const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata);
74+
6675Q_SIGNALS:
6776 void idChanged(const QString&);
6877 void nameChanged(const QString&);
@@ -78,7 +87,12 @@ Q_SIGNALS:
7887 void noResultsHintChanged();
7988 void formFactorChanged();
8089
81−private:
90+ // signals triggered by activate(..) or preview(..) requests.
91+ void previewReady(Preview *preview);
92+ void activateApplication(const QString &desktop);
93+
94+protected:
95+
8296 QString m_id;
8397 QString m_iconHint;
8498 QString m_description;
tests/mocks/Unity/fake_scopes.cpp+4−1
@@ -19,6 +19,9 @@
1919// Self
2020#include "fake_scopes.h"
2121
22+// Local
23+#include "fake_applications_scope.h"
24+
2225// TODO: Implement remaining pieces, like Categories (i.e. LensView now gives warnings)
2326
2427// Qt
@@ -53,7 +56,7 @@ void Scopes::updateScopes()
5356 addScope(new Scope("MockScope1", "People", true, this));
5457 addScope(new Scope("MockScope2", "Music", false, this));
5558 addScope(new Scope("home.scope", "Home", true, this));
56− addScope(new Scope("applications.scope", "Applications", true, this));
59+ addScope(new ApplicationsScope(true, this));
5760 addScope(new Scope("MockScope5", "Videos", true, this));
5861
5962 if (!m_loaded) {