1
0
mirror of https://invent.kde.org/system/dolphin synced 2024-07-02 16:31:23 +00:00

Improve DnD handling in read-only dirs

1. Places panel and tabbar update drag status in read-only dir
2. Don't create drop job in readonly directories
This commit is contained in:
Jin Liu 2024-02-17 11:14:46 +00:00
parent cda139ccab
commit c9c3531c0b
8 changed files with 89 additions and 8 deletions

View 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);
}

View 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);

View 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) {

View 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.

View 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

View 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);
}
}
}

View 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();

View 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.
*/