From 47b03783d225412c45b6fcd4e02e16b021464eaf Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 23 Sep 2024 13:34:05 +0200 Subject: [PATCH] Axivion: Start using the path mapping In case the one uses the axivion perspective without an open project we could not open files from the issues table without the matching project opened. The mapping allows to find the preferred location for a file of a project even if the project is not opened. We explicitly give the mapping no precedence as * open a file without a project results in follow-up problems like additional syntax / semantic highlighting markers * having a project open which has the respective file listed is more likely to be the correct one than some mapping, e.g. working with different folders for different branches may end up opening a matching file from the other project folder / branch otherwise Change-Id: I0d410f835ca2857cc2d10f09e6ba7f734dd5ff0f Reviewed-by: Mohammad Mehdi Salem Naraghi Reviewed-by: hjk --- src/plugins/axivion/axivionperspective.cpp | 48 ++++++++++++++++++++-- src/plugins/axivion/axivionsettings.cpp | 14 ++++--- src/plugins/axivion/axivionsettings.h | 2 +- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/plugins/axivion/axivionperspective.cpp b/src/plugins/axivion/axivionperspective.cpp index fe677329b56..86baa4b50ff 100644 --- a/src/plugins/axivion/axivionperspective.cpp +++ b/src/plugins/axivion/axivionperspective.cpp @@ -80,6 +80,33 @@ struct LinkWithColumns static bool issueListContextMenuEvent(const ItemViewEvent &ev); // impl at bottom +static std::optional findPathMappingMatch(const QString &projectName, + const Link &link) +{ + QTC_ASSERT(!projectName.isEmpty(), return std::nullopt); + for (const PathMapping &mapping : settings().validPathMappings()) { + if (mapping.projectName != projectName) + continue; + if (mapping.localPath.isRelativePath()) // TODO mark inside settings + continue; + if (mapping.analysisPath.isAbsolutePath()) // TODO mark inside settings + continue; + + if (mapping.analysisPath.isEmpty()) + return mapping; + + QString analysis = mapping.analysisPath.toString(); + // ensure we use complete paths + if (!analysis.endsWith('/')) + analysis.append('/'); + if (!link.targetFilePath.startsWith(analysis)) + continue; + + return mapping; + } + return std::nullopt; +} + class IssueListItem final : public ListItem { public: @@ -109,9 +136,24 @@ public: = Utils::findOr(m_links, m_links.first(), [column](const LinkWithColumns &link) { return link.columns.contains(column); }).link; - Project *project = ProjectManager::startupProject(); - FilePath baseDir = project ? project->projectDirectory() : FilePath{}; - link.targetFilePath = findFileForIssuePath(link.targetFilePath); + + // get the file path either by the open project(s) or by using the path mapping + // prefer to use the open project's file instead of some generic approach + const FilePath computedPath = findFileForIssuePath(link.targetFilePath); + FilePath targetFilePath; + if (!computedPath.exists()) { + if (const std::optional pInfo = projectInfo()) { + if (auto mapping = findPathMappingMatch(pInfo->name, link)) { + std::optional fp = link.targetFilePath.prefixRemoved( + mapping->analysisPath.toString()); + QTC_CHECK(fp); + fp = mapping->localPath.pathAppended(fp->toString()); + if (fp->exists()) + targetFilePath = *fp; + } + } + } + link.targetFilePath = targetFilePath.isEmpty() ? computedPath : targetFilePath; if (link.targetFilePath.exists()) EditorManager::openEditorAt(link); } diff --git a/src/plugins/axivion/axivionsettings.cpp b/src/plugins/axivion/axivionsettings.cpp index 776bb7f6793..c19748148f6 100644 --- a/src/plugins/axivion/axivionsettings.cpp +++ b/src/plugins/axivion/axivionsettings.cpp @@ -171,7 +171,11 @@ public: } QVariant variantValue() const final { return pathMappingsToSetting(m_pathMapping); } - const QList pathMappings() const { return m_pathMapping; } + + const QList validPathMappings() const + { + return Utils::filtered(m_pathMapping, &PathMapping::isValid); + } private: QList m_pathMapping; @@ -254,9 +258,9 @@ void AxivionSettings::updateDashboardServers(const QList &other) emit changed(); // should we be more detailed? (id) } -const QList AxivionSettings::pathMappings() const +const QList AxivionSettings::validPathMappings() const { - return pathMappingSettings().pathMappings(); + return pathMappingSettings().validPathMappings(); } // AxivionSettingsPage @@ -574,7 +578,7 @@ PathMappingSettingsWidget::PathMappingSettingsWidget() m_detailsWidget }.attachTo(this); - const QList items = Utils::transform(pathMappingSettings().pathMappings(), + const QList items = Utils::transform(pathMappingSettings().validPathMappings(), [this](const PathMapping &m) { QTreeWidgetItem *item = new QTreeWidgetItem(&m_mappingTree, {m.projectName, @@ -604,7 +608,7 @@ PathMappingSettingsWidget::PathMappingSettingsWidget() void PathMappingSettingsWidget::apply() { - const QList oldMappings = settings().pathMappings(); + const QList oldMappings = settings().validPathMappings(); QList newMappings; for (int row = 0, count = m_mappingTree.topLevelItemCount(); row < count; ++row) { const QTreeWidgetItem * const item = m_mappingTree.topLevelItem(row); diff --git a/src/plugins/axivion/axivionsettings.h b/src/plugins/axivion/axivionsettings.h index 62eef67395d..3ca45d6026a 100644 --- a/src/plugins/axivion/axivionsettings.h +++ b/src/plugins/axivion/axivionsettings.h @@ -58,7 +58,7 @@ public: void disableCertificateValidation(const Utils::Id &id); const QList allAvailableServers() const { return m_allServers; }; void updateDashboardServers(const QList &other); - const QList pathMappings() const; + const QList validPathMappings() const; Utils::BoolAspect highlightMarks{this}; private: