forked from qt-creator/qt-creator
Provide functionality for fetching project information
Change-Id: Id0968c08eb3017eb6f902c3cea3a363bc3f0c35c Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -89,4 +89,9 @@ void AxivionOutputPane::goToPrev()
|
||||
{
|
||||
}
|
||||
|
||||
void AxivionOutputPane::updateDashboard()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} // Axivion::Internal
|
||||
|
||||
@@ -33,6 +33,7 @@ public:
|
||||
void goToNext() override;
|
||||
void goToPrev() override;
|
||||
|
||||
void updateDashboard();
|
||||
private:
|
||||
QStackedWidget *m_outputWidget = nullptr;
|
||||
};
|
||||
|
||||
@@ -5,14 +5,18 @@
|
||||
|
||||
#include "axivionoutputpane.h"
|
||||
#include "axivionprojectsettings.h"
|
||||
#include "axivionquery.h"
|
||||
#include "axivionresultparser.h"
|
||||
#include "axivionsettings.h"
|
||||
#include "axivionsettingspage.h"
|
||||
#include "axiviontr.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/messagemanager.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projectpanelfactory.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#ifdef LICENSECHECKER
|
||||
@@ -20,16 +24,22 @@
|
||||
#endif
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QTimer>
|
||||
|
||||
namespace Axivion::Internal {
|
||||
|
||||
class AxivionPluginPrivate
|
||||
class AxivionPluginPrivate : public QObject
|
||||
{
|
||||
public:
|
||||
void fetchProjectInfo(const QString &projectName);
|
||||
void handleProjectInfo(const ProjectInfo &info);
|
||||
|
||||
AxivionSettings axivionSettings;
|
||||
AxivionSettingsPage axivionSettingsPage{&axivionSettings};
|
||||
AxivionOutputPane axivionOutputPane;
|
||||
QHash<ProjectExplorer::Project *, AxivionProjectSettings *> projectSettings;
|
||||
ProjectInfo currentProjectInfo;
|
||||
bool runningQuery = false;
|
||||
};
|
||||
|
||||
static AxivionPlugin *s_instance = nullptr;
|
||||
@@ -78,9 +88,26 @@ bool AxivionPlugin::initialize(const QStringList &arguments, QString *errorMessa
|
||||
return new AxivionProjectSettingsWidget(project);
|
||||
});
|
||||
ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
|
||||
connect(ProjectExplorer::SessionManager::instance(),
|
||||
&ProjectExplorer::SessionManager::startupProjectChanged,
|
||||
this, &AxivionPlugin::onStartupProjectChanged);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AxivionPlugin::onStartupProjectChanged()
|
||||
{
|
||||
QTC_ASSERT(dd, return);
|
||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
||||
if (!project) {
|
||||
dd->currentProjectInfo = ProjectInfo();
|
||||
dd->axivionOutputPane.updateDashboard();
|
||||
return;
|
||||
}
|
||||
|
||||
const AxivionProjectSettings *projSettings = projectSettings(project);
|
||||
dd->fetchProjectInfo(projSettings->dashboardProjectName());
|
||||
}
|
||||
|
||||
AxivionSettings *AxivionPlugin::settings()
|
||||
{
|
||||
QTC_ASSERT(dd, return nullptr);
|
||||
@@ -116,4 +143,44 @@ bool AxivionPlugin::handleCertificateIssue()
|
||||
return true;
|
||||
}
|
||||
|
||||
void AxivionPlugin::fetchProjectInfo(const QString &projectName)
|
||||
{
|
||||
QTC_ASSERT(dd, return);
|
||||
dd->fetchProjectInfo(projectName);
|
||||
}
|
||||
|
||||
void AxivionPluginPrivate::fetchProjectInfo(const QString &projectName)
|
||||
{
|
||||
if (runningQuery) { // re-schedule
|
||||
QTimer::singleShot(3000, [this, projectName]{ fetchProjectInfo(projectName); });
|
||||
return;
|
||||
}
|
||||
if (projectName.isEmpty()) {
|
||||
currentProjectInfo = ProjectInfo();
|
||||
axivionOutputPane.updateDashboard();
|
||||
return;
|
||||
}
|
||||
runningQuery = true;
|
||||
|
||||
AxivionQuery query(AxivionQuery::ProjectInfo, {projectName});
|
||||
AxivionQueryRunner *runner = new AxivionQueryRunner(query, this);
|
||||
connect(runner, &AxivionQueryRunner::resultRetrieved, this, [this](const QByteArray &result){
|
||||
handleProjectInfo(ResultParser::parseProjectInfo(result));
|
||||
});
|
||||
connect(runner, &AxivionQueryRunner::finished, [runner]{ runner->deleteLater(); });
|
||||
runner->start();
|
||||
}
|
||||
|
||||
void AxivionPluginPrivate::handleProjectInfo(const ProjectInfo &info)
|
||||
{
|
||||
runningQuery = false;
|
||||
if (!info.error.isEmpty()) {
|
||||
Core::MessageManager::writeFlashing("Axivion: " + info.error);
|
||||
return;
|
||||
}
|
||||
|
||||
currentProjectInfo = info;
|
||||
axivionOutputPane.updateDashboard();
|
||||
}
|
||||
|
||||
} // Axivion::Internal
|
||||
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
static AxivionProjectSettings *projectSettings(ProjectExplorer::Project *project);
|
||||
|
||||
static bool handleCertificateIssue();
|
||||
static void fetchProjectInfo(const QString &projectName);
|
||||
|
||||
signals:
|
||||
void settingsChanged();
|
||||
@@ -33,6 +34,7 @@ signals:
|
||||
private:
|
||||
bool initialize(const QStringList &arguments, QString *errorMessage) final;
|
||||
void extensionsInitialized() final {}
|
||||
void onStartupProjectChanged();
|
||||
};
|
||||
|
||||
} // Axivion::Internal
|
||||
|
||||
@@ -136,8 +136,10 @@ void AxivionProjectSettingsWidget::linkProject()
|
||||
const QList<QTreeWidgetItem *> selected = m_dashboardProjects->selectedItems();
|
||||
QTC_ASSERT(selected.size() == 1, return);
|
||||
|
||||
m_projectSettings->setDashboardProjectName(selected.first()->text(0));
|
||||
const QString projectName = selected.first()->text(0);
|
||||
m_projectSettings->setDashboardProjectName(projectName);
|
||||
updateUi();
|
||||
AxivionPlugin::fetchProjectInfo(projectName);
|
||||
}
|
||||
|
||||
void AxivionProjectSettingsWidget::unlinkProject()
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <utils/processenums.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QUrl>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace Axivion::Internal {
|
||||
@@ -27,6 +29,10 @@ QString AxivionQuery::toString() const
|
||||
return {};
|
||||
case DashboardInfo:
|
||||
return query;
|
||||
case ProjectInfo:
|
||||
QTC_ASSERT(m_parameters.size() == 1, return {});
|
||||
query += "/projects/" + QUrl::toPercentEncoding(m_parameters.first());
|
||||
return query;
|
||||
}
|
||||
|
||||
return {};
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Axivion::Internal {
|
||||
class AxivionQuery
|
||||
{
|
||||
public:
|
||||
enum QueryType {NoQuery, DashboardInfo};
|
||||
enum QueryType {NoQuery, DashboardInfo, ProjectInfo};
|
||||
explicit AxivionQuery(QueryType type, const QStringList ¶meters = {});
|
||||
|
||||
QString toString() const;
|
||||
|
||||
@@ -70,6 +70,124 @@ static std::pair<BaseResult, QJsonDocument> prehandleHeaderAndBody(const QByteAr
|
||||
return {result, doc};
|
||||
}
|
||||
|
||||
static User::UserType userTypeForString(const QString &type)
|
||||
{
|
||||
if (type == "DASHBOARD_USER")
|
||||
return User::Dashboard;
|
||||
if (type == "VIRTUAL_USER")
|
||||
return User::Virtual;
|
||||
return User::Unknown;
|
||||
}
|
||||
|
||||
static User userFromJson(const QJsonObject &object)
|
||||
{
|
||||
User result;
|
||||
if (object.isEmpty()) {
|
||||
result.error = "Not a user object.";
|
||||
return result;
|
||||
}
|
||||
result.name = object.value("name").toString();
|
||||
result.displayName = object.value("displayName").toString();
|
||||
result.type = userTypeForString(object.value("type").toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
static QList<User> usersFromJson(const QJsonArray &array)
|
||||
{
|
||||
QList<User> result;
|
||||
for (const QJsonValue &value : array) {
|
||||
User user = userFromJson(value.toObject());
|
||||
if (!user.error.isEmpty()) // add this error to result.error?
|
||||
continue;
|
||||
result.append(user);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static IssueCount issueCountFromJson(const QJsonObject &object)
|
||||
{
|
||||
IssueCount result;
|
||||
if (object.isEmpty()) {
|
||||
result.error = "Not an issue count object.";
|
||||
return result;
|
||||
}
|
||||
result.added = object.value("Added").toInt();
|
||||
result.removed = object.value("Removed").toInt();
|
||||
result.total = object.value("Total").toInt();
|
||||
return result;
|
||||
}
|
||||
|
||||
static QList<IssueCount> issueCountsFromJson(const QJsonObject &object)
|
||||
{
|
||||
QList<IssueCount> result;
|
||||
|
||||
const QStringList keys = object.keys();
|
||||
for (const QString &k : keys) {
|
||||
IssueCount issue = issueCountFromJson(object.value(k).toObject());
|
||||
if (!issue.error.isEmpty()) // add this error to result.error?
|
||||
continue;
|
||||
issue.issueKind = k;
|
||||
result.append(issue);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static ResultVersion versionFromJson(const QJsonObject &object)
|
||||
{
|
||||
ResultVersion result;
|
||||
if (object.isEmpty()) {
|
||||
result.error = "Not a version object.";
|
||||
return result;
|
||||
}
|
||||
const QJsonValue issuesValue = object.value("issueCounts");
|
||||
if (!issuesValue.isObject()) {
|
||||
result.error = "Not an object (issueCounts).";
|
||||
return result;
|
||||
}
|
||||
result.issueCounts = issueCountsFromJson(issuesValue.toObject());
|
||||
result.timeStamp = object.value("date").toString();
|
||||
result.name = object.value("name").toString();
|
||||
result.linesOfCode = object.value("linesOfCode").toInt();
|
||||
return result;
|
||||
}
|
||||
|
||||
static QList<ResultVersion> versionsFromJson(const QJsonArray &array)
|
||||
{
|
||||
QList<ResultVersion> result;
|
||||
for (const QJsonValue &value : array) {
|
||||
ResultVersion version = versionFromJson(value.toObject());
|
||||
if (!version.error.isEmpty()) // add this error to result.error?
|
||||
continue;
|
||||
result.append(version);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static IssueKind issueKindFromJson(const QJsonObject &object)
|
||||
{
|
||||
IssueKind result;
|
||||
if (object.isEmpty()) {
|
||||
result.error = "Not an issue kind object.";
|
||||
return result;
|
||||
}
|
||||
result.prefix = object.value("prefix").toString();
|
||||
result.niceSingular = object.value("niceSingularName").toString();
|
||||
result.nicePlural = object.value("nicePluralName").toString();
|
||||
return result;
|
||||
}
|
||||
|
||||
static QList<IssueKind> issueKindsFromJson(const QJsonArray &array)
|
||||
{
|
||||
QList<IssueKind> result;
|
||||
for (const QJsonValue &value : array) {
|
||||
IssueKind kind = issueKindFromJson(value.toObject());
|
||||
if (!kind.error.isEmpty()) // add this error to result.error?
|
||||
continue;
|
||||
result.append(kind);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace ResultParser {
|
||||
|
||||
DashboardInfo parseDashboardInfo(const QByteArray &input)
|
||||
@@ -109,6 +227,43 @@ DashboardInfo parseDashboardInfo(const QByteArray &input)
|
||||
return result;
|
||||
}
|
||||
|
||||
ProjectInfo parseProjectInfo(const QByteArray &input)
|
||||
{
|
||||
ProjectInfo result;
|
||||
|
||||
auto [header, body] = splitHeaderAndBody(input);
|
||||
auto [error, doc] = prehandleHeaderAndBody(header, body);
|
||||
if (!error.error.isEmpty()) {
|
||||
result.error = error.error;
|
||||
return result;
|
||||
}
|
||||
|
||||
const QJsonObject object = doc.object();
|
||||
result.name = object.value("name").toString();
|
||||
|
||||
const QJsonValue usersValue = object.value("users");
|
||||
if (!usersValue.isArray()) {
|
||||
result.error = "Malformed json response (users).";
|
||||
return result;
|
||||
}
|
||||
result.users = usersFromJson(usersValue.toArray());
|
||||
|
||||
const QJsonValue versionsValue = object.value("versions");
|
||||
if (!versionsValue.isArray()) {
|
||||
result.error = "Malformed json response (versions).";
|
||||
return result;
|
||||
}
|
||||
result.versions = versionsFromJson(versionsValue.toArray());
|
||||
|
||||
const QJsonValue issueKindsValue = object.value("issueKinds");
|
||||
if (!issueKindsValue.isArray()) {
|
||||
result.error = "Malformed json response (issueKinds).";
|
||||
return result;
|
||||
}
|
||||
result.issueKinds = issueKindsFromJson(issueKindsValue.toArray());
|
||||
return result;
|
||||
}
|
||||
|
||||
} // ResultParser
|
||||
|
||||
} // Axivion::Internal
|
||||
|
||||
@@ -27,9 +27,53 @@ public:
|
||||
QList<Project> projects;
|
||||
};
|
||||
|
||||
class User : public BaseResult
|
||||
{
|
||||
public:
|
||||
QString name;
|
||||
QString displayName;
|
||||
enum UserType { Dashboard, Virtual, Unknown } type;
|
||||
};
|
||||
|
||||
class IssueKind : public BaseResult
|
||||
{
|
||||
public:
|
||||
QString prefix;
|
||||
QString niceSingular;
|
||||
QString nicePlural;
|
||||
};
|
||||
|
||||
class IssueCount : public BaseResult
|
||||
{
|
||||
public:
|
||||
QString issueKind;
|
||||
int total = 0;
|
||||
int added = 0;
|
||||
int removed = 0;
|
||||
};
|
||||
|
||||
class ResultVersion : public BaseResult
|
||||
{
|
||||
public:
|
||||
QString name;
|
||||
QString timeStamp;
|
||||
QList<IssueCount> issueCounts;
|
||||
int linesOfCode = 0;
|
||||
};
|
||||
|
||||
class ProjectInfo : public BaseResult
|
||||
{
|
||||
public:
|
||||
QString name;
|
||||
QList<User> users;
|
||||
QList<ResultVersion> versions;
|
||||
QList<IssueKind> issueKinds;
|
||||
};
|
||||
|
||||
namespace ResultParser {
|
||||
|
||||
DashboardInfo parseDashboardInfo(const QByteArray &input);
|
||||
ProjectInfo parseProjectInfo(const QByteArray &input);
|
||||
|
||||
} // ResultParser
|
||||
|
||||
|
||||
Reference in New Issue
Block a user