summaryrefslogtreecommitdiff
path: root/src/libs/utils/fileinprojectfinder.cpp
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@theqtcompany.com>2015-02-05 11:52:03 +0100
committerJoerg Bornemann <joerg.bornemann@theqtcompany.com>2015-02-05 16:29:08 +0000
commit4e09ec98c7d0d757693717a276ec324d76c8daf1 (patch)
tree4d7bfa01f2d56b71288669fd23b030089695ca69 /src/libs/utils/fileinprojectfinder.cpp
parenta9454b3e557088eab8e1ee768c47d67dc0308e59 (diff)
downloadqt-creator-4e09ec98c7d0d757693717a276ec324d76c8daf1.tar.gz
Utils: make FileInProjectFinder work with same file names
Consider having files with the same name in different subdirectories of your project. The FileInProjectFinder will now choose the best matching file path, which is the one that has the longest right-aligned common substring with the path to find. For the candidates ["/home/jim/MyProject/Resources/qml/1/foo.qml", "/home/jim/MyProject/Resources/qml/2/foo.qml"] and the file path to find being "/SomeWhere/Else/qml/2/foo.qml" the ranks are 8 and 10. Therefore, the second path is chosen. Task-number: QTCREATORBUG-12908 Change-Id: I6225fd1dce8cc79a90d02ae0a54cdf80f75f45af Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com> Reviewed-by: Ulf Hermann <ulf.hermann@theqtcompany.com>
Diffstat (limited to 'src/libs/utils/fileinprojectfinder.cpp')
-rw-r--r--src/libs/utils/fileinprojectfinder.cpp63
1 files changed, 52 insertions, 11 deletions
diff --git a/src/libs/utils/fileinprojectfinder.cpp b/src/libs/utils/fileinprojectfinder.cpp
index 1450b7bef6..a4170bbbf3 100644
--- a/src/libs/utils/fileinprojectfinder.cpp
+++ b/src/libs/utils/fileinprojectfinder.cpp
@@ -36,6 +36,8 @@
#include <QFileInfo>
#include <QUrl>
+#include <algorithm>
+
enum { debug = false };
namespace Utils {
@@ -212,20 +214,19 @@ QString FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const
}
}
- // find (solely by filename) in project files
+ // find best matching file path in project files
if (debug)
qDebug() << "FileInProjectFinder: checking project files ...";
- const QString fileName = FileName::fromString(originalPath).fileName();
- foreach (const QString &f, m_projectFiles) {
- if (FileName::fromString(f).fileName() == fileName) {
- m_cache.insert(originalPath, f);
- if (success)
- *success = true;
- if (debug)
- qDebug() << "FileInProjectFinder: found" << f << "in project files";
- return f;
- }
+ const QString matchedFilePath
+ = bestMatch(
+ filesWithSameFileName(FileName::fromString(originalPath).fileName()),
+ originalPath);
+ if (!matchedFilePath.isEmpty()) {
+ m_cache.insert(originalPath, matchedFilePath);
+ if (success)
+ *success = true;
+ return matchedFilePath;
}
if (debug)
@@ -252,4 +253,44 @@ QString FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const
return originalPath;
}
+QStringList FileInProjectFinder::filesWithSameFileName(const QString &fileName) const
+{
+ QStringList result;
+ foreach (const QString &f, m_projectFiles) {
+ if (FileName::fromString(f).fileName() == fileName)
+ result << f;
+ }
+ return result;
+}
+
+int FileInProjectFinder::rankFilePath(const QString &candidatePath, const QString &filePathToFind)
+{
+ int rank = 0;
+ for (int a = candidatePath.length(), b = filePathToFind.length();
+ --a >= 0 && --b >= 0 && candidatePath.at(a) == filePathToFind.at(b);)
+ rank++;
+ return rank;
+}
+
+QString FileInProjectFinder::bestMatch(const QStringList &filePaths, const QString &filePathToFind)
+{
+ if (filePaths.isEmpty())
+ return QString();
+ if (filePaths.length() == 1) {
+ if (debug)
+ qDebug() << "FileInProjectFinder: found" << filePaths.first() << "in project files";
+ return filePaths.first();
+ }
+ auto it = std::max_element(filePaths.constBegin(), filePaths.constEnd(),
+ [&filePathToFind] (const QString &a, const QString &b) -> bool {
+ return rankFilePath(a, filePathToFind) < rankFilePath(b, filePathToFind);
+ });
+ if (it != filePaths.cend()) {
+ if (debug)
+ qDebug() << "FileInProjectFinder: found best match" << *it << "in project files";
+ return *it;
+ }
+ return QString();
+}
+
} // namespace Utils