Merge lp:~mterry/unity8/wizard-plugin into lp:unity8

Proposed by Michael Terry
Status: Merged
Approved by: Andrea Cimitan
Approved revision: 1451
Merged at revision: 1475
Proposed branch: lp:~mterry/unity8/wizard-plugin
Merge into: lp:unity8
Prerequisite: lp:~mterry/unity8/wizard-import
Diff against target: 3248 lines (+924/-1207)
80 files modified
CMakeLists.txt (+5/-1)
build.sh (+1/-0)
debian/control (+2/-12)
debian/rules (+1/-1)
debian/ubuntu-system-settings-wizard.install (+0/-5)
debian/ubuntu-system-settings-wizard.lintian-overrides (+0/-1)
debian/unity8-common.install (+1/-0)
debian/unity8-private.install (+1/-0)
debian/unity8.install (+1/-0)
include/paths.h.in (+2/-0)
plugins/AccountsService/AccountsService.cpp (+61/-2)
plugins/AccountsService/AccountsService.h (+20/-0)
plugins/CMakeLists.txt (+1/-0)
plugins/Unity/Launcher/desktopfilehandler.cpp (+1/-1)
plugins/Unity/Launcher/launcheritem.cpp (+11/-4)
plugins/Unity/Launcher/launchermodel.cpp (+1/-0)
plugins/Unity/Launcher/launchermodel.h (+1/-1)
plugins/Wizard/CMakeLists.txt (+8/-62)
plugins/Wizard/PageList.cpp (+10/-9)
plugins/Wizard/PageList.h (+3/-5)
plugins/Wizard/System.cpp (+76/-95)
plugins/Wizard/System.h (+15/-22)
plugins/Wizard/Wizard.qmltypes (+36/-0)
plugins/Wizard/plugin.cpp (+42/-0)
plugins/Wizard/plugin.h (+32/-0)
plugins/Wizard/qmldir (+3/-0)
qml/CMakeLists.txt (+1/-0)
qml/Components/Dialogs.qml (+17/-21)
qml/Components/EdgeDemo.qml (+19/-6)
qml/Greeter/Clock.qml (+10/-0)
qml/Greeter/GreeterContent.qml (+5/-0)
qml/Launcher/Launcher.qml (+5/-0)
qml/Shell.qml (+26/-15)
qml/Wizard/CheckableSetting.qml (+0/-1)
qml/Wizard/Page.qml (+1/-2)
qml/Wizard/Pages.qml (+80/-197)
qml/Wizard/Pages/10-welcome.qml (+7/-5)
qml/Wizard/Pages/20-sim.qml (+1/-1)
qml/Wizard/Pages/30-passwd-type.qml (+13/-1)
qml/Wizard/Pages/40-wifi.qml (+1/-2)
qml/Wizard/Pages/50-location.qml (+7/-7)
qml/Wizard/Pages/60-reporting.qml (+1/-1)
qml/Wizard/Pages/80-finished.qml (+1/-1)
qml/Wizard/Pages/here-terms.qml (+4/-4)
qml/Wizard/Pages/passwd-confirm.qml (+2/-2)
qml/Wizard/Pages/passwd-set.qml (+2/-2)
qml/Wizard/Wizard.qml (+55/-0)
tests/CMakeLists.txt (+0/-1)
tests/mocks/AccountsService/AccountsService.cpp (+31/-1)
tests/mocks/AccountsService/AccountsService.h (+20/-0)
tests/mocks/CMakeLists.txt (+1/-0)
tests/mocks/QMenuModel/CMakeLists.txt (+1/-0)
tests/mocks/QMenuModel/dbus-enums.h (+52/-0)
tests/mocks/QMenuModel/plugin.cpp (+3/-0)
tests/mocks/Wizard/CMakeLists.txt (+12/-0)
tests/mocks/Wizard/MockSystem.cpp (+38/-0)
tests/mocks/Wizard/MockSystem.h (+46/-0)
tests/mocks/Wizard/Wizard.qmltypes (+36/-0)
tests/mocks/Wizard/mockplugin.cpp (+42/-0)
tests/mocks/Wizard/mockplugin.h (+32/-0)
tests/mocks/Wizard/qmldir (+3/-0)
tests/plugins/CMakeLists.txt (+1/-0)
tests/plugins/Wizard/CMakeLists.txt (+12/-5)
tests/plugins/Wizard/tst_pagelist.cpp (+1/-3)
wizard/Unity/Application/CMakeLists.txt (+0/-3)
wizard/Unity/Application/OSKController.qml (+0/-20)
wizard/Unity/Application/qmldir (+0/-2)
wizard/Unity/CMakeLists.txt (+0/-1)
wizard/Utils/CMakeLists.txt (+0/-27)
wizard/Utils/plugin.cpp (+0/-41)
wizard/Utils/plugin.h (+0/-33)
wizard/Utils/qmldir (+0/-2)
wizard/Utils/qsortfilterproxymodelqml.cpp (+0/-167)
wizard/Utils/qsortfilterproxymodelqml.h (+0/-63)
wizard/main.cpp (+0/-93)
wizard/qml/Components/InputMethod.qml (+0/-113)
wizard/test.sh (+0/-18)
wizard/ubuntu-system-settings-wizard-cleanup.conf (+0/-20)
wizard/ubuntu-system-settings-wizard-set-lang.conf (+0/-30)
wizard/ubuntu-system-settings-wizard.conf (+0/-75)
To merge this branch: bzr merge lp:~mterry/unity8/wizard-plugin
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+241912@code.launchpad.net

Commit message

Convert the welcome wizard from a separate executable into a qml plugin (with a small C++ plugin for support).

- This changes the path for adding customized wizard pages (drops system-settings namespacing). I checked with cwayne, that support isn't being used yet. So that's safe to adjust while we're here.

- I did not change the path for the 'has the wizard run yet' marker, since that is being used in the wild. But I added a comment as to why we're using the phrase "ubuntu-system-settings" in that filename.

- I fleshed out unity8's support for changing the language on the fly, since that's now done in-process. I believe I caught all cases (anything that used a qml binding to i18n worked automatically, just had to catch the cases that were pulling from outside sources like infographics).

- If an incoming call happens during the wizard, we just bail out of it and the edge demo. I'm not sure what the ideal behavior is, but this is at least reasonable. There's nothing in the wizard that *needs* to be done.

- Making the wizard a plugin lets us drop the gap between the end of the wizard and the start of the shell. Yay!

Description of the change

Convert the welcome wizard from a separate executable into a qml plugin (with a small C++ plugin for support).

- This changes the path for adding customized wizard pages (drops system-settings namespacing). I checked with cwayne, that support isn't being used yet. So that's safe to adjust while we're here.

- I did not change the path for the 'has the wizard run yet' marker, since that is being used in the wild. But I added a comment as to why we're using the phrase "ubuntu-system-settings" in that filename.

- I fleshed out unity8's support for changing the language on the fly, since that's now done in-process. I believe I caught all cases (anything that used a qml binding to i18n worked automatically, just had to catch the cases that were pulling from outside sources like infographics).

- Making the wizard a plugin lets us drop the gap between the end of the wizard and the start of the shell. Yay!

- If an incoming call happens during the wizard, we just bail out of it and the edge demo. I'm not sure what the ideal behavior is, but this is at least reasonable. There's nothing in the wizard that *needs* to be done.

There are no tests in this branch. That will come in a later branch, but I'd like to avoid landing this without them. Still, please review in the meantime, so everything can land smoothly!

== Checklist ==

 * Are there any related MPs required for this MP to build/function as expected? Please list.
 Yes:
  https://code.launchpad.net/~mterry/unity8/wizard-import/+merge/242245
  https://code.launchpad.net/~mterry/ubuntu-system-settings/drop-wizard/+merge/242244

 * Did you perform an exploratory manual test run of your code change and any related functionality?
 Yes

 * 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 in that team

 * If you changed the UI, has there been a design review?
 NA

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~mterry/unity8/wizard-plugin updated
1444. By Michael Terry

Only update language if it changed

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~mterry/unity8/wizard-plugin updated
1445. By Michael Terry

Conflict with the wizard package, so both aren't installed at the same time

1446. By Michael Terry

And depend on ubuntu-system-settings itself for its plugins that the wizard uses

1447. By Michael Terry

Some more minor packaging cleanup

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~mterry/unity8/wizard-plugin updated
1448. By Michael Terry

Don't undo clock date label binding, rather just force it to regenerate itself

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Andrea Cimitan (cimi) :
lp:~mterry/unity8/wizard-plugin updated
1449. By Michael Terry

Use a separate property rather than a special one-space value to signal when we have a valid HERE path

1450. By Michael Terry

Address review nits

Revision history for this message
Michael Terry (mterry) wrote :

OK, addressed all your comments (including the one on IRC about using " " as a special value for hereLicensePath).

Except for your question about the copyright for tests/mocks/QMenuModel/dbus-enums.h -- I copied that file directly from QMenuModel without modifying it, so I left the original copyright in place.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~mterry/unity8/wizard-plugin updated
1451. By Michael Terry

Let hereLicensePath update from null to empty string

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Andrea Cimitan (cimi) wrote :

 * Did you perform an exploratory manual test run of the code change and any related functionality?
Yes, tested -tests branch
 * Did CI run pass? If not, please explain why.
AP
 * Did you make sure that the branch does not contain spurious tags?
Yes

review: Approve
lp:~mterry/unity8/wizard-plugin updated
1452. By Michael Terry

