on a3657be help sign in
Jenkinsfile+29−12
since splitsnapshots
unifiedsplit
@@ -12,25 +12,40 @@ pipeline {
12 steps {
12 steps {
13 parallel(
13 parallel(
14 "Build binary - armhf": {
14 "Build binary - armhf": {
15− node(label: 'xenial-arm64') {
15+ node(label: 'arm64') {
16+ cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
16 unstash 'source'
17 unstash 'source'
17 sh '''export architecture="armhf"
18 sh '''export architecture="armhf"
19+ export DEBBUILDOPTS="-sa"
20+ export SKIP_ARCH_BUILD=false
21+ export SKIP_SOURCE_REMOVAL=true
18build-binary.sh'''
22build-binary.sh'''
19− stash(includes: '*.gz,*.bz2,*.xz,*.deb,*.dsc,*.changes,*.buildinfo,lintian.txt', name: 'build')
23+ stash(includes: '*.gz,*.bz2,*.xz,*.deb,*.dsc,*.changes,*.buildinfo,lintian.txt', name: 'build-armhf')
20 cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
24 cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
21 }
25 }
22
26
23
27
24 },
28 },
25− "Build binary - all": {
29+ "Build binary - arm64": {
26− node(label: 'xenial-arm64') {
30+ node(label: 'arm64') {
31+ cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
27 unstash 'source'
32 unstash 'source'
28− sh '''export architecture="armhf"
33+ sh '''export architecture="arm64"
29− export DEBBUILDOPTS="-A"
34+ export DEBBUILDOPTS="-sa"
30 export SKIP_ARCH_BUILD=false
35 export SKIP_ARCH_BUILD=false
31 export SKIP_SOURCE_REMOVAL=true
36 export SKIP_SOURCE_REMOVAL=true
37+ #build-binary.sh'''
38+ stash(includes: '*.gz,*.bz2,*.xz,*.deb,*.dsc,*.changes,*.buildinfo,lintian.txt', name: 'build-arm64')
39+ cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
40+ }
41+ },
42+ "Build binary - amd64": {
43+ node(label: 'amd64') {
44+ cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
45+ unstash 'source'
46+ sh '''export architecture="amd64"
32− build-binary.sh'''
47+ #build-binary.sh'''
33− stash(includes: '*.gz,*.bz2,*.xz,*.deb,*.dsc,*.changes,*.buildinfo,lintian.txt', name: 'build-all')
48+ stash(includes: '*.gz,*.bz2,*.xz,*.deb,*.dsc,*.changes,*.buildinfo,lintian.txt', name: 'build-amd64')
34 cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
49 cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
35 }
50 }
36 }
51 }
@@ -39,11 +54,12 @@ build-binary.sh'''
39 }
54 }
40 stage('Results') {
55 stage('Results') {
41 steps {
56 steps {
57+ cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
42− unstash 'build'
58+ unstash 'build-armhf'
43− unstash 'build-all'
59+ unstash 'build-arm64'
60+ unstash 'build-amd64'
44 archiveArtifacts(artifacts: '*.gz,*.bz2,*.xz,*.deb,*.dsc,*.changes,*.buildinfo', fingerprint: true, onlyIfSuccessful: true)
61 archiveArtifacts(artifacts: '*.gz,*.bz2,*.xz,*.deb,*.dsc,*.changes,*.buildinfo', fingerprint: true, onlyIfSuccessful: true)
45− sh '''export architecture="armhf"
46−/usr/bin/build-repo.sh'''
62+ sh '''/usr/bin/build-repo.sh'''
47 }
63 }
48 }
64 }
49 stage('Cleanup') {
65 stage('Cleanup') {
@@ -53,3 +69,4 @@ build-binary.sh'''
53 }
69 }
54 }
70 }
55}
71}
72+
README.mdnew file+51
@@ -0,0 +1,51 @@
1+# Unity8
2+
3+A convergent desktop environment.
4+
5+
6+[![Unity 8](http://ubuntufun.de/wp-content/uploads/2016/05/screenshot20160518_232322980.png)](https://unity8.io)
7+
8+
9+### How to install
10+
11+The latest development preview of Unity8 for desktop can be installed on Ubuntu 16.04 (xenial) and 18.04 (bionic) as follows:
12+
13+1. Run the install script
14+```
15+bash <(wget -qO- https://raw.githubusercontent.com/ubports/unity8-desktop-install-tools/master/install.sh)
16+```
17+2. Reboot, select "unity8" at the login prompt, and enjoy :)
18+
19+
20+**NOTE:** The above installation instructions currently only work on Ubuntu 16.04 (xenial) and 18.04 (bionic). Please be aware that the script will install the latest *development preview* of Unity8 for desktop. ***Expect bugs!*** Only install this preview if you understand the risks and are willing/able to fix your system if the preview breaks anything. You are advised *not* to install this preview onto a production system.
21+
22+See [CODING](CODING) for build instructions.
23+
24+
25+### Where to report issues
26+
27+Issues related to the version of Unity8 for desktop (the latest development preview) installed using the above instructions should be reported on the [Unity8 issue tracker](https://github.com/ubports/unity8/issues) in *this* repository.
28+
29+Note that issues related to the version of Unity8 that currently runs on Ubuntu Touch devices should *NOT* be reported in this repository, but instead should be reported on the [Ubuntu Touch issue tracker](https://github.com/ubports/ubuntu-touch/issues). This will change once Ubuntu Touch moves to the latest version of Unity8.
30+
31+
32+### What works / what does not work
33+
34+*This list is incomplete, please help improve it*
35+
36+What works:
37+- Most Wayland apps work
38+- Many report being able to log in using LightDM, but may require a few attempts
39+
40+Does not work:
41+- Most Xapps don't (yet) work
42+- Proprietary drivers don't (yet) work
43+- Many report being unable to log in using GDM
44+
45+
46+### Get involved
47+
48+* [Kanban-Board](https://github.com/ubports/unity8/projects/1)
49+* If you are interesting in helping us in any way you can join [Unity8 Forum](https://forums.ubports.com/category/36/unity8).
50+* For reporting bugs or filing feature-requests, please use the project’s [issues page](https://github.com/ubports/unity8/issues).
51+* For IM you can join our Telegram group [for Developer users](https://t.me/UBports_Unity8).
data/CMakeLists.txt+1
@@ -31,5 +31,6 @@ install(FILES
31add_custom_target(pkgversion ALL COMMAND dpkg-parsechangelog -l${CMAKE_SOURCE_DIR}/debian/changelog --show-field version > ${CMAKE_CURRENT_BINARY_DIR}/version)
31add_custom_target(pkgversion ALL COMMAND dpkg-parsechangelog -l${CMAKE_SOURCE_DIR}/debian/changelog --show-field version > ${CMAKE_CURRENT_BINARY_DIR}/version)
32
32
33install(FILES com.canonical.Unity8.gschema.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/glib-2.0/schemas)
33install(FILES com.canonical.Unity8.gschema.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/glib-2.0/schemas)
34+install(FILES com.canonical.Unity.gschema.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/glib-2.0/schemas)
34install(FILES unity8-dash.url-dispatcher DESTINATION ${CMAKE_INSTALL_DATADIR}/url-dispatcher/urls)
35install(FILES unity8-dash.url-dispatcher DESTINATION ${CMAKE_INSTALL_DATADIR}/url-dispatcher/urls)
35install(FILES ${CMAKE_CURRENT_BINARY_DIR}/version DESTINATION ${CMAKE_INSTALL_LOCALSTATEDIR}/lib/unity8)
36install(FILES ${CMAKE_CURRENT_BINARY_DIR}/version DESTINATION ${CMAKE_INSTALL_LOCALSTATEDIR}/lib/unity8)
data/com.canonical.Unity.gschema.xmlnew file+255
@@ -0,0 +1,255 @@
1+<schemalist>
2+ <enum id="form-factor-enum">
3+ <value nick="Automatic" value="0" />
4+ <value nick="Desktop" value="1" />
5+ <value nick="Netbook" value="2" />
6+ <value nick="TV" value="3" />
7+ </enum>
8+ <enum id="home-expanded-enum">
9+ <value nick="Not Expanded" value="0" />
10+ <value nick="Expanded" value="1" />
11+ </enum>
12+ <enum id="launcher-position-enum">
13+ <value nick="Left" value="0" />
14+ <value nick="Bottom" value="1" />
15+ </enum>
16+ <enum id="desktop-type-enum">
17+ <value nick="Ubuntu" value="0" />
18+ <value nick="UbuntuKylin" value="1" />
19+ </enum>
20+
21+ <schema path="/com/canonical/unity/" id="com.canonical.Unity" gettext-domain="unity">
22+ <key enum="form-factor-enum" name="form-factor">
23+ <default>"Automatic"</default>
24+ <summary>The form factor Unity should target.</summary>
25+ <description>The form factor chosen will affect the size and appearance of the Dash, Launcher and also the Window Management behaviour.</description>
26+ </key>
27+ <key enum="home-expanded-enum" name="home-expanded">
28+ <default>"Expanded"</default>
29+ <summary>Whether the home screen should be expanded.</summary>
30+ <description>Whether the home screen should be expanded.</description>
31+ </key>
32+ <key enum="desktop-type-enum" name="desktop-type">
33+ <default>"Ubuntu"</default>
34+ <summary>The current desktop name.</summary>
35+ <description>The current desktop name.</description>
36+ </key>
37+ <key type="i" name="minimize-count">
38+ <default>0</default>
39+ <summary>Number of times a normal window has been minimized.</summary>
40+ <description>This is used to adjust the animation speed by making it progressively faster the more it is used.</description>
41+ </key>
42+ <key type="i" name="minimize-fast-duration">
43+ <default>300</default>
44+ <summary>The duration for the minimize animation when it is at its fastest setting.</summary>
45+ <description>This is the duration that the minimize animation will have when it has been used more than an number of times equal minimize-speed-threshold.</description>
46+ </key>
47+ <key type="i" name="minimize-slow-duration">
48+ <default>800</default>
49+ <summary>The duration for the minimize animation when it is at its slowest setting.</summary>
50+ <description>This is the duration that the minimize animation will have when it has never been used.</description>
51+ </key>
52+ <key type="i" name="minimize-speed-threshold">
53+ <default>100</default>
54+ <summary>The number of minimizations required to reach maximum speed.</summary>
55+ <description>The speed of the minimize animation will progressively get faster as minimize-count approaches this value.</description>
56+ </key>
57+ <key type="b" name="double-click-activate">
58+ <default>true</default>
59+ <summary>Enable/Disable dash result double-click activation.</summary>
60+ <description>This is used to enable/disable double-click result activation in the dash. Double-click to activate, single click preview</description>
61+ </key>
62+ <key type="b" name="integrated-menus">
63+ <default>false</default>
64+ <summary>Enable/Disable the integrated menus in Unity.</summary>
65+ <description>When this is enabled, the application menus will be shown
66+ on the window decoration, otherwise they will be always shown on the
67+ unity top panel</description>
68+ </key>
69+ <key type="u" name="show-menus-now-delay">
70+ <default>180</default>
71+ <range min="0" max="5000"/>
72+ <summary>Delay (in ms) before showing the menus when pressing Alt</summary>
73+ <description>This allows tune the delay before presenting unity menus
74+ (in non always-show-menus mode).</description>
75+ </key>
76+ <key type="b" name="always-show-menus">
77+ <default>false</default>
78+ <summary>Toggle the menu visibility based on mouse hovering.</summary>
79+ <description>When this is enabled, the application menus will be always
80+ shown (on the window decoration or in the unity panel, depending whether
81+ integrated menus are enabled), otherwise they will be shown only when
82+ the mouse cursor is over the relative mouse area.</description>
83+ </key>
84+ <key type="as" name="whitelist-repeated-keys">
85+ <default>[
86+ 'XF86KbdBrightnessUp',
87+ 'XF86KbdBrightnessDown',
88+ 'XF86MonBrightnessUp',
89+ 'XF86MonBrightnessDown',
90+ 'XF86AudioRaiseVolume',
91+ 'XF86AudioLowerVolume'
92+ ]</default>
93+ <summary>List of keycodes that should be processed even if auto-repated.</summary>
94+ <description>These keycodes are processed even if they are auto-repeated.</description>
95+ </key>
96+ <key type="b" name="pam-check-account-type">
97+ <default>false</default>
98+ <summary>Enable/Disable PAM account checking</summary>
99+ <description>Whether PAM should check the result of account modules
100+ when authenticating. Only do this if you have account
101+ configured properly on your system.</description>
102+ </key>
103+ <key type="b" name="lowgfx">
104+ <default>false</default>
105+ <summary>Enable/Disable Low Graphics Mode</summary>
106+ <description>Whether Unity runs in Low Graphics Mode.</description>
107+ </key>
108+ </schema>
109+ <schema path="/com/canonical/unity/interface/" id="com.canonical.Unity.Interface" gettext-domain="unity">
110+ <key type="d" name="text-scale-factor">
111+ <default>1.0</default>
112+ <range min="0.5" max="3.0"/>
113+ <summary>Font scaling for unity and applications.</summary>
114+ <description>This value defines the global font scaling used by both
115+ unity and applications. It will match the current system font scaling.</description>
116+ </key>
117+ <key type="d" name="cursor-scale-factor">
118+ <default>1.0</default>
119+ <range min="0.5" max="3.0"/>
120+ <summary>Mouse cursor scaling.</summary>
121+ <description>This value defines the global mouse cursor scaling used by both
122+ unity and applications. Changing this value allows to use a custom scaling
123+ for the mouse cursor.</description>
124+ </key>
125+ <key type="s" name="app-scale-factor-monitor">
126+ <default>''</default>
127+ <summary>The name of the monitor that controls the global app scaling factor.</summary>
128+ <description>This value defines the monitor that unity will use (if found) as reference
129+ for scaling all the applications.</description>
130+ </key>
131+ <key type="b" name="app-fallback-to-maximum-scale-factor">
132+ <default>true</default>
133+ <summary>Use the maximum per-monitor scale-factor as application scale factor if no target monitor is found.</summary>
134+ <description>When this is enabled, the applications scale factor will match
135+ the scale factor of the monitor with the greater value, in case the monitor
136+ defined in 'app-scale-factor-monitor' is not provided or available.</description>
137+ </key>
138+ </schema>
139+ <schema path="/com/canonical/unity/launcher/" id="com.canonical.Unity.Launcher" gettext-domain="unity">
140+ <key type="as" name="favorites">
141+ <default>[
142+ 'application://ubiquity.desktop',
143+ 'application://org.gnome.Nautilus.desktop',
144+ 'application://firefox.desktop',
145+ 'application://libreoffice-writer.desktop',
146+ 'application://libreoffice-calc.desktop',
147+ 'application://libreoffice-impress.desktop',
148+ 'application://org.gnome.Software.desktop',
149+ 'application://ubuntu-amazon-default.desktop',
150+ 'application://unity-control-center.desktop',
151+ 'unity://running-apps',
152+ 'unity://expo-icon',
153+ 'unity://devices'
154+ ]</default>
155+ <summary>List of items that should be shown by default in the launcher</summary>
156+ <description>These items can be: application://desktop-id.desktop, device://uiid and unity://special-id (including: unity://running-apps (icons of running applications) unity://devices (icons of attached devices), unity://expo-icon (icon of the workspace switcher) and unity://desktop-icon (the show-desktop icon)); the order of this list determines the launcher item's position.</description>
157+ </key>
158+ <key type="as" name="items">
159+ <default>[
160+ 'application:///dialer-app.desktop',
161+ 'application:///messaging-app.desktop',
162+ 'application:///address-book-app.desktop',
163+ 'application:///ubuntu-system-settings.desktop',
164+ 'appid://openstore.openstore-team/openstore/current-user-version',
165+ 'appid://com.ubuntu.camera/camera/current-user-version',
166+ 'appid://com.ubuntu.gallery/gallery/current-user-version',
167+ 'application:///webbrowser-app.desktop'
168+ ]</default>
169+ <summary>List of items that should be shown by default in the launcher</summary>
170+ <description>These items can be: application:///desktop-id.desktop or appid://package/app/current-user-version.</description>
171+ </key>
172+ <key type="s" name="favorite-migration">
173+ <default>''</default>
174+ <summary>Version of last migration done</summary>
175+ <description>This is a detection key for the favorite migration script to know whether the needed migration is done or not.</description>
176+ </key>
177+ <key enum="launcher-position-enum" name="launcher-position">
178+ <default>"Left"</default>
179+ <summary>The position of launcher.</summary>
180+ <description>The position of launcher.</description>
181+ </key>
182+ </schema>
183+ <schema path="/com/canonical/unity/devices/" id="com.canonical.Unity.Devices" gettext-domain="unity">
184+ <key type="as" name="blacklist">
185+ <default>[]</default>
186+ <summary>List of device uuid blacklist from the launcher.</summary>
187+ <description>These devices are not shown in the launcher by default.</description>
188+ </key>
189+ </schema>
190+ <schema path="/com/canonical/unity/dash/" id="com.canonical.Unity.Dash" gettext-domain="unity">
191+ <key type="as" name="scopes">
192+ <default>[ 'home.scope', 'applications.scope', 'files.scope', 'video.scope', 'music.scope', 'photos.scope', 'social.scope' ]</default>
193+ <summary>List of scope ids specifying which scopes should be created and the order to display them in.</summary>
194+ <description>The scopes listed in the scope bar will be ordered according to this list.</description>
195+ </key>
196+ <key type="as" name="favorite-scopes">
197+ <default>[ 'scope://clickscope', 'scope://musicaggregator', 'scope://videoaggregator' ]</default>
198+ <summary>List of scope queries specifying what should be displayed in the dash.</summary>
199+ <description>List of favorite scopes displayed in the dash.</description>
200+ </key>
201+ </schema>
202+ <schema path="/com/canonical/unity/decorations/" id="com.canonical.Unity.Decorations" gettext-domain="unity">
203+ <key type="u" name="grab-wait">
204+ <default>175</default>
205+ <range min="0" max="1000"/>
206+ <summary>Milliseconds to wait before considering a mouse pressure a grab</summary>
207+ <description>The number of ms to wait before starting the window movement (and then
208+ showing the proper mouse cursor, and grabbing the window)</description>
209+ </key>
210+ </schema>
211+ <schema path="/com/canonical/unity/integrated-menus/" id="com.canonical.Unity.IntegratedMenus" gettext-domain="unity">
212+ <key type="u" name="click-movement-threshold">
213+ <default>15</default>
214+ <range min="0" max="30"/>
215+ <summary>Number of pixels to ignore on mouse pressure</summary>
216+ <description>This value define how many pixels the user can move the mouse
217+ when holding the mouse button, before we consider his action a movement
218+ (to grab the window).</description>
219+ </key>
220+ <key type="u" name="double-click-wait">
221+ <default>0</default>
222+ <range min="0" max="300"/>
223+ <summary>Milliseconds to wait before activating a menu after mouse release</summary>
224+ <description>The number of ms to wait after a mouse button release event before considering
225+ it a click. When this value is greater than 0, then it's possible to maximize
226+ a window by double-clicking on its menus if the second click happens before the
227+ specified value of ms is elapsed</description>
228+ </key>
229+ <key type="b" name="unfocused-windows-popup">
230+ <default>true</default>
231+ <summary>Whether to pop-up a menu when clicking over unfocused windows entries</summary>
232+ <description>By disabling this setting you can make unity to only focus a window
233+ when clicking over unfocused menu entries</description>
234+ </key>
235+ </schema>
236+ <schema path="/com/canonical/unity/gestures/" id="com.canonical.Unity.Gestures" gettext-domain="unity">
237+ <key type="b" name="launcher-drag">
238+ <default>true</default>
239+ <summary>Multi-touch gesture to reveal the launcher.</summary>
240+ <description>When this is enabled, a 4 finger swipe from left to right will reveal launcher,
241+ provided that the launcher is set to auto-hide.</description>
242+ </key>
243+ <key type="b" name="dash-tap">
244+ <default>true</default>
245+ <summary>Multi-touch gesture to open the dash.</summary>
246+ <description>When this is enabled, a 4 finger tap will open the dash.</description>
247+ </key>
248+ <key type="b" name="windows-drag-pinch">
249+ <default>true</default>
250+ <summary>Multi-touch gestures to manage the windows.</summary>
251+ <description>When this is enabled, 3 finger gestures such as drag, and pinch, will
252+ help manage the windows.</description>
253+ </key>
254+ </schema>
255+</schemalist>
data/unity8.conf+33−32
@@ -8,31 +8,44 @@ stop on desktop-end
8
8
9kill timeout 120
9kill timeout 120
10
10
11+#
12+# Ensure the shell always gets unthrottled touch events, so that applications
13+# who want full speed low-latency input can get it (LP: #1497105) and so that
14+# apps can use QML touch compression safely (the QML touch compression
15+# algorithm does not support nesting well - LP: #1486341, LP: #1556763 - so
16+# must be fed by the raw input event stream from Unity8).
17+#
18+env QML_NO_TOUCH_COMPRESSION=1
19+
11respawn
20respawn
12expect stop
21expect stop
13
22
23+# FIXME Create an autopilot test that makes sure start+stop and restart
24+# work fine at least 2 times
25+
14pre-start script
26pre-start script
15 # Tell unity-mir to raise SIGSTOP after we start
27 # Tell unity-mir to raise SIGSTOP after we start
16 initctl set-env UNITY_MIR_EMITS_SIGSTOP=1
28 initctl set-env UNITY_MIR_EMITS_SIGSTOP=1
17
29
18− if [ -n "$MIR_SOCKET" ]; then
19− # FIXME Create an autopilot test that makes sure start+stop and restart
20− # work fine at least 2 times
21− # Save original value of MIR_SOCKET in case we are stopped,
30+ # Save original value of MIR_SOCKET so that we can restore it when stopped,
22− # as we modify the variable for future jobs, including ourself.
31+ # as we modify the variable for future jobs, including ourself.
23− UNITY_MIR_SOCKET=$(initctl get-env --global MIR_SOCKET)
24− initctl set-env --global UNITY_MIR_SOCKET=$UNITY_MIR_SOCKET
32+ initctl set-env UNITY_MIR_SOCKET=$MIR_SOCKET
25
33
26− # Point unity8 at unity-system-compositor
34+ # Decide where we are going to put our own socket file
35+ if [ -n "$SNAP" ]; then
36+ # In snappy, we want to hard code our path because our apparmor profile
37+ # only lets us put the socket in one place. And consumers expect it
38+ # there.
39+ MIR_SERVER_FILE=/run/user/$(id -u)/mir_socket
40+ else
27 MIR_SERVER_FILE=$XDG_RUNTIME_DIR/mir_socket
41 MIR_SERVER_FILE=$XDG_RUNTIME_DIR/mir_socket
28− initctl set-env MIR_SERVER_FILE=$MIR_SERVER_FILE
29− initctl set-env MIR_SERVER_HOST_SOCKET=$UNITY_MIR_SOCKET
30−
31− # Point all future jobs in this session to our Mir socket instead of
32− # unity-system-compositor's socket.
33− initctl set-env --global MIR_SOCKET=$MIR_SERVER_FILE
34− gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'MIR_SOCKET': '$MIR_SERVER_FILE'}"
35 fi
42 fi
43+ initctl set-env MIR_SERVER_FILE=$MIR_SERVER_FILE
44+
45+ # Point all future jobs in this session to our Mir socket instead of
46+ # unity-system-compositor's socket.
47+ initctl set-env --global MIR_SOCKET=$MIR_SERVER_FILE
48+ gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'MIR_SOCKET': '$MIR_SERVER_FILE'}"
36
49
37 # Remove the normal and trusted sockets if still there
50 # Remove the normal and trusted sockets if still there
38 if [ -S "$MIR_SERVER_FILE" ]; then
51 if [ -S "$MIR_SERVER_FILE" ]; then
@@ -46,6 +59,7 @@ pre-start script
46 initctl set-env --global MIR_SERVER_PROMPT_FILE=1
59 initctl set-env --global MIR_SERVER_PROMPT_FILE=1
47
60
48 # Disable Qt's stuttering 'touch compression' to fix scrolling smoothness
61 # Disable Qt's stuttering 'touch compression' to fix scrolling smoothness
62+
49 # issues (LP: #1486341, LP: #1556763). As a bonus, this eliminates most of
63 # issues (LP: #1486341, LP: #1556763). As a bonus, this eliminates most of
50 # the lag seen in the indicator panel pull-down (LP: #1488327) and also
64 # the lag seen in the indicator panel pull-down (LP: #1488327) and also
51 # reduces lag seen in apps:
65 # reduces lag seen in apps:
@@ -54,7 +68,6 @@ pre-start script
54 # Workaround for text not rendering correctly
68 # Workaround for text not rendering correctly
55 initctl set-env --global QT_ENABLE_GLYPH_CACHE_WORKAROUND=1
69 initctl set-env --global QT_ENABLE_GLYPH_CACHE_WORKAROUND=1
56
70
57−
58 if [ "$XDG_SESSION_DESKTOP" = "ubuntu-touch" ]; then
71 if [ "$XDG_SESSION_DESKTOP" = "ubuntu-touch" ]; then
59 # On Ubuntu Touch, we currently use a trick where we auto-login the
72 # On Ubuntu Touch, we currently use a trick where we auto-login the
60 # user without a LightDM greeter at all. In this case, we want to
73 # user without a LightDM greeter at all. In this case, we want to
@@ -66,32 +79,20 @@ pre-start script
66 fi
79 fi
67
80
68 # HACK! WORKAROUND FOR HALIUM MISSING UBUNTU_PLATFORM_API
81 # HACK! WORKAROUND FOR HALIUM MISSING UBUNTU_PLATFORM_API
82+ if [ ! -f /system/lib/libubuntu_application_api.so ]; then
69− initctl set-env --global UBUNTU_PLATFORM_API_BACKEND=test.so.3
83+ initctl set-env --global UBUNTU_PLATFORM_API_BACKEND=test.so.3
70− initctl set-env --global UBUNTU_PLATFORM_API_SENSOR_TEST=/etc/ubuntusensors/test.sensors
84+ initctl set-env --global UBUNTU_PLATFORM_API_SENSOR_TEST=/etc/ubuntusensors/test.sensors
85+ fi
71end script
86end script
72
87
73exec ${BINARY:-unity8} --mode=$MODE $ARGS
88exec ${BINARY:-unity8} --mode=$MODE $ARGS
74
89
75post-start script
90post-start script
76− # If no MIR_SOCKET was defined on launch, we try to set one here
77− if [ -z "$(initctl get-env --global UNITY_MIR_SOCKET)" ]; then
78− if [ -S "$XDG_RUNTIME_DIR/mir_socket" ]; then
79− mir_socket=$XDG_RUNTIME_DIR/mir_socket
80− elif [ -S "/tmp/mir_socket" ]; then
81− mir_socket=/tmp/mir_socket
82− fi
83−
84− if [ -n "$mir_socket" ]; then
85− initctl set-env --global MIR_SOCKET="$mir_socket"
86− fi
87− fi
88−
89 initctl emit --no-wait indicator-services-start
91 initctl emit --no-wait indicator-services-start
90end script
92end script
91
93
92post-stop script
94post-stop script
93 initctl set-env --global MIR_SOCKET=$UNITY_MIR_SOCKET
95 initctl set-env --global MIR_SOCKET=$UNITY_MIR_SOCKET
94− initctl unset-env --global UNITY_MIR_SOCKET
95 initctl unset-env --global MIR_SERVER_PROMPT_FILE
96 initctl unset-env --global MIR_SERVER_PROMPT_FILE
96 initctl emit application-end
97 initctl emit application-end
97end script
98end script
debian/changelog+36
@@ -1,3 +1,39 @@
1+unity8 (8.17+ubports5) xenial; urgency=medium
2+
3+ * Yet more papercuts in Wizard update interaction:
4+ * It's not possible to skip the app update page while it's checking for
5+ updates, so make it say "Please wait..." while checking
6+ * Make Changelog page indicate that the next page is loading after the next
7+ button has been clicked. This avoids skipping the app update page.
8+
9+-- Dalton Durst <dalton@ubports.com> Mon, 8 Oct 2018 13:32:13 -0500
10+
11+unity8 (8.17+ubports4) xenial; urgency=medium
12+
13+ * Replace dependency on ubuntu-wallpapers with ubports-wallpapers
14+
15+ -- Dalton Durst <dalton@ubports.com> Fri, 5 Oct 2018 13:28:20 -0500
16+
17+unity8 (8.17+ubports3) xenial; urgency=medium
18+
19+ * Fix papercuts in Wizard update page interaction:
20+ * Remove "Stop" button for app update check
21+ * Make "not connected to internet" message more clear
22+
23+ -- Dalton Durst <dalton@ubports.com> Fri, 28 Sep 2018 14:08:00 -0500
24+
25+unity8 (8.17+ubports2) xenial; urgency=medium
26+
27+ * Fix for https://github.com/ubports/ubuntu-touch/issues/624
28+
29+ -- Dalton Durst <dalton@ubports.com> Fri, 1 Jun 2018 16:14:11 -0500
30+
31+unity8 (8.17+ubports1) UNRELEASED; urgency=medium
32+
33+ * No change rebuild to generate sources in ubports repo
34+
35+ -- Dan Chapman <dan@ubports.com> Tue, 20 Feb 2018 07:09:11 +0000
36+
1unity8 (8.16+ubports) xenial; urgency=medium
37unity8 (8.16+ubports) xenial; urgency=medium
2
38
3 * Imported to UBports
39 * Imported to UBports
debian/control+15−4
@@ -26,7 +26,6 @@ Build-Depends: cmake,
26 libhardware-dev,
26 libhardware-dev,
27 liblightdm-qt5-3-dev,
27 liblightdm-qt5-3-dev,
28 libpam0g-dev,
28 libpam0g-dev,
29− libpay2-dev,
30 libpulse-dev,
29 libpulse-dev,
31 libqmenumodel-dev (>= 0.2.10),
30 libqmenumodel-dev (>= 0.2.10),
32 libqt5svg5-dev,
31 libqt5svg5-dev,
@@ -159,12 +158,13 @@ Depends: qml-module-qtquick-layouts,
159 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
158 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
160 qttranslations5-l10n,
159 qttranslations5-l10n,
161 ubuntu-thumbnailer-impl-0,
160 ubuntu-thumbnailer-impl-0,
162− ubuntu-wallpapers,
161+ ubports-wallpapers,
163 unity-application-impl-22,
162 unity-application-impl-22,
164 unity-notifications-impl-3,
163 unity-notifications-impl-3,
165 unity-plugin-scopes | unity-scopes-impl,
164 unity-plugin-scopes | unity-scopes-impl,
166 unity-scopes-impl-12,
165 unity-scopes-impl-12,
167 unity8-fake-env | unity-application-impl,
166 unity8-fake-env | unity-application-impl,
167+ unity8-schemas,
168 ${misc:Depends},
168 ${misc:Depends},
169Breaks: unity8 (<< 7.86),
169Breaks: unity8 (<< 7.86),
170Replaces: unity8 (<< 7.86),
170Replaces: unity8 (<< 7.86),
@@ -219,8 +219,7 @@ Pre-Depends: ${misc:Pre-Depends},
219Depends: accountsservice-ubuntu-schemas (>= 0.0.7),
219Depends: accountsservice-ubuntu-schemas (>= 0.0.7),
220 gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
220 gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
221 libhardware2,
221 libhardware2,
222− pay-service,
222+ unity8-schemas,
223− unity-schemas (>= 7.3.1+14.10.20140915),
224 qtdeclarative5-gsettings1.0,
223 qtdeclarative5-gsettings1.0,
225 qml-module-qtmultimedia,
224 qml-module-qtmultimedia,
226 ${misc:Depends},
225 ${misc:Depends},
@@ -233,6 +232,18 @@ Description: Unity 8 private libs
233 This package contains the private libraries for QML and other components
232 This package contains the private libraries for QML and other components
234 only used by the shell.
233 only used by the shell.
235
234
235+
236+Package: unity8-schemas
237+Architecture: all
238+Multi-Arch: foreign
239+Depends: ${misc:Depends},
240+Replaces: unity-schemas (>= 7.3.1+14.10.20140915),
241+Breaks: unity-schemas (>= 7.3.1+14.10.20140915),
242+Description: Unity 8 schemas
243+ The Unity 8 shell is the primary user interface for Ubuntu devices.
244+ .
245+ This package contains the configuration schemas used by unity.
246+
236Package: unity8-doc
247Package: unity8-doc
237Section: doc
248Section: doc
238Architecture: all
249Architecture: all
debian/unity8-common.install−1
@@ -1,4 +1,3 @@
1−usr/share/glib-2.0/schemas
2usr/share/locale
1usr/share/locale
3usr/share/unity8/Components
2usr/share/unity8/Components
4usr/share/unity8/Dash
3usr/share/unity8/Dash
debian/unity8-schemas.installnew file+1
@@ -0,0 +1 @@
1+usr/share/glib-2.0/schemas
plugins/Dash/abstractdashview.cpp+1−1
@@ -236,7 +236,7 @@ QQuickItem *AbstractDashView::createItem(int modelIndex, bool asynchronous)
236 return nullptr;
236 return nullptr;
237
237
238 m_asyncRequestedIndex = -1;
238 m_asyncRequestedIndex = -1;
239− QObject* object = m_delegateModel->object(modelIndex, asynchronous);
239+ QObject* object = m_delegateModel->object(modelIndex, asynchronous ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
240 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
240 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
241 if (!item) {
241 if (!item) {
242 if (object) {
242 if (object) {
plugins/Dash/listviewwithpageheader.cpp+4−6
@@ -871,7 +871,7 @@ ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIn
871 return nullptr;
871 return nullptr;
872
872
873 m_asyncRequestedIndex = -1;
873 m_asyncRequestedIndex = -1;
874− QObject* object = m_delegateModel->object(modelIndex, asynchronous);
874+ QObject* object = m_delegateModel->object(modelIndex, asynchronous ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
875 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
875 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
876 if (!item) {
876 if (!item) {
877 if (object) {
877 if (object) {
@@ -1141,11 +1141,10 @@ void ListViewWithPageHeader::contentYAnimationRunningChanged(bool running)
1141 }
1141 }
1142}
1142}
1143
1143
1144−/*
1145−void ListViewWithPageHeader::itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry)
1144+void ListViewWithPageHeader::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry)
1146{
1145{
1146+ if (change.heightChange()) {
1147− const qreal heightDiff = newGeometry.height() - oldGeometry.height();
1147+ const qreal heightDiff = height() - oldGeometry.height();
1148− if (heightDiff != 0) {
1149 if (!m_visibleItems.isEmpty()) {
1148 if (!m_visibleItems.isEmpty()) {
1150 ListItem *firstItem = m_visibleItems.first();
1149 ListItem *firstItem = m_visibleItems.first();
1151 const auto prevFirstItemY = firstItem->y();
1150 const auto prevFirstItemY = firstItem->y();
@@ -1166,7 +1165,6 @@ void ListViewWithPageHeader::itemGeometryChanged(QQuickItem *item, const QRectF
1166 m_contentHeightDirty = true;
1165 m_contentHeightDirty = true;
1167 }
1166 }
1168}
1167}
1169−*/
1170
1168
1171void ListViewWithPageHeader::itemImplicitHeightChanged(QQuickItem *item)
1169void ListViewWithPageHeader::itemImplicitHeightChanged(QQuickItem *item)
1172{
1170{
plugins/Dash/listviewwithpageheader.h+1−1
@@ -116,7 +116,7 @@ protected:
116 void viewportMoved(Qt::Orientations orient) override;
116 void viewportMoved(Qt::Orientations orient) override;
117 qreal minYExtent() const override;
117 qreal minYExtent() const override;
118 qreal maxYExtent() const override;
118 qreal maxYExtent() const override;
119− //void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) override;
119+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) override;
120 void itemImplicitHeightChanged(QQuickItem *item) override;
120 void itemImplicitHeightChanged(QQuickItem *item) override;
121 void updatePolish() override;
121 void updatePolish() override;
122
122
plugins/Dash/verticaljournal.cpp+6−8
@@ -271,11 +271,9 @@ void VerticalJournal::processModelRemoves(const QVector<QQmlChangeSet::Change> &
271 }
271 }
272}
272}
273
273
274−
275−//void VerticalJournal::itemGeometryChanged(QQuickItem * /*item*/, const QRectF &newGeometry, const QRectF &oldGeometry)
274+void VerticalJournal::itemGeometryChanged(QQuickItem * /*item*/, QQuickGeometryChange change, const QRectF &)
276−//{
275+{
277−// const qreal heightDiff = newGeometry.height() - oldGeometry.height();
276+ if (change.verticalChange()) {
278−// if (heightDiff != 0) {
279−// relayout();
277+ relayout();
280−// }
278+ }
281−//}
279+}
plugins/Dash/verticaljournal.h+1−1
@@ -66,7 +66,7 @@ public:
66 void setColumnWidth(qreal columnWidth);
66 void setColumnWidth(qreal columnWidth);
67
67
68protected:
68protected:
69−// void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) override;
69+ void itemGeometryChanged(QQuickItem * /*item*/, QQuickGeometryChange change, const QRectF &oldGeometry) override;
70
70
71Q_SIGNALS:
71Q_SIGNALS:
72 void columnWidthChanged();
72 void columnWidthChanged();
plugins/Ubuntu/CMakeLists.txt+1−1
@@ -1,4 +1,4 @@
1add_subdirectory(Gestures)
1add_subdirectory(Gestures)
2add_subdirectory(DownloadDaemonListener)
2add_subdirectory(DownloadDaemonListener)
3−add_subdirectory(Payments)
3+#add_subdirectory(Payments)
4add_subdirectory(SystemImage)
4add_subdirectory(SystemImage)
plugins/Wizard/CMakeLists.txt+1
@@ -10,6 +10,7 @@ add_library(Wizard-qml MODULE
10 timezonemodel.cpp
10 timezonemodel.cpp
11 Status.cpp
11 Status.cpp
12 keyboardLayoutsModel.cpp
12 keyboardLayoutsModel.cpp
13+ Changelog.cpp
13)
14)
14
15
15qt5_use_modules(Wizard-qml DBus Qml)
16qt5_use_modules(Wizard-qml DBus Qml)
plugins/Wizard/Changelog.cppnew file+58
@@ -0,0 +1,58 @@
1+/*
2+ * Copyright (C) 2018 The UBports project
3+ * Written by: Marius Gripsgard <marius@ubports.com>
4+ *
5+ * This program is free software: you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 3, as published
7+ * by the Free Software Foundation.
8+ *
9+ * This program is distributed in the hope that it will be useful, but
10+ * WITHOUT ANY WARRANTY; without even the implied warranties of
11+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12+ * PURPOSE. See the GNU General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public License along
15+ * with this program. If not, see <http://www.gnu.org/licenses/>.
16+ */
17+
18+#include "Changelog.h"
19+
20+#include <QDir>
21+#include <QFile>
22+#include <QTextStream>
23+
24+Changelog::Changelog()
25+ : QObject()
26+{
27+ readChangelog();
28+ if(QFile::exists(changelogPath()))
29+ m_fsWatcher.addPath(changelogPath());
30+ connect(&m_fsWatcher, &QFileSystemWatcher::fileChanged, this, &Changelog::watcherFileChanged);
31+}
32+
33+QString Changelog::changelogPath()
34+{
35+ return "/usr/share/ubports/changelogs/current";
36+}
37+
38+QString Changelog::text() const
39+{
40+ return m_text;
41+}
42+
43+void Changelog::readChangelog()
44+{
45+ if(!QFile::exists(changelogPath()))
46+ return;
47+ QFile f(changelogPath());
48+ if (!f.open(QFile::ReadOnly | QFile::Text)) return;
49+ QTextStream in(&f);
50+ m_text = in.readAll();
51+ Q_EMIT textChanged();
52+}
53+
54+void Changelog::watcherFileChanged()
55+{
56+ readChangelog();
57+ m_fsWatcher.removePath(changelogPath());
58+}
plugins/Wizard/Changelog.hnew file+52
@@ -0,0 +1,52 @@
1+/*
2+ * Copyright (C) 2018 The UBports project
3+ * Written by: Marius Gripsgard <marius@ubports.com>
4+ *
5+ * This program is free software: you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 3, as published
7+ * by the Free Software Foundation.
8+ *
9+ * This program is distributed in the hope that it will be useful, but
10+ * WITHOUT ANY WARRANTY; without even the implied warranties of
11+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12+ * PURPOSE. See the GNU General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public License along
15+ * with this program. If not, see <http://www.gnu.org/licenses/>.
16+ */
17+
18+#ifndef WIZARD_CHANGELOG_H
19+#define WIZARD_CHANGELOG_H
20+
21+#include <QFileSystemWatcher>
22+#include <QObject>
23+#include <QString>
24+
25+class Changelog : public QObject
26+{
27+ Q_OBJECT
28+ Q_PROPERTY(QString text READ text NOTIFY textChanged)
29+
30+public:
31+ Changelog();
32+ ~Changelog() = default;
33+
34+ QString text() const;
35+
36+Q_SIGNALS:
37+ void textChanged();
38+
39+private Q_SLOTS:
40+ void watcherFileChanged();
41+
42+private:
43+ Q_DISABLE_COPY(Changelog)
44+
45+ static QString changelogPath();
46+ void readChangelog();
47+
48+ QFileSystemWatcher m_fsWatcher;
49+ QString m_text;
50+};
51+
52+#endif
plugins/Wizard/System.cpp+64−3
@@ -1,4 +1,5 @@
1/*
1/*
2+ * Copyright (C) 2018 The UBports project
2 * Copyright (C) 2014-2016 Canonical Ltd.
3 * Copyright (C) 2014-2016 Canonical Ltd.
3 *
4 *
4 * This program is free software: you can redistribute it and/or modify it
5 * This program is free software: you can redistribute it and/or modify it
@@ -46,29 +47,89 @@ QString System::wizardEnabledPath()
46 return QDir::home().filePath(QStringLiteral(".config/ubuntu-system-settings/wizard-has-run"));
47 return QDir::home().filePath(QStringLiteral(".config/ubuntu-system-settings/wizard-has-run"));
47}
48}
48
49
50+QString System::currentFrameworkPath()
51+{
52+ QFileInfo f("/usr/share/click/frameworks/current");
53+ return f.canonicalFilePath();
54+}
55+
56+/*
57+wizardEnabled and isUpdate logic
58+
59+if wizard-has-run does NOT exist == is new install
60+if wizard-has-run exists but does NOT match current framework == is update
61+if wizard-has-run exists but does match current framework == show no wizard
62+*/
63+
64+bool System::wizardPathExists() {
65+ return QFile::exists(wizardEnabledPath());
66+}
67+
49bool System::wizardEnabled() const
68bool System::wizardEnabled() const
50{
69{
70+ if (!wizardPathExists()) {
71+ return true;
72+ }
73+ return isUpdate();
74+}
75+
76+QString System::readCurrentFramework()
77+{
78+ QFile f(currentFrameworkPath());
79+ if (!f.open(QFile::ReadOnly | QFile::Text)) return "";
80+ QTextStream in(&f);
81+ return in.readAll();
82+}
83+
84+QString System::readWizardEnabled()
85+{
51− return !QFile::exists(wizardEnabledPath());
86+ QFile f(wizardEnabledPath());
87+ if (!f.open(QFile::ReadOnly | QFile::Text)) return "";
88+ QTextStream in(&f);
89+ return in.readAll();
90+}
91+
92+QString System::version() const
93+{
94+ return readCurrentFramework();
95+}
96+
97+bool System::isUpdate() const
98+{
99+ if (!wizardPathExists()) {
100+ return false;
101+ }
102+
103+ return readCurrentFramework() != readWizardEnabled();
52}
104}
53
105
54void System::setWizardEnabled(bool enabled)
106void System::setWizardEnabled(bool enabled)
55{
107{
56− if (wizardEnabled() == enabled)
108+ if (wizardEnabled() == enabled && !isUpdate())
57 return;
109 return;
58
110
59 if (enabled) {
111 if (enabled) {
60 QFile::remove(wizardEnabledPath());
112 QFile::remove(wizardEnabledPath());
61 } else {
113 } else {
62 QDir(wizardEnabledPath()).mkpath(QStringLiteral(".."));
114 QDir(wizardEnabledPath()).mkpath(QStringLiteral(".."));
63− QFile(wizardEnabledPath()).open(QIODevice::WriteOnly);
115+ if (QFile::exists(wizardEnabledPath())) {
116+ QFile::remove(wizardEnabledPath());
117+ }
118+ // For special cases check if wizardEnabledPath is a folder
119+ if (QDir(wizardEnabledPath()).exists()) {
120+ QDir(wizardEnabledPath()).removeRecursively();
121+ }
122+ QFile::copy(currentFrameworkPath(), wizardEnabledPath());
64 m_fsWatcher.addPath(wizardEnabledPath());
123 m_fsWatcher.addPath(wizardEnabledPath());
65 Q_EMIT wizardEnabledChanged();
124 Q_EMIT wizardEnabledChanged();
125+ Q_EMIT isUpdateChanged();
66 }
126 }
67}
127}
68
128
69void System::watcherFileChanged()
129void System::watcherFileChanged()
70{
130{
71 Q_EMIT wizardEnabledChanged();
131 Q_EMIT wizardEnabledChanged();
132+ Q_EMIT isUpdateChanged();
72 m_fsWatcher.removePath(wizardEnabledPath());
133 m_fsWatcher.removePath(wizardEnabledPath());
73}
134}
74
135
plugins/Wizard/System.h+17
@@ -1,4 +1,5 @@
1/*
1/*
2+ * Copyright (C) 2018 The UBports project
2 * Copyright (C) 2014-2016 Canonical Ltd.
3 * Copyright (C) 2014-2016 Canonical Ltd.
3 *
4 *
4 * This program is free software: you can redistribute it and/or modify it
5 * This program is free software: you can redistribute it and/or modify it
@@ -18,6 +19,7 @@
18#define WIZARD_SYSTEM_H
19#define WIZARD_SYSTEM_H
19
20
20#include <QFileSystemWatcher>
21#include <QFileSystemWatcher>
22+#include <QVersionNumber>
21#include <QObject>
23#include <QObject>
22#include <QString>
24#include <QString>
23
25
@@ -25,12 +27,21 @@ class System : public QObject
25{
27{
26 Q_OBJECT
28 Q_OBJECT
27 Q_PROPERTY(bool wizardEnabled READ wizardEnabled WRITE setWizardEnabled NOTIFY wizardEnabledChanged)
29 Q_PROPERTY(bool wizardEnabled READ wizardEnabled WRITE setWizardEnabled NOTIFY wizardEnabledChanged)
30+ Q_PROPERTY(QString version READ version NOTIFY versionChanged)
31+ Q_PROPERTY(bool isUpdate READ isUpdate NOTIFY isUpdateChanged)
28
32
29public:
33public:
30 System();
34 System();
31 ~System() = default;
35 ~System() = default;
32
36
37+ /**
38+ * Checks whether the wizard is enabled for first-run or otherwise.
39+ */
33 bool wizardEnabled() const;
40 bool wizardEnabled() const;
41+
42+ QString version() const;
43+ bool isUpdate() const;
44+
34 void setWizardEnabled(bool enabled);
45 void setWizardEnabled(bool enabled);
35
46
36public Q_SLOTS:
47public Q_SLOTS:
@@ -42,6 +53,8 @@ public Q_SLOTS:
42
53
43Q_SIGNALS:
54Q_SIGNALS:
44 void wizardEnabledChanged();
55 void wizardEnabledChanged();
56+ void versionChanged();
57+ void isUpdateChanged();
45
58
46private Q_SLOTS:
59private Q_SLOTS:
47 void watcherFileChanged();
60 void watcherFileChanged();
@@ -50,7 +63,11 @@ private:
50 Q_DISABLE_COPY(System)
63 Q_DISABLE_COPY(System)
51
64
52 static QString wizardEnabledPath();
65 static QString wizardEnabledPath();
66+ static QString currentFrameworkPath();
53 static void setSessionVariable(const QString &variable, const QString &value);
67 static void setSessionVariable(const QString &variable, const QString &value);
68+ static QString readCurrentFramework();
69+ static QString readWizardEnabled();
70+ static bool wizardPathExists();
54
71
55 QFileSystemWatcher m_fsWatcher;
72 QFileSystemWatcher m_fsWatcher;
56};
73};
plugins/Wizard/plugin.cpp+2
@@ -20,6 +20,7 @@
20#include "timezonemodel.h"
20#include "timezonemodel.h"
21#include "LocalePlugin.h"
21#include "LocalePlugin.h"
22#include "Status.h"
22#include "Status.h"
23+#include "Changelog.h"
23#include "keyboardLayoutsModel.h"
24#include "keyboardLayoutsModel.h"
24
25
25#include <QtQml/qqml.h>
26#include <QtQml/qqml.h>
@@ -30,6 +31,7 @@ void WizardPlugin::registerTypes(const char *uri)
30 qmlRegisterType<PageList>(uri, 0, 1, "PageList");
31 qmlRegisterType<PageList>(uri, 0, 1, "PageList");
31 qmlRegisterSingletonType<System>(uri, 0, 1, "System", [](QQmlEngine*, QJSEngine*) -> QObject* { return new System; });
32 qmlRegisterSingletonType<System>(uri, 0, 1, "System", [](QQmlEngine*, QJSEngine*) -> QObject* { return new System; });
32 qmlRegisterSingletonType<Status>(uri, 0, 1, "Status", [](QQmlEngine*, QJSEngine*) -> QObject* { return new Status; });
33 qmlRegisterSingletonType<Status>(uri, 0, 1, "Status", [](QQmlEngine*, QJSEngine*) -> QObject* { return new Status; });
34+ qmlRegisterSingletonType<Changelog>(uri, 0, 1, "Changelog", [](QQmlEngine*, QJSEngine*) -> QObject* { return new Changelog; });
33 qmlRegisterType<TimeZoneLocationModel>(uri, 0, 1, "TimeZoneModel");
35 qmlRegisterType<TimeZoneLocationModel>(uri, 0, 1, "TimeZoneModel");
34 qmlRegisterType<KeyboardLayoutsModel>(uri, 0, 1, "KeyboardLayoutsModel");
36 qmlRegisterType<KeyboardLayoutsModel>(uri, 0, 1, "KeyboardLayoutsModel");
35 qmlRegisterType<LocalePlugin>(uri, 0, 1, "LocalePlugin");
37 qmlRegisterType<LocalePlugin>(uri, 0, 1, "LocalePlugin");
po/unity8.pot+159−84
@@ -8,7 +8,7 @@ msgid ""
8msgstr ""
8msgstr ""
9"Project-Id-Version: unity8\n"
9"Project-Id-Version: unity8\n"
10"Report-Msgid-Bugs-To: \n"
10"Report-Msgid-Bugs-To: \n"
11−"POT-Creation-Date: 2016-11-29 09:43+0000\n"
11+"POT-Creation-Date: 2018-10-08 13:29-0500\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -449,7 +449,7 @@ msgstr ""
449msgid "Passcode"
449msgid "Passcode"
450msgstr ""
450msgstr ""
451
451
452−#: qml/Greeter/LoginList.qml:98
452+#: qml/Greeter/LoginList.qml:98 qml/Wizard/Pages/UpdateDelegate.qml:118
453msgid "Retry"
453msgid "Retry"
454msgstr ""
454msgstr ""
455
455
@@ -517,6 +517,7 @@ msgid "In queue…"
517msgstr ""
517msgstr ""
518
518
519#: qml/Panel/Indicators/MenuItemFactory.qml:999
519#: qml/Panel/Indicators/MenuItemFactory.qml:999
520+#: qml/Wizard/Pages/UpdateDelegate.qml:226
520msgid "Downloading"
521msgid "Downloading"
521msgstr ""
522msgstr ""
522
523
@@ -576,25 +577,43 @@ msgstr ""
576msgid "Swipe from the top edge to access notifications and quick settings"
577msgid "Swipe from the top edge to access notifications and quick settings"
577msgstr ""
578msgstr ""
578
579
579−#: qml/Wizard/Page.qml:54
580+#: qml/Wizard/Page.qml:59
580msgctxt "Button: Go back one page in the Wizard"
581msgctxt "Button: Go back one page in the Wizard"
581msgid "Back"
582msgid "Back"
582msgstr ""
583msgstr ""
583
584
584−#: qml/Wizard/Pages/10-welcome.qml:28
585+#: qml/Wizard/Pages/10-welcome.qml:29
585msgid "Language"
586msgid "Language"
586msgstr ""
587msgstr ""
587
588
588−#: qml/Wizard/Pages/10-welcome.qml:173 qml/Wizard/Pages/20-keyboard.qml:152
589+#: qml/Wizard/Pages/10-welcome.qml:175
589−#: qml/Wizard/Pages/30-wifi.qml:207 qml/Wizard/Pages/40-location.qml:271
590+#: qml/Wizard/Pages/10-welcome-update.qml:126
591+#: qml/Wizard/Pages/11-changelog.qml:74 qml/Wizard/Pages/20-keyboard.qml:152
590−#: qml/Wizard/Pages/50-timezone.qml:271 qml/Wizard/Pages/60-account.qml:65
592+#: qml/Wizard/Pages/30-wifi.qml:208 qml/Wizard/Pages/50-timezone.qml:272
591−#: qml/Wizard/Pages/70-passwd-type.qml:145
593+#: qml/Wizard/Pages/60-account.qml:66 qml/Wizard/Pages/70-passwd-type.qml:146
592−#: qml/Wizard/Pages/75-report-check.qml:84
594+#: qml/Wizard/Pages/75-report-check.qml:85
595+#: qml/Wizard/Pages/76-app-update.qml:236
593#: qml/Wizard/Pages/passcode-desktop.qml:142
596#: qml/Wizard/Pages/passcode-desktop.qml:142
594#: qml/Wizard/Pages/password-set.qml:142
597#: qml/Wizard/Pages/password-set.qml:142
595msgid "Next"
598msgid "Next"
596msgstr ""
599msgstr ""
597
600
601+#: qml/Wizard/Pages/10-welcome-update.qml:91
602+msgid "Welcome to "
603+msgstr ""
604+
605+#: qml/Wizard/Pages/10-welcome-update.qml:106
606+msgid "We will make sure your device is ready to use "
607+msgstr ""
608+
609+#: qml/Wizard/Pages/11-changelog.qml:28
610+msgid "What's new"
611+msgstr ""
612+
613+#: qml/Wizard/Pages/11-changelog.qml:74
614+msgid "Loading..."
615+msgstr ""
616+
598#: qml/Wizard/Pages/20-keyboard.qml:31
617#: qml/Wizard/Pages/20-keyboard.qml:31
599msgid "Select Keyboard"
618msgid "Select Keyboard"
600msgstr ""
619msgstr ""
@@ -607,9 +626,9 @@ msgstr ""
607msgid "Keyboard layout"
626msgid "Keyboard layout"
608msgstr ""
627msgstr ""
609
628
610−#: qml/Wizard/Pages/20-keyboard.qml:152 qml/Wizard/Pages/30-wifi.qml:207
629+#: qml/Wizard/Pages/20-keyboard.qml:152 qml/Wizard/Pages/30-wifi.qml:208
611−#: qml/Wizard/Pages/60-account.qml:65 qml/Wizard/Pages/77-system-update.qml:152
630+#: qml/Wizard/Pages/60-account.qml:66 qml/Wizard/Pages/76-app-update.qml:240
612−#: qml/Wizard/Pages/sim.qml:101
631+#: qml/Wizard/Pages/79-system-update.qml:152 qml/Wizard/Pages/sim.qml:101
613msgid "Skip"
632msgid "Skip"
614msgstr ""
633msgstr ""
615
634
@@ -617,55 +636,23 @@ msgstr ""
617msgid "Connect to Wi‑Fi"
636msgid "Connect to Wi‑Fi"
618msgstr ""
637msgstr ""
619
638
620−#: qml/Wizard/Pages/30-wifi.qml:132
639+#: qml/Wizard/Pages/30-wifi.qml:133
621msgid "Connected"
640msgid "Connected"
622msgstr ""
641msgstr ""
623
642
624−#: qml/Wizard/Pages/30-wifi.qml:165
643+#: qml/Wizard/Pages/30-wifi.qml:166
625msgid "Available Wi-Fi networks"
644msgid "Available Wi-Fi networks"
626msgstr ""
645msgstr ""
627
646
628−#: qml/Wizard/Pages/30-wifi.qml:166
647+#: qml/Wizard/Pages/30-wifi.qml:167
629msgid "No available Wi-Fi networks"
648msgid "No available Wi-Fi networks"
630msgstr ""
649msgstr ""
631
650
632−#: qml/Wizard/Pages/40-location.qml:27
633−msgid "Location Services"
634−msgstr ""
635−
636−#: qml/Wizard/Pages/40-location.qml:83
637−msgid ""
638−"Use GPS, Wi-Fi hotspots and mobile network anonymously to detect location "
639−"(recommended)"
640−msgstr ""
641−
642−#: qml/Wizard/Pages/40-location.qml:105
643−#, qt-format
644−msgid "By selecting this option you agree to the Nokia HERE %1."
645−msgstr ""
646−
647−#: qml/Wizard/Pages/40-location.qml:106
648−msgctxt "part of: Nokia HERE terms and conditions"
649−msgid "terms and conditions"
650−msgstr ""
651−
652−#: qml/Wizard/Pages/40-location.qml:160
653−msgid "GPS only"
654−msgstr ""
655−
656−#: qml/Wizard/Pages/40-location.qml:214
657−msgid "Don't use my location"
658−msgstr ""
659−
660−#: qml/Wizard/Pages/40-location.qml:260
661−msgid "You can change it later in System Settings."
662−msgstr ""
663−
664#: qml/Wizard/Pages/50-timezone.qml:30
651#: qml/Wizard/Pages/50-timezone.qml:30
665msgid "Time Zone"
652msgid "Time Zone"
666msgstr ""
653msgstr ""
667
654
668−#: qml/Wizard/Pages/50-timezone.qml:182
655+#: qml/Wizard/Pages/50-timezone.qml:183
669msgid "Enter your city"
656msgid "Enter your city"
670msgstr ""
657msgstr ""
671
658
@@ -673,7 +660,7 @@ msgstr ""
673msgid "Personalize Your Device"
660msgid "Personalize Your Device"
674msgstr ""
661msgstr ""
675
662
676−#: qml/Wizard/Pages/60-account.qml:48
663+#: qml/Wizard/Pages/60-account.qml:49
677msgid "Preferred Name"
664msgid "Preferred Name"
678msgstr ""
665msgstr ""
679
666
@@ -681,22 +668,22 @@ msgstr ""
681msgid "Lock Screen"
668msgid "Lock Screen"
682msgstr ""
669msgstr ""
683
670
684−#: qml/Wizard/Pages/70-passwd-type.qml:102
671+#: qml/Wizard/Pages/70-passwd-type.qml:103
685msgctxt "Label: Type of security method"
672msgctxt "Label: Type of security method"
686msgid "Create new password"
673msgid "Create new password"
687msgstr ""
674msgstr ""
688
675
689−#: qml/Wizard/Pages/70-passwd-type.qml:104
676+#: qml/Wizard/Pages/70-passwd-type.qml:105
690msgctxt "Label: Type of security method"
677msgctxt "Label: Type of security method"
691msgid "Create passcode (numbers only)"
678msgid "Create passcode (numbers only)"
692msgstr ""
679msgstr ""
693
680
694−#: qml/Wizard/Pages/70-passwd-type.qml:106
681+#: qml/Wizard/Pages/70-passwd-type.qml:107
695msgctxt "Label: Type of security method"
682msgctxt "Label: Type of security method"
696msgid "No lock code"
683msgid "No lock code"
697msgstr ""
684msgstr ""
698
685
699−#: qml/Wizard/Pages/75-report-check.qml:26 qml/Wizard/Pages/here-terms.qml:108
686+#: qml/Wizard/Pages/75-report-check.qml:26
700msgid "Privacy Policy"
687msgid "Privacy Policy"
701msgstr ""
688msgstr ""
702
689
@@ -704,83 +691,109 @@ msgstr ""
704msgid "Help Us Improve"
691msgid "Help Us Improve"
705msgstr ""
692msgstr ""
706
693
707−#: qml/Wizard/Pages/75-report-check.qml:59
694+#: qml/Wizard/Pages/75-report-check.qml:60
708msgid "Improve system performance by sending us crashes and error reports."
695msgid "Improve system performance by sending us crashes and error reports."
709msgstr ""
696msgstr ""
710
697
711−#: qml/Wizard/Pages/75-report-check.qml:60
698+#: qml/Wizard/Pages/75-report-check.qml:61
712msgid "Privacy policy"
699msgid "Privacy policy"
713msgstr ""
700msgstr ""
714
701
702+#: qml/Wizard/Pages/76-app-update.qml:35
703+msgid "Update Apps"
704+msgstr ""
705+
706+#: qml/Wizard/Pages/76-app-update.qml:127
707+msgid "This device is not connected to the internet."
708+msgstr ""
709+
710+#: qml/Wizard/Pages/76-app-update.qml:128
711+#: qml/Wizard/Pages/76-app-update.qml:134
712+msgid "Use the OpenStore app to check for updates once connected."
713+msgstr ""
714+
715+#: qml/Wizard/Pages/76-app-update.qml:130
716+msgid "Software is up to date"
717+msgstr ""
718+
719+#: qml/Wizard/Pages/76-app-update.qml:133
720+msgid "The update server is not responding."
721+msgstr ""
722+
723+#: qml/Wizard/Pages/76-app-update.qml:238
724+msgid "Please wait..."
725+msgstr ""
726+
715−#: qml/Wizard/Pages/77-system-update.qml:28
727+#: qml/Wizard/Pages/79-system-update.qml:28
716msgid "Update Device"
728msgid "Update Device"
717msgstr ""
729msgstr ""
718
730
719−#: qml/Wizard/Pages/77-system-update.qml:55
731+#: qml/Wizard/Pages/79-system-update.qml:55
720msgid ""
732msgid ""
721"There is a system update available and ready to install. Afterwards, the "
733"There is a system update available and ready to install. Afterwards, the "
722"device will automatically restart."
734"device will automatically restart."
723msgstr ""
735msgstr ""
724
736
725−#: qml/Wizard/Pages/77-system-update.qml:76
737+#: qml/Wizard/Pages/79-system-update.qml:76
726msgctxt "string identifying name of the update"
738msgctxt "string identifying name of the update"
727msgid "Ubuntu system"
739msgid "Ubuntu system"
728msgstr ""
740msgstr ""
729
741
730−#: qml/Wizard/Pages/77-system-update.qml:83
742+#: qml/Wizard/Pages/79-system-update.qml:83
731#, qt-format
743#, qt-format
732msgctxt "version of the system update"
744msgctxt "version of the system update"
733msgid "Version %1"
745msgid "Version %1"
734msgstr ""
746msgstr ""
735
747
736−#: qml/Wizard/Pages/77-system-update.qml:102
748+#: qml/Wizard/Pages/79-system-update.qml:102
737msgid "This could take a few minutes..."
749msgid "This could take a few minutes..."
738msgstr ""
750msgstr ""
739
751
740−#: qml/Wizard/Pages/77-system-update.qml:116
752+#: qml/Wizard/Pages/79-system-update.qml:116
741msgid "Install and restart now"
753msgid "Install and restart now"
742msgstr ""
754msgstr ""
743
755
744−#: qml/Wizard/Pages/80-finished.qml:89
756+#: qml/Wizard/Pages/80-finished.qml:91
745−msgid "Welcome to Ubuntu"
757+msgid "Welcome Back"
746msgstr ""
758msgstr ""
747
759
748−#: qml/Wizard/Pages/80-finished.qml:104
760+#: qml/Wizard/Pages/80-finished.qml:91
749−msgid "You are ready to use your device now"
761+msgid "Welcome to Ubuntu"
750msgstr ""
762msgstr ""
751
763
752−#: qml/Wizard/Pages/80-finished.qml:124
764+#: qml/Wizard/Pages/80-finished.qml:106
753−msgid "Get Started"
765+msgid "You are ready to use your device now"
754msgstr ""
766msgstr ""
755
767
756−#: qml/Wizard/Pages/here-terms.qml:25
768+#: qml/Wizard/Pages/80-finished.qml:126
757−msgid "Terms & Conditions"
769+msgid "Continue"
758msgstr ""
770msgstr ""
759
771
760−#: qml/Wizard/Pages/here-terms.qml:69
772+#: qml/Wizard/Pages/80-finished.qml:126
761−msgid "Your device uses positioning technologies provided by HERE."
773+msgid "Get Started"
762msgstr ""
774msgstr ""
763
775
764−#: qml/Wizard/Pages/here-terms.qml:81
776+#: qml/Wizard/Pages/DownloadHandler.qml:174
765−msgid ""
777+msgid "Installation failed"
766−"To provide you with positioning services and to improve their quality, HERE "
767−"collects information about nearby cell towers and Wi-Fi hotspots around your "
768−"current location whenever your position is being found."
769msgstr ""
778msgstr ""
770
779
771−#: qml/Wizard/Pages/here-terms.qml:93
780+#: qml/Wizard/Pages/GlobalUpdateControls.qml:84
772−msgid ""
781+msgid "Checking for updates…"
773−"The information collected is used to analyze the service and to improve the "
774−"use of service, but not to identify you personally."
775msgstr ""
782msgstr ""
776
783
777−#: qml/Wizard/Pages/here-terms.qml:106
784+#: qml/Wizard/Pages/GlobalUpdateControls.qml:109
778#, qt-format
785#, qt-format
779−msgid "By continuing, you agree to the HERE platform %1 and %2."
786+msgid "%1 update available"
787+msgid_plural "%1 updates available"
788+msgstr[0] ""
789+msgstr[1] ""
790+
791+#: qml/Wizard/Pages/GlobalUpdateControls.qml:119
792+msgid "Update all…"
780msgstr ""
793msgstr ""
781
794
782−#: qml/Wizard/Pages/here-terms.qml:107
795+#: qml/Wizard/Pages/GlobalUpdateControls.qml:121
783−msgid "Service Terms"
796+msgid "Update all"
784msgstr ""
797msgstr ""
785
798
786#: qml/Wizard/Pages/passcode-confirm.qml:43
799#: qml/Wizard/Pages/passcode-confirm.qml:43
@@ -866,6 +879,68 @@ msgstr ""
866msgid "To proceed with no SIM tap Skip."
879msgid "To proceed with no SIM tap Skip."
867msgstr ""
880msgstr ""
868
881
882+#: qml/Wizard/Pages/UpdateDelegate.qml:123
883+msgid "Update"
884+msgstr ""
885+
886+#: qml/Wizard/Pages/UpdateDelegate.qml:125
887+msgid "Download"
888+msgstr ""
889+
890+#: qml/Wizard/Pages/UpdateDelegate.qml:131
891+msgid "Resume"
892+msgstr ""
893+
894+#: qml/Wizard/Pages/UpdateDelegate.qml:138
895+msgid "Pause"
896+msgstr ""
897+
898+#: qml/Wizard/Pages/UpdateDelegate.qml:142
899+msgid "Install…"
900+msgstr ""
901+
902+#: qml/Wizard/Pages/UpdateDelegate.qml:144
903+msgid "Install"
904+msgstr ""
905+
906+#: qml/Wizard/Pages/UpdateDelegate.qml:148
907+msgid "Open"
908+msgstr ""
909+
910+#: qml/Wizard/Pages/UpdateDelegate.qml:216
911+msgid "Installing"
912+msgstr ""
913+
914+#: qml/Wizard/Pages/UpdateDelegate.qml:220
915+msgid "Paused"
916+msgstr ""
917+
918+#: qml/Wizard/Pages/UpdateDelegate.qml:223
919+msgid "Waiting to download"
920+msgstr ""
921+
922+#: qml/Wizard/Pages/UpdateDelegate.qml:279
923+#, qt-format
924+msgid "%1 of %2"
925+msgstr ""
926+
927+#: qml/Wizard/Pages/UpdateDelegate.qml:283
928+msgid "Downloaded"
929+msgstr ""
930+
931+#: qml/Wizard/Pages/UpdateDelegate.qml:286
932+msgid "Installed"
933+msgstr ""
934+
935+#: qml/Wizard/Pages/UpdateDelegate.qml:291
936+#, qt-format
937+msgid "Updated %1"
938+msgstr ""
939+
940+#: qml/Wizard/Pages/UpdateDelegate.qml:315
941+msgid "Update failed"
942+msgstr ""
943+
869#: qml/Wizard/PasswordMeter.qml:87
944#: qml/Wizard/PasswordMeter.qml:87
870msgid "Password too short"
945msgid "Password too short"
871msgstr ""
946msgstr ""
qml/Dash/DashBackground.qml+1−1
@@ -31,6 +31,6 @@ Rectangle {
31 source: AccountsService.backgroundFile
31 source: AccountsService.backgroundFile
32 anchors.fill: parent
32 anchors.fill: parent
33 fillMode: Image.PreserveAspectCrop
33 fillMode: Image.PreserveAspectCrop
34− opacity: 0.6
34+ opacity: settings.backgroundOpacity
35 }
35 }
36}
36}
qml/Dash/Previews/PreviewWidgetFactory.qml−1
@@ -67,7 +67,6 @@ Loader {
67 case "icon-actions": return "PreviewIconActions.qml";
67 case "icon-actions": return "PreviewIconActions.qml";
68 case "image": return "PreviewZoomableImage.qml";
68 case "image": return "PreviewZoomableImage.qml";
69 case "progress": return "PreviewProgress.qml";
69 case "progress": return "PreviewProgress.qml";
70− case "payments": return "PreviewPayments.qml";
71 case "rating-input": return "PreviewRatingInput.qml";
70 case "rating-input": return "PreviewRatingInput.qml";
72 case "rating-edit": return "PreviewRatingEdit.qml";
71 case "rating-edit": return "PreviewRatingEdit.qml";
73 case "reviews": return "PreviewRatingDisplay.qml";
72 case "reviews": return "PreviewRatingDisplay.qml";
qml/Shell.qml+2−1
@@ -1,4 +1,5 @@
1/*
1/*
2+ * Copyright (C) 2018 The UBports project
2 * Copyright (C) 2013-2016 Canonical, Ltd.
3 * Copyright (C) 2013-2016 Canonical, Ltd.
3 *
4 *
4 * This program is free software; you can redistribute it and/or modify
5 * This program is free software; you can redistribute it and/or modify
@@ -346,7 +347,7 @@ StyledItem {
346 hides: [launcher, panel.indicators]
347 hides: [launcher, panel.indicators]
347 tabletMode: shell.usageScenario != "phone"
348 tabletMode: shell.usageScenario != "phone"
348 launcherOffset: launcher.progress
349 launcherOffset: launcher.progress
349− forcedUnlock: wizard.active || shell.mode === "full-shell"
350+ forcedUnlock: wizard.active && !wizard.isUpdate || shell.mode === "full-shell"
350 background: wallpaperResolver.cachedBackground
351 background: wallpaperResolver.cachedBackground
351 hasCustomBackground: wallpaperResolver.hasCustomBackground
352 hasCustomBackground: wallpaperResolver.hasCustomBackground
352 allowFingerprint: !dialogs.hasActiveDialog &&
353 allowFingerprint: !dialogs.hasActiveDialog &&
qml/Stage/Stage.qml+8−2
@@ -1726,11 +1726,12 @@ FocusScope {
1726
1726
1727 property int scrollAreaWidth: width / 3
1727 property int scrollAreaWidth: width / 3
1728 property bool progressiveScrollingEnabled: false
1728 property bool progressiveScrollingEnabled: false
1729+ property bool wasTouchPress: false
1729
1730
1730 onMouseXChanged: {
1731 onMouseXChanged: {
1731 mouse.accepted = false
1732 mouse.accepted = false
1732
1733
1733− if (hoverMouseArea.pressed) {
1734+ if (hoverMouseArea.pressed || wasTouchPress) {
1734 return;
1735 return;
1735 }
1736 }
1736
1737
@@ -1766,7 +1767,12 @@ FocusScope {
1766 }
1767 }
1767 }
1768 }
1768
1769
1770+ onPressed: {
1769− onPressed: mouse.accepted = false
1771+ mouse.accepted = false;
1772+ wasTouchPress = mouse.source === Qt.MouseEventSynthesizedByQt;
1773+ }
1774+
1775+ onExited: wasTouchPress = false;
1770 }
1776 }
1771
1777
1772 FloatingFlickable {
1778 FloatingFlickable {
qml/Stage/WindowResizeArea.qml+4−1
@@ -101,7 +101,10 @@ MouseArea {
101 state = WindowStateStorage.WindowStateNormal;
101 state = WindowStateStorage.WindowStateNormal;
102 }
102 }
103 windowStateStorage.saveState(root.windowId, state & ~WindowStateStorage.WindowStateMinimized); // clear the minimized bit when saving
103 windowStateStorage.saveState(root.windowId, state & ~WindowStateStorage.WindowStateMinimized); // clear the minimized bit when saving
104+ // do not store window sizes if they are zero. this happens in staged mode
105+ if ( priv.normalWidth && priv.normalHeight ) {
104− windowStateStorage.saveGeometry(root.windowId, Qt.rect(priv.normalX, priv.normalY, priv.normalWidth, priv.normalHeight));
106+ windowStateStorage.saveGeometry(root.windowId, Qt.rect(priv.normalX, priv.normalY, priv.normalWidth, priv.normalHeight));
107+ }
105 }
108 }
106
109
107 QtObject {
110 QtObject {
qml/Wizard/Components/InputMethod.qml+9−9
@@ -21,19 +21,19 @@ import Ubuntu.Components 0.1
21// TODO: try to share this code with that from the unity8 shell
21// TODO: try to share this code with that from the unity8 shell
22
22
23Item {
23Item {
24− id: root
24+ id: inputMethodRoot
25
25
26 Connections {
26 Connections {
27 target: SurfaceManager
27 target: SurfaceManager
28 onSurfaceCreated: {
28 onSurfaceCreated: {
29 if (surface.type == MirSurfaceItem.InputMethod) {
29 if (surface.type == MirSurfaceItem.InputMethod) {
30− root.surface = surface;
30+ inputMethodRoot.surface = surface;
31 }
31 }
32 }
32 }
33
33
34 onSurfaceDestroyed: {
34 onSurfaceDestroyed: {
35− if (root.surface == surface) {
35+ if (inputMethodRoot.surface == surface) {
36− root.surface = null;
36+ inputMethodRoot.surface = null;
37 surface.parent = null;
37 surface.parent = null;
38 }
38 }
39 if (!surface.parent) {
39 if (!surface.parent) {
@@ -71,7 +71,7 @@ Item {
71 visible: false
71 visible: false
72 // half-way down because the vkb occupies only the lower half of the surface
72 // half-way down because the vkb occupies only the lower half of the surface
73 // TODO: consider keyboard rotation
73 // TODO: consider keyboard rotation
74− y: root.parent.height / 2.0
74+ y: inputMethodRoot.parent.height / 2.0
75 }
75 }
76 }
76 }
77 ]
77 ]
@@ -89,17 +89,17 @@ Item {
89 ignoreUnknownSignals: true // don't wanna spam the log when surface is null
89 ignoreUnknownSignals: true // don't wanna spam the log when surface is null
90 onStateChanged: {
90 onStateChanged: {
91 if (state == MirSurfaceItem.Minimized) {
91 if (state == MirSurfaceItem.Minimized) {
92− root.hide();
92+ inputMethodRoot.hide();
93 } else if (state == MirSurfaceItem.Maximized) {
93 } else if (state == MirSurfaceItem.Maximized) {
94− root.show();
94+ inputMethodRoot.show();
95 }
95 }
96 }
96 }
97 }
97 }
98
98
99 onSurfaceChanged: {
99 onSurfaceChanged: {
100 if (surface) {
100 if (surface) {
101− surface.parent = root;
101+ surface.parent = inputMethodRoot;
102− surface.anchors.fill = root;
102+ surface.anchors.fill = inputMethodRoot;
103 }
103 }
104 }
104 }
105
105
qml/Wizard/Page.qml+5
@@ -1,4 +1,5 @@
1/*
1/*
2+ * Copyright (C) 2018 The UBports project
2 * Copyright (C) 2013-2016 Canonical, Ltd.
3 * Copyright (C) 2013-2016 Canonical, Ltd.
3 *
4 *
4 * This program is free software; you can redistribute it and/or modify
5 * This program is free software; you can redistribute it and/or modify
@@ -50,6 +51,10 @@ Item {
50 property bool skipValid: true
51 property bool skipValid: true
51 property bool skip: false
52 property bool skip: false
52
53
54+ // Marks if should be only shown if update or install
55+ property bool onlyOnUpdate: false
56+ property bool onlyOnInstall: false
57+
53 property bool hasBackButton: true
58 property bool hasBackButton: true
54 property string backButtonText: i18n.ctr("Button: Go back one page in the Wizard", "Back")
59 property string backButtonText: i18n.ctr("Button: Go back one page in the Wizard", "Back")
55 property bool customBack: false
60 property bool customBack: false
qml/Wizard/Pages.qml+48−7
@@ -1,4 +1,5 @@
1/*
1/*
2+ * Copyright (C) 2018 The UBports project
2 * Copyright (C) 2013-2016 Canonical, Ltd.
3 * Copyright (C) 2013-2016 Canonical, Ltd.
3 *
4 *
4 * This program is free software; you can redistribute it and/or modify
5 * This program is free software; you can redistribute it and/or modify
@@ -105,6 +106,37 @@ StyledItem {
105 id: pageList
106 id: pageList
106 }
107 }
107
108
109+ ActivityIndicator {
110+ id: pagesSpinner
111+ anchors.centerIn: parent
112+ z: 100
113+ running: false
114+ visible: running
115+
116+ NumberAnimation on opacity {
117+ id: fadeInAnimation
118+ from: 0
119+ to: 1
120+ duration: 200
121+ }
122+
123+ onVisibleChanged: {
124+ if (visible) {
125+ opacity = 0;
126+ fadeInAnimation.start();
127+ }
128+ }
129+ }
130+
131+ Timer {
132+ id: impatientLoadingTimer
133+ interval: 1700
134+ onTriggered: {
135+ console.warn("Impatient timer going off. Fix the wizard, it's too slow at skipping pages.")
136+ pagesSpinner.running = true;
137+ }
138+ }
139+
108 PageStack {
140 PageStack {
109 id: pageStack
141 id: pageStack
110 objectName: "pageStack"
142 objectName: "pageStack"
@@ -139,18 +171,21 @@ StyledItem {
139
171
140 function load(path) {
172 function load(path) {
141 if (currentPage) {
173 if (currentPage) {
142− currentPage.enabled = false
174+ currentPage.enabled = false;
143 }
175 }
144
176
145 // First load it invisible, check that we should actually use
177 // First load it invisible, check that we should actually use
146 // this page, and either skip it or continue.
178 // this page, and either skip it or continue.
147− push(path, {"opacity": 0, "enabled": false})
179+ push(path, {"opacity": 0, "enabled": false});
148
180
149 timeout.restart();
181 timeout.restart();
182+ impatientLoadingTimer.start();
183+
184+ console.info("Loading page " + currentPage.objectName);
150
185
151 // Check for immediate skip or not. We may have to wait for
186 // Check for immediate skip or not. We may have to wait for
152 // skipValid to be assigned (see Connections object below)
187 // skipValid to be assigned (see Connections object below)
153− checkSkip()
188+ checkSkip();
154
189
155 var isPrimaryPage = !currentPage.customTitle;
190 var isPrimaryPage = !currentPage.customTitle;
156 if (isPrimaryPage) {
191 if (isPrimaryPage) {
@@ -162,13 +197,19 @@ StyledItem {
162
197
163 function checkSkip() {
198 function checkSkip() {
164 if (!currentPage) { // may have had a parse error
199 if (!currentPage) { // may have had a parse error
200+ console.warn("Wizard page skipped due to possible parse error.");
165− next()
201+ next();
166 } else if (currentPage.skipValid) {
202 } else if (currentPage.skipValid) {
167 if (currentPage.skip) {
203 if (currentPage.skip) {
168− next()
204+ next();
205+ } else if ((currentPage.onlyOnUpdate && !wizard.isUpdate) ||
206+ (currentPage.onlyOnInstall && wizard.isUpdate)) {
207+ next();
169 } else {
208 } else {
209+ impatientLoadingTimer.stop()
210+ pagesSpinner.running = false;
170− currentPage.opacity = 1
211+ currentPage.opacity = 1;
171− currentPage.enabled = true
212+ currentPage.enabled = true;
172 timeout.stop();
213 timeout.stop();
173 }
214 }
174 }
215 }
qml/Wizard/Pages/10-welcome-update.qmlnew file+137
@@ -0,0 +1,137 @@
1+/*
2+ * Copyright (C) 2018 The UBports project
3+ *
4+ * Written by: Marius Gripsgard <marius@ubports.com>
5+ *
6+ * This program is free software; you can redistribute it and/or modify
7+ * it under the terms of the GNU General Public License as published by
8+ * the Free Software Foundation; version 3.
9+ *
10+ * This program is distributed in the hope that it will be useful,
11+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License
16+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17+ */
18+
19+import QtQuick 2.4
20+import Ubuntu.Components 1.3
21+import Wizard 0.1
22+import ".." as LocalComponents
23+
24+LocalComponents.Page {
25+ objectName: "welcomeUpdate"
26+
27+ hasBackButton: false
28+ customTitle: true
29+ buttonBarVisible: false
30+ onlyOnUpdate: true
31+
32+ Component.onCompleted: {
33+ state = "reanchored";
34+ }
35+
36+ states: State {
37+ name: "reanchored"
38+ AnchorChanges { target: bgImage; anchors.top: parent.top; anchors.bottom: parent.bottom }
39+ AnchorChanges { target: column;
40+ anchors.verticalCenter: parent.verticalCenter;
41+ anchors.top: undefined
42+ }
43+ }
44+
45+ SequentialAnimation {
46+ id: splashAnimation
47+ PauseAnimation { duration: UbuntuAnimation.BriskDuration }
48+ SmoothedAnimation {
49+ target: bgImage
50+ property: "height"
51+ to: units.gu(16)
52+ duration: UbuntuAnimation.BriskDuration
53+ }
54+ NumberAnimation {
55+ target: bgImage
56+ property: 'opacity'
57+ from: 1
58+ to: 0
59+ }
60+ }
61+
62+ Image {
63+ id: bgImage
64+ source: wideMode ? "data/Desktop_splash_screen_bkg.png" : "data/Phone_splash_screen_bkg.png"
65+ scale: Image.PreserveAspectFit
66+ anchors.left: parent.left
67+ anchors.right: parent.right
68+ anchors.bottom: parent.top // outside to let it slide down
69+ visible: opacity > 0
70+ }
71+
72+ Item {
73+ id: column
74+ anchors.leftMargin: leftMargin
75+ anchors.rightMargin: rightMargin
76+ anchors.left: parent.left
77+ anchors.right: parent.right
78+ anchors.top: parent.bottom // outside to let it slide in
79+ height: childrenRect.height
80+ visible: opacity > 0
81+
82+ Label {
83+ id: welcomeLabel
84+ anchors.left: parent.left
85+ anchors.right: parent.right
86+ horizontalAlignment: Text.AlignHCenter
87+ wrapMode: Text.Wrap
88+ fontSize: "x-large"
89+ font.weight: Font.Light
90+ lineHeight: 1.2
91+ text: i18n.tr("Welcome to ") + System.version.split("Base-Version: ")[1]
92+ color: whiteColor
93+ }
94+
95+ Label {
96+ id: welcomeText
97+ anchors.left: parent.left
98+ anchors.right: parent.right
99+ anchors.top: welcomeLabel.bottom
100+ anchors.topMargin: units.gu(2)
101+ horizontalAlignment: Text.AlignHCenter
102+ wrapMode: Text.Wrap
103+ fontSize: "large"
104+ font.weight: Font.Light
105+ lineHeight: 1.2
106+ text: i18n.tr("We will make sure your device is ready to use ") + System.version.split("Base-Version: ")[1]
107+ color: whiteColor
108+ }
109+
110+ Rectangle {
111+ anchors {
112+ top: welcomeText.bottom
113+ horizontalCenter: parent.horizontalCenter
114+ topMargin: units.gu(4)
115+ }
116+ color: "transparent"
117+ border.width: units.dp(1)
118+ border.color: whiteColor
119+ radius: units.dp(4)
120+ width: buttonLabel.paintedWidth + units.gu(6)
121+ height: buttonLabel.paintedHeight + units.gu(1.8)
122+
123+ Label {
124+ id: buttonLabel
125+ color: whiteColor
126+ text: i18n.tr("Next")
127+ fontSize: "medium"
128+ anchors.centerIn: parent
129+ }
130+ AbstractButton {
131+ objectName: "nextButton"
132+ anchors.fill: parent
133+ onClicked: pageStack.next();
134+ }
135+ }
136+ }
137+}
qml/Wizard/Pages/10-welcome.qml+2
@@ -1,4 +1,5 @@
1/*
1/*
2+ * Copyright (C) 2018 The UBports project
2 * Copyright (C) 2013-2016 Canonical, Ltd.
3 * Copyright (C) 2013-2016 Canonical, Ltd.
3 *
4 *
4 * This program is free software; you can redistribute it and/or modify
5 * This program is free software; you can redistribute it and/or modify
@@ -27,6 +28,7 @@ LocalComponents.Page {
27
28
28 title: i18n.tr("Language")
29 title: i18n.tr("Language")
29 forwardButtonSourceComponent: forwardButton
30 forwardButtonSourceComponent: forwardButton
31+ onlyOnInstall: true
30
32
31 UbuntuLanguagePlugin {
33 UbuntuLanguagePlugin {
32 id: plugin
34 id: plugin
qml/Wizard/Pages/11-changelog.qmlnew file+95
@@ -0,0 +1,95 @@
1+/*
2+ * Copyright (C) 2018 The UBports project
3+ *
4+ * Written by: Dalton Durst <dalton@ubports.com>
5+ * Marius Gripsgard <marius@ubports.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+import QtQuick 2.4
21+import Ubuntu.Components 1.3
22+import AccountsService 0.1
23+import Wizard 0.1
24+import ".." as LocalComponents
25+
26+LocalComponents.Page {
27+ objectName: "changelogPage"
28+ title: i18n.tr("What's new")
29+ id: changelogPage
30+
31+ // See skipTimer below for information about this hack
32+ property bool loading: false
33+
34+ forwardButtonSourceComponent: forwardButton
35+ onlyOnUpdate: true
36+
37+ ScrollView {
38+ id: scroll
39+
40+ anchors {
41+ fill: content
42+ leftMargin: wideMode ? parent.leftMargin : staticMargin
43+ rightMargin: wideMode ? parent.rightMargin : staticMargin
44+ }
45+
46+ Column {
47+ id: column
48+
49+ width: scroll.width
50+
51+ // Make it appear that the text is hiding behind the header
52+ Item {
53+ height: staticMargin
54+ width: units.gu(1)
55+ }
56+
57+ Label {
58+ anchors {
59+ // Keep the scroll bar from interfering with text
60+ rightMargin: units.gu(1)
61+ }
62+ id: changelogText
63+ width: parent.width
64+ wrapMode: Text.WordWrap
65+ textSize: Label.Medium
66+ text: Changelog.text
67+ }
68+ }
69+ }
70+
71+ Component {
72+ id: forwardButton
73+ LocalComponents.StackButton {
74+ text: loading ? i18n.tr("Loading...") : i18n.tr("Next")
75+ onClicked: {
76+ changelogPage.loading = true;
77+ skipTimer.restart();
78+ }
79+ }
80+ }
81+
82+ // A horrible hack to make sure the UI refreshes before actually skipping
83+ // Without this, people press the Next button multiple times and skip
84+ // multiple pages at once.
85+ Timer {
86+ id: skipTimer
87+ interval: 100
88+ repeat: false
89+ running: false
90+ onTriggered: {
91+ changelogPage.loading = false;
92+ pageStack.next();
93+ }
94+ }
95+}
qml/Wizard/Pages/30-wifi.qml+1
@@ -32,6 +32,7 @@ LocalComponents.Page {
32 forwardButtonSourceComponent: forwardButton
32 forwardButtonSourceComponent: forwardButton
33
33
34 readonly property bool connected: Connectivity.online
34 readonly property bool connected: Connectivity.online
35+ skip: connected
35
36
36 function getExtendedProperty(object, propertyName, defaultValue) {
37 function getExtendedProperty(object, propertyName, defaultValue) {
37 if (object && object.hasOwnProperty(propertyName)) {
38 if (object && object.hasOwnProperty(propertyName)) {
qml/Wizard/Pages/40-location.qmldeleted−290
@@ -1,290 +0,0 @@
1−/*
2− * Copyright (C) 2013-2016 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.4
18−import AccountsService 0.1
19−import QMenuModel 0.1 as QMenuModel
20−import Qt.labs.folderlistmodel 2.1
21−import Ubuntu.Components 1.3
22−import ".." as LocalComponents
23−
24−LocalComponents.Page {
25− objectName: "locationPage"
26−
27− title: i18n.tr("Location Services")
28− forwardButtonSourceComponent: forwardButton
29−
30− readonly property bool pathSet: AccountsService.hereLicensePathValid
31− skipValid: pathSet && (AccountsService.hereLicensePath === "" || termsModel.count > 0)
32− skip: skipValid && (AccountsService.hereLicensePath === "" || termsModel.count === 2) // no files but . and ..
33−
34− FolderListModel {
35− id: termsModel
36− folder: AccountsService.hereLicensePath
37− nameFilters: ["*.html"]
38− showOnlyReadable: true
39− showDotAndDotDot: true // so that count == 0 means we're not done scanning yet
40− }
41−
42− QMenuModel.QDBusActionGroup {
43− id: locationActionGroup
44− objectName: "locationActionGroup"
45− busType: QMenuModel.DBus.SessionBus
46− busName: "com.canonical.indicator.location"
47− objectPath: "/com/canonical/indicator/location"
48− property variant location: action("location-detection-enabled")
49− property variant gps: action("gps-detection-enabled")
50− Component.onCompleted: start()
51− }
52−
53− Item {
54− id: column
55− anchors.fill: content
56− anchors.topMargin: customMargin
57− anchors.leftMargin: wideMode ? parent.leftMargin : 0
58− anchors.rightMargin: wideMode ? parent.rightMargin : 0
59−
60− Item {
61− id: hereCheckGroup
62− anchors {
63− left: parent.left
64− right: parent.right
65− top: parent.top
66− }
67− height: hereCheckLabel.height + hereTermsLabel.height
68−
69− Label {
70− id: hereCheckLabel
71− objectName: "hereCheckLabel"
72− anchors {
73− left: parent.left
74− right: hereTermsCheck.left
75− top: parent.top
76− leftMargin: column.anchors.leftMargin == 0 ? staticMargin : 0
77− rightMargin: units.gu(2)
78− }
79− lineHeight: 1.2
80− wrapMode: Text.WordWrap
81− color: textColor
82− font.weight: checked ? Font.Normal : Font.Light
83− text: i18n.tr("Use GPS, Wi-Fi hotspots and mobile network anonymously to detect location (recommended)")
84− property bool checked: true
85− }
86−
87− Label {
88− id: hereTermsLabel
89− objectName: "hereTermsLabel"
90− anchors {
91− left: parent.left
92− right: hereTermsCheck.left
93− top: hereCheckLabel.bottom
94− topMargin: units.gu(1)
95− leftMargin: column.anchors.leftMargin == 0 ? staticMargin : 0
96− rightMargin: units.gu(2)
97− }
98−
99− wrapMode: Text.WordWrap
100− color: textColor
101− font.weight: Font.Light
102− fontSize: "small"
103− lineHeight: 1.2
104− linkColor: UbuntuColors.orange
105− text: i18n.tr("By selecting this option you agree to the Nokia HERE %1.")
106− .arg("<a href='#'>" + i18n.ctr("part of: Nokia HERE terms and conditions", "terms and conditions") + "</a>")
107− Mouse.forwardTo: hereCheckArea // clicking on the link also selects this group
108− Mouse.priority: Mouse.AfterItem
109− onLinkActivated: {
110− pageStack.load(Qt.resolvedUrl("here-terms.qml"));
111− }
112− }
113−
114− Image {
115− id: hereTermsCheck
116− fillMode: Image.PreserveAspectFit
117− height: units.gu(1.5)
118− source: "data/Tick@30.png"
119− opacity: hereCheckLabel.checked ? 1 : 0
120− anchors.right: parent.right
121− anchors.verticalCenter: hereCheckLabel.verticalCenter
122− anchors.rightMargin: column.anchors.rightMargin == 0 ? staticMargin : 0
123− }
124−
125− MouseArea {
126− id: hereCheckArea
127− anchors.fill: parent
128− z: hereCheckGroup.z - 1 // so that the link can be activated
129− onClicked: {
130− if (!hereCheckLabel.checked) {
131− hereCheckLabel.checked = true;
132− gpsCheckLabel.checked = false;
133− nopeCheckLabel.checked = false;
134− }
135− }
136− }
137− }
138−
139− Rectangle {
140− id: divider
141− anchors.left: parent.left
142− anchors.right: parent.right
143− anchors.top: hereCheckGroup.bottom
144− anchors.topMargin: units.gu(3)
145− height: units.dp(1)
146− color: dividerColor
147− }
148−
149− Label {
150− id: gpsCheckLabel
151− objectName: "gpsCheckLabel"
152− anchors {
153− left: parent.left
154− right: parent.right
155− top: divider.bottom
156− topMargin: units.gu(3)
157− leftMargin: column.anchors.leftMargin == 0 ? staticMargin : 0
158− rightMargin: units.gu(2)
159− }
160− text: i18n.tr("GPS only")
161− wrapMode: Text.WordWrap
162− color: textColor
163− font.weight: checked ? Font.Normal : Font.Light
164− width: content.width
165− property bool checked: false
166−
167− MouseArea {
168− anchors.fill: parent
169− onClicked: {
170− if (!gpsCheckLabel.checked) {
171− hereCheckLabel.checked = false;
172− gpsCheckLabel.checked = true;
173− nopeCheckLabel.checked = false;
174− }
175− }
176− }
177− }
178−
179− Image {
180− fillMode: Image.PreserveAspectFit
181− height: units.gu(1.5)
182− source: "data/Tick@30.png"
183− opacity: gpsCheckLabel.checked ? 1 : 0
184− anchors.right: parent.right
185− anchors.verticalCenter: gpsCheckLabel.verticalCenter
186− anchors.rightMargin: column.anchors.rightMargin == 0 ? staticMargin : 0
187− }
188−
189− Rectangle {
190− id: divider2
191− anchors.left: parent.left
192− anchors.right: parent.right
193− anchors.top: gpsCheckLabel.bottom
194− anchors.topMargin: units.gu(3)
195− height: units.dp(1)
196− color: dividerColor
197− }
198−
199− Label {
200− id: nopeCheckLabel
201− objectName: "nopeCheckLabel"
202− anchors {
203− left: parent.left
204− right: parent.right
205− top: divider2.bottom
206− topMargin: units.gu(3)
207− leftMargin: column.anchors.leftMargin == 0 ? staticMargin : 0
208− rightMargin: units.gu(2)
209− }
210− wrapMode: Text.WordWrap
211− color: textColor
212− font.weight: checked ? Font.Normal : Font.Light
213− width: content.width
214− text: i18n.tr("Don't use my location")
215− property bool checked: false
216−
217− MouseArea {
218− anchors.fill: parent
219− onClicked: {
220− if (!nopeCheckLabel.checked) {
221− hereCheckLabel.checked = false;
222− gpsCheckLabel.checked = false;
223− nopeCheckLabel.checked = true;
224− }
225− }
226− }
227− }
228−
229− Image {
230− fillMode: Image.PreserveAspectFit
231− height: units.gu(1.5)
232− source: "data/Tick@30.png"
233− opacity: nopeCheckLabel.checked ? 1 : 0
234− anchors.right: parent.right
235− anchors.verticalCenter: nopeCheckLabel.verticalCenter
236− anchors.rightMargin: column.anchors.rightMargin == 0 ? staticMargin : 0
237− }
238−
239− Rectangle {
240− id: divider3
241− anchors.left: parent.left
242− anchors.right: parent.right
243− anchors.top: nopeCheckLabel.bottom
244− anchors.topMargin: units.gu(3)
245− height: units.dp(1)
246− color: dividerColor
247− }
248−
249− Label {
250− id: infoLabel
251− anchors {
252− left: parent.left
253− right: parent.right
254− top: divider3.bottom
255− topMargin: units.gu(4)
256− leftMargin: column.anchors.leftMargin == 0 ? staticMargin : 0
257− rightMargin: column.anchors.rightMargin == 0 ? staticMargin : 0
258− }
259− wrapMode: Text.Wrap
260− text: i18n.tr("You can change it later in System Settings.")
261− color: textColor
262− fontSize: "small"
263− font.weight: Font.Light
264− width: content.width
265− }
266− }
267−
268− Component {
269− id: forwardButton
270− LocalComponents.StackButton {
271− text: i18n.tr("Next")
272− onClicked: {
273− var locationOn = gpsCheckLabel.checked || hereCheckLabel.checked;
274− var gpsOn = gpsCheckLabel.checked || hereCheckLabel.checked;
275− var hereOn = hereCheckLabel.checked;
276−
277− // location service doesn't currently listen to updateState
278− // requests, so we activate the actions if needed.
279− if (locationActionGroup.location.state != locationOn) {
280− locationActionGroup.location.activate();
281− }
282− if (locationActionGroup.gps.state != gpsOn) {
283− locationActionGroup.gps.activate();
284− }
285− AccountsService.hereEnabled = hereOn;
286− pageStack.next();
287− }
288− }
289− }
290−}
qml/Wizard/Pages/50-timezone.qml+1
@@ -36,6 +36,7 @@ LocalComponents.Page {
36
36
37 // for testing
37 // for testing
38 readonly property alias tdModule: timeDatePanel
38 readonly property alias tdModule: timeDatePanel
39+ onlyOnInstall: true
39
40
40 function highlightTimezone(offset) {
41 function highlightTimezone(offset) {
41 highlightImage.source = "data/timezonemap/timezone_" + offset + ".png";
42 highlightImage.source = "data/timezonemap/timezone_" + offset + ".png";
qml/Wizard/Pages/60-account.qml+1
@@ -24,6 +24,7 @@ LocalComponents.Page {
24 title: i18n.tr("Personalize Your Device")
24 title: i18n.tr("Personalize Your Device")
25
25
26 forwardButtonSourceComponent: forwardButton
26 forwardButtonSourceComponent: forwardButton
27+ onlyOnInstall: true
27
28
28 QtObject {
29 QtObject {
29 id: d
30 id: d
qml/Wizard/Pages/70-passwd-type.qml+1
@@ -44,6 +44,7 @@ LocalComponents.Page {
44 // or this isn't the first time the wizard has been run, etc). We can't
44 // or this isn't the first time the wizard has been run, etc). We can't
45 // properly set the password again, so let's not pretend we can.
45 // properly set the password again, so let's not pretend we can.
46 skip: securityPrivacy.securityType !== UbuntuSecurityPrivacyPanel.Swipe
46 skip: securityPrivacy.securityType !== UbuntuSecurityPrivacyPanel.Swipe
47+ onlyOnInstall: true
47
48
48 function indexToMethod(index) {
49 function indexToMethod(index) {
49 if (index === 0/* || index === 1*/)
50 if (index === 0/* || index === 1*/)
qml/Wizard/Pages/75-report-check.qml → qml/Wizard/Pages/75-report-check.qml.disabledrenamed+1
@@ -27,6 +27,7 @@ LocalComponents.Page {
27 forwardButtonSourceComponent: !webview.visible ? forwardButton : null
27 forwardButtonSourceComponent: !webview.visible ? forwardButton : null
28 customBack: true
28 customBack: true
29 customTitle: webview.visible
29 customTitle: webview.visible
30+ onlyOnInstall: true
30
31
31 skip: !diagnostics.reportCrashes // skip the page when the system is configured not to report crashes
32 skip: !diagnostics.reportCrashes // skip the page when the system is configured not to report crashes
32
33
qml/Wizard/Pages/76-app-update.qmlnew file+246
@@ -0,0 +1,246 @@
1+/*
2+ * Copyright (C) 2018 The UBports project
3+ *
4+ * Written by: Dalton Durst <dalton@ubports.com>
5+ * Marius Gripsgard <marius@ubports.com>
6+ *
7+ * This program is free software: you can redistribute it and/or modify it
8+ * under the terms of the GNU General Public License version 3, as published
9+ * by the Free Software Foundation.
10+ *
11+ * This program is distributed in the hope that it will be useful, but
12+ * WITHOUT ANY WARRANTY; without even the implied warranties of
13+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14+ * PURPOSE. See the GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License along
17+ * with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+import QMenuModel 0.1
21+import QtQuick 2.4
22+import QtQuick.Layouts 1.1
23+import Ubuntu.Components 1.3
24+import Ubuntu.Components.ListItems 1.3 as ListItem
25+import Ubuntu.Components.Popups 1.3
26+import Ubuntu.SystemSettings.Update 1.0
27+import Ubuntu.Connectivity 1.0
28+import Wizard 0.1
29+import ".." as LocalComponents
30+
31+LocalComponents.Page {
32+ id: appUpdatePage
33+ objectName: "appUpdatePage"
34+
35+ title: i18n.tr("Update Apps")
36+ forwardButtonSourceComponent: forwardButton
37+
38+ property bool batchMode: false
39+ property bool online: NetworkingStatus.online
40+ property bool authenticated: UpdateManager.authenticated
41+
42+ onlyOnUpdate: true
43+
44+ property int updatesCount: {
45+ var count = 0;
46+ if (authenticated) {
47+ count += clickRepeater.count;
48+ }
49+ return count;
50+ }
51+
52+ function check(force) {
53+ UpdateManager.check(UpdateManager.CheckClickIgnoreVersion);
54+ }
55+
56+ DownloadHandler {
57+ id: downloadHandler
58+ updateModel: UpdateManager.model
59+ }
60+
61+ Flickable {
62+ id: scrollWidget
63+ anchors {
64+ fill: content
65+ leftMargin: parent.leftMargin
66+ rightMargin: parent.rightMargin
67+ }
68+ clip: true
69+ contentHeight: scrollWidgetContent.height
70+ boundsBehavior: (contentHeight > scrollWidgetContent.height) ?
71+ Flickable.DragAndOvershootBounds :
72+ Flickable.StopAtBounds
73+ flickableDirection: Flickable.VerticalFlick
74+
75+ Column {
76+ id: scrollWidgetContent
77+ anchors {
78+ left: parent.left
79+ right: parent.right
80+ }
81+
82+ GlobalUpdateControls {
83+ id: g
84+ objectName: "global"
85+ anchors { left: parent.left; right: parent.right }
86+
87+ height: hidden ? 0 : units.gu(8)
88+ clip: true
89+ status: UpdateManager.status
90+ batchMode: appUpdatePage.batchMode
91+ updatesCount: appUpdatePage.updatesCount
92+ online: appUpdatePage.online
93+ onStop: UpdateManager.cancel()
94+
95+ onRequestInstall: {
96+ install();
97+ }
98+ onInstall: {
99+ appUpdatePage.batchMode = true
100+ postClickBatchHandler.target = appUpdatePage;
101+ }
102+ }
103+
104+ Rectangle {
105+ id: overlay
106+ objectName: "overlay"
107+ anchors {
108+ left: parent.left
109+ leftMargin: units.gu(2)
110+ right: parent.right
111+ rightMargin: units.gu(2)
112+ }
113+ visible: placeholder.text
114+ color: theme.palette.normal.background
115+ height: units.gu(10)
116+
117+ Label {
118+ id: placeholder
119+ objectName: "overlayText"
120+ anchors.fill: parent
121+ verticalAlignment: Text.AlignVCenter
122+ horizontalAlignment: Text.AlignHCenter
123+ wrapMode: Text.WordWrap
124+ text: {
125+ var s = UpdateManager.status;
126+ if (!appUpdatePage.online) {
127+ return i18n.tr("This device is not connected to the internet.") + " " +
128+ i18n.tr("Use the OpenStore app to check for updates once connected.");
129+ } else if (s === UpdateManager.StatusIdle && updatesCount === 0) {
130+ return i18n.tr("Software is up to date");
131+ } else if (s === UpdateManager.StatusServerError ||
132+ s === UpdateManager.StatusNetworkError) {
133+ return i18n.tr("The update server is not responding.") + " " +
134+ i18n.tr("Use the OpenStore app to check for updates once connected.");
135+ }
136+ return "";
137+ }
138+ }
139+ }
140+
141+ Column {
142+ id: clickUpdatesCol
143+ objectName: "clickUpdates"
144+ anchors { left: parent.left; right: parent.right }
145+ visible: {
146+ var s = UpdateManager.status;
147+ var haveUpdates = clickRepeater.count > 0;
148+ switch (s) {
149+ case UpdateManager.StatusCheckingImageUpdates:
150+ case UpdateManager.StatusIdle:
151+ return haveUpdates && online && authenticated;
152+ }
153+ return false;
154+ }
155+
156+ Repeater {
157+ id: clickRepeater
158+ model: UpdateManager.clickUpdates
159+
160+ delegate: ClickUpdateDelegate {
161+ objectName: "clickUpdatesDelegate" + index
162+ width: clickUpdatesCol.width
163+ updateState: model.updateState
164+ progress: model.progress
165+ version: remoteVersion
166+ size: model.size
167+ name: title
168+ iconUrl: model.iconUrl
169+ kind: model.kind
170+ error: model.error
171+ signedUrl: signedDownloadUrl
172+
173+ onInstall: downloadHandler.createDownload(model);
174+ onPause: downloadHandler.pauseDownload(model)
175+ onResume: downloadHandler.resumeDownload(model)
176+ onRetry: {
177+ /* This creates a new signed URL with which we can
178+ retry the download. See onSignedUrlChanged. */
179+ UpdateManager.retry(model.identifier,
180+ model.revision);
181+ }
182+
183+ onSignedUrlChanged: {
184+ // If we have a signedUrl, user intend to retry.
185+ if (signedUrl) {
186+ downloadHandler.retryDownload(model);
187+ }
188+ }
189+
190+ Connections {
191+ target: g
192+ onInstall: install()
193+ }
194+
195+ /* If we a downloadId, we expect UDM to restore it
196+ after some time. Workaround for lp:1603770. */
197+ Timer {
198+ id: downloadTimeout
199+ interval: 30000
200+ running: true
201+ onTriggered: {
202+ var s = updateState;
203+ if (model.downloadId
204+ || s === Update.StateQueuedForDownload
205+ || s === Update.StateDownloading) {
206+ downloadHandler.assertDownloadExist(model);
207+ }
208+ }
209+ }
210+ }
211+ }
212+ }
213+ } // Column inside flickable
214+ } // Flickable
215+
216+ Connections {
217+ id: postClickBatchHandler
218+ ignoreUnknownSignals: true
219+ target: null
220+ onUpdatesCountChanged: {
221+ if (target.updatesCount === 0) {
222+ appUpdatePage.batchMode = false;
223+ target = null;
224+ }
225+ }
226+ }
227+
228+ Component.onCompleted: check()
229+
230+ Component {
231+ id: forwardButton
232+ LocalComponents.StackButton {
233+ text: {
234+ var s = UpdateManager.status;
235+ if (s === UpdateManager.StatusIdle && updatesCount === 0) {
236+ return i18n.tr("Next");
237+ } else if (s === UpdateManager.StatusCheckingClickUpdates) {
238+ return i18n.tr("Please wait...")
239+ } else {
240+ return i18n.tr("Skip");
241+ }
242+ }
243+ onClicked: pageStack.next()
244+ }
245+ }
246+}
qml/Wizard/Pages/78-firmware-update.qml.disablednew file+246
@@ -0,0 +1,246 @@
1+/*
2+ * Copyright (C) 2018 The UBports project
3+ *
4+ * Written by: Marius Gripsgard <marius@ubports.com>
5+ *
6+ * This program is free software; you can redistribute it and/or modify
7+ * it under the terms of the GNU General Public License as published by
8+ * the Free Software Foundation; version 3.
9+ *
10+ * This program is distributed in the hope that it will be useful,
11+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License
16+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17+ */
18+
19+import QtQuick 2.4
20+import QtQuick.Layouts 1.1
21+import Ubuntu.Components 1.3
22+import Ubuntu.SystemSettings.Update 1.0
23+import Ubuntu.Connectivity 1.0
24+import Wizard 0.1
25+import ".." as LocalComponents
26+
27+LocalComponents.Page {
28+ id: firmwareUpdatePage
29+ objectName: "firmwareUpdatePage"
30+
31+ title: i18n.tr("Firmware Update")
32+ forwardButtonSourceComponent: forwardButton
33+
34+ skip: !SystemImage.supportsFirmwareUpdate()
35+
36+ property bool online: NetworkingStatus.online
37+ property bool hasUpdate: false
38+ property bool isUpdating: false
39+ property bool isChecking: true
40+ property var partitions: ""
41+
42+ function check() {
43+ if (!SystemImage.supportsFirmwareUpdate()) {
44+ return;
45+ }
46+ firmwareUpdatePage.isChecking = true;
47+ SystemImage.checkForFirmwareUpdate();
48+ }
49+
50+ function flash() {
51+ if (!SystemImage.supportsFirmwareUpdate()) {
52+ return pageStack.next();
53+ }
54+ firmwareUpdatePage.isUpdating = true;
55+ SystemImage.updateFirmware();
56+ }
57+
58+ Connections {
59+ target: SystemImage
60+ onCheckForFirmwareUpdateDone: {
61+ var updateobj = JSON.parse(updateObj);
62+ if (Array.isArray(updateobj) && updateobj.length > 0) {
63+ for (var u in updateobj) {
64+ console.log(u);
65+ if (firmwareUpdatePage.partitions === "") {
66+ firmwareUpdatePage.partitions += updateobj[u].file;
67+ } else {
68+ firmwareUpdatePage.partitions += ", " + updateobj[u].file;
69+ }
70+ }
71+ firmwareUpdatePage.hasUpdate = true;
72+ }
73+ console.log(updateobj);
74+ firmwareUpdatePage.isChecking = false;
75+ }
76+ onUpdateFirmwareDone: {
77+ var updateobj = JSON.parse(updateObj);
78+ if (Array.isArray(updateobj) && updateobj.length === 0) {
79+ // This means success!
80+ firmwareUpdatePage.hasUpdate = false;
81+ firmwareUpdatePage.partitions = "";
82+ System.skipUntilFinishedPage();
83+ SystemImage.reboot();
84+ return;
85+ }
86+ console.log(updateobj);
87+ firmwareUpdatePage.isUpdating = false;
88+ }
89+ }
90+
91+ Column {
92+ id: column
93+ anchors {
94+ fill: content
95+ leftMargin: firmwareUpdatePage.leftMargin
96+ rightMargin: firmwareUpdatePage.rightMargin
97+ topMargin: firmwareUpdatePage.customMargin
98+ }
99+ spacing: units.gu(3)
100+ opacity: spinner.visible ? 0.5 : 1
101+ Behavior on opacity {
102+ UbuntuNumberAnimation {}
103+ }
104+
105+ Label {
106+ visible: !firmwareUpdatePage.isChecking
107+ anchors.horizontalCenter: parent.horizontalCenter
108+ font.weight: Font.Light
109+ wrapMode: Text.Wrap
110+ textSize: Label.Medium
111+ text: firmwareUpdatePage.hasUpdate ? i18n.tr("There is a firmware update available!")
112+ : online ? i18n.tr("Firmware is up to date!")
113+ : i18n.tr("Please connect to the Internet to check for updates.")
114+
115+ }
116+
117+ GridLayout {
118+ rows: 3
119+ columns: 2
120+ rowSpacing: units.gu(1)
121+ columnSpacing: units.gu(2)
122+ anchors.horizontalCenter: parent.horizontalCenter
123+ visible: hasUpdate
124+
125+ Icon {
126+ Layout.rowSpan: 3
127+ Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
128+ width: units.gu(5)
129+ height: width
130+ name: "security-alert"
131+ }
132+
133+ Label {
134+ font.weight: Font.Normal
135+ textSize: Label.Medium
136+ text: i18n.tr("Firmware Update")
137+ }
138+
139+ Label {
140+ font.weight: Font.Light
141+ wrapMode: Text.WordWrap
142+ fontSize: "small"
143+ text: firmwareUpdatePage.partitions
144+ }
145+
146+ Label {
147+ font.weight: Font.Light
148+ fontSize: "small"
149+ text: i18n.tr("The device will automatically restart after installing is done.")
150+ }
151+ }
152+
153+ Rectangle {
154+ anchors.left: parent.left
155+ anchors.leftMargin: 3
156+ anchors.horizontalCenter: parent.horizontalCenter
157+ color: theme.palette.normal.foreground
158+ radius: units.dp(4)
159+ width: buttonLabel.paintedWidth + units.gu(3)
160+ height: buttonLabel.paintedHeight + units.gu(1.8)
161+ visible: hasUpdate
162+
163+ Label {
164+ id: buttonLabel
165+ text: i18n.tr("Install and restart now")
166+ font.weight: Font.Light
167+ anchors.horizontalCenter: parent.horizontalCenter
168+ anchors.centerIn: parent
169+ }
170+
171+ AbstractButton {
172+ id: button
173+ objectName: "installButton"
174+ anchors.fill: parent
175+ anchors.horizontalCenter: parent.horizontalCenter
176+ onClicked: {
177+ firmwareUpdatePage.flash()
178+ }
179+ }
180+
181+ transformOrigin: Item.Top
182+ scale: button.pressed ? 0.98 : 1.0
183+ Behavior on scale {
184+ ScaleAnimator {
185+ duration: UbuntuAnimation.SnapDuration
186+ easing.type: Easing.Linear
187+ }
188+ }
189+ }
190+ }
191+
192+ Column {
193+ id: spinner
194+ anchors.centerIn: firmwareUpdatePage
195+ visible: firmwareUpdatePage.isChecking || firmwareUpdatePage.isUpdating
196+ spacing: units.gu(1)
197+
198+ ActivityIndicator {
199+ anchors.horizontalCenter: parent.horizontalCenter
200+ running: parent.visible
201+ }
202+
203+ Label {
204+ wrapMode: Text.Wrap
205+ width: firmwareUpdatePage.width - units.gu(3)
206+ fontSize: "small"
207+ text: i18n.tr("Downloading and Flashing firmware updates, this could take a few minutes...")
208+ visible: firmwareUpdatePage.isUpdating
209+ }
210+
211+ Label {
212+ wrapMode: Text.Wrap
213+ fontSize: "small"
214+ text: i18n.tr("Checking for firmware update")
215+ visible: firmwareUpdatePage.isChecking
216+ }
217+
218+ Component.onCompleted: {
219+ if (online) {
220+ firmwareUpdatePage.check();
221+ }
222+ else {
223+ firmwareUpdatePage.isChecking = false;
224+ }
225+ }
226+ }
227+
228+ Connections {
229+ target: NetworkingStatus
230+ onOnlineChanged: {
231+ if (online) {
232+ firmwareUpdatePage.check();
233+ } else {
234+ firmwareUpdatePage.isChecking = false;
235+ }
236+ }
237+ }
238+
239+ Component {
240+ id: forwardButton
241+ LocalComponents.StackButton {
242+ text: (!firmwareUpdatePage.hasUpdate && !spinner.visible) ? i18n.tr("Next") : i18n.tr("Skip");
243+ onClicked: pageStack.next();
244+ }
245+ }
246+}
qml/Wizard/Pages/77-system-update.qml → qml/Wizard/Pages/79-system-update.qmlrenamed

