forked from qt-creator/qt-creator
Axivion: Morph into Perspective
Replace the current approach of having separated widgets for Axivion by a perspective tying them together. This gets rid of the Axivion output pane and the mis-used navigation widget and moves their content into the Axivion perspective. This perspective is now part of the Debug view like other analyzing tools. Change-Id: I5b40c94ea32a3759fdfda41cbeaae11cc69f66cc Reviewed-by: Mohammad Mehdi Salem Naraghi <mehdi.salem@qt.io> Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -23,7 +23,6 @@ add_subdirectory(projectexplorer)
|
|||||||
add_subdirectory(silversearcher)
|
add_subdirectory(silversearcher)
|
||||||
|
|
||||||
# Level 3: (only depends on Level 2 and below)
|
# Level 3: (only depends on Level 2 and below)
|
||||||
add_subdirectory(axivion)
|
|
||||||
add_subdirectory(compilerexplorer)
|
add_subdirectory(compilerexplorer)
|
||||||
add_subdirectory(cppeditor)
|
add_subdirectory(cppeditor)
|
||||||
add_subdirectory(haskell)
|
add_subdirectory(haskell)
|
||||||
@@ -84,6 +83,7 @@ add_subdirectory(cmakeprojectmanager)
|
|||||||
# Level 7:
|
# Level 7:
|
||||||
add_subdirectory(android)
|
add_subdirectory(android)
|
||||||
add_subdirectory(autotest)
|
add_subdirectory(autotest)
|
||||||
|
add_subdirectory(axivion)
|
||||||
add_subdirectory(baremetal)
|
add_subdirectory(baremetal)
|
||||||
add_subdirectory(clangcodemodel)
|
add_subdirectory(clangcodemodel)
|
||||||
add_subdirectory(clangtools)
|
add_subdirectory(clangtools)
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
add_qtc_plugin(Axivion
|
add_qtc_plugin(Axivion
|
||||||
PLUGIN_DEPENDS
|
PLUGIN_DEPENDS
|
||||||
Core ProjectExplorer TextEditor
|
Core Debugger ProjectExplorer TextEditor
|
||||||
DEPENDS Qt::Network Qt::Widgets ExtensionSystem Utils qtkeychain
|
DEPENDS Qt::Network Qt::Widgets ExtensionSystem Utils qtkeychain
|
||||||
SOURCES
|
SOURCES
|
||||||
axivion.qrc
|
axivion.qrc
|
||||||
axivionoutputpane.cpp axivionoutputpane.h
|
axivionperspective.cpp axivionperspective.h
|
||||||
axivionplugin.cpp axivionplugin.h
|
axivionplugin.cpp axivionplugin.h
|
||||||
axivionsettings.cpp axivionsettings.h
|
axivionsettings.cpp axivionsettings.h
|
||||||
axiviontr.h
|
axiviontr.h
|
||||||
|
@@ -4,6 +4,7 @@ QtcPlugin {
|
|||||||
name: "Axivion"
|
name: "Axivion"
|
||||||
|
|
||||||
Depends { name: "Core" }
|
Depends { name: "Core" }
|
||||||
|
Depends { name: "Debugger" }
|
||||||
Depends { name: "ExtensionSystem" }
|
Depends { name: "ExtensionSystem" }
|
||||||
Depends { name: "ProjectExplorer" }
|
Depends { name: "ProjectExplorer" }
|
||||||
Depends { name: "TextEditor" }
|
Depends { name: "TextEditor" }
|
||||||
@@ -14,8 +15,8 @@ QtcPlugin {
|
|||||||
|
|
||||||
files: [
|
files: [
|
||||||
"axivion.qrc",
|
"axivion.qrc",
|
||||||
"axivionoutputpane.cpp",
|
"axivionperspective.cpp",
|
||||||
"axivionoutputpane.h",
|
"axivionperspective.h",
|
||||||
"axivionplugin.cpp",
|
"axivionplugin.cpp",
|
||||||
"axivionplugin.h",
|
"axivionplugin.h",
|
||||||
"axivionsettings.cpp",
|
"axivionsettings.cpp",
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// Copyright (C) 2022 The Qt Company Ltd.
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#include "axivionoutputpane.h"
|
#include "axivionperspective.h"
|
||||||
|
|
||||||
#include "axivionplugin.h"
|
#include "axivionplugin.h"
|
||||||
#include "axivionsettings.h"
|
#include "axivionsettings.h"
|
||||||
@@ -10,8 +10,12 @@
|
|||||||
#include "issueheaderview.h"
|
#include "issueheaderview.h"
|
||||||
#include "dynamiclistmodel.h"
|
#include "dynamiclistmodel.h"
|
||||||
|
|
||||||
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/ioutputpane.h>
|
|
||||||
|
#include <debugger/analyzer/analyzerconstants.h>
|
||||||
|
#include <debugger/debuggermainwindow.h>
|
||||||
|
|
||||||
#include <projectexplorer/projectexplorericons.h>
|
#include <projectexplorer/projectexplorericons.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
@@ -22,6 +26,7 @@
|
|||||||
#include <texteditor/textdocument.h>
|
#include <texteditor/textdocument.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/checkablemessagebox.h>
|
||||||
#include <utils/guard.h>
|
#include <utils/guard.h>
|
||||||
#include <utils/layoutbuilder.h>
|
#include <utils/layoutbuilder.h>
|
||||||
#include <utils/link.h>
|
#include <utils/link.h>
|
||||||
@@ -42,6 +47,7 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
|
#include <QTextBrowser>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
#include <QUrlQuery>
|
#include <QUrlQuery>
|
||||||
|
|
||||||
@@ -755,94 +761,103 @@ void IssuesWidget::hideOverlay()
|
|||||||
m_overlay->hide();
|
m_overlay->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
class AxivionOutputPane final : public IOutputPane
|
class AxivionPerspective : public Perspective
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit AxivionOutputPane(QObject *parent)
|
AxivionPerspective() : Perspective("Axivion.Perspective", Tr::tr("Axivion")) {}
|
||||||
: IOutputPane(parent)
|
void initPerspective();
|
||||||
{
|
|
||||||
setId("Axivion");
|
|
||||||
setDisplayName(Tr::tr("Axivion"));
|
|
||||||
setPriorityInStatusBar(-50);
|
|
||||||
|
|
||||||
|
void handleShowIssues(const QString &kind);
|
||||||
|
void handleShowFilterException(const QString &errorMessage);
|
||||||
|
void reinitDashboardList(const QString &preferredProject);
|
||||||
|
void resetDashboard();
|
||||||
|
bool handleContextMenu(const QString &issue, const ItemViewEvent &e);
|
||||||
|
void setIssueDetailsHtml(const QString &html) { m_issueDetails->setHtml(html); }
|
||||||
|
void handleAnchorClicked(const QUrl &url);
|
||||||
|
|
||||||
|
private:
|
||||||
|
IssuesWidget *m_issuesWidget = nullptr;
|
||||||
|
QTextBrowser *m_issueDetails = nullptr;
|
||||||
|
QAction *m_disableInlineIssues = nullptr;
|
||||||
|
QAction *m_toggleIssues = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
void AxivionPerspective::initPerspective()
|
||||||
|
{
|
||||||
m_issuesWidget = new IssuesWidget;
|
m_issuesWidget = new IssuesWidget;
|
||||||
|
m_issuesWidget->setObjectName("AxivionIssuesWidget");
|
||||||
|
m_issuesWidget->setWindowTitle(Tr::tr("Issues"));
|
||||||
QPalette pal = m_issuesWidget->palette();
|
QPalette pal = m_issuesWidget->palette();
|
||||||
pal.setColor(QPalette::Window, creatorColor(Theme::Color::BackgroundColorNormal));
|
pal.setColor(QPalette::Window, creatorColor(Theme::Color::BackgroundColorNormal));
|
||||||
m_issuesWidget->setPalette(pal);
|
m_issuesWidget->setPalette(pal);
|
||||||
|
|
||||||
m_disableInlineIssues = new QToolButton(m_issuesWidget);
|
m_issueDetails = new QTextBrowser;
|
||||||
|
m_issueDetails->setObjectName("AxivionIssuesDetails");
|
||||||
|
m_issueDetails->setWindowTitle(Tr::tr("Issue Details"));
|
||||||
|
const QString text = Tr::tr(
|
||||||
|
"Search for issues inside the Axivion dashboard or request issue details for "
|
||||||
|
"Axivion inline annotations to see them here.");
|
||||||
|
m_issueDetails->setText("<p style='text-align:center'>" + text + "</p>");
|
||||||
|
m_issueDetails->setOpenLinks(false);
|
||||||
|
connect(m_issueDetails, &QTextBrowser::anchorClicked,
|
||||||
|
this, &AxivionPerspective::handleAnchorClicked);
|
||||||
|
|
||||||
|
m_disableInlineIssues = new QAction(this);
|
||||||
m_disableInlineIssues->setIcon(ProjectExplorer::Icons::BUILDSTEP_DISABLE.icon());
|
m_disableInlineIssues->setIcon(ProjectExplorer::Icons::BUILDSTEP_DISABLE.icon());
|
||||||
m_disableInlineIssues->setToolTip(Tr::tr("Disable inline issues"));
|
m_disableInlineIssues->setToolTip(Tr::tr("Disable inline issues"));
|
||||||
m_disableInlineIssues->setCheckable(true);
|
m_disableInlineIssues->setCheckable(true);
|
||||||
m_disableInlineIssues->setChecked(false);
|
m_disableInlineIssues->setChecked(false);
|
||||||
connect(m_disableInlineIssues, &QToolButton::toggled,
|
connect(m_disableInlineIssues, &QAction::toggled,
|
||||||
this, [](bool checked) { disableInlineIssues(checked); });
|
this, [](bool checked) { disableInlineIssues(checked); });
|
||||||
m_toggleIssues = new QToolButton(m_issuesWidget);
|
m_toggleIssues = new QAction(this);
|
||||||
m_toggleIssues->setIcon(Utils::Icons::WARNING_TOOLBAR.icon());
|
m_toggleIssues->setIcon(Utils::Icons::WARNING_TOOLBAR.icon());
|
||||||
m_toggleIssues->setToolTip(Tr::tr("Show issue annotations inline"));
|
m_toggleIssues->setToolTip(Tr::tr("Show issue annotations inline"));
|
||||||
m_toggleIssues->setCheckable(true);
|
m_toggleIssues->setCheckable(true);
|
||||||
m_toggleIssues->setChecked(true);
|
m_toggleIssues->setChecked(true);
|
||||||
connect(m_toggleIssues, &QToolButton::toggled, this, [](bool checked) {
|
connect(m_toggleIssues, &QAction::toggled, this, [](bool checked) {
|
||||||
if (checked)
|
if (checked)
|
||||||
TextEditor::TextDocument::showMarksAnnotation("AxivionTextMark");
|
TextEditor::TextDocument::showMarksAnnotation("AxivionTextMark");
|
||||||
else
|
else
|
||||||
TextEditor::TextDocument::temporaryHideMarksAnnotation("AxivionTextMark");
|
TextEditor::TextDocument::temporaryHideMarksAnnotation("AxivionTextMark");
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
~AxivionOutputPane()
|
|
||||||
{
|
|
||||||
if (!m_issuesWidget->parent())
|
|
||||||
delete m_issuesWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget *outputWidget(QWidget *parent) final
|
addToolBarAction(m_disableInlineIssues);
|
||||||
{
|
addToolBarAction(m_toggleIssues);
|
||||||
if (m_issuesWidget)
|
|
||||||
m_issuesWidget->setParent(parent);
|
|
||||||
else
|
|
||||||
QTC_CHECK(false);
|
|
||||||
return m_issuesWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QWidget *> toolBarWidgets() const final
|
addWindow(m_issuesWidget, Perspective::SplitVertical, nullptr);
|
||||||
{
|
addWindow(m_issueDetails, Perspective::AddToTab, nullptr, true, Qt::RightDockWidgetArea);
|
||||||
return {m_disableInlineIssues, m_toggleIssues};
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearContents() final {}
|
ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER);
|
||||||
void setFocus() final {}
|
QAction *action = new QAction(Tr::tr("Axivion"), this);
|
||||||
bool hasFocus() const final { return false; }
|
menu->addAction(ActionManager::registerAction(action, "Axivion.Perspective"),
|
||||||
bool canFocus() const final { return true; }
|
Debugger::Constants::G_ANALYZER_TOOLS);
|
||||||
bool canNavigate() const final { return true; }
|
connect(action, &QAction::triggered,
|
||||||
bool canNext() const final { return false; }
|
this, &Perspective::select);
|
||||||
bool canPrevious() const final { return false; }
|
}
|
||||||
void goToNext() final {}
|
|
||||||
void goToPrev() final {}
|
|
||||||
|
|
||||||
void handleShowIssues(const QString &kind)
|
void AxivionPerspective::handleShowIssues(const QString &kind)
|
||||||
{
|
{
|
||||||
m_issuesWidget->updateUi(kind);
|
m_issuesWidget->updateUi(kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleShowFilterException(const QString &errorMessage)
|
void AxivionPerspective::handleShowFilterException(const QString &errorMessage)
|
||||||
{
|
{
|
||||||
m_issuesWidget->showOverlay(errorMessage);
|
m_issuesWidget->showOverlay(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reinitDashboardList(const QString &preferredProject)
|
void AxivionPerspective::reinitDashboardList(const QString &preferredProject)
|
||||||
{
|
{
|
||||||
m_issuesWidget->initDashboardList(preferredProject);
|
m_issuesWidget->initDashboardList(preferredProject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetDashboard()
|
void AxivionPerspective::resetDashboard()
|
||||||
{
|
{
|
||||||
m_issuesWidget->resetDashboard();
|
m_issuesWidget->resetDashboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handleContextMenu(const QString &issue, const ItemViewEvent &e)
|
bool AxivionPerspective::handleContextMenu(const QString &issue, const ItemViewEvent &e)
|
||||||
{
|
{
|
||||||
std::optional<Dto::TableInfoDto> tableInfoOpt = m_issuesWidget->currentTableInfo();
|
std::optional<Dto::TableInfoDto> tableInfoOpt = m_issuesWidget->currentTableInfo();
|
||||||
if (!tableInfoOpt)
|
if (!tableInfoOpt)
|
||||||
return false;
|
return false;
|
||||||
@@ -879,56 +894,84 @@ public:
|
|||||||
QObject::connect(menu, &QMenu::aboutToHide, menu, &QObject::deleteLater);
|
QObject::connect(menu, &QMenu::aboutToHide, menu, &QObject::deleteLater);
|
||||||
menu->popup(e.globalPos());
|
menu->popup(e.globalPos());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
void AxivionPerspective::handleAnchorClicked(const QUrl &url)
|
||||||
IssuesWidget *m_issuesWidget = nullptr;
|
|
||||||
QToolButton *m_toggleIssues = nullptr;
|
|
||||||
QToolButton *m_disableInlineIssues = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static QPointer<AxivionOutputPane> theAxivionOutputPane;
|
|
||||||
|
|
||||||
void setupAxivionOutputPane(QObject *guard)
|
|
||||||
{
|
{
|
||||||
theAxivionOutputPane = new AxivionOutputPane(guard);
|
if (!url.scheme().isEmpty()) {
|
||||||
|
const QString detail = Tr::tr("The activated link appears to be external.\n"
|
||||||
|
"Do you want to open \"%1\" with its default application?")
|
||||||
|
.arg(url.toString());
|
||||||
|
const QMessageBox::StandardButton pressed
|
||||||
|
= CheckableMessageBox::question(Core::ICore::dialogParent(),
|
||||||
|
Tr::tr("Open External Links"),
|
||||||
|
detail,
|
||||||
|
Key("AxivionOpenExternalLinks"));
|
||||||
|
if (pressed == QMessageBox::Yes)
|
||||||
|
QDesktopServices::openUrl(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QUrlQuery query(url);
|
||||||
|
if (query.isEmpty())
|
||||||
|
return;
|
||||||
|
Link link;
|
||||||
|
if (const QString path = query.queryItemValue("filename", QUrl::FullyDecoded); !path.isEmpty())
|
||||||
|
link.targetFilePath = findFileForIssuePath(FilePath::fromUserInput(path));
|
||||||
|
if (const QString line = query.queryItemValue("line"); !line.isEmpty())
|
||||||
|
link.targetLine = line.toInt();
|
||||||
|
// column entry is wrong - so, ignore it
|
||||||
|
if (link.hasValidTarget() && link.targetFilePath.exists())
|
||||||
|
EditorManager::openEditorAt(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QPointer<AxivionPerspective> theAxivionPerspective;
|
||||||
|
|
||||||
|
void setupAxivionPerspective()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(!theAxivionPerspective, return);
|
||||||
|
theAxivionPerspective = new AxivionPerspective();
|
||||||
|
theAxivionPerspective->initPerspective();
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateDashboard()
|
void updateDashboard()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(theAxivionOutputPane, return);
|
QTC_ASSERT(theAxivionPerspective, return);
|
||||||
theAxivionOutputPane->handleShowIssues({});
|
theAxivionPerspective->handleShowIssues({});
|
||||||
theAxivionOutputPane->flash();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reinitDashboard(const QString &preferredProject)
|
void reinitDashboard(const QString &preferredProject)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(theAxivionOutputPane, return);
|
QTC_ASSERT(theAxivionPerspective, return);
|
||||||
theAxivionOutputPane->reinitDashboardList(preferredProject);
|
theAxivionPerspective->reinitDashboardList(preferredProject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetDashboard()
|
void resetDashboard()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(theAxivionOutputPane, return);
|
QTC_ASSERT(theAxivionPerspective, return);
|
||||||
theAxivionOutputPane->resetDashboard();
|
theAxivionPerspective->resetDashboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool issueListContextMenuEvent(const ItemViewEvent &ev)
|
static bool issueListContextMenuEvent(const ItemViewEvent &ev)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(theAxivionOutputPane, return false);
|
QTC_ASSERT(theAxivionPerspective, return false);
|
||||||
const QModelIndexList selectedIndices = ev.selectedRows();
|
const QModelIndexList selectedIndices = ev.selectedRows();
|
||||||
const QModelIndex first = selectedIndices.isEmpty() ? QModelIndex() : selectedIndices.first();
|
const QModelIndex first = selectedIndices.isEmpty() ? QModelIndex() : selectedIndices.first();
|
||||||
if (!first.isValid())
|
if (!first.isValid())
|
||||||
return false;
|
return false;
|
||||||
const QString issue = first.data().toString();
|
const QString issue = first.data().toString();
|
||||||
return theAxivionOutputPane->handleContextMenu(issue, ev);
|
return theAxivionPerspective->handleContextMenu(issue, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showFilterException(const QString &errorMessage)
|
void showFilterException(const QString &errorMessage)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(theAxivionOutputPane, return);
|
QTC_ASSERT(theAxivionPerspective, return);
|
||||||
theAxivionOutputPane->handleShowFilterException(errorMessage);
|
theAxivionPerspective->handleShowFilterException(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateIssueDetails(const QString &html)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(theAxivionPerspective, return);
|
||||||
|
theAxivionPerspective->setIssueDetailsHtml(html);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Axivion::Internal
|
} // Axivion::Internal
|
@@ -7,10 +7,11 @@
|
|||||||
|
|
||||||
namespace Axivion::Internal {
|
namespace Axivion::Internal {
|
||||||
|
|
||||||
void setupAxivionOutputPane(QObject *guard);
|
void setupAxivionPerspective();
|
||||||
void updateDashboard();
|
void updateDashboard();
|
||||||
void showFilterException(const QString &errorMessage);
|
void showFilterException(const QString &errorMessage);
|
||||||
void reinitDashboard(const QString &projectName);
|
void reinitDashboard(const QString &projectName);
|
||||||
void resetDashboard();
|
void resetDashboard();
|
||||||
|
void updateIssueDetails(const QString &html);
|
||||||
|
|
||||||
} // Axivion::Internal
|
} // Axivion::Internal
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "axivionplugin.h"
|
#include "axivionplugin.h"
|
||||||
|
|
||||||
#include "axivionoutputpane.h"
|
#include "axivionperspective.h"
|
||||||
#include "axivionsettings.h"
|
#include "axivionsettings.h"
|
||||||
#include "axiviontr.h"
|
#include "axiviontr.h"
|
||||||
#include "credentialquery.h"
|
#include "credentialquery.h"
|
||||||
@@ -13,14 +13,11 @@
|
|||||||
#include <coreplugin/editormanager/documentmodel.h>
|
#include <coreplugin/editormanager/documentmodel.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/inavigationwidgetfactory.h>
|
|
||||||
#include <coreplugin/messagemanager.h>
|
#include <coreplugin/messagemanager.h>
|
||||||
#include <coreplugin/navigationwidget.h>
|
|
||||||
#include <coreplugin/session.h>
|
#include <coreplugin/session.h>
|
||||||
|
|
||||||
#include <extensionsystem/iplugin.h>
|
#include <extensionsystem/iplugin.h>
|
||||||
|
|
||||||
#include <projectexplorer/buildsystem.h>
|
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/projectmanager.h>
|
#include <projectexplorer/projectmanager.h>
|
||||||
|
|
||||||
@@ -28,12 +25,10 @@
|
|||||||
#include <solutions/tasking/tasktreerunner.h>
|
#include <solutions/tasking/tasktreerunner.h>
|
||||||
|
|
||||||
#include <texteditor/textdocument.h>
|
#include <texteditor/textdocument.h>
|
||||||
#include <texteditor/texteditor.h>
|
|
||||||
#include <texteditor/textmark.h>
|
#include <texteditor/textmark.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/async.h>
|
#include <utils/async.h>
|
||||||
#include <utils/checkablemessagebox.h>
|
|
||||||
#include <utils/environment.h>
|
#include <utils/environment.h>
|
||||||
#include <utils/fileinprojectfinder.h>
|
#include <utils/fileinprojectfinder.h>
|
||||||
#include <utils/networkaccessmanager.h>
|
#include <utils/networkaccessmanager.h>
|
||||||
@@ -41,13 +36,10 @@
|
|||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QTextBrowser>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QUrlQuery>
|
#include <QUrlQuery>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -224,15 +216,10 @@ public:
|
|||||||
void handleIssuesForFile(const Dto::FileViewDto &fileView);
|
void handleIssuesForFile(const Dto::FileViewDto &fileView);
|
||||||
void disableInlineIssues(bool disable);
|
void disableInlineIssues(bool disable);
|
||||||
void fetchIssueInfo(const QString &id);
|
void fetchIssueInfo(const QString &id);
|
||||||
void setIssueDetails(const QString &issueDetailsHtml);
|
|
||||||
void handleAnchorClicked(const QUrl &url);
|
|
||||||
|
|
||||||
void onSessionLoaded(const QString &sessionName);
|
void onSessionLoaded(const QString &sessionName);
|
||||||
void onAboutToSaveSession();
|
void onAboutToSaveSession();
|
||||||
|
|
||||||
signals:
|
|
||||||
void issueDetailsChanged(const QString &issueDetailsHtml);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// active id used for any network communication, defaults to settings' default
|
// active id used for any network communication, defaults to settings' default
|
||||||
// set to projects settings' dashboard id on open project
|
// set to projects settings' dashboard id on open project
|
||||||
@@ -934,18 +921,12 @@ void AxivionPluginPrivate::fetchIssueInfo(const QString &id)
|
|||||||
if (idx >= 0)
|
if (idx >= 0)
|
||||||
fixedHtml = "<html><body>" + htmlText.mid(idx);
|
fixedHtml = "<html><body>" + htmlText.mid(idx);
|
||||||
|
|
||||||
NavigationWidget::activateSubWidget("Axivion.Issue", Side::Right);
|
updateIssueDetails(QString::fromUtf8(fixedHtml));
|
||||||
dd->setIssueDetails(QString::fromUtf8(fixedHtml));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
m_issueInfoRunner.start(issueHtmlRecipe(id, ruleHandler));
|
m_issueInfoRunner.start(issueHtmlRecipe(id, ruleHandler));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AxivionPluginPrivate::setIssueDetails(const QString &issueDetailsHtml)
|
|
||||||
{
|
|
||||||
emit issueDetailsChanged(issueDetailsHtml);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AxivionPluginPrivate::handleOpenedDocs()
|
void AxivionPluginPrivate::handleOpenedDocs()
|
||||||
{
|
{
|
||||||
const QList<IDocument *> openDocuments = DocumentModel::openedDocuments();
|
const QList<IDocument *> openDocuments = DocumentModel::openedDocuments();
|
||||||
@@ -1050,36 +1031,6 @@ void AxivionPluginPrivate::disableInlineIssues(bool disable)
|
|||||||
handleOpenedDocs();
|
handleOpenedDocs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AxivionPluginPrivate::handleAnchorClicked(const QUrl &url)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(dd, return);
|
|
||||||
QTC_ASSERT(dd->m_project, return);
|
|
||||||
if (!url.scheme().isEmpty()) {
|
|
||||||
const QString detail = Tr::tr("The activated link appears to be external.\n"
|
|
||||||
"Do you want to open \"%1\" with its default application?")
|
|
||||||
.arg(url.toString());
|
|
||||||
const QMessageBox::StandardButton pressed
|
|
||||||
= CheckableMessageBox::question(Core::ICore::dialogParent(),
|
|
||||||
Tr::tr("Open External Links"),
|
|
||||||
detail,
|
|
||||||
Key("AxivionOpenExternalLinks"));
|
|
||||||
if (pressed == QMessageBox::Yes)
|
|
||||||
QDesktopServices::openUrl(url);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const QUrlQuery query(url);
|
|
||||||
if (query.isEmpty())
|
|
||||||
return;
|
|
||||||
Link link;
|
|
||||||
if (const QString path = query.queryItemValue("filename", QUrl::FullyDecoded); !path.isEmpty())
|
|
||||||
link.targetFilePath = findFileForIssuePath(FilePath::fromUserInput(path));
|
|
||||||
if (const QString line = query.queryItemValue("line"); !line.isEmpty())
|
|
||||||
link.targetLine = line.toInt();
|
|
||||||
// column entry is wrong - so, ignore it
|
|
||||||
if (link.hasValidTarget() && link.targetFilePath.exists())
|
|
||||||
EditorManager::openEditorAt(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr char SV_PROJECTNAME[] = "Axivion.ProjectName";
|
static constexpr char SV_PROJECTNAME[] = "Axivion.ProjectName";
|
||||||
static constexpr char SV_DASHBOARDID[] = "Axivion.DashboardId";
|
static constexpr char SV_DASHBOARDID[] = "Axivion.DashboardId";
|
||||||
|
|
||||||
@@ -1113,39 +1064,6 @@ void AxivionPluginPrivate::onAboutToSaveSession()
|
|||||||
SessionManager::setSessionValue(SV_PROJECTNAME, projectName);
|
SessionManager::setSessionValue(SV_PROJECTNAME, projectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
class AxivionIssueWidgetFactory final : public INavigationWidgetFactory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AxivionIssueWidgetFactory()
|
|
||||||
{
|
|
||||||
setDisplayName(Tr::tr("Axivion"));
|
|
||||||
setId("Axivion.Issue");
|
|
||||||
setPriority(555);
|
|
||||||
}
|
|
||||||
|
|
||||||
NavigationView createWidget() final
|
|
||||||
{
|
|
||||||
QTC_ASSERT(dd, return {});
|
|
||||||
QTextBrowser *browser = new QTextBrowser;
|
|
||||||
const QString text = Tr::tr(
|
|
||||||
"Search for issues inside the Axivion dashboard or request issue details for "
|
|
||||||
"Axivion inline annotations to see them here.");
|
|
||||||
browser->setText("<p style='text-align:center'>" + text + "</p>");
|
|
||||||
browser->setOpenLinks(false);
|
|
||||||
NavigationView view;
|
|
||||||
view.widget = browser;
|
|
||||||
connect(dd, &AxivionPluginPrivate::issueDetailsChanged, browser, &QTextBrowser::setHtml);
|
|
||||||
connect(browser, &QTextBrowser::anchorClicked,
|
|
||||||
dd, &AxivionPluginPrivate::handleAnchorClicked);
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void setupAxivionIssueWidgetFactory()
|
|
||||||
{
|
|
||||||
static AxivionIssueWidgetFactory issueWidgetFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
class AxivionPlugin final : public ExtensionSystem::IPlugin
|
class AxivionPlugin final : public ExtensionSystem::IPlugin
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -1159,12 +1077,10 @@ class AxivionPlugin final : public ExtensionSystem::IPlugin
|
|||||||
|
|
||||||
void initialize() final
|
void initialize() final
|
||||||
{
|
{
|
||||||
setupAxivionOutputPane(this);
|
setupAxivionPerspective();
|
||||||
|
|
||||||
dd = new AxivionPluginPrivate;
|
dd = new AxivionPluginPrivate;
|
||||||
|
|
||||||
setupAxivionIssueWidgetFactory();
|
|
||||||
|
|
||||||
connect(ProjectManager::instance(), &ProjectManager::startupProjectChanged,
|
connect(ProjectManager::instance(), &ProjectManager::startupProjectChanged,
|
||||||
dd, &AxivionPluginPrivate::onStartupProjectChanged);
|
dd, &AxivionPluginPrivate::onStartupProjectChanged);
|
||||||
connect(EditorManager::instance(), &EditorManager::documentOpened,
|
connect(EditorManager::instance(), &EditorManager::documentOpened,
|
||||||
|
Reference in New Issue
Block a user