Axivion: Prepare ui for displaying issues

UI preparation which may change when adding the functionality
of retrieving respective information from the dashboard.

Change-Id: I9ec8069d780f925b00ba63982af6b410ddec9a5a
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
Christian Stenger
2024-01-19 13:47:03 +01:00
parent 0a7dc1ac1e
commit 0ba1e17797
16 changed files with 160 additions and 2 deletions

View File

@@ -2,5 +2,17 @@
<qresource prefix="/axivion"> <qresource prefix="/axivion">
<file>images/axivion.png</file> <file>images/axivion.png</file>
<file>images/axivion@2x.png</file> <file>images/axivion@2x.png</file>
<file>images/button-av.png</file>
<file>images/button-av@2x.png</file>
<file>images/button-cl.png</file>
<file>images/button-cl@2x.png</file>
<file>images/button-cy.png</file>
<file>images/button-cy@2x.png</file>
<file>images/button-de.png</file>
<file>images/button-de@2x.png</file>
<file>images/button-mv.png</file>
<file>images/button-mv@2x.png</file>
<file>images/button-sv.png</file>
<file>images/button-sv@2x.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -10,9 +10,12 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
#include <QComboBox>
#include <QFormLayout> #include <QFormLayout>
#include <QGridLayout> #include <QGridLayout>
#include <QHeaderView>
#include <QLabel> #include <QLabel>
#include <QPushButton>
#include <QScrollArea> #include <QScrollArea>
#include <QStackedWidget> #include <QStackedWidget>
#include <QTextBrowser> #include <QTextBrowser>
@@ -168,6 +171,116 @@ void DashboardWidget::updateUi()
addValuesWidgets(Tr::tr("Total:"), allTotal, allAdded, allRemoved, row); addValuesWidgets(Tr::tr("Total:"), allTotal, allAdded, allRemoved, row);
} }
class IssuesWidget : public QScrollArea
{
public:
explicit IssuesWidget(QWidget *parent = nullptr);
void updateUi();
private:
void updateTableView();
QString m_currentPrefix;
std::optional<Dto::TableInfoDto> m_currentTableInfo;
QHBoxLayout *m_typesLayout = nullptr;
QHBoxLayout *m_filtersLayout = nullptr;
QPushButton *m_addedFilter = nullptr;
QPushButton *m_removedFilter = nullptr;
QComboBox *m_ownerFilter = nullptr;
QComboBox *m_versionStart = nullptr;
QComboBox *m_versionEnd = nullptr;
QLineEdit *m_pathGlobFilter = nullptr; // FancyLineEdit instead?
};
IssuesWidget::IssuesWidget(QWidget *parent)
: QScrollArea(parent)
{
QWidget *widget = new QWidget(this);
QVBoxLayout *layout = new QVBoxLayout(widget);
// row with issue types (-> depending on choice, tables below change)
// and a selectable range (start version, end version)
// row with added/removed and some filters (assignee, path glob, (named filter))
// table, columns depend on chosen issue type
QHBoxLayout *top = new QHBoxLayout;
layout->addLayout(top);
m_typesLayout = new QHBoxLayout;
top->addLayout(m_typesLayout);
top->addStretch(1);
m_versionStart = new QComboBox(this);
m_versionStart->setMinimumContentsLength(25);
top->addWidget(m_versionStart);
m_versionEnd = new QComboBox(this);
m_versionEnd->setMinimumContentsLength(25);
top->addWidget(m_versionEnd);
top->addStretch(1);
m_filtersLayout = new QHBoxLayout;
m_addedFilter = new QPushButton(this);
m_addedFilter->setIcon(trendIcon(1, 0));
m_addedFilter->setText("0");
m_filtersLayout->addWidget(m_addedFilter);
m_removedFilter = new QPushButton(this);
m_removedFilter->setIcon(trendIcon(0, 1));
m_removedFilter->setText("0");
m_filtersLayout->addWidget(m_removedFilter);
m_filtersLayout->addSpacing(1);
m_ownerFilter = new QComboBox(this);
m_ownerFilter->setToolTip(Tr::tr("Owner"));
m_ownerFilter->setMinimumContentsLength(25);
m_filtersLayout->addWidget(m_ownerFilter);
m_pathGlobFilter = new QLineEdit(this);
m_pathGlobFilter->setPlaceholderText(Tr::tr("Path globbing"));
m_filtersLayout->addWidget(m_pathGlobFilter);
layout->addLayout(m_filtersLayout);
// TODO the issues table
layout->addStretch(1);
setWidget(widget);
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
setWidgetResizable(true);
}
void IssuesWidget::updateUi()
{
m_filtersLayout->setEnabled(false);
// TODO extract parts of it and do them only when necessary
QLayoutItem *child;
while ((child = m_typesLayout->takeAt(0)) != nullptr) {
delete child->widget();
delete child;
}
std::optional<Dto::ProjectInfoDto> projectInfo = Internal::projectInfo();
if (!projectInfo)
return;
const Dto::ProjectInfoDto &info = *projectInfo;
if (info.versions.empty()) // add some warning/information?
return;
// for now just a start..
const Dto::AnalysisVersionDto &last = info.versions.back();
const std::vector<Dto::IssueKindInfoDto> &issueKinds = info.issueKinds;
for (const Dto::IssueKindInfoDto &kind : issueKinds) {
auto button = new QToolButton(this);
button->setIcon(iconForIssue(kind.prefix));
button->setToolTip(kind.nicePluralName);
connect(button, &QToolButton::clicked, this, [this, prefix = kind.prefix]{
m_currentPrefix = prefix;
updateTableView();
});
m_typesLayout->addWidget(button);
}
// TODO versions range...
// TODO fill owners
m_filtersLayout->setEnabled(true);
}
void IssuesWidget::updateTableView()
{
// fetch table dto and apply
// on done fetch first data for the selected issues
}
AxivionOutputPane::AxivionOutputPane(QObject *parent) AxivionOutputPane::AxivionOutputPane(QObject *parent)
: Core::IOutputPane(parent) : Core::IOutputPane(parent)
{ {
@@ -178,6 +291,8 @@ AxivionOutputPane::AxivionOutputPane(QObject *parent)
m_outputWidget = new QStackedWidget; m_outputWidget = new QStackedWidget;
DashboardWidget *dashboardWidget = new DashboardWidget(m_outputWidget); DashboardWidget *dashboardWidget = new DashboardWidget(m_outputWidget);
m_outputWidget->addWidget(dashboardWidget); m_outputWidget->addWidget(dashboardWidget);
IssuesWidget *issuesWidget = new IssuesWidget(m_outputWidget);
m_outputWidget->addWidget(issuesWidget);
QTextBrowser *browser = new QTextBrowser(m_outputWidget); QTextBrowser *browser = new QTextBrowser(m_outputWidget);
m_outputWidget->addWidget(browser); m_outputWidget->addWidget(browser);
} }
@@ -208,6 +323,16 @@ QList<QWidget *> AxivionOutputPane::toolBarWidgets() const
m_outputWidget->setCurrentIndex(0); m_outputWidget->setCurrentIndex(0);
}); });
buttons.append(showDashboard); buttons.append(showDashboard);
auto showIssues = new QToolButton(m_outputWidget);
showIssues->setIcon(Utils::Icons::ZOOM_TOOLBAR.icon());
showIssues->setToolTip(Tr::tr("Search for issues"));
connect(showIssues, &QToolButton::clicked, this, [this]{
QTC_ASSERT(m_outputWidget, return);
m_outputWidget->setCurrentIndex(1);
if (auto issues = static_cast<IssuesWidget *>(m_outputWidget->widget(1)))
issues->updateUi();
});
buttons.append(showIssues);
return buttons; return buttons;
} }
@@ -264,10 +389,10 @@ void AxivionOutputPane::updateDashboard()
void AxivionOutputPane::updateAndShowRule(const QString &ruleHtml) void AxivionOutputPane::updateAndShowRule(const QString &ruleHtml)
{ {
if (auto browser = static_cast<QTextBrowser *>(m_outputWidget->widget(1))) { if (auto browser = static_cast<QTextBrowser *>(m_outputWidget->widget(2))) {
browser->setText(ruleHtml); browser->setText(ruleHtml);
if (!ruleHtml.isEmpty()) { if (!ruleHtml.isEmpty()) {
m_outputWidget->setCurrentIndex(1); m_outputWidget->setCurrentIndex(2);
popup(Core::IOutputPane::NoModeSwitch); popup(Core::IOutputPane::NoModeSwitch);
} }
} }

View File

@@ -55,6 +55,20 @@ using namespace Utils;
namespace Axivion::Internal { namespace Axivion::Internal {
QIcon iconForIssue(const QString &prefix)
{
static QHash<QString, QIcon> prefixToIcon;
auto it = prefixToIcon.find(prefix);
if (it == prefixToIcon.end()) {
Icon icon({{FilePath::fromString(":/axivion/images/button-" + prefix.toLower() + ".png"),
Theme::PaletteButtonText}},
Icon::Tint);
it = prefixToIcon.insert(prefix, icon.icon());
}
return it.value();
}
class AxivionPluginPrivate : public QObject class AxivionPluginPrivate : public QObject
{ {
public: public:
@@ -94,6 +108,7 @@ AxivionTextMark::AxivionTextMark(const FilePath &filePath, const ShortIssue &iss
const QString markText = issue.entity.isEmpty() ? issue.message const QString markText = issue.entity.isEmpty() ? issue.message
: issue.entity + ": " + issue.message; : issue.entity + ": " + issue.message;
setToolTip(issue.errorNumber + " " + markText); setToolTip(issue.errorNumber + " " + markText);
setIcon(iconForIssue("SV")); // FIXME adapt to the issue
setPriority(TextEditor::TextMark::NormalPriority); setPriority(TextEditor::TextMark::NormalPriority);
setLineAnnotation(markText); setLineAnnotation(markText);
setActionsProvider([this]{ setActionsProvider([this]{

View File

@@ -7,6 +7,10 @@
#include <memory> #include <memory>
QT_BEGIN_NAMESPACE
class QIcon;
QT_END_NAMESPACE
namespace ProjectExplorer { class Project; } namespace ProjectExplorer { class Project; }
namespace Axivion::Internal { namespace Axivion::Internal {
@@ -15,5 +19,7 @@ void fetchProjectInfo(const QString &projectName);
std::optional<Dto::ProjectInfoDto> projectInfo(); std::optional<Dto::ProjectInfoDto> projectInfo();
bool handleCertificateIssue(); bool handleCertificateIssue();
QIcon iconForIssue(const QString &prefix);
} // Axivion::Internal } // Axivion::Internal

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B