on e22bf89 help sign in
unity8/plugins/Unity/Indicators/qml/MenuItemFactory.qml
582 lines 22 kB history raw
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 */
20import QtQuick 2.0
21import Ubuntu.Settings.Menus 0.1 as Menus
22import QMenuModel 0.1 as QMenuModel
23import Utils 0.1 as Utils
24import Ubuntu.Components.ListItems 0.1 as ListItems
25import Ubuntu.Components 0.1
27Item {
28 id: menuFactory
30 property var menuModel: null
32 property var _map: {
33 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
34 "unity.widgets.systemsettings.tablet.switch" : switchMenu,
36 "com.canonical.indicator.button" : buttonMenu,
37 "com.canonical.indicator.div" : separatorMenu,
38 "com.canonical.indicator.section" : sectionMenu,
39 "com.canonical.indicator.progress" : progressMenu,
40 "com.canonical.indicator.slider" : sliderMenu,
41 "com.canonical.indicator.switch" : switchMenu,
42 "com.canonical.indicator.alarm" : alarmMenu,
43 "com.canonical.indicator.appointment" : appointmentMenu,
45 "com.canonical.indicator.messages.messageitem" : messageItem,
46 "com.canonical.indicator.messages.sourceitem" : groupedMessage,
48 "com.canonical.unity.slider" : sliderMenu,
49 "com.canonical.unity.switch" : switchMenu,
51 "com.canonical.unity.media-player" : mediaPayerMenu,
52 "com.canonical.unity.playback-item" : playbackItemMenu,
54 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
55 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
56 "com.canonical.indicator.network.modeminfoitem" : modeminfoitem,
57 }
59 function getExtendedProperty(object, propertyName, defaultValue) {
60 if (object && object.hasOwnProperty(propertyName)) {
61 return object[propertyName];
62 }
63 return defaultValue;
64 }
66 Component {
67 id: separatorMenu;
68 Menus.SeparatorMenu {
69 objectName: "separatorMenu"
70 }
71 }
73 Component {
74 id: sliderMenu;
75 Menus.SliderMenu {
76 objectName: "sliderMenu"
77 property QtObject menuData: null
78 property var menuModel: menuFactory.menuModel
79 property int menuIndex: -1
80 property var extendedData: menuData && menuData.ext || undefined
81 property var serverValue: getExtendedProperty(menuData, "actionState", undefined)
83 text: menuData && menuData.label || ""
84 iconSource: menuData && menuData.icon || ""
85 minIcon: getExtendedProperty(extendedData, "minIcon", "")
86 maxIcon: getExtendedProperty(extendedData, "maxIcon", "")
88 minimumValue: getExtendedProperty(extendedData, "minValue", 0.0)
89 maximumValue: {
90 var maximum = getExtendedProperty(extendedData, "maxValue", 1.0);
91 if (maximum <= minimumValue) {
92 return minimumValue + 1;
93 }
94 return maximum;
95 }
96 enabled: menuData && menuData.sensitive || false
98 onMenuModelChanged: {
99 loadAttributes();
100 }
101 onMenuIndexChanged: {
102 loadAttributes();
103 }
104 onServerValueChanged: {
105 // value can be changed by slider, so a binding won't work.
106 if (serverValue !== undefined) {
107 value = serverValue;
108 }
109 }
110 onUpdated: {
111 menuModel.changeState(menuIndex, value);
112 }
114 function loadAttributes() {
115 if (!menuModel || menuIndex == -1) return;
116 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
117 'max-value': 'double',
118 'min-icon': 'icon',
119 'max-icon': 'icon'});
120 }
121 }
122 }
124 Component {
125 id: buttonMenu;
126 Menus.ButtonMenu {
127 objectName: "buttonMenu"
128 property QtObject menuData: null
129 property var menuModel: menuFactory.menuModel
130 property int menuIndex: -1
132 buttonText: menuData && menuData.label || ""
133 enabled: menuData && menuData.sensitive || false
135 onTriggered: {
136 menuModel.activate(menuIndex);
137 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
138 }
139 }
140 }
141 Component {
142 id: sectionMenu;
143 Menus.SectionMenu {
144 objectName: "sectionMenu"
145 property QtObject menuData: null
146 property var menuIndex: undefined
148 text: menuData && menuData.label || ""
149 busy: false
150 }
151 }
153 Component {
154 id: progressMenu;
155 Menus.ProgressValueMenu {
156 objectName: "progressMenu"
157 property QtObject menuData: null
158 property int menuIndex: -1
160 text: menuData && menuData.label || ""
161 iconSource: menuData && menuData.icon || ""
162 value : menuData && menuData.actionState || 0.0
163 enabled: menuData && menuData.sensitive || false
164 }
165 }
167 Component {
168 id: standardMenu;
169 ListItems.Standard {
170 objectName: "standardMenu"
171 property QtObject menuData: null
172 property int menuIndex: -1
174 text: menuData && menuData.label || ""
175 iconSource: menuData && menuData.icon || ""
176 enabled: menuData && menuData.sensitive || false
178 onTriggered: {
179 menuModel.activate(menuIndex);
180 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
181 }
182 }
183 }
185 Component {
186 id: checkableMenu;
187 Menus.CheckableMenu {
188 objectName: "checkableMenu"
189 property QtObject menuData: null
190 property int menuIndex: -1
192 text: menuData && menuData.label || ""
193 enabled: menuData && menuData.sensitive || false
194 checked: menuData && menuData.isToggled || false
196 onTriggered: {
197 menuModel.activate(menuIndex);
198 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
199 }
200 }
201 }
204 Component {
205 id: switchMenu;
206 Menus.SwitchMenu {
207 objectName: "switchMenu"
208 property QtObject menuData: null
209 property int menuIndex: -1
211 text: menuData && menuData.label || ""
212 iconSource: menuData && menuData.icon || ""
213 enabled: menuData && menuData.sensitive || false
214 checked: menuData && menuData.isToggled || false
216 onTriggered: {
217 menuModel.activate(menuIndex);
218 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
219 }
220 }
221 }
223 Component {
224 id: alarmMenu;
225 Menus.EventMenu {
226 objectName: "alarmMenu"
227 property QtObject menuData: null
228 property var menuModel: menuFactory.menuModel
229 property int menuIndex: -1
230 property var extendedData: menuData && menuData.ext || undefined
231 // TODO - bug #1260728
232 property var timeFormatter: Utils.GDateTimeFormatter {
233 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
234 format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
235 }
237 text: menuData && menuData.label || ""
238 iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
239 time: timeFormatter.timeString
240 enabled: menuData && menuData.sensitive || false
242 onMenuModelChanged: {
243 loadAttributes();
244 }
245 onMenuIndexChanged: {
246 loadAttributes();
247 }
248 onTriggered: {
249 menuModel.activate(menuIndex);
250 }
252 function loadAttributes() {
253 if (!menuModel || menuIndex == -1) return;
254 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
255 'x-canonical-time-format': 'string'});
256 }
257 }
258 }
260 Component {
261 id: appointmentMenu;
262 Menus.EventMenu {
263 objectName: "appointmentMenu"
264 property QtObject menuData: null
265 property var menuModel: menuFactory.menuModel
266 property int menuIndex: -1
267 property var extendedData: menuData && menuData.ext || undefined
268 // TODO - bug #1260728
269 property var timeFormatter: Utils.GDateTimeFormatter {
270 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
271 format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
272 }
274 text: menuData && menuData.label || ""
275 iconSource: menuData && menuData.icon || "image://theme/calendar"
276 time: timeFormatter.timeString
277 eventColor: getExtendedProperty(extendedData, "xCanonicalColor", Qt.rgba(0.0, 0.0, 0.0, 0.0))
278 enabled: menuData && menuData.sensitive || false
280 onMenuModelChanged: {
281 loadAttributes();
282 }
283 onMenuIndexChanged: {
284 loadAttributes();
285 }
286 onTriggered: {
287 menuModel.activate(menuIndex);
288 }
290 function loadAttributes() {
291 if (!menuModel || menuIndex == -1) return;
292 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
293 'x-canonical-time': 'int64',
294 'x-canonical-time-format': 'string'});
295 }
296 }
297 }
299 Component {
300 id: wifiSection;
301 Menus.SectionMenu {
302 objectName: "wifiSection"
303 property QtObject menuData: null
304 property var menuModel: menuFactory.menuModel
305 property int menuIndex: -1
306 property var extendedData: menuData && menuData.ext || undefined
308 text: menuData && menuData.label || ""
309 busy: getExtendedProperty(extendedData, "xCanonicalBusyAction", false)
311 onMenuModelChanged: {
312 loadAttributes();
313 }
314 onMenuIndexChanged: {
315 loadAttributes();
316 }
318 function loadAttributes() {
319 if (!menuModel || menuIndex == -1) return;
320 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
321 }
322 }
323 }
325 Component {
326 id: accessPoint;
327 Menus.AccessPointMenu {
328 objectName: "accessPoint"
329 property QtObject menuData: null
330 property var menuModel: menuFactory.menuModel
331 property int menuIndex: -1
332 property var extendedData: menuData && menuData.ext || undefined
334 property var strengthAction: QMenuModel.UnityMenuAction {
335 model: menuModel
336 index: menuIndex
337 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
338 }
340 text: menuData && menuData.label || ""
341 enabled: menuData && menuData.sensitive || false
342 checked: menuData && menuData.isToggled || false
343 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
344 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
345 signalStrength: strengthAction.valid ? strengthAction.state : 0
347 onMenuModelChanged: {
348 loadAttributes();
349 }
350 onMenuIndexChanged: {
351 loadAttributes();
352 }
353 onTriggered: {
354 menuModel.activate(menuIndex);
355 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
356 }
358 function loadAttributes() {
359 if (!menuModel || menuIndex == -1) return;
360 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
361 'x-canonical-wifi-ap-is-secure': 'bool',
362 'x-canonical-wifi-ap-strength-action': 'string'});
363 }
364 }
365 }
367 Component {
368 id: modeminfoitem;
369 ModemInfoItem {
370 objectName: "modemInfoItem"
371 property QtObject menuData: null
372 property var menuModel: menuFactory.menuModel
373 property int menuIndex: -1
374 property var extendedData: menuData && menuData.ext || undefined
376 property var statusLabelAction: QMenuModel.UnityMenuAction {
377 model: menuModel
378 index: menuIndex
379 name: getExtendedProperty(extendedData, "xCanonicalModemStatusLabelAction", "")
380 }
381 statusText: statusLabelAction.valid ? statusLabelAction.state : ""
383 property var statusIconAction: QMenuModel.UnityMenuAction {
384 model: menuModel
385 index: menuIndex
386 name: getExtendedProperty(extendedData, "xCanonicalModemStatusIconAction", "")
387 }
388 statusIcon: statusIconAction.valid ? statusIconAction.state : ""
390 property var connectivityIconAction: QMenuModel.UnityMenuAction {
391 model: menuModel
392 index: menuIndex
393 name: getExtendedProperty(extendedData, "xCanonicalModemConnectivityIconAction", "")
394 }
395 connectivityIcon: connectivityIconAction.valid ? connectivityIconAction.state : ""
397 property var simIdentifierLabelAction: QMenuModel.UnityMenuAction {
398 model: menuModel
399 index: menuIndex
400 name: getExtendedProperty(extendedData, "xCanonicalModemSimIdentifierLabelAction", "")
401 }
402 simIdentifierText: simIdentifierLabelAction.valid ? simIdentifierLabelAction.state : ""
404 property var roamingAction: QMenuModel.UnityMenuAction {
405 model: menuModel
406 index: menuIndex
407 name: getExtendedProperty(extendedData, "xCanonicalModemRoamingAction", "")
408 }
409 roaming: roamingAction.valid ? roamingAction.state : false
411 property var unlockAction: QMenuModel.UnityMenuAction {
412 model: menuModel
413 index: menuIndex
414 name: getExtendedProperty(extendedData, "xCanonicalModemLockedAction", "")
415 }
416 onUnlock: {
417 unlockAction.activate();
418 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
419 }
420 locked: unlockAction.valid ? unlockAction.state : false
422 onMenuModelChanged: {
423 loadAttributes();
424 }
425 onMenuIndexChanged: {
426 loadAttributes();
427 }
429 function loadAttributes() {
430 if (!menuModel || menuIndex == -1) return;
431 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-modem-status-label-action': 'string',
432 'x-canonical-modem-status-icon-action': 'string',
433 'x-canonical-modem-connectivity-icon-action': 'string',
434 'x-canonical-modem-sim-identifier-label': 'string',
435 'x-canonical-modem-roaming-action': 'string',
436 'x-canonical-modem-locked-action': 'string'});
437 }
438 }
439 }
441 Component {
442 id: messageItem
443 MessageMenuItemFactory {
444 objectName: "messageItem"
445 menuModel: menuFactory.menuModel
446 }
447 }
449 Component {
450 id: groupedMessage
451 Menus.GroupedMessageMenu {
452 objectName: "groupedMessage"
453 property QtObject menuData: null
454 property var menuModel: menuFactory.menuModel
455 property int menuIndex: -1
456 property var extendedData: menuData && menuData.ext || undefined
458 text: menuData && menuData.label || ""
459 iconSource: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_app.svg")
460 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
461 enabled: menuData && menuData.sensitive || false
462 removable: true
464 onMenuModelChanged: {
465 loadAttributes();
466 }
467 onMenuIndexChanged: {
468 loadAttributes();
469 }
470 onClicked: {
471 menuModel.activate(menuIndex, true);
472 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
473 }
474 onDismissed: {
475 menuModel.activate(menuIndex, false);
476 }
478 function loadAttributes() {
479 if (!menuModel || menuIndex == -1) return;
480 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
481 }
482 }
483 }
485 Component {
486 id: mediaPayerMenu;
487 Menus.MediaPlayerMenu {
488 objectName: "mediaPayerMenu"
489 property QtObject menuData: null
490 property var menuModel: menuFactory.menuModel
491 property int menuIndex: -1
492 property var actionState: menuData && menuData.actionState || undefined
494 playerIcon: menuData && menuData.icon || ""
495 playerName: menuData && menuData.label || ""
497 albumArt: getExtendedProperty(actionState, "art-url", "")
498 song: getExtendedProperty(actionState, "title", "unknown")
499 artist: getExtendedProperty(actionState, "artist", "unknown")
500 album: getExtendedProperty(actionState, "album", "unknown")
501 running: getExtendedProperty(actionState, "running", false)
502 state: getExtendedProperty(actionState, "state", "")
503 enabled: menuData && menuData.sensitive || false
505 onTriggered: {
506 model.activate(modelIndex);
507 }
508 }
509 }
511 Component {
512 id: playbackItemMenu;
513 Menus.PlaybackItemMenu {
514 objectName: "playbackItemMenu"
515 property QtObject menuData: null
516 property var menuModel: menuFactory.menuModel
517 property int menuIndex: -1
518 property var extendedData: menuData && menuData.ext || undefined
520 property var playAction: QMenuModel.UnityMenuAction {
521 model: menuModel
522 index: menuIndex
523 name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
524 }
525 property var nextAction: QMenuModel.UnityMenuAction {
526 model: menuModel
527 index: menuIndex
528 name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
529 }
530 property var previousAction: QMenuModel.UnityMenuAction {
531 model: menuModel
532 index: menuIndex
533 name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
534 }
536 playing: playAction.state === "Playing"
537 canPlay: playAction.valid
538 canGoNext: nextAction.valid
539 canGoPrevious: previousAction.valid
540 enabled: menuData && menuData.sensitive || false
542 onPlay: {
543 playAction.activate();
544 }
545 onNext: {
546 nextAction.activate();
547 }
548 onPrevious: {
549 previousAction.activate();
550 }
551 onMenuModelChanged: {
552 loadAttributes();
553 }
554 onMenuIndexChanged: {
555 loadAttributes();
556 }
558 function loadAttributes() {
559 if (!menuModel || menuIndex == -1) return;
560 menuModel.loadExtendedAttributes(modelIndex, {'x-canonical-play-action': 'string',
561 'x-canonical-next-action': 'string',
562 'x-canonical-previous-action': 'string'});
563 }
564 }
565 }
567 function load(modelData) {
568 if (modelData.type !== undefined) {
569 var component = _map[modelData.type];
570 if (component !== undefined) {
571 return component;
572 }
573 }
574 if (modelData.isCheck || modelData.isRadio) {
575 return checkableMenu;
576 }
577 if (modelData.isSeparator) {
578 return separatorMenu;
579 }
580 return standardMenu;
581 }