#
#
# add_file "guitone/res/forms/application_update.ui"
# content [cfb6889da734fdfa20f68943c73d93983951ce5a]
#
# add_file "guitone/src/view/dialogs/ApplicationUpdate.cpp"
# content [eaf85075d1a7efa6517061e099a28b4b90beb22a]
#
# add_file "guitone/src/view/dialogs/ApplicationUpdate.h"
# content [5f42159d23f734674a94869ad9ed1f52d51ca9b6]
#
# patch "guitone/guitone.pro"
# from [385a99b8d611c6c3eece333dd1e8add6438d9f33]
# to [25e4e5caf9d2f4b8c6771f0826f74efd9a84b766]
#
# patch "guitone/src/monotone/Monotone.cpp"
# from [c022744d0e1f616a544f8702e9bb4ff2b72a4dc6]
# to [eecfb2cd2d994160207be138cce8dbfcc1a2fd97]
#
# patch "guitone/src/monotone/Monotone.h"
# from [8ed8e4851e892adfd5c8d445ff798f39a6a0019b]
# to [213aa23621ca345b374b3f6ef790f09dd69b3cf0]
#
# patch "guitone/src/view/MainWindow.cpp"
# from [e80f15193271437547c136a59a25e9d29bc37f40]
# to [9ef3c4f865905bad693c01929f732595f3a222ca]
#
============================================================
--- guitone/res/forms/application_update.ui cfb6889da734fdfa20f68943c73d93983951ce5a
+++ guitone/res/forms/application_update.ui cfb6889da734fdfa20f68943c73d93983951ce5a
@@ -0,0 +1,98 @@
+
+ ApplicationUpdateDialog
+
+
+
+ 0
+ 0
+ 541
+ 376
+
+
+
+ A new version of guitone is available!
+
+
+ :/icons/guitone.png
+
+
+
+ 9
+
+
+ 6
+
+ -
+
+
+ 0
+
+
+ 6
+
+
-
+
+
+ -
+
+
+ 0
+
+
+ 6
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Visit website
+
+
+
+ -
+
+
+ Close
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ close
+ clicked()
+ ApplicationUpdateDialog
+ accept()
+
+
+ 222
+ 263
+
+
+ 199
+ 149
+
+
+
+
+
============================================================
--- guitone/src/view/dialogs/ApplicationUpdate.cpp eaf85075d1a7efa6517061e099a28b4b90beb22a
+++ guitone/src/view/dialogs/ApplicationUpdate.cpp eaf85075d1a7efa6517061e099a28b4b90beb22a
@@ -0,0 +1,110 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Thomas Keller *
+ * address@hidden *
+ * *
+ * This program 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include "ApplicationUpdate.h"
+#include "SignalWaiter.h"
+#include "Guitone.h"
+#include "Platform.h"
+
+#include
+#include
+
+ApplicationUpdate::ApplicationUpdate(QWidget * parent)
+ : Dialog(parent), update_available(false)
+{
+ setupUi(this);
+ Dialog::init();
+
+ connect(
+ visitWebsite, SIGNAL(clicked()),
+ this, SLOT(openWebsite())
+ );
+
+ QHttp http;
+ http.setHost("guitone.thomaskeller.biz");
+ http.get("/appcast.xml");
+
+ SignalWaiter waiter(&http, SIGNAL(done(bool)));
+
+ // TODO: we definitely should display some status window here
+ // while waiting for a response on slow connections
+ waiter.wait();
+
+ QDomDocument doc;
+ QString err;
+ int line, col;
+
+ if (!doc.setContent(http.readAll(), true, &err, &line, &col))
+ {
+ W(QString("Cannot parse document: %1 (line %2, col %3)")
+ .arg(err).arg(line).arg(col));
+ return;
+ }
+
+ QDomElement channel = doc.documentElement().firstChild().toElement();
+ Q_ASSERT(!channel.isNull());
+
+ QDomNodeList items = channel.elementsByTagName("item");
+
+ QPair latest(GUITONE_VERSION, "");
+
+ for (int i=0, j=items.size(); i 0)
+ {
+ latest.first = version;
+ QDomNodeList descs = item.elementsByTagName("description");
+ Q_ASSERT(descs.size() == 1);
+ QDomElement desc = descs.item(0).toElement();
+ Q_ASSERT(!desc.isNull());
+ latest.second = desc.text();
+ }
+ }
+ }
+
+ if (latest.first != GUITONE_VERSION)
+ {
+ textBrowser->setHtml(latest.second);
+ update_available = true;
+ }
+}
+
+ApplicationUpdate::~ApplicationUpdate() {}
+
+void ApplicationUpdate::openWebsite()
+{
+ Platform::openFile(this, "http://guitone.thomaskeller.biz");
+ accept();
+}
+
============================================================
--- guitone/src/view/dialogs/ApplicationUpdate.h 5f42159d23f734674a94869ad9ed1f52d51ca9b6
+++ guitone/src/view/dialogs/ApplicationUpdate.h 5f42159d23f734674a94869ad9ed1f52d51ca9b6
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Thomas Keller *
+ * address@hidden *
+ * *
+ * This program 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef APPLICATION_UPDATE_H
+#define APPLICATION_UPDATE_H
+
+#include "ui_application_update.h"
+#include "Dialog.h"
+
+class ApplicationUpdate : public Dialog, private Ui::ApplicationUpdateDialog
+{
+ Q_OBJECT
+
+public:
+ ApplicationUpdate(QWidget*);
+ ~ApplicationUpdate();
+ inline bool updateAvailable() { return update_available; };
+
+private:
+ bool update_available;
+
+private slots:
+ void openWebsite();
+};
+
+#endif
============================================================
--- guitone/guitone.pro 385a99b8d611c6c3eece333dd1e8add6438d9f33
+++ guitone/guitone.pro 25e4e5caf9d2f4b8c6771f0826f74efd9a84b766
@@ -1,11 +1,12 @@
#
# Common configuration
#
-GUITONE_VERSION = "0.6-dev"
+GUITONE_VERSION = "0.6"
TEMPLATE = app
TARGET = guitone
CONFIG += qt debug
+QT += xml network
DEFINES += GUITONE_VERSION=\\\"$${GUITONE_VERSION}\\\"
INCLUDEPATH = src/ \
@@ -35,6 +36,7 @@ HEADERS += src/view/MainWindow.h \
src/view/dialogs/ChangesetBrowser.h \
src/view/dialogs/RevisionManifest.h \
src/view/dialogs/CommitRevision.h \
+ src/view/dialogs/ApplicationUpdate.h \
src/monotone/Monotone.h \
src/monotone/MonotoneDelegate.h \
src/monotone/FileExporter.h \
@@ -89,6 +91,7 @@ SOURCES += src/view/MainWindow.cpp \
src/view/dialogs/ChangesetBrowser.cpp \
src/view/dialogs/RevisionManifest.cpp \
src/view/dialogs/CommitRevision.cpp \
+ src/view/dialogs/ApplicationUpdate.cpp \
src/monotone/Monotone.cpp \
src/monotone/MonotoneDelegate.cpp \
src/monotone/FileExporter.cpp \
@@ -136,7 +139,8 @@ FORMS += res/forms/select_revision.ui
res/forms/main_window.ui \
res/forms/changeset_browser.ui \
res/forms/manifest.ui \
- res/forms/commit_revision.ui
+ res/forms/commit_revision.ui \
+ res/forms/application_update.ui
UI_DIR = tmp
OBJECTS_DIR = tmp
============================================================
--- guitone/src/monotone/Monotone.cpp c022744d0e1f616a544f8702e9bb4ff2b72a4dc6
+++ guitone/src/monotone/Monotone.cpp eecfb2cd2d994160207be138cce8dbfcc1a2fd97
@@ -577,7 +577,7 @@ bool Monotone::checkProgramVersion(const
return false;
}
- QRegExp regex("^monotone (\\d+).(\\d+)");
+ QRegExp regex("^monotone (\\d+(?:\\.\\d+))");
if (regex.indexIn(output) == -1)
{
@@ -585,22 +585,14 @@ bool Monotone::checkProgramVersion(const
return false;
}
- QStringList curVersion = regex.capturedTexts();
- curVersion.pop_front();
- QStringList needVersion = RequiredProgramVersion.split(".");
-
+ QString curVersion = regex.cap(1);
+
D(QString("monotone version: %1, need: %2")
- .arg(curVersion.join("."))
+ .arg(curVersion)
.arg(RequiredProgramVersion)
);
- unsigned int curMajor = curVersion.at(0).toUInt();
- unsigned int curMinor = curVersion.at(1).toUInt();
-
- unsigned int needMajor = needVersion.at(0).toUInt();
- unsigned int needMinor = needVersion.at(1).toUInt();
-
- return curMajor > needMajor || curMajor == needMajor && curMinor >= needMinor;
+ return versionCompare(curVersion, RequiredProgramVersion) >= 0;
}
bool Monotone::checkInterfaceVersion(const QString & path)
@@ -614,7 +606,7 @@ bool Monotone::checkInterfaceVersion(con
return false;
}
- QRegExp regex("^(\\d+).(\\d+)");
+ QRegExp regex("^(\\d+(?:\\.\\d+))");
if (regex.indexIn(output) == -1)
{
@@ -622,22 +614,15 @@ bool Monotone::checkInterfaceVersion(con
return false;
}
- QStringList curVersion = regex.capturedTexts();
- curVersion.pop_front();
+ QString curVersion = regex.cap(1);
QStringList needVersion = RequiredInterfaceVersion.split(".");
D(QString("interface version: %1, need: %2")
- .arg(curVersion.join("."))
+ .arg(curVersion)
.arg(RequiredInterfaceVersion)
);
- unsigned int curMajor = curVersion.at(0).toUInt();
- unsigned int curMinor = curVersion.at(1).toUInt();
-
- unsigned int needMajor = needVersion.at(0).toUInt();
- unsigned int needMinor = needVersion.at(1).toUInt();
-
- return curMajor > needMajor || curMajor == needMajor && curMinor >= needMinor;
+ return versionCompare(curVersion, RequiredInterfaceVersion) >= 0;
}
// strip mtn: warning: and alike from error strings coming from mtn
@@ -663,3 +648,32 @@ QString Monotone::stripMtnPrefix(const Q
return output.trimmed();
}
+// Returns
+// -1 if right is greater
+// 0 if both are equal
+// 1 if left is greater
+// FIXME: this should be moved somewhere else
+int Monotone::versionCompare(const QString & left, const QString & right)
+{
+ QStringList leftParts = left.split(".");
+ QStringList rightParts = right.split(".");
+
+ int leftCount = leftParts.size();
+ int rightCount = rightParts.size();
+ int maxCount = leftCount > rightCount ? leftCount : rightCount;
+
+ for (int i=0, j=maxCount; i r) return 1;
+ return -1;
+ }
+
+ return 0;
+}
+
============================================================
--- guitone/src/monotone/Monotone.h 8ed8e4851e892adfd5c8d445ff798f39a6a0019b
+++ guitone/src/monotone/Monotone.h 213aa23621ca345b374b3f6ef790f09dd69b3cf0
@@ -35,6 +35,7 @@ class Monotone : public QObject
static bool checkProgramVersion(const QString &);
static bool checkInterfaceVersion(const QString &);
static QString stripMtnPrefix(const QString &);
+ static int versionCompare(const QString &, const QString &);
static const QString RequiredProgramVersion;
static const QString RequiredInterfaceVersion;
static const int StdioBufferSize;
============================================================
--- guitone/src/view/MainWindow.cpp e80f15193271437547c136a59a25e9d29bc37f40
+++ guitone/src/view/MainWindow.cpp 9ef3c4f865905bad693c01929f732595f3a222ca
@@ -30,6 +30,7 @@
#include "UpdateWorkspace.h"
#include "CommitRevision.h"
#include "CheckoutRevision.h"
+#include "ApplicationUpdate.h"
#include "Platform.h"
#include "Preferences.h"
#include "KeyManagement.h"
@@ -614,7 +615,19 @@ void MainWindow::on_actionCheck_for_upda
#ifdef Q_WS_MAC
CocoaUtil::checkForUpdates();
#else
- Platform::openFile(this, "http://guitone.thomaskeller.biz");
+ ApplicationUpdate dlg(this);
+ if (!dlg.updateAvailable())
+ {
+ QMessageBox::information(
+ this,
+ tr("No updates available"),
+ tr("Your version of guitone (%1) is already up-to-date.")
+ .arg(GUITONE_VERSION),
+ QMessageBox::Ok
+ );
+ return;
+ }
+ dlg.exec();
#endif
}