on fa2f331 help sign in
unity8/qml/Panel/Indicators/MenuItemFactory.qml
982 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 }
131 ServerPropertySynchroniser {
132 objectName: "sync"
133 syncTimeout: Utils.Constants.indicatorValueTimeout
134 bufferedSyncTimeout: true
135 maximumWaitBufferInterval: 16
137 serverTarget: sliderItem
138 serverProperty: "serverValue"
139 userTarget: sliderItem
140 userProperty: "value"
142 onSyncTriggered: menuModel.changeState(menuIndex, value)
143 }
144 }
145 }
147 Component {
148 id: buttonMenu;
150 Menus.ButtonMenu {
151 objectName: "buttonMenu"
152 property QtObject menuData: null
153 property var menuModel: menuFactory.menuModel
154 property int menuIndex: -1
156 buttonText: menuData && menuData.label || ""
157 enabled: menuData && menuData.sensitive || false
158 highlightWhenPressed: false
160 onTriggered: {
161 menuModel.activate(menuIndex);
162 }
163 }
164 }
166 Component {
167 id: messagesButtonMenu;
169 Item {
170 objectName: "messagesButtonMenu"
171 property QtObject menuData: null
172 property var menuModel: menuFactory.menuModel
173 property int menuIndex: -1
175 implicitHeight: units.gu(5)
176 enabled: menuData && menuData.sensitive || false
178 Label {
179 id: buttonMenuLabel
180 text: menuData && menuData.label || ""
181 anchors.centerIn: parent
182 font.bold: true
183 }
185 MouseArea {
186 anchors {
187 fill: buttonMenuLabel
188 margins: units.gu(-1)
189 }
190 onClicked: menuModel.activate(menuIndex);
191 }
192 }
193 }
195 Component {
196 id: sectionMenu;
198 Menus.SectionMenu {
199 objectName: "sectionMenu"
200 property QtObject menuData: null
201 property var menuIndex: undefined
203 text: menuData && menuData.label || ""
204 busy: false
205 }
206 }
208 Component {
209 id: progressMenu;
211 Menus.ProgressValueMenu {
212 objectName: "progressMenu"
213 property QtObject menuData: null
214 property int menuIndex: -1
216 text: menuData && menuData.label || ""
217 iconSource: menuData && menuData.icon || ""
218 value : menuData && menuData.actionState || 0.0
219 enabled: menuData && menuData.sensitive || false
220 highlightWhenPressed: false
221 }
222 }
224 Component {
225 id: standardMenu;
227 Menus.StandardMenu {
228 objectName: "standardMenu"
229 property QtObject menuData: null
230 property int menuIndex: -1
232 text: menuData && menuData.label || ""
233 iconSource: menuData && menuData.icon || ""
234 enabled: menuData && menuData.sensitive || false
235 highlightWhenPressed: false
237 onTriggered: {
238 menuModel.activate(menuIndex);
239 }
241 // FIXME : At the moment, the indicators aren't using
242 // com.canonical.indicators.link for settings menu. Need to fudge it.
243 property bool settingsMenu: menuData && menuData.action.indexOf("settings") > -1 || false
244 backColor: settingsMenu ? Qt.rgba(1,1,1,0.07) : "transparent"
245 component: settingsMenu ? buttonForSettings : undefined
246 Component {
247 id: buttonForSettings
248 Icon {
249 name: "settings"
250 height: units.gu(3)
251 width: height
252 color: theme.palette.selected.backgroundText
253 }
254 }
255 }
256 }
258 Component {
259 id: linkMenu;
261 Menus.StandardMenu {
262 objectName: "linkMenu"
263 property QtObject menuData: null
264 property int menuIndex: -1
266 text: menuData && menuData.label || ""
267 iconSource: menuData && menuData.icon || ""
268 enabled: menuData && menuData.sensitive || false
269 highlightWhenPressed: false
271 onTriggered: {
272 menuModel.activate(menuIndex);
273 }
275 backColor: Qt.rgba(1,1,1,0.07)
277 component: menuData.icon ? icon : undefined
278 Component {
279 id: icon
280 Icon {
281 source: menuData.icon
282 height: units.gu(3)
283 width: height
284 color: theme.palette.selected.backgroundText
285 }
286 }
287 }
288 }
290 Component {
291 id: checkableMenu;
293 Menus.CheckableMenu {
294 id: checkItem
295 objectName: "checkableMenu"
296 property QtObject menuData: null
297 property int menuIndex: -1
298 property bool serverChecked: menuData && menuData.isToggled || false
300 text: menuData && menuData.label || ""
301 enabled: menuData && menuData.sensitive || false
302 checked: serverChecked
303 highlightWhenPressed: false
305 ServerPropertySynchroniser {
306 objectName: "sync"
307 syncTimeout: Utils.Constants.indicatorValueTimeout
309 serverTarget: checkItem
310 serverProperty: "serverChecked"
311 userTarget: checkItem
312 userProperty: "checked"
314 onSyncTriggered: menuModel.activate(checkItem.menuIndex)
315 }
316 }
317 }
319 Component {
320 id: switchMenu;
322 Menus.SwitchMenu {
323 id: switchItem
324 objectName: "switchMenu"
325 property QtObject menuData: null
326 property int menuIndex: -1
327 property bool serverChecked: menuData && menuData.isToggled || false
329 text: menuData && menuData.label || ""
330 iconSource: menuData && menuData.icon || ""
331 enabled: menuData && menuData.sensitive || false
332 checked: serverChecked
333 highlightWhenPressed: false
335 ServerPropertySynchroniser {
336 objectName: "sync"
337 syncTimeout: Utils.Constants.indicatorValueTimeout
339 serverTarget: switchItem
340 serverProperty: "serverChecked"
341 userTarget: switchItem
342 userProperty: "checked"
344 onSyncTriggered: menuModel.activate(switchItem.menuIndex);
345 }
346 }
347 }
349 Component {
350 id: alarmMenu;
352 Menus.EventMenu {
353 id: alarmItem
354 objectName: "alarmMenu"
355 property QtObject menuData: null
356 property var menuModel: menuFactory.menuModel
357 property int menuIndex: -1
358 property var extendedData: menuData && menuData.ext || undefined
360 property date serverTime: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
361 LiveTimer {
362 frequency: LiveTimer.Relative
363 relativeTime: alarmItem.serverTime
364 onTrigger: alarmItem.serverTime = new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
365 }
367 text: menuData && menuData.label || ""
368 iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
369 time: i18n.relativeDateTime(serverTime)
370 enabled: menuData && menuData.sensitive || false
371 highlightWhenPressed: false
373 onMenuModelChanged: {
374 loadAttributes();
375 }
376 onMenuIndexChanged: {
377 loadAttributes();
378 }
379 onTriggered: {
380 menuModel.activate(menuIndex);
381 }
383 function loadAttributes() {
384 if (!menuModel || menuIndex == -1) return;
385 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64'});
386 }
387 }
388 }
390 Component {
391 id: appointmentMenu;
393 Menus.EventMenu {
394 id: appointmentItem
395 objectName: "appointmentMenu"
396 property QtObject menuData: null
397 property var menuModel: menuFactory.menuModel
398 property int menuIndex: -1
399 property var extendedData: menuData && menuData.ext || undefined
401 property date serverTime: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
402 LiveTimer {
403 frequency: LiveTimer.Relative
404 relativeTime: appointmentItem.serverTime
405 onTrigger: appointmentItem.serverTime = new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
406 }
408 text: menuData && menuData.label || ""
409 iconSource: menuData && menuData.icon || "image://theme/calendar"
410 time: i18n.relativeDateTime(serverTime)
411 eventColor: getExtendedProperty(extendedData, "xCanonicalColor", Qt.rgba(0.0, 0.0, 0.0, 0.0))
412 enabled: menuData && menuData.sensitive || false
413 highlightWhenPressed: false
415 onMenuModelChanged: {
416 loadAttributes();
417 }
418 onMenuIndexChanged: {
419 loadAttributes();
420 }
421 onTriggered: {
422 menuModel.activate(menuIndex);
423 }
425 function loadAttributes() {
426 if (!menuModel || menuIndex == -1) return;
427 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
428 'x-canonical-time': 'int64'});
429 }
430 }
431 }
433 Component {
434 id: userMenuItem
436 Menus.UserSessionMenu {
437 objectName: "userSessionMenu"
438 highlightWhenPressed: false
440 property QtObject menuData: null
441 property var menuModel: menuFactory.menuModel
442 property int menuIndex: -1
444 name: menuData && menuData.label || "" // label is the user's real name
445 iconSource: menuData && menuData.icon || ""
447 // would be better to compare with the logname but sadly the indicator doesn't expose that
448 active: DBusUnitySessionService.RealName() !== "" ? DBusUnitySessionService.RealName() == name
449 : DBusUnitySessionService.UserName() == name
451 onTriggered: {
452 menuModel.activate(menuIndex);
453 }
454 }
455 }
457 Component {
458 id: calendarMenu
460 Menus.CalendarMenu {
461 objectName: "calendarMenu"
462 highlightWhenPressed: false
463 focus: true
464 }
465 }
467 Component {
468 id: timezoneMenu
470 Menus.TimeZoneMenu {
471 id: tzMenuItem
472 objectName: "timezoneMenu"
474 property QtObject menuData: null
475 property var menuModel: menuFactory.menuModel
476 property int menuIndex: -1
477 property var extendedData: menuData && menuData.ext || undefined
478 readonly property string tz: getExtendedProperty(extendedData, "xCanonicalTimezone", "UTC")
479 property var updateTimer: Timer {
480 repeat: true
481 running: tzMenuItem.visible // only run when we're open
482 onTriggered: tzMenuItem.time = Utils.TimezoneFormatter.currentTimeInTimezone(tzMenuItem.tz)
483 }
485 city: menuData && menuData.label || ""
486 time: Utils.TimezoneFormatter.currentTimeInTimezone(tz)
487 enabled: menuData && menuData.sensitive || false
489 onMenuModelChanged: {
490 loadAttributes();
491 }
492 onMenuIndexChanged: {
493 loadAttributes();
494 }
495 onTriggered: {
496 tzActionGroup.setLocation.activate(tz);
497 }
499 QDBusActionGroup {
500 id: tzActionGroup
501 busType: DBus.SessionBus
502 busName: "com.canonical.indicator.datetime"
503 objectPath: "/com/canonical/indicator/datetime"
505 property variant setLocation: action("set-location")
507 Component.onCompleted: tzActionGroup.start()
508 }
510 function loadAttributes() {
511 if (!menuModel || menuIndex == -1) return;
512 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-timezone': 'string'});
513 }
514 }
515 }
517 Component {
518 id: wifiSection;
520 Menus.SectionMenu {
521 objectName: "wifiSection"
522 property QtObject menuData: null
523 property var menuModel: menuFactory.menuModel
524 property int menuIndex: -1
525 property var extendedData: menuData && menuData.ext || undefined
527 text: menuData && menuData.label || ""
528 busy: getExtendedProperty(extendedData, "xCanonicalBusyAction", false)
530 onMenuModelChanged: {
531 loadAttributes();
532 }
533 onMenuIndexChanged: {
534 loadAttributes();
535 }
537 function loadAttributes() {
538 if (!menuModel || menuIndex == -1) return;
539 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
540 }
541 }
542 }
544 Component {
545 id: accessPoint;
547 Menus.AccessPointMenu {
548 id: apItem
549 objectName: "accessPoint"
550 property QtObject menuData: null
551 property var menuModel: menuFactory.menuModel
552 property int menuIndex: -1
553 property var extendedData: menuData && menuData.ext || undefined
554 property bool serverChecked: menuData && menuData.isToggled || false
556 property var strengthAction: UnityMenuAction {
557 model: menuModel
558 index: menuIndex
559 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
560 }
562 text: menuData && menuData.label || ""
563 enabled: menuData && menuData.sensitive || false
564 active: serverChecked
565 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
566 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
567 signalStrength: strengthAction.valid ? strengthAction.state : 0
568 highlightWhenPressed: false
570 onMenuModelChanged: {
571 loadAttributes();
572 }
573 onMenuIndexChanged: {
574 loadAttributes();
575 }
577 function loadAttributes() {
578 if (!menuModel || menuIndex == -1) return;
579 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
580 'x-canonical-wifi-ap-is-secure': 'bool',
581 'x-canonical-wifi-ap-strength-action': 'string'});
582 }
584 ServerPropertySynchroniser {
585 objectName: "sync"
586 syncTimeout: Utils.Constants.indicatorValueTimeout
588 serverTarget: apItem
589 serverProperty: "serverChecked"
590 userTarget: apItem
591 userProperty: "active"
592 userTrigger: "onTriggered"
594 onSyncTriggered: menuModel.activate(apItem.menuIndex)
595 }
596 }
597 }
599 Component {
600 id: modeminfoitem;
601 ModemInfoItem {
602 objectName: "modemInfoItem"
603 property QtObject menuData: null
604 property var menuModel: menuFactory.menuModel
605 property int menuIndex: -1
606 property var extendedData: menuData && menuData.ext || undefined
607 highlightWhenPressed: false
609 property var statusLabelAction: UnityMenuAction {
610 model: menuModel
611 index: menuIndex
612 name: getExtendedProperty(extendedData, "xCanonicalModemStatusLabelAction", "")
613 }
614 statusText: statusLabelAction.valid ? statusLabelAction.state : ""
616 property var statusIconAction: UnityMenuAction {
617 model: menuModel
618 index: menuIndex
619 name: getExtendedProperty(extendedData, "xCanonicalModemStatusIconAction", "")
620 }
621 statusIcon: statusIconAction.valid ? statusIconAction.state : ""
623 property var connectivityIconAction: UnityMenuAction {
624 model: menuModel
625 index: menuIndex
626 name: getExtendedProperty(extendedData, "xCanonicalModemConnectivityIconAction", "")
627 }
628 connectivityIcon: connectivityIconAction.valid ? connectivityIconAction.state : ""
630 property var simIdentifierLabelAction: UnityMenuAction {
631 model: menuModel
632 index: menuIndex
633 name: getExtendedProperty(extendedData, "xCanonicalModemSimIdentifierLabelAction", "")
634 }
635 simIdentifierText: simIdentifierLabelAction.valid ? simIdentifierLabelAction.state : ""
637 property var roamingAction: UnityMenuAction {
638 model: menuModel
639 index: menuIndex
640 name: getExtendedProperty(extendedData, "xCanonicalModemRoamingAction", "")
641 }
642 roaming: roamingAction.valid ? roamingAction.state : false
644 property var unlockAction: UnityMenuAction {
645 model: menuModel
646 index: menuIndex
647 name: getExtendedProperty(extendedData, "xCanonicalModemLockedAction", "")
648 }
649 onUnlock: {
650 unlockAction.activate();
651 }
652 locked: unlockAction.valid ? unlockAction.state : false
654 onMenuModelChanged: {
655 loadAttributes();
656 }
657 onMenuIndexChanged: {
658 loadAttributes();
659 }
661 function loadAttributes() {
662 if (!menuModel || menuIndex == -1) return;
663 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-modem-status-label-action': 'string',
664 'x-canonical-modem-status-icon-action': 'string',
665 'x-canonical-modem-connectivity-icon-action': 'string',
666 'x-canonical-modem-sim-identifier-label-action': 'string',
667 'x-canonical-modem-roaming-action': 'string',
668 'x-canonical-modem-locked-action': 'string'});
669 }
670 }
671 }
673 Component {
674 id: messageItem
676 MessageMenuItemFactory {
677 objectName: "messageItem"
678 menuModel: menuFactory.menuModel
679 }
680 }
682 Component {
683 id: groupedMessage
685 Menus.GroupedMessageMenu {
686 objectName: "groupedMessage"
687 property QtObject menuData: null
688 property var menuModel: menuFactory.menuModel
689 property int menuIndex: -1
690 property var extendedData: menuData && menuData.ext || undefined
692 text: menuData && menuData.label || ""
693 iconSource: getExtendedProperty(extendedData, "icon", "image://theme/message")
694 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
695 enabled: menuData && menuData.sensitive || false
696 highlightWhenPressed: false
697 removable: true
699 onMenuModelChanged: {
700 loadAttributes();
701 }
702 onMenuIndexChanged: {
703 loadAttributes();
704 }
705 onClicked: {
706 menuModel.activate(menuIndex, true);
707 }
708 onDismissed: {
709 menuModel.activate(menuIndex, false);
710 }
712 function loadAttributes() {
713 if (!menuModel || menuIndex == -1) return;
714 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
715 }
716 }
717 }
719 Component {
720 id: mediaPayerMenu;
722 Menus.MediaPlayerMenu {
723 objectName: "mediaPayerMenu"
724 property QtObject menuData: null
725 property var menuModel: menuFactory.menuModel
726 property int menuIndex: -1
727 property var actionState: menuData && menuData.actionState || undefined
728 property bool running: getExtendedProperty(actionState, "running", false)
730 playerIcon: menuData && menuData.icon || "image://theme/stock_music"
731 playerName: menuData && menuData.label || i18n.tr("Nothing is playing")
733 albumArt: getExtendedProperty(actionState, "art-url", "image://theme/stock_music")
734 song: getExtendedProperty(actionState, "title", "")
735 artist: getExtendedProperty(actionState, "artist", "")
736 album: getExtendedProperty(actionState, "album", "")
737 showTrack: running && (state == "Playing" || state == "Paused")
738 state: getExtendedProperty(actionState, "state", "")
739 enabled: menuData && menuData.sensitive || false
740 highlightWhenPressed: false
741 showDivider: false
743 onTriggered: {
744 model.activate(modelIndex);
745 }
746 }
747 }
749 Component {
750 id: playbackItemMenu;
752 Menus.PlaybackItemMenu {
753 objectName: "playbackItemMenu"
754 property QtObject menuData: null
755 property var menuModel: menuFactory.menuModel
756 property int menuIndex: -1
757 property var extendedData: menuData && menuData.ext || undefined
759 property var playAction: UnityMenuAction {
760 model: menuModel
761 index: menuIndex
762 name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
763 }
764 property var nextAction: UnityMenuAction {
765 model: menuModel
766 index: menuIndex
767 name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
768 }
769 property var previousAction: UnityMenuAction {
770 model: menuModel
771 index: menuIndex
772 name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
773 }
775 playing: playAction.state === "Playing"
776 canPlay: playAction.valid
777 canGoNext: nextAction.valid
778 canGoPrevious: previousAction.valid
779 enabled: menuData && menuData.sensitive || false
780 highlightWhenPressed: false
782 onPlay: {
783 playAction.activate();
784 }
785 onNext: {
786 nextAction.activate();
787 }
788 onPrevious: {
789 previousAction.activate();
790 }
791 onMenuModelChanged: {
792 loadAttributes();
793 }
794 onMenuIndexChanged: {
795 loadAttributes();
796 }
798 function loadAttributes() {
799 if (!menuModel || menuIndex == -1) return;
800 menuModel.loadExtendedAttributes(modelIndex, {'x-canonical-play-action': 'string',
801 'x-canonical-next-action': 'string',
802 'x-canonical-previous-action': 'string'});
803 }
804 }
805 }
807 Component {
808 id: transferMenu
810 Menus.TransferMenu {
811 objectName: "transferMenu"
812 id: transfer
813 property QtObject menuData: null
814 property var menuModel: menuFactory.menuModel
815 property int menuIndex: -1
816 property var extendedData: menuData && menuData.ext || undefined
817 property var uid: getExtendedProperty(extendedData, "xCanonicalUid", undefined)
819 text: menuData && menuData.label || ""
820 iconSource: menuData && menuData.icon || "image://theme/transfer-none"
821 maximum: 1.0
822 enabled: menuData && menuData.sensitive || false
823 highlightWhenPressed: false
824 removable: true
825 confirmRemoval: true
827 QDBusActionGroup {
828 id: actionGroup
829 busType: 1
830 busName: rootModel.busName
831 objectPath: rootModel.actions["indicator"]
833 property var activateAction: action("activate-transfer")
834 property var cancelAction: action("cancel-transfer")
835 property var transferStateAction: uid !== undefined ? action("transfer-state."+uid) : null
837 Component.onCompleted: actionGroup.start()
838 }
840 property var transferState: {
841 if (actionGroup.transferStateAction === null) return undefined;
842 return actionGroup.transferStateAction.valid ? actionGroup.transferStateAction.state : undefined
843 }
845 property var runningState : transferState !== undefined ? transferState["state"] : undefined
846 property var secondsLeft : transferState !== undefined ? transferState["seconds-left"] : undefined
848 active: runningState !== undefined && runningState !== Menus.TransferState.Finished
849 progress: transferState !== undefined ? transferState["percent"] : 0.0
851 // TODO - Should be in the SDK
852 property var timeRemaining: {
853 if (secondsLeft === undefined) return undefined;
855 var remaining = "";
856 var hours = Math.floor(secondsLeft / (60 * 60));
857 var minutes = Math.floor(secondsLeft / 60) % 60;
858 var seconds = secondsLeft % 60;
859 if (hours > 0) {
860 remaining += i18n.tr("%1 hour", "%1 hours", hours).arg(hours)
861 }
862 if (minutes > 0) {
863 if (remaining != "") remaining += ", ";
864 remaining += i18n.tr("%1 minute", "%1 minutes", minutes).arg(minutes)
865 }
866 // don't include seconds if hours > 0
867 if (hours == 0 && minutes < 5 && seconds > 0) {
868 if (remaining != "") remaining += ", ";
869 remaining += i18n.tr("%1 second", "%1 seconds", seconds).arg(seconds)
870 }
871 if (remaining == "")
872 remaining = i18n.tr("0 seconds");
873 // Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
874 return i18n.tr("%1 remaining").arg(remaining);
875 }
877 stateText: {
878 switch (runningState) {
879 case Menus.TransferState.Queued:
880 return i18n.tr("In queue…");
881 case Menus.TransferState.Hashing:
882 case Menus.TransferState.Processing:
883 case Menus.TransferState.Running:
884 return timeRemaining === undefined ? i18n.tr("Downloading") : timeRemaining;
885 case Menus.TransferState.Paused:
886 return i18n.tr("Paused, tap to resume");
887 case Menus.TransferState.Canceled:
888 return i18n.tr("Canceled");
889 case Menus.TransferState.Finished:
890 return i18n.tr("Finished");
891 case Menus.TransferState.Error:
892 return i18n.tr("Failed, tap to retry");
893 }
894 return "";
895 }
897 onMenuModelChanged: {
898 loadAttributes();
899 }
900 onMenuIndexChanged: {
901 loadAttributes();
902 }
903 onTriggered: {
904 actionGroup.activateAction.activate(uid);
905 }
906 onItemRemoved: {
907 actionGroup.cancelAction.activate(uid);
908 }
910 function loadAttributes() {
911 if (!menuModel || menuIndex == -1) return;
912 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-uid': 'string'});
913 }
914 }
915 }
917 Component {
918 id: buttonSectionMenu;
920 Menus.StandardMenu {
921 objectName: "buttonSectionMenu"
922 property QtObject menuData: null
923 property var menuModel: menuFactory.menuModel
924 property int menuIndex: -1
925 property var extendedData: menuData && menuData.ext || undefined
927 iconSource: menuData && menuData.icon || ""
928 enabled: menuData && menuData.sensitive || false
929 highlightWhenPressed: false
930 text: menuData && menuData.label || ""
931 foregroundColor: theme.palette.normal.backgroundText
933 onMenuModelChanged: {
934 loadAttributes();
935 }
936 onMenuIndexChanged: {
937 loadAttributes();
938 }
939 function loadAttributes() {
940 if (!menuModel || menuIndex == -1) return;
941 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-extra-label': 'string'});
942 }
944 component: Component {
945 Button {
946 objectName: "buttonSectionMenuControl"
947 text: getExtendedProperty(extendedData, "xCanonicalExtraLabel", "")
949 onClicked: {
950 menuModel.activate(menuIndex);
951 }
952 }
953 }
954 }
955 }
957 function load(modelData, context) {
958 if (modelData.type !== undefined && modelData.type !== "") {
959 var component = undefined;
961 var contextComponents = _map[context];
962 if (contextComponents !== undefined) {
963 component = contextComponents[modelData.type];
964 }
966 if (component === undefined) {
967 component = _map["default"][modelData.type];
968 }
969 if (component !== undefined) {
970 return component;
971 }
972 console.debug("Don't know how to make " + modelData.type + " for " + context);
973 }
974 if (modelData.isCheck || modelData.isRadio) {
975 return checkableMenu;
976 }
977 if (modelData.isSeparator) {
978 return separatorMenu;
979 }
980 return standardMenu;
981 }