diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2019-02-25 14:21:42 +0100 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2019-02-25 14:52:35 +0000 |
commit | f3778d77fecbf423c876661991954e2538e31a8a (patch) | |
tree | fc38e35deb8bdf428891cda5472c6060c18fa18e /src | |
parent | 2b1b00d0e6261bb47660d569553d639a59a73a77 (diff) | |
download | qt-creator-f3778d77fecbf423c876661991954e2538e31a8a.tar.gz |
ProjectExplorer: Add fallback finder for file paths in issues pane
The more specific output parsers often fail to resolve relative file
paths, so add a fallback that attempts to find the corresponding file in
the current session.
A follow-up patch should add support for manual ambiguity resolving.
Change-Id: If0aecbab0f3bf1aa779f4a538076c87ae6bf22d4
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/projectexplorer/fileinsessionfinder.cpp | 90 | ||||
-rw-r--r-- | src/plugins/projectexplorer/fileinsessionfinder.h | 36 | ||||
-rw-r--r-- | src/plugins/projectexplorer/projectexplorer.pro | 2 | ||||
-rw-r--r-- | src/plugins/projectexplorer/projectexplorer.qbs | 1 | ||||
-rw-r--r-- | src/plugins/projectexplorer/taskmodel.cpp | 21 | ||||
-rw-r--r-- | src/plugins/projectexplorer/taskmodel.h | 4 | ||||
-rw-r--r-- | src/plugins/projectexplorer/taskwindow.cpp | 2 |
7 files changed, 147 insertions, 9 deletions
diff --git a/src/plugins/projectexplorer/fileinsessionfinder.cpp b/src/plugins/projectexplorer/fileinsessionfinder.cpp new file mode 100644 index 0000000000..15164f9fcc --- /dev/null +++ b/src/plugins/projectexplorer/fileinsessionfinder.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "fileinsessionfinder.h" + +#include "project.h" +#include "session.h" + +#include <utils/fileinprojectfinder.h> +#include <utils/fileutils.h> + +#include <QUrl> + +using namespace Utils; + +namespace ProjectExplorer { +namespace Internal { + +class FileInSessionFinder : public QObject +{ +public: + FileInSessionFinder(); + + FileName doFindFile(const FileName &filePath); + void invalidateFinder() { m_finderIsUpToDate = false; } + +private: + FileInProjectFinder m_finder; + bool m_finderIsUpToDate = false; +}; + +FileInSessionFinder::FileInSessionFinder() +{ + connect(SessionManager::instance(), &SessionManager::projectAdded, + this, [this](const Project *p) { + invalidateFinder(); + connect(p, &Project::fileListChanged, this, &FileInSessionFinder::invalidateFinder); + }); + connect(SessionManager::instance(), &SessionManager::projectRemoved, + this, [this](const Project *p) { + invalidateFinder(); + p->disconnect(this); + }); +} + +FileName FileInSessionFinder::doFindFile(const FileName &filePath) +{ + if (!m_finderIsUpToDate) { + m_finder.setProjectDirectory(SessionManager::startupProject() + ? SessionManager::startupProject()->projectDirectory() + : FileName()); + FileNameList allFiles; + for (const Project * const p : SessionManager::projects()) + allFiles << p->files(Project::AllFiles); + m_finder.setProjectFiles(allFiles); + m_finderIsUpToDate = true; + } + return FileName::fromString(m_finder.findFile(QUrl::fromLocalFile(filePath.toString()))); +} + +FileName findFileInSession(const FileName &filePath) +{ + static FileInSessionFinder finder; + return finder.doFindFile(filePath); +} + +} // namespace Internal +} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/fileinsessionfinder.h b/src/plugins/projectexplorer/fileinsessionfinder.h new file mode 100644 index 0000000000..8c31a87609 --- /dev/null +++ b/src/plugins/projectexplorer/fileinsessionfinder.h @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +namespace Utils { class FileName; } + +namespace ProjectExplorer { +namespace Internal { + +Utils::FileName findFileInSession(const Utils::FileName &filePath); + +} // namespace Internal +} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro index c88962827f..ef62139156 100644 --- a/src/plugins/projectexplorer/projectexplorer.pro +++ b/src/plugins/projectexplorer/projectexplorer.pro @@ -18,6 +18,7 @@ HEADERS += projectexplorer.h \ environmentaspect.h \ environmentaspectwidget.h \ extraabi.h \ + fileinsessionfinder.h \ filterkitaspectsdialog.h \ gcctoolchain.h \ importwidget.h \ @@ -171,6 +172,7 @@ SOURCES += projectexplorer.cpp \ environmentaspect.cpp \ environmentaspectwidget.cpp \ extraabi.cpp \ + fileinsessionfinder.cpp \ filterkitaspectsdialog.cpp \ gcctoolchain.cpp \ importwidget.cpp \ diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs index c7a1a903dc..d10d5eb28c 100644 --- a/src/plugins/projectexplorer/projectexplorer.qbs +++ b/src/plugins/projectexplorer/projectexplorer.qbs @@ -70,6 +70,7 @@ Project { "expanddata.cpp", "expanddata.h", "extraabi.cpp", "extraabi.h", "extracompiler.cpp", "extracompiler.h", + "fileinsessionfinder.cpp", "fileinsessionfinder.h", "filterkitaspectsdialog.cpp", "filterkitaspectsdialog.h", "foldernavigationwidget.cpp", "foldernavigationwidget.h", "gccparser.cpp", "gccparser.h", diff --git a/src/plugins/projectexplorer/taskmodel.cpp b/src/plugins/projectexplorer/taskmodel.cpp index 3a1ecda5c3..1780bb4870 100644 --- a/src/plugins/projectexplorer/taskmodel.cpp +++ b/src/plugins/projectexplorer/taskmodel.cpp @@ -25,11 +25,13 @@ #include "taskmodel.h" +#include "fileinsessionfinder.h" #include "task.h" #include "taskhub.h" #include <utils/qtcassert.h> +#include <QFileInfo> #include <QFontMetrics> #include <algorithm> @@ -102,8 +104,14 @@ bool sortById(const Task &task, unsigned int id) return task.taskId < id; } -void TaskModel::addTask(const Task &task) +void TaskModel::addTask(const Task &t) { + 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()]; @@ -117,17 +125,18 @@ void TaskModel::addTask(const Task &task) endInsertRows(); } -void TaskModel::removeTask(const Task &task) +void TaskModel::removeTask(unsigned int id) { - int index = m_tasks.indexOf(task); - if (index >= 0) { + for (int index = 0; index < m_tasks.length(); ++index) { + if (m_tasks.at(index).taskId != id) + continue; const Task &t = m_tasks.at(index); - beginRemoveRows(QModelIndex(), index, index); - m_categories[task.category].removeTask(t); + m_categories[t.category].removeTask(t); m_categories[Core::Id()].removeTask(t); m_tasks.removeAt(index); endRemoveRows(); + break; } } diff --git a/src/plugins/projectexplorer/taskmodel.h b/src/plugins/projectexplorer/taskmodel.h index 4b2757c289..a0e5e5a0a4 100644 --- a/src/plugins/projectexplorer/taskmodel.h +++ b/src/plugins/projectexplorer/taskmodel.h @@ -54,8 +54,8 @@ public: void addCategory(Core::Id categoryId, const QString &categoryName); QList<Task> tasks(Core::Id categoryId = Core::Id()) const; - void addTask(const Task &task); - void removeTask(const Task &task); + void addTask(const Task &t); + void removeTask(unsigned int id); void clearTasks(Core::Id categoryId = Core::Id()); void updateTaskFileName(unsigned int id, const QString &fileName); void updateTaskLineNumber(unsigned int id, int line); diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index 2f1920a68b..38c21fbddd 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -454,7 +454,7 @@ void TaskWindow::addTask(const Task &task) void TaskWindow::removeTask(const Task &task) { - d->m_model->removeTask(task); + d->m_model->removeTask(task.taskId); emit tasksChanged(); navigateStateChanged(); |