/*************************************************************************** * Copyright (C) 2012-2013 by Eike Hein * * * * This program 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. * * * * This program 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ import QtQuick 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.draganddrop 2.0 import org.kde.plasma.private.taskmanager 0.1 as TaskManager import "../code/layout.js" as LayoutManager import "../code/tools.js" as TaskTools MouseArea { id: task width: groupDialog.mainItem.width height: units.iconSizes.small + LayoutManager.verticalMargins() visible: false LayoutMirroring.enabled: (Qt.application.layoutDirection == Qt.RightToLeft) LayoutMirroring.childrenInherit: (Qt.application.layoutDirection == Qt.RightToLeft) property int itemIndex: index property int itemId: model.Id property bool inPopup: false property bool isGroupParent: model.hasModelChildren property bool isLauncher: model.IsLauncher property bool isStartup: model.IsStartup property bool demandsAttention: model.DemandsAttention property int textWidth: label.implicitWidth property bool pressed: false property int pressX: -1 property int pressY: -1 property Item busyIndicator property int wheelDelta: 0 acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MidButton hoverEnabled: true onItemIndexChanged: { if (!inPopup && !tasks.vertical && LayoutManager.calculateStripes() > 1) { var newWidth = LayoutManager.taskWidth(); if (index == backend.tasksModel.launcherCount) { newWidth += LayoutManager.launcherLayoutWidthDiff(); } width = newWidth; } } onIsStartupChanged: { if (!isStartup) { tasks.itemGeometryChanged(task, itemId); busyIndicator.visible = false; busyIndicator.running = false; icon.visible = true; } } onDemandsAttentionChanged: { tasks.updateStatus(demandsAttention); } onContainsMouseChanged: { if (!containsMouse) { pressed = false; } tasks.itemHovered(model.Id, containsMouse); } onPressed: { if (mouse.button == Qt.LeftButton || mouse.button == Qt.MidButton) { pressed = true; pressX = mouse.x; pressY = mouse.y; } else if (mouse.button == Qt.RightButton) { if (plasmoid.configuration.showToolTips) { toolTip.hideToolTip(); } tasks.itemContextMenu(task, plasmoid.action("configure")); } } onReleased: { if (pressed) { if (mouse.button == Qt.MidButton) { if (plasmoid.configuration.middleClickAction == TaskManager.Backend.NewInstance) { tasks.launchNewInstance(model.Id); } else if (plasmoid.configuration.middleClickAction == TaskManager.Backend.Close) { tasks.closeByItemId(model.Id); } } else if (mouse.button == Qt.LeftButton) { if (mouse.modifiers & Qt.ShiftModifier) { tasks.launchNewInstance(model.Id); } else if (isGroupParent) { if ((iconsOnly || mouse.modifiers == Qt.ControlModifier) && backend.canPresentWindows()) { tasks.presentWindows(model.Id); } else if (groupDialog.visible) { groupDialog.visible = false; } else { groupDialog.visualParent = task; groupDialog.visible = true; } } else { tasks.activateItem(model.Id, true); } } } pressed = false; pressX = -1; pressY = -1; } onPositionChanged: { if (pressX != -1 && dragHelper.isDrag(pressX, pressY, mouse.x, mouse.y)) { tasks.dragSource = task; dragHelper.startDrag(task, model.MimeType, model.MimeData, model.LauncherUrl, model.DecorationRole); pressX = -1; pressY = -1; return; } } onWheel: { if (plasmoid.configuration.wheelEnabled) { wheelDelta = TaskTools.wheelActivateNextPrevTask(task, wheelDelta, wheel.angleDelta.y); } } PlasmaCore.FrameSvgItem { id: frame anchors.fill: parent imagePath: "widgets/tasks" property string basePrefix: "normal" prefix: TaskTools.taskPrefix("normal") onRepaintNeeded: prefix = TaskTools.taskPrefix(basePrefix); onBasePrefixChanged: prefix = TaskTools.taskPrefix(basePrefix); PlasmaCore.ToolTipArea { id: toolTip anchors.fill: parent active: !inPopup && !groupDialog.visible && plasmoid.configuration.showToolTips interactive: true location: plasmoid.location mainItem: toolTipDelegate //FIXME TODO: highlightWindows: plasmoid.configuration.highlightWindows onContainsMouseChanged: { if (containsMouse) { toolTipDelegate.windows = model.WindowList; toolTipDelegate.mainText = model.DisplayRole; toolTipDelegate.icon = model.DecorationRole; toolTipDelegate.subText = model.IsLauncher ? model.GenericName : toolTip.generateSubText(model); } } function generateSubText(task) { var subTextEntries = new Array(); if (!plasmoid.configuration.showOnlyCurrentDesktop) { subTextEntries.push(i18n("On %1", task.DesktopName)); } if (task.OnAllActivities) { subTextEntries.push(i18nc("Which virtual desktop a window is currently on", "Available on all activities")); } else if (plasmoid.configuration.showOnlyCurrentActivity) { if (task.OtherActivityNames.length > 0) { subTextEntries.push(i18nc("Activities a window is currently on (apart from the current one)", "Also available on %1", task.OtherActivityNames.join(", "))); } } else if (task.ActivityNames.length > 0) { subTextEntries.push(i18nc("Which activities a window is currently on", "Available on %1", task.ActivityNames.join(", "))); } return subTextEntries.join("\n"); } } } Item { id: iconBox anchors { left: parent.left leftMargin: tasks.vertical && !label.visible ? adjustMargin(true, parent.width, taskFrame.margins.left) : taskFrame.margins.left top: parent.top topMargin: adjustMargin(false, parent.height, taskFrame.margins.top); bottom: parent.bottom bottomMargin: adjustMargin(false, parent.height, taskFrame.margins.bottom); right: (tasks.vertical && !label.visible && !inPopup) ? parent.right : undefined rightMargin: tasks.vertical && !label.visible ? adjustMargin(true, parent.width, taskFrame.margins.right) : undefined } function adjustMargin(vert, size, margin) { if (!size) { return margin; } var margins = vert ? LayoutManager.horizontalMargins() : LayoutManager.verticalMargins(); if ((size - margins) < units.iconSizes.small) { return Math.ceil((margin * (units.iconSizes.small / size)) / 2); } return margin; } width: inPopup ? units.iconSizes.small : Math.min(height, parent.width - LayoutManager.horizontalMargins()) PlasmaCore.IconItem { id: icon anchors.fill: parent visible: false active: task.containsMouse enabled: !(model.Minimized && !plasmoid.configuration.showOnlyMinimized) source: model.DecorationRole onVisibleChanged: { if (visible && busyIndicator) { busyIndicator.destroy(); } } } PlasmaComponents.BusyIndicator { id: busyIndicator anchors.fill: parent visible: false running: false } states: [ // Using a state transition avoids a binding loop between label.visible and // the text label margin, which derives from the icon width. State { name: "standalone" when: !label.visible AnchorChanges { target: iconBox anchors.left: undefined anchors.horizontalCenter: parent.horizontalCenter } PropertyChanges { target: iconBox anchors.leftMargin: 0 } } ] } TaskManager.TextLabel { id: label anchors { fill: parent leftMargin: taskFrame.margins.left + icon.width + (units.smallSpacing * 2) topMargin: taskFrame.margins.top rightMargin: taskFrame.margins.right bottomMargin: taskFrame.margins.bottom } visible: (inPopup || !iconsOnly && !model.IsLauncher && (parent.width - LayoutManager.horizontalMargins()) >= (theme.mSize(theme.defaultFont).width * 7)) enabled: !model.Minimized text: (!inPopup && iconsOnly) ? "" : model.DisplayRole color: theme.textColor elide: !inPopup } states: [ State { name: "launcher" when: model.IsLauncher PropertyChanges { target: frame basePrefix: "" } }, State { name: "hovered" when: containsMouse PropertyChanges { target: frame basePrefix: "hover" } }, State { name: "attention" when: model.DemandsAttention PropertyChanges { target: frame basePrefix: "attention" } }, State { name: "minimized" when: model.Minimized && !(groupDialog.visible && groupDialog.target == task) PropertyChanges { target: frame basePrefix: "minimized" } }, State { name: "active" when: model.Active || groupDialog.visible && groupDialog.target == task PropertyChanges { target: frame basePrefix: "focus" } } ] Component.onCompleted: { if (model.IsStartup) { busyIndicator.running = true; busyIndicator.visible = true; } else { icon.visible = true; } if (model.hasModelChildren) { var component = Qt.createComponent("GroupExpanderOverlay.qml"); component.createObject(task); } } /* Component.onDestruction: { if (groupDialog.visible && groupDialog.groupItemId == model.Id) { groupDialog.visible = false; } } */ }