aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/axivion/axivionplugin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/axivion/axivionplugin.cpp')
-rw-r--r--src/plugins/axivion/axivionplugin.cpp148
1 files changed, 54 insertions, 94 deletions
diff --git a/src/plugins/axivion/axivionplugin.cpp b/src/plugins/axivion/axivionplugin.cpp
index 26f5196a9a..cd8fca0a0c 100644
--- a/src/plugins/axivion/axivionplugin.cpp
+++ b/src/plugins/axivion/axivionplugin.cpp
@@ -53,21 +53,6 @@ using namespace Utils;
namespace Axivion::Internal {
-class Issue
-{
-public:
- QString id;
- QString state;
- QString errorNumber;
- QString message;
- QString entity;
- QString filePath;
- QString severity;
- int lineNumber = 0;
-};
-
-using Issues = QList<Issue>;
-
QIcon iconForIssue(const QString &prefix)
{
static QHash<QString, QIcon> prefixToIcon;
@@ -154,7 +139,7 @@ public:
void onDocumentOpened(IDocument *doc);
void onDocumentClosed(IDocument * doc);
void clearAllMarks();
- void handleIssuesForFile(const Issues &issues);
+ void handleIssuesForFile(const Dto::FileViewDto &fileView);
void fetchIssueInfo(const QString &id);
NetworkAccessManager m_networkAccessManager;
@@ -173,18 +158,18 @@ static AxivionPluginPrivate *dd = nullptr;
class AxivionTextMark : public TextMark
{
public:
- AxivionTextMark(const FilePath &filePath, const Issue &issue)
- : TextMark(filePath, issue.lineNumber, {Tr::tr("Axivion"), AxivionTextMarkId})
+ AxivionTextMark(const FilePath &filePath, const Dto::LineMarkerDto &issue)
+ : TextMark(filePath, issue.startLine, {Tr::tr("Axivion"), AxivionTextMarkId})
{
- const QString markText = issue.entity.isEmpty() ? issue.message
- : issue.entity + ": " + issue.message;
- setToolTip(issue.errorNumber + " " + markText);
- setIcon(iconForIssue("SV")); // FIXME adapt to the issue
+ const QString markText = issue.description;
+ const QString id = issue.kind + QString::number(issue.id.value_or(-1));
+ setToolTip(id + markText);
+ setIcon(iconForIssue(issue.kind));
setPriority(TextMark::NormalPriority);
setLineAnnotation(markText);
- setActionsProvider([id = issue.id] {
+ setActionsProvider([id] {
auto action = new QAction;
- action->setIcon(Utils::Icons::INFO.icon());
+ action->setIcon(Icons::INFO.icon());
action->setToolTip(Tr::tr("Show rule details"));
QObject::connect(action, &QAction::triggered, dd, [id] { dd->fetchIssueInfo(id); });
return QList{action};
@@ -281,8 +266,8 @@ static QUrl urlForProject(const QString &projectName)
}
static constexpr int httpStatusCodeOk = 200;
-static const QLatin1String jsonContentType{ "application/json" };
-static const QLatin1String htmlContentType{ "text/html" };
+constexpr char s_htmlContentType[] = "text/html";
+constexpr char s_jsonContentType[] = "application/json";
static Group fetchHtmlRecipe(const QUrl &url, const std::function<void(const QByteArray &)> &handler)
{
@@ -299,15 +284,11 @@ static Group fetchHtmlRecipe(const QUrl &url, const std::function<void(const QBy
const auto onQuerySetup = [storage, url](NetworkQuery &query) {
QNetworkRequest request(url);
- request.setRawHeader(QByteArrayLiteral("Accept"),
- QByteArray(htmlContentType.data(), htmlContentType.size()));
- request.setRawHeader(QByteArrayLiteral("Authorization"),
- storage->credentials);
- const QByteArray ua = QByteArrayLiteral("Axivion")
- + QCoreApplication::applicationName().toUtf8()
- + QByteArrayLiteral("Plugin/")
- + QCoreApplication::applicationVersion().toUtf8();
- request.setRawHeader(QByteArrayLiteral("X-Axivion-User-Agent"), ua);
+ request.setRawHeader("Accept", s_htmlContentType);
+ request.setRawHeader("Authorization", storage->credentials);
+ const QByteArray ua = "Axivion" + QCoreApplication::applicationName().toUtf8() +
+ "Plugin/" + QCoreApplication::applicationVersion().toUtf8();
+ request.setRawHeader("X-Axivion-User-Agent", ua);
query.setRequest(request);
query.setNetworkAccessManager(&dd->m_networkAccessManager);
};
@@ -322,11 +303,10 @@ static Group fetchHtmlRecipe(const QUrl &url, const std::function<void(const QBy
.trimmed()
.toLower();
if (doneWith == DoneWith::Success && statusCode == httpStatusCodeOk
- && contentType == htmlContentType) {
+ && contentType == s_htmlContentType) {
handler(reply->readAll());
return DoneResult::Success;
}
-
return DoneResult::Error;
};
@@ -355,22 +335,19 @@ static Group fetchDataRecipe(const QUrl &url,
storage->credentials = QByteArrayLiteral("AxToken ") + settings().server.token.toUtf8();
};
- const auto onQuerySetup = [storage, url](NetworkQuery &query) {
+ const auto onNetworkQuerySetup = [storage, url](NetworkQuery &query) {
QNetworkRequest request(url);
- request.setRawHeader(QByteArrayLiteral("Accept"),
- QByteArray(jsonContentType.data(), jsonContentType.size()));
- request.setRawHeader(QByteArrayLiteral("Authorization"),
- storage->credentials);
- const QByteArray ua = QByteArrayLiteral("Axivion")
- + QCoreApplication::applicationName().toUtf8()
- + QByteArrayLiteral("Plugin/")
- + QCoreApplication::applicationVersion().toUtf8();
- request.setRawHeader(QByteArrayLiteral("X-Axivion-User-Agent"), ua);
+ request.setRawHeader("Accept", s_jsonContentType);
+ request.setRawHeader("Authorization", storage->credentials);
+ const QByteArray ua = "Axivion" + QCoreApplication::applicationName().toUtf8() +
+ "Plugin/" + QCoreApplication::applicationVersion().toUtf8();
+ request.setRawHeader("X-Axivion-User-Agent", ua);
query.setRequest(request);
query.setNetworkAccessManager(&dd->m_networkAccessManager);
+ return SetupResult::Continue;
};
- const auto onQueryDone = [storage, url](const NetworkQuery &query, DoneWith doneWith) {
+ const auto onNetworkQueryDone = [storage, url](const NetworkQuery &query, DoneWith doneWith) {
QNetworkReply *reply = query.reply();
const QNetworkReply::NetworkError error = reply->error();
const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
@@ -381,13 +358,13 @@ static Group fetchDataRecipe(const QUrl &url,
.trimmed()
.toLower();
if (doneWith == DoneWith::Success && statusCode == httpStatusCodeOk
- && contentType == jsonContentType) {
+ && contentType == s_jsonContentType) {
storage->serializableData = reply->readAll();
return DoneResult::Success;
}
const auto getError = [&]() -> Error {
- if (contentType == jsonContentType) {
+ if (contentType == s_jsonContentType) {
try {
return DashboardError(reply->url(), statusCode,
reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(),
@@ -404,8 +381,7 @@ static Group fetchDataRecipe(const QUrl &url,
return NetworkError(reply->url(), error, reply->errorString());
};
- MessageManager::writeFlashing(
- QStringLiteral("Axivion: %1").arg(getError().message()));
+ MessageManager::writeFlashing(QStringLiteral("Axivion: %1").arg(getError().message()));
return DoneResult::Error;
};
@@ -426,7 +402,7 @@ static Group fetchDataRecipe(const QUrl &url,
const Group recipe {
storage,
Sync(onCredentialSetup),
- NetworkQueryTask(onQuerySetup, onQueryDone),
+ NetworkQueryTask(onNetworkQuerySetup, onNetworkQueryDone),
AsyncTask<SerializableType>(onDeserializeSetup, onDeserializeDone)
};
@@ -495,6 +471,17 @@ Group issueTableRecipe(const IssueListSearch &search, const IssueTableHandler &h
return fetchDataRecipe<Dto::IssueTableDto>(url, handler);
}
+Group lineMarkerRecipe(const FilePath &filePath, const LineMarkerHandler &handler)
+{
+ QTC_ASSERT(dd->m_currentProjectInfo, return {}); // TODO: Call handler with unexpected?
+ QTC_ASSERT(!filePath.isEmpty(), return {}); // TODO: Call handler with unexpected?
+
+ const QString fileName = QString::fromUtf8(QUrl::toPercentEncoding(filePath.path()));
+ const QUrl url = urlForProject(dd->m_currentProjectInfo.value().name + '/')
+ .resolved(QString("files?filename=" + fileName));
+ return fetchDataRecipe<Dto::FileViewDto>(url, handler);
+}
+
Group issueHtmlRecipe(const QString &issueId, const HtmlHandler &handler)
{
QTC_ASSERT(dd->m_currentProjectInfo, return {}); // TODO: Call handler with unexpected?
@@ -569,7 +556,7 @@ void AxivionPluginPrivate::fetchIssueInfo(const QString &id)
dd->m_axivionOutputPane.updateAndShowRule(QString::fromUtf8(fixedHtml));
};
- m_issueInfoRunner.start(issueHtmlRecipe(QString("SV") + id, ruleHandler));
+ m_issueInfoRunner.start(issueHtmlRecipe(id, ruleHandler));
}
void AxivionPluginPrivate::handleOpenedDocs()
@@ -591,41 +578,16 @@ void AxivionPluginPrivate::onDocumentOpened(IDocument *doc)
if (!doc || !m_currentProjectInfo || !m_project || !m_project->isKnownFile(doc->filePath()))
return;
- IssueListSearch search;
- search.kind = "SV";
- search.filter_path = doc->filePath().relativeChildPath(m_project->projectDirectory()).path();
- search.limit = 0;
-
- const auto issuesHandler = [this](const Dto::IssueTableDto &dto) {
- Issues issues;
- const std::vector<std::map<QString, Dto::Any>> &rows = dto.rows;
- for (const auto &row : rows) {
- Issue issue;
- for (auto it = row.cbegin(); it != row.cend(); ++it) {
- if (it->first == "id")
- issue.id = anyToSimpleString(it->second);
- else if (it->first == "state")
- issue.state = anyToSimpleString(it->second);
- else if (it->first == "errorNumber")
- issue.errorNumber = anyToSimpleString(it->second);
- else if (it->first == "message")
- issue.message = anyToSimpleString(it->second);
- else if (it->first == "entity")
- issue.entity = anyToSimpleString(it->second);
- else if (it->first == "path")
- issue.filePath = anyToSimpleString(it->second);
- else if (it->first == "severity")
- issue.severity = anyToSimpleString(it->second);
- else if (it->first == "line")
- issue.lineNumber = anyToSimpleString(it->second).toInt();
- }
- issues << issue;
- }
- handleIssuesForFile(issues);
- };
+ const FilePath filePath = doc->filePath().relativeChildPath(m_project->projectDirectory());
+ QTC_ASSERT(!filePath.isEmpty(), return);
+ const auto handler = [this](const Dto::FileViewDto &data) {
+ if (data.lineMarkers.empty())
+ return;
+ handleIssuesForFile(data);
+ };
TaskTree *taskTree = new TaskTree;
- taskTree->setRecipe(issueTableRecipe(search, issuesHandler));
+ taskTree->setRecipe(lineMarkerRecipe(filePath, handler));
m_docMarksTrees.insert_or_assign(doc, std::unique_ptr<TaskTree>(taskTree));
connect(taskTree, &TaskTree::done, this, [this, doc] {
const auto it = m_docMarksTrees.find(doc);
@@ -653,24 +615,22 @@ void AxivionPluginPrivate::onDocumentClosed(IDocument *doc)
}
}
-void AxivionPluginPrivate::handleIssuesForFile(const Issues &issues)
+void AxivionPluginPrivate::handleIssuesForFile(const Dto::FileViewDto &fileView)
{
- if (issues.isEmpty())
+ if (fileView.lineMarkers.empty())
return;
Project *project = ProjectManager::startupProject();
if (!project)
return;
- const FilePath filePath = project->projectDirectory()
- .pathAppended(issues.first().filePath);
+ const FilePath filePath = project->projectDirectory().pathAppended(fileView.fileName);
- const Id axivionId(AxivionTextMarkId);
- for (const Issue &issue : issues) {
+ for (const Dto::LineMarkerDto &marker : std::as_const(fileView.lineMarkers)) {
// FIXME the line location can be wrong (even the whole issue could be wrong)
// depending on whether this line has been changed since the last axivion run and the
// current state of the file - some magic has to happen here
- new AxivionTextMark(filePath, issue);
+ new AxivionTextMark(filePath, marker);
}
}