2 * Copyright 2013-2016 Canonical Ltd.
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.
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.
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/>.
18 import QtQuick.Window 2.2
19 import Ubuntu.Settings.Menus 0.1 as Menus
20 import Ubuntu.Settings.Components 0.1
22 import Utils 0.1 as Utils
23 import Ubuntu.Components.ListItems 1.3 as ListItems
24 import Ubuntu.Components 1.3
25 import Unity.Session 0.1
26 import Unity.Platform 1.0
31 property var rootModel: null
32 property var menuModel: null
34 property var _userMap: null
35 readonly property var _typeToComponent: {
37 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
38 "unity.widgets.systemsettings.tablet.switch" : switchMenu,
40 "com.canonical.indicator.button" : buttonMenu,
41 "com.canonical.indicator.div" : separatorMenu,
42 "com.canonical.indicator.section" : sectionMenu,
43 "com.canonical.indicator.progress" : progressMenu,
44 "com.canonical.indicator.slider" : sliderMenu,
45 "com.canonical.indicator.switch" : switchMenu,
46 "com.canonical.indicator.alarm" : alarmMenu,
47 "com.canonical.indicator.appointment" : appointmentMenu,
48 "com.canonical.indicator.transfer" : transferMenu,
49 "com.canonical.indicator.button-section" : buttonSectionMenu,
50 "com.canonical.indicator.link" : linkMenu,
52 "com.canonical.indicator.messages.messageitem" : messageItem,
53 "com.canonical.indicator.messages.sourceitem" : groupedMessage,
55 "com.canonical.unity.slider" : sliderMenu,
56 "com.canonical.unity.switch" : switchMenu,
58 "com.canonical.unity.media-player" : mediaPayerMenu,
59 "com.canonical.unity.playback-item" : playbackItemMenu,
61 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
62 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
63 "com.canonical.indicator.network.modeminfoitem" : modeminfoitem,
65 "com.canonical.indicator.calendar": calendarMenu,
66 "com.canonical.indicator.location": timezoneMenu,
68 "indicator-session": {
69 "indicator.user-menu-item": Platform.isPC ? userMenuItem : null,
70 "indicator.guest-menu-item": Platform.isPC ? userMenuItem : null,
71 "com.canonical.indicator.switch": Math.min(Screen.width, Screen.height) > units.gu(60) ? switchMenu : null // Desktop mode switch
73 "indicator-messages": {
74 "com.canonical.indicator.button": messagesButtonMenu
78 readonly property var _action_filter_map: {
79 "indicator-session": {
80 "indicator.logout": Platform.isPC ? undefined : null,
81 "indicator.suspend": Platform.isPC ? undefined : null,
82 "indicator.hibernate": Platform.isPC ? undefined : null,
83 "indicator.reboot": Platform.isPC ? undefined : null
85 "indicator-keyboard": {
86 "indicator.map": null,
87 "indicator.chart": null
91 function getComponentForIndicatorEntryType(indicator, type) {
92 var component = undefined;
93 var map = _userMap || _typeToComponent
94 var indicatorComponents = map[indicator];
96 if (type === undefined || type === "") {
100 if (indicatorComponents !== undefined) {
101 component = indicatorComponents[type];
104 if (component === undefined) {
105 component = map["default"][type];
108 if (component === undefined) {
109 console.debug("Don't know how to make " + type + " for " + indicator);
115 function getComponentForIndicatorEntryAction(indicator, action) {
116 var component = undefined;
117 var indicatorFilter = _action_filter_map[indicator]
119 if (action === undefined || action === "") {
123 if (indicatorFilter !== undefined) {
124 component = indicatorFilter[action];
129 function getExtendedProperty(object, propertyName, defaultValue) {
130 if (object && object.hasOwnProperty(propertyName)) {
131 return object[propertyName];
139 Menus.SeparatorMenu {
140 objectName: "separatorMenu"
149 objectName: "sliderMenu"
150 property QtObject menuData: null
151 property var menuModel: menuFactory.menuModel
152 property int menuIndex: -1
153 property var extendedData: menuData && menuData.ext || undefined
154 property var serverValue: getExtendedProperty(menuData, "actionState", undefined)
156 text: menuData && menuData.label || ""
157 minIcon: getExtendedProperty(extendedData, "minIcon", "")
158 maxIcon: getExtendedProperty(extendedData, "maxIcon", "")
160 minimumValue: getExtendedProperty(extendedData, "minValue", 0.0)
162 var maximum = getExtendedProperty(extendedData, "maxValue", 1.0);
163 if (maximum <= minimumValue) {
164 return minimumValue + 1;
168 enabled: menuData && menuData.sensitive || false
169 highlightWhenPressed: false
171 onMenuModelChanged: {
174 onMenuIndexChanged: {
178 function loadAttributes() {
179 if (!menuModel || menuIndex == -1) return;
180 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
181 'max-value': 'double',
184 'x-canonical-sync-action': 'string'});
187 ServerPropertySynchroniser {
188 id: sliderPropertySync
190 syncTimeout: Utils.Constants.indicatorValueTimeout
191 bufferedSyncTimeout: true
192 maximumWaitBufferInterval: 16
194 serverTarget: sliderItem
195 serverProperty: "serverValue"
196 userTarget: sliderItem
197 userProperty: "value"
199 onSyncTriggered: menuModel.changeState(menuIndex, value)
205 name: getExtendedProperty(extendedData, "xCanonicalSyncAction", "")
207 sliderPropertySync.reset();
208 sliderPropertySync.updateUserValue();
218 objectName: "buttonMenu"
219 property QtObject menuData: null
220 property var menuModel: menuFactory.menuModel
221 property int menuIndex: -1
223 buttonText: menuData && menuData.label || ""
224 enabled: menuData && menuData.sensitive || false
225 highlightWhenPressed: false
228 menuModel.activate(menuIndex);
234 id: messagesButtonMenu;
236 Menus.BaseLayoutMenu {
237 objectName: "messagesButtonMenu"
238 property QtObject menuData: null
239 property var menuModel: menuFactory.menuModel
240 property int menuIndex: -1
242 highlightWhenPressed: false
243 enabled: menuData && menuData.sensitive || false
244 text: menuData && menuData.label || ""
245 title.color: theme.palette.selected.backgroundText
246 title.horizontalAlignment: Text.AlignHCenter
247 title.font.bold: true
249 onClicked: menuModel.activate(menuIndex);
257 objectName: "sectionMenu"
258 property QtObject menuData: null
259 property var menuIndex: undefined
261 text: menuData && menuData.label || ""
269 Menus.ProgressValueMenu {
270 objectName: "progressMenu"
271 property QtObject menuData: null
272 property int menuIndex: -1
274 text: menuData && menuData.label || ""
275 iconSource: menuData && menuData.icon || ""
276 value : menuData && menuData.actionState || 0.0
277 enabled: menuData && menuData.sensitive || false
285 objectName: "standardMenu"
286 property QtObject menuData: null
287 property int menuIndex: -1
289 text: menuData && menuData.label || ""
290 iconSource: menuData && menuData.icon || ""
291 enabled: menuData && menuData.sensitive || false
292 highlightWhenPressed: false
295 menuModel.activate(menuIndex);
303 Menus.BaseLayoutMenu {
304 objectName: "linkMenu"
305 property QtObject menuData: null
306 property int menuIndex: -1
308 text: menuData && menuData.label || ""
309 enabled: menuData && menuData.sensitive || false
310 backColor: Qt.rgba(1,1,1,0.07)
311 highlightWhenPressed: false
314 menuModel.activate(menuIndex);
320 if (menuData.icon && menuData.icon != "") {
322 } else if (menuData.action.indexOf("settings") > -1) {
323 return "image://theme/settings"
330 color: theme.palette.normal.backgroundText
331 SlotsLayout.position: SlotsLayout.Trailing
339 Menus.CheckableMenu {
341 objectName: "checkableMenu"
342 property QtObject menuData: null
343 property int menuIndex: -1
344 property bool serverChecked: menuData && menuData.isToggled || false
346 text: menuData && menuData.label || ""
347 enabled: menuData && menuData.sensitive || false
348 checked: serverChecked
349 highlightWhenPressed: false
351 ServerPropertySynchroniser {
353 syncTimeout: Utils.Constants.indicatorValueTimeout
355 serverTarget: checkItem
356 serverProperty: "serverChecked"
357 userTarget: checkItem
358 userProperty: "checked"
360 onSyncTriggered: menuModel.activate(checkItem.menuIndex)
370 objectName: "radioMenu"
371 property QtObject menuData: null
372 property int menuIndex: -1
373 property bool serverChecked: menuData && menuData.isToggled || false
375 text: menuData && menuData.label || ""
376 enabled: menuData && menuData.sensitive || false
377 checked: serverChecked
378 highlightWhenPressed: false
380 ServerPropertySynchroniser {
382 syncTimeout: Utils.Constants.indicatorValueTimeout
384 serverTarget: radioItem
385 serverProperty: "serverChecked"
386 userTarget: radioItem
387 userProperty: "checked"
389 onSyncTriggered: menuModel.activate(radioItem.menuIndex)
399 objectName: "switchMenu"
400 property QtObject menuData: null
401 property var menuModel: menuFactory.menuModel
402 property int menuIndex: -1
403 property var extendedData: menuData && menuData.ext || undefined
404 property bool serverChecked: menuData && menuData.isToggled || false
406 text: menuData && menuData.label || ""
407 iconSource: menuData && menuData.icon || ""
408 enabled: menuData && menuData.sensitive || false
409 checked: serverChecked
410 highlightWhenPressed: false
412 property var subtitleAction: UnityMenuAction {
415 name: getExtendedProperty(extendedData, "xCanonicalSubtitleAction", "")
417 subtitle.text: subtitleAction.valid ? subtitleAction.state : ""
419 onMenuModelChanged: {
422 onMenuIndexChanged: {
426 function loadAttributes() {
427 if (!menuModel || menuIndex == -1) return;
428 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-subtitle-action': 'string'});
431 ServerPropertySynchroniser {
433 syncTimeout: Utils.Constants.indicatorValueTimeout
435 serverTarget: switchItem
436 serverProperty: "serverChecked"
437 userTarget: switchItem
438 userProperty: "checked"
440 onSyncTriggered: menuModel.activate(switchItem.menuIndex);
450 objectName: "alarmMenu"
451 property QtObject menuData: null
452 property var menuModel: menuFactory.menuModel
453 property int menuIndex: -1
454 property var extendedData: menuData && menuData.ext || undefined
456 readonly property date serverTime: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
458 frequency: LiveTimer.Relative
459 relativeTime: alarmItem.serverTime
460 onTrigger: alarmItem.time = i18n.relativeDateTime(alarmItem.serverTime)
463 text: menuData && menuData.label || ""
464 iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
465 time: i18n.relativeDateTime(serverTime)
466 enabled: menuData && menuData.sensitive || false
467 highlightWhenPressed: false
469 onMenuModelChanged: {
472 onMenuIndexChanged: {
476 menuModel.activate(menuIndex);
479 function loadAttributes() {
480 if (!menuModel || menuIndex == -1) return;
481 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64'});
491 objectName: "appointmentMenu"
492 property QtObject menuData: null
493 property var menuModel: menuFactory.menuModel
494 property int menuIndex: -1
495 property var extendedData: menuData && menuData.ext || undefined
497 readonly property date serverTime: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
500 frequency: LiveTimer.Relative
501 relativeTime: appointmentItem.serverTime
502 onTrigger: appointmentItem.time = i18n.relativeDateTime(appointmentItem.serverTime)
505 text: menuData && menuData.label || ""
506 iconSource: menuData && menuData.icon || "image://theme/calendar"
507 time: i18n.relativeDateTime(serverTime)
508 eventColor: getExtendedProperty(extendedData, "xCanonicalColor", Qt.rgba(0.0, 0.0, 0.0, 0.0))
509 enabled: menuData && menuData.sensitive || false
510 highlightWhenPressed: false
512 onMenuModelChanged: {
515 onMenuIndexChanged: {
519 menuModel.activate(menuIndex);
522 function loadAttributes() {
523 if (!menuModel || menuIndex == -1) return;
524 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
525 'x-canonical-time': 'int64'});
533 Menus.UserSessionMenu {
534 objectName: "userSessionMenu"
535 highlightWhenPressed: false
537 property QtObject menuData: null
538 property var menuModel: menuFactory.menuModel
539 property int menuIndex: -1
541 name: menuData && menuData.label || "" // label is the user's real name
542 iconSource: menuData && menuData.icon || ""
544 // would be better to compare with the logname but sadly the indicator doesn't expose that
545 active: DBusUnitySessionService.RealName() !== "" ? DBusUnitySessionService.RealName() == name
546 : DBusUnitySessionService.UserName() == name
549 menuModel.activate(menuIndex);
559 objectName: "calendarMenu"
562 property QtObject menuData: null
563 property var menuModel: menuFactory.menuModel
564 property var actionState: menuData && menuData.actionState || null
565 property real calendarDay: getExtendedProperty(actionState, "calendar-day", 0)
566 property int menuIndex: -1
568 showWeekNumbers: getExtendedProperty(actionState, "show-week-numbers", false)
569 eventDays: getExtendedProperty(actionState, "appointment-days", [])
571 onCalendarDayChanged: {
572 if (calendarDay > 0) {
573 // This would trigger a selectionDateChanged signal, thus
574 // we've to avoid that the subsequent model activation
575 // would cause an infinite loop
576 modelUpdateConnections.enabled = false
577 currentDate = new Date(calendarDay * 1000)
578 modelUpdateConnections.enabled = true
583 id: modelUpdateConnections
584 property bool enabled: true
585 target: (enabled && calendarItem.visible) ? calendarItem : null
587 onSelectedDateChanged: {
588 menuModel.activate(menuIndex, selectedDate.getTime() / 1000 | 0)
599 objectName: "timezoneMenu"
601 property QtObject menuData: null
602 property var menuModel: menuFactory.menuModel
603 property int menuIndex: -1
604 property var extendedData: menuData && menuData.ext || undefined
605 readonly property string tz: getExtendedProperty(extendedData, "xCanonicalTimezone", "UTC")
606 property var updateTimer: Timer {
608 running: tzMenuItem.visible // only run when we're open
609 onTriggered: tzMenuItem.time = Utils.TimezoneFormatter.currentTimeInTimezone(tzMenuItem.tz)
612 city: menuData && menuData.label || ""
613 time: Utils.TimezoneFormatter.currentTimeInTimezone(tz)
614 enabled: menuData && menuData.sensitive || false
616 onMenuModelChanged: {
619 onMenuIndexChanged: {
623 tzActionGroup.setLocation.activate(tz);
628 busType: DBus.SessionBus
629 busName: "com.canonical.indicator.datetime"
630 objectPath: "/com/canonical/indicator/datetime"
632 property variant setLocation: action("set-location")
634 Component.onCompleted: tzActionGroup.start()
637 function loadAttributes() {
638 if (!menuModel || menuIndex == -1) return;
639 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-timezone': 'string'});
648 objectName: "wifiSection"
649 property QtObject menuData: null
650 property var menuModel: menuFactory.menuModel
651 property int menuIndex: -1
652 property var extendedData: menuData && menuData.ext || undefined
654 text: menuData && menuData.label || ""
655 busy: getExtendedProperty(extendedData, "xCanonicalBusyAction", false)
657 onMenuModelChanged: {
660 onMenuIndexChanged: {
664 function loadAttributes() {
665 if (!menuModel || menuIndex == -1) return;
666 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
674 Menus.AccessPointMenu {
676 objectName: "accessPoint"
677 property QtObject menuData: null
678 property var menuModel: menuFactory.menuModel
679 property int menuIndex: -1
680 property var extendedData: menuData && menuData.ext || undefined
681 property bool serverChecked: menuData && menuData.isToggled || false
683 property var strengthAction: UnityMenuAction {
686 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
689 text: menuData && menuData.label || ""
690 enabled: menuData && menuData.sensitive || false
691 active: serverChecked
692 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
693 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
695 if (strengthAction.valid) {
696 var state = strengthAction.state; // handle both int and uchar
697 // FIXME remove the special casing when we switch to indicator-network completely
698 if (typeof state == "string") {
699 return state.charCodeAt();
705 highlightWhenPressed: false
707 onMenuModelChanged: {
710 onMenuIndexChanged: {
714 function loadAttributes() {
715 if (!menuModel || menuIndex == -1) return;
716 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
717 'x-canonical-wifi-ap-is-secure': 'bool',
718 'x-canonical-wifi-ap-strength-action': 'string'});
721 ServerPropertySynchroniser {
723 syncTimeout: Utils.Constants.indicatorValueTimeout
726 serverProperty: "serverChecked"
728 userProperty: "active"
729 userTrigger: "onTriggered"
731 onSyncTriggered: menuModel.activate(apItem.menuIndex)
738 Menus.ModemInfoItem {
739 objectName: "modemInfoItem"
740 property QtObject menuData: null
741 property var menuModel: menuFactory.menuModel
742 property int menuIndex: -1
743 property var extendedData: menuData && menuData.ext || undefined
744 highlightWhenPressed: false
746 property var statusLabelAction: UnityMenuAction {
749 name: getExtendedProperty(extendedData, "xCanonicalModemStatusLabelAction", "")
751 statusText: statusLabelAction.valid ? statusLabelAction.state : ""
753 property var statusIconAction: UnityMenuAction {
756 name: getExtendedProperty(extendedData, "xCanonicalModemStatusIconAction", "")
758 statusIcon: statusIconAction.valid ? statusIconAction.state : ""
760 property var connectivityIconAction: UnityMenuAction {
763 name: getExtendedProperty(extendedData, "xCanonicalModemConnectivityIconAction", "")
765 connectivityIcon: connectivityIconAction.valid ? connectivityIconAction.state : ""
767 property var simIdentifierLabelAction: UnityMenuAction {
770 name: getExtendedProperty(extendedData, "xCanonicalModemSimIdentifierLabelAction", "")
772 simIdentifierText: simIdentifierLabelAction.valid ? simIdentifierLabelAction.state : ""
774 property var roamingAction: UnityMenuAction {
777 name: getExtendedProperty(extendedData, "xCanonicalModemRoamingAction", "")
779 roaming: roamingAction.valid ? roamingAction.state : false
781 property var unlockAction: UnityMenuAction {
784 name: getExtendedProperty(extendedData, "xCanonicalModemLockedAction", "")
787 unlockAction.activate();
789 locked: unlockAction.valid ? unlockAction.state : false
791 onMenuModelChanged: {
794 onMenuIndexChanged: {
798 function loadAttributes() {
799 if (!menuModel || menuIndex == -1) return;
800 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-modem-status-label-action': 'string',
801 'x-canonical-modem-status-icon-action': 'string',
802 'x-canonical-modem-connectivity-icon-action': 'string',
803 'x-canonical-modem-sim-identifier-label-action': 'string',
804 'x-canonical-modem-roaming-action': 'string',
805 'x-canonical-modem-locked-action': 'string'});
813 MessageMenuItemFactory {
814 objectName: "messageItem"
815 menuModel: menuFactory.menuModel
822 Menus.GroupedMessageMenu {
823 objectName: "groupedMessage"
824 property QtObject menuData: null
825 property var menuModel: menuFactory.menuModel
826 property int menuIndex: -1
827 property var extendedData: menuData && menuData.ext || undefined
829 text: menuData && menuData.label || ""
830 iconSource: getExtendedProperty(extendedData, "icon", "image://theme/message")
831 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
832 enabled: menuData && menuData.sensitive || false
833 highlightWhenPressed: false
836 onMenuModelChanged: {
839 onMenuIndexChanged: {
843 menuModel.activate(menuIndex, true);
846 menuModel.activate(menuIndex, false);
849 function loadAttributes() {
850 if (!menuModel || menuIndex == -1) return;
851 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
859 Menus.MediaPlayerMenu {
860 objectName: "mediaPayerMenu"
861 property QtObject menuData: null
862 property var menuModel: menuFactory.menuModel
863 property int menuIndex: -1
864 property var actionState: menuData && menuData.actionState || undefined
865 property bool running: getExtendedProperty(actionState, "running", false)
867 playerIcon: menuData && menuData.icon || "image://theme/stock_music"
868 playerName: menuData && menuData.label || i18n.tr("Nothing is playing")
870 albumArt: getExtendedProperty(actionState, "art-url", "image://theme/stock_music")
871 song: getExtendedProperty(actionState, "title", "")
872 artist: getExtendedProperty(actionState, "artist", "")
873 album: getExtendedProperty(actionState, "album", "")
874 showTrack: running && (state == "Playing" || state == "Paused")
875 state: getExtendedProperty(actionState, "state", "")
876 enabled: menuData && menuData.sensitive || false
877 highlightWhenPressed: false
880 model.activate(modelIndex);
886 id: playbackItemMenu;
888 Menus.PlaybackItemMenu {
889 objectName: "playbackItemMenu"
890 property QtObject menuData: null
891 property var menuModel: menuFactory.menuModel
892 property int menuIndex: -1
893 property var extendedData: menuData && menuData.ext || undefined
895 property var playAction: UnityMenuAction {
898 name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
900 property var nextAction: UnityMenuAction {
903 name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
905 property var previousAction: UnityMenuAction {
908 name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
911 playing: playAction.state === "Playing"
912 canPlay: playAction.valid
913 canGoNext: nextAction.valid
914 canGoPrevious: previousAction.valid
915 enabled: menuData && menuData.sensitive || false
916 highlightWhenPressed: false
919 playAction.activate();
922 nextAction.activate();
925 previousAction.activate();
927 onMenuModelChanged: {
930 onMenuIndexChanged: {
934 function loadAttributes() {
935 if (!menuModel || menuIndex == -1) return;
936 menuModel.loadExtendedAttributes(modelIndex, {'x-canonical-play-action': 'string',
937 'x-canonical-next-action': 'string',
938 'x-canonical-previous-action': 'string'});
947 objectName: "transferMenu"
949 property QtObject menuData: null
950 property var menuModel: menuFactory.menuModel
951 property int menuIndex: -1
952 property var extendedData: menuData && menuData.ext || undefined
953 property var uid: getExtendedProperty(extendedData, "xCanonicalUid", undefined)
955 text: menuData && menuData.label || ""
956 iconSource: menuData && menuData.icon || "image://theme/transfer-none"
958 enabled: menuData && menuData.sensitive || false
959 highlightWhenPressed: false
966 busName: rootModel.busName
967 objectPath: rootModel.actions["indicator"]
969 property var activateAction: action("activate-transfer")
970 property var cancelAction: action("cancel-transfer")
971 property var transferStateAction: uid !== undefined ? action("transfer-state."+uid) : null
973 Component.onCompleted: actionGroup.start()
976 property var transferState: {
977 if (actionGroup.transferStateAction === null) return undefined;
978 return actionGroup.transferStateAction.valid ? actionGroup.transferStateAction.state : undefined
981 property var runningState : transferState !== undefined ? transferState["state"] : undefined
982 property var secondsLeft : transferState !== undefined ? transferState["seconds-left"] : undefined
984 active: runningState !== undefined && runningState !== Menus.TransferState.Finished
985 progress: transferState !== undefined ? transferState["percent"] : 0.0
987 // TODO - Should be in the SDK
988 property var timeRemaining: {
989 if (secondsLeft === undefined) return undefined;
992 var hours = Math.floor(secondsLeft / (60 * 60));
993 var minutes = Math.floor(secondsLeft / 60) % 60;
994 var seconds = secondsLeft % 60;
996 remaining += i18n.tr("%1 hour", "%1 hours", hours).arg(hours)
999 if (remaining != "") remaining += ", ";
1000 remaining += i18n.tr("%1 minute", "%1 minutes", minutes).arg(minutes)
1002 // don't include seconds if hours > 0
1003 if (hours == 0 && minutes < 5 && seconds > 0) {
1004 if (remaining != "") remaining += ", ";
1005 remaining += i18n.tr("%1 second", "%1 seconds", seconds).arg(seconds)
1007 if (remaining == "")
1008 remaining = i18n.tr("0 seconds");
1009 // Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
1010 return i18n.tr("%1 remaining").arg(remaining);
1014 switch (runningState) {
1015 case Menus.TransferState.Queued:
1016 return i18n.tr("In queue…");
1017 case Menus.TransferState.Hashing:
1018 case Menus.TransferState.Processing:
1019 case Menus.TransferState.Running:
1020 return timeRemaining === undefined ? i18n.tr("Downloading") : timeRemaining;
1021 case Menus.TransferState.Paused:
1022 return i18n.tr("Paused, tap to resume");
1023 case Menus.TransferState.Canceled:
1024 return i18n.tr("Canceled");
1025 case Menus.TransferState.Finished:
1026 return i18n.tr("Finished");
1027 case Menus.TransferState.Error:
1028 return i18n.tr("Failed, tap to retry");
1033 onMenuModelChanged: {
1036 onMenuIndexChanged: {
1040 actionGroup.activateAction.activate(uid);
1043 actionGroup.cancelAction.activate(uid);
1046 function loadAttributes() {
1047 if (!menuModel || menuIndex == -1) return;
1048 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-uid': 'string'});
1054 id: buttonSectionMenu;
1057 objectName: "buttonSectionMenu"
1058 property QtObject menuData: null
1059 property var menuModel: menuFactory.menuModel
1060 property int menuIndex: -1
1061 property var extendedData: menuData && menuData.ext || undefined
1063 iconSource: menuData && menuData.icon || ""
1064 enabled: menuData && menuData.sensitive || false
1065 highlightWhenPressed: false
1066 text: menuData && menuData.label || ""
1067 foregroundColor: theme.palette.normal.backgroundText
1068 buttonText: getExtendedProperty(extendedData, "xCanonicalExtraLabel", "")
1070 onMenuModelChanged: {
1073 onMenuIndexChanged: {
1076 function loadAttributes() {
1077 if (!menuModel || menuIndex == -1) return;
1078 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-extra-label': 'string'});
1081 onButtonClicked: menuModel.activate(menuIndex);
1085 function load(modelData, context) {
1086 if (context && context.indexOf("fake-") == 0) {
1087 context = context.substring("fake-".length)
1090 var component = getComponentForIndicatorEntryAction(context, modelData.action)
1091 if (component !== undefined) {
1095 component = getComponentForIndicatorEntryType(context, modelData.type)
1096 if (component !== undefined) {
1100 if (modelData.isCheck) {
1101 return checkableMenu;
1103 if (modelData.isRadio) {
1106 if (modelData.isSeparator) {
1107 return separatorMenu;
1109 if (modelData.action !== undefined && modelData.action.indexOf("settings") > -1) {
1110 // FIXME : At the moment, the indicators aren't using
1111 // com.canonical.indicators.link for settings menu. Need to fudge it.
1114 return standardMenu;