]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Improve DnD handling in read-only dirs
authorJin Liu <m.liu.jin@gmail.com>
Sat, 17 Feb 2024 11:14:46 +0000 (11:14 +0000)
committerJin Liu <m.liu.jin@gmail.com>
Sat, 17 Feb 2024 11:14:46 +0000 (11:14 +0000)
1. Places panel and tabbar update drag status in read-only dir
2. Don't create drop job in readonly directories

src/dolphintabbar.cpp
src/dolphintabbar.h
src/dolphintabwidget.cpp
src/dolphintabwidget.h
src/kitemviews/kfileitemmodel.cpp
src/panels/places/placespanel.cpp
src/views/draganddrophelper.cpp
src/views/draganddrophelper.h

index 4c918e6114db4625c57b402fa9585fea14bf4b3f..f6af9932da2f4df3a15da0884a84a3484748a3e2 100644 (file)
@@ -80,6 +80,7 @@ void DolphinTabBar::dragMoveEvent(QDragMoveEvent *event)
     const int index = tabAt(event->position().toPoint());
 
     if (mimeData->hasUrls()) {
+        Q_EMIT tabDragMoveEvent(index, event);
         updateAutoActivationTimer(index);
     }
 
index 1177cda9342014df82a8b2f2a63f74b71e2f06f9..4a59199bee1ab4fe6827460c1740668e201ac407 100644 (file)
@@ -18,6 +18,7 @@ public:
 
 Q_SIGNALS:
     void openNewActivatedTab(int index);
+    void tabDragMoveEvent(int index, QDragMoveEvent *event);
     void tabDropEvent(int index, QDropEvent *event);
     void tabDetachRequested(int index);
 
index f274ffa2abbb4b7f64555ae9daa329a4b4e6bee7..f80b94ea7cc49e43775da1a0d57ae1dfa82920b0 100644 (file)
@@ -9,6 +9,7 @@
 #include "dolphin_generalsettings.h"
 #include "dolphintabbar.h"
 #include "dolphinviewcontainer.h"
+#include "views/draganddrophelper.h"
 
 #include <KAcceleratorManager>
 #include <KConfigGroup>
@@ -33,6 +34,7 @@ DolphinTabWidget::DolphinTabWidget(DolphinNavigatorsWidgetAction *navigatorsWidg
 
     DolphinTabBar *tabBar = new DolphinTabBar(this);
     connect(tabBar, &DolphinTabBar::openNewActivatedTab, this, QOverload<int>::of(&DolphinTabWidget::openNewActivatedTab));
+    connect(tabBar, &DolphinTabBar::tabDragMoveEvent, this, &DolphinTabWidget::tabDragMoveEvent);
     connect(tabBar, &DolphinTabBar::tabDropEvent, this, &DolphinTabWidget::tabDropEvent);
     connect(tabBar, &DolphinTabBar::tabDetachRequested, this, &DolphinTabWidget::detachTab);
 
@@ -388,6 +390,14 @@ void DolphinTabWidget::openNewActivatedTab(int index)
     openNewActivatedTab(tabPage->activeViewContainer()->url());
 }
 
