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.12
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 string usageScenario
37  property size screenSize: Qt.size(Screen.width, Screen.height)
38  property bool hasKeyboard: false
39 
40  signal powerOffClicked();
41 
42  function showPowerDialog() {
43  d.showPowerDialog();
44  }
45 
46  property var doOnClosedAllWindows: function() {}
47  Connections {
48  target: topLevelSurfaceList
49 
50  onClosedAllWindows: {
51  doOnClosedAllWindows();
52  }
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  doOnClosedAllWindows = function(unitySessionService, rebootDialog) {
226  return function() {
227  unitySessionService.reboot();
228  rebootDialog.hide();
229  }
230  }(unitySessionService, rebootDialog);
231  topLevelSurfaceList.closeAllWindows();
232  }
233  color: theme.palette.normal.negative
234  Component.onCompleted: if (root.hasKeyboard) forceActiveFocus(Qt.TabFocusReason)
235  }
236  }
237  }
238 
239  Component {
240  id: powerDialogComponent
241  ShellDialog {
242  id: powerDialog
243  title: i18n.ctr("Title: Power off/Restart dialog", "Power")
244  text: i18n.tr("Are you sure you would like\nto power off?")
245  Button {
246  width: parent.width
247  focus: true
248  text: i18n.ctr("Button: Power off the system", "Power off")
249  onClicked: {
250  doOnClosedAllWindows = function(root, powerDialog) {
251  return function() {
252  powerDialog.hide();
253  root.powerOffClicked();
254  }
255  }(root, powerDialog);
256  topLevelSurfaceList.closeAllWindows();
257  }
258  color: theme.palette.normal.negative
259  Component.onCompleted: if (root.hasKeyboard) forceActiveFocus(Qt.TabFocusReason)
260  }
261  Button {
262  width: parent.width
263  text: i18n.ctr("Button: Restart the system", "Restart")
264  onClicked: {
265  doOnClosedAllWindows = function(unitySessionService, powerDialog) {
266  return function() {
267  unitySessionService.reboot();
268  powerDialog.hide();
269  }
270  }(unitySessionService, powerDialog);
271  topLevelSurfaceList.closeAllWindows();
272  }
273  }
274  Button {
275  width: parent.width
276  text: i18n.tr("Screenshot")
277  onClicked: {
278  powerDialog.hide();
279  itemGrabber.capture(shell);
280  }
281  }
282  Button {
283  width: parent.width
284  text: i18n.tr("Cancel")
285  onClicked: {
286  powerDialog.hide();
287  }
288  }
289  }
290  }
291 
292  Connections {
293  target: root.unitySessionService
294 
295  onLogoutRequested: {
296  // Display a dialog to ask the user to confirm.
297  if (!dialogLoader.active) {
298  dialogLoader.sourceComponent = logoutDialogComponent;
299  dialogLoader.focus = true;
300  dialogLoader.active = true;
301  }
302  }
303 
304  onShutdownRequested: {
305  // Display a dialog to ask the user to confirm.
306  showPowerDialog();
307  }
308 
309  onRebootRequested: {
310  // Display a dialog to ask the user to confirm.
311 
312  // display a combined reboot/shutdown dialog, sadly the session indicator calls rather the "Reboot()" method
313  // than shutdown when clicking on the "Shutdown..." menu item
314  // FIXME: when/if session indicator is fixed, put the rebootDialogComponent here
315  showPowerDialog();
316  }
317 
318  onLogoutReady: {
319  doOnClosedAllWindows = function(unitySessionService) {
320  return function() {
321  Qt.quit();
322  unitySessionService.endSession();
323  }
324  }(unitySessionService);
325  topLevelSurfaceList.closeAllWindows();
326  }
327  }
328 }