Merge from wizard-import

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-12-02 18:48:08 +0000
3+++ CMakeLists.txt 2014-12-02 18:48:08 +0000
4@@ -61,6 +61,11 @@
5 set(SHELL_APP_DIR ${CMAKE_INSTALL_DATADIR}/unity8)
6 set(SHELL_PRIVATE_LIBDIR ${CMAKE_INSTALL_LIBDIR}/unity8)
7
8+execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=plugin_private_module_dir SystemSettings OUTPUT_VARIABLE USS_PRIVATE_PLUGINDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
9+if(USS_PRIVATE_PLUGINDIR STREQUAL "")
10+ message(FATAL_ERROR "Could not determine USS private plugin installation dir.")
11+endif()
12+
13 execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=plugindir_suffix unity-shell-api OUTPUT_VARIABLE SHELL_INSTALL_QML OUTPUT_STRIP_TRAILING_WHITESPACE)
14 if(SHELL_INSTALL_QML STREQUAL "")
15 message(FATAL_ERROR "Could not determine plugin installation dir.")
16@@ -117,7 +122,6 @@
17 add_subdirectory(qml)
18 add_subdirectory(tests)
19 add_subdirectory(plugins)
20-add_subdirectory(wizard)
21
22 #
23 # Data files
24
25=== modified file 'build.sh'
26--- build.sh 2014-10-27 08:58:17 +0000
27+++ build.sh 2014-12-02 18:48:08 +0000
28@@ -54,6 +54,7 @@
29 qtdeclarative5-unity-notifications-plugin \
30 qml-module-ubuntu-connectivity \
31 ubuntu-mobile-icons \
32+ ubuntu-system-settings \
33 unity-plugin-scopes \
34 xvfb \
35 || exit 5
36
37=== modified file 'debian/control'
38--- debian/control 2014-12-02 18:48:08 +0000
39+++ debian/control 2014-12-02 18:48:08 +0000
40@@ -88,6 +88,7 @@
41 qtdeclarative5-gsettings1.0,
42 qtdeclarative5-qtmir-plugin (>= 0.4.4),
43 qtdeclarative5-ubuntu-telephony0.1,
44+ ubuntu-system-settings,
45 unity-launcher-impl-4,
46 unity8-common (= ${source:Version}),
47 unity8-private (= ${binary:Version}),
48@@ -102,6 +103,7 @@
49 unity8-greeter (<< 7.89),
50 Replaces: ubuntu-touch-session (<< 0.82~),
51 unity8-greeter (<< 7.89),
52+Conflicts: ubuntu-system-settings-wizard,
53 Description: Unity 8 shell
54 The Unity 8 shell is the primary user interface for Ubuntu devices.
55
56@@ -192,15 +194,3 @@
57 Depends: ${misc:Depends},
58 Description: Documentation for Unity8
59 The Unity 8 shell is the primary user interface for Ubuntu devices. (documentation)
60-
61-Package: ubuntu-system-settings-wizard
62-Architecture: any
63-Depends: unity8 (= ${binary:Version}),
64- ${misc:Depends},
65- ${shlibs:Depends},
66-Recommends: qtdeclarative5-qtmir-plugin (>= 0.4),
67-Breaks: ubuntu-system-settings (<< 0.4),
68-Replaces: ubuntu-system-settings (<< 0.4),
69-Description: Welcome Wizard for Ubuntu Touch
70- This package contains the Welcome Wizard used on the Ubuntu Touch images,
71- it's designed for phones, tablets and convergent devices.
72
73=== modified file 'debian/rules'
74--- debian/rules 2014-12-02 18:48:08 +0000
75+++ debian/rules 2014-07-23 15:30:38 +0000
76@@ -40,7 +40,7 @@
77
78 # use private lib directories
79 override_dh_makeshlibs:
80- dh_makeshlibs -Nunity8-private -Nunity8-fake-env -Nubuntu-system-settings-wizard
81+ dh_makeshlibs -Nunity8-private -Nunity8-fake-env
82
83 # libMockLightDM-qml.so links against liblightdm-qt5-2.so which doesn't exist
84 override_dh_shlibdeps:
85
86=== removed file 'debian/ubuntu-system-settings-wizard.install'
87--- debian/ubuntu-system-settings-wizard.install 2014-12-02 18:48:08 +0000
88+++ debian/ubuntu-system-settings-wizard.install 1970-01-01 00:00:00 +0000
89@@ -1,5 +0,0 @@
90-usr/bin/system-settings-wizard
91-usr/share/ubuntu/settings/wizard
92-usr/share/upstart/sessions/ubuntu-system-settings-wizard*.conf
93-usr/lib/*/ubuntu-system-settings/private/Ubuntu/SystemSettings/Wizard
94-var/lib/polkit-1/localauthority/10-vendor.d/50-com.ubuntu.system-settings.wizard.pkla
95
96=== removed file 'debian/ubuntu-system-settings-wizard.lintian-overrides'
97--- debian/ubuntu-system-settings-wizard.lintian-overrides 2014-12-02 18:48:08 +0000
98+++ debian/ubuntu-system-settings-wizard.lintian-overrides 1970-01-01 00:00:00 +0000
99@@ -1,1 +0,0 @@
100-ubuntu-system-settings-wizard: binary-without-manpage usr/bin/system-settings-wizard
101
102=== modified file 'debian/unity8-common.install'
103--- debian/unity8-common.install 2014-08-27 07:57:54 +0000
104+++ debian/unity8-common.install 2014-12-02 18:48:08 +0000
105@@ -3,3 +3,4 @@
106 usr/share/unity8/Dash
107 usr/share/unity8/Notifications
108 usr/share/unity8/graphics
109+var/lib/polkit-1/localauthority/10-vendor.d
110
111=== modified file 'debian/unity8-private.install'
112--- debian/unity8-private.install 2014-11-05 08:30:16 +0000
113+++ debian/unity8-private.install 2014-12-02 18:48:08 +0000
114@@ -9,6 +9,7 @@
115 usr/lib/*/unity8/qml/Ubuntu
116 usr/lib/*/unity8/qml/Unity
117 usr/lib/*/unity8/qml/Utils
118+usr/lib/*/unity8/qml/Wizard
119 usr/lib/*/unity8/libUbuntuGestures*
120 usr/share/accountsservice/interfaces
121 usr/share/dbus-1/interfaces
122
123=== modified file 'debian/unity8.install'
124--- debian/unity8.install 2014-10-28 14:01:09 +0000
125+++ debian/unity8.install 2014-12-02 18:48:08 +0000
126@@ -10,4 +10,5 @@
127 usr/share/unity8/Panel
128 usr/share/unity8/Shell.qml
129 usr/share/unity8/Stages
130+usr/share/unity8/Wizard
131 usr/share/url-dispatcher/urls/unity8-dash.url-dispatcher
132
133=== modified file 'include/paths.h.in'
134--- include/paths.h.in 2014-08-26 08:14:44 +0000
135+++ include/paths.h.in 2014-12-02 18:48:08 +0000
136@@ -71,9 +71,11 @@
137 QStringList paths;
138 if (isRunningInstalled()) {
139 paths << QString("@CMAKE_INSTALL_PREFIX@/@SHELL_INSTALL_QML@");
140+ paths << QString("@USS_PRIVATE_PLUGINDIR@");
141 paths << QString("@SHELL_PLUGINDIR@");
142 paths << QString("@CMAKE_INSTALL_PREFIX@/@SHELL_INSTALL_QML@/mocks");
143 } else {
144+ paths << QString("@USS_PRIVATE_PLUGINDIR@");
145 paths << QString("@SHELL_PLUGINDIR@");
146 paths << QString("@CMAKE_BINARY_DIR@/tests/mocks");
147 }
148
149=== modified file 'plugins/AccountsService/AccountsService.cpp'
150--- plugins/AccountsService/AccountsService.cpp 2014-08-19 15:25:08 +0000
151+++ plugins/AccountsService/AccountsService.cpp 2014-12-02 18:48:08 +0000
152@@ -19,23 +19,28 @@
153 #include "AccountsService.h"
154 #include "AccountsServiceDBusAdaptor.h"
155
156+#include <QFile>
157 #include <QStringList>
158
159 AccountsService::AccountsService(QObject* parent)
160 : QObject(parent),
161 m_service(new AccountsServiceDBusAdaptor(this)),
162- m_user(qgetenv("USER")),
163+ m_user(""),
164 m_demoEdges(false),
165 m_enableLauncherWhileLocked(false),
166 m_enableIndicatorsWhileLocked(false),
167 m_statsWelcomeScreen(false),
168 m_passwordDisplayHint(Keyboard),
169- m_failedLogins(0)
170+ m_failedLogins(0),
171+ m_hereEnabled(false),
172+ m_hereLicensePath() // null means not set yet
173 {
174 connect(m_service, SIGNAL(propertiesChanged(const QString &, const QString &, const QStringList &)),
175 this, SLOT(propertiesChanged(const QString &, const QString &, const QStringList &)));
176 connect(m_service, SIGNAL(maybeChanged(const QString &)),
177 this, SLOT(maybeChanged(const QString &)));
178+
179+ setUser(qgetenv("USER"));
180 }
181
182 QString AccountsService::user() const
183@@ -45,6 +50,9 @@
184
185 void AccountsService::setUser(const QString &user)
186 {
187+ if (user.isEmpty() || m_user == user)
188+ return;
189+
190 m_user = user;
191 Q_EMIT userChanged();
192
193@@ -55,6 +63,8 @@
194 updateStatsWelcomeScreen();
195 updatePasswordDisplayHint();
196 updateFailedLogins();
197+ updateHereEnabled();
198+ updateHereLicensePath();
199 }
200
201 bool AccountsService::demoEdges() const
202@@ -93,6 +103,26 @@
203 return m_passwordDisplayHint;
204 }
205
206+bool AccountsService::hereEnabled() const
207+{
208+ return m_hereEnabled;
209+}
210+
211+void AccountsService::setHereEnabled(bool enabled)
212+{
213+ m_service->setUserProperty(m_user, "com.ubuntu.location.providers.here.AccountsService", "LicenseAccepted", enabled);
214+}
215+
216+QString AccountsService::hereLicensePath() const
217+{
218+ return m_hereLicensePath;
219+}
220+
221+bool AccountsService::hereLicensePathValid() const
222+{
223+ return !m_hereLicensePath.isNull();
224+}
225+
226 void AccountsService::updateDemoEdges()
227 {
228 auto demoEdges = m_service->getUserProperty(m_user, "com.canonical.unity.AccountsService", "demo-edges").toBool();
229@@ -156,6 +186,28 @@
230 }
231 }
232
233+void AccountsService::updateHereEnabled()
234+{
235+ bool hereEnabled = m_service->getUserProperty(m_user, "com.ubuntu.location.providers.here.AccountsService", "LicenseAccepted").toBool();
236+ if (m_hereEnabled != hereEnabled) {
237+ m_hereEnabled = hereEnabled;
238+ Q_EMIT hereEnabledChanged();
239+ }
240+}
241+
242+void AccountsService::updateHereLicensePath()
243+{
244+ QString hereLicensePath = m_service->getUserProperty(m_user, "com.ubuntu.location.providers.here.AccountsService", "LicenseBasePath").toString();
245+
246+ if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
247+ hereLicensePath = "";
248+
249+ if (m_hereLicensePath.isNull() || m_hereLicensePath != hereLicensePath) {
250+ m_hereLicensePath = hereLicensePath;
251+ Q_EMIT hereLicensePathChanged();
252+ }
253+}
254+
255 uint AccountsService::failedLogins() const
256 {
257 return m_failedLogins;
258@@ -195,6 +247,13 @@
259 if (changed.contains("EnableIndicatorsWhileLocked")) {
260 updateEnableIndicatorsWhileLocked();
261 }
262+ } else if (interface == "com.ubuntu.location.providers.here.AccountsService") {
263+ if (changed.contains("LicenseAccepted")) {
264+ updateHereEnabled();
265+ }
266+ if (changed.contains("LicenseBasePath")) {
267+ updateHereLicensePath();
268+ }
269 }
270 }
271
272
273=== modified file 'plugins/AccountsService/AccountsService.h'
274--- plugins/AccountsService/AccountsService.h 2014-08-19 15:03:48 +0000
275+++ plugins/AccountsService/AccountsService.h 2014-12-02 18:48:08 +0000
276@@ -55,6 +55,16 @@
277 READ failedLogins
278 WRITE setFailedLogins
279 NOTIFY failedLoginsChanged)
280+ Q_PROPERTY(bool hereEnabled
281+ READ hereEnabled
282+ WRITE setHereEnabled
283+ NOTIFY hereEnabledChanged)
284+ Q_PROPERTY(QString hereLicensePath
285+ READ hereLicensePath
286+ NOTIFY hereLicensePathChanged)
287+ Q_PROPERTY(bool hereLicensePathValid // qml sees a null string as "", so we use proxy setting for that
288+ READ hereLicensePathValid
289+ NOTIFY hereLicensePathChanged)
290
291 public:
292 enum PasswordDisplayHint {
293@@ -75,6 +85,10 @@
294 PasswordDisplayHint passwordDisplayHint() const;
295 uint failedLogins() const;
296 void setFailedLogins(uint failedLogins);
297+ bool hereEnabled() const;
298+ void setHereEnabled(bool enabled);
299+ QString hereLicensePath() const;
300+ bool hereLicensePathValid() const;
301
302 Q_SIGNALS:
303 void userChanged();
304@@ -85,6 +99,8 @@
305 void statsWelcomeScreenChanged();
306 void passwordDisplayHintChanged();
307 void failedLoginsChanged();
308+ void hereEnabledChanged();
309+ void hereLicensePathChanged();
310
311 private Q_SLOTS:
312 void propertiesChanged(const QString &user, const QString &interface, const QStringList &changed);
313@@ -98,6 +114,8 @@
314 void updateStatsWelcomeScreen();
315 void updatePasswordDisplayHint();
316 void updateFailedLogins();
317+ void updateHereEnabled();
318+ void updateHereLicensePath();
319
320 AccountsServiceDBusAdaptor *m_service;
321 QString m_user;
322@@ -108,6 +126,8 @@
323 bool m_statsWelcomeScreen;
324 PasswordDisplayHint m_passwordDisplayHint;
325 uint m_failedLogins;
326+ bool m_hereEnabled;
327+ QString m_hereLicensePath;
328 };
329
330 #endif
331
332=== modified file 'plugins/CMakeLists.txt'
333--- plugins/CMakeLists.txt 2014-11-05 08:30:16 +0000
334+++ plugins/CMakeLists.txt 2014-12-02 18:48:08 +0000
335@@ -21,3 +21,4 @@
336 add_subdirectory(Ubuntu)
337 add_subdirectory(Unity)
338 add_subdirectory(Utils)
339+add_subdirectory(Wizard)
340
341=== modified file 'plugins/Unity/Launcher/desktopfilehandler.cpp'
342--- plugins/Unity/Launcher/desktopfilehandler.cpp 2014-11-04 12:53:48 +0000
343+++ plugins/Unity/Launcher/desktopfilehandler.cpp 2014-12-02 18:48:08 +0000
344@@ -110,7 +110,7 @@
345 settings.beginGroup("Desktop Entry");
346
347 // First try to find Name[xx_YY] and Name[xx] in .desktop file
348- QString locale = QLocale::system().name();
349+ QString locale = QLocale().name();
350 QString shortLocale = locale.split('_').first();
351
352 if (locale != shortLocale && settings.contains(QString("Name[%1]").arg(locale))) {
353
354=== modified file 'plugins/Unity/Launcher/launcheritem.cpp'
355--- plugins/Unity/Launcher/launcheritem.cpp 2014-09-10 11:31:51 +0000
356+++ plugins/Unity/Launcher/launcheritem.cpp 2014-12-02 18:48:08 +0000
357@@ -60,6 +60,10 @@
358 {
359 if (m_name != name) {
360 m_name = name;
361+ QuickListEntry entry;
362+ entry.setActionId("launch_item");
363+ entry.setText(m_name);
364+ m_quickList->updateAction(entry);
365 Q_EMIT nameChanged(name);
366 }
367 }
368@@ -86,12 +90,15 @@
369 {
370 if (m_pinned != pinned) {
371 m_pinned = pinned;
372- QuickListEntry entry;
373- entry.setActionId("pin_item");
374- entry.setText(pinned ? gettext("Unpin shortcut") : gettext("Pin shortcut"));
375- m_quickList->updateAction(entry);
376 Q_EMIT pinnedChanged(pinned);
377 }
378+
379+ // Even if pinned status didn't change, we want to update text in case
380+ // the locale has changed since we last set pinned status.
381+ QuickListEntry entry;
382+ entry.setActionId("pin_item");
383+ entry.setText(pinned ? gettext("Unpin shortcut") : gettext("Pin shortcut"));
384+ m_quickList->updateAction(entry);
385 }
386
387 bool LauncherItem::running() const
388
389=== modified file 'plugins/Unity/Launcher/launchermodel.cpp'
390--- plugins/Unity/Launcher/launchermodel.cpp 2014-10-21 20:24:10 +0000
391+++ plugins/Unity/Launcher/launchermodel.cpp 2014-12-02 18:48:08 +0000
392@@ -370,6 +370,7 @@
393 int idx = m_list.indexOf(item);
394 item->setName(desktopFile.displayName());
395 item->setIcon(desktopFile.icon());
396+ item->setPinned(item->pinned()); // update pinned text if needed
397 Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleName << RoleIcon);
398 }
399 }
400
401=== modified file 'plugins/Unity/Launcher/launchermodel.h'
402--- plugins/Unity/Launcher/launchermodel.h 2014-10-15 11:59:20 +0000
403+++ plugins/Unity/Launcher/launchermodel.h 2014-12-02 18:48:08 +0000
404@@ -58,6 +58,7 @@
405
406 public Q_SLOTS:
407 void requestRemove(const QString &appId);
408+ Q_INVOKABLE void refresh();
409
410 private:
411 void storeAppList();
412@@ -68,7 +69,6 @@
413 void countChanged(const QString &appId, int count);
414 void countVisibleChanged(const QString &appId, int count);
415 void progressChanged(const QString &appId, int progress);
416- void refresh();
417
418 void applicationAdded(const QModelIndex &parent, int row);
419 void applicationRemoved(const QModelIndex &parent, int row);
420
421=== renamed directory 'wizard' => 'plugins/Wizard'
422=== renamed file 'wizard/50-com.ubuntu.system-settings.wizard.pkla' => 'plugins/Wizard/50-com.canonical.unity.wizard.pkla'
423=== modified file 'plugins/Wizard/CMakeLists.txt'
424--- wizard/CMakeLists.txt 2014-12-02 18:48:08 +0000
425+++ plugins/Wizard/CMakeLists.txt 2014-12-02 18:48:08 +0000
426@@ -1,65 +1,11 @@
427-# This file uses a lot of namespacing like "ubuntu-system-settings" instead of
428-# "unity8". This is because we have imported it from ubuntu-system-settings
429-# and haven't fully integrated it yet.
430-
431-include_directories(
432- ${CMAKE_CURRENT_BINARY_DIR}
433- ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
434-)
435-
436-set(PLUGIN_MANIFEST_DIR_BASE share/ubuntu/settings/system)
437-set(PLUGIN_MODULE_DIR_BASE ubuntu-system-settings)
438-set(PLUGIN_PRIVATE_MODULE_DIR_BASE "${PLUGIN_MODULE_DIR_BASE}/private")
439-set(PLUGIN_QML_DIR_BASE share/ubuntu/settings/system/qml-plugins)
440-
441-set(PLUGIN_MANIFEST_DIR "${CMAKE_INSTALL_PREFIX}/${PLUGIN_MANIFEST_DIR_BASE}")
442-set(PLUGIN_MODULE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${PLUGIN_MODULE_DIR_BASE}")
443-set(PLUGIN_PRIVATE_MODULE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${PLUGIN_PRIVATE_MODULE_DIR_BASE}")
444-set(PLUGIN_QML_DIR "${CMAKE_INSTALL_PREFIX}/${PLUGIN_QML_DIR_BASE}")
445-
446-add_definitions(-DI18N_DOMAIN="unity8")
447-add_definitions(-DPLUGIN_MANIFEST_DIR="${PLUGIN_MANIFEST_DIR}")
448-add_definitions(-DPLUGIN_MODULE_DIR="${PLUGIN_MODULE_DIR}")
449-add_definitions(-DPLUGIN_PRIVATE_MODULE_DIR="${PLUGIN_PRIVATE_MODULE_DIR}")
450-add_definitions(-DPLUGIN_QML_DIR="${PLUGIN_QML_DIR}")
451-
452-execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=plugindir unity-shell-api OUTPUT_VARIABLE SHELL_PLUGINDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
453-if(SHELL_PLUGINDIR STREQUAL "")
454- message(FATAL_ERROR "Could not determine plugin import dir.")
455-endif()
456-
457-add_definitions(-DSHELL_PLUGINDIR="${SHELL_PLUGINDIR}")
458-
459-set(WIZARD_ROOT "${CMAKE_INSTALL_PREFIX}/share")
460-add_definitions(-DWIZARD_ROOT="${WIZARD_ROOT}")
461-
462-file(GLOB_RECURSE QML_FILES
463- qml/*
464-)
465-
466-set(WIZARD_SOURCES
467- main.cpp
468+add_library(Wizard-qml MODULE
469+ plugin.cpp
470 PageList.cpp
471-)
472-
473-add_executable(system-settings-wizard
474- ${WIZARD_SOURCES}
475- ${system-settings-wizard-resources}
476- ${QML_FILES} # This is to make qml and image files appear in the IDE's project tree
477-)
478-
479-qt5_use_modules(system-settings-wizard Core Gui Quick Qml)
480-
481-add_subdirectory(Unity)
482-add_subdirectory(Utils)
483-
484-install(TARGETS system-settings-wizard RUNTIME DESTINATION bin)
485-install(FILES ubuntu-system-settings-wizard.conf
486- ubuntu-system-settings-wizard-cleanup.conf
487- ubuntu-system-settings-wizard-set-lang.conf
488- DESTINATION share/upstart/sessions)
489+ System.cpp
490+)
491+
492+qt5_use_modules(Wizard-qml DBus Qml)
493+add_unity8_plugin(Wizard 0.1 Wizard TARGETS Wizard-qml)
494
495 set(POLKIT_LIB_DIR "${CMAKE_INSTALL_LOCALSTATEDIR}/lib/polkit-1")
496-install(FILES 50-com.ubuntu.system-settings.wizard.pkla DESTINATION ${POLKIT_LIB_DIR}/localauthority/10-vendor.d)
497-
498-install(DIRECTORY qml DESTINATION ${WIZARD_ROOT}/ubuntu/settings/wizard)
499+install(FILES 50-com.canonical.unity.wizard.pkla DESTINATION ${POLKIT_LIB_DIR}/localauthority/10-vendor.d)
500
501=== modified file 'plugins/Wizard/PageList.cpp'
502--- wizard/PageList.cpp 2014-12-02 18:48:08 +0000
503+++ plugins/Wizard/PageList.cpp 2014-12-02 18:48:08 +0000
504@@ -1,6 +1,4 @@
505 /*
506- * This file is part of system-settings
507- *
508 * Copyright (C) 2014 Canonical Ltd.
509 *
510 * This program is free software: you can redistribute it and/or modify it
511@@ -19,7 +17,7 @@
512 /**
513 * This class lets the list of wizard pages be dynamic.
514 * - To add new ones, drop them into
515- * $XDG_DATA_DIRS/ubuntu/settings/wizard/qml/Pages with a numbered prefix,
516+ * $XDG_DATA_DIRS/Wizard/Pages with a numbered prefix,
517 * like "21-custom-page.qml". The number determines the order in the page
518 * sequence that your page will appear.
519 * - To disable an existing page, add a file like "21-custom-page.qml.disabled"
520@@ -32,10 +30,11 @@
521 */
522
523 #include "PageList.h"
524+#include <paths.h>
525 #include <QDir>
526+#include <QSet>
527 #include <QStandardPaths>
528
529-#include <QDebug>
530 PageList::PageList(QObject *parent)
531 : QObject(parent),
532 m_index(-1),
533@@ -44,14 +43,16 @@
534 QString qmlSuffix = ".qml";
535 QString disabledSuffix = ".disabled";
536 QSet<QString> disabledPages;
537- QStringList dataDirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
538+ QStringList dataDirs;
539
540- QString rootDir = qgetenv("UBUNTU_SYSTEM_SETTINGS_WIZARD_ROOT"); // for testing
541- if (!rootDir.isEmpty())
542- dataDirs = QStringList() << rootDir;
543+ if (!isRunningInstalled() && getenv("UNITY_TEST_ENV") == nullptr) {
544+ dataDirs = QStringList() << qmlDirectory();
545+ } else {
546+ dataDirs = shellDataDirs();
547+ }
548
549 Q_FOREACH(const QString &dataDir, dataDirs) {
550- QDir dir(dataDir + "/ubuntu/settings/wizard/qml/Pages");
551+ QDir dir(dataDir + "/Wizard/Pages");
552 QStringList entries = dir.entryList(QStringList("[0-9]*"), QDir::Files | QDir::Readable);
553 Q_FOREACH(const QString &entry, entries) {
554 if (!m_pages.contains(entry) && entry.endsWith(qmlSuffix))
555
556=== modified file 'plugins/Wizard/PageList.h'
557--- wizard/PageList.h 2014-12-02 18:48:08 +0000
558+++ plugins/Wizard/PageList.h 2014-12-02 18:48:08 +0000
559@@ -1,6 +1,4 @@
560 /*
561- * This file is part of system-settings
562- *
563 * Copyright (C) 2014 Canonical Ltd.
564 *
565 * This program is free software: you can redistribute it and/or modify it
566@@ -16,8 +14,8 @@
567 * with this program. If not, see <http://www.gnu.org/licenses/>.
568 */
569
570-#ifndef PAGELIST_H
571-#define PAGEList_H
572+#ifndef WIZARD_PAGELIST_H
573+#define WIZARD_PAGELIST_H
574
575 #include <QMap>
576 #include <QObject>
577@@ -52,4 +50,4 @@
578 QMap<QString, QString> m_pages;
579 };
580
581-#endif // PAGELIST_H
582+#endif // WIZARD_PAGELIST_H
583
584=== renamed file 'wizard/Utils/system.cpp' => 'plugins/Wizard/System.cpp'
585--- wizard/Utils/system.cpp 2014-12-02 18:48:08 +0000
586+++ plugins/Wizard/System.cpp 2014-12-02 18:48:08 +0000
587@@ -1,6 +1,4 @@
588 /*
589- * This file is part of system-settings
590- *
591 * Copyright (C) 2014 Canonical Ltd.
592 *
593 * This program is free software: you can redistribute it and/or modify it
594@@ -16,103 +14,86 @@
595 * with this program. If not, see <http://www.gnu.org/licenses/>.
596 */
597
598-#include "system.h"
599+#include "System.h"
600+
601 #include <QDBusInterface>
602-#include <QDBusPendingCall>
603-#include <QDBusPendingReply>
604+#include <QDBusMetaType>
605+#include <QDir>
606 #include <QFile>
607+#include <QLocale>
608+#include <QMap>
609 #include <QProcess>
610-#include <unistd.h>
611-
612-#define HERE_IFACE "com.ubuntu.location.providers.here.AccountsService"
613-#define ENABLED_PROP "LicenseAccepted"
614-#define PATH_PROP "LicenseBasePath"
615
616 System::System()
617 : QObject(),
618- m_accounts(nullptr),
619- m_hereEnabled(false),
620- m_hereLicensePath(" ") // use a single space to indicate it is unasssigned
621-{
622- m_accounts = new QDBusInterface("org.freedesktop.Accounts",
623- "/org/freedesktop/Accounts/User" + QString::number(geteuid()),
624- "org.freedesktop.DBus.Properties",
625- QDBusConnection::systemBus(),
626- this);
627-
628- m_accounts->connection().connect(m_accounts->service(),
629- m_accounts->path(),
630- m_accounts->interface(),
631- "PropertiesChanged",
632- this,
633- SLOT(propertiesChanged(QString, QVariantMap, QStringList)));
634-
635- QDBusPendingCall call = m_accounts->asyncCall("Get", HERE_IFACE, PATH_PROP);
636- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
637- QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)),
638- this, SLOT(getHereLicensePathFinished(QDBusPendingCallWatcher *)));
639-}
640-
641-void System::propertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalid)
642-{
643- if (interface == HERE_IFACE) {
644- if (changed.contains(ENABLED_PROP)) {
645- m_hereEnabled = changed[ENABLED_PROP].toBool();
646- Q_EMIT hereEnabledChanged();
647- } else if (invalid.contains(ENABLED_PROP)) {
648- QDBusPendingCall call = m_accounts->asyncCall("Get", HERE_IFACE, ENABLED_PROP);
649- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
650- QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)),
651- this, SLOT(getHereEnabledFinished(QDBusPendingCallWatcher *)));
652- }
653- }
654-}
655-
656-void System::getHereEnabledFinished(QDBusPendingCallWatcher *watcher)
657-{
658- QDBusPendingReply<QVariant> reply = *watcher;
659- if (!reply.isError()) {
660- QVariant value = reply.argumentAt<0>();
661- m_hereEnabled = value.toBool();
662- Q_EMIT hereEnabledChanged();
663- }
664- watcher->deleteLater();
665-}
666-
667-void System::getHereLicensePathFinished(QDBusPendingCallWatcher *watcher)
668-{
669- QDBusPendingReply<QVariant> reply = *watcher;
670-
671- m_hereLicensePath = "";
672-
673- if (!reply.isError()) {
674- QVariant value = reply.argumentAt<0>();
675- if (QFile::exists(value.toString())) {
676- m_hereLicensePath = value.toString();
677- }
678- }
679-
680- Q_EMIT hereLicensePathChanged();
681-
682- watcher->deleteLater();
683-}
684-
685-bool System::hereEnabled() const
686-{
687- return m_hereEnabled;
688-}
689-
690-void System::setHereEnabled(bool enabled)
691-{
692- m_accounts->asyncCall("Set", HERE_IFACE, ENABLED_PROP, QVariant::fromValue(QDBusVariant(enabled)));
693-}
694-
695-QString System::hereLicensePath() const
696-{
697- return m_hereLicensePath;
698-}
699-
700-void System::updateSessionLanguage()
701-{
702- 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\"");
703+ m_fsWatcher()
704+{
705+ // Register the argument needed for UpdateActivationEnvironment below
706+ qDBusRegisterMetaType<QMap<QString,QString>>();
707+
708+ m_fsWatcher.addPath(wizardEnabledPath());
709+ connect(&m_fsWatcher, SIGNAL(fileChanged(const QString &)),
710+ this, SIGNAL(wizardEnabledChanged()));
711+}
712+
713+QString System::wizardEnabledPath()
714+{
715+ // Uses ubuntu-system-settings namespace for historic compatibility reasons
716+ return QDir::home().filePath(".config/ubuntu-system-settings/wizard-has-run");
717+}
718+
719+bool System::wizardEnabled() const
720+{
721+ return !QFile::exists(wizardEnabledPath());
722+}
723+
724+void System::setWizardEnabled(bool enabled)
725+{
726+ if (wizardEnabled() == enabled)
727+ return;
728+
729+ if (enabled) {
730+ QFile::remove(wizardEnabledPath());
731+ } else {
732+ QDir(wizardEnabledPath()).mkpath("..");
733+ QFile(wizardEnabledPath()).open(QIODevice::WriteOnly);
734+ m_fsWatcher.addPath(wizardEnabledPath());
735+ wizardEnabledChanged();
736+ }
737+}
738+
739+void System::setSessionVariable(const QString &variable, const QString &value)
740+{
741+ // We need to update both upstart's and DBus's environment
742+ QProcess::execute(QString("initctl set-env --global %1=%2").arg(variable, value));
743+
744+ QDBusInterface iface("org.freedesktop.DBus",
745+ "/org/freedesktop/DBus",
746+ "org.freedesktop.DBus",
747+ QDBusConnection::sessionBus());
748+
749+ QMap<QString,QString> valueMap;
750+ valueMap.insert(variable, value);
751+ iface.call("UpdateActivationEnvironment", QVariant::fromValue(valueMap));
752+}
753+
754+void System::updateSessionLanguage(const QString &locale)
755+{
756+ QString language = locale.split(".")[0];
757+
758+ setSessionVariable("LANGUAGE", language);
759+ setSessionVariable("LANG", locale);
760+ setSessionVariable("LC_ALL", locale);
761+
762+ // QLocale caches the default locale on startup, and Qt uses that cached
763+ // copy when formatting dates. So manually update it here.
764+ QLocale::setDefault(QLocale(locale));
765+
766+ // Restart bits of the session to pick up new language.
767+ QProcess::startDetached("sh -c \"initctl emit indicator-services-end; \
768+ initctl stop scope-registry; \
769+ initctl stop smart-scopes-proxy; \
770+ initctl emit --no-wait indicator-services-start; \
771+ initctl restart --no-wait maliit-server; \
772+ initctl restart --no-wait unity8-dash\"");
773 }
774
775=== renamed file 'wizard/Utils/system.h' => 'plugins/Wizard/System.h'
776--- wizard/Utils/system.h 2014-12-02 18:48:08 +0000
777+++ plugins/Wizard/System.h 2014-12-02 18:48:08 +0000
778@@ -1,6 +1,4 @@
779 /*
780- * This file is part of system-settings
781- *
782 * Copyright (C) 2014 Canonical Ltd.
783 *
784 * This program is free software: you can redistribute it and/or modify it
785@@ -16,42 +14,37 @@
786 * with this program. If not, see <http://www.gnu.org/licenses/>.
787 */
788
789+#ifndef WIZARD_SYSTEM_H
790+#define WIZARD_SYSTEM_H
791+
792+#include <QFileSystemWatcher>
793 #include <QObject>
794 #include <QString>
795
796-class QDBusInterface;
797-class QDBusPendingCallWatcher;
798-
799 class System : public QObject
800 {
801 Q_OBJECT
802- Q_PROPERTY(bool hereEnabled READ hereEnabled WRITE setHereEnabled NOTIFY hereEnabledChanged)
803- Q_PROPERTY(QString hereLicensePath READ hereLicensePath NOTIFY hereLicensePathChanged)
804+ Q_PROPERTY(bool wizardEnabled READ wizardEnabled WRITE setWizardEnabled NOTIFY wizardEnabledChanged)
805
806 public:
807 System();
808
809- bool hereEnabled() const;
810- void setHereEnabled(bool enabled);
811-
812- QString hereLicensePath() const;
813+ bool wizardEnabled() const;
814+ void setWizardEnabled(bool enabled);
815
816 public Q_SLOTS:
817- void updateSessionLanguage();
818+ void updateSessionLanguage(const QString &locale);
819
820 Q_SIGNALS:
821- void hereEnabledChanged();
822- void hereLicensePathChanged();
823-
824-private Q_SLOTS:
825- void propertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalid);
826- void getHereEnabledFinished(QDBusPendingCallWatcher *watcher);
827- void getHereLicensePathFinished(QDBusPendingCallWatcher *watcher);
828+ void wizardEnabledChanged();
829
830 private:
831 Q_DISABLE_COPY(System)
832
833- QDBusInterface *m_accounts;
834- bool m_hereEnabled;
835- QString m_hereLicensePath;
836+ static QString wizardEnabledPath();
837+ static void setSessionVariable(const QString &variable, const QString &value);
838+
839+ QFileSystemWatcher m_fsWatcher;
840 };
841+
842+#endif
843
844=== added file 'plugins/Wizard/Wizard.qmltypes'
845--- plugins/Wizard/Wizard.qmltypes 1970-01-01 00:00:00 +0000
846+++ plugins/Wizard/Wizard.qmltypes 2014-12-02 18:48:08 +0000
847@@ -0,0 +1,36 @@
848+import QtQuick.tooling 1.1
849+
850+// This file describes the plugin-supplied types contained in the library.
851+// It is used for QML tooling purposes only.
852+//
853+// This file was auto-generated by:
854+// 'qmlplugindump -notrelocatable Wizard 0.1 plugins'
855+
856+Module {
857+ Component {
858+ name: "PageList"
859+ prototype: "QObject"
860+ exports: ["Wizard/PageList 0.1"]
861+ isCreatable: false
862+ isSingleton: true
863+ exportMetaObjectRevisions: [0]
864+ Property { name: "index"; type: "int"; isReadonly: true }
865+ Property { name: "numPages"; type: "int"; isReadonly: true }
866+ Method { name: "prev"; type: "string" }
867+ Method { name: "next"; type: "string" }
868+ }
869+ Component {
870+ name: "System"
871+ prototype: "QObject"
872+ exports: ["Wizard/System 0.1"]
873+ isCreatable: false
874+ isSingleton: true
875+ exportMetaObjectRevisions: [0]
876+ Property { name: "wizardEnabled"; type: "bool" }
877+ Method {
878+ name: "updateSessionLanguage"
879+ Parameter { name: "locale"; type: "string" }
880+ }
881+ }
882+}
883+
884
885=== added file 'plugins/Wizard/plugin.cpp'
886--- plugins/Wizard/plugin.cpp 1970-01-01 00:00:00 +0000
887+++ plugins/Wizard/plugin.cpp 2014-12-02 18:48:08 +0000
888@@ -0,0 +1,42 @@
889+/*
890+ * Copyright (C) 2014 Canonical Ltd.
891+ *
892+ * This program is free software: you can redistribute it and/or modify it
893+ * under the terms of the GNU General Public License version 3, as published
894+ * by the Free Software Foundation.
895+ *
896+ * This program is distributed in the hope that it will be useful, but
897+ * WITHOUT ANY WARRANTY; without even the implied warranties of
898+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
899+ * PURPOSE. See the GNU General Public License for more details.
900+ *
901+ * You should have received a copy of the GNU General Public License along
902+ * with this program. If not, see <http://www.gnu.org/licenses/>.
903+ */
904+
905+#include "plugin.h"
906+#include "PageList.h"
907+#include "System.h"
908+
909+#include <QtQml/qqml.h>
910+
911+static QObject *pagelist_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
912+{
913+ Q_UNUSED(engine)
914+ Q_UNUSED(scriptEngine)
915+ return new PageList();
916+}
917+
918+static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
919+{
920+ Q_UNUSED(engine)
921+ Q_UNUSED(scriptEngine)
922+ return new System();
923+}
924+
925+void WizardPlugin::registerTypes(const char *uri)
926+{
927+ Q_ASSERT(uri == QLatin1String("Wizard"));
928+ qmlRegisterSingletonType<PageList>(uri, 0, 1, "PageList", pagelist_provider);
929+ qmlRegisterSingletonType<System>(uri, 0, 1, "System", system_provider);
930+}
931
932=== added file 'plugins/Wizard/plugin.h'
933--- plugins/Wizard/plugin.h 1970-01-01 00:00:00 +0000
934+++ plugins/Wizard/plugin.h 2014-12-02 18:48:08 +0000
935@@ -0,0 +1,32 @@
936+/*
937+ * Copyright (C) 2014 Canonical, Ltd.
938+ *
939+ * This program is free software; you can redistribute it and/or modify
940+ * it under the terms of the GNU General Public License as published by
941+ * the Free Software Foundation; version 3.
942+ *
943+ * This program is distributed in the hope that it will be useful,
944+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
945+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
946+ * GNU General Public License for more details.
947+ *
948+ * You should have received a copy of the GNU General Public License
949+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
950+ */
951+
952+#ifndef WIZARD_PLUGIN_H
953+#define WIZARD_PLUGIN_H
954+
955+#include <QtQml/QQmlEngine>
956+#include <QtQml/QQmlExtensionPlugin>
957+
958+class WizardPlugin : public QQmlExtensionPlugin
959+{
960+ Q_OBJECT
961+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
962+
963+public:
964+ void registerTypes(const char *uri);
965+};
966+
967+#endif
968
969=== added file 'plugins/Wizard/qmldir'
970--- plugins/Wizard/qmldir 1970-01-01 00:00:00 +0000
971+++ plugins/Wizard/qmldir 2014-12-02 18:48:08 +0000
972@@ -0,0 +1,3 @@
973+module Wizard
974+plugin Wizard-qml
975+typeinfo Wizard.qmltypes
976
977=== modified file 'qml/CMakeLists.txt'
978--- qml/CMakeLists.txt 2014-10-28 11:06:31 +0000
979+++ qml/CMakeLists.txt 2014-12-02 18:48:08 +0000
980@@ -13,6 +13,7 @@
981 Launcher
982 Stages
983 Notifications
984+ Wizard
985 )
986
987 install(DIRECTORY ${QML_DIRS}
988
989=== modified file 'qml/Components/Dialogs.qml'
990--- qml/Components/Dialogs.qml 2014-10-31 09:38:22 +0000
991+++ qml/Components/Dialogs.qml 2014-12-02 18:48:08 +0000
992@@ -24,10 +24,6 @@
993 Item {
994 id: root
995
996- // Explicitly use the right domain for this widget because it might be used
997- // in other applications like the welcome wizard.
998- readonly property string domain: "unity8"
999-
1000 function onPowerKeyPressed() {
1001 // FIXME: event.isAutoRepeat is always false on Nexus 4.
1002 // So we use powerKeyTimer.running to avoid the PowerOff key repeat
1003@@ -71,17 +67,17 @@
1004 id: logoutDialog
1005 Dialog {
1006 id: dialogueLogout
1007- title: i18n.dtr(root.domain, "Log out")
1008- text: i18n.dtr(root.domain, "Are you sure you want to log out?")
1009+ title: i18n.tr("Log out")
1010+ text: i18n.tr("Are you sure you want to log out?")
1011 Button {
1012- text: i18n.dtr(root.domain, "No")
1013+ text: i18n.tr("No")
1014 onClicked: {
1015 PopupUtils.close(dialogueLogout);
1016 d.dialogShown = false;
1017 }
1018 }
1019 Button {
1020- text: i18n.dtr(root.domain, "Yes")
1021+ text: i18n.tr("Yes")
1022 onClicked: {
1023 DBusUnitySessionService.Logout();
1024 PopupUtils.close(dialogueLogout);
1025@@ -95,17 +91,17 @@
1026 id: shutdownDialog
1027 Dialog {
1028 id: dialogueShutdown
1029- title: i18n.dtr(root.domain, "Shut down")
1030- text: i18n.dtr(root.domain, "Are you sure you want to shut down?")
1031+ title: i18n.tr("Shut down")
1032+ text: i18n.tr("Are you sure you want to shut down?")
1033 Button {
1034- text: i18n.dtr(root.domain, "No")
1035+ text: i18n.tr("No")
1036 onClicked: {
1037 PopupUtils.close(dialogueShutdown);
1038 d.dialogShown = false;
1039 }
1040 }
1041 Button {
1042- text: i18n.dtr(root.domain, "Yes")
1043+ text: i18n.tr("Yes")
1044 onClicked: {
1045 dBusUnitySessionServiceConnection.closeAllApps();
1046 DBusUnitySessionService.Shutdown();
1047@@ -120,17 +116,17 @@
1048 id: rebootDialog
1049 Dialog {
1050 id: dialogueReboot
1051- title: i18n.dtr(root.domain, "Reboot")
1052- text: i18n.dtr(root.domain, "Are you sure you want to reboot?")
1053+ title: i18n.tr("Reboot")
1054+ text: i18n.tr("Are you sure you want to reboot?")
1055 Button {
1056- text: i18n.dtr(root.domain, "No")
1057+ text: i18n.tr("No")
1058 onClicked: {
1059 PopupUtils.close(dialogueReboot)
1060 d.dialogShown = false;
1061 }
1062 }
1063 Button {
1064- text: i18n.dtr(root.domain, "Yes")
1065+ text: i18n.tr("Yes")
1066 onClicked: {
1067 dBusUnitySessionServiceConnection.closeAllApps();
1068 DBusUnitySessionService.Reboot();
1069@@ -145,10 +141,10 @@
1070 id: powerDialog
1071 Dialog {
1072 id: dialoguePower
1073- title: i18n.dtr(root.domain, "Power")
1074- text: i18n.dtr(root.domain, "Are you sure you would like\nto power off?")
1075+ title: i18n.tr("Power")
1076+ text: i18n.tr("Are you sure you would like\nto power off?")
1077 Button {
1078- text: i18n.dtr(root.domain, "Power off")
1079+ text: i18n.tr("Power off")
1080 onClicked: {
1081 dBusUnitySessionServiceConnection.closeAllApps();
1082 PopupUtils.close(dialoguePower);
1083@@ -158,7 +154,7 @@
1084 color: UbuntuColors.red
1085 }
1086 Button {
1087- text: i18n.dtr(root.domain, "Restart")
1088+ text: i18n.tr("Restart")
1089 onClicked: {
1090 dBusUnitySessionServiceConnection.closeAllApps();
1091 DBusUnitySessionService.Reboot();
1092@@ -168,7 +164,7 @@
1093 color: UbuntuColors.green
1094 }
1095 Button {
1096- text: i18n.dtr(root.domain, "Cancel")
1097+ text: i18n.tr("Cancel")
1098 onClicked: {
1099 PopupUtils.close(dialoguePower);
1100 d.dialogShown = false;
1101
1102=== modified file 'qml/Components/EdgeDemo.qml'
1103--- qml/Components/EdgeDemo.qml 2014-10-17 09:29:42 +0000
1104+++ qml/Components/EdgeDemo.qml 2014-12-02 18:48:08 +0000
1105@@ -17,6 +17,7 @@
1106 import AccountsService 0.1
1107 import LightDM 0.1 as LightDM
1108 import QtQuick 2.0
1109+import Ubuntu.Components 1.1
1110
1111 Item {
1112 id: demo
1113@@ -61,11 +62,16 @@
1114 stagesEnabled = true
1115 panelEnabled = true
1116 panelContentEnabled = true
1117- if (d.rightEdgeDemo) d.rightEdgeDemo.destroy()
1118- if (d.topEdgeDemo) d.topEdgeDemo.destroy()
1119- if (d.bottomEdgeDemo) d.bottomEdgeDemo.destroy()
1120- if (d.leftEdgeDemo) d.leftEdgeDemo.destroy()
1121- if (d.finalEdgeDemo) d.finalEdgeDemo.destroy()
1122+
1123+ // Use a tiny delay for these destroy() calls because if a lot is
1124+ // happening at once (like creating and being destroyed in same event
1125+ // loop, as might happen when answering a call while demo is open),
1126+ // the destroy() call will be ignored.
1127+ if (d.rightEdgeDemo) d.rightEdgeDemo.destroy(1);
1128+ if (d.topEdgeDemo) d.topEdgeDemo.destroy(1);
1129+ if (d.bottomEdgeDemo) d.bottomEdgeDemo.destroy(1);
1130+ if (d.leftEdgeDemo) d.leftEdgeDemo.destroy(1);
1131+ if (d.finalEdgeDemo) d.finalEdgeDemo.destroy(1);
1132 }
1133
1134 function startDemo() {
1135@@ -97,12 +103,19 @@
1136 property bool showEdgeDemo: AccountsService.demoEdges
1137 property bool showEdgeDemoInGreeter: AccountsService.demoEdges // TODO: AccountsService.demoEdges as lightdm user
1138
1139- onShowEdgeDemoChanged: {
1140+ function restartDemo() {
1141 stopDemo()
1142 if (d.showEdgeDemo) {
1143 startDemo()
1144 }
1145 }
1146+
1147+ onShowEdgeDemoChanged: restartDemo()
1148+ }
1149+
1150+ Connections {
1151+ target: i18n
1152+ onLanguageChanged: d.restartDemo()
1153 }
1154
1155 function startRightEdgeDemo() {
1156
1157=== modified file 'qml/Greeter/Clock.qml'
1158--- qml/Greeter/Clock.qml 2014-10-07 10:28:59 +0000
1159+++ qml/Greeter/Clock.qml 2014-12-02 18:48:08 +0000
1160@@ -34,6 +34,16 @@
1161 }
1162 }
1163
1164+ Connections {
1165+ target: i18n
1166+ onLanguageChanged: {
1167+ if (visible) {
1168+ timeLabel.text = Qt.formatTime(clock.currentDate); // kicks time
1169+ clock.currentDate = new Date(); // kicks date
1170+ }
1171+ }
1172+ }
1173+
1174 Indicators.SharedUnityMenuModel {
1175 id: timeModel
1176 objectName: "timeModel"
1177
1178=== modified file 'qml/Greeter/GreeterContent.qml'
1179--- qml/Greeter/GreeterContent.qml 2014-11-07 11:54:10 +0000
1180+++ qml/Greeter/GreeterContent.qml 2014-12-02 18:48:08 +0000
1181@@ -133,6 +133,11 @@
1182 onSelected: infographics.selectedUser = greeterContentLoader.model.data(uid, LightDM.UserRoles.NameRole)
1183 }
1184
1185+ Connections {
1186+ target: i18n
1187+ onLanguageChanged: greeterContentLoader.infographicModel.readyForDataChange()
1188+ }
1189+
1190 anchors {
1191 verticalCenter: parent.verticalCenter
1192 left: narrowMode ? root.left : loginLoader.right
1193
1194=== modified file 'qml/Launcher/Launcher.qml'
1195--- qml/Launcher/Launcher.qml 2014-11-04 12:54:03 +0000
1196+++ qml/Launcher/Launcher.qml 2014-12-02 18:48:08 +0000
1197@@ -118,6 +118,11 @@
1198 onHint: hint();
1199 }
1200
1201+ Connections {
1202+ target: i18n
1203+ onLanguageChanged: LauncherModel.refresh()
1204+ }
1205+
1206 SequentialAnimation {
1207 id: fadeOutAnimation
1208 ScriptAction {
1209
1210=== modified file 'qml/Shell.qml'
1211--- qml/Shell.qml 2014-12-02 09:26:10 +0000
1212+++ qml/Shell.qml 2014-12-02 18:48:08 +0000
1213@@ -37,6 +37,7 @@
1214 import "Notifications"
1215 import "Stages"
1216 import "Panel/Indicators"
1217+import "Wizard"
1218 import Unity.Notifications 1.0 as NotificationBackend
1219 import Unity.Session 0.1
1220 import Unity.DashCommunicator 0.1
1221@@ -236,6 +237,14 @@
1222 onApplicationAdded: {
1223 if (greeter.shown && appId != "unity8-dash") {
1224 greeter.startUnlock()
1225+
1226+ // If this happens on first boot, we may be in edge
1227+ // tutorial or wizard while receiving a call. But a call
1228+ // is more important than wizard so just bail out of those.
1229+ if (edgeDemo.running) {
1230+ edgeDemo.hideEdgeDemos();
1231+ wizard.hide();
1232+ }
1233 }
1234 if (greeter.narrowMode && greeter.hasLockedApp && appId === greeter.lockedApp) {
1235 lockscreen.hide() // show locked app
1236@@ -354,6 +363,15 @@
1237 minPinLength: 4
1238 maxPinLength: 4
1239
1240+ property string promptText
1241+ infoText: promptText !== "" ? i18n.tr("Enter %1").arg(promptText) :
1242+ alphaNumeric ? i18n.tr("Enter passphrase") :
1243+ i18n.tr("Enter passcode")
1244+ errorText: promptText !== "" ? i18n.tr("Sorry, incorrect %1").arg(promptText) :
1245+ alphaNumeric ? i18n.tr("Sorry, incorrect passphrase") + "\n" +
1246+ i18n.tr("Please re-enter") :
1247+ i18n.tr("Sorry, incorrect passcode")
1248+
1249 // FIXME: We *should* show emergency dialer if there is a SIM present,
1250 // regardless of whether the side stage is enabled. But right now,
1251 // the assumption is that narrow screens are phones which have SIMs
1252@@ -407,20 +425,7 @@
1253 return; // could happen if hideGreeter() comes in before we prompt
1254 }
1255 if (greeter.narrowMode) {
1256- if (isDefaultPrompt) {
1257- if (lockscreen.alphaNumeric) {
1258- lockscreen.infoText = i18n.tr("Enter passphrase")
1259- lockscreen.errorText = i18n.tr("Sorry, incorrect passphrase") + "\n" +
1260- i18n.tr("Please re-enter")
1261- } else {
1262- lockscreen.infoText = i18n.tr("Enter passcode")
1263- lockscreen.errorText = i18n.tr("Sorry, incorrect passcode")
1264- }
1265- } else {
1266- lockscreen.infoText = i18n.tr("Enter %1").arg(text.toLowerCase())
1267- lockscreen.errorText = i18n.tr("Sorry, incorrect %1").arg(text.toLowerCase())
1268- }
1269-
1270+ lockscreen.promptText = isDefaultPrompt ? "" : text.toLowerCase();
1271 lockscreen.maybeShow();
1272 }
1273 }
1274@@ -748,6 +753,12 @@
1275 }
1276 }
1277
1278+ Wizard {
1279+ id: wizard
1280+ anchors.fill: parent
1281+ background: shell.background
1282+ }
1283+
1284 Rectangle {
1285 id: modalNotificationBackground
1286
1287@@ -809,7 +820,7 @@
1288 id: edgeDemo
1289 objectName: "edgeDemo"
1290 z: dialogs.z + 10
1291- paused: Powerd.status === Powerd.Off // Saves power
1292+ paused: Powerd.status === Powerd.Off || wizard.active // Saves power
1293 greeter: greeter
1294 launcher: launcher
1295 panel: panel
1296
1297=== renamed directory 'wizard/qml' => 'qml/Wizard'
1298=== renamed file 'wizard/qml/Components/CheckableSetting.qml' => 'qml/Wizard/CheckableSetting.qml'
1299--- wizard/qml/Components/CheckableSetting.qml 2014-12-02 18:48:08 +0000
1300+++ qml/Wizard/CheckableSetting.qml 2014-12-02 18:48:08 +0000
1301@@ -15,7 +15,6 @@
1302 */
1303
1304 import QtQuick 2.3
1305-import QMenuModel 0.1
1306 import Ubuntu.Components 1.1
1307 import Ubuntu.Components.ListItems 1.0 as ListItem
1308
1309
1310=== renamed file 'wizard/qml/Components/Page.qml' => 'qml/Wizard/Page.qml'
1311--- wizard/qml/Components/Page.qml 2014-12-02 18:48:08 +0000
1312+++ qml/Wizard/Page.qml 2014-12-02 18:48:08 +0000
1313@@ -16,7 +16,6 @@
1314
1315 import QtQuick 2.3
1316 import Ubuntu.Components 1.1
1317-import "." as LocalComponents
1318
1319 Item {
1320 readonly property real buttonMargin: units.gu(2)
1321@@ -76,7 +75,7 @@
1322 }
1323 }
1324
1325- LocalComponents.StackButton {
1326+ StackButton {
1327 id: backButton
1328 width: buttonWidth
1329 anchors {
1330
1331=== renamed file 'wizard/qml/main.qml' => 'qml/Wizard/Pages.qml'
1332--- wizard/qml/main.qml 2014-12-02 18:48:08 +0000
1333+++ qml/Wizard/Pages.qml 2014-12-02 18:48:08 +0000
1334@@ -15,42 +15,30 @@
1335 */
1336
1337 import QtQuick 2.3
1338-import GSettings 1.0
1339 import Ubuntu.Components 1.1
1340 import Ubuntu.SystemSettings.SecurityPrivacy 1.0
1341-import Unity.Application 0.1
1342-import Unity.Notifications 1.0 as NotificationBackend
1343-import Unity.Session 0.1
1344-import "Components"
1345-import "file:///usr/share/unity8/Notifications" as Notifications // FIXME This should become a module or go away
1346-import "file:///usr/share/unity8/Components" as UnityComponents
1347+import Wizard 0.1
1348+import "../Components"
1349
1350 Item {
1351 id: root
1352- width: units.gu(40)
1353- height: units.gu(71)
1354 focus: true
1355
1356+ // The background wallpaper to use
1357+ property string background
1358+
1359+ signal quit()
1360+
1361 // These should be set by a security page and we apply the settings when
1362 // the user exits the wizard.
1363 property int passwordMethod: UbuntuSecurityPrivacyPanel.Passcode
1364 property string password: ""
1365
1366- Component.onCompleted: {
1367- Theme.name = "Ubuntu.Components.Themes.SuruGradient"
1368- // A visible selected background looks bad in ListItem widgets with our theme
1369- Theme.palette.selected.background = "#00000000"
1370- i18n.domain = "unity8"
1371- }
1372-
1373 UbuntuSecurityPrivacyPanel {
1374 id: securityPrivacy
1375 }
1376
1377 function quitWizard() {
1378- // Immediately go to black to give quick feedback
1379- blackCover.visible = true
1380-
1381 var errorMsg = securityPrivacy.setSecurity("", password, passwordMethod)
1382 if (errorMsg !== "") {
1383 // Ignore (but log) any errors, since we're past where the user set
1384@@ -59,188 +47,83 @@
1385 console.log("Error setting security method:", errorMsg)
1386 }
1387
1388- Qt.quit()
1389- }
1390-
1391- // This is just a little screen to immediately go to black once the wizard
1392- // is done, to give quick feedback to the user.
1393- Rectangle {
1394- id: blackCover
1395- color: "#000000"
1396- anchors.fill: parent
1397- z: 1
1398- visible: false
1399- }
1400-
1401- MainView {
1402- anchors.fill: parent
1403- headerColor: "#57365E"
1404- backgroundColor: "#A55263"
1405- footerColor: "#D75669"
1406- anchorToKeyboard: true
1407- useDeprecatedToolbar: false
1408-
1409- GSettings {
1410- id: background
1411- schema.id: "org.gnome.desktop.background"
1412- }
1413-
1414- Image {
1415- id: image
1416- // Use x/y/height/width instead of anchors so that we don't adjust
1417- // the image when the OSK appears.
1418- x: 0
1419- y: 0
1420- height: root.height
1421- width: root.width
1422- source: background.pictureUri
1423- fillMode: Image.PreserveAspectCrop
1424- visible: status === Image.Ready
1425- }
1426-
1427- PageStack {
1428- id: pageStack
1429-
1430- function next() {
1431- // If we've opened any extra (non-main) pages, pop them before
1432- // continuing so back button returns to the previous main page.
1433- while (pageList.index < pageStack.depth - 1)
1434- pop()
1435- load(pageList.next())
1436- }
1437-
1438- function prev() {
1439- if (pageList.index >= pageStack.depth - 1)
1440- pageList.prev() // update pageList.index, but not for extra pages
1441+ quit();
1442+ }
1443+
1444+ MouseArea { // eat anything that gets past widgets
1445+ anchors.fill: parent
1446+ }
1447+
1448+ Image {
1449+ id: image
1450+ // Use x/y/height/width instead of anchors so that we don't adjust
1451+ // the image when the OSK appears.
1452+ x: 0
1453+ y: 0
1454+ height: root.height
1455+ width: root.width
1456+ sourceSize.height: height
1457+ sourceSize.width: width
1458+ source: root.background
1459+ fillMode: Image.PreserveAspectCrop
1460+ visible: status === Image.Ready
1461+ }
1462+
1463+ PageStack {
1464+ id: pageStack
1465+ anchors.fill: parent
1466+
1467+ function next() {
1468+ // If we've opened any extra (non-main) pages, pop them before
1469+ // continuing so back button returns to the previous main page.
1470+ while (PageList.index < pageStack.depth - 1)
1471 pop()
1472- if (!currentPage || currentPage.opacity === 0) { // undo skipped pages
1473- prev()
1474+ load(PageList.next())
1475+ }
1476+
1477+ function prev() {
1478+ if (PageList.index >= pageStack.depth - 1)
1479+ PageList.prev() // update PageList.index, but not for extra pages
1480+ pop()
1481+ if (!currentPage || currentPage.opacity === 0) { // undo skipped pages
1482+ prev()
1483+ } else {
1484+ currentPage.enabled = true
1485+ }
1486+ }
1487+
1488+ function load(path) {
1489+ if (currentPage) {
1490+ currentPage.enabled = false
1491+ }
1492+
1493+ // First load it invisible, check that we should actually use
1494+ // this page, and either skip it or continue.
1495+ push(path, {"opacity": 0, "enabled": false})
1496+
1497+ // Check for immediate skip or not. We may have to wait for
1498+ // skipValid to be assigned (see Connections object below)
1499+ checkSkip()
1500+ }
1501+
1502+ function checkSkip() {
1503+ if (!currentPage) { // may have had a parse error
1504+ next()
1505+ } else if (currentPage.skipValid) {
1506+ if (currentPage.skip) {
1507+ next()
1508 } else {
1509+ currentPage.opacity = 1
1510 currentPage.enabled = true
1511 }
1512 }
1513-
1514- function load(path) {
1515- if (currentPage) {
1516- currentPage.enabled = false
1517- }
1518-
1519- // First load it invisible, check that we should actually use
1520- // this page, and either skip it or continue.
1521- push(path, {"opacity": 0, "enabled": false})
1522-
1523- // Check for immediate skip or not. We may have to wait for
1524- // skipValid to be assigned (see Connections object below)
1525- _checkSkip()
1526- }
1527-
1528- function _checkSkip() {
1529- if (!currentPage) { // may have had a parse error
1530- next()
1531- } else if (currentPage.skipValid) {
1532- if (currentPage.skip) {
1533- next()
1534- } else {
1535- currentPage.opacity = 1
1536- currentPage.enabled = true
1537- }
1538- }
1539- }
1540-
1541- Connections {
1542- target: pageStack.currentPage
1543- onSkipValidChanged: pageStack._checkSkip()
1544- }
1545-
1546- Component.onCompleted: next()
1547- }
1548- }
1549-
1550- Rectangle {
1551- id: modalNotificationBackground
1552- visible: notifications.useModal && (notifications.state == "narrow")
1553- anchors.fill: parent
1554- color: "#80000000"
1555-
1556- MouseArea {
1557- anchors.fill: parent
1558- }
1559- }
1560-
1561- InputMethod {
1562- anchors.fill: parent
1563- }
1564-
1565- Notifications.Notifications {
1566- id: notifications
1567- model: NotificationBackend.Model
1568- margin: units.gu(1)
1569- anchors {
1570- top: parent.top
1571- right: parent.right
1572- bottom: parent.bottom
1573- }
1574- states: [
1575- State {
1576- name: "narrow"
1577- when: parent.width <= units.gu(60)
1578- AnchorChanges { target: notifications; anchors.left: parent.left }
1579- },
1580- State {
1581- name: "wide"
1582- when: parent.width > units.gu(60)
1583- AnchorChanges { target: notifications; anchors.left: undefined }
1584- PropertyChanges { target: notifications; width: units.gu(38) }
1585- }
1586- ]
1587- }
1588-
1589- UnityComponents.Dialogs {
1590- id: dialogs
1591- anchors.fill: parent
1592- z: 10
1593- onPowerOffClicked: {
1594- shutdownFadeOutRectangle.enabled = true;
1595- shutdownFadeOutRectangle.visible = true;
1596- shutdownFadeOut.start();
1597- }
1598- }
1599-
1600- Rectangle {
1601- id: shutdownFadeOutRectangle
1602- z: dialogs.z + 10
1603- enabled: false
1604- visible: false
1605- color: "black"
1606- anchors.fill: parent
1607- opacity: 0.0
1608- NumberAnimation on opacity {
1609- id: shutdownFadeOut
1610- from: 0.0
1611- to: 1.0
1612- onStopped: {
1613- if (shutdownFadeOutRectangle.enabled && shutdownFadeOutRectangle.visible) {
1614- DBusUnitySessionService.Shutdown();
1615- }
1616- }
1617- }
1618- }
1619-
1620- Keys.onPressed: {
1621- if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
1622- dialogs.onPowerKeyPressed();
1623- event.accepted = true;
1624- } else {
1625- event.accepted = false;
1626- }
1627- }
1628-
1629- Keys.onReleased: {
1630- if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
1631- dialogs.onPowerKeyReleased();
1632- event.accepted = true;
1633- } else {
1634- event.accepted = false;
1635- }
1636+ }
1637+
1638+ Connections {
1639+ target: pageStack.currentPage
1640+ onSkipValidChanged: pageStack.checkSkip()
1641+ }
1642+
1643+ Component.onCompleted: next()
1644 }
1645 }
1646
1647=== modified file 'qml/Wizard/Pages/10-welcome.qml'
1648--- wizard/qml/Pages/10-welcome.qml 2014-12-02 18:48:08 +0000
1649+++ qml/Wizard/Pages/10-welcome.qml 2014-12-02 18:48:08 +0000
1650@@ -18,8 +18,8 @@
1651 import Ubuntu.Components 1.1
1652 import Ubuntu.Components.ListItems 0.1
1653 import Ubuntu.SystemSettings.LanguagePlugin 1.0
1654-import Ubuntu.SystemSettings.Wizard.Utils 0.1
1655-import "../Components" as LocalComponents
1656+import Wizard 0.1
1657+import ".." as LocalComponents
1658
1659 LocalComponents.Page {
1660 title: i18n.tr("Hi!")
1661@@ -72,7 +72,6 @@
1662 listview.currentIndex = index
1663 combo.expanded = false
1664 i18n.language = plugin.languageCodes[index]
1665- i18n.domain = i18n.domain
1666 }
1667 }
1668 }
1669@@ -84,8 +83,11 @@
1670 LocalComponents.StackButton {
1671 text: i18n.tr("Continue")
1672 onClicked: {
1673- plugin.currentLanguage = listview.currentIndex
1674- System.updateSessionLanguage()
1675+ if (plugin.currentLanguage !== listview.currentIndex) {
1676+ plugin.currentLanguage = listview.currentIndex;
1677+ System.updateSessionLanguage(plugin.languageCodes[listview.currentIndex]);
1678+ i18n.language = i18n.language; // re-notify of change after above call (for qlocale change)
1679+ }
1680 pageStack.next()
1681 }
1682 }
1683
1684=== modified file 'qml/Wizard/Pages/20-sim.qml'
1685--- wizard/qml/Pages/20-sim.qml 2014-12-02 18:48:08 +0000
1686+++ qml/Wizard/Pages/20-sim.qml 2014-12-02 18:48:08 +0000
1687@@ -17,7 +17,7 @@
1688 import QtQuick 2.0
1689 import MeeGo.QOfono 0.2
1690 import Ubuntu.Components 0.1
1691-import "../Components" as LocalComponents
1692+import ".." as LocalComponents
1693
1694 LocalComponents.Page {
1695 title: i18n.tr("Add a SIM card and restart your device")
1696
1697=== modified file 'qml/Wizard/Pages/30-passwd-type.qml'
1698--- wizard/qml/Pages/30-passwd-type.qml 2014-12-02 18:48:08 +0000
1699+++ qml/Wizard/Pages/30-passwd-type.qml 2014-12-02 18:48:08 +0000
1700@@ -18,7 +18,7 @@
1701 import Ubuntu.Components 1.1
1702 import Ubuntu.Components.ListItems 1.0
1703 import Ubuntu.SystemSettings.SecurityPrivacy 1.0
1704-import "../Components" as LocalComponents
1705+import ".." as LocalComponents
1706
1707 /**
1708 * One quirk with this page: we don't actually set the password. We avoid
1709@@ -77,6 +77,7 @@
1710 expanded: true
1711 anchors.left: parent.left
1712 anchors.right: parent.right
1713+ property color originalBackground
1714
1715 model: ["", "", ""] // otherwise the delegate will show the text itself and we only want subText
1716
1717@@ -103,6 +104,17 @@
1718 }
1719
1720 style: Item {}
1721+
1722+ Component.onCompleted: {
1723+ // A visible selected background looks bad in ListItem widgets with our theme
1724+ originalBackground = Theme.palette.selected.background
1725+ Theme.palette.selected.background = "transparent"
1726+ }
1727+
1728+ Component.onDestruction: {
1729+ // Restore original theme background
1730+ Theme.palette.selected.background = originalBackground
1731+ }
1732 }
1733 }
1734
1735
1736=== modified file 'qml/Wizard/Pages/40-wifi.qml'
1737--- wizard/qml/Pages/40-wifi.qml 2014-12-02 18:48:08 +0000
1738+++ qml/Wizard/Pages/40-wifi.qml 2014-12-02 18:48:08 +0000
1739@@ -18,9 +18,8 @@
1740 import QMenuModel 0.1 as QMenuModel
1741 import Ubuntu.Components 0.1
1742 import Ubuntu.Components.ListItems 0.1 as ListItem
1743-import Ubuntu.SystemSettings.Wizard.Utils 0.1
1744 import Ubuntu.Settings.Menus 0.1 as Menus
1745-import "../Components" as LocalComponents
1746+import ".." as LocalComponents
1747
1748 LocalComponents.Page {
1749 id: wifiPage
1750
1751=== modified file 'qml/Wizard/Pages/50-location.qml'
1752--- wizard/qml/Pages/50-location.qml 2014-12-02 18:48:08 +0000
1753+++ qml/Wizard/Pages/50-location.qml 2014-12-02 18:48:08 +0000
1754@@ -15,20 +15,20 @@
1755 */
1756
1757 import QtQuick 2.3
1758+import AccountsService 0.1
1759 import QMenuModel 0.1 as QMenuModel
1760 import Qt.labs.folderlistmodel 2.1
1761 import Ubuntu.Components 1.1
1762-import Ubuntu.SystemSettings.Wizard.Utils 0.1
1763-import "../Components" as LocalComponents
1764+import ".." as LocalComponents
1765
1766 LocalComponents.Page {
1767 title: i18n.tr("Location")
1768 forwardButtonSourceComponent: forwardButton
1769
1770- property bool pathSet: System.hereLicensePath !== " " // single space means it's unassigned
1771+ property bool pathSet: AccountsService.hereLicensePathValid
1772 property bool countSet: false
1773- skipValid: pathSet && (System.hereLicensePath === "" || countSet)
1774- skip: skipValid && (System.hereLicensePath === "" || termsModel.count === 0)
1775+ skipValid: pathSet && (AccountsService.hereLicensePath === "" || countSet)
1776+ skip: skipValid && (AccountsService.hereLicensePath === "" || termsModel.count === 0)
1777
1778 Connections {
1779 target: termsModel
1780@@ -37,7 +37,7 @@
1781
1782 FolderListModel {
1783 id: termsModel
1784- folder: System.hereLicensePath
1785+ folder: AccountsService.hereLicensePath
1786 nameFilters: ["*.html"]
1787 showDirs: false
1788 showOnlyReadable: true
1789@@ -141,7 +141,7 @@
1790 if (locationActionGroup.gps.state != gpsOn) {
1791 locationActionGroup.gps.activate();
1792 }
1793- System.hereEnabled = hereOn;
1794+ AccountsService.hereEnabled = hereOn;
1795 pageStack.next()
1796 }
1797 }
1798
1799=== modified file 'qml/Wizard/Pages/60-reporting.qml'
1800--- wizard/qml/Pages/60-reporting.qml 2014-12-02 18:48:08 +0000
1801+++ qml/Wizard/Pages/60-reporting.qml 2014-12-02 18:48:08 +0000
1802@@ -16,7 +16,7 @@
1803
1804 import QtQuick 2.0
1805 import Ubuntu.Components 0.1
1806-import "../Components" as LocalComponents
1807+import ".." as LocalComponents
1808
1809 LocalComponents.Page {
1810 title: i18n.tr("Improving your experience")
1811
1812=== modified file 'qml/Wizard/Pages/80-finished.qml'
1813--- wizard/qml/Pages/80-finished.qml 2014-12-02 18:48:08 +0000
1814+++ qml/Wizard/Pages/80-finished.qml 2014-12-02 18:48:08 +0000
1815@@ -16,7 +16,7 @@
1816
1817 import QtQuick 2.0
1818 import Ubuntu.Components 0.1
1819-import "../Components" as LocalComponents
1820+import ".." as LocalComponents
1821
1822 LocalComponents.Page {
1823 title: i18n.tr("All done")
1824
1825=== modified file 'qml/Wizard/Pages/here-terms.qml'
1826--- wizard/qml/Pages/here-terms.qml 2014-12-02 18:48:08 +0000
1827+++ qml/Wizard/Pages/here-terms.qml 2014-12-02 18:48:08 +0000
1828@@ -15,11 +15,11 @@
1829 */
1830
1831 import QtQuick 2.3
1832+import AccountsService 0.1
1833 import Qt.labs.folderlistmodel 2.1
1834 import Ubuntu.Components 1.1
1835-import Ubuntu.SystemSettings.Wizard.Utils 0.1
1836 import Ubuntu.Web 0.2
1837-import "../Components" as LocalComponents
1838+import ".." as LocalComponents
1839
1840 LocalComponents.Page {
1841 title: i18n.tr("Terms & Conditions")
1842@@ -27,7 +27,7 @@
1843
1844 FolderListModel {
1845 id: termsModel
1846- folder: System.hereLicensePath
1847+ folder: AccountsService.hereLicensePath
1848 nameFilters: ["*.html"]
1849 showDirs: false
1850 showOnlyReadable: true
1851@@ -73,7 +73,7 @@
1852
1853 function loadFileContent() {
1854 var xhr = new XMLHttpRequest
1855- xhr.open("GET", System.hereLicensePath + "/" + determineFileName())
1856+ xhr.open("GET", AccountsService.hereLicensePath + "/" + determineFileName())
1857 xhr.onreadystatechange = function() {
1858 if (xhr.readyState == XMLHttpRequest.DONE) {
1859 termsLabel.text = xhr.responseText
1860
1861=== modified file 'qml/Wizard/Pages/passwd-confirm.qml'
1862--- wizard/qml/Pages/passwd-confirm.qml 2014-12-02 18:48:08 +0000
1863+++ qml/Wizard/Pages/passwd-confirm.qml 2014-12-02 18:48:08 +0000
1864@@ -17,8 +17,8 @@
1865 import QtQuick 2.3
1866 import Ubuntu.Components 1.1
1867 import Ubuntu.SystemSettings.SecurityPrivacy 1.0
1868-import "../Components" as LocalComponents
1869-import "file:///usr/share/unity8/Components" as UnityComponents
1870+import ".." as LocalComponents
1871+import "../../Components" as UnityComponents
1872
1873 /**
1874 * See the main passwd-type page for an explanation of why we don't actually
1875
1876=== modified file 'qml/Wizard/Pages/passwd-set.qml'
1877--- wizard/qml/Pages/passwd-set.qml 2014-12-02 18:48:08 +0000
1878+++ qml/Wizard/Pages/passwd-set.qml 2014-12-02 18:48:08 +0000
1879@@ -17,8 +17,8 @@
1880 import QtQuick 2.3
1881 import Ubuntu.Components 1.1
1882 import Ubuntu.SystemSettings.SecurityPrivacy 1.0
1883-import "../Components" as LocalComponents
1884-import "file:///usr/share/unity8/Components" as UnityComponents
1885+import ".." as LocalComponents
1886+import "../../Components" as UnityComponents
1887
1888 /**
1889 * See the main passwd-type page for an explanation of why we don't actually
1890
1891=== renamed file 'wizard/qml/Components/StackButton.qml' => 'qml/Wizard/StackButton.qml'
1892=== added file 'qml/Wizard/Wizard.qml'
1893--- qml/Wizard/Wizard.qml 1970-01-01 00:00:00 +0000
1894+++ qml/Wizard/Wizard.qml 2014-12-02 18:48:08 +0000
1895@@ -0,0 +1,55 @@
1896+/*
1897+ * Copyright (C) 2013 Canonical, Ltd.
1898+ *
1899+ * This program is free software; you can redistribute it and/or modify
1900+ * it under the terms of the GNU General Public License as published by
1901+ * the Free Software Foundation; version 3.
1902+ *
1903+ * This program is distributed in the hope that it will be useful,
1904+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1905+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1906+ * GNU General Public License for more details.
1907+ *
1908+ * You should have received a copy of the GNU General Public License
1909+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1910+ */
1911+
1912+import QtQuick 2.3
1913+import Ubuntu.Components 1.1
1914+import Wizard 0.1
1915+import "../Components"
1916+
1917+Showable {
1918+ id: root
1919+
1920+ // The background wallpaper to use
1921+ property string background
1922+
1923+ readonly property alias active: loader.active
1924+
1925+ hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
1926+
1927+ onRequiredChanged: {
1928+ if (!required) {
1929+ System.wizardEnabled = false;
1930+ }
1931+ }
1932+
1933+ Loader {
1934+ id: loader
1935+ anchors.fill: parent
1936+ active: System.wizardEnabled
1937+ source: "Pages.qml"
1938+
1939+ Binding {
1940+ target: loader.item
1941+ property: "background"
1942+ value: root.background
1943+ }
1944+
1945+ Connections {
1946+ target: loader.item
1947+ onQuit: root.hide()
1948+ }
1949+ }
1950+}
1951
1952=== modified file 'tests/CMakeLists.txt'
1953--- tests/CMakeLists.txt 2014-12-02 18:48:08 +0000
1954+++ tests/CMakeLists.txt 2014-10-01 13:20:32 +0000
1955@@ -14,4 +14,3 @@
1956 add_subdirectory(plugins)
1957 add_subdirectory(utils)
1958 add_subdirectory(uqmlscene)
1959-add_subdirectory(wizard)
1960
1961=== modified file 'tests/mocks/AccountsService/AccountsService.cpp'
1962--- tests/mocks/AccountsService/AccountsService.cpp 2014-10-05 20:54:11 +0000
1963+++ tests/mocks/AccountsService/AccountsService.cpp 2014-12-02 18:48:08 +0000
1964@@ -27,7 +27,9 @@
1965 m_backgroundFile(qmlDirectory() + "graphics/phone_background.jpg"),
1966 m_statsWelcomeScreen(true),
1967 m_failedLogins(0),
1968- m_demoEdges(false)
1969+ m_demoEdges(false),
1970+ m_hereEnabled(false),
1971+ m_hereLicensePath("")
1972 {
1973 }
1974
1975@@ -116,3 +118,31 @@
1976 m_failedLogins = failedLogins;
1977 failedLoginsChanged();
1978 }
1979+
1980+bool AccountsService::hereEnabled() const
1981+{
1982+ return m_hereEnabled;
1983+}
1984+
1985+void AccountsService::setHereEnabled(bool enabled)
1986+{
1987+ m_hereEnabled = enabled;
1988+ hereEnabledChanged();
1989+}
1990+
1991+QString AccountsService::hereLicensePath() const
1992+{
1993+ return m_hereLicensePath;
1994+}
1995+
1996+void AccountsService::setHereLicensePath(const QString &path)
1997+{
1998+ // Path should always be valid (this code is all synchronous)
1999+ m_hereLicensePath = path.isNull() ? "" : path;
2000+ hereLicensePathChanged();
2001+}
2002+
2003+bool AccountsService::hereLicensePathValid() const
2004+{
2005+ return !m_hereLicensePath.isNull();
2006+}
2007
2008=== modified file 'tests/mocks/AccountsService/AccountsService.h'
2009--- tests/mocks/AccountsService/AccountsService.h 2014-10-05 20:54:11 +0000
2010+++ tests/mocks/AccountsService/AccountsService.h 2014-12-02 18:48:08 +0000
2011@@ -59,6 +59,17 @@
2012 READ failedLogins
2013 WRITE setFailedLogins
2014 NOTIFY failedLoginsChanged)
2015+ Q_PROPERTY(bool hereEnabled
2016+ READ hereEnabled
2017+ WRITE setHereEnabled
2018+ NOTIFY hereEnabledChanged)
2019+ Q_PROPERTY(QString hereLicensePath
2020+ READ hereLicensePath
2021+ WRITE setHereLicensePath // only available in mock
2022+ NOTIFY hereLicensePathChanged)
2023+ Q_PROPERTY(bool hereLicensePathValid // qml sees a null string as "", so we use proxy setting for that
2024+ READ hereLicensePathValid
2025+ NOTIFY hereLicensePathChanged)
2026
2027 public:
2028 enum PasswordDisplayHint {
2029@@ -83,6 +94,11 @@
2030 PasswordDisplayHint passwordDisplayHint() const;
2031 uint failedLogins() const;
2032 void setFailedLogins(uint failedLogins);
2033+ bool hereEnabled() const;
2034+ void setHereEnabled(bool enabled);
2035+ QString hereLicensePath() const;
2036+ void setHereLicensePath(const QString &path);
2037+ bool hereLicensePathValid() const;
2038
2039 Q_SIGNALS:
2040 void userChanged();
2041@@ -93,6 +109,8 @@
2042 void statsWelcomeScreenChanged();
2043 void passwordDisplayHintChanged();
2044 void failedLoginsChanged();
2045+ void hereEnabledChanged();
2046+ void hereLicensePathChanged();
2047
2048 private:
2049 bool m_enableLauncherWhileLocked;
2050@@ -102,6 +120,8 @@
2051 bool m_statsWelcomeScreen;
2052 uint m_failedLogins;
2053 bool m_demoEdges;
2054+ bool m_hereEnabled;
2055+ QString m_hereLicensePath;
2056 };
2057
2058 #endif
2059
2060=== modified file 'tests/mocks/CMakeLists.txt'
2061--- tests/mocks/CMakeLists.txt 2014-10-28 11:06:31 +0000
2062+++ tests/mocks/CMakeLists.txt 2014-12-02 18:48:08 +0000
2063@@ -37,6 +37,7 @@
2064 add_subdirectory(Ubuntu)
2065 add_subdirectory(Unity)
2066 add_subdirectory(QtMultimedia)
2067+add_subdirectory(Wizard)
2068
2069 install(
2070 DIRECTORY data
2071
2072=== modified file 'tests/mocks/QMenuModel/CMakeLists.txt'
2073--- tests/mocks/QMenuModel/CMakeLists.txt 2014-05-02 22:57:21 +0000
2074+++ tests/mocks/QMenuModel/CMakeLists.txt 2014-12-02 18:48:08 +0000
2075@@ -5,6 +5,7 @@
2076
2077 set(QMenuModelQml_SOURCES
2078 actionstateparser.cpp
2079+ dbus-enums.h
2080 plugin.cpp
2081 unitymenumodel.cpp
2082 )
2083
2084=== added file 'tests/mocks/QMenuModel/dbus-enums.h'
2085--- tests/mocks/QMenuModel/dbus-enums.h 1970-01-01 00:00:00 +0000
2086+++ tests/mocks/QMenuModel/dbus-enums.h 2014-12-02 18:48:08 +0000
2087@@ -0,0 +1,52 @@
2088+/*
2089+ * Copyright 2012 Canonical Ltd.
2090+ *
2091+ * This program is free software; you can redistribute it and/or modify
2092+ * it under the terms of the GNU Lesser General Public License as published by
2093+ * the Free Software Foundation; version 3.
2094+ *
2095+ * This program is distributed in the hope that it will be useful,
2096+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2097+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2098+ * GNU Lesser General Public License for more details.
2099+ *
2100+ * You should have received a copy of the GNU Lesser General Public License
2101+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2102+ *
2103+ * Authors:
2104+ * Olivier Tilloy <olivier.tilloy@canonical.com>
2105+ */
2106+
2107+#ifndef __DBUS_ENUMS__
2108+#define __DBUS_ENUMS__
2109+
2110+#include <QObject>
2111+
2112+// This class acts as a namespace only, with the addition that its enums
2113+// are registered to be exposed on the QML side.
2114+class DBusEnums : public QObject
2115+{
2116+ Q_OBJECT
2117+
2118+ Q_ENUMS(BusType)
2119+ Q_ENUMS(ConnectionStatus)
2120+
2121+public:
2122+ enum BusType {
2123+ None = 0,
2124+ SessionBus,
2125+ SystemBus,
2126+ LastBusType
2127+ };
2128+
2129+ enum ConnectionStatus {
2130+ Disconnected = 0,
2131+ Connecting,
2132+ Connected
2133+ };
2134+
2135+private:
2136+ DBusEnums() {}
2137+};
2138+
2139+#endif // __DBUS_ENUMS__
2140
2141=== modified file 'tests/mocks/QMenuModel/plugin.cpp'
2142--- tests/mocks/QMenuModel/plugin.cpp 2013-11-19 17:01:25 +0000
2143+++ tests/mocks/QMenuModel/plugin.cpp 2014-12-02 18:48:08 +0000
2144@@ -19,12 +19,15 @@
2145 #include "plugin.h"
2146 #include "unitymenumodel.h"
2147 #include "actionstateparser.h"
2148+#include "dbus-enums.h"
2149
2150 #include <QtQml/qqml.h>
2151
2152 void QMenuModelPlugin::registerTypes(const char *uri)
2153 {
2154 Q_ASSERT(uri == QLatin1String("QMenuModel"));
2155+ qmlRegisterUncreatableType<DBusEnums>(uri, 0, 1, "DBus",
2156+ "DBus is only a namespace");
2157 qmlRegisterType<UnityMenuModel>(uri, 0, 1, "UnityMenuModel");
2158 qmlRegisterType<ActionStateParser>(uri, 0, 1, "ActionStateParser");
2159 }
2160
2161=== added directory 'tests/mocks/Wizard'
2162=== added file 'tests/mocks/Wizard/CMakeLists.txt'
2163--- tests/mocks/Wizard/CMakeLists.txt 1970-01-01 00:00:00 +0000
2164+++ tests/mocks/Wizard/CMakeLists.txt 2014-12-02 18:48:08 +0000
2165@@ -0,0 +1,12 @@
2166+include_directories(
2167+ ${CMAKE_SOURCE_DIR}/plugins/Wizard
2168+)
2169+
2170+add_library(MockWizard-qml MODULE
2171+ mockplugin.cpp
2172+ MockSystem.cpp
2173+ ${CMAKE_SOURCE_DIR}/plugins/Wizard/PageList.cpp
2174+)
2175+
2176+qt5_use_modules(MockWizard-qml Qml)
2177+add_unity8_mock(Wizard 0.1 Wizard TARGETS MockWizard-qml)
2178
2179=== added file 'tests/mocks/Wizard/MockSystem.cpp'
2180--- tests/mocks/Wizard/MockSystem.cpp 1970-01-01 00:00:00 +0000
2181+++ tests/mocks/Wizard/MockSystem.cpp 2014-12-02 18:48:08 +0000
2182@@ -0,0 +1,38 @@
2183+/*
2184+ * Copyright (C) 2014 Canonical Ltd.
2185+ *
2186+ * This program is free software: you can redistribute it and/or modify it
2187+ * under the terms of the GNU General Public License version 3, as published
2188+ * by the Free Software Foundation.
2189+ *
2190+ * This program is distributed in the hope that it will be useful, but
2191+ * WITHOUT ANY WARRANTY; without even the implied warranties of
2192+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2193+ * PURPOSE. See the GNU General Public License for more details.
2194+ *
2195+ * You should have received a copy of the GNU General Public License along
2196+ * with this program. If not, see <http://www.gnu.org/licenses/>.
2197+ */
2198+
2199+#include "MockSystem.h"
2200+
2201+MockSystem::MockSystem()
2202+ : QObject(),
2203+ m_wizardEnabled(false)
2204+{
2205+}
2206+
2207+bool MockSystem::wizardEnabled() const
2208+{
2209+ return m_wizardEnabled;
2210+}
2211+
2212+void MockSystem::setWizardEnabled(bool enabled)
2213+{
2214+ m_wizardEnabled = enabled;
2215+ Q_EMIT wizardEnabledChanged();
2216+}
2217+
2218+void MockSystem::updateSessionLanguage(const QString &)
2219+{
2220+}
2221
2222=== added file 'tests/mocks/Wizard/MockSystem.h'
2223--- tests/mocks/Wizard/MockSystem.h 1970-01-01 00:00:00 +0000
2224+++ tests/mocks/Wizard/MockSystem.h 2014-12-02 18:48:08 +0000
2225@@ -0,0 +1,46 @@
2226+/*
2227+ * Copyright (C) 2014 Canonical Ltd.
2228+ *
2229+ * This program is free software: you can redistribute it and/or modify it
2230+ * under the terms of the GNU General Public License version 3, as published
2231+ * by the Free Software Foundation.
2232+ *
2233+ * This program is distributed in the hope that it will be useful, but
2234+ * WITHOUT ANY WARRANTY; without even the implied warranties of
2235+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2236+ * PURPOSE. See the GNU General Public License for more details.
2237+ *
2238+ * You should have received a copy of the GNU General Public License along
2239+ * with this program. If not, see <http://www.gnu.org/licenses/>.
2240+ */
2241+
2242+#ifndef WIZARD_MOCK_SYSTEM_H
2243+#define WIZARD_MOCK_SYSTEM_H
2244+
2245+#include <QObject>
2246+#include <QString>
2247+
2248+class MockSystem : public QObject
2249+{
2250+ Q_OBJECT
2251+ Q_PROPERTY(bool wizardEnabled READ wizardEnabled WRITE setWizardEnabled NOTIFY wizardEnabledChanged)
2252+
2253+public:
2254+ MockSystem();
2255+
2256+ bool wizardEnabled() const;
2257+ void setWizardEnabled(bool enabled);
2258+
2259+public Q_SLOTS:
2260+ void updateSessionLanguage(const QString &locale);
2261+
2262+Q_SIGNALS:
2263+ void wizardEnabledChanged();
2264+
2265+private:
2266+ Q_DISABLE_COPY(MockSystem)
2267+
2268+ bool m_wizardEnabled;
2269+};
2270+
2271+#endif
2272
2273=== added file 'tests/mocks/Wizard/Wizard.qmltypes'
2274--- tests/mocks/Wizard/Wizard.qmltypes 1970-01-01 00:00:00 +0000
2275+++ tests/mocks/Wizard/Wizard.qmltypes 2014-12-02 18:48:08 +0000
2276@@ -0,0 +1,36 @@
2277+import QtQuick.tooling 1.1
2278+
2279+// This file describes the plugin-supplied types contained in the library.
2280+// It is used for QML tooling purposes only.
2281+//
2282+// This file was auto-generated by:
2283+// 'qmlplugindump -notrelocatable Wizard 0.1 tests/mocks'
2284+
2285+Module {
2286+ Component {
2287+ name: "MockSystem"
2288+ prototype: "QObject"
2289+ exports: ["Wizard/System 0.1"]
2290+ isCreatable: false
2291+ isSingleton: true
2292+ exportMetaObjectRevisions: [0]
2293+ Property { name: "wizardEnabled"; type: "bool" }
2294+ Method {
2295+ name: "updateSessionLanguage"
2296+ Parameter { name: "locale"; type: "string" }
2297+ }
2298+ }
2299+ Component {
2300+ name: "PageList"
2301+ prototype: "QObject"
2302+ exports: ["Wizard/PageList 0.1"]
2303+ isCreatable: false
2304+ isSingleton: true
2305+ exportMetaObjectRevisions: [0]
2306+ Property { name: "index"; type: "int"; isReadonly: true }
2307+ Property { name: "numPages"; type: "int"; isReadonly: true }
2308+ Method { name: "prev"; type: "string" }
2309+ Method { name: "next"; type: "string" }
2310+ }
2311+}
2312+
2313
2314=== added file 'tests/mocks/Wizard/mockplugin.cpp'
2315--- tests/mocks/Wizard/mockplugin.cpp 1970-01-01 00:00:00 +0000
2316+++ tests/mocks/Wizard/mockplugin.cpp 2014-12-02 18:48:08 +0000
2317@@ -0,0 +1,42 @@
2318+/*
2319+ * Copyright (C) 2012,2013 Canonical, Ltd.
2320+ *
2321+ * This program is free software; you can redistribute it and/or modify
2322+ * it under the terms of the GNU General Public License as published by
2323+ * the Free Software Foundation; version 3.
2324+ *
2325+ * This program is distributed in the hope that it will be useful,
2326+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2327+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2328+ * GNU General Public License for more details.
2329+ *
2330+ * You should have received a copy of the GNU General Public License
2331+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2332+ */
2333+
2334+#include "mockplugin.h"
2335+#include "MockSystem.h"
2336+#include "PageList.h"
2337+
2338+#include <QtQml/qqml.h>
2339+
2340+static QObject *pagelist_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
2341+{
2342+ Q_UNUSED(engine)
2343+ Q_UNUSED(scriptEngine)
2344+ return new PageList();
2345+}
2346+
2347+static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
2348+{
2349+ Q_UNUSED(engine)
2350+ Q_UNUSED(scriptEngine)
2351+ return new MockSystem();
2352+}
2353+
2354+void MockWizardPlugin::registerTypes(const char *uri)
2355+{
2356+ Q_ASSERT(uri == QLatin1String("Wizard"));
2357+ qmlRegisterSingletonType<PageList>(uri, 0, 1, "PageList", pagelist_provider);
2358+ qmlRegisterSingletonType<MockSystem>(uri, 0, 1, "System", system_provider);
2359+}
2360
2361=== added file 'tests/mocks/Wizard/mockplugin.h'
2362--- tests/mocks/Wizard/mockplugin.h 1970-01-01 00:00:00 +0000
2363+++ tests/mocks/Wizard/mockplugin.h 2014-12-02 18:48:08 +0000
2364@@ -0,0 +1,32 @@
2365+/*
2366+ * Copyright (C) 2014 Canonical, Ltd.
2367+ *
2368+ * This program is free software; you can redistribute it and/or modify
2369+ * it under the terms of the GNU General Public License as published by
2370+ * the Free Software Foundation; version 3.
2371+ *
2372+ * This program is distributed in the hope that it will be useful,
2373+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2374+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2375+ * GNU General Public License for more details.
2376+ *
2377+ * You should have received a copy of the GNU General Public License
2378+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2379+ */
2380+
2381+#ifndef MOCK_WIZARD_PLUGIN_H
2382+#define MOCK_WIZARD_PLUGIN_H
2383+
2384+#include <QtQml/QQmlEngine>
2385+#include <QtQml/QQmlExtensionPlugin>
2386+
2387+class MockWizardPlugin : public QQmlExtensionPlugin
2388+{
2389+ Q_OBJECT
2390+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
2391+
2392+public:
2393+ void registerTypes(const char *uri);
2394+};
2395+
2396+#endif
2397
2398=== added file 'tests/mocks/Wizard/qmldir'
2399--- tests/mocks/Wizard/qmldir 1970-01-01 00:00:00 +0000
2400+++ tests/mocks/Wizard/qmldir 2014-12-02 18:48:08 +0000
2401@@ -0,0 +1,3 @@
2402+module Wizard
2403+plugin MockWizard-qml
2404+typeinfo Wizard.qmltypes
2405
2406=== modified file 'tests/plugins/CMakeLists.txt'
2407--- tests/plugins/CMakeLists.txt 2014-06-11 15:36:51 +0000
2408+++ tests/plugins/CMakeLists.txt 2014-12-02 18:48:08 +0000
2409@@ -4,3 +4,4 @@
2410 add_subdirectory(Ubuntu)
2411 add_subdirectory(Unity)
2412 add_subdirectory(Utils)
2413+add_subdirectory(Wizard)
2414
2415=== renamed directory 'tests/wizard' => 'tests/plugins/Wizard'
2416=== modified file 'tests/plugins/Wizard/CMakeLists.txt'
2417--- tests/wizard/CMakeLists.txt 2014-12-02 18:48:08 +0000
2418+++ tests/plugins/Wizard/CMakeLists.txt 2014-12-02 18:48:08 +0000
2419@@ -1,5 +1,12 @@
2420-add_executable(tst-pagelist tst_pagelist.cpp ${CMAKE_SOURCE_DIR}/wizard/PageList.cpp)
2421-set_target_properties(tst-pagelist PROPERTIES
2422- INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR};${CMAKE_SOURCE_DIR}/wizard")
2423-qt5_use_modules(tst-pagelist Core Test)
2424-add_test(tst-pagelist tst-pagelist)
2425+include_directories(
2426+ ${CMAKE_CURRENT_BINARY_DIR}
2427+ ${CMAKE_SOURCE_DIR}/plugins/Wizard
2428+)
2429+
2430+add_executable(tst-pagelist
2431+ tst_pagelist.cpp
2432+ ${CMAKE_SOURCE_DIR}/plugins/Wizard/PageList.cpp
2433+)
2434+qt5_use_modules(tst-pagelist Core Qml Test)
2435+
2436+add_test(NAME pagelisttest COMMAND env UNITY_TEST_ENV=1 ${CMAKE_CURRENT_BINARY_DIR}/tst-pagelist)
2437
2438=== modified file 'tests/plugins/Wizard/tst_pagelist.cpp'
2439--- tests/wizard/tst_pagelist.cpp 2014-12-02 18:48:08 +0000
2440+++ tests/plugins/Wizard/tst_pagelist.cpp 2014-12-02 18:48:08 +0000
2441@@ -1,6 +1,4 @@
2442 /*
2443- * This file is part of system-settings
2444- *
2445 * Copyright (C) 2014 Canonical Ltd.
2446 *
2447 * This program is free software: you can redistribute it and/or modify it
2448@@ -23,7 +21,7 @@
2449 #include <QTemporaryDir>
2450 #include <QTest>
2451
2452-#define PAGES_PATH "ubuntu/settings/wizard/qml/Pages"
2453+#define PAGES_PATH "Wizard/Pages"
2454
2455 class PageListTest: public QObject
2456 {
2457
2458=== removed directory 'wizard/Unity'
2459=== removed directory 'wizard/Unity/Application'
2460=== removed file 'wizard/Unity/Application/CMakeLists.txt'
2461--- wizard/Unity/Application/CMakeLists.txt 2014-12-02 18:48:08 +0000
2462+++ wizard/Unity/Application/CMakeLists.txt 1970-01-01 00:00:00 +0000
2463@@ -1,3 +0,0 @@
2464-# This is just a small fake Unity.Application for non-Mir environments
2465-set(PLUG_DIR ${PLUGIN_PRIVATE_MODULE_DIR}/Ubuntu/SystemSettings/Wizard/NonMir/Unity/Application)
2466-install(FILES qmldir OSKController.qml DESTINATION ${PLUG_DIR})
2467
2468=== removed file 'wizard/Unity/Application/OSKController.qml'
2469--- wizard/Unity/Application/OSKController.qml 2014-12-02 18:48:08 +0000
2470+++ wizard/Unity/Application/OSKController.qml 1970-01-01 00:00:00 +0000
2471@@ -1,20 +0,0 @@
2472-/*
2473- * Copyright (C) 2013 Canonical, Ltd.
2474- *
2475- * This program is free software; you can redistribute it and/or modify
2476- * it under the terms of the GNU General Public License as published by
2477- * the Free Software Foundation; version 3.
2478- *
2479- * This program is distributed in the hope that it will be useful,
2480- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2481- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2482- * GNU General Public License for more details.
2483- *
2484- * You should have received a copy of the GNU General Public License
2485- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2486- */
2487-
2488-import QtQuick 2.0;
2489-
2490-Item {
2491-}
2492
2493=== removed file 'wizard/Unity/Application/qmldir'
2494--- wizard/Unity/Application/qmldir 2014-12-02 18:48:08 +0000
2495+++ wizard/Unity/Application/qmldir 1970-01-01 00:00:00 +0000
2496@@ -1,2 +0,0 @@
2497-module Unity.Application
2498-OSKController 0.1 OSKController.qml
2499
2500=== removed file 'wizard/Unity/CMakeLists.txt'
2501--- wizard/Unity/CMakeLists.txt 2014-12-02 18:48:08 +0000
2502+++ wizard/Unity/CMakeLists.txt 1970-01-01 00:00:00 +0000
2503@@ -1,1 +0,0 @@
2504-add_subdirectory(Application)
2505
2506=== removed directory 'wizard/Utils'
2507=== removed file 'wizard/Utils/CMakeLists.txt'
2508--- wizard/Utils/CMakeLists.txt 2014-12-02 18:48:08 +0000
2509+++ wizard/Utils/CMakeLists.txt 1970-01-01 00:00:00 +0000
2510@@ -1,27 +0,0 @@
2511-include_directories(
2512- ${CMAKE_CURRENT_SOURCE_DIR}
2513- ${CMAKE_CURRENT_BINARY_DIR}
2514- ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
2515-)
2516-
2517-set(QMLPLUGIN_SRC
2518- qsortfilterproxymodelqml.cpp
2519- plugin.cpp
2520- system.cpp
2521- )
2522-
2523-add_library(WizardUtils-qml SHARED
2524- ${QMLPLUGIN_SRC}
2525- )
2526-
2527-# Because this is an internal support library, we want
2528-# to expose all symbols in it. Consider changing this
2529-# either to a static library or just using the
2530-# files directly in targets.
2531-set_target_properties(WizardUtils-qml PROPERTIES COMPILE_FLAGS -fvisibility=default)
2532-
2533-qt5_use_modules(WizardUtils-qml DBus Qml Quick)
2534-
2535-set(PLUG_DIR ${PLUGIN_PRIVATE_MODULE_DIR}/Ubuntu/SystemSettings/Wizard/Utils)
2536-install(FILES qmldir DESTINATION ${PLUG_DIR})
2537-install(TARGETS WizardUtils-qml DESTINATION ${PLUG_DIR})
2538
2539=== removed file 'wizard/Utils/plugin.cpp'
2540--- wizard/Utils/plugin.cpp 2014-12-02 18:48:08 +0000
2541+++ wizard/Utils/plugin.cpp 1970-01-01 00:00:00 +0000
2542@@ -1,41 +0,0 @@
2543-/*
2544- * Copyright (C) 2014 Canonical, Ltd.
2545- *
2546- * This program is free software; you can redistribute it and/or modify
2547- * it under the terms of the GNU General Public License as published by
2548- * the Free Software Foundation; version 3.
2549- *
2550- * This program is distributed in the hope that it will be useful,
2551- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2552- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2553- * GNU General Public License for more details.
2554- *
2555- * You should have received a copy of the GNU General Public License
2556- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2557- */
2558-
2559-// Qt
2560-#include <QtQml/qqml.h>
2561-#include <QQmlContext>
2562-#include <QDebug>
2563-// self
2564-#include "plugin.h"
2565-
2566-// local
2567-#include "qsortfilterproxymodelqml.h"
2568-#include "system.h"
2569-
2570-static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
2571-{
2572- Q_UNUSED(engine)
2573- Q_UNUSED(scriptEngine)
2574- return new System();
2575-}
2576-
2577-void UtilsPlugin::registerTypes(const char *uri)
2578-{
2579- Q_ASSERT(uri == QLatin1String("Ubuntu.SystemSettings.Wizard.Utils"));
2580- qmlRegisterType<QAbstractItemModel>();
2581- qmlRegisterType<QSortFilterProxyModelQML>(uri, 0, 1, "SortFilterProxyModel");
2582- qmlRegisterSingletonType<System>(uri, 0, 1, "System", system_provider);
2583-}
2584
2585=== removed file 'wizard/Utils/plugin.h'
2586--- wizard/Utils/plugin.h 2014-12-02 18:48:08 +0000
2587+++ wizard/Utils/plugin.h 1970-01-01 00:00:00 +0000
2588@@ -1,33 +0,0 @@
2589-/*
2590- * Copyright (C) 2014 Canonical, Ltd.
2591- *
2592- * This program is free software; you can redistribute it and/or modify
2593- * it under the terms of the GNU General Public License as published by
2594- * the Free Software Foundation; version 3.
2595- *
2596- * This program is distributed in the hope that it will be useful,
2597- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2598- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2599- * GNU General Public License for more details.
2600- *
2601- * You should have received a copy of the GNU General Public License
2602- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2603- *
2604- */
2605-
2606-#ifndef UTILS_PLUGIN_H
2607-#define UTILS_PLUGIN_H
2608-
2609-#include <QtQml/QQmlEngine>
2610-#include <QtQml/QQmlExtensionPlugin>
2611-
2612-class UtilsPlugin : public QQmlExtensionPlugin
2613-{
2614- Q_OBJECT
2615- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
2616-
2617-public:
2618- void registerTypes(const char *uri);
2619-};
2620-
2621-#endif
2622
2623=== removed file 'wizard/Utils/qmldir'
2624--- wizard/Utils/qmldir 2014-12-02 18:48:08 +0000
2625+++ wizard/Utils/qmldir 1970-01-01 00:00:00 +0000
2626@@ -1,2 +0,0 @@
2627-module Ubuntu.SystemSettings.Wizard.Utils
2628-plugin WizardUtils-qml
2629
2630=== removed file 'wizard/Utils/qsortfilterproxymodelqml.cpp'
2631--- wizard/Utils/qsortfilterproxymodelqml.cpp 2014-12-02 18:48:08 +0000
2632+++ wizard/Utils/qsortfilterproxymodelqml.cpp 1970-01-01 00:00:00 +0000
2633@@ -1,167 +0,0 @@
2634-/*
2635- * Copyright (C) 2012 Canonical, Ltd.
2636- *
2637- * This program is free software; you can redistribute it and/or modify
2638- * it under the terms of the GNU General Public License as published by
2639- * the Free Software Foundation; version 3.
2640- *
2641- * This program is distributed in the hope that it will be useful,
2642- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2643- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2644- * GNU General Public License for more details.
2645- *
2646- * You should have received a copy of the GNU General Public License
2647- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2648- */
2649-
2650-// self
2651-#include "qsortfilterproxymodelqml.h"
2652-
2653-// Qt
2654-#include <QDebug>
2655-
2656-QSortFilterProxyModelQML::QSortFilterProxyModelQML(QObject *parent)
2657- : QSortFilterProxyModel(parent)
2658- , m_invertMatch(false)
2659-{
2660- connect(this, SIGNAL(modelReset()), SIGNAL(countChanged()));
2661- connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(countChanged()));
2662- connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(countChanged()));
2663-}
2664-
2665-/*
2666- * Enter row index of filtered/sorted model, returns row index of source model
2667- */
2668-int QSortFilterProxyModelQML::mapRowToSource(int row)
2669-{
2670- if (sourceModel() == NULL)
2671- return -1;
2672-
2673- return QSortFilterProxyModel::mapToSource(index(row, 0)).row();
2674-}
2675-
2676-QHash<int, QByteArray> QSortFilterProxyModelQML::roleNames() const
2677-{
2678- return sourceModel() ? sourceModel()->roleNames() : QHash<int, QByteArray>();
2679-}
2680-
2681-void
2682-QSortFilterProxyModelQML::setModel(QAbstractItemModel *itemModel)
2683-{
2684- if (itemModel == NULL) {
2685- return;
2686- }
2687-
2688- if (itemModel != sourceModel()) {
2689- if (sourceModel() != NULL) {
2690- sourceModel()->disconnect(this);
2691- }
2692-
2693- setSourceModel(itemModel);
2694-
2695- connect(itemModel, SIGNAL(modelReset()), SIGNAL(totalCountChanged()));
2696- connect(itemModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
2697- connect(itemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
2698-
2699- Q_EMIT totalCountChanged();
2700- Q_EMIT modelChanged();
2701- }
2702-}
2703-
2704-QVariantMap
2705-QSortFilterProxyModelQML::get(int row)
2706-{
2707- QVariantMap res;
2708- const QHash<int, QByteArray> roles = roleNames();
2709- auto it = roles.begin();
2710- for ( ; it != roles.end(); ++it) {
2711- res[*it] = data(row, it.key());
2712- }
2713- return res;
2714-}
2715-
2716-QVariant
2717-QSortFilterProxyModelQML::data(int row, int role)
2718-{
2719- if (sourceModel() == NULL) {
2720- return QVariant();
2721- }
2722-
2723- return index(row, 0).data(role);
2724-}
2725-
2726-int
2727-QSortFilterProxyModelQML::totalCount() const
2728-{
2729- if (sourceModel() != NULL) {
2730- return sourceModel()->rowCount();
2731- } else {
2732- return 0;
2733- }
2734-}
2735-
2736-int
2737-QSortFilterProxyModelQML::count()
2738-{
2739- return rowCount();
2740-}
2741-
2742-bool
2743-QSortFilterProxyModelQML::invertMatch() const
2744-{
2745- return m_invertMatch;
2746-}
2747-
2748-void
2749-QSortFilterProxyModelQML::setInvertMatch(bool invertMatch)
2750-{
2751- if (invertMatch != m_invertMatch) {
2752- m_invertMatch = invertMatch;
2753- Q_EMIT invertMatchChanged(invertMatch);
2754- invalidateFilter();
2755- }
2756-}
2757-
2758-bool
2759-QSortFilterProxyModelQML::filterAcceptsRow(int sourceRow,
2760- const QModelIndex &sourceParent) const
2761-{
2762- // If there's no regexp set, always accept all rows indepenently of the invertMatch setting
2763- if (filterRegExp().isEmpty()) {
2764- return true;
2765- }
2766-
2767- bool result = QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
2768- return (m_invertMatch) ? !result : result;
2769-}
2770-
2771-int
2772-QSortFilterProxyModelQML::findFirst(int role, const QVariant& value) const
2773-{
2774- QModelIndexList matches = match(index(0, 0), role, value, 1, Qt::MatchExactly);
2775- if (!matches.isEmpty()) {
2776- return matches.first().row();
2777- } else {
2778- return -1;
2779- }
2780-}
2781-
2782-int
2783-QSortFilterProxyModelQML::mapFromSource(int row)
2784-{
2785- if (sourceModel() != NULL) {
2786- return QSortFilterProxyModel::mapFromSource(sourceModel()->index(row, 0)).row();
2787- } else {
2788- return -1;
2789- }
2790-}
2791-
2792-int
2793-QSortFilterProxyModelQML::mapToSource(int row)
2794-{
2795- if (sourceModel() != NULL) {
2796- return QSortFilterProxyModel::mapToSource(index(row, 0)).row();
2797- } else {
2798- return -1;
2799- }
2800-}
2801
2802=== removed file 'wizard/Utils/qsortfilterproxymodelqml.h'
2803--- wizard/Utils/qsortfilterproxymodelqml.h 2014-12-02 18:48:08 +0000
2804+++ wizard/Utils/qsortfilterproxymodelqml.h 1970-01-01 00:00:00 +0000
2805@@ -1,63 +0,0 @@
2806-/*
2807- * Copyright (C) 2012 Canonical, Ltd.
2808- *
2809- * This program is free software; you can redistribute it and/or modify
2810- * it under the terms of the GNU General Public License as published by
2811- * the Free Software Foundation; version 3.
2812- *
2813- * This program is distributed in the hope that it will be useful,
2814- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2815- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2816- * GNU General Public License for more details.
2817- *
2818- * You should have received a copy of the GNU General Public License
2819- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2820- */
2821-
2822-#ifndef QSORTFILTERPROXYMODELQML_H
2823-#define QSORTFILTERPROXYMODELQML_H
2824-
2825-#include <QSortFilterProxyModel>
2826-
2827-class QSortFilterProxyModelQML : public QSortFilterProxyModel
2828-{
2829- Q_OBJECT
2830-
2831- Q_PROPERTY(QAbstractItemModel* model READ sourceModel WRITE setModel NOTIFY modelChanged)
2832- Q_PROPERTY(int totalCount READ totalCount NOTIFY totalCountChanged)
2833- Q_PROPERTY(int count READ count NOTIFY countChanged)
2834- Q_PROPERTY(bool invertMatch READ invertMatch WRITE setInvertMatch NOTIFY invertMatchChanged)
2835-
2836-public:
2837- explicit QSortFilterProxyModelQML(QObject *parent = 0);
2838-
2839- Q_INVOKABLE QVariantMap get(int row); // Use with caution, it can be slow to query all the roles
2840- Q_INVOKABLE QVariant data(int row, int role);
2841- Q_INVOKABLE int count();
2842- Q_INVOKABLE int findFirst(int role, const QVariant& value) const;
2843- Q_INVOKABLE int mapRowToSource(int row);
2844- virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
2845-
2846- /* getters */
2847- int totalCount() const;
2848- bool invertMatch() const;
2849- QHash<int, QByteArray> roleNames() const;
2850-
2851- /* setters */
2852- void setModel(QAbstractItemModel *model);
2853- void setInvertMatch(bool invertMatch);
2854-
2855- Q_INVOKABLE int mapFromSource(int row);
2856- Q_INVOKABLE int mapToSource(int row);
2857-
2858-Q_SIGNALS:
2859- void totalCountChanged();
2860- void countChanged();
2861- void invertMatchChanged(bool);
2862- void modelChanged();
2863-
2864-private:
2865- bool m_invertMatch;
2866-};
2867-
2868-#endif // QSORTFILTERPROXYMODELQML_H
2869
2870=== removed file 'wizard/main.cpp'
2871--- wizard/main.cpp 2014-12-02 18:48:08 +0000
2872+++ wizard/main.cpp 1970-01-01 00:00:00 +0000
2873@@ -1,93 +0,0 @@
2874-/*
2875- * This file is part of system-settings
2876- *
2877- * Copyright (C) 2014 Canonical Ltd.
2878- *
2879- * This program is free software: you can redistribute it and/or modify it
2880- * under the terms of the GNU General Public License version 3, as published
2881- * by the Free Software Foundation.
2882- *
2883- * This program is distributed in the hope that it will be useful, but
2884- * WITHOUT ANY WARRANTY; without even the implied warranties of
2885- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2886- * PURPOSE. See the GNU General Public License for more details.
2887- *
2888- * You should have received a copy of the GNU General Public License along
2889- * with this program. If not, see <http://www.gnu.org/licenses/>.
2890- */
2891-
2892-#include <csignal>
2893-#include <libintl.h>
2894-#include <qpa/qplatformnativeinterface.h>
2895-#include <QDebug>
2896-#include <QGuiApplication>
2897-#include <QLibrary>
2898-#include <QObject>
2899-#include <QProcess>
2900-#include <QQmlContext>
2901-#include <QQmlEngine>
2902-#include <QQuickItem>
2903-#include <QQuickView>
2904-#include <QTimer>
2905-
2906-#include "PageList.h"
2907-
2908-void handleQuit()
2909-{
2910- QProcess::startDetached("initctl start ubuntu-system-settings-wizard-cleanup");
2911-}
2912-
2913-int main(int argc, const char *argv[])
2914-{
2915- bool isMirServer = false;
2916- if (qgetenv("QT_QPA_PLATFORM") == "ubuntumirclient") {
2917- setenv("QT_QPA_PLATFORM", "mirserver", 1 /* overwrite */);
2918- isMirServer = true;
2919- }
2920-
2921- QGuiApplication::setApplicationName("System Settings Wizard");
2922- QGuiApplication *application = new QGuiApplication(argc, (char**)argv);
2923-
2924- bindtextdomain(I18N_DOMAIN, NULL);
2925- textdomain(I18N_DOMAIN);
2926-
2927- QQuickView* view = new QQuickView();
2928- view->setResizeMode(QQuickView::SizeRootObjectToView);
2929- view->setTitle("Welcome Wizard");
2930-
2931- QString rootDir = qgetenv("UBUNTU_SYSTEM_SETTINGS_WIZARD_ROOT"); // for testing
2932- if (rootDir.isEmpty())
2933- rootDir = WIZARD_ROOT;
2934-
2935- QString modulesDir = qgetenv("UBUNTU_SYSTEM_SETTINGS_WIZARD_MODULES"); // for testing
2936- if (modulesDir.isEmpty())
2937- modulesDir = PLUGIN_PRIVATE_MODULE_DIR;
2938-
2939- if (!isMirServer) {
2940- view->engine()->addImportPath(modulesDir + "/Ubuntu/SystemSettings/Wizard/NonMir");
2941- }
2942- view->engine()->addImportPath(modulesDir);
2943- view->engine()->addImportPath(PLUGIN_QML_DIR);
2944- view->engine()->addImportPath(SHELL_PLUGINDIR);
2945-
2946- PageList pageList;
2947- view->rootContext()->setContextProperty("pageList", &pageList);
2948- view->setSource(QUrl(rootDir + "/ubuntu/settings/wizard/qml/main.qml"));
2949- view->setColor("transparent");
2950-
2951- QObject::connect(view->engine(), &QQmlEngine::quit, handleQuit);
2952-
2953- if (isMirServer) {
2954- view->showFullScreen();
2955- } else {
2956- view->show();
2957- }
2958-
2959- int result = application->exec();
2960-
2961- delete view;
2962- delete application;
2963- return result;
2964-}
2965-
2966-#include "main.moc"
2967
2968=== removed directory 'wizard/qml/Components'
2969=== removed file 'wizard/qml/Components/InputMethod.qml'
2970--- wizard/qml/Components/InputMethod.qml 2014-12-02 18:48:08 +0000
2971+++ wizard/qml/Components/InputMethod.qml 1970-01-01 00:00:00 +0000
2972@@ -1,113 +0,0 @@
2973-/*
2974- * Copyright (C) 2014 Canonical, Ltd.
2975- *
2976- * This program is free software; you can redistribute it and/or modify
2977- * it under the terms of the GNU General Public License as published by
2978- * the Free Software Foundation; version 3.
2979- *
2980- * This program is distributed in the hope that it will be useful,
2981- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2982- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2983- * GNU General Public License for more details.
2984- *
2985- * You should have received a copy of the GNU General Public License
2986- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2987- */
2988-
2989-import QtQuick 2.0
2990-import Unity.Application 0.1
2991-import Ubuntu.Components 0.1
2992-
2993-// TODO: try to share this code with that from the unity8 shell
2994-
2995-Item {
2996- id: root
2997-
2998- Connections {
2999- target: SurfaceManager
3000- onSurfaceCreated: {
3001- if (surface.type == MirSurfaceItem.InputMethod) {
3002- root.surface = surface;
3003- }
3004- }
3005-
3006- onSurfaceDestroyed: {
3007- if (root.surface == surface) {
3008- root.surface = null;
3009- surface.parent = null;
3010- }
3011- if (!surface.parent) {
3012- // there's no one displaying it. delete it right away
3013- surface.release();
3014- }
3015- }
3016- }
3017-
3018- property var surface: null
3019-
3020- property int transitionDuration: UbuntuAnimation.FastDuration
3021-
3022- state: {
3023- if (surface && surface.state != MirSurfaceItem.Minimized) {
3024- return "shown";
3025- } else {
3026- return "hidden";
3027- }
3028- }
3029-
3030- states: [
3031- State {
3032- name: "shown"
3033- PropertyChanges {
3034- target: root
3035- visible: true
3036- y: 0
3037- }
3038- },
3039- State {
3040- name: "hidden"
3041- PropertyChanges {
3042- target: root
3043- visible: false
3044- // half-way down because the vkb occupies only the lower half of the surface
3045- // TODO: consider keyboard rotation
3046- y: root.parent.height / 2.0
3047- }
3048- }
3049- ]
3050-
3051- transitions: [
3052- Transition {
3053- from: "*"; to: "*"
3054- PropertyAction { property: "visible"; value: true }
3055- UbuntuNumberAnimation { property: "y"; duration: transitionDuration }
3056- }
3057- ]
3058-
3059- Connections {
3060- target: surface
3061- ignoreUnknownSignals: true // don't wanna spam the log when surface is null
3062- onStateChanged: {
3063- if (state == MirSurfaceItem.Minimized) {
3064- root.hide();
3065- } else if (state == MirSurfaceItem.Maximized) {
3066- root.show();
3067- }
3068- }
3069- }
3070-
3071- onSurfaceChanged: {
3072- if (surface) {
3073- surface.parent = root;
3074- surface.anchors.fill = root;
3075- }
3076- }
3077-
3078- Component.onDestruction: {
3079- if (surface) {
3080- surface.parent = null;
3081- surface.release();
3082- surface = null;
3083- }
3084- }
3085-}
3086
3087=== removed file 'wizard/test.sh'
3088--- wizard/test.sh 2014-12-02 18:48:08 +0000
3089+++ wizard/test.sh 1970-01-01 00:00:00 +0000
3090@@ -1,18 +0,0 @@
3091-#!/bin/sh
3092-
3093-TOPDIR=$(readlink -e "$(dirname ${0})/..")
3094-
3095-LOCAL_PRIVATE_DIR=$(ls -d ${TOPDIR}/debian/tmp/usr/lib/*/ubuntu-system-settings/private)
3096-if [ -n ${LOCAL_PRIVATE_DIR} ]; then
3097- echo "Testing against locally built version"
3098- export UBUNTU_SYSTEM_SETTINGS_WIZARD_ROOT="${TOPDIR}/debian/tmp/usr/share"
3099- export UBUNTU_SYSTEM_SETTINGS_WIZARD_MODULES="${LOCAL_PRIVATE_DIR}"
3100- export QML2_IMPORT_PATH=${LOCAL_PRIVATE_DIR}:${QML2_IMPORT_PATH}
3101- export PATH=${TOPDIR}/debian/tmp/usr/bin:${PATH}
3102-else
3103- echo "Testing against system version"
3104-fi
3105-
3106-export QML2_IMPORT_PATH=${TOPDIR}/tests/mocks:${QML2_IMPORT_PATH}
3107-
3108-exec system-settings-wizard
3109
3110=== removed file 'wizard/ubuntu-system-settings-wizard-cleanup.conf'
3111--- wizard/ubuntu-system-settings-wizard-cleanup.conf 2014-12-02 18:48:08 +0000
3112+++ wizard/ubuntu-system-settings-wizard-cleanup.conf 1970-01-01 00:00:00 +0000
3113@@ -1,20 +0,0 @@
3114-description "Welcome to Ubuntu Cleanup"
3115-author "Michael Terry <michael.terry@canonical.com>"
3116-
3117-# These are all tasks that need to be completed only if the wizard was
3118-# intentionally stopped (i.e. the user clicked 'Finish' at the end)
3119-
3120-task
3121-
3122-# If you change this, also change it in the main upstart job
3123-env RUN_FILE=".config/ubuntu-system-settings/wizard-has-run"
3124-
3125-script
3126- # Don't run again in the future. We do this here, rather than in the main
3127- # job because we only want to run this code if user actually clicked on the
3128- # "Finish" button.
3129- mkdir -p $(dirname "$HOME/$RUN_FILE")
3130- touch "$HOME/$RUN_FILE" || true
3131-
3132- stop ubuntu-system-settings-wizard
3133-end script
3134
3135=== removed file 'wizard/ubuntu-system-settings-wizard-set-lang.conf'
3136--- wizard/ubuntu-system-settings-wizard-set-lang.conf 2014-12-02 18:48:08 +0000
3137+++ wizard/ubuntu-system-settings-wizard-set-lang.conf 1970-01-01 00:00:00 +0000
3138@@ -1,30 +0,0 @@
3139-description "Welcome to Ubuntu Cleanup"
3140-author "Michael Terry <michael.terry@canonical.com>"
3141-
3142-# This job updates the system idea of what language is configured. It adjusts
3143-# the upstart env and the DBus activation env. It also stops indicators and
3144-# the OSK so that they can be restarted with the new env.
3145-
3146-task
3147-
3148-script
3149- setenv() {
3150- initctl set-env --global $1=$2
3151- gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'$1': '$2'}"
3152- }
3153-
3154- UID=$(id -u)
3155-
3156- # Change upstart's ideas about locales
3157- 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)
3158- setenv LANGUAGE $LANGUAGE
3159- echo "Set language for $USER_PATH as $LANGUAGE"
3160- 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)
3161- setenv LC_ALL $LOCALE
3162- setenv LANG $LOCALE
3163- echo "Set locale as $LOCALE"
3164-
3165- # Stop any indicators and OSK so they will be restarted with new environment
3166- initctl emit indicator-services-end
3167- stop maliit-server || true
3168-end script
3169
3170=== removed file 'wizard/ubuntu-system-settings-wizard.conf'
3171--- wizard/ubuntu-system-settings-wizard.conf 2014-12-02 18:48:08 +0000
3172+++ wizard/ubuntu-system-settings-wizard.conf 1970-01-01 00:00:00 +0000
3173@@ -1,75 +0,0 @@
3174-description "Welcome to Ubuntu"
3175-author "Michael Terry <michael.terry@canonical.com>"
3176-
3177-start on starting unity8
3178-task
3179-
3180-expect stop
3181-
3182-# If you change this, also change it in the cleanup upstart job
3183-env RUN_FILE=".config/ubuntu-system-settings/wizard-has-run"
3184-
3185-pre-start script
3186- if [ -e "$HOME/$RUN_FILE" ]; then
3187- initctl set-env WIZARD_SKIPPED=true
3188- stop
3189- else
3190- # Stop unity8, we'll start it again in post-stop (this avoids a race
3191- # between post-stop and unity8 unpausing)
3192- stop --no-wait $JOB
3193-
3194- # Tell unity-mir to raise SIGSTOP after we start
3195- initctl set-env UNITY_MIR_EMITS_SIGSTOP=1
3196-
3197- if [ -n "$MIR_SOCKET" ]; then
3198- initctl set-env --global WIZARD_ORIG_MIR_SOCKET=$MIR_SOCKET
3199-
3200- # Point wizard at unity-system-compositor
3201- MIR_SERVER_FILE=$XDG_RUNTIME_DIR/wizard_socket
3202- initctl set-env MIR_SERVER_FILE=$MIR_SERVER_FILE
3203- initctl set-env MIR_SERVER_HOST_SOCKET=$MIR_SOCKET
3204-
3205- # Remove the socket if still there
3206- if [ -S "$MIR_SERVER_FILE" ]; then
3207- rm "$MIR_SERVER_FILE"
3208- fi
3209-
3210- # Point future jobs in this session to our Mir socket instead of
3211- # unity-system-compositor's socket.
3212- initctl set-env --global MIR_SOCKET=$MIR_SERVER_FILE
3213- gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'MIR_SOCKET': '$MIR_SERVER_FILE'}"
3214- fi
3215- fi
3216-end script
3217-
3218-exec system-settings-wizard
3219-
3220-post-stop script
3221- if [ -n "$WIZARD_SKIPPED" ]; then
3222- exit
3223- fi
3224-
3225- setenv() {
3226- initctl set-env --global $1=$2
3227- gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'$1': '$2'}"
3228- }
3229-
3230- echo "Ending wizard"
3231-
3232- if [ -S "$MIR_SERVER_FILE" ]; then
3233- rm -f "$MIR_SERVER_FILE"
3234- fi
3235-
3236- # Undo changes to global variables
3237- if [ -n "$WIZARD_ORIG_MIR_SOCKET" ]; then
3238- echo "Resetting MIR_SOCKET to $WIZARD_ORIG_MIR_SOCKET"
3239- setenv MIR_SOCKET $WIZARD_ORIG_MIR_SOCKET
3240- fi
3241-
3242- # Stop any indicators and OSK so they will be restarted with new environment
3243- initctl emit indicator-services-end
3244- stop maliit-server || true
3245-
3246- # And finally, resume unity8
3247- start --no-wait $JOB || true
3248-end script

Subscribers

People subscribed via source and target branches