Warning, /plasma/latte-dock/plasmoid/package/contents/ui/ContextMenu.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2016 Smith AR <audoban@openmailbox.org>
0003     SPDX-FileCopyrightText: 2016 Michail Vourlakos <mvourlakos@gmail.com>
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 import QtQuick 2.0
0008 
0009 import org.kde.plasma.plasmoid 2.0
0010 
0011 import org.kde.plasma.core 2.0 as PlasmaCore
0012 import org.kde.plasma.components 2.0 as PlasmaComponents
0013 import org.kde.activities 0.1 as Activities
0014 import org.kde.taskmanager 0.1 as TaskManager
0015 
0016 import org.kde.latte.core 0.2 as LatteCore
0017 import org.kde.latte.private.tasks 0.1 as LatteTasks
0018 
0019 import "../code/activitiesTools.js" as ActivitiesTools
0020 
0021 PlasmaComponents.ContextMenu {
0022     id: menu
0023 
0024     property bool changingLayout: false
0025 
0026     property QtObject mpris2Source
0027     property QtObject backend
0028 
0029     property var modelIndex
0030     readonly property var atm: TaskManager.AbstractTasksModel
0031 
0032     placement: {
0033         if (root.location === PlasmaCore.Types.LeftEdge) {
0034             return PlasmaCore.Types.RightPosedTopAlignedPopup;
0035         } else if (root.location === PlasmaCore.Types.TopEdge) {
0036             return PlasmaCore.Types.BottomPosedLeftAlignedPopup;
0037         } else if (root.location === PlasmaCore.Types.RightEdge) {
0038             return PlasmaCore.Types.LeftPosedTopAlignedPopup;
0039         } else {
0040             return PlasmaCore.Types.TopPosedLeftAlignedPopup;
0041         }
0042     }
0043 
0044     minimumWidth: visualParent ? visualParent.width : 1
0045 
0046     property bool isOnAllActivitiesLauncher: true
0047     property bool showAllPlaces: false
0048 
0049     property int activitiesCount: 0
0050 
0051     readonly property string tailSeparatorText: plasmoid.formFactor === PlasmaCore.Types.Vertical ? i18n("Top Separator") :
0052                                                                                                     (!root.LayoutMirroring.enabled ? i18n("Left Separator") : i18n("Right Separator"))
0053     readonly property string headSeparatorText: plasmoid.formFactor === PlasmaCore.Types.Vertical ? i18n("Bottom Separator") :
0054                                                                                                     (!root.LayoutMirroring.enabled ? i18n("Right Separator") : i18n("Left Separator"))
0055 
0056     onStatusChanged: {
0057         if (visualParent && get(atm.LauncherUrlWithoutIcon) != null && status == PlasmaComponents.DialogStatus.Open) {
0058             launcherToggleAction.checked = (tasksModel.launcherPosition(get(atm.LauncherUrlWithoutIcon)) != -1);
0059             activitiesDesktopsMenu.refresh();
0060         } else if (status == PlasmaComponents.DialogStatus.Closed) {
0061             root.contextMenu = null;
0062             menu.destroy();
0063             backend.ungrabMouse(visualParent);
0064         }
0065     }
0066 
0067     function get(modelProp) {
0068         return tasksModel.data(modelIndex, modelProp)
0069     }
0070 
0071     function show() {
0072         loadDynamicLaunchActions(visualParent.m.LauncherUrlWithoutIcon);
0073         loadMyViewActions();
0074         // backend.ungrabMouse(visualParent);
0075         openRelative();
0076 
0077         if (LatteCore.WindowSystem.isPlatformWayland){
0078             //!Hiding previews under wayland it needs a delay otherwise it creates crashes
0079             windowsPreviewCheckerToNotShowTimer.start();
0080         } else {
0081             windowsPreviewDlg.hide("9.4");
0082         }
0083     }
0084 
0085     function newMenuItem(parent) {
0086         return Qt.createQmlObject(
0087                     "import org.kde.plasma.components 2.0 as PlasmaComponents;" +
0088                     "PlasmaComponents.MenuItem {}",
0089                     parent);
0090     }
0091 
0092     function newSeparator(parent) {
0093         return Qt.createQmlObject(
0094                     "import org.kde.plasma.components 2.0 as PlasmaComponents;" +
0095                     "PlasmaComponents.MenuItem { separator: true }",
0096                     parent);
0097     }
0098 
0099     function loadDynamicLaunchActions(launcherUrl) {
0100         var sections = [
0101                     {
0102                         title:   i18n("Places"),
0103                         group:   "places",
0104                         actions: backend.placesActions(launcherUrl, showAllPlaces, menu)
0105                     },
0106                     {
0107                         title:   i18n("Recent Files"),
0108                         group:   "recents",
0109                         actions: backend.recentDocumentActions(launcherUrl, menu)
0110                     },
0111                     {
0112                         title:   i18n("Actions"),
0113                         group:   "actions",
0114                         actions: backend.jumpListActions(launcherUrl, menu)
0115                     }
0116                 ]
0117 
0118         // C++ can override section heading by returning a QString as first action
0119         sections.forEach((section) => {
0120                              if (typeof section.actions[0] === "string") {
0121                                  section.title = section.actions.shift(); // take first
0122                              }
0123                          });
0124 
0125         // QMenu does not limit its width automatically. Even if we set a maximumWidth
0126         // it would just cut off text rather than eliding. So we do this manually.
0127         var textMetrics = Qt.createQmlObject("import QtQuick 2.4; TextMetrics {}", menu);
0128         var maximumWidth = theme.mSize(theme.defaultFont).width * 22;
0129 
0130         sections.forEach(function (section) {
0131             if (section["actions"].length > 0 || section["group"] == "actions") {
0132                 // Don't add the "Actions" header if the menu has nothing but actions
0133                 // in it, because then it's redundant (all menus have actions)
0134                 if (
0135                         (section["group"] != "actions") ||
0136                         (section["group"] == "actions" && (sections[0]["actions"].length > 0 || sections[1]["actions"].length > 0))
0137                         ) {
0138                     var sectionHeader = newMenuItem(menu);
0139                     sectionHeader.text = section["title"];
0140                     sectionHeader.section = true;
0141                     menu.addMenuItem(sectionHeader, startNewInstanceItem);
0142                 }
0143             }
0144 
0145             for (var i = 0; i < section["actions"].length; ++i) {
0146                 var item = newMenuItem(menu);
0147                 item.action = section["actions"][i];
0148 
0149                 // Crude way of manually eliding...
0150                 var elided = false;
0151                 textMetrics.text = Qt.binding(function() {
0152                     return item.action.text;
0153                 });
0154 
0155                 while (textMetrics.width > maximumWidth) {
0156                     item.action.text = item.action.text.slice(0, -1);
0157                     elided = true;
0158                 }
0159 
0160                 if (elided) {
0161                     item.action.text += "…";
0162                 }
0163 
0164                 menu.addMenuItem(item, startNewInstanceItem);
0165             }
0166         });
0167 
0168         // Add Media Player control actions
0169         var sourceName = mpris2Source.sourceNameForLauncherUrl(launcherUrl, get(atm.AppPid));
0170 
0171         var winIdList = atm.WinIdList;
0172 
0173         if (sourceName && !(get(winIdList) !== undefined && get(winIdList).length > 1)) {
0174             var playerData = mpris2Source.data[sourceName]
0175 
0176             if (playerData.CanControl) {
0177                 var menuItem = menu.newMenuItem(menu);
0178                 menuItem.text = i18nc("Play previous track", "Previous Track");
0179                 menuItem.icon = "media-skip-backward";
0180                 menuItem.enabled = Qt.binding(function() {
0181                     return playerData.CanGoPrevious;
0182                 });
0183                 menuItem.clicked.connect(function() {
0184                     mpris2Source.goPrevious(sourceName);
0185                 });
0186                 menu.addMenuItem(menuItem, virtualDesktopsMenuItem);
0187 
0188                 menuItem = menu.newMenuItem(menu);
0189                 // PlasmaCore Menu doesn't actually handle icons or labels changing at runtime...
0190                 menuItem.text = Qt.binding(function() {
0191                     return playerData.PlaybackStatus === "Playing" ? i18nc("Pause playback", "Pause") : i18nc("Start playback", "Play");
0192                 });
0193                 menuItem.icon = Qt.binding(function() {
0194                     return playerData.PlaybackStatus === "Playing" ? "media-playback-pause" : "media-playback-start";
0195                 });
0196                 menuItem.enabled = Qt.binding(function() {
0197                     return playerData.PlaybackStatus === "Playing" ? playerData.CanPause : playerData.CanPlay;
0198                 });
0199                 menuItem.clicked.connect(function() {
0200                     mpris2Source.playPause(sourceName);
0201                 });
0202                 menu.addMenuItem(menuItem, virtualDesktopsMenuItem);
0203 
0204                 menuItem = menu.newMenuItem(menu);
0205                 menuItem.text = i18nc("Play next track", "Next Track");
0206                 menuItem.icon = "media-skip-forward";
0207                 menuItem.enabled = Qt.binding(function() {
0208                     return playerData.CanGoNext;
0209                 });
0210                 menuItem.clicked.connect(function() {
0211                     mpris2Source.goNext(sourceName);
0212                 });
0213                 menu.addMenuItem(menuItem, virtualDesktopsMenuItem);
0214 
0215                 menuItem = menu.newMenuItem(menu);
0216                 menuItem.text = i18nc("Stop playback", "Stop");
0217                 menuItem.icon = "media-playback-stop";
0218                 menuItem.clicked.connect(function() {
0219                     mpris2Source.stop(sourceName);
0220                 });
0221                 menu.addMenuItem(menuItem, virtualDesktopsMenuItem);
0222 
0223                 // Technically media controls and audio streams are separate but for the user they're
0224                 // semantically related, don't add a separator inbetween.
0225                 if (!menu.visualParent.hasAudioStream) {
0226                     menu.addMenuItem(newSeparator(menu), virtualDesktopsMenuItem);
0227                 }
0228 
0229                 // If we don't have a window associated with the player but we can quit
0230                 // it through MPRIS we'll offer a "Quit" option instead of "Close"
0231                 if (!closeWindowItem.visible && playerData.CanQuit) {
0232                     menuItem = menu.newMenuItem(menu);
0233                     menuItem.text = i18nc("Quit media player app", "Quit");
0234                     menuItem.icon = "application-exit";
0235                     menuItem.visible = Qt.binding(function() {
0236                         return !closeWindowItem.visible;
0237                     });
0238                     menuItem.clicked.connect(function() {
0239                         mpris2Source.quit(sourceName);
0240                     });
0241                     menu.addMenuItem(menuItem);
0242                 }
0243 
0244                 // If we don't have a window associated with the player but we can raise
0245                 // it through MPRIS we'll offer a "Restore" option
0246                 if (!startNewInstanceItem.visible && playerData.CanRaise) {
0247                     menuItem = menu.newMenuItem(menu);
0248                     menuItem.text = i18nc("Open or bring to the front window of media player app", "Restore");
0249                     menuItem.icon = playerData["Desktop Icon Name"];
0250                     menuItem.visible = Qt.binding(function() {
0251                         return !startNewInstanceItem.visible;
0252                     });
0253                     menuItem.clicked.connect(function() {
0254                         mpris2Source.raise(sourceName);
0255                     });
0256                     menu.addMenuItem(menuItem, startNewInstanceItem);
0257                 }
0258             }
0259         }
0260 
0261         // We allow mute/unmute whenever an application has a stream, regardless of whether it
0262         // is actually playing sound.
0263         // This way you can unmute, e.g. a telephony app, even after the conversation has ended,
0264         // so you still have it ringing later on.
0265         if (menu.visualParent.hasAudioStream) {
0266             var muteItem = menu.newMenuItem(menu);
0267             muteItem.checkable = true;
0268             muteItem.checked = Qt.binding(function() {
0269                 return menu.visualParent && menu.visualParent.muted;
0270             });
0271             muteItem.clicked.connect(function() {
0272                 menu.visualParent.toggleMuted();
0273             });
0274             muteItem.text = i18n("Mute");
0275             muteItem.icon = "audio-volume-muted";
0276             menu.addMenuItem(muteItem, virtualDesktopsMenuItem);
0277 
0278             menu.addMenuItem(newSeparator(menu), virtualDesktopsMenuItem);
0279         }
0280     }
0281 
0282     function loadMyViewActions() {
0283         if (!appletAbilities.myView.isReady) {
0284             return;
0285         }
0286 
0287         var actionsCount = appletAbilities.myView.containmentActions.length;
0288 
0289         for (var i=0; i<actionsCount; ++i) {
0290             var item = newMenuItem(menu);
0291             item.action = appletAbilities.myView.containmentActions[i];
0292             item.visible = Qt.binding(function() {
0293                 return this.action.visible;
0294             });
0295             menu.addMenuItem(item, myViewActions);
0296         }
0297     }
0298 
0299     ///REMOVE
0300     function updateOnAllActivitiesLauncher(){
0301         //isOnAllActivitiesLauncher = ActivitiesTools.isOnAllActivities(visualParent.m.LauncherUrlWithoutIcon);
0302     }
0303 
0304     Component.onCompleted: {
0305         ActivitiesTools.launchersOnActivities = root.launchersOnActivities
0306         ActivitiesTools.currentActivity = activityInfo.currentActivity;
0307         ActivitiesTools.plasmoid = plasmoid;
0308 
0309         //From Plasma 5.10 and frameworks 5.34 jumpLists and
0310         //places are supported
0311         if (LatteCore.Environment.frameworksVersion >= 336384) {
0312             // Cannot have "Connections" as child of PlasmaCoponents.ContextMenu.
0313             backend.showAllPlaces.connect(function() {
0314                 visualParent.showContextMenu({showAllPlaces: true});
0315             });
0316         }
0317         //  updateOnAllActivitiesLauncher();
0318     }
0319 
0320 
0321     Component.onDestruction: {
0322         if (!changingLayout) {
0323             root.contextMenu = null;
0324             backend.ungrabMouse(visualParent);
0325         }
0326     }
0327 
0328     /// Sub Items
0329 
0330     PlasmaComponents.MenuItem {
0331         id: startNewInstanceItem
0332         visible: (visualParent && visualParent.m.IsLauncher !== true && visualParent.m.IsStartup !== true)
0333 
0334         enabled: visualParent && visualParent.m.LauncherUrlWithoutIcon != null
0335 
0336         text: i18n("Start New Instance")
0337         icon: "list-add-symbolic"
0338 
0339         onClicked: tasksModel.requestNewInstance(menu.modelIndex)
0340     }
0341 
0342     PlasmaComponents.MenuItem {
0343         id: virtualDesktopsMenuItem
0344 
0345         visible: virtualDesktopInfo.numberOfDesktops > 1
0346                  && (visualParent && get(atm.IsLauncher) !== true
0347                      && get(atm.IsStartup) !== true
0348                      && get(atm.IsVirtualDesktopsChangeable) === true)
0349 
0350         enabled: visible
0351 
0352         text: i18n("Move To &Desktop")
0353 
0354         Connections {
0355             target: virtualDesktopInfo
0356             onDesktopIdsChanged: Qt.callLater(virtualDesktopsMenu.refresh)
0357             onDesktopNamesChanged: Qt.callLater(virtualDesktopsMenu.refresh)
0358             onNumberOfDesktopsChanged: Qt.callLater(virtualDesktopsMenu.refresh)
0359         }
0360 
0361         PlasmaComponents.ContextMenu {
0362             id: virtualDesktopsMenu
0363 
0364             visualParent: virtualDesktopsMenuItem.action
0365 
0366             function refresh() {
0367                 clearMenuItems();
0368 
0369                 if (virtualDesktopInfo.numberOfDesktops <= 1) {
0370                     return;
0371                 }
0372 
0373                 var menuItem = menu.newMenuItem(virtualDesktopsMenu);
0374                 menuItem.text = i18n("Move &To Current Desktop");
0375                 menuItem.enabled = Qt.binding(function() {
0376                     var vds = menu.get(atm.VirtualDesktops);
0377                     return menu.visualParent && (vds !== undefined) && vds.indexOf(virtualDesktopInfo.currentDesktop) == -1;
0378                 });
0379                 menuItem.clicked.connect(function() {
0380                     tasksModel.requestVirtualDesktops(menu.modelIndex, [virtualDesktopInfo.currentDesktop]);
0381                 });
0382 
0383                 menuItem = menu.newMenuItem(virtualDesktopsMenu);
0384                 menuItem.text = i18n("&All Desktops");
0385                 menuItem.checkable = true;
0386                 menuItem.checked = Qt.binding(function() {
0387                     return menu.visualParent && menu.visualParent.m.IsOnAllVirtualDesktops === true;
0388                 });
0389                 menuItem.clicked.connect(function() {
0390                     tasksModel.requestVirtualDesktops(menu.modelIndex, []);
0391                 });
0392                 backend.setActionGroup(menuItem.action);
0393 
0394                 menu.newSeparator(virtualDesktopsMenu);
0395 
0396                 for (var i = 0; i < virtualDesktopInfo.desktopNames.length; ++i) {
0397                     menuItem = menu.newMenuItem(virtualDesktopsMenu);
0398                     //menuItem.text = i18nc("1 = number of desktop, 2 = desktop name", "%1 Desktop %2", i + 1, virtualDesktopInfo.desktopNames[i]);
0399                     menuItem.text = (i + 1) + ". " + virtualDesktopInfo.desktopNames[i];
0400                     menuItem.checkable = true;
0401                     menuItem.checked = Qt.binding((function(i) {
0402                         return function() {
0403                             return (menu.visualParent && menu.get(atm.VirtualDesktops).indexOf(virtualDesktopInfo.desktopIds[i]) > -1);
0404                         };
0405                     })(i));
0406                     menuItem.clicked.connect((function(i) {
0407                         return function() {
0408                             return tasksModel.requestVirtualDesktops(menu.modelIndex, [virtualDesktopInfo.desktopIds[i]]);
0409                         };
0410                     })(i));
0411                     backend.setActionGroup(menuItem.action);
0412                 }
0413 
0414                 menu.newSeparator(virtualDesktopsMenu);
0415 
0416                 menuItem = menu.newMenuItem(virtualDesktopsMenu);
0417                 menuItem.text = i18n("&New Desktop");
0418                 menuItem.clicked.connect(function() {
0419                     tasksModel.requestNewVirtualDesktop(menu.modelIndex);
0420                 });
0421             }
0422 
0423             Component.onCompleted: refresh()
0424         }
0425     }
0426 
0427 
0428     PlasmaComponents.MenuItem {
0429         id: activitiesDesktopsMenuItem
0430 
0431         visible: activityInfo.numberOfRunningActivities > 1
0432                  && (visualParent && !visualParent.m.IsLauncher
0433                      && !visualParent.m.IsStartup)
0434                  && !root.disableAllWindowsFunctionality
0435 
0436         enabled: visible
0437 
0438         text: i18n("Move To &Activity")
0439 
0440         Connections {
0441             target: activityInfo
0442 
0443             onNumberOfRunningActivitiesChanged: activitiesDesktopsMenu.refresh()
0444         }
0445 
0446         PlasmaComponents.ContextMenu {
0447             id: activitiesDesktopsMenu
0448 
0449             visualParent: activitiesDesktopsMenuItem.action
0450 
0451             function refresh() {
0452                 clearMenuItems();
0453 
0454                 if (activityInfo.numberOfRunningActivities <= 1) {
0455                     return;
0456                 }
0457 
0458                 var menuItem = menu.newMenuItem(activitiesDesktopsMenu);
0459                 menuItem.text = i18n("Add To Current Activity");
0460                 menuItem.enabled = Qt.binding(function() {
0461                     return menu.visualParent && menu.visualParent.m.Activities.length > 0 &&
0462                             menu.visualParent.m.Activities.indexOf(activityInfo.currentActivity) < 0;
0463                 });
0464                 menuItem.clicked.connect(function() {
0465                     tasksModel.requestActivities(menu.modelIndex, menu.visualParent.m.Activities.concat(activityInfo.currentActivity));
0466                 });
0467 
0468                 menuItem = menu.newMenuItem(activitiesDesktopsMenu);
0469                 menuItem.text = i18n("All Activities");
0470                 menuItem.checkable = true;
0471                 menuItem.checked = Qt.binding(function() {
0472                     return menu.visualParent && menu.visualParent.m.Activities.length === 0;
0473                 });
0474                 menuItem.clicked.connect(function() {
0475                     var checked = menuItem.checked;
0476                     var newActivities = menu.visualParent.m.Activities;
0477                     var size = newActivities.length;
0478 
0479                     newActivities = undefined; // will cast to an empty QStringList i.e all activities
0480                     if (size === 0) {
0481                         newActivities = new Array(activityInfo.currentActivity);
0482                     }
0483 
0484                     tasksModel.requestActivities(menu.modelIndex, newActivities);
0485                 });
0486 
0487                 menu.newSeparator(activitiesDesktopsMenu);
0488 
0489                 var runningActivities = activityInfo.runningActivities();
0490                 for (var i = 0; i < runningActivities.length; ++i) {
0491                     var activityId = runningActivities[i];
0492 
0493                     menuItem = menu.newMenuItem(activitiesDesktopsMenu);
0494                     menuItem.text = activityInfo.activityName(runningActivities[i]);
0495                     menuItem.checkable = true;
0496                     menuItem.checked = Qt.binding( (function(activityId) {
0497                         return function() {
0498                             return menu.visualParent && menu.visualParent.m.Activities.indexOf(activityId) >= 0;
0499                         };
0500                     })(activityId));
0501                     menuItem.clicked.connect((function(activityId) {
0502                         return function () {
0503                             var checked = menuItem.checked;
0504                             var newActivities = menu.visualParent.m.Activities;
0505                             var index = newActivities.indexOf(activityId)
0506 
0507                             if (index < 0) {
0508                                 newActivities = newActivities.concat(activityId);
0509                             } else {
0510                                 //newActivities = newActivities.splice(index, 1);  //this does not work!!!
0511                                 newActivities.splice(index, 1);
0512                             }
0513                             return tasksModel.requestActivities(menu.modelIndex, newActivities);
0514                         };
0515                     })(activityId));
0516                 }
0517 
0518                 menu.newSeparator(activitiesDesktopsMenu);
0519             }
0520 
0521             Component.onCompleted: refresh()
0522         }
0523     }
0524 
0525     PlasmaComponents.MenuItem {
0526         id: moreActionsMenuItem
0527 
0528         visible: (visualParent
0529                   && visualParent.m.IsLauncher !== true
0530                   && visualParent.m.IsStartup !== true
0531                   && root.showWindowActions
0532                   && !root.disableAllWindowsFunctionality)
0533 
0534         enabled: visible
0535 
0536         text: i18n("More Actions")
0537         icon: "view-more-symbolic"
0538 
0539         PlasmaComponents.ContextMenu {
0540             visualParent: moreActionsMenuItem.action
0541 
0542             PlasmaComponents.MenuItem {
0543                 enabled: menu.visualParent && menu.visualParent.m.IsMovable === true
0544 
0545                 text: i18n("&Move")
0546                 icon: "transform-move"
0547 
0548                 onClicked: tasksModel.requestMove(menu.modelIndex)
0549             }
0550 
0551             PlasmaComponents.MenuItem {
0552                 enabled: menu.visualParent && menu.visualParent.m.IsResizable === true
0553 
0554                 text: i18n("Re&size")
0555                 icon: "transform-scale"
0556 
0557                 onClicked: tasksModel.requestResize(menu.modelIndex)
0558             }
0559 
0560             PlasmaComponents.MenuItem {
0561                 visible: (visualParent
0562                           && visualParent.m.IsLauncher !== true
0563                           && visualParent.m.IsStartup !== true
0564                           && root.showWindowActions
0565                           && !root.disableAllWindowsFunctionality)
0566 
0567                 enabled: visualParent && visualParent.m.IsMaximizable === true
0568 
0569                 checkable: true
0570                 checked: visualParent && visualParent.m.IsMaximized === true
0571 
0572                 text: i18n("Ma&ximize")
0573                 icon: "window-maximize"
0574 
0575                 onClicked: tasksModel.requestToggleMaximized(menu.modelIndex)
0576             }
0577 
0578             PlasmaComponents.MenuItem {
0579                 visible: (visualParent
0580                           && visualParent.m.IsLauncher !== true
0581                           && visualParent.m.IsStartup !== true
0582                           && root.showWindowActions
0583                           && !root.disableAllWindowsFunctionality)
0584 
0585                 enabled: visualParent && visualParent.m.IsMinimizable === true
0586 
0587                 checkable: true
0588                 checked: visualParent && visualParent.m.IsMinimized === true
0589 
0590                 text: i18n("Mi&nimize")
0591                 icon: "window-minimize"
0592 
0593                 onClicked: tasksModel.requestToggleMinimized(menu.modelIndex)
0594             }
0595 
0596             PlasmaComponents.MenuItem {
0597                 checkable: true
0598                 checked: menu.visualParent && menu.visualParent.m.IsKeepAbove === true
0599 
0600                 text: i18n("Keep &Above Others")
0601                 icon: "window-keep-above"
0602 
0603                 onClicked: tasksModel.requestToggleKeepAbove(menu.modelIndex)
0604             }
0605 
0606             PlasmaComponents.MenuItem {
0607                 checkable: true
0608                 checked: menu.visualParent && menu.visualParent.m.IsKeepBelow === true
0609 
0610                 text: i18n("Keep &Below Others")
0611                 icon: "window-keep-below"
0612 
0613                 onClicked: tasksModel.requestToggleKeepBelow(menu.modelIndex)
0614             }
0615 
0616             PlasmaComponents.MenuItem {
0617                 enabled: menu.visualParent && menu.visualParent.m.IsFullScreenable === true
0618 
0619                 checkable: true
0620                 checked: menu.visualParent && menu.visualParent.m.IsFullScreen === true
0621 
0622                 text: i18n("&Fullscreen")
0623                 icon: "view-fullscreen"
0624 
0625                 onClicked: tasksModel.requestToggleFullScreen(menu.modelIndex)
0626             }
0627 
0628             PlasmaComponents.MenuItem {
0629                 enabled: menu.visualParent && menu.visualParent.m.IsShadeable === true
0630 
0631                 checkable: true
0632                 checked: menu.visualParent && menu.visualParent.m.IsShaded === true
0633 
0634                 text: i18n("&Shade")
0635                 icon: "window-shade"
0636 
0637                 onClicked: tasksModel.requestToggleShaded(menu.modelIndex)
0638             }
0639 
0640             PlasmaComponents.MenuItem {
0641                 separator: true
0642             }
0643 
0644             PlasmaComponents.MenuItem {
0645                 visible: (plasmoid.configuration.groupingStrategy !== 0) && menu.visualParent.m.IsWindow === true
0646 
0647                 checkable: true
0648                 checked: menu.visualParent && menu.visualParent.m.IsGroupable === true
0649 
0650                 text: i18n("Allow this program to be grouped")
0651 
0652                 onClicked: tasksModel.requestToggleGrouping(menu.modelIndex)
0653             }
0654         }
0655     }
0656 
0657     /*    PlasmaComponents.MenuItem {
0658         separator: true
0659 
0660         visible: (visualParent
0661                   && visualParent.m.IsLauncher !== true
0662                   && visualParent.m.IsStartup !== true
0663                   && root.showWindowActions)
0664     }*/
0665 
0666     //// NEW Launchers Mechanism
0667     PlasmaComponents.MenuItem {
0668         id: launcherToggleAction
0669 
0670         visible: visualParent
0671                  && get(atm.IsLauncher) !== true
0672                  && get(atm.IsStartup) !== true
0673                  && (activityInfo.numberOfRunningActivities < 2)
0674         //&& plasmoid.immutability !== PlasmaCore.Types.SystemImmutable
0675 
0676         enabled: visualParent && get(atm.LauncherUrlWithoutIcon) !== ""
0677 
0678         checkable: true
0679 
0680         text: i18n("&Pin Launcher")
0681         icon: "window-pin"
0682 
0683         onClicked: {
0684             if (tasksModel.launcherPosition(get(atm.LauncherUrlWithoutIcon)) !== -1) {
0685                 appletAbilities.launchers.removeLauncher(get(atm.LauncherUrl));
0686             } else {
0687                 appletAbilities.launchers.addLauncher(get(atm.LauncherUrl))
0688             }
0689         }
0690     }
0691 
0692     PlasmaComponents.MenuItem {
0693         id: showLauncherInActivitiesItem
0694 
0695         text: i18n("&Pin Launcher")
0696         icon: "window-pin"
0697 
0698         visible: visualParent && (!visualParent.isSeparator || (visualParent.isSeparator && root.inEditMode))
0699         // && get(atm.IsLauncher) !== true
0700                  && get(atm.IsStartup) !== true
0701                  && plasmoid.immutability !== PlasmaCore.Types.SystemImmutable
0702                  && (activityInfo.numberOfRunningActivities >= 2)
0703 
0704         Connections {
0705             target: activityInfo
0706             onNumberOfRunningActivitiesChanged: activitiesDesktopsMenu.refresh()
0707         }
0708 
0709         PlasmaComponents.ContextMenu {
0710             id: activitiesLaunchersMenu
0711             visualParent: showLauncherInActivitiesItem.action
0712 
0713             function refresh() {
0714                 clearMenuItems();
0715 
0716                 if (menu.visualParent === null) return;
0717 
0718                 var createNewItem = function(id, title, url, activities) {
0719                     var result = menu.newMenuItem(activitiesLaunchersMenu);
0720                     result.text = title;
0721 
0722                     result.visible = true;
0723                     result.checkable = true;
0724 
0725                     result.checked = activities.some(function(activity) { return activity === id });
0726 
0727                     result.clicked.connect(
0728                                 function() {
0729                                     if (result.checked) {
0730                                         appletAbilities.launchers.addLauncherToActivity(url,id);
0731                                     } else {
0732                                         appletAbilities.launchers.removeLauncherFromActivity(url, id);
0733                                     }
0734                                 }
0735                                 );
0736 
0737                     return result;
0738                 }
0739 
0740                 if (menu.visualParent === null) return;
0741 
0742                 var url = menu.get(atm.LauncherUrlWithoutIcon);
0743 
0744                 var activities = tasksModel.launcherActivities(url);
0745 
0746                 var NULL_UUID = "00000000-0000-0000-0000-000000000000";
0747 
0748                 createNewItem(NULL_UUID, i18n("On All Activities"), url, activities);
0749 
0750                 if (activityInfo.numberOfRunningActivities <= 1) {
0751                     return;
0752                 }
0753 
0754                 createNewItem(activityInfo.currentActivity, i18n("On The Current Activity"), url, activities);
0755 
0756                 menu.newSeparator(activitiesLaunchersMenu);
0757 
0758                 var runningActivities = activityInfo.runningActivities();
0759 
0760                 runningActivities.forEach(function(id) {
0761                     createNewItem(id, activityInfo.activityName(id), url, activities);
0762                 });
0763             }
0764 
0765             Component.onCompleted: {
0766                 menu.onVisualParentChanged.connect(refresh);
0767                 refresh();
0768             }
0769         }
0770     }
0771 
0772     PlasmaComponents.MenuItem {
0773         visible: (visualParent && !visualParent.isSeparator && get(atm.IsLauncher) === true)
0774                  && plasmoid.immutability !== PlasmaCore.Types.SystemImmutable
0775 
0776         text: i18n("Unpin Launcher")
0777         icon: "window-unpin"
0778 
0779         onClicked: {
0780             appletAbilities.launchers.removeLauncher(get(atm.LauncherUrlWithoutIcon));
0781         }
0782     }
0783 
0784     //////END OF NEW ARCHITECTURE
0785 
0786     PlasmaComponents.MenuItem {
0787         id: addInternalSeparatorItem
0788         enabled: !visualParent.tailItemIsSeparator || !visualParent.headItemIsSeparator
0789         visible: visualParent.hasShownLauncher
0790         icon: "add"
0791         text: !visualParent.tailItemIsSeparator ? i18nc("add separator","Add %1", tailSeparatorText) : i18nc("add separator","Add %1", headSeparatorText)
0792 
0793         onClicked: {
0794             var pos=visualParent.itemIndex;
0795 
0796             if (!visualParent.tailItemIsSeparator) {
0797                 appletAbilities.launchers.addInternalSeparatorAtPos(pos);
0798             } else {
0799                 appletAbilities.launchers.addInternalSeparatorAtPos(pos+1);
0800             }
0801         }
0802     }
0803 
0804     PlasmaComponents.MenuItem {
0805         id: removeFollowingInternalSeparatorItem
0806         visible: visualParent && visualParent.headItemIsSeparator
0807 
0808         icon: "remove"
0809         text: i18nc("remove separator", "Remove %1", headSeparatorText)
0810 
0811         onClicked: {
0812             if (visualParent.headItemIsSeparator) {
0813                 appletAbilities.launchers.removeInternalSeparatorAtPos(visualParent.itemIndex + 1);
0814             }
0815         }
0816     }
0817 
0818     PlasmaComponents.MenuItem {
0819         id: removeTailInternalSeparatorItem
0820         visible: visualParent && visualParent.tailItemIsSeparator
0821 
0822         icon: "remove"
0823         text: i18nc("remove separator", "Remove %1", tailSeparatorText)
0824 
0825         onClicked: {
0826             if (visualParent.tailItemIsSeparator) {
0827                 appletAbilities.launchers.removeInternalSeparatorAtPos(visualParent.itemIndex - 1);
0828             }
0829         }
0830     }
0831 
0832     PlasmaComponents.MenuItem {
0833         id: alternativesMenuItem
0834         visible: (appletAbilities.myView.isReady && appletAbilities.myView.inEditMode)
0835                  || (!appletAbilities.myView.isReady && plasmoid.userConfiguring /*normal plasmoid in the desktop*/)
0836         text: plasmoid.action("alternatives").text
0837         icon: plasmoid.action("alternatives").icon
0838 
0839         onClicked: plasmoid.action("alternatives").trigger();
0840     }
0841 
0842     PlasmaComponents.MenuItem {
0843         id: myViewActions
0844         separator: true
0845         visible: false
0846     }
0847 
0848     PlasmaComponents.MenuItem {
0849         separator: true
0850         visible: removePlasmoidInMyViewEditMode.visible
0851     }
0852 
0853     PlasmaComponents.MenuItem {
0854         id: removePlasmoidInMyViewEditMode
0855         //! Workaround: this is preferred compared to:
0856         //!   action:plasmoid.action("remove")
0857         //! which shows the action always and not dependent of myView.inEditMode flag
0858         text: plasmoid.action("remove").text
0859         icon: plasmoid.action("remove").icon
0860         visible: appletAbilities.myView.isReady && appletAbilities.myView.inEditMode
0861 
0862         onClicked: plasmoid.action("remove").trigger();
0863     }
0864 
0865     PlasmaComponents.MenuItem {
0866         section: true
0867         text: i18n("Window")
0868         visible: closeWindowItem.visible
0869     }
0870 
0871     //!move window Close button at the very bottom in order to not alter users workflow
0872     //!comparing with the design decisions of other taskmanagers
0873     PlasmaComponents.MenuItem {
0874         id: closeWindowItem
0875         visible: (visualParent && visualParent.m.IsLauncher !== true && visualParent.m.IsStartup !== true) && !root.disableAllWindowsFunctionality
0876 
0877         enabled: visualParent && visualParent.m.IsClosable === true
0878 
0879         text: i18n("&Close")
0880         icon: "window-close"
0881 
0882         onClicked: {
0883             if (appletAbilities.parabolic.factor.zoom>1) {
0884                 delayWindowRemovalTimer.modelIndex = menu.modelIndex;
0885                 delayWindowRemovalTimer.start();
0886             } else {
0887                 tasksModel.requestClose(menu.modelIndex);
0888             }
0889         }
0890     }
0891 }