Merge lp:~unity-api-team/unity-scopes-shell/scope-settings into lp:unity-scopes-shell
- scope-settings
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Michal Hruby |
Approved revision: | 155 |
Merged at revision: | 105 |
Proposed branch: | lp:~unity-api-team/unity-scopes-shell/scope-settings |
Merge into: | lp:unity-scopes-shell |
Diff against target: |
905 lines (+727/-3) 15 files modified
debian/control (+2/-1) src/Unity/CMakeLists.txt (+7/-2) src/Unity/plugin.cpp (+2/-0) src/Unity/scope.cpp (+21/-0) src/Unity/scope.h (+3/-0) src/Unity/settingsmodel.cpp (+169/-0) src/Unity/settingsmodel.h (+93/-0) tests/CMakeLists.txt (+3/-0) tests/settingstest.cpp (+311/-0) tools/settings/Settings.qml (+68/-0) tools/settings/run.sh (+9/-0) tools/settings/widgets/booleanSettingsWidget.qml (+9/-0) tools/settings/widgets/listSettingsWidget.qml (+11/-0) tools/settings/widgets/numberSettingsWidget.qml (+10/-0) tools/settings/widgets/stringSettingsWidget.qml (+9/-0) |
To merge this branch: | bzr merge lp:~unity-api-team/unity-scopes-shell/scope-settings |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michal Hruby (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Review via email:
|
Commit message
Add settings support
Description of the change
Add settings support
- 151. By Pete Woods
-
Increase version requirement
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:151
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:152
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 152. By Pete Woods
-
Merge trunk
- 153. By Pete Woods
-
Increment build deps
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:153
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 154. By Pete Woods
-
Implement the count method
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:154
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Michal Hruby (mhr3) wrote : | # |
33 +pkg_check_
Missing in debian/control
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Michal Hruby (mhr3) wrote : | # |
110 + new SettingsModel(
111 + scopeVariantToQ
Isn't the .local/
211 + QVariantMap data = it.toMap();
Can we rely on the data being valid? Shouldn't it check first that all the necessary keys are in there?
234 + m_timers[id] = timer;
A timer per-setting? Why's that needed?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Pete Woods (pete-woods) wrote : | # |
> 110 + new
> SettingsModel(
> 111 + scopeVariantToQ
> this));
>
> Isn't the .local/
> scopes? Can unity even write in there?
>
This is the standard place for apps to write settings AFAIK. It's different to the path "~/.local/
> 211 + QVariantMap data = it.toMap();
>
> Can we rely on the data being valid? Shouldn't it check first that all the
> necessary keys are in there?
>
Yes. I removed the validation code because Michi performs all these checks in the scopes API itself.
> 234 + m_timers[id] = timer;
>
> A timer per-setting? Why's that needed?
The individual timers are used to avoid the need for a queue of changes, and generally keep the timing logic simple. Each timer just gets a cached version of the newest value of the setting it manages set as a property while it's active. Given there are only going to be < 10 of them, they shouldn't be an expensive overhead.
- 155. By Pete Woods
-
Change timer type to VeryCoarseTimer
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Michal Hruby (mhr3) wrote : | # |
> Change timer type to VeryCoarseTimer
Ok, that makes me happier.
- 156. By Pete Woods
-
Re-order to help with performance
- 157. By Pete Woods
-
Add missing build dependency
Preview Diff
1 | === modified file 'debian/control' | |||
2 | --- debian/control 2014-06-26 08:16:37 +0000 | |||
3 | +++ debian/control 2014-07-10 07:45:27 +0000 | |||
4 | @@ -4,8 +4,9 @@ | |||
5 | 4 | Build-Depends: cmake, | 4 | Build-Depends: cmake, |
6 | 5 | debhelper (>= 9), | 5 | debhelper (>= 9), |
7 | 6 | libunity-api-dev (>= 7.83), | 6 | libunity-api-dev (>= 7.83), |
9 | 7 | libunity-scopes-dev (>= 0.5.1~), | 7 | libunity-scopes-dev (>= 0.5.2~), |
10 | 8 | libgsettings-qt-dev (>= 0.1), | 8 | libgsettings-qt-dev (>= 0.1), |
11 | 9 | libu1db-qt5-dev, | ||
12 | 9 | pkg-config, | 10 | pkg-config, |
13 | 10 | qt5-default, | 11 | qt5-default, |
14 | 11 | qtdeclarative5-dev, | 12 | qtdeclarative5-dev, |
15 | 12 | 13 | ||
16 | === modified file 'src/Unity/CMakeLists.txt' | |||
17 | --- src/Unity/CMakeLists.txt 2014-06-05 10:37:50 +0000 | |||
18 | +++ src/Unity/CMakeLists.txt 2014-07-10 07:45:27 +0000 | |||
19 | @@ -2,15 +2,17 @@ | |||
20 | 2 | include(Plugins) | 2 | include(Plugins) |
21 | 3 | 3 | ||
22 | 4 | # Dependencies | 4 | # Dependencies |
25 | 5 | pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=1) | 5 | pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=2) |
26 | 6 | pkg_check_modules(SCOPESLIB REQUIRED libunity-scopes>=0.4.8) | 6 | pkg_check_modules(SCOPESLIB REQUIRED libunity-scopes>=0.5.2) |
27 | 7 | pkg_check_modules(GSETTINGSQT REQUIRED gsettings-qt) | 7 | pkg_check_modules(GSETTINGSQT REQUIRED gsettings-qt) |
28 | 8 | pkg_check_modules(U1DB REQUIRED libu1db-qt5) | ||
29 | 8 | 9 | ||
30 | 9 | include_directories( | 10 | include_directories( |
31 | 10 | ${CMAKE_CURRENT_SOURCE_DIR} | 11 | ${CMAKE_CURRENT_SOURCE_DIR} |
32 | 11 | ${CMAKE_CURRENT_BINARY_DIR} | 12 | ${CMAKE_CURRENT_BINARY_DIR} |
33 | 12 | ${SCOPESLIB_INCLUDE_DIRS} | 13 | ${SCOPESLIB_INCLUDE_DIRS} |
34 | 13 | ${GSETTINGSQT_INCLUDE_DIRS} | 14 | ${GSETTINGSQT_INCLUDE_DIRS} |
35 | 15 | ${U1DB_INCLUDE_DIRS} | ||
36 | 14 | ) | 16 | ) |
37 | 15 | 17 | ||
38 | 16 | set(QMLPLUGIN_SRC | 18 | set(QMLPLUGIN_SRC |
39 | @@ -24,6 +26,7 @@ | |||
40 | 24 | resultsmodel.cpp | 26 | resultsmodel.cpp |
41 | 25 | scope.cpp | 27 | scope.cpp |
42 | 26 | scopes.cpp | 28 | scopes.cpp |
43 | 29 | settingsmodel.cpp | ||
44 | 27 | utils.cpp | 30 | utils.cpp |
45 | 28 | plugin.cpp | 31 | plugin.cpp |
46 | 29 | iconutils.cpp | 32 | iconutils.cpp |
47 | @@ -37,6 +40,7 @@ | |||
48 | 37 | ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ResultsModelInterface.h | 40 | ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ResultsModelInterface.h |
49 | 38 | ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ScopeInterface.h | 41 | ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ScopeInterface.h |
50 | 39 | ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ScopesInterface.h | 42 | ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ScopesInterface.h |
51 | 43 | ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/SettingsModelInterface.h | ||
52 | 40 | ) | 44 | ) |
53 | 41 | 45 | ||
54 | 42 | add_library(Unity-qml SHARED ${QMLPLUGIN_SRC}) | 46 | add_library(Unity-qml SHARED ${QMLPLUGIN_SRC}) |
55 | @@ -44,6 +48,7 @@ | |||
56 | 44 | target_link_libraries(Unity-qml | 48 | target_link_libraries(Unity-qml |
57 | 45 | ${SCOPESLIB_LDFLAGS} | 49 | ${SCOPESLIB_LDFLAGS} |
58 | 46 | ${GSETTINGSQT_LDFLAGS} | 50 | ${GSETTINGSQT_LDFLAGS} |
59 | 51 | ${U1DB_LDFLAGS} | ||
60 | 47 | ) | 52 | ) |
61 | 48 | 53 | ||
62 | 49 | qt5_use_modules(Unity-qml Qml Gui DBus) | 54 | qt5_use_modules(Unity-qml Qml Gui DBus) |
63 | 50 | 55 | ||
64 | === modified file 'src/Unity/plugin.cpp' | |||
65 | --- src/Unity/plugin.cpp 2014-06-03 15:51:13 +0000 | |||
66 | +++ src/Unity/plugin.cpp 2014-07-10 07:45:27 +0000 | |||
67 | @@ -32,6 +32,7 @@ | |||
68 | 32 | #include "previewstack.h" | 32 | #include "previewstack.h" |
69 | 33 | #include "previewmodel.h" | 33 | #include "previewmodel.h" |
70 | 34 | #include "previewwidgetmodel.h" | 34 | #include "previewwidgetmodel.h" |
71 | 35 | #include "settingsmodel.h" | ||
72 | 35 | 36 | ||
73 | 36 | void UnityPlugin::registerTypes(const char *uri) | 37 | void UnityPlugin::registerTypes(const char *uri) |
74 | 37 | { | 38 | { |
75 | @@ -42,6 +43,7 @@ | |||
76 | 42 | 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."); |
77 | 43 | 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::DepartmentInterface>(uri, 0, 2, "Department", "Can't create Department object in QML. Get them from Scope instance."); |
78 | 44 | 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."); |
79 | 46 | qmlRegisterUncreatableType<unity::shell::scopes::SettingsModelInterface>(uri, 0, 2, "Settings", "Can't create Settings object in QML. Get them from Scope instance."); | ||
80 | 45 | 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."); |
81 | 46 | qmlRegisterUncreatableType<unity::shell::scopes::PreviewModelInterface>(uri, 0, 2, "PreviewModel", "Can't create new PreviewModel in QML. Get them from PreviewStack instance."); | 48 | qmlRegisterUncreatableType<unity::shell::scopes::PreviewModelInterface>(uri, 0, 2, "PreviewModel", "Can't create new PreviewModel in QML. Get them from PreviewStack instance."); |
82 | 47 | qmlRegisterUncreatableType<scopes_ng::PreviewWidgetModel>(uri, 0, 2, "PreviewWidgetModel", "Can't create new PreviewWidgetModel in QML. Get them from PreviewModel instance."); | 49 | qmlRegisterUncreatableType<scopes_ng::PreviewWidgetModel>(uri, 0, 2, "PreviewWidgetModel", "Can't create new PreviewWidgetModel in QML. Get them from PreviewModel instance."); |
83 | 48 | 50 | ||
84 | === modified file 'src/Unity/scope.cpp' | |||
85 | --- src/Unity/scope.cpp 2014-06-25 17:00:21 +0000 | |||
86 | +++ src/Unity/scope.cpp 2014-07-10 07:45:27 +0000 | |||
87 | @@ -26,6 +26,7 @@ | |||
88 | 26 | #include "previewstack.h" | 26 | #include "previewstack.h" |
89 | 27 | #include "utils.h" | 27 | #include "utils.h" |
90 | 28 | #include "scopes.h" | 28 | #include "scopes.h" |
91 | 29 | #include "settingsmodel.h" | ||
92 | 29 | 30 | ||
93 | 30 | // Qt | 31 | // Qt |
94 | 31 | #include <QUrl> | 32 | #include <QUrl> |
95 | @@ -533,6 +534,21 @@ | |||
96 | 533 | QVariant converted(scopeVariantToQVariant(scopes::Variant(m_scopeMetadata->appearance_attributes()))); | 534 | QVariant converted(scopeVariantToQVariant(scopes::Variant(m_scopeMetadata->appearance_attributes()))); |
97 | 534 | m_customizations = converted.toMap(); | 535 | m_customizations = converted.toMap(); |
98 | 535 | Q_EMIT customizationsChanged(); | 536 | Q_EMIT customizationsChanged(); |
99 | 537 | |||
100 | 538 | try | ||
101 | 539 | { | ||
102 | 540 | scopes::Variant settings_definitions; | ||
103 | 541 | settings_definitions = m_scopeMetadata->settings_definitions(); | ||
104 | 542 | m_settingsModel.reset( | ||
105 | 543 | new SettingsModel(QDir::home().filePath(".local/share"), id(), | ||
106 | 544 | scopeVariantToQVariant(settings_definitions), this)); | ||
107 | 545 | } | ||
108 | 546 | catch (unity::scopes::NotFoundException&) | ||
109 | 547 | { | ||
110 | 548 | // If there's no settings data | ||
111 | 549 | m_settingsModel.reset(); | ||
112 | 550 | } | ||
113 | 551 | Q_EMIT settingsChanged(); | ||
114 | 536 | } | 552 | } |
115 | 537 | 553 | ||
116 | 538 | QString Scope::id() const | 554 | QString Scope::id() const |
117 | @@ -599,6 +615,11 @@ | |||
118 | 599 | return m_categories; | 615 | return m_categories; |
119 | 600 | } | 616 | } |
120 | 601 | 617 | ||
121 | 618 | unity::shell::scopes::SettingsModelInterface* Scope::settings() const | ||
122 | 619 | { | ||
123 | 620 | return m_settingsModel.data(); | ||
124 | 621 | } | ||
125 | 622 | |||
126 | 602 | /* | 623 | /* |
127 | 603 | Filters* Scope::filters() const | 624 | Filters* Scope::filters() const |
128 | 604 | { | 625 | { |
129 | 605 | 626 | ||
130 | === modified file 'src/Unity/scope.h' | |||
131 | --- src/Unity/scope.h 2014-06-25 16:57:46 +0000 | |||
132 | +++ src/Unity/scope.h 2014-07-10 07:45:27 +0000 | |||
133 | @@ -47,6 +47,7 @@ | |||
134 | 47 | class Categories; | 47 | class Categories; |
135 | 48 | class PushEvent; | 48 | class PushEvent; |
136 | 49 | class PreviewStack; | 49 | class PreviewStack; |
137 | 50 | class SettingsModel; | ||
138 | 50 | 51 | ||
139 | 51 | class CollectionController | 52 | class CollectionController |
140 | 52 | { | 53 | { |
141 | @@ -116,6 +117,7 @@ | |||
142 | 116 | QString shortcut() const override; | 117 | QString shortcut() const override; |
143 | 117 | bool searchInProgress() const override; | 118 | bool searchInProgress() const override; |
144 | 118 | unity::shell::scopes::CategoriesInterface* categories() const override; | 119 | unity::shell::scopes::CategoriesInterface* categories() const override; |
145 | 120 | unity::shell::scopes::SettingsModelInterface* settings() const override; | ||
146 | 119 | QString searchQuery() const override; | 121 | QString searchQuery() const override; |
147 | 120 | QString noResultsHint() const override; | 122 | QString noResultsHint() const override; |
148 | 121 | QString formFactor() const override; | 123 | QString formFactor() const override; |
149 | @@ -189,6 +191,7 @@ | |||
150 | 189 | unity::scopes::Department::SCPtr m_lastRootDepartment; | 191 | unity::scopes::Department::SCPtr m_lastRootDepartment; |
151 | 190 | QGSettings* m_settings; | 192 | QGSettings* m_settings; |
152 | 191 | Categories* m_categories; | 193 | Categories* m_categories; |
153 | 194 | QScopedPointer<SettingsModel> m_settingsModel; | ||
154 | 192 | QSharedPointer<DepartmentNode> m_departmentTree; | 195 | QSharedPointer<DepartmentNode> m_departmentTree; |
155 | 193 | QTimer m_aggregatorTimer; | 196 | QTimer m_aggregatorTimer; |
156 | 194 | QTimer m_clearTimer; | 197 | QTimer m_clearTimer; |
157 | 195 | 198 | ||
158 | === added file 'src/Unity/settingsmodel.cpp' | |||
159 | --- src/Unity/settingsmodel.cpp 1970-01-01 00:00:00 +0000 | |||
160 | +++ src/Unity/settingsmodel.cpp 2014-07-10 07:45:27 +0000 | |||
161 | @@ -0,0 +1,169 @@ | |||
162 | 1 | /* | ||
163 | 2 | * Copyright (C) 2014 Canonical, Ltd. | ||
164 | 3 | * | ||
165 | 4 | * Authors: | ||
166 | 5 | * Pete Woods <pete.woods@canonical.com> | ||
167 | 6 | * | ||
168 | 7 | * This program is free software; you can redistribute it and/or modify | ||
169 | 8 | * it under the terms of the GNU General Public License as published by | ||
170 | 9 | * the Free Software Foundation; version 3. | ||
171 | 10 | * | ||
172 | 11 | * This program is distributed in the hope that it will be useful, | ||
173 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
174 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
175 | 14 | * GNU General Public License for more details. | ||
176 | 15 | * | ||
177 | 16 | * You should have received a copy of the GNU General Public License | ||
178 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
179 | 18 | */ | ||
180 | 19 | |||
181 | 20 | #include "settingsmodel.h" | ||
182 | 21 | #include "utils.h" | ||
183 | 22 | |||
184 | 23 | #include <QDebug> | ||
185 | 24 | #include <QDir> | ||
186 | 25 | #include <QTimer> | ||
187 | 26 | |||
188 | 27 | using namespace scopes_ng; | ||
189 | 28 | namespace sc = unity::scopes; | ||
190 | 29 | |||
191 | 30 | static const QString SETTING_GROUP("default"); | ||
192 | 31 | |||
193 | 32 | static const QString SETTING_ID_PATTERN("%1-%2"); | ||
194 | 33 | |||
195 | 34 | SettingsModel::SettingsModel(const QDir& shareDir, const QString& scopeId, | ||
196 | 35 | const QVariant& settingsDefinitions, QObject* parent, | ||
197 | 36 | int settingsTimeout) | ||
198 | 37 | : SettingsModelInterface(parent), m_settingsTimeout(settingsTimeout) | ||
199 | 38 | { | ||
200 | 39 | shareDir.mkdir(scopeId); | ||
201 | 40 | QDir databaseDir = shareDir.filePath(scopeId); | ||
202 | 41 | m_database.setPath(databaseDir.filePath("settings.db")); | ||
203 | 42 | |||
204 | 43 | for (const auto &it : settingsDefinitions.toList()) | ||
205 | 44 | { | ||
206 | 45 | QVariantMap data = it.toMap(); | ||
207 | 46 | QString id = data["id"].toString(); | ||
208 | 47 | QString displayName = data["displayName"].toString(); | ||
209 | 48 | QVariantMap properties = data["parameters"].toMap(); | ||
210 | 49 | QString type = data["type"].toString(); | ||
211 | 50 | |||
212 | 51 | QVariantMap defaults; | ||
213 | 52 | defaults["value"] = properties["defaultValue"]; | ||
214 | 53 | |||
215 | 54 | QSharedPointer<U1db::Document> document(new U1db::Document); | ||
216 | 55 | document->setDocId(SETTING_ID_PATTERN.arg(SETTING_GROUP, id)); | ||
217 | 56 | document->setDefaults(defaults); | ||
218 | 57 | document->setDatabase(&m_database); | ||
219 | 58 | document->setCreate(true); | ||
220 | 59 | |||
221 | 60 | m_documents[id] = document; | ||
222 | 61 | |||
223 | 62 | QSharedPointer<QTimer> timer(new QTimer()); | ||
224 | 63 | timer->setProperty("setting_id", id); | ||
225 | 64 | timer->setSingleShot(true); | ||
226 | 65 | timer->setInterval(m_settingsTimeout); | ||
227 | 66 | timer->setTimerType(Qt::VeryCoarseTimer); | ||
228 | 67 | connect(timer.data(), SIGNAL(timeout()), this, | ||
229 | 68 | SLOT(settings_timeout())); | ||
230 | 69 | m_timers[id] = timer; | ||
231 | 70 | |||
232 | 71 | QSharedPointer<Data> setting( | ||
233 | 72 | new Data(id, displayName, type, properties)); | ||
234 | 73 | |||
235 | 74 | m_data << setting; | ||
236 | 75 | } | ||
237 | 76 | } | ||
238 | 77 | |||
239 | 78 | QVariant SettingsModel::data(const QModelIndex& index, int role) const | ||
240 | 79 | { | ||
241 | 80 | int row = index.row(); | ||
242 | 81 | QVariant result; | ||
243 | 82 | |||
244 | 83 | if (row < m_data.size()) | ||
245 | 84 | { | ||
246 | 85 | auto data = m_data[row]; | ||
247 | 86 | |||
248 | 87 | switch (role) | ||
249 | 88 | { | ||
250 | 89 | case Roles::RoleSettingId: | ||
251 | 90 | result = data->id; | ||
252 | 91 | break; | ||
253 | 92 | case Roles::RoleDisplayName: | ||
254 | 93 | result = data->displayName; | ||
255 | 94 | break; | ||
256 | 95 | case Roles::RoleType: | ||
257 | 96 | result = data->type; | ||
258 | 97 | break; | ||
259 | 98 | case Roles::RoleProperties: | ||
260 | 99 | result = data->properties; | ||
261 | 100 | break; | ||
262 | 101 | case Roles::RoleValue: | ||
263 | 102 | { | ||
264 | 103 | QSharedPointer<U1db::Document> document = m_documents[data->id]; | ||
265 | 104 | QVariantMap contents = document->getContents().toMap(); | ||
266 | 105 | result = contents["value"]; | ||
267 | 106 | break; | ||
268 | 107 | } | ||
269 | 108 | default: | ||
270 | 109 | break; | ||
271 | 110 | } | ||
272 | 111 | } | ||
273 | 112 | |||
274 | 113 | return result; | ||
275 | 114 | } | ||
276 | 115 | |||
277 | 116 | bool SettingsModel::setData(const QModelIndex &index, const QVariant &value, | ||
278 | 117 | int role) | ||
279 | 118 | { | ||
280 | 119 | int row = index.row(); | ||
281 | 120 | QVariant result; | ||
282 | 121 | |||
283 | 122 | if (row < m_data.size()) | ||
284 | 123 | { | ||
285 | 124 | auto data = m_data[row]; | ||
286 | 125 | |||
287 | 126 | switch (role) | ||
288 | 127 | { | ||
289 | 128 | case Roles::RoleValue: | ||
290 | 129 | { | ||
291 | 130 | QSharedPointer<QTimer> timer = m_timers[data->id]; | ||
292 | 131 | timer->setProperty("value", value); | ||
293 | 132 | timer->start(); | ||
294 | 133 | |||
295 | 134 | return true; | ||
296 | 135 | } | ||
297 | 136 | default: | ||
298 | 137 | break; | ||
299 | 138 | } | ||
300 | 139 | } | ||
301 | 140 | |||
302 | 141 | return false; | ||
303 | 142 | } | ||
304 | 143 | |||
305 | 144 | int SettingsModel::rowCount(const QModelIndex&) const | ||
306 | 145 | { | ||
307 | 146 | return count(); | ||
308 | 147 | } | ||
309 | 148 | |||
310 | 149 | int SettingsModel::count() const | ||
311 | 150 | { | ||
312 | 151 | return m_data.size(); | ||
313 | 152 | } | ||
314 | 153 | |||
315 | 154 | void SettingsModel::settings_timeout() | ||
316 | 155 | { | ||
317 | 156 | QObject *timer = sender(); | ||
318 | 157 | if (!timer) | ||
319 | 158 | { | ||
320 | 159 | return; | ||
321 | 160 | } | ||
322 | 161 | |||
323 | 162 | QString setting_id = timer->property("setting_id").toString(); | ||
324 | 163 | QVariant value = timer->property("value"); | ||
325 | 164 | |||
326 | 165 | QSharedPointer<U1db::Document> document = m_documents[setting_id]; | ||
327 | 166 | QVariantMap map; | ||
328 | 167 | map["value"] = value; | ||
329 | 168 | document->setContents(map); | ||
330 | 169 | } | ||
331 | 0 | 170 | ||
332 | === added file 'src/Unity/settingsmodel.h' | |||
333 | --- src/Unity/settingsmodel.h 1970-01-01 00:00:00 +0000 | |||
334 | +++ src/Unity/settingsmodel.h 2014-07-10 07:45:27 +0000 | |||
335 | @@ -0,0 +1,93 @@ | |||
336 | 1 | /* | ||
337 | 2 | * Copyright (C) 2014 Canonical, Ltd. | ||
338 | 3 | * | ||
339 | 4 | * Authors: | ||
340 | 5 | * Pete Woods <pete.woods@canonical.com> | ||
341 | 6 | * | ||
342 | 7 | * This program is free software; you can redistribute it and/or modify | ||
343 | 8 | * it under the terms of the GNU General Public License as published by | ||
344 | 9 | * the Free Software Foundation; version 3. | ||
345 | 10 | * | ||
346 | 11 | * This program is distributed in the hope that it will be useful, | ||
347 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
348 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
349 | 14 | * GNU General Public License for more details. | ||
350 | 15 | * | ||
351 | 16 | * You should have received a copy of the GNU General Public License | ||
352 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
353 | 18 | */ | ||
354 | 19 | |||
355 | 20 | #ifndef NG_PREVIEW_SETTTINGSMODEL_H_ | ||
356 | 21 | #define NG_PREVIEW_SETTTINGSMODEL_H_ | ||
357 | 22 | |||
358 | 23 | #include <libu1db-qt5/database.h> | ||
359 | 24 | #include <libu1db-qt5/document.h> | ||
360 | 25 | #include <unity/SymbolExport.h> | ||
361 | 26 | #include <unity/shell/scopes/SettingsModelInterface.h> | ||
362 | 27 | |||
363 | 28 | #include <QAbstractListModel> | ||
364 | 29 | #include <QList> | ||
365 | 30 | #include <QSharedPointer> | ||
366 | 31 | |||
367 | 32 | QT_BEGIN_NAMESPACE | ||
368 | 33 | class QDir; | ||
369 | 34 | class QTimer; | ||
370 | 35 | QT_END_NAMESPACE | ||
371 | 36 | |||
372 | 37 | namespace scopes_ng | ||
373 | 38 | { | ||
374 | 39 | |||
375 | 40 | class Q_DECL_EXPORT SettingsModel: public unity::shell::scopes::SettingsModelInterface | ||
376 | 41 | { | ||
377 | 42 | Q_OBJECT | ||
378 | 43 | |||
379 | 44 | struct Data | ||
380 | 45 | { | ||
381 | 46 | QString id; | ||
382 | 47 | QString displayName; | ||
383 | 48 | QString type; | ||
384 | 49 | QVariant properties; | ||
385 | 50 | |||
386 | 51 | Data(QString const& id_, QString const& displayName_, | ||
387 | 52 | QString const& type_, QVariant const& properties_) | ||
388 | 53 | : id(id_), displayName(displayName_), type(type_), properties( | ||
389 | 54 | properties_) | ||
390 | 55 | { | ||
391 | 56 | } | ||
392 | 57 | }; | ||
393 | 58 | |||
394 | 59 | public: | ||
395 | 60 | explicit SettingsModel(const QDir& shareDir, const QString& scopeId, | ||
396 | 61 | const QVariant& settingsDefinitions, QObject* parent = 0, | ||
397 | 62 | int settingsTimeout = 300); | ||
398 | 63 | |||
399 | 64 | QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const | ||
400 | 65 | override; | ||
401 | 66 | |||
402 | 67 | bool setData(const QModelIndex&index, const QVariant& value, int role = | ||
403 | 68 | Qt::EditRole) override; | ||
404 | 69 | |||
405 | 70 | int rowCount(const QModelIndex& parent = QModelIndex()) const override; | ||
406 | 71 | |||
407 | 72 | int count() const override; | ||
408 | 73 | |||
409 | 74 | protected Q_SLOTS: | ||
410 | 75 | void settings_timeout(); | ||
411 | 76 | |||
412 | 77 | protected: | ||
413 | 78 | int m_settingsTimeout; | ||
414 | 79 | |||
415 | 80 | QList<QSharedPointer<Data>> m_data; | ||
416 | 81 | |||
417 | 82 | U1db::Database m_database; | ||
418 | 83 | |||
419 | 84 | QMap<QString, QSharedPointer<U1db::Document>> m_documents; | ||
420 | 85 | |||
421 | 86 | QMap<QString, QSharedPointer<QTimer>> m_timers; | ||
422 | 87 | }; | ||
423 | 88 | |||
424 | 89 | } | ||
425 | 90 | |||
426 | 91 | Q_DECLARE_METATYPE(scopes_ng::SettingsModel*) | ||
427 | 92 | |||
428 | 93 | #endif /* NG_PREVIEW_SETTTINGSMODEL_H_ */ | ||
429 | 0 | 94 | ||
430 | === modified file 'tests/CMakeLists.txt' | |||
431 | --- tests/CMakeLists.txt 2014-06-05 10:37:50 +0000 | |||
432 | +++ tests/CMakeLists.txt 2014-07-10 07:45:27 +0000 | |||
433 | @@ -51,4 +51,7 @@ | |||
434 | 51 | resultstest | 51 | resultstest |
435 | 52 | previewtest | 52 | previewtest |
436 | 53 | utilstest | 53 | utilstest |
437 | 54 | settingstest | ||
438 | 54 | ) | 55 | ) |
439 | 56 | |||
440 | 57 | qt5_use_modules(settingstestExec Sql) | ||
441 | 55 | 58 | ||
442 | === added file 'tests/settingstest.cpp' | |||
443 | --- tests/settingstest.cpp 1970-01-01 00:00:00 +0000 | |||
444 | +++ tests/settingstest.cpp 2014-07-10 07:45:27 +0000 | |||
445 | @@ -0,0 +1,311 @@ | |||
446 | 1 | /* | ||
447 | 2 | * Copyright (C) 2013-2014 Canonical, Ltd. | ||
448 | 3 | * | ||
449 | 4 | * This program is free software; you can redistribute it and/or modify | ||
450 | 5 | * it under the terms of the GNU General Public License as published by | ||
451 | 6 | * the Free Software Foundation; version 3. | ||
452 | 7 | * | ||
453 | 8 | * This program is distributed in the hope that it will be useful, | ||
454 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
455 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
456 | 11 | * GNU General Public License for more details. | ||
457 | 12 | * | ||
458 | 13 | * You should have received a copy of the GNU General Public License | ||
459 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
460 | 15 | * | ||
461 | 16 | * Authors: | ||
462 | 17 | * Pete Woods <pete.woods@canonical.com> | ||
463 | 18 | */ | ||
464 | 19 | |||
465 | 20 | #include <QJsonDocument> | ||
466 | 21 | #include <QObject> | ||
467 | 22 | #include <QTemporaryDir> | ||
468 | 23 | #include <QTest> | ||
469 | 24 | |||
470 | 25 | #include <settingsmodel.h> | ||
471 | 26 | |||
472 | 27 | using namespace scopes_ng; | ||
473 | 28 | using namespace unity::shell::scopes; | ||
474 | 29 | |||
475 | 30 | namespace | ||
476 | 31 | { | ||
477 | 32 | |||
478 | 33 | const static QByteArray BOOLEAN_DEFINITION = | ||
479 | 34 | R"( | ||
480 | 35 | [ | ||
481 | 36 | { | ||
482 | 37 | "id": "enabledSetting", | ||
483 | 38 | "displayName": "Enabled", | ||
484 | 39 | "type": "boolean", | ||
485 | 40 | "parameters": { | ||
486 | 41 | "defaultValue": true | ||
487 | 42 | } | ||
488 | 43 | } | ||
489 | 44 | ] | ||
490 | 45 | )"; | ||
491 | 46 | |||
492 | 47 | const static QByteArray LIST_DEFINITION = | ||
493 | 48 | R"( | ||
494 | 49 | [ | ||
495 | 50 | { | ||
496 | 51 | "id": "unitTempSetting", | ||
497 | 52 | "displayName": "Temperature Units", | ||
498 | 53 | "type": "list", | ||
499 | 54 | "parameters": { | ||
500 | 55 | "defaultValue": 1, | ||
501 | 56 | "values": ["Celcius", "Fahrenheit"] | ||
502 | 57 | } | ||
503 | 58 | } | ||
504 | 59 | ] | ||
505 | 60 | )"; | ||
506 | 61 | |||
507 | 62 | const static QByteArray NUMBER_DEFINITION = | ||
508 | 63 | R"( | ||
509 | 64 | [ | ||
510 | 65 | { | ||
511 | 66 | "id": "ageSetting", | ||
512 | 67 | "displayName": "Age", | ||
513 | 68 | "type": "number", | ||
514 | 69 | "parameters": { | ||
515 | 70 | "defaultValue": 23 | ||
516 | 71 | } | ||
517 | 72 | } | ||
518 | 73 | ] | ||
519 | 74 | )"; | ||
520 | 75 | |||
521 | 76 | const static QByteArray STRING_DEFINITION = | ||
522 | 77 | R"( | ||
523 | 78 | [ | ||
524 | 79 | { | ||
525 | 80 | "id": "locationSetting", | ||
526 | 81 | "displayName": "Location", | ||
527 | 82 | "type": "string", | ||
528 | 83 | "parameters": { | ||
529 | 84 | "defaultValue": "London" | ||
530 | 85 | } | ||
531 | 86 | } | ||
532 | 87 | ] | ||
533 | 88 | )"; | ||
534 | 89 | |||
535 | 90 | const static QByteArray MIXED_DEFINITION = | ||
536 | 91 | R"( | ||
537 | 92 | [ | ||
538 | 93 | { | ||
539 | 94 | "id": "locationSetting", | ||
540 | 95 | "displayName": "Location", | ||
541 | 96 | "type": "string", | ||
542 | 97 | "parameters": { | ||
543 | 98 | "defaultValue": "London" | ||
544 | 99 | } | ||
545 | 100 | }, | ||
546 | 101 | { | ||
547 | 102 | "id": "unitTempSetting", | ||
548 | 103 | "displayName": "Temperature Units", | ||
549 | 104 | "type": "list", | ||
550 | 105 | "parameters": { | ||
551 | 106 | "defaultValue": 1, | ||
552 | 107 | "values": ["Celcius", "Fahrenheit"] | ||
553 | 108 | } | ||
554 | 109 | }, | ||
555 | 110 | { | ||
556 | 111 | "id": "ageSetting", | ||
557 | 112 | "displayName": "Age", | ||
558 | 113 | "type": "number", | ||
559 | 114 | "parameters": { | ||
560 | 115 | "defaultValue": 23 | ||
561 | 116 | } | ||
562 | 117 | }, | ||
563 | 118 | { | ||
564 | 119 | "id": "enabledSetting", | ||
565 | 120 | "displayName": "Enabled", | ||
566 | 121 | "type": "boolean", | ||
567 | 122 | "parameters": { | ||
568 | 123 | "defaultValue": true | ||
569 | 124 | } | ||
570 | 125 | } | ||
571 | 126 | ] | ||
572 | 127 | )"; | ||
573 | 128 | |||
574 | 129 | class SettingsTest: public QObject | ||
575 | 130 | { | ||
576 | 131 | Q_OBJECT | ||
577 | 132 | private: | ||
578 | 133 | QScopedPointer<QTemporaryDir> tempDir; | ||
579 | 134 | |||
580 | 135 | QSharedPointer<SettingsModelInterface> settings; | ||
581 | 136 | |||
582 | 137 | void newSettingsModel(const QString& id, const QByteArray& json) | ||
583 | 138 | { | ||
584 | 139 | QJsonDocument doc = QJsonDocument::fromJson(json); | ||
585 | 140 | QVariant definitions = doc.toVariant(); | ||
586 | 141 | settings.reset( | ||
587 | 142 | new SettingsModel(tempDir->path(), id, definitions, 0, 0)); | ||
588 | 143 | } | ||
589 | 144 | |||
590 | 145 | void verifyData(int index, const QString& id, const QString& displayName, | ||
591 | 146 | const QString& type, const QVariant& properties) | ||
592 | 147 | { | ||
593 | 148 | QCOMPARE( | ||
594 | 149 | settings->data(settings->index(index), | ||
595 | 150 | SettingsModelInterface::RoleSettingId), QVariant(id)); | ||
596 | 151 | QCOMPARE( | ||
597 | 152 | settings->data(settings->index(index), | ||
598 | 153 | SettingsModelInterface::RoleDisplayName), | ||
599 | 154 | QVariant(displayName)); | ||
600 | 155 | QCOMPARE( | ||
601 | 156 | settings->data(settings->index(index), | ||
602 | 157 | SettingsModelInterface::RoleType), QVariant(type)); | ||
603 | 158 | QCOMPARE( | ||
604 | 159 | settings->data(settings->index(index), | ||
605 | 160 | SettingsModelInterface::RoleProperties), properties); | ||
606 | 161 | } | ||
607 | 162 | |||
608 | 163 | void verifyValue(int index, const QVariant& value) | ||
609 | 164 | { | ||
610 | 165 | // Using this "TRY" macro repeatedly attempts the comparison until a timeout | ||
611 | 166 | QTRY_COMPARE( | ||
612 | 167 | settings->data(settings->index(index), | ||
613 | 168 | SettingsModelInterface::RoleValue), value); | ||
614 | 169 | } | ||
615 | 170 | |||
616 | 171 | void setValue(int index, const QVariant& value) | ||
617 | 172 | { | ||
618 | 173 | QVERIFY(settings->setData(settings->index(index), value, | ||
619 | 174 | SettingsModelInterface::RoleValue)); | ||
620 | 175 | } | ||
621 | 176 | |||
622 | 177 | private Q_SLOTS: | ||
623 | 178 | void init() | ||
624 | 179 | { | ||
625 | 180 | tempDir.reset(new QTemporaryDir); | ||
626 | 181 | } | ||
627 | 182 | |||
628 | 183 | void testBooleanDefinition() | ||
629 | 184 | { | ||
630 | 185 | newSettingsModel("boolean", BOOLEAN_DEFINITION); | ||
631 | 186 | QCOMPARE(settings->rowCount(), 1); | ||
632 | 187 | |||
633 | 188 | // Check the various properties make it through | ||
634 | 189 | QVariantMap properties; | ||
635 | 190 | properties["defaultValue"] = true; | ||
636 | 191 | verifyData(0, "enabledSetting", "Enabled", "boolean", properties); | ||
637 | 192 | |||
638 | 193 | verifyValue(0, true); | ||
639 | 194 | } | ||
640 | 195 | |||
641 | 196 | void testListDefinition() | ||
642 | 197 | { | ||
643 | 198 | newSettingsModel("list", LIST_DEFINITION); | ||
644 | 199 | QCOMPARE(settings->rowCount(), 1); | ||
645 | 200 | |||
646 | 201 | // Check the various properties make it through | ||
647 | 202 | QVariantMap properties; | ||
648 | 203 | properties["defaultValue"] = 1; | ||
649 | 204 | properties["values"] = QVariantList() << "Celcius" << "Fahrenheit"; | ||
650 | 205 | verifyData(0, "unitTempSetting", "Temperature Units", "list", | ||
651 | 206 | properties); | ||
652 | 207 | |||
653 | 208 | // Check the default value | ||
654 | 209 | verifyValue(0, 1); | ||
655 | 210 | } | ||
656 | 211 | |||
657 | 212 | void testNumberDefinition() | ||
658 | 213 | { | ||
659 | 214 | newSettingsModel("number", NUMBER_DEFINITION); | ||
660 | 215 | QCOMPARE(settings->rowCount(), 1); | ||
661 | 216 | |||
662 | 217 | // Check the various properties make it through | ||
663 | 218 | QVariantMap properties; | ||
664 | 219 | properties["defaultValue"] = 23; | ||
665 | 220 | verifyData(0, "ageSetting", "Age", "number", properties); | ||
666 | 221 | |||
667 | 222 | // Check the default value | ||
668 | 223 | verifyValue(0, 23); | ||
669 | 224 | } | ||
670 | 225 | |||
671 | 226 | void testStringDefinition() | ||
672 | 227 | { | ||
673 | 228 | newSettingsModel("string", STRING_DEFINITION); | ||
674 | 229 | QCOMPARE(settings->rowCount(), 1); | ||
675 | 230 | |||
676 | 231 | // Check the various properties make it through | ||
677 | 232 | QVariantMap properties; | ||
678 | 233 | properties["defaultValue"] = "London"; | ||
679 | 234 | verifyData(0, "locationSetting", "Location", "string", properties); | ||
680 | 235 | |||
681 | 236 | // Check the default value | ||
682 | 237 | verifyValue(0, "London"); | ||
683 | 238 | } | ||
684 | 239 | |||
685 | 240 | void testMixedDefinition() | ||
686 | 241 | { | ||
687 | 242 | newSettingsModel("mixed", MIXED_DEFINITION); | ||
688 | 243 | QCOMPARE(settings->rowCount(), 4); | ||
689 | 244 | |||
690 | 245 | { | ||
691 | 246 | QVariantMap properties; | ||
692 | 247 | properties["defaultValue"] = "London"; | ||
693 | 248 | verifyData(0, "locationSetting", "Location", "string", properties); | ||
694 | 249 | verifyValue(0, "London"); | ||
695 | 250 | } | ||
696 | 251 | { | ||
697 | 252 | QVariantMap properties; | ||
698 | 253 | properties["defaultValue"] = 1; | ||
699 | 254 | properties["values"] = QVariantList() << "Celcius" << "Fahrenheit"; | ||
700 | 255 | verifyData(1, "unitTempSetting", "Temperature Units", "list", | ||
701 | 256 | properties); | ||
702 | 257 | verifyValue(1, 1); | ||
703 | 258 | } | ||
704 | 259 | { | ||
705 | 260 | QVariantMap properties; | ||
706 | 261 | properties["defaultValue"] = 23; | ||
707 | 262 | verifyData(2, "ageSetting", "Age", "number", properties); | ||
708 | 263 | verifyValue(2, 23); | ||
709 | 264 | } | ||
710 | 265 | { | ||
711 | 266 | QVariantMap properties; | ||
712 | 267 | properties["defaultValue"] = true; | ||
713 | 268 | verifyData(3, "enabledSetting", "Enabled", "boolean", properties); | ||
714 | 269 | verifyValue(3, true); | ||
715 | 270 | } | ||
716 | 271 | } | ||
717 | 272 | |||
718 | 273 | void testUpdateValue() | ||
719 | 274 | { | ||
720 | 275 | // Create an initial settings model | ||
721 | 276 | newSettingsModel("update", MIXED_DEFINITION); | ||
722 | 277 | |||
723 | 278 | // Verify the initial values | ||
724 | 279 | verifyValue(0, "London"); | ||
725 | 280 | verifyValue(1, 1); | ||
726 | 281 | verifyValue(2, 23); | ||
727 | 282 | verifyValue(3, true); | ||
728 | 283 | |||
729 | 284 | // Update the string value | ||
730 | 285 | setValue(0, "Banana"); | ||
731 | 286 | verifyValue(0, "Banana"); | ||
732 | 287 | |||
733 | 288 | // Update the list value | ||
734 | 289 | setValue(1, 0); | ||
735 | 290 | verifyValue(1, 0); | ||
736 | 291 | |||
737 | 292 | // Update the number value | ||
738 | 293 | setValue(2, 123); | ||
739 | 294 | verifyValue(2, 123); | ||
740 | 295 | |||
741 | 296 | // Update the boolean value | ||
742 | 297 | setValue(3, false); | ||
743 | 298 | verifyValue(3, false); | ||
744 | 299 | |||
745 | 300 | // Make a new settings model to check the settings were saved to disk | ||
746 | 301 | newSettingsModel("update", MIXED_DEFINITION); | ||
747 | 302 | verifyValue(0, "Banana"); | ||
748 | 303 | verifyValue(1, 0); | ||
749 | 304 | verifyValue(2, 123); | ||
750 | 305 | verifyValue(3, false); | ||
751 | 306 | } | ||
752 | 307 | }; | ||
753 | 308 | |||
754 | 309 | } | ||
755 | 310 | QTEST_GUILESS_MAIN(SettingsTest) | ||
756 | 311 | #include <settingstest.moc> | ||
757 | 0 | 312 | ||
758 | === added directory 'tools' | |||
759 | === added directory 'tools/settings' | |||
760 | === added file 'tools/settings/Settings.qml' | |||
761 | --- tools/settings/Settings.qml 1970-01-01 00:00:00 +0000 | |||
762 | +++ tools/settings/Settings.qml 2014-07-10 07:45:27 +0000 | |||
763 | @@ -0,0 +1,68 @@ | |||
764 | 1 | import QtQuick 2.0 | ||
765 | 2 | import Ubuntu.Components 1.1 | ||
766 | 3 | import Unity 0.2 | ||
767 | 4 | |||
768 | 5 | MainView { | ||
769 | 6 | id: app | ||
770 | 7 | applicationName: "example" | ||
771 | 8 | width: units.gu(40) | ||
772 | 9 | height: units.gu(60) | ||
773 | 10 | |||
774 | 11 | Arguments { | ||
775 | 12 | id: args | ||
776 | 13 | defaultArgument.help: "Expects a scope ID" | ||
777 | 14 | defaultArgument.valueNames: ["SCOPE"] | ||
778 | 15 | } | ||
779 | 16 | |||
780 | 17 | Scopes { | ||
781 | 18 | id: scopes | ||
782 | 19 | onLoadedChanged: { | ||
783 | 20 | app.scope = scopes.getScope(args.defaultArgument.at(0)) | ||
784 | 21 | } | ||
785 | 22 | } | ||
786 | 23 | |||
787 | 24 | property var scope: ListModel{} | ||
788 | 25 | |||
789 | 26 | function toFileName(type) { | ||
790 | 27 | return "widgets/" + type + "SettingsWidget.qml" | ||
791 | 28 | } | ||
792 | 29 | |||
793 | 30 | Page { | ||
794 | 31 | title: "Settings for " + scope.name | ||
795 | 32 | |||
796 | 33 | ListView { | ||
797 | 34 | anchors.fill: parent | ||
798 | 35 | spacing: units.gu(1) | ||
799 | 36 | |||
800 | 37 | model: scope.settings | ||
801 | 38 | delegate: Loader { | ||
802 | 39 | id: loader | ||
803 | 40 | source: toFileName(type) | ||
804 | 41 | onLoaded: { | ||
805 | 42 | item.properties = properties | ||
806 | 43 | item.value = value | ||
807 | 44 | |||
808 | 45 | if (type != "boolean") { | ||
809 | 46 | loader.width = parent.width | ||
810 | 47 | } | ||
811 | 48 | if (type == "list") { | ||
812 | 49 | loader.height = units.gu(10) | ||
813 | 50 | } | ||
814 | 51 | |||
815 | 52 | itemValue = Qt.binding(function() { return item.value }) | ||
816 | 53 | } | ||
817 | 54 | property var itemValue | ||
818 | 55 | onItemValueChanged: { | ||
819 | 56 | if (value !== item.value) { | ||
820 | 57 | value = item.value | ||
821 | 58 | } | ||
822 | 59 | } | ||
823 | 60 | } | ||
824 | 61 | section.property: "displayName" | ||
825 | 62 | section.delegate: Text { | ||
826 | 63 | width: parent.width | ||
827 | 64 | text: section | ||
828 | 65 | } | ||
829 | 66 | } | ||
830 | 67 | } | ||
831 | 68 | } | ||
832 | 0 | 69 | ||
833 | === added file 'tools/settings/run.sh' | |||
834 | --- tools/settings/run.sh 1970-01-01 00:00:00 +0000 | |||
835 | +++ tools/settings/run.sh 2014-07-10 07:45:27 +0000 | |||
836 | @@ -0,0 +1,9 @@ | |||
837 | 1 | #!/bin/bash | ||
838 | 2 | |||
839 | 3 | if [ "$#" -ne 1 ]; then | ||
840 | 4 | echo "ERROR: Usage $0 SCOPE_ID" | ||
841 | 5 | exit 1 | ||
842 | 6 | fi | ||
843 | 7 | |||
844 | 8 | DIR="$(dirname "$0")" | ||
845 | 9 | APP_ID="example" qmlscene "$DIR/Settings.qml" -- "$1" | ||
846 | 0 | 10 | ||
847 | === added directory 'tools/settings/widgets' | |||
848 | === added file 'tools/settings/widgets/booleanSettingsWidget.qml' | |||
849 | --- tools/settings/widgets/booleanSettingsWidget.qml 1970-01-01 00:00:00 +0000 | |||
850 | +++ tools/settings/widgets/booleanSettingsWidget.qml 2014-07-10 07:45:27 +0000 | |||
851 | @@ -0,0 +1,9 @@ | |||
852 | 1 | import QtQuick 2.0 | ||
853 | 2 | import Ubuntu.Components 1.1 | ||
854 | 3 | |||
855 | 4 | |||
856 | 5 | CheckBox { | ||
857 | 6 | id: box | ||
858 | 7 | property var properties | ||
859 | 8 | property alias value: box.checked | ||
860 | 9 | } | ||
861 | 0 | 10 | ||
862 | === added file 'tools/settings/widgets/listSettingsWidget.qml' | |||
863 | --- tools/settings/widgets/listSettingsWidget.qml 1970-01-01 00:00:00 +0000 | |||
864 | +++ tools/settings/widgets/listSettingsWidget.qml 2014-07-10 07:45:27 +0000 | |||
865 | @@ -0,0 +1,11 @@ | |||
866 | 1 | import QtQuick 2.0 | ||
867 | 2 | import Ubuntu.Components 1.1 | ||
868 | 3 | |||
869 | 4 | OptionSelector { | ||
870 | 5 | id: combo | ||
871 | 6 | |||
872 | 7 | property var properties | ||
873 | 8 | property alias value: combo.selectedIndex | ||
874 | 9 | |||
875 | 10 | model: properties["values"] | ||
876 | 11 | } | ||
877 | 0 | 12 | ||
878 | === added file 'tools/settings/widgets/numberSettingsWidget.qml' | |||
879 | --- tools/settings/widgets/numberSettingsWidget.qml 1970-01-01 00:00:00 +0000 | |||
880 | +++ tools/settings/widgets/numberSettingsWidget.qml 2014-07-10 07:45:27 +0000 | |||
881 | @@ -0,0 +1,10 @@ | |||
882 | 1 | import QtQuick 2.0 | ||
883 | 2 | import Ubuntu.Components 1.1 | ||
884 | 3 | |||
885 | 4 | |||
886 | 5 | TextField { | ||
887 | 6 | id: field | ||
888 | 7 | property var properties | ||
889 | 8 | property alias value: field.text | ||
890 | 9 | validator: DoubleValidator {} | ||
891 | 10 | } | ||
892 | 0 | 11 | ||
893 | === added file 'tools/settings/widgets/stringSettingsWidget.qml' | |||
894 | --- tools/settings/widgets/stringSettingsWidget.qml 1970-01-01 00:00:00 +0000 | |||
895 | +++ tools/settings/widgets/stringSettingsWidget.qml 2014-07-10 07:45:27 +0000 | |||
896 | @@ -0,0 +1,9 @@ | |||
897 | 1 | import QtQuick 2.0 | ||
898 | 2 | import Ubuntu.Components 1.1 | ||
899 | 3 | |||
900 | 4 | |||
901 | 5 | TextField { | ||
902 | 6 | id: field | ||
903 | 7 | property var properties | ||
904 | 8 | property alias value: field.text | ||
905 | 9 | } |
FAILED: Continuous integration, rev:150 jenkins. qa.ubuntu. com/job/ unity-scopes- shell-ci/ 138/ jenkins. qa.ubuntu. com/job/ unity-scopes- shell-utopic- amd64-ci/ 35/console jenkins. qa.ubuntu. com/job/ unity-scopes- shell-utopic- armhf-ci/ 35/console jenkins. qa.ubuntu. com/job/ unity-scopes- shell-utopic- i386-ci/ 35/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity- scopes- shell-ci/ 138/rebuild
http://