Merge lp:~mterry/unity8/wizard-import into lp:unity8
- wizard-import
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Andrea Cimitan |
Approved revision: | 1435 |
Merged at revision: | 1474 |
Proposed branch: | lp:~mterry/unity8/wizard-import |
Merge into: | lp:unity8 |
Diff against target: |
3078 lines (+2822/-1) 44 files modified
CMakeLists.txt (+1/-0) debian/control (+13/-0) debian/rules (+1/-1) debian/ubuntu-system-settings-wizard.install (+5/-0) debian/ubuntu-system-settings-wizard.lintian-overrides (+1/-0) tests/CMakeLists.txt (+1/-0) tests/wizard/CMakeLists.txt (+5/-0) tests/wizard/tst_pagelist.cpp (+156/-0) wizard/50-com.ubuntu.system-settings.wizard.pkla (+6/-0) wizard/CMakeLists.txt (+65/-0) wizard/PageList.cpp (+111/-0) wizard/PageList.h (+55/-0) wizard/Unity/Application/CMakeLists.txt (+3/-0) wizard/Unity/Application/OSKController.qml (+20/-0) wizard/Unity/Application/qmldir (+2/-0) wizard/Unity/CMakeLists.txt (+1/-0) wizard/Utils/CMakeLists.txt (+27/-0) wizard/Utils/plugin.cpp (+41/-0) wizard/Utils/plugin.h (+33/-0) wizard/Utils/qmldir (+2/-0) wizard/Utils/qsortfilterproxymodelqml.cpp (+167/-0) wizard/Utils/qsortfilterproxymodelqml.h (+63/-0) wizard/Utils/system.cpp (+118/-0) wizard/Utils/system.h (+57/-0) wizard/main.cpp (+93/-0) wizard/qml/Components/CheckableSetting.qml (+85/-0) wizard/qml/Components/InputMethod.qml (+113/-0) wizard/qml/Components/Page.qml (+107/-0) wizard/qml/Components/StackButton.qml (+47/-0) wizard/qml/Pages/10-welcome.qml (+93/-0) wizard/qml/Pages/20-sim.qml (+71/-0) wizard/qml/Pages/30-passwd-type.qml (+119/-0) wizard/qml/Pages/40-wifi.qml (+200/-0) wizard/qml/Pages/50-location.qml (+149/-0) wizard/qml/Pages/60-reporting.qml (+52/-0) wizard/qml/Pages/80-finished.qml (+55/-0) wizard/qml/Pages/here-terms.qml (+117/-0) wizard/qml/Pages/passwd-confirm.qml (+85/-0) wizard/qml/Pages/passwd-set.qml (+93/-0) wizard/qml/main.qml (+246/-0) wizard/test.sh (+18/-0) wizard/ubuntu-system-settings-wizard-cleanup.conf (+20/-0) wizard/ubuntu-system-settings-wizard-set-lang.conf (+30/-0) wizard/ubuntu-system-settings-wizard.conf (+75/-0) |
To merge this branch: | bzr merge lp:~mterry/unity8/wizard-import |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andrea Cimitan (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Unity Team | Pending | ||
Review via email: mp+242245@code.launchpad.net |
Commit message
Import wizard code from ubuntu-
This branch does not guarantee it works, just that it builds and ships the right stuff. I wanted a baseline with as few changes as possible, so my actual changes to the code could be reviewed on their own.
Description of the change
Import wizard code from ubuntu-
This branch does not guarantee it works, just that it builds and ships the right stuff. I wanted a baseline with as few changes as possible, so my actual changes to the code could be reviewed on their own.
This should not be landed without the 'wizard-plugin' (done) and 'wizard-tests' (not done yet) branches.
== Checklist ==
* Are there any related MPs required for this MP to build/function as expected? Please list.
Yesish. https:/
It also expects https:/
* Did you perform an exploratory manual test run of your code change and any related functionality?
Yesish. It builds and ships.
* Did you make sure that your branch does not contain spurious tags?
Yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
I'm on that team.
* If you changed the UI, has there been a design review?
NA
PS Jenkins bot (ps-jenkins) wrote : | # |
Andrea Cimitan (cimi) wrote : | # |
* Did you perform an exploratory manual test run of the code change and any related functionality?
Not of this, but following branch
* Did CI run pass? If not, please explain why.
AP
* Did you make sure that the branch does not contain spurious tags?
yes
- 1436. By Michael Terry
-
Merge from trunk
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2014-11-26 08:30:12 +0000 |
3 | +++ CMakeLists.txt 2014-12-02 18:43:43 +0000 |
4 | @@ -117,6 +117,7 @@ |
5 | add_subdirectory(qml) |
6 | add_subdirectory(tests) |
7 | add_subdirectory(plugins) |
8 | +add_subdirectory(wizard) |
9 | |
10 | # |
11 | # Data files |
12 | |
13 | === modified file 'debian/control' |
14 | --- debian/control 2014-12-02 09:25:23 +0000 |
15 | +++ debian/control 2014-12-02 18:43:43 +0000 |
16 | @@ -24,6 +24,7 @@ |
17 | libpulse-dev, |
18 | libqmenumodel-dev (>= 0.2.8), |
19 | libqt5xmlpatterns5-dev, |
20 | + libsystemsettings-dev, |
21 | libunity-api-dev (>= 7.93), |
22 | libusermetricsoutput1-dev, |
23 | libxcb1-dev, |
24 | @@ -191,3 +192,15 @@ |
25 | Depends: ${misc:Depends}, |
26 | Description: Documentation for Unity8 |
27 | The Unity 8 shell is the primary user interface for Ubuntu devices. (documentation) |
28 | + |
29 | +Package: ubuntu-system-settings-wizard |
30 | +Architecture: any |
31 | +Depends: unity8 (= ${binary:Version}), |
32 | + ${misc:Depends}, |
33 | + ${shlibs:Depends}, |
34 | +Recommends: qtdeclarative5-qtmir-plugin (>= 0.4), |
35 | +Breaks: ubuntu-system-settings (<< 0.4), |
36 | +Replaces: ubuntu-system-settings (<< 0.4), |
37 | +Description: Welcome Wizard for Ubuntu Touch |
38 | + This package contains the Welcome Wizard used on the Ubuntu Touch images, |
39 | + it's designed for phones, tablets and convergent devices. |
40 | |
41 | === modified file 'debian/rules' |
42 | --- debian/rules 2014-07-23 15:30:38 +0000 |
43 | +++ debian/rules 2014-12-02 18:43:43 +0000 |
44 | @@ -40,7 +40,7 @@ |
45 | |
46 | # use private lib directories |
47 | override_dh_makeshlibs: |
48 | - dh_makeshlibs -Nunity8-private -Nunity8-fake-env |
49 | + dh_makeshlibs -Nunity8-private -Nunity8-fake-env -Nubuntu-system-settings-wizard |
50 | |
51 | # libMockLightDM-qml.so links against liblightdm-qt5-2.so which doesn't exist |
52 | override_dh_shlibdeps: |
53 | |
54 | === added file 'debian/ubuntu-system-settings-wizard.install' |
55 | --- debian/ubuntu-system-settings-wizard.install 1970-01-01 00:00:00 +0000 |
56 | +++ debian/ubuntu-system-settings-wizard.install 2014-12-02 18:43:43 +0000 |
57 | @@ -0,0 +1,5 @@ |
58 | +usr/bin/system-settings-wizard |
59 | +usr/share/ubuntu/settings/wizard |
60 | +usr/share/upstart/sessions/ubuntu-system-settings-wizard*.conf |
61 | +usr/lib/*/ubuntu-system-settings/private/Ubuntu/SystemSettings/Wizard |
62 | +var/lib/polkit-1/localauthority/10-vendor.d/50-com.ubuntu.system-settings.wizard.pkla |
63 | |
64 | === added file 'debian/ubuntu-system-settings-wizard.lintian-overrides' |
65 | --- debian/ubuntu-system-settings-wizard.lintian-overrides 1970-01-01 00:00:00 +0000 |
66 | +++ debian/ubuntu-system-settings-wizard.lintian-overrides 2014-12-02 18:43:43 +0000 |
67 | @@ -0,0 +1,1 @@ |
68 | +ubuntu-system-settings-wizard: binary-without-manpage usr/bin/system-settings-wizard |
69 | |
70 | === modified file 'tests/CMakeLists.txt' |
71 | --- tests/CMakeLists.txt 2014-10-01 13:20:32 +0000 |
72 | +++ tests/CMakeLists.txt 2014-12-02 18:43:43 +0000 |
73 | @@ -14,3 +14,4 @@ |
74 | add_subdirectory(plugins) |
75 | add_subdirectory(utils) |
76 | add_subdirectory(uqmlscene) |
77 | +add_subdirectory(wizard) |
78 | |
79 | === added directory 'tests/wizard' |
80 | === added file 'tests/wizard/CMakeLists.txt' |
81 | --- tests/wizard/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
82 | +++ tests/wizard/CMakeLists.txt 2014-12-02 18:43:43 +0000 |
83 | @@ -0,0 +1,5 @@ |
84 | +add_executable(tst-pagelist tst_pagelist.cpp ${CMAKE_SOURCE_DIR}/wizard/PageList.cpp) |
85 | +set_target_properties(tst-pagelist PROPERTIES |
86 | + INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR};${CMAKE_SOURCE_DIR}/wizard") |
87 | +qt5_use_modules(tst-pagelist Core Test) |
88 | +add_test(tst-pagelist tst-pagelist) |
89 | |
90 | === added file 'tests/wizard/tst_pagelist.cpp' |
91 | --- tests/wizard/tst_pagelist.cpp 1970-01-01 00:00:00 +0000 |
92 | +++ tests/wizard/tst_pagelist.cpp 2014-12-02 18:43:43 +0000 |
93 | @@ -0,0 +1,156 @@ |
94 | +/* |
95 | + * This file is part of system-settings |
96 | + * |
97 | + * Copyright (C) 2014 Canonical Ltd. |
98 | + * |
99 | + * This program is free software: you can redistribute it and/or modify it |
100 | + * under the terms of the GNU General Public License version 3, as published |
101 | + * by the Free Software Foundation. |
102 | + * |
103 | + * This program is distributed in the hope that it will be useful, but |
104 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
105 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
106 | + * PURPOSE. See the GNU General Public License for more details. |
107 | + * |
108 | + * You should have received a copy of the GNU General Public License along |
109 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
110 | + */ |
111 | + |
112 | +#include "PageList.h" |
113 | + |
114 | +#include <QDebug> |
115 | +#include <QObject> |
116 | +#include <QTemporaryDir> |
117 | +#include <QTest> |
118 | + |
119 | +#define PAGES_PATH "ubuntu/settings/wizard/qml/Pages" |
120 | + |
121 | +class PageListTest: public QObject |
122 | +{ |
123 | + Q_OBJECT |
124 | + |
125 | +public: |
126 | + PageListTest() {}; |
127 | + |
128 | +private Q_SLOTS: |
129 | + void testCollect(); |
130 | + void testIterate(); |
131 | + void testIgnoreNonNumbered(); |
132 | + void testIgnoreNonQml(); |
133 | + void testIgnoreDuplicates(); |
134 | + void testDisabled(); |
135 | + |
136 | +private: |
137 | + void fillRoot(const QTemporaryDir &root); |
138 | + void makeFile(const QTemporaryDir &root, const QString &dir, const QString &filename); |
139 | +}; |
140 | + |
141 | +void PageListTest::fillRoot(const QTemporaryDir &root) |
142 | +{ |
143 | + QVERIFY(root.isValid()); |
144 | + QDir rootDir = root.path(); |
145 | + QVERIFY(rootDir.mkpath(QString("a/") + PAGES_PATH)); |
146 | + QVERIFY(rootDir.mkpath(QString("b/") + PAGES_PATH)); |
147 | + QVERIFY(rootDir.mkpath(QString("c/") + PAGES_PATH)); |
148 | + qputenv("XDG_DATA_DIRS", QString(rootDir.path() + "/a:" + |
149 | + rootDir.path() + "/b:" + |
150 | + rootDir.path() + "/c").toLatin1()); |
151 | +} |
152 | + |
153 | +void PageListTest::makeFile(const QTemporaryDir &root, const QString &dir, const QString &filename) |
154 | +{ |
155 | + QFile file(root.path() + "/" + dir + "/" + PAGES_PATH + "/" + filename); |
156 | + QVERIFY(file.open(QIODevice::WriteOnly)); |
157 | + file.close(); |
158 | + QVERIFY(file.exists()); |
159 | +} |
160 | + |
161 | +void PageListTest::testCollect() |
162 | +{ |
163 | + QTemporaryDir root; |
164 | + fillRoot(root); |
165 | + makeFile(root, "a", "3.qml"); |
166 | + makeFile(root, "b", "1.qml"); |
167 | + makeFile(root, "c", "2.qml"); |
168 | + |
169 | + PageList pageList; |
170 | + QCOMPARE(pageList.entries(), QStringList() << "1.qml" << "2.qml" << "3.qml"); |
171 | + QCOMPARE(pageList.paths(), QStringList() << root.path() + "/b/" + PAGES_PATH + "/1.qml" |
172 | + << root.path() + "/c/" + PAGES_PATH + "/2.qml" |
173 | + << root.path() + "/a/" + PAGES_PATH + "/3.qml"); |
174 | +} |
175 | + |
176 | +void PageListTest::testIterate() |
177 | +{ |
178 | + QTemporaryDir root; |
179 | + fillRoot(root); |
180 | + makeFile(root, "a", "1.qml"); |
181 | + makeFile(root, "a", "2.qml"); |
182 | + makeFile(root, "a", "3.qml"); |
183 | + |
184 | + PageList pageList; |
185 | + QCOMPARE(pageList.index(), -1); |
186 | + QCOMPARE(pageList.next(), root.path() + "/a/" + PAGES_PATH + "/1.qml"); |
187 | + QCOMPARE(pageList.prev(), QString()); |
188 | + QCOMPARE(pageList.next(), root.path() + "/a/" + PAGES_PATH + "/2.qml"); |
189 | + QCOMPARE(pageList.prev(), root.path() + "/a/" + PAGES_PATH + "/1.qml"); |
190 | + QCOMPARE(pageList.index(), 0); |
191 | + QCOMPARE(pageList.next(), root.path() + "/a/" + PAGES_PATH + "/2.qml"); |
192 | + QCOMPARE(pageList.next(), root.path() + "/a/" + PAGES_PATH + "/3.qml"); |
193 | + QCOMPARE(pageList.index(), 2); |
194 | + QCOMPARE(pageList.next(), QString()); |
195 | + QCOMPARE(pageList.index(), 2); |
196 | +} |
197 | + |
198 | +void PageListTest::testIgnoreNonNumbered() |
199 | +{ |
200 | + QTemporaryDir root; |
201 | + fillRoot(root); |
202 | + makeFile(root, "a", "1.qml"); |
203 | + makeFile(root, "a", "nope.qml"); |
204 | + |
205 | + PageList pageList; |
206 | + QCOMPARE(pageList.entries(), QStringList() << "1.qml"); |
207 | +} |
208 | + |
209 | +void PageListTest::testIgnoreNonQml() |
210 | +{ |
211 | + QTemporaryDir root; |
212 | + fillRoot(root); |
213 | + makeFile(root, "a", "1.qml"); |
214 | + makeFile(root, "a", "2"); |
215 | + makeFile(root, "a", "2.txt"); |
216 | + |
217 | + PageList pageList; |
218 | + QCOMPARE(pageList.entries(), QStringList() << "1.qml"); |
219 | +} |
220 | + |
221 | +void PageListTest::testIgnoreDuplicates() |
222 | +{ |
223 | + QTemporaryDir root; |
224 | + fillRoot(root); |
225 | + makeFile(root, "a", "1.qml"); |
226 | + makeFile(root, "b", "1.qml"); |
227 | + |
228 | + PageList pageList; |
229 | + QCOMPARE(pageList.paths(), QStringList() << root.path() + "/a/" + PAGES_PATH + "/1.qml"); |
230 | +} |
231 | + |
232 | +void PageListTest::testDisabled() |
233 | +{ |
234 | + QTemporaryDir root; |
235 | + fillRoot(root); |
236 | + makeFile(root, "a", "1.qml.disabled"); // before the fact |
237 | + makeFile(root, "b", "1.qml"); |
238 | + makeFile(root, "b", "2.qml"); |
239 | + makeFile(root, "b", "2.qml.disabled"); // same dir |
240 | + makeFile(root, "b", "3.qml"); |
241 | + makeFile(root, "b", "4.qml"); // only survivor |
242 | + makeFile(root, "c", "3.qml.disabled"); // after the fact |
243 | + |
244 | + PageList pageList; |
245 | + QCOMPARE(pageList.entries(), QStringList() << "4.qml"); |
246 | +} |
247 | + |
248 | +QTEST_MAIN(PageListTest) |
249 | +#include "tst_pagelist.moc" |
250 | |
251 | === added directory 'wizard' |
252 | === added file 'wizard/50-com.ubuntu.system-settings.wizard.pkla' |
253 | --- wizard/50-com.ubuntu.system-settings.wizard.pkla 1970-01-01 00:00:00 +0000 |
254 | +++ wizard/50-com.ubuntu.system-settings.wizard.pkla 2014-12-02 18:43:43 +0000 |
255 | @@ -0,0 +1,6 @@ |
256 | +[Allow welcome wizard to set AccountsService fields] |
257 | +Identity=unix-user:lightdm |
258 | +Action=org.freedesktop.accounts.user-administration |
259 | +ResultActive=yes |
260 | +ResultInactive=no |
261 | +ResultAny=no |
262 | |
263 | === added file 'wizard/CMakeLists.txt' |
264 | --- wizard/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
265 | +++ wizard/CMakeLists.txt 2014-12-02 18:43:43 +0000 |
266 | @@ -0,0 +1,65 @@ |
267 | +# This file uses a lot of namespacing like "ubuntu-system-settings" instead of |
268 | +# "unity8". This is because we have imported it from ubuntu-system-settings |
269 | +# and haven't fully integrated it yet. |
270 | + |
271 | +include_directories( |
272 | + ${CMAKE_CURRENT_BINARY_DIR} |
273 | + ${Qt5Gui_PRIVATE_INCLUDE_DIRS} |
274 | +) |
275 | + |
276 | +set(PLUGIN_MANIFEST_DIR_BASE share/ubuntu/settings/system) |
277 | +set(PLUGIN_MODULE_DIR_BASE ubuntu-system-settings) |
278 | +set(PLUGIN_PRIVATE_MODULE_DIR_BASE "${PLUGIN_MODULE_DIR_BASE}/private") |
279 | +set(PLUGIN_QML_DIR_BASE share/ubuntu/settings/system/qml-plugins) |
280 | + |
281 | +set(PLUGIN_MANIFEST_DIR "${CMAKE_INSTALL_PREFIX}/${PLUGIN_MANIFEST_DIR_BASE}") |
282 | +set(PLUGIN_MODULE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${PLUGIN_MODULE_DIR_BASE}") |
283 | +set(PLUGIN_PRIVATE_MODULE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${PLUGIN_PRIVATE_MODULE_DIR_BASE}") |
284 | +set(PLUGIN_QML_DIR "${CMAKE_INSTALL_PREFIX}/${PLUGIN_QML_DIR_BASE}") |
285 | + |
286 | +add_definitions(-DI18N_DOMAIN="unity8") |
287 | +add_definitions(-DPLUGIN_MANIFEST_DIR="${PLUGIN_MANIFEST_DIR}") |
288 | +add_definitions(-DPLUGIN_MODULE_DIR="${PLUGIN_MODULE_DIR}") |
289 | +add_definitions(-DPLUGIN_PRIVATE_MODULE_DIR="${PLUGIN_PRIVATE_MODULE_DIR}") |
290 | +add_definitions(-DPLUGIN_QML_DIR="${PLUGIN_QML_DIR}") |
291 | + |
292 | +execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=plugindir unity-shell-api OUTPUT_VARIABLE SHELL_PLUGINDIR OUTPUT_STRIP_TRAILING_WHITESPACE) |
293 | +if(SHELL_PLUGINDIR STREQUAL "") |
294 | + message(FATAL_ERROR "Could not determine plugin import dir.") |
295 | +endif() |
296 | + |
297 | +add_definitions(-DSHELL_PLUGINDIR="${SHELL_PLUGINDIR}") |
298 | + |
299 | +set(WIZARD_ROOT "${CMAKE_INSTALL_PREFIX}/share") |
300 | +add_definitions(-DWIZARD_ROOT="${WIZARD_ROOT}") |
301 | + |
302 | +file(GLOB_RECURSE QML_FILES |
303 | + qml/* |
304 | +) |
305 | + |
306 | +set(WIZARD_SOURCES |
307 | + main.cpp |
308 | + PageList.cpp |
309 | +) |
310 | + |
311 | +add_executable(system-settings-wizard |
312 | + ${WIZARD_SOURCES} |
313 | + ${system-settings-wizard-resources} |
314 | + ${QML_FILES} # This is to make qml and image files appear in the IDE's project tree |
315 | +) |
316 | + |
317 | +qt5_use_modules(system-settings-wizard Core Gui Quick Qml) |
318 | + |
319 | +add_subdirectory(Unity) |
320 | +add_subdirectory(Utils) |
321 | + |
322 | +install(TARGETS system-settings-wizard RUNTIME DESTINATION bin) |
323 | +install(FILES ubuntu-system-settings-wizard.conf |
324 | + ubuntu-system-settings-wizard-cleanup.conf |
325 | + ubuntu-system-settings-wizard-set-lang.conf |
326 | + DESTINATION share/upstart/sessions) |
327 | + |
328 | +set(POLKIT_LIB_DIR "${CMAKE_INSTALL_LOCALSTATEDIR}/lib/polkit-1") |
329 | +install(FILES 50-com.ubuntu.system-settings.wizard.pkla DESTINATION ${POLKIT_LIB_DIR}/localauthority/10-vendor.d) |
330 | + |
331 | +install(DIRECTORY qml DESTINATION ${WIZARD_ROOT}/ubuntu/settings/wizard) |
332 | |
333 | === added file 'wizard/PageList.cpp' |
334 | --- wizard/PageList.cpp 1970-01-01 00:00:00 +0000 |
335 | +++ wizard/PageList.cpp 2014-12-02 18:43:43 +0000 |
336 | @@ -0,0 +1,111 @@ |
337 | +/* |
338 | + * This file is part of system-settings |
339 | + * |
340 | + * Copyright (C) 2014 Canonical Ltd. |
341 | + * |
342 | + * This program is free software: you can redistribute it and/or modify it |
343 | + * under the terms of the GNU General Public License version 3, as published |
344 | + * by the Free Software Foundation. |
345 | + * |
346 | + * This program is distributed in the hope that it will be useful, but |
347 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
348 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
349 | + * PURPOSE. See the GNU General Public License for more details. |
350 | + * |
351 | + * You should have received a copy of the GNU General Public License along |
352 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
353 | + */ |
354 | + |
355 | +/** |
356 | + * This class lets the list of wizard pages be dynamic. |
357 | + * - To add new ones, drop them into |
358 | + * $XDG_DATA_DIRS/ubuntu/settings/wizard/qml/Pages with a numbered prefix, |
359 | + * like "21-custom-page.qml". The number determines the order in the page |
360 | + * sequence that your page will appear. |
361 | + * - To disable an existing page, add a file like "21-custom-page.qml.disabled" |
362 | + * - To go to the next page, use pageStack.next() |
363 | + * - To go back to the previous page, use pageStack.prev() |
364 | + * - To load a page outside of the normal flow (so that it doesn't affect the |
365 | + * back button), use pageStack.push(Qt.resolvedUrl("custom-page.qml")) in |
366 | + * your page. |
367 | + * - See default pages for plenty of examples. |
368 | + */ |
369 | + |
370 | +#include "PageList.h" |
371 | +#include <QDir> |
372 | +#include <QStandardPaths> |
373 | + |
374 | +#include <QDebug> |
375 | +PageList::PageList(QObject *parent) |
376 | + : QObject(parent), |
377 | + m_index(-1), |
378 | + m_pages() |
379 | +{ |
380 | + QString qmlSuffix = ".qml"; |
381 | + QString disabledSuffix = ".disabled"; |
382 | + QSet<QString> disabledPages; |
383 | + QStringList dataDirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); |
384 | + |
385 | + QString rootDir = qgetenv("UBUNTU_SYSTEM_SETTINGS_WIZARD_ROOT"); // for testing |
386 | + if (!rootDir.isEmpty()) |
387 | + dataDirs = QStringList() << rootDir; |
388 | + |
389 | + Q_FOREACH(const QString &dataDir, dataDirs) { |
390 | + QDir dir(dataDir + "/ubuntu/settings/wizard/qml/Pages"); |
391 | + QStringList entries = dir.entryList(QStringList("[0-9]*"), QDir::Files | QDir::Readable); |
392 | + Q_FOREACH(const QString &entry, entries) { |
393 | + if (!m_pages.contains(entry) && entry.endsWith(qmlSuffix)) |
394 | + m_pages.insert(entry, dir.absoluteFilePath(entry)); |
395 | + else if (entry.endsWith(qmlSuffix + disabledSuffix)) |
396 | + disabledPages.insert(entry.left(entry.size() - disabledSuffix.size())); |
397 | + } |
398 | + } |
399 | + |
400 | + // Now remove any explicitly disabled entries |
401 | + Q_FOREACH(const QString &page, disabledPages) { |
402 | + m_pages.remove(page); |
403 | + } |
404 | +} |
405 | + |
406 | +QStringList PageList::entries() const |
407 | +{ |
408 | + return m_pages.keys(); |
409 | +} |
410 | + |
411 | +QStringList PageList::paths() const |
412 | +{ |
413 | + return m_pages.values(); |
414 | +} |
415 | + |
416 | +int PageList::index() const |
417 | +{ |
418 | + return m_index; |
419 | +} |
420 | + |
421 | +int PageList::numPages() const |
422 | +{ |
423 | + return m_pages.size(); |
424 | +} |
425 | + |
426 | +QString PageList::prev() |
427 | +{ |
428 | + if (m_index > 0) |
429 | + return m_pages.values()[setIndex(m_index - 1)]; |
430 | + else |
431 | + return QString(); |
432 | +} |
433 | + |
434 | +QString PageList::next() |
435 | +{ |
436 | + if (m_index < m_pages.count() - 1) |
437 | + return m_pages.values()[setIndex(m_index + 1)]; |
438 | + else |
439 | + return QString(); |
440 | +} |
441 | + |
442 | +int PageList::setIndex(int index) |
443 | +{ |
444 | + m_index = index; |
445 | + Q_EMIT indexChanged(); |
446 | + return m_index; |
447 | +} |
448 | |
449 | === added file 'wizard/PageList.h' |
450 | --- wizard/PageList.h 1970-01-01 00:00:00 +0000 |
451 | +++ wizard/PageList.h 2014-12-02 18:43:43 +0000 |
452 | @@ -0,0 +1,55 @@ |
453 | +/* |
454 | + * This file is part of system-settings |
455 | + * |
456 | + * Copyright (C) 2014 Canonical Ltd. |
457 | + * |
458 | + * This program is free software: you can redistribute it and/or modify it |
459 | + * under the terms of the GNU General Public License version 3, as published |
460 | + * by the Free Software Foundation. |
461 | + * |
462 | + * This program is distributed in the hope that it will be useful, but |
463 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
464 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
465 | + * PURPOSE. See the GNU General Public License for more details. |
466 | + * |
467 | + * You should have received a copy of the GNU General Public License along |
468 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
469 | + */ |
470 | + |
471 | +#ifndef PAGELIST_H |
472 | +#define PAGEList_H |
473 | + |
474 | +#include <QMap> |
475 | +#include <QObject> |
476 | +#include <QString> |
477 | + |
478 | +class PageList : public QObject |
479 | +{ |
480 | + Q_OBJECT |
481 | + Q_PROPERTY(int index READ index NOTIFY indexChanged) |
482 | + Q_PROPERTY(int numPages READ numPages NOTIFY numPagesChanged) |
483 | + |
484 | +public: |
485 | + explicit PageList(QObject *parent = 0); |
486 | + |
487 | + QStringList entries() const; |
488 | + QStringList paths() const; |
489 | + int index() const; |
490 | + int numPages() const; |
491 | + |
492 | +public Q_SLOTS: |
493 | + QString prev(); |
494 | + QString next(); |
495 | + |
496 | +Q_SIGNALS: |
497 | + void indexChanged(); |
498 | + void numPagesChanged(); // never emitted, just here to quiet Qml warnings |
499 | + |
500 | +private: |
501 | + int setIndex(int index); |
502 | + |
503 | + int m_index; |
504 | + QMap<QString, QString> m_pages; |
505 | +}; |
506 | + |
507 | +#endif // PAGELIST_H |
508 | |
509 | === added directory 'wizard/Unity' |
510 | === added directory 'wizard/Unity/Application' |
511 | === added file 'wizard/Unity/Application/CMakeLists.txt' |
512 | --- wizard/Unity/Application/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
513 | +++ wizard/Unity/Application/CMakeLists.txt 2014-12-02 18:43:43 +0000 |
514 | @@ -0,0 +1,3 @@ |
515 | +# This is just a small fake Unity.Application for non-Mir environments |
516 | +set(PLUG_DIR ${PLUGIN_PRIVATE_MODULE_DIR}/Ubuntu/SystemSettings/Wizard/NonMir/Unity/Application) |
517 | +install(FILES qmldir OSKController.qml DESTINATION ${PLUG_DIR}) |
518 | |
519 | === added file 'wizard/Unity/Application/OSKController.qml' |
520 | --- wizard/Unity/Application/OSKController.qml 1970-01-01 00:00:00 +0000 |
521 | +++ wizard/Unity/Application/OSKController.qml 2014-12-02 18:43:43 +0000 |
522 | @@ -0,0 +1,20 @@ |
523 | +/* |
524 | + * Copyright (C) 2013 Canonical, Ltd. |
525 | + * |
526 | + * This program is free software; you can redistribute it and/or modify |
527 | + * it under the terms of the GNU General Public License as published by |
528 | + * the Free Software Foundation; version 3. |
529 | + * |
530 | + * This program is distributed in the hope that it will be useful, |
531 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
532 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
533 | + * GNU General Public License for more details. |
534 | + * |
535 | + * You should have received a copy of the GNU General Public License |
536 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
537 | + */ |
538 | + |
539 | +import QtQuick 2.0; |
540 | + |
541 | +Item { |
542 | +} |
543 | |
544 | === added file 'wizard/Unity/Application/qmldir' |
545 | --- wizard/Unity/Application/qmldir 1970-01-01 00:00:00 +0000 |
546 | +++ wizard/Unity/Application/qmldir 2014-12-02 18:43:43 +0000 |
547 | @@ -0,0 +1,2 @@ |
548 | +module Unity.Application |
549 | +OSKController 0.1 OSKController.qml |
550 | |
551 | === added file 'wizard/Unity/CMakeLists.txt' |
552 | --- wizard/Unity/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
553 | +++ wizard/Unity/CMakeLists.txt 2014-12-02 18:43:43 +0000 |
554 | @@ -0,0 +1,1 @@ |
555 | +add_subdirectory(Application) |
556 | |
557 | === added directory 'wizard/Utils' |
558 | === added file 'wizard/Utils/CMakeLists.txt' |
559 | --- wizard/Utils/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
560 | +++ wizard/Utils/CMakeLists.txt 2014-12-02 18:43:43 +0000 |
561 | @@ -0,0 +1,27 @@ |
562 | +include_directories( |
563 | + ${CMAKE_CURRENT_SOURCE_DIR} |
564 | + ${CMAKE_CURRENT_BINARY_DIR} |
565 | + ${Qt5Gui_PRIVATE_INCLUDE_DIRS} |
566 | +) |
567 | + |
568 | +set(QMLPLUGIN_SRC |
569 | + qsortfilterproxymodelqml.cpp |
570 | + plugin.cpp |
571 | + system.cpp |
572 | + ) |
573 | + |
574 | +add_library(WizardUtils-qml SHARED |
575 | + ${QMLPLUGIN_SRC} |
576 | + ) |
577 | + |
578 | +# Because this is an internal support library, we want |
579 | +# to expose all symbols in it. Consider changing this |
580 | +# either to a static library or just using the |
581 | +# files directly in targets. |
582 | +set_target_properties(WizardUtils-qml PROPERTIES COMPILE_FLAGS -fvisibility=default) |
583 | + |
584 | +qt5_use_modules(WizardUtils-qml DBus Qml Quick) |
585 | + |
586 | +set(PLUG_DIR ${PLUGIN_PRIVATE_MODULE_DIR}/Ubuntu/SystemSettings/Wizard/Utils) |
587 | +install(FILES qmldir DESTINATION ${PLUG_DIR}) |
588 | +install(TARGETS WizardUtils-qml DESTINATION ${PLUG_DIR}) |
589 | |
590 | === added file 'wizard/Utils/plugin.cpp' |
591 | --- wizard/Utils/plugin.cpp 1970-01-01 00:00:00 +0000 |
592 | +++ wizard/Utils/plugin.cpp 2014-12-02 18:43:43 +0000 |
593 | @@ -0,0 +1,41 @@ |
594 | +/* |
595 | + * Copyright (C) 2014 Canonical, Ltd. |
596 | + * |
597 | + * This program is free software; you can redistribute it and/or modify |
598 | + * it under the terms of the GNU General Public License as published by |
599 | + * the Free Software Foundation; version 3. |
600 | + * |
601 | + * This program is distributed in the hope that it will be useful, |
602 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
603 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
604 | + * GNU General Public License for more details. |
605 | + * |
606 | + * You should have received a copy of the GNU General Public License |
607 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
608 | + */ |
609 | + |
610 | +// Qt |
611 | +#include <QtQml/qqml.h> |
612 | +#include <QQmlContext> |
613 | +#include <QDebug> |
614 | +// self |
615 | +#include "plugin.h" |
616 | + |
617 | +// local |
618 | +#include "qsortfilterproxymodelqml.h" |
619 | +#include "system.h" |
620 | + |
621 | +static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine) |
622 | +{ |
623 | + Q_UNUSED(engine) |
624 | + Q_UNUSED(scriptEngine) |
625 | + return new System(); |
626 | +} |
627 | + |
628 | +void UtilsPlugin::registerTypes(const char *uri) |
629 | +{ |
630 | + Q_ASSERT(uri == QLatin1String("Ubuntu.SystemSettings.Wizard.Utils")); |
631 | + qmlRegisterType<QAbstractItemModel>(); |
632 | + qmlRegisterType<QSortFilterProxyModelQML>(uri, 0, 1, "SortFilterProxyModel"); |
633 | + qmlRegisterSingletonType<System>(uri, 0, 1, "System", system_provider); |
634 | +} |
635 | |
636 | === added file 'wizard/Utils/plugin.h' |
637 | --- wizard/Utils/plugin.h 1970-01-01 00:00:00 +0000 |
638 | +++ wizard/Utils/plugin.h 2014-12-02 18:43:43 +0000 |
639 | @@ -0,0 +1,33 @@ |
640 | +/* |
641 | + * Copyright (C) 2014 Canonical, Ltd. |
642 | + * |
643 | + * This program is free software; you can redistribute it and/or modify |
644 | + * it under the terms of the GNU General Public License as published by |
645 | + * the Free Software Foundation; version 3. |
646 | + * |
647 | + * This program is distributed in the hope that it will be useful, |
648 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
649 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
650 | + * GNU General Public License for more details. |
651 | + * |
652 | + * You should have received a copy of the GNU General Public License |
653 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
654 | + * |
655 | + */ |
656 | + |
657 | +#ifndef UTILS_PLUGIN_H |
658 | +#define UTILS_PLUGIN_H |
659 | + |
660 | +#include <QtQml/QQmlEngine> |
661 | +#include <QtQml/QQmlExtensionPlugin> |
662 | + |
663 | +class UtilsPlugin : public QQmlExtensionPlugin |
664 | +{ |
665 | + Q_OBJECT |
666 | + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") |
667 | + |
668 | +public: |
669 | + void registerTypes(const char *uri); |
670 | +}; |
671 | + |
672 | +#endif |
673 | |
674 | === added file 'wizard/Utils/qmldir' |
675 | --- wizard/Utils/qmldir 1970-01-01 00:00:00 +0000 |
676 | +++ wizard/Utils/qmldir 2014-12-02 18:43:43 +0000 |
677 | @@ -0,0 +1,2 @@ |
678 | +module Ubuntu.SystemSettings.Wizard.Utils |
679 | +plugin WizardUtils-qml |
680 | |
681 | === added file 'wizard/Utils/qsortfilterproxymodelqml.cpp' |
682 | --- wizard/Utils/qsortfilterproxymodelqml.cpp 1970-01-01 00:00:00 +0000 |
683 | +++ wizard/Utils/qsortfilterproxymodelqml.cpp 2014-12-02 18:43:43 +0000 |
684 | @@ -0,0 +1,167 @@ |
685 | +/* |
686 | + * Copyright (C) 2012 Canonical, Ltd. |
687 | + * |
688 | + * This program is free software; you can redistribute it and/or modify |
689 | + * it under the terms of the GNU General Public License as published by |
690 | + * the Free Software Foundation; version 3. |
691 | + * |
692 | + * This program is distributed in the hope that it will be useful, |
693 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
694 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
695 | + * GNU General Public License for more details. |
696 | + * |
697 | + * You should have received a copy of the GNU General Public License |
698 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
699 | + */ |
700 | + |
701 | +// self |
702 | +#include "qsortfilterproxymodelqml.h" |
703 | + |
704 | +// Qt |
705 | +#include <QDebug> |
706 | + |
707 | +QSortFilterProxyModelQML::QSortFilterProxyModelQML(QObject *parent) |
708 | + : QSortFilterProxyModel(parent) |
709 | + , m_invertMatch(false) |
710 | +{ |
711 | + connect(this, SIGNAL(modelReset()), SIGNAL(countChanged())); |
712 | + connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(countChanged())); |
713 | + connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(countChanged())); |
714 | +} |
715 | + |
716 | +/* |
717 | + * Enter row index of filtered/sorted model, returns row index of source model |
718 | + */ |
719 | +int QSortFilterProxyModelQML::mapRowToSource(int row) |
720 | +{ |
721 | + if (sourceModel() == NULL) |
722 | + return -1; |
723 | + |
724 | + return QSortFilterProxyModel::mapToSource(index(row, 0)).row(); |
725 | +} |
726 | + |
727 | +QHash<int, QByteArray> QSortFilterProxyModelQML::roleNames() const |
728 | +{ |
729 | + return sourceModel() ? sourceModel()->roleNames() : QHash<int, QByteArray>(); |
730 | +} |
731 | + |
732 | +void |
733 | +QSortFilterProxyModelQML::setModel(QAbstractItemModel *itemModel) |
734 | +{ |
735 | + if (itemModel == NULL) { |
736 | + return; |
737 | + } |
738 | + |
739 | + if (itemModel != sourceModel()) { |
740 | + if (sourceModel() != NULL) { |
741 | + sourceModel()->disconnect(this); |
742 | + } |
743 | + |
744 | + setSourceModel(itemModel); |
745 | + |
746 | + connect(itemModel, SIGNAL(modelReset()), SIGNAL(totalCountChanged())); |
747 | + connect(itemModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(totalCountChanged())); |
748 | + connect(itemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(totalCountChanged())); |
749 | + |
750 | + Q_EMIT totalCountChanged(); |
751 | + Q_EMIT modelChanged(); |
752 | + } |
753 | +} |
754 | + |
755 | +QVariantMap |
756 | +QSortFilterProxyModelQML::get(int row) |
757 | +{ |
758 | + QVariantMap res; |
759 | + const QHash<int, QByteArray> roles = roleNames(); |
760 | + auto it = roles.begin(); |
761 | + for ( ; it != roles.end(); ++it) { |
762 | + res[*it] = data(row, it.key()); |
763 | + } |
764 | + return res; |
765 | +} |
766 | + |
767 | +QVariant |
768 | +QSortFilterProxyModelQML::data(int row, int role) |
769 | +{ |
770 | + if (sourceModel() == NULL) { |
771 | + return QVariant(); |
772 | + } |
773 | + |
774 | + return index(row, 0).data(role); |
775 | +} |
776 | + |
777 | +int |
778 | +QSortFilterProxyModelQML::totalCount() const |
779 | +{ |
780 | + if (sourceModel() != NULL) { |
781 | + return sourceModel()->rowCount(); |
782 | + } else { |
783 | + return 0; |
784 | + } |
785 | +} |
786 | + |
787 | +int |
788 | +QSortFilterProxyModelQML::count() |
789 | +{ |
790 | + return rowCount(); |
791 | +} |
792 | + |
793 | +bool |
794 | +QSortFilterProxyModelQML::invertMatch() const |
795 | +{ |
796 | + return m_invertMatch; |
797 | +} |
798 | + |
799 | +void |
800 | +QSortFilterProxyModelQML::setInvertMatch(bool invertMatch) |
801 | +{ |
802 | + if (invertMatch != m_invertMatch) { |
803 | + m_invertMatch = invertMatch; |
804 | + Q_EMIT invertMatchChanged(invertMatch); |
805 | + invalidateFilter(); |
806 | + } |
807 | +} |
808 | + |
809 | +bool |
810 | +QSortFilterProxyModelQML::filterAcceptsRow(int sourceRow, |
811 | + const QModelIndex &sourceParent) const |
812 | +{ |
813 | + // If there's no regexp set, always accept all rows indepenently of the invertMatch setting |
814 | + if (filterRegExp().isEmpty()) { |
815 | + return true; |
816 | + } |
817 | + |
818 | + bool result = QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); |
819 | + return (m_invertMatch) ? !result : result; |
820 | +} |
821 | + |
822 | +int |
823 | +QSortFilterProxyModelQML::findFirst(int role, const QVariant& value) const |
824 | +{ |
825 | + QModelIndexList matches = match(index(0, 0), role, value, 1, Qt::MatchExactly); |
826 | + if (!matches.isEmpty()) { |
827 | + return matches.first().row(); |
828 | + } else { |
829 | + return -1; |
830 | + } |
831 | +} |
832 | + |
833 | +int |
834 | +QSortFilterProxyModelQML::mapFromSource(int row) |
835 | +{ |
836 | + if (sourceModel() != NULL) { |
837 | + return QSortFilterProxyModel::mapFromSource(sourceModel()->index(row, 0)).row(); |
838 | + } else { |
839 | + return -1; |
840 | + } |
841 | +} |
842 | + |
843 | +int |
844 | +QSortFilterProxyModelQML::mapToSource(int row) |
845 | +{ |
846 | + if (sourceModel() != NULL) { |
847 | + return QSortFilterProxyModel::mapToSource(index(row, 0)).row(); |
848 | + } else { |
849 | + return -1; |
850 | + } |
851 | +} |
852 | |
853 | === added file 'wizard/Utils/qsortfilterproxymodelqml.h' |
854 | --- wizard/Utils/qsortfilterproxymodelqml.h 1970-01-01 00:00:00 +0000 |
855 | +++ wizard/Utils/qsortfilterproxymodelqml.h 2014-12-02 18:43:43 +0000 |
856 | @@ -0,0 +1,63 @@ |
857 | +/* |
858 | + * Copyright (C) 2012 Canonical, Ltd. |
859 | + * |
860 | + * This program is free software; you can redistribute it and/or modify |
861 | + * it under the terms of the GNU General Public License as published by |
862 | + * the Free Software Foundation; version 3. |
863 | + * |
864 | + * This program is distributed in the hope that it will be useful, |
865 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
866 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
867 | + * GNU General Public License for more details. |
868 | + * |
869 | + * You should have received a copy of the GNU General Public License |
870 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
871 | + */ |
872 | + |
873 | +#ifndef QSORTFILTERPROXYMODELQML_H |
874 | +#define QSORTFILTERPROXYMODELQML_H |
875 | + |
876 | +#include <QSortFilterProxyModel> |
877 | + |
878 | +class QSortFilterProxyModelQML : public QSortFilterProxyModel |
879 | +{ |
880 | + Q_OBJECT |
881 | + |
882 | + Q_PROPERTY(QAbstractItemModel* model READ sourceModel WRITE setModel NOTIFY modelChanged) |
883 | + Q_PROPERTY(int totalCount READ totalCount NOTIFY totalCountChanged) |
884 | + Q_PROPERTY(int count READ count NOTIFY countChanged) |
885 | + Q_PROPERTY(bool invertMatch READ invertMatch WRITE setInvertMatch NOTIFY invertMatchChanged) |
886 | + |
887 | +public: |
888 | + explicit QSortFilterProxyModelQML(QObject *parent = 0); |
889 | + |
890 | + Q_INVOKABLE QVariantMap get(int row); // Use with caution, it can be slow to query all the roles |
891 | + Q_INVOKABLE QVariant data(int row, int role); |
892 | + Q_INVOKABLE int count(); |
893 | + Q_INVOKABLE int findFirst(int role, const QVariant& value) const; |
894 | + Q_INVOKABLE int mapRowToSource(int row); |
895 | + virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; |
896 | + |
897 | + /* getters */ |
898 | + int totalCount() const; |
899 | + bool invertMatch() const; |
900 | + QHash<int, QByteArray> roleNames() const; |
901 | + |
902 | + /* setters */ |
903 | + void setModel(QAbstractItemModel *model); |
904 | + void setInvertMatch(bool invertMatch); |
905 | + |
906 | + Q_INVOKABLE int mapFromSource(int row); |
907 | + Q_INVOKABLE int mapToSource(int row); |
908 | + |
909 | +Q_SIGNALS: |
910 | + void totalCountChanged(); |
911 | + void countChanged(); |
912 | + void invertMatchChanged(bool); |
913 | + void modelChanged(); |
914 | + |
915 | +private: |
916 | + bool m_invertMatch; |
917 | +}; |
918 | + |
919 | +#endif // QSORTFILTERPROXYMODELQML_H |
920 | |
921 | === added file 'wizard/Utils/system.cpp' |
922 | --- wizard/Utils/system.cpp 1970-01-01 00:00:00 +0000 |
923 | +++ wizard/Utils/system.cpp 2014-12-02 18:43:43 +0000 |
924 | @@ -0,0 +1,118 @@ |
925 | +/* |
926 | + * This file is part of system-settings |
927 | + * |
928 | + * Copyright (C) 2014 Canonical Ltd. |
929 | + * |
930 | + * This program is free software: you can redistribute it and/or modify it |
931 | + * under the terms of the GNU General Public License version 3, as published |
932 | + * by the Free Software Foundation. |
933 | + * |
934 | + * This program is distributed in the hope that it will be useful, but |
935 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
936 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
937 | + * PURPOSE. See the GNU General Public License for more details. |
938 | + * |
939 | + * You should have received a copy of the GNU General Public License along |
940 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
941 | + */ |
942 | + |
943 | +#include "system.h" |
944 | +#include <QDBusInterface> |
945 | +#include <QDBusPendingCall> |
946 | +#include <QDBusPendingReply> |
947 | +#include <QFile> |
948 | +#include <QProcess> |
949 | +#include <unistd.h> |
950 | + |
951 | +#define HERE_IFACE "com.ubuntu.location.providers.here.AccountsService" |
952 | +#define ENABLED_PROP "LicenseAccepted" |
953 | +#define PATH_PROP "LicenseBasePath" |
954 | + |
955 | +System::System() |
956 | + : QObject(), |
957 | + m_accounts(nullptr), |
958 | + m_hereEnabled(false), |
959 | + m_hereLicensePath(" ") // use a single space to indicate it is unasssigned |
960 | +{ |
961 | + m_accounts = new QDBusInterface("org.freedesktop.Accounts", |
962 | + "/org/freedesktop/Accounts/User" + QString::number(geteuid()), |
963 | + "org.freedesktop.DBus.Properties", |
964 | + QDBusConnection::systemBus(), |
965 | + this); |
966 | + |
967 | + m_accounts->connection().connect(m_accounts->service(), |
968 | + m_accounts->path(), |
969 | + m_accounts->interface(), |
970 | + "PropertiesChanged", |
971 | + this, |
972 | + SLOT(propertiesChanged(QString, QVariantMap, QStringList))); |
973 | + |
974 | + QDBusPendingCall call = m_accounts->asyncCall("Get", HERE_IFACE, PATH_PROP); |
975 | + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); |
976 | + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)), |
977 | + this, SLOT(getHereLicensePathFinished(QDBusPendingCallWatcher *))); |
978 | +} |
979 | + |
980 | +void System::propertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalid) |
981 | +{ |
982 | + if (interface == HERE_IFACE) { |
983 | + if (changed.contains(ENABLED_PROP)) { |
984 | + m_hereEnabled = changed[ENABLED_PROP].toBool(); |
985 | + Q_EMIT hereEnabledChanged(); |
986 | + } else if (invalid.contains(ENABLED_PROP)) { |
987 | + QDBusPendingCall call = m_accounts->asyncCall("Get", HERE_IFACE, ENABLED_PROP); |
988 | + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); |
989 | + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)), |
990 | + this, SLOT(getHereEnabledFinished(QDBusPendingCallWatcher *))); |
991 | + } |
992 | + } |
993 | +} |
994 | + |
995 | +void System::getHereEnabledFinished(QDBusPendingCallWatcher *watcher) |
996 | +{ |
997 | + QDBusPendingReply<QVariant> reply = *watcher; |
998 | + if (!reply.isError()) { |
999 | + QVariant value = reply.argumentAt<0>(); |
1000 | + m_hereEnabled = value.toBool(); |
1001 | + Q_EMIT hereEnabledChanged(); |
1002 | + } |
1003 | + watcher->deleteLater(); |
1004 | +} |
1005 | + |
1006 | +void System::getHereLicensePathFinished(QDBusPendingCallWatcher *watcher) |
1007 | +{ |
1008 | + QDBusPendingReply<QVariant> reply = *watcher; |
1009 | + |
1010 | + m_hereLicensePath = ""; |
1011 | + |
1012 | + if (!reply.isError()) { |
1013 | + QVariant value = reply.argumentAt<0>(); |
1014 | + if (QFile::exists(value.toString())) { |
1015 | + m_hereLicensePath = value.toString(); |
1016 | + } |
1017 | + } |
1018 | + |
1019 | + Q_EMIT hereLicensePathChanged(); |
1020 | + |
1021 | + watcher->deleteLater(); |
1022 | +} |
1023 | + |
1024 | +bool System::hereEnabled() const |
1025 | +{ |
1026 | + return m_hereEnabled; |
1027 | +} |
1028 | + |
1029 | +void System::setHereEnabled(bool enabled) |
1030 | +{ |
1031 | + m_accounts->asyncCall("Set", HERE_IFACE, ENABLED_PROP, QVariant::fromValue(QDBusVariant(enabled))); |
1032 | +} |
1033 | + |
1034 | +QString System::hereLicensePath() const |
1035 | +{ |
1036 | + return m_hereLicensePath; |
1037 | +} |
1038 | + |
1039 | +void System::updateSessionLanguage() |
1040 | +{ |
1041 | + QProcess::startDetached("sh -c \"initctl start ubuntu-system-settings-wizard-set-lang; initctl emit --no-wait indicator-services-start; initctl start --no-wait maliit-server\""); |
1042 | +} |
1043 | |
1044 | === added file 'wizard/Utils/system.h' |
1045 | --- wizard/Utils/system.h 1970-01-01 00:00:00 +0000 |
1046 | +++ wizard/Utils/system.h 2014-12-02 18:43:43 +0000 |
1047 | @@ -0,0 +1,57 @@ |
1048 | +/* |
1049 | + * This file is part of system-settings |
1050 | + * |
1051 | + * Copyright (C) 2014 Canonical Ltd. |
1052 | + * |
1053 | + * This program is free software: you can redistribute it and/or modify it |
1054 | + * under the terms of the GNU General Public License version 3, as published |
1055 | + * by the Free Software Foundation. |
1056 | + * |
1057 | + * This program is distributed in the hope that it will be useful, but |
1058 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1059 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1060 | + * PURPOSE. See the GNU General Public License for more details. |
1061 | + * |
1062 | + * You should have received a copy of the GNU General Public License along |
1063 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1064 | + */ |
1065 | + |
1066 | +#include <QObject> |
1067 | +#include <QString> |
1068 | + |
1069 | +class QDBusInterface; |
1070 | +class QDBusPendingCallWatcher; |
1071 | + |
1072 | +class System : public QObject |
1073 | +{ |
1074 | + Q_OBJECT |
1075 | + Q_PROPERTY(bool hereEnabled READ hereEnabled WRITE setHereEnabled NOTIFY hereEnabledChanged) |
1076 | + Q_PROPERTY(QString hereLicensePath READ hereLicensePath NOTIFY hereLicensePathChanged) |
1077 | + |
1078 | +public: |
1079 | + System(); |
1080 | + |
1081 | + bool hereEnabled() const; |
1082 | + void setHereEnabled(bool enabled); |
1083 | + |
1084 | + QString hereLicensePath() const; |
1085 | + |
1086 | +public Q_SLOTS: |
1087 | + void updateSessionLanguage(); |
1088 | + |
1089 | +Q_SIGNALS: |
1090 | + void hereEnabledChanged(); |
1091 | + void hereLicensePathChanged(); |
1092 | + |
1093 | +private Q_SLOTS: |
1094 | + void propertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalid); |
1095 | + void getHereEnabledFinished(QDBusPendingCallWatcher *watcher); |
1096 | + void getHereLicensePathFinished(QDBusPendingCallWatcher *watcher); |
1097 | + |
1098 | +private: |
1099 | + Q_DISABLE_COPY(System) |
1100 | + |
1101 | + QDBusInterface *m_accounts; |
1102 | + bool m_hereEnabled; |
1103 | + QString m_hereLicensePath; |
1104 | +}; |
1105 | |
1106 | === added file 'wizard/main.cpp' |
1107 | --- wizard/main.cpp 1970-01-01 00:00:00 +0000 |
1108 | +++ wizard/main.cpp 2014-12-02 18:43:43 +0000 |
1109 | @@ -0,0 +1,93 @@ |
1110 | +/* |
1111 | + * This file is part of system-settings |
1112 | + * |
1113 | + * Copyright (C) 2014 Canonical Ltd. |
1114 | + * |
1115 | + * This program is free software: you can redistribute it and/or modify it |
1116 | + * under the terms of the GNU General Public License version 3, as published |
1117 | + * by the Free Software Foundation. |
1118 | + * |
1119 | + * This program is distributed in the hope that it will be useful, but |
1120 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1121 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1122 | + * PURPOSE. See the GNU General Public License for more details. |
1123 | + * |
1124 | + * You should have received a copy of the GNU General Public License along |
1125 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1126 | + */ |
1127 | + |
1128 | +#include <csignal> |
1129 | +#include <libintl.h> |
1130 | +#include <qpa/qplatformnativeinterface.h> |
1131 | +#include <QDebug> |
1132 | +#include <QGuiApplication> |
1133 | +#include <QLibrary> |
1134 | +#include <QObject> |
1135 | +#include <QProcess> |
1136 | +#include <QQmlContext> |
1137 | +#include <QQmlEngine> |
1138 | +#include <QQuickItem> |
1139 | +#include <QQuickView> |
1140 | +#include <QTimer> |
1141 | + |
1142 | +#include "PageList.h" |
1143 | + |
1144 | +void handleQuit() |
1145 | +{ |
1146 | + QProcess::startDetached("initctl start ubuntu-system-settings-wizard-cleanup"); |
1147 | +} |
1148 | + |
1149 | +int main(int argc, const char *argv[]) |
1150 | +{ |
1151 | + bool isMirServer = false; |
1152 | + if (qgetenv("QT_QPA_PLATFORM") == "ubuntumirclient") { |
1153 | + setenv("QT_QPA_PLATFORM", "mirserver", 1 /* overwrite */); |
1154 | + isMirServer = true; |
1155 | + } |
1156 | + |
1157 | + QGuiApplication::setApplicationName("System Settings Wizard"); |
1158 | + QGuiApplication *application = new QGuiApplication(argc, (char**)argv); |
1159 | + |
1160 | + bindtextdomain(I18N_DOMAIN, NULL); |
1161 | + textdomain(I18N_DOMAIN); |
1162 | + |
1163 | + QQuickView* view = new QQuickView(); |
1164 | + view->setResizeMode(QQuickView::SizeRootObjectToView); |
1165 | + view->setTitle("Welcome Wizard"); |
1166 | + |
1167 | + QString rootDir = qgetenv("UBUNTU_SYSTEM_SETTINGS_WIZARD_ROOT"); // for testing |
1168 | + if (rootDir.isEmpty()) |
1169 | + rootDir = WIZARD_ROOT; |
1170 | + |
1171 | + QString modulesDir = qgetenv("UBUNTU_SYSTEM_SETTINGS_WIZARD_MODULES"); // for testing |
1172 | + if (modulesDir.isEmpty()) |
1173 | + modulesDir = PLUGIN_PRIVATE_MODULE_DIR; |
1174 | + |
1175 | + if (!isMirServer) { |
1176 | + view->engine()->addImportPath(modulesDir + "/Ubuntu/SystemSettings/Wizard/NonMir"); |
1177 | + } |
1178 | + view->engine()->addImportPath(modulesDir); |
1179 | + view->engine()->addImportPath(PLUGIN_QML_DIR); |
1180 | + view->engine()->addImportPath(SHELL_PLUGINDIR); |
1181 | + |
1182 | + PageList pageList; |
1183 | + view->rootContext()->setContextProperty("pageList", &pageList); |
1184 | + view->setSource(QUrl(rootDir + "/ubuntu/settings/wizard/qml/main.qml")); |
1185 | + view->setColor("transparent"); |
1186 | + |
1187 | + QObject::connect(view->engine(), &QQmlEngine::quit, handleQuit); |
1188 | + |
1189 | + if (isMirServer) { |
1190 | + view->showFullScreen(); |
1191 | + } else { |
1192 | + view->show(); |
1193 | + } |
1194 | + |
1195 | + int result = application->exec(); |
1196 | + |
1197 | + delete view; |
1198 | + delete application; |
1199 | + return result; |
1200 | +} |
1201 | + |
1202 | +#include "main.moc" |
1203 | |
1204 | === added directory 'wizard/qml' |
1205 | === added directory 'wizard/qml/Components' |
1206 | === added file 'wizard/qml/Components/CheckableSetting.qml' |
1207 | --- wizard/qml/Components/CheckableSetting.qml 1970-01-01 00:00:00 +0000 |
1208 | +++ wizard/qml/Components/CheckableSetting.qml 2014-12-02 18:43:43 +0000 |
1209 | @@ -0,0 +1,85 @@ |
1210 | +/* |
1211 | + * Copyright (C) 2014 Canonical, Ltd. |
1212 | + * |
1213 | + * This program is free software; you can redistribute it and/or modify |
1214 | + * it under the terms of the GNU General Public License as published by |
1215 | + * the Free Software Foundation; version 3. |
1216 | + * |
1217 | + * This program is distributed in the hope that it will be useful, |
1218 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1219 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1220 | + * GNU General Public License for more details. |
1221 | + * |
1222 | + * You should have received a copy of the GNU General Public License |
1223 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1224 | + */ |
1225 | + |
1226 | +import QtQuick 2.3 |
1227 | +import QMenuModel 0.1 |
1228 | +import Ubuntu.Components 1.1 |
1229 | +import Ubuntu.Components.ListItems 1.0 as ListItem |
1230 | + |
1231 | +ListItem.Empty { |
1232 | + id: listItem |
1233 | + |
1234 | + property alias text: label.text |
1235 | + property bool checked: false |
1236 | + property real leftMargin |
1237 | + property real rightMargin |
1238 | + |
1239 | + readonly property real labelOffset: label.x |
1240 | + |
1241 | + signal linkActivated(string link) |
1242 | + |
1243 | + implicitHeight: Math.max(label.height, checkBox.height) |
1244 | + |
1245 | + Item { |
1246 | + anchors.fill: parent |
1247 | + |
1248 | + CheckBox { |
1249 | + id: checkBox |
1250 | + |
1251 | + anchors { |
1252 | + left: parent.left |
1253 | + top: parent.top |
1254 | + leftMargin: listItem.leftMargin |
1255 | + } |
1256 | + |
1257 | + Component.onCompleted: { |
1258 | + checked = listItem.checked; |
1259 | + } |
1260 | + |
1261 | + onClicked: { |
1262 | + listItem.checked = checked |
1263 | + listItem.triggered(listItem.checked) |
1264 | + } |
1265 | + |
1266 | + Connections { |
1267 | + target: listItem |
1268 | + onCheckedChanged: checkBox.checked = listItem.checked |
1269 | + } |
1270 | + |
1271 | + Connections { |
1272 | + target: listItem.__mouseArea |
1273 | + onClicked: { |
1274 | + listItem.checked = !listItem.checked |
1275 | + listItem.triggered(listItem.checked) |
1276 | + } |
1277 | + } |
1278 | + } |
1279 | + |
1280 | + Label { |
1281 | + id: label |
1282 | + anchors { |
1283 | + left: checkBox.right |
1284 | + right: parent.right |
1285 | + verticalCenter: parent.verticalCenter |
1286 | + leftMargin: units.gu(2) |
1287 | + rightMargin: listItem.rightMargin |
1288 | + } |
1289 | + wrapMode: Text.Wrap |
1290 | + linkColor: Theme.palette.normal.foregroundText |
1291 | + onLinkActivated: listItem.linkActivated(link) |
1292 | + } |
1293 | + } |
1294 | +} |
1295 | |
1296 | === added file 'wizard/qml/Components/InputMethod.qml' |
1297 | --- wizard/qml/Components/InputMethod.qml 1970-01-01 00:00:00 +0000 |
1298 | +++ wizard/qml/Components/InputMethod.qml 2014-12-02 18:43:43 +0000 |
1299 | @@ -0,0 +1,113 @@ |
1300 | +/* |
1301 | + * Copyright (C) 2014 Canonical, Ltd. |
1302 | + * |
1303 | + * This program is free software; you can redistribute it and/or modify |
1304 | + * it under the terms of the GNU General Public License as published by |
1305 | + * the Free Software Foundation; version 3. |
1306 | + * |
1307 | + * This program is distributed in the hope that it will be useful, |
1308 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1309 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1310 | + * GNU General Public License for more details. |
1311 | + * |
1312 | + * You should have received a copy of the GNU General Public License |
1313 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1314 | + */ |
1315 | + |
1316 | +import QtQuick 2.0 |
1317 | +import Unity.Application 0.1 |
1318 | +import Ubuntu.Components 0.1 |
1319 | + |
1320 | +// TODO: try to share this code with that from the unity8 shell |
1321 | + |
1322 | +Item { |
1323 | + id: root |
1324 | + |
1325 | + Connections { |
1326 | + target: SurfaceManager |
1327 | + onSurfaceCreated: { |
1328 | + if (surface.type == MirSurfaceItem.InputMethod) { |
1329 | + root.surface = surface; |
1330 | + } |
1331 | + } |
1332 | + |
1333 | + onSurfaceDestroyed: { |
1334 | + if (root.surface == surface) { |
1335 | + root.surface = null; |
1336 | + surface.parent = null; |
1337 | + } |
1338 | + if (!surface.parent) { |
1339 | + // there's no one displaying it. delete it right away |
1340 | + surface.release(); |
1341 | + } |
1342 | + } |
1343 | + } |
1344 | + |
1345 | + property var surface: null |
1346 | + |
1347 | + property int transitionDuration: UbuntuAnimation.FastDuration |
1348 | + |
1349 | + state: { |
1350 | + if (surface && surface.state != MirSurfaceItem.Minimized) { |
1351 | + return "shown"; |
1352 | + } else { |
1353 | + return "hidden"; |
1354 | + } |
1355 | + } |
1356 | + |
1357 | + states: [ |
1358 | + State { |
1359 | + name: "shown" |
1360 | + PropertyChanges { |
1361 | + target: root |
1362 | + visible: true |
1363 | + y: 0 |
1364 | + } |
1365 | + }, |
1366 | + State { |
1367 | + name: "hidden" |
1368 | + PropertyChanges { |
1369 | + target: root |
1370 | + visible: false |
1371 | + // half-way down because the vkb occupies only the lower half of the surface |
1372 | + // TODO: consider keyboard rotation |
1373 | + y: root.parent.height / 2.0 |
1374 | + } |
1375 | + } |
1376 | + ] |
1377 | + |
1378 | + transitions: [ |
1379 | + Transition { |
1380 | + from: "*"; to: "*" |
1381 | + PropertyAction { property: "visible"; value: true } |
1382 | + UbuntuNumberAnimation { property: "y"; duration: transitionDuration } |
1383 | + } |
1384 | + ] |
1385 | + |
1386 | + Connections { |
1387 | + target: surface |
1388 | + ignoreUnknownSignals: true // don't wanna spam the log when surface is null |
1389 | + onStateChanged: { |
1390 | + if (state == MirSurfaceItem.Minimized) { |
1391 | + root.hide(); |
1392 | + } else if (state == MirSurfaceItem.Maximized) { |
1393 | + root.show(); |
1394 | + } |
1395 | + } |
1396 | + } |
1397 | + |
1398 | + onSurfaceChanged: { |
1399 | + if (surface) { |
1400 | + surface.parent = root; |
1401 | + surface.anchors.fill = root; |
1402 | + } |
1403 | + } |
1404 | + |
1405 | + Component.onDestruction: { |
1406 | + if (surface) { |
1407 | + surface.parent = null; |
1408 | + surface.release(); |
1409 | + surface = null; |
1410 | + } |
1411 | + } |
1412 | +} |
1413 | |
1414 | === added file 'wizard/qml/Components/Page.qml' |
1415 | --- wizard/qml/Components/Page.qml 1970-01-01 00:00:00 +0000 |
1416 | +++ wizard/qml/Components/Page.qml 2014-12-02 18:43:43 +0000 |
1417 | @@ -0,0 +1,107 @@ |
1418 | +/* |
1419 | + * Copyright (C) 2013 Canonical, Ltd. |
1420 | + * |
1421 | + * This program is free software; you can redistribute it and/or modify |
1422 | + * it under the terms of the GNU General Public License as published by |
1423 | + * the Free Software Foundation; version 3. |
1424 | + * |
1425 | + * This program is distributed in the hope that it will be useful, |
1426 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1427 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1428 | + * GNU General Public License for more details. |
1429 | + * |
1430 | + * You should have received a copy of the GNU General Public License |
1431 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1432 | + */ |
1433 | + |
1434 | +import QtQuick 2.3 |
1435 | +import Ubuntu.Components 1.1 |
1436 | +import "." as LocalComponents |
1437 | + |
1438 | +Item { |
1439 | + readonly property real buttonMargin: units.gu(2) |
1440 | + readonly property real buttonWidth: (width - buttonMargin * 2) / 2 - |
1441 | + buttonMargin / 2 |
1442 | + readonly property real topMargin: units.gu(8) |
1443 | + readonly property real leftMargin: units.gu(2) |
1444 | + readonly property real rightMargin: units.gu(2) |
1445 | + |
1446 | + // If you want to skip a page, mark skipValid false while you figure out |
1447 | + // whether to skip, then set it to true once you've determined the value |
1448 | + // of the skip property. |
1449 | + property bool skipValid: true |
1450 | + property bool skip: false |
1451 | + |
1452 | + property bool hasBackButton: true |
1453 | + property bool customBack: false |
1454 | + property alias forwardButtonSourceComponent: forwardButton.sourceComponent |
1455 | + property alias content: contentHolder |
1456 | + |
1457 | + property string title: "" |
1458 | + |
1459 | + signal backClicked() |
1460 | + |
1461 | + visible: false |
1462 | + anchors.fill: parent |
1463 | + |
1464 | + // We want larger than even fontSize: "x-large", so we use a Text instead |
1465 | + // of a Label. |
1466 | + Text { |
1467 | + id: titleLabel |
1468 | + anchors { |
1469 | + top: parent.top |
1470 | + left: parent.left |
1471 | + right: parent.right |
1472 | + topMargin: topMargin |
1473 | + leftMargin: leftMargin |
1474 | + rightMargin: rightMargin |
1475 | + } |
1476 | + wrapMode: Text.Wrap |
1477 | + text: title |
1478 | + color: Theme.palette.normal.baseText |
1479 | + font.pixelSize: units.gu(4) |
1480 | + } |
1481 | + |
1482 | + Item { |
1483 | + id: contentHolder |
1484 | + anchors { |
1485 | + top: titleLabel.bottom |
1486 | + left: parent.left |
1487 | + right: parent.right |
1488 | + bottom: backButton.top |
1489 | + topMargin: units.gu(4) |
1490 | + leftMargin: leftMargin |
1491 | + rightMargin: rightMargin |
1492 | + bottomMargin: buttonMargin |
1493 | + } |
1494 | + } |
1495 | + |
1496 | + LocalComponents.StackButton { |
1497 | + id: backButton |
1498 | + width: buttonWidth |
1499 | + anchors { |
1500 | + left: parent.left |
1501 | + bottom: parent.bottom |
1502 | + leftMargin: buttonMargin |
1503 | + bottomMargin: buttonMargin |
1504 | + } |
1505 | + z: 1 |
1506 | + text: i18n.tr("Back") |
1507 | + visible: pageStack.depth > 1 && hasBackButton |
1508 | + backArrow: true |
1509 | + |
1510 | + onClicked: customBack ? backClicked() : pageStack.prev() |
1511 | + } |
1512 | + |
1513 | + Loader { |
1514 | + id: forwardButton |
1515 | + width: buttonWidth |
1516 | + anchors { |
1517 | + right: parent.right |
1518 | + bottom: parent.bottom |
1519 | + rightMargin: buttonMargin |
1520 | + bottomMargin: buttonMargin |
1521 | + } |
1522 | + z: 1 |
1523 | + } |
1524 | +} |
1525 | |
1526 | === added file 'wizard/qml/Components/StackButton.qml' |
1527 | --- wizard/qml/Components/StackButton.qml 1970-01-01 00:00:00 +0000 |
1528 | +++ wizard/qml/Components/StackButton.qml 2014-12-02 18:43:43 +0000 |
1529 | @@ -0,0 +1,47 @@ |
1530 | +/* |
1531 | + * Copyright (C) 2014 Canonical, Ltd. |
1532 | + * |
1533 | + * This program is free software; you can redistribute it and/or modify |
1534 | + * it under the terms of the GNU General Public License as published by |
1535 | + * the Free Software Foundation; version 3. |
1536 | + * |
1537 | + * This program is distributed in the hope that it will be useful, |
1538 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1539 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1540 | + * GNU General Public License for more details. |
1541 | + * |
1542 | + * You should have received a copy of the GNU General Public License |
1543 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1544 | + */ |
1545 | + |
1546 | +import QtQuick 2.3 |
1547 | +import Ubuntu.Components 1.1 |
1548 | + |
1549 | +AbstractButton { |
1550 | + id: stackButton |
1551 | + |
1552 | + property string text |
1553 | + |
1554 | + property bool backArrow: false |
1555 | + |
1556 | + width: label.width |
1557 | + height: label.height + units.gu(4) |
1558 | + |
1559 | + Label { |
1560 | + id: label |
1561 | + anchors.verticalCenter: parent.verticalCenter |
1562 | + anchors.left: parent.left |
1563 | + anchors.right: parent.right |
1564 | + color: enabled ? Theme.palette.selected.backgroundText : Qt.darker(Theme.palette.selected.backgroundText, 1.5) |
1565 | + text: { |
1566 | + if (backArrow) { |
1567 | + // Translators: This is the arrow for "Back" buttons |
1568 | + return i18n.tr("〈 %1".arg(stackButton.text)) |
1569 | + } else { |
1570 | + // Translators: This is the arrow for "Forward" buttons |
1571 | + return i18n.tr("%1 〉".arg(stackButton.text)) |
1572 | + } |
1573 | + } |
1574 | + horizontalAlignment: backArrow ? Text.AlignLeft : Text.AlignRight |
1575 | + } |
1576 | +} |
1577 | |
1578 | === added directory 'wizard/qml/Pages' |
1579 | === added file 'wizard/qml/Pages/10-welcome.qml' |
1580 | --- wizard/qml/Pages/10-welcome.qml 1970-01-01 00:00:00 +0000 |
1581 | +++ wizard/qml/Pages/10-welcome.qml 2014-12-02 18:43:43 +0000 |
1582 | @@ -0,0 +1,93 @@ |
1583 | +/* |
1584 | + * Copyright (C) 2013 Canonical, Ltd. |
1585 | + * |
1586 | + * This program is free software; you can redistribute it and/or modify |
1587 | + * it under the terms of the GNU General Public License as published by |
1588 | + * the Free Software Foundation; version 3. |
1589 | + * |
1590 | + * This program is distributed in the hope that it will be useful, |
1591 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1592 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1593 | + * GNU General Public License for more details. |
1594 | + * |
1595 | + * You should have received a copy of the GNU General Public License |
1596 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1597 | + */ |
1598 | + |
1599 | +import QtQuick 2.3 |
1600 | +import Ubuntu.Components 1.1 |
1601 | +import Ubuntu.Components.ListItems 0.1 |
1602 | +import Ubuntu.SystemSettings.LanguagePlugin 1.0 |
1603 | +import Ubuntu.SystemSettings.Wizard.Utils 0.1 |
1604 | +import "../Components" as LocalComponents |
1605 | + |
1606 | +LocalComponents.Page { |
1607 | + title: i18n.tr("Hi!") |
1608 | + forwardButtonSourceComponent: forwardButton |
1609 | + |
1610 | + UbuntuLanguagePlugin { |
1611 | + id: plugin |
1612 | + } |
1613 | + |
1614 | + Column { |
1615 | + id: column |
1616 | + anchors.fill: content |
1617 | + spacing: units.gu(1) |
1618 | + |
1619 | + Label { |
1620 | + id: label1 |
1621 | + anchors.left: parent.left |
1622 | + anchors.right: parent.right |
1623 | + wrapMode: Text.Wrap |
1624 | + text: i18n.tr("Welcome to your Ubuntu phone.") |
1625 | + } |
1626 | + |
1627 | + Label { |
1628 | + id: label2 |
1629 | + anchors.left: parent.left |
1630 | + anchors.right: parent.right |
1631 | + wrapMode: Text.Wrap |
1632 | + text: i18n.tr("Let’s get started.") |
1633 | + } |
1634 | + |
1635 | + Item { // spacer |
1636 | + height: units.gu(2) |
1637 | + width: units.gu(1) // needed else it will be ignored |
1638 | + } |
1639 | + |
1640 | + ComboButton { |
1641 | + id: combo |
1642 | + anchors.left: parent.left |
1643 | + anchors.right: parent.right |
1644 | + text: listview.currentItem.text |
1645 | + onClicked: expanded = !expanded |
1646 | + expandedHeight: column.height - combo.y |
1647 | + UbuntuListView { |
1648 | + id: listview |
1649 | + model: plugin.languageNames |
1650 | + currentIndex: plugin.currentLanguage |
1651 | + delegate: Standard { |
1652 | + text: modelData |
1653 | + onClicked: { |
1654 | + listview.currentIndex = index |
1655 | + combo.expanded = false |
1656 | + i18n.language = plugin.languageCodes[index] |
1657 | + i18n.domain = i18n.domain |
1658 | + } |
1659 | + } |
1660 | + } |
1661 | + } |
1662 | + } |
1663 | + |
1664 | + Component { |
1665 | + id: forwardButton |
1666 | + LocalComponents.StackButton { |
1667 | + text: i18n.tr("Continue") |
1668 | + onClicked: { |
1669 | + plugin.currentLanguage = listview.currentIndex |
1670 | + System.updateSessionLanguage() |
1671 | + pageStack.next() |
1672 | + } |
1673 | + } |
1674 | + } |
1675 | +} |
1676 | |
1677 | === added file 'wizard/qml/Pages/20-sim.qml' |
1678 | --- wizard/qml/Pages/20-sim.qml 1970-01-01 00:00:00 +0000 |
1679 | +++ wizard/qml/Pages/20-sim.qml 2014-12-02 18:43:43 +0000 |
1680 | @@ -0,0 +1,71 @@ |
1681 | +/* |
1682 | + * Copyright (C) 2013 Canonical, Ltd. |
1683 | + * |
1684 | + * This program is free software; you can redistribute it and/or modify |
1685 | + * it under the terms of the GNU General Public License as published by |
1686 | + * the Free Software Foundation; version 3. |
1687 | + * |
1688 | + * This program is distributed in the hope that it will be useful, |
1689 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1690 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1691 | + * GNU General Public License for more details. |
1692 | + * |
1693 | + * You should have received a copy of the GNU General Public License |
1694 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1695 | + */ |
1696 | + |
1697 | +import QtQuick 2.0 |
1698 | +import MeeGo.QOfono 0.2 |
1699 | +import Ubuntu.Components 0.1 |
1700 | +import "../Components" as LocalComponents |
1701 | + |
1702 | +LocalComponents.Page { |
1703 | + title: i18n.tr("Add a SIM card and restart your device") |
1704 | + forwardButtonSourceComponent: forwardButton |
1705 | + |
1706 | + // No need for skipValid, since OfonoManager does everything synchronously |
1707 | + skip: !manager.available || manager.modems.length === 0 || simManager0.present || simManager1.present |
1708 | + |
1709 | + OfonoManager { |
1710 | + id: manager |
1711 | + } |
1712 | + |
1713 | + // Ideally we would query the system more cleverly than hardcoding two |
1714 | + // modems. But we don't yet have a more clever way. :( |
1715 | + OfonoSimManager { |
1716 | + id: simManager0 |
1717 | + modemPath: manager.modems.length >= 1 ? manager.modems[0] : "" |
1718 | + } |
1719 | + |
1720 | + OfonoSimManager { |
1721 | + id: simManager1 |
1722 | + modemPath: manager.modems.length >= 2 ? manager.modems[1] : "" |
1723 | + } |
1724 | + |
1725 | + Column { |
1726 | + anchors.fill: content |
1727 | + spacing: units.gu(4) |
1728 | + |
1729 | + Label { |
1730 | + anchors.left: parent.left |
1731 | + anchors.right: parent.right |
1732 | + wrapMode: Text.Wrap |
1733 | + text: i18n.tr("Without it, you won’t be able to make calls or use text messaging.") |
1734 | + } |
1735 | + |
1736 | + Image { |
1737 | + id: image |
1738 | + source: "data/meet_ubuntu_simcard@30.png" |
1739 | + height: units.gu(6.5) |
1740 | + width: units.gu(9) |
1741 | + } |
1742 | + } |
1743 | + |
1744 | + Component { |
1745 | + id: forwardButton |
1746 | + LocalComponents.StackButton { |
1747 | + text: i18n.tr("Skip") |
1748 | + onClicked: pageStack.next() |
1749 | + } |
1750 | + } |
1751 | +} |
1752 | |
1753 | === added file 'wizard/qml/Pages/30-passwd-type.qml' |
1754 | --- wizard/qml/Pages/30-passwd-type.qml 1970-01-01 00:00:00 +0000 |
1755 | +++ wizard/qml/Pages/30-passwd-type.qml 2014-12-02 18:43:43 +0000 |
1756 | @@ -0,0 +1,119 @@ |
1757 | +/* |
1758 | + * Copyright (C) 2014 Canonical, Ltd. |
1759 | + * |
1760 | + * This program is free software; you can redistribute it and/or modify |
1761 | + * it under the terms of the GNU General Public License as published by |
1762 | + * the Free Software Foundation; version 3. |
1763 | + * |
1764 | + * This program is distributed in the hope that it will be useful, |
1765 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1766 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1767 | + * GNU General Public License for more details. |
1768 | + * |
1769 | + * You should have received a copy of the GNU General Public License |
1770 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1771 | + */ |
1772 | + |
1773 | +import QtQuick 2.3 |
1774 | +import Ubuntu.Components 1.1 |
1775 | +import Ubuntu.Components.ListItems 1.0 |
1776 | +import Ubuntu.SystemSettings.SecurityPrivacy 1.0 |
1777 | +import "../Components" as LocalComponents |
1778 | + |
1779 | +/** |
1780 | + * One quirk with this page: we don't actually set the password. We avoid |
1781 | + * doing it here because the user can come back to this page and change their |
1782 | + * answer. We don't run as root, so if we did set the password immediately, |
1783 | + * we'd need to prompt for their previous password when they came back and |
1784 | + * changed their answer. Which is silly UX. So instead, we just keep track |
1785 | + * of their choice and set the password at the end (see main.qml). |
1786 | + * Setting the password shouldn't fail, since Ubuntu Touch has loose password |
1787 | + * requirements, but we'll check what we can here. Ideally we'd be able to ask |
1788 | + * the system if a password is legal without actually setting that password. |
1789 | + */ |
1790 | + |
1791 | +LocalComponents.Page { |
1792 | + id: passwdPage |
1793 | + title: i18n.tr("Lock security") |
1794 | + forwardButtonSourceComponent: forwardButton |
1795 | + |
1796 | + function indexToMethod(index) { |
1797 | + if (index === 0) |
1798 | + return UbuntuSecurityPrivacyPanel.Swipe |
1799 | + else if (index === 1) |
1800 | + return UbuntuSecurityPrivacyPanel.Passcode |
1801 | + else |
1802 | + return UbuntuSecurityPrivacyPanel.Passphrase |
1803 | + } |
1804 | + |
1805 | + function methodToIndex(method) { |
1806 | + if (method === UbuntuSecurityPrivacyPanel.Swipe) |
1807 | + return 0 |
1808 | + else if (method === UbuntuSecurityPrivacyPanel.Passcode) |
1809 | + return 1 |
1810 | + else |
1811 | + return 2 |
1812 | + } |
1813 | + |
1814 | + Connections { |
1815 | + target: root |
1816 | + onPasswordMethodChanged: selector.selectedIndex = methodToIndex(root.passwordMethod) |
1817 | + } |
1818 | + |
1819 | + Column { |
1820 | + id: column |
1821 | + anchors.fill: content |
1822 | + spacing: units.gu(4) |
1823 | + |
1824 | + Label { |
1825 | + anchors.left: parent.left |
1826 | + anchors.right: parent.right |
1827 | + wrapMode: Text.Wrap |
1828 | + text: i18n.tr("Please select how you’d like to unlock your phone.") |
1829 | + } |
1830 | + |
1831 | + ItemSelector { |
1832 | + id: selector |
1833 | + expanded: true |
1834 | + anchors.left: parent.left |
1835 | + anchors.right: parent.right |
1836 | + |
1837 | + model: ["", "", ""] // otherwise the delegate will show the text itself and we only want subText |
1838 | + |
1839 | + selectedIndex: methodToIndex(root.passwordMethod) |
1840 | + |
1841 | + delegate: OptionSelectorDelegate { |
1842 | + // use subText because we want the text to be small, and we have no other way to control it |
1843 | + subText: { |
1844 | + var method = indexToMethod(index) |
1845 | + var name = "" |
1846 | + var desc = "" |
1847 | + if (method === UbuntuSecurityPrivacyPanel.Swipe) { |
1848 | + name = i18n.tr("Swipe") |
1849 | + desc = i18n.tr("No security") |
1850 | + } else if (method === UbuntuSecurityPrivacyPanel.Passcode) { |
1851 | + name = i18n.tr("Passcode") |
1852 | + desc = i18n.tr("4 digits only") |
1853 | + } else { |
1854 | + name = i18n.tr("Passphrase") |
1855 | + desc = i18n.tr("Numbers and letters") |
1856 | + } |
1857 | + return "<b>%1</b> (%2)".arg(name).arg(desc) |
1858 | + } |
1859 | + } |
1860 | + |
1861 | + style: Item {} |
1862 | + } |
1863 | + } |
1864 | + |
1865 | + Component { |
1866 | + id: forwardButton |
1867 | + LocalComponents.StackButton { |
1868 | + text: i18n.tr("Continue") |
1869 | + onClicked: { |
1870 | + root.passwordMethod = indexToMethod(selector.selectedIndex) |
1871 | + pageStack.load(Qt.resolvedUrl("passwd-set.qml")) |
1872 | + } |
1873 | + } |
1874 | + } |
1875 | +} |
1876 | |
1877 | === added file 'wizard/qml/Pages/40-wifi.qml' |
1878 | --- wizard/qml/Pages/40-wifi.qml 1970-01-01 00:00:00 +0000 |
1879 | +++ wizard/qml/Pages/40-wifi.qml 2014-12-02 18:43:43 +0000 |
1880 | @@ -0,0 +1,200 @@ |
1881 | +/* |
1882 | + * Copyright (C) 2013 Canonical, Ltd. |
1883 | + * |
1884 | + * This program is free software; you can redistribute it and/or modify |
1885 | + * it under the terms of the GNU General Public License as published by |
1886 | + * the Free Software Foundation; version 3. |
1887 | + * |
1888 | + * This program is distributed in the hope that it will be useful, |
1889 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1890 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1891 | + * GNU General Public License for more details. |
1892 | + * |
1893 | + * You should have received a copy of the GNU General Public License |
1894 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1895 | + */ |
1896 | + |
1897 | +import QtQuick 2.0 |
1898 | +import QMenuModel 0.1 as QMenuModel |
1899 | +import Ubuntu.Components 0.1 |
1900 | +import Ubuntu.Components.ListItems 0.1 as ListItem |
1901 | +import Ubuntu.SystemSettings.Wizard.Utils 0.1 |
1902 | +import Ubuntu.Settings.Menus 0.1 as Menus |
1903 | +import "../Components" as LocalComponents |
1904 | + |
1905 | +LocalComponents.Page { |
1906 | + id: wifiPage |
1907 | + title: i18n.tr("Connect to Wi‑Fi") |
1908 | + forwardButtonSourceComponent: forwardButton |
1909 | + |
1910 | + readonly property bool connected: mainMenu.connectedAPs === 1 |
1911 | + |
1912 | + function getExtendedProperty(object, propertyName, defaultValue) { |
1913 | + if (object && object.hasOwnProperty(propertyName)) { |
1914 | + return object[propertyName]; |
1915 | + } |
1916 | + return defaultValue; |
1917 | + } |
1918 | + |
1919 | + QMenuModel.UnityMenuModel { |
1920 | + id: menuModel |
1921 | + busName: "com.canonical.indicator.network" |
1922 | + actions: { "indicator": "/com/canonical/indicator/network" } |
1923 | + menuObjectPath: "/com/canonical/indicator/network/phone_wifi_settings" |
1924 | + } |
1925 | + |
1926 | + Component { |
1927 | + id: accessPointComponent |
1928 | + ListItem.Standard { |
1929 | + id: accessPoint |
1930 | + objectName: "accessPoint" |
1931 | + |
1932 | + property QtObject menuData: null |
1933 | + property var unityMenuModel: menuModel |
1934 | + property var extendedData: menuData && menuData.ext || undefined |
1935 | + property var strengthAction: QMenuModel.UnityMenuAction { |
1936 | + model: unityMenuModel |
1937 | + index: menuIndex |
1938 | + name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "") |
1939 | + } |
1940 | + property bool checked: menuData && menuData.isToggled || false |
1941 | + property bool secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false) |
1942 | + property bool adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false) |
1943 | + property int signalStrength: strengthAction.valid ? strengthAction.state : 0 |
1944 | + property int menuIndex: -1 |
1945 | + |
1946 | + function loadAttributes() { |
1947 | + if (!unityMenuModel || menuIndex == -1) return; |
1948 | + unityMenuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool', |
1949 | + 'x-canonical-wifi-ap-is-secure': 'bool', |
1950 | + 'x-canonical-wifi-ap-strength-action': 'string'}); |
1951 | + } |
1952 | + |
1953 | + signal activate() |
1954 | + |
1955 | + text: menuData && menuData.label || "" |
1956 | + enabled: menuData && menuData.sensitive || false |
1957 | + iconName: { |
1958 | + var imageName = "nm-signal-100"; |
1959 | + |
1960 | + if (adHoc) { |
1961 | + imageName = "nm-adhoc"; |
1962 | + } else if (signalStrength == 0) { |
1963 | + imageName = "nm-signal-00"; |
1964 | + } else if (signalStrength <= 25) { |
1965 | + imageName = "nm-signal-25"; |
1966 | + } else if (signalStrength <= 50) { |
1967 | + imageName = "nm-signal-50"; |
1968 | + } else if (signalStrength <= 75) { |
1969 | + imageName = "nm-signal-75"; |
1970 | + } |
1971 | + |
1972 | + if (secure) { |
1973 | + imageName += "-secure"; |
1974 | + } |
1975 | + return imageName; |
1976 | + } |
1977 | + iconFrame: false |
1978 | + control: CheckBox { |
1979 | + id: checkBoxActive |
1980 | + |
1981 | + onClicked: { |
1982 | + accessPoint.activate(); |
1983 | + } |
1984 | + } |
1985 | + style: Rectangle { |
1986 | + color: "#4c000000" |
1987 | + } |
1988 | + |
1989 | + Component.onCompleted: { |
1990 | + loadAttributes(); |
1991 | + } |
1992 | + onUnityMenuModelChanged: { |
1993 | + loadAttributes(); |
1994 | + } |
1995 | + onMenuIndexChanged: { |
1996 | + loadAttributes(); |
1997 | + } |
1998 | + onCheckedChanged: { |
1999 | + // Can't rely on binding. Checked is assigned on click. |
2000 | + checkBoxActive.checked = checked; |
2001 | + if (checked) { |
2002 | + mainMenu.connectedAPs++ |
2003 | + } else { |
2004 | + mainMenu.connectedAPs-- |
2005 | + } |
2006 | + } |
2007 | + onActivate: unityMenuModel.activate(menuIndex); |
2008 | + } |
2009 | + } |
2010 | + |
2011 | + Column { |
2012 | + id: column |
2013 | + spacing: units.gu(2) |
2014 | + anchors.top: content.top |
2015 | + anchors.bottom: content.bottom |
2016 | + anchors.left: wifiPage.left |
2017 | + anchors.right: wifiPage.right |
2018 | + |
2019 | + Label { |
2020 | + id: label |
2021 | + anchors.left: parent.left |
2022 | + anchors.leftMargin: leftMargin |
2023 | + anchors.right: parent.right |
2024 | + anchors.rightMargin: rightMargin |
2025 | + fontSize: "small" |
2026 | + text: mainMenu.count > 0 ? i18n.tr("Available networks…") |
2027 | + : i18n.tr("No available networks.") |
2028 | + } |
2029 | + |
2030 | + Flickable { |
2031 | + anchors.left: parent.left |
2032 | + anchors.right: parent.right |
2033 | + height: column.height - label.height - column.spacing |
2034 | + contentHeight: contentItem.childrenRect.height |
2035 | + clip: true |
2036 | + flickDeceleration: 1500 * units.gridUnit / 8 |
2037 | + maximumFlickVelocity: 2500 * units.gridUnit / 8 |
2038 | + boundsBehavior: (contentHeight > height) ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds |
2039 | + |
2040 | + Column { |
2041 | + anchors.left: parent.left |
2042 | + anchors.right: parent.right |
2043 | + |
2044 | + Repeater { |
2045 | + id: mainMenu |
2046 | + |
2047 | + // FIXME Check connection better https://bugs.launchpad.net/indicator-network/+bug/1349371 |
2048 | + property int connectedAPs: 0 |
2049 | + |
2050 | + model: menuModel |
2051 | + |
2052 | + delegate: Loader { |
2053 | + id: loader |
2054 | + |
2055 | + readonly property bool isAccessPoint: model.type === "unity.widgets.systemsettings.tablet.accesspoint" |
2056 | + |
2057 | + anchors.left: parent.left |
2058 | + anchors.right: parent.right |
2059 | + height: isAccessPoint ? units.gu(6) : 0 |
2060 | + asynchronous: true |
2061 | + sourceComponent: isAccessPoint ? accessPointComponent : null |
2062 | + |
2063 | + onLoaded: { |
2064 | + item.menuData = Qt.binding(function() { return model; }); |
2065 | + item.menuIndex = Qt.binding(function() { return index; }); |
2066 | + } |
2067 | + } |
2068 | + } |
2069 | + } |
2070 | + } |
2071 | + } |
2072 | + |
2073 | + Component { |
2074 | + id: forwardButton |
2075 | + LocalComponents.StackButton { |
2076 | + text: (connected || mainMenu.count === 0) ? i18n.tr("Continue") : i18n.tr("Skip") |
2077 | + onClicked: pageStack.next() |
2078 | + } |
2079 | + } |
2080 | +} |
2081 | |
2082 | === added file 'wizard/qml/Pages/50-location.qml' |
2083 | --- wizard/qml/Pages/50-location.qml 1970-01-01 00:00:00 +0000 |
2084 | +++ wizard/qml/Pages/50-location.qml 2014-12-02 18:43:43 +0000 |
2085 | @@ -0,0 +1,149 @@ |
2086 | +/* |
2087 | + * Copyright (C) 2013,2014 Canonical, Ltd. |
2088 | + * |
2089 | + * This program is free software; you can redistribute it and/or modify |
2090 | + * it under the terms of the GNU General Public License as published by |
2091 | + * the Free Software Foundation; version 3. |
2092 | + * |
2093 | + * This program is distributed in the hope that it will be useful, |
2094 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2095 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2096 | + * GNU General Public License for more details. |
2097 | + * |
2098 | + * You should have received a copy of the GNU General Public License |
2099 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2100 | + */ |
2101 | + |
2102 | +import QtQuick 2.3 |
2103 | +import QMenuModel 0.1 as QMenuModel |
2104 | +import Qt.labs.folderlistmodel 2.1 |
2105 | +import Ubuntu.Components 1.1 |
2106 | +import Ubuntu.SystemSettings.Wizard.Utils 0.1 |
2107 | +import "../Components" as LocalComponents |
2108 | + |
2109 | +LocalComponents.Page { |
2110 | + title: i18n.tr("Location") |
2111 | + forwardButtonSourceComponent: forwardButton |
2112 | + |
2113 | + property bool pathSet: System.hereLicensePath !== " " // single space means it's unassigned |
2114 | + property bool countSet: false |
2115 | + skipValid: pathSet && (System.hereLicensePath === "" || countSet) |
2116 | + skip: skipValid && (System.hereLicensePath === "" || termsModel.count === 0) |
2117 | + |
2118 | + Connections { |
2119 | + target: termsModel |
2120 | + onCountChanged: if (pathSet) countSet = true |
2121 | + } |
2122 | + |
2123 | + FolderListModel { |
2124 | + id: termsModel |
2125 | + folder: System.hereLicensePath |
2126 | + nameFilters: ["*.html"] |
2127 | + showDirs: false |
2128 | + showOnlyReadable: true |
2129 | + } |
2130 | + |
2131 | + QMenuModel.QDBusActionGroup { |
2132 | + id: locationActionGroup |
2133 | + busType: QMenuModel.DBus.SessionBus |
2134 | + busName: "com.canonical.indicator.location" |
2135 | + objectPath: "/com/canonical/indicator/location" |
2136 | + property variant location: action("location-detection-enabled") |
2137 | + property variant gps: action("gps-detection-enabled") |
2138 | + Component.onCompleted: start() |
2139 | + } |
2140 | + |
2141 | + Column { |
2142 | + id: column |
2143 | + anchors.fill: content |
2144 | + spacing: units.gu(3) |
2145 | + |
2146 | + Label { |
2147 | + anchors.left: parent.left |
2148 | + anchors.right: parent.right |
2149 | + wrapMode: Text.Wrap |
2150 | + text: i18n.tr("Let the phone detect your location:") |
2151 | + } |
2152 | + |
2153 | + LocalComponents.CheckableSetting { |
2154 | + id: gpsCheck |
2155 | + showDivider: false |
2156 | + text: i18n.tr("Using GPS only (less accurate)") |
2157 | + onTriggered: { |
2158 | + gpsCheck.checked = true; |
2159 | + hereCheck.checked = false; |
2160 | + nopeCheck.checked = false; |
2161 | + } |
2162 | + } |
2163 | + |
2164 | + Column { |
2165 | + anchors.left: parent.left |
2166 | + anchors.right: parent.right |
2167 | + height: childrenRect.height |
2168 | + |
2169 | + LocalComponents.CheckableSetting { |
2170 | + id: hereCheck |
2171 | + showDivider: false |
2172 | + text: i18n.tr("Using GPS, anonymized Wi-Fi and cellular network info (recommended)") |
2173 | + checked: true |
2174 | + onTriggered: { |
2175 | + gpsCheck.checked = false; |
2176 | + hereCheck.checked = true; |
2177 | + nopeCheck.checked = false; |
2178 | + } |
2179 | + } |
2180 | + |
2181 | + Label { |
2182 | + anchors.left: parent.left |
2183 | + anchors.leftMargin: hereCheck.labelOffset |
2184 | + anchors.right: parent.right |
2185 | + wrapMode: Text.Wrap |
2186 | + linkColor: Theme.palette.normal.foregroundText |
2187 | + // TRANSLATORS: HERE is a trademark for Nokia's location service, you probably shouldn't translate it |
2188 | + text: i18n.tr("By selecting this option you agree to the Nokia HERE <a href='#'>terms and conditions</a>.") |
2189 | + onLinkActivated: pageStack.load(Qt.resolvedUrl("here-terms.qml")) |
2190 | + } |
2191 | + } |
2192 | + |
2193 | + LocalComponents.CheckableSetting { |
2194 | + id: nopeCheck |
2195 | + showDivider: false |
2196 | + text: i18n.tr("Not at all") |
2197 | + onTriggered: { |
2198 | + gpsCheck.checked = false; |
2199 | + hereCheck.checked = false; |
2200 | + nopeCheck.checked = true; |
2201 | + } |
2202 | + } |
2203 | + |
2204 | + Label { |
2205 | + anchors.left: parent.left |
2206 | + anchors.right: parent.right |
2207 | + wrapMode: Text.Wrap |
2208 | + text: i18n.tr("You can change your mind later in <b>System Settings</b>.") |
2209 | + } |
2210 | + } |
2211 | + |
2212 | + Component { |
2213 | + id: forwardButton |
2214 | + LocalComponents.StackButton { |
2215 | + text: i18n.tr("Continue") |
2216 | + onClicked: { |
2217 | + var locationOn = gpsCheck.checked || hereCheck.checked; |
2218 | + var gpsOn = gpsCheck.checked || hereCheck.checked; |
2219 | + var hereOn = hereCheck.checked; |
2220 | + |
2221 | + // location service doesn't currently listen to updateState |
2222 | + // requests, so we activate the actions if needed. |
2223 | + if (locationActionGroup.location.state != locationOn) { |
2224 | + locationActionGroup.location.activate(); |
2225 | + } |
2226 | + if (locationActionGroup.gps.state != gpsOn) { |
2227 | + locationActionGroup.gps.activate(); |
2228 | + } |
2229 | + System.hereEnabled = hereOn; |
2230 | + pageStack.next() |
2231 | + } |
2232 | + } |
2233 | + } |
2234 | +} |
2235 | |
2236 | === added file 'wizard/qml/Pages/60-reporting.qml' |
2237 | --- wizard/qml/Pages/60-reporting.qml 1970-01-01 00:00:00 +0000 |
2238 | +++ wizard/qml/Pages/60-reporting.qml 2014-12-02 18:43:43 +0000 |
2239 | @@ -0,0 +1,52 @@ |
2240 | +/* |
2241 | + * Copyright (C) 2013,2014 Canonical, Ltd. |
2242 | + * |
2243 | + * This program is free software; you can redistribute it and/or modify |
2244 | + * it under the terms of the GNU General Public License as published by |
2245 | + * the Free Software Foundation; version 3. |
2246 | + * |
2247 | + * This program is distributed in the hope that it will be useful, |
2248 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2249 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2250 | + * GNU General Public License for more details. |
2251 | + * |
2252 | + * You should have received a copy of the GNU General Public License |
2253 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2254 | + */ |
2255 | + |
2256 | +import QtQuick 2.0 |
2257 | +import Ubuntu.Components 0.1 |
2258 | +import "../Components" as LocalComponents |
2259 | + |
2260 | +LocalComponents.Page { |
2261 | + title: i18n.tr("Improving your experience") |
2262 | + forwardButtonSourceComponent: forwardButton |
2263 | + |
2264 | + Column { |
2265 | + id: column |
2266 | + anchors.fill: content |
2267 | + spacing: units.gu(2) |
2268 | + |
2269 | + Label { |
2270 | + anchors.left: parent.left |
2271 | + anchors.right: parent.right |
2272 | + wrapMode: Text.Wrap |
2273 | + text: i18n.tr("Your phone is set up to automatically report errors to Canonical and its partners, the makers of the operating system.") |
2274 | + } |
2275 | + |
2276 | + Label { |
2277 | + anchors.left: parent.left |
2278 | + anchors.right: parent.right |
2279 | + wrapMode: Text.Wrap |
2280 | + text: i18n.tr("This can be disabled in <b>System Settings</b> under <b>Security & Privacy</b>") |
2281 | + } |
2282 | + } |
2283 | + |
2284 | + Component { |
2285 | + id: forwardButton |
2286 | + LocalComponents.StackButton { |
2287 | + text: i18n.tr("Continue") |
2288 | + onClicked: pageStack.next() |
2289 | + } |
2290 | + } |
2291 | +} |
2292 | |
2293 | === added file 'wizard/qml/Pages/80-finished.qml' |
2294 | --- wizard/qml/Pages/80-finished.qml 1970-01-01 00:00:00 +0000 |
2295 | +++ wizard/qml/Pages/80-finished.qml 2014-12-02 18:43:43 +0000 |
2296 | @@ -0,0 +1,55 @@ |
2297 | +/* |
2298 | + * Copyright (C) 2013,2014 Canonical, Ltd. |
2299 | + * |
2300 | + * This program is free software; you can redistribute it and/or modify |
2301 | + * it under the terms of the GNU General Public License as published by |
2302 | + * the Free Software Foundation; version 3. |
2303 | + * |
2304 | + * This program is distributed in the hope that it will be useful, |
2305 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2306 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2307 | + * GNU General Public License for more details. |
2308 | + * |
2309 | + * You should have received a copy of the GNU General Public License |
2310 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2311 | + */ |
2312 | + |
2313 | +import QtQuick 2.0 |
2314 | +import Ubuntu.Components 0.1 |
2315 | +import "../Components" as LocalComponents |
2316 | + |
2317 | +LocalComponents.Page { |
2318 | + title: i18n.tr("All done") |
2319 | + forwardButtonSourceComponent: forwardButton |
2320 | + hasBackButton: false |
2321 | + |
2322 | + Column { |
2323 | + id: column |
2324 | + anchors.fill: content |
2325 | + spacing: units.gu(1) |
2326 | + |
2327 | + Label { |
2328 | + anchors.left: parent.left |
2329 | + anchors.right: parent.right |
2330 | + wrapMode: Text.Wrap |
2331 | + fontSize: "large" |
2332 | + font.bold: true |
2333 | + text: i18n.tr("Nice work!") |
2334 | + } |
2335 | + |
2336 | + Label { |
2337 | + anchors.left: parent.left |
2338 | + anchors.right: parent.right |
2339 | + wrapMode: Text.Wrap |
2340 | + text: i18n.tr("Your phone is now ready to use.") |
2341 | + } |
2342 | + } |
2343 | + |
2344 | + Component { |
2345 | + id: forwardButton |
2346 | + LocalComponents.StackButton { |
2347 | + text: i18n.tr("Finish") |
2348 | + onClicked: root.quitWizard() |
2349 | + } |
2350 | + } |
2351 | +} |
2352 | |
2353 | === added directory 'wizard/qml/Pages/data' |
2354 | === added file 'wizard/qml/Pages/data/meet_ubuntu_simcard@30.png' |
2355 | Binary files wizard/qml/Pages/data/meet_ubuntu_simcard@30.png 1970-01-01 00:00:00 +0000 and wizard/qml/Pages/data/meet_ubuntu_simcard@30.png 2014-12-02 18:43:43 +0000 differ |
2356 | === added file 'wizard/qml/Pages/here-terms.qml' |
2357 | --- wizard/qml/Pages/here-terms.qml 1970-01-01 00:00:00 +0000 |
2358 | +++ wizard/qml/Pages/here-terms.qml 2014-12-02 18:43:43 +0000 |
2359 | @@ -0,0 +1,117 @@ |
2360 | +/* |
2361 | + * Copyright (C) 2014 Canonical, Ltd. |
2362 | + * |
2363 | + * This program is free software; you can redistribute it and/or modify |
2364 | + * it under the terms of the GNU General Public License as published by |
2365 | + * the Free Software Foundation; version 3. |
2366 | + * |
2367 | + * This program is distributed in the hope that it will be useful, |
2368 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2369 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2370 | + * GNU General Public License for more details. |
2371 | + * |
2372 | + * You should have received a copy of the GNU General Public License |
2373 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2374 | + */ |
2375 | + |
2376 | +import QtQuick 2.3 |
2377 | +import Qt.labs.folderlistmodel 2.1 |
2378 | +import Ubuntu.Components 1.1 |
2379 | +import Ubuntu.SystemSettings.Wizard.Utils 0.1 |
2380 | +import Ubuntu.Web 0.2 |
2381 | +import "../Components" as LocalComponents |
2382 | + |
2383 | +LocalComponents.Page { |
2384 | + title: i18n.tr("Terms & Conditions") |
2385 | + customBack: true |
2386 | + |
2387 | + FolderListModel { |
2388 | + id: termsModel |
2389 | + folder: System.hereLicensePath |
2390 | + nameFilters: ["*.html"] |
2391 | + showDirs: false |
2392 | + showOnlyReadable: true |
2393 | + onCountChanged: loadFileContent() |
2394 | + } |
2395 | + |
2396 | + function makeFileName(lang, country) { |
2397 | + return lang + "_" + country + ".html" |
2398 | + } |
2399 | + |
2400 | + function defaultCountryForLanguage(lang) { |
2401 | + if (lang === "da") return "DK" |
2402 | + if (lang === "en") return "US" |
2403 | + if (lang === "ko") return "KR" |
2404 | + if (lang === "zh") return "CN" |
2405 | + return lang.toUpperCase() |
2406 | + } |
2407 | + |
2408 | + function determineFileName() { |
2409 | + var codes = i18n.language.split(".")[0].split("_") |
2410 | + var defaultCountry = defaultCountryForLanguage(codes[0]) |
2411 | + if (codes.count === 1) |
2412 | + codes = [codes[0], defaultCountry] |
2413 | + var perfectMatch = makeFileName(codes[0], codes[1]) |
2414 | + var nearMatch = makeFileName(codes[0], defaultCountry) |
2415 | + var nearMatchExists = false |
2416 | + |
2417 | + for (var i = 0; i < termsModel.count; i++) { |
2418 | + var fileName = termsModel.get(i, "fileName") |
2419 | + if (fileName == perfectMatch) { |
2420 | + return perfectMatch |
2421 | + } else if (fileName == nearMatch) { |
2422 | + nearMatchExists = true |
2423 | + } |
2424 | + } |
2425 | + |
2426 | + if (nearMatchExists) { |
2427 | + return nearMatch |
2428 | + } else { |
2429 | + return makeFileName("en", "US") |
2430 | + } |
2431 | + } |
2432 | + |
2433 | + function loadFileContent() { |
2434 | + var xhr = new XMLHttpRequest |
2435 | + xhr.open("GET", System.hereLicensePath + "/" + determineFileName()) |
2436 | + xhr.onreadystatechange = function() { |
2437 | + if (xhr.readyState == XMLHttpRequest.DONE) { |
2438 | + termsLabel.text = xhr.responseText |
2439 | + } |
2440 | + } |
2441 | + xhr.send() |
2442 | + } |
2443 | + |
2444 | + onBackClicked: { |
2445 | + if (webview.visible) { |
2446 | + termsLabel.visible = true |
2447 | + } else { |
2448 | + pageStack.prev() |
2449 | + } |
2450 | + } |
2451 | + |
2452 | + Column { |
2453 | + id: column |
2454 | + anchors.fill: content |
2455 | + |
2456 | + Label { |
2457 | + id: termsLabel |
2458 | + anchors.left: parent.left |
2459 | + anchors.right: parent.right |
2460 | + wrapMode: Text.Wrap |
2461 | + linkColor: Theme.palette.normal.foregroundText |
2462 | + onLinkActivated: { |
2463 | + webview.url = link |
2464 | + termsLabel.visible = false |
2465 | + } |
2466 | + } |
2467 | + |
2468 | + WebView { |
2469 | + id: webview |
2470 | + anchors.left: parent.left |
2471 | + anchors.right: parent.right |
2472 | + height: parent.height |
2473 | + visible: !termsLabel.visible |
2474 | + } |
2475 | + } |
2476 | +} |
2477 | |
2478 | === added file 'wizard/qml/Pages/passwd-confirm.qml' |
2479 | --- wizard/qml/Pages/passwd-confirm.qml 1970-01-01 00:00:00 +0000 |
2480 | +++ wizard/qml/Pages/passwd-confirm.qml 2014-12-02 18:43:43 +0000 |
2481 | @@ -0,0 +1,85 @@ |
2482 | +/* |
2483 | + * Copyright (C) 2014 Canonical, Ltd. |
2484 | + * |
2485 | + * This program is free software; you can redistribute it and/or modify |
2486 | + * it under the terms of the GNU General Public License as published by |
2487 | + * the Free Software Foundation; version 3. |
2488 | + * |
2489 | + * This program is distributed in the hope that it will be useful, |
2490 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2491 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2492 | + * GNU General Public License for more details. |
2493 | + * |
2494 | + * You should have received a copy of the GNU General Public License |
2495 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2496 | + */ |
2497 | + |
2498 | +import QtQuick 2.3 |
2499 | +import Ubuntu.Components 1.1 |
2500 | +import Ubuntu.SystemSettings.SecurityPrivacy 1.0 |
2501 | +import "../Components" as LocalComponents |
2502 | +import "file:///usr/share/unity8/Components" as UnityComponents |
2503 | + |
2504 | +/** |
2505 | + * See the main passwd-type page for an explanation of why we don't actually |
2506 | + * directly set the password here. |
2507 | + */ |
2508 | + |
2509 | +LocalComponents.Page { |
2510 | + id: passwdSetPage |
2511 | + forwardButtonSourceComponent: forwardButton |
2512 | + |
2513 | + skip: root.passwordMethod === UbuntuSecurityPrivacyPanel.Swipe |
2514 | + |
2515 | + // If we are entering this page, clear any saved password and get focus |
2516 | + onEnabledChanged: if (enabled) lockscreen.clear(false) |
2517 | + |
2518 | + UnityComponents.Lockscreen { |
2519 | + id: lockscreen |
2520 | + anchors { |
2521 | + fill: parent |
2522 | + topMargin: topMargin |
2523 | + leftMargin: leftMargin |
2524 | + rightMargin: rightMargin |
2525 | + bottomMargin: buttonMargin |
2526 | + } |
2527 | + |
2528 | + infoText: root.passwordMethod === UbuntuSecurityPrivacyPanel.Passphrase ? |
2529 | + i18n.tr("Confirm passphrase") : |
2530 | + i18n.tr("Confirm passcode") |
2531 | + |
2532 | + errorText: root.passwordMethod === UbuntuSecurityPrivacyPanel.Passphrase ? |
2533 | + i18n.tr("Sorry, incorrect passphrase.") + "\n" + i18n.tr("Please try again.") : |
2534 | + i18n.tr("Sorry, incorrect passcode.") + "\n" + i18n.tr("Please try again.") |
2535 | + |
2536 | + showEmergencyCallButton: false |
2537 | + showCancelButton: false |
2538 | + alphaNumeric: root.passwordMethod === UbuntuSecurityPrivacyPanel.Passphrase |
2539 | + minPinLength: 4 |
2540 | + maxPinLength: 4 |
2541 | + |
2542 | + onEntered: { |
2543 | + if (passphrase === root.password) { |
2544 | + confirmTimer.start() |
2545 | + } else { |
2546 | + clear(true) |
2547 | + } |
2548 | + } |
2549 | + |
2550 | + Timer { |
2551 | + id: confirmTimer |
2552 | + interval: UbuntuAnimation.SnapDuration |
2553 | + onTriggered: pageStack.next() |
2554 | + } |
2555 | + } |
2556 | + |
2557 | + Component { |
2558 | + id: forwardButton |
2559 | + LocalComponents.StackButton { |
2560 | + visible: root.passwordMethod === UbuntuSecurityPrivacyPanel.Passphrase |
2561 | + enabled: root.password === lockscreen.passphrase |
2562 | + text: i18n.tr("Continue") |
2563 | + onClicked: pageStack.next() |
2564 | + } |
2565 | + } |
2566 | +} |
2567 | |
2568 | === added file 'wizard/qml/Pages/passwd-set.qml' |
2569 | --- wizard/qml/Pages/passwd-set.qml 1970-01-01 00:00:00 +0000 |
2570 | +++ wizard/qml/Pages/passwd-set.qml 2014-12-02 18:43:43 +0000 |
2571 | @@ -0,0 +1,93 @@ |
2572 | +/* |
2573 | + * Copyright (C) 2014 Canonical, Ltd. |
2574 | + * |
2575 | + * This program is free software; you can redistribute it and/or modify |
2576 | + * it under the terms of the GNU General Public License as published by |
2577 | + * the Free Software Foundation; version 3. |
2578 | + * |
2579 | + * This program is distributed in the hope that it will be useful, |
2580 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2581 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2582 | + * GNU General Public License for more details. |
2583 | + * |
2584 | + * You should have received a copy of the GNU General Public License |
2585 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2586 | + */ |
2587 | + |
2588 | +import QtQuick 2.3 |
2589 | +import Ubuntu.Components 1.1 |
2590 | +import Ubuntu.SystemSettings.SecurityPrivacy 1.0 |
2591 | +import "../Components" as LocalComponents |
2592 | +import "file:///usr/share/unity8/Components" as UnityComponents |
2593 | + |
2594 | +/** |
2595 | + * See the main passwd-type page for an explanation of why we don't actually |
2596 | + * directly set the password here. |
2597 | + */ |
2598 | + |
2599 | +LocalComponents.Page { |
2600 | + id: passwdSetPage |
2601 | + forwardButtonSourceComponent: forwardButton |
2602 | + |
2603 | + skip: root.passwordMethod === UbuntuSecurityPrivacyPanel.Swipe |
2604 | + |
2605 | + // If we are entering this page, clear any saved password and get focus |
2606 | + onEnabledChanged: if (enabled) lockscreen.clear(false) |
2607 | + |
2608 | + function confirm() { |
2609 | + root.password = lockscreen.passphrase; |
2610 | + confirmTimer.start() |
2611 | + } |
2612 | + |
2613 | + Timer { |
2614 | + id: confirmTimer |
2615 | + interval: UbuntuAnimation.SnapDuration |
2616 | + onTriggered: pageStack.load(Qt.resolvedUrl("passwd-confirm.qml")); |
2617 | + } |
2618 | + |
2619 | + UnityComponents.Lockscreen { |
2620 | + id: lockscreen |
2621 | + anchors { |
2622 | + fill: parent |
2623 | + topMargin: topMargin |
2624 | + leftMargin: leftMargin |
2625 | + rightMargin: rightMargin |
2626 | + bottomMargin: buttonMargin |
2627 | + } |
2628 | + |
2629 | + infoText: root.passwordMethod === UbuntuSecurityPrivacyPanel.Passphrase ? |
2630 | + i18n.tr("Enter passphrase") : |
2631 | + i18n.tr("Choose your passcode") |
2632 | + |
2633 | + // Note that the number four comes from PAM settings, |
2634 | + // which we don't have a good way to interrogate. We |
2635 | + // only do this matching instead of PAM because we want |
2636 | + // to set the password via PAM in a different place |
2637 | + // than this page. See comments at top of passwd-type file. |
2638 | + errorText: i18n.tr("Passphrase must be 4 characters long") |
2639 | + |
2640 | + showEmergencyCallButton: false |
2641 | + showCancelButton: false |
2642 | + alphaNumeric: root.passwordMethod === UbuntuSecurityPrivacyPanel.Passphrase |
2643 | + minPinLength: 4 |
2644 | + maxPinLength: 4 |
2645 | + |
2646 | + onEntered: { |
2647 | + if (passphrase.length >= 4) { |
2648 | + passwdSetPage.confirm(); |
2649 | + } else { |
2650 | + lockscreen.clear(true) |
2651 | + } |
2652 | + } |
2653 | + } |
2654 | + |
2655 | + Component { |
2656 | + id: forwardButton |
2657 | + LocalComponents.StackButton { |
2658 | + visible: root.passwordMethod === UbuntuSecurityPrivacyPanel.Passphrase |
2659 | + enabled: lockscreen.passphrase.length >= 4 |
2660 | + text: i18n.tr("Continue") |
2661 | + onClicked: passwdSetPage.confirm() |
2662 | + } |
2663 | + } |
2664 | +} |
2665 | |
2666 | === added file 'wizard/qml/main.qml' |
2667 | --- wizard/qml/main.qml 1970-01-01 00:00:00 +0000 |
2668 | +++ wizard/qml/main.qml 2014-12-02 18:43:43 +0000 |
2669 | @@ -0,0 +1,246 @@ |
2670 | +/* |
2671 | + * Copyright (C) 2013 Canonical, Ltd. |
2672 | + * |
2673 | + * This program is free software; you can redistribute it and/or modify |
2674 | + * it under the terms of the GNU General Public License as published by |
2675 | + * the Free Software Foundation; version 3. |
2676 | + * |
2677 | + * This program is distributed in the hope that it will be useful, |
2678 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2679 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2680 | + * GNU General Public License for more details. |
2681 | + * |
2682 | + * You should have received a copy of the GNU General Public License |
2683 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2684 | + */ |
2685 | + |
2686 | +import QtQuick 2.3 |
2687 | +import GSettings 1.0 |
2688 | +import Ubuntu.Components 1.1 |
2689 | +import Ubuntu.SystemSettings.SecurityPrivacy 1.0 |
2690 | +import Unity.Application 0.1 |
2691 | +import Unity.Notifications 1.0 as NotificationBackend |
2692 | +import Unity.Session 0.1 |
2693 | +import "Components" |
2694 | +import "file:///usr/share/unity8/Notifications" as Notifications // FIXME This should become a module or go away |
2695 | +import "file:///usr/share/unity8/Components" as UnityComponents |
2696 | + |
2697 | +Item { |
2698 | + id: root |
2699 | + width: units.gu(40) |
2700 | + height: units.gu(71) |
2701 | + focus: true |
2702 | + |
2703 | + // These should be set by a security page and we apply the settings when |
2704 | + // the user exits the wizard. |
2705 | + property int passwordMethod: UbuntuSecurityPrivacyPanel.Passcode |
2706 | + property string password: "" |
2707 | + |
2708 | + Component.onCompleted: { |
2709 | + Theme.name = "Ubuntu.Components.Themes.SuruGradient" |
2710 | + // A visible selected background looks bad in ListItem widgets with our theme |
2711 | + Theme.palette.selected.background = "#00000000" |
2712 | + i18n.domain = "unity8" |
2713 | + } |
2714 | + |
2715 | + UbuntuSecurityPrivacyPanel { |
2716 | + id: securityPrivacy |
2717 | + } |
2718 | + |
2719 | + function quitWizard() { |
2720 | + // Immediately go to black to give quick feedback |
2721 | + blackCover.visible = true |
2722 | + |
2723 | + var errorMsg = securityPrivacy.setSecurity("", password, passwordMethod) |
2724 | + if (errorMsg !== "") { |
2725 | + // Ignore (but log) any errors, since we're past where the user set |
2726 | + // the method. Worst case, we just leave the user with a swipe |
2727 | + // security method and they fix it in the system settings. |
2728 | + console.log("Error setting security method:", errorMsg) |
2729 | + } |
2730 | + |
2731 | + Qt.quit() |
2732 | + } |
2733 | + |
2734 | + // This is just a little screen to immediately go to black once the wizard |
2735 | + // is done, to give quick feedback to the user. |
2736 | + Rectangle { |
2737 | + id: blackCover |
2738 | + color: "#000000" |
2739 | + anchors.fill: parent |
2740 | + z: 1 |
2741 | + visible: false |
2742 | + } |
2743 | + |
2744 | + MainView { |
2745 | + anchors.fill: parent |
2746 | + headerColor: "#57365E" |
2747 | + backgroundColor: "#A55263" |
2748 | + footerColor: "#D75669" |
2749 | + anchorToKeyboard: true |
2750 | + useDeprecatedToolbar: false |
2751 | + |
2752 | + GSettings { |
2753 | + id: background |
2754 | + schema.id: "org.gnome.desktop.background" |
2755 | + } |
2756 | + |
2757 | + Image { |
2758 | + id: image |
2759 | + // Use x/y/height/width instead of anchors so that we don't adjust |
2760 | + // the image when the OSK appears. |
2761 | + x: 0 |
2762 | + y: 0 |
2763 | + height: root.height |
2764 | + width: root.width |
2765 | + source: background.pictureUri |
2766 | + fillMode: Image.PreserveAspectCrop |
2767 | + visible: status === Image.Ready |
2768 | + } |
2769 | + |
2770 | + PageStack { |
2771 | + id: pageStack |
2772 | + |
2773 | + function next() { |
2774 | + // If we've opened any extra (non-main) pages, pop them before |
2775 | + // continuing so back button returns to the previous main page. |
2776 | + while (pageList.index < pageStack.depth - 1) |
2777 | + pop() |
2778 | + load(pageList.next()) |
2779 | + } |
2780 | + |
2781 | + function prev() { |
2782 | + if (pageList.index >= pageStack.depth - 1) |
2783 | + pageList.prev() // update pageList.index, but not for extra pages |
2784 | + pop() |
2785 | + if (!currentPage || currentPage.opacity === 0) { // undo skipped pages |
2786 | + prev() |
2787 | + } else { |
2788 | + currentPage.enabled = true |
2789 | + } |
2790 | + } |
2791 | + |
2792 | + function load(path) { |
2793 | + if (currentPage) { |
2794 | + currentPage.enabled = false |
2795 | + } |
2796 | + |
2797 | + // First load it invisible, check that we should actually use |
2798 | + // this page, and either skip it or continue. |
2799 | + push(path, {"opacity": 0, "enabled": false}) |
2800 | + |
2801 | + // Check for immediate skip or not. We may have to wait for |
2802 | + // skipValid to be assigned (see Connections object below) |
2803 | + _checkSkip() |
2804 | + } |
2805 | + |
2806 | + function _checkSkip() { |
2807 | + if (!currentPage) { // may have had a parse error |
2808 | + next() |
2809 | + } else if (currentPage.skipValid) { |
2810 | + if (currentPage.skip) { |
2811 | + next() |
2812 | + } else { |
2813 | + currentPage.opacity = 1 |
2814 | + currentPage.enabled = true |
2815 | + } |
2816 | + } |
2817 | + } |
2818 | + |
2819 | + Connections { |
2820 | + target: pageStack.currentPage |
2821 | + onSkipValidChanged: pageStack._checkSkip() |
2822 | + } |
2823 | + |
2824 | + Component.onCompleted: next() |
2825 | + } |
2826 | + } |
2827 | + |
2828 | + Rectangle { |
2829 | + id: modalNotificationBackground |
2830 | + visible: notifications.useModal && (notifications.state == "narrow") |
2831 | + anchors.fill: parent |
2832 | + color: "#80000000" |
2833 | + |
2834 | + MouseArea { |
2835 | + anchors.fill: parent |
2836 | + } |
2837 | + } |
2838 | + |
2839 | + InputMethod { |
2840 | + anchors.fill: parent |
2841 | + } |
2842 | + |
2843 | + Notifications.Notifications { |
2844 | + id: notifications |
2845 | + model: NotificationBackend.Model |
2846 | + margin: units.gu(1) |
2847 | + anchors { |
2848 | + top: parent.top |
2849 | + right: parent.right |
2850 | + bottom: parent.bottom |
2851 | + } |
2852 | + states: [ |
2853 | + State { |
2854 | + name: "narrow" |
2855 | + when: parent.width <= units.gu(60) |
2856 | + AnchorChanges { target: notifications; anchors.left: parent.left } |
2857 | + }, |
2858 | + State { |
2859 | + name: "wide" |
2860 | + when: parent.width > units.gu(60) |
2861 | + AnchorChanges { target: notifications; anchors.left: undefined } |
2862 | + PropertyChanges { target: notifications; width: units.gu(38) } |
2863 | + } |
2864 | + ] |
2865 | + } |
2866 | + |
2867 | + UnityComponents.Dialogs { |
2868 | + id: dialogs |
2869 | + anchors.fill: parent |
2870 | + z: 10 |
2871 | + onPowerOffClicked: { |
2872 | + shutdownFadeOutRectangle.enabled = true; |
2873 | + shutdownFadeOutRectangle.visible = true; |
2874 | + shutdownFadeOut.start(); |
2875 | + } |
2876 | + } |
2877 | + |
2878 | + Rectangle { |
2879 | + id: shutdownFadeOutRectangle |
2880 | + z: dialogs.z + 10 |
2881 | + enabled: false |
2882 | + visible: false |
2883 | + color: "black" |
2884 | + anchors.fill: parent |
2885 | + opacity: 0.0 |
2886 | + NumberAnimation on opacity { |
2887 | + id: shutdownFadeOut |
2888 | + from: 0.0 |
2889 | + to: 1.0 |
2890 | + onStopped: { |
2891 | + if (shutdownFadeOutRectangle.enabled && shutdownFadeOutRectangle.visible) { |
2892 | + DBusUnitySessionService.Shutdown(); |
2893 | + } |
2894 | + } |
2895 | + } |
2896 | + } |
2897 | + |
2898 | + Keys.onPressed: { |
2899 | + if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) { |
2900 | + dialogs.onPowerKeyPressed(); |
2901 | + event.accepted = true; |
2902 | + } else { |
2903 | + event.accepted = false; |
2904 | + } |
2905 | + } |
2906 | + |
2907 | + Keys.onReleased: { |
2908 | + if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) { |
2909 | + dialogs.onPowerKeyReleased(); |
2910 | + event.accepted = true; |
2911 | + } else { |
2912 | + event.accepted = false; |
2913 | + } |
2914 | + } |
2915 | +} |
2916 | |
2917 | === added file 'wizard/test.sh' |
2918 | --- wizard/test.sh 1970-01-01 00:00:00 +0000 |
2919 | +++ wizard/test.sh 2014-12-02 18:43:43 +0000 |
2920 | @@ -0,0 +1,18 @@ |
2921 | +#!/bin/sh |
2922 | + |
2923 | +TOPDIR=$(readlink -e "$(dirname ${0})/..") |
2924 | + |
2925 | +LOCAL_PRIVATE_DIR=$(ls -d ${TOPDIR}/debian/tmp/usr/lib/*/ubuntu-system-settings/private) |
2926 | +if [ -n ${LOCAL_PRIVATE_DIR} ]; then |
2927 | + echo "Testing against locally built version" |
2928 | + export UBUNTU_SYSTEM_SETTINGS_WIZARD_ROOT="${TOPDIR}/debian/tmp/usr/share" |
2929 | + export UBUNTU_SYSTEM_SETTINGS_WIZARD_MODULES="${LOCAL_PRIVATE_DIR}" |
2930 | + export QML2_IMPORT_PATH=${LOCAL_PRIVATE_DIR}:${QML2_IMPORT_PATH} |
2931 | + export PATH=${TOPDIR}/debian/tmp/usr/bin:${PATH} |
2932 | +else |
2933 | + echo "Testing against system version" |
2934 | +fi |
2935 | + |
2936 | +export QML2_IMPORT_PATH=${TOPDIR}/tests/mocks:${QML2_IMPORT_PATH} |
2937 | + |
2938 | +exec system-settings-wizard |
2939 | |
2940 | === added file 'wizard/ubuntu-system-settings-wizard-cleanup.conf' |
2941 | --- wizard/ubuntu-system-settings-wizard-cleanup.conf 1970-01-01 00:00:00 +0000 |
2942 | +++ wizard/ubuntu-system-settings-wizard-cleanup.conf 2014-12-02 18:43:43 +0000 |
2943 | @@ -0,0 +1,20 @@ |
2944 | +description "Welcome to Ubuntu Cleanup" |
2945 | +author "Michael Terry <michael.terry@canonical.com>" |
2946 | + |
2947 | +# These are all tasks that need to be completed only if the wizard was |
2948 | +# intentionally stopped (i.e. the user clicked 'Finish' at the end) |
2949 | + |
2950 | +task |
2951 | + |
2952 | +# If you change this, also change it in the main upstart job |
2953 | +env RUN_FILE=".config/ubuntu-system-settings/wizard-has-run" |
2954 | + |
2955 | +script |
2956 | + # Don't run again in the future. We do this here, rather than in the main |
2957 | + # job because we only want to run this code if user actually clicked on the |
2958 | + # "Finish" button. |
2959 | + mkdir -p $(dirname "$HOME/$RUN_FILE") |
2960 | + touch "$HOME/$RUN_FILE" || true |
2961 | + |
2962 | + stop ubuntu-system-settings-wizard |
2963 | +end script |
2964 | |
2965 | === added file 'wizard/ubuntu-system-settings-wizard-set-lang.conf' |
2966 | --- wizard/ubuntu-system-settings-wizard-set-lang.conf 1970-01-01 00:00:00 +0000 |
2967 | +++ wizard/ubuntu-system-settings-wizard-set-lang.conf 2014-12-02 18:43:43 +0000 |
2968 | @@ -0,0 +1,30 @@ |
2969 | +description "Welcome to Ubuntu Cleanup" |
2970 | +author "Michael Terry <michael.terry@canonical.com>" |
2971 | + |
2972 | +# This job updates the system idea of what language is configured. It adjusts |
2973 | +# the upstart env and the DBus activation env. It also stops indicators and |
2974 | +# the OSK so that they can be restarted with the new env. |
2975 | + |
2976 | +task |
2977 | + |
2978 | +script |
2979 | + setenv() { |
2980 | + initctl set-env --global $1=$2 |
2981 | + gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'$1': '$2'}" |
2982 | + } |
2983 | + |
2984 | + UID=$(id -u) |
2985 | + |
2986 | + # Change upstart's ideas about locales |
2987 | + LANGUAGE=$(gdbus call --system --dest org.freedesktop.Accounts --object-path /org/freedesktop/Accounts/User$UID --method org.freedesktop.DBus.Properties.Get org.freedesktop.Accounts.User Language | cut -d\' -f2) |
2988 | + setenv LANGUAGE $LANGUAGE |
2989 | + echo "Set language for $USER_PATH as $LANGUAGE" |
2990 | + LOCALE=$(gdbus call --system --dest org.freedesktop.Accounts --object-path /org/freedesktop/Accounts/User$UID --method org.freedesktop.DBus.Properties.Get org.freedesktop.Accounts.User FormatsLocale | cut -d\' -f2) |
2991 | + setenv LC_ALL $LOCALE |
2992 | + setenv LANG $LOCALE |
2993 | + echo "Set locale as $LOCALE" |
2994 | + |
2995 | + # Stop any indicators and OSK so they will be restarted with new environment |
2996 | + initctl emit indicator-services-end |
2997 | + stop maliit-server || true |
2998 | +end script |
2999 | |
3000 | === added file 'wizard/ubuntu-system-settings-wizard.conf' |
3001 | --- wizard/ubuntu-system-settings-wizard.conf 1970-01-01 00:00:00 +0000 |
3002 | +++ wizard/ubuntu-system-settings-wizard.conf 2014-12-02 18:43:43 +0000 |
3003 | @@ -0,0 +1,75 @@ |
3004 | +description "Welcome to Ubuntu" |
3005 | +author "Michael Terry <michael.terry@canonical.com>" |
3006 | + |
3007 | +start on starting unity8 |
3008 | +task |
3009 | + |
3010 | +expect stop |
3011 | + |
3012 | +# If you change this, also change it in the cleanup upstart job |
3013 | +env RUN_FILE=".config/ubuntu-system-settings/wizard-has-run" |
3014 | + |
3015 | +pre-start script |
3016 | + if [ -e "$HOME/$RUN_FILE" ]; then |
3017 | + initctl set-env WIZARD_SKIPPED=true |
3018 | + stop |
3019 | + else |
3020 | + # Stop unity8, we'll start it again in post-stop (this avoids a race |
3021 | + # between post-stop and unity8 unpausing) |
3022 | + stop --no-wait $JOB |
3023 | + |
3024 | + # Tell unity-mir to raise SIGSTOP after we start |
3025 | + initctl set-env UNITY_MIR_EMITS_SIGSTOP=1 |
3026 | + |
3027 | + if [ -n "$MIR_SOCKET" ]; then |
3028 | + initctl set-env --global WIZARD_ORIG_MIR_SOCKET=$MIR_SOCKET |
3029 | + |
3030 | + # Point wizard at unity-system-compositor |
3031 | + MIR_SERVER_FILE=$XDG_RUNTIME_DIR/wizard_socket |
3032 | + initctl set-env MIR_SERVER_FILE=$MIR_SERVER_FILE |
3033 | + initctl set-env MIR_SERVER_HOST_SOCKET=$MIR_SOCKET |
3034 | + |
3035 | + # Remove the socket if still there |
3036 | + if [ -S "$MIR_SERVER_FILE" ]; then |
3037 | + rm "$MIR_SERVER_FILE" |
3038 | + fi |
3039 | + |
3040 | + # Point future jobs in this session to our Mir socket instead of |
3041 | + # unity-system-compositor's socket. |
3042 | + initctl set-env --global MIR_SOCKET=$MIR_SERVER_FILE |
3043 | + gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'MIR_SOCKET': '$MIR_SERVER_FILE'}" |
3044 | + fi |
3045 | + fi |
3046 | +end script |
3047 | + |
3048 | +exec system-settings-wizard |
3049 | + |
3050 | +post-stop script |
3051 | + if [ -n "$WIZARD_SKIPPED" ]; then |
3052 | + exit |
3053 | + fi |
3054 | + |
3055 | + setenv() { |
3056 | + initctl set-env --global $1=$2 |
3057 | + gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'$1': '$2'}" |
3058 | + } |
3059 | + |
3060 | + echo "Ending wizard" |
3061 | + |
3062 | + if [ -S "$MIR_SERVER_FILE" ]; then |
3063 | + rm -f "$MIR_SERVER_FILE" |
3064 | + fi |
3065 | + |
3066 | + # Undo changes to global variables |
3067 | + if [ -n "$WIZARD_ORIG_MIR_SOCKET" ]; then |
3068 | + echo "Resetting MIR_SOCKET to $WIZARD_ORIG_MIR_SOCKET" |
3069 | + setenv MIR_SOCKET $WIZARD_ORIG_MIR_SOCKET |
3070 | + fi |
3071 | + |
3072 | + # Stop any indicators and OSK so they will be restarted with new environment |
3073 | + initctl emit indicator-services-end |
3074 | + stop maliit-server || true |
3075 | + |
3076 | + # And finally, resume unity8 |
3077 | + start --no-wait $JOB || true |
3078 | +end script |
FAILED: Continuous integration, rev:1435 /code.launchpad .net/~mterry/ unity8/ wizard- import/ +merge/ 242245/ +edit-commit- message
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http:// jenkins. qa.ubuntu. com/job/ unity8- ci/4932/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 283 jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- vivid/109 jenkins. qa.ubuntu. com/job/ unity8- vivid-amd64- ci/97 jenkins. qa.ubuntu. com/job/ unity8- vivid-i386- ci/97 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- vivid-mako/ 257 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 283 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 283/artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 16010
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity8- ci/4932/ rebuild
http://