on xenial help sign in
Make qmltests compile again
553eef8Michal Hruby
tests/qmltests/plugins/Unity/CMakeLists.txt+2−3
@@ -19,11 +19,10 @@ include_directories(
19add_definitions(-DQT_NO_KEYWORDS)
19add_definitions(-DQT_NO_KEYWORDS)
20
20
21set(UnityQML_SOURCES
21set(UnityQML_SOURCES
22− ${CMAKE_SOURCE_DIR}/plugins/Unity/categories.cpp
22+ ${CMAKE_SOURCE_DIR}/plugins/Unity/categoryresults.cpp
23− ${CMAKE_SOURCE_DIR}/plugins/Unity/categoryfilter.cpp
24− ${CMAKE_SOURCE_DIR}/plugins/Utils/qsortfilterproxymodelqml.cpp
25 fake_scope.cpp
23 fake_scope.cpp
26 fake_scopes.cpp
24 fake_scopes.cpp
25+ fake_categories.cpp
27 fake_unity_plugin.cpp
26 fake_unity_plugin.cpp
28 fake_launchermodel.cpp
27 fake_launchermodel.cpp
29)
28)
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
26// TODO: Implement remaining pieces
26// TODO: Implement remaining pieces
27
27
28Scope::Scope(QObject* parent)
28Scope::Scope(QObject* parent)
29−: QObject(parent),
29+ : QObject(parent)
30− m_visible(false),
30+ , m_visible(false)
31− m_categories(new Categories(this)),
31+ , m_categories(new Categories(this))
32− m_results(new DeeListModel(this))
32+ , m_results(new DeeListModel(this))
33{
33{
34+ DeeModel* results_model = create_results_model(4, 30);
35+ m_categories->setResultModel(results_model);
34 m_categories->setModel(create_categories_model(4));
36 m_categories->setModel(create_categories_model(4));
35− m_results->setModel(create_results_model(4, 30));
37+ m_results->setModel(results_model);
36−
37− m_categories->setResultModel(m_results);
38}
38}
39
39
40−Scope::Scope(QString const& id,
40+Scope::Scope(QString const& id, QString const& name, bool visible, QObject* parent)
41− QString const& name,
42− bool visible,
43− QObject* parent)
44−: QObject(parent),
41+ : QObject(parent)
45− m_id(id),
42+ , m_id(id)
46− m_name(name),
43+ , m_name(name)
47− m_visible(visible),
44+ , m_visible(visible)
48− m_categories(new Categories(this)),
45+ , m_categories(new Categories(this))
49− m_results(new DeeListModel(this))
46+ , m_results(new DeeListModel(this))
50{
47{
48+ DeeModel* results_model = create_results_model(4, 30);
49+ m_categories->setResultModel(results_model);
51 m_categories->setModel(create_categories_model(4));
50 m_categories->setModel(create_categories_model(4));
52− m_results->setModel(create_results_model(4, 30));
51+ m_results->setModel(results_model);
53−
54− m_categories->setResultModel(m_results);
55}
52}
56
53
57QString Scope::id() const {
54QString Scope::id() const {
@@ -66,6 +63,42 @@ QString Scope::searchQuery() const {
66 return m_searchQuery;
63 return m_searchQuery;
67}
64}
68
65
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+
69void Scope::setName(const QString &str) {
102void Scope::setName(const QString &str) {
70 if (str != m_name) {
103 if (str != m_name) {
71 m_name = str;
104 m_name = str;
@@ -76,45 +109,47 @@ void Scope::setName(const QString &str) {
76void Scope::setSearchQuery(const QString &str) {
109void Scope::setSearchQuery(const QString &str) {
77 if (str != m_searchQuery) {
110 if (str != m_searchQuery) {
78 m_searchQuery = str;
111 m_searchQuery = str;
79− Q_EMIT searchQueryChanged(m_searchQuery);
112+ Q_EMIT searchQueryChanged();
80 }
113 }
81}
114}
82
115
83−bool Scope::visible() const {
116+void Scope::setFormFactor(const QString &str) {
84− return m_visible;
117+ if (str != m_formFactor) {
118+ m_formFactor = str;
119+ Q_EMIT formFactorChanged();
120+ }
85}
121}
86
122
87−Categories* Scope::categories() const {
123+void Scope::setNoResultsHint(const QString& str) {
88− return m_categories;
124+ if (str != m_noResultsHint) {
125+ m_noResultsHint = str;
126+ Q_EMIT noResultsHintChanged();
127+ }
89}
128}
90
129
91static const gchar * categories_model_schema[] = {
130static const gchar * categories_model_schema[] = {
92− "s", //ID
131+ "s", //ID
93− "s", // DISPLAY_NAME
132+ "s", // DISPLAY_NAME
94− "s", // ICON_HINT
133+ "s", // ICON_HINT
95− "s", // RENDERER_NAME
134+ "s", // RENDERER_NAME
96− "a{sv}" // HINTS
135+ "a{sv}" // HINTS
97};
136};
98
137
99
138
100DeeModel* create_categories_model(unsigned category_count) {
139DeeModel* create_categories_model(unsigned category_count) {
101 DeeModel* category_model = dee_sequence_model_new();
140 DeeModel* category_model = dee_sequence_model_new();
102 dee_model_set_schema_full(category_model, categories_model_schema, G_N_ELEMENTS(categories_model_schema));
141 dee_model_set_schema_full(category_model, categories_model_schema, G_N_ELEMENTS(categories_model_schema));
103−
142+ GVariant* hints = g_variant_new_array(g_variant_type_element(G_VARIANT_TYPE_VARDICT), NULL, 0);
104− GVariantBuilder b;
105− g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
106− GVariant *hints = g_variant_builder_end(&b);
107
143
108 for(unsigned i = 0; i < category_count; ++i)
144 for(unsigned i = 0; i < category_count; ++i)
109 {
145 {
110− dee_model_append(category_model,
146+ dee_model_append(category_model,
111− std::to_string(i).c_str(),
147+ std::to_string(i).c_str(),
112− ("Category "+std::to_string(i)).c_str(),
148+ ("Category "+std::to_string(i)).c_str(),
113− "gtk-apply",
149+ "gtk-apply",
114− "grid",
150+ "grid",
115− hints);
151+ hints);
116 }
152 }
117− g_variant_unref(hints);
118 return category_model;
153 return category_model;
119}
154}
120
155
@@ -122,48 +157,44 @@ DeeModel* create_categories_model(unsigned category_count) {
122/* Schema that is used in the DeeModel representing
157/* Schema that is used in the DeeModel representing
123 the results */
158 the results */
124static const gchar * results_model_schema[] = {
159static const gchar * results_model_schema[] = {
125− "s", // URI
160+ "s", // URI
126− "s", // ICON_HINT
161+ "s", // ICON_HINT
127− "u", // CATEGORY
162+ "u", // CATEGORY
128− "u", // RESULT_TYPE
163+ "u", // RESULT_TYPE
129− "s", // MIMETYPE
164+ "s", // MIMETYPE
130− "s", // TITLE
165+ "s", // TITLE
131− "s", // COMMENT
166+ "s", // COMMENT
132− "s", // DND_URI
167+ "s", // DND_URI
133− "a{sv}" // METADATA
168+ "a{sv}" // METADATA
134};
169};
135
170
136static const gchar * icons[] = {
171static const gchar * icons[] = {
137− "Applications.png",
172+ "Applications.png",
138− "Home.png",
173+ "Home.png",
139− "Music.png",
174+ "Music.png",
140− "People.png",
175+ "People.png",
141− "Videos.png",
176+ "Videos.png",
142};
177};
143
178
144DeeModel* create_results_model(unsigned category_count, unsigned result_count) {
179DeeModel* create_results_model(unsigned category_count, unsigned result_count) {
145 DeeModel* results_model = dee_sequence_model_new();
180 DeeModel* results_model = dee_sequence_model_new();
146 dee_model_set_schema_full(results_model, results_model_schema, G_N_ELEMENTS(results_model_schema));
181 dee_model_set_schema_full(results_model, results_model_schema, G_N_ELEMENTS(results_model_schema));
147−
182+ GVariant* hints = g_variant_new_array(g_variant_type_element(G_VARIANT_TYPE_VARDICT), NULL, 0);
148− GVariantBuilder b;
149− g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
150− GVariant *hints = g_variant_builder_end(&b);
151
183
152 for(unsigned i = 0; i < result_count; ++i)
184 for(unsigned i = 0; i < result_count; ++i)
153 {
185 {
154− unsigned category = i % category_count;
186+ unsigned category = i % category_count;
155−
187+
156− dee_model_append(results_model,
188+ dee_model_append(results_model,
157− ("uri://result."+std::to_string(i)).c_str(),
189+ ("uri://result."+std::to_string(i)).c_str(),
158− (shellAppDirectory() + "Dash/graphics/scopeIcons/" + (icons[i%G_N_ELEMENTS(icons)])).toLatin1().data(),
190+ (shellAppDirectory() + "Dash/graphics/scopeIcons/" + (icons[i%G_N_ELEMENTS(icons)])).toLatin1().data(),
159− category,
191+ category,
160− 0,
192+ 0,
161− "application/x-desktop",
193+ "application/x-desktop",
162− ("Title."+std::to_string(i)).c_str(),
194+ ("Title."+std::to_string(i)).c_str(),
163− ("Comment."+std::to_string(i)).c_str(),
195+ ("Comment."+std::to_string(i)).c_str(),
164− ("uri://result."+std::to_string(i)).c_str(),
196+ ("uri://result."+std::to_string(i)).c_str(),
165− hints);
197+ hints);
166 }
198 }
167− g_variant_unref(hints);
168 return results_model;
199 return results_model;
169− }
200+}
tests/qmltests/plugins/Unity/fake_scope.h+43−11
@@ -19,43 +19,75 @@
19
19
20// Qt
20// Qt
21#include <QObject>
21#include <QObject>
22−#include "categories.h"
22+#include "fake_categories.h"
23
23
24class Scope : public QObject
24class Scope : public QObject
25{
25{
26 Q_OBJECT
26 Q_OBJECT
27+
27 Q_PROPERTY(QString id READ id NOTIFY idChanged)
28 Q_PROPERTY(QString id READ id NOTIFY idChanged)
28− Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
29+ Q_PROPERTY(QString name READ name NOTIFY nameChanged)
29− Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
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)
30 Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
33 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)
31 Q_PROPERTY(Categories* categories READ categories NOTIFY categoriesChanged)
36 Q_PROPERTY(Categories* categories READ categories NOTIFY categoriesChanged)
32
37
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+
33public:
42public:
34 Scope(QObject* parent = 0);
43 Scope(QObject* parent = 0);
35 Scope(QString const& id, QString const& name, bool visible, QObject* parent = 0);
44 Scope(QString const& id, QString const& name, bool visible, QObject* parent = 0);
36
45
46+ /* getters */
37 QString id() const;
47 QString id() const;
38 QString name() const;
48 QString name() const;
39− QString searchQuery() const;
49+ QString iconHint() const;
50+ QString description() const;
51+ QString searchHint() const;
40 bool visible() const;
52 bool visible() const;
41−
53+ QString shortcut() const;
42− void setName(const QString &str);
54+ bool connected() const;
43− void setSearchQuery(const QString &str);
44−
45 Categories* categories() const;
55 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);
46
65
47Q_SIGNALS:
66Q_SIGNALS:
48− void idChanged(QString);
67+ void idChanged(const QString&);
49− void nameChanged(QString);
68+ void nameChanged(const QString&);
50− void searchQueryChanged(QString);
69+ void iconHintChanged(const QString&);
70+ void descriptionChanged(const QString&);
71+ void searchHintChanged(const QString&);
51 void visibleChanged(bool);
72 void visibleChanged(bool);
73+ void shortcutChanged(const QString&);
74+ void connectedChanged(bool);
52 void categoriesChanged();
75 void categoriesChanged();
76+ void searchFinished(const QString&);
77+ void searchQueryChanged();
78+ void noResultsHintChanged();
79+ void formFactorChanged();
53
80
54private:
81private:
55 QString m_id;
82 QString m_id;
83+ QString m_iconHint;
84+ QString m_description;
56 QString m_name;
85 QString m_name;
57 QString m_searchQuery;
86 QString m_searchQuery;
87+ QString m_noResultsHint;
88+ QString m_formFactor;
58 bool m_visible;
89 bool m_visible;
90+
59 Categories* m_categories;
91 Categories* m_categories;
60 DeeListModel* m_results;
92 DeeListModel* m_results;
61};
93};
tests/qmltests/plugins/Unity/fake_unity_plugin.cpp+3−3
@@ -21,8 +21,8 @@
21
21
22// local
22// local
23#include "fake_scopes.h"
23#include "fake_scopes.h"
24−#include "categories.h"
24+#include "fake_categories.h"
25−#include "categoryfilter.h"
25+#include "categoryresults.h"
26#include "fake_launchermodel.h"
26#include "fake_launchermodel.h"
27
27
28// External
28// External
@@ -40,7 +40,7 @@ void FakeUnityPlugin::registerTypes(const char *uri)
40 qmlRegisterType<Scopes>(uri, 0, 1, "Scopes");
40 qmlRegisterType<Scopes>(uri, 0, 1, "Scopes");
41 qmlRegisterType<Scope>(uri, 0, 1, "Scope");
41 qmlRegisterType<Scope>(uri, 0, 1, "Scope");
42 qmlRegisterType<Categories>(uri, 0, 1, "Categories");
42 qmlRegisterType<Categories>(uri, 0, 1, "Categories");
43− qmlRegisterType<CategoryFilter>(uri, 0, 1, "CategoryFilter");
43+ qmlRegisterType<CategoryResults>(uri, 0, 1, "CategoryResults");
44 qmlRegisterType<LauncherModel>(uri, 0, 1, "LauncherModel");
44 qmlRegisterType<LauncherModel>(uri, 0, 1, "LauncherModel");
45 qmlRegisterUncreatableType<LauncherItem>(uri, 0, 1, "LauncherItem", "Can't create");
45 qmlRegisterUncreatableType<LauncherItem>(uri, 0, 1, "LauncherItem", "Can't create");
46}
46}