diff options
-rw-r--r-- | src/libs/utils/fileinprojectfinder.cpp | 137 | ||||
-rw-r--r-- | src/libs/utils/fileinprojectfinder.h | 14 | ||||
-rw-r--r-- | src/plugins/debugger/console/consoleview.cpp | 3 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerengine.cpp | 2 | ||||
-rw-r--r-- | src/plugins/perfprofiler/perfprofilertool.cpp | 2 | ||||
-rw-r--r-- | src/plugins/projectexplorer/fileinsessionfinder.cpp | 9 | ||||
-rw-r--r-- | src/plugins/projectexplorer/fileinsessionfinder.h | 4 | ||||
-rw-r--r-- | src/plugins/projectexplorer/task.cpp | 9 | ||||
-rw-r--r-- | src/plugins/projectexplorer/task.h | 1 | ||||
-rw-r--r-- | src/plugins/projectexplorer/taskmodel.cpp | 8 | ||||
-rw-r--r-- | src/plugins/projectexplorer/taskwindow.cpp | 10 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp | 2 | ||||
-rw-r--r-- | src/plugins/qtsupport/qtoutputformatter.cpp | 11 |
13 files changed, 133 insertions, 79 deletions
diff --git a/src/libs/utils/fileinprojectfinder.cpp b/src/libs/utils/fileinprojectfinder.cpp index 04495893920..054e5d9c3b4 100644 --- a/src/libs/utils/fileinprojectfinder.cpp +++ b/src/libs/utils/fileinprojectfinder.cpp @@ -31,11 +31,13 @@ #include "qrcparser.h" #include "qtcassert.h" +#include <QCursor> #include <QDebug> +#include <QDir> #include <QFileInfo> #include <QLoggingCategory> +#include <QMenu> #include <QUrl> -#include <QDir> #include <algorithm> @@ -140,12 +142,12 @@ void FileInProjectFinder::addMappedPath(const FileName &localFilePath, const QSt folder specified. Third, we walk the list of project files, and search for a file name match there. If all fails, it returns the original path from the file URL. */ -QString FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const +FileNameList FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const { qCDebug(finderLog) << "FileInProjectFinder: trying to find file" << fileUrl.toString() << "..."; if (fileUrl.scheme() == "qrc" || fileUrl.toString().startsWith(':')) { - const QString result = m_qrcUrlFinder.find(fileUrl); + const FileNameList result = m_qrcUrlFinder.find(fileUrl); if (!result.isEmpty()) { if (success) *success = true; @@ -157,10 +159,12 @@ QString FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const if (originalPath.isEmpty()) // e.g. qrc:// originalPath = fileUrl.path(); - QString result = originalPath; + FileNameList result; bool found = findFileOrDirectory(originalPath, [&](const QString &fileName, int) { - result = fileName; + result << FileName::fromString(fileName); }); + if (!found) + result << FileName::fromString(originalPath); if (success) *success = found; @@ -168,12 +172,12 @@ QString FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const return result; } -bool FileInProjectFinder::handleSuccess(const QString &originalPath, const QString &found, +bool FileInProjectFinder::handleSuccess(const QString &originalPath, const QStringList &found, int matchLength, const char *where) const { qCDebug(finderLog) << "FileInProjectFinder: found" << found << where; CacheEntry entry; - entry.path = found; + entry.paths = found; entry.matchLength = matchLength; m_cache.insert(originalPath, entry); return true; @@ -202,8 +206,10 @@ bool FileInProjectFinder::findFileOrDirectory(const QString &originalPath, FileH if (node) { if (!node->localPath.isEmpty()) { const QString localPath = node->localPath.toString(); - if (checkPath(localPath, origLength, fileHandler, directoryHandler)) - return handleSuccess(originalPath, localPath, origLength, "in mapped paths"); + if (checkPath(localPath, origLength, fileHandler, directoryHandler)) { + return handleSuccess(originalPath, QStringList(localPath), origLength, + "in mapped paths"); + } } else if (directoryHandler) { directoryHandler(node->children.keys(), origLength); qCDebug(finderLog) << "FileInProjectFinder: found virtual directory" << originalPath @@ -216,13 +222,18 @@ bool FileInProjectFinder::findFileOrDirectory(const QString &originalPath, FileH if (it != m_cache.end()) { qCDebug(finderLog) << "FileInProjectFinder: checking cache ..."; // check if cached path is still there - const CacheEntry &candidate = it.value(); - if (checkPath(candidate.path, candidate.matchLength, fileHandler, directoryHandler)) { - qCDebug(finderLog) << "FileInProjectFinder: found" << candidate.path << "in the cache"; - return true; - } else { - m_cache.erase(it); + CacheEntry &candidate = it.value(); + for (auto pathIt = candidate.paths.begin(); pathIt != candidate.paths.end();) { + if (checkPath(*pathIt, candidate.matchLength, fileHandler, directoryHandler)) { + qCDebug(finderLog) << "FileInProjectFinder: found" << *pathIt << "in the cache"; + ++pathIt; + } else { + pathIt = candidate.paths.erase(pathIt); + } } + if (!candidate.paths.empty()) + return true; + m_cache.erase(it); } if (!m_projectDir.isEmpty()) { @@ -244,7 +255,7 @@ bool FileInProjectFinder::findFileOrDirectory(const QString &originalPath, FileH if (prefixToIgnore == -1 && checkPath(originalPath, origLength, fileHandler, directoryHandler)) { - return handleSuccess(originalPath, originalPath, origLength, + return handleSuccess(originalPath, QStringList(originalPath), origLength, "in project directory"); } } @@ -267,8 +278,11 @@ bool FileInProjectFinder::findFileOrDirectory(const QString &originalPath, FileH candidate.remove(0, prefixToIgnore); candidate.prepend(m_projectDir.toString()); const int matchLength = origLength - prefixToIgnore; - if (checkPath(candidate, matchLength, fileHandler, directoryHandler)) - return handleSuccess(originalPath, candidate, matchLength, "in project directory"); + // FIXME: This might be a worse match than what we find later. + if (checkPath(candidate, matchLength, fileHandler, directoryHandler)) { + return handleSuccess(originalPath, QStringList(candidate), matchLength, + "in project directory"); + } prefixToIgnore = originalPath.indexOf(separator, prefixToIgnore + 1); } } @@ -282,17 +296,23 @@ bool FileInProjectFinder::findFileOrDirectory(const QString &originalPath, FileH matches.append(filesWithSameFileName(lastSegment)); if (directoryHandler) matches.append(pathSegmentsWithSameName(lastSegment)); - const QString matchedFilePath = bestMatch(matches, originalPath); - const int matchLength = commonPostFixLength(matchedFilePath, originalPath); - if (!matchedFilePath.isEmpty() - && checkPath(matchedFilePath, matchLength, fileHandler, directoryHandler)) { - return handleSuccess(originalPath, matchedFilePath, matchLength, - "when matching project files"); + const QStringList matchedFilePaths = bestMatches(matches, originalPath); + if (!matchedFilePaths.empty()) { + const int matchLength = commonPostFixLength(matchedFilePaths.first(), originalPath); + QStringList hits; + for (const QString &matchedFilePath : matchedFilePaths) { + if (checkPath(matchedFilePath, matchLength, fileHandler, directoryHandler)) + hits << matchedFilePath; + } + if (!hits.empty()) + return handleSuccess(originalPath, hits, matchLength, "when matching project files"); } CacheEntry foundPath = findInSearchPaths(originalPath, fileHandler, directoryHandler); - if (!foundPath.path.isEmpty()) - return handleSuccess(originalPath, foundPath.path, foundPath.matchLength, "in search path"); + if (!foundPath.paths.isEmpty()) { + return handleSuccess(originalPath, foundPath.paths, foundPath.matchLength, + "in search path"); + } qCDebug(finderLog) << "FileInProjectFinder: checking absolute path in sysroot ..."; @@ -300,8 +320,10 @@ bool FileInProjectFinder::findFileOrDirectory(const QString &originalPath, FileH if (!m_sysroot.isEmpty()) { FileName sysrootPath = m_sysroot; sysrootPath.appendPath(originalPath); - if (checkPath(sysrootPath.toString(), origLength, fileHandler, directoryHandler)) - return handleSuccess(originalPath, sysrootPath.toString(), origLength, "in sysroot"); + if (checkPath(sysrootPath.toString(), origLength, fileHandler, directoryHandler)) { + return handleSuccess(originalPath, QStringList(sysrootPath.toString()), origLength, + "in sysroot"); + } } qCDebug(finderLog) << "FileInProjectFinder: couldn't find file!"; @@ -315,7 +337,7 @@ FileInProjectFinder::CacheEntry FileInProjectFinder::findInSearchPaths( for (const FileName &dirPath : m_searchDirectories) { const CacheEntry found = findInSearchPath(dirPath.toString(), filePath, fileHandler, directoryHandler); - if (!found.path.isEmpty()) + if (!found.paths.isEmpty()) return found; } @@ -340,17 +362,17 @@ FileInProjectFinder::CacheEntry FileInProjectFinder::findInSearchPath( QString s = filePath; while (!s.isEmpty()) { CacheEntry result; - result.path = searchPath + QLatin1Char('/') + s; + result.paths << searchPath + '/' + s; result.matchLength = s.length() + 1; - qCDebug(finderLog) << "FileInProjectFinder: trying" << result.path; + qCDebug(finderLog) << "FileInProjectFinder: trying" << result.paths.first(); - if (checkPath(result.path, result.matchLength, fileHandler, directoryHandler)) + if (checkPath(result.paths.first(), result.matchLength, fileHandler, directoryHandler)) return result; QString next = chopFirstDir(s); if (next.isEmpty()) { if (directoryHandler && QFileInfo(searchPath).fileName() == s) { - result.path = searchPath; + result.paths = QStringList{searchPath}; directoryHandler(QDir(searchPath).entryList(), result.matchLength); return result; } @@ -399,24 +421,30 @@ int FileInProjectFinder::commonPostFixLength(const QString &candidatePath, return rank; } -QString FileInProjectFinder::bestMatch(const QStringList &filePaths, const QString &filePathToFind) +QStringList FileInProjectFinder::bestMatches(const QStringList &filePaths, + const QString &filePathToFind) { if (filePaths.isEmpty()) - return QString(); + return {}; if (filePaths.length() == 1) { qCDebug(finderLog) << "FileInProjectFinder: found" << filePaths.first() << "in project files"; - return filePaths.first(); + return filePaths; } - auto it = std::max_element(filePaths.constBegin(), filePaths.constEnd(), - [&filePathToFind] (const QString &a, const QString &b) -> bool { - return commonPostFixLength(a, filePathToFind) < commonPostFixLength(b, filePathToFind); - }); - if (it != filePaths.cend()) { - qCDebug(finderLog) << "FileInProjectFinder: found best match" << *it << "in project files"; - return *it; + int bestRank = -1; + QStringList bestFilePaths; + for (const QString &fp : filePaths) { + const int currentRank = commonPostFixLength(fp, filePathToFind); + if (currentRank < bestRank) + continue; + if (currentRank > bestRank) { + bestRank = currentRank; + bestFilePaths.clear(); + } + bestFilePaths << fp; } - return QString(); + QTC_CHECK(!bestFilePaths.empty()); + return bestFilePaths; } FileNameList FileInProjectFinder::searchDirectories() const @@ -434,9 +462,9 @@ FileInProjectFinder::PathMappingNode::~PathMappingNode() qDeleteAll(children); } -QString FileInProjectFinder::QrcUrlFinder::find(const QUrl &fileUrl) const +FileNameList FileInProjectFinder::QrcUrlFinder::find(const QUrl &fileUrl) const { - QString result; + FileNameList result; const auto fileIt = m_fileCache.constFind(fileUrl); if (fileIt != m_fileCache.cend()) return fileIt.value(); @@ -448,10 +476,7 @@ QString FileInProjectFinder::QrcUrlFinder::find(const QUrl &fileUrl) const continue; QStringList hits; qrcParser->collectFilesAtPath(QrcParser::normalizedQrcFilePath(fileUrl.toString()), &hits); - if (!hits.empty()) { - result = hits.first(); - break; - } + result = transform(hits, [](const QString &fp) { return FileName::fromString(fp); }); } m_fileCache.insert(fileUrl, result); return result; @@ -464,4 +489,16 @@ void FileInProjectFinder::QrcUrlFinder::setProjectFiles(const FileNameList &proj m_parserCache.clear(); } +FileName chooseFileFromList(const FileNameList &candidates) +{ + if (candidates.length() == 1) + return candidates.first(); + QMenu filesMenu; + for (const FileName &candidate : candidates) + filesMenu.addAction(candidate.toUserOutput()); + if (const QAction * const action = filesMenu.exec(QCursor::pos())) + return FileName::fromUserInput(action->text()); + return FileName(); +} + } // namespace Utils diff --git a/src/libs/utils/fileinprojectfinder.h b/src/libs/utils/fileinprojectfinder.h index 2b1dc940902..ac8cd0a588c 100644 --- a/src/libs/utils/fileinprojectfinder.h +++ b/src/libs/utils/fileinprojectfinder.h @@ -55,7 +55,7 @@ public: void addMappedPath(const FileName &localFilePath, const QString &remoteFilePath); - QString findFile(const QUrl &fileUrl, bool *success = nullptr) const; + FileNameList findFile(const QUrl &fileUrl, bool *success = nullptr) const; bool findFileOrDirectory(const QString &originalPath, FileHandler fileHandler = nullptr, DirectoryHandler directoryHandler = nullptr) const; @@ -71,17 +71,17 @@ private: }; struct CacheEntry { - QString path; + QStringList paths; int matchLength = 0; }; class QrcUrlFinder { public: - QString find(const QUrl &fileUrl) const; + FileNameList find(const QUrl &fileUrl) const; void setProjectFiles(const FileNameList &projectFiles); private: FileNameList m_allQrcFiles; - mutable QHash<QUrl, QString> m_fileCache; + mutable QHash<QUrl, FileNameList> m_fileCache; mutable QHash<FileName, QSharedPointer<QrcParser>> m_parserCache; }; @@ -92,11 +92,11 @@ private: QStringList filesWithSameFileName(const QString &fileName) const; QStringList pathSegmentsWithSameName(const QString &path) const; - bool handleSuccess(const QString &originalPath, const QString &found, int confidence, + bool handleSuccess(const QString &originalPath, const QStringList &found, int confidence, const char *where) const; static int commonPostFixLength(const QString &candidatePath, const QString &filePathToFind); - static QString bestMatch(const QStringList &filePaths, const QString &filePathToFind); + static QStringList bestMatches(const QStringList &filePaths, const QString &filePathToFind); FileName m_projectDir; FileName m_sysroot; @@ -108,4 +108,6 @@ private: QrcUrlFinder m_qrcUrlFinder; }; +QTCREATOR_UTILS_EXPORT FileName chooseFileFromList(const FileNameList &candidates); + } // namespace Utils diff --git a/src/plugins/debugger/console/consoleview.cpp b/src/plugins/debugger/console/consoleview.cpp index 9969bfb0f5c..c6387cc9e05 100644 --- a/src/plugins/debugger/console/consoleview.cpp +++ b/src/plugins/debugger/console/consoleview.cpp @@ -218,7 +218,8 @@ void ConsoleView::onRowActivated(const QModelIndex &index) if (!index.isValid()) return; - const QFileInfo fi(m_finder.findFile(model()->data(index, ConsoleItem::FileRole).toString())); + const QFileInfo fi = m_finder.findFile(model()->data(index, ConsoleItem::FileRole).toString()) + .first().toFileInfo(); if (fi.exists() && fi.isFile() && fi.isReadable()) { Core::EditorManager::openEditorAt(fi.canonicalFilePath(), model()->data(index, ConsoleItem::LineRole).toInt()); diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 7399c99b7f9..3c9d5ce37f7 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -1828,7 +1828,7 @@ QString DebuggerEngine::toFileInProject(const QUrl &fileUrl) d->m_fileFinder.setAdditionalSearchDirectories(rp.additionalSearchDirectories); d->m_fileFinder.setSysroot(rp.sysRoot); - return d->m_fileFinder.findFile(fileUrl); + return d->m_fileFinder.findFile(fileUrl).first().toString(); } QString DebuggerEngine::expand(const QString &string) const diff --git a/src/plugins/perfprofiler/perfprofilertool.cpp b/src/plugins/perfprofiler/perfprofilertool.cpp index 57de5ce14ac..662e9ef5484 100644 --- a/src/plugins/perfprofiler/perfprofilertool.cpp +++ b/src/plugins/perfprofiler/perfprofilertool.cpp @@ -540,7 +540,7 @@ void PerfProfilerTool::gotoSourceLocation(QString filePath, int lineNumber, int QFileInfo fi(filePath); if (!fi.isAbsolute() || !fi.exists() || !fi.isReadable()) { - fi.setFile(m_fileFinder.findFile(filePath)); + fi.setFile(m_fileFinder.findFile(filePath).first().toString()); if (!fi.exists() || !fi.isReadable()) return; } diff --git a/src/plugins/projectexplorer/fileinsessionfinder.cpp b/src/plugins/projectexplorer/fileinsessionfinder.cpp index 15164f9fcc1..667cbdd22e5 100644 --- a/src/plugins/projectexplorer/fileinsessionfinder.cpp +++ b/src/plugins/projectexplorer/fileinsessionfinder.cpp @@ -29,7 +29,6 @@ #include "session.h" #include <utils/fileinprojectfinder.h> -#include <utils/fileutils.h> #include <QUrl> @@ -43,7 +42,7 @@ class FileInSessionFinder : public QObject public: FileInSessionFinder(); - FileName doFindFile(const FileName &filePath); + FileNameList doFindFile(const FileName &filePath); void invalidateFinder() { m_finderIsUpToDate = false; } private: @@ -65,7 +64,7 @@ FileInSessionFinder::FileInSessionFinder() }); } -FileName FileInSessionFinder::doFindFile(const FileName &filePath) +FileNameList FileInSessionFinder::doFindFile(const FileName &filePath) { if (!m_finderIsUpToDate) { m_finder.setProjectDirectory(SessionManager::startupProject() @@ -77,10 +76,10 @@ FileName FileInSessionFinder::doFindFile(const FileName &filePath) m_finder.setProjectFiles(allFiles); m_finderIsUpToDate = true; } - return FileName::fromString(m_finder.findFile(QUrl::fromLocalFile(filePath.toString()))); + return m_finder.findFile(QUrl::fromLocalFile(filePath.toString())); } -FileName findFileInSession(const FileName &filePath) +FileNameList findFileInSession(const FileName &filePath) { static FileInSessionFinder finder; return finder.doFindFile(filePath); diff --git a/src/plugins/projectexplorer/fileinsessionfinder.h b/src/plugins/projectexplorer/fileinsessionfinder.h index 8c31a876092..4f08e67d93d 100644 --- a/src/plugins/projectexplorer/fileinsessionfinder.h +++ b/src/plugins/projectexplorer/fileinsessionfinder.h @@ -25,12 +25,12 @@ #pragma once -namespace Utils { class FileName; } +#include <utils/fileutils.h> namespace ProjectExplorer { namespace Internal { -Utils::FileName findFileInSession(const Utils::FileName &filePath); +Utils::FileNameList findFileInSession(const Utils::FileName &filePath); } // namespace Internal } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/task.cpp b/src/plugins/projectexplorer/task.cpp index 83409fadd5a..4d334a78e8a 100644 --- a/src/plugins/projectexplorer/task.cpp +++ b/src/plugins/projectexplorer/task.cpp @@ -25,6 +25,7 @@ #include "task.h" +#include "fileinsessionfinder.h" #include "projectexplorerconstants.h" #include <app/app_version.h> @@ -34,6 +35,7 @@ #include <utils/utilsicons.h> #include <utils/qtcassert.h> +#include <QFileInfo> #include <QTextStream> namespace ProjectExplorer @@ -67,6 +69,13 @@ Task::Task(TaskType type_, const QString &description_, icon(icon.isNull() ? taskTypeIcon(type_) : icon) { ++s_nextId; + if (!file.isEmpty() && !file.toFileInfo().isAbsolute()) { + Utils::FileNameList possiblePaths = Internal::findFileInSession(file); + if (possiblePaths.length() == 1) + file = possiblePaths.first(); + else + fileCandidates = possiblePaths; + } } Task Task::compilerMissingTask() diff --git a/src/plugins/projectexplorer/task.h b/src/plugins/projectexplorer/task.h index f3e1b76c88b..b8b80784aa4 100644 --- a/src/plugins/projectexplorer/task.h +++ b/src/plugins/projectexplorer/task.h @@ -76,6 +76,7 @@ public: Options options = AddTextMark | FlashWorthy; QString description; Utils::FileName file; + Utils::FileNameList fileCandidates; int line = -1; int movedLine = -1; // contains a line number if the line was moved in the editor Core::Id category; diff --git a/src/plugins/projectexplorer/taskmodel.cpp b/src/plugins/projectexplorer/taskmodel.cpp index 1780bb4870a..1cae2b60a68 100644 --- a/src/plugins/projectexplorer/taskmodel.cpp +++ b/src/plugins/projectexplorer/taskmodel.cpp @@ -104,14 +104,8 @@ bool sortById(const Task &task, unsigned int id) return task.taskId < id; } -void TaskModel::addTask(const Task &t) +void TaskModel::addTask(const Task &task) { - Task task = t; - if (!task.file.isEmpty() && !task.file.toFileInfo().isAbsolute()) { - const Utils::FileName fullFilePath = findFileInSession(task.file); - if (!fullFilePath.isEmpty()) - task.file = fullFilePath; - } Q_ASSERT(m_categories.keys().contains(task.category)); CategoryData &data = m_categories[task.category]; CategoryData &global = m_categories[Core::Id()]; diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index 38c21fbdddc..95f3c081298 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -38,6 +38,7 @@ #include <coreplugin/icontext.h> #include <utils/algorithm.h> +#include <utils/fileinprojectfinder.h> #include <utils/qtcassert.h> #include <utils/itemviews.h> #include <utils/utilsicons.h> @@ -498,6 +499,15 @@ void TaskWindow::triggerDefaultHandler(const QModelIndex &index) if (task.isNull()) return; + if (!task.file.isEmpty() && !task.file.toFileInfo().isAbsolute() + && !task.fileCandidates.empty()) { + const Utils::FileName userChoice = Utils::chooseFileFromList(task.fileCandidates); + if (!userChoice.isEmpty()) { + task.file = userChoice; + updatedTaskFileName(task.taskId, task.file.toString()); + } + } + if (d->m_defaultHandler->canHandle(task)) { d->m_defaultHandler->handle(task); } else { diff --git a/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp b/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp index e96a92623f8..cc97f7eb6a3 100644 --- a/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp @@ -112,7 +112,7 @@ void QmlProfilerDetailsRewriter::requestDetailsForLocation(int typeId, QString QmlProfilerDetailsRewriter::getLocalFile(const QString &remoteFile) { - const QString localFile = m_projectFinder.findFile(remoteFile); + const QString localFile = m_projectFinder.findFile(remoteFile).first().toString(); const QFileInfo fileInfo(localFile); if (!fileInfo.exists() || !fileInfo.isReadable()) return QString(); diff --git a/src/plugins/qtsupport/qtoutputformatter.cpp b/src/plugins/qtsupport/qtoutputformatter.cpp index cb98654858c..f554c6e8946 100644 --- a/src/plugins/qtsupport/qtoutputformatter.cpp +++ b/src/plugins/qtsupport/qtoutputformatter.cpp @@ -211,13 +211,14 @@ void QtOutputFormatter::handleLink(const QString &href) ":(\\d+)$"); // column const QRegularExpressionMatch qmlLineColumnMatch = qmlLineColumnLink.match(href); + const auto getFileToOpen = [this](const QUrl &fileUrl) { + return chooseFileFromList(d->projectFinder.findFile(fileUrl)).toString(); + }; if (qmlLineColumnMatch.hasMatch()) { const QUrl fileUrl = QUrl(qmlLineColumnMatch.captured(1)); const int line = qmlLineColumnMatch.captured(2).toInt(); const int column = qmlLineColumnMatch.captured(3).toInt(); - - openEditor(d->projectFinder.findFile(fileUrl), line, column - 1); - + openEditor(getFileToOpen(fileUrl), line, column - 1); return; } @@ -228,7 +229,7 @@ void QtOutputFormatter::handleLink(const QString &href) if (qmlLineMatch.hasMatch()) { const QUrl fileUrl = QUrl(qmlLineMatch.captured(1)); const int line = qmlLineMatch.captured(2).toInt(); - openEditor(d->projectFinder.findFile(fileUrl), line); + openEditor(getFileToOpen(fileUrl), line); return; } @@ -257,7 +258,7 @@ void QtOutputFormatter::handleLink(const QString &href) } if (!fileName.isEmpty()) { - fileName = d->projectFinder.findFile(QUrl::fromLocalFile(fileName)); + fileName = getFileToOpen(QUrl::fromLocalFile(fileName)); openEditor(fileName, line); return; } |