2 * Copyright 2013,2015 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
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,
64 "com.canonical.indicator.calendar": calendarMenu,
65 "com.canonical.indicator.location": timezoneMenu,
67 "indicator-session": {
68 "indicator.user-menu-item": Platform.isPC ? userMenuItem : null,
69 "indicator.guest-menu-item": Platform.isPC ? userMenuItem : null,
70 "com.canonical.indicator.switch": Math.min(Screen.width, Screen.height) > units.gu(60) ? switchMenu : null // Desktop mode switch
72 "indicator-messages" : {
73 "com.canonical.indicator.button" : messagesButtonMenu
77 function getExtendedProperty(object, propertyName, defaultValue) {
78 if (object && object.hasOwnProperty(propertyName)) {
79 return object[propertyName];
88 objectName: "separatorMenu"
97 objectName: "sliderMenu"
98 property QtObject menuData: null
99 property var menuModel: menuFactory.menuModel
100 property int menuIndex: -1
101 property var extendedData: menuData && menuData.ext || undefined
102 property var serverValue: getExtendedProperty(menuData, "actionState", undefined)
104 text: menuData && menuData.label || ""
105 iconSource: menuData && menuData.icon || ""
106 minIcon: getExtendedProperty(extendedData, "minIcon", "")
107 maxIcon: getExtendedProperty(extendedData, "maxIcon", "")
109 minimumValue: getExtendedProperty(extendedData, "minValue", 0.0)
111 var maximum = getExtendedProperty(extendedData, "maxValue", 1.0);
112 if (maximum <= minimumValue) {
113 return minimumValue + 1;
117 enabled: menuData && menuData.sensitive || false
118 highlightWhenPressed: false
120 onMenuModelChanged: {
123 onMenuIndexChanged: {
127 function loadAttributes() {
128 if (!menuModel || menuIndex == -1) return;
129 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
130 'max-value': 'double',
133 'x-canonical-sync-action': 'string'});
136 ServerPropertySynchroniser {
137 id: sliderPropertySync
139 syncTimeout: Utils.Constants.indicatorValueTimeout
140 bufferedSyncTimeout: true
141 maximumWaitBufferInterval: 16
143 serverTarget: sliderItem
144 serverProperty: "serverValue"
145 userTarget: sliderItem
146 userProperty: "value"
148 onSyncTriggered: menuModel.changeState(menuIndex, value)
154 name: getExtendedProperty(extendedData, "xCanonicalSyncAction", "")
156 sliderPropertySync.reset();
157 sliderPropertySync.updateUserValue();
167 objectName: "buttonMenu"
168 property QtObject menuData: null
169 property var menuModel: menuFactory.menuModel
170 property int menuIndex: -1
172 buttonText: menuData && menuData.label || ""
173 enabled: menuData && menuData.sensitive || false
174 highlightWhenPressed: false
177 menuModel.activate(menuIndex);
183 id: messagesButtonMenu;
186 objectName: "messagesButtonMenu"
187 property QtObject menuData: null
188 property var menuModel: menuFactory.menuModel
189 property int menuIndex: -1
191 implicitHeight: units.gu(5)
192 enabled: menuData && menuData.sensitive || false
196 text: menuData && menuData.label || ""
197 anchors.centerIn: parent
203 fill: buttonMenuLabel
204 margins: units.gu(-1)
206 onClicked: menuModel.activate(menuIndex);
215 objectName: "sectionMenu"
216 property QtObject menuData: null
217 property var menuIndex: undefined
219 text: menuData && menuData.label || ""
227 Menus.ProgressValueMenu {
228 objectName: "progressMenu"
229 property QtObject menuData: null
230 property int menuIndex: -1
232 text: menuData && menuData.label || ""
233 iconSource: menuData && menuData.icon || ""
234 value : menuData && menuData.actionState || 0.0
235 enabled: menuData && menuData.sensitive || false
236 // FIXME: Because of this bug, setting it to the theme foreground color (white)
237 // currently doesn't work. Let's hack it to be "close enough"
238 // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1555784
239 foregroundColor: "#fffffe"
240 highlightWhenPressed: false
248 objectName: "standardMenu"
249 property QtObject menuData: null
250 property int menuIndex: -1
252 text: menuData && menuData.label || ""
253 iconSource: menuData && menuData.icon || ""
254 enabled: menuData && menuData.sensitive || false
255 highlightWhenPressed: false
258 menuModel.activate(menuIndex);
261 // FIXME : At the moment, the indicators aren't using
262 // com.canonical.indicators.link for settings menu. Need to fudge it.
263 property bool settingsMenu: menuData && menuData.action.indexOf("settings") > -1 || false
264 backColor: settingsMenu ? Qt.rgba(1,1,1,0.07) : "transparent"
265 component: settingsMenu ? buttonForSettings : undefined
267 id: buttonForSettings
272 color: theme.palette.normal.backgroundText
282 objectName: "linkMenu"
283 property QtObject menuData: null
284 property int menuIndex: -1
286 text: menuData && menuData.label || ""
287 iconSource: menuData && menuData.icon || ""
288 enabled: menuData && menuData.sensitive || false
289 highlightWhenPressed: false
292 menuModel.activate(menuIndex);
295 backColor: Qt.rgba(1,1,1,0.07)
297 component: menuData.icon ? icon : undefined
301 source: menuData.icon
304 color: theme.palette.normal.backgroundText
313 Menus.CheckableMenu {
315 objectName: "checkableMenu"
316 property QtObject menuData: null
317 property int menuIndex: -1
318 property bool serverChecked: menuData && menuData.isToggled || false
320 text: menuData && menuData.label || ""
321 enabled: menuData && menuData.sensitive || false
322 checked: serverChecked
323 highlightWhenPressed: false
325 ServerPropertySynchroniser {
327 syncTimeout: Utils.Constants.indicatorValueTimeout
329 serverTarget: checkItem
330 serverProperty: "serverChecked"
331 userTarget: checkItem
332 userProperty: "checked"
334 onSyncTriggered: menuModel.activate(checkItem.menuIndex)
344 objectName: "switchMenu"
345 property QtObject menuData: null
346 property int menuIndex: -1
347 property bool serverChecked: menuData && menuData.isToggled || false
349 text: menuData && menuData.label || ""
350 iconSource: menuData && menuData.icon || ""
351 enabled: menuData && menuData.sensitive || false
352 checked: serverChecked
353 highlightWhenPressed: false
355 ServerPropertySynchroniser {
357 syncTimeout: Utils.Constants.indicatorValueTimeout
359 serverTarget: switchItem
360 serverProperty: "serverChecked"
361 userTarget: switchItem
362 userProperty: "checked"
364 onSyncTriggered: menuModel.activate(switchItem.menuIndex);
374 objectName: "alarmMenu"
375 property QtObject menuData: null
376 property var menuModel: menuFactory.menuModel
377 property int menuIndex: -1
378 property var extendedData: menuData && menuData.ext || undefined
380 property date serverTime: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
382 frequency: LiveTimer.Relative
383 relativeTime: alarmItem.serverTime
384 onTrigger: alarmItem.serverTime = new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
387 text: menuData && menuData.label || ""
388 iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
389 time: i18n.relativeDateTime(serverTime)
390 enabled: menuData && menuData.sensitive || false
391 highlightWhenPressed: false
393 onMenuModelChanged: {
396 onMenuIndexChanged: {
400 menuModel.activate(menuIndex);
403 function loadAttributes() {
404 if (!menuModel || menuIndex == -1) return;
405 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64'});
415 objectName: "appointmentMenu"
416 property QtObject menuData: null
417 property var menuModel: menuFactory.menuModel
418 property int menuIndex: -1
419 property var extendedData: menuData && menuData.ext || undefined
421 property date serverTime: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
423 frequency: LiveTimer.Relative
424 relativeTime: appointmentItem.serverTime
425 onTrigger: appointmentItem.serverTime = new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
428 text: menuData && menuData.label || ""
429 iconSource: menuData && menuData.icon || "image://theme/calendar"
430 time: i18n.relativeDateTime(serverTime)
431 eventColor: getExtendedProperty(extendedData, "xCanonicalColor", Qt.rgba(0.0, 0.0, 0.0, 0.0))
432 enabled: menuData && menuData.sensitive || false
433 highlightWhenPressed: false
435 onMenuModelChanged: {
438 onMenuIndexChanged: {
442 menuModel.activate(menuIndex);
445 function loadAttributes() {
446 if (!menuModel || menuIndex == -1) return;
447 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
448 'x-canonical-time': 'int64'});
456 Menus.UserSessionMenu {
457 objectName: "userSessionMenu"
458 highlightWhenPressed: false
460 property QtObject menuData: null
461 property var menuModel: menuFactory.menuModel
462 property int menuIndex: -1
464 name: menuData && menuData.label || "" // label is the user's real name
465 iconSource: menuData && menuData.icon || ""
467 // would be better to compare with the logname but sadly the indicator doesn't expose that
468 active: DBusUnitySessionService.RealName() !== "" ? DBusUnitySessionService.RealName() == name
469 : DBusUnitySessionService.UserName() == name
472 menuModel.activate(menuIndex);
481 objectName: "calendarMenu"
482 highlightWhenPressed: false
492 objectName: "timezoneMenu"
494 property QtObject menuData: null
495 property var menuModel: menuFactory.menuModel
496 property int menuIndex: -1
497 property var extendedData: menuData && menuData.ext || undefined
498 readonly property string tz: getExtendedProperty(extendedData, "xCanonicalTimezone", "UTC")
499 property var updateTimer: Timer {
501 running: tzMenuItem.visible // only run when we're open
502 onTriggered: tzMenuItem.time = Utils.TimezoneFormatter.currentTimeInTimezone(tzMenuItem.tz)
505 city: menuData && menuData.label || ""
506 time: Utils.TimezoneFormatter.currentTimeInTimezone(tz)
507 enabled: menuData && menuData.sensitive || false
509 onMenuModelChanged: {
512 onMenuIndexChanged: {
516 tzActionGroup.setLocation.activate(tz);
521 busType: DBus.SessionBus
522 busName: "com.canonical.indicator.datetime"
523 objectPath: "/com/canonical/indicator/datetime"
525 property variant setLocation: action("set-location")
527 Component.onCompleted: tzActionGroup.start()
530 function loadAttributes() {
531 if (!menuModel || menuIndex == -1) return;
532 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-timezone': 'string'});
541 objectName: "wifiSection"
542 property QtObject menuData: null
543 property var menuModel: menuFactory.menuModel
544 property int menuIndex: -1
545 property var extendedData: menuData && menuData.ext || undefined
547 text: menuData && menuData.label || ""
548 busy: getExtendedProperty(extendedData, "xCanonicalBusyAction", false)
550 onMenuModelChanged: {
553 onMenuIndexChanged: {
557 function loadAttributes() {
558 if (!menuModel || menuIndex == -1) return;
559 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
567 Menus.AccessPointMenu {
569 objectName: "accessPoint"
570 property QtObject menuData: null
571 property var menuModel: menuFactory.menuModel
572 property int menuIndex: -1
573 property var extendedData: menuData && menuData.ext || undefined
574 property bool serverChecked: menuData && menuData.isToggled || false
576 property var strengthAction: UnityMenuAction {
579 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
582 text: menuData && menuData.label || ""
583 enabled: menuData && menuData.sensitive || false
584 active: serverChecked
585 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
586 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
588 if (strengthAction.valid) {
589 var state = strengthAction.state; // handle both int and uchar
590 // FIXME remove the special casing when we switch to indicator-network completely
591 if (typeof state == "string") {
592 return state.charCodeAt();
598 highlightWhenPressed: false
600 onMenuModelChanged: {
603 onMenuIndexChanged: {
607 function loadAttributes() {
608 if (!menuModel || menuIndex == -1) return;
609 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
610 'x-canonical-wifi-ap-is-secure': 'bool',
611 'x-canonical-wifi-ap-strength-action': 'string'});
614 ServerPropertySynchroniser {
616 syncTimeout: Utils.Constants.indicatorValueTimeout
619 serverProperty: "serverChecked"
621 userProperty: "active"
622 userTrigger: "onTriggered"
624 onSyncTriggered: menuModel.activate(apItem.menuIndex)
631 Menus.ModemInfoItem {
632 objectName: "modemInfoItem"
633 property QtObject menuData: null
634 property var menuModel: menuFactory.menuModel
635 property int menuIndex: -1
636 property var extendedData: menuData && menuData.ext || undefined
637 highlightWhenPressed: false
639 property var statusLabelAction: UnityMenuAction {
642 name: getExtendedProperty(extendedData, "xCanonicalModemStatusLabelAction", "")
644 statusText: statusLabelAction.valid ? statusLabelAction.state : ""
646 property var statusIconAction: UnityMenuAction {
649 name: getExtendedProperty(extendedData, "xCanonicalModemStatusIconAction", "")
651 statusIcon: statusIconAction.valid ? statusIconAction.state : ""
653 property var connectivityIconAction: UnityMenuAction {
656 name: getExtendedProperty(extendedData, "xCanonicalModemConnectivityIconAction", "")
658 connectivityIcon: connectivityIconAction.valid ? connectivityIconAction.state : ""
660 property var simIdentifierLabelAction: UnityMenuAction {
663 name: getExtendedProperty(extendedData, "xCanonicalModemSimIdentifierLabelAction", "")
665 simIdentifierText: simIdentifierLabelAction.valid ? simIdentifierLabelAction.state : ""
667 property var roamingAction: UnityMenuAction {
670 name: getExtendedProperty(extendedData, "xCanonicalModemRoamingAction", "")
672 roaming: roamingAction.valid ? roamingAction.state : false
674 property var unlockAction: UnityMenuAction {
677 name: getExtendedProperty(extendedData, "xCanonicalModemLockedAction", "")
680 unlockAction.activate();
682 locked: unlockAction.valid ? unlockAction.state : false
684 onMenuModelChanged: {
687 onMenuIndexChanged: {
691 function loadAttributes() {
692 if (!menuModel || menuIndex == -1) return;
693 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-modem-status-label-action': 'string',
694 'x-canonical-modem-status-icon-action': 'string',
695 'x-canonical-modem-connectivity-icon-action': 'string',
696 'x-canonical-modem-sim-identifier-label-action': 'string',
697 'x-canonical-modem-roaming-action': 'string',
698 'x-canonical-modem-locked-action': 'string'});
706 MessageMenuItemFactory {
707 objectName: "messageItem"
708 menuModel: menuFactory.menuModel
715 Menus.GroupedMessageMenu {
716 objectName: "groupedMessage"
717 property QtObject menuData: null
718 property var menuModel: menuFactory.menuModel
719 property int menuIndex: -1
720 property var extendedData: menuData && menuData.ext || undefined
722 text: menuData && menuData.label || ""
723 iconSource: getExtendedProperty(extendedData, "icon", "image://theme/message")
724 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
725 enabled: menuData && menuData.sensitive || false
726 highlightWhenPressed: false
729 onMenuModelChanged: {
732 onMenuIndexChanged: {
736 menuModel.activate(menuIndex, true);
739 menuModel.activate(menuIndex, false);
742 function loadAttributes() {
743 if (!menuModel || menuIndex == -1) return;
744 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
752 Menus.MediaPlayerMenu {
753 objectName: "mediaPayerMenu"
754 property QtObject menuData: null
755 property var menuModel: menuFactory.menuModel
756 property int menuIndex: -1
757 property var actionState: menuData && menuData.actionState || undefined
758 property bool running: getExtendedProperty(actionState, "running", false)
760 playerIcon: menuData && menuData.icon || "image://theme/stock_music"
761 playerName: menuData && menuData.label || i18n.tr("Nothing is playing")
763 albumArt: getExtendedProperty(actionState, "art-url", "image://theme/stock_music")
764 song: getExtendedProperty(actionState, "title", "")
765 artist: getExtendedProperty(actionState, "artist", "")
766 album: getExtendedProperty(actionState, "album", "")
767 showTrack: running && (state == "Playing" || state == "Paused")
768 state: getExtendedProperty(actionState, "state", "")
769 enabled: menuData && menuData.sensitive || false
770 highlightWhenPressed: false
774 model.activate(modelIndex);
780 id: playbackItemMenu;
782 Menus.PlaybackItemMenu {
783 objectName: "playbackItemMenu"
784 property QtObject menuData: null
785 property var menuModel: menuFactory.menuModel
786 property int menuIndex: -1
787 property var extendedData: menuData && menuData.ext || undefined
789 property var playAction: UnityMenuAction {
792 name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
794 property var nextAction: UnityMenuAction {
797 name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
799 property var previousAction: UnityMenuAction {
802 name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
805 playing: playAction.state === "Playing"
806 canPlay: playAction.valid
807 canGoNext: nextAction.valid
808 canGoPrevious: previousAction.valid
809 enabled: menuData && menuData.sensitive || false
810 highlightWhenPressed: false
813 playAction.activate();
816 nextAction.activate();
819 previousAction.activate();
821 onMenuModelChanged: {
824 onMenuIndexChanged: {
828 function loadAttributes() {
829 if (!menuModel || menuIndex == -1) return;
830 menuModel.loadExtendedAttributes(modelIndex, {'x-canonical-play-action': 'string',
831 'x-canonical-next-action': 'string',
832 'x-canonical-previous-action': 'string'});
841 objectName: "transferMenu"
843 property QtObject menuData: null
844 property var menuModel: menuFactory.menuModel
845 property int menuIndex: -1
846 property var extendedData: menuData && menuData.ext || undefined
847 property var uid: getExtendedProperty(extendedData, "xCanonicalUid", undefined)
849 text: menuData && menuData.label || ""
850 iconSource: menuData && menuData.icon || "image://theme/transfer-none"
852 enabled: menuData && menuData.sensitive || false
853 highlightWhenPressed: false
860 busName: rootModel.busName
861 objectPath: rootModel.actions["indicator"]
863 property var activateAction: action("activate-transfer")
864 property var cancelAction: action("cancel-transfer")
865 property var transferStateAction: uid !== undefined ? action("transfer-state."+uid) : null
867 Component.onCompleted: actionGroup.start()
870 property var transferState: {
871 if (actionGroup.transferStateAction === null) return undefined;
872 return actionGroup.transferStateAction.valid ? actionGroup.transferStateAction.state : undefined
875 property var runningState : transferState !== undefined ? transferState["state"] : undefined
876 property var secondsLeft : transferState !== undefined ? transferState["seconds-left"] : undefined
878 active: runningState !== undefined && runningState !== Menus.TransferState.Finished
879 progress: transferState !== undefined ? transferState["percent"] : 0.0
881 // TODO - Should be in the SDK
882 property var timeRemaining: {
883 if (secondsLeft === undefined) return undefined;
886 var hours = Math.floor(secondsLeft / (60 * 60));
887 var minutes = Math.floor(secondsLeft / 60) % 60;
888 var seconds = secondsLeft % 60;
890 remaining += i18n.tr("%1 hour", "%1 hours", hours).arg(hours)
893 if (remaining != "") remaining += ", ";
894 remaining += i18n.tr("%1 minute", "%1 minutes", minutes).arg(minutes)
896 // don't include seconds if hours > 0
897 if (hours == 0 && minutes < 5 && seconds > 0) {
898 if (remaining != "") remaining += ", ";
899 remaining += i18n.tr("%1 second", "%1 seconds", seconds).arg(seconds)
902 remaining = i18n.tr("0 seconds");
903 // Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
904 return i18n.tr("%1 remaining").arg(remaining);
908 switch (runningState) {
909 case Menus.TransferState.Queued:
910 return i18n.tr("In queue…");
911 case Menus.TransferState.Hashing:
912 case Menus.TransferState.Processing:
913 case Menus.TransferState.Running:
914 return timeRemaining === undefined ? i18n.tr("Downloading") : timeRemaining;
915 case Menus.TransferState.Paused:
916 return i18n.tr("Paused, tap to resume");
917 case Menus.TransferState.Canceled:
918 return i18n.tr("Canceled");
919 case Menus.TransferState.Finished:
920 return i18n.tr("Finished");
921 case Menus.TransferState.Error:
922 return i18n.tr("Failed, tap to retry");
927 onMenuModelChanged: {
930 onMenuIndexChanged: {
934 actionGroup.activateAction.activate(uid);
937 actionGroup.cancelAction.activate(uid);
940 function loadAttributes() {
941 if (!menuModel || menuIndex == -1) return;
942 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-uid': 'string'});
948 id: buttonSectionMenu;
951 objectName: "buttonSectionMenu"
952 property QtObject menuData: null
953 property var menuModel: menuFactory.menuModel
954 property int menuIndex: -1
955 property var extendedData: menuData && menuData.ext || undefined
957 iconSource: menuData && menuData.icon || ""
958 enabled: menuData && menuData.sensitive || false
959 highlightWhenPressed: false
960 text: menuData && menuData.label || ""
961 foregroundColor: theme.palette.normal.backgroundText
963 onMenuModelChanged: {
966 onMenuIndexChanged: {
969 function loadAttributes() {
970 if (!menuModel || menuIndex == -1) return;
971 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-extra-label': 'string'});
974 component: Component {
976 objectName: "buttonSectionMenuControl"
977 text: getExtendedProperty(extendedData, "xCanonicalExtraLabel", "")
980 menuModel.activate(menuIndex);
987 function load(modelData, context) {
988 // tweak indicator-session items
989 if (context === "indicator-session") {
990 if ((modelData.action === "indicator.logout" || modelData.action === "indicator.suspend" || modelData.action === "indicator.hibernate" ||
991 modelData.action === "indicator.reboot")
993 return null; // logout, suspend and hibernate hidden on devices
997 if (modelData.type !== undefined && modelData.type !== "") {
998 var component = undefined;
1000 var contextComponents = _map[context];
1001 if (contextComponents !== undefined) {
1002 component = contextComponents[modelData.type];
1005 if (component === undefined) {
1006 component = _map["default"][modelData.type];
1008 if (component !== undefined) {
1011 console.debug("Don't know how to make " + modelData.type + " for " + context);
1013 if (modelData.isCheck || modelData.isRadio) {
1014 return checkableMenu;
1016 if (modelData.isSeparator) {
1017 return separatorMenu;
1019 return standardMenu;