The content is the same.

qml/Wizard/Pages/80-finished.qml+4−2
@@ -1,4 +1,5 @@
1/*
1/*
2+ * Copyright (C) 2018 The UBports project
2 * Copyright (C) 2013-2016 Canonical, Ltd.
3 * Copyright (C) 2013-2016 Canonical, Ltd.
3 *
4 *
4 * This program is free software; you can redistribute it and/or modify
5 * This program is free software; you can redistribute it and/or modify
@@ -16,6 +17,7 @@
16
17
17import QtQuick 2.4
18import QtQuick 2.4
18import Ubuntu.Components 1.3
19import Ubuntu.Components 1.3
20+import Wizard 0.1
19import ".." as LocalComponents
21import ".." as LocalComponents
20
22
21LocalComponents.Page {
23LocalComponents.Page {
@@ -86,7 +88,7 @@ LocalComponents.Page {
86 fontSize: "x-large"
88 fontSize: "x-large"
87 font.weight: Font.Light
89 font.weight: Font.Light
88 lineHeight: 1.2
90 lineHeight: 1.2
89− text: i18n.tr("Welcome to Ubuntu")
91+ text: (System.isUpdate) ? i18n.tr("Welcome Back") : i18n.tr("Welcome to Ubuntu")
90 color: whiteColor
92 color: whiteColor
91 }
93 }
92
94
@@ -121,7 +123,7 @@ LocalComponents.Page {
121 Label {
123 Label {
122 id: buttonLabel
124 id: buttonLabel
123 color: whiteColor
125 color: whiteColor
124− text: i18n.tr("Get Started")
126+ text: (System.isUpdate) ? i18n.tr("Continue") : i18n.tr("Get Started")
125 fontSize: "medium"
127 fontSize: "medium"
126 anchors.centerIn: parent
128 anchors.centerIn: parent
127 }
129 }
qml/Wizard/Pages/ClickUpdateDelegate.qmlnew file+26
@@ -0,0 +1,26 @@
1+/*
2+ * This file is part of system-settings
3+ *
4+ * Copyright (C) 2016 Canonical Ltd.
5+ *
6+ * This program is free software: you can redistribute it and/or modify it
7+ * under the terms of the GNU General Public License version 3, as published
8+ * by the Free Software Foundation.
9+ *
10+ * This program is distributed in the hope that it will be useful, but
11+ * WITHOUT ANY WARRANTY; without even the implied warranties of
12+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
13+ * PURPOSE. See the GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License along
16+ * with this program. If not, see <http://www.gnu.org/licenses/>.
17+ */
18+
19+import QtQuick 2.4
20+import Ubuntu.SystemSettings.Update 1.0
21+
22+UpdateDelegate {
23+ id: update
24+
25+ property string signedUrl
26+}
qml/Wizard/Pages/DownloadHandler.qmlnew file+204
@@ -0,0 +1,204 @@
1+/*
2+ * This file is part of system-settings
3+ *
4+ * Copyright (C) 2016 Canonical Ltd.
5+ *
6+ * This program is free software: you can redistribute it and/or modify it
7+ * under the terms of the GNU General Public License version 3, as published
8+ * by the Free Software Foundation.
9+ *
10+ * This program is distributed in the hope that it will be useful, but
11+ * WITHOUT ANY WARRANTY; without even the implied warranties of
12+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
13+ * PURPOSE. See the GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License along
16+ * with this program. If not, see <http://www.gnu.org/licenses/>.
17+ *
18+ */
19+import QtQuick 2.4
20+import Ubuntu.DownloadManager 1.2
21+
22+Item {
23+ id: downloadHandler
24+ property var updateModel
25+ property alias downloads: downloadManager.downloads
26+ property var udm: DownloadManager {
27+ id: downloadManager
28+ onDownloadFinished: {
29+ updateModel.setInstalled(download.metadata.custom.identifier,
30+ download.metadata.custom.revision);
31+ }
32+ onDownloadPaused: {
33+ updateModel.pauseUpdate(download.metadata.custom.identifier,
34+ download.metadata.custom.revision)
35+ }
36+ onDownloadResumed: {
37+ updateModel.resumeUpdate(download.metadata.custom.identifier,
38+ download.metadata.custom.revision)
39+ }
40+ onDownloadCanceled: {
41+ updateModel.cancelUpdate(download.metadata.custom.identifier,
42+ download.metadata.custom.revision)
43+ }
44+ onErrorFound: {
45+ updateModel.setError(download.metadata.custom.identifier,
46+ download.metadata.custom.revision,
47+ download.errorMessage)
48+ }
49+ onDownloadsChanged: restoreDownloads()
50+ Component.onCompleted: restoreDownloads()
51+ }
52+
53+ function downloadAll() {
54+
55+ }
56+
57+ function restoreDownloads() {
58+ var dl;
59+ for (var i = 0; i<downloads.length; i++) {
60+ dl = downloads[i];
61+ if (!dl._bound) {
62+ /* We only bind those signals here, that the UDM does not
63+ receive, i.e. processing and progressChanged. */
64+ dl.progressChanged.connect(onDownloadProgress.bind(dl));
65+ dl.processing.connect(onDownloadProcessing.bind(dl));
66+ dl._bound = true;
67+ }
68+ }
69+ }
70+
71+ function resumeDownload(click) {
72+ var download = getDownloadFor(click);
73+ if (download && !download.downloading && !download.isCompleted) {
74+ download.resume();
75+ }
76+ }
77+
78+ function pauseDownload(click) {
79+ var download = getDownloadFor(click);
80+ if (download && download.downloading) {
81+ download.pause();
82+ }
83+ }
84+
85+ // Return download for a click update.
86+ function getDownloadFor(click) {
87+ var cust;
88+ var dl;
89+
90+ for (var i = 0; i<downloads.length; i++) {
91+ dl = downloads[i];
92+ if (dl.errorMessage || dl.isCompleted) {
93+ // Ignore failed and completed downloads.
94+ continue;
95+ }
96+
97+ cust = downloads[i].metadata.custom;
98+ if (cust.identifier === click.identifier && cust.revision === click.revision) {
99+ return downloads[i];
100+ }
101+ }
102+ return null;
103+ }
104+
105+ function hasExistingDownload(click) {
106+ var existingDownload = getDownloadFor(click);
107+ return (existingDownload !== null &&
108+ !existingDownload.errorMessage &&
109+ !existingDownload.isCompleted);
110+ }
111+
112+ function retryDownload(click) {
113+ return createDownload(click, true);
114+ }
115+
116+ function createDownload(click, useSignedUrl) {
117+ if (hasExistingDownload(click)) {
118+ return null;
119+ }
120+ var downloadUrl = click.downloadUrl;
121+ var metadata = {
122+ "command": click.command,
123+ "title": click.title,
124+ "showInIndicator": false
125+ };
126+ var metadataObj = mdt.createObject(root, metadata);
127+ metadataObj.custom = {
128+ "identifier": click.identifier,
129+ "package-name": click.identifier,
130+ "revision": click.revision,
131+ };
132+
133+ var hdrs = {}
134+ if (useSignedUrl) {
135+ if (!click.signedDownloadUrl) {
136+ console.warn('The signed download URL was empty.');
137+ }
138+ downloadUrl = click.signedDownloadUrl;
139+ } else {
140+ // If we're using an unsigned URL, we need to provide this header.
141+ hdrs["X-Click-Token"] = click.token;
142+ }
143+
144+ var singleDownloadObj = sdl.createObject(root, {
145+ "autoStart": true,
146+ "hash": click.downloadHash,
147+ "algorithm": "sha512",
148+ "headers": hdrs,
149+ "metadata": metadataObj,
150+ "revision": click.revision,
151+ "identifier": click.identifier
152+ });
153+ singleDownloadObj.download(downloadUrl);
154+ return singleDownloadObj;
155+ }
156+
157+ function onDownloadProgress(progress) {
158+ updateModel.setProgress(this.metadata.custom.identifier,
159+ this.metadata.custom.revision,
160+ this.progress);
161+ }
162+
163+ function onDownloadProcessing() {
164+ updateModel.processUpdate(this.metadata.custom.identifier,
165+ this.metadata.custom.revision);
166+ }
167+
168+ /* If a update's model has a downloadId, check if UDM knows it. If not,
169+ treat this as a failure. Workaround for lp:1603770. */
170+ function assertDownloadExist(click) {
171+ if (!getDownloadFor(click)) {
172+ updateModel.setError(
173+ click.identifier, click.revision,
174+ i18n.tr("Installation failed")
175+ );
176+ }
177+ }
178+
179+ Component {
180+ id: sdl
181+ SingleDownload {
182+ id: download
183+ objectName: "singleDownload"
184+ property bool _bound: true
185+
186+ onDownloadIdChanged: {
187+ updateModel.queueUpdate(metadata.custom.identifier,
188+ metadata.custom.revision,
189+ downloadId);
190+ }
191+ onStarted: {
192+ updateModel.startUpdate(metadata.custom.identifier,
193+ metadata.custom.revision);
194+ }
195+ onProgressChanged: onDownloadProgress.call(download)
196+ onProcessing: onDownloadProcessing.call(download)
197+ }
198+ }
199+
200+ Component {
201+ id: mdt
202+ Metadata {}
203+ }
204+}
qml/Wizard/Pages/GlobalUpdateControls.qmlnew file+138
@@ -0,0 +1,138 @@
1+/*
2+ * This file is part of system-settings
3+ *
4+ * Copyright (C) 2016 Canonical Ltd.
5+ *
6+ * This program is free software: you can redistribute it and/or modify it
7+ * under the terms of the GNU General Public License version 3, as published
8+ * by the Free Software Foundation.
9+ *
10+ * This program is distributed in the hope that it will be useful, but
11+ * WITHOUT ANY WARRANTY; without even the implied warranties of
12+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
13+ * PURPOSE. See the GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License along
16+ * with this program. If not, see <http://www.gnu.org/licenses/>.
17+ */
18+
19+import QtQuick 2.4
20+import QtQuick.Layouts 1.1
21+import Ubuntu.Components 1.3
22+import Ubuntu.Components.ListItems 1.3 as ListItems
23+import Ubuntu.SystemSettings.Update 1.0
24+
25+Item {
26+ id: g
27+
28+ property bool batchMode
29+ property int status // A UpdateManager::Status
30+ property bool requireRestart: false
31+ property int updatesCount: 0
32+ property bool online: false
33+
34+ property bool hidden: {
35+ switch (status) {
36+ case UpdateManager.StatusNetworkError:
37+ case UpdateManager.StatusServerError:
38+ return true;
39+ }
40+ return !online ||
41+ (updatesCount <= 1 && status === UpdateManager.StatusIdle) ||
42+ batchMode
43+ }
44+
45+ signal stop()
46+ signal requestInstall()
47+ signal install()
48+
49+ Behavior on height {
50+ UbuntuNumberAnimation {}
51+ }
52+
53+ RowLayout {
54+ id: checking
55+ spacing: units.gu(2)
56+ anchors {
57+ fill: parent
58+ margins: units.gu(2)
59+ }
60+
61+ Behavior on opacity {
62+ UbuntuNumberAnimation {}
63+ }
64+
65+ opacity: visible ? 1 : 0
66+ visible: {
67+ switch (g.status) {
68+ case UpdateManager.StatusCheckingClickUpdates:
69+ case UpdateManager.StatusCheckingImageUpdates:
70+ case UpdateManager.StatusCheckingAllUpdates:
71+ return true;
72+ }
73+ return false;
74+ }
75+
76+ ActivityIndicator {
77+ running: parent.visible
78+ }
79+
80+ Label {
81+ objectName: "checkLabel"
82+ Layout.fillWidth: true
83+ elide: Text.ElideRight
84+ text: i18n.tr("Checking for updates…")
85+ }
86+ }
87+
88+ RowLayout {
89+ id: install
90+ anchors {
91+ fill: parent
92+ margins: units.gu(2)
93+ }
94+ spacing: units.gu(2)
95+
96+ Behavior on opacity {
97+ UbuntuNumberAnimation {}
98+ }
99+
100+ opacity: visible ? 1 : 0
101+ visible: {
102+ var canInstall = g.status === UpdateManager.StatusIdle;
103+ return canInstall && updatesCount > 1;
104+ }
105+
106+ Label {
107+ objectName: "updatesGlobalInfoLabel"
108+ // // TRANSLATORS: %1 is number of software updates available.
109+ text: i18n.tr("%1 update available",
110+ "%1 updates available",
111+ updatesCount).arg(updatesCount)
112+ Layout.fillWidth: true
113+ }
114+
115+ Button {
116+ objectName: "updatesGlobalInstallButton"
117+ text: {
118+ if (g.requireRestart === true) {
119+ return i18n.tr("Update all…");
120+ } else {
121+ return i18n.tr("Update all");
122+ }
123+ }
124+ onClicked: g.requestInstall()
125+ color: theme.palette.normal.positive
126+ strokeColor: "transparent"
127+ }
128+ }
129+
130+ ListItems.ThinDivider {
131+ visible: !g.hidden
132+ anchors {
133+ left: parent.left
134+ right: parent.right
135+ bottom: parent.bottom
136+ }
137+ }
138+}
qml/Wizard/Pages/UpdateDelegate.qmlnew file+389
@@ -0,0 +1,389 @@
1+/*
2+ * This file is part of system-settings
3+ *
4+ * Copyright (C) 2016 Canonical Ltd.
5+ *
6+ * Contact: Jonas G. Drange <jonas.drange@canonical.com>
7+ *
8+ * This program is free software: you can redistribute it and/or modify it
9+ * under the terms of the GNU General Public License version 3, as published
10+ * by the Free Software Foundation.
11+ *
12+ * This program is distributed in the hope that it will be useful, but
13+ * WITHOUT ANY WARRANTY; without even the implied warranties of
14+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15+ * PURPOSE. See the GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License along
18+ * with this program. If not, see <http://www.gnu.org/licenses/>.
19+ *
20+ */
21+
22+import QtQuick 2.4
23+import QtQuick.Layouts 1.1
24+import Ubuntu.Components 1.3
25+import Ubuntu.Components.ListItems 1.3 as ListItems
26+import Ubuntu.Components.Themes 1.3
27+import Ubuntu.SystemSettings.Update 1.0
28+
29+ListItem {
30+ id: update
31+
32+ property int updateState // This is an Update::State
33+ property int kind // This is an Update::Kind
34+ property real size
35+ property string version
36+ property string downloadId
37+ property date updatedAt
38+ property bool launchable: false
39+
40+ property alias name: nameLabel.text
41+ property alias error: errorElementDetail.text
42+ property alias iconUrl: icon.source
43+ property alias progress: progressBar.value
44+
45+ signal retry()
46+ signal download()
47+ signal pause()
48+ signal resume()
49+ signal install()
50+ signal launch()
51+
52+ height: layout.height + (divider.visible ? divider.height : 0)
53+ Behavior on height {
54+ animation: UbuntuNumberAnimation {}
55+ }
56+
57+ SlotsLayout {
58+ id: layout
59+ mainSlot: ColumnLayout {
60+ spacing: units.gu(1)
61+ // Width the parent, minus the icon and some padding
62+ width: parent.width - (icon.width + (layout.padding.top * 3))
63+
64+ RowLayout {
65+ spacing: units.gu(2)
66+
67+ Label {
68+ id: nameLabel
69+ verticalAlignment: Text.AlignVCenter
70+ elide: Text.ElideMiddle
71+ Layout.fillWidth: true
72+ Layout.fillHeight: true
73+ }
74+
75+ Button {
76+ id: button
77+ objectName: "updateButton"
78+ Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
79+ visible: {
80+ switch (updateState) {
81+ case Update.StateInstalled:
82+ return launchable;
83+ default:
84+ return true;
85+ }
86+ }
87+ enabled: {
88+ switch(updateState) {
89+ case Update.StateAvailable:
90+ case Update.StateDownloading:
91+ case Update.StateDownloadingAutomatically:
92+ case Update.StateDownloadPaused:
93+ case Update.StateAutomaticDownloadPaused:
94+ case Update.StateInstallPaused:
95+ case Update.StateDownloaded:
96+ case Update.StateFailed:
97+ return true;
98+
99+ // Enabled if installed and a click app (can launch).
100+ case Update.StateInstalled:
101+ return kind === Update.KindClick;
102+
103+ case Update.StateInstalling:
104+ case Update.StateInstallingAutomatically:
105+ case Update.StateUnavailable:
106+ case Update.StateInstallFinished:
107+ case Update.StateQueuedForDownload:
108+ case Update.StateUnknown:
109+ default:
110+ return false;
111+ }
112+ }
113+ text: {
114+ switch(updateState) {
115+ case Update.StateUnknown:
116+ case Update.StateUnavailable:
117+ case Update.StateFailed:
118+ return i18n.tr("Retry");
119+
120+ case Update.StateAvailable:
121+ case Update.StateQueuedForDownload:
122+ if (update.kind === Update.KindClick) {
123+ return i18n.tr("Update");
124+ } else {
125+ return i18n.tr("Download");
126+ }
127+
128+ case Update.StateDownloadPaused:
129+ case Update.StateAutomaticDownloadPaused:
130+ case Update.StateInstallPaused:
131+ return i18n.tr("Resume");
132+
133+ case Update.StateDownloading:
134+ case Update.StateDownloadingAutomatically:
135+ case Update.StateInstalling:
136+ case Update.StateInstallingAutomatically:
137+ case Update.StateInstallFinished:
138+ return i18n.tr("Pause");
139+
140+ case Update.StateDownloaded:
141+ if (kind === Update.KindImage) {
142+ return i18n.tr("Install…");
143+ } else {
144+ return i18n.tr("Install");
145+ }
146+
147+ case Update.StateInstalled:
148+ return i18n.tr("Open");
149+
150+ default:
151+ console.error("Unknown update state", updateState);
152+ }
153+ }
154+
155+ onClicked: {
156+ switch (updateState) {
157+
158+ // Retries.
159+ case Update.StateUnknown:
160+ case Update.StateUnavailable:
161+ case Update.StateFailed:
162+ update.retry();
163+ break;
164+
165+ case Update.StateDownloadPaused:
166+ case Update.StateAutomaticDownloadPaused:
167+ case Update.StateInstallPaused:
168+ update.resume();
169+ break;
170+
171+ case Update.StateAvailable:
172+ if (kind === Update.KindClick) {
173+ update.install();
174+ } else {
175+ update.download();
176+ }
177+ break;
178+
179+ case Update.StateDownloaded:
180+ update.install();
181+ break;
182+
183+ case Update.StateDownloading:
184+ case Update.StateDownloadingAutomatically:
185+ case Update.StateInstalling:
186+ case Update.StateInstallingAutomatically:
187+ update.pause();
188+ break;
189+
190+ case Update.StateInstalled:
191+ update.launch();
192+ break;
193+ }
194+ }
195+ } // Button
196+ } // Name/button RowLayout
197+
198+ RowLayout {
199+ spacing: units.gu(2)
200+
201+ Label {
202+ id: downloadLabel
203+ objectName: "updateDownloadLabel"
204+
205+ Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
206+
207+ visible: text !== ""
208+
209+ fontSize: "small"
210+ text: {
211+ switch (updateState) {
212+
213+ case Update.StateInstalling:
214+ case Update.StateInstallingAutomatically:
215+ case Update.StateInstallPaused:
216+ return i18n.tr("Installing");
217+
218+ case Update.StateInstallPaused:
219+ case Update.StateDownloadPaused:
220+ return i18n.tr("Paused");
221+
222+ case Update.StateQueuedForDownload:
223+ return i18n.tr("Waiting to download");
224+
225+ case Update.StateDownloading:
226+ return i18n.tr("Downloading");
227+
228+ default:
229+ return "";
230+ }
231+ }
232+ }
233+
234+ Label {
235+ id: statusLabel
236+ objectName: "updateStatusLabel"
237+
238+ visible: text !== ""
239+ Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
240+ Layout.fillWidth: true
241+
242+ horizontalAlignment: Text.AlignRight
243+ fontSize: "small"
244+
245+ text: {
246+
247+ function humanFileSize(bytes, si) {
248+ var thresh = si ? 1000 : 1024;
249+ if(Math.abs(bytes) < thresh) {
250+ return bytes + ' B';
251+ }
252+ var units = si
253+ ? ['kB','MB','GB','TB','PB','EB','ZB','YB']
254+ : ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
255+ var u = -1;
256+ do {
257+ bytes /= thresh;
258+ ++u;
259+ } while(Math.abs(bytes) >= thresh && u < units.length - 1);
260+ return bytes.toFixed(1)+' '+units[u];
261+ }
262+
263+ switch (updateState) {
264+ case Update.StateAvailable:
265+ return humanFileSize(size, 1000);
266+
267+ case Update.StateDownloading:
268+ case Update.StateDownloadingAutomatically:
269+ case Update.StateDownloadPaused:
270+ case Update.StateAutomaticDownloadPaused:
271+ var down = humanFileSize((size / 100) * progress, 1000);
272+ var left = humanFileSize(size, 1000);
273+ if (progress > 100) {
274+ return left;
275+ } else {
276+ /* TRANSLATORS: %1 is the human readable amount
277+ of bytes downloaded, and %2 is the total to be
278+ downloaded. */
279+ return i18n.tr("%1 of %2").arg(down).arg(left);
280+ }
281+
282+ case Update.StateDownloaded:
283+ return i18n.tr("Downloaded");
284+
285+ case Update.StateInstallFinished:
286+ return i18n.tr("Installed");
287+
288+ case Update.StateInstalled:
289+ /* TRANSLATORS: %1 is the date at which this
290+ update was applied. */
291+ return i18n.tr("Updated %1").arg(
292+ updatedAt.toLocaleDateString(Qt.locale(), "d MMMM")
293+ );
294+ default:
295+ return "";
296+ }
297+ }
298+
299+ /* Seems AlignRight causes a rendering issue that can be
300+ fixed by doing an explicit doLayout. */
301+ Component.onCompleted: doLayout()
302+ }
303+ }
304+
305+ Column {
306+ id: error
307+ objectName: "updateError"
308+ spacing: units.gu(1)
309+ height: childrenRect.height
310+ Layout.fillWidth: true
311+ visible: errorElementDetail.text
312+
313+ Label {
314+ id: errorElementTitle
315+ text: i18n.tr("Update failed")
316+ color: UbuntuColors.red
317+ }
318+
319+ Label {
320+ id: errorElementDetail
321+ anchors { left: parent.left; right: parent.right }
322+ fontSize: "small"
323+ wrapMode: Text.WrapAnywhere
324+ }
325+ } // Error column
326+
327+ ProgressBar {
328+ id: progressBar
329+ objectName: "updateProgressbar"
330+
331+ visible: {
332+ switch (updateState) {
333+ case Update.StateQueuedForDownload:
334+ case Update.StateDownloading:
335+ case Update.StateDownloadPaused:
336+ case Update.StateInstalling:
337+ case Update.StateInstallPaused:
338+ return true;
339+
340+ default:
341+ return false;
342+ }
343+ }
344+ Layout.maximumHeight: units.gu(0.5)
345+ Layout.fillWidth: true
346+ indeterminate: update.progress < 0 || update.progress > 100
347+ minimumValue: 0
348+ maximumValue: 100
349+ showProgressPercentage: false
350+
351+ Behavior on value {
352+ animation: UbuntuNumberAnimation {}
353+ }
354+ } // Progress bar
355+ } // Layout for the rest of the stuff
356+
357+ Item {
358+ SlotsLayout.position: SlotsLayout.Leading;
359+ width: units.gu(4)
360+ height: width
361+
362+ Image {
363+ id: icon
364+ visible: kind === Update.KindImage && !fallback.visible
365+ anchors.fill: parent
366+ asynchronous: true
367+ smooth: true
368+ mipmap: true
369+ }
370+
371+ UbuntuShape {
372+ id: shape
373+ visible: kind !== Update.KindImage && !fallback.visible
374+ anchors.fill: parent
375+ source: icon
376+ }
377+
378+ Image {
379+ id: fallback
380+ visible: icon.status === Image.Error
381+ source : Qt.resolvedUrl("/usr/share/icons/suru/apps/scalable/ubuntu-logo-symbolic.svg")
382+ anchors.fill: parent
383+ asynchronous: true
384+ smooth: true
385+ mipmap: true
386+ }
387+ }
388+ }
389+}
qml/Wizard/Pages/here-terms.qmldeleted−126
@@ -1,126 +0,0 @@
1−/*
2− * Copyright (C) 2014-2016 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.4
18−import Ubuntu.Components 1.3
19−import Ubuntu.Web 0.2
20−import ".." as LocalComponents
21−
22−LocalComponents.Page {
23− objectName: "hereTermsPage"
24−
25− title: i18n.tr("Terms & Conditions")
26− customBack: true
27− customTitle: true
28−
29− onBackClicked: {
30− if (webview.visible) {
31− showBrowser(false);
32− } else {
33− pageStack.prev();
34− }
35− }
36−
37− function showBrowser(show) {
38− if (show) {
39− label1.visible = false;
40− label2.visible = false;
41− label3.visible = false;
42− label4.visible = false;
43− webview.visible = true;
44− } else {
45− webview.visible = false;
46− label1.visible = true;
47− label2.visible = true;
48− label3.visible = true;
49− label4.visible = true;
50− }
51− }
52−
53− Column {
54− id: column
55− anchors.fill: content
56− anchors.leftMargin: staticMargin
57− anchors.rightMargin: wideMode ? parent.rightMargin : staticMargin
58− spacing: units.gu(3)
59−
60− Label {
61− id: label1
62− anchors.left: parent.left
63− anchors.right: parent.right
64− wrapMode: Text.Wrap
65− color: textColor
66− fontSize: "small"
67− font.weight: Font.Light
68− lineHeight: 1.2
69− text: i18n.tr("Your device uses positioning technologies provided by HERE.")
70− }
71−
72− Label {
73− id: label2
74− anchors.left: parent.left
75− anchors.right: parent.right
76− wrapMode: Text.Wrap
77− color: textColor
78− fontSize: "small"
79− font.weight: Font.Light
80− lineHeight: 1.2
81− text: i18n.tr("To provide you with positioning services and to improve their quality, HERE collects information about nearby cell towers and Wi-Fi hotspots around your current location whenever your position is being found.")
82− }
83−
84− Label {
85− id: label3
86− anchors.left: parent.left
87− anchors.right: parent.right
88− wrapMode: Text.Wrap
89− color: textColor
90− fontSize: "small"
91− font.weight: Font.Light
92− lineHeight: 1.2
93− text: i18n.tr("The information collected is used to analyze the service and to improve the use of service, but not to identify you personally.")
94− }
95−
96− Label {
97− id: label4
98− anchors.left: parent.left
99− anchors.right: parent.right
100− wrapMode: Text.Wrap
101− color: textColor
102− fontSize: "small"
103− font.weight: Font.Light
104− lineHeight: 1.2
105− linkColor: UbuntuColors.orange
106− text: i18n.tr("By continuing, you agree to the HERE platform %1 and %2.")
107− .arg("<a href=\"http://here.com/terms/service-terms\">" + i18n.tr("Service Terms") + "</a>")
108− .arg("<a href=\"http://here.com/privacy/privacy-policy\">" + i18n.tr("Privacy Policy") + "</a>");
109− onLinkActivated: {
110− showBrowser(true);
111− webview.url = link;
112− }
113− }
114−
115− WebView {
116− id: webview
117− objectName: "webview"
118− anchors.left: parent.left
119− anchors.right: parent.right
120− anchors.leftMargin: -leftMargin
121− anchors.rightMargin: -rightMargin
122− height: parent.height
123− visible: false
124− }
125− }
126−}
qml/Wizard/Wizard.qml+5−2
@@ -1,4 +1,5 @@
1/*
1/*
2+ * Copyright (C) 2018 The UBports project
2 * Copyright (C) 2013, 2015 Canonical, Ltd.
3 * Copyright (C) 2013, 2015 Canonical, Ltd.
3 *
4 *
4 * This program is free software; you can redistribute it and/or modify
5 * This program is free software; you can redistribute it and/or modify
@@ -20,7 +21,7 @@ import Wizard 0.1
20import "../Components"
21import "../Components"
21
22
22Showable {
23Showable {
23− id: root
24+ id: wizard
24
25
25 // This is a bool instead of an alias because Loader classes like to emit
26 // This is a bool instead of an alias because Loader classes like to emit
26 // changed signals for 'active' during startup even if they aren't actually
27 // changed signals for 'active' during startup even if they aren't actually
@@ -29,6 +30,8 @@ Showable {
29 // expected behavior of no emission on startup.
30 // expected behavior of no emission on startup.
30 readonly property bool active: loader.active
31 readonly property bool active: loader.active
31
32
33+ property bool isUpdate: System.isUpdate
34+
32 // The wizard should be run at a later time if, for example, unity8 is
35 // The wizard should be run at a later time if, for example, unity8 is
33 // in greeter mode
36 // in greeter mode
34 property bool deferred: false
37 property bool deferred: false
@@ -49,7 +52,7 @@ Showable {
49
52
50 Connections {
53 Connections {
51 target: loader.item
54 target: loader.item
52− onQuit: root.hide()
55+ onQuit: wizard.hide()
53 }
56 }
54 }
57 }
55}
58}
tests/plugins/CMakeLists.txt+1−1
@@ -8,5 +8,5 @@ add_subdirectory(LightDM)
8add_subdirectory(SessionBroadcast)
8add_subdirectory(SessionBroadcast)
9add_subdirectory(Ubuntu)
9add_subdirectory(Ubuntu)
10add_subdirectory(Unity)
10add_subdirectory(Unity)
11−#add_subdirectory(Utils) #FIXME broken with qt 5.9
11+add_subdirectory(Utils)
12add_subdirectory(Wizard)
12add_subdirectory(Wizard)
tests/plugins/Ubuntu/CMakeLists.txt+1−1
@@ -1 +1 @@
1−#add_subdirectory(Gestures) #FIXME broken with qt 5.9
1+add_subdirectory(Gestures)
tests/plugins/Ubuntu/Gestures/GestureTest.cpp+1−1
@@ -107,7 +107,7 @@ void GestureTest::sendTouch(qint64 timestamp, int id, QPointF pos,
107 QCoreApplication::sendEvent(m_view, &touchEvent);
107 QCoreApplication::sendEvent(m_view, &touchEvent);
108
108
109 QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(m_view);
109 QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(m_view);
110− windowPrivate->flushDelayedTouchEvent();
110+ windowPrivate->flushFrameSynchronousEvents();
111}
111}
112
112
113void GestureTest::passTime(qint64 timeSpanMs)
113void GestureTest::passTime(qint64 timeSpanMs)
tests/plugins/Ubuntu/Gestures/tst_TouchGate.cpp+1−1
@@ -189,7 +189,7 @@ void tst_TouchGate::holdsEventsUntilGainsOwnership()
189 if (!ownershipAfterTouchEnd) {
189 if (!ownershipAfterTouchEnd) {
190 touchRegistry->removeCandidateOwnerForTouch(0, candidateItem);
190 touchRegistry->removeCandidateOwnerForTouch(0, candidateItem);
191 QQuickWindowPrivate *wp = QQuickWindowPrivate::get(testItem->window());
191 QQuickWindowPrivate *wp = QQuickWindowPrivate::get(testItem->window());
192− wp->flushDelayedTouchEvent();
192+ wp->flushFrameSynchronousEvents();
193 // TouchGate should now open its flood gates and let testItem get all
193 // TouchGate should now open its flood gates and let testItem get all
194 // events from touch 0 produced so far
194 // events from touch 0 produced so far
195 QCOMPARE(testItem->touchEventsReceived.count(), 2);
195 QCOMPARE(testItem->touchEventsReceived.count(), 2);
tests/plugins/Utils/ModelTest.cpp+1−1
@@ -441,7 +441,7 @@ void ModelTest::data()
441 QVariant textAlignmentVariant = model->data ( model->index ( 0, 0 ), Qt::TextAlignmentRole );
441 QVariant textAlignmentVariant = model->data ( model->index ( 0, 0 ), Qt::TextAlignmentRole );
442 if ( textAlignmentVariant.isValid() ) {
442 if ( textAlignmentVariant.isValid() ) {
443 int alignment = textAlignmentVariant.toInt();
443 int alignment = textAlignmentVariant.toInt();
444− QCOMPARE( alignment, ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) );
444+ QCOMPARE( alignment, (int) ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ));
445 }
445 }
446
446
447 // General Purpose roles that should return a QColor
447 // General Purpose roles that should return a QColor
tests/qmltests/CMakeLists.txt+2−2
@@ -1,5 +1,5 @@
1
1
2−#add_subdirectory(Components) #FIXME broken with qt 5.9
2+add_subdirectory(Components)
3
3
4add_unity8_qmltest(. OrientedShell)
4add_unity8_qmltest(. OrientedShell)
5add_unity8_qmltest(. DisabledScreenNotice)
5add_unity8_qmltest(. DisabledScreenNotice)
@@ -44,7 +44,7 @@ add_unity8_qmltest(Dash/Previews PreviewIconActions)
44add_unity8_qmltest(Dash/Previews PreviewImageGallery)
44add_unity8_qmltest(Dash/Previews PreviewImageGallery)
45add_unity8_qmltest(Dash/Previews PreviewInlineVideo)
45add_unity8_qmltest(Dash/Previews PreviewInlineVideo)
46add_unity8_qmltest(Dash/Previews PreviewMediaToolbar)
46add_unity8_qmltest(Dash/Previews PreviewMediaToolbar)
47−add_unity8_qmltest(Dash/Previews PreviewPayments)
47+#add_unity8_qmltest(Dash/Previews PreviewPayments)
48add_unity8_qmltest(Dash/Previews PreviewProgress)
48add_unity8_qmltest(Dash/Previews PreviewProgress)
49add_unity8_qmltest(Dash/Previews PreviewRatingDisplay)
49add_unity8_qmltest(Dash/Previews PreviewRatingDisplay)
50add_unity8_qmltest(Dash/Previews PreviewRatingDisplayCreationRanges)
50add_unity8_qmltest(Dash/Previews PreviewRatingDisplayCreationRanges)
tests/qmltests/Components/tst_DragHandle.cpp+2−2
@@ -177,7 +177,7 @@ void tst_DragHandle::flickAndHold(QQuickItem *dragHandle,
177 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
177 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
178
178
179 QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(m_view);
179 QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(m_view);
180− windowPrivate->flushDelayedTouchEvent();
180+ windowPrivate->flushFrameSynchronousEvents();
181}
181}
182
182
183void tst_DragHandle::drag(QPointF &touchPoint, const QPointF& direction, qreal distance,
183void tst_DragHandle::drag(QPointF &touchPoint, const QPointF& direction, qreal distance,
@@ -192,7 +192,7 @@ void tst_DragHandle::drag(QPointF &touchPoint, const QPointF& direction, qreal d
192 m_fakeTimeSource->m_msecsSinceReference += timeStep;
192 m_fakeTimeSource->m_msecsSinceReference += timeStep;
193 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
193 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
194
194
195− windowPrivate->flushDelayedTouchEvent();
195+ windowPrivate->flushFrameSynchronousEvents();
196 }
196 }
197}
197}
198
198
tests/utils/CMakeLists.txt+1−1
@@ -1 +1 @@
1−#add_subdirectory(modules) #FIXME broken with qt 5.9
1+add_subdirectory(modules)
tests/utils/modules/Unity/Test/TouchEventSequenceWrapper.cpp−9
@@ -26,16 +26,7 @@ TouchEventSequenceWrapper::TouchEventSequenceWrapper(QTest::QTouchEventSequence
26
26
27void TouchEventSequenceWrapper::commit(bool processEvents)
27void TouchEventSequenceWrapper::commit(bool processEvents)
28{
28{
29− // Item might be deleted as a consequence of this event sequence being handled
30− // So store its window beforehand
31− QQuickWindow *window = m_item->window();
32−
33 m_eventSequence.commit(processEvents);
29 m_eventSequence.commit(processEvents);
34−
35− if (window) {
36− QQuickWindowPrivate *wp = QQuickWindowPrivate::get(window);
37− wp->flushDelayedTouchEvent();
38− }
39}
30}
40
31
41void TouchEventSequenceWrapper::move(int touchId, int x, int y)
32void TouchEventSequenceWrapper::move(int touchId, int x, int y)