on d6bcfae help sign in
unity8/qml/Panel/Indicators/MenuItemFactory.qml
994 lines 36 kB history raw
1/*
2 * Copyright 2013,2015 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 */
17import QtQuick 2.4
18import Ubuntu.Settings.Menus 0.1 as Menus
19import Ubuntu.Settings.Components 0.1
20import QMenuModel 0.1
21import Utils 0.1 as Utils
22import Ubuntu.Components.ListItems 1.3 as ListItems
23import Ubuntu.Components 1.3
24import Unity.Session 0.1
26Item {
27 id: menuFactory
29 property var rootModel: null
30 property var menuModel: null
32 property var _map: {
33 "default": {
34 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
35 "unity.widgets.systemsettings.tablet.switch" : switchMenu,
37 "com.canonical.indicator.button" : buttonMenu,
38 "com.canonical.indicator.div" : separatorMenu,
39 "com.canonical.indicator.section" : sectionMenu,
40 "com.canonical.indicator.progress" : progressMenu,
41 "com.canonical.indicator.slider" : sliderMenu,
42 "com.canonical.indicator.switch" : switchMenu,
43 "com.canonical.indicator.alarm" : alarmMenu,
44 "com.canonical.indicator.appointment" : appointmentMenu,
45 "com.canonical.indicator.transfer" : transferMenu,
46 "com.canonical.indicator.button-section" : buttonSectionMenu,
47 "com.canonical.indicator.link" : linkMenu,
49 "com.canonical.indicator.messages.messageitem" : messageItem,
50 "com.canonical.indicator.messages.sourceitem" : groupedMessage,
52 "com.canonical.unity.slider" : sliderMenu,
53 "com.canonical.unity.switch" : switchMenu,
55 "com.canonical.unity.media-player" : mediaPayerMenu,
56 "com.canonical.unity.playback-item" : playbackItemMenu,
58 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
59 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
60 "com.canonical.indicator.network.modeminfoitem" : modeminfoitem,
62 "com.canonical.indicator.calendar": calendarMenu,
63 "com.canonical.indicator.location": timezoneMenu,
65 "indicator.user-menu-item": userMenuItem,
66 "indicator.guest-menu-item": userMenuItem
67 },
68 "indicator-messages" : {
69 "com.canonical.indicator.button" : messagesButtonMenu
70 }
71 }
73 function getExtendedProperty(object, propertyName, defaultValue) {
74 if (object && object.hasOwnProperty(propertyName)) {
75 return object[propertyName];
76 }
77 return defaultValue;
78 }
80 Component {
81 id: separatorMenu;
83 Menus.SeparatorMenu {
84 objectName: "separatorMenu"
85 }
86 }
88 Component {
89 id: sliderMenu;
91 Menus.SliderMenu {
92 id: sliderItem
93 objectName: "sliderMenu"
94 property QtObject menuData: null
95 property var menuModel: menuFactory.menuModel
96 property int menuIndex: -1
97 property var extendedData: menuData && menuData.ext || undefined
98 property var serverValue: getExtendedProperty(menuData, "actionState", undefined)
100 text: menuData && menuData.label || ""
101 iconSource: menuData && menuData.icon || ""
102 minIcon: getExtendedProperty(extendedData, "minIcon", "")
103 maxIcon: getExtendedProperty(extendedData, "maxIcon", "")
105 minimumValue: getExtendedProperty(extendedData, "minValue", 0.0)
106 maximumValue: {
107 var maximum = getExtendedProperty(extendedData, "maxValue", 1.0);
108 if (maximum <= minimumValue) {
109 return minimumValue + 1;
110 }
111 return maximum;
112 }
113 enabled: menuData && menuData.sensitive || false
114 highlightWhenPressed: false
116 onMenuModelChanged: {
117 loadAttributes();
118 }
119 onMenuIndexChanged: {
120 loadAttributes();
121 }
123 function loadAttributes() {
124 if (!menuModel || menuIndex == -1) return;
125 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
126 'max-value': 'double',
127 'min-icon': 'icon',
128 'max-icon': 'icon',
129 'x-canonical-sync-action': 'string'});
130 }
132 ServerPropertySynchroniser {
133 id: sliderPropertySync
134 objectName: "sync"
135 syncTimeout: Utils.Constants.indicatorValueTimeout
136 bufferedSyncTimeout: true
137 maximumWaitBufferInterval: 16
139 serverTarget: sliderItem
140 serverProperty: "serverValue"
141 userTarget: sliderItem
142 userProperty: "value"
144 onSyncTriggered: menuModel.changeState(menuIndex, value)
145 }
147 UnityMenuAction {
148 model: menuModel
149 index: menuIndex
150 name: getExtendedProperty(extendedData, "xCanonicalSyncAction", "")
151 onStateChanged: {
152 sliderPropertySync.reset();
153 sliderPropertySync.updateUserValue();
154 }
155 }
156 }
157 }
159 Component {
160 id: buttonMenu;
162 Menus.ButtonMenu {
163 objectName: "buttonMenu"
164 property QtObject menuData: null
165 property var menuModel: menuFactory.menuModel
166 property int menuIndex: -1
168 buttonText: menuData && menuData.label || ""
169 enabled: menuData && menuData.sensitive || false
170 highlightWhenPressed: false
172 onTriggered: {
173 menuModel.activate(menuIndex);
174 }
175 }
176 }
178 Component {
179 id: messagesButtonMenu;
181 Item {
182 objectName: "messagesButtonMenu"
183 property QtObject menuData: null
184 property var menuModel: menuFactory.menuModel
185 property int menuIndex: -1
187 implicitHeight: units.gu(5)
188 enabled: menuData && menuData.sensitive || false
190 Label {
191 id: buttonMenuLabel
192 text: menuData && menuData.label || ""
193 anchors.centerIn: parent
194 font.bold: true
195 }
197 MouseArea {
198 anchors {
199 fill: buttonMenuLabel
200 margins: units.gu(-1)
201 }
202 onClicked: menuModel.activate(menuIndex);
203 }
204 }
205 }
207 Component {
208 id: sectionMenu;
210 Menus.SectionMenu {
211 objectName: "sectionMenu"
212 property QtObject menuData: null
213 property var menuIndex: undefined
215 text: menuData && menuData.label || ""
216 busy: false
217 }
218 }
220 Component {
221 id: progressMenu;
223 Menus.ProgressValueMenu {
224 objectName: "progressMenu"
225 property QtObject menuData: null
226 property int menuIndex: -1
228 text: menuData && menuData.label || ""
229 iconSource: menuData && menuData.icon || ""
230 value : menuData && menuData.actionState || 0.0
231 enabled: menuData && menuData.sensitive || false
232 highlightWhenPressed: false
233 }
234 }
236 Component {
237 id: standardMenu;
239 Menus.StandardMenu {
240 objectName: "standardMenu"
241 property QtObject menuData: null
242 property int menuIndex: -1
244 text: menuData && menuData.label || ""
245 iconSource: menuData && menuData.icon || ""
246 enabled: menuData && menuData.sensitive || false
247 highlightWhenPressed: false
249 onTriggered: {
250 menuModel.activate(menuIndex);
251 }
253 // FIXME : At the moment, the indicators aren't using
254 // com.canonical.indicators.link for settings menu. Need to fudge it.
255 property bool settingsMenu: menuData && menuData.action.indexOf("settings") > -1 || false
256 backColor: settingsMenu ? Qt.rgba(1,1,1,0.07) : "transparent"
257 component: settingsMenu ? buttonForSettings : undefined
258 Component {
259 id: buttonForSettings
260 Icon {
261 name: "settings"
262 height: units.gu(3)
263 width: height
264 color: theme.palette.selected.backgroundText
265 }
266 }
267 }
268 }
270 Component {
271 id: linkMenu;
273 Menus.StandardMenu {
274 objectName: "linkMenu"
275 property QtObject menuData: null
276 property int menuIndex: -1
278 text: menuData && menuData.label || ""
279 iconSource: menuData && menuData.icon || ""
280 enabled: menuData && menuData.sensitive || false
281 highlightWhenPressed: false
283 onTriggered: {
284 menuModel.activate(menuIndex);
285 }
287 backColor: Qt.rgba(1,1,1,0.07)
289 component: menuData.icon ? icon : undefined
290 Component {
291 id: icon
292 Icon {
293 source: menuData.icon
294 height: units.gu(3)
295 width: height
296 color: theme.palette.selected.backgroundText
297 }
298 }
299 }
300 }
302 Component {
303 id: checkableMenu;
305 Menus.CheckableMenu {
306 id: checkItem
307 objectName: "checkableMenu"
308 property QtObject menuData: null
309 property int menuIndex: -1
310 property bool serverChecked: menuData && menuData.isToggled || false
312 text: menuData && menuData.label || ""
313 enabled: menuData && menuData.sensitive || false
314 checked: serverChecked
315 highlightWhenPressed: false
317 ServerPropertySynchroniser {
318 objectName: "sync"
319 syncTimeout: Utils.Constants.indicatorValueTimeout
321 serverTarget: checkItem
322 serverProperty: "serverChecked"
323 userTarget: checkItem
324 userProperty: "checked"
326 onSyncTriggered: menuModel.activate(checkItem.menuIndex)
327 }
328 }
329 }
331 Component {
332 id: switchMenu;
334 Menus.SwitchMenu {
335 id: switchItem
336 objectName: "switchMenu"
337 property QtObject menuData: null
338 property int menuIndex: -1
339 property bool serverChecked: menuData && menuData.isToggled || false
341 text: menuData && menuData.label || ""
342 iconSource: menuData && menuData.icon || ""
343 enabled: menuData && menuData.sensitive || false
344 checked: serverChecked
345 highlightWhenPressed: false
347 ServerPropertySynchroniser {
348 objectName: "sync"
349 syncTimeout: Utils.Constants.indicatorValueTimeout
351 serverTarget: switchItem
352 serverProperty: "serverChecked"
353 userTarget: switchItem
354 userProperty: "checked"
356 onSyncTriggered: menuModel.activate(switchItem.menuIndex);
357 }
358 }
359 }
361 Component {
362 id: alarmMenu;
364 Menus.EventMenu {
365 id: alarmItem
366 objectName: "alarmMenu"
367 property QtObject menuData: null
368 property var menuModel: menuFactory.menuModel
369 property int menuIndex: -1
370 property var extendedData: menuData && menuData.ext || undefined
372 property date serverTime: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
373 LiveTimer {
374 frequency: LiveTimer.Relative
375 relativeTime: alarmItem.serverTime
376 onTrigger: alarmItem.serverTime = new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
377 }
379 text: menuData && menuData.label || ""
380 iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
381 time: i18n.relativeDateTime(serverTime)
382 enabled: menuData && menuData.sensitive || false
383 highlightWhenPressed: false
385 onMenuModelChanged: {
386 loadAttributes();
387 }
388 onMenuIndexChanged: {
389 loadAttributes();
390 }
391 onTriggered: {
392 menuModel.activate(menuIndex);
393 }
395 function loadAttributes() {
396 if (!menuModel || menuIndex == -1) return;
397 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64'});
398 }
399 }
400 }
402 Component {
403 id: appointmentMenu;
405 Menus.EventMenu {
406 id: appointmentItem
407 objectName: "appointmentMenu"
408 property QtObject menuData: null
409 property var menuModel: menuFactory.menuModel
410 property int menuIndex: -1
411 property var extendedData: menuData && menuData.ext || undefined
413 property date serverTime: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
414 LiveTimer {
415 frequency: LiveTimer.Relative
416 relativeTime: appointmentItem.serverTime
417 onTrigger: appointmentItem.serverTime = new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
418 }
420 text: menuData && menuData.label || ""
421 iconSource: menuData && menuData.icon || "image://theme/calendar"
422 time: i18n.relativeDateTime(serverTime)
423 eventColor: getExtendedProperty(extendedData, "xCanonicalColor", Qt.rgba(0.0, 0.0, 0.0, 0.0))
424 enabled: menuData && menuData.sensitive || false
425 highlightWhenPressed: false
427 onMenuModelChanged: {
428 loadAttributes();
429 }
430 onMenuIndexChanged: {
431 loadAttributes();
432 }
433 onTriggered: {
434 menuModel.activate(menuIndex);
435 }
437 function loadAttributes() {
438 if (!menuModel || menuIndex == -1) return;
439 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
440 'x-canonical-time': 'int64'});
441 }
442 }
443 }
445 Component {
446 id: userMenuItem
448 Menus.UserSessionMenu {
449 objectName: "userSessionMenu"
450 highlightWhenPressed: false
452 property QtObject menuData: null
453 property var menuModel: menuFactory.menuModel
454 property int menuIndex: -1
456 name: menuData && menuData.label || "" // label is the user's real name
457 iconSource: menuData && menuData.icon || ""
459 // would be better to compare with the logname but sadly the indicator doesn't expose that
460 active: DBusUnitySessionService.RealName() !== "" ? DBusUnitySessionService.RealName() == name
461 : DBusUnitySessionService.UserName() == name
463 onTriggered: {
464 menuModel.activate(menuIndex);
465 }
466 }
467 }
469 Component {
470 id: calendarMenu
472 Menus.CalendarMenu {
473 objectName: "calendarMenu"
474 highlightWhenPressed: false
475 focus: true
476 }
477 }
479 Component {
480 id: timezoneMenu
482 Menus.TimeZoneMenu {
483 id: tzMenuItem
484 objectName: "timezoneMenu"
486 property QtObject menuData: null
487 property var menuModel: menuFactory.menuModel
488 property int menuIndex: -1
489 property var extendedData: menuData && menuData.ext || undefined
490 readonly property string tz: getExtendedProperty(extendedData, "xCanonicalTimezone", "UTC")
491 property var updateTimer: Timer {
492 repeat: true
493 running: tzMenuItem.visible // only run when we're open
494 onTriggered: tzMenuItem.time = Utils.TimezoneFormatter.currentTimeInTimezone(tzMenuItem.tz)
495 }
497 city: menuData && menuData.label || ""
498 time: Utils.TimezoneFormatter.currentTimeInTimezone(tz)
499 enabled: menuData && menuData.sensitive || false
501 onMenuModelChanged: {
502 loadAttributes();
503 }
504 onMenuIndexChanged: {
505 loadAttributes();
506 }
507 onTriggered: {
508 tzActionGroup.setLocation.activate(tz);
509 }
511 QDBusActionGroup {
512 id: tzActionGroup
513 busType: DBus.SessionBus
514 busName: "com.canonical.indicator.datetime"
515 objectPath: "/com/canonical/indicator/datetime"
517 property variant setLocation: action("set-location")
519 Component.onCompleted: tzActionGroup.start()
520 }
522 function loadAttributes() {
523 if (!menuModel || menuIndex == -1) return;
524 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-timezone': 'string'});
525 }
526 }
527 }
529 Component {
530 id: wifiSection;
532 Menus.SectionMenu {
533 objectName: "wifiSection"
534 property QtObject menuData: null
535 property var menuModel: menuFactory.menuModel
536 property int menuIndex: -1
537 property var extendedData: menuData && menuData.ext || undefined
539 text: menuData && menuData.label || ""
540 busy: getExtendedProperty(extendedData, "xCanonicalBusyAction", false)
542 onMenuModelChanged: {
543 loadAttributes();
544 }
545 onMenuIndexChanged: {
546 loadAttributes();
547 }
549 function loadAttributes() {
550 if (!menuModel || menuIndex == -1) return;
551 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
552 }
553 }
554 }
556 Component {
557 id: accessPoint;
559 Menus.AccessPointMenu {
560 id: apItem
561 objectName: "accessPoint"
562 property QtObject menuData: null
563 property var menuModel: menuFactory.menuModel
564 property int menuIndex: -1
565 property var extendedData: menuData && menuData.ext || undefined
566 property bool serverChecked: menuData && menuData.isToggled || false
568 property var strengthAction: UnityMenuAction {
569 model: menuModel
570 index: menuIndex
571 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
572 }
574 text: menuData && menuData.label || ""
575 enabled: menuData && menuData.sensitive || false
576 active: serverChecked
577 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
578 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
579 signalStrength: strengthAction.valid ? strengthAction.state : 0
580 highlightWhenPressed: false
582 onMenuModelChanged: {
583 loadAttributes();
584 }
585 onMenuIndexChanged: {
586 loadAttributes();
587 }
589 function loadAttributes() {
590 if (!menuModel || menuIndex == -1) return;
591 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
592 'x-canonical-wifi-ap-is-secure': 'bool',
593 'x-canonical-wifi-ap-strength-action': 'string'});
594 }
596 ServerPropertySynchroniser {
597 objectName: "sync"
598 syncTimeout: Utils.Constants.indicatorValueTimeout
600 serverTarget: apItem
601 serverProperty: "serverChecked"
602 userTarget: apItem
603 userProperty: "active"
604 userTrigger: "onTriggered"
606 onSyncTriggered: menuModel.activate(apItem.menuIndex)
607 }
608 }
609 }
611 Component {
612 id: modeminfoitem;
613 ModemInfoItem {
614 objectName: "modemInfoItem"
615 property QtObject menuData: null
616 property var menuModel: menuFactory.menuModel
617 property int menuIndex: -1
618 property var extendedData: menuData && menuData.ext || undefined
619 highlightWhenPressed: false
621 property var statusLabelAction: UnityMenuAction {
622 model: menuModel
623 index: menuIndex
624 name: getExtendedProperty(extendedData, "xCanonicalModemStatusLabelAction", "")
625 }
626 statusText: statusLabelAction.valid ? statusLabelAction.state : ""
628 property var statusIconAction: UnityMenuAction {
629 model: menuModel
630 index: menuIndex
631 name: getExtendedProperty(extendedData, "xCanonicalModemStatusIconAction", "")
632 }
633 statusIcon: statusIconAction.valid ? statusIconAction.state : ""
635 property var connectivityIconAction: UnityMenuAction {
636 model: menuModel
637 index: menuIndex
638 name: getExtendedProperty(extendedData, "xCanonicalModemConnectivityIconAction", "")
639 }
640 connectivityIcon: connectivityIconAction.valid ? connectivityIconAction.state : ""
642 property var simIdentifierLabelAction: UnityMenuAction {
643 model: menuModel
644 index: menuIndex
645 name: getExtendedProperty(extendedData, "xCanonicalModemSimIdentifierLabelAction", "")
646 }
647 simIdentifierText: simIdentifierLabelAction.valid ? simIdentifierLabelAction.state : ""
649 property var roamingAction: UnityMenuAction {
650 model: menuModel
651 index: menuIndex
652 name: getExtendedProperty(extendedData, "xCanonicalModemRoamingAction", "")
653 }
654 roaming: roamingAction.valid ? roamingAction.state : false
656 property var unlockAction: UnityMenuAction {
657 model: menuModel
658 index: menuIndex
659 name: getExtendedProperty(extendedData, "xCanonicalModemLockedAction", "")
660 }
661 onUnlock: {
662 unlockAction.activate();
663 }
664 locked: unlockAction.valid ? unlockAction.state : false
666 onMenuModelChanged: {
667 loadAttributes();
668 }
669 onMenuIndexChanged: {
670 loadAttributes();
671 }
673 function loadAttributes() {
674 if (!menuModel || menuIndex == -1) return;
675 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-modem-status-label-action': 'string',
676 'x-canonical-modem-status-icon-action': 'string',
677 'x-canonical-modem-connectivity-icon-action': 'string',
678 'x-canonical-modem-sim-identifier-label-action': 'string',
679 'x-canonical-modem-roaming-action': 'string',
680 'x-canonical-modem-locked-action': 'string'});
681 }
682 }
683 }
685 Component {
686 id: messageItem
688 MessageMenuItemFactory {
689 objectName: "messageItem"
690 menuModel: menuFactory.menuModel
691 }
692 }
694 Component {
695 id: groupedMessage
697 Menus.GroupedMessageMenu {
698 objectName: "groupedMessage"
699 property QtObject menuData: null
700 property var menuModel: menuFactory.menuModel
701 property int menuIndex: -1
702 property var extendedData: menuData && menuData.ext || undefined
704 text: menuData && menuData.label || ""
705 iconSource: getExtendedProperty(extendedData, "icon", "image://theme/message")
706 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
707 enabled: menuData && menuData.sensitive || false
708 highlightWhenPressed: false
709 removable: true
711 onMenuModelChanged: {
712 loadAttributes();
713 }
714 onMenuIndexChanged: {
715 loadAttributes();
716 }
717 onClicked: {
718 menuModel.activate(menuIndex, true);
719 }
720 onDismissed: {
721 menuModel.activate(menuIndex, false);
722 }
724 function loadAttributes() {
725 if (!menuModel || menuIndex == -1) return;
726 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
727 }
728 }
729 }
731 Component {
732 id: mediaPayerMenu;
734 Menus.MediaPlayerMenu {
735 objectName: "mediaPayerMenu"
736 property QtObject menuData: null
737 property var menuModel: menuFactory.menuModel
738 property int menuIndex: -1
739 property var actionState: menuData && menuData.actionState || undefined
740 property bool running: getExtendedProperty(actionState, "running", false)
742 playerIcon: menuData && menuData.icon || "image://theme/stock_music"
743 playerName: menuData && menuData.label || i18n.tr("Nothing is playing")
745 albumArt: getExtendedProperty(actionState, "art-url", "image://theme/stock_music")
746 song: getExtendedProperty(actionState, "title", "")
747 artist: getExtendedProperty(actionState, "artist", "")
748 album: getExtendedProperty(actionState, "album", "")
749 showTrack: running && (state == "Playing" || state == "Paused")
750 state: getExtendedProperty(actionState, "state", "")
751 enabled: menuData && menuData.sensitive || false
752 highlightWhenPressed: false
753 showDivider: false
755 onTriggered: {
756 model.activate(modelIndex);
757 }
758 }
759 }
761 Component {
762 id: playbackItemMenu;
764 Menus.PlaybackItemMenu {
765 objectName: "playbackItemMenu"
766 property QtObject menuData: null
767 property var menuModel: menuFactory.menuModel
768 property int menuIndex: -1
769 property var extendedData: menuData && menuData.ext || undefined
771 property var playAction: UnityMenuAction {
772 model: menuModel
773 index: menuIndex
774 name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
775 }
776 property var nextAction: UnityMenuAction {
777 model: menuModel
778 index: menuIndex
779 name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
780 }
781 property var previousAction: UnityMenuAction {
782 model: menuModel
783 index: menuIndex
784 name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
785 }
787 playing: playAction.state === "Playing"
788 canPlay: playAction.valid
789 canGoNext: nextAction.valid
790 canGoPrevious: previousAction.valid
791 enabled: menuData && menuData.sensitive || false
792 highlightWhenPressed: false
794 onPlay: {
795 playAction.activate();
796 }
797 onNext: {
798 nextAction.activate();
799 }
800 onPrevious: {
801 previousAction.activate();
802 }
803 onMenuModelChanged: {
804 loadAttributes();
805 }
806 onMenuIndexChanged: {
807 loadAttributes();
808 }
810 function loadAttributes() {
811 if (!menuModel || menuIndex == -1) return;
812 menuModel.loadExtendedAttributes(modelIndex, {'x-canonical-play-action': 'string',
813 'x-canonical-next-action': 'string',
814 'x-canonical-previous-action': 'string'});
815 }
816 }
817 }
819 Component {
820 id: transferMenu
822 Menus.TransferMenu {
823 objectName: "transferMenu"
824 id: transfer
825 property QtObject menuData: null
826 property var menuModel: menuFactory.menuModel
827 property int menuIndex: -1
828 property var extendedData: menuData && menuData.ext || undefined
829 property var uid: getExtendedProperty(extendedData, "xCanonicalUid", undefined)
831 text: menuData && menuData.label || ""
832 iconSource: menuData && menuData.icon || "image://theme/transfer-none"
833 maximum: 1.0
834 enabled: menuData && menuData.sensitive || false
835 highlightWhenPressed: false
836 removable: true
837 confirmRemoval: true
839 QDBusActionGroup {
840 id: actionGroup
841 busType: 1
842 busName: rootModel.busName
843 objectPath: rootModel.actions["indicator"]
845 property var activateAction: action("activate-transfer")
846 property var cancelAction: action("cancel-transfer")
847 property var transferStateAction: uid !== undefined ? action("transfer-state."+uid) : null
849 Component.onCompleted: actionGroup.start()
850 }
852 property var transferState: {
853 if (actionGroup.transferStateAction === null) return undefined;
854 return actionGroup.transferStateAction.valid ? actionGroup.transferStateAction.state : undefined
855 }
857 property var runningState : transferState !== undefined ? transferState["state"] : undefined
858 property var secondsLeft : transferState !== undefined ? transferState["seconds-left"] : undefined
860 active: runningState !== undefined && runningState !== Menus.TransferState.Finished
861 progress: transferState !== undefined ? transferState["percent"] : 0.0
863 // TODO - Should be in the SDK
864 property var timeRemaining: {
865 if (secondsLeft === undefined) return undefined;
867 var remaining = "";
868 var hours = Math.floor(secondsLeft / (60 * 60));
869 var minutes = Math.floor(secondsLeft / 60) % 60;
870 var seconds = secondsLeft % 60;
871 if (hours > 0) {
872 remaining += i18n.tr("%1 hour", "%1 hours", hours).arg(hours)
873 }
874 if (minutes > 0) {
875 if (remaining != "") remaining += ", ";
876 remaining += i18n.tr("%1 minute", "%1 minutes", minutes).arg(minutes)
877 }
878 // don't include seconds if hours > 0
879 if (hours == 0 && minutes < 5 && seconds > 0) {
880 if (remaining != "") remaining += ", ";
881 remaining += i18n.tr("%1 second", "%1 seconds", seconds).arg(seconds)
882 }
883 if (remaining == "")
884 remaining = i18n.tr("0 seconds");
885 // Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
886 return i18n.tr("%1 remaining").arg(remaining);
887 }
889 stateText: {
890 switch (runningState) {
891 case Menus.TransferState.Queued:
892 return i18n.tr("In queue…");
893 case Menus.TransferState.Hashing:
894 case Menus.TransferState.Processing:
895 case Menus.TransferState.Running:
896 return timeRemaining === undefined ? i18n.tr("Downloading") : timeRemaining;
897 case Menus.TransferState.Paused:
898 return i18n.tr("Paused, tap to resume");
899 case Menus.TransferState.Canceled:
900 return i18n.tr("Canceled");
901 case Menus.TransferState.Finished:
902 return i18n.tr("Finished");
903 case Menus.TransferState.Error:
904 return i18n.tr("Failed, tap to retry");
905 }
906 return "";
907 }
909 onMenuModelChanged: {
910 loadAttributes();
911 }
912 onMenuIndexChanged: {
913 loadAttributes();
914 }
915 onTriggered: {
916 actionGroup.activateAction.activate(uid);
917 }
918 onItemRemoved: {
919 actionGroup.cancelAction.activate(uid);
920 }
922 function loadAttributes() {
923 if (!menuModel || menuIndex == -1) return;
924 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-uid': 'string'});
925 }
926 }
927 }
929 Component {
930 id: buttonSectionMenu;
932 Menus.StandardMenu {
933 objectName: "buttonSectionMenu"
934 property QtObject menuData: null
935 property var menuModel: menuFactory.menuModel
936 property int menuIndex: -1
937 property var extendedData: menuData && menuData.ext || undefined
939 iconSource: menuData && menuData.icon || ""
940 enabled: menuData && menuData.sensitive || false
941 highlightWhenPressed: false
942 text: menuData && menuData.label || ""
943 foregroundColor: theme.palette.normal.backgroundText
945 onMenuModelChanged: {
946 loadAttributes();
947 }
948 onMenuIndexChanged: {
949 loadAttributes();
950 }
951 function loadAttributes() {
952 if (!menuModel || menuIndex == -1) return;
953 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-extra-label': 'string'});
954 }
956 component: Component {
957 Button {
958 objectName: "buttonSectionMenuControl"
959 text: getExtendedProperty(extendedData, "xCanonicalExtraLabel", "")
961 onClicked: {
962 menuModel.activate(menuIndex);
963 }
964 }
965 }
966 }
967 }
969 function load(modelData, context) {
970 if (modelData.type !== undefined && modelData.type !== "") {
971 var component = undefined;
973 var contextComponents = _map[context];
974 if (contextComponents !== undefined) {
975 component = contextComponents[modelData.type];
976 }
978 if (component === undefined) {
979 component = _map["default"][modelData.type];
980 }
981 if (component !== undefined) {
982 return component;
983 }
984 console.debug("Don't know how to make " + modelData.type + " for " + context);
985 }
986 if (modelData.isCheck || modelData.isRadio) {
987 return checkableMenu;
988 }
989 if (modelData.isSeparator) {
990 return separatorMenu;
991 }
992 return standardMenu;
993 }