diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,6 +29,7 @@ target_link_libraries( dolphinvcs PUBLIC Qt5::Widgets + Qt5::Concurrent ) set_target_properties(dolphinvcs PROPERTIES diff --git a/src/views/draganddrophelper.cpp b/src/views/draganddrophelper.cpp --- a/src/views/draganddrophelper.cpp +++ b/src/views/draganddrophelper.cpp @@ -25,16 +25,40 @@ #include #include #include +#include #include #include - bool DragAndDropHelper::urlListMatchesUrl(const QList& urls, const QUrl& destUrl) { - return std::find_if(urls.constBegin(), urls.constEnd(), [destUrl](const QUrl& url) { - return url.matches(destUrl, QUrl::StripTrailingSlash); - }) != urls.constEnd(); + // This method is quite expensive and is called several times when the mouse is + // moved from the drag origin to the drop destination. Use a cache. + static bool lastResult = false; + static const QList* lastUrls = nullptr; + static const QUrl* lastDestUrl = nullptr; + + // If checking the same data as last time, return the same result. + if (&urls == lastUrls && &destUrl == lastDestUrl) { + return lastResult; + } + // otherwise do the expensive check and store the results + const QUrl& adjustedDestUrl = destUrl.adjusted(QUrl::StripTrailingSlash); + + // Use all the cpu availables. + std::function stripMap = [&](const QUrl &url) -> bool { + return adjustedDestUrl == url.adjusted(QUrl::StripTrailingSlash); + }; + auto andReduce = [&](bool &result, const bool partial) { + result &= partial; + }; + + lastResult = QtConcurrent::blockingMappedReduced + (urls.constBegin(), urls.constEnd(), stripMap, andReduce); + lastUrls = &urls; + lastDestUrl = &destUrl; + + return lastResult; } KIO::DropJob* DragAndDropHelper::dropUrls(const QUrl& destUrl, QDropEvent* event, QWidget* window)