Unity 8
Pages.qml
1 /*
2  * Copyright (C) 2018 The UBports project
3  * Copyright (C) 2013-2016 Canonical, Ltd.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; version 3.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 import QtQuick 2.12
19 import MeeGo.QOfono 0.2
20 import Ubuntu.Components 1.3
21 import Ubuntu.SystemSettings.SecurityPrivacy 1.0
22 import Ubuntu.SystemSettings.Update 1.0
23 import Ubuntu.Connectivity 1.0
24 import Wizard 0.1
25 import "../Components"
26 
27 StyledItem {
28  id: root
29  objectName: "wizardPages"
30  focus: true
31 
32  signal quit()
33 
34  // These should be set by a security page and we apply the settings when
35  // the user exits the wizard.
36  property int passwordMethod: UbuntuSecurityPrivacyPanel.Passphrase
37  property string password: ""
38 
39  property bool seenSIMPage: false // we want to see the SIM page at most once
40  readonly property bool connected: NetworkingStatus.online
41 
42  property bool checkedForUpdates: false
43  property bool updateDownloaded: false
44 
45  property alias modemManager: modemManager
46  property alias simManager0: simManager0
47  property alias simManager1: simManager1
48 
49  theme: ThemeSettings {
50  name: "Ubuntu.Components.Themes.Ambiance"
51  }
52 
53  UbuntuSecurityPrivacyPanel {
54  id: securityPrivacy
55  objectName: "securityPrivacy"
56  }
57 
58  OfonoManager { // need it here for the language and country detection
59  id: modemManager
60  readonly property bool gotSimCard: available && ((simManager0.ready && simManager0.present) || (simManager1.ready && simManager1.present))
61  property bool ready: false
62  onModemsChanged: {
63  ready = true;
64  }
65  }
66 
67  // Ideally we would query the system more cleverly than hardcoding two
68  // sims. But we don't yet have a more clever way. :(
69  OfonoSimManager {
70  id: simManager0
71  modemPath: modemManager.modems.length >= 1 ? modemManager.modems[0] : ""
72  }
73 
74  OfonoSimManager {
75  id: simManager1
76  modemPath: modemManager.modems.length >= 2 ? modemManager.modems[1] : ""
77  }
78 
79  function checkForUpdatesIfConnected() {
80  if (connected && !checkedForUpdates) {
81  console.info("Wizard: Checking for system-image update");
82  SystemImage.checkForUpdate();
83  checkedForUpdates = true;
84  }
85  }
86 
87  function quitWizard() {
88  pageStack.currentPage.enabled = false;
89 
90  if (password != "") {
91  var errorMsg = securityPrivacy.setSecurity("", password, passwordMethod)
92  if (errorMsg !== "") {
93  // Ignore (but log) any errors, since we're past where the user set
94  // the method. Worst case, we just leave the user with a swipe
95  // security method and they fix it in the system settings.
96  console.log("Wizard: Error setting security method:", errorMsg)
97  }
98  }
99 
100  quit();
101  }
102 
103  MouseArea { // eat anything that gets past widgets
104  anchors.fill: parent
105  }
106 
107  Rectangle {
108  id: background
109  anchors.fill: root
110  color: "#fdfdfd"
111  }
112 
113  PageList {
114  id: pageList
115  }
116 
117  ActivityIndicator {
118  id: pagesSpinner
119  anchors.centerIn: parent
120  z: 100
121  running: false
122  visible: running
123 
124  NumberAnimation on opacity {
125  id: fadeInAnimation
126  from: 0
127  to: 1
128  duration: 200
129  }
130 
131  onVisibleChanged: {
132  if (visible) {
133  opacity = 0;
134  fadeInAnimation.start();
135  }
136  }
137  }
138 
139  onConnectedChanged: {
140  checkForUpdatesIfConnected();
141  }
142 
143  Connections {
144  target: SystemImage
145  onUpdateDownloaded: {
146  console.info("Wizard: A system-image update has been downloaded!")
147  root.updateDownloaded = true;
148  }
149  onCheckingForUpdatesChanged: {
150  if (!SystemImage.checkingForUpdates) {
151  console.info("Wizard: Update check finished")
152  if (SystemImage.updateAvailable) {
153  console.info("Wizard: A system-image update is available!")
154  } else {
155  console.info("Wizard: No update found.")
156  }
157  }
158  }
159  }
160 
161  Timer {
162  id: impatientLoadingTimer
163  interval: 1700
164  onTriggered: {
165  console.warn("Wizard: Impatient timer going off. Fix the wizard, it's too slow at skipping pages.")
166  pagesSpinner.running = true;
167  }
168  }
169 
170  PageStack {
171  id: pageStack
172  objectName: "pageStack"
173  anchors.fill: parent
174 
175  function next() {
176  // If we've opened any extra (non-main) pages, pop them before
177  // continuing so back button returns to the previous main page.
178  while (pageList.index < pageStack.depth - 1)
179  pop();
180  load(pageList.next());
181  }
182 
183  function prev() {
184  var isPrimaryPage = currentPage && !currentPage.customTitle;
185  if (pageList.index >= pageStack.depth - 1) {
186  pageList.prev(); // update pageList.index, but not for extra pages
187  }
188  pop()
189  if (!currentPage || currentPage.opacity === 0) { // undo skipped pages
190  prev();
191  } else {
192  currentPage.enabled = true;
193  }
194 
195  if (isPrimaryPage) {
196  currentPage.aboutToShow(UbuntuAnimation.BriskDuration, Qt.LeftToRight);
197  } else {
198  currentPage.aboutToShowSecondary(UbuntuAnimation.BriskDuration);
199  }
200  }
201 
202  function load(path) {
203  if (currentPage) {
204  currentPage.enabled = false;
205  }
206 
207  // First load it invisible, check that we should actually use
208  // this page, and either skip it or continue.
209  push(path, {"opacity": 0, "enabled": false});
210 
211  timeout.restart();
212  impatientLoadingTimer.start();
213 
214  console.info("Wizard: Loading page " + currentPage.objectName);
215 
216  // Check for immediate skip or not. We may have to wait for
217  // skipValid to be assigned (see Connections object below)
218  checkSkip();
219 
220  var isPrimaryPage = !currentPage.customTitle;
221  if (isPrimaryPage) {
222  currentPage.aboutToShow(UbuntuAnimation.BriskDuration, Qt.RightToLeft);
223  } else {
224  currentPage.aboutToShowSecondary(UbuntuAnimation.BriskDuration);
225  }
226  }
227 
228  function checkSkip() {
229  if (!currentPage) { // may have had a parse error
230  console.warn("Wizard: page skipped due to possible parse error.");
231  next();
232  } else if (currentPage.skipValid) {
233  if (currentPage.skip) {
234  next();
235  } else if ((currentPage.onlyOnUpdate && !wizard.isUpdate) ||
236  (currentPage.onlyOnInstall && wizard.isUpdate)) {
237  next();
238  } else {
239  impatientLoadingTimer.stop()
240  pagesSpinner.running = false;
241  currentPage.opacity = 1;
242  currentPage.enabled = true;
243  timeout.stop();
244  }
245  }
246  }
247 
248  Timer {
249  id: timeout
250  objectName: "timeout"
251  interval: 2000 // wizard pages shouldn't take long
252  onTriggered: {
253  console.warn("Wizard: Page " + pageStack.currentPage.objectName + " skipped due to taking too long!!!");
254  pageStack.currentPage.skip = true;
255  pageStack.currentPage.skipValid = true;
256  }
257  }
258 
259  Connections {
260  target: pageStack.currentPage
261  onSkipValidChanged: pageStack.checkSkip()
262  }
263 
264  Component.onCompleted: {
265  checkForUpdatesIfConnected();
266  next();
267  }
268  }
269 }