#
#
# delete "src/util/SignalWaiter.cpp"
#
# delete "src/util/SignalWaiter.h"
#
# patch "NEWS"
# from [d695681e168b4be74c9d423c5fbd1f2743fb9975]
# to [09aa8102c6720729211af155002349be28690a97]
#
# patch "guitone.pro"
# from [fa8a9b837bc6c3f23089fa2c7c960eb43c3954a0]
# to [a84bcaf4e5e125fed275b7d70c4d8dc030108c58]
#
# patch "res/forms/application_update.ui"
# from [7d2b3993e719ba0fea62c815d0cee25d6fd48562]
# to [5258144de27b682d19ea5cf5e9edf2a506cf419c]
#
# patch "src/Guitone.cpp"
# from [7d7e4e26247c3ecee04de41553e97715699ae723]
# to [a8876c05a77ca3e2a69cb7dc5b80745de0a0fad9]
#
# patch "src/util/Settings.cpp"
# from [1605f183154e84e6dcf6afd3e7505afc7d8aad53]
# to [7fe33df35ead425818ac4cbd35444dbb82de072f]
#
# patch "src/util/Settings.h"
# from [c270582aa028c7a903405c024cabd2e6ed0cb965]
# to [19b198d8e78259744a90bb47f052b0699a668913]
#
# patch "src/view/dialogs/ApplicationUpdate.cpp"
# from [1877bdbdb1b60402d2b30335a9312c1a7b9dfbec]
# to [c9c4629c72bbc2c0eaad7a16c5eed07a1cce7fe5]
#
# patch "src/view/dialogs/ApplicationUpdate.h"
# from [15d58d7ed4e847db2d4669c24fbe4bd894786722]
# to [3c09b46adc9dd244f503df8ad9a27ada57813483]
#
# patch "src/vocab.h"
# from [7f21cf44b67083fb6101067d98ae4be51b44fea9]
# to [b4b58ec186846eedc156ee5bf76f3b6d757a58d0]
#
============================================================
--- NEWS d695681e168b4be74c9d423c5fbd1f2743fb9975
+++ NEWS 09aa8102c6720729211af155002349be28690a97
@@ -8,8 +8,9 @@
and changeset browser and open the diff dialog for these files
- new: support for viewing the complete changeset for merge revisions in the
changeset browser
- - new: a panel to view and edit database variables
+ - new: a panel to view and edit database variables
(open it via View > Panels > Database Variables)
+ - new: possibility to skip a new program version in the native dialog
- improved: startup dialog slightly changed - now contains the possibility
to edit the preferences, open recent databases and workspaces. Removed this
functionality from the initialization phase of the application which was
@@ -20,9 +21,12 @@
huge workloads (f.e. big chunks of inventory output)
- improved: starting with mtn 0.39 incremental workspace loading is enabled
by default
+ - bugfix: if a not supported mtn version is found and the user hits cancel
+ in the preferences dialog, guitone is now closed properly and does not
+ sit in the background doing nothing
- bugfix: if guitone is closed too fast (f.e. before the internal mtn thread
could be started), the application wasn't closed properly, but only removed
- all open windows.
+ all open windows
2008-01-16 (0.7)
- new: possibility to display the history of a single file in chronological
============================================================
--- guitone.pro fa8a9b837bc6c3f23089fa2c7c960eb43c3954a0
+++ guitone.pro a84bcaf4e5e125fed275b7d70c4d8dc030108c58
@@ -87,7 +87,6 @@ HEADERS = src/view/TreeView.h \
src/util/BasicIOWriter.h \
src/util/Settings.h \
src/util/DiffParser.h \
- src/util/SignalWaiter.h \
src/util/Platform.h \
src/util/TreeBuilder.h \
src/util/DebugLog.h \
@@ -160,7 +159,6 @@ SOURCES += src/view/TreeView.cpp \
src/util/BasicIOWriter.cpp \
src/util/Settings.cpp \
src/util/DiffParser.cpp \
- src/util/SignalWaiter.cpp \
src/util/Platform.cpp \
src/util/TreeBuilder.cpp \
src/util/DebugLog.cpp \
============================================================
--- res/forms/application_update.ui 7d2b3993e719ba0fea62c815d0cee25d6fd48562
+++ res/forms/application_update.ui 5258144de27b682d19ea5cf5e9edf2a506cf419c
@@ -16,32 +16,66 @@
:/icons/guitone.png
-
+
+ 6
+
+
9
-
- 6
+
+ 9
+
+ 9
+
+
+ 9
+
-
-
+
+ 6
+
+
0
-
- 6
+
+ 0
+
+ 0
+
+
+ 0
+
-
-
-
+
+ 6
+
+
0
-
- 6
+
+ 0
+
+ 0
+
+
+ 0
+
-
+
+
+ Skip this version
+
+
+
+ -
Visit website
============================================================
--- src/Guitone.cpp 7d7e4e26247c3ecee04de41553e97715699ae723
+++ src/Guitone.cpp a8876c05a77ca3e2a69cb7dc5b80745de0a0fad9
@@ -112,6 +112,7 @@ void Guitone::setMonotoneBinaryPath()
// the user has rejected the dialog, i.e. made no new settings
if (dialog.exec() == QDialog::Rejected)
{
+ quit();
return;
}
}
@@ -367,21 +368,7 @@ void Guitone::checkForApplicationUpdates
updateDialog = new ApplicationUpdate(NULL);
}
- if (!updateDialog->updateAvailable())
- {
- if (!silent)
- {
- QMessageBox::information(
- NULL,
- tr("No updates available"),
- tr("Your version of guitone (%1) is already up-to-date.")
- .arg(GUITONE_VERSION),
- QMessageBox::Ok
- );
- }
- return;
- }
- updateDialog->show();
+ updateDialog->checkForUpdates(silent);
#endif
}
============================================================
--- src/util/Settings.cpp 1605f183154e84e6dcf6afd3e7505afc7d8aad53
+++ src/util/Settings.cpp 7fe33df35ead425818ac4cbd35444dbb82de072f
@@ -52,6 +52,18 @@ bool Settings::getBool(const QString & n
return singleton()->value(name, defaultVal).toBool();
}
+void Settings::setString(const QString & name, const QString & value)
+{
+ I(!name.isEmpty());
+ singleton()->setValue(name, value);
+}
+
+QString Settings::getString(const QString & name, const QString & defaultVal)
+{
+ I(!name.isEmpty());
+ return singleton()->value(name, defaultVal).toString();
+}
+
void Settings::setWindowGeometry(const QString & windowClass, const QByteArray & data)
{
I(!windowClass.isEmpty());
@@ -74,7 +86,7 @@ QString Settings::getMtnBinaryPath()
return singleton()->value("MtnExePath", "mtn").toString();
}
-void Settings::setMtnBinaryPath(QString path)
+void Settings::setMtnBinaryPath(const QString & path)
{
singleton()->setValue("MtnExePath", path);
}
@@ -110,7 +122,7 @@ void Settings::setLogLevel(int verbosity
singleton()->setValue("LogLevel", verbosity);
}
-void Settings::saveHeaderViewState(QHeaderView *view, QString name)
+void Settings::saveHeaderViewState(QHeaderView * view, const QString & name)
{
I(!name.isEmpty());
QStringList cols;
@@ -126,7 +138,7 @@ void Settings::saveHeaderViewState(QHead
settings->setValue(name, cols.join(","));
}
-void Settings::restoreHeaderViewState(QHeaderView *view, QString name)
+void Settings::restoreHeaderViewState(QHeaderView * view, const QString & name)
{
I(!name.isEmpty());
QString colConfig(singleton()->value(name).toString());
@@ -148,13 +160,13 @@ void Settings::restoreHeaderViewState(QH
}
}
-QByteArray Settings::getSplitterState(QString name)
+QByteArray Settings::getSplitterState(const QString & name)
{
I(!name.isEmpty());
return singleton()->value(name).toByteArray();
}
-void Settings::setSplitterState(const QByteArray & byteArray, QString name)
+void Settings::setSplitterState(const QByteArray & byteArray, const QString & name)
{
I(!name.isEmpty());
Settings *settings = singleton();
============================================================
--- src/util/Settings.h c270582aa028c7a903405c024cabd2e6ed0cb965
+++ src/util/Settings.h 19b198d8e78259744a90bb47f052b0699a668913
@@ -30,16 +30,19 @@ public:
static void setBool(const QString &, bool);
static bool getBool(const QString &, bool);
+ static void setString(const QString &, const QString &);
+ static QString getString(const QString &, const QString &);
+
static void setWindowGeometry(const QString &, const QByteArray &);
static QByteArray getWindowGeometry(const QString &);
static QStringList getItemList(const QString &);
static void setItemList(const QString &, const QStringList &);
- static void addItemToList(const QString&, const QString &, int);
+ static void addItemToList(const QString &, const QString &, int);
static void removeItemFromList(const QString &, const QString &);
static QString getMtnBinaryPath();
- static void setMtnBinaryPath(QString);
+ static void setMtnBinaryPath(const QString &);
static bool getConsoleLogEnabled();
static void setConsoleLogEnabled(bool);
@@ -48,19 +51,19 @@ public:
static int getLogLevel();
static void setLogLevel(int);
- static void saveHeaderViewState(QHeaderView *, QString);
- static void restoreHeaderViewState(QHeaderView *, QString);
+ static void saveHeaderViewState(QHeaderView *, const QString &);
+ static void restoreHeaderViewState(QHeaderView *, const QString &);
- static QByteArray getSplitterState(QString);
- static void setSplitterState(const QByteArray &, QString);
+ static QByteArray getSplitterState(const QString &);
+ static void setSplitterState(const QByteArray &, const QString &);
static void sync();
private:
Settings();
~Settings(void);
- static Settings* singleton();
- static Settings* instance;
+ static Settings * singleton();
+ static Settings * instance;
};
============================================================
--- src/view/dialogs/ApplicationUpdate.cpp 1877bdbdb1b60402d2b30335a9312c1a7b9dfbec
+++ src/view/dialogs/ApplicationUpdate.cpp c9c4629c72bbc2c0eaad7a16c5eed07a1cce7fe5
@@ -17,39 +17,115 @@
***************************************************************************/
#include "ApplicationUpdate.h"
-#include "SignalWaiter.h"
#include "MonotoneManager.h"
#include "Platform.h"
+#include "Settings.h"
-#include
#include
+#include
ApplicationUpdate::ApplicationUpdate(QWidget * parent)
- : Dialog(parent), update_available(false)
+ : Dialog(parent)
{
setupUi(this);
Dialog::init();
+ setWindowModality(Qt::ApplicationModal);
+
connect(
visitWebsite, SIGNAL(clicked()),
this, SLOT(openWebsite())
);
- QHttp http;
- http.setHost("guitone.thomaskeller.biz");
- http.get("/web/appcast.xml");
+ connect(
+ skipVersion, SIGNAL(clicked()),
+ this, SLOT(skipThisVersion())
+ );
- SignalWaiter waiter(&http, SIGNAL(done(bool)));
+ httpConnection = new QHttp();
+ connect(
+ httpConnection, SIGNAL(done(bool)),
+ this, SLOT(processHttpResult(bool))
+ );
+}
- // TODO: we definitely should display some status window here
- // while waiting for a response on slow connections
- waiter.wait();
+ApplicationUpdate::~ApplicationUpdate()
+{
+ delete httpConnection;
+}
+/**
+ * If the we check for a new application version silently, the user
+ * is not nagged with error messages like f.e. that there is no new version
+ * available or that the check failed. However, if there is a new version
+ * available, the dialog is shown to the user.
+ * Now if he clicks on "SkipThisVersion" in the dialog, he is not remembered
+ * again on the next application start that there is a new version, BUT
+ * only unless he triggers the version check by hand from the "File" menu
+ * which calls checkForUpdates without the silent flag set to false. In
+ * this case the "Skip this version" button is also made invisible since it
+ * has no functionality here.
+ */
+void ApplicationUpdate::checkForUpdates(bool silent)
+{
+ if (httpConnection->hasPendingRequests())
+ {
+ C("HTTP connection has pending requests... aborting");
+ return;
+ }
+
+ silentCheck = silent;
+
+ httpConnection->setHost("guitone.thomaskeller.biz");
+ httpConnection->get("/web/appcast.xml");
+
+ QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+}
+
+void ApplicationUpdate::processHttpResult(bool error)
+{
+ QApplication::restoreOverrideCursor();
+
+ if (error)
+ {
+ QString errStr = httpConnection->errorString();
+
+ C(QString("unable to fetch update information: %1").arg(errStr));
+
+ if (!silentCheck)
+ {
+ QMessageBox::critical(
+ this,
+ tr("Error"),
+ tr("Unable to fetch update information:\n%1").arg(errStr),
+ QMessageBox::Ok, 0, 0
+ );
+ }
+ return;
+ }
+
+ int statusCode = httpConnection->lastResponse().statusCode();
+ if (statusCode != 200)
+ {
+ C(QString("status code was: %1").arg(statusCode));
+
+ if (!silentCheck)
+ {
+ QMessageBox::critical(
+ this,
+ tr("Error"),
+ tr("Unable to fetch update information (error %1).").arg(statusCode),
+ QMessageBox::Ok, 0, 0
+ );
+ }
+ return;
+ }
+
QDomDocument doc;
QString err;
int line, col;
- if (!doc.setContent(http.readAll(), true, &err, &line, &col))
+ if (!doc.setContent(httpConnection->readAll(), true, &err, &line, &col))
{
W(QString("Cannot parse document: %1 (line %2, col %3)")
.arg(err).arg(line).arg(col));
@@ -61,7 +137,8 @@ ApplicationUpdate::ApplicationUpdate(QWi
QDomNodeList items = channel.elementsByTagName("item");
- QPair latest(GUITONE_VERSION, "");
+ latestVersion = GUITONE_VERSION;
+ QString versionDescription;
for (int i=0, j=items.size(); i 0)
+ if (MonotoneManager::versionCompare(version, latestVersion) > 0)
{
- latest.first = version;
+ latestVersion = version;
QDomNodeList descs = item.elementsByTagName("description");
I(descs.size() == 1);
QDomElement desc = descs.item(0).toElement();
I(!desc.isNull());
- latest.second = desc.text();
+ versionDescription = desc.text();
}
}
}
- if (latest.first != GUITONE_VERSION)
+ if (latestVersion != GUITONE_VERSION)
{
- textBrowser->setHtml(latest.second);
- update_available = true;
+ QString versionToSkip = Settings::getString("SkipGuitoneVersion", "");
+
+ if (silentCheck && !versionToSkip.isEmpty() &&
+ MonotoneManager::versionCompare(latestVersion, versionToSkip) <= 0)
+ {
+ L(QString("skipping %1 per user request").arg(latestVersion));
+ return;
+ }
+
+ textBrowser->setHtml(versionDescription);
+ if (!silentCheck)
+ {
+ skipVersion->setVisible(false);
+ }
+
+ show();
}
+ else
+ {
+ if (!silentCheck)
+ {
+ QMessageBox::information(
+ NULL,
+ tr("No updates available"),
+ tr("Your version of guitone (%1) is already up-to-date.")
+ .arg(GUITONE_VERSION),
+ QMessageBox::Ok
+ );
+ }
+ }
}
-ApplicationUpdate::~ApplicationUpdate() {}
-
void ApplicationUpdate::openWebsite()
{
Platform::openFile("http://guitone.thomaskeller.biz");
accept();
}
+void ApplicationUpdate::skipThisVersion()
+{
+ Settings::setString("SkipGuitoneVersion", latestVersion);
+ accept();
+}
+
+
============================================================
--- src/view/dialogs/ApplicationUpdate.h 15d58d7ed4e847db2d4669c24fbe4bd894786722
+++ src/view/dialogs/ApplicationUpdate.h 3c09b46adc9dd244f503df8ad9a27ada57813483
@@ -22,19 +22,25 @@
#include "ui_application_update.h"
#include "Dialog.h"
+#include
+
class ApplicationUpdate : public Dialog, private Ui::ApplicationUpdateDialog
{
Q_OBJECT
public:
ApplicationUpdate(QWidget *);
~ApplicationUpdate();
- inline bool updateAvailable() { return update_available; };
+ void checkForUpdates(bool);
private:
- bool update_available;
+ QHttp * httpConnection;
+ bool silentCheck;
+ QString latestVersion;
private slots:
+ void processHttpResult(bool);
void openWebsite();
+ void skipThisVersion();
};
#endif
============================================================
--- src/vocab.h 7f21cf44b67083fb6101067d98ae4be51b44fea9
+++ src/vocab.h b4b58ec186846eedc156ee5bf76f3b6d757a58d0
@@ -5,10 +5,8 @@
// global macros and defines
//
-// if you use any of those two, you also have to include Guitone.h
class Guitone;
-#define APP reinterpret_cast(qApp)
-#define MTN(arg) APP->getMonotoneInstance(arg)
+#define APP reinterpret_cast(qApp)
#include "DebugLog.h"
#ifdef QT_NO_DEBUG
@@ -96,10 +94,11 @@ typedef QList StanzaList;
typedef QList Stanza;
typedef QList StanzaList;
+// FIXME: just a few stupid typedefs which should be expanded later on
+// to more "intelligent" objects
typedef QString GuitoneException;
-
-// TODO: maybe we can load workspace normalization into this
typedef QString WorkspacePath;
typedef QString DatabaseFile;
#endif
+