diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -113,6 +113,7 @@ middleclickactioneventfilter.cpp dolphinnewfilemenu.cpp dolphindebug.cpp + utils/directoryfindchilditem.cpp ) if(HAVE_BALOO) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -58,6 +58,11 @@ TEST_NAME dolphinmainwindowtest LINK_LIBRARIES dolphinprivate dolphinstatic Qt5::Test) +# CommonAncestorTest +ecm_add_test(directoryfindchilditemtest.cpp +TEST_NAME directoryfindchilditemtest +LINK_LIBRARIES dolphinprivate dolphinstatic Qt5::Test) + ecm_add_test(draganddrophelpertest.cpp LINK_LIBRARIES dolphinprivate Qt5::Test) # PlacesItemModelTest diff --git a/src/tests/directoryfindchilditemtest.cpp b/src/tests/directoryfindchilditemtest.cpp new file mode 100644 --- /dev/null +++ b/src/tests/directoryfindchilditemtest.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2018 by Emirald Mateli * + * * + * 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 * + ***************************************************************************/ + +#include "utils/directoryfindchilditem.cpp" +#include + +class DirectoryFindChildItemTest : public QObject +{ + Q_OBJECT + +private slots: + void testDirectoryFindChildItem_data(); + void testDirectoryFindChildItem(); +}; + +void DirectoryFindChildItemTest::testDirectoryFindChildItem_data() +{ + QTest::addColumn("directory"); + QTest::addColumn("url"); + QTest::addColumn("expected"); + + QTest::newRow("Test directory with file located in one of its children") + << QUrl::fromLocalFile("dir") + << QUrl::fromLocalFile("dir/sub/x/y/z") + << QUrl::fromLocalFile("dir/sub"); + + QTest::newRow("Test directory with trailing path delimiter") + << QUrl::fromLocalFile("dir/sub/x/") + << QUrl::fromLocalFile("dir/sub/x/y/z") + << QUrl::fromLocalFile("dir/sub/x/y"); + + QTest::newRow("Test two unrelated directories") + << QUrl::fromLocalFile("unrelated") + << QUrl::fromLocalFile("dir/sub/x/y/z") + << QUrl(); +} + +void DirectoryFindChildItemTest::testDirectoryFindChildItem() +{ + QFETCH(QUrl, directory); + QFETCH(QUrl, url); + QFETCH(QUrl, expected); + + QCOMPARE(directoryFindChildItem(directory, url), expected); +} + +QTEST_MAIN(DirectoryFindChildItemTest) + +#include "directoryfindchilditemtest.moc" diff --git a/src/utils/directoryfindchilditem.h b/src/utils/directoryfindchilditem.h new file mode 100644 --- /dev/null +++ b/src/utils/directoryfindchilditem.h @@ -0,0 +1,6 @@ +#ifndef DIRECTORY_FIND_CHILD_ITEM +#define DIRECTORY_FIND_CHILD_ITEM + +QUrl directoryFindChildItem(const QUrl& directory, const QUrl& filename); + +#endif diff --git a/src/utils/directoryfindchilditem.cpp b/src/utils/directoryfindchilditem.cpp new file mode 100644 --- /dev/null +++ b/src/utils/directoryfindchilditem.cpp @@ -0,0 +1,27 @@ +#include +#include +#include +#include "directoryfindchilditem.h" + +/** + * Returns the item which is located in directory in the argument + * when filename is an item located in directory or one of its children. + * Returns an empty QUrl when that is not the case + * + * @param directory + * @param filename + * @return + */ +QUrl directoryFindChildItem(const QUrl& directory, const QUrl& filename) +{ + const QString dirStr = directory.adjusted(QUrl::StripTrailingSlash).toString(); + const QString urlStr = filename.toString(); + const int dirLen = dirStr.length() + 1; + + if (!urlStr.startsWith(dirStr)) { + return QUrl(); + } + + return QUrl(QStringLiteral("%1/%2").arg( + dirStr, urlStr.mid(dirLen, urlStr.indexOf(QDir::separator(), dirLen + 1) - dirLen))); +} \ No newline at end of file diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -68,6 +68,7 @@ #include #include #include +#include DolphinView::DolphinView(const QUrl& url, QWidget* parent) : QWidget(parent), @@ -1332,9 +1333,14 @@ void DolphinView::observeCreatedItem(const QUrl& url) { - if (m_active) { - forceUrlsSelection(url, {url}); + if (!m_active) { + return; } + + // In case url is located in a subdirectory, select its ancestor located in the current dir. + const QUrl ancestorName = directoryFindChildItem(m_model->directory().url(), url); + + forceUrlsSelection(ancestorName, {ancestorName}); } void DolphinView::slotDirectoryRedirection(const QUrl& oldUrl, const QUrl& newUrl) @@ -1807,4 +1813,5 @@ m_clearSelectionBeforeSelectingNewItems = true; markUrlAsCurrent(current); markUrlsAsSelected(selected); + updateViewState(); }