2022-08-28 21:48:51 +00:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: 2014-2015 Eike Hein <hein@kde.org>
|
|
|
|
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
import QtQuick 2.15
|
2022-08-28 21:48:51 +00:00
|
|
|
import QtQml 2.15
|
|
|
|
|
|
|
|
import org.kde.plasma.plasmoid 2.0
|
2024-08-09 01:20:25 +00:00
|
|
|
import org.kde.plasma.core as PlasmaCore
|
|
|
|
import org.kde.plasma.components 3.0 as PlasmaComponents
|
|
|
|
import org.kde.config // for KAuthorized
|
|
|
|
import org.kde.kirigami 2.20 as Kirigami
|
2022-08-28 21:48:51 +00:00
|
|
|
|
|
|
|
import org.kde.private.desktopcontainment.folder 0.1 as Folder
|
|
|
|
|
|
|
|
FocusScope {
|
|
|
|
id: folderViewLayerComponent
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
property var sharedActions: ["newMenu", "paste", "undo", "emptyTrash"]
|
2022-08-28 21:48:51 +00:00
|
|
|
property Component folderViewDialogComponent: Qt.createComponent("FolderViewDialog.qml", Qt.Asynchronous, root)
|
|
|
|
|
|
|
|
property Item view: folderView
|
|
|
|
property Item label: null
|
2024-08-09 01:20:25 +00:00
|
|
|
property int labelHeight: Kirigami.Units.iconSizes.sizeForLabels
|
|
|
|
+ (root.isPopup ? (Kirigami.Units.smallSpacing * 2) : 0)
|
2022-08-28 21:48:51 +00:00
|
|
|
|
|
|
|
property alias model: folderView.model
|
|
|
|
property alias overflowing: folderView.overflowing
|
|
|
|
property alias flow: folderView.flow
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
property string resolution: Math.round(root.screenGeometry.width) + "x" + Math.round(root.screenGeometry.height)
|
2022-08-28 21:48:51 +00:00
|
|
|
|
|
|
|
readonly property bool lockedByKiosk: !KAuthorized.authorize("editable_desktop_icons")
|
|
|
|
|
|
|
|
focus: true
|
|
|
|
|
|
|
|
function updateContextualActions() {
|
|
|
|
folderView.model.updateActions();
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
for (let i = 0, len = sharedActions.length; i < len; i++) {
|
|
|
|
const actionName = sharedActions[i];
|
|
|
|
const appletAction = Plasmoid.internalAction(actionName);
|
|
|
|
if (appletAction) {
|
|
|
|
modelAction = folderView.model.action(actionName);
|
|
|
|
appletAction.text = modelAction.text;
|
|
|
|
appletAction.enabled = modelAction.enabled;
|
|
|
|
appletAction.visible = modelAction.visible;
|
|
|
|
}
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function cancelRename() {
|
|
|
|
folderView.cancelRename();
|
|
|
|
}
|
|
|
|
|
|
|
|
function goHome() {
|
2024-08-09 01:20:25 +00:00
|
|
|
if (folderView.url !== Plasmoid.configuration.url) {
|
|
|
|
folderView.url = Qt.binding(() => Plasmoid.configuration.url);
|
2022-08-28 21:48:51 +00:00
|
|
|
folderView.history = [];
|
|
|
|
folderView.updateHistory();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Binding {
|
2024-08-09 01:20:25 +00:00
|
|
|
target: Plasmoid
|
2022-08-28 21:48:51 +00:00
|
|
|
property: "title"
|
|
|
|
value: labelGenerator.displayLabel
|
|
|
|
restoreMode: Binding.RestoreBinding
|
|
|
|
}
|
|
|
|
|
|
|
|
Folder.LabelGenerator {
|
|
|
|
id: labelGenerator
|
|
|
|
|
|
|
|
folderModel: folderView.model
|
2024-08-09 01:20:25 +00:00
|
|
|
rtl: (Qt.application.layoutDirection === Qt.RightToLeft)
|
|
|
|
labelMode: Plasmoid.configuration.labelMode || (isContainment ? 0 : 1)
|
|
|
|
labelText: Plasmoid.configuration.labelText
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Folder.ViewPropertiesMenu {
|
|
|
|
id: viewPropertiesMenu
|
|
|
|
|
|
|
|
showLayoutActions: !isPopup
|
|
|
|
showLockAction: isContainment
|
|
|
|
showIconSizeActions: !root.useListViewMode
|
|
|
|
|
|
|
|
lockedEnabled: !lockedByKiosk
|
|
|
|
|
|
|
|
onArrangementChanged: {
|
2024-08-09 01:20:25 +00:00
|
|
|
Plasmoid.configuration.arrangement = arrangement;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onAlignmentChanged: {
|
2024-08-09 01:20:25 +00:00
|
|
|
Plasmoid.configuration.alignment = alignment;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onPreviewsChanged: {
|
2024-08-09 01:20:25 +00:00
|
|
|
Plasmoid.configuration.previews = previews;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onLockedChanged: {
|
|
|
|
if (!lockedByKiosk) {
|
2024-08-09 01:20:25 +00:00
|
|
|
Plasmoid.configuration.locked = locked;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onSortModeChanged: {
|
2024-08-09 01:20:25 +00:00
|
|
|
Plasmoid.configuration.sortMode = sortMode;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onSortDescChanged: {
|
2024-08-09 01:20:25 +00:00
|
|
|
Plasmoid.configuration.sortDesc = sortDesc;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onSortDirsFirstChanged: {
|
2024-08-09 01:20:25 +00:00
|
|
|
Plasmoid.configuration.sortDirsFirst = sortDirsFirst;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onIconSizeChanged: {
|
2024-08-09 01:20:25 +00:00
|
|
|
Plasmoid.configuration.iconSize = iconSize;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Component.onCompleted: {
|
2024-08-09 01:20:25 +00:00
|
|
|
arrangement = Plasmoid.configuration.arrangement;
|
|
|
|
alignment = Plasmoid.configuration.alignment;
|
|
|
|
previews = Plasmoid.configuration.previews;
|
|
|
|
locked = Plasmoid.configuration.locked || lockedByKiosk;
|
|
|
|
sortMode = Plasmoid.configuration.sortMode;
|
|
|
|
sortDesc = Plasmoid.configuration.sortDesc;
|
|
|
|
sortDirsFirst = Plasmoid.configuration.sortDirsFirst;
|
|
|
|
iconSize = Plasmoid.configuration.iconSize;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PlasmaComponents.Label {
|
|
|
|
anchors.fill: parent
|
|
|
|
|
|
|
|
text: folderView.errorString
|
2024-08-09 01:20:25 +00:00
|
|
|
textFormat: Text.PlainText
|
2022-08-28 21:48:51 +00:00
|
|
|
|
|
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
|
|
wrapMode: Text.Wrap
|
|
|
|
}
|
|
|
|
|
|
|
|
Connections {
|
2024-08-09 01:20:25 +00:00
|
|
|
target: root
|
2022-08-28 21:48:51 +00:00
|
|
|
|
|
|
|
function onExpandedChanged() {
|
|
|
|
if (root.isPopup) {
|
2024-08-09 01:20:25 +00:00
|
|
|
if (root.expanded) {
|
2022-08-28 21:48:51 +00:00
|
|
|
folderView.currentIndex = -1;
|
|
|
|
folderView.forceActiveFocus();
|
|
|
|
folderView.positionViewAtBeginning();
|
|
|
|
} else {
|
|
|
|
goHome();
|
|
|
|
|
|
|
|
folderView.currentIndex = -1;
|
|
|
|
folderView.model.clearSelection();
|
|
|
|
folderView.cancelRename();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getPositions() {
|
2024-08-09 01:20:25 +00:00
|
|
|
let allPositions;
|
2022-08-28 21:48:51 +00:00
|
|
|
try {
|
2024-08-09 01:20:25 +00:00
|
|
|
allPositions = JSON.parse(Plasmoid.configuration.positions);
|
2022-08-28 21:48:51 +00:00
|
|
|
} catch (err) {
|
2024-08-09 01:20:25 +00:00
|
|
|
allPositions = {};
|
|
|
|
allPositions[resolution] = Plasmoid.configuration.positions;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
return allPositions[resolution] || "";
|
|
|
|
}
|
|
|
|
|
|
|
|
function savePositions(positions) {
|
2024-08-09 01:20:25 +00:00
|
|
|
let allPositions;
|
2022-08-28 21:48:51 +00:00
|
|
|
try {
|
2024-08-09 01:20:25 +00:00
|
|
|
allPositions = JSON.parse(Plasmoid.configuration.positions);
|
2022-08-28 21:48:51 +00:00
|
|
|
} catch (err) {
|
2024-08-09 01:20:25 +00:00
|
|
|
allPositions = {};
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
allPositions[resolution] = positions;
|
2024-08-09 01:20:25 +00:00
|
|
|
Plasmoid.configuration.positions = JSON.stringify(allPositions, Object.keys(allPositions).sort());
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Connections {
|
2024-08-09 01:20:25 +00:00
|
|
|
target: Plasmoid.configuration
|
2022-08-28 21:48:51 +00:00
|
|
|
|
|
|
|
function onArrangementChanged() {
|
2024-08-09 01:20:25 +00:00
|
|
|
viewPropertiesMenu.arrangement = Plasmoid.configuration.arrangement;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function onAlignmentChanged() {
|
2024-08-09 01:20:25 +00:00
|
|
|
viewPropertiesMenu.alignment = Plasmoid.configuration.alignment;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function onLockedChanged() {
|
2024-08-09 01:20:25 +00:00
|
|
|
viewPropertiesMenu.locked = Plasmoid.configuration.locked;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function onSortModeChanged() {
|
2024-08-09 01:20:25 +00:00
|
|
|
folderView.sortMode = Plasmoid.configuration.sortMode;
|
|
|
|
viewPropertiesMenu.sortMode = Plasmoid.configuration.sortMode;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function onSortDescChanged() {
|
2024-08-09 01:20:25 +00:00
|
|
|
viewPropertiesMenu.sortDesc = Plasmoid.configuration.sortDesc;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function onSortDirsFirstChanged() {
|
2024-08-09 01:20:25 +00:00
|
|
|
viewPropertiesMenu.sortDirsFirst = Plasmoid.configuration.sortDirsFirst;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function onIconSizeChanged() {
|
2024-08-09 01:20:25 +00:00
|
|
|
viewPropertiesMenu.iconSize = Plasmoid.configuration.iconSize;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function onPositionsChanged() {
|
|
|
|
folderView.positions = getPositions();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FolderView {
|
|
|
|
id: folderView
|
|
|
|
|
|
|
|
anchors.left: parent.left
|
|
|
|
anchors.top: parent.top
|
2024-08-09 01:20:25 +00:00
|
|
|
anchors.topMargin: folderViewLayerComponent.label !== null ? folderViewLayerComponent.label.height : 0
|
2022-08-28 21:48:51 +00:00
|
|
|
anchors.right: parent.right
|
|
|
|
anchors.bottom: parent.bottom
|
|
|
|
|
|
|
|
focus: true
|
|
|
|
isRootView: true
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
url: Plasmoid.configuration.url
|
|
|
|
locked: (Plasmoid.configuration.locked || !isContainment || lockedByKiosk)
|
|
|
|
filterMode: Plasmoid.configuration.filterMode
|
|
|
|
filterPattern: Plasmoid.configuration.filterPattern
|
|
|
|
filterMimeTypes: Plasmoid.configuration.filterMimeTypes
|
|
|
|
showHiddenFiles: Plasmoid.configuration.showHiddenFiles
|
2022-08-28 21:48:51 +00:00
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
flow: (Plasmoid.configuration.arrangement === 0) ? GridView.FlowLeftToRight : GridView.FlowTopToBottom
|
|
|
|
layoutDirection: (Plasmoid.configuration.alignment === 0) ? Qt.LeftToRight : Qt.RightToLeft
|
2022-08-28 21:48:51 +00:00
|
|
|
|
|
|
|
onSortModeChanged: {
|
2024-08-09 01:20:25 +00:00
|
|
|
Plasmoid.configuration.sortMode = sortMode;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onPositionsChanged: {
|
2024-08-09 01:20:25 +00:00
|
|
|
saveTimer.restart()
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onPerStripeChanged: {
|
|
|
|
folderView.positions = getPositions();
|
|
|
|
}
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
Timer {
|
|
|
|
id: saveTimer
|
|
|
|
interval: Kirigami.Units.humanMoment
|
|
|
|
onTriggered: savePositions(folderView.positions)
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:48:51 +00:00
|
|
|
Component.onCompleted: {
|
2024-08-09 01:20:25 +00:00
|
|
|
folderView.sortMode = Plasmoid.configuration.sortMode;
|
2022-08-28 21:48:51 +00:00
|
|
|
folderView.positions = getPositions();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: labelComponent
|
|
|
|
|
|
|
|
Item {
|
|
|
|
id: label
|
|
|
|
|
|
|
|
// If we bind height to visible, it will be invisible initially (since "visible"
|
|
|
|
// propagates recursively) and that confuses the Label, hence the temp property.
|
2024-08-09 01:20:25 +00:00
|
|
|
readonly property bool active: (Plasmoid.configuration.labelMode !== 0)
|
2022-08-28 21:48:51 +00:00
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
readonly property bool showPin: root.isPopup && root.compactRepresentationItem && root.compactRepresentationItem.visible
|
2022-08-28 21:48:51 +00:00
|
|
|
|
|
|
|
width: parent.width
|
|
|
|
height: active ? labelHeight : 0
|
|
|
|
|
|
|
|
visible: active
|
|
|
|
|
|
|
|
property Item windowPin: null
|
|
|
|
property Item homeButton: null
|
|
|
|
|
|
|
|
onVisibleChanged: {
|
|
|
|
if (root.isPopup && !visible) {
|
2024-08-09 01:20:25 +00:00
|
|
|
root.hideOnWindowDeactivate = true;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onShowPinChanged: {
|
|
|
|
if (!windowPin && showPin) {
|
|
|
|
windowPin = windowPinComponent.createObject(label);
|
|
|
|
} else if (windowPin) {
|
|
|
|
windowPin.destroy();
|
|
|
|
windowPin = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Connections {
|
|
|
|
target: folderView
|
|
|
|
|
|
|
|
function onUrlChanged() {
|
2024-08-09 01:20:25 +00:00
|
|
|
if (!label.homeButton && folderView.url !== Plasmoid.configuration.url) {
|
2022-08-28 21:48:51 +00:00
|
|
|
label.homeButton = homeButtonComponent.createObject(label);
|
2024-08-09 01:20:25 +00:00
|
|
|
} else if (label.homeButton && folderView.url === Plasmoid.configuration.url) {
|
2022-08-28 21:48:51 +00:00
|
|
|
label.homeButton.destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PlasmaComponents.Label {
|
|
|
|
id: text
|
|
|
|
|
|
|
|
anchors {
|
|
|
|
left: label.homeButton ? label.homeButton.right : parent.left
|
|
|
|
right: label.windowPin ? label.windowPin.left : parent.right
|
2024-08-09 01:20:25 +00:00
|
|
|
margins: Kirigami.Units.smallSpacing
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
height: parent.height
|
|
|
|
|
|
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
verticalAlignment: Text.AlignTop
|
|
|
|
elide: Text.ElideMiddle
|
|
|
|
text: labelGenerator.displayLabel
|
2024-08-09 01:20:25 +00:00
|
|
|
textFormat: Text.PlainText
|
2022-08-28 21:48:51 +00:00
|
|
|
font.underline: labelMouseArea.containsMouse
|
|
|
|
}
|
|
|
|
|
|
|
|
MouseArea {
|
|
|
|
id: labelMouseArea
|
|
|
|
anchors {
|
|
|
|
top: text.top
|
|
|
|
horizontalCenter: text.horizontalCenter
|
|
|
|
}
|
|
|
|
width: text.contentWidth
|
|
|
|
height: text.contentHeight
|
|
|
|
hoverEnabled: true
|
|
|
|
cursorShape: Qt.PointingHandCursor
|
|
|
|
|
|
|
|
onClicked: {
|
2024-08-09 01:20:25 +00:00
|
|
|
Folder.AppLauncher.openUrl(folderView.url)
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: windowPinComponent
|
|
|
|
|
|
|
|
PlasmaComponents.ToolButton {
|
|
|
|
id: windowPin
|
|
|
|
|
|
|
|
anchors.right: parent.right
|
|
|
|
|
|
|
|
visible: label.showPin
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
width: root.isPopup ? Math.round(Kirigami.Units.iconSizes.small * 1.25) : 0
|
2022-08-28 21:48:51 +00:00
|
|
|
height: width
|
|
|
|
checkable: true
|
2024-08-09 01:20:25 +00:00
|
|
|
icon.name: "window-pin"
|
|
|
|
onCheckedChanged: root.hideOnWindowDeactivate = !checked
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: homeButtonComponent
|
|
|
|
|
|
|
|
PlasmaComponents.ToolButton {
|
|
|
|
id: homeButton
|
|
|
|
|
|
|
|
anchors.left: parent.left
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
visible: root.isPopup && folderView.url !== Plasmoid.configuration.url
|
2022-08-28 21:48:51 +00:00
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
width: root.isPopup ? Math.round(Kirigami.Units.iconSizes.small * 1.25) : 0
|
2022-08-28 21:48:51 +00:00
|
|
|
height: width
|
2024-08-09 01:20:25 +00:00
|
|
|
icon.name: "go-home"
|
2022-08-28 21:48:51 +00:00
|
|
|
|
|
|
|
onClicked: goHome()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component.onCompleted: {
|
|
|
|
if (root.showPin) {
|
|
|
|
windowPin = windowPinComponent.createObject(label);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
|
|
|
|
PlasmaCore.Action {
|
|
|
|
id: viewPropertiesAction
|
|
|
|
text: i18n("Icons")
|
|
|
|
icon.name: "view-list-icons"
|
|
|
|
menu: viewPropertiesMenu.menu
|
|
|
|
}
|
|
|
|
PlasmaCore.Action {
|
|
|
|
id: actionSeparator
|
|
|
|
isSeparator: true
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:48:51 +00:00
|
|
|
Component.onCompleted: {
|
|
|
|
if (!isContainment) {
|
|
|
|
label = labelComponent.createObject(folderViewLayerComponent);
|
|
|
|
}
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
for (let i = 0, len = sharedActions.length; i < len; i++) {
|
|
|
|
const actionName = sharedActions[i];
|
|
|
|
const modelAction = folderView.model.action(actionName);
|
|
|
|
Plasmoid.contextualActions.push(modelAction)
|
2022-08-28 21:48:51 +00:00
|
|
|
if (actionName === "newMenu") {
|
2024-08-09 01:20:25 +00:00
|
|
|
Plasmoid.contextualActions.push(viewPropertiesAction)
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
Plasmoid.contextualActions.push(actionSeparator);
|
2022-08-28 21:48:51 +00:00
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
Plasmoid.contextualActionsAboutToShow.connect(updateContextualActions);
|
|
|
|
Plasmoid.contextualActionsAboutToShow.connect(folderView.model.clearSelection);
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
}
|