Merge lp:~artmello/ubuntu-system-settings/category-list-view into lp:ubuntu-system-settings
- category-list-view
- Merge into trunk
Status: | Approved |
---|---|
Approved by: | Jonas G. Drange |
Approved revision: | 1772 |
Proposed branch: | lp:~artmello/ubuntu-system-settings/category-list-view |
Merge into: | lp:ubuntu-system-settings |
Diff against target: |
748 lines (+141/-313) 14 files modified
src/CMakeLists.txt (+0/-2) src/item-model.cpp (+21/-9) src/item-model.h (+2/-0) src/plugin-manager.cpp (+29/-51) src/plugin-manager.h (+2/-3) src/qml/CategorySection.qml (+0/-91) src/qml/MainWindow.qml (+57/-35) src/qml/UncategorizedItemsView.qml (+0/-72) src/ui.qrc (+0/-2) tests/mocks/SystemSettings/MockPluginManager.cpp (+9/-11) tests/mocks/SystemSettings/MockPluginManager.h (+3/-4) tests/mocks/SystemSettings/qmldir (+0/-2) tests/plugins/main/tst_MainWindow.qml (+2/-2) tests/tst_plugins.cpp (+16/-29) |
To merge this branch: | bzr merge lp:~artmello/ubuntu-system-settings/category-list-view |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jonas G. Drange (community) | Approve | ||
system-apps-ci-bot | continuous-integration | Approve | |
Review via email: mp+321133@code.launchpad.net |
Commit message
Change Categories list view to use ListView qml Component
- Change PluginManager to keep only one instance of ItemModel instead of one for each category;
- Change ItemModel to order entries taking category in account;
- Change MainWindow to use ListView instead of Columns;
- Update tests
Description of the change
Change Categories list view to use ListView qml Component
- Change PluginManager to keep only one instance of ItemModel instead of one for each category;
- Change ItemModel to order entries taking category in account;
- Change MainWindow to use ListView instead of Columns;
- Update tests
system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
- 1770. By Arthur Mello
-
Disable sorting plugins test
system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:1770
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Jonas G. Drange (jonas-drange) wrote : | # |
There's that test failing, but it works really well!
- 1771. By Arthur Mello
-
Fix Plugins' sorting test
- 1772. By Arthur Mello
-
Fix testMainWindow
system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:1772
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Jonas G. Drange (jonas-drange) wrote : | # |
Real fine. Thanks!
- 1773. By Arthur Mello
-
Merge with trunk
Unmerged revisions
- 1773. By Arthur Mello
-
Merge with trunk
- 1772. By Arthur Mello
-
Fix testMainWindow
- 1771. By Arthur Mello
-
Fix Plugins' sorting test
- 1770. By Arthur Mello
-
Disable sorting plugins test
- 1769. By Arthur Mello
-
Change Categories list view to use ListView qml Component
- Change PluginManager to keep only one instance of ItemModel instead of one for each category;
- Change ItemModel to order entries taking category in account;
- Change MainWindow to use ListView instead of Columns;
- Update tests;
Preview Diff
1 | === modified file 'src/CMakeLists.txt' |
2 | --- src/CMakeLists.txt 2017-03-15 19:17:14 +0000 |
3 | +++ src/CMakeLists.txt 2017-03-30 12:58:38 +0000 |
4 | @@ -22,10 +22,8 @@ |
5 | ) |
6 | |
7 | set(QML_SOURCES |
8 | - qml/CategorySection.qml |
9 | qml/EntryComponent.qml |
10 | qml/MainWindow.qml |
11 | - qml/UncategorizedItemsView.qml |
12 | SystemSettings/ItemPage.qml |
13 | SystemSettings/SettingsItemTitle.qml |
14 | ) |
15 | |
16 | === modified file 'src/item-model.cpp' |
17 | --- src/item-model.cpp 2015-05-12 12:08:47 +0000 |
18 | +++ src/item-model.cpp 2017-03-30 12:58:38 +0000 |
19 | @@ -160,6 +160,11 @@ |
20 | ItemModelSortProxy::ItemModelSortProxy(QObject *parent) |
21 | : QSortFilterProxyModel(parent) |
22 | { |
23 | + m_categoriesOrder << "uncategorized-top"; |
24 | + m_categoriesOrder << "network"; |
25 | + m_categoriesOrder << "personal"; |
26 | + m_categoriesOrder << "system"; |
27 | + m_categoriesOrder << "uncategorized-bottom"; |
28 | } |
29 | |
30 | bool ItemModelSortProxy::lessThan(const QModelIndex &left, |
31 | @@ -172,15 +177,22 @@ |
32 | Plugin *rightPlugin = rightData.value<Plugin *>(); |
33 | |
34 | if (leftPlugin && rightPlugin) { |
35 | - int leftPriority = leftPlugin->priority(); |
36 | - int rightPriority = rightPlugin->priority(); |
37 | - |
38 | - /* In case two plugins happen to have the same priority, sort them |
39 | - alphabetically */ |
40 | - if (leftPriority == rightPriority) |
41 | - return leftPlugin->displayName() < rightPlugin->displayName(); |
42 | - |
43 | - return leftPriority < rightPriority; |
44 | + int leftCategoryOrder = m_categoriesOrder.indexOf(leftPlugin->category()); |
45 | + int rightCategoryOrder = m_categoriesOrder.indexOf(rightPlugin->category()); |
46 | + |
47 | + if (leftCategoryOrder == rightCategoryOrder) { |
48 | + int leftPriority = leftPlugin->priority(); |
49 | + int rightPriority = rightPlugin->priority(); |
50 | + |
51 | + /* In case two plugins happen to have the same priority, sort them |
52 | + alphabetically */ |
53 | + if (leftPriority == rightPriority) |
54 | + return leftPlugin->displayName() < rightPlugin->displayName(); |
55 | + |
56 | + return leftPriority < rightPriority; |
57 | + } |
58 | + |
59 | + return leftCategoryOrder < rightCategoryOrder; |
60 | } |
61 | |
62 | return false; |
63 | |
64 | === modified file 'src/item-model.h' |
65 | --- src/item-model.h 2014-07-23 13:29:15 +0000 |
66 | +++ src/item-model.h 2017-03-30 12:58:38 +0000 |
67 | @@ -69,6 +69,8 @@ |
68 | const QModelIndex &right) const; |
69 | virtual bool filterAcceptsRow(int source_row, |
70 | const QModelIndex &source_parent) const; |
71 | +private: |
72 | + QList<QString> m_categoriesOrder; |
73 | }; |
74 | |
75 | } // namespace |
76 | |
77 | === modified file 'src/plugin-manager.cpp' |
78 | --- src/plugin-manager.cpp 2016-09-23 13:13:24 +0000 |
79 | +++ src/plugin-manager.cpp 2017-03-30 12:58:38 +0000 |
80 | @@ -49,14 +49,15 @@ |
81 | |
82 | private: |
83 | mutable PluginManager *q_ptr; |
84 | - QMap<QString,QMap<QString, Plugin*> > m_plugins; |
85 | - QHash<QString,ItemModelSortProxy*> m_models; |
86 | + QMap<QString, Plugin*> m_plugins; |
87 | + ItemModelSortProxy* m_model; |
88 | }; |
89 | |
90 | } // namespace |
91 | |
92 | PluginManagerPrivate::PluginManagerPrivate(PluginManager *q): |
93 | - q_ptr(q) |
94 | + q_ptr(q), |
95 | + m_model(0) |
96 | { |
97 | } |
98 | |
99 | @@ -67,12 +68,8 @@ |
100 | |
101 | void PluginManagerPrivate::clear() |
102 | { |
103 | - QMapIterator<QString, QMap<QString, Plugin*> > it(m_plugins); |
104 | - while (it.hasNext()) { |
105 | - it.next(); |
106 | - Q_FOREACH(Plugin *plugin, it.value().values()) { |
107 | - delete plugin; |
108 | - } |
109 | + Q_FOREACH(Plugin *plugin, m_plugins.values()) { |
110 | + delete plugin; |
111 | } |
112 | m_plugins.clear(); |
113 | } |
114 | @@ -109,9 +106,8 @@ |
115 | Q_FOREACH(const QFileInfo &fileInfo, searchPaths) { |
116 | Plugin *plugin = new Plugin(fileInfo); |
117 | QQmlEngine::setContextForObject(plugin, ctx); |
118 | - QMap<QString, Plugin*> &pluginList = m_plugins[plugin->category()]; |
119 | if (showAll || !plugin->hideByDefault()) |
120 | - pluginList.insert(fileInfo.baseName(), plugin); |
121 | + m_plugins.insert(fileInfo.baseName(), plugin); |
122 | } |
123 | } |
124 | |
125 | @@ -126,59 +122,45 @@ |
126 | delete d_ptr; |
127 | } |
128 | |
129 | -QStringList PluginManager::categories() const |
130 | -{ |
131 | - Q_D(const PluginManager); |
132 | - return d->m_plugins.keys(); |
133 | -} |
134 | - |
135 | -QMap<QString, Plugin *> PluginManager::plugins(const QString &category) const |
136 | -{ |
137 | - Q_D(const PluginManager); |
138 | - return d->m_plugins.value(category); |
139 | +QMap<QString, Plugin *> PluginManager::plugins() const |
140 | +{ |
141 | + Q_D(const PluginManager); |
142 | + return d->m_plugins; |
143 | } |
144 | |
145 | void PluginManager::resetPlugins() |
146 | { |
147 | Q_D(const PluginManager); |
148 | - |
149 | - typedef QMap<QString, Plugin *> Plugins; |
150 | - Q_FOREACH (const Plugins &plugins, d->m_plugins.values()) { |
151 | - Q_FOREACH (Plugin *plugin, plugins.values()) { |
152 | + Q_FOREACH (Plugin *plugin, d->m_plugins) { |
153 | plugin->reset(); |
154 | - } |
155 | } |
156 | } |
157 | |
158 | -QAbstractItemModel *PluginManager::itemModel(const QString &category) |
159 | +QAbstractItemModel *PluginManager::itemModel() |
160 | { |
161 | Q_D(PluginManager); |
162 | - ItemModelSortProxy *&model = d->m_models[category]; |
163 | - if (model == 0) { |
164 | + if (d->m_model == 0) { |
165 | ItemModel *backing_model = new ItemModel(this); |
166 | - backing_model->setPlugins(plugins(category)); |
167 | + backing_model->setPlugins(plugins()); |
168 | /* Return a sorted proxy backed by the real model containing the items */ |
169 | - model = new ItemModelSortProxy(this); |
170 | - model->setSourceModel(backing_model); |
171 | - model->setDynamicSortFilter(true); |
172 | - model->setFilterCaseSensitivity(Qt::CaseInsensitive); |
173 | - model->setFilterRole(ItemModel::KeywordRole); |
174 | + d->m_model = new ItemModelSortProxy(this); |
175 | + d->m_model->setSourceModel(backing_model); |
176 | + d->m_model->setDynamicSortFilter(true); |
177 | + d->m_model->setFilterCaseSensitivity(Qt::CaseInsensitive); |
178 | + d->m_model->setFilterRole(ItemModel::KeywordRole); |
179 | /* we only have one column as this is a QAbstractListModel */ |
180 | - model->sort(0); |
181 | + d->m_model->sort(0); |
182 | } |
183 | |
184 | - return model; |
185 | + return d->m_model; |
186 | } |
187 | |
188 | QObject *PluginManager::getByName(const QString &name) const |
189 | { |
190 | Q_D(const PluginManager); |
191 | - QMapIterator<QString, QMap<QString, Plugin *> > plugins(d->m_plugins); |
192 | - while (plugins.hasNext()) { |
193 | - plugins.next(); |
194 | - if (plugins.value().contains(name)) |
195 | - return plugins.value()[name]; |
196 | - } |
197 | + if (d->m_plugins.contains(name)) |
198 | + return d->m_plugins[name]; |
199 | + |
200 | return nullptr; |
201 | } |
202 | |
203 | @@ -190,14 +172,10 @@ |
204 | void PluginManager::setFilter(const QString &filter) |
205 | { |
206 | Q_D(PluginManager); |
207 | - QHashIterator<QString,ItemModelSortProxy*> it(d->m_models); |
208 | - while (it.hasNext()) { |
209 | - it.next(); |
210 | - if (filter.isEmpty()) |
211 | - it.value()->setFilterRegExp(""); |
212 | - else |
213 | - it.value()->setFilterRegExp(filter); |
214 | - } |
215 | + if (filter.isEmpty()) |
216 | + d->m_model->setFilterRegExp(""); |
217 | + else |
218 | + d->m_model->setFilterRegExp(filter); |
219 | m_filter = filter; |
220 | Q_EMIT (filterChanged()); |
221 | } |
222 | |
223 | === modified file 'src/plugin-manager.h' |
224 | --- src/plugin-manager.h 2014-08-11 09:18:12 +0000 |
225 | +++ src/plugin-manager.h 2017-03-30 12:58:38 +0000 |
226 | @@ -45,11 +45,10 @@ |
227 | explicit PluginManager(QObject *parent = 0); |
228 | ~PluginManager(); |
229 | |
230 | - QStringList categories() const; |
231 | - QMap<QString, Plugin *> plugins(const QString &category) const; |
232 | + QMap<QString, Plugin *> plugins() const; |
233 | |
234 | Q_INVOKABLE QObject *getByName(const QString &name) const; |
235 | - Q_INVOKABLE QAbstractItemModel *itemModel(const QString &category); |
236 | + Q_INVOKABLE QAbstractItemModel *itemModel(); |
237 | Q_INVOKABLE void resetPlugins(); |
238 | QString getFilter(); |
239 | void setFilter(const QString &filter); |
240 | |
241 | === removed file 'src/qml/CategorySection.qml' |
242 | --- src/qml/CategorySection.qml 2016-12-09 15:19:24 +0000 |
243 | +++ src/qml/CategorySection.qml 1970-01-01 00:00:00 +0000 |
244 | @@ -1,91 +0,0 @@ |
245 | -/* |
246 | - * This file is part of system-settings |
247 | - * |
248 | - * Copyright (C) 2015-2016 Canonical Ltd. |
249 | - * |
250 | - * Contact: Ken VanDine <ken.vandine@canonical.com> |
251 | - * |
252 | - * This program is free software: you can redistribute it and/or modify it |
253 | - * under the terms of the GNU General Public License version 3, as published |
254 | - * by the Free Software Foundation. |
255 | - * |
256 | - * This program is distributed in the hope that it will be useful, but |
257 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
258 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
259 | - * PURPOSE. See the GNU General Public License for more details. |
260 | - * |
261 | - * You should have received a copy of the GNU General Public License along |
262 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
263 | - */ |
264 | - |
265 | -import QtQuick 2.4 |
266 | -import SystemSettings 1.0 |
267 | -import SystemSettings.ListItems 1.0 as SettingsListItems |
268 | -import Ubuntu.Components 1.3 |
269 | - |
270 | - |
271 | -Column { |
272 | - anchors { |
273 | - left: parent.left |
274 | - right: parent.right |
275 | - } |
276 | - spacing: units.gu(1) |
277 | - |
278 | - property string category |
279 | - property string categoryName |
280 | - |
281 | - objectName: "categoryGrid-" + category |
282 | - |
283 | - SettingsItemTitle { |
284 | - id: header |
285 | - text: categoryName |
286 | - visible: repeater.count > 0 |
287 | - } |
288 | - |
289 | - Column { |
290 | - id: col |
291 | - anchors { |
292 | - left: parent.left |
293 | - right: parent.right |
294 | - } |
295 | - |
296 | - Repeater { |
297 | - id: repeater |
298 | - |
299 | - model: pluginManager.itemModel(category) |
300 | - |
301 | - delegate: Loader { |
302 | - id: loader |
303 | - anchors { |
304 | - left: col.left |
305 | - right: col.right |
306 | - } |
307 | - sourceComponent: model.item.entryComponent |
308 | - active: model.item.visible |
309 | - Connections { |
310 | - ignoreUnknownSignals: true |
311 | - target: loader.item |
312 | - onClicked: { |
313 | - var pageComponent = model.item.pageComponent |
314 | - if (pageComponent) { |
315 | - Haptics.play(); |
316 | - loadPluginByName(model.item.baseName); |
317 | - } |
318 | - } |
319 | - } |
320 | - Binding { |
321 | - target: loader.item |
322 | - property: "color" |
323 | - value: theme.palette.highlighted.background |
324 | - when: currentPlugin == model.item.baseName && apl.columns > 1 |
325 | - } |
326 | - Binding { |
327 | - target: loader.item |
328 | - property: "color" |
329 | - value: "transparent" |
330 | - when: currentPlugin != model.item.baseName || apl.columns == 1 |
331 | - } |
332 | - } |
333 | - } |
334 | - } |
335 | -} |
336 | |
337 | === modified file 'src/qml/MainWindow.qml' |
338 | --- src/qml/MainWindow.qml 2017-03-24 10:35:32 +0000 |
339 | +++ src/qml/MainWindow.qml 2017-03-30 12:58:38 +0000 |
340 | @@ -168,7 +168,7 @@ |
341 | automaticHeight: false |
342 | visible: mainPage.header === standardHeader |
343 | title: i18n.tr("System Settings") |
344 | - flickable: mainFlickable |
345 | + flickable: categoriesListView |
346 | trailingActionBar.actions: [ |
347 | Action { |
348 | objectName: "searchAction" |
349 | @@ -189,7 +189,7 @@ |
350 | // so when in APL the height doesn't change |
351 | automaticHeight: false |
352 | visible: mainPage.header === searchHeader |
353 | - flickable: mainFlickable |
354 | + flickable: categoriesListView |
355 | contents: TextField { |
356 | id: searchField |
357 | objectName: "searchField" |
358 | @@ -219,40 +219,62 @@ |
359 | z: 1 |
360 | } |
361 | |
362 | - Flickable { |
363 | - id: mainFlickable |
364 | + ListView { |
365 | + id: categoriesListView |
366 | anchors.fill: parent |
367 | - contentHeight: contentItem.childrenRect.height |
368 | - boundsBehavior: (contentHeight > mainPage.height) ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds |
369 | - /* Set the direction to workaround https://bugreports.qt-project.org/browse/QTBUG-31905 |
370 | - otherwise the UI might end up in a situation where scrolling doesn't work */ |
371 | - flickableDirection: Flickable.VerticalFlick |
372 | - |
373 | - Column { |
374 | - anchors.left: parent.left |
375 | - anchors.right: parent.right |
376 | - |
377 | - UncategorizedItemsView { |
378 | - model: pluginManager.itemModel("uncategorized-top") |
379 | - } |
380 | - |
381 | - CategorySection { |
382 | - category: "network" |
383 | - categoryName: i18n.tr("Network") |
384 | - } |
385 | - |
386 | - CategorySection { |
387 | - category: "personal" |
388 | - categoryName: i18n.tr("Personal") |
389 | - } |
390 | - |
391 | - CategorySection { |
392 | - category: "system" |
393 | - categoryName: i18n.tr("System") |
394 | - } |
395 | - |
396 | - UncategorizedItemsView { |
397 | - model: pluginManager.itemModel("uncategorized-bottom") |
398 | + model: pluginManager.itemModel() |
399 | + focus: true |
400 | + section.property: "item.category" |
401 | + section.delegate: Loader { |
402 | + anchors { |
403 | + left: parent.left |
404 | + right: parent.right |
405 | + } |
406 | + active: section !== "uncategorized-top" && section !== "uncategorized-bottom" |
407 | + sourceComponent: SettingsItemTitle { |
408 | + text: { |
409 | + if (section === "network") { |
410 | + return i18n.tr("Network") |
411 | + } else if (section === "personal") { |
412 | + return i18n.tr("Personal") |
413 | + } else if (section === "system") { |
414 | + return i18n.tr("System") |
415 | + } |
416 | + return section |
417 | + } |
418 | + } |
419 | + } |
420 | + |
421 | + delegate: Loader { |
422 | + id: loader |
423 | + anchors { |
424 | + left: parent.left |
425 | + right: parent.right |
426 | + } |
427 | + sourceComponent: model.item.entryComponent |
428 | + active: model.item.visible |
429 | + Connections { |
430 | + ignoreUnknownSignals: true |
431 | + target: loader.item |
432 | + onClicked: { |
433 | + var pageComponent = model.item.pageComponent |
434 | + if (pageComponent) { |
435 | + Haptics.play(); |
436 | + loadPluginByName(model.item.baseName); |
437 | + } |
438 | + } |
439 | + } |
440 | + Binding { |
441 | + target: loader.item |
442 | + property: "color" |
443 | + value: theme.palette.highlighted.background |
444 | + when: currentPlugin == model.item.baseName && apl.columns > 1 |
445 | + } |
446 | + Binding { |
447 | + target: loader.item |
448 | + property: "color" |
449 | + value: "transparent" |
450 | + when: currentPlugin != model.item.baseName || apl.columns == 1 |
451 | } |
452 | } |
453 | } |
454 | |
455 | === removed file 'src/qml/UncategorizedItemsView.qml' |
456 | --- src/qml/UncategorizedItemsView.qml 2016-12-09 15:19:24 +0000 |
457 | +++ src/qml/UncategorizedItemsView.qml 1970-01-01 00:00:00 +0000 |
458 | @@ -1,72 +0,0 @@ |
459 | -/* |
460 | - * This file is part of system-settings |
461 | - * |
462 | - * Copyright (C) 2013 Canonical Ltd. |
463 | - * |
464 | - * Contact: Alberto Mardegan <alberto.mardegan@canonical.com> |
465 | - * |
466 | - * This program is free software: you can redistribute it and/or modify it |
467 | - * under the terms of the GNU General Public License version 3, as published |
468 | - * by the Free Software Foundation. |
469 | - * |
470 | - * This program is distributed in the hope that it will be useful, but |
471 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
472 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
473 | - * PURPOSE. See the GNU General Public License for more details. |
474 | - * |
475 | - * You should have received a copy of the GNU General Public License along |
476 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
477 | - */ |
478 | - |
479 | -import QtQuick 2.4 |
480 | -import Ubuntu.Components 1.3 |
481 | -import Ubuntu.Components.ListItems 1.3 as ListItem |
482 | -import SystemSettings 1.0 |
483 | - |
484 | -Column { |
485 | - property alias model: repeater.model |
486 | - |
487 | - visible: repeater.count > 0 |
488 | - |
489 | - anchors.left: parent.left |
490 | - anchors.right: parent.right |
491 | - |
492 | - Repeater { |
493 | - id: repeater |
494 | - Column { |
495 | - anchors.left: parent.left |
496 | - anchors.right: parent.right |
497 | - |
498 | - Loader { |
499 | - id: loader |
500 | - anchors.left: parent.left |
501 | - anchors.right: parent.right |
502 | - sourceComponent: model.item.entryComponent |
503 | - active: model.item.visible |
504 | - Connections { |
505 | - ignoreUnknownSignals: true |
506 | - target: loader.item |
507 | - onClicked: { |
508 | - var pageComponent = model.item.pageComponent |
509 | - if (pageComponent) { |
510 | - Haptics.play(); |
511 | - loadPluginByName(model.item.baseName); |
512 | - } |
513 | - } |
514 | - } |
515 | - Binding { |
516 | - target: loader.item |
517 | - property: "color" |
518 | - value: theme.palette.highlighted.background |
519 | - when: currentPlugin == model.item.baseName && apl.columns > 1 |
520 | - } |
521 | - Binding { |
522 | - target: loader.item |
523 | - property: "color" |
524 | - value: "transparent" |
525 | - when: currentPlugin != model.item.baseName || apl.columns == 1 |
526 | - } |
527 | - } |
528 | - } |
529 | - } |
530 | -} |
531 | |
532 | === modified file 'src/ui.qrc' |
533 | --- src/ui.qrc 2016-10-14 14:41:20 +0000 |
534 | +++ src/ui.qrc 2017-03-30 12:58:38 +0000 |
535 | @@ -1,8 +1,6 @@ |
536 | <!DOCTYPE RCC><RCC version="1.0"> |
537 | <qresource> |
538 | - <file>qml/CategorySection.qml</file> |
539 | <file>qml/EntryComponent.qml</file> |
540 | <file>qml/MainWindow.qml</file> |
541 | - <file>qml/UncategorizedItemsView.qml</file> |
542 | </qresource> |
543 | </RCC> |
544 | |
545 | === modified file 'tests/mocks/SystemSettings/MockPluginManager.cpp' |
546 | --- tests/mocks/SystemSettings/MockPluginManager.cpp 2017-03-17 13:16:41 +0000 |
547 | +++ tests/mocks/SystemSettings/MockPluginManager.cpp 2017-03-30 12:58:38 +0000 |
548 | @@ -21,7 +21,9 @@ |
549 | #include <QDebug> |
550 | #include <QQmlEngine> |
551 | |
552 | -MockPluginManager::MockPluginManager(QObject *parent) : QObject(parent) |
553 | +MockPluginManager::MockPluginManager(QObject *parent) : |
554 | + QObject(parent), |
555 | + m_model(0) |
556 | { |
557 | } |
558 | |
559 | @@ -32,9 +34,9 @@ |
560 | return p; |
561 | } |
562 | |
563 | -QAbstractItemModel* MockPluginManager::itemModel(const QString &category) |
564 | +QAbstractItemModel* MockPluginManager::itemModel() |
565 | { |
566 | - QAbstractItemModel* m = m_models.value(category); |
567 | + QAbstractItemModel* m = m_model; |
568 | QQmlEngine::setObjectOwnership(m, QQmlEngine::CppOwnership); |
569 | return m; |
570 | } |
571 | @@ -55,21 +57,17 @@ |
572 | } |
573 | |
574 | void MockPluginManager::addPlugin(const QString &name, QQmlComponent *entry, |
575 | - QQmlComponent *page, const QString &category) |
576 | + QQmlComponent *page) |
577 | { |
578 | - MockItemModel *model = nullptr; |
579 | - if (m_models.contains(category)) { |
580 | - model = (MockItemModel*) m_models.value(category); |
581 | - } else { |
582 | - model = new MockItemModel(this); |
583 | - m_models.insert(category, model); |
584 | + if (!m_model) { |
585 | + m_model = new MockItemModel(this); |
586 | } |
587 | |
588 | MockItem* item = new MockItem(this); |
589 | item->setBaseName(name); |
590 | item->setEntryComponent(entry); |
591 | item->setPageComponent(page); |
592 | - model->addPlugin(item); |
593 | + m_model->addPlugin(item); |
594 | m_plugins.insert(name, item); |
595 | } |
596 | |
597 | |
598 | === modified file 'tests/mocks/SystemSettings/MockPluginManager.h' |
599 | --- tests/mocks/SystemSettings/MockPluginManager.h 2017-03-17 13:16:41 +0000 |
600 | +++ tests/mocks/SystemSettings/MockPluginManager.h 2017-03-30 12:58:38 +0000 |
601 | @@ -38,21 +38,20 @@ |
602 | |
603 | public Q_SLOTS: |
604 | QObject* getByName(const QString &name) const; |
605 | - QAbstractItemModel* itemModel(const QString &category); |
606 | + QAbstractItemModel* itemModel(); |
607 | void resetPlugins(); |
608 | QString getFilter(); |
609 | void setFilter(const QString &filter); |
610 | void addPlugin(const QString &name, |
611 | QQmlComponent *entry, |
612 | - QQmlComponent *page, |
613 | - const QString &category = "uncategorized-bottom"); |
614 | + QQmlComponent *page); |
615 | |
616 | Q_SIGNALS: |
617 | void filterChanged(); |
618 | |
619 | private: |
620 | QString m_filter = QString::null; |
621 | - QMap<QString, MockItemModel*> m_models; |
622 | + MockItemModel* m_model; |
623 | QMap<QString, MockItem*> m_plugins; |
624 | }; |
625 | |
626 | |
627 | === modified file 'tests/mocks/SystemSettings/qmldir' |
628 | --- tests/mocks/SystemSettings/qmldir 2017-03-17 13:16:41 +0000 |
629 | +++ tests/mocks/SystemSettings/qmldir 2017-03-30 12:58:38 +0000 |
630 | @@ -4,6 +4,4 @@ |
631 | ItemPage 1.0 file://${CMAKE_SOURCE_DIR}/src/SystemSettings/ItemPage.qml |
632 | SettingsItemTitle 1.0 file://${CMAKE_SOURCE_DIR}/src/SystemSettings/SettingsItemTitle.qml |
633 | USSAdaptivePageLayout 1.0 file://${CMAKE_SOURCE_DIR}/src/SystemSettings/USSAdaptivePageLayout.qml |
634 | -CategorySection 1.0 file://${CMAKE_SOURCE_DIR}/src/qml/CategorySection.qml |
635 | -UncategorizedItemsView.qml 1.0 file://${CMAKE_SOURCE_DIR}/src/qml/UncategorizedItemsView.qml.qml |
636 | MainWindow 1.0 file://${CMAKE_SOURCE_DIR}/src/qml/MainWindow.qml |
637 | |
638 | === modified file 'tests/plugins/main/tst_MainWindow.qml' |
639 | --- tests/plugins/main/tst_MainWindow.qml 2016-12-14 13:37:49 +0000 |
640 | +++ tests/plugins/main/tst_MainWindow.qml 2017-03-30 12:58:38 +0000 |
641 | @@ -171,8 +171,8 @@ |
642 | uncategorizedEntry = testUncategorizedEntry; |
643 | page = testPageComponent; |
644 | |
645 | - manager.addPlugin("Test", personalEntry, page, "personal"); |
646 | - manager.addPlugin("Phone", uncategorizedEntry, page, "uncategorized-bottom"); |
647 | + manager.addPlugin("Test", personalEntry, page); |
648 | + manager.addPlugin("Phone", uncategorizedEntry, page); |
649 | } |
650 | |
651 | function cleanup() { |
652 | |
653 | === modified file 'tests/tst_plugins.cpp' |
654 | --- tests/tst_plugins.cpp 2015-08-13 20:31:53 +0000 |
655 | +++ tests/tst_plugins.cpp 2017-03-30 12:58:38 +0000 |
656 | @@ -53,23 +53,16 @@ |
657 | manager.classBegin(); |
658 | manager.componentComplete(); |
659 | |
660 | + QMap<QString, Plugin *> plugins = manager.plugins(); |
661 | + QCOMPARE(plugins.count(), 5); |
662 | + |
663 | + QStringList categories; |
664 | + Q_FOREACH(Plugin *plugin, plugins) { |
665 | + categories << plugin->category(); |
666 | + } |
667 | QSet<QString> expectedCategories; |
668 | expectedCategories << "phone" << "network" << "misc" << "system"; |
669 | - QCOMPARE(manager.categories().toSet(), expectedCategories); |
670 | - |
671 | - QMap<QString, Plugin *> plugins = manager.plugins("phone"); |
672 | - QCOMPARE(plugins.count(), 1); |
673 | - QCOMPARE(plugins.value("cellular")->displayName(), QString("Cellular")); |
674 | - |
675 | - plugins = manager.plugins("network"); |
676 | - QCOMPARE(plugins.count(), 2); |
677 | - QStringList names; |
678 | - Q_FOREACH(Plugin *plugin, plugins) { |
679 | - names << plugin->displayName(); |
680 | - } |
681 | - QSet<QString> expectedNames; |
682 | - expectedNames << "Bluetooth" << "Wireless"; |
683 | - QCOMPARE(names.toSet(), expectedNames); |
684 | + QCOMPARE(categories.toSet(), expectedCategories); |
685 | } |
686 | |
687 | void PluginsTest::testName() |
688 | @@ -79,7 +72,7 @@ |
689 | manager.componentComplete(); |
690 | |
691 | Plugin *brightness = 0; |
692 | - Q_FOREACH(Plugin *plugin, manager.plugins("system")) { |
693 | + Q_FOREACH(Plugin *plugin, manager.plugins()) { |
694 | if (plugin->displayName() == "Brightness & Display") { |
695 | brightness = plugin; |
696 | } |
697 | @@ -98,7 +91,7 @@ |
698 | |
699 | Plugin *wireless = 0; |
700 | Plugin *bluetooth = 0; |
701 | - Q_FOREACH(Plugin *plugin, manager.plugins("network")) { |
702 | + Q_FOREACH(Plugin *plugin, manager.plugins()) { |
703 | if (plugin->displayName() == "Bluetooth") { |
704 | bluetooth = plugin; |
705 | } else if (plugin->displayName() == "Wireless") { |
706 | @@ -127,14 +120,14 @@ |
707 | manager.classBegin(); |
708 | manager.componentComplete(); |
709 | |
710 | - QAbstractItemModel *model(manager.itemModel("network")); |
711 | + QAbstractItemModel *model(manager.itemModel()); |
712 | |
713 | QVERIFY(model != 0); |
714 | - QCOMPARE(model->rowCount(), 2); |
715 | + QCOMPARE(model->rowCount(), 5); |
716 | |
717 | - Plugin *wireless = (Plugin *) model->data(model->index(0, 0), |
718 | + Plugin *wireless = (Plugin *) model->data(model->index(2, 0), |
719 | ItemModel::ItemRole).value<QObject *>(); |
720 | - Plugin *cellular = (Plugin *) model->data(model->index(1, 0), |
721 | + Plugin *cellular = (Plugin *) model->data(model->index(3, 0), |
722 | ItemModel::ItemRole).value<QObject *>(); |
723 | |
724 | QCOMPARE(wireless->displayName(), QString("Wireless")); |
725 | @@ -148,10 +141,7 @@ |
726 | manager.classBegin(); |
727 | manager.componentComplete(); |
728 | |
729 | - QAbstractItemModel *model(manager.itemModel("network")); |
730 | - Plugin *wireless = (Plugin *) model->data(model->index(0, 0), |
731 | - ItemModel::ItemRole).value<QObject *>(); |
732 | - |
733 | + Plugin *wireless = (Plugin *) manager.getByName("wireless"); |
734 | QQmlEngine engine; |
735 | QQmlContext *context = new QQmlContext(engine.rootContext()); |
736 | QQmlEngine::setContextForObject(wireless, context); |
737 | @@ -167,10 +157,7 @@ |
738 | manager.classBegin(); |
739 | manager.componentComplete(); |
740 | |
741 | - QAbstractItemModel *model(manager.itemModel("misc")); |
742 | - Plugin *phone = (Plugin *) model->data(model->index(0, 0), |
743 | - ItemModel::ItemRole).value<QObject *>(); |
744 | - |
745 | + Plugin *phone = (Plugin *) manager.getByName("phone"); |
746 | QQmlEngine engine; |
747 | QQmlContext *context = new QQmlContext(engine.rootContext()); |
748 | QQmlEngine::setContextForObject(phone, context); |
FAILED: Continuous integration, rev:1769 /jenkins. canonical. com/system- apps/job/ lp-ubuntu- system- settings- ci/22/ /jenkins. canonical. com/system- apps/job/ build/2359/ console /jenkins. canonical. com/system- apps/job/ build-0- fetch/2359 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 2176/console /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=amd64, release= zesty/2176/ console /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 2176/console /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=armhf, release= zesty/2176/ console /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 2176/console /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=i386, release= zesty/2176/ console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/system- apps/job/ lp-ubuntu- system- settings- ci/22/rebuild
https:/