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