@@ -0,0 +1,246 @@
1+/*
2+ * Copyright (C) 2013 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.3
18+import GSettings 1.0
19+import Ubuntu.Components 1.1
20+import Ubuntu.SystemSettings.SecurityPrivacy 1.0
21+import Unity.Application 0.1
22+import Unity.Notifications 1.0 as NotificationBackend
23+import Unity.Session 0.1
24+import "Components"
25+import "file:///usr/share/unity8/Notifications" as Notifications // FIXME This should become a module or go away
26+import "file:///usr/share/unity8/Components" as UnityComponents
27+
28+Item {
29+ id: root
30+ width: units.gu(40)
31+ height: units.gu(71)
32+ focus: true
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.Passcode
37+ property string password: ""
38+
39+ Component.onCompleted: {
40+ Theme.name = "Ubuntu.Components.Themes.SuruGradient"
41+ // A visible selected background looks bad in ListItem widgets with our theme
42+ Theme.palette.selected.background = "#00000000"
43+ i18n.domain = "unity8"
44+ }
45+
46+ UbuntuSecurityPrivacyPanel {
47+ id: securityPrivacy
48+ }
49+
50+ function quitWizard() {
51+ // Immediately go to black to give quick feedback
52+ blackCover.visible = true
53+
54+ var errorMsg = securityPrivacy.setSecurity("", password, passwordMethod)
55+ if (errorMsg !== "") {
56+ // Ignore (but log) any errors, since we're past where the user set
57+ // the method. Worst case, we just leave the user with a swipe
58+ // security method and they fix it in the system settings.
59+ console.log("Error setting security method:", errorMsg)
60+ }
61+
62+ Qt.quit()
63+ }
64+
65+ // This is just a little screen to immediately go to black once the wizard
66+ // is done, to give quick feedback to the user.
67+ Rectangle {
68+ id: blackCover
69+ color: "#000000"
70+ anchors.fill: parent
71+ z: 1
72+ visible: false
73+ }
74+
75+ MainView {
76+ anchors.fill: parent
77+ headerColor: "#57365E"
78+ backgroundColor: "#A55263"
79+ footerColor: "#D75669"
80+ anchorToKeyboard: true
81+ useDeprecatedToolbar: false
82+
83+ GSettings {
84+ id: background
85+ schema.id: "org.gnome.desktop.background"
86+ }
87+
88+ Image {
89+ id: image
90+ // Use x/y/height/width instead of anchors so that we don't adjust
91+ // the image when the OSK appears.
92+ x: 0
93+ y: 0
94+ height: root.height
95+ width: root.width
96+ source: background.pictureUri
97+ fillMode: Image.PreserveAspectCrop
98+ visible: status === Image.Ready
99+ }
100+
101+ PageStack {
102+ id: pageStack
103+
104+ function next() {
105+ // If we've opened any extra (non-main) pages, pop them before
106+ // continuing so back button returns to the previous main page.
107+ while (pageList.index < pageStack.depth - 1)
108+ pop()
109+ load(pageList.next())
110+ }
111+
112+ function prev() {
113+ if (pageList.index >= pageStack.depth - 1)
114+ pageList.prev() // update pageList.index, but not for extra pages
115+ pop()
116+ if (!currentPage || currentPage.opacity === 0) { // undo skipped pages
117+ prev()
118+ } else {
119+ currentPage.enabled = true
120+ }
121+ }
122+
123+ function load(path) {
124+ if (currentPage) {
125+ currentPage.enabled = false
126+ }
127+
128+ // First load it invisible, check that we should actually use
129+ // this page, and either skip it or continue.
130+ push(path, {"opacity": 0, "enabled": false})
131+
132+ // Check for immediate skip or not. We may have to wait for
133+ // skipValid to be assigned (see Connections object below)
134+ _checkSkip()
135+ }
136+
137+ function _checkSkip() {
138+ if (!currentPage) { // may have had a parse error
139+ next()
140+ } else if (currentPage.skipValid) {
141+ if (currentPage.skip) {
142+ next()
143+ } else {
144+ currentPage.opacity = 1
145+ currentPage.enabled = true
146+ }
147+ }
148+ }
149+
150+ Connections {
151+ target: pageStack.currentPage
152+ onSkipValidChanged: pageStack._checkSkip()
153+ }
154+
155+ Component.onCompleted: next()
156+ }
157+ }
158+
159+ Rectangle {
160+ id: modalNotificationBackground
161+ visible: notifications.useModal && (notifications.state == "narrow")
162+ anchors.fill: parent
163+ color: "#80000000"
164+
165+ MouseArea {
166+ anchors.fill: parent
167+ }
168+ }
169+
170+ InputMethod {
171+ anchors.fill: parent
172+ }
173+
174+ Notifications.Notifications {
175+ id: notifications
176+ model: NotificationBackend.Model
177+ margin: units.gu(1)
178+ anchors {
179+ top: parent.top
180+ right: parent.right
181+ bottom: parent.bottom
182+ }
183+ states: [
184+ State {
185+ name: "narrow"
186+ when: parent.width <= units.gu(60)
187+ AnchorChanges { target: notifications; anchors.left: parent.left }
188+ },
189+ State {
190+ name: "wide"
191+ when: parent.width > units.gu(60)
192+ AnchorChanges { target: notifications; anchors.left: undefined }
193+ PropertyChanges { target: notifications; width: units.gu(38) }
194+ }
195+ ]
196+ }
197+
198+ UnityComponents.Dialogs {
199+ id: dialogs
200+ anchors.fill: parent
201+ z: 10
202+ onPowerOffClicked: {
203+ shutdownFadeOutRectangle.enabled = true;
204+ shutdownFadeOutRectangle.visible = true;
205+ shutdownFadeOut.start();
206+ }
207+ }
208+
209+ Rectangle {
210+ id: shutdownFadeOutRectangle
211+ z: dialogs.z + 10
212+ enabled: false
213+ visible: false
214+ color: "black"
215+ anchors.fill: parent
216+ opacity: 0.0
217+ NumberAnimation on opacity {
218+ id: shutdownFadeOut
219+ from: 0.0
220+ to: 1.0
221+ onStopped: {
222+ if (shutdownFadeOutRectangle.enabled && shutdownFadeOutRectangle.visible) {
223+ DBusUnitySessionService.Shutdown();
224+ }
225+ }
226+ }
227+ }
228+
229+ Keys.onPressed: {
230+ if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
231+ dialogs.onPowerKeyPressed();
232+ event.accepted = true;
233+ } else {
234+ event.accepted = false;
235+ }
236+ }
237+
238+ Keys.onReleased: {
239+ if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
240+ dialogs.onPowerKeyReleased();
241+ event.accepted = true;
242+ } else {
243+ event.accepted = false;
244+ }
245+ }
246+}