diff --git a/plasmoid/package/contents/ui/ContextMenu.qml b/plasmoid/package/contents/ui/ContextMenu.qml index fd481fcb..37c5b47b 100644 --- a/plasmoid/package/contents/ui/ContextMenu.qml +++ b/plasmoid/package/contents/ui/ContextMenu.qml @@ -1,1021 +1,1020 @@ /* * Copyright 2016 Smith AR * Michail Vourlakos * * This file is part of Latte-Dock * * Latte-Dock is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * Latte-Dock is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.0 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.activities 0.1 as Activities import org.kde.taskmanager 0.1 as TaskManager import org.kde.latte.core 0.2 as LatteCore import org.kde.latte.private.tasks 0.1 as LatteTasks import "../code/activitiesTools.js" as ActivitiesTools PlasmaComponents.ContextMenu { id: menu property bool changingLayout: false property QtObject mpris2Source property QtObject backend property var modelIndex readonly property var atm: TaskManager.AbstractTasksModel readonly property var containmentActions: latteView ? latteView.containmentActions() : [] placement: { if (root.location === PlasmaCore.Types.LeftEdge) { return PlasmaCore.Types.RightPosedTopAlignedPopup; } else if (root.location === PlasmaCore.Types.TopEdge) { return PlasmaCore.Types.BottomPosedLeftAlignedPopup; } else if (root.location === PlasmaCore.Types.RightEdge) { return PlasmaCore.Types.LeftPosedTopAlignedPopup; } else { return PlasmaCore.Types.TopPosedLeftAlignedPopup; } } minimumWidth: visualParent ? visualParent.width : 1 property bool isOnAllActivitiesLauncher: true property bool showAllPlaces: false property int activitiesCount: 0 onStatusChanged: { if (visualParent && get(atm.LauncherUrlWithoutIcon) != null && status == PlasmaComponents.DialogStatus.Open) { launcherToggleAction.checked = (tasksModel.launcherPosition(get(atm.LauncherUrlWithoutIcon)) != -1); activitiesDesktopsMenu.refresh(); } else if (status == PlasmaComponents.DialogStatus.Closed) { root.contextMenu = null; menu.destroy(); backend.ungrabMouse(visualParent); } } function get(modelProp) { return tasksModel.data(modelIndex, modelProp) } function show() { loadDynamicLaunchActions(visualParent.m.LauncherUrlWithoutIcon); // backend.ungrabMouse(visualParent); openRelative(); if (LatteCore.WindowSystem.isPlatformWayland){ //!Hiding previews under wayland it needs a delay otherwise it creates crashes windowsPreviewCheckerToNotShowTimer.start(); } else { windowsPreviewDlg.hide("9.4"); } if (root.latteView){ root.latteView.hideTooltipLabel(); } } function newMenuItem(parent) { return Qt.createQmlObject( "import org.kde.plasma.components 2.0 as PlasmaComponents;" + "PlasmaComponents.MenuItem {}", parent); } function newSeparator(parent) { return Qt.createQmlObject( "import org.kde.plasma.components 2.0 as PlasmaComponents;" + "PlasmaComponents.MenuItem { separator: true }", parent); } function loadDynamicLaunchActions(launcherUrl) { var sections = []; //From Plasma 5.10 and frameworks 5.34, places are also supported if (LatteCore.Environment.frameworksVersion >= 336384 && (typeof backend.placesActions === "function")) { sections = [ { title: i18n("Places"), group: "places", actions: backend.placesActions(launcherUrl, showAllPlaces, menu) }, { title: i18n("Recent Documents"), group: "recents", actions: backend.recentDocumentActions(launcherUrl, menu) }, { title: i18n("Actions"), group: "actions", actions: backend.jumpListActions(launcherUrl, menu) } ]; } else { sections = [ { title: i18n("Recent Documents"), group: "recents", actions: backend.recentDocumentActions(launcherUrl, menu) }, { title: i18n("Actions"), group: "actions", actions: backend.jumpListActions(launcherUrl, menu) } ]; } // QMenu does not limit its width automatically. Even if we set a maximumWidth // it would just cut off text rather than eliding. So we do this manually. var textMetrics = Qt.createQmlObject("import QtQuick 2.4; TextMetrics {}", menu); var maximumWidth = theme.mSize(theme.defaultFont).width * 22; sections.forEach(function (section) { // Always show the "Actions:" header, since we visually merge // This section with the one beneath it that shows universal actions if (section["actions"].length > 0 || section["group"] == "actions") { var sectionHeader = newMenuItem(menu); sectionHeader.text = section["title"]; sectionHeader.section = true; menu.addMenuItem(sectionHeader, startNewInstanceItem); } for (var i = 0; i < section["actions"].length; ++i) { var item = newMenuItem(menu); item.action = section["actions"][i]; // Crude way of manually eliding... var elided = false; textMetrics.text = Qt.binding(function() { return item.action.text; }); while (textMetrics.width > maximumWidth) { item.action.text = item.action.text.slice(0, -1); elided = true; } if (elided) { item.action.text += "..."; } menu.addMenuItem(item, startNewInstanceItem); } }); // Add Media Player control actions var sourceName = mpris2Source.sourceNameForLauncherUrl(launcherUrl, get(atm.AppPid)); var winIdList = root.plasma515 ? atm.WinIdList : atm.LegacyWinIdList; if (sourceName && !(get(winIdList) !== undefined && get(winIdList).length > 1)) { var playerData = mpris2Source.data[sourceName] if (playerData.CanControl) { var menuItem = menu.newMenuItem(menu); menuItem.text = i18nc("Play previous track", "Previous Track"); menuItem.icon = "media-skip-backward"; menuItem.enabled = Qt.binding(function() { return playerData.CanGoPrevious; }); menuItem.clicked.connect(function() { mpris2Source.goPrevious(sourceName); }); menu.addMenuItem(menuItem, virtualDesktopsMenuItem); menuItem = menu.newMenuItem(menu); // PlasmaCore Menu doesn't actually handle icons or labels changing at runtime... menuItem.text = Qt.binding(function() { return playerData.PlaybackStatus === "Playing" ? i18nc("Pause playback", "Pause") : i18nc("Start playback", "Play"); }); menuItem.icon = Qt.binding(function() { return playerData.PlaybackStatus === "Playing" ? "media-playback-pause" : "media-playback-start"; }); menuItem.enabled = Qt.binding(function() { return playerData.PlaybackStatus === "Playing" ? playerData.CanPause : playerData.CanPlay; }); menuItem.clicked.connect(function() { mpris2Source.playPause(sourceName); }); menu.addMenuItem(menuItem, virtualDesktopsMenuItem); menuItem = menu.newMenuItem(menu); menuItem.text = i18nc("Play next track", "Next Track"); menuItem.icon = "media-skip-forward"; menuItem.enabled = Qt.binding(function() { return playerData.CanGoNext; }); menuItem.clicked.connect(function() { mpris2Source.goNext(sourceName); }); menu.addMenuItem(menuItem, virtualDesktopsMenuItem); menuItem = menu.newMenuItem(menu); menuItem.text = i18nc("Stop playback", "Stop"); menuItem.icon = "media-playback-stop"; menuItem.clicked.connect(function() { mpris2Source.stop(sourceName); }); menu.addMenuItem(menuItem, virtualDesktopsMenuItem); // Technically media controls and audio streams are separate but for the user they're // semantically related, don't add a separator inbetween. if (!menu.visualParent.hasAudioStream) { menu.addMenuItem(newSeparator(menu), virtualDesktopsMenuItem); } // If we don't have a window associated with the player but we can quit // it through MPRIS we'll offer a "Quit" option instead of "Close" if (!closeWindowItem.visible && playerData.CanQuit) { menuItem = menu.newMenuItem(menu); menuItem.text = i18nc("Quit media player app", "Quit"); menuItem.icon = "application-exit"; menuItem.visible = Qt.binding(function() { return !closeWindowItem.visible; }); menuItem.clicked.connect(function() { mpris2Source.quit(sourceName); }); menu.addMenuItem(menuItem); } // If we don't have a window associated with the player but we can raise // it through MPRIS we'll offer a "Restore" option if (!startNewInstanceItem.visible && playerData.CanRaise) { menuItem = menu.newMenuItem(menu); menuItem.text = i18nc("Open or bring to the front window of media player app", "Restore"); menuItem.icon = playerData["Desktop Icon Name"]; menuItem.visible = Qt.binding(function() { return !startNewInstanceItem.visible; }); menuItem.clicked.connect(function() { mpris2Source.raise(sourceName); }); menu.addMenuItem(menuItem, startNewInstanceItem); } } } // We allow mute/unmute whenever an application has a stream, regardless of whether it // is actually playing sound. // This way you can unmute, e.g. a telephony app, even after the conversation has ended, // so you still have it ringing later on. if (menu.visualParent.hasAudioStream) { var muteItem = menu.newMenuItem(menu); muteItem.checkable = true; muteItem.checked = Qt.binding(function() { return menu.visualParent && menu.visualParent.muted; }); muteItem.clicked.connect(function() { menu.visualParent.toggleMuted(); }); muteItem.text = i18n("Mute"); muteItem.icon = "audio-volume-muted"; menu.addMenuItem(muteItem, virtualDesktopsMenuItem); menu.addMenuItem(newSeparator(menu), virtualDesktopsMenuItem); } } ///REMOVE function updateOnAllActivitiesLauncher(){ //isOnAllActivitiesLauncher = ActivitiesTools.isOnAllActivities(visualParent.m.LauncherUrlWithoutIcon); } Component.onCompleted: { ActivitiesTools.launchersOnActivities = root.launchersOnActivities ActivitiesTools.currentActivity = activityInfo.currentActivity; ActivitiesTools.plasmoid = plasmoid; //From Plasma 5.10 and frameworks 5.34 jumpLists and //places are supported if (LatteCore.Environment.frameworksVersion >= 336384) { // Cannot have "Connections" as child of PlasmaCoponents.ContextMenu. backend.showAllPlaces.connect(function() { visualParent.showContextMenu({showAllPlaces: true}); }); } // updateOnAllActivitiesLauncher(); } Component.onDestruction: { if (!changingLayout) { root.contextMenu = null; backend.ungrabMouse(visualParent); } } /// Sub Items PlasmaComponents.MenuItem { id: startNewInstanceItem visible: (visualParent && visualParent.m.IsLauncher !== true && visualParent.m.IsStartup !== true) enabled: visualParent && visualParent.m.LauncherUrlWithoutIcon != null text: i18n("Start New Instance") icon: "list-add-symbolic" onClicked: tasksModel.requestNewInstance(menu.modelIndex) } PlasmaComponents.MenuItem { id: virtualDesktopsMenuItem visible: virtualDesktopInfo.numberOfDesktops > 1 && (visualParent && get(atm.IsLauncher) !== true && get(atm.IsStartup) !== true && (root.plasma515 ? get(atm.IsVirtualDesktopsChangeable) === true : get(atm.IsVirtualDesktopChangeable) === true ) ) enabled: visible text: i18n("Move To &Desktop") Connections { target: virtualDesktopInfo onNumberOfDesktopsChanged: root.plasma515 ? Qt.callLater(virtualDesktopsMenu.refresh) : virtualDesktopsMenu.refresh() onDesktopNamesChanged: root.plasma515 ? Qt.callLater(virtualDesktopsMenu.refresh) : virtualDesktopsMenu.refresh() } Connections { target: root.plasma515 ? virtualDesktopInfo : null onDesktopIdsChanged: root.plasma515 ? Qt.callLater(virtualDesktopsMenu.refresh) : virtualDesktopsMenu.refresh() } PlasmaComponents.ContextMenu { id: virtualDesktopsMenu visualParent: virtualDesktopsMenuItem.action function refresh() { clearMenuItems(); if (virtualDesktopInfo.numberOfDesktops <= 1) { return; } var menuItem = menu.newMenuItem(virtualDesktopsMenu); menuItem.text = i18n("Move &To Current Desktop"); menuItem.enabled = Qt.binding(function() { if (root.plasma515) { var vds = menu.get(atm.VirtualDesktops); return menu.visualParent && (vds !== undefined) && vds.indexOf(virtualDesktopInfo.currentDesktop) == -1; } else { return menu.visualParent && menu.get(atm.VirtualDesktop) !== virtualDesktopInfo.currentDesktop; } }); menuItem.clicked.connect(function() { if (root.plasma515) { tasksModel.requestVirtualDesktops(menu.modelIndex, [virtualDesktopInfo.currentDesktop]); } else { tasksModel.requestVirtualDesktop(menu.modelIndex, virtualDesktopInfo.currentDesktop); } }); menuItem = menu.newMenuItem(virtualDesktopsMenu); menuItem.text = i18n("&All Desktops"); menuItem.checkable = true; menuItem.checked = Qt.binding(function() { return menu.visualParent && menu.visualParent.m.IsOnAllVirtualDesktops === true; }); menuItem.clicked.connect(function() { if (root.plasma515) { tasksModel.requestVirtualDesktops(menu.modelIndex, []); } else { tasksModel.requestVirtualDesktop(menu.modelIndex, 0); } }); backend.setActionGroup(menuItem.action); menu.newSeparator(virtualDesktopsMenu); for (var i = 0; i < virtualDesktopInfo.desktopNames.length; ++i) { menuItem = menu.newMenuItem(virtualDesktopsMenu); //menuItem.text = i18nc("1 = number of desktop, 2 = desktop name", "%1 Desktop %2", i + 1, virtualDesktopInfo.desktopNames[i]); menuItem.text = (i + 1) + ". " + virtualDesktopInfo.desktopNames[i]; menuItem.checkable = true; menuItem.checked = Qt.binding((function(i) { return function() { if (root.plasma515) { return (menu.visualParent && menu.get(atm.VirtualDesktops).indexOf(virtualDesktopInfo.desktopIds[i]) > -1); } else { return (menu.visualParent && menu.get(atm.VirtualDesktop) === (i + 1)); } }; })(i)); menuItem.clicked.connect((function(i) { return function() { if (root.plasma515) { return tasksModel.requestVirtualDesktops(menu.modelIndex, [virtualDesktopInfo.desktopIds[i]]); } else { return tasksModel.requestVirtualDesktop(menu.modelIndex, i + 1); } }; })(i)); backend.setActionGroup(menuItem.action); } menu.newSeparator(virtualDesktopsMenu); menuItem = menu.newMenuItem(virtualDesktopsMenu); menuItem.text = i18n("&New Desktop"); menuItem.clicked.connect(function() { if (root.plasma515) { tasksModel.requestNewVirtualDesktop(menu.modelIndex); } else { tasksModel.requestVirtualDesktop(menu.modelIndex, virtualDesktopInfo.numberOfDesktops + 1) } }); } Component.onCompleted: refresh() } } PlasmaComponents.MenuItem { id: activitiesDesktopsMenuItem visible: activityInfo.numberOfRunningActivities > 1 && (visualParent && !visualParent.m.IsLauncher && !visualParent.m.IsStartup) && !root.disableAllWindowsFunctionality enabled: visible text: i18n("Move To &Activity") Connections { target: activityInfo onNumberOfRunningActivitiesChanged: activitiesDesktopsMenu.refresh() } PlasmaComponents.ContextMenu { id: activitiesDesktopsMenu visualParent: activitiesDesktopsMenuItem.action function refresh() { clearMenuItems(); if (activityInfo.numberOfRunningActivities <= 1) { return; } var menuItem = menu.newMenuItem(activitiesDesktopsMenu); menuItem.text = i18n("Add To Current Activity"); menuItem.enabled = Qt.binding(function() { return menu.visualParent && menu.visualParent.m.Activities.length > 0 && menu.visualParent.m.Activities.indexOf(activityInfo.currentActivity) < 0; }); menuItem.clicked.connect(function() { tasksModel.requestActivities(menu.modelIndex, menu.visualParent.m.Activities.concat(activityInfo.currentActivity)); }); menuItem = menu.newMenuItem(activitiesDesktopsMenu); menuItem.text = i18n("All Activities"); menuItem.checkable = true; menuItem.checked = Qt.binding(function() { return menu.visualParent && menu.visualParent.m.Activities.length === 0; }); menuItem.clicked.connect(function() { var checked = menuItem.checked; var newActivities = menu.visualParent.m.Activities; var size = newActivities.length; newActivities = undefined; // will cast to an empty QStringList i.e all activities if (size === 0) { newActivities = new Array(activityInfo.currentActivity); } tasksModel.requestActivities(menu.modelIndex, newActivities); }); menu.newSeparator(activitiesDesktopsMenu); var runningActivities = activityInfo.runningActivities(); for (var i = 0; i < runningActivities.length; ++i) { var activityId = runningActivities[i]; menuItem = menu.newMenuItem(activitiesDesktopsMenu); menuItem.text = activityInfo.activityName(runningActivities[i]); menuItem.checkable = true; menuItem.checked = Qt.binding( (function(activityId) { return function() { return menu.visualParent && menu.visualParent.m.Activities.indexOf(activityId) >= 0; }; })(activityId)); menuItem.clicked.connect((function(activityId) { return function () { var checked = menuItem.checked; var newActivities = menu.visualParent.m.Activities; var index = newActivities.indexOf(activityId) if (index < 0) { newActivities = newActivities.concat(activityId); } else { //newActivities = newActivities.splice(index, 1); //this does not work!!! newActivities.splice(index, 1); } return tasksModel.requestActivities(menu.modelIndex, newActivities); }; })(activityId)); } menu.newSeparator(activitiesDesktopsMenu); } Component.onCompleted: refresh() } } PlasmaComponents.MenuItem { id: moreActionsMenuItem visible: (visualParent && visualParent.m.IsLauncher !== true && visualParent.m.IsStartup !== true && root.showWindowActions && !root.disableAllWindowsFunctionality) enabled: visible text: i18n("More Actions") icon: "view-more-symbolic" PlasmaComponents.ContextMenu { visualParent: moreActionsMenuItem.action PlasmaComponents.MenuItem { enabled: menu.visualParent && menu.visualParent.m.IsMovable === true text: i18n("&Move") icon: "transform-move" onClicked: tasksModel.requestMove(menu.modelIndex) } PlasmaComponents.MenuItem { enabled: menu.visualParent && menu.visualParent.m.IsResizable === true text: i18n("Re&size") icon: "transform-scale" onClicked: tasksModel.requestResize(menu.modelIndex) } PlasmaComponents.MenuItem { visible: (visualParent && visualParent.m.IsLauncher !== true && visualParent.m.IsStartup !== true && root.showWindowActions && !root.disableAllWindowsFunctionality) enabled: visualParent && visualParent.m.IsMaximizable === true checkable: true checked: visualParent && visualParent.m.IsMaximized === true text: i18n("Ma&ximize") icon: "window-maximize" onClicked: tasksModel.requestToggleMaximized(menu.modelIndex) } PlasmaComponents.MenuItem { visible: (visualParent && visualParent.m.IsLauncher !== true && visualParent.m.IsStartup !== true && root.showWindowActions && !root.disableAllWindowsFunctionality) enabled: visualParent && visualParent.m.IsMinimizable === true checkable: true checked: visualParent && visualParent.m.IsMinimized === true text: i18n("Mi&nimize") icon: "window-minimize" onClicked: tasksModel.requestToggleMinimized(menu.modelIndex) } PlasmaComponents.MenuItem { checkable: true checked: menu.visualParent && menu.visualParent.m.IsKeepAbove === true text: i18n("Keep &Above Others") icon: "window-keep-above" onClicked: tasksModel.requestToggleKeepAbove(menu.modelIndex) } PlasmaComponents.MenuItem { checkable: true checked: menu.visualParent && menu.visualParent.m.IsKeepBelow === true text: i18n("Keep &Below Others") icon: "window-keep-below" onClicked: tasksModel.requestToggleKeepBelow(menu.modelIndex) } PlasmaComponents.MenuItem { enabled: menu.visualParent && menu.visualParent.m.IsFullScreenable === true checkable: true checked: menu.visualParent && menu.visualParent.m.IsFullScreen === true text: i18n("&Fullscreen") icon: "view-fullscreen" onClicked: tasksModel.requestToggleFullScreen(menu.modelIndex) } PlasmaComponents.MenuItem { enabled: menu.visualParent && menu.visualParent.m.IsShadeable === true checkable: true checked: menu.visualParent && menu.visualParent.m.IsShaded === true text: i18n("&Shade") icon: "window-shade" onClicked: tasksModel.requestToggleShaded(menu.modelIndex) } PlasmaComponents.MenuItem { separator: true } PlasmaComponents.MenuItem { visible: (plasmoid.configuration.groupingStrategy != 0) && menu.visualParent.m.IsWindow === true checkable: true checked: menu.visualParent && menu.visualParent.m.IsGroupable === true text: i18n("Allow this program to be grouped") onClicked: tasksModel.requestToggleGrouping(menu.modelIndex) } } } /* PlasmaComponents.MenuItem { separator: true visible: (visualParent && visualParent.m.IsLauncher !== true && visualParent.m.IsStartup !== true && root.showWindowActions) }*/ //// NEW Launchers Mechanism PlasmaComponents.MenuItem { id: launcherToggleAction visible: visualParent && get(atm.IsLauncher) !== true && get(atm.IsStartup) !== true && (activityInfo.numberOfRunningActivities < 2) //&& plasmoid.immutability !== PlasmaCore.Types.SystemImmutable enabled: visualParent && get(atm.LauncherUrlWithoutIcon) !== "" checkable: true text: i18n("&Pin Launcher") icon: "window-pin" onClicked: { if (tasksModel.launcherPosition(get(atm.LauncherUrlWithoutIcon)) != -1) { var launcher = get(atm.LauncherUrl); if (latteView && root.launchersGroup >= LatteCore.Types.LayoutLaunchers) { latteView.layoutsManager.launchersSignals.removeLauncher(root.viewLayoutName, root.launchersGroup, launcher); } else { root.launcherForRemoval = launcher; tasksModel.requestRemoveLauncher(launcher); root.launchersUpdatedFor(launcher); } } else { var launcher = get(atm.LauncherUrl); if (latteView && root.launchersGroup >= LatteCore.Types.LayoutLaunchers) { latteView.layoutsManager.launchersSignals.addLauncher(root.viewLayoutName, root.launchersGroup, launcher); } else { tasksModel.requestAddLauncher(launcher); root.launchersUpdatedFor(launcher); } } } } PlasmaComponents.MenuItem { id: showLauncherInActivitiesItem text: i18n("&Pin Launcher") icon: "window-pin" visible: visualParent && (!visualParent.isSeparator || (visualParent.isSeparator && root.editMode)) // && get(atm.IsLauncher) !== true && get(atm.IsStartup) !== true && plasmoid.immutability !== PlasmaCore.Types.SystemImmutable && (activityInfo.numberOfRunningActivities >= 2) Connections { target: activityInfo onNumberOfRunningActivitiesChanged: activitiesDesktopsMenu.refresh() } PlasmaComponents.ContextMenu { id: activitiesLaunchersMenu visualParent: showLauncherInActivitiesItem.action function refresh() { clearMenuItems(); if (menu.visualParent === null) return; var createNewItem = function(id, title, url, activities) { var result = menu.newMenuItem(activitiesLaunchersMenu); result.text = title; result.visible = true; result.checkable = true; result.checked = activities.some(function(activity) { return activity === id }); result.clicked.connect( function() { if (result.checked) { if (latteView && root.launchersGroup >= LatteCore.Types.LayoutLaunchers) { latteView.layoutsManager.launchersSignals.addLauncherToActivity(root.viewLayoutName, root.launchersGroup, url, id); } else { if (id !== tasksModel.activity && (activities[0] === "00000000-0000-0000-0000-000000000000")) { root.launcherForRemoval = url; } tasksModel.requestAddLauncherToActivity(url, id); root.launchersUpdatedFor(url); } } else { if (latteView && root.launchersGroup >= LatteCore.Types.LayoutLaunchers) { latteView.layoutsManager.launchersSignals.removeLauncherFromActivity(root.viewLayoutName, root.launchersGroup, url, id); } else { if (id === tasksModel.activity) { root.launcherForRemoval = url; } tasksModel.requestRemoveLauncherFromActivity(url, id); root.launchersUpdatedFor(url); } } } ); return result; } if (menu.visualParent === null) return; var url = menu.get(atm.LauncherUrlWithoutIcon); var activities = tasksModel.launcherActivities(url); var NULL_UUID = "00000000-0000-0000-0000-000000000000"; createNewItem(NULL_UUID, i18n("On All Activities"), url, activities); if (activityInfo.numberOfRunningActivities <= 1) { return; } createNewItem(activityInfo.currentActivity, i18n("On The Current Activity"), url, activities); menu.newSeparator(activitiesLaunchersMenu); var runningActivities = activityInfo.runningActivities(); runningActivities.forEach(function(id) { createNewItem(id, activityInfo.activityName(id), url, activities); }); } Component.onCompleted: { menu.onVisualParentChanged.connect(refresh); refresh(); } } } PlasmaComponents.MenuItem { visible: (visualParent && !visualParent.isSeparator && get(atm.IsLauncher) === true) && plasmoid.immutability !== PlasmaCore.Types.SystemImmutable text: i18n("Unpin Launcher") icon: "window-unpin" onClicked: { var launcher = get(atm.LauncherUrlWithoutIcon); if (latteView && root.launchersGroup >= LatteCore.Types.LayoutLaunchers) { latteView.layoutsManager.launchersSignals.removeLauncher(root.viewLayoutName, root.launchersGroup, launcher); } else { root.launcherForRemoval = launcher tasksModel.requestRemoveLauncher(launcher); root.launchersUpdatedFor(launcher); } } } //////END OF NEW ARCHITECTURE /*PlasmaComponents.MenuItem { separator: true visible: root.editMode }*/ PlasmaComponents.MenuItem { id: addInternalSeparatorItem visible: root.editMode icon: "add" text: i18n("Add Separator") onClicked: { var pos=visualParent.itemIndex; root.addInternalSeparatorAtPos(pos); } } PlasmaComponents.MenuItem { id: removeInternalSeparatorItem visible: root.editMode && visualParent.isSeparator icon: "remove" text: i18n("Remove Separator") enabled: (root.indexer.separators.length > 0) && visualParent && visualParent.isSeparator onClicked: { - //root.removeLastSeparator(); var launcher = get(atm.LauncherUrlWithoutIcon); if (latteView && root.launchersGroup >= LatteCore.Types.LayoutLaunchers) { latteView.layoutsManager.launchersSignals.removeLauncher(root.viewLayoutName, root.launchersGroup, launcher); } else { root.launcherForRemoval = launcher; tasksModel.requestRemoveLauncher(launcher); root.launchersUpdatedFor(launcher); } } } PlasmaComponents.MenuItem { //text: i18n("Configure") //section: true separator: true visible: preferenceMenuItem.visible } /* PlasmaComponents.MenuItem { separator: true visible: root.editMode }*/ PlasmaComponents.MenuItem { id: layoutsMenuItem action: latteView ? containmentActions[1] : plasmoid.action("configure") enabled: visible visible: latteView && latteView.layoutsManager.menuLayouts.length>1 } PlasmaComponents.MenuItem { id: preferenceMenuItem action: latteView ? containmentActions[2] : plasmoid.action("configure") visible: latteView } PlasmaComponents.MenuItem { id: quitApplicationItem action: latteView ? containmentActions[3] : plasmoid.action("configure") visible: latteView } PlasmaComponents.MenuItem { separator: true visible: preferenceMenuItem.visible } PlasmaComponents.MenuItem { id: alternativesMenuItem visible: root.editMode && !visualParent.isSeparator text: plasmoid.action("alternatives").text icon: plasmoid.action("alternatives").icon onClicked: plasmoid.action("alternatives").trigger(); } PlasmaComponents.MenuItem { id: addWidgets action: latteView ? containmentActions[5] : plasmoid.action("configure"); visible: latteView } PlasmaComponents.MenuItem { id: configureItem action: latteView ? containmentActions[6] : plasmoid.action("configure") } //! BEGIN: Plasmoid actions when it isnt inside a Latte dock PlasmaComponents.MenuItem { id: configurePlasmoid visible: !latteView && !plasmoid.immutable text: plasmoid.action("configure").text icon: plasmoid.action("configure").icon onClicked: plasmoid.action("configure").trigger(); } //! END: Plasmoid actions when it isnt inside a Latte dock PlasmaComponents.MenuItem { separator: true visible: closeWindowItem.visible } //!move window Close button at the very bottom in order to not alter users workflow //!comparing with the design decisions of other taskmanagers PlasmaComponents.MenuItem { id: closeWindowItem visible: (visualParent && visualParent.m.IsLauncher !== true && visualParent.m.IsStartup !== true) enabled: visualParent && visualParent.m.IsClosable === true text: i18n("&Close") icon: "window-close" onClicked: { if (parabolic.factor.zoom>1) { delayWindowRemovalTimer.modelIndex = menu.modelIndex; delayWindowRemovalTimer.start(); } else { tasksModel.requestClose(menu.modelIndex); } } } PlasmaComponents.MenuItem { separator: true visible: removePlasmoid.visible } PlasmaComponents.MenuItem { id: removePlasmoid visible: (latteView && latteView.editMode) || (!latteView && !plasmoid.immutable /*normal plasmoid in the desktop*/) text: plasmoid.action("remove").text icon: plasmoid.action("remove").icon onClicked: plasmoid.action("remove").trigger(); } } diff --git a/plasmoid/package/contents/ui/ParabolicManager.qml b/plasmoid/package/contents/ui/ParabolicManager.qml deleted file mode 100644 index 7ec33019..00000000 --- a/plasmoid/package/contents/ui/ParabolicManager.qml +++ /dev/null @@ -1,264 +0,0 @@ -/* -* Copyright 2016 Smith AR -* Michail Vourlakos -* -* This file is part of Latte-Dock -* -* Latte-Dock is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 of -* the License, or (at your option) any later version. -* -* Latte-Dock is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*/ - -import QtQuick 2.0 - -import org.kde.plasma.plasmoid 2.0 - -// holds all the logic around parabolic effect signals into one place. -// ParabolicManager is responsible for triggering all the messages to tasks -// that are neighbour to the hovered task. This will help a lot to catch cases -// such as separators and proper clearing zoom. - -Item { - id: parManager - - property bool hasInternalSeparator: false - - property int firstRealTaskIndex: -1 - property int lastRealTaskIndex: -1 - property int countRealTasks: -1 - - Connections{ - target: root - onTasksCountChanged: parManager.updateTasksEdgesIndexes(); - onHiddenTasksUpdated: parManager.updateTasksEdgesIndexes(); - } - - Component.onCompleted: { - updateHasInternalSeparator(); - updateTasksEdgesIndexes(); - } - - function updateTasksEdgesIndexes() { - var newFirstTask = firstRealTask(); - var newLastTask = lastRealTask(); - - if (newFirstTask !== firstRealTaskIndex || newLastTask !== lastRealTaskIndex ){ - firstRealTaskIndex = newFirstTask; - lastRealTaskIndex = newLastTask; - } - - countRealTasks = realTasks(); - } - - function updateHasInternalSeparator() { - var count = icList.contentItem.children.length; - for (var i=0; i=0 - && (taskIsSeparator(next) || (root.showWindowsOnlyFromLaunchers && taskIsForcedHidden(next))) ) - next = next - 1; - - return next; - } - - function availableHigherIndex(from) { - var next = from; - - while (next<=root.tasksCount-1 - && (taskIsSeparator(next) || (root.showWindowsOnlyFromLaunchers && taskIsForcedHidden(next))) ) { - next = next + 1; - } - - return next; - } - - function isSeparator(launcher){ - return (launcher.indexOf("latte-separator")!==-1 && launcher.indexOf(".desktop")!==1); - } - - function taskIsSeparator(taskIndex){ - var task = icList.childAtIndex(taskIndex); - - return (task && !task.isForcedHidden && task.isSeparator); - } - - function taskIsForcedHidden(taskIndex) { - var task = icList.childAtIndex(taskIndex); - - //!tasks that become hidden there is a chance to have index===-1 and to not be - //!able to be tracked down - return ((!task && (taskIndex>=0 && taskIndex=0); - } - - //! the real index task after we take into account the separators before it - //! for example the first task if there is a separator before it is 1, it isnt 0 - function realTaskIndex(pseudoIndex) { - if (hasInternalSeparator) { - var steps = pseudoIndex + 1; - var pos = 0; - - while (steps > 0) { - if (!taskIsSeparator(pos)) { - steps = steps - 1; - } - - if (steps > 0) - pos = pos + 1; - } - - return pos; - } else { - return pseudoIndex; - } - } - - //! the pseudo index task after we take into account the separators before it - //! for example the third task if there is a separator before it is 1, it isnt 2 - function pseudoTaskIndex(realIndex) { - var pseudoIndex = realIndex; - - if (hasInternalSeparator) { - for (var i=0; i