diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index 5678be86b2b..562f3247bd8 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -2334,12 +2334,30 @@ QTCREATOR_UTILS_EXPORT bool operator!=(const FilePath &first, const FilePath &se QTCREATOR_UTILS_EXPORT bool operator<(const FilePath &first, const FilePath &second) { - const int cmp = first.pathView().compare(second.pathView(), first.caseSensitivity()); - if (cmp != 0) - return cmp < 0; - if (first.host() != second.host()) - return first.host() < second.host(); - return first.scheme() < second.scheme(); + const bool firstNeedsDevice = first.needsDevice(); + const bool secondNeedsDevice = second.needsDevice(); + + // If either needs a device, we have to compare host and scheme first. + if (firstNeedsDevice || secondNeedsDevice) { + // Paths needing a device are "larger" than those not needing one. + if (firstNeedsDevice < secondNeedsDevice) + return true; + else if (firstNeedsDevice > secondNeedsDevice) + return false; + + // First we sort by scheme ... + const int s = first.scheme().compare(second.scheme()); + if (s != 0) + return s < 0; + + // than by host ... + const int h = first.host().compare(second.host()); + if (h != 0) + return h < 0; + } + + const int p = first.pathView().compare(second.pathView(), first.caseSensitivity()); + return p < 0; } QTCREATOR_UTILS_EXPORT bool operator<=(const FilePath &first, const FilePath &second) diff --git a/tests/auto/utils/filepath/tst_filepath.cpp b/tests/auto/utils/filepath/tst_filepath.cpp index 0cd0629609e..369fb6a2584 100644 --- a/tests/auto/utils/filepath/tst_filepath.cpp +++ b/tests/auto/utils/filepath/tst_filepath.cpp @@ -117,6 +117,11 @@ private slots: void isRootPath(); + void lessThan(); + void lessThan_data(); + + void asQMapKey(); + private: QTemporaryDir tempDir; QString rootPath; @@ -1666,6 +1671,42 @@ void tst_filepath::sort() QCOMPARE(sortedPaths, sorted); } +void tst_filepath::lessThan_data() +{ + QTest::addColumn("left"); + QTest::addColumn("right"); + QTest::addColumn("expected"); + + QTest::newRow("empty") << FilePath() << FilePath() << false; + QTest::newRow("simple") << FilePath("/a") << FilePath("/b") << true; + QTest::newRow("simple-2") << FilePath("/a") << FilePath("/a") << false; + QTest::newRow("simple-3") << FilePath("/b") << FilePath("/a") << false; + + QTest::newRow("remote-vs-local") << FilePath("docker://1234/a") << FilePath("/a") << false; + QTest::newRow("local-vs-remote") << FilePath("/a") << FilePath("docker://1234/a") << true; + + QTest::newRow("remote-vs-local-2") << FilePath("docker://1234/a") << FilePath("/b") << false; + QTest::newRow("local-vs-remote-2") << FilePath("/a") << FilePath("docker://1234/b") << true; +} + +void tst_filepath::lessThan() +{ + QFETCH(FilePath, left); + QFETCH(FilePath, right); + QFETCH(bool, expected); + + QCOMPARE(left < right, expected); +} + +void tst_filepath::asQMapKey() +{ + QMap map; + map.insert(FilePath::fromString("/Users/mtillmanns/projects/qt/qtc-work/fsengine"), 1); + + QCOMPARE(map.contains(FilePath::fromString("ssh://marcus@mad-ubuntu-23.local/tmp/untitled")), + false); +} + void tst_filepath::isRootPath() { FilePath localRoot = FilePath::fromString(QDir::rootPath());