on 6ca9421 help sign in
unity8/qml/Panel/Indicators/MenuItemFactory.qml
978 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.0
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 0.1 as ListItems
23import Ubuntu.Components 1.2
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 objectName: "alarmMenu"
354 property QtObject menuData: null
355 property var menuModel: menuFactory.menuModel
356 property int menuIndex: -1
357 property var extendedData: menuData && menuData.ext || undefined
358 // TODO - bug #1260728
359 property var timeFormatter: Utils.GDateTimeFormatter {
360 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
361 format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
362 }
364 text: menuData && menuData.label || ""
365 iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
366 time: timeFormatter.timeString
367 enabled: menuData && menuData.sensitive || false
368 highlightWhenPressed: false
370 onMenuModelChanged: {
371 loadAttributes();
372 }
373 onMenuIndexChanged: {
374 loadAttributes();
375 }
376 onTriggered: {
377 menuModel.activate(menuIndex);
378 }
380 function loadAttributes() {
381 if (!menuModel || menuIndex == -1) return;
382 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
383 'x-canonical-time-format': 'string'});
384 }
385 }
386 }
388 Component {
389 id: appointmentMenu;
391 Menus.EventMenu {
392 objectName: "appointmentMenu"
393 property QtObject menuData: null
394 property var menuModel: menuFactory.menuModel
395 property int menuIndex: -1
396 property var extendedData: menuData && menuData.ext || undefined
397 // TODO - bug #1260728
398 property var timeFormatter: Utils.GDateTimeFormatter {
399 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
400 format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
401 }
403 text: menuData && menuData.label || ""
404 iconSource: menuData && menuData.icon || "image://theme/calendar"
405 time: timeFormatter.timeString
406 eventColor: getExtendedProperty(extendedData, "xCanonicalColor", Qt.rgba(0.0, 0.0, 0.0, 0.0))
407 enabled: menuData && menuData.sensitive || false
408 highlightWhenPressed: false
410 onMenuModelChanged: {
411 loadAttributes();
412 }
413 onMenuIndexChanged: {
414 loadAttributes();
415 }
416 onTriggered: {
417 menuModel.activate(menuIndex);
418 }
420 function loadAttributes() {
421 if (!menuModel || menuIndex == -1) return;
422 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
423 'x-canonical-time': 'int64',
424 'x-canonical-time-format': 'string'});
425 }
426 }
427 }
429 Component {
430 id: userMenuItem
432 Menus.UserSessionMenu {
433 objectName: "userSessionMenu"
434 highlightWhenPressed: false
436 property QtObject menuData: null
437 property var menuModel: menuFactory.menuModel
438 property int menuIndex: -1
440 name: menuData && menuData.label || "" // label is the user's real name
441 iconSource: menuData && menuData.icon || ""
443 // would be better to compare with the logname but sadly the indicator doesn't expose that
444 active: DBusUnitySessionService.RealName() !== "" ? DBusUnitySessionService.RealName() == name
445 : DBusUnitySessionService.UserName() == name
447 onTriggered: {
448 menuModel.activate(menuIndex);
449 }
450 }
451 }
453 Component {
454 id: calendarMenu
456 Menus.CalendarMenu {
457 objectName: "calendarMenu"
458 highlightWhenPressed: false
459 focus: true
460 }
461 }
463 Component {
464 id: timezoneMenu
466 Menus.TimeZoneMenu {
467 id: tzMenuItem
468 objectName: "timezoneMenu"
470 property QtObject menuData: null
471 property var menuModel: menuFactory.menuModel
472 property int menuIndex: -1
473 property var extendedData: menuData && menuData.ext || undefined
474 readonly property string tz: getExtendedProperty(extendedData, "xCanonicalTimezone", "UTC")
475 property var updateTimer: Timer {
476 repeat: true
477 running: tzMenuItem.visible // only run when we're open
478 onTriggered: tzMenuItem.time = Utils.TimezoneFormatter.currentTimeInTimezone(tzMenuItem.tz)
479 }
481 city: menuData && menuData.label || ""
482 time: Utils.TimezoneFormatter.currentTimeInTimezone(tz)
483 enabled: menuData && menuData.sensitive || false
485 onMenuModelChanged: {
486 loadAttributes();
487 }
488 onMenuIndexChanged: {
489 loadAttributes();
490 }
491 onTriggered: {
492 tzActionGroup.setLocation.activate(tz);
493 }
495 QDBusActionGroup {
496 id: tzActionGroup
497 busType: DBus.SessionBus
498 busName: "com.canonical.indicator.datetime"
499 objectPath: "/com/canonical/indicator/datetime"
501 property variant setLocation: action("set-location")
503 Component.onCompleted: tzActionGroup.start()
504 }
506 function loadAttributes() {
507 if (!menuModel || menuIndex == -1) return;
508 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-timezone': 'string'});
509 }
510 }
511 }
513 Component {
514 id: wifiSection;
516 Menus.SectionMenu {
517 objectName: "wifiSection"
518 property QtObject menuData: null
519 property var menuModel: menuFactory.menuModel
520 property int menuIndex: -1
521 property var extendedData: menuData && menuData.ext || undefined
523 text: menuData && menuData.label || ""
524 busy: getExtendedProperty(extendedData, "xCanonicalBusyAction", false)
526 onMenuModelChanged: {
527 loadAttributes();
528 }
529 onMenuIndexChanged: {
530 loadAttributes();
531 }
533 function loadAttributes() {
534 if (!menuModel || menuIndex == -1) return;
535 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
536 }
537 }
538 }
540 Component {
541 id: accessPoint;
543 Menus.AccessPointMenu {
544 id: apItem
545 objectName: "accessPoint"
546 property QtObject menuData: null
547 property var menuModel: menuFactory.menuModel
548 property int menuIndex: -1
549 property var extendedData: menuData && menuData.ext || undefined
550 property bool serverChecked: menuData && menuData.isToggled || false
552 property var strengthAction: UnityMenuAction {
553 model: menuModel
554 index: menuIndex
555 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
556 }
558 text: menuData && menuData.label || ""
559 enabled: menuData && menuData.sensitive || false
560 active: serverChecked
561 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
562 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
563 signalStrength: strengthAction.valid ? strengthAction.state : 0
564 highlightWhenPressed: false
566 onMenuModelChanged: {
567 loadAttributes();
568 }
569 onMenuIndexChanged: {
570 loadAttributes();
571 }
573 function loadAttributes() {
574 if (!menuModel || menuIndex == -1) return;
575 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
576 'x-canonical-wifi-ap-is-secure': 'bool',
577 'x-canonical-wifi-ap-strength-action': 'string'});
578 }
580 ServerPropertySynchroniser {
581 objectName: "sync"
582 syncTimeout: Utils.Constants.indicatorValueTimeout
584 serverTarget: apItem
585 serverProperty: "serverChecked"
586 userTarget: apItem
587 userProperty: "active"
588 userTrigger: "onTriggered"
590 onSyncTriggered: menuModel.activate(apItem.menuIndex)
591 }
592 }
593 }
595 Component {
596 id: modeminfoitem;
597 ModemInfoItem {
598 objectName: "modemInfoItem"
599 property QtObject menuData: null
600 property var menuModel: menuFactory.menuModel
601 property int menuIndex: -1
602 property var extendedData: menuData && menuData.ext || undefined
603 highlightWhenPressed: false
605 property var statusLabelAction: UnityMenuAction {
606 model: menuModel
607 index: menuIndex
608 name: getExtendedProperty(extendedData, "xCanonicalModemStatusLabelAction", "")
609 }
610 statusText: statusLabelAction.valid ? statusLabelAction.state : ""
612 property var statusIconAction: UnityMenuAction {
613 model: menuModel
614 index: menuIndex
615 name: getExtendedProperty(extendedData, "xCanonicalModemStatusIconAction", "")
616 }
617 statusIcon: statusIconAction.valid ? statusIconAction.state : ""
619 property var connectivityIconAction: UnityMenuAction {
620 model: menuModel
621 index: menuIndex
622 name: getExtendedProperty(extendedData, "xCanonicalModemConnectivityIconAction", "")
623 }
624 connectivityIcon: connectivityIconAction.valid ? connectivityIconAction.state : ""
626 property var simIdentifierLabelAction: UnityMenuAction {
627 model: menuModel
628 index: menuIndex
629 name: getExtendedProperty(extendedData, "xCanonicalModemSimIdentifierLabelAction", "")
630 }
631 simIdentifierText: simIdentifierLabelAction.valid ? simIdentifierLabelAction.state : ""
633 property var roamingAction: UnityMenuAction {
634 model: menuModel
635 index: menuIndex
636 name: getExtendedProperty(extendedData, "xCanonicalModemRoamingAction", "")
637 }
638 roaming: roamingAction.valid ? roamingAction.state : false
640 property var unlockAction: UnityMenuAction {
641 model: menuModel
642 index: menuIndex
643 name: getExtendedProperty(extendedData, "xCanonicalModemLockedAction", "")
644 }
645 onUnlock: {
646 unlockAction.activate();
647 }
648 locked: unlockAction.valid ? unlockAction.state : false
650 onMenuModelChanged: {
651 loadAttributes();
652 }
653 onMenuIndexChanged: {
654 loadAttributes();
655 }
657 function loadAttributes() {
658 if (!menuModel || menuIndex == -1) return;
659 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-modem-status-label-action': 'string',
660 'x-canonical-modem-status-icon-action': 'string',
661 'x-canonical-modem-connectivity-icon-action': 'string',
662 'x-canonical-modem-sim-identifier-label-action': 'string',
663 'x-canonical-modem-roaming-action': 'string',
664 'x-canonical-modem-locked-action': 'string'});
665 }
666 }
667 }
669 Component {
670 id: messageItem
672 MessageMenuItemFactory {
673 objectName: "messageItem"
674 menuModel: menuFactory.menuModel
675 }
676 }
678 Component {
679 id: groupedMessage
681 Menus.GroupedMessageMenu {
682 objectName: "groupedMessage"
683 property QtObject menuData: null
684 property var menuModel: menuFactory.menuModel
685 property int menuIndex: -1
686 property var extendedData: menuData && menuData.ext || undefined
688 text: menuData && menuData.label || ""
689 iconSource: getExtendedProperty(extendedData, "icon", "image://theme/message")
690 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
691 enabled: menuData && menuData.sensitive || false
692 highlightWhenPressed: false
693 removable: true
695 onMenuModelChanged: {
696 loadAttributes();
697 }
698 onMenuIndexChanged: {
699 loadAttributes();
700 }
701 onClicked: {
702 menuModel.activate(menuIndex, true);
703 }
704 onDismissed: {
705 menuModel.activate(menuIndex, false);
706 }
708 function loadAttributes() {
709 if (!menuModel || menuIndex == -1) return;
710 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
711 }
712 }
713 }
715 Component {
716 id: mediaPayerMenu;
718 Menus.MediaPlayerMenu {
719 objectName: "mediaPayerMenu"
720 property QtObject menuData: null
721 property var menuModel: menuFactory.menuModel
722 property int menuIndex: -1
723 property var actionState: menuData && menuData.actionState || undefined
724 property bool running: getExtendedProperty(actionState, "running", false)
726 playerIcon: menuData && menuData.icon || "image://theme/stock_music"
727 playerName: menuData && menuData.label || i18n.tr("Nothing is playing")
729 albumArt: getExtendedProperty(actionState, "art-url", "image://theme/stock_music")
730 song: getExtendedProperty(actionState, "title", "")
731 artist: getExtendedProperty(actionState, "artist", "")
732 album: getExtendedProperty(actionState, "album", "")
733 showTrack: running && (state == "Playing" || state == "Paused")
734 state: getExtendedProperty(actionState, "state", "")
735 enabled: menuData && menuData.sensitive || false
736 highlightWhenPressed: false
737 showDivider: false
739 onTriggered: {
740 model.activate(modelIndex);
741 }
742 }
743 }
745 Component {
746 id: playbackItemMenu;
748 Menus.PlaybackItemMenu {
749 objectName: "playbackItemMenu"
750 property QtObject menuData: null
751 property var menuModel: menuFactory.menuModel
752 property int menuIndex: -1
753 property var extendedData: menuData && menuData.ext || undefined
755 property var playAction: UnityMenuAction {
756 model: menuModel
757 index: menuIndex
758 name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
759 }
760 property var nextAction: UnityMenuAction {
761 model: menuModel
762 index: menuIndex
763 name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
764 }
765 property var previousAction: UnityMenuAction {
766 model: menuModel
767 index: menuIndex
768 name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
769 }
771 playing: playAction.state === "Playing"
772 canPlay: playAction.valid
773 canGoNext: nextAction.valid
774 canGoPrevious: previousAction.valid
775 enabled: menuData && menuData.sensitive || false
776 highlightWhenPressed: false
778 onPlay: {
779 playAction.activate();
780 }
781 onNext: {
782 nextAction.activate();
783 }
784 onPrevious: {
785 previousAction.activate();
786 }
787 onMenuModelChanged: {
788 loadAttributes();
789 }
790 onMenuIndexChanged: {
791 loadAttributes();
792 }
794 function loadAttributes() {
795 if (!menuModel || menuIndex == -1) return;
796 menuModel.loadExtendedAttributes(modelIndex, {'x-canonical-play-action': 'string',
797 'x-canonical-next-action': 'string',
798 'x-canonical-previous-action': 'string'});
799 }
800 }
801 }
803 Component {
804 id: transferMenu
806 Menus.TransferMenu {
807 objectName: "transferMenu"
808 id: transfer
809 property QtObject menuData: null
810 property var menuModel: menuFactory.menuModel
811 property int menuIndex: -1
812 property var extendedData: menuData && menuData.ext || undefined
813 property var uid: getExtendedProperty(extendedData, "xCanonicalUid", undefined)
815 text: menuData && menuData.label || ""
816 iconSource: menuData && menuData.icon || "image://theme/transfer-none"
817 maximum: 1.0
818 enabled: menuData && menuData.sensitive || false
819 highlightWhenPressed: false
820 removable: true
821 confirmRemoval: true
823 QDBusActionGroup {
824 id: actionGroup
825 busType: 1
826 busName: rootModel.busName
827 objectPath: rootModel.actions["indicator"]
829 property var activateAction: action("activate-transfer")
830 property var cancelAction: action("cancel-transfer")
831 property var transferStateAction: uid !== undefined ? action("transfer-state."+uid) : null
833 Component.onCompleted: actionGroup.start()
834 }
836 property var transferState: {
837 if (actionGroup.transferStateAction === null) return undefined;
838 return actionGroup.transferStateAction.valid ? actionGroup.transferStateAction.state : undefined
839 }
841 property var runningState : transferState !== undefined ? transferState["state"] : undefined
842 property var secondsLeft : transferState !== undefined ? transferState["seconds-left"] : undefined
844 active: runningState !== undefined && runningState !== Menus.TransferState.Finished
845 progress: transferState !== undefined ? transferState["percent"] : 0.0
847 // TODO - Should be in the SDK
848 property var timeRemaining: {
849 if (secondsLeft === undefined) return undefined;
851 var remaining = "";
852 var hours = Math.floor(secondsLeft / (60 * 60));
853 var minutes = Math.floor(secondsLeft / 60) % 60;
854 var seconds = secondsLeft % 60;
855 if (hours > 0) {
856 remaining += i18n.tr("%1 hour", "%1 hours", hours).arg(hours)
857 }
858 if (minutes > 0) {
859 if (remaining != "") remaining += ", ";
860 remaining += i18n.tr("%1 minute", "%1 minutes", minutes).arg(minutes)
861 }
862 // don't include seconds if hours > 0
863 if (hours == 0 && minutes < 5 && seconds > 0) {
864 if (remaining != "") remaining += ", ";
865 remaining += i18n.tr("%1 second", "%1 seconds", seconds).arg(seconds)
866 }
867 if (remaining == "")
868 remaining = i18n.tr("0 seconds");
869 // Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
870 return i18n.tr("%1 remaining").arg(remaining);
871 }
873 stateText: {
874 switch (runningState) {
875 case Menus.TransferState.Queued:
876 return i18n.tr("In queue…");
877 case Menus.TransferState.Hashing:
878 case Menus.TransferState.Processing:
879 case Menus.TransferState.Running:
880 return timeRemaining === undefined ? i18n.tr("Downloading") : timeRemaining;
881 case Menus.TransferState.Paused:
882 return i18n.tr("Paused, tap to resume");
883 case Menus.TransferState.Canceled:
884 return i18n.tr("Canceled");
885 case Menus.TransferState.Finished:
886 return i18n.tr("Finished");
887 case Menus.TransferState.Error:
888 return i18n.tr("Failed, tap to retry");
889 }
890 return "";
891 }
893 onMenuModelChanged: {
894 loadAttributes();
895 }
896 onMenuIndexChanged: {
897 loadAttributes();
898 }
899 onTriggered: {
900 actionGroup.activateAction.activate(uid);
901 }
902 onItemRemoved: {
903 actionGroup.cancelAction.activate(uid);
904 }
906 function loadAttributes() {
907 if (!menuModel || menuIndex == -1) return;
908 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-uid': 'string'});
909 }
910 }
911 }
913 Component {
914 id: buttonSectionMenu;
916 Menus.StandardMenu {
917 objectName: "buttonSectionMenu"
918 property QtObject menuData: null
919 property var menuModel: menuFactory.menuModel
920 property int menuIndex: -1
921 property var extendedData: menuData && menuData.ext || undefined
923 iconSource: menuData && menuData.icon || ""
924 enabled: menuData && menuData.sensitive || false
925 highlightWhenPressed: false
926 text: menuData && menuData.label || ""
927 foregroundColor: Theme.palette.normal.backgroundText
929 onMenuModelChanged: {
930 loadAttributes();
931 }
932 onMenuIndexChanged: {
933 loadAttributes();
934 }
935 function loadAttributes() {
936 if (!menuModel || menuIndex == -1) return;
937 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-extra-label': 'string'});
938 }
940 component: Component {
941 Button {
942 objectName: "buttonSectionMenuControl"
943 text: getExtendedProperty(extendedData, "xCanonicalExtraLabel", "")
945 onClicked: {
946 menuModel.activate(menuIndex);
947 }
948 }
949 }
950 }
951 }
953 function load(modelData, context) {
954 if (modelData.type !== undefined && modelData.type !== "") {
955 var component = undefined;
957 var contextComponents = _map[context];
958 if (contextComponents !== undefined) {
959 component = contextComponents[modelData.type];
960 }
962 if (component === undefined) {
963 component = _map["default"][modelData.type];
964 }
965 if (component !== undefined) {
966 return component;
967 }
968 console.debug("Don't know how to make " + modelData.type + " for " + context);
969 }
970 if (modelData.isCheck || modelData.isRadio) {
971 return checkableMenu;
972 }
973 if (modelData.isSeparator) {
974 return separatorMenu;
975 }
976 return standardMenu;
977 }