diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui
index d70180d4..ea7d340a 100644
--- a/forms/mainwindow.ui
+++ b/forms/mainwindow.ui
@@ -1715,7 +1715,7 @@
0
0
100
- 30
+ 16
@@ -1809,7 +1809,7 @@
0
0
100
- 30
+ 16
@@ -1903,7 +1903,7 @@
0
0
100
- 30
+ 16
@@ -2003,7 +2003,7 @@
0
0
100
- 30
+ 16
@@ -2097,7 +2097,7 @@
0
0
100
- 30
+ 16
@@ -3112,6 +3112,7 @@
+
diff --git a/include/mainwindow.h b/include/mainwindow.h
index e95db003..7d512ef5 100644
--- a/include/mainwindow.h
+++ b/include/mainwindow.h
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include "project.h"
#include "orderedjson.h"
#include "config.h"
@@ -288,6 +289,7 @@ private slots:
void on_spinBox_SelectedCollision_valueChanged(int collision);
void on_actionRegion_Map_Editor_triggered();
void on_actionPreferences_triggered();
+ void on_actionCheck_for_Updates_triggered();
void togglePreferenceSpecificUi();
void on_actionProject_Settings_triggered();
void on_actionCustom_Scripts_triggered();
@@ -296,6 +298,7 @@ private slots:
public:
Ui::MainWindow *ui;
Editor *editor = nullptr;
+ QPointer networkAccessManager = nullptr;
private:
QLabel *label_MapRulerStatus = nullptr;
@@ -396,6 +399,8 @@ private:
QObjectList shortcutableObjects() const;
void addCustomHeaderValue(QString key, QJsonValue value, bool isNew = false);
int insertTilesetLabel(QStringList * list, QString label);
+
+ void checkForUpdates();
};
enum MapListUserRoles {
diff --git a/porymap.pro b/porymap.pro
index ddb3f621..90072830 100644
--- a/porymap.pro
+++ b/porymap.pro
@@ -4,7 +4,7 @@
#
#-------------------------------------------------
-QT += core gui qml
+QT += core gui qml network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 3a649062..7027ebca 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -242,6 +242,63 @@ void MainWindow::initExtraSignals() {
label_MapRulerStatus->setAlignment(Qt::AlignCenter);
label_MapRulerStatus->setTextFormat(Qt::PlainText);
label_MapRulerStatus->setTextInteractionFlags(Qt::TextSelectableByMouse);
+
+ // TODO: (if enabled) queue an automatic "Check for Updates"
+}
+
+// TODO: Relocate
+#include
+#include
+void MainWindow::on_actionCheck_for_Updates_triggered() {
+ checkForUpdates();
+}
+
+void MainWindow::checkForUpdates() {
+ if (!this->networkAccessManager)
+ this->networkAccessManager = new QNetworkAccessManager(this);
+
+ // We could get ".../releases/latest" to retrieve less data, but this would run into problems if the
+ // most recent item on the releases page is not actually a new release (like the static windows build).
+ QNetworkRequest request(QUrl("https://api.github.com/repos/huderlem/porymap/releases"));
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+
+ QNetworkReply * reply = this->networkAccessManager->get(request);
+
+ connect(reply, &QNetworkReply::finished, [this, reply] {
+ QJsonDocument data = QJsonDocument::fromJson(reply->readAll());
+ QJsonArray releases = data.array();
+
+ // Read all the items on the releases page, stopping when we find a tag that parses as a version identifier.
+ // Objects in the releases page data are sorted newest to oldest. Although I can't find a guarantee of this in
+ // GitHub's API documentation, this seems unlikely to change.
+ for (int i = 0; i < releases.size(); i++) {
+ auto release = releases.at(i).toObject();
+
+ const QStringList tag = release.value("tag_name").toString().split(".");
+ if (tag.length() != 3) continue;
+
+ bool ok;
+ int major = tag.at(0).toInt(&ok);
+ if (!ok) continue;
+ int minor = tag.at(1).toInt(&ok);
+ if (!ok) continue;
+ int patch = tag.at(2).toInt(&ok);
+ if (!ok) continue;
+
+ const QString downloadLink = release.value("html_url").toString();
+ if (downloadLink.isEmpty()) continue;
+
+ // We've found a valid release tag, we can stop reading.
+ logInfo(QString("Newest release is %1.%2.%3\n%4").arg(major).arg(minor).arg(patch).arg(downloadLink));
+
+ // If the release was published very recently it won't have a description yet, in which case don't tell the user.
+ const QString changelog = release.value("body").toString();
+ if (changelog.isEmpty()) break;
+
+ // TODO: Compare version to host version, then show appropriate dialog
+ break;
+ }
+ });
}
void MainWindow::initEditor() {