on a142f21 help sign in
unity8/qml/Panel/Indicators/MenuItemFactory.qml
890 lines 33 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 Ubuntu.Settings.Components 0.1
23import QMenuModel 0.1
24import Utils 0.1 as Utils
25import Ubuntu.Components.ListItems 0.1 as ListItems
26import Ubuntu.Components 1.1
28Item {
29 id: menuFactory
31 property var rootModel: null
32 property var menuModel: null
34 property var _map: {
35 "default": {
36 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
37 "unity.widgets.systemsettings.tablet.switch" : switchMenu,
39 "com.canonical.indicator.button" : buttonMenu,
40 "com.canonical.indicator.div" : separatorMenu,
41 "com.canonical.indicator.section" : sectionMenu,
42 "com.canonical.indicator.progress" : progressMenu,
43 "com.canonical.indicator.slider" : sliderMenu,
44 "com.canonical.indicator.switch" : switchMenu,
45 "com.canonical.indicator.alarm" : alarmMenu,
46 "com.canonical.indicator.appointment" : appointmentMenu,
47 "com.canonical.indicator.transfer" : transferMenu,
48 "com.canonical.indicator.button-section" : buttonSectionMenu,
49 "com.canonical.indicator.link" : linkMenu,
51 "com.canonical.indicator.messages.messageitem" : messageItem,
52 "com.canonical.indicator.messages.sourceitem" : groupedMessage,
54 "com.canonical.unity.slider" : sliderMenu,
55 "com.canonical.unity.switch" : switchMenu,
57 "com.canonical.unity.media-player" : mediaPayerMenu,
58 "com.canonical.unity.playback-item" : playbackItemMenu,
60 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
61 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
62 "com.canonical.indicator.network.modeminfoitem" : modeminfoitem,
63 },
64 "indicator-messages" : {
65 "com.canonical.indicator.button" : messagesButtonMenu
66 }
67 }
69 function getExtendedProperty(object, propertyName, defaultValue) {
70 if (object && object.hasOwnProperty(propertyName)) {
71 return object[propertyName];
72 }
73 return defaultValue;
74 }
76 Component {
77 id: separatorMenu;
79 Menus.SeparatorMenu {
80 objectName: "separatorMenu"
81 }
82 }
84 Component {
85 id: sliderMenu;
87 Menus.SliderMenu {
88 id: sliderItem
89 objectName: "sliderMenu"
90 property QtObject menuData: null
91 property var menuModel: menuFactory.menuModel
92 property int menuIndex: -1
93 property var extendedData: menuData && menuData.ext || undefined
94 property var serverValue: getExtendedProperty(menuData, "actionState", undefined)
96 text: menuData && menuData.label || ""
97 iconSource: menuData && menuData.icon || ""
98 minIcon: getExtendedProperty(extendedData, "minIcon", "")
99 maxIcon: getExtendedProperty(extendedData, "maxIcon", "")
101 minimumValue: getExtendedProperty(extendedData, "minValue", 0.0)
102 maximumValue: {
103 var maximum = getExtendedProperty(extendedData, "maxValue", 1.0);
104 if (maximum <= minimumValue) {
105 return minimumValue + 1;
106 }
107 return maximum;
108 }
109 enabled: menuData && menuData.sensitive || false
110 highlightWhenPressed: false
112 onMenuModelChanged: {
113 loadAttributes();
114 }
115 onMenuIndexChanged: {
116 loadAttributes();
117 }
119 function loadAttributes() {
120 if (!menuModel || menuIndex == -1) return;
121 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
122 'max-value': 'double',
123 'min-icon': 'icon',
124 'max-icon': 'icon'});
125 }
127 ServerPropertySynchroniser {
128 objectName: "sync"
129 syncTimeout: Utils.Constants.indicatorValueTimeout
130 bufferedSyncTimeout: true
131 maximumWaitBufferInterval: 16
133 serverTarget: sliderItem
134 serverProperty: "serverValue"
135 userTarget: sliderItem
136 userProperty: "value"
138 onSyncTriggered: menuModel.changeState(menuIndex, value)
139 }
140 }
141 }
143 Component {
144 id: buttonMenu;
146 Menus.ButtonMenu {
147 objectName: "buttonMenu"
148 property QtObject menuData: null
149 property var menuModel: menuFactory.menuModel
150 property int menuIndex: -1
152 buttonText: menuData && menuData.label || ""
153 enabled: menuData && menuData.sensitive || false
154 highlightWhenPressed: false
156 onTriggered: {
157 menuModel.activate(menuIndex);
158 }
159 }
160 }
162 Component {
163 id: messagesButtonMenu;
165 Item {
166 objectName: "messagesButtonMenu"
167 property QtObject menuData: null
168 property var menuModel: menuFactory.menuModel
169 property int menuIndex: -1
171 implicitHeight: units.gu(5)
172 enabled: menuData && menuData.sensitive || false
174 Label {
175 id: buttonMenuLabel
176 text: menuData && menuData.label || ""
177 anchors.centerIn: parent
178 font.bold: true
179 }
181 MouseArea {
182 anchors {
183 fill: buttonMenuLabel
184 margins: units.gu(-1)
185 }
186 onClicked: menuModel.activate(menuIndex);
187 }
188 }
189 }
191 Component {
192 id: sectionMenu;
194 Menus.SectionMenu {
195 objectName: "sectionMenu"
196 property QtObject menuData: null
197 property var menuIndex: undefined
199 text: menuData && menuData.label || ""
200 busy: false
201 }
202 }
204 Component {
205 id: progressMenu;
207 Menus.ProgressValueMenu {
208 objectName: "progressMenu"
209 property QtObject menuData: null
210 property int menuIndex: -1
212 text: menuData && menuData.label || ""
213 iconSource: menuData && menuData.icon || ""
214 value : menuData && menuData.actionState || 0.0
215 enabled: menuData && menuData.sensitive || false
216 highlightWhenPressed: false
217 }
218 }
220 Component {
221 id: standardMenu;
223 Menus.StandardMenu {
224 objectName: "standardMenu"
225 property QtObject menuData: null
226 property int menuIndex: -1
228 text: menuData && menuData.label || ""
229 iconSource: menuData && menuData.icon || ""
230 enabled: menuData && menuData.sensitive || false
231 highlightWhenPressed: false
233 onTriggered: {
234 menuModel.activate(menuIndex);
235 }
237 // FIXME : At the moment, the indicators aren't using
238 // com.canonical.indicators.link for settings menu. Need to fudge it.
239 property bool settingsMenu: menuData && menuData.action.indexOf("settings") > -1 || false
240 backColor: settingsMenu ? Qt.rgba(1,1,1,0.07) : "transparent"
241 component: settingsMenu ? buttonForSettings : undefined
242 Component {
243 id: buttonForSettings
244 Icon {
245 name: "settings"
246 height: units.gu(3)
247 width: height
248 color: Theme.palette.selected.backgroundText
249 }
250 }
251 }
252 }
254 Component {
255 id: linkMenu;
257 Menus.StandardMenu {
258 objectName: "linkMenu"
259 property QtObject menuData: null
260 property int menuIndex: -1
262 text: menuData && menuData.label || ""
263 iconSource: menuData && menuData.icon || ""
264 enabled: menuData && menuData.sensitive || false
265 highlightWhenPressed: false
267 onTriggered: {
268 menuModel.activate(menuIndex);
269 }
271 backColor: Qt.rgba(1,1,1,0.07)
273 component: menuData.icon ? icon : undefined
274 Component {
275 id: icon
276 Icon {
277 source: menuData.icon
278 height: units.gu(3)
279 width: height
280 color: Theme.palette.selected.backgroundText
281 }
282 }
283 }
284 }
286 Component {
287 id: checkableMenu;
289 Menus.CheckableMenu {
290 id: checkItem
291 objectName: "checkableMenu"
292 property QtObject menuData: null
293 property int menuIndex: -1
294 property bool serverChecked: menuData && menuData.isToggled || false
296 text: menuData && menuData.label || ""
297 enabled: menuData && menuData.sensitive || false
298 checked: serverChecked
299 highlightWhenPressed: false
301 ServerPropertySynchroniser {
302 objectName: "sync"
303 syncTimeout: Utils.Constants.indicatorValueTimeout
305 serverTarget: checkItem
306 serverProperty: "serverChecked"
307 userTarget: checkItem
308 userProperty: "checked"
310 onSyncTriggered: menuModel.activate(checkItem.menuIndex)
311 }
312 }
313 }
315 Component {
316 id: switchMenu;
318 Menus.SwitchMenu {
319 id: switchItem
320 objectName: "switchMenu"
321 property QtObject menuData: null
322 property int menuIndex: -1
323 property bool serverChecked: menuData && menuData.isToggled || false
325 text: menuData && menuData.label || ""
326 iconSource: menuData && menuData.icon || ""
327 enabled: menuData && menuData.sensitive || false
328 checked: serverChecked
329 highlightWhenPressed: false
331 ServerPropertySynchroniser {
332 objectName: "sync"
333 syncTimeout: Utils.Constants.indicatorValueTimeout
335 serverTarget: switchItem
336 serverProperty: "serverChecked"
337 userTarget: switchItem
338 userProperty: "checked"
340 onSyncTriggered: menuModel.activate(switchItem.menuIndex);
341 }
342 }
343 }
345 Component {
346 id: alarmMenu;
348 Menus.EventMenu {
349 objectName: "alarmMenu"
350 property QtObject menuData: null
351 property var menuModel: menuFactory.menuModel
352 property int menuIndex: -1
353 property var extendedData: menuData && menuData.ext || undefined
354 // TODO - bug #1260728
355 property var timeFormatter: Utils.GDateTimeFormatter {
356 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
357 format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
358 }
360 text: menuData && menuData.label || ""
361 iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
362 time: timeFormatter.timeString
363 enabled: menuData && menuData.sensitive || false
364 highlightWhenPressed: false
366 onMenuModelChanged: {
367 loadAttributes();
368 }
369 onMenuIndexChanged: {
370 loadAttributes();
371 }
372 onTriggered: {
373 menuModel.activate(menuIndex);
374 }
376 function loadAttributes() {
377 if (!menuModel || menuIndex == -1) return;
378 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
379 'x-canonical-time-format': 'string'});
380 }
381 }
382 }
384 Component {
385 id: appointmentMenu;
387 Menus.EventMenu {
388 objectName: "appointmentMenu"
389 property QtObject menuData: null
390 property var menuModel: menuFactory.menuModel
391 property int menuIndex: -1
392 property var extendedData: menuData && menuData.ext || undefined
393 // TODO - bug #1260728
394 property var timeFormatter: Utils.GDateTimeFormatter {
395 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
396 format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
397 }
399 text: menuData && menuData.label || ""
400 iconSource: menuData && menuData.icon || "image://theme/calendar"
401 time: timeFormatter.timeString
402 eventColor: getExtendedProperty(extendedData, "xCanonicalColor", Qt.rgba(0.0, 0.0, 0.0, 0.0))
403 enabled: menuData && menuData.sensitive || false
404 highlightWhenPressed: false
406 onMenuModelChanged: {
407 loadAttributes();
408 }
409 onMenuIndexChanged: {
410 loadAttributes();
411 }
412 onTriggered: {
413 menuModel.activate(menuIndex);
414 }
416 function loadAttributes() {
417 if (!menuModel || menuIndex == -1) return;
418 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
419 'x-canonical-time': 'int64',
420 'x-canonical-time-format': 'string'});
421 }
422 }
423 }
425 Component {
426 id: wifiSection;
428 Menus.SectionMenu {
429 objectName: "wifiSection"
430 property QtObject menuData: null
431 property var menuModel: menuFactory.menuModel
432 property int menuIndex: -1
433 property var extendedData: menuData && menuData.ext || undefined
435 text: menuData && menuData.label || ""
436 busy: getExtendedProperty(extendedData, "xCanonicalBusyAction", false)
438 onMenuModelChanged: {
439 loadAttributes();
440 }
441 onMenuIndexChanged: {
442 loadAttributes();
443 }
445 function loadAttributes() {
446 if (!menuModel || menuIndex == -1) return;
447 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
448 }
449 }
450 }
452 Component {
453 id: accessPoint;
455 Menus.AccessPointMenu {
456 id: apItem
457 objectName: "accessPoint"
458 property QtObject menuData: null
459 property var menuModel: menuFactory.menuModel
460 property int menuIndex: -1
461 property var extendedData: menuData && menuData.ext || undefined
462 property bool serverChecked: menuData && menuData.isToggled || false
464 property var strengthAction: UnityMenuAction {
465 model: menuModel
466 index: menuIndex
467 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
468 }
470 text: menuData && menuData.label || ""
471 enabled: menuData && menuData.sensitive || false
472 active: serverChecked
473 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
474 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
475 signalStrength: strengthAction.valid ? strengthAction.state : 0
476 highlightWhenPressed: false
478 onMenuModelChanged: {
479 loadAttributes();
480 }
481 onMenuIndexChanged: {
482 loadAttributes();
483 }
485 function loadAttributes() {
486 if (!menuModel || menuIndex == -1) return;
487 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
488 'x-canonical-wifi-ap-is-secure': 'bool',
489 'x-canonical-wifi-ap-strength-action': 'string'});
490 }
492 ServerPropertySynchroniser {
493 objectName: "sync"
494 syncTimeout: Utils.Constants.indicatorValueTimeout
496 serverTarget: apItem
497 serverProperty: "serverChecked"
498 userTarget: apItem
499 userProperty: "active"
500 userTrigger: "onTriggered"
502 onSyncTriggered: menuModel.activate(apItem.menuIndex)
503 }
504 }
505 }
507 Component {
508 id: modeminfoitem;
509 ModemInfoItem {
510 objectName: "modemInfoItem"
511 property QtObject menuData: null
512 property var menuModel: menuFactory.menuModel
513 property int menuIndex: -1
514 property var extendedData: menuData && menuData.ext || undefined
515 highlightWhenPressed: false
517 property var statusLabelAction: UnityMenuAction {
518 model: menuModel
519 index: menuIndex
520 name: getExtendedProperty(extendedData, "xCanonicalModemStatusLabelAction", "")
521 }
522 statusText: statusLabelAction.valid ? statusLabelAction.state : ""
524 property var statusIconAction: UnityMenuAction {
525 model: menuModel
526 index: menuIndex
527 name: getExtendedProperty(extendedData, "xCanonicalModemStatusIconAction", "")
528 }
529 statusIcon: statusIconAction.valid ? statusIconAction.state : ""
531 property var connectivityIconAction: UnityMenuAction {
532 model: menuModel
533 index: menuIndex
534 name: getExtendedProperty(extendedData, "xCanonicalModemConnectivityIconAction", "")
535 }
536 connectivityIcon: connectivityIconAction.valid ? connectivityIconAction.state : ""
538 property var simIdentifierLabelAction: UnityMenuAction {
539 model: menuModel
540 index: menuIndex
541 name: getExtendedProperty(extendedData, "xCanonicalModemSimIdentifierLabelAction", "")
542 }
543 simIdentifierText: simIdentifierLabelAction.valid ? simIdentifierLabelAction.state : ""
545 property var roamingAction: UnityMenuAction {
546 model: menuModel
547 index: menuIndex
548 name: getExtendedProperty(extendedData, "xCanonicalModemRoamingAction", "")
549 }
550 roaming: roamingAction.valid ? roamingAction.state : false
552 property var unlockAction: UnityMenuAction {
553 model: menuModel
554 index: menuIndex
555 name: getExtendedProperty(extendedData, "xCanonicalModemLockedAction", "")
556 }
557 onUnlock: {
558 unlockAction.activate();
559 }
560 locked: unlockAction.valid ? unlockAction.state : false
562 onMenuModelChanged: {
563 loadAttributes();
564 }
565 onMenuIndexChanged: {
566 loadAttributes();
567 }
569 function loadAttributes() {
570 if (!menuModel || menuIndex == -1) return;
571 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-modem-status-label-action': 'string',
572 'x-canonical-modem-status-icon-action': 'string',
573 'x-canonical-modem-connectivity-icon-action': 'string',
574 'x-canonical-modem-sim-identifier-label-action': 'string',
575 'x-canonical-modem-roaming-action': 'string',
576 'x-canonical-modem-locked-action': 'string'});
577 }
578 }
579 }
581 Component {
582 id: messageItem
584 MessageMenuItemFactory {
585 objectName: "messageItem"
586 menuModel: menuFactory.menuModel
587 }
588 }
590 Component {
591 id: groupedMessage
593 Menus.GroupedMessageMenu {
594 objectName: "groupedMessage"
595 property QtObject menuData: null
596 property var menuModel: menuFactory.menuModel
597 property int menuIndex: -1
598 property var extendedData: menuData && menuData.ext || undefined
600 text: menuData && menuData.label || ""
601 iconSource: getExtendedProperty(extendedData, "icon", "image://theme/message")
602 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
603 enabled: menuData && menuData.sensitive || false
604 highlightWhenPressed: false
605 removable: true
607 onMenuModelChanged: {
608 loadAttributes();
609 }
610 onMenuIndexChanged: {
611 loadAttributes();
612 }
613 onClicked: {
614 menuModel.activate(menuIndex, true);
615 }
616 onDismissed: {
617 menuModel.activate(menuIndex, false);
618 }
620 function loadAttributes() {
621 if (!menuModel || menuIndex == -1) return;
622 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
623 }
624 }
625 }
627 Component {
628 id: mediaPayerMenu;
630 Menus.MediaPlayerMenu {
631 objectName: "mediaPayerMenu"
632 property QtObject menuData: null
633 property var menuModel: menuFactory.menuModel
634 property int menuIndex: -1
635 property var actionState: menuData && menuData.actionState || undefined
636 property bool running: getExtendedProperty(actionState, "running", false)
638 playerIcon: menuData && menuData.icon || "image://theme/stock_music"
639 playerName: menuData && menuData.label || i18n.tr("Nothing is playing")
641 albumArt: getExtendedProperty(actionState, "art-url", "image://theme/stock_music")
642 song: getExtendedProperty(actionState, "title", "")
643 artist: getExtendedProperty(actionState, "artist", "")
644 album: getExtendedProperty(actionState, "album", "")
645 showTrack: running && (state == "Playing" || state == "Paused")
646 state: getExtendedProperty(actionState, "state", "")
647 enabled: menuData && menuData.sensitive || false
648 highlightWhenPressed: false
649 showDivider: false
651 onTriggered: {
652 model.activate(modelIndex);
653 }
654 }
655 }
657 Component {
658 id: playbackItemMenu;
660 Menus.PlaybackItemMenu {
661 objectName: "playbackItemMenu"
662 property QtObject menuData: null
663 property var menuModel: menuFactory.menuModel
664 property int menuIndex: -1
665 property var extendedData: menuData && menuData.ext || undefined
667 property var playAction: UnityMenuAction {
668 model: menuModel
669 index: menuIndex
670 name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
671 }
672 property var nextAction: UnityMenuAction {
673 model: menuModel
674 index: menuIndex
675 name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
676 }
677 property var previousAction: UnityMenuAction {
678 model: menuModel
679 index: menuIndex
680 name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
681 }
683 playing: playAction.state === "Playing"
684 canPlay: playAction.valid
685 canGoNext: nextAction.valid
686 canGoPrevious: previousAction.valid
687 enabled: menuData && menuData.sensitive || false
688 highlightWhenPressed: false
690 onPlay: {
691 playAction.activate();
692 }
693 onNext: {
694 nextAction.activate();
695 }
696 onPrevious: {
697 previousAction.activate();
698 }
699 onMenuModelChanged: {
700 loadAttributes();
701 }
702 onMenuIndexChanged: {
703 loadAttributes();
704 }
706 function loadAttributes() {
707 if (!menuModel || menuIndex == -1) return;
708 menuModel.loadExtendedAttributes(modelIndex, {'x-canonical-play-action': 'string',
709 'x-canonical-next-action': 'string',
710 'x-canonical-previous-action': 'string'});
711 }
712 }
713 }
715 Component {
716 id: transferMenu
718 Menus.TransferMenu {
719 objectName: "transferMenu"
720 id: transfer
721 property QtObject menuData: null
722 property var menuModel: menuFactory.menuModel
723 property int menuIndex: -1
724 property var extendedData: menuData && menuData.ext || undefined
725 property var uid: getExtendedProperty(extendedData, "xCanonicalUid", undefined)
727 text: menuData && menuData.label || ""
728 iconSource: menuData && menuData.icon || "image://theme/transfer-none"
729 maximum: 1.0
730 enabled: menuData && menuData.sensitive || false
731 highlightWhenPressed: false
732 removable: true
733 confirmRemoval: true
735 QDBusActionGroup {
736 id: actionGroup
737 busType: 1
738 busName: rootModel.busName
739 objectPath: rootModel.actions["indicator"]
741 property var activateAction: action("activate-transfer")
742 property var cancelAction: action("cancel-transfer")
743 property var transferStateAction: uid !== undefined ? action("transfer-state."+uid) : null
745 Component.onCompleted: actionGroup.start()
746 }
748 property var transferState: {
749 if (actionGroup.transferStateAction === null) return undefined;
750 return actionGroup.transferStateAction.valid ? actionGroup.transferStateAction.state : undefined
751 }
753 property var runningState : transferState !== undefined ? transferState["state"] : undefined
754 property var secondsLeft : transferState !== undefined ? transferState["seconds-left"] : undefined
756 active: runningState !== undefined && runningState !== Menus.TransferState.Finished
757 progress: transferState !== undefined ? transferState["percent"] : 0.0
759 // TODO - Should be in the SDK
760 property var timeRemaining: {
761 if (secondsLeft === undefined) return undefined;
763 var remaining = "";
764 var hours = Math.floor(secondsLeft / (60 * 60));
765 var minutes = Math.floor(secondsLeft / 60) % 60;
766 var seconds = secondsLeft % 60;
767 if (hours > 0) {
768 remaining += i18n.tr("%1 hour", "%1 hours", hours).arg(hours)
769 }
770 if (minutes > 0) {
771 if (remaining != "") remaining += ", ";
772 remaining += i18n.tr("%1 minute", "%1 minutes", minutes).arg(minutes)
773 }
774 // don't include seconds if hours > 0
775 if (hours == 0 && minutes < 5 && seconds > 0) {
776 if (remaining != "") remaining += ", ";
777 remaining += i18n.tr("%1 second", "%1 seconds", seconds).arg(seconds)
778 }
779 if (remaining == "")
780 remaining = i18n.tr("0 seconds");
781 // Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
782 return i18n.tr("%1 remaining").arg(remaining);
783 }
785 stateText: {
786 switch (runningState) {
787 case Menus.TransferState.Queued:
788 return i18n.tr("In queue…");
789 case Menus.TransferState.Hashing:
790 case Menus.TransferState.Processing:
791 case Menus.TransferState.Running:
792 return timeRemaining === undefined ? i18n.tr("Downloading") : timeRemaining;
793 case Menus.TransferState.Paused:
794 return i18n.tr("Paused, tap to resume");
795 case Menus.TransferState.Canceled:
796 return i18n.tr("Canceled");
797 case Menus.TransferState.Finished:
798 return i18n.tr("Finished");
799 case Menus.TransferState.Error:
800 return i18n.tr("Failed, tap to retry");
801 }
802 return "";
803 }
805 onMenuModelChanged: {
806 loadAttributes();
807 }
808 onMenuIndexChanged: {
809 loadAttributes();
810 }
811 onTriggered: {
812 actionGroup.activateAction.activate(uid);
813 }
814 onItemRemoved: {
815 actionGroup.cancelAction.activate(uid);
816 }
818 function loadAttributes() {
819 if (!menuModel || menuIndex == -1) return;
820 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-uid': 'string'});
821 }
822 }
823 }
825 Component {
826 id: buttonSectionMenu;
828 Menus.StandardMenu {
829 objectName: "buttonSectionMenu"
830 property QtObject menuData: null
831 property var menuModel: menuFactory.menuModel
832 property int menuIndex: -1
833 property var extendedData: menuData && menuData.ext || undefined
835 iconSource: menuData && menuData.icon || ""
836 enabled: menuData && menuData.sensitive || false
837 highlightWhenPressed: false
838 text: menuData && menuData.label || ""
839 foregroundColor: Theme.palette.normal.backgroundText
841 onMenuModelChanged: {
842 loadAttributes();
843 }
844 onMenuIndexChanged: {
845 loadAttributes();
846 }
847 function loadAttributes() {
848 if (!menuModel || menuIndex == -1) return;
849 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-extra-label': 'string'});
850 }
852 component: Component {
853 Button {
854 objectName: "buttonSectionMenuControl"
855 text: getExtendedProperty(extendedData, "xCanonicalExtraLabel", "")
857 onClicked: {
858 menuModel.activate(menuIndex);
859 }
860 }
861 }
862 }
863 }
865 function load(modelData, context) {
866 if (modelData.type !== undefined && modelData.type !== "") {
867 var component = undefined;
869 var contextComponents = _map[context];
870 if (contextComponents !== undefined) {
871 component = contextComponents[modelData.type];
872 }
874 if (component === undefined) {
875 component = _map["default"][modelData.type];
876 }
877 if (component !== undefined) {
878 return component;
879 }
880 console.debug("Don't know how to make " + modelData.type + " for " + context);
881 }
882 if (modelData.isCheck || modelData.isRadio) {
883 return checkableMenu;
884 }
885 if (modelData.isSeparator) {
886 return separatorMenu;
887 }
888 return standardMenu;
889 }