diff --git a/containments/desktop/package/contents/ui/FolderItemDelegate.qml b/containments/desktop/package/contents/ui/FolderItemDelegate.qml --- a/containments/desktop/package/contents/ui/FolderItemDelegate.qml +++ b/containments/desktop/package/contents/ui/FolderItemDelegate.qml @@ -41,6 +41,12 @@ property Item hoverArea: loader.item ? loader.item.hoverArea : null property Item toolTip: loader.item ? loader.item.toolTip : null + function openPopup() { + if (isDir) { + loader.item.openPopup(); + } + } + Loader { id: loader @@ -90,7 +96,7 @@ } onHoveredChanged: { - if (hovered && !main.GridView.view.isRootView && model.isDir) { + if (hovered && (!main.GridView.view.isRootView || root.containsDrag) && model.isDir) { openPopupTimer.start(); } else if (!hovered) openPopupTimer.stop(); @@ -113,13 +119,27 @@ Timer { id: openPopupTimer - interval: units.longDuration * 3 + interval: 750 // Magic number that matches Dolphin's auto-expand folders delay. onTriggered: { impl.openPopup(); } } + Connections { + target: main.GridView.view + + enabled: hovered + + onContentXChanged: { + openPopupTimer.stop(); + } + + onContentYChanged: { + openPopupTimer.stop(); + } + } + PlasmaCore.ToolTipArea { id: toolTip @@ -314,6 +334,8 @@ Column { id: actions + visible: !root.containsDrag && (!popupDialog || !popupDialog.containsDrag) && (!dialog || !dialog.containsDrag) + x: units.smallSpacing * 3 y: units.smallSpacing * 3 diff --git a/containments/desktop/package/contents/ui/FolderView.qml b/containments/desktop/package/contents/ui/FolderView.qml --- a/containments/desktop/package/contents/ui/FolderView.qml +++ b/containments/desktop/package/contents/ui/FolderView.qml @@ -56,6 +56,7 @@ property alias scrollRight: gridView.scrollRight property alias scrollUp: gridView.scrollUp property alias scrollDown: gridView.scrollDown + property alias hoveredItem: listener.hoveredItem property var history: [] property Item backButton: null @@ -70,6 +71,11 @@ dir.linkHere(sourceUrl); } + function itemAt(x, y) { + var pos = mapToItem(gridView.contentItem, x, y); + return gridView.itemAt(pos.x, pos.y); + } + function dropItemAt(pos) { var item = gridView.itemAt(pos.x, pos.y); @@ -368,7 +374,7 @@ } onHoveredItemChanged: { - doubleClickInProgress = false; + doubleClickInProgress = false;3 } function pressCanceled() { diff --git a/containments/desktop/package/contents/ui/FolderViewDialog.qml b/containments/desktop/package/contents/ui/FolderViewDialog.qml --- a/containments/desktop/package/contents/ui/FolderViewDialog.qml +++ b/containments/desktop/package/contents/ui/FolderViewDialog.qml @@ -29,6 +29,7 @@ visible: false + property alias containsDrag: folderViewDropArea.containsDrag property QtObject closeTimer: closeTimer property QtObject childDialog: (folderView.hoveredItem != null) ? folderView.hoveredItem.popupDialog : null property bool containsMouse: folderView.containsMouse || (childDialog != null && childDialog.containsMouse) @@ -46,22 +47,30 @@ } } - mainItem: FolderView { - id: folderView + mainItem: FolderViewDropArea { + id: folderViewDropArea - width: cellWidth * 3 + (10 * units.devicePixelRatio) // FIXME HACK: Use actual scrollbar width. - height: cellHeight * 2 + width: folderView.cellWidth * 3 + (10 * units.devicePixelRatio) // FIXME HACK: Use actual scrollbar width. + height: folderView.cellHeight * 2 - isRootView: false + folderView: folderView - locked: true + FolderView { + id: folderView - sortMode: ((plasmoid.configuration.sortMode == 0) ? 1 : plasmoid.configuration.sortMode) - filterMode: 0 + anchors.fill: parent - // TODO: Bidi. - flow: GridView.FlowLeftToRight - layoutDirection: Qt.LeftToRight + isRootView: false + + locked: true + + sortMode: ((plasmoid.configuration.sortMode == 0) ? 1 : plasmoid.configuration.sortMode) + filterMode: 0 + + // TODO: Bidi. + flow: GridView.FlowLeftToRight + layoutDirection: Qt.LeftToRight + } } data: [ diff --git a/containments/desktop/package/contents/ui/FolderViewDropArea.qml b/containments/desktop/package/contents/ui/FolderViewDropArea.qml new file mode 100644 --- /dev/null +++ b/containments/desktop/package/contents/ui/FolderViewDropArea.qml @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2014-2017 by Eike Hein * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +import QtQuick 2.4 + +import org.kde.draganddrop 2.0 as DragDrop + +DragDrop.DropArea { + id: dropArea + + property Item folderView: null + + function handleDragMove(folderView, event) { + // Trigger autoscroll. + folderView.scrollLeft = (event.x < (units.largeSpacing * 3)); + folderView.scrollRight = (event.x > width - (units.largeSpacing * 3)); + folderView.scrollUp = (event.y < (units.largeSpacing * 3)); + folderView.scrollDown = (event.y > height - (units.largeSpacing * 3)); + + // Set hovered item. + folderView.hoveredItem = folderView.itemAt(event.x, event.y); + } + + function handleDragEnd(folderView) { + // Cancel autoscroll. + folderView.scrollLeft = false; + folderView.scrollRight = false; + folderView.scrollUp = false; + folderView.scrollDown = false; + + // Unset hovered item. + if (folderView.hoveredItem && !folderView.hoveredItem.popupDialog) { + folderView.hoveredItem = null; + } + } + + onDragMove: { + // 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, event); + } + } + + onDragLeave: { + if (folderView) { + handleDragEnd(folderView); + } + } + + onDrop: { + if (folderView) { + handleDragEnd(folderView); + + folderView.drop(folderView, event, mapToItem(folderView, event.x, event.y)); + } + } +} diff --git a/containments/desktop/package/contents/ui/main.qml b/containments/desktop/package/contents/ui/main.qml --- a/containments/desktop/package/contents/ui/main.qml +++ b/containments/desktop/package/contents/ui/main.qml @@ -33,7 +33,7 @@ import "LayoutManager.js" as LayoutManager import "FolderTools.js" as FolderTools -DragDrop.DropArea { +FolderViewDropArea { id: root objectName: isFolder ? "folder" : "desktop" @@ -255,10 +255,7 @@ // Trigger autoscroll. if (isFolder && FolderTools.isFileDrag(event)) { - folderViewLayer.view.scrollLeft = (event.x < (units.largeSpacing * 3)); - folderViewLayer.view.scrollRight = (event.x > width - (units.largeSpacing * 3)); - folderViewLayer.view.scrollUp = (event.y < (units.largeSpacing * 3)); - folderViewLayer.view.scrollDown = (event.y > height - (units.largeSpacing * 3)); + handleDragMove(folderViewLayer.view, event); } else if (isContainment) { placeHolder.width = LayoutManager.defaultAppletSize.width; placeHolder.height = LayoutManager.defaultAppletSize.height; @@ -274,10 +271,7 @@ onDragLeave: { // Cancel autoscroll. if (isFolder) { - folderViewLayer.view.scrollLeft = false; - folderViewLayer.view.scrollRight = false; - folderViewLayer.view.scrollUp = false; - folderViewLayer.view.scrollDown = false; + handleDragEnd(folderViewLayer.view); } if (isContainment) { @@ -287,12 +281,7 @@ onDrop: { if (isFolder && FolderTools.isFileDrag(event)) { - // Cancel autoscroll. - folderViewLayer.view.scrollLeft = false; - folderViewLayer.view.scrollRight = false; - folderViewLayer.view.scrollUp = false; - folderViewLayer.view.scrollDown = false; - + handleDragEnd(folderViewLayer.view); folderViewLayer.view.drop(root, event, mapToItem(folderViewLayer.view, event.x, event.y)); } else if (isContainment) { placeHolderPaint.opacity = 0; diff --git a/containments/desktop/plugins/folder/foldermodel.cpp b/containments/desktop/plugins/folder/foldermodel.cpp --- a/containments/desktop/plugins/folder/foldermodel.cpp +++ b/containments/desktop/plugins/folder/foldermodel.cpp @@ -875,6 +875,11 @@ QUrl dropTargetUrl; + // So we get to run mostLocalUrl() over the current URL. + if (item.isNull()) { + item = m_dirModel->dirLister()->rootItem(); + } + if (item.isNull()) { dropTargetUrl = m_dirModel->dirLister()->url(); } else if (m_parseDesktopFiles && item.isDesktopFile()) {