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 Ubuntu.Settings.Menus 0.1 as Menus
19 import Ubuntu.Settings.Components 0.1
21 import Utils 0.1 as Utils
22 import Ubuntu.Components.ListItems 0.1 as ListItems
23 import Ubuntu.Components 1.2
24 import Unity.Session 0.1
29 property var rootModel: null
30 property var menuModel: null
34 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
35 "unity.widgets.systemsettings.tablet.switch" : switchMenu,
37 "com.canonical.indicator.button" : buttonMenu,
38 "com.canonical.indicator.div" : separatorMenu,
39 "com.canonical.indicator.section" : sectionMenu,
40 "com.canonical.indicator.progress" : progressMenu,
41 "com.canonical.indicator.slider" : sliderMenu,
42 "com.canonical.indicator.switch" : switchMenu,
43 "com.canonical.indicator.alarm" : alarmMenu,
44 "com.canonical.indicator.appointment" : appointmentMenu,
45 "com.canonical.indicator.transfer" : transferMenu,
46 "com.canonical.indicator.button-section" : buttonSectionMenu,
47 "com.canonical.indicator.link" : linkMenu,
49 "com.canonical.indicator.messages.messageitem" : messageItem,
50 "com.canonical.indicator.messages.sourceitem" : groupedMessage,
52 "com.canonical.unity.slider" : sliderMenu,
53 "com.canonical.unity.switch" : switchMenu,
55 "com.canonical.unity.media-player" : mediaPayerMenu,
56 "com.canonical.unity.playback-item" : playbackItemMenu,
58 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
59 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
60 "com.canonical.indicator.network.modeminfoitem" : modeminfoitem,
62 "com.canonical.indicator.calendar": calendarMenu,
63 "com.canonical.indicator.location": timezoneMenu,
65 "indicator.user-menu-item": userMenuItem,
66 "indicator.guest-menu-item": userMenuItem
68 "indicator-messages" : {
69 "com.canonical.indicator.button" : messagesButtonMenu
73 function getExtendedProperty(object, propertyName, defaultValue) {
74 if (object && object.hasOwnProperty(propertyName)) {
75 return object[propertyName];
84 objectName: "separatorMenu"
93 objectName: "sliderMenu"
94 property QtObject menuData: null
95 property var menuModel: menuFactory.menuModel
96 property int menuIndex: -1
97 property var extendedData: menuData && menuData.ext || undefined
98 property var serverValue: getExtendedProperty(menuData, "actionState", undefined)
100 text: menuData && menuData.label || ""
101 iconSource: menuData && menuData.icon || ""
102 minIcon: getExtendedProperty(extendedData, "minIcon", "")
103 maxIcon: getExtendedProperty(extendedData, "maxIcon", "")
105 minimumValue: getExtendedProperty(extendedData, "minValue", 0.0)
107 var maximum = getExtendedProperty(extendedData, "maxValue", 1.0);
108 if (maximum <= minimumValue) {
109 return minimumValue + 1;
113 enabled: menuData && menuData.sensitive || false
114 highlightWhenPressed: false
116 onMenuModelChanged: {
119 onMenuIndexChanged: {
123 function loadAttributes() {
124 if (!menuModel || menuIndex == -1) return;
125 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
126 'max-value': 'double',
128 'max-icon': 'icon'});
131 ServerPropertySynchroniser {
133 syncTimeout: Utils.Constants.indicatorValueTimeout
134 bufferedSyncTimeout: true
135 maximumWaitBufferInterval: 16
137 serverTarget: sliderItem
138 serverProperty: "serverValue"
139 userTarget: sliderItem
140 userProperty: "value"
142 onSyncTriggered: menuModel.changeState(menuIndex, value)
151 objectName: "buttonMenu"
152 property QtObject menuData: null
153 property var menuModel: menuFactory.menuModel
154 property int menuIndex: -1
156 buttonText: menuData && menuData.label || ""
157 enabled: menuData && menuData.sensitive || false
158 highlightWhenPressed: false
161 menuModel.activate(menuIndex);
167 id: messagesButtonMenu;
170 objectName: "messagesButtonMenu"
171 property QtObject menuData: null
172 property var menuModel: menuFactory.menuModel
173 property int menuIndex: -1
175 implicitHeight: units.gu(5)
176 enabled: menuData && menuData.sensitive || false
180 text: menuData && menuData.label || ""
181 anchors.centerIn: parent
187 fill: buttonMenuLabel
188 margins: units.gu(-1)
190 onClicked: menuModel.activate(menuIndex);
199 objectName: "sectionMenu"
200 property QtObject menuData: null
201 property var menuIndex: undefined
203 text: menuData && menuData.label || ""
211 Menus.ProgressValueMenu {
212 objectName: "progressMenu"
213 property QtObject menuData: null
214 property int menuIndex: -1
216 text: menuData && menuData.label || ""
217 iconSource: menuData && menuData.icon || ""
218 value : menuData && menuData.actionState || 0.0
219 enabled: menuData && menuData.sensitive || false
220 highlightWhenPressed: false
228 objectName: "standardMenu"
229 property QtObject menuData: null
230 property int menuIndex: -1
232 text: menuData && menuData.label || ""
233 iconSource: menuData && menuData.icon || ""
234 enabled: menuData && menuData.sensitive || false
235 highlightWhenPressed: false
238 menuModel.activate(menuIndex);
241 // FIXME : At the moment, the indicators aren't using
242 // com.canonical.indicators.link for settings menu. Need to fudge it.
243 property bool settingsMenu: menuData && menuData.action.indexOf("settings") > -1 || false
244 backColor: settingsMenu ? Qt.rgba(1,1,1,0.07) : "transparent"
245 component: settingsMenu ? buttonForSettings : undefined
247 id: buttonForSettings
252 color: Theme.palette.selected.backgroundText
262 objectName: "linkMenu"
263 property QtObject menuData: null
264 property int menuIndex: -1
266 text: menuData && menuData.label || ""
267 iconSource: menuData && menuData.icon || ""
268 enabled: menuData && menuData.sensitive || false
269 highlightWhenPressed: false
272 menuModel.activate(menuIndex);
275 backColor: Qt.rgba(1,1,1,0.07)
277 component: menuData.icon ? icon : undefined
281 source: menuData.icon
284 color: Theme.palette.selected.backgroundText
293 Menus.CheckableMenu {
295 objectName: "checkableMenu"
296 property QtObject menuData: null
297 property int menuIndex: -1
298 property bool serverChecked: menuData && menuData.isToggled || false
300 text: menuData && menuData.label || ""
301 enabled: menuData && menuData.sensitive || false
302 checked: serverChecked
303 highlightWhenPressed: false
305 ServerPropertySynchroniser {
307 syncTimeout: Utils.Constants.indicatorValueTimeout
309 serverTarget: checkItem
310 serverProperty: "serverChecked"
311 userTarget: checkItem
312 userProperty: "checked"
314 onSyncTriggered: menuModel.activate(checkItem.menuIndex)
324 objectName: "switchMenu"
325 property QtObject menuData: null
326 property int menuIndex: -1
327 property bool serverChecked: menuData && menuData.isToggled || false
329 text: menuData && menuData.label || ""
330 iconSource: menuData && menuData.icon || ""
331 enabled: menuData && menuData.sensitive || false
332 checked: serverChecked
333 highlightWhenPressed: false
335 ServerPropertySynchroniser {
337 syncTimeout: Utils.Constants.indicatorValueTimeout
339 serverTarget: switchItem
340 serverProperty: "serverChecked"
341 userTarget: switchItem
342 userProperty: "checked"
344 onSyncTriggered: menuModel.activate(switchItem.menuIndex);
353 objectName: "alarmMenu"
354 property QtObject menuData: null
355 property var menuModel: menuFactory.menuModel
356 property int menuIndex: -1
357 property var extendedData: menuData && menuData.ext || undefined
358 // TODO - bug #1260728
359 property var timeFormatter: Utils.GDateTimeFormatter {
360 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
361 format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
364 text: menuData && menuData.label || ""
365 iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
366 time: timeFormatter.timeString
367 enabled: menuData && menuData.sensitive || false
368 highlightWhenPressed: false
370 onMenuModelChanged: {
373 onMenuIndexChanged: {
377 menuModel.activate(menuIndex);
380 function loadAttributes() {
381 if (!menuModel || menuIndex == -1) return;
382 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
383 'x-canonical-time-format': 'string'});
392 objectName: "appointmentMenu"
393 property QtObject menuData: null
394 property var menuModel: menuFactory.menuModel
395 property int menuIndex: -1
396 property var extendedData: menuData && menuData.ext || undefined
397 // TODO - bug #1260728
398 property var timeFormatter: Utils.GDateTimeFormatter {
399 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
400 format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
403 text: menuData && menuData.label || ""
404 iconSource: menuData && menuData.icon || "image://theme/calendar"
405 time: timeFormatter.timeString
406 eventColor: getExtendedProperty(extendedData, "xCanonicalColor", Qt.rgba(0.0, 0.0, 0.0, 0.0))
407 enabled: menuData && menuData.sensitive || false
408 highlightWhenPressed: false
410 onMenuModelChanged: {
413 onMenuIndexChanged: {
417 menuModel.activate(menuIndex);
420 function loadAttributes() {
421 if (!menuModel || menuIndex == -1) return;
422 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
423 'x-canonical-time': 'int64',
424 'x-canonical-time-format': 'string'});
432 Menus.UserSessionMenu {
433 objectName: "userSessionMenu"
434 highlightWhenPressed: false
436 property QtObject menuData: null
437 property var menuModel: menuFactory.menuModel
438 property int menuIndex: -1
440 name: menuData && menuData.label || "" // label is the user's real name
441 iconSource: menuData && menuData.icon || ""
443 // would be better to compare with the logname but sadly the indicator doesn't expose that
444 active: DBusUnitySessionService.RealName() !== "" ? DBusUnitySessionService.RealName() == name
445 : DBusUnitySessionService.UserName() == name
448 menuModel.activate(menuIndex);
457 objectName: "calendarMenu"
458 highlightWhenPressed: false
468 objectName: "timezoneMenu"
470 property QtObject menuData: null
471 property var menuModel: menuFactory.menuModel
472 property int menuIndex: -1
473 property var extendedData: menuData && menuData.ext || undefined
474 readonly property string tz: getExtendedProperty(extendedData, "xCanonicalTimezone", "UTC")
475 property var updateTimer: Timer {
477 running: tzMenuItem.visible // only run when we're open
478 onTriggered: tzMenuItem.time = Utils.TimezoneFormatter.currentTimeInTimezone(tzMenuItem.tz)
481 city: menuData && menuData.label || ""
482 time: Utils.TimezoneFormatter.currentTimeInTimezone(tz)
483 enabled: menuData && menuData.sensitive || false
485 onMenuModelChanged: {
488 onMenuIndexChanged: {
492 tzActionGroup.setLocation.activate(tz);
497 busType: DBus.SessionBus
498 busName: "com.canonical.indicator.datetime"
499 objectPath: "/com/canonical/indicator/datetime"
501 property variant setLocation: action("set-location")
503 Component.onCompleted: tzActionGroup.start()
506 function loadAttributes() {
507 if (!menuModel || menuIndex == -1) return;
508 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-timezone': 'string'});
517 objectName: "wifiSection"
518 property QtObject menuData: null
519 property var menuModel: menuFactory.menuModel
520 property int menuIndex: -1
521 property var extendedData: menuData && menuData.ext || undefined
523 text: menuData && menuData.label || ""
524 busy: getExtendedProperty(extendedData, "xCanonicalBusyAction", false)
526 onMenuModelChanged: {
529 onMenuIndexChanged: {
533 function loadAttributes() {
534 if (!menuModel || menuIndex == -1) return;
535 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
543 Menus.AccessPointMenu {
545 objectName: "accessPoint"
546 property QtObject menuData: null
547 property var menuModel: menuFactory.menuModel
548 property int menuIndex: -1
549 property var extendedData: menuData && menuData.ext || undefined
550 property bool serverChecked: menuData && menuData.isToggled || false
552 property var strengthAction: UnityMenuAction {
555 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
558 text: menuData && menuData.label || ""
559 enabled: menuData && menuData.sensitive || false
560 active: serverChecked
561 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
562 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
563 signalStrength: strengthAction.valid ? strengthAction.state : 0
564 highlightWhenPressed: false
566 onMenuModelChanged: {
569 onMenuIndexChanged: {
573 function loadAttributes() {
574 if (!menuModel || menuIndex == -1) return;
575 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
576 'x-canonical-wifi-ap-is-secure': 'bool',
577 'x-canonical-wifi-ap-strength-action': 'string'});
580 ServerPropertySynchroniser {
582 syncTimeout: Utils.Constants.indicatorValueTimeout
585 serverProperty: "serverChecked"
587 userProperty: "active"
588 userTrigger: "onTriggered"
590 onSyncTriggered: menuModel.activate(apItem.menuIndex)
598 objectName: "modemInfoItem"
599 property QtObject menuData: null
600 property var menuModel: menuFactory.menuModel
601 property int menuIndex: -1
602 property var extendedData: menuData && menuData.ext || undefined
603 highlightWhenPressed: false
605 property var statusLabelAction: UnityMenuAction {
608 name: getExtendedProperty(extendedData, "xCanonicalModemStatusLabelAction", "")
610 statusText: statusLabelAction.valid ? statusLabelAction.state : ""
612 property var statusIconAction: UnityMenuAction {
615 name: getExtendedProperty(extendedData, "xCanonicalModemStatusIconAction", "")
617 statusIcon: statusIconAction.valid ? statusIconAction.state : ""
619 property var connectivityIconAction: UnityMenuAction {
622 name: getExtendedProperty(extendedData, "xCanonicalModemConnectivityIconAction", "")
624 connectivityIcon: connectivityIconAction.valid ? connectivityIconAction.state : ""
626 property var simIdentifierLabelAction: UnityMenuAction {
629 name: getExtendedProperty(extendedData, "xCanonicalModemSimIdentifierLabelAction", "")
631 simIdentifierText: simIdentifierLabelAction.valid ? simIdentifierLabelAction.state : ""
633 property var roamingAction: UnityMenuAction {
636 name: getExtendedProperty(extendedData, "xCanonicalModemRoamingAction", "")
638 roaming: roamingAction.valid ? roamingAction.state : false
640 property var unlockAction: UnityMenuAction {
643 name: getExtendedProperty(extendedData, "xCanonicalModemLockedAction", "")
646 unlockAction.activate();
648 locked: unlockAction.valid ? unlockAction.state : false
650 onMenuModelChanged: {
653 onMenuIndexChanged: {
657 function loadAttributes() {
658 if (!menuModel || menuIndex == -1) return;
659 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-modem-status-label-action': 'string',
660 'x-canonical-modem-status-icon-action': 'string',
661 'x-canonical-modem-connectivity-icon-action': 'string',
662 'x-canonical-modem-sim-identifier-label-action': 'string',
663 'x-canonical-modem-roaming-action': 'string',
664 'x-canonical-modem-locked-action': 'string'});
672 MessageMenuItemFactory {
673 objectName: "messageItem"
674 menuModel: menuFactory.menuModel
681 Menus.GroupedMessageMenu {
682 objectName: "groupedMessage"
683 property QtObject menuData: null
684 property var menuModel: menuFactory.menuModel
685 property int menuIndex: -1
686 property var extendedData: menuData && menuData.ext || undefined
688 text: menuData && menuData.label || ""
689 iconSource: getExtendedProperty(extendedData, "icon", "image://theme/message")
690 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
691 enabled: menuData && menuData.sensitive || false
692 highlightWhenPressed: false
695 onMenuModelChanged: {
698 onMenuIndexChanged: {
702 menuModel.activate(menuIndex, true);
705 menuModel.activate(menuIndex, false);
708 function loadAttributes() {
709 if (!menuModel || menuIndex == -1) return;
710 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
718 Menus.MediaPlayerMenu {
719 objectName: "mediaPayerMenu"
720 property QtObject menuData: null
721 property var menuModel: menuFactory.menuModel
722 property int menuIndex: -1
723 property var actionState: menuData && menuData.actionState || undefined
724 property bool running: getExtendedProperty(actionState, "running", false)
726 playerIcon: menuData && menuData.icon || "image://theme/stock_music"
727 playerName: menuData && menuData.label || i18n.tr("Nothing is playing")
729 albumArt: getExtendedProperty(actionState, "art-url", "image://theme/stock_music")
730 song: getExtendedProperty(actionState, "title", "")
731 artist: getExtendedProperty(actionState, "artist", "")
732 album: getExtendedProperty(actionState, "album", "")
733 showTrack: running && (state == "Playing" || state == "Paused")
734 state: getExtendedProperty(actionState, "state", "")
735 enabled: menuData && menuData.sensitive || false
736 highlightWhenPressed: false
740 model.activate(modelIndex);
746 id: playbackItemMenu;
748 Menus.PlaybackItemMenu {
749 objectName: "playbackItemMenu"
750 property QtObject menuData: null
751 property var menuModel: menuFactory.menuModel
752 property int menuIndex: -1
753 property var extendedData: menuData && menuData.ext || undefined
755 property var playAction: UnityMenuAction {
758 name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
760 property var nextAction: UnityMenuAction {
763 name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
765 property var previousAction: UnityMenuAction {
768 name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
771 playing: playAction.state === "Playing"
772 canPlay: playAction.valid
773 canGoNext: nextAction.valid
774 canGoPrevious: previousAction.valid
775 enabled: menuData && menuData.sensitive || false
776 highlightWhenPressed: false
779 playAction.activate();
782 nextAction.activate();
785 previousAction.activate();
787 onMenuModelChanged: {
790 onMenuIndexChanged: {
794 function loadAttributes() {
795 if (!menuModel || menuIndex == -1) return;
796 menuModel.loadExtendedAttributes(modelIndex, {'x-canonical-play-action': 'string',
797 'x-canonical-next-action': 'string',
798 'x-canonical-previous-action': 'string'});
807 objectName: "transferMenu"
809 property QtObject menuData: null
810 property var menuModel: menuFactory.menuModel
811 property int menuIndex: -1
812 property var extendedData: menuData && menuData.ext || undefined
813 property var uid: getExtendedProperty(extendedData, "xCanonicalUid", undefined)
815 text: menuData && menuData.label || ""
816 iconSource: menuData && menuData.icon || "image://theme/transfer-none"
818 enabled: menuData && menuData.sensitive || false
819 highlightWhenPressed: false
826 busName: rootModel.busName
827 objectPath: rootModel.actions["indicator"]
829 property var activateAction: action("activate-transfer")
830 property var cancelAction: action("cancel-transfer")
831 property var transferStateAction: uid !== undefined ? action("transfer-state."+uid) : null
833 Component.onCompleted: actionGroup.start()
836 property var transferState: {
837 if (actionGroup.transferStateAction === null) return undefined;
838 return actionGroup.transferStateAction.valid ? actionGroup.transferStateAction.state : undefined
841 property var runningState : transferState !== undefined ? transferState["state"] : undefined
842 property var secondsLeft : transferState !== undefined ? transferState["seconds-left"] : undefined
844 active: runningState !== undefined && runningState !== Menus.TransferState.Finished
845 progress: transferState !== undefined ? transferState["percent"] : 0.0
847 // TODO - Should be in the SDK
848 property var timeRemaining: {
849 if (secondsLeft === undefined) return undefined;
852 var hours = Math.floor(secondsLeft / (60 * 60));
853 var minutes = Math.floor(secondsLeft / 60) % 60;
854 var seconds = secondsLeft % 60;
856 remaining += i18n.tr("%1 hour", "%1 hours", hours).arg(hours)
859 if (remaining != "") remaining += ", ";
860 remaining += i18n.tr("%1 minute", "%1 minutes", minutes).arg(minutes)
862 // don't include seconds if hours > 0
863 if (hours == 0 && minutes < 5 && seconds > 0) {
864 if (remaining != "") remaining += ", ";
865 remaining += i18n.tr("%1 second", "%1 seconds", seconds).arg(seconds)
868 remaining = i18n.tr("0 seconds");
869 // Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
870 return i18n.tr("%1 remaining").arg(remaining);
874 switch (runningState) {
875 case Menus.TransferState.Queued:
876 return i18n.tr("In queue…");
877 case Menus.TransferState.Hashing:
878 case Menus.TransferState.Processing:
879 case Menus.TransferState.Running:
880 return timeRemaining === undefined ? i18n.tr("Downloading") : timeRemaining;
881 case Menus.TransferState.Paused:
882 return i18n.tr("Paused, tap to resume");
883 case Menus.TransferState.Canceled:
884 return i18n.tr("Canceled");
885 case Menus.TransferState.Finished:
886 return i18n.tr("Finished");
887 case Menus.TransferState.Error:
888 return i18n.tr("Failed, tap to retry");
893 onMenuModelChanged: {
896 onMenuIndexChanged: {
900 actionGroup.activateAction.activate(uid);
903 actionGroup.cancelAction.activate(uid);
906 function loadAttributes() {
907 if (!menuModel || menuIndex == -1) return;
908 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-uid': 'string'});
914 id: buttonSectionMenu;
917 objectName: "buttonSectionMenu"
918 property QtObject menuData: null
919 property var menuModel: menuFactory.menuModel
920 property int menuIndex: -1
921 property var extendedData: menuData && menuData.ext || undefined
923 iconSource: menuData && menuData.icon || ""
924 enabled: menuData && menuData.sensitive || false
925 highlightWhenPressed: false
926 text: menuData && menuData.label || ""
927 foregroundColor: Theme.palette.normal.backgroundText
929 onMenuModelChanged: {
932 onMenuIndexChanged: {
935 function loadAttributes() {
936 if (!menuModel || menuIndex == -1) return;
937 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-extra-label': 'string'});
940 component: Component {
942 objectName: "buttonSectionMenuControl"
943 text: getExtendedProperty(extendedData, "xCanonicalExtraLabel", "")
946 menuModel.activate(menuIndex);
953 function load(modelData, context) {
954 if (modelData.type !== undefined && modelData.type !== "") {
955 var component = undefined;
957 var contextComponents = _map[context];
958 if (contextComponents !== undefined) {
959 component = contextComponents[modelData.type];
962 if (component === undefined) {
963 component = _map["default"][modelData.type];
965 if (component !== undefined) {
968 console.debug("Don't know how to make " + modelData.type + " for " + context);
970 if (modelData.isCheck || modelData.isRadio) {
971 return checkableMenu;
973 if (modelData.isSeparator) {
974 return separatorMenu;