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 }