diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 79cd708..f69a856 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -29,6 +29,7 @@ along with this program. If not, see #include "preferences.h" #include "settings.h" #include "ui_about.h" +#include "updater.h" #include #include @@ -42,6 +43,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow (parent) { QString serverApp = QCoreApplication::applicationDirPath(); + Updater *updater = new Updater(); #ifdef Q_OS_MAC // applicationDirPath() does not return bundle, but executable inside bundle @@ -90,6 +92,10 @@ MainWindow::MainWindow(QWidget *parent) connect(actionFileExit, SIGNAL(triggered()), this, SLOT(close())); connect(actionAboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + + connect(updater, SIGNAL(newVersionAvailable(QString)), + this, SLOT(onNewVersion(QString))); + updater->checkForNewVersion(); #if 0 { DbgThread *dbg = new DbgThread(pgl); @@ -140,3 +146,8 @@ void MainWindow::on_actionHelpAbout_triggered() delete aboutDialog; } +void MainWindow::onNewVersion(QString newVersion) +{ + statusBar()->showMessage(QString("New Ostinato version %1 available. " + "Visit http://ostinato.org to download").arg(newVersion)); +} diff --git a/client/mainwindow.h b/client/mainwindow.h index 2f2602d..2b68ca5 100644 --- a/client/mainwindow.h +++ b/client/mainwindow.h @@ -47,6 +47,9 @@ public: public slots: void on_actionPreferences_triggered(); void on_actionHelpAbout_triggered(); + +private slots: + void onNewVersion(QString version); }; #endif diff --git a/client/ostinato.pro b/client/ostinato.pro index 9a4af25..456f349 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -50,7 +50,8 @@ HEADERS += \ settings.h \ streamconfigdialog.h \ streamlistdelegate.h \ - streammodel.h + streammodel.h \ + updater.h FORMS += \ about.ui \ @@ -81,7 +82,8 @@ SOURCES += \ preferences.cpp \ streamconfigdialog.cpp \ streamlistdelegate.cpp \ - streammodel.cpp + streammodel.cpp \ + updater.cpp QMAKE_DISTCLEAN += object_script.* diff --git a/client/updater.cpp b/client/updater.cpp new file mode 100644 index 0000000..669cfb2 --- /dev/null +++ b/client/updater.cpp @@ -0,0 +1,127 @@ +/* +Copyright (C) 2015 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#include "updater.h" + +#include +#include +#include + +extern const char* version; + +Updater::Updater() +{ + http_ = NULL; + file_ = NULL; + +#if 1 + // Tests! + Q_ASSERT(isVersionNewer("1.1", "1") == true); + Q_ASSERT(isVersionNewer("10.1", "2") == true); + Q_ASSERT(isVersionNewer("0.10", "0.2") == true); + Q_ASSERT(isVersionNewer("1.10.1", "1.2.3") == true); +#endif +} + +Updater::~Updater() +{ + delete http_; + delete file_; +} + +void Updater::checkForNewVersion() +{ + http_ = new QHttp("wiki.ostinato.googlecode.com"); + file_ = new QTemporaryFile(); + + connect(http_, SIGNAL(responseHeaderReceived(QHttpResponseHeader)), + this, SLOT(responseReceived(QHttpResponseHeader))); + connect(http_, SIGNAL(requestFinished(int, bool)), + this, SLOT(parseXml(int, bool))); + connect(http_, SIGNAL(stateChanged(int)), + this, SLOT(stateUpdate(int))); + + file_->open(); + qDebug("Updater: PAD XML file - %s", qPrintable(file_->fileName())); + + http_->get("/hg/html/pad.xml", file_); + qDebug("Updater: %s", qPrintable(http_->currentRequest().toString() + .replace("\r\n", "\nUpdater: "))); +} + +void Updater::stateUpdate(int state) +{ + qDebug("Updater: state %d", state); +} + +void Updater::responseReceived(QHttpResponseHeader response) +{ + qDebug("Updater: HTTP/%d.%d %d %s", + response.majorVersion(), response.minorVersion(), + response.statusCode(), qPrintable(response.reasonPhrase())); +} + +void Updater::parseXml(int id, bool error) +{ + QXmlStreamReader xml; + QString newVersion; + + if (error) { + qDebug("Updater: %s", qPrintable(http_->errorString())); + goto _exit; + } + + // Close and reopen the file so that we read from the top + file_->close(); + file_->open(); + xml.setDevice(file_); + + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && (xml.name() == "Program_Version")) + newVersion = xml.readElementText(); + } + + qDebug("Updater: latest version = %s", qPrintable(newVersion)); + if (!newVersion.isEmpty() && isVersionNewer(newVersion, QString(version))) + emit newVersionAvailable(newVersion); + +_exit: + // Job done, time to self-destruct + deleteLater(); +} + +bool Updater::isVersionNewer(QString newVersion, QString curVersion) +{ + QStringList curVer = QString(curVersion).split('.'); + QStringList newVer = QString(newVersion).split('.'); + + for (int i = 0; i < qMin(curVer.size(), newVer.size()); i++) { + bool isOk; + if (newVer.at(i).toUInt(&isOk) > curVer.at(i).toUInt(&isOk)) + return true; + } + + if (newVer.size() > curVer.size()) + return true; + + return false; +} + + diff --git a/client/updater.h b/client/updater.h new file mode 100644 index 0000000..2d61e3d --- /dev/null +++ b/client/updater.h @@ -0,0 +1,52 @@ +/* +Copyright (C) 2015 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#ifndef _UPDATER_H +#define _UPDATER_H + +#include +#include + +class QHttp; +class QTemporaryFile; + +class Updater : public QObject +{ + Q_OBJECT +public: + Updater(); + virtual ~Updater(); + void checkForNewVersion(); + static bool isVersionNewer(QString newVersion, QString curVersion); + +signals: + void newVersionAvailable(QString); + +private slots: + void stateUpdate(int state); + void responseReceived(QHttpResponseHeader response); + void parseXml(int id, bool error); + +private: + QHttp *http_; + QTemporaryFile *file_; +}; + +#endif +