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 <mehdi.salem@qt.io>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Stenger
2024-09-23 13:34:05 +02:00
parent 36bbcb223c
commit 47b03783d2
3 changed files with 55 additions and 9 deletions

View File

@@ -80,6 +80,33 @@ struct LinkWithColumns
static bool issueListContextMenuEvent(const ItemViewEvent &ev); // impl at bottom static bool issueListContextMenuEvent(const ItemViewEvent &ev); // impl at bottom
static std::optional<PathMapping> 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 class IssueListItem final : public ListItem
{ {
public: public:
@@ -109,9 +136,24 @@ public:
= Utils::findOr(m_links, m_links.first(), [column](const LinkWithColumns &link) { = Utils::findOr(m_links, m_links.first(), [column](const LinkWithColumns &link) {
return link.columns.contains(column); return link.columns.contains(column);
}).link; }).link;
Project *project = ProjectManager::startupProject();
FilePath baseDir = project ? project->projectDirectory() : FilePath{}; // get the file path either by the open project(s) or by using the path mapping
link.targetFilePath = findFileForIssuePath(link.targetFilePath); // 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<Dto::ProjectInfoDto> pInfo = projectInfo()) {
if (auto mapping = findPathMappingMatch(pInfo->name, link)) {
std::optional<FilePath> 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()) if (link.targetFilePath.exists())
EditorManager::openEditorAt(link); EditorManager::openEditorAt(link);
} }

View File

@@ -171,7 +171,11 @@ public:
} }
QVariant variantValue() const final { return pathMappingsToSetting(m_pathMapping); } QVariant variantValue() const final { return pathMappingsToSetting(m_pathMapping); }
const QList<PathMapping> pathMappings() const { return m_pathMapping; }
const QList<PathMapping> validPathMappings() const
{
return Utils::filtered(m_pathMapping, &PathMapping::isValid);
}
private: private:
QList<PathMapping> m_pathMapping; QList<PathMapping> m_pathMapping;
@@ -254,9 +258,9 @@ void AxivionSettings::updateDashboardServers(const QList<AxivionServer> &other)
emit changed(); // should we be more detailed? (id) emit changed(); // should we be more detailed? (id)
} }
const QList<PathMapping> AxivionSettings::pathMappings() const const QList<PathMapping> AxivionSettings::validPathMappings() const
{ {
return pathMappingSettings().pathMappings(); return pathMappingSettings().validPathMappings();
} }
// AxivionSettingsPage // AxivionSettingsPage
@@ -574,7 +578,7 @@ PathMappingSettingsWidget::PathMappingSettingsWidget()
m_detailsWidget m_detailsWidget
}.attachTo(this); }.attachTo(this);
const QList<QTreeWidgetItem *> items = Utils::transform(pathMappingSettings().pathMappings(), const QList<QTreeWidgetItem *> items = Utils::transform(pathMappingSettings().validPathMappings(),
[this](const PathMapping &m) { [this](const PathMapping &m) {
QTreeWidgetItem *item = new QTreeWidgetItem(&m_mappingTree, QTreeWidgetItem *item = new QTreeWidgetItem(&m_mappingTree,
{m.projectName, {m.projectName,
@@ -604,7 +608,7 @@ PathMappingSettingsWidget::PathMappingSettingsWidget()
void PathMappingSettingsWidget::apply() void PathMappingSettingsWidget::apply()
{ {
const QList<PathMapping> oldMappings = settings().pathMappings(); const QList<PathMapping> oldMappings = settings().validPathMappings();
QList<PathMapping> newMappings; QList<PathMapping> newMappings;
for (int row = 0, count = m_mappingTree.topLevelItemCount(); row < count; ++row) { for (int row = 0, count = m_mappingTree.topLevelItemCount(); row < count; ++row) {
const QTreeWidgetItem * const item = m_mappingTree.topLevelItem(row); const QTreeWidgetItem * const item = m_mappingTree.topLevelItem(row);

View File

@@ -58,7 +58,7 @@ public:
void disableCertificateValidation(const Utils::Id &id); void disableCertificateValidation(const Utils::Id &id);
const QList<AxivionServer> allAvailableServers() const { return m_allServers; }; const QList<AxivionServer> allAvailableServers() const { return m_allServers; };
void updateDashboardServers(const QList<AxivionServer> &other); void updateDashboardServers(const QList<AxivionServer> &other);
const QList<PathMapping> pathMappings() const; const QList<PathMapping> validPathMappings() const;
Utils::BoolAspect highlightMarks{this}; Utils::BoolAspect highlightMarks{this};
private: private: