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 string indicator
32 property var rootModel: null
33 property var menuModel: null
35 property var _userMap: null
36 readonly property var _typeToComponent: {
38 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
39 "unity.widgets.systemsettings.tablet.switch" : switchMenu,
41 "com.canonical.indicator.button" : buttonMenu,
42 "com.canonical.indicator.div" : separatorMenu,
43 "com.canonical.indicator.section" : sectionMenu,
44 "com.canonical.indicator.progress" : progressMenu,
45 "com.canonical.indicator.slider" : sliderMenu,
46 "com.canonical.indicator.switch" : switchMenu,
47 "com.canonical.indicator.alarm" : alarmMenu,
48 "com.canonical.indicator.appointment" : appointmentMenu,
49 "com.canonical.indicator.transfer" : transferMenu,
50 "com.canonical.indicator.button-section" : buttonSectionMenu,
51 "com.canonical.indicator.link" : linkMenu,
53 "com.canonical.indicator.messages.messageitem" : messageItem,
54 "com.canonical.indicator.messages.sourceitem" : groupedMessage,
56 "com.canonical.unity.slider" : sliderMenu,
57 "com.canonical.unity.switch" : switchMenu,
59 "com.canonical.unity.media-player" : mediaPayerMenu,
60 "com.canonical.unity.playback-item" : playbackItemMenu,
62 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
63 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
64 "com.canonical.indicator.network.modeminfoitem" : modeminfoitem,
66 "com.canonical.indicator.calendar": calendarMenu,
67 "com.canonical.indicator.location": timezoneMenu,
69 "indicator-session": {
70 "indicator.user-menu-item": Platform.isPC ? userMenuItem : null,
71 "indicator.guest-menu-item": Platform.isPC ? userMenuItem : null,
72 "com.canonical.indicator.switch": Math.min(Screen.width, Screen.height) > units.gu(60) ? switchMenu : null // Desktop mode switch
74 "indicator-messages": {
75 "com.canonical.indicator.button": messagesButtonMenu
79 readonly property var _action_filter_map: {
80 "indicator-session": {
81 "indicator.logout": Platform.isPC ? undefined : null,
82 "indicator.suspend": Platform.isPC ? undefined : null,
83 "indicator.hibernate": Platform.isPC ? undefined : null,
84 "indicator.reboot": Platform.isPC ? undefined : null
86 "indicator-keyboard": {
87 "indicator.map": null,
88 "indicator.chart": null
92 function getComponentForIndicatorEntryType(type) {
93 var component = undefined;
94 var map = _userMap || _typeToComponent
95 var indicatorComponents = map[indicator];
97 if (type === undefined || type === "") {
101 if (indicatorComponents !== undefined) {
102 component = indicatorComponents[type];
105 if (component === undefined) {
106 component = map["default"][type];
109 if (component === undefined) {
110 console.debug("Don't know how to make " + type + " for " + indicator);
116 function getComponentForIndicatorEntryAction(action) {
117 var component = undefined;
118 var indicatorFilter = _action_filter_map[indicator]
120 if (action === undefined || action === "") {
124 if (indicatorFilter !== undefined) {
125 component = indicatorFilter[action];
130 function getExtendedProperty(object, propertyName, defaultValue) {
131 if (object && object.hasOwnProperty(propertyName)) {
132 return object[propertyName];
140 Menus.SeparatorMenu {
141 objectName: "separatorMenu"
150 objectName: "sliderMenu"
151 property QtObject menuData: null
152 property var menuModel: menuFactory.menuModel
153 property int menuIndex: -1
154 property var extendedData: menuData && menuData.ext || undefined
155 property var serverValue: getExtendedProperty(menuData, "actionState", undefined)
157 text: menuData && menuData.label || ""
158 minIcon: getExtendedProperty(extendedData, "minIcon", "")
159 maxIcon: getExtendedProperty(extendedData, "maxIcon", "")
161 minimumValue: getExtendedProperty(extendedData, "minValue", 0.0)
163 var maximum = getExtendedProperty(extendedData, "maxValue", 1.0);
164 if (maximum <= minimumValue) {
165 return minimumValue + 1;
169 enabled: menuData && menuData.sensitive || false
170 highlightWhenPressed: false
172 onMenuModelChanged: {
175 onMenuIndexChanged: {
179 function loadAttributes() {
180 if (!menuModel || menuIndex == -1) return;
181 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
182 'max-value': 'double',
185 'x-canonical-sync-action': 'string'});
188 ServerPropertySynchroniser {
189 id: sliderPropertySync
191 syncTimeout: Utils.Constants.indicatorValueTimeout
192 bufferedSyncTimeout: true
193 maximumWaitBufferInterval: 16
195 serverTarget: sliderItem
196 serverProperty: "serverValue"
197 userTarget: sliderItem
198 userProperty: "value"
200 onSyncTriggered: menuModel.changeState(menuIndex, value)
206 name: getExtendedProperty(extendedData, "xCanonicalSyncAction", "")
208 sliderPropertySync.reset();
209 sliderPropertySync.updateUserValue();
219 objectName: "buttonMenu"
220 property QtObject menuData: null
221 property var menuModel: menuFactory.menuModel
222 property int menuIndex: -1
224 buttonText: menuData && menuData.label || ""
225 enabled: menuData && menuData.sensitive || false
226 highlightWhenPressed: false
229 menuModel.activate(menuIndex);
235 id: messagesButtonMenu;
237 Menus.BaseLayoutMenu {
238 objectName: "messagesButtonMenu"
239 property QtObject menuData: null
240 property var menuModel: menuFactory.menuModel
241 property int menuIndex: -1
243 highlightWhenPressed: false
244 enabled: menuData && menuData.sensitive || false
245 text: menuData && menuData.label || ""
246 title.color: theme.palette.selected.backgroundText
247 title.horizontalAlignment: Text.AlignHCenter
248 title.font.bold: true
250 onClicked: menuModel.activate(menuIndex);
258 objectName: "sectionMenu"
259 property QtObject menuData: null
260 property var menuIndex: undefined
262 text: menuData && menuData.label || ""
270 Menus.ProgressValueMenu {
271 objectName: "progressMenu"
272 property QtObject menuData: null
273 property int menuIndex: -1
275 text: menuData && menuData.label || ""
276 iconSource: menuData && menuData.icon || ""
277 value : menuData && menuData.actionState || 0.0
278 enabled: menuData && menuData.sensitive || false
286 objectName: "standardMenu"
287 property QtObject menuData: null
288 property int menuIndex: -1
290 text: menuData && menuData.label || ""
291 iconSource: menuData && menuData.icon || ""
292 enabled: menuData && menuData.sensitive || false
293 highlightWhenPressed: false
296 menuModel.activate(menuIndex);
304 Menus.BaseLayoutMenu {
305 objectName: "linkMenu"
306 property QtObject menuData: null
307 property int menuIndex: -1
309 text: menuData && menuData.label || ""
310 enabled: menuData && menuData.sensitive || false
311 backColor: Qt.rgba(1,1,1,0.07)
312 highlightWhenPressed: false
315 menuModel.activate(menuIndex);
321 if (menuData.icon && menuData.icon != "") {
323 } else if (menuData.action.indexOf("settings") > -1) {
324 return "image://theme/settings"
331 color: theme.palette.normal.backgroundText
332 SlotsLayout.position: SlotsLayout.Trailing
340 Menus.CheckableMenu {
342 objectName: "checkableMenu"
343 property QtObject menuData: null
344 property int menuIndex: -1
345 property bool serverChecked: menuData && menuData.isToggled || false
347 text: menuData && menuData.label || ""
348 enabled: menuData && menuData.sensitive || false
349 checked: serverChecked
350 highlightWhenPressed: false
352 ServerPropertySynchroniser {
354 syncTimeout: Utils.Constants.indicatorValueTimeout
356 serverTarget: checkItem
357 serverProperty: "serverChecked"
358 userTarget: checkItem
359 userProperty: "checked"
361 onSyncTriggered: menuModel.activate(checkItem.menuIndex)
371 objectName: "radioMenu"
372 property QtObject menuData: null
373 property int menuIndex: -1
374 property bool serverChecked: menuData && menuData.isToggled || false
376 text: menuData && menuData.label || ""
377 enabled: menuData && menuData.sensitive || false
378 checked: serverChecked
379 highlightWhenPressed: false
381 ServerPropertySynchroniser {
383 syncTimeout: Utils.Constants.indicatorValueTimeout
385 serverTarget: radioItem
386 serverProperty: "serverChecked"
387 userTarget: radioItem
388 userProperty: "checked"
390 onSyncTriggered: menuModel.activate(radioItem.menuIndex)
400 objectName: "switchMenu"
401 property QtObject menuData: null
402 property var menuModel: menuFactory.menuModel
403 property int menuIndex: -1
404 property var extendedData: menuData && menuData.ext || undefined
405 property bool serverChecked: menuData && menuData.isToggled || false
407 text: menuData && menuData.label || ""
408 iconSource: menuData && menuData.icon || ""
409 enabled: menuData && menuData.sensitive || false
410 checked: serverChecked
411 highlightWhenPressed: false
413 property var subtitleAction: UnityMenuAction {
416 name: getExtendedProperty(extendedData, "xCanonicalSubtitleAction", "")
418 subtitle.text: subtitleAction.valid ? subtitleAction.state : ""
420 onMenuModelChanged: {
423 onMenuIndexChanged: {
427 function loadAttributes() {
428 if (!menuModel || menuIndex == -1) return;
429 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-subtitle-action': 'string'});
432 ServerPropertySynchroniser {
434 syncTimeout: Utils.Constants.indicatorValueTimeout
436 serverTarget: switchItem
437 serverProperty: "serverChecked"
438 userTarget: switchItem
439 userProperty: "checked"
441 onSyncTriggered: menuModel.activate(switchItem.menuIndex);
451 objectName: "alarmMenu"
452 property QtObject menuData: null
453 property var menuModel: menuFactory.menuModel
454 property int menuIndex: -1
455 property var extendedData: menuData && menuData.ext || undefined
457 readonly property date serverTime: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
459 frequency: LiveTimer.Relative
460 relativeTime: alarmItem.serverTime
461 onTrigger: alarmItem.time = i18n.relativeDateTime(alarmItem.serverTime)
464 text: menuData && menuData.label || ""
465 iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
466 time: i18n.relativeDateTime(serverTime)
467 enabled: menuData && menuData.sensitive || false
468 highlightWhenPressed: false
470 onMenuModelChanged: {
473 onMenuIndexChanged: {
477 menuModel.activate(menuIndex);
480 function loadAttributes() {
481 if (!menuModel || menuIndex == -1) return;
482 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64'});
492 objectName: "appointmentMenu"
493 property QtObject menuData: null
494 property var menuModel: menuFactory.menuModel
495 property int menuIndex: -1
496 property var extendedData: menuData && menuData.ext || undefined
498 readonly property date serverTime: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
501 frequency: LiveTimer.Relative
502 relativeTime: appointmentItem.serverTime
503 onTrigger: appointmentItem.time = i18n.relativeDateTime(appointmentItem.serverTime)
506 text: menuData && menuData.label || ""
507 iconSource: menuData && menuData.icon || "image://theme/calendar"
508 time: i18n.relativeDateTime(serverTime)
509 eventColor: getExtendedProperty(extendedData, "xCanonicalColor", Qt.rgba(0.0, 0.0, 0.0, 0.0))
510 enabled: menuData && menuData.sensitive || false
511 highlightWhenPressed: false
513 onMenuModelChanged: {
516 onMenuIndexChanged: {
520 menuModel.activate(menuIndex);
523 function loadAttributes() {
524 if (!menuModel || menuIndex == -1) return;
525 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
526 'x-canonical-time': 'int64'});
534 Menus.UserSessionMenu {
535 objectName: "userSessionMenu"
536 highlightWhenPressed: false
538 property QtObject menuData: null
539 property var menuModel: menuFactory.menuModel
540 property int menuIndex: -1
542 name: menuData && menuData.label || "" // label is the user's real name
543 iconSource: menuData && menuData.icon || ""
545 // would be better to compare with the logname but sadly the indicator doesn't expose that
546 active: DBusUnitySessionService.RealName() !== "" ? DBusUnitySessionService.RealName() == name
547 : DBusUnitySessionService.UserName() == name
550 menuModel.activate(menuIndex);
560 objectName: "calendarMenu"
563 property QtObject menuData: null
564 property var menuModel: menuFactory.menuModel
565 property var actionState: menuData && menuData.actionState || null
566 property real calendarDay: getExtendedProperty(actionState, "calendar-day", 0)
567 property int menuIndex: -1
569 showWeekNumbers: getExtendedProperty(actionState, "show-week-numbers", false)
570 eventDays: getExtendedProperty(actionState, "appointment-days", [])
572 onCalendarDayChanged: {
573 if (calendarDay > 0) {
574 // This would trigger a selectionDateChanged signal, thus
575 // we've to avoid that the subsequent model activation
576 // would cause an infinite loop
577 modelUpdateConnections.enabled = false
578 currentDate = new Date(calendarDay * 1000)
579 modelUpdateConnections.enabled = true
584 id: modelUpdateConnections
585 property bool enabled: true
586 target: (enabled && calendarItem.visible) ? calendarItem : null
588 onSelectedDateChanged: {
589 menuModel.activate(menuIndex, selectedDate.getTime() / 1000 | 0)
600 objectName: "timezoneMenu"
602 property QtObject menuData: null
603 property var menuModel: menuFactory.menuModel
604 property int menuIndex: -1
605 property var extendedData: menuData && menuData.ext || undefined
606 readonly property string tz: getExtendedProperty(extendedData, "xCanonicalTimezone", "UTC")
607 property var updateTimer: Timer {
609 running: tzMenuItem.visible // only run when we're open
610 onTriggered: tzMenuItem.time = Utils.TimezoneFormatter.currentTimeInTimezone(tzMenuItem.tz)
613 city: menuData && menuData.label || ""
614 time: Utils.TimezoneFormatter.currentTimeInTimezone(tz)
615 enabled: menuData && menuData.sensitive || false
617 onMenuModelChanged: {
620 onMenuIndexChanged: {
624 tzActionGroup.setLocation.activate(tz);
629 busType: DBus.SessionBus
630 busName: "com.canonical.indicator.datetime"
631 objectPath: "/com/canonical/indicator/datetime"
633 property variant setLocation: action("set-location")
635 Component.onCompleted: tzActionGroup.start()
638 function loadAttributes() {
639 if (!menuModel || menuIndex == -1) return;
640 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-timezone': 'string'});
649 objectName: "wifiSection"
650 property QtObject menuData: null
651 property var menuModel: menuFactory.menuModel
652 property int menuIndex: -1
653 property var extendedData: menuData && menuData.ext || undefined
655 text: menuData && menuData.label || ""
656 busy: getExtendedProperty(extendedData, "xCanonicalBusyAction", false)
658 onMenuModelChanged: {
661 onMenuIndexChanged: {
665 function loadAttributes() {
666 if (!menuModel || menuIndex == -1) return;
667 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
675 Menus.AccessPointMenu {
677 objectName: "accessPoint"
678 property QtObject menuData: null
679 property var menuModel: menuFactory.menuModel
680 property int menuIndex: -1
681 property var extendedData: menuData && menuData.ext || undefined
682 property bool serverChecked: menuData && menuData.isToggled || false
684 property var strengthAction: UnityMenuAction {
687 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
690 text: menuData && menuData.label || ""
691 enabled: menuData && menuData.sensitive || false
692 active: serverChecked
693 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
694 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
696 if (strengthAction.valid) {
697 var state = strengthAction.state; // handle both int and uchar
698 // FIXME remove the special casing when we switch to indicator-network completely
699 if (typeof state == "string") {
700 return state.charCodeAt();
706 highlightWhenPressed: false
708 onMenuModelChanged: {
711 onMenuIndexChanged: {
715 function loadAttributes() {
716 if (!menuModel || menuIndex == -1) return;
717 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
718 'x-canonical-wifi-ap-is-secure': 'bool',
719 'x-canonical-wifi-ap-strength-action': 'string'});
722 ServerPropertySynchroniser {
724 syncTimeout: Utils.Constants.indicatorValueTimeout
727 serverProperty: "serverChecked"
729 userProperty: "active"
730 userTrigger: "onTriggered"
732 onSyncTriggered: menuModel.activate(apItem.menuIndex)
739 Menus.ModemInfoItem {
740 objectName: "modemInfoItem"
741 property QtObject menuData: null
742 property var menuModel: menuFactory.menuModel
743 property int menuIndex: -1
744 property var extendedData: menuData && menuData.ext || undefined
745 highlightWhenPressed: false
747 property var statusLabelAction: UnityMenuAction {
750 name: getExtendedProperty(extendedData, "xCanonicalModemStatusLabelAction", "")
752 statusText: statusLabelAction.valid ? statusLabelAction.state : ""
754 property var statusIconAction: UnityMenuAction {
757 name: getExtendedProperty(extendedData, "xCanonicalModemStatusIconAction", "")
759 statusIcon: statusIconAction.valid ? statusIconAction.state : ""
761 property var connectivityIconAction: UnityMenuAction {
764 name: getExtendedProperty(extendedData, "xCanonicalModemConnectivityIconAction", "")
766 connectivityIcon: connectivityIconAction.valid ? connectivityIconAction.state : ""
768 property var simIdentifierLabelAction: UnityMenuAction {
771 name: getExtendedProperty(extendedData, "xCanonicalModemSimIdentifierLabelAction", "")
773 simIdentifierText: simIdentifierLabelAction.valid ? simIdentifierLabelAction.state : ""
775 property var roamingAction: UnityMenuAction {
778 name: getExtendedProperty(extendedData, "xCanonicalModemRoamingAction", "")
780 roaming: roamingAction.valid ? roamingAction.state : false
782 property var unlockAction: UnityMenuAction {
785 name: getExtendedProperty(extendedData, "xCanonicalModemLockedAction", "")
788 unlockAction.activate();
790 locked: unlockAction.valid ? unlockAction.state : false
792 onMenuModelChanged: {
795 onMenuIndexChanged: {
799 function loadAttributes() {
800 if (!menuModel || menuIndex == -1) return;
801 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-modem-status-label-action': 'string',
802 'x-canonical-modem-status-icon-action': 'string',
803 'x-canonical-modem-connectivity-icon-action': 'string',
804 'x-canonical-modem-sim-identifier-label-action': 'string',
805 'x-canonical-modem-roaming-action': 'string',
806 'x-canonical-modem-locked-action': 'string'});
814 MessageMenuItemFactory {
815 objectName: "messageItem"
816 menuModel: menuFactory.menuModel
823 Menus.GroupedMessageMenu {
824 objectName: "groupedMessage"
825 property QtObject menuData: null
826 property var menuModel: menuFactory.menuModel
827 property int menuIndex: -1
828 property var extendedData: menuData && menuData.ext || undefined
830 text: menuData && menuData.label || ""
831 iconSource: getExtendedProperty(extendedData, "icon", "image://theme/message")
832 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
833 enabled: menuData && menuData.sensitive || false
834 highlightWhenPressed: false
837 onMenuModelChanged: {
840 onMenuIndexChanged: {
844 menuModel.activate(menuIndex, true);
847 menuModel.activate(menuIndex, false);
850 function loadAttributes() {
851 if (!menuModel || menuIndex == -1) return;
852 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
860 Menus.MediaPlayerMenu {
861 objectName: "mediaPayerMenu"
862 property QtObject menuData: null
863 property var menuModel: menuFactory.menuModel
864 property int menuIndex: -1
865 property var actionState: menuData && menuData.actionState || undefined
866 property bool running: getExtendedProperty(actionState, "running", false)
868 playerIcon: menuData && menuData.icon || "image://theme/stock_music"
869 playerName: menuData && menuData.label || i18n.tr("Nothing is playing")
871 albumArt: getExtendedProperty(actionState, "art-url", "image://theme/stock_music")
872 song: getExtendedProperty(actionState, "title", "")
873 artist: getExtendedProperty(actionState, "artist", "")
874 album: getExtendedProperty(actionState, "album", "")
875 showTrack: running && (state == "Playing" || state == "Paused")
876 state: getExtendedProperty(actionState, "state", "")
877 enabled: menuData && menuData.sensitive || false
878 highlightWhenPressed: false
881 model.activate(modelIndex);
887 id: playbackItemMenu;
889 Menus.PlaybackItemMenu {
890 objectName: "playbackItemMenu"
891 property QtObject menuData: null
892 property var menuModel: menuFactory.menuModel
893 property int menuIndex: -1
894 property var extendedData: menuData && menuData.ext || undefined
896 property var playAction: UnityMenuAction {
899 name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
901 property var nextAction: UnityMenuAction {
904 name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
906 property var previousAction: UnityMenuAction {
909 name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
912 playing: playAction.state === "Playing"
913 canPlay: playAction.valid
914 canGoNext: nextAction.valid
915 canGoPrevious: previousAction.valid
916 enabled: menuData && menuData.sensitive || false
917 highlightWhenPressed: false
920 playAction.activate();
923 nextAction.activate();
926 previousAction.activate();
928 onMenuModelChanged: {
931 onMenuIndexChanged: {
935 function loadAttributes() {
936 if (!menuModel || menuIndex == -1) return;
937 menuModel.loadExtendedAttributes(modelIndex, {'x-canonical-play-action': 'string',
938 'x-canonical-next-action': 'string',
939 'x-canonical-previous-action': 'string'});
948 objectName: "transferMenu"
950 property QtObject menuData: null
951 property var menuModel: menuFactory.menuModel
952 property int menuIndex: -1
953 property var extendedData: menuData && menuData.ext || undefined
954 property var uid: getExtendedProperty(extendedData, "xCanonicalUid", undefined)
956 text: menuData && menuData.label || ""
957 iconSource: menuData && menuData.icon || "image://theme/transfer-none"
959 enabled: menuData && menuData.sensitive || false
960 highlightWhenPressed: false
967 busName: rootModel.busName
968 objectPath: rootModel.actions["indicator"]
970 property var activateAction: action("activate-transfer")
971 property var cancelAction: action("cancel-transfer")
972 property var transferStateAction: uid !== undefined ? action("transfer-state."+uid) : null
974 Component.onCompleted: actionGroup.start()
977 property var transferState: {
978 if (actionGroup.transferStateAction === null) return undefined;
979 return actionGroup.transferStateAction.valid ? actionGroup.transferStateAction.state : undefined
982 property var runningState : transferState !== undefined ? transferState["state"] : undefined
983 property var secondsLeft : transferState !== undefined ? transferState["seconds-left"] : undefined
985 active: runningState !== undefined && runningState !== Menus.TransferState.Finished
986 progress: transferState !== undefined ? transferState["percent"] : 0.0
988 // TODO - Should be in the SDK
989 property var timeRemaining: {
990 if (secondsLeft === undefined) return undefined;
993 var hours = Math.floor(secondsLeft / (60 * 60));
994 var minutes = Math.floor(secondsLeft / 60) % 60;
995 var seconds = secondsLeft % 60;
997 remaining += i18n.tr("%1 hour", "%1 hours", hours).arg(hours)
1000 if (remaining != "") remaining += ", ";
1001 remaining += i18n.tr("%1 minute", "%1 minutes", minutes).arg(minutes)
1003 // don't include seconds if hours > 0
1004 if (hours == 0 && minutes < 5 && seconds > 0) {
1005 if (remaining != "") remaining += ", ";
1006 remaining += i18n.tr("%1 second", "%1 seconds", seconds).arg(seconds)
1008 if (remaining == "")
1009 remaining = i18n.tr("0 seconds");
1010 // Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
1011 return i18n.tr("%1 remaining").arg(remaining);
1015 switch (runningState) {
1016 case Menus.TransferState.Queued:
1017 return i18n.tr("In queue…");
1018 case Menus.TransferState.Hashing:
1019 case Menus.TransferState.Processing:
1020 case Menus.TransferState.Running:
1021 return timeRemaining === undefined ? i18n.tr("Downloading") : timeRemaining;
1022 case Menus.TransferState.Paused:
1023 return i18n.tr("Paused, tap to resume");
1024 case Menus.TransferState.Canceled:
1025 return i18n.tr("Canceled");
1026 case Menus.TransferState.Finished:
1027 return i18n.tr("Finished");
1028 case Menus.TransferState.Error:
1029 return i18n.tr("Failed, tap to retry");
1034 onMenuModelChanged: {
1037 onMenuIndexChanged: {
1041 actionGroup.activateAction.activate(uid);
1044 actionGroup.cancelAction.activate(uid);
1047 function loadAttributes() {
1048 if (!menuModel || menuIndex == -1) return;
1049 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-uid': 'string'});
1055 id: buttonSectionMenu;
1058 objectName: "buttonSectionMenu"
1059 property QtObject menuData: null
1060 property var menuModel: menuFactory.menuModel
1061 property int menuIndex: -1
1062 property var extendedData: menuData && menuData.ext || undefined
1064 iconSource: menuData && menuData.icon || ""
1065 enabled: menuData && menuData.sensitive || false
1066 highlightWhenPressed: false
1067 text: menuData && menuData.label || ""
1068 foregroundColor: theme.palette.normal.backgroundText
1069 buttonText: getExtendedProperty(extendedData, "xCanonicalExtraLabel", "")
1071 onMenuModelChanged: {
1074 onMenuIndexChanged: {
1077 function loadAttributes() {
1078 if (!menuModel || menuIndex == -1) return;
1079 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-extra-label': 'string'});
1082 onButtonClicked: menuModel.activate(menuIndex);
1086 function load(modelData) {
1087 var component = getComponentForIndicatorEntryAction(modelData.action)
1088 if (component !== undefined) {
1092 component = getComponentForIndicatorEntryType(modelData.type)
1093 if (component !== undefined) {
1097 if (modelData.isCheck) {
1098 return checkableMenu;
1100 if (modelData.isRadio) {
1103 if (modelData.isSeparator) {
1104 return separatorMenu;
1106 if (modelData.action !== undefined && modelData.action.indexOf("settings") > -1) {
1107 // FIXME : At the moment, the indicators aren't using
1108 // com.canonical.indicators.link for settings menu. Need to fudge it.
1111 return standardMenu;