forked from qt-creator/qt-creator
Axivion: Move a bit closer towards latest settings setup pattern
Change-Id: I5b99d53790818d353730d3af4409f95e5616ff00 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -10,7 +10,6 @@ add_qtc_plugin(Axivion
|
|||||||
axivionquery.h axivionquery.cpp
|
axivionquery.h axivionquery.cpp
|
||||||
axivionresultparser.h axivionresultparser.cpp
|
axivionresultparser.h axivionresultparser.cpp
|
||||||
axivionsettings.cpp axivionsettings.h
|
axivionsettings.cpp axivionsettings.h
|
||||||
axivionsettingspage.cpp axivionsettingspage.h
|
|
||||||
axiviontr.h
|
axiviontr.h
|
||||||
dashboard/dto.cpp dashboard/dto.h
|
dashboard/dto.cpp dashboard/dto.h
|
||||||
dashboard/concat.cpp dashboard/concat.h
|
dashboard/concat.cpp dashboard/concat.h
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ QtcPlugin {
|
|||||||
"axivionresultparser.cpp",
|
"axivionresultparser.cpp",
|
||||||
"axivionsettings.cpp",
|
"axivionsettings.cpp",
|
||||||
"axivionsettings.h",
|
"axivionsettings.h",
|
||||||
"axivionsettingspage.cpp",
|
|
||||||
"axivionsettingspage.h",
|
|
||||||
"axiviontr.h",
|
"axiviontr.h",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
#include "axivionprojectsettings.h"
|
#include "axivionprojectsettings.h"
|
||||||
#include "axivionquery.h"
|
#include "axivionquery.h"
|
||||||
#include "axivionresultparser.h"
|
#include "axivionresultparser.h"
|
||||||
#include "axivionsettings.h"
|
|
||||||
#include "axivionsettingspage.h"
|
|
||||||
#include "axiviontr.h"
|
#include "axiviontr.h"
|
||||||
|
|
||||||
#include <coreplugin/editormanager/documentmodel.h>
|
#include <coreplugin/editormanager/documentmodel.h>
|
||||||
@@ -50,15 +48,12 @@ public:
|
|||||||
void handleIssuesForFile(const IssuesList &issues);
|
void handleIssuesForFile(const IssuesList &issues);
|
||||||
void fetchRuleInfo(const QString &id);
|
void fetchRuleInfo(const QString &id);
|
||||||
|
|
||||||
AxivionSettings m_axivionSettings;
|
|
||||||
AxivionSettingsPage m_axivionSettingsPage{&m_axivionSettings};
|
|
||||||
AxivionOutputPane m_axivionOutputPane;
|
AxivionOutputPane m_axivionOutputPane;
|
||||||
QHash<ProjectExplorer::Project *, AxivionProjectSettings *> m_axivionProjectSettings;
|
QHash<ProjectExplorer::Project *, AxivionProjectSettings *> m_axivionProjectSettings;
|
||||||
ProjectInfo m_currentProjectInfo;
|
ProjectInfo m_currentProjectInfo;
|
||||||
bool m_runningQuery = false;
|
bool m_runningQuery = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
static AxivionPlugin *s_instance = nullptr;
|
|
||||||
static AxivionPluginPrivate *dd = nullptr;
|
static AxivionPluginPrivate *dd = nullptr;
|
||||||
|
|
||||||
class AxivionTextMark : public TextEditor::TextMark
|
class AxivionTextMark : public TextEditor::TextMark
|
||||||
@@ -89,11 +84,6 @@ AxivionTextMark::AxivionTextMark(const Utils::FilePath &filePath, const ShortIss
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
AxivionPlugin::AxivionPlugin()
|
|
||||||
{
|
|
||||||
s_instance = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AxivionPlugin::~AxivionPlugin()
|
AxivionPlugin::~AxivionPlugin()
|
||||||
{
|
{
|
||||||
if (dd && !dd->m_axivionProjectSettings.isEmpty()) {
|
if (dd && !dd->m_axivionProjectSettings.isEmpty()) {
|
||||||
@@ -104,18 +94,12 @@ AxivionPlugin::~AxivionPlugin()
|
|||||||
dd = nullptr;
|
dd = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
AxivionPlugin *AxivionPlugin::instance()
|
|
||||||
{
|
|
||||||
return s_instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AxivionPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
bool AxivionPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||||
{
|
{
|
||||||
Q_UNUSED(arguments)
|
Q_UNUSED(arguments)
|
||||||
Q_UNUSED(errorMessage)
|
Q_UNUSED(errorMessage)
|
||||||
|
|
||||||
dd = new AxivionPluginPrivate;
|
dd = new AxivionPluginPrivate;
|
||||||
dd->m_axivionSettings.fromSettings();
|
|
||||||
|
|
||||||
auto panelFactory = new ProjectExplorer::ProjectPanelFactory;
|
auto panelFactory = new ProjectExplorer::ProjectPanelFactory;
|
||||||
panelFactory->setPriority(250);
|
panelFactory->setPriority(250);
|
||||||
@@ -134,12 +118,6 @@ bool AxivionPlugin::initialize(const QStringList &arguments, QString *errorMessa
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AxivionSettings *AxivionPlugin::settings()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(dd, return nullptr);
|
|
||||||
return &dd->m_axivionSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
AxivionProjectSettings *AxivionPlugin::projectSettings(ProjectExplorer::Project *project)
|
AxivionProjectSettings *AxivionPlugin::projectSettings(ProjectExplorer::Project *project)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(project, return nullptr);
|
QTC_ASSERT(project, return nullptr);
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ namespace ProjectExplorer { class Project; }
|
|||||||
|
|
||||||
namespace Axivion::Internal {
|
namespace Axivion::Internal {
|
||||||
|
|
||||||
class AxivionSettings;
|
|
||||||
class AxivionProjectSettings;
|
class AxivionProjectSettings;
|
||||||
class ProjectInfo;
|
class ProjectInfo;
|
||||||
|
|
||||||
@@ -19,17 +18,13 @@ class AxivionPlugin final : public ExtensionSystem::IPlugin
|
|||||||
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Axivion.json")
|
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Axivion.json")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AxivionPlugin();
|
AxivionPlugin() {}
|
||||||
~AxivionPlugin() final;
|
~AxivionPlugin() final;
|
||||||
|
|
||||||
static AxivionPlugin *instance();
|
|
||||||
static AxivionSettings *settings();
|
|
||||||
static AxivionProjectSettings *projectSettings(ProjectExplorer::Project *project);
|
static AxivionProjectSettings *projectSettings(ProjectExplorer::Project *project);
|
||||||
|
|
||||||
static void fetchProjectInfo(const QString &projectName);
|
static void fetchProjectInfo(const QString &projectName);
|
||||||
static ProjectInfo projectInfo();
|
static ProjectInfo projectInfo();
|
||||||
signals:
|
|
||||||
void settingsChanged();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool initialize(const QStringList &arguments, QString *errorMessage) final;
|
bool initialize(const QStringList &arguments, QString *errorMessage) final;
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Axivion::Internal {
|
namespace Axivion::Internal {
|
||||||
|
|
||||||
const char PSK_PROJECTNAME[] = "Axivion.ProjectName";
|
const char PSK_PROJECTNAME[] = "Axivion.ProjectName";
|
||||||
@@ -45,7 +47,6 @@ AxivionProjectSettingsWidget::AxivionProjectSettingsWidget(ProjectExplorer::Proj
|
|||||||
QWidget *parent)
|
QWidget *parent)
|
||||||
: ProjectExplorer::ProjectSettingsWidget{parent}
|
: ProjectExplorer::ProjectSettingsWidget{parent}
|
||||||
, m_projectSettings(AxivionPlugin::projectSettings(project))
|
, m_projectSettings(AxivionPlugin::projectSettings(project))
|
||||||
, m_globalSettings(AxivionPlugin::settings())
|
|
||||||
{
|
{
|
||||||
setUseGlobalSettingsCheckBoxVisible(false);
|
setUseGlobalSettingsCheckBoxVisible(false);
|
||||||
setUseGlobalSettingsLabelVisible(true);
|
setUseGlobalSettingsLabelVisible(true);
|
||||||
@@ -87,7 +88,7 @@ AxivionProjectSettingsWidget::AxivionProjectSettingsWidget(ProjectExplorer::Proj
|
|||||||
this, &AxivionProjectSettingsWidget::linkProject);
|
this, &AxivionProjectSettingsWidget::linkProject);
|
||||||
connect(m_unlink, &QPushButton::clicked,
|
connect(m_unlink, &QPushButton::clicked,
|
||||||
this, &AxivionProjectSettingsWidget::unlinkProject);
|
this, &AxivionProjectSettingsWidget::unlinkProject);
|
||||||
connect(AxivionPlugin::instance(), &AxivionPlugin::settingsChanged,
|
connect(&settings(), &AspectContainer::changed,
|
||||||
this, &AxivionProjectSettingsWidget::onSettingsChanged);
|
this, &AxivionProjectSettingsWidget::onSettingsChanged);
|
||||||
|
|
||||||
updateUi();
|
updateUi();
|
||||||
@@ -163,9 +164,9 @@ void AxivionProjectSettingsWidget::updateUi()
|
|||||||
|
|
||||||
void AxivionProjectSettingsWidget::updateEnabledStates()
|
void AxivionProjectSettingsWidget::updateEnabledStates()
|
||||||
{
|
{
|
||||||
const bool hasDashboardSettings = m_globalSettings->curl().isExecutableFile()
|
const bool hasDashboardSettings = settings().curl().isExecutableFile()
|
||||||
&& !m_globalSettings->server.dashboard.isEmpty()
|
&& !settings().server.dashboard.isEmpty()
|
||||||
&& !m_globalSettings->server.token.isEmpty();
|
&& !settings().server.token.isEmpty();
|
||||||
const bool linked = !m_projectSettings->dashboardProjectName().isEmpty();
|
const bool linked = !m_projectSettings->dashboardProjectName().isEmpty();
|
||||||
const bool linkable = m_dashboardProjects->topLevelItemCount()
|
const bool linkable = m_dashboardProjects->topLevelItemCount()
|
||||||
&& !m_dashboardProjects->selectedItems().isEmpty();
|
&& !m_dashboardProjects->selectedItems().isEmpty();
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ private:
|
|||||||
void updateEnabledStates();
|
void updateEnabledStates();
|
||||||
|
|
||||||
AxivionProjectSettings *m_projectSettings = nullptr;
|
AxivionProjectSettings *m_projectSettings = nullptr;
|
||||||
AxivionSettings *m_globalSettings;
|
|
||||||
QLabel *m_linkedProject = nullptr;
|
QLabel *m_linkedProject = nullptr;
|
||||||
QTreeWidget *m_dashboardProjects = nullptr;
|
QTreeWidget *m_dashboardProjects = nullptr;
|
||||||
QPushButton *m_fetchProjects = nullptr;
|
QPushButton *m_fetchProjects = nullptr;
|
||||||
|
|||||||
@@ -56,8 +56,7 @@ QString AxivionQuery::toString() const
|
|||||||
|
|
||||||
static bool handleCertificateIssue()
|
static bool handleCertificateIssue()
|
||||||
{
|
{
|
||||||
AxivionSettings *settings = AxivionPlugin::settings();
|
const QString serverHost = QUrl(settings().server.dashboard).host();
|
||||||
const QString serverHost = QUrl(settings->server.dashboard).host();
|
|
||||||
if (QMessageBox::question(Core::ICore::dialogParent(), Tr::tr("Certificate Error"),
|
if (QMessageBox::question(Core::ICore::dialogParent(), Tr::tr("Certificate Error"),
|
||||||
Tr::tr("Server certificate for %1 cannot be authenticated.\n"
|
Tr::tr("Server certificate for %1 cannot be authenticated.\n"
|
||||||
"Do you want to disable SSL verification for this server?\n"
|
"Do you want to disable SSL verification for this server?\n"
|
||||||
@@ -66,8 +65,8 @@ static bool handleCertificateIssue()
|
|||||||
!= QMessageBox::Yes) {
|
!= QMessageBox::Yes) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
settings->server.validateCert = false;
|
settings().server.validateCert = false;
|
||||||
settings->apply();
|
settings().apply();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -75,8 +74,7 @@ static bool handleCertificateIssue()
|
|||||||
AxivionQueryRunner::AxivionQueryRunner(const AxivionQuery &query, QObject *parent)
|
AxivionQueryRunner::AxivionQueryRunner(const AxivionQuery &query, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
const AxivionSettings *settings = AxivionPlugin::settings();
|
const AxivionServer server = settings().server;
|
||||||
const AxivionServer server = settings->server;
|
|
||||||
|
|
||||||
QStringList args = server.curlArguments();
|
QStringList args = server.curlArguments();
|
||||||
args << "-i";
|
args << "-i";
|
||||||
@@ -87,7 +85,7 @@ AxivionQueryRunner::AxivionQueryRunner(const AxivionQuery &query, QObject *paren
|
|||||||
url += query.toString();
|
url += query.toString();
|
||||||
args << url;
|
args << url;
|
||||||
|
|
||||||
m_process.setCommand({settings->curl(), args});
|
m_process.setCommand({settings().curl(), args});
|
||||||
connect(&m_process, &Process::done, this, [this]{
|
connect(&m_process, &Process::done, this, [this]{
|
||||||
if (m_process.result() != ProcessResult::FinishedWithSuccess) {
|
if (m_process.result() != ProcessResult::FinishedWithSuccess) {
|
||||||
const int exitCode = m_process.exitCode();
|
const int exitCode = m_process.exitCode();
|
||||||
|
|||||||
@@ -5,15 +5,26 @@
|
|||||||
|
|
||||||
#include "axiviontr.h"
|
#include "axiviontr.h"
|
||||||
|
|
||||||
|
#include <coreplugin/dialogs/ioptionspage.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <utils/filepath.h>
|
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
|
#include <utils/id.h>
|
||||||
|
#include <utils/layoutbuilder.h>
|
||||||
|
#include <utils/pathchooser.h>
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QSettings>
|
#include <QLabel>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QRegularExpression>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
#include <QUuid>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Axivion::Internal {
|
namespace Axivion::Internal {
|
||||||
|
|
||||||
@@ -74,15 +85,6 @@ QStringList AxivionServer::curlArguments() const
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
AxivionSettings::AxivionSettings()
|
|
||||||
{
|
|
||||||
setSettingsGroup("Axivion");
|
|
||||||
|
|
||||||
curl.setSettingsKey("Curl");
|
|
||||||
curl.setLabelText(Tr::tr("curl:"));
|
|
||||||
curl.setExpectedKind(Utils::PathChooser::ExistingCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Utils::FilePath tokensFilePath()
|
static Utils::FilePath tokensFilePath()
|
||||||
{
|
{
|
||||||
return Utils::FilePath::fromString(Core::ICore::settings()->fileName()).parentDir()
|
return Utils::FilePath::fromString(Core::ICore::settings()->fileName()).parentDir()
|
||||||
@@ -111,23 +113,231 @@ static AxivionServer readTokenFile(const Utils::FilePath &filePath)
|
|||||||
return AxivionServer::fromJson(doc.object());
|
return AxivionServer::fromJson(doc.object());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AxivionSetting
|
||||||
|
|
||||||
|
AxivionSettings &settings()
|
||||||
|
{
|
||||||
|
static AxivionSettings theSettings;
|
||||||
|
return theSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
AxivionSettings::AxivionSettings()
|
||||||
|
{
|
||||||
|
setSettingsGroup("Axivion");
|
||||||
|
|
||||||
|
curl.setSettingsKey("Curl");
|
||||||
|
curl.setLabelText(Tr::tr("curl:"));
|
||||||
|
curl.setExpectedKind(Utils::PathChooser::ExistingCommand);
|
||||||
|
|
||||||
|
AspectContainer::readSettings();
|
||||||
|
|
||||||
|
server = readTokenFile(tokensFilePath());
|
||||||
|
|
||||||
|
if (curl().isEmpty() || !curl().exists()) {
|
||||||
|
const QString curlPath = QStandardPaths::findExecutable(
|
||||||
|
HostOsInfo::withExecutableSuffix("curl"));
|
||||||
|
if (!curlPath.isEmpty())
|
||||||
|
curl.setValue(FilePath::fromString(curlPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AxivionSettings::toSettings() const
|
void AxivionSettings::toSettings() const
|
||||||
{
|
{
|
||||||
writeTokenFile(tokensFilePath(), server);
|
writeTokenFile(tokensFilePath(), server);
|
||||||
Utils::AspectContainer::writeSettings();
|
Utils::AspectContainer::writeSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AxivionSettings::fromSettings()
|
// AxivionSettingsPage
|
||||||
{
|
|
||||||
Utils::AspectContainer::readSettings();
|
|
||||||
server = readTokenFile(tokensFilePath());
|
|
||||||
|
|
||||||
if (curl().isEmpty() || !curl().exists()) {
|
// may allow some invalid, but does some minimal check for legality
|
||||||
const QString curlPath = QStandardPaths::findExecutable(
|
static bool hostValid(const QString &host)
|
||||||
Utils::HostOsInfo::withExecutableSuffix("curl"));
|
{
|
||||||
if (!curlPath.isEmpty())
|
static const QRegularExpression ip(R"(^(\d+).(\d+).(\d+).(\d+)$)");
|
||||||
curl.setValue(Utils::FilePath::fromString(curlPath));
|
static const QRegularExpression dn(R"(^([a-zA-Z0-9][a-zA-Z0-9-]+\.)+[a-zA-Z0-9][a-zA-Z0-9-]+$)");
|
||||||
|
const QRegularExpressionMatch match = ip.match(host);
|
||||||
|
if (match.hasMatch()) {
|
||||||
|
for (int i = 1; i < 5; ++i) {
|
||||||
|
int val = match.captured(i).toInt();
|
||||||
|
if (val < 0 || val > 255)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return (host == "localhost") || dn.match(host).hasMatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isUrlValid(const QString &in)
|
||||||
|
{
|
||||||
|
const QUrl url(in);
|
||||||
|
return hostValid(url.host()) && (url.scheme() == "https" || url.scheme() == "http");
|
||||||
|
}
|
||||||
|
|
||||||
|
class DashboardSettingsWidget : public QWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Mode { Display, Edit };
|
||||||
|
explicit DashboardSettingsWidget(Mode m, QWidget *parent, QPushButton *ok = nullptr);
|
||||||
|
|
||||||
|
AxivionServer dashboardServer() const;
|
||||||
|
void setDashboardServer(const AxivionServer &server);
|
||||||
|
|
||||||
|
bool isValid() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Mode m_mode = Display;
|
||||||
|
Id m_id;
|
||||||
|
StringAspect m_dashboardUrl;
|
||||||
|
StringAspect m_description;
|
||||||
|
StringAspect m_token;
|
||||||
|
BoolAspect m_valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
DashboardSettingsWidget::DashboardSettingsWidget(Mode mode, QWidget *parent, QPushButton *ok)
|
||||||
|
: QWidget(parent)
|
||||||
|
, m_mode(mode)
|
||||||
|
{
|
||||||
|
auto labelStyle = mode == Display ? StringAspect::LabelDisplay : StringAspect::LineEditDisplay;
|
||||||
|
m_dashboardUrl.setLabelText(Tr::tr("Dashboard URL:"));
|
||||||
|
m_dashboardUrl.setDisplayStyle(labelStyle);
|
||||||
|
m_dashboardUrl.setValidationFunction([](FancyLineEdit *edit, QString *){
|
||||||
|
return isUrlValid(edit->text());
|
||||||
|
});
|
||||||
|
m_description.setLabelText(Tr::tr("Description:"));
|
||||||
|
m_description.setDisplayStyle(labelStyle);
|
||||||
|
m_description.setPlaceHolderText(Tr::tr("Non-empty description"));
|
||||||
|
|
||||||
|
m_token.setLabelText(Tr::tr("Access token:"));
|
||||||
|
m_token.setDisplayStyle(labelStyle);
|
||||||
|
m_token.setPlaceHolderText(Tr::tr("IDE Access Token"));
|
||||||
|
m_token.setVisible(mode == Edit);
|
||||||
|
|
||||||
|
using namespace Layouting;
|
||||||
|
|
||||||
|
Form {
|
||||||
|
m_dashboardUrl, br,
|
||||||
|
m_description, br,
|
||||||
|
m_token, br,
|
||||||
|
mode == Edit ? normalMargin : noMargin
|
||||||
|
}.attachTo(this);
|
||||||
|
|
||||||
|
if (mode == Edit) {
|
||||||
|
QTC_ASSERT(ok, return);
|
||||||
|
auto checkValidity = [this, ok] {
|
||||||
|
m_valid.setValue(isValid());
|
||||||
|
ok->setEnabled(m_valid());
|
||||||
|
};
|
||||||
|
connect(&m_dashboardUrl, &BaseAspect::changed, this, checkValidity);
|
||||||
|
connect(&m_description, &BaseAspect::changed, this, checkValidity);
|
||||||
|
connect(&m_token, &BaseAspect::changed, this, checkValidity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AxivionServer DashboardSettingsWidget::dashboardServer() const
|
||||||
|
{
|
||||||
|
AxivionServer result;
|
||||||
|
if (m_id.isValid())
|
||||||
|
result.id = m_id;
|
||||||
|
else
|
||||||
|
result.id = m_mode == Edit ? Utils::Id::fromName(QUuid::createUuid().toByteArray()) : m_id;
|
||||||
|
result.dashboard = m_dashboardUrl();
|
||||||
|
result.description = m_description();
|
||||||
|
result.token = m_token();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DashboardSettingsWidget::setDashboardServer(const AxivionServer &server)
|
||||||
|
{
|
||||||
|
m_id = server.id;
|
||||||
|
m_dashboardUrl.setValue(server.dashboard);
|
||||||
|
m_description.setValue(server.description);
|
||||||
|
m_token.setValue(server.token);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DashboardSettingsWidget::isValid() const
|
||||||
|
{
|
||||||
|
return !m_token().isEmpty() && !m_description().isEmpty() && isUrlValid(m_dashboardUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
class AxivionSettingsWidget : public Core::IOptionsPageWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AxivionSettingsWidget();
|
||||||
|
|
||||||
|
void apply() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void showEditServerDialog();
|
||||||
|
|
||||||
|
DashboardSettingsWidget *m_dashboardDisplay = nullptr;
|
||||||
|
QPushButton *m_edit = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
AxivionSettingsWidget::AxivionSettingsWidget()
|
||||||
|
{
|
||||||
|
using namespace Layouting;
|
||||||
|
|
||||||
|
m_dashboardDisplay = new DashboardSettingsWidget(DashboardSettingsWidget::Display, this);
|
||||||
|
m_dashboardDisplay->setDashboardServer(settings().server);
|
||||||
|
m_edit = new QPushButton(Tr::tr("Edit..."), this);
|
||||||
|
Row {
|
||||||
|
Form {
|
||||||
|
m_dashboardDisplay, br,
|
||||||
|
settings().curl, br,
|
||||||
|
}, Column { m_edit, st }
|
||||||
|
}.attachTo(this);
|
||||||
|
|
||||||
|
connect(m_edit, &QPushButton::clicked, this, &AxivionSettingsWidget::showEditServerDialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AxivionSettingsWidget::apply()
|
||||||
|
{
|
||||||
|
settings().server = m_dashboardDisplay->dashboardServer();
|
||||||
|
settings().toSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AxivionSettingsWidget::showEditServerDialog()
|
||||||
|
{
|
||||||
|
const AxivionServer old = m_dashboardDisplay->dashboardServer();
|
||||||
|
QDialog d;
|
||||||
|
d.setWindowTitle(Tr::tr("Edit Dashboard Configuration"));
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout;
|
||||||
|
auto buttons = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, this);
|
||||||
|
auto ok = buttons->button(QDialogButtonBox::Ok);
|
||||||
|
auto dashboardWidget = new DashboardSettingsWidget(DashboardSettingsWidget::Edit, this, ok);
|
||||||
|
dashboardWidget->setDashboardServer(old);
|
||||||
|
layout->addWidget(dashboardWidget);
|
||||||
|
ok->setEnabled(m_dashboardDisplay->isValid());
|
||||||
|
connect(buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, &d, &QDialog::reject);
|
||||||
|
connect(ok, &QPushButton::clicked, &d, &QDialog::accept);
|
||||||
|
layout->addWidget(buttons);
|
||||||
|
d.setLayout(layout);
|
||||||
|
d.resize(500, 200);
|
||||||
|
|
||||||
|
if (d.exec() != QDialog::Accepted)
|
||||||
|
return;
|
||||||
|
if (dashboardWidget->isValid()) {
|
||||||
|
const AxivionServer server = dashboardWidget->dashboardServer();
|
||||||
|
if (server != old)
|
||||||
|
m_dashboardDisplay->setDashboardServer(server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AxivionSettingsPage
|
||||||
|
|
||||||
|
class AxivionSettingsPage : public Core::IOptionsPage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AxivionSettingsPage()
|
||||||
|
{
|
||||||
|
setId("Axivion.Settings.General");
|
||||||
|
setDisplayName(Tr::tr("General"));
|
||||||
|
setCategory("XY.Axivion");
|
||||||
|
setDisplayCategory(Tr::tr("Axivion"));
|
||||||
|
setCategoryIconPath(":/axivion/images/axivion.png");
|
||||||
|
setWidgetCreator([] { return new AxivionSettingsWidget; });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const AxivionSettingsPage settingsPage;
|
||||||
|
|
||||||
} // Axivion::Internal
|
} // Axivion::Internal
|
||||||
|
|||||||
@@ -40,11 +40,13 @@ class AxivionSettings : public Utils::AspectContainer
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AxivionSettings();
|
AxivionSettings();
|
||||||
|
|
||||||
void toSettings() const;
|
void toSettings() const;
|
||||||
void fromSettings();
|
|
||||||
|
|
||||||
AxivionServer server; // shall we have more than one?
|
AxivionServer server; // shall we have more than one?
|
||||||
Utils::FilePathAspect curl{this};
|
Utils::FilePathAspect curl{this};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AxivionSettings &settings();
|
||||||
|
|
||||||
} // Axivion::Internal
|
} // Axivion::Internal
|
||||||
|
|||||||
@@ -1,214 +0,0 @@
|
|||||||
// Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
||||||
|
|
||||||
#include "axivionsettingspage.h"
|
|
||||||
|
|
||||||
#include "axivionplugin.h"
|
|
||||||
#include "axivionsettings.h"
|
|
||||||
#include "axiviontr.h"
|
|
||||||
|
|
||||||
#include <utils/aspects.h>
|
|
||||||
#include <utils/id.h>
|
|
||||||
#include <utils/layoutbuilder.h>
|
|
||||||
#include <utils/pathchooser.h>
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QDialogButtonBox>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QRegularExpression>
|
|
||||||
#include <QUuid>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
|
|
||||||
using namespace Utils;
|
|
||||||
|
|
||||||
namespace Axivion::Internal {
|
|
||||||
|
|
||||||
// may allow some invalid, but does some minimal check for legality
|
|
||||||
static bool hostValid(const QString &host)
|
|
||||||
{
|
|
||||||
static const QRegularExpression ip(R"(^(\d+).(\d+).(\d+).(\d+)$)");
|
|
||||||
static const QRegularExpression dn(R"(^([a-zA-Z0-9][a-zA-Z0-9-]+\.)+[a-zA-Z0-9][a-zA-Z0-9-]+$)");
|
|
||||||
const QRegularExpressionMatch match = ip.match(host);
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
for (int i = 1; i < 5; ++i) {
|
|
||||||
int val = match.captured(i).toInt();
|
|
||||||
if (val < 0 || val > 255)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return (host == "localhost") || dn.match(host).hasMatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isUrlValid(const QString &in)
|
|
||||||
{
|
|
||||||
const QUrl url(in);
|
|
||||||
return hostValid(url.host()) && (url.scheme() == "https" || url.scheme() == "http");
|
|
||||||
}
|
|
||||||
|
|
||||||
class DashboardSettingsWidget : public QWidget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum Mode { Display, Edit };
|
|
||||||
explicit DashboardSettingsWidget(Mode m, QWidget *parent, QPushButton *ok = nullptr);
|
|
||||||
|
|
||||||
AxivionServer dashboardServer() const;
|
|
||||||
void setDashboardServer(const AxivionServer &server);
|
|
||||||
|
|
||||||
bool isValid() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Mode m_mode = Display;
|
|
||||||
Id m_id;
|
|
||||||
StringAspect m_dashboardUrl;
|
|
||||||
StringAspect m_description;
|
|
||||||
StringAspect m_token;
|
|
||||||
BoolAspect m_valid;
|
|
||||||
};
|
|
||||||
|
|
||||||
DashboardSettingsWidget::DashboardSettingsWidget(Mode mode, QWidget *parent, QPushButton *ok)
|
|
||||||
: QWidget(parent)
|
|
||||||
, m_mode(mode)
|
|
||||||
{
|
|
||||||
auto labelStyle = mode == Display ? StringAspect::LabelDisplay : StringAspect::LineEditDisplay;
|
|
||||||
m_dashboardUrl.setLabelText(Tr::tr("Dashboard URL:"));
|
|
||||||
m_dashboardUrl.setDisplayStyle(labelStyle);
|
|
||||||
m_dashboardUrl.setValidationFunction([](FancyLineEdit *edit, QString *){
|
|
||||||
return isUrlValid(edit->text());
|
|
||||||
});
|
|
||||||
m_description.setLabelText(Tr::tr("Description:"));
|
|
||||||
m_description.setDisplayStyle(labelStyle);
|
|
||||||
m_description.setPlaceHolderText(Tr::tr("Non-empty description"));
|
|
||||||
|
|
||||||
m_token.setLabelText(Tr::tr("Access token:"));
|
|
||||||
m_token.setDisplayStyle(labelStyle);
|
|
||||||
m_token.setPlaceHolderText(Tr::tr("IDE Access Token"));
|
|
||||||
m_token.setVisible(mode == Edit);
|
|
||||||
|
|
||||||
using namespace Layouting;
|
|
||||||
|
|
||||||
Form {
|
|
||||||
m_dashboardUrl, br,
|
|
||||||
m_description, br,
|
|
||||||
m_token, br,
|
|
||||||
mode == Edit ? normalMargin : noMargin
|
|
||||||
}.attachTo(this);
|
|
||||||
|
|
||||||
if (mode == Edit) {
|
|
||||||
QTC_ASSERT(ok, return);
|
|
||||||
auto checkValidity = [this, ok] {
|
|
||||||
m_valid.setValue(isValid());
|
|
||||||
ok->setEnabled(m_valid());
|
|
||||||
};
|
|
||||||
connect(&m_dashboardUrl, &BaseAspect::changed, this, checkValidity);
|
|
||||||
connect(&m_description, &BaseAspect::changed, this, checkValidity);
|
|
||||||
connect(&m_token, &BaseAspect::changed, this, checkValidity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AxivionServer DashboardSettingsWidget::dashboardServer() const
|
|
||||||
{
|
|
||||||
AxivionServer result;
|
|
||||||
if (m_id.isValid())
|
|
||||||
result.id = m_id;
|
|
||||||
else
|
|
||||||
result.id = m_mode == Edit ? Utils::Id::fromName(QUuid::createUuid().toByteArray()) : m_id;
|
|
||||||
result.dashboard = m_dashboardUrl();
|
|
||||||
result.description = m_description();
|
|
||||||
result.token = m_token();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DashboardSettingsWidget::setDashboardServer(const AxivionServer &server)
|
|
||||||
{
|
|
||||||
m_id = server.id;
|
|
||||||
m_dashboardUrl.setValue(server.dashboard);
|
|
||||||
m_description.setValue(server.description);
|
|
||||||
m_token.setValue(server.token);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DashboardSettingsWidget::isValid() const
|
|
||||||
{
|
|
||||||
return !m_token().isEmpty() && !m_description().isEmpty() && isUrlValid(m_dashboardUrl());
|
|
||||||
}
|
|
||||||
|
|
||||||
class AxivionSettingsWidget : public Core::IOptionsPageWidget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit AxivionSettingsWidget(AxivionSettings *settings);
|
|
||||||
|
|
||||||
void apply() override;
|
|
||||||
private:
|
|
||||||
void showEditServerDialog();
|
|
||||||
|
|
||||||
AxivionSettings *m_settings;
|
|
||||||
|
|
||||||
DashboardSettingsWidget *m_dashboardDisplay = nullptr;
|
|
||||||
QPushButton *m_edit = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
AxivionSettingsWidget::AxivionSettingsWidget(AxivionSettings *settings)
|
|
||||||
: m_settings(settings)
|
|
||||||
{
|
|
||||||
using namespace Layouting;
|
|
||||||
|
|
||||||
m_dashboardDisplay = new DashboardSettingsWidget(DashboardSettingsWidget::Display, this);
|
|
||||||
m_dashboardDisplay->setDashboardServer(m_settings->server);
|
|
||||||
m_edit = new QPushButton(Tr::tr("Edit..."), this);
|
|
||||||
Row {
|
|
||||||
Form {
|
|
||||||
m_dashboardDisplay, br,
|
|
||||||
m_settings->curl, br,
|
|
||||||
}, Column { m_edit, st }
|
|
||||||
}.attachTo(this);
|
|
||||||
|
|
||||||
connect(m_edit, &QPushButton::clicked, this, &AxivionSettingsWidget::showEditServerDialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AxivionSettingsWidget::apply()
|
|
||||||
{
|
|
||||||
m_settings->server = m_dashboardDisplay->dashboardServer();
|
|
||||||
m_settings->toSettings();
|
|
||||||
emit AxivionPlugin::instance()->settingsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AxivionSettingsWidget::showEditServerDialog()
|
|
||||||
{
|
|
||||||
const AxivionServer old = m_dashboardDisplay->dashboardServer();
|
|
||||||
QDialog d;
|
|
||||||
d.setWindowTitle(Tr::tr("Edit Dashboard Configuration"));
|
|
||||||
QVBoxLayout *layout = new QVBoxLayout;
|
|
||||||
auto buttons = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, this);
|
|
||||||
auto ok = buttons->button(QDialogButtonBox::Ok);
|
|
||||||
auto dashboardWidget = new DashboardSettingsWidget(DashboardSettingsWidget::Edit, this, ok);
|
|
||||||
dashboardWidget->setDashboardServer(old);
|
|
||||||
layout->addWidget(dashboardWidget);
|
|
||||||
ok->setEnabled(m_dashboardDisplay->isValid());
|
|
||||||
connect(buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, &d, &QDialog::reject);
|
|
||||||
connect(ok, &QPushButton::clicked, &d, &QDialog::accept);
|
|
||||||
layout->addWidget(buttons);
|
|
||||||
d.setLayout(layout);
|
|
||||||
d.resize(500, 200);
|
|
||||||
|
|
||||||
if (d.exec() != QDialog::Accepted)
|
|
||||||
return;
|
|
||||||
if (dashboardWidget->isValid()) {
|
|
||||||
const AxivionServer server = dashboardWidget->dashboardServer();
|
|
||||||
if (server != old)
|
|
||||||
m_dashboardDisplay->setDashboardServer(server);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AxivionSettingsPage::AxivionSettingsPage(AxivionSettings *settings)
|
|
||||||
: m_settings(settings)
|
|
||||||
{
|
|
||||||
setId("Axivion.Settings.General");
|
|
||||||
setDisplayName(Tr::tr("General"));
|
|
||||||
setCategory("XY.Axivion");
|
|
||||||
setDisplayCategory(Tr::tr("Axivion"));
|
|
||||||
setCategoryIconPath(":/axivion/images/axivion.png");
|
|
||||||
setWidgetCreator([this] { return new AxivionSettingsWidget(m_settings); });
|
|
||||||
}
|
|
||||||
|
|
||||||
} // Axivion::Internal
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
// Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <coreplugin/dialogs/ioptionspage.h>
|
|
||||||
|
|
||||||
namespace Axivion::Internal {
|
|
||||||
|
|
||||||
class AxivionSettings;
|
|
||||||
|
|
||||||
class AxivionSettingsPage : public Core::IOptionsPage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit AxivionSettingsPage(AxivionSettings *settings);
|
|
||||||
|
|
||||||
private:
|
|
||||||
AxivionSettings *m_settings;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // Axivion::Internal
|
|
||||||
Reference in New Issue
Block a user