on ccea24e help sign in
63 files changed+2483−912
since splitsnapshots
unifiedsplit
CODING−164 CODING.md+74 Jenkinsfile+28−11 README.md+51 data/CMakeLists.txt+1 data/com.canonical.Unity.gschema.xml+255 data/unity8.conf+33−32 debian/changelog+36 debian/control+15−6 debian/unity8-common.install−1 debian/unity8-schemas.install+1 plugins/Dash/abstractdashview.cpp+1−1 plugins/Dash/listviewwithpageheader.cpp+4−6 plugins/Dash/listviewwithpageheader.h+1−1 plugins/Dash/verticaljournal.cpp+6−8 plugins/Dash/verticaljournal.h+1−1 plugins/Ubuntu/CMakeLists.txt+1−1 plugins/Wizard/CMakeLists.txt+1 plugins/Wizard/Changelog.cpp+58 plugins/Wizard/Changelog.h+52 plugins/Wizard/System.cpp+68−3 plugins/Wizard/System.h+17 plugins/Wizard/plugin.cpp+2 po/unity8.pot+159−84 qml/Dash/DashBackground.qml+1−1 qml/Dash/Previews/PreviewWidgetFactory.qml−1 qml/Shell.qml+2−1 qml/Stage/Stage.qml+8−2 qml/Stage/WindowResizeArea.qml+4−1 qml/Wizard/Components/InputMethod.qml+9−9 qml/Wizard/Page.qml+5 qml/Wizard/Pages.qml+48−13 qml/Wizard/Pages/10-welcome-update.qml+137 qml/Wizard/Pages/10-welcome.qml+2 qml/Wizard/Pages/11-changelog.qml+95 qml/Wizard/Pages/30-wifi.qml+1 qml/Wizard/Pages/40-location.qml−290 qml/Wizard/Pages/50-timezone.qml+1 qml/Wizard/Pages/60-account.qml+11−10 qml/Wizard/Pages/70-passwd-type.qml+1 qml/Wizard/Pages/75-report-check.qml−91 qml/Wizard/Pages/76-app-update.qml+246 qml/Wizard/Pages/78-firmware-update.qml.disabled+246 qml/Wizard/Pages/77-system-update.qml → qml/Wizard/Pages/79-system-update.qml qml/Wizard/Pages/80-finished.qml+4−2 qml/Wizard/Pages/ClickUpdateDelegate.qml+26 qml/Wizard/Pages/DownloadHandler.qml+204 qml/Wizard/Pages/GlobalUpdateControls.qml+138 qml/Wizard/Pages/UpdateDelegate.qml+389 qml/Wizard/Pages/here-terms.qml−126 qml/Wizard/Pages/passcode-desktop.qml+13−5 qml/Wizard/Pages/password-set.qml+11−4 qml/Wizard/Wizard.qml+5−2 tests/plugins/CMakeLists.txt+1−1 tests/plugins/Ubuntu/CMakeLists.txt+1−1 tests/plugins/Ubuntu/Gestures/GestureTest.cpp+1−1 tests/plugins/Ubuntu/Gestures/tst_TouchGate.cpp+1−1 tests/plugins/Utils/ModelTest.cpp+1−1 tests/qmltests/CMakeLists.txt+2−2 tests/qmltests/Components/tst_DragHandle.cpp+2−2 tests/qmltests/Wizard/tst_Wizard.qml+1−16 tests/utils/CMakeLists.txt+1−1 tests/utils/modules/Unity/Test/TouchEventSequenceWrapper.cpp−9
CODINGdeleted−164
@@ -1,164 +0,0 @@
1−Building Unity 8
2−================
3−
4−Only Ubuntu 14.04 (trusty) is supported as a developement environment.
5−
6−download source
7−---------------
8−- create a parent folder to not pollute your setup. so that you can have different unity
9− branches there (trunk, WIP etc)
10−
11− $ mkdir ~/unity8
12−
13−- fetch Unity 8 source
14− $ sudo apt-get install bzr
15− $ bzr branch lp:unity8 ~/unity8/trunk
16− $ cd ~/unity8/trunk
17−
18−install dependencies and build Unity 8
19−--------------------
20−
21−$ cd ~/unity8/trunk
22−$ ./build.sh
23−
24− If its your first time, this will install the required dependencies to build and
25− build it.
26−
27− You might want to also install unity-scope-home and unity-scope-click which
28− are technically "recommends", not strict dependencies
29−
30−You may also rebuild with the -c for clean, which just deletes the build
31−directory.
32−
33−
34−Running Unity 8 on your desktop
35−===============================
36−
37−run the Unity 8 shell
38−---------------------
39−$ cd ~/unity8/trunk
40−$ cd builddir
41−
42−Each component of unity8 can be ran independently for development and testing
43−For example:
44−$ make tryShell
45−$ make tryLauncher
46−$ make tryLockscreen
47−
48−Check out the tests/qmltests/ directory for a list of things that can be ran.
49−
50−Notes
51−-----
52−- to navigate, utilize the mouse left button as you would your finger
53−- a three point drag (for side stage operations) can be performed by using
54− the Shift+Control+Alt (all together) keyboard modifiers while using the mouse.
55−- to get the translations work, currently you have to do make install to
56− put the *.mo files into correct structure. We'll look for a better solution
57− later.
58− $ cd builddir; make install
59−- if you wish to populate contacts
60− $ sudo apt-get install gir1.2-ebook-1.2
61− $ manage-address-book.py create
62− this will:
63− - Create an EDS address book
64− - Populate the address book with sample data
65−
66−
67−Running Unity 8 on devices
68−==========================
69−
70−Running unity8 on a device should be done using crossbuilder.
71−Go to
72−* https://launchpad.net/crossbuilder and
73−* https://wiki.ubuntu.com/Touch/Crossbuilder
74−for more details on crossbuilder.
75−
76−unity8 will automatically restart on the phone once deployment
77−has finished due to post-build-steps set up in this repository.
78−
79−Coding guidelines
80−=================
81−The work-in-progress coding guidelines are available under:
82−https://launchpad.net/canonical-client-development-guidelines
83−
84−
85−Development Environment
86−=======================
87−QtCreator (available via the Software Center) is the best IDE to hack on
88−Unity 8.
89−
90−If using VIM, make sure you install some syntax highlighting for QML, like
91−https://github.com/peterhoeg/vim-qml
92−
93−Running tests
94−=============
95−
96−Tests are run from the build directory (which will be ./builddir if you used
97−the ./build.sh script).
98−
99−To run the tests that do not require any graphical capability and therefore
100−are pretty fast run:
101−
102−$ make test
103−
104−or, alternatively:
105−
106−$ ctest
107−
108−To run all graphical tests, which can take a couple of minutes:
109−
110−$ make uitests
111−
112−To run the tests for a single component/class:
113−
114−$ make testComponentName
115−
116−So, for the DragHandle component that would be:
117−
118−$ make testDragHandle
119−
120−To run the tests for a single component/class under gdb (so you can catch SEGFAULTS)
121−
122−$ make gdbtestComponentName
123−
124−To run a single test function of a single component/class:
125−
126−$ make testComponentName FUNCTION="TestCaseName::functionName"
127−
128−To run a test application that allow you to manually test or to simply try out
129−a given component:
130−
131−$ make tryComponentName
132−
133−So to try out, for instance, the DragHandle component, you would do:
134−
135−$ make tryDragHandle
136−
137−NB: Manual test or interation doesn't make sense for all components or classes,
138−particularly the non-graphical ones. In such cases no "tryFoo" make target is
139−provided.
140−
141−Running autopilot tests
142−=======================
143−
144−Autopilot tests are run from the build directory (which will be ./builddir if you used
145−the ./build.sh script).
146−
147−$ make autopilot
148−
149−If you want you can also run tests individually, for that you need to install first,
150−otherwise the tests will run on the system-installed version
151−
152−$ make install
153−
154−To see the list of existing autopilot tests you can do
155−
156−$ PYTHONPATH=../tests/autopilot autopilot3 list unity8
157−
158−And then run a single test with
159−
160−$ PYTHONPATH=../tests/autopilot autopilot3 run unity8.some.very.long.test.name
161−
162−or run them all with
163−
164−$ PYTHONPATH=../tests/autopilot autopilot3 run unity8
CODING.mdnew file+74
@@ -0,0 +1,74 @@
1+# Unity8 development docs
2+
3+It is recommended to use [crossbuilder](#crosscompile) for platform-independent building. You can also [build natively](#build-natively), but keep in mind that you will have to install lots of dependencies on your host OS.
4+
5+## Crosscompile
6+
7+To crosscompile, we have a tool called [crossbuilder](https://github.com/ubports/crossbuilder), this will automatically build and deploy to the device. [Here's how to set it up](https://docs.ubports.com/en/latest/systemdev/testing-locally.html#cross-building-with-crossbuilder).
8+
9+To build deb package just run:
10+```
11+crossbuilder
12+```
13+
14+or if you want to build without packaging:
15+```
16+crossbuilder --no-deb
17+```
18+
19+Use crossbuilder shell if you want to define your own cmake options. (this will not automaticly deploy to your device!)
20+```
21+crossbuilder shell
22+cd unity8
23+mkdir build-arm
24+cmake .. {OPTION(S)}
25+make
26+```
27+
28+For these changes to take effect, you will need to restart unity8, you can do this with `restart unity8` or reboot the device.
29+
30+You dont need to rebuild if changes is made to QML files, you can simply adb push the qml files and copy them to there location, then restart unity8.
31+
32+QML folder for unity8 is `/usr/share/unity8`.
33+
34+# Build natively
35+
36+## Install deps
37+
38+You need to add repo.ubports.com to your sources.list.
39+
40+Here is an example for bionic:
41+```
42+sudo apt install gnupg
43+echo "deb http://repo.ubports.com/ bionic main" | sudo tee /etc/apt/sources.list.d/ubports.list
44+wget http://repo.ubports.com/keyring.gpg -O - | sudo apt-key add
45+sudo apt update
46+```
47+
48+Then run mk-build-tools to install all the dependencies needed to build unity8.
49+```
50+sudo mk-build-deps -i
51+```
52+
53+## Build
54+
55+Then make build directory `mkdir build && cd build`
56+
57+Then run cmake `cmake ..` here you can also provide your build options
58+
59+Now its the fun part, build! `make -j4` (-j defines number of threads to build on)
60+
61+# Tests
62+
63+To run tests,
64+
65+```
66+make test
67+```
68+
69+You can also specify the differnet test targets to run with `make tryComponentName and make testComponentName`
70+
71+# Doxygen docs
72+
73+You can also install docs from the bionic or xenial repo that inclues a auto-generated docs including class infomation. This package is called unity8-doc and will be installed to `/usr/share/doc/unity8` here there will be an index.html, open this in your browser.
74+
Jenkinsfile+28−11
@@ -12,25 +12,40 @@ pipeline {
1212 steps {
1313 parallel(
1414 "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)
1617 unstash 'source'
1718 sh '''export architecture="armhf"
19+ export DEBBUILDOPTS="-sa"
20+ export SKIP_ARCH_BUILD=false
21+ export SKIP_SOURCE_REMOVAL=true
1822build-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')
2024 cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
2125 }
2226
2327
2428 },
25− "Build binary - all": {
26− node(label: 'xenial-arm64') {
29+ "Build binary - arm64": {
30+ node(label: 'arm64') {
31+ cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
2732 unstash 'source'
28− sh '''export architecture="armhf"
29− export DEBBUILDOPTS="-A"
33+ sh '''export architecture="arm64"
34+ export DEBBUILDOPTS="-sa"
3035 export SKIP_ARCH_BUILD=false
3136 export SKIP_SOURCE_REMOVAL=true
3237 build-binary.sh'''
33− stash(includes: '*.gz,*.bz2,*.xz,*.deb,*.dsc,*.changes,*.buildinfo,lintian.txt', name: 'build-all')
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"
47+ #build-binary.sh'''
48+ stash(includes: '*.gz,*.bz2,*.xz,*.deb,*.dsc,*.changes,*.buildinfo,lintian.txt', name: 'build-amd64')
3449 cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
3550 }
3651 }
@@ -39,11 +54,12 @@ build-binary.sh'''
3954 }
4055 stage('Results') {
4156 steps {
42− unstash 'build'
43− unstash 'build-all'
57+ cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
58+ unstash 'build-armhf'
59+ unstash 'build-arm64'
60+ unstash 'build-amd64'
4461 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'''
4763 }
4864 }
4965 stage('Cleanup') {
@@ -53,3 +69,4 @@ build-binary.sh'''
5369 }
5470 }
5571}
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.md) 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
3131add_custom_target(pkgversion ALL COMMAND dpkg-parsechangelog -l${CMAKE_SOURCE_DIR}/debian/changelog --show-field version > ${CMAKE_CURRENT_BINARY_DIR}/version)
3232
3333install(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)
3435install(FILES unity8-dash.url-dispatcher DESTINATION ${CMAKE_INSTALL_DATADIR}/url-dispatcher/urls)
3536install(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
88
99kill timeout 120
1010
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+
1120respawn
1221expect stop
1322
23+# FIXME Create an autopilot test that makes sure start+stop and restart
24+# work fine at least 2 times
25+
1426pre-start script
1527 # Tell unity-mir to raise SIGSTOP after we start
1628 initctl set-env UNITY_MIR_EMITS_SIGSTOP=1
1729
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,
22− # 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
30+ # Save original value of MIR_SOCKET so that we can restore it when stopped,
31+ # as we modify the variable for future jobs, including ourself.
32+ initctl set-env UNITY_MIR_SOCKET=$MIR_SOCKET
2533
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
2741 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'}"
3542 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'}"
3649
3750 # Remove the normal and trusted sockets if still there
3851 if [ -S "$MIR_SERVER_FILE" ]; then
@@ -46,6 +59,7 @@ pre-start script
4659 initctl set-env --global MIR_SERVER_PROMPT_FILE=1
4760
4861 # Disable Qt's stuttering 'touch compression' to fix scrolling smoothness
62+
4963 # issues (LP: #1486341, LP: #1556763). As a bonus, this eliminates most of
5064 # the lag seen in the indicator panel pull-down (LP: #1488327) and also
5165 # reduces lag seen in apps:
@@ -54,7 +68,6 @@ pre-start script
5468 # Workaround for text not rendering correctly
5569 initctl set-env --global QT_ENABLE_GLYPH_CACHE_WORKAROUND=1
5670
57−
5871 if [ "$XDG_SESSION_DESKTOP" = "ubuntu-touch" ]; then
5972 # On Ubuntu Touch, we currently use a trick where we auto-login the
6073 # user without a LightDM greeter at all. In this case, we want to
@@ -66,32 +79,20 @@ pre-start script
6679 fi
6780
6881 # HACK! WORKAROUND FOR HALIUM MISSING UBUNTU_PLATFORM_API
69− 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
82+ if [ ! -f /system/lib/libubuntu_application_api.so ]; then
83+ initctl set-env --global UBUNTU_PLATFORM_API_BACKEND=test.so.3
84+ initctl set-env --global UBUNTU_PLATFORM_API_SENSOR_TEST=/etc/ubuntusensors/test.sensors
85+ fi
7186end script
7287
7388exec ${BINARY:-unity8} --mode=$MODE $ARGS
7489
7590post-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−
8991 initctl emit --no-wait indicator-services-start
9092end script
9193
9294post-stop script
9395 initctl set-env --global MIR_SOCKET=$UNITY_MIR_SOCKET
94− initctl unset-env --global UNITY_MIR_SOCKET
9596 initctl unset-env --global MIR_SERVER_PROMPT_FILE
9697 initctl emit application-end
9798end 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+
137unity8 (8.16+ubports) xenial; urgency=medium
238
339 * Imported to UBports
debian/control+15−6
@@ -26,7 +26,6 @@ Build-Depends: cmake,
2626 libhardware-dev,
2727 liblightdm-qt5-3-dev,
2828 libpam0g-dev,
29− libpay2-dev,
3029 libpulse-dev,
3130 libqmenumodel-dev (>= 0.2.10),
3231 libqt5svg5-dev,
@@ -57,7 +56,6 @@ Build-Depends: cmake,
5756 qml-module-qtsysteminfo,
5857 qml-module-qttest,
5958 qml-module-ubuntu-components (>= 1.3.2030) | qml-module-ubuntu-components-gles (>= 1.3.2030),
60− qml-module-ubuntu-web,
6159 qt5-default,
6260 qtbase5-dev (>= 5.4),
6361 qtbase5-dev-tools,
@@ -125,7 +123,6 @@ Depends: dmz-cursor-theme,
125123 qml-module-qtqml-statemachine,
126124 qml-module-qtquick-xmllistmodel,
127125 qml-module-qtsysteminfo,
128− qml-module-ubuntu-web,
129126 qtdeclarative5-qtmir-plugin (>= 0.4.8),
130127 qtdeclarative5-ubuntu-telephony0.1,
131128 ubuntu-system-settings (>= 0.4),
@@ -159,12 +156,13 @@ Depends: qml-module-qtquick-layouts,
159156 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
160157 qttranslations5-l10n,
161158 ubuntu-thumbnailer-impl-0,
162− ubuntu-wallpapers,
159+ ubports-wallpapers,
163160 unity-application-impl-22,
164161 unity-notifications-impl-3,
165162 unity-plugin-scopes | unity-scopes-impl,
166163 unity-scopes-impl-12,
167164 unity8-fake-env | unity-application-impl,
165+ unity8-schemas,
168166 ${misc:Depends},
169167Breaks: unity8 (<< 7.86),
170168Replaces: unity8 (<< 7.86),
@@ -219,8 +217,7 @@ Pre-Depends: ${misc:Pre-Depends},
219217Depends: accountsservice-ubuntu-schemas (>= 0.0.7),
220218 gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
221219 libhardware2,
222− pay-service,
223− unity-schemas (>= 7.3.1+14.10.20140915),
220+ unity8-schemas,
224221 qtdeclarative5-gsettings1.0,
225222 qml-module-qtmultimedia,
226223 ${misc:Depends},
@@ -233,6 +230,18 @@ Description: Unity 8 private libs
233230 This package contains the private libraries for QML and other components
234231 only used by the shell.
235232
233+
234+Package: unity8-schemas
235+Architecture: all
236+Multi-Arch: foreign
237+Depends: ${misc:Depends},
238+Replaces: unity-schemas (>= 7.3.1+14.10.20140915),
239+Breaks: unity-schemas (>= 7.3.1+14.10.20140915),
240+Description: Unity 8 schemas
241+ The Unity 8 shell is the primary user interface for Ubuntu devices.
242+ .
243+ This package contains the configuration schemas used by unity.
244+
236245Package: unity8-doc
237246Section: doc
238247Architecture: all
debian/unity8-common.install−1
@@ -1,4 +1,3 @@
1−usr/share/glib-2.0/schemas
21usr/share/locale
32usr/share/unity8/Components
43usr/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)
236236 return nullptr;
237237
238238 m_asyncRequestedIndex = -1;
239− QObject* object = m_delegateModel->object(modelIndex, asynchronous);
239+ QObject* object = m_delegateModel->object(modelIndex, asynchronous ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
240240 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
241241 if (!item) {
242242 if (object) {
plugins/Dash/listviewwithpageheader.cpp+4−6
@@ -871,7 +871,7 @@ ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIn
871871 return nullptr;
872872
873873 m_asyncRequestedIndex = -1;
874− QObject* object = m_delegateModel->object(modelIndex, asynchronous);
874+ QObject* object = m_delegateModel->object(modelIndex, asynchronous ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
875875 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
876876 if (!item) {
877877 if (object) {
@@ -1141,11 +1141,10 @@ void ListViewWithPageHeader::contentYAnimationRunningChanged(bool running)
11411141 }
11421142}
11431143
1144−/*
1145−void ListViewWithPageHeader::itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry)
1144+void ListViewWithPageHeader::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry)
11461145{
1147− const qreal heightDiff = newGeometry.height() - oldGeometry.height();
1148− if (heightDiff != 0) {
1146+ if (change.heightChange()) {
1147+ const qreal heightDiff = height() - oldGeometry.height();
11491148 if (!m_visibleItems.isEmpty()) {
11501149 ListItem *firstItem = m_visibleItems.first();
11511150 const auto prevFirstItemY = firstItem->y();
@@ -1166,7 +1165,6 @@ void ListViewWithPageHeader::itemGeometryChanged(QQuickItem *item, const QRectF
11661165 m_contentHeightDirty = true;
11671166 }
11681167}
1169−*/
11701168
11711169void ListViewWithPageHeader::itemImplicitHeightChanged(QQuickItem *item)
11721170{
plugins/Dash/listviewwithpageheader.h+1−1
@@ -116,7 +116,7 @@ protected:
116116 void viewportMoved(Qt::Orientations orient) override;
117117 qreal minYExtent() const override;
118118 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;
120120 void itemImplicitHeightChanged(QQuickItem *item) override;
121121 void updatePolish() override;
122122
plugins/Dash/verticaljournal.cpp+6−8
@@ -271,11 +271,9 @@ void VerticalJournal::processModelRemoves(const QVector<QQmlChangeSet::Change> &
271271 }
272272}
273273
274−
275−//void VerticalJournal::itemGeometryChanged(QQuickItem * /*item*/, const QRectF &newGeometry, const QRectF &oldGeometry)
276−//{
277−// const qreal heightDiff = newGeometry.height() - oldGeometry.height();
278−// if (heightDiff != 0) {
279−// relayout();
280−// }
281−//}
274+void VerticalJournal::itemGeometryChanged(QQuickItem * /*item*/, QQuickGeometryChange change, const QRectF &)
275+{
276+ if (change.verticalChange()) {
277+ relayout();
278+ }
279+}
plugins/Dash/verticaljournal.h+1−1
@@ -66,7 +66,7 @@ public:
6666 void setColumnWidth(qreal columnWidth);
6767
6868protected:
69−// void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) override;
69+ void itemGeometryChanged(QQuickItem * /*item*/, QQuickGeometryChange change, const QRectF &oldGeometry) override;
7070
7171Q_SIGNALS:
7272 void columnWidthChanged();
plugins/Ubuntu/CMakeLists.txt+1−1
@@ -1,4 +1,4 @@
11add_subdirectory(Gestures)
22add_subdirectory(DownloadDaemonListener)
3−add_subdirectory(Payments)
3+#add_subdirectory(Payments)
44add_subdirectory(SystemImage)
plugins/Wizard/CMakeLists.txt+1
@@ -10,6 +10,7 @@ add_library(Wizard-qml MODULE
1010 timezonemodel.cpp
1111 Status.cpp
1212 keyboardLayoutsModel.cpp
13+ Changelog.cpp
1314)
1415
1516qt5_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+68−3
@@ -1,4 +1,5 @@
11/*
2+ * Copyright (C) 2018 The UBports project
23 * Copyright (C) 2014-2016 Canonical Ltd.
34 *
45 * This program is free software: you can redistribute it and/or modify it
@@ -46,29 +47,93 @@ QString System::wizardEnabledPath()
4647 return QDir::home().filePath(QStringLiteral(".config/ubuntu-system-settings/wizard-has-run"));
4748}
4849
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+
4968bool System::wizardEnabled() const
5069{
51− return !QFile::exists(wizardEnabledPath());
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+{
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();
52104}
53105
54106void System::setWizardEnabled(bool enabled)
55107{
56− if (wizardEnabled() == enabled)
108+ if (wizardEnabled() == enabled && !isUpdate())
57109 return;
58110
59111 if (enabled) {
60112 QFile::remove(wizardEnabledPath());
61113 } else {
62114 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+ if (!QFile::copy(currentFrameworkPath(), wizardEnabledPath())) {
123+ // Make en empty file if framework does not exist
124+ QFile f(wizardEnabledPath());
125+ f.open(QFile::WriteOnly);
126+ }
64127 m_fsWatcher.addPath(wizardEnabledPath());
65128 Q_EMIT wizardEnabledChanged();
129+ Q_EMIT isUpdateChanged();
66130 }
67131}
68132
69133void System::watcherFileChanged()
70134{
71135 Q_EMIT wizardEnabledChanged();
136+ Q_EMIT isUpdateChanged();
72137 m_fsWatcher.removePath(wizardEnabledPath());
73138}
74139
plugins/Wizard/System.h+17
@@ -1,4 +1,5 @@
11/*
2+ * Copyright (C) 2018 The UBports project
23 * Copyright (C) 2014-2016 Canonical Ltd.
34 *
45 * This program is free software: you can redistribute it and/or modify it
@@ -18,6 +19,7 @@
1819#define WIZARD_SYSTEM_H
1920
2021#include <QFileSystemWatcher>
22+#include <QVersionNumber>
2123#include <QObject>
2224#include <QString>
2325
@@ -25,12 +27,21 @@ class System : public QObject
2527{
2628 Q_OBJECT
2729 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)
2832
2933public:
3034 System();
3135 ~System() = default;
3236
37+ /**
38+ * Checks whether the wizard is enabled for first-run or otherwise.
39+ */
3340 bool wizardEnabled() const;
41+
42+ QString version() const;
43+ bool isUpdate() const;
44+
3445 void setWizardEnabled(bool enabled);
3546
3647public Q_SLOTS:
@@ -42,6 +53,8 @@ public Q_SLOTS:
4253
4354Q_SIGNALS:
4455 void wizardEnabledChanged();
56+ void versionChanged();
57+ void isUpdateChanged();
4558
4659private Q_SLOTS:
4760 void watcherFileChanged();
@@ -50,7 +63,11 @@ private:
5063 Q_DISABLE_COPY(System)
5164
5265 static QString wizardEnabledPath();
66+ static QString currentFrameworkPath();
5367 static void setSessionVariable(const QString &variable, const QString &value);
68+ static QString readCurrentFramework();
69+ static QString readWizardEnabled();
70+ static bool wizardPathExists();
5471
5572 QFileSystemWatcher m_fsWatcher;
5673};
plugins/Wizard/plugin.cpp+2
@@ -20,6 +20,7 @@
2020#include "timezonemodel.h"
2121#include "LocalePlugin.h"
2222#include "Status.h"
23+#include "Changelog.h"
2324#include "keyboardLayoutsModel.h"
2425
2526#include <QtQml/qqml.h>
@@ -30,6 +31,7 @@ void WizardPlugin::registerTypes(const char *uri)
3031 qmlRegisterType<PageList>(uri, 0, 1, "PageList");
3132 qmlRegisterSingletonType<System>(uri, 0, 1, "System", [](QQmlEngine*, QJSEngine*) -> QObject* { return new System; });
3233 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; });
3335 qmlRegisterType<TimeZoneLocationModel>(uri, 0, 1, "TimeZoneModel");
3436 qmlRegisterType<KeyboardLayoutsModel>(uri, 0, 1, "KeyboardLayoutsModel");
3537 qmlRegisterType<LocalePlugin>(uri, 0, 1, "LocalePlugin");
po/unity8.pot+159−84
@@ -8,7 +8,7 @@ msgid ""
88msgstr ""
99"Project-Id-Version: unity8\n"
1010"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"
1212"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1414"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -449,7 +449,7 @@ msgstr ""
449449msgid "Passcode"
450450msgstr ""
451451
452−#: qml/Greeter/LoginList.qml:98
452+#: qml/Greeter/LoginList.qml:98 qml/Wizard/Pages/UpdateDelegate.qml:118
453453msgid "Retry"
454454msgstr ""
455455
@@ -517,6 +517,7 @@ msgid "In queue…"
517517msgstr ""
518518
519519#: qml/Panel/Indicators/MenuItemFactory.qml:999
520+#: qml/Wizard/Pages/UpdateDelegate.qml:226
520521msgid "Downloading"
521522msgstr ""
522523
@@ -576,25 +577,43 @@ msgstr ""
576577msgid "Swipe from the top edge to access notifications and quick settings"
577578msgstr ""
578579
579−#: qml/Wizard/Page.qml:54
580+#: qml/Wizard/Page.qml:59
580581msgctxt "Button: Go back one page in the Wizard"
581582msgid "Back"
582583msgstr ""
583584
584−#: qml/Wizard/Pages/10-welcome.qml:28
585+#: qml/Wizard/Pages/10-welcome.qml:29
585586msgid "Language"
586587msgstr ""
587588
588−#: qml/Wizard/Pages/10-welcome.qml:173 qml/Wizard/Pages/20-keyboard.qml:152
589−#: qml/Wizard/Pages/30-wifi.qml:207 qml/Wizard/Pages/40-location.qml:271
590−#: qml/Wizard/Pages/50-timezone.qml:271 qml/Wizard/Pages/60-account.qml:65
591−#: qml/Wizard/Pages/70-passwd-type.qml:145
592−#: qml/Wizard/Pages/75-report-check.qml:84
589+#: qml/Wizard/Pages/10-welcome.qml:175
590+#: qml/Wizard/Pages/10-welcome-update.qml:126
591+#: qml/Wizard/Pages/11-changelog.qml:74 qml/Wizard/Pages/20-keyboard.qml:152
592+#: qml/Wizard/Pages/30-wifi.qml:208 qml/Wizard/Pages/50-timezone.qml:272
593+#: qml/Wizard/Pages/60-account.qml:66 qml/Wizard/Pages/70-passwd-type.qml:146
594+#: qml/Wizard/Pages/75-report-check.qml:85
595+#: qml/Wizard/Pages/76-app-update.qml:236
593596#: qml/Wizard/Pages/passcode-desktop.qml:142
594597#: qml/Wizard/Pages/password-set.qml:142
595598msgid "Next"
596599msgstr ""
597600
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+
598617#: qml/Wizard/Pages/20-keyboard.qml:31
599618msgid "Select Keyboard"
600619msgstr ""
@@ -607,9 +626,9 @@ msgstr ""
607626msgid "Keyboard layout"
608627msgstr ""
609628
610−#: qml/Wizard/Pages/20-keyboard.qml:152 qml/Wizard/Pages/30-wifi.qml:207
611−#: qml/Wizard/Pages/60-account.qml:65 qml/Wizard/Pages/77-system-update.qml:152
612−#: qml/Wizard/Pages/sim.qml:101
629+#: qml/Wizard/Pages/20-keyboard.qml:152 qml/Wizard/Pages/30-wifi.qml:208
630+#: qml/Wizard/Pages/60-account.qml:66 qml/Wizard/Pages/76-app-update.qml:240
631+#: qml/Wizard/Pages/79-system-update.qml:152 qml/Wizard/Pages/sim.qml:101
613632msgid "Skip"
614633msgstr ""
615634
@@ -617,55 +636,23 @@ msgstr ""
617636msgid "Connect to Wi‑Fi"
618637msgstr ""
619638
620−#: qml/Wizard/Pages/30-wifi.qml:132
639+#: qml/Wizard/Pages/30-wifi.qml:133
621640msgid "Connected"
622641msgstr ""
623642
624−#: qml/Wizard/Pages/30-wifi.qml:165
643+#: qml/Wizard/Pages/30-wifi.qml:166
625644msgid "Available Wi-Fi networks"
626645msgstr ""
627646
628−#: qml/Wizard/Pages/30-wifi.qml:166
647+#: qml/Wizard/Pages/30-wifi.qml:167
629648msgid "No available Wi-Fi networks"
630649msgstr ""
631650
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−
664651#: qml/Wizard/Pages/50-timezone.qml:30
665652msgid "Time Zone"
666653msgstr ""
667654
668−#: qml/Wizard/Pages/50-timezone.qml:182
655+#: qml/Wizard/Pages/50-timezone.qml:183
669656msgid "Enter your city"
670657msgstr ""
671658
@@ -673,7 +660,7 @@ msgstr ""
673660msgid "Personalize Your Device"
674661msgstr ""
675662
676−#: qml/Wizard/Pages/60-account.qml:48
663+#: qml/Wizard/Pages/60-account.qml:49
677664msgid "Preferred Name"
678665msgstr ""
679666
@@ -681,22 +668,22 @@ msgstr ""
681668msgid "Lock Screen"
682669msgstr ""
683670
684−#: qml/Wizard/Pages/70-passwd-type.qml:102
671+#: qml/Wizard/Pages/70-passwd-type.qml:103
685672msgctxt "Label: Type of security method"
686673msgid "Create new password"
687674msgstr ""
688675
689−#: qml/Wizard/Pages/70-passwd-type.qml:104
676+#: qml/Wizard/Pages/70-passwd-type.qml:105
690677msgctxt "Label: Type of security method"
691678msgid "Create passcode (numbers only)"
692679msgstr ""
693680
694−#: qml/Wizard/Pages/70-passwd-type.qml:106
681+#: qml/Wizard/Pages/70-passwd-type.qml:107
695682msgctxt "Label: Type of security method"
696683msgid "No lock code"
697684msgstr ""
698685
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
700687msgid "Privacy Policy"
701688msgstr ""
702689
@@ -704,83 +691,109 @@ msgstr ""
704691msgid "Help Us Improve"
705692msgstr ""
706693
707−#: qml/Wizard/Pages/75-report-check.qml:59
694+#: qml/Wizard/Pages/75-report-check.qml:60
708695msgid "Improve system performance by sending us crashes and error reports."
709696msgstr ""
710697
711−#: qml/Wizard/Pages/75-report-check.qml:60
698+#: qml/Wizard/Pages/75-report-check.qml:61
712699msgid "Privacy policy"
713700msgstr ""
714701
715−#: qml/Wizard/Pages/77-system-update.qml:28
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+
727+#: qml/Wizard/Pages/79-system-update.qml:28
716728msgid "Update Device"
717729msgstr ""
718730
719−#: qml/Wizard/Pages/77-system-update.qml:55
731+#: qml/Wizard/Pages/79-system-update.qml:55
720732msgid ""
721733"There is a system update available and ready to install. Afterwards, the "
722734"device will automatically restart."
723735msgstr ""
724736
725−#: qml/Wizard/Pages/77-system-update.qml:76
737+#: qml/Wizard/Pages/79-system-update.qml:76
726738msgctxt "string identifying name of the update"
727739msgid "Ubuntu system"
728740msgstr ""
729741
730−#: qml/Wizard/Pages/77-system-update.qml:83
742+#: qml/Wizard/Pages/79-system-update.qml:83
731743#, qt-format
732744msgctxt "version of the system update"
733745msgid "Version %1"
734746msgstr ""
735747
736−#: qml/Wizard/Pages/77-system-update.qml:102
748+#: qml/Wizard/Pages/79-system-update.qml:102
737749msgid "This could take a few minutes..."
738750msgstr ""
739751
740−#: qml/Wizard/Pages/77-system-update.qml:116
752+#: qml/Wizard/Pages/79-system-update.qml:116
741753msgid "Install and restart now"
742754msgstr ""
743755
744−#: qml/Wizard/Pages/80-finished.qml:89
745−msgid "Welcome to Ubuntu"
756+#: qml/Wizard/Pages/80-finished.qml:91
757+msgid "Welcome Back"
746758msgstr ""
747759
748−#: qml/Wizard/Pages/80-finished.qml:104
749−msgid "You are ready to use your device now"
760+#: qml/Wizard/Pages/80-finished.qml:91
761+msgid "Welcome to Ubuntu"
750762msgstr ""
751763
752−#: qml/Wizard/Pages/80-finished.qml:124
753−msgid "Get Started"
764+#: qml/Wizard/Pages/80-finished.qml:106
765+msgid "You are ready to use your device now"
754766msgstr ""
755767
756−#: qml/Wizard/Pages/here-terms.qml:25
757−msgid "Terms & Conditions"
768+#: qml/Wizard/Pages/80-finished.qml:126
769+msgid "Continue"
758770msgstr ""
759771
760−#: qml/Wizard/Pages/here-terms.qml:69
761−msgid "Your device uses positioning technologies provided by HERE."
772+#: qml/Wizard/Pages/80-finished.qml:126
773+msgid "Get Started"
762774msgstr ""
763775
764−#: qml/Wizard/Pages/here-terms.qml:81
765−msgid ""
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."
776+#: qml/Wizard/Pages/DownloadHandler.qml:174
777+msgid "Installation failed"
769778msgstr ""
770779
771−#: qml/Wizard/Pages/here-terms.qml:93
772−msgid ""
773−"The information collected is used to analyze the service and to improve the "
774−"use of service, but not to identify you personally."
780+#: qml/Wizard/Pages/GlobalUpdateControls.qml:84
781+msgid "Checking for updates…"
775782msgstr ""
776783
777−#: qml/Wizard/Pages/here-terms.qml:106
784+#: qml/Wizard/Pages/GlobalUpdateControls.qml:109
778785#, 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…"
780793msgstr ""
781794
782−#: qml/Wizard/Pages/here-terms.qml:107
783−msgid "Service Terms"
795+#: qml/Wizard/Pages/GlobalUpdateControls.qml:121
796+msgid "Update all"
784797msgstr ""
785798
786799#: qml/Wizard/Pages/passcode-confirm.qml:43
@@ -866,6 +879,68 @@ msgstr ""
866879msgid "To proceed with no SIM tap Skip."
867880msgstr ""
868881
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+
869944#: qml/Wizard/PasswordMeter.qml:87
870945msgid "Password too short"
871946msgstr ""
qml/Dash/DashBackground.qml+1−1
@@ -31,6 +31,6 @@ Rectangle {
3131 source: AccountsService.backgroundFile
3232 anchors.fill: parent
3333 fillMode: Image.PreserveAspectCrop
34− opacity: 0.6
34+ opacity: settings.backgroundOpacity
3535 }
3636}
qml/Dash/Previews/PreviewWidgetFactory.qml−1
@@ -67,7 +67,6 @@ Loader {
6767 case "icon-actions": return "PreviewIconActions.qml";
6868 case "image": return "PreviewZoomableImage.qml";
6969 case "progress": return "PreviewProgress.qml";
70− case "payments": return "PreviewPayments.qml";
7170 case "rating-input": return "PreviewRatingInput.qml";
7271 case "rating-edit": return "PreviewRatingEdit.qml";
7372 case "reviews": return "PreviewRatingDisplay.qml";
qml/Shell.qml+2−1
@@ -1,4 +1,5 @@
11/*
2+ * Copyright (C) 2018 The UBports project
23 * Copyright (C) 2013-2016 Canonical, Ltd.
34 *
45 * This program is free software; you can redistribute it and/or modify
@@ -346,7 +347,7 @@ StyledItem {
346347 hides: [launcher, panel.indicators]
347348 tabletMode: shell.usageScenario != "phone"
348349 launcherOffset: launcher.progress
349− forcedUnlock: wizard.active || shell.mode === "full-shell"
350+ forcedUnlock: wizard.active && !wizard.isUpdate || shell.mode === "full-shell"
350351 background: wallpaperResolver.cachedBackground
351352 hasCustomBackground: wallpaperResolver.hasCustomBackground
352353 allowFingerprint: !dialogs.hasActiveDialog &&
qml/Stage/Stage.qml+8−2
@@ -1726,11 +1726,12 @@ FocusScope {
17261726
17271727 property int scrollAreaWidth: width / 3
17281728 property bool progressiveScrollingEnabled: false
1729+ property bool wasTouchPress: false
17291730
17301731 onMouseXChanged: {
17311732 mouse.accepted = false
17321733
1733− if (hoverMouseArea.pressed) {
1734+ if (hoverMouseArea.pressed || wasTouchPress) {
17341735 return;
17351736 }
17361737
@@ -1766,7 +1767,12 @@ FocusScope {
17661767 }
17671768 }
17681769
1769− onPressed: mouse.accepted = false
1770+ onPressed: {
1771+ mouse.accepted = false;
1772+ wasTouchPress = mouse.source === Qt.MouseEventSynthesizedByQt;
1773+ }
1774+
1775+ onExited: wasTouchPress = false;
17701776 }
17711777
17721778 FloatingFlickable {
qml/Stage/WindowResizeArea.qml+4−1
@@ -101,7 +101,10 @@ MouseArea {
101101 state = WindowStateStorage.WindowStateNormal;
102102 }
103103 windowStateStorage.saveState(root.windowId, state & ~WindowStateStorage.WindowStateMinimized); // clear the minimized bit when saving
104− windowStateStorage.saveGeometry(root.windowId, Qt.rect(priv.normalX, priv.normalY, priv.normalWidth, priv.normalHeight));
104+ // do not store window sizes if they are zero. this happens in staged mode
105+ if ( priv.normalWidth && priv.normalHeight ) {
106+ windowStateStorage.saveGeometry(root.windowId, Qt.rect(priv.normalX, priv.normalY, priv.normalWidth, priv.normalHeight));
107+ }
105108 }
106109
107110 QtObject {
qml/Wizard/Components/InputMethod.qml+9−9
@@ -21,19 +21,19 @@ import Ubuntu.Components 0.1
2121// TODO: try to share this code with that from the unity8 shell
2222
2323Item {
24− id: root
24+ id: inputMethodRoot
2525
2626 Connections {
2727 target: SurfaceManager
2828 onSurfaceCreated: {
2929 if (surface.type == MirSurfaceItem.InputMethod) {
30− root.surface = surface;
30+ inputMethodRoot.surface = surface;
3131 }
3232 }
3333
3434 onSurfaceDestroyed: {
35− if (root.surface == surface) {
36− root.surface = null;
35+ if (inputMethodRoot.surface == surface) {
36+ inputMethodRoot.surface = null;
3737 surface.parent = null;
3838 }
3939 if (!surface.parent) {
@@ -71,7 +71,7 @@ Item {
7171 visible: false
7272 // half-way down because the vkb occupies only the lower half of the surface
7373 // TODO: consider keyboard rotation
74− y: root.parent.height / 2.0
74+ y: inputMethodRoot.parent.height / 2.0
7575 }
7676 }
7777 ]
@@ -89,17 +89,17 @@ Item {
8989 ignoreUnknownSignals: true // don't wanna spam the log when surface is null
9090 onStateChanged: {
9191 if (state == MirSurfaceItem.Minimized) {
92− root.hide();
92+ inputMethodRoot.hide();
9393 } else if (state == MirSurfaceItem.Maximized) {
94− root.show();
94+ inputMethodRoot.show();
9595 }
9696 }
9797 }
9898
9999 onSurfaceChanged: {
100100 if (surface) {
101− surface.parent = root;
102− surface.anchors.fill = root;
101+ surface.parent = inputMethodRoot;
102+ surface.anchors.fill = inputMethodRoot;
103103 }
104104 }
105105
qml/Wizard/Page.qml+5
@@ -1,4 +1,5 @@
11/*
2+ * Copyright (C) 2018 The UBports project
23 * Copyright (C) 2013-2016 Canonical, Ltd.
34 *
45 * This program is free software; you can redistribute it and/or modify
@@ -50,6 +51,10 @@ Item {
5051 property bool skipValid: true
5152 property bool skip: false
5253
54+ // Marks if should be only shown if update or install
55+ property bool onlyOnUpdate: false
56+ property bool onlyOnInstall: false
57+
5358 property bool hasBackButton: true
5459 property string backButtonText: i18n.ctr("Button: Go back one page in the Wizard", "Back")
5560 property bool customBack: false
qml/Wizard/Pages.qml+48−13
@@ -1,4 +1,5 @@
11/*
2+ * Copyright (C) 2018 The UBports project
23 * Copyright (C) 2013-2016 Canonical, Ltd.
34 *
45 * This program is free software; you can redistribute it and/or modify
@@ -18,7 +19,6 @@ import QtQuick 2.4
1819import MeeGo.QOfono 0.2
1920import Ubuntu.Components 1.3
2021import Ubuntu.SystemSettings.SecurityPrivacy 1.0
21−import Ubuntu.SystemSettings.Diagnostics 1.0
2222import Wizard 0.1
2323import "../Components"
2424
@@ -49,11 +49,6 @@ StyledItem {
4949 objectName: "securityPrivacy"
5050 }
5151
52− UbuntuDiagnostics {
53− id: diagnostics
54− objectName: "diagnostics"
55− }
56−
5752 OfonoManager { // need it here for the language and country detection
5853 id: modemManager
5954 readonly property bool gotSimCard: available && ((simManager0.ready && simManager0.present) || (simManager1.ready && simManager1.present))
@@ -105,6 +100,37 @@ StyledItem {
105100 id: pageList
106101 }
107102
103+ ActivityIndicator {
104+ id: pagesSpinner
105+ anchors.centerIn: parent
106+ z: 100
107+ running: false
108+ visible: running
109+
110+ NumberAnimation on opacity {
111+ id: fadeInAnimation
112+ from: 0
113+ to: 1
114+ duration: 200
115+ }
116+
117+ onVisibleChanged: {
118+ if (visible) {
119+ opacity = 0;
120+ fadeInAnimation.start();
121+ }
122+ }
123+ }
124+
125+ Timer {
126+ id: impatientLoadingTimer
127+ interval: 1700
128+ onTriggered: {
129+ console.warn("Impatient timer going off. Fix the wizard, it's too slow at skipping pages.")
130+ pagesSpinner.running = true;
131+ }
132+ }
133+
108134 PageStack {
109135 id: pageStack
110136 objectName: "pageStack"
@@ -139,18 +165,21 @@ StyledItem {
139165
140166 function load(path) {
141167 if (currentPage) {
142− currentPage.enabled = false
168+ currentPage.enabled = false;
143169 }
144170
145171 // First load it invisible, check that we should actually use
146172 // this page, and either skip it or continue.
147− push(path, {"opacity": 0, "enabled": false})
173+ push(path, {"opacity": 0, "enabled": false});
148174
149175 timeout.restart();
176+ impatientLoadingTimer.start();
177+
178+ console.info("Loading page " + currentPage.objectName);
150179
151180 // Check for immediate skip or not. We may have to wait for
152181 // skipValid to be assigned (see Connections object below)
153− checkSkip()
182+ checkSkip();
154183
155184 var isPrimaryPage = !currentPage.customTitle;
156185 if (isPrimaryPage) {
@@ -162,13 +191,19 @@ StyledItem {
162191
163192 function checkSkip() {
164193 if (!currentPage) { // may have had a parse error
165− next()
194+ console.warn("Wizard page skipped due to possible parse error.");
195+ next();
166196 } else if (currentPage.skipValid) {
167197 if (currentPage.skip) {
168− next()
198+ next();
199+ } else if ((currentPage.onlyOnUpdate && !wizard.isUpdate) ||
200+ (currentPage.onlyOnInstall && wizard.isUpdate)) {
201+ next();
169202 } else {
170− currentPage.opacity = 1
171− currentPage.enabled = true
203+ impatientLoadingTimer.stop()
204+ pagesSpinner.running = false;
205+ currentPage.opacity = 1;
206+ currentPage.enabled = true;
172207 timeout.stop();
173208 }
174209 }
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 @@
11/*
2+ * Copyright (C) 2018 The UBports project
23 * Copyright (C) 2013-2016 Canonical, Ltd.
34 *
45 * This program is free software; you can redistribute it and/or modify
@@ -27,6 +28,7 @@ LocalComponents.Page {
2728
2829 title: i18n.tr("Language")
2930 forwardButtonSourceComponent: forwardButton
31+ onlyOnInstall: true
3032
3133 UbuntuLanguagePlugin {
3234 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 {
3232 forwardButtonSourceComponent: forwardButton
3333
3434 readonly property bool connected: Connectivity.online
35+ skip: connected
3536
3637 function getExtendedProperty(object, propertyName, defaultValue) {
3738 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 {
3636
3737 // for testing
3838 readonly property alias tdModule: timeDatePanel
39+ onlyOnInstall: true
3940
4041 function highlightTimezone(offset) {
4142 highlightImage.source = "data/timezonemap/timezone_" + offset + ".png";
qml/Wizard/Pages/60-account.qml+11−10
@@ -24,10 +24,15 @@ LocalComponents.Page {
2424 title: i18n.tr("Personalize Your Device")
2525
2626 forwardButtonSourceComponent: forwardButton
27+ onlyOnInstall: true
2728
28− QtObject {
29− id: d
30− readonly property string validName: nameInput.text.trim()
29+ readonly property string validName: nameInput.text.trim()
30+
31+ function saveNameAndGoNext() {
32+ if (validName) {
33+ AccountsService.realName = validName;
34+ }
35+ pageStack.next();
3136 }
3237
3338 Column {
@@ -56,19 +61,15 @@ LocalComponents.Page {
5661 anchors.left: parent.left
5762 anchors.right: parent.right
5863 inputMethodHints: Qt.ImhNoPredictiveText
64+ onAccepted: saveNameAndGoNext()
5965 }
6066 }
6167
6268 Component {
6369 id: forwardButton
6470 LocalComponents.StackButton {
65− text: d.validName ? i18n.tr("Next") : i18n.tr("Skip")
66− onClicked: {
67− if (d.validName) {
68− AccountsService.realName = d.validName;
69− }
70− pageStack.next();
71− }
71+ text: validName ? i18n.tr("Next") : i18n.tr("Skip")
72+ onClicked: saveNameAndGoNext()
7273 }
7374 }
7475}
qml/Wizard/Pages/70-passwd-type.qml+1
@@ -44,6 +44,7 @@ LocalComponents.Page {
4444 // or this isn't the first time the wizard has been run, etc). We can't
4545 // properly set the password again, so let's not pretend we can.
4646 skip: securityPrivacy.securityType !== UbuntuSecurityPrivacyPanel.Swipe
47+ onlyOnInstall: true
4748
4849 function indexToMethod(index) {
4950 if (index === 0/* || index === 1*/)
qml/Wizard/Pages/75-report-check.qmldeleted−91
@@ -1,91 +0,0 @@
1−/*
2− * Copyright (C) 2015-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− id: reportingPage
24− objectName: "reportingPage"
25−
26− title: webview.visible ? i18n.tr("Privacy Policy") : i18n.tr("Help Us Improve")
27− forwardButtonSourceComponent: !webview.visible ? forwardButton : null
28− customBack: true
29− customTitle: webview.visible
30−
31− skip: !diagnostics.reportCrashes // skip the page when the system is configured not to report crashes
32−
33− onBackClicked: {
34− if (webview.visible) {
35− webview.visible = false;
36− } else {
37− pageStack.prev();
38− }
39− }
40−
41− Column {
42− id: column
43− anchors {
44− fill: content
45− leftMargin: leftMargin
46− rightMargin: rightMargin
47− topMargin: customMargin
48− }
49−
50− LocalComponents.CheckableSetting {
51− anchors {
52− left: parent.left
53− right: parent.right
54− }
55−
56− id: reportCheck
57− objectName: "reportCheck"
58− showDivider: false
59− text: i18n.tr("Improve system performance by sending us crashes and error reports.") + "<br><br><a href='#'>" +
60− i18n.tr("Privacy policy") + "</a>"
61− checked: diagnostics.reportCrashes
62− visible: !webview.visible
63− onLinkActivated: {
64− webview.url = "http://www.ubuntu.com/legal/terms-and-policies/privacy-policy";
65− webview.visible = true;
66− }
67− }
68−
69− WebView {
70− id: webview
71− objectName: "webview"
72− anchors.left: parent.left
73− anchors.right: parent.right
74− anchors.leftMargin: -leftMargin
75− anchors.rightMargin: -rightMargin
76− height: parent.height
77− visible: false
78− }
79− }
80−
81− Component {
82− id: forwardButton
83− LocalComponents.StackButton {
84− text: i18n.tr("Next")
85− onClicked: {
86− diagnostics.setReportCrashes(reportCheck.checked);
87− pageStack.next();
88− }
89− }
90− }
91−}
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 @@
11/*
2+ * Copyright (C) 2018 The UBports project
23 * Copyright (C) 2013-2016 Canonical, Ltd.
34 *
45 * This program is free software; you can redistribute it and/or modify
@@ -16,6 +17,7 @@
1617
1718import QtQuick 2.4
1819import Ubuntu.Components 1.3
20+import Wizard 0.1
1921import ".." as LocalComponents
2022
2123LocalComponents.Page {
@@ -86,7 +88,7 @@ LocalComponents.Page {
8688 fontSize: "x-large"
8789 font.weight: Font.Light
8890 lineHeight: 1.2
89− text: i18n.tr("Welcome to Ubuntu")
91+ text: (System.isUpdate) ? i18n.tr("Welcome Back") : i18n.tr("Welcome to Ubuntu")
9092 color: whiteColor
9193 }
9294
@@ -121,7 +123,7 @@ LocalComponents.Page {
121123 Label {
122124 id: buttonLabel
123125 color: whiteColor
124− text: i18n.tr("Get Started")
126+ text: (System.isUpdate) ? i18n.tr("Continue") : i18n.tr("Get Started")
125127 fontSize: "medium"
126128 anchors.centerIn: parent
127129 }
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/Pages/passcode-desktop.qml+13−5
@@ -33,6 +33,12 @@ LocalComponents.Page {
3333
3434 readonly property alias password: passwordField.text
3535 readonly property alias password2: password2Field.text
36+ readonly property bool passwordsMatching: password != "" && password == password2
37+
38+ function savePasswordAndGoNext() {
39+ root.password = password;
40+ pageStack.next();
41+ }
3642
3743 Flickable {
3844 id: column
@@ -105,6 +111,11 @@ LocalComponents.Page {
105111 inputMethodHints: Qt.ImhDigitsOnly
106112 validator: RegExpValidator { regExp: /^\d{4}$/ }
107113 maximumLength: 4
114+ onAccepted: {
115+ if (passwordsMatching) {
116+ savePasswordAndGoNext();
117+ }
118+ }
108119 onActiveFocusChanged: {
109120 if (activeFocus) {
110121 column.contentY = y
@@ -140,11 +151,8 @@ LocalComponents.Page {
140151 id: forwardButton
141152 LocalComponents.StackButton {
142153 text: i18n.tr("Next")
143− enabled: password != "" && password == password2
144− onClicked: {
145− root.password = password;
146− pageStack.next();
147− }
154+ enabled: passwordsMatching
155+ onClicked: savePasswordAndGoNext()
148156 }
149157 }
150158}
qml/Wizard/Pages/password-set.qml+11−4
@@ -35,6 +35,11 @@ LocalComponents.Page {
3535 readonly property alias password2: password2Field.text
3636 readonly property bool passwordsMatching: password == password2 && password.trim().length > 7
3737
38+ function savePasswordAndGoNext() {
39+ root.password = password;
40+ pageStack.next();
41+ }
42+
3843 Flickable {
3944 id: column
4045 clip: true
@@ -114,6 +119,11 @@ LocalComponents.Page {
114119 id: password2Field
115120 objectName: "password2Field"
116121 echoMode: TextInput.Password
122+ onAccepted: {
123+ if (passwordsMatching) {
124+ savePasswordAndGoNext();
125+ }
126+ }
117127 onActiveFocusChanged: {
118128 if (activeFocus) {
119129 column.contentY = pass2Label.y
@@ -141,10 +151,7 @@ LocalComponents.Page {
141151 LocalComponents.StackButton {
142152 text: i18n.tr("Next")
143153 enabled: passwordsMatching
144− onClicked: {
145− root.password = password;
146− pageStack.next();
147− }
154+ onClicked: savePasswordAndGoNext()
148155 }
149156 }
150157}
qml/Wizard/Wizard.qml+5−2
@@ -1,4 +1,5 @@
11/*
2+ * Copyright (C) 2018 The UBports project
23 * Copyright (C) 2013, 2015 Canonical, Ltd.
34 *
45 * This program is free software; you can redistribute it and/or modify
@@ -20,7 +21,7 @@ import Wizard 0.1
2021import "../Components"
2122
2223Showable {
23− id: root
24+ id: wizard
2425
2526 // This is a bool instead of an alias because Loader classes like to emit
2627 // changed signals for 'active' during startup even if they aren't actually
@@ -29,6 +30,8 @@ Showable {
2930 // expected behavior of no emission on startup.
3031 readonly property bool active: loader.active
3132
33+ property bool isUpdate: System.isUpdate
34+
3235 // The wizard should be run at a later time if, for example, unity8 is
3336 // in greeter mode
3437 property bool deferred: false
@@ -49,7 +52,7 @@ Showable {
4952
5053 Connections {
5154 target: loader.item
52− onQuit: root.hide()
55+ onQuit: wizard.hide()
5356 }
5457 }
5558}
tests/plugins/CMakeLists.txt+1−1
@@ -8,5 +8,5 @@ add_subdirectory(LightDM)
88add_subdirectory(SessionBroadcast)
99add_subdirectory(Ubuntu)
1010add_subdirectory(Unity)
11−#add_subdirectory(Utils) #FIXME broken with qt 5.9
11+add_subdirectory(Utils)
1212add_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,
107107 QCoreApplication::sendEvent(m_view, &touchEvent);
108108
109109 QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(m_view);
110− windowPrivate->flushDelayedTouchEvent();
110+ windowPrivate->flushFrameSynchronousEvents();
111111}
112112
113113void GestureTest::passTime(qint64 timeSpanMs)
tests/plugins/Ubuntu/Gestures/tst_TouchGate.cpp+1−1
@@ -189,7 +189,7 @@ void tst_TouchGate::holdsEventsUntilGainsOwnership()
189189 if (!ownershipAfterTouchEnd) {
190190 touchRegistry->removeCandidateOwnerForTouch(0, candidateItem);
191191 QQuickWindowPrivate *wp = QQuickWindowPrivate::get(testItem->window());
192− wp->flushDelayedTouchEvent();
192+ wp->flushFrameSynchronousEvents();
193193 // TouchGate should now open its flood gates and let testItem get all
194194 // events from touch 0 produced so far
195195 QCOMPARE(testItem->touchEventsReceived.count(), 2);
tests/plugins/Utils/ModelTest.cpp+1−1
@@ -441,7 +441,7 @@ void ModelTest::data()
441441 QVariant textAlignmentVariant = model->data ( model->index ( 0, 0 ), Qt::TextAlignmentRole );
442442 if ( textAlignmentVariant.isValid() ) {
443443 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 ) ));
445445 }
446446
447447 // General Purpose roles that should return a QColor
tests/qmltests/CMakeLists.txt+2−2
@@ -1,5 +1,5 @@
11
2−#add_subdirectory(Components) #FIXME broken with qt 5.9
2+add_subdirectory(Components)
33
44add_unity8_qmltest(. OrientedShell)
55add_unity8_qmltest(. DisabledScreenNotice)
@@ -44,7 +44,7 @@ add_unity8_qmltest(Dash/Previews PreviewIconActions)
4444add_unity8_qmltest(Dash/Previews PreviewImageGallery)
4545add_unity8_qmltest(Dash/Previews PreviewInlineVideo)
4646add_unity8_qmltest(Dash/Previews PreviewMediaToolbar)
47−add_unity8_qmltest(Dash/Previews PreviewPayments)
47+#add_unity8_qmltest(Dash/Previews PreviewPayments)
4848add_unity8_qmltest(Dash/Previews PreviewProgress)
4949add_unity8_qmltest(Dash/Previews PreviewRatingDisplay)
5050add_unity8_qmltest(Dash/Previews PreviewRatingDisplayCreationRanges)
tests/qmltests/Components/tst_DragHandle.cpp+2−2
@@ -177,7 +177,7 @@ void tst_DragHandle::flickAndHold(QQuickItem *dragHandle,
177177 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
178178
179179 QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(m_view);
180− windowPrivate->flushDelayedTouchEvent();
180+ windowPrivate->flushFrameSynchronousEvents();
181181}
182182
183183void 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
192192 m_fakeTimeSource->m_msecsSinceReference += timeStep;
193193 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
194194
195− windowPrivate->flushDelayedTouchEvent();
195+ windowPrivate->flushFrameSynchronousEvents();
196196 }
197197}
198198
tests/qmltests/Wizard/tst_Wizard.qml+1−16
@@ -168,16 +168,13 @@ Item {
168168 return stack.currentPage;
169169 }
170170
171− function goToPage(name, skipSim, skipLocation, skipReporting) {
171+ function goToPage(name, skipSim, skipLocation) {
172172 if (skipSim === undefined) {
173173 skipSim = false;
174174 }
175175 if (skipLocation === undefined) {
176176 skipLocation = false;
177177 }
178− if (skipReporting === undefined) {
179− skipReporting = false;
180− }
181178
182179 var page = waitForPage("languagePage");
183180 if (name === page.objectName) return page;
@@ -222,12 +219,6 @@ Item {
222219 if (name === page.objectName) return page;
223220 tap(findChild(page, "forwardButton"));
224221
225− if (!skipReporting) {
226− page = waitForPage("reportingPage");
227− if (name === page.objectName) return page;
228− tap(findChild(page, "forwardButton"));
229− }
230−
231222 page = waitForPage("finishedPage");
232223 if (name === page.objectName) return page;
233224 waitUntilTransitionsEnd(page);
@@ -334,8 +325,6 @@ Item {
334325 enterPasscode("1111");
335326
336327 // now finish up
337− page = waitForPage("reportingPage");
338− tap(findChild(page, "forwardButton"));
339328 page = waitForPage("systemUpdatePage");
340329 tap(findChild(page, "forwardButton"));
341330 page = waitForPage("finishedPage");
@@ -376,8 +365,6 @@ Item {
376365 tap(continueButton);
377366
378367 // now finish up
379− page = waitForPage("reportingPage");
380− tap(findChild(page, "forwardButton"));
381368 page = waitForPage("systemUpdatePage");
382369 tap(findChild(page, "forwardButton"));
383370 page = waitForPage("finishedPage");
@@ -396,8 +383,6 @@ Item {
396383
397384 // now finish up
398385 tap(findChild(page, "forwardButton"));
399− page = waitForPage("reportingPage");
400− tap(findChild(page, "forwardButton"));
401386 page = waitForPage("systemUpdatePage");
402387 tap(findChild(page, "forwardButton"));
403388 page = waitForPage("finishedPage");
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
2626
2727void TouchEventSequenceWrapper::commit(bool processEvents)
2828{
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−
3329 m_eventSequence.commit(processEvents);
34−
35− if (window) {
36− QQuickWindowPrivate *wp = QQuickWindowPrivate::get(window);
37− wp->flushDelayedTouchEvent();
38− }
3930}
4031
4132void TouchEventSequenceWrapper::move(int touchId, int x, int y)