+void DolphinTabWidget::tabDragMoveEvent(int index, QDragMoveEvent *event)
+{
+    if (index >= 0) {
+        DolphinView *view = tabPageAt(index)->activeViewContainer()->view();
+        DragAndDropHelper::updateDropAction(event, view->url());
+    }
+}
+
 void DolphinTabWidget::tabDropEvent(int index, QDropEvent *event)
 {
     if (index >= 0) {
index 22f65b634c634510af0ad6bc058403e94c0aea64..a28a6bea1ff0941d78e265a28bec044c6febdede 100644 (file)
@@ -208,6 +208,12 @@ private Q_SLOTS:
      */
     void openNewActivatedTab(int index);
 
+    /**
+     * Is connected to the KTabBar signal receivedDragMoveEvent.
+     * Allows dragging and dropping files onto tabs.
+     */
+    void tabDragMoveEvent(int tab, QDragMoveEvent *event);
+
     /**
      * Is connected to the KTabBar signal receivedDropEvent.
      * Allows dragging and dropping files onto tabs.
index f9bab74cd63fa9502dbd6577a8226f029255316e..99a3d163fe3fca24906c304bbd2d98a59e8b20bd 100644 (file)
@@ -12,6 +12,7 @@
 #include "dolphin_generalsettings.h"
 #include "dolphindebug.h"
 #include "private/kfileitemmodelsortalgorithm.h"
+#include "views/draganddrophelper.h"
 
 #include <KDirLister>
 #include <KIO/Job>
@@ -348,7 +349,7 @@ bool KFileItemModel::supportsDropping(int index) const
     } else {
         item = fileItem(index);
     }
-    return !item.isNull() && ((item.isDir() && item.isWritable()) || item.isDesktopFile());
+    return !item.isNull() && DragAndDropHelper::supportsDropping(item);
 }
 
 QString KFileItemModel::roleDescription(const QByteArray &role) const
index 2c19d8f29410bccf05889b0d59f9a06a5fa2dbfb..ba3451bd5e603f353e38fa4ec01f5e6590cceaf0 100644 (file)
@@ -156,9 +156,13 @@ void PlacesPanel::dragMoveEvent(QDragMoveEvent *event)
         // Reject drag ontop of a non-writable protocol
         // We don't know whether we're dropping inbetween or ontop of a place
         // so still allow internal drag events so that re-arranging still works.
-        const QUrl url = placesModel->url(index);
-        if (url.isValid() && !isInternalDrag(event->mimeData()) && !KProtocolManager::supportsWriting(url)) {
-            event->setDropAction(Qt::IgnoreAction);
+        if (!isInternalDrag(event->mimeData())) {
+            const QUrl url = placesModel->url(index);
+            if (!url.isValid() || !KProtocolManager::supportsWriting(url)) {
+                event->setDropAction(Qt::IgnoreAction);
+            } else {
+                DragAndDropHelper::updateDropAction(event, url);
+            }
         }
     }
 
index 2953233d0d08a18af50f9279b41da802788f4cb0..efdec5b92c73e4d7b6975069e2c183948663fc34 100644 (file)
@@ -52,15 +52,43 @@ KIO::DropJob *DragAndDropHelper::dropUrls(const QUrl &destUrl, QDropEvent *event
             return nullptr;
         }
 
-        // Drop into a directory or a desktop-file
-        KIO::DropJob *job = KIO::drop(event, destUrl);
-        KJobWidgets::setWindow(job, window);
-        return job;
+        if (supportsDropping(destUrl)) {
+            // Drop into a directory or a desktop-file
+            KIO::DropJob *job = KIO::drop(event, destUrl);
+            KJobWidgets::setWindow(job, window);
+            return job;
+        }
     }
 
     return nullptr;
 }
 
+bool DragAndDropHelper::supportsDropping(const QUrl &destUrl)
+{
+    KFileItem item(destUrl);
+    return supportsDropping(item);
+}
+
+bool DragAndDropHelper::supportsDropping(const KFileItem &destItem)
+{
+    return (destItem.isDir() && destItem.isWritable()) || destItem.isDesktopFile();
+}
+
+void DragAndDropHelper::updateDropAction(QDropEvent *event, const QUrl &destUrl)
+{
+    if (urlListMatchesUrl(event->mimeData()->urls(), destUrl)) {
+        event->setDropAction(Qt::IgnoreAction);
+        event->ignore();
+    }
+    if (supportsDropping(destUrl)) {
+        event->setDropAction(event->proposedAction());
+        event->accept();
+    } else {
+        event->setDropAction(Qt::IgnoreAction);
+        event->ignore();
+    }
+}
+
 void DragAndDropHelper::clearUrlListMatchesUrlCache()
 {
     DragAndDropHelper::m_urlListMatchesUrlCache.clear();
index 656cefe1be62384c6e14ed13064f717982ade605..0eee34a3d84b288c5b5de43ced283aa2e504bea1 100644 (file)
@@ -10,6 +10,8 @@
 
 #include "dolphin_export.h"
 
+#include <KFileItem>
+
 #include <QList>
 #include <QString>
 #include <QUrl>
@@ -40,6 +42,34 @@ public:
      */
     static KIO::DropJob *dropUrls(const QUrl &destUrl, QDropEvent *event, QWidget *window);
 
+    /**
+     * Checks if the destination supports dropping.
+     *
+     * @param destUrl   URL of the item destination.
+     * @return          True if the destination is a directory and is writable, or it's a desktop file.
+     *                  False otherwise.
+     */
+    static bool supportsDropping(const QUrl &destUrl);
+
+    /**
+     * Checks if the destination supports dropping.
+     *
+     * @param destItem  The item destination.
+     * @return          True if the destination is a directory and is writable, or it's a desktop file.
+     *                  False otherwise.
+     */
+    static bool supportsDropping(const KFileItem &destItem);
+
+    /**
+     * Updates the drop action according to whether the destination supports dropping.
+     * If supportsDropping(destUrl), set dropAction = proposedAction. Otherwise, set
+     * dropAction = Qt::IgnoreAction.
+     *
+     * @param event     Drop event.
+     * @param destUrl   Destination URL.
+     */
+    static void updateDropAction(QDropEvent *event, const QUrl &destUrl);
+
     /**
      * @return True if destUrl is contained in the urls parameter.
      */