mirror of
https://gitgud.io/wackyideas/aerothemeplasma.git
synced 2024-08-15 00:43:43 +00:00
Very early KDE 6 release.
This commit is contained in:
parent
7cc4ccabbc
commit
686046d4f7
6272 changed files with 140920 additions and 529657 deletions
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014-2015 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.configuration 2.0
|
||||
|
||||
ConfigModel {
|
||||
property bool isFolder: (Plasmoid.pluginName === "org.kde.plasma.folder")
|
||||
|
||||
ConfigCategory {
|
||||
name: i18n("Location")
|
||||
icon: "inode-directory"
|
||||
source: "ConfigLocation.qml"
|
||||
visible: isFolder
|
||||
}
|
||||
|
||||
ConfigCategory {
|
||||
name: i18n("Icons")
|
||||
icon: "preferences-desktop-icons"
|
||||
source: "ConfigIcons.qml"
|
||||
visible: isFolder
|
||||
}
|
||||
|
||||
ConfigCategory {
|
||||
name: i18n("Filter")
|
||||
icon: "preferences-desktop-filter"
|
||||
source: "ConfigFilter.qml"
|
||||
visible: isFolder
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
||||
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
|
||||
<kcfgfile name=""/>
|
||||
|
||||
<group name="General">
|
||||
<entry name="icon" type="String">
|
||||
<label>The name of the custom icon to use for the compact representation (e.g. on a small panel) of the Folder View applet. Only used if useCustomIcon is true.</label>
|
||||
<default>folder-symbolic</default>
|
||||
</entry>
|
||||
<entry name="useCustomIcon" type="Bool">
|
||||
<label>Whether to use a custom icon for the compact representation (e.g. on a small panel) of the Folder View Applet.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
|
||||
<entry name="ItemsGeometries" type="String" hidden="true">
|
||||
<label>Encoded geometries of items (resource categories).</label>
|
||||
</entry>
|
||||
<entry name="ToolBoxButtonState" type="String">
|
||||
<label>Position state of the toolbox button.</label>
|
||||
<default></default>
|
||||
</entry>
|
||||
<entry name="ToolBoxButtonX" type="int">
|
||||
<label>X coordinate of the toolbox.</label>
|
||||
</entry>
|
||||
<entry name="ToolBoxButtonY" type="int">
|
||||
<label>Y coordinate of the toolbox.</label>
|
||||
</entry>
|
||||
<entry name="FirstStartup" type="Bool" hidden="true">
|
||||
<label>First time the containment starts?</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
|
||||
<entry name="positions" type="StringList" hidden="true">
|
||||
<default></default>
|
||||
</entry>
|
||||
|
||||
<entry name="url" type="String">
|
||||
<label>URL of the file system location being shown.</label>
|
||||
<default>desktop:/</default>
|
||||
</entry>
|
||||
<entry name="labelMode" type="Int">
|
||||
<label>How to show the Folder View label: 0 = No label, 1 = Friendly version of path relative to closest Places entry, 2 = Full path, 3 = Custom title</label>
|
||||
<default>1</default>
|
||||
</entry>
|
||||
<entry name="labelText" type="String">
|
||||
<label>Custom text for the Folder View label. Only used if labelMode is 3.</label>
|
||||
<default></default>
|
||||
</entry>
|
||||
|
||||
<entry name="arrangement" type="Int">
|
||||
<label>How Folder View icons are arranged: 0 = Rows, 1 = Columns</label>
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="alignment" type="Int">
|
||||
<label>How Folder View icons are aligned: 0 = Left, 1 = Right</label>
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="locked" type="Bool">
|
||||
<label>Whether Folder View icons are locked or not. Only used when serving as containment.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="sortMode" type="Int">
|
||||
<label>How Folder View icons are sorted: 0 = Unsorted, 1 = Name, 2 = Size, 3 = Type, 4 = Date</label>
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="sortDesc" type="Bool">
|
||||
<label>Whether to sort Folder View icons descending instead of ascending.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="sortDirsFirst" type="Bool">
|
||||
<label>Whether to sort folders before files in Folder View.</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="toolTips" type="Bool">
|
||||
<label>Whether to show info tooltips when hovering Folder View icons.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="selectionMarkers" type="Bool">
|
||||
<label>Whether to show selection markers when hovering Folder View icons.</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="renameInline" type="Bool">
|
||||
<label>Whether to initiate inline renaming when clicking on the text of an already-selected item, while using the systemwide double-click mode.</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="popups" type="Bool">
|
||||
<label>Whether to show a popup preview window for Folder View icons for folders.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="previews" type="Bool">
|
||||
<label>Whether to show preview thumbnails in Folder View.</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="previewPlugins" type="StringList">
|
||||
<label>List of ids of the thumbnail preview plugins to use in Folder View. If empty, uses a default set of thumbnailers (cf. KIO::PreviewJob::defaultPlugins)</label>
|
||||
<default></default>
|
||||
</entry>
|
||||
<entry name="viewMode" type="Int">
|
||||
<label>The Folder View view mode (used only by the widget full representation): 0 = Grid, 1 = List</label>
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="iconSize" type="Int">
|
||||
<label>The icon size to use for Folder View icons. 0 = 22px (smallMedium); 1 = 32px (medium); 2 = 48px (large); 3 = 64px (huge); 4 = 96px (large * 2); 5 = 128px (enormous); 6 = 256px (enormous * 2)</label>
|
||||
<default>3</default>
|
||||
</entry>
|
||||
<entry name="labelWidth" type="Int">
|
||||
<label>The width of the grid cells when using icon view. 0 = Narrow, 1 = Medium, 2 = Wide</label>
|
||||
<default>1</default>
|
||||
</entry>
|
||||
<entry name="textLines" type="Int">
|
||||
<label>The (maximum) number of lines of text to use below Folder View icons.</label>
|
||||
<default>2</default>
|
||||
</entry>
|
||||
<entry name="textColor" type="String">
|
||||
<label>The text color to use below Folder View icons. Only used when serving as containment.</label>
|
||||
<default>white</default>
|
||||
</entry>
|
||||
|
||||
<entry name="filterPattern" type="String">
|
||||
<label>The pattern to filter files by. Supports wildcards.</label>
|
||||
<default>*</default>
|
||||
</entry>
|
||||
<entry name="filterMode" type="Int">
|
||||
<label>The file filter mode: 0 = Show All Files, 1 = Show Files Matching, 2 = Hide Files Matching</label>
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="filterMimeTypes" type="StringList">
|
||||
<label>List of MIME types to filter by.</label>
|
||||
<default>all/all</default>
|
||||
</entry>
|
||||
<entry name="showHiddenFiles" type="Bool">
|
||||
<label>Show hidden files.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="textShadows" type="Bool">
|
||||
<label>Use drop shadows for icon labels on the desktop.</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="iconShadows" type="Bool">
|
||||
<label>Use drop shadows for icons on the desktop.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
</group>
|
||||
</kcfg>
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2011 Marco Martin <mart@kde.org>
|
||||
SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import org.kde.plasma.components 3.0 as PC3
|
||||
|
||||
PC3.ToolButton {
|
||||
id: button
|
||||
|
||||
property QtObject qAction
|
||||
readonly property int iconSize: Kirigami.Settings.hasTransientTouchInput
|
||||
? Kirigami.Units.iconSizes.medium
|
||||
: Kirigami.Units.iconSizes.small
|
||||
|
||||
property alias toolTip: toolTip.text
|
||||
|
||||
onClicked: {
|
||||
if (qAction) {
|
||||
qAction.trigger()
|
||||
}
|
||||
if (!Plasmoid.containment.corona.editMode) {
|
||||
appletContainer.editMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
icon.width: iconSize
|
||||
icon.height: iconSize
|
||||
|
||||
PC3.ToolTip {
|
||||
id: toolTip
|
||||
text: button.qAction ? button.qAction.text : ""
|
||||
delay: 0
|
||||
visible: button.hovered && text.length > 0
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
Kirigami.Theme.inherit: false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2011-2013 Sebastian Kügler <sebas@kde.org>
|
||||
SPDX-FileCopyrightText: 2011 Marco Martin <mart@kde.org>
|
||||
SPDX-FileCopyrightText: 2014-2015 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
|
||||
import org.kde.ksvg 1.0 as KSvg
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents3
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
KSvg.FrameSvgItem {
|
||||
id: upButton
|
||||
|
||||
width: gridView.cellWidth
|
||||
height: visible ? gridView.cellHeight : 0
|
||||
|
||||
visible: history.length !== 0
|
||||
|
||||
property bool ignoreClick: false
|
||||
property bool containsDrag: false
|
||||
|
||||
imagePath: "widgets/viewitem"
|
||||
|
||||
function handleDragMove() {
|
||||
containsDrag = true;
|
||||
hoverActivateTimer.restart();
|
||||
}
|
||||
|
||||
function endDragMove() {
|
||||
containsDrag = false;
|
||||
hoverActivateTimer.stop();
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
acceptedButtons: Qt.LeftButton | Qt.BackButton
|
||||
hoverEnabled: true
|
||||
|
||||
onContainsMouseChanged: {
|
||||
gridView.hoveredItem = null;
|
||||
}
|
||||
|
||||
onPressed: mouse => {
|
||||
if (mouse.buttons & Qt.BackButton) {
|
||||
if (root.isPopup && dir.resolvedUrl !== dir.resolve(Plasmoid.configuration.url)) {
|
||||
doBack();
|
||||
ignoreClick = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: mouse => {
|
||||
if (ignoreClick) {
|
||||
ignoreClick = false;
|
||||
return;
|
||||
}
|
||||
|
||||
doBack();
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
id: icon
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: Kirigami.Units.smallSpacing
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
width: gridView.iconSize
|
||||
height: gridView.iconSize
|
||||
|
||||
source: "arrow-left"
|
||||
}
|
||||
|
||||
PlasmaComponents3.Label {
|
||||
id: label
|
||||
|
||||
anchors {
|
||||
left: icon.right
|
||||
leftMargin: Kirigami.Units.smallSpacing * 2
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
width: parent.width - icon.width - (Kirigami.Units.smallSpacing * 4);
|
||||
|
||||
height: undefined // Unset PlasmaComponents.Label's default.
|
||||
|
||||
textFormat: Text.PlainText
|
||||
|
||||
maximumLineCount: root.isPopup ? 1 : Plasmoid.configuration.textLines
|
||||
wrapMode: Text.Wrap
|
||||
elide: Text.ElideRight
|
||||
|
||||
text: i18n("Back")
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: hoverActivateTimer
|
||||
|
||||
interval: root.hoverActivateDelay
|
||||
|
||||
onTriggered: doBack()
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "hover"
|
||||
when: mouseArea.containsMouse || containsDrag
|
||||
|
||||
PropertyChanges {
|
||||
target: upButton
|
||||
prefix: "hover"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013-2014 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.draganddrop 2.0 as DragDrop
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
DragDrop.DropArea {
|
||||
readonly property bool inPanel: [
|
||||
PlasmaCore.Types.TopEdge,
|
||||
PlasmaCore.Types.LeftEdge,
|
||||
PlasmaCore.Types.RightEdge,
|
||||
PlasmaCore.Types.BottomEdge,
|
||||
].includes(Plasmoid.location)
|
||||
|
||||
Layout.minimumWidth: Plasmoid.formFactor === PlasmaCore.Types.Horizontal ? height : Kirigami.Units.iconSizes.small
|
||||
Layout.minimumHeight: Plasmoid.formFactor === PlasmaCore.Types.Vertical ? width : (Kirigami.Units.iconSizes.small + 2 * Kirigami.Units.iconSizes.sizeForLabels)
|
||||
|
||||
property Item folderView: null
|
||||
|
||||
onContainsDragChanged: contained => {
|
||||
if (containsDrag) {
|
||||
hoverActivateTimer.restart();
|
||||
} else {
|
||||
hoverActivateTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
onDrop: event => {
|
||||
folderView.model.dropCwd(event);
|
||||
}
|
||||
|
||||
preventStealing: true
|
||||
|
||||
function toggle() {
|
||||
root.expanded = !root.expanded;
|
||||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
id: icon
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
active: mouseArea.containsMouse
|
||||
|
||||
source: Plasmoid.configuration.useCustomIcon ? Plasmoid.configuration.icon : folderView.model.iconName
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: mouse => toggle()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: hoverActivateTimer
|
||||
|
||||
interval: root.hoverActivateDelay
|
||||
|
||||
onTriggered: toggle()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.private.desktopcontainment.folder 0.1 as Folder
|
||||
import org.kde.kitemmodels 1.0 as KItemModels
|
||||
|
||||
ColumnLayout {
|
||||
id: configIcons
|
||||
|
||||
property alias cfg_filterMode: filterMode.currentIndex
|
||||
property alias cfg_filterPattern: filterPattern.text
|
||||
property alias cfg_filterMimeTypes: mimeTypesModel.checkedTypes
|
||||
property alias cfg_showHiddenFiles: showHiddenFiles.checked
|
||||
|
||||
KItemModels.KSortFilterProxyModel {
|
||||
id: filteredMimeTypesModel
|
||||
|
||||
sourceModel: Folder.MimeTypesModel {
|
||||
id: mimeTypesModel
|
||||
}
|
||||
|
||||
filterRegularExpression: RegExp(mimeFilter.text, "i")
|
||||
filterRoleName: "name"
|
||||
|
||||
sortRoleName: "name"
|
||||
sortOrder: Qt.AscendingOrder
|
||||
|
||||
function checkFiltered() {
|
||||
var types = [];
|
||||
|
||||
for (var i = 0; i < count; ++i) {
|
||||
types.push(get(i).name);
|
||||
}
|
||||
|
||||
mimeTypesModel.checkedTypes = types;
|
||||
}
|
||||
|
||||
function uncheckFiltered() {
|
||||
var types = [];
|
||||
|
||||
for (var i = 0; i < count; ++i) {
|
||||
types.push(get(i).name);
|
||||
}
|
||||
|
||||
mimeTypesModel.checkedTypes = mimeTypesModel.checkedTypes
|
||||
.filter(x => types.indexOf(x) === -1);
|
||||
}
|
||||
}
|
||||
Kirigami.FormLayout {
|
||||
ComboBox {
|
||||
id: filterMode
|
||||
Kirigami.FormData.label: i18n("Files:")
|
||||
model: [i18n("Show all"), i18n("Show matching"), i18n("Hide matching")]
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: filterPattern
|
||||
Kirigami.FormData.label: i18n("File name pattern:")
|
||||
enabled: (filterMode.currentIndex > 0)
|
||||
inputMethodHints: Qt.ImhNoPredictiveText
|
||||
}
|
||||
|
||||
Kirigami.SearchField {
|
||||
id: mimeFilter
|
||||
Kirigami.FormData.label: i18n("File types:")
|
||||
enabled: (filterMode.currentIndex > 0)
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: showHiddenFiles
|
||||
Kirigami.FormData.label: i18n("Show hidden files:")
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
CheckBox { // Purely for metrics.
|
||||
id: metricsCheckBox
|
||||
visible: false
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
id: scrollView
|
||||
enabled: (filterMode.currentIndex > 0)
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredHeight: 100 // Note: this arbitrary number is a workaround to the layout trying to resize the scrollview to an huge value, the behavior is still correctly stretching
|
||||
|
||||
Component.onCompleted: {
|
||||
if (background) {
|
||||
background.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: ListView {
|
||||
id: mimeTypesView
|
||||
clip: true
|
||||
|
||||
// Signal the delegates listen to when user presses space to toggle current row.
|
||||
signal toggleCurrent()
|
||||
|
||||
|
||||
model: filteredMimeTypesModel
|
||||
property real columnSize: Kirigami.Units.iconSizes.small * 15
|
||||
headerPositioning: ListView.OverlayHeader
|
||||
|
||||
Keys.onSpacePressed: toggleCurrent()
|
||||
|
||||
header: HorizontalHeaderView {
|
||||
id: headerView
|
||||
z: 9
|
||||
implicitWidth: mimeTypesView.width
|
||||
rowHeightProvider: function () {
|
||||
return Kirigami.Units.iconSizes.small * 2
|
||||
}
|
||||
clip: true // This removes event handling blocking by the header
|
||||
model: ListModel {
|
||||
Component.onCompleted: {
|
||||
append({ display: i18n("File Type") });
|
||||
append({ display: i18n("Description") });
|
||||
}
|
||||
}
|
||||
interactive: false
|
||||
columnWidthProvider: function(column) {
|
||||
if (column === 0) {
|
||||
return mimeTypesView.columnSize;
|
||||
} else {
|
||||
return mimeTypesView.width - mimeTypesView.columnSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delegate: ItemDelegate {
|
||||
id: delegate
|
||||
width: mimeTypesView.width
|
||||
required property string name
|
||||
required property string comment
|
||||
required property var decoration
|
||||
|
||||
contentItem: RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Kirigami.Units.iconSizes.small
|
||||
RowLayout {
|
||||
Layout.preferredWidth: mimeTypesView.columnSize
|
||||
Layout.maximumWidth: mimeTypesView.columnSize
|
||||
Layout.fillHeight: true
|
||||
CheckBox {
|
||||
Layout.fillHeight: true
|
||||
checked: mimeTypesModel.checkedTypes.indexOf(name) >= 0
|
||||
onToggled: {
|
||||
let idx = mimeTypesModel.checkedTypes.indexOf(name);
|
||||
if (idx >= 0) {
|
||||
mimeTypesModel.checkedTypes.splice(idx, 1);
|
||||
} else {
|
||||
mimeTypesModel.checkedTypes.push(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
Kirigami.Icon {
|
||||
Layout.fillHeight: true
|
||||
implicitWidth: Kirigami.Units.iconSizes.small
|
||||
implicitHeight: Kirigami.Units.iconSizes.small
|
||||
animated: false // TableView re-uses delegates, avoid animation when sorting/filtering.
|
||||
source: decoration
|
||||
}
|
||||
Label {
|
||||
text: name
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
Label {
|
||||
text: comment
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: selectLayout
|
||||
Button {
|
||||
id: selectAllButton
|
||||
enabled: (filterMode.currentIndex > 0)
|
||||
icon.name: "edit-select-all"
|
||||
ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
ToolTip.visible: (Kirigami.Settings.isMobile ? pressed : hovered) && ToolTip.text.length > 0
|
||||
ToolTip.text: i18n("Select All")
|
||||
onClicked: filteredMimeTypesModel.checkFiltered()
|
||||
}
|
||||
|
||||
Button {
|
||||
id: deselectAllButton
|
||||
enabled: (filterMode.currentIndex > 0)
|
||||
icon.name: "edit-select-none"
|
||||
ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
ToolTip.visible: (Kirigami.Settings.isMobile ? pressed : hovered) && ToolTip.text.length > 0
|
||||
ToolTip.text: i18n("Deselect All")
|
||||
onClicked: filteredMimeTypesModel.uncheckFiltered()
|
||||
}
|
||||
|
||||
Button {
|
||||
enabled: (filterMode.currentIndex > 0)
|
||||
icon.name: filteredMimeTypesModel.sortOrder === Qt.AscendingOrder ? "view-sort-ascending-symbolic" : "view-sort-descending-symbolic"
|
||||
ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
ToolTip.visible: (Kirigami.Settings.isMobile ? pressed : hovered) && ToolTip.text.length > 0
|
||||
ToolTip.text: i18n("Switch Sort Order")
|
||||
onClicked: {
|
||||
filteredMimeTypesModel.sortOrder = filteredMimeTypesModel.sortOrder === Qt.AscendingOrder ? Qt.DescendingOrder : Qt.AscendingOrder;
|
||||
filteredMimeTypesModel.sort(0, filteredMimeTypesModel.sortOrder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,370 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014 Eike Hein <hein@kde.org>
|
||||
SPDX-FileCopyrightText: 2015 Kai Uwe Broulik <kde@privat.broulik.de>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||
import org.kde.iconthemes as KIconThemes
|
||||
import org.kde.config // for KAuthorized
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
import org.kde.private.desktopcontainment.folder 0.1 as Folder
|
||||
|
||||
Item {
|
||||
id: configIcons
|
||||
|
||||
property bool isPopup: (Plasmoid.location !== PlasmaCore.Types.Floating)
|
||||
|
||||
property string cfg_icon: Plasmoid.configuration.icon
|
||||
property alias cfg_useCustomIcon: useCustomIcon.checked
|
||||
property alias cfg_arrangement: arrangement.currentIndex
|
||||
property alias cfg_alignment: alignment.currentIndex
|
||||
property bool cfg_locked
|
||||
property alias cfg_sortMode: sortMode.mode
|
||||
property alias cfg_sortDesc: sortDesc.checked
|
||||
property alias cfg_sortDirsFirst: sortDirsFirst.checked
|
||||
property alias cfg_toolTips: toolTips.checked
|
||||
property alias cfg_selectionMarkers: selectionMarkers.checked
|
||||
property alias cfg_renameInline: renameInline.checked
|
||||
property alias cfg_popups: popups.checked
|
||||
property alias cfg_previews: previews.checked
|
||||
property var cfg_previewPlugins
|
||||
property alias cfg_viewMode: viewMode.currentIndex
|
||||
property alias cfg_iconSize: iconSize.value
|
||||
property alias cfg_labelWidth: labelWidth.currentIndex
|
||||
property alias cfg_textLines: textLines.value
|
||||
|
||||
property alias cfg_textShadows: textShadows.checked
|
||||
property alias cfg_iconShadows: iconShadows.checked
|
||||
|
||||
|
||||
readonly property bool lockedByKiosk: !KAuthorized.authorize("editable_desktop_icons")
|
||||
|
||||
KIconThemes.IconDialog {
|
||||
id: iconDialog
|
||||
onIconNameChanged: cfg_icon = iconName || "folder-symbolic";
|
||||
}
|
||||
|
||||
Kirigami.FormLayout {
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
// Panel button
|
||||
RowLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
visible: isPopup
|
||||
|
||||
Kirigami.FormData.label: i18n("Panel button:")
|
||||
|
||||
CheckBox {
|
||||
id: useCustomIcon
|
||||
visible: isPopup
|
||||
checked: cfg_useCustomIcon
|
||||
text: i18n("Use a custom icon")
|
||||
}
|
||||
|
||||
Button {
|
||||
id: iconButton
|
||||
Layout.minimumWidth: Kirigami.Units.iconSizes.large + Kirigami.Units.smallSpacing * 2
|
||||
Layout.maximumWidth: Layout.minimumWidth
|
||||
Layout.minimumHeight: Layout.minimumWidth
|
||||
Layout.maximumHeight: Layout.minimumWidth
|
||||
|
||||
checkable: true
|
||||
enabled: useCustomIcon.checked
|
||||
|
||||
onClicked: {
|
||||
checked = Qt.binding(() =>
|
||||
iconMenu.status === PlasmaExtras.Menu.Open);
|
||||
|
||||
iconMenu.open(0, height);
|
||||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
anchors.centerIn: parent
|
||||
width: Kirigami.Units.iconSizes.large
|
||||
height: width
|
||||
source: cfg_icon
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaExtras.Menu {
|
||||
id: iconMenu
|
||||
visualParent: iconButton
|
||||
|
||||
PlasmaExtras.MenuItem {
|
||||
text: i18nc("@item:inmenu Open icon chooser dialog", "Choose…")
|
||||
icon: "document-open-folder"
|
||||
onClicked: iconDialog.open()
|
||||
}
|
||||
|
||||
PlasmaExtras.MenuItem {
|
||||
text: i18nc("@item:inmenu Reset icon to default", "Clear Icon")
|
||||
icon: "edit-clear"
|
||||
onClicked: cfg_icon = "folder-symbolic";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
visible: isPopup
|
||||
Kirigami.FormData.isSection: true
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Arrangement section
|
||||
ComboBox {
|
||||
id: arrangement
|
||||
Layout.fillWidth: true
|
||||
visible: !isPopup || viewMode.currentIndex === 1 /* Icons mode */
|
||||
|
||||
Kirigami.FormData.label: i18n("Arrangement:")
|
||||
|
||||
model: [
|
||||
Qt.application.layoutDirection === Qt.LeftToRight ?
|
||||
i18nc("@item:inlistbox arrangement of icons", "Left to Right") :
|
||||
i18nc("@item:inlistbox arrangement of icons", "Right to Left"),
|
||||
i18nc("@item:inlistbox arrangement of icons", "Top to Bottom"),
|
||||
]
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: alignment
|
||||
Layout.fillWidth: true
|
||||
visible: !isPopup || viewMode.currentIndex === 1 /* Icons mode */
|
||||
|
||||
model: [i18nc("@item:inlistbox alignment of icons", "Align left"),
|
||||
i18nc("@item:inlistbox alignment of icons", "Align right")]
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: locked
|
||||
visible: ("containmentType" in plasmoid)
|
||||
checked: cfg_locked || lockedByKiosk
|
||||
enabled: !lockedByKiosk
|
||||
|
||||
onCheckedChanged: {
|
||||
if (!lockedByKiosk) {
|
||||
cfg_locked = checked;
|
||||
}
|
||||
}
|
||||
|
||||
text: i18n("Lock in place")
|
||||
}
|
||||
|
||||
Item {
|
||||
Kirigami.FormData.isSection: true
|
||||
visible: !isPopup || viewMode.currentIndex === 1 /* Icons mode */
|
||||
}
|
||||
|
||||
|
||||
// Sorting section
|
||||
ComboBox {
|
||||
id: sortMode
|
||||
Layout.fillWidth: true
|
||||
|
||||
Kirigami.FormData.label: i18n("Sorting:")
|
||||
|
||||
property int mode
|
||||
// FIXME TODO HACK: This maps the combo box list model to the KDirModel::ModelColumns
|
||||
// enum, which should be done in C++.
|
||||
property var indexToMode: [-1, 0, 1, 6, 2]
|
||||
property var modeToIndex: {'-1': '0', '0': '1', '1': '2', '6': '3', '2': '4'}
|
||||
|
||||
model: [i18nc("@item:inlistbox sort icons manually", "Manual"),
|
||||
i18nc("@item:inlistbox sort icons by name", "Name"),
|
||||
i18nc("@item:inlistbox sort icons by size", "Size"),
|
||||
i18nc("@item:inlistbox sort icons by file type", "Type"),
|
||||
i18nc("@item:inlistbox sort icons by date", "Date")]
|
||||
|
||||
Component.onCompleted: currentIndex = modeToIndex[mode]
|
||||
onActivated: mode = indexToMode[index]
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: sortDesc
|
||||
|
||||
enabled: sortMode.currentIndex !== 0
|
||||
|
||||
text: i18nc("@option:check sort icons in descending order", "Descending")
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: sortDirsFirst
|
||||
|
||||
enabled: sortMode.currentIndex !== 0
|
||||
|
||||
text: i18nc("@option:check sort icons with folders first", "Folders first")
|
||||
}
|
||||
|
||||
Item {
|
||||
Kirigami.FormData.isSection: true
|
||||
}
|
||||
|
||||
|
||||
// View Mode section (only if we're a pop-up)
|
||||
ComboBox {
|
||||
id: viewMode
|
||||
visible: isPopup
|
||||
Layout.fillWidth: true
|
||||
|
||||
Kirigami.FormData.label: i18nc("whether to use icon or list view", "View mode:")
|
||||
|
||||
model: [i18nc("@item:inlistbox show icons in a list", "List"),
|
||||
i18nc("@item:inlistbox show icons in a grid", "Grid")]
|
||||
}
|
||||
|
||||
|
||||
// Size section
|
||||
Slider {
|
||||
id: iconSize
|
||||
|
||||
Layout.fillWidth: true
|
||||
visible: !isPopup || viewMode.currentIndex === 1 /* Icons mode */
|
||||
|
||||
Kirigami.FormData.label: i18n("Icon size:")
|
||||
|
||||
from: 0
|
||||
to: 6
|
||||
stepSize: 1
|
||||
snapMode: Slider.SnapAlways
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
visible: !isPopup || viewMode.currentIndex === 1 /* Icons mode */
|
||||
|
||||
text: i18nc("@label:slider smallest icon size", "Small")
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
visible: !isPopup || viewMode.currentIndex === 1 /* Icons mode */
|
||||
|
||||
text: i18nc("@label:slider largest icon size", "Large")
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: labelWidth
|
||||
visible: !isPopup || viewMode.currentIndex === 1 /* Icons mode */
|
||||
Layout.fillWidth: true
|
||||
|
||||
Kirigami.FormData.label: i18n("Label width:")
|
||||
|
||||
model: [
|
||||
i18nc("@item:inlistbox how long a text label should be", "Narrow"),
|
||||
i18nc("@item:inlistbox how long a text label should be", "Medium"),
|
||||
i18nc("@item:inlistbox how long a text label should be", "Wide"),
|
||||
]
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: textLines
|
||||
visible: !isPopup || viewMode.currentIndex === 1 /* Icons mode */
|
||||
|
||||
Kirigami.FormData.label: i18n("Text lines:")
|
||||
|
||||
from: 1
|
||||
to: 10
|
||||
stepSize: 1
|
||||
}
|
||||
|
||||
Item {
|
||||
Kirigami.FormData.isSection: true
|
||||
}
|
||||
|
||||
|
||||
// Features section
|
||||
CheckBox {
|
||||
id: toolTips
|
||||
|
||||
Kirigami.FormData.label: i18n("When hovering over icons:")
|
||||
|
||||
text: i18n("Show tooltips")
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: selectionMarkers
|
||||
visible: Qt.styleHints.singleClickActivation
|
||||
|
||||
text: i18n("Show selection markers")
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: popups
|
||||
visible: !isPopup
|
||||
|
||||
text: i18n("Show folder preview popups")
|
||||
}
|
||||
|
||||
Item {
|
||||
Kirigami.FormData.isSection: true
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: renameInline
|
||||
|
||||
Kirigami.FormData.label: i18n("Rename:")
|
||||
|
||||
visible: !selectionMarkers.visible
|
||||
|
||||
text: i18n("Rename inline by clicking selected item's text")
|
||||
}
|
||||
|
||||
Item {
|
||||
Kirigami.FormData.isSection: true
|
||||
visible: renameInline.visible
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: textShadows
|
||||
text: i18n("Use drop shadows for icon labels on the desktop")
|
||||
}
|
||||
CheckBox {
|
||||
id: iconShadows
|
||||
text: i18n("Use drop shadows for icons on the desktop")
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: previews
|
||||
|
||||
Kirigami.FormData.label: i18n("Previews:")
|
||||
|
||||
text: i18n("Show preview thumbnails")
|
||||
}
|
||||
|
||||
Button {
|
||||
id: previewSettings
|
||||
Layout.fillWidth: true
|
||||
|
||||
icon.name: "configure"
|
||||
text: i18n("Configure Preview Plugins…")
|
||||
|
||||
onClicked: {
|
||||
const component = Qt.createComponent(Qt.resolvedUrl("FolderItemPreviewPluginsDialog.qml"));
|
||||
component.incubateObject(configIcons.Window.window.contentItem, {
|
||||
"previewPlugins": configIcons.cfg_previewPlugins,
|
||||
}, Qt.Asynchronous);
|
||||
component.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
import org.kde.private.desktopcontainment.folder 0.1 as Folder
|
||||
|
||||
Item {
|
||||
id: configLocation
|
||||
|
||||
property string cfg_url
|
||||
property alias cfg_labelMode: labelMode.currentIndex
|
||||
property alias cfg_labelText: labelText.text
|
||||
property bool titleVisible: !("containmentType" in plasmoid)
|
||||
|
||||
onCfg_urlChanged: applyConfig()
|
||||
|
||||
function applyConfig(force) {
|
||||
if (!force && locationGroup.checkedButton !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cfg_url === "desktop:/") {
|
||||
locationDesktop.checked = true;
|
||||
locationCustomValue.text = "";
|
||||
} else if (cfg_url === "activities:/current/") {
|
||||
locationCurrentActivity.checked = true;
|
||||
locationCustomValue.text = "";
|
||||
} else {
|
||||
var placeForUrl = placesModel.indexForUrl(cfg_url);
|
||||
|
||||
if (placeForUrl !== -1) {
|
||||
locationPlace.checked = true;
|
||||
locationPlaceValue.currentIndex = placeForUrl;
|
||||
locationCustomValue.text = "";
|
||||
} else {
|
||||
locationCustom.checked = true;
|
||||
locationCustomValue.text = cfg_url;
|
||||
}
|
||||
}
|
||||
|
||||
locationPlaceValue.enabled = locationPlace.checked;
|
||||
}
|
||||
|
||||
Folder.PlacesModel {
|
||||
id: placesModel
|
||||
showDesktopEntry: false
|
||||
|
||||
onPlacesChanged: applyConfig(true)
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: locationGroup
|
||||
|
||||
buttons: [locationDesktop, locationCurrentActivity, locationPlace, locationCustom]
|
||||
|
||||
onCheckedButtonChanged: {
|
||||
if (checkedButton === locationDesktop) {
|
||||
cfg_url = "desktop:/";
|
||||
} else if (checkedButton === locationCurrentActivity) {
|
||||
cfg_url = "activities:/current/";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.FormLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
RadioButton {
|
||||
id: locationDesktop
|
||||
|
||||
Kirigami.FormData.label: i18n("Show:")
|
||||
|
||||
text: i18n("Desktop folder")
|
||||
}
|
||||
|
||||
RadioButton {
|
||||
id: locationCurrentActivity
|
||||
visible: placesModel.activityLinkingEnabled
|
||||
|
||||
text: i18n("Files linked to the current activity")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
RadioButton {
|
||||
id: locationPlace
|
||||
|
||||
text: i18n("Places panel item:")
|
||||
|
||||
onCheckedChanged: {
|
||||
locationPlaceValue.enabled = checked;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: locationPlaceValue
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
model: placesModel
|
||||
textRole: "display"
|
||||
|
||||
enabled: true
|
||||
|
||||
onEnabledChanged: {
|
||||
if (enabled && currentIndex !== -1) {
|
||||
cfg_url = placesModel.urlForIndex(currentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
onActivated: {
|
||||
cfg_url = placesModel.urlForIndex(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
RadioButton {
|
||||
id: locationCustom
|
||||
|
||||
text: i18n("Custom location:")
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: locationCustomValue
|
||||
enabled: locationCustom.checked
|
||||
Layout.fillWidth: true
|
||||
|
||||
placeholderText: i18n("Type path or URL…")
|
||||
|
||||
inputMethodHints: Qt.ImhNoPredictiveText
|
||||
|
||||
onEnabledChanged: {
|
||||
if (enabled && text !== "") {
|
||||
cfg_url = text;
|
||||
}
|
||||
}
|
||||
|
||||
onTextChanged: {
|
||||
if (enabled) {
|
||||
cfg_url = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
Button {
|
||||
icon.name: "document-open"
|
||||
|
||||
enabled: locationCustom.checked
|
||||
|
||||
onClicked: {
|
||||
directoryPicker.open();
|
||||
}
|
||||
}
|
||||
Folder.DirectoryPicker {
|
||||
id: directoryPicker
|
||||
|
||||
onUrlChanged: {
|
||||
locationCustomValue.text = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
visible: titleVisible
|
||||
Kirigami.FormData.isSection: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: labelMode
|
||||
visible: titleVisible
|
||||
|
||||
Kirigami.FormData.label: i18n("Title:")
|
||||
|
||||
model: [i18n("None"), i18n("Default"), i18n("Full path"), i18n("Custom title")]
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: titleVisible
|
||||
|
||||
Item {
|
||||
width: Kirigami.Units.iconSizes.small
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: labelText
|
||||
Layout.fillWidth: true
|
||||
enabled: (labelMode.currentIndex === 3)
|
||||
|
||||
placeholderText: i18n("Enter custom title…")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import org.kde.ksvg 1.0 as KSvg
|
||||
|
||||
|
||||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
||||
|
||||
ContainmentLayoutManager.ConfigOverlayWithHandles {
|
||||
id: overlay
|
||||
|
||||
SequentialAnimation {
|
||||
id: removeAnim
|
||||
|
||||
NumberAnimation {
|
||||
target: overlay.itemContainer
|
||||
property: "scale"
|
||||
from: 1
|
||||
to: 0
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
ScriptAction {
|
||||
script: {
|
||||
appletContainer.applet.plasmoid.internalAction("remove").trigger();
|
||||
appletContainer.editMode = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KSvg.FrameSvgItem {
|
||||
id: frame
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
x: overlay.rightAvailableSpace > width + Kirigami.Units.iconSizes.small
|
||||
? parent.width + Kirigami.Units.iconSizes.small
|
||||
: -width - Kirigami.Units.iconSizes.small
|
||||
|
||||
// This MouseArea is used to block input between the applet and the handle, to not make it steal by other applets
|
||||
MouseArea {
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
z: -1
|
||||
x: overlay.rightAvailableSpace > parent.width + Kirigami.Units.iconSizes.small ? -Kirigami.Units.iconSizes.small : 0
|
||||
width: Kirigami.Units.iconSizes.small + parent.width
|
||||
hoverEnabled: true
|
||||
}
|
||||
transform: Translate {
|
||||
x: open ? 0 : (overlay.rightAvailableSpace > frame.width + Kirigami.Units.iconSizes.small ? -frame.width : frame.width)
|
||||
|
||||
Behavior on x {
|
||||
NumberAnimation {
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
width: layout.implicitWidth + margins.left + margins.right
|
||||
height: Math.max(layout.implicitHeight + margins.top + margins.bottom, parent.height)
|
||||
imagePath: "widgets/background"
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors {
|
||||
fill: parent
|
||||
topMargin: parent.margins.top
|
||||
leftMargin: parent.margins.left
|
||||
bottomMargin: parent.margins.bottom
|
||||
rightMargin: parent.margins.right
|
||||
}
|
||||
|
||||
ActionButton {
|
||||
id: rotateButton
|
||||
icon.name: "object-rotate-left-symbolic"
|
||||
toolTip: !rotateHandle.pressed ? i18n("Click and drag to rotate") : ""
|
||||
action: applet ? applet.plasmoid.internalAction("rotate") : null
|
||||
down: rotateHandle.pressed
|
||||
Component.onCompleted: {
|
||||
if (action !== null) {
|
||||
action.enabled = true;
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
id: rotateHandle
|
||||
anchors.fill: parent
|
||||
|
||||
property int startRotation
|
||||
property real startCenterRelativeAngle
|
||||
|
||||
function pointAngle(pos: point): real {
|
||||
var r = Math.sqrt(pos.x * pos.x + pos.y * pos.y);
|
||||
var cosine = pos.x / r;
|
||||
|
||||
if (pos.y >= 0) {
|
||||
return Math.acos(cosine) * (180/Math.PI);
|
||||
} else {
|
||||
return -Math.acos(cosine) * (180/Math.PI);
|
||||
}
|
||||
}
|
||||
|
||||
function centerRelativePos(x: real, y: real): point {
|
||||
var mousePos = overlay.itemContainer.parent.mapFromItem(rotateButton, x, y);
|
||||
var centerPos = overlay.itemContainer.parent.mapFromItem(overlay.itemContainer, overlay.itemContainer.width/2, overlay.itemContainer.height/2);
|
||||
|
||||
mousePos.x -= centerPos.x;
|
||||
mousePos.y -= centerPos.y;
|
||||
return mousePos;
|
||||
}
|
||||
|
||||
onPressed: mouse => {
|
||||
mouse.accepted = true;
|
||||
startRotation = overlay.itemContainer.rotation;
|
||||
startCenterRelativeAngle = pointAngle(centerRelativePos(mouse.x, mouse.y));
|
||||
}
|
||||
|
||||
onPositionChanged: mouse => {
|
||||
var rot = startRotation % 360;
|
||||
var snap = 4;
|
||||
var newRotation = Math.round(pointAngle(centerRelativePos(mouse.x, mouse.y)) - startCenterRelativeAngle + startRotation);
|
||||
|
||||
if (newRotation < 0) {
|
||||
newRotation = newRotation + 360;
|
||||
} else if (newRotation >= 360) {
|
||||
newRotation = newRotation % 360;
|
||||
}
|
||||
|
||||
snapIt(0);
|
||||
snapIt(90);
|
||||
snapIt(180);
|
||||
snapIt(270);
|
||||
|
||||
function snapIt(snapTo) {
|
||||
if (newRotation > (snapTo - snap) && newRotation < (snapTo + snap)) {
|
||||
newRotation = snapTo;
|
||||
}
|
||||
}
|
||||
|
||||
overlay.itemContainer.rotation = newRotation;
|
||||
}
|
||||
|
||||
onReleased: mouse => {
|
||||
// save rotation
|
||||
appletsLayout.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ActionButton {
|
||||
icon.name: "configure"
|
||||
visible: qAction && qAction.enabled && (applet && applet.plasmoid.hasConfigurationInterface)
|
||||
qAction: applet ? applet.plasmoid.internalAction("configure") : null
|
||||
Component.onCompleted: {
|
||||
if (qAction) {
|
||||
qAction.enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ActionButton {
|
||||
// FIXME: missing from Breeze icons! See
|
||||
// https://bugs.kde.org/show_bug.cgi?id=472863.
|
||||
icon.name: "showbackground"
|
||||
toolTip: checked ? i18n("Hide Background") : i18n("Show Background")
|
||||
visible: (applet.plasmoid.backgroundHints & PlasmaCore.Types.ConfigurableBackground)
|
||||
checked: applet.plasmoid.effectiveBackgroundHints & PlasmaCore.Types.StandardBackground || applet.plasmoid.effectiveBackgroundHints & PlasmaCore.Types.TranslucentBackground
|
||||
checkable: true
|
||||
onClicked: {
|
||||
if (checked) {
|
||||
if (applet.plasmoid.backgroundHints & PlasmaCore.Types.StandardBackground || applet.plasmoid.backgroundHints & PlasmaCore.Types.TranslucentBackground) {
|
||||
applet.plasmoid.userBackgroundHints = applet.plasmoid.backgroundHints;
|
||||
} else {
|
||||
applet.plasmoid.userBackgroundHints = PlasmaCore.Types.StandardBackground;
|
||||
}
|
||||
} else {
|
||||
if (applet.plasmoid.backgroundHints & PlasmaCore.Types.ShadowBackground || applet.plasmoid.backgroundHints & PlasmaCore.Types.NoBackground) {
|
||||
applet.plasmoid.userBackgroundHints = applet.plasmoid.backgroundHints;
|
||||
} else {
|
||||
applet.plasmoid.userBackgroundHints = PlasmaCore.Types.ShadowBackground;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
drag.target: overlay.itemContainer
|
||||
Layout.minimumHeight: Kirigami.Units.iconSizes.small * 3
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
cursorShape: containsPress ? Qt.DragMoveCursor : Qt.OpenHandCursor
|
||||
hoverEnabled: true
|
||||
onPressed: mouse => {
|
||||
appletsLayout.releaseSpace(overlay.itemContainer);
|
||||
}
|
||||
onPositionChanged: mouse => {
|
||||
if (!pressed) {
|
||||
return;
|
||||
}
|
||||
appletsLayout.showPlaceHolderForItem(overlay.itemContainer);
|
||||
var dragPos = mapToItem(overlay.itemContainer, mouse.x, mouse.y);
|
||||
overlay.itemContainer.userDrag(Qt.point(overlay.itemContainer.x, overlay.itemContainer.y), dragPos);
|
||||
}
|
||||
onReleased: mouse => {
|
||||
appletsLayout.hidePlaceHolder();
|
||||
appletsLayout.positionItem(overlay.itemContainer);
|
||||
}
|
||||
}
|
||||
|
||||
ActionButton {
|
||||
id: closeButton
|
||||
icon.name: "edit-delete-remove"
|
||||
toolTip: i18n("Remove")
|
||||
visible: {
|
||||
if (!applet) {
|
||||
return false;
|
||||
}
|
||||
var a = applet.plasmoid.internalAction("remove");
|
||||
return a && a.enabled || false;
|
||||
}
|
||||
// we don't set action, since we want to catch the button click,
|
||||
// animate, and then trigger the "remove" action
|
||||
// Triggering the action is handled in the overlay.itemContainer, we just
|
||||
// Q_EMIT a signal here to avoid the applet-gets-removed-before-we-
|
||||
// can-animate it race condition.
|
||||
onClicked: {
|
||||
removeAnim.restart();
|
||||
}
|
||||
Component.onCompleted: {
|
||||
var a = applet.plasmoid.internalAction("remove");
|
||||
if (a) {
|
||||
a.enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import org.kde.ksvg 1.0 as KSvg
|
||||
|
||||
KSvg.SvgItem {
|
||||
id: actionButton
|
||||
|
||||
width: {
|
||||
if (!visible) {
|
||||
return 0;
|
||||
}
|
||||
switch (Plasmoid.configuration.iconSize) {
|
||||
case 0: return Kirigami.Units.iconSizes.small;
|
||||
case 1: return Kirigami.Units.iconSizes.small;
|
||||
case 2: return Kirigami.Units.iconSizes.smallMedium;
|
||||
case 3: return Kirigami.Units.iconSizes.smallMedium;
|
||||
case 4: return Kirigami.Units.iconSizes.smallMedium;
|
||||
case 5: return Kirigami.Units.iconSizes.medium;
|
||||
case 6: return Kirigami.Units.iconSizes.large;
|
||||
default: return Kirigami.Units.iconSizes.small;
|
||||
}
|
||||
}
|
||||
height: width
|
||||
|
||||
signal clicked()
|
||||
|
||||
property string element
|
||||
|
||||
svg: KSvg.Svg {
|
||||
imagePath: "widgets/action-overlays"
|
||||
multipleImages: true
|
||||
size: "16x16"
|
||||
}
|
||||
elementId: element + "-normal"
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: Kirigami.Units.shortDuration }
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: actionButtonMouseArea
|
||||
|
||||
anchors.fill: actionButton
|
||||
|
||||
acceptedButtons: Qt.LeftButton
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: mouse => actionButton.clicked()
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "hover"
|
||||
when: actionButtonMouseArea.containsMouse && !actionButtonMouseArea.pressed
|
||||
|
||||
PropertyChanges {
|
||||
target: actionButton
|
||||
elementId: actionButton.element + "-hover"
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "pressed"
|
||||
when: actionButtonMouseArea.pressed
|
||||
|
||||
PropertyChanges {
|
||||
target: actionButton
|
||||
elementId: actionButton.element + "-pressed"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,517 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014-2015 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Window 2.15
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.extras as PlasmaExtras
|
||||
import org.kde.plasma.components as PlasmaComponents
|
||||
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import org.kde.ksvg 1.0 as KSvg
|
||||
import org.kde.kquickcontrolsaddons 2.0
|
||||
|
||||
Item {
|
||||
id: main
|
||||
|
||||
property int index: model.index
|
||||
property string name: model.blank ? "" : model.display
|
||||
property string nameWrapped: model.blank ? "" : model.displayWrapped
|
||||
property bool blank: model.blank
|
||||
property bool isDir: loader.item ? loader.item.isDir : false
|
||||
property QtObject popupDialog: loader.item ? loader.item.popupDialog : null
|
||||
property Item iconArea: loader.item ? loader.item.iconArea : null
|
||||
property Item label: loader.item ? loader.item.label : null
|
||||
property Item labelArea: loader.item ? loader.item.labelArea : null
|
||||
property Item actionsOverlay: loader.item ? loader.item.actionsOverlay : null
|
||||
property Item hoverArea: loader.item ? loader.item.hoverArea : null
|
||||
property Item frame: loader.item ? loader.item.frame : null
|
||||
property Item toolTip: loader.item ? loader.item.toolTip : null
|
||||
Accessible.name: name
|
||||
Accessible.role: Accessible.Canvas
|
||||
|
||||
// This MouseArea exists to intercept press and hold; preventing edit mode
|
||||
// from being triggered when pressing and holding on an icon (if there is one).
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
visible: !main.blank
|
||||
}
|
||||
|
||||
function openPopup() {
|
||||
if (isDir) {
|
||||
loader.item.openPopup();
|
||||
}
|
||||
}
|
||||
|
||||
function closePopup() {
|
||||
if (popupDialog) {
|
||||
popupDialog.requestDestroy();
|
||||
loader.item.popupDialog = null;
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
|
||||
// On the desktop we pad our cellSize to avoid a gap at the right/bottom of the screen.
|
||||
// The padding per item is quite small and causes the delegate to be positioned on fractional pixels
|
||||
// leading to blurry rendering. The Loader is offset to account for this.
|
||||
x: -main.x % 1
|
||||
y: -main.y % 1
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
visible: status === Loader.Ready
|
||||
|
||||
active: !model.blank
|
||||
|
||||
sourceComponent: delegateImplementation
|
||||
|
||||
asynchronous: true
|
||||
}
|
||||
|
||||
Component {
|
||||
id: delegateImplementation
|
||||
|
||||
Item {
|
||||
id: impl
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
property bool blank: model.blank
|
||||
property bool selected: model.blank ? false : model.selected
|
||||
property bool isDir: model.blank ? false : model.isDir
|
||||
property bool hovered: (main.GridView.view.hoveredItem === main)
|
||||
property QtObject popupDialog: null
|
||||
property Item iconArea: icon
|
||||
property Item label: label
|
||||
property Item labelArea: label
|
||||
property Item actionsOverlay: actions
|
||||
property Item hoverArea: toolTip
|
||||
property Item frame: frameLoader
|
||||
property Item toolTip: toolTip
|
||||
property Item selectionButton: null
|
||||
property Item popupButton: null
|
||||
|
||||
readonly property bool iconAndLabelsShouldlookSelected: impl.hovered
|
||||
|
||||
// When a drop happens, a new item is created, and is set to selected
|
||||
// grabToImagebefore it gets the final width, making grabToImage fail because it's still 0x0
|
||||
onSelectedChanged: Qt.callLater(updateDragImage)
|
||||
function updateDragImage() {
|
||||
if (selected && !blank) {
|
||||
frameLoader.grabToImage(result => {
|
||||
dir.addItemDragImage(positioner.map(index), main.x + frameLoader.x, main.y + frameLoader.y, frameLoader.width, frameLoader.height, result.image);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: model
|
||||
|
||||
function onSelectedChanged() {
|
||||
if (dir.usedByContainment && model.selected) {
|
||||
gridView.currentIndex = model.index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onHoveredChanged: {
|
||||
if (hovered) {
|
||||
// In list view, it behaves more like a menu, and menus always activate their items on a single click
|
||||
if (Plasmoid.configuration.selectionMarkers && (Qt.styleHints.singleClickActivation || root.useListViewMode)) {
|
||||
selectionButton = selectionButtonComponent.createObject(actions);
|
||||
}
|
||||
|
||||
if (model.isDir) {
|
||||
if (!main.GridView.view.isRootView || root.containsDrag) {
|
||||
hoverActivateTimer.restart();
|
||||
}
|
||||
|
||||
if (Plasmoid.configuration.popups && !root.useListViewMode) {
|
||||
popupButton = popupButtonComponent.createObject(actions);
|
||||
}
|
||||
}
|
||||
} else if (!hovered) {
|
||||
if (popupDialog != null) {
|
||||
closePopup();
|
||||
}
|
||||
|
||||
if (selectionButton) {
|
||||
selectionButton.destroy();
|
||||
selectionButton = null;
|
||||
}
|
||||
|
||||
if (popupButton) {
|
||||
popupButton.destroy();
|
||||
popupButton = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function openPopup() {
|
||||
if (folderViewDialogComponent.status === Component.Ready) {
|
||||
impl.popupDialog = folderViewDialogComponent.createObject(impl);
|
||||
impl.popupDialog.visualParent = icon;
|
||||
impl.popupDialog.url = model.linkDestinationUrl;
|
||||
impl.popupDialog.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaCore.ToolTipArea {
|
||||
id: toolTip
|
||||
|
||||
active: (Plasmoid.configuration.toolTips || label.truncated)
|
||||
&& popupDialog === null
|
||||
&& !model.blank
|
||||
interactive: false
|
||||
location: root.useListViewMode ? (Plasmoid.location === PlasmaCore.Types.LeftEdge ? PlasmaCore.Types.LeftEdge : PlasmaCore.Types.RightEdge) : Plasmoid.location
|
||||
z: 999
|
||||
//anchors.fill: parent
|
||||
MouseArea {
|
||||
id: ma
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
propagateComposedEvents: true
|
||||
onPositionChanged: (mouse) => {
|
||||
|
||||
if (containsMouse && !model.blank) {
|
||||
if (toolTip.active) {
|
||||
|
||||
toolTip.textFormat = Text.RichText;
|
||||
toolTip.mainText = model.display;
|
||||
|
||||
if (model.size !== undefined) {
|
||||
toolTip.subText = model.type + "<br>" + "Size: " + model.size;
|
||||
} else {
|
||||
toolTip.subText = model.type;
|
||||
}
|
||||
}
|
||||
|
||||
main.GridView.view.hoveredItem = main;
|
||||
}
|
||||
mouse.accepted = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
states: [
|
||||
State { // icon view
|
||||
when: !root.useListViewMode
|
||||
|
||||
AnchorChanges {
|
||||
target: toolTip
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: toolTip
|
||||
x: Kirigami.Units.smallSpacing
|
||||
y: Kirigami.Units.smallSpacing
|
||||
width: parent.width - Kirigami.Units.smallSpacing
|
||||
height: parent.height - Kirigami.Units.smallSpacing
|
||||
//width: Math.max(icon.paintedWidth, label.paintedWidth)
|
||||
//height: (label.y + label.paintedHeight)
|
||||
//y: frameLoader.y + icon.y
|
||||
//width: Math.max(icon.paintedWidth, label.paintedWidth)
|
||||
//height: (label.y + label.paintedHeight) - y
|
||||
}
|
||||
},
|
||||
State { // list view
|
||||
when: root.useListViewMode
|
||||
|
||||
AnchorChanges {
|
||||
target: toolTip
|
||||
anchors.horizontalCenter: undefined
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: toolTip
|
||||
x: frameLoader.x
|
||||
y: frameLoader.y
|
||||
width: frameLoader.width
|
||||
height: frameLoader.height
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: frameLoader
|
||||
|
||||
x: 0//root.useListViewMode ? 0 : Kirigami.Units.smallSpacing
|
||||
y: root.useListViewMode ? 0 : Kirigami.Units.smallSpacing
|
||||
|
||||
property Item iconShadow: null
|
||||
property string prefix: ""
|
||||
|
||||
sourceComponent: frameComponent
|
||||
active: impl.iconAndLabelsShouldlookSelected || model.selected
|
||||
asynchronous: true
|
||||
|
||||
width: {
|
||||
if (root.useListViewMode) {
|
||||
if (main.GridView.view.overflowing) {
|
||||
return parent.width// - Kirigami.Units.smallSpacing;
|
||||
} else {
|
||||
return parent.width;
|
||||
}
|
||||
}
|
||||
|
||||
return parent.width// - (Kirigami.Units.smallSpacing * 2);
|
||||
}
|
||||
|
||||
height: root.useListViewMode
|
||||
? parent.height
|
||||
// the smallSpacings are for padding
|
||||
: icon.height + (Kirigami.Units.iconSizes.small * label.lineCount) + (Kirigami.Units.smallSpacing * 3)
|
||||
|
||||
Kirigami.Icon {
|
||||
id: icon
|
||||
|
||||
z: 2
|
||||
|
||||
states: [
|
||||
State { // icon view
|
||||
when: !root.useListViewMode
|
||||
|
||||
AnchorChanges {
|
||||
target: icon
|
||||
anchors.top: parent.top
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
},
|
||||
State { // list view
|
||||
when: root.useListViewMode
|
||||
|
||||
AnchorChanges {
|
||||
target: icon
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
anchors {
|
||||
topMargin: Kirigami.Units.smallSpacing
|
||||
leftMargin: Kirigami.Units.smallSpacing
|
||||
}
|
||||
|
||||
width: root.useListViewMode ? main.GridView.view.iconSize : (parent.width - 2 * Kirigami.Units.smallSpacing)
|
||||
height: main.GridView.view.iconSize
|
||||
|
||||
opacity: {
|
||||
if (root.useListViewMode && selectionButton) {
|
||||
return 0.3;
|
||||
}
|
||||
|
||||
if (model.isHidden) {
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
animated: false
|
||||
|
||||
source: model.decoration
|
||||
}
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: label
|
||||
|
||||
z: 2 // So it's always above the highlight effect
|
||||
|
||||
states: [
|
||||
State { // icon view
|
||||
when: !root.useListViewMode
|
||||
|
||||
AnchorChanges {
|
||||
target: label
|
||||
anchors.top: icon.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
PropertyChanges {
|
||||
target: label
|
||||
anchors.topMargin: Kirigami.Units.smallSpacing
|
||||
width: parent.width - Kirigami.Units.smallSpacing
|
||||
maximumLineCount: Plasmoid.configuration.textLines
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
},
|
||||
State { // list view
|
||||
when: root.useListViewMode
|
||||
|
||||
AnchorChanges {
|
||||
target: label
|
||||
anchors.left: icon.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
PropertyChanges {
|
||||
target: label
|
||||
anchors.leftMargin: Kirigami.Units.smallSpacing * 2
|
||||
anchors.rightMargin: Kirigami.Units.smallSpacing * 2
|
||||
width: parent.width - icon.width - (Kirigami.Units.smallSpacing * 4)
|
||||
maximumLineCount: 1
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
color: {
|
||||
if (Plasmoid.isContainment) {
|
||||
// In this situation there's a shadow or a background rect, both of which are always black
|
||||
return "white";
|
||||
}
|
||||
|
||||
if (model.selected) {
|
||||
return Kirigami.Theme.highlightedTextColor;
|
||||
}
|
||||
|
||||
return Kirigami.Theme.textColor;
|
||||
|
||||
}
|
||||
//renderShadow: false //(Plasmoid.isContainment && (!editor || editor.targetItem !== main)) && Plasmoid.configuration.textShadows
|
||||
opacity: model.isHidden ? 0.6 : 1
|
||||
|
||||
text: main.nameWrapped
|
||||
elide: Text.ElideRight
|
||||
//font.italic: model.isLink
|
||||
wrapMode: (maximumLineCount === 1) ? Text.NoWrap : Text.Wrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
anchors.fill: label
|
||||
|
||||
z: 1
|
||||
|
||||
horizontalOffset: 1
|
||||
verticalOffset: 1
|
||||
|
||||
radius: 3.0
|
||||
samples: radius * 2
|
||||
spread: 0.435
|
||||
|
||||
color: "#F9080808"
|
||||
|
||||
opacity: model.isHidden ? 0.6 : 1
|
||||
|
||||
source: label
|
||||
|
||||
visible: (Plasmoid.isContainment && (!editor || editor.targetItem !== main)) && Plasmoid.configuration.textShadows
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: frameComponent
|
||||
|
||||
PlasmaExtras.Highlight {
|
||||
// Workaround for a bug where the frameComponent does not
|
||||
// get unloaded when items are dragged to a different
|
||||
// place on the desktop.
|
||||
visible: this === frameLoader.item
|
||||
hovered: impl.iconAndLabelsShouldlookSelected
|
||||
pressed: model.selected
|
||||
active: Window.active
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: selectionButtonComponent
|
||||
|
||||
FolderItemActionButton {
|
||||
element: model.selected ? "remove" : "add"
|
||||
|
||||
onClicked: {
|
||||
dir.toggleSelected(positioner.map(index));
|
||||
main.GridView.view.currentIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: popupButtonComponent
|
||||
|
||||
FolderItemActionButton {
|
||||
visible: main.GridView.view.isRootView && (popupDialog == null)
|
||||
|
||||
element: "open"
|
||||
|
||||
onClicked: {
|
||||
dir.setSelected(positioner.map(index));
|
||||
main.GridView.view.currentIndex = index;
|
||||
openPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: iconShadowComponent
|
||||
|
||||
DropShadow {
|
||||
anchors.fill: icon
|
||||
|
||||
z: 1
|
||||
|
||||
verticalOffset: 1
|
||||
|
||||
radius: 5.0
|
||||
samples: radius * 2 + 1
|
||||
spread: 0.05
|
||||
|
||||
color: "black"
|
||||
|
||||
opacity: model.isHidden ? 0.3 : 0.6
|
||||
visible: Plasmoid.configuration.iconShadows
|
||||
source: icon
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Column {
|
||||
id: actions
|
||||
|
||||
visible: {
|
||||
if (main.GridView.view.isRootView && root.containsDrag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!main.GridView.view.isRootView && main.GridView.view.dialog && main.GridView.view.dialog.containsDrag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (popupDialog) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
anchors {
|
||||
left: frameLoader.left
|
||||
top: frameLoader.top
|
||||
leftMargin: root.useListViewMode ? (icon.x + (icon.width / 2)) - (width / 2) : 0
|
||||
topMargin: root.useListViewMode ? (icon.y + (icon.height / 2)) - (height / 2) : 0
|
||||
}
|
||||
|
||||
width: implicitWidth
|
||||
height: implicitHeight
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (Plasmoid.isContainment && main.GridView.view.isRootView && root.GraphicsInfo.api === GraphicsInfo.OpenGL) {
|
||||
frameLoader.iconShadow = iconShadowComponent.createObject(frameLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.private.desktopcontainment.folder 0.1 as Folder
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
id: dialog
|
||||
|
||||
required property var previewPlugins
|
||||
|
||||
title: i18n("Preview Plugins")
|
||||
|
||||
onClosed: destroy()
|
||||
|
||||
footer: DialogButtonBox {
|
||||
standardButtons: DialogButtonBox.Ok | DialogButtonBox.Cancel
|
||||
onAccepted: {
|
||||
configIcons.cfg_previewPlugins = previewPluginsModel.checkedPlugins;
|
||||
dialog.close();
|
||||
}
|
||||
onRejected: dialog.close();
|
||||
}
|
||||
|
||||
ListView {
|
||||
implicitWidth: Kirigami.Units.iconSizes.small * 15
|
||||
|
||||
model: Folder.PreviewPluginsModel {
|
||||
id: previewPluginsModel
|
||||
}
|
||||
|
||||
delegate: CheckDelegate {
|
||||
width: ListView.view.width
|
||||
text: model.display
|
||||
|
||||
checked: model.checked
|
||||
onToggled: model.checked = checked;
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
previewPluginsModel.checkedPlugins = dialog.previewPlugins;
|
||||
open();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014-2015 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
import org.kde.private.desktopcontainment.folder 0.1 as Folder
|
||||
|
||||
Folder.SubDialog {
|
||||
id: dialog
|
||||
|
||||
visible: false
|
||||
|
||||
property bool containsDrag: {
|
||||
if (folderViewDropArea.containsDrag) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (folderView.hoveredItem && folderView.hoveredItem.popupDialog) {
|
||||
return folderView.hoveredItem.popupDialog.containsDrag;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
property QtObject closeTimer: closeTimer
|
||||
property QtObject childDialog: (folderView.hoveredItem !== null) ? folderView.hoveredItem.popupDialog : null
|
||||
property bool containsMouse: folderView.containsMouse || (childDialog !== null && childDialog.containsMouse)
|
||||
|
||||
property alias url: folderView.url
|
||||
|
||||
location: PlasmaCore.Types.Floating
|
||||
hideOnWindowDeactivate: (childDialog === null)
|
||||
|
||||
onContainsMouseChanged: {
|
||||
if (containsMouse) {
|
||||
closeTimer.stop();
|
||||
} else {
|
||||
closeTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
mainItem: FolderViewDropArea {
|
||||
id: folderViewDropArea
|
||||
|
||||
width: folderView.cellWidth * 3 + Kirigami.Units.iconSizes.small // FIXME HACK: Use actual scrollbar width.
|
||||
height: folderView.cellHeight * 2
|
||||
|
||||
folderView: folderView
|
||||
|
||||
FolderView {
|
||||
id: folderView
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
isRootView: false
|
||||
dialog: dialog
|
||||
|
||||
locked: true
|
||||
|
||||
sortMode: ((Plasmoid.configuration.sortMode === 0) ? 1 : Plasmoid.configuration.sortMode)
|
||||
filterMode: 0
|
||||
|
||||
// TODO: Bidi.
|
||||
flow: GridView.FlowLeftToRight
|
||||
layoutDirection: Qt.LeftToRight
|
||||
|
||||
onDragInProgressAnywhereChanged: {
|
||||
if (!dragInProgressAnywhere && !dialog.visible) {
|
||||
dialog.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data: [
|
||||
Timer {
|
||||
id: closeTimer
|
||||
|
||||
interval: Kirigami.Units.longDuration * 2
|
||||
|
||||
onTriggered: {
|
||||
if (childDialog !== null) {
|
||||
childDialog.closeTimer.stop();
|
||||
childDialog.visible = false;
|
||||
}
|
||||
|
||||
dialog.visible = false;
|
||||
delayedDestroy();
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
function requestDestroy() {
|
||||
if (folderView.dragInProgressAnywhere) {
|
||||
visible = false;
|
||||
} else {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
function delayedDestroy() {
|
||||
Qt.callLater(() => itemDialog.destroy());
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
closeTimer.stop();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014-2017 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.4
|
||||
|
||||
import org.kde.draganddrop 2.0 as DragDrop
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
DragDrop.DropArea {
|
||||
id: dropArea
|
||||
|
||||
property Item folderView: null
|
||||
|
||||
function handleDragMove(folderView, pos) {
|
||||
// Trigger autoscroll.
|
||||
folderView.scrollLeft = (pos.x < (Kirigami.Units.iconSizes.small * 3));
|
||||
folderView.scrollRight = (pos.x > width - (Kirigami.Units.iconSizes.small * 3));
|
||||
folderView.scrollUp = (pos.y < (Kirigami.Units.iconSizes.small * 3));
|
||||
folderView.scrollDown = (pos.y > height - (Kirigami.Units.iconSizes.small * 3));
|
||||
|
||||
folderView.handleDragMove(pos.x, pos.y);
|
||||
}
|
||||
|
||||
function handleDragEnd(folderView) {
|
||||
// Cancel autoscroll.
|
||||
folderView.scrollLeft = false;
|
||||
folderView.scrollRight = false;
|
||||
folderView.scrollUp = false;
|
||||
folderView.scrollDown = false;
|
||||
|
||||
folderView.endDragMove();
|
||||
}
|
||||
|
||||
onDragMove: event => {
|
||||
// TODO: We should reject drag moves onto file items that don't accept drops
|
||||
// (cf. QAbstractItemModel::flags() here, but DeclarativeDropArea currently
|
||||
// is currently incapable of rejecting drag events.
|
||||
|
||||
if (folderView) {
|
||||
handleDragMove(folderView, mapToItem(folderView, event.x, event.y));
|
||||
}
|
||||
}
|
||||
|
||||
onDragLeave: event => {
|
||||
if (folderView) {
|
||||
handleDragEnd(folderView);
|
||||
}
|
||||
}
|
||||
|
||||
onDrop: event => {
|
||||
if (folderView) {
|
||||
handleDragEnd(folderView);
|
||||
|
||||
folderView.drop(folderView, event, mapToItem(folderView, event.x, event.y));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,429 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014-2015 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQml 2.15
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
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
|
||||
|
||||
import org.kde.private.desktopcontainment.folder 0.1 as Folder
|
||||
|
||||
FocusScope {
|
||||
id: folderViewLayerComponent
|
||||
|
||||
property var sharedActions: ["newMenu", "paste", "undo", "emptyTrash"]
|
||||
property Component folderViewDialogComponent: Qt.createComponent("FolderViewDialog.qml", Qt.Asynchronous, root)
|
||||
|
||||
property Item view: folderView
|
||||
property Item label: null
|
||||
property int labelHeight: Kirigami.Units.iconSizes.sizeForLabels
|
||||
+ (root.isPopup ? (Kirigami.Units.smallSpacing * 2) : 0)
|
||||
|
||||
property alias model: folderView.model
|
||||
property alias overflowing: folderView.overflowing
|
||||
property alias flow: folderView.flow
|
||||
|
||||
property string resolution: Math.round(root.screenGeometry.width) + "x" + Math.round(root.screenGeometry.height)
|
||||
|
||||
readonly property bool lockedByKiosk: !KAuthorized.authorize("editable_desktop_icons")
|
||||
|
||||
focus: true
|
||||
|
||||
function updateContextualActions() {
|
||||
folderView.model.updateActions();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cancelRename() {
|
||||
folderView.cancelRename();
|
||||
}
|
||||
|
||||
function goHome() {
|
||||
if (folderView.url !== Plasmoid.configuration.url) {
|
||||
folderView.url = Qt.binding(() => Plasmoid.configuration.url);
|
||||
folderView.history = [];
|
||||
folderView.updateHistory();
|
||||
}
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: Plasmoid
|
||||
property: "title"
|
||||
value: labelGenerator.displayLabel
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
Folder.LabelGenerator {
|
||||
id: labelGenerator
|
||||
|
||||
folderModel: folderView.model
|
||||
rtl: (Qt.application.layoutDirection === Qt.RightToLeft)
|
||||
labelMode: Plasmoid.configuration.labelMode || (isContainment ? 0 : 1)
|
||||
labelText: Plasmoid.configuration.labelText
|
||||
}
|
||||
|
||||
Folder.ViewPropertiesMenu {
|
||||
id: viewPropertiesMenu
|
||||
|
||||
showLayoutActions: !isPopup
|
||||
showLockAction: isContainment
|
||||
showIconSizeActions: !root.useListViewMode
|
||||
|
||||
lockedEnabled: !lockedByKiosk
|
||||
|
||||
onArrangementChanged: {
|
||||
Plasmoid.configuration.arrangement = arrangement;
|
||||
}
|
||||
|
||||
onAlignmentChanged: {
|
||||
Plasmoid.configuration.alignment = alignment;
|
||||
}
|
||||
|
||||
onPreviewsChanged: {
|
||||
Plasmoid.configuration.previews = previews;
|
||||
}
|
||||
|
||||
onLockedChanged: {
|
||||
if (!lockedByKiosk) {
|
||||
Plasmoid.configuration.locked = locked;
|
||||
}
|
||||
}
|
||||
|
||||
onSortModeChanged: {
|
||||
Plasmoid.configuration.sortMode = sortMode;
|
||||
}
|
||||
|
||||
onSortDescChanged: {
|
||||
Plasmoid.configuration.sortDesc = sortDesc;
|
||||
}
|
||||
|
||||
onSortDirsFirstChanged: {
|
||||
Plasmoid.configuration.sortDirsFirst = sortDirsFirst;
|
||||
}
|
||||
|
||||
onIconSizeChanged: {
|
||||
Plasmoid.configuration.iconSize = iconSize;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaComponents.Label {
|
||||
anchors.fill: parent
|
||||
|
||||
text: folderView.errorString
|
||||
textFormat: Text.PlainText
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
|
||||
function onExpandedChanged() {
|
||||
if (root.isPopup) {
|
||||
if (root.expanded) {
|
||||
folderView.currentIndex = -1;
|
||||
folderView.forceActiveFocus();
|
||||
folderView.positionViewAtBeginning();
|
||||
} else {
|
||||
goHome();
|
||||
|
||||
folderView.currentIndex = -1;
|
||||
folderView.model.clearSelection();
|
||||
folderView.cancelRename();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getPositions() {
|
||||
let allPositions;
|
||||
try {
|
||||
allPositions = JSON.parse(Plasmoid.configuration.positions);
|
||||
} catch (err) {
|
||||
allPositions = {};
|
||||
allPositions[resolution] = Plasmoid.configuration.positions;
|
||||
}
|
||||
return allPositions[resolution] || "";
|
||||
}
|
||||
|
||||
function savePositions(positions) {
|
||||
let allPositions;
|
||||
try {
|
||||
allPositions = JSON.parse(Plasmoid.configuration.positions);
|
||||
} catch (err) {
|
||||
allPositions = {};
|
||||
}
|
||||
allPositions[resolution] = positions;
|
||||
Plasmoid.configuration.positions = JSON.stringify(allPositions, Object.keys(allPositions).sort());
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Plasmoid.configuration
|
||||
|
||||
function onArrangementChanged() {
|
||||
viewPropertiesMenu.arrangement = Plasmoid.configuration.arrangement;
|
||||
}
|
||||
|
||||
function onAlignmentChanged() {
|
||||
viewPropertiesMenu.alignment = Plasmoid.configuration.alignment;
|
||||
}
|
||||
|
||||
function onLockedChanged() {
|
||||
viewPropertiesMenu.locked = Plasmoid.configuration.locked;
|
||||
}
|
||||
|
||||
function onSortModeChanged() {
|
||||
folderView.sortMode = Plasmoid.configuration.sortMode;
|
||||
viewPropertiesMenu.sortMode = Plasmoid.configuration.sortMode;
|
||||
}
|
||||
|
||||
function onSortDescChanged() {
|
||||
viewPropertiesMenu.sortDesc = Plasmoid.configuration.sortDesc;
|
||||
}
|
||||
|
||||
function onSortDirsFirstChanged() {
|
||||
viewPropertiesMenu.sortDirsFirst = Plasmoid.configuration.sortDirsFirst;
|
||||
}
|
||||
|
||||
function onIconSizeChanged() {
|
||||
viewPropertiesMenu.iconSize = Plasmoid.configuration.iconSize;
|
||||
}
|
||||
|
||||
function onPositionsChanged() {
|
||||
folderView.positions = getPositions();
|
||||
}
|
||||
}
|
||||
|
||||
FolderView {
|
||||
id: folderView
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: folderViewLayerComponent.label !== null ? folderViewLayerComponent.label.height : 0
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
focus: true
|
||||
isRootView: true
|
||||
|
||||
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
|
||||
|
||||
flow: (Plasmoid.configuration.arrangement === 0) ? GridView.FlowLeftToRight : GridView.FlowTopToBottom
|
||||
layoutDirection: (Plasmoid.configuration.alignment === 0) ? Qt.LeftToRight : Qt.RightToLeft
|
||||
|
||||
onSortModeChanged: {
|
||||
Plasmoid.configuration.sortMode = sortMode;
|
||||
}
|
||||
|
||||
onPositionsChanged: {
|
||||
saveTimer.restart()
|
||||
}
|
||||
|
||||
onPerStripeChanged: {
|
||||
folderView.positions = getPositions();
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: saveTimer
|
||||
interval: Kirigami.Units.humanMoment
|
||||
onTriggered: savePositions(folderView.positions)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
folderView.sortMode = Plasmoid.configuration.sortMode;
|
||||
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.
|
||||
readonly property bool active: (Plasmoid.configuration.labelMode !== 0)
|
||||
|
||||
readonly property bool showPin: root.isPopup && root.compactRepresentationItem && root.compactRepresentationItem.visible
|
||||
|
||||
width: parent.width
|
||||
height: active ? labelHeight : 0
|
||||
|
||||
visible: active
|
||||
|
||||
property Item windowPin: null
|
||||
property Item homeButton: null
|
||||
|
||||
onVisibleChanged: {
|
||||
if (root.isPopup && !visible) {
|
||||
root.hideOnWindowDeactivate = true;
|
||||
}
|
||||
}
|
||||
|
||||
onShowPinChanged: {
|
||||
if (!windowPin && showPin) {
|
||||
windowPin = windowPinComponent.createObject(label);
|
||||
} else if (windowPin) {
|
||||
windowPin.destroy();
|
||||
windowPin = null;
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: folderView
|
||||
|
||||
function onUrlChanged() {
|
||||
if (!label.homeButton && folderView.url !== Plasmoid.configuration.url) {
|
||||
label.homeButton = homeButtonComponent.createObject(label);
|
||||
} else if (label.homeButton && folderView.url === Plasmoid.configuration.url) {
|
||||
label.homeButton.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: text
|
||||
|
||||
anchors {
|
||||
left: label.homeButton ? label.homeButton.right : parent.left
|
||||
right: label.windowPin ? label.windowPin.left : parent.right
|
||||
margins: Kirigami.Units.smallSpacing
|
||||
}
|
||||
height: parent.height
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignTop
|
||||
elide: Text.ElideMiddle
|
||||
text: labelGenerator.displayLabel
|
||||
textFormat: Text.PlainText
|
||||
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: {
|
||||
Folder.AppLauncher.openUrl(folderView.url)
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: windowPinComponent
|
||||
|
||||
PlasmaComponents.ToolButton {
|
||||
id: windowPin
|
||||
|
||||
anchors.right: parent.right
|
||||
|
||||
visible: label.showPin
|
||||
|
||||
width: root.isPopup ? Math.round(Kirigami.Units.iconSizes.small * 1.25) : 0
|
||||
height: width
|
||||
checkable: true
|
||||
icon.name: "window-pin"
|
||||
onCheckedChanged: root.hideOnWindowDeactivate = !checked
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: homeButtonComponent
|
||||
|
||||
PlasmaComponents.ToolButton {
|
||||
id: homeButton
|
||||
|
||||
anchors.left: parent.left
|
||||
|
||||
visible: root.isPopup && folderView.url !== Plasmoid.configuration.url
|
||||
|
||||
width: root.isPopup ? Math.round(Kirigami.Units.iconSizes.small * 1.25) : 0
|
||||
height: width
|
||||
icon.name: "go-home"
|
||||
|
||||
onClicked: goHome()
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (root.showPin) {
|
||||
windowPin = windowPinComponent.createObject(label);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PlasmaCore.Action {
|
||||
id: viewPropertiesAction
|
||||
text: i18n("Icons")
|
||||
icon.name: "view-list-icons"
|
||||
menu: viewPropertiesMenu.menu
|
||||
}
|
||||
PlasmaCore.Action {
|
||||
id: actionSeparator
|
||||
isSeparator: true
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!isContainment) {
|
||||
label = labelComponent.createObject(folderViewLayerComponent);
|
||||
}
|
||||
|
||||
for (let i = 0, len = sharedActions.length; i < len; i++) {
|
||||
const actionName = sharedActions[i];
|
||||
const modelAction = folderView.model.action(actionName);
|
||||
Plasmoid.contextualActions.push(modelAction)
|
||||
if (actionName === "newMenu") {
|
||||
Plasmoid.contextualActions.push(viewPropertiesAction)
|
||||
}
|
||||
}
|
||||
|
||||
Plasmoid.contextualActions.push(actionSeparator);
|
||||
|
||||
Plasmoid.contextualActionsAboutToShow.connect(updateContextualActions);
|
||||
Plasmoid.contextualActionsAboutToShow.connect(folderView.model.clearSelection);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014-2015 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQml 2.15
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||
import org.kde.kquickcontrolsaddons 2.0
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
|
||||
PlasmaComponents.ScrollView {
|
||||
id: root
|
||||
|
||||
property alias text: editor.text
|
||||
property alias targetItem: editor.targetItem
|
||||
signal commit
|
||||
|
||||
onFocusChanged: {
|
||||
if (focus) {
|
||||
editor.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaComponents.TextArea {
|
||||
id: editor
|
||||
|
||||
wrapMode: root.useListViewMode ? TextEdit.NoWrap : TextEdit.Wrap
|
||||
|
||||
textMargin: 0
|
||||
//leftPadding:
|
||||
|
||||
horizontalAlignment: root.useListViewMode ? TextEdit.AlignLeft : TextEdit.AlignHCenter
|
||||
|
||||
rightPadding: root.PlasmaComponents.ScrollBar.vertical.visible ? root.PlasmaComponents.ScrollBar.vertical.width : Kirigami.Units.smallSpacing
|
||||
|
||||
property Item targetItem: null
|
||||
|
||||
Binding {
|
||||
target: editor.background
|
||||
property: "width"
|
||||
value: root.width
|
||||
}
|
||||
Binding {
|
||||
target: editor.background
|
||||
property: "height"
|
||||
value: root.height
|
||||
}
|
||||
Component.onCompleted: root.contentItem.clip = false
|
||||
|
||||
onTargetItemChanged: {
|
||||
if (targetItem !== null) {
|
||||
var xy = getXY();
|
||||
root.x = xy[0];
|
||||
root.y = xy[1];
|
||||
root.width = getWidth();
|
||||
root.height = getInitHeight();
|
||||
text = targetItem.name;
|
||||
adjustSize();
|
||||
editor.select(0, dir.fileExtensionBoundary(positioner.map(targetItem.index)));
|
||||
if (isPopup) {
|
||||
root.contentItem.contentX = Math.max(root.contentItem.contentWidth - contentItem.width, 0);
|
||||
} else {
|
||||
root.contentItem.contentY = Math.max(root.contentItem.contentHeight - contentItem.height, 0);
|
||||
}
|
||||
root.visible = true;
|
||||
} else {
|
||||
root.x = 0;
|
||||
root.y = 0;
|
||||
root.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: event => {
|
||||
switch(event.key) {
|
||||
case Qt.Key_Return:
|
||||
case Qt.Key_Enter:
|
||||
root.commit();
|
||||
break;
|
||||
case Qt.Key_Escape:
|
||||
if (targetItem) {
|
||||
targetItem = null;
|
||||
event.accepted = true;
|
||||
}
|
||||
break;
|
||||
case Qt.Key_Home:
|
||||
if (event.modifiers & Qt.ShiftModifier) {
|
||||
editor.select(0, cursorPosition);
|
||||
} else {
|
||||
editor.select(0, 0);
|
||||
}
|
||||
event.accepted = true;
|
||||
break;
|
||||
case Qt.Key_End:
|
||||
if (event.modifiers & Qt.ShiftModifier) {
|
||||
editor.select(cursorPosition, text.length);
|
||||
} else {
|
||||
editor.select(text.length, text.length);
|
||||
}
|
||||
event.accepted = true;
|
||||
break;
|
||||
default:
|
||||
adjustSize();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onReleased: event => {
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
function getXY() {
|
||||
if (!targetItem) {
|
||||
return [0,0];
|
||||
}
|
||||
var pos = main.mapFromItem(targetItem, targetItem.labelArea.x, targetItem.labelArea.y);
|
||||
var _x, _y;
|
||||
if (root.useListViewMode) {
|
||||
_x = targetItem.labelArea.x - editor.leftPadding;
|
||||
_y = pos.y - editor.topPadding;
|
||||
} else {
|
||||
_x = targetItem.x + Math.abs(Math.min(gridView.contentX, gridView.originX));
|
||||
_x += editor.leftPadding;
|
||||
_x += scrollArea.viewport.x;
|
||||
_x -= Kirigami.Units.smallSpacing*2;
|
||||
if (root.PlasmaComponents.ScrollBar.vertical.policy === Qt.ScrollBarAlwaysOn
|
||||
&& gridView.effectiveLayoutDirection === Qt.RightToLeft) {
|
||||
_x -= root.PlasmaComponents.ScrollBar.vertical.width;
|
||||
|
||||
}
|
||||
_y = pos.y + Kirigami.Units.smallSpacing - editor.topPadding;
|
||||
}
|
||||
return [ _x, _y ];
|
||||
}
|
||||
|
||||
function getWidth(addWidthVerticalScroller) {
|
||||
if (!targetItem) {
|
||||
return 0;
|
||||
}
|
||||
return(targetItem.label.parent.width + Kirigami.Units.smallSpacing +
|
||||
(root.useListViewMode ? -(editor.leftPadding + editor.rightPadding + Kirigami.Units.smallSpacing) : 0) +
|
||||
(addWidthVerticalScroller ? root.PlasmaComponents.ScrollBar.vertical.width : 0));
|
||||
}
|
||||
|
||||
function getHeight(addWidthHoriozontalScroller, init) {
|
||||
if (!targetItem) {
|
||||
return 0;
|
||||
}
|
||||
var _height;
|
||||
if (isPopup || init) {
|
||||
_height = targetItem.labelArea.height + editor.topPadding + editor.bottomPadding;
|
||||
} else {
|
||||
var realHeight = contentHeight + editor.topPadding + editor.bottomPadding;
|
||||
var maxHeight = Kirigami.Units.iconSizes.sizeForLabels * (Plasmoid.configuration.textLines + 1) + editor.topPadding + editor.bottomPadding;
|
||||
_height = Math.min(realHeight, maxHeight);
|
||||
}
|
||||
return _height + (addWidthHoriozontalScroller ? root.PlasmaComponents.ScrollBar.horizontal.height : 0);
|
||||
}
|
||||
|
||||
function getInitHeight() {
|
||||
return getHeight(false, true);
|
||||
}
|
||||
|
||||
function adjustSize() {
|
||||
if (isPopup) {
|
||||
if(contentWidth + editor.leftPadding + editor.rightPadding > root.width) {
|
||||
root.visible = targetItem !== null;
|
||||
root.PlasmaComponents.ScrollBar.horizontal.policy = Qt.ScrollBarAlwaysOn;
|
||||
root.height = getHeight(true);
|
||||
} else {
|
||||
root.PlasmaComponents.ScrollBar.horizontal.policy = Qt.ScrollBarAlwaysOff;
|
||||
root.height = getHeight();
|
||||
}
|
||||
} else {
|
||||
root.height = getHeight();
|
||||
if(contentHeight + editor.topPadding + editor.bottomPadding > root.height) {
|
||||
root.visible = targetItem !== null;
|
||||
root.PlasmaComponents.ScrollBar.vertical.policy = Qt.ScrollBarAlwaysOn;
|
||||
root.width = getWidth(true);
|
||||
|
||||
} else {
|
||||
root.PlasmaComponents.ScrollBar.vertical.policy = Qt.ScrollBarAlwaysOff;
|
||||
root.width = getWidth();
|
||||
}
|
||||
}
|
||||
|
||||
var xy = getXY();
|
||||
root.x = xy[0];
|
||||
root.y = xy[1];
|
||||
if(root.PlasmaComponents.ScrollBar.vertical.policy === Qt.ScrollBarAlwaysOn)
|
||||
root.x -= root.PlasmaComponents.ScrollBar.vertical.width/2;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
var iconSizes = [Kirigami.Units.iconSizes.smallMedium,
|
||||
Kirigami.Units.iconSizes.medium,
|
||||
Kirigami.Units.iconSizes.large,
|
||||
Kirigami.Units.iconSizes.huge,
|
||||
Kirigami.Units.iconSizes.large*2,
|
||||
Kirigami.Units.iconSizes.enormous,
|
||||
Kirigami.Units.iconSizes.enormous*2];
|
||||
|
||||
function iconSizeFromTheme(size) {
|
||||
return iconSizes[size];
|
||||
}
|
||||
|
||||
function effectiveNavDirection(flow, layoutDirection, direction) {
|
||||
if (direction == Qt.LeftArrow) {
|
||||
if (flow == GridView.FlowLeftToRight) {
|
||||
if (layoutDirection == Qt.LeftToRight) {
|
||||
return Qt.LeftArrow;
|
||||
} else {
|
||||
return Qt.RightArrow;
|
||||
}
|
||||
} else {
|
||||
if (layoutDirection == Qt.LeftToRight) {
|
||||
return Qt.UpArrow;
|
||||
} else {
|
||||
return Qt.DownArrow;
|
||||
}
|
||||
}
|
||||
} else if (direction == Qt.RightArrow) {
|
||||
if (flow == GridView.FlowLeftToRight) {
|
||||
if (layoutDirection == Qt.LeftToRight) {
|
||||
return Qt.RightArrow;
|
||||
} else {
|
||||
return Qt.LeftArrow;
|
||||
}
|
||||
} else {
|
||||
if (layoutDirection == Qt.LeftToRight) {
|
||||
return Qt.DownArrow;
|
||||
} else {
|
||||
return Qt.UpArrow;
|
||||
}
|
||||
}
|
||||
} else if (direction == Qt.UpArrow) {
|
||||
if (flow == GridView.FlowLeftToRight) {
|
||||
return Qt.UpArrow;
|
||||
} else {
|
||||
return Qt.LeftArrow;
|
||||
}
|
||||
} else if (direction == Qt.DownArrow) {
|
||||
if (flow == GridView.FlowLeftToRight) {
|
||||
return Qt.DownArrow;
|
||||
} else {
|
||||
return Qt.RightArrow
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isFileDrag(event) {
|
||||
var taskUrl = event.mimeData.formats.indexOf("text/x-orgkdeplasmataskmanager_taskurl") != -1;
|
||||
var arkService = event.mimeData.formats.indexOf("application/x-kde-ark-dndextract-service") != -1;
|
||||
var arkPath = event.mimeData.formats.indexOf("application/x-kde-ark-dndextract-path") != -1;
|
||||
|
||||
return (event.mimeData.hasUrls || taskUrl || (arkService && arkPath));
|
||||
}
|
404
plasma/plasmoids/org.kde.desktopcontainment/contents/ui/main.qml
Normal file
404
plasma/plasmoids/org.kde.desktopcontainment/contents/ui/main.qml
Normal file
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2011-2013 Sebastian Kügler <sebas@kde.org>
|
||||
SPDX-FileCopyrightText: 2011-2019 Marco Martin <mart@kde.org>
|
||||
SPDX-FileCopyrightText: 2014-2015 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.ksvg 1.0 as KSvg
|
||||
import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
import org.kde.private.desktopcontainment.folder 0.1 as Folder
|
||||
|
||||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
||||
|
||||
import "code/FolderTools.js" as FolderTools
|
||||
|
||||
ContainmentItem {
|
||||
id: root
|
||||
|
||||
switchWidth: { switchSize(); }
|
||||
switchHeight: { switchSize(); }
|
||||
|
||||
// Only exists because the default CompactRepresentation doesn't:
|
||||
// - open on drag
|
||||
// - allow defining a custom drop handler
|
||||
// TODO remove once it gains that feature (perhaps optionally?)
|
||||
compactRepresentation: (isFolder && !isContainment) ? compactRepresentation : null
|
||||
|
||||
objectName: isFolder ? "folder" : "desktop"
|
||||
|
||||
width: isPopup ? undefined : preferredWidth(false) // Initial size when adding to e.g. desktop.
|
||||
height: isPopup ? undefined : preferredHeight(false) // Initial size when adding to e.g. desktop.
|
||||
|
||||
function switchSize() {
|
||||
// Support expanding into the full representation on very thick vertical panels.
|
||||
if (isPopup && Plasmoid.formFactor === PlasmaCore.Types.Vertical) {
|
||||
return Kirigami.Units.iconSizes.small * 8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
property bool isFolder: (Plasmoid.pluginName === "org.kde.plasma.folder")
|
||||
property bool isContainment: Plasmoid.isContainment
|
||||
property bool isPopup: (Plasmoid.location !== PlasmaCore.Types.Floating)
|
||||
property bool useListViewMode: isPopup && Plasmoid.configuration.viewMode === 0
|
||||
|
||||
property Component appletAppearanceComponent
|
||||
property Item toolBox
|
||||
|
||||
property int handleDelay: 800
|
||||
property real haloOpacity: 0.5
|
||||
|
||||
property int iconSize: Kirigami.Units.iconSizes.small
|
||||
property int iconWidth: iconSize
|
||||
property int iconHeight: iconWidth
|
||||
|
||||
readonly property int hoverActivateDelay: 750 // Magic number that matches Dolphin's auto-expand folders delay.
|
||||
|
||||
readonly property Loader folderViewLayer: fullRepresentationItem.folderViewLayer
|
||||
readonly property ContainmentLayoutManager.AppletsLayout appletsLayout: fullRepresentationItem.appletsLayout
|
||||
|
||||
// Plasmoid.title is set by a Binding {} in FolderViewLayer
|
||||
toolTipSubText: ""
|
||||
Plasmoid.icon: (!Plasmoid.configuration.useCustomIcon && folderViewLayer.ready) ? symbolicizeIconName(folderViewLayer.view.model.iconName) : Plasmoid.configuration.icon
|
||||
|
||||
onIconHeightChanged: updateGridSize()
|
||||
|
||||
// We want to do this here rather than in the model because we don't always want
|
||||
// symbolic icons everywhere, but we do know that we always want them in this
|
||||
// specific representation right here
|
||||
function symbolicizeIconName(iconName) {
|
||||
const symbolicSuffix = "-symbolic";
|
||||
if (iconName.endsWith(symbolicSuffix)) {
|
||||
return iconName;
|
||||
}
|
||||
|
||||
return iconName + symbolicSuffix;
|
||||
}
|
||||
|
||||
function updateGridSize() {
|
||||
// onIconHeightChanged can be triggered before this component is complete and all the children are created
|
||||
if (!toolBoxSvg) {
|
||||
return;
|
||||
}
|
||||
appletsLayout.cellWidth = root.iconWidth + toolBoxSvg.elementSize("left").width + toolBoxSvg.elementSize("right").width;
|
||||
appletsLayout.cellHeight = root.iconHeight + toolBoxSvg.elementSize("top").height + toolBoxSvg.elementSize("bottom").height;
|
||||
appletsLayout.defaultItemWidth = appletsLayout.cellWidth * 6;
|
||||
appletsLayout.defaultItemHeight = appletsLayout.cellHeight * 6;
|
||||
}
|
||||
|
||||
function addLauncher(desktopUrl) {
|
||||
if (!isFolder) {
|
||||
return;
|
||||
}
|
||||
|
||||
folderViewLayer.view.linkHere(desktopUrl);
|
||||
}
|
||||
|
||||
function preferredWidth(forMinimumSize: bool): real {
|
||||
if (isContainment || !folderViewLayer.ready) {
|
||||
return -1;
|
||||
} else if (useListViewMode) {
|
||||
return (forMinimumSize ? folderViewLayer.view.cellHeight * 4 : Kirigami.Units.iconSizes.small * 16);
|
||||
}
|
||||
|
||||
return (folderViewLayer.view.cellWidth * (forMinimumSize ? 1 : 3)) + (Kirigami.Units.iconSizes.small * 2);
|
||||
}
|
||||
|
||||
function preferredHeight(forMinimumSize: bool): real {
|
||||
let height;
|
||||
if (isContainment || !folderViewLayer.ready) {
|
||||
return -1;
|
||||
} else if (useListViewMode) {
|
||||
height = (folderViewLayer.view.cellHeight * (forMinimumSize ? 1 : 15)) + Kirigami.Units.smallSpacing;
|
||||
} else {
|
||||
height = (folderViewLayer.view.cellHeight * (forMinimumSize ? 1 : 2)) + Kirigami.Units.iconSizes.small;
|
||||
}
|
||||
|
||||
if (Plasmoid.configuration.labelMode !== 0) {
|
||||
height += folderViewLayer.item.labelHeight;
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
function isDrag(fromX, fromY, toX, toY) {
|
||||
const length = Math.abs(fromX - toX) + Math.abs(fromY - toY);
|
||||
return length >= Qt.styleHints.startDragDistance;
|
||||
}
|
||||
|
||||
onFocusChanged: {
|
||||
if (focus && isFolder) {
|
||||
folderViewLayer.item.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
|
||||
onExternalData: (mimetype, data) => {
|
||||
Plasmoid.configuration.url = data
|
||||
}
|
||||
|
||||
component ShortDropBehavior : Behavior {
|
||||
NumberAnimation {
|
||||
duration: Kirigami.Units.shortDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
component LongDropBehavior : Behavior {
|
||||
NumberAnimation {
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
KSvg.FrameSvgItem {
|
||||
id: highlightItemSvg
|
||||
|
||||
visible: false
|
||||
|
||||
imagePath: isPopup ? "widgets/viewitem" : ""
|
||||
prefix: "hover"
|
||||
}
|
||||
|
||||
KSvg.FrameSvgItem {
|
||||
id: listItemSvg
|
||||
|
||||
visible: false
|
||||
|
||||
imagePath: isPopup ? "widgets/viewitem" : ""
|
||||
prefix: "normal"
|
||||
}
|
||||
|
||||
KSvg.Svg {
|
||||
id: toolBoxSvg
|
||||
imagePath: "widgets/toolbox"
|
||||
property int rightBorder: elementSize("right").width
|
||||
property int topBorder: elementSize("top").height
|
||||
property int bottomBorder: elementSize("bottom").height
|
||||
property int leftBorder: elementSize("left").width
|
||||
}
|
||||
|
||||
// FIXME: the use and existence of this property is a workaround
|
||||
preloadFullRepresentation: true
|
||||
fullRepresentation: FolderViewDropArea {
|
||||
id: dropArea
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: (isContainment && root.availableScreenRect) ? root.availableScreenRect.x : 0
|
||||
topMargin: (isContainment && root.availableScreenRect) ? root.availableScreenRect.y : 0
|
||||
|
||||
rightMargin: (isContainment && root.availableScreenRect && parent)
|
||||
? (parent.width - root.availableScreenRect.x - root.availableScreenRect.width) : 0
|
||||
|
||||
bottomMargin: (isContainment && root.availableScreenRect && parent)
|
||||
? (parent.height - root.availableScreenRect.y - root.availableScreenRect.height) : 0
|
||||
}
|
||||
|
||||
LongDropBehavior on anchors.topMargin { }
|
||||
LongDropBehavior on anchors.leftMargin { }
|
||||
LongDropBehavior on anchors.rightMargin { }
|
||||
LongDropBehavior on anchors.bottomMargin { }
|
||||
|
||||
property alias folderViewLayer: folderViewLayer
|
||||
property alias appletsLayout: appletsLayout
|
||||
|
||||
Layout.minimumWidth: preferredWidth(!isPopup)
|
||||
Layout.minimumHeight: preferredHeight(!isPopup)
|
||||
|
||||
Layout.preferredWidth: preferredWidth(false)
|
||||
Layout.preferredHeight: preferredHeight(false)
|
||||
// Maximum size is intentionally unbounded
|
||||
|
||||
preventStealing: true
|
||||
|
||||
onDragEnter: event => {
|
||||
if (isContainment && Plasmoid.immutable && !(isFolder && FolderTools.isFileDrag(event))) {
|
||||
event.ignore();
|
||||
}
|
||||
|
||||
// Don't allow any drops while listing.
|
||||
if (isFolder && folderViewLayer.view.status === Folder.FolderModel.Listing) {
|
||||
event.ignore();
|
||||
}
|
||||
|
||||
// Firefox tabs are regular drags. Since all of our drop handling is asynchronous
|
||||
// we would accept this drop and have Firefox not spawn a new window. (Bug 337711)
|
||||
if (event.mimeData.formats.indexOf("application/x-moz-tabbrowser-tab") !== -1) {
|
||||
event.ignore();
|
||||
}
|
||||
}
|
||||
|
||||
onDragMove: event => {
|
||||
// TODO: We should reject drag moves onto file items that don't accept drops
|
||||
// (cf. QAbstractItemModel::flags() here, but DeclarativeDropArea currently
|
||||
// is currently incapable of rejecting drag events.
|
||||
|
||||
// Trigger autoscroll.
|
||||
if (isFolder && FolderTools.isFileDrag(event)) {
|
||||
handleDragMove(folderViewLayer.view, mapToItem(folderViewLayer.view, event.x, event.y));
|
||||
} else if (isContainment) {
|
||||
appletsLayout.showPlaceHolderAt(
|
||||
Qt.rect(event.x - appletsLayout.minimumItemWidth / 2,
|
||||
event.y - appletsLayout.minimumItemHeight / 2,
|
||||
appletsLayout.minimumItemWidth,
|
||||
appletsLayout.minimumItemHeight)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
onDragLeave: event => {
|
||||
// Cancel autoscroll.
|
||||
if (isFolder) {
|
||||
handleDragEnd(folderViewLayer.view);
|
||||
}
|
||||
|
||||
if (isContainment) {
|
||||
appletsLayout.hidePlaceHolder();
|
||||
}
|
||||
}
|
||||
|
||||
onDrop: event => {
|
||||
if (isFolder && FolderTools.isFileDrag(event)) {
|
||||
handleDragEnd(folderViewLayer.view);
|
||||
folderViewLayer.view.drop(root, event, mapToItem(folderViewLayer.view, event.x, event.y));
|
||||
} else if (isContainment) {
|
||||
root.processMimeData(event.mimeData,
|
||||
event.x - appletsLayout.placeHolder.width / 2,
|
||||
event.y - appletsLayout.placeHolder.height / 2);
|
||||
event.accept(event.proposedAction);
|
||||
appletsLayout.hidePlaceHolder();
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: compactRepresentation
|
||||
CompactRepresentation { folderView: folderViewLayer.view }
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Plasmoid.containment.corona
|
||||
ignoreUnknownSignals: true
|
||||
|
||||
function onEditModeChanged() {
|
||||
appletsLayout.editMode = Plasmoid.containment.corona.editMode;
|
||||
}
|
||||
}
|
||||
|
||||
ContainmentLayoutManager.AppletsLayout {
|
||||
id: appletsLayout
|
||||
anchors.fill: parent
|
||||
relayoutLock: width !== root.availableScreenRect.width || height !== root.availableScreenRect.height
|
||||
// NOTE: use root.availableScreenRect and not own width and height as they are updated not atomically
|
||||
configKey: "ItemGeometries-" + Math.round(root.screenGeometry.width) + "x" + Math.round(root.screenGeometry.height)
|
||||
fallbackConfigKey: root.availableScreenRect.width > root.availableScreenRect.height ? "ItemGeometriesHorizontal" : "ItemGeometriesVertical"
|
||||
|
||||
containment: Plasmoid
|
||||
containmentItem: root
|
||||
editModeCondition: Plasmoid.immutable
|
||||
? ContainmentLayoutManager.AppletsLayout.Locked
|
||||
: ContainmentLayoutManager.AppletsLayout.AfterPressAndHold
|
||||
|
||||
// Sets the containment in edit mode when we go in edit mode as well
|
||||
onEditModeChanged: Plasmoid.containment.corona.editMode = editMode;
|
||||
|
||||
minimumItemWidth: Kirigami.Units.iconSizes.small * 3
|
||||
minimumItemHeight: minimumItemWidth
|
||||
|
||||
cellWidth: Kirigami.Units.iconSizes.small
|
||||
cellHeight: cellWidth
|
||||
|
||||
eventManagerToFilter: folderViewLayer.item?.view.view ?? null
|
||||
|
||||
appletContainerComponent: ContainmentLayoutManager.BasicAppletContainer {
|
||||
id: appletContainer
|
||||
|
||||
editModeCondition: Plasmoid.immutable
|
||||
? ContainmentLayoutManager.ItemContainer.Locked
|
||||
: ContainmentLayoutManager.ItemContainer.AfterPressAndHold
|
||||
|
||||
configOverlaySource: "ConfigOverlay.qml"
|
||||
|
||||
onUserDrag: (newPosition, dragCenter) => {
|
||||
const pos = mapToItem(root.parent, dragCenter.x, dragCenter.y);
|
||||
const newCont = root.containmentItemAt(pos.x, pos.y);
|
||||
|
||||
if (newCont && newCont.plasmoid !== Plasmoid) {
|
||||
const newPos = newCont.mapFromApplet(Plasmoid, pos.x, pos.y);
|
||||
|
||||
// First go out of applet edit mode, get rid of the config overlay, release mouse grabs in preparation of applet reparenting
|
||||
cancelEdit();
|
||||
newCont.Plasmoid.addApplet(appletContainer.applet.plasmoid, Qt.rect(newPos.x, newPos.y, appletContainer.applet.width, appletContainer.applet.height));
|
||||
appletsLayout.hidePlaceHolder();
|
||||
}
|
||||
}
|
||||
|
||||
ShortDropBehavior on x { }
|
||||
ShortDropBehavior on y { }
|
||||
}
|
||||
|
||||
placeHolder: ContainmentLayoutManager.PlaceHolder {}
|
||||
|
||||
Loader {
|
||||
id: folderViewLayer
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
property bool ready: status === Loader.Ready
|
||||
property Item view: item?.view ?? null
|
||||
property QtObject model: item?.model ?? null
|
||||
|
||||
focus: true
|
||||
|
||||
active: isFolder
|
||||
asynchronous: false
|
||||
|
||||
source: "FolderViewLayer.qml"
|
||||
|
||||
onFocusChanged: {
|
||||
if (!focus && model) {
|
||||
model.clearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: folderViewLayer.view
|
||||
|
||||
// `FolderViewDropArea` is not a FocusScope. We need to forward manually.
|
||||
function onPressed() {
|
||||
folderViewLayer.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaCore.Action {
|
||||
id: configAction
|
||||
text: i18n("Desktop and Wallpaper")
|
||||
icon.name: "preferences-desktop-wallpaper"
|
||||
shortcut: "alt+d,alt+s"
|
||||
onTriggered: Plasmoid.containment.configureRequested(Plasmoid)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!Plasmoid.isContainment) {
|
||||
return;
|
||||
}
|
||||
|
||||
Plasmoid.setInternalAction("configure", configAction)
|
||||
updateGridSize();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue