You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
251 lines
9.0 KiB
251 lines
9.0 KiB
/* |
|
* Copyright 2019 Kai Uwe Broulik <kde@privat.broulik.de> |
|
* |
|
* 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) version 3 or any later version |
|
* accepted by the membership of KDE e.V. (or its successor approved |
|
* by the membership of KDE e.V.), which shall act as a proxy |
|
* defined in Section 14 of version 3 of the license. |
|
* |
|
* 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, see <http://www.gnu.org/licenses/> |
|
*/ |
|
|
|
import QtQuick 2.8 |
|
import QtQuick.Window 2.2 |
|
import QtQuick.Layouts 1.1 |
|
|
|
import org.kde.plasma.core 2.0 as PlasmaCore |
|
import org.kde.plasma.components 3.0 as PlasmaComponents3 |
|
|
|
import org.kde.notificationmanager 1.0 as NotificationManager |
|
|
|
import org.kde.plasma.private.notifications 2.0 as Notifications |
|
|
|
ColumnLayout { |
|
id: jobItem |
|
|
|
property int jobState |
|
property int jobError |
|
|
|
property alias percentage: progressBar.value |
|
property alias suspendable: suspendButton.visible |
|
property alias killable: killButton.visible |
|
|
|
property bool hovered |
|
property QtObject jobDetails |
|
|
|
readonly property int totalFiles: jobItem.jobDetails && jobItem.jobDetails.totalFiles || 0 |
|
readonly property var url: { |
|
if (jobItem.jobState !== NotificationManager.Notifications.JobStateStopped |
|
|| jobItem.jobError |
|
|| totalFiles <= 0) { |
|
return null; |
|
} |
|
|
|
// For a single file show actions for it |
|
if (totalFiles === 1) { |
|
return jobItem.jobDetails.descriptionUrl; |
|
// Otherwise the destination folder all of them were copied into |
|
} else { |
|
return jobItem.jobDetails.destUrl; |
|
} |
|
} |
|
|
|
property alias iconContainerItem: jobDragIcon.parent |
|
|
|
readonly property alias dragging: jobDragArea.dragging |
|
readonly property alias menuOpen: otherFileActionsMenu.visible |
|
|
|
signal suspendJobClicked |
|
signal resumeJobClicked |
|
signal killJobClicked |
|
|
|
signal openUrl(string url) |
|
signal fileActionInvoked |
|
|
|
spacing: 0 |
|
|
|
// This item is parented to the NotificationItem iconContainer |
|
PlasmaCore.IconItem { |
|
id: jobDragIcon |
|
width: parent ? parent.width : 0 |
|
height: parent ? parent.height : 0 |
|
usesPlasmaTheme: false |
|
visible: valid |
|
active: jobDragArea.containsMouse |
|
source: jobItem.totalFiles === 1 && jobItem.url ? plasmoid.nativeInterface.iconNameForUrl(jobItem.url) : "" |
|
|
|
Binding { |
|
target: jobDragIcon.parent |
|
property: "visible" |
|
value: true |
|
when: jobDragIcon.valid |
|
} |
|
|
|
DraggableFileArea { |
|
id: jobDragArea |
|
anchors.fill: parent |
|
|
|
hoverEnabled: true |
|
dragParent: jobDragIcon |
|
dragUrl: jobItem.url || "" |
|
dragPixmap: jobDragIcon.source |
|
|
|
onActivated: jobItem.openUrl(jobItem.url) |
|
onContextMenuRequested: { |
|
// avoid menu button glowing if we didn't actually press it |
|
otherFileActionsButton.checked = false; |
|
|
|
otherFileActionsMenu.visualParent = this; |
|
otherFileActionsMenu.open(x, y); |
|
} |
|
} |
|
} |
|
|
|
RowLayout { |
|
id: progressRow |
|
Layout.fillWidth: true |
|
spacing: units.smallSpacing |
|
|
|
PlasmaComponents3.ProgressBar { |
|
id: progressBar |
|
Layout.fillWidth: true |
|
from: 0 |
|
to: 100 |
|
// TODO do we actually need the window visible check? perhaps I do because it can be in popup or expanded plasmoid |
|
indeterminate: visible && Window.window && Window.window.visible && percentage < 1 |
|
&& jobItem.jobState === NotificationManager.Notifications.JobStateRunning |
|
// is this too annoying? |
|
&& (jobItem.jobDetails.processedBytes === 0 || jobItem.jobDetails.totalBytes === 0) |
|
&& jobItem.jobDetails.processedFiles === 0 |
|
//&& jobItem.jobDetails.processedDirectories === 0 |
|
} |
|
|
|
RowLayout { |
|
spacing: 0 |
|
|
|
PlasmaComponents3.ToolButton { |
|
id: suspendButton |
|
icon.name: "media-playback-pause" |
|
onClicked: jobItem.jobState === NotificationManager.Notifications.JobStateSuspended ? jobItem.resumeJobClicked() |
|
: jobItem.suspendJobClicked() |
|
|
|
PlasmaComponents3.ToolTip { |
|
text: i18ndc("plasma_applet_org.kde.plasma.notifications", "Pause running job", "Pause") |
|
} |
|
} |
|
|
|
PlasmaComponents3.ToolButton { |
|
id: killButton |
|
icon.name: "media-playback-stop" |
|
onClicked: jobItem.killJobClicked() |
|
|
|
PlasmaComponents3.ToolTip { |
|
text: i18ndc("plasma_applet_org.kde.plasma.notifications", "Cancel running job", "Cancel") |
|
} |
|
} |
|
|
|
PlasmaComponents3.ToolButton { |
|
id: expandButton |
|
icon.name: checked ? "arrow-down" : (LayoutMirroring.enabled ? "arrow-left" : "arrow-right") |
|
checkable: true |
|
enabled: jobItem.jobDetails && jobItem.jobDetails.hasDetails |
|
|
|
PlasmaComponents3.ToolTip { |
|
text: expandButton.checked ? i18ndc("plasma_applet_org.kde.plasma.notifications", "A button tooltip; hides item details", "Hide Details") |
|
: i18ndc("plasma_applet_org.kde.plasma.notifications", "A button tooltip; expands the item to show details", "Show Details") |
|
} |
|
} |
|
} |
|
} |
|
|
|
Loader { |
|
Layout.fillWidth: true |
|
active: expandButton.checked |
|
// Loader doesn't reset its height when unloaded, just hide it altogether |
|
visible: active |
|
sourceComponent: JobDetails { |
|
jobDetails: jobItem.jobDetails |
|
} |
|
} |
|
|
|
Flow { // it's a Flow so it can wrap if too long |
|
Layout.fillWidth: true |
|
spacing: units.smallSpacing |
|
// We want the actions to be right-aligned but Flow also reverses |
|
// the order of items, so we put them in reverse order |
|
layoutDirection: Qt.RightToLeft |
|
visible: url && url.toString() !== "" |
|
|
|
PlasmaComponents3.Button { |
|
id: otherFileActionsButton |
|
height: Math.max(implicitHeight, openButton.implicitHeight) |
|
icon.name: "application-menu" |
|
checkable: true |
|
onPressedChanged: { |
|
if (pressed) { |
|
checked = Qt.binding(function() { |
|
return otherFileActionsMenu.visible; |
|
}); |
|
otherFileActionsMenu.visualParent = this; |
|
// -1 tells it to "align bottom left of visualParent (this)" |
|
otherFileActionsMenu.open(-1, -1); |
|
} |
|
} |
|
|
|
PlasmaComponents3.ToolTip { |
|
text: i18nd("plasma_applet_org.kde.plasma.notifications", "More Options...") |
|
} |
|
|
|
Notifications.FileMenu { |
|
id: otherFileActionsMenu |
|
url: jobItem.url || "" |
|
onActionTriggered: jobItem.fileActionInvoked() |
|
} |
|
} |
|
|
|
PlasmaComponents3.Button { |
|
id: openButton |
|
height: Math.max(implicitHeight, otherFileActionsButton.implicitHeight) |
|
// would be nice to have the file icon here? |
|
text: jobItem.jobDetails && jobItem.jobDetails.totalFiles > 1 |
|
? i18nd("plasma_applet_org.kde.plasma.notifications", "Open Containing Folder") |
|
: i18nd("plasma_applet_org.kde.plasma.notifications", "Open") |
|
onClicked: jobItem.openUrl(jobItem.url) |
|
} |
|
} |
|
|
|
states: [ |
|
State { |
|
when: jobItem.jobState === NotificationManager.Notifications.JobStateSuspended |
|
PropertyChanges { |
|
target: suspendButton |
|
tooltip: i18ndc("plasma_applet_org.kde.plasma.notifications", "Resume paused job", "Resume") |
|
checked: true |
|
} |
|
PropertyChanges { |
|
target: progressBar |
|
enabled: false |
|
} |
|
}, |
|
State { |
|
when: jobItem.jobState === NotificationManager.Notifications.JobStateStopped |
|
PropertyChanges { |
|
target: progressRow |
|
visible: false |
|
} |
|
PropertyChanges { |
|
target: expandButton |
|
checked: false |
|
} |
|
} |
|
] |
|
}
|
|
|