Unity 8
Dialogs.qml
1 /*
2  * Copyright (C) 2014-2017 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 QtQuick.Window 2.2
19 import Unity.Application 0.1
20 import Unity.Session 0.1
21 import GlobalShortcut 1.0
22 import Ubuntu.Components 1.3
23 import Unity.Platform 1.0
24 import Utils 0.1
25 
26 MouseArea {
27  id: root
28  acceptedButtons: Qt.AllButtons
29  hoverEnabled: true
30  onWheel: wheel.accepted = true
31 
32  readonly property bool hasActiveDialog: dialogLoader.active || d.modeSwitchWarningPopup
33 
34  // to be set from outside, useful mostly for testing purposes
35  property var unitySessionService: DBusUnitySessionService
36  property var closeAllApps: function() {
37  while (true) {
38  var app = ApplicationManager.get(0);
39  if (app === null) {
40  break;
41  }
42  ApplicationManager.stopApplication(app.appId);
43  }
44  }
45  property string usageScenario
46  property size screenSize: Qt.size(Screen.width, Screen.height)
47  property bool hasKeyboard: false
48 
49  signal powerOffClicked();
50 
51  function showPowerDialog() {
52  d.showPowerDialog();
53  }
54 
55  onUsageScenarioChanged: {
56  // if we let the user switch manually to desktop mode, don't display the warning dialog
57  // see MenuItemFactory.qml, for the Desktop Mode switch logic
58  var isTabletSize = Math.min(screenSize.width, screenSize.height) > units.gu(60);
59 
60  if (usageScenario != "desktop" && legacyAppsModel.count > 0 && !d.modeSwitchWarningPopup && !isTabletSize) {
61  var comp = Qt.createComponent(Qt.resolvedUrl("ModeSwitchWarningDialog.qml"))
62  d.modeSwitchWarningPopup = comp.createObject(root, {model: legacyAppsModel});
63  d.modeSwitchWarningPopup.forceClose.connect(function() {
64  for (var i = legacyAppsModel.count - 1; i >= 0; i--) {
65  ApplicationManager.stopApplication(legacyAppsModel.get(i).appId);
66  }
67  d.modeSwitchWarningPopup.hide();
68  d.modeSwitchWarningPopup.destroy();
69  d.modeSwitchWarningPopup = null;
70  })
71  } else if (usageScenario == "desktop" && d.modeSwitchWarningPopup) {
72  d.modeSwitchWarningPopup.hide();
73  d.modeSwitchWarningPopup.destroy();
74  d.modeSwitchWarningPopup = null;
75  }
76  }
77 
78  ApplicationsFilterModel {
79  id: legacyAppsModel
80  applicationsModel: ApplicationManager
81  filterTouchApps: true
82  }
83 
84  GlobalShortcut { // reboot/shutdown dialog
85  shortcut: Qt.Key_PowerDown
86  active: Platform.isPC
87  onTriggered: root.unitySessionService.RequestShutdown()
88  }
89 
90  GlobalShortcut { // reboot/shutdown dialog
91  shortcut: Qt.Key_PowerOff
92  active: Platform.isPC
93  onTriggered: root.unitySessionService.RequestShutdown()
94  }
95 
96  GlobalShortcut { // sleep
97  shortcut: Qt.Key_Sleep
98  onTriggered: root.unitySessionService.Suspend()
99  }
100 
101  GlobalShortcut { // hibernate
102  shortcut: Qt.Key_Hibernate
103  onTriggered: root.unitySessionService.Hibernate()
104  }
105 
106  GlobalShortcut { // logout/lock dialog
107  shortcut: Qt.Key_LogOff
108  onTriggered: root.unitySessionService.RequestLogout()
109  }
110 
111  GlobalShortcut { // logout/lock dialog
112  shortcut: Qt.ControlModifier|Qt.AltModifier|Qt.Key_Delete
113  onTriggered: root.unitySessionService.RequestLogout()
114  }
115 
116  GlobalShortcut { // lock screen
117  shortcut: Qt.Key_ScreenSaver
118  onTriggered: root.unitySessionService.PromptLock()
119  }
120 
121  GlobalShortcut { // lock screen
122  shortcut: Qt.ControlModifier|Qt.AltModifier|Qt.Key_L
123  onTriggered: root.unitySessionService.PromptLock()
124  }
125 
126  GlobalShortcut { // lock screen
127  shortcut: Qt.MetaModifier|Qt.Key_L
128  onTriggered: root.unitySessionService.PromptLock()
129  }
130 
131  QtObject {
132  id: d // private stuff
133  objectName: "dialogsPrivate"
134 
135  property var modeSwitchWarningPopup: null
136 
137  function showPowerDialog() {
138  if (!dialogLoader.active) {
139  dialogLoader.sourceComponent = powerDialogComponent;
140  dialogLoader.focus = true;
141  dialogLoader.active = true;
142  }
143  }
144  }
145 
146  Loader {
147  id: dialogLoader
148  objectName: "dialogLoader"
149  anchors.fill: parent
150  active: false
151  onActiveChanged: {
152  if (!active) {
153  if (previousFocusedItem) {
154  previousFocusedItem.forceActiveFocus(Qt.OtherFocusReason);
155  previousFocusedItem = undefined;
156  }
157  previousSourceComponent = undefined;
158  sourceComponent = undefined;
159  }
160  }
161  onSourceComponentChanged: {
162  if (previousSourceComponent !== sourceComponent) {
163  previousSourceComponent = sourceComponent;
164  previousFocusedItem = window.activeFocusItem;
165  }
166  }
167 
168  property var previousSourceComponent: undefined
169  property var previousFocusedItem: undefined
170  }
171 
172  Component {
173  id: logoutDialogComponent
174  ShellDialog {
175  id: logoutDialog
176  title: i18n.ctr("Title: Lock/Log out dialog", "Log out")
177  text: i18n.tr("Are you sure you want to log out?")
178  Button {
179  width: parent.width
180  text: i18n.ctr("Button: Lock the system", "Lock")
181  visible: root.unitySessionService.CanLock()
182  onClicked: {
183  root.unitySessionService.PromptLock();
184  logoutDialog.hide();
185  }
186  Component.onCompleted: if (root.hasKeyboard) forceActiveFocus(Qt.TabFocusReason)
187  }
188  Button {
189  width: parent.width
190  focus: true
191  text: i18n.ctr("Button: Log out from the system", "Log Out")
192  onClicked: {
193  unitySessionService.logout();
194  logoutDialog.hide();
195  }
196  }
197  Button {
198  width: parent.width
199  text: i18n.tr("Cancel")
200  onClicked: {
201  logoutDialog.hide();
202  }
203  }
204  }
205  }
206 
207  Component {
208  id: rebootDialogComponent
209  ShellDialog {
210  id: rebootDialog
211  title: i18n.ctr("Title: Reboot dialog", "Reboot")
212  text: i18n.tr("Are you sure you want to reboot?")
213  Button {
214  width: parent.width
215  text: i18n.tr("No")
216  onClicked: {
217  rebootDialog.hide();
218  }
219  }
220  Button {
221  width: parent.width
222  focus: true
223  text: i18n.tr("Yes")
224  onClicked: {
225  root.closeAllApps();
226  unitySessionService.reboot();
227  rebootDialog.hide();
228  }
229  color: theme.palette.normal.negative
230  Component.onCompleted: if (root.hasKeyboard) forceActiveFocus(Qt.TabFocusReason)
231  }
232  }
233  }
234 
235  Component {
236  id: powerDialogComponent
237  ShellDialog {
238  id: powerDialog
239  title: i18n.ctr("Title: Power off/Restart dialog", "Power")
240  text: i18n.tr("Are you sure you would like\nto power off?")
241  Button {
242  width: parent.width
243  focus: true
244  text: i18n.ctr("Button: Power off the system", "Power off")
245  onClicked: {
246  root.closeAllApps();
247  powerDialog.hide();
248  root.powerOffClicked();
249  }
250  color: theme.palette.normal.negative
251  Component.onCompleted: if (root.hasKeyboard) forceActiveFocus(Qt.TabFocusReason)
252  }
253  Button {
254  width: parent.width
255  text: i18n.ctr("Button: Restart the system", "Restart")
256  onClicked: {
257  root.closeAllApps();
258  unitySessionService.reboot();
259  powerDialog.hide();
260  }
261  }
262  Button {
263  width: parent.width
264  text: i18n.tr("Cancel")
265  onClicked: {
266  powerDialog.hide();
267  }
268  }
269  }
270  }
271 
272  Connections {
273  target: root.unitySessionService
274 
275  onLogoutRequested: {
276  // Display a dialog to ask the user to confirm.
277  if (!dialogLoader.active) {
278  dialogLoader.sourceComponent = logoutDialogComponent;
279  dialogLoader.focus = true;
280  dialogLoader.active = true;
281  }
282  }
283 
284  onShutdownRequested: {
285  // Display a dialog to ask the user to confirm.
286  showPowerDialog();
287  }
288 
289  onRebootRequested: {
290  // Display a dialog to ask the user to confirm.
291 
292  // display a combined reboot/shutdown dialog, sadly the session indicator calls rather the "Reboot()" method
293  // than shutdown when clicking on the "Shutdown..." menu item
294  // FIXME: when/if session indicator is fixed, put the rebootDialogComponent here
295  showPowerDialog();
296  }
297 
298  onLogoutReady: {
299  root.closeAllApps();
300  Qt.quit();
301  unitySessionService.endSession();
302  }
303  }
304 }