Unity 8
NotificationMenuItemFactory.qml
1 /*
2  * Copyright 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 Lesser 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 Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser 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 QMenuModel 0.1
20 import "../Components"
21 
22 Loader {
23  id: menuFactory
24 
25  property QtObject menuModel: null
26  property QtObject menuData: null
27  property int menuIndex : -1
28  property int maxHeight
29  readonly property bool fullscreen: menuData.type === "com.canonical.snapdecision.pinlock"
30  property url background: ""
31 
32  signal accepted()
33 
34  property var _map: {
35  "com.canonical.snapdecision.textfield": textfield,
36  "com.canonical.snapdecision.pinlock" : pinLock,
37  }
38 
39  sourceComponent: {
40  if (menuData.type !== undefined) {
41  var component = _map[menuData.type];
42  if (component !== undefined) {
43  if (component === pinLock && shell.hasLockedApp) {
44  // In case we are in emergency mode, just skip this unlock.
45  // Happens with two locked SIMs but the user clicks
46  // Emergency Call on the first unlock dialog.
47  // TODO: if we ever allow showing the indicators in
48  // emergency mode, we'll need to differentiate between
49  // user-initiated ones which we *do* want to show and the
50  // dialogs that appear on boot, which we don't. But for
51  // now we can get away with skipping all such dialogs.
52  menuModel.activate(menuIndex, false);
53  return null;
54  }
55  return component;
56  }
57  }
58  }
59 
60  function getExtendedProperty(object, propertyName, defaultValue) {
61  if (object && object.hasOwnProperty(propertyName)) {
62  return object[propertyName];
63  }
64  return defaultValue;
65  }
66 
67  Component {
68  id: textfield
69 
70  Column {
71  spacing: notification.margins
72 
73  anchors {
74  left: parent.left
75  right: parent.right
76  margins: spacing
77  }
78 
79  Component.onCompleted: {
80  menuModel.loadExtendedAttributes(menuIndex, {"x-echo-mode-password": "bool"});
81  checkBox.checked = menuData.ext.xEchoModePassword ? false : true
82  checkBoxRow.visible = menuData.ext.xEchoModePassword
83  }
84 
85  Label {
86  text: menuData.label
87  color: theme.palette.normal.backgroundSecondaryText
88  }
89 
90  TextField {
91  // TODO using Qt.ImhNoPredictiveText here until lp #1291575 is fixed for ubuntu-ui-toolkit
92  inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
93  anchors {
94  left: parent.left
95  right: parent.right
96  }
97  echoMode: checkBox.checked ? TextInput.Normal : TextInput.Password
98  height: units.gu(5)
99  Component.onCompleted: {
100  forceActiveFocus();
101  }
102  onTextChanged: {
103  menuModel.changeState(menuIndex, text);
104  }
105  onAccepted: {
106  menuFactory.accepted()
107  }
108  }
109 
110  Row {
111  id: checkBoxRow
112 
113  spacing: notification.margins
114 
115  CheckBox {
116  id: checkBox
117 
118  checked: false
119  activeFocusOnPress: false
120  }
121 
122  Label {
123  anchors.verticalCenter: checkBox.verticalCenter
124  text: i18n.tr("Show password")
125  color: theme.palette.normal.backgroundSecondaryText
126 
127  MouseArea {
128  anchors.fill: parent
129  onClicked: { checkBox.checked = !checkBox.checked }
130  }
131  }
132  }
133  }
134  }
135 
136  Component {
137  id: pinLock
138 
139  Lockscreen {
140  anchors {
141  left: parent.left
142  right: parent.right
143  }
144  height: menuFactory.maxHeight
145  infoText: notification.summary
146  errorText: errorAction.valid ? errorAction.state : ""
147  retryText: notification.body
148  background: menuFactory.background
149  darkenBackground: 0.4
150 
151  onEntered: {
152  menuModel.changeState(menuIndex, passphrase);
153  clear(false);
154  notification.dismissed()
155  }
156 
157  onCancel: {
158  menuModel.activate(menuIndex, false);
159  notification.dismissed()
160  }
161 
162  onEmergencyCall: {
163  shell.startLockedApp("dialer-app");
164  menuModel.activate(menuIndex, false);
165  notification.dismissed()
166  }
167 
168  property var extendedData: menuData && menuData.ext || undefined
169 
170  property var pinMinMaxAction : UnityMenuAction {
171  model: menuModel
172  index: menuIndex
173  name: getExtendedProperty(extendedData, "xCanonicalPinMinMax", "")
174 
175  onStateChanged: {
176  var min = pinMinMaxAction.state[0];
177  var max = pinMinMaxAction.state[1];
178 
179  if (min === 0) min = -1;
180  if (max === 0) max = -1;
181 
182  minPinLength = min
183  maxPinLength = max
184  }
185  }
186 
187  property var popupAction: UnityMenuAction {
188  model: menuModel
189  index: menuIndex
190  name: getExtendedProperty(extendedData, "xCanonicalPinPopup", "")
191  onStateChanged: {
192  if (state !== "")
193  showInfoPopup("", state);
194  }
195  }
196  onInfoPopupConfirmed: {
197  popupAction.activate();
198  }
199 
200  Timer {
201  id: errorTimer
202  interval: 4000;
203  running: false;
204  repeat: false
205  onTriggered: {
206  errorAction.activate();
207  }
208  }
209  property var errorAction: UnityMenuAction {
210  model: menuModel
211  index: menuIndex
212  name: getExtendedProperty(extendedData, "xCanonicalPinError", "")
213  onStateChanged: {
214  errorText = state;
215  if (state !== "") {
216  clear(true);
217  errorTimer.running = true;
218  }
219  }
220  }
221 
222  function loadAttributes() {
223  if (!menuModel || menuIndex == -1) return;
224  menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-pin-min-max': 'string',
225  'x-canonical-pin-popup': 'string',
226  'x-canonical-pin-error': 'string'});
227  }
228  Component.onCompleted: {
229  loadAttributes();
230  }
231  }
232  }
233 }