diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1a0de7e6e..3debc185b 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -71,8 +71,8 @@ project(rssguard)
set(APP_NAME "RSS Guard")
set(APP_LOW_NAME "rssguard")
-set(APP_VERSION "2.0.0.4")
-set(FILE_VERSION "2,0,0,4")
+set(APP_VERSION "2.1")
+set(FILE_VERSION "2,1,0,0")
set(APP_AUTHOR "Martin Rotter")
set(APP_URL "http://bitbucket.org/skunkos/rssguard")
set(APP_URL_ISSUES "http://bitbucket.org/skunkos/rssguard/issues")
diff --git a/resources/text/CHANGELOG b/resources/text/CHANGELOG
index 547e7e511..759e6d2dc 100644
--- a/resources/text/CHANGELOG
+++ b/resources/text/CHANGELOG
@@ -1,4 +1,15 @@
+2.1
+
+Fixed:
+
+
+Added:
+
+
+
2.0.0.4
Fixed:
diff --git a/src/core/feedsmodelcategory.cpp b/src/core/feedsmodelcategory.cpp
index 73a23efd6..f57d34805 100755
--- a/src/core/feedsmodelcategory.cpp
+++ b/src/core/feedsmodelcategory.cpp
@@ -86,9 +86,9 @@ QVariant FeedsModelCategory::data(int column, int role) const {
return m_title;
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
- return qApp->settings()->value(APP_CFG_FEEDS, COUNT_FORMAT, DEFAULT_VALUE(COUNT_FORMAT)).toString()
- .replace("%unread", QString::number(countOfUnreadMessages()))
- .replace("%all", QString::number(countOfAllMessages()));
+ return qApp->settings()->value(APP_CFG_FEEDS, SETTING(Feeds::CountFormat)).toString()
+ .replace(PLACEHOLDER_UNREAD_COUNTS, QString::number(countOfUnreadMessages()))
+ .replace(PLACEHOLDER_ALL_COUNTS, QString::number(countOfAllMessages()));
}
else {
return QVariant();
diff --git a/src/core/feedsmodelfeed.cpp b/src/core/feedsmodelfeed.cpp
index 001a2b380..c8d748519 100755
--- a/src/core/feedsmodelfeed.cpp
+++ b/src/core/feedsmodelfeed.cpp
@@ -175,8 +175,7 @@ QPair FeedsModelFeed::guessFeed(co
QByteArray feed_contents;
NetworkResult network_result = NetworkFactory::downloadFeedFile(url,
qApp->settings()->value(APP_CFG_FEEDS,
- UPDATE_TIMEOUT,
- DEFAULT_VALUE(UPDATE_TIMEOUT)).toInt(),
+ SETTING(Feeds::UpdateTimeout)).toInt(),
feed_contents,
!username.isEmpty(),
username,
@@ -288,9 +287,9 @@ QVariant FeedsModelFeed::data(int column, int role) const {
return m_title;
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
- return qApp->settings()->value(APP_CFG_FEEDS, COUNT_FORMAT, DEFAULT_VALUE(COUNT_FORMAT)).toString()
- .replace("%unread", QString::number(countOfUnreadMessages()))
- .replace("%all", QString::number(countOfAllMessages()));
+ return qApp->settings()->value(APP_CFG_FEEDS, SETTING(Feeds::CountFormat)).toString()
+ .replace(PLACEHOLDER_UNREAD_COUNTS, QString::number(countOfUnreadMessages()))
+ .replace(PLACEHOLDER_ALL_COUNTS, QString::number(countOfAllMessages()));
}
else {
return QVariant();
@@ -390,7 +389,7 @@ QVariant FeedsModelFeed::data(int column, int role) const {
void FeedsModelFeed::update() {
QByteArray feed_contents;
- int download_timeout = qApp->settings()->value(APP_CFG_FEEDS, UPDATE_TIMEOUT, DEFAULT_VALUE(UPDATE_TIMEOUT)).toInt();
+ int download_timeout = qApp->settings()->value(APP_CFG_FEEDS, SETTING(Feeds::UpdateTimeout)).toInt();
m_networkError = NetworkFactory::downloadFeedFile(url(), download_timeout, feed_contents, passwordProtected(), username(), password()).first;
if (m_networkError != QNetworkReply::NoError) {
diff --git a/src/core/feedsmodelrecyclebin.cpp b/src/core/feedsmodelrecyclebin.cpp
index 5fabc9d7f..dd48a9b88 100644
--- a/src/core/feedsmodelrecyclebin.cpp
+++ b/src/core/feedsmodelrecyclebin.cpp
@@ -62,9 +62,9 @@ QVariant FeedsModelRecycleBin::data(int column, int role) const {
return m_title;
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
- return qApp->settings()->value(APP_CFG_FEEDS, COUNT_FORMAT, DEFAULT_VALUE(COUNT_FORMAT)).toString()
- .replace("%unread", QString::number(countOfUnreadMessages()))
- .replace("%all", QString::number(countOfAllMessages()));
+ return qApp->settings()->value(APP_CFG_FEEDS, SETTING(Feeds::CountFormat)).toString()
+ .replace(PLACEHOLDER_UNREAD_COUNTS, QString::number(countOfUnreadMessages()))
+ .replace(PLACEHOLDER_ALL_COUNTS, QString::number(countOfAllMessages()));
}
else {
return QVariant();
diff --git a/src/core/messagesmodel.cpp b/src/core/messagesmodel.cpp
index 52898f9a1..6670c9610 100755
--- a/src/core/messagesmodel.cpp
+++ b/src/core/messagesmodel.cpp
@@ -108,8 +108,8 @@ int MessagesModel::messageId(int row_index) const {
}
void MessagesModel::updateDateFormat() {
- if (qApp->settings()->value(APP_CFG_MESSAGES, "use_custom_date").toBool()) {
- m_customDateFormat = qApp->settings()->value(APP_CFG_MESSAGES, "custom_date_format").toString();
+ if (qApp->settings()->value(APP_CFG_MESSAGES, SETTING(Messages::UseCustomDate)).toBool()) {
+ m_customDateFormat = qApp->settings()->value(APP_CFG_MESSAGES, SETTING(Messages::CustomDateFormat)).toString();
}
else {
m_customDateFormat = QString();
diff --git a/src/definitions/definitions.h.in b/src/definitions/definitions.h.in
index 10912ade4..216191adf 100755
--- a/src/definitions/definitions.h.in
+++ b/src/definitions/definitions.h.in
@@ -76,6 +76,9 @@
#define ACCEPT_HEADER_FOR_FEED_DOWNLOADER "application/atom+xml,application/xml;q=0.9,text/xml;q=0.8,*/*;q=0.7"
#define MIME_TYPE_ITEM_POINTER "rssguard/itempointer"
+#define PLACEHOLDER_UNREAD_COUNTS "%unread"
+#define PLACEHOLDER_ALL_COUNTS "%all"
+
#define BACKUP_NAME_SETTINGS "config"
#define BACKUP_SUFFIX_SETTINGS ".ini.backup"
#define BACKUP_NAME_DATABASE "database"
diff --git a/src/dynamic-shortcuts/dynamicshortcuts.cpp b/src/dynamic-shortcuts/dynamicshortcuts.cpp
index 80f1acad2..c36c5e74b 100755
--- a/src/dynamic-shortcuts/dynamicshortcuts.cpp
+++ b/src/dynamic-shortcuts/dynamicshortcuts.cpp
@@ -44,7 +44,6 @@ void DynamicShortcuts::load(const QList actions) {
QString shortcut_for_action = settings->value(APP_CFG_CUTS,
action->objectName(),
action->shortcut().toString(QKeySequence::PortableText)).toString();
- action->setShortcut(QKeySequence::fromString(shortcut_for_action,
- QKeySequence::PortableText));
+ action->setShortcut(QKeySequence::fromString(shortcut_for_action, QKeySequence::PortableText));
}
}
diff --git a/src/gui/feedmessageviewer.cpp b/src/gui/feedmessageviewer.cpp
index e703c1dca..3d46d588d 100755
--- a/src/gui/feedmessageviewer.cpp
+++ b/src/gui/feedmessageviewer.cpp
@@ -105,8 +105,8 @@ void FeedMessageViewer::loadSize() {
m_feedsView->loadExpandedStates();
// Restore offsets of splitters.
- m_feedSplitter->restoreState(QByteArray::fromBase64(settings->value(APP_CFG_GUI, "splitter_feeds").toString().toLocal8Bit()));
- m_messageSplitter->restoreState(QByteArray::fromBase64(settings->value(APP_CFG_GUI, "splitter_messages").toString().toLocal8Bit()));
+ m_feedSplitter->restoreState(QByteArray::fromBase64(settings->value(APP_CFG_GUI, SETTING(GUI::SplitterFeeds)).toString().toLocal8Bit()));
+ m_messageSplitter->restoreState(QByteArray::fromBase64(settings->value(APP_CFG_GUI, SETTING(GUI::SplitterMessages)).toString().toLocal8Bit()));
// Splitters are restored, now, restore widths of columns.
m_messagesView->setColumnWidth(MSG_DB_AUTHOR_INDEX, settings->value(APP_CFG_GUI,
@@ -128,7 +128,7 @@ void FeedMessageViewer::quit() {
qDebug("Feed downloader thread aborted. Deleting it from memory.");
m_feedDownloader->deleteLater();
- if (qApp->settings()->value(APP_CFG_MESSAGES, "clear_read_on_exit", false).toBool()) {
+ if (qApp->settings()->value(APP_CFG_MESSAGES, SETTING(Messages::ClearReadOnExit)).toBool()) {
m_feedsView->clearAllReadMessages();
}
}
@@ -397,8 +397,7 @@ void FeedMessageViewer::vacuumDatabase() {
void FeedMessageViewer::refreshVisualProperties() {
Qt::ToolButtonStyle button_style = static_cast(qApp->settings()->value(APP_CFG_GUI,
- "toolbar_style",
- Qt::ToolButtonIconOnly).toInt());
+ SETTING(GUI::ToolbarStyle)).toInt());
m_toolBarFeeds->setToolButtonStyle(button_style);
m_toolBarMessages->setToolButtonStyle(button_style);
diff --git a/src/gui/formsettings.cpp b/src/gui/formsettings.cpp
index cb5c6d8c0..5bd0ccc9e 100755
--- a/src/gui/formsettings.cpp
+++ b/src/gui/formsettings.cpp
@@ -182,7 +182,7 @@ void FormSettings::loadFeedsMessages() {
m_ui->m_checkRemoveReadMessagesOnExit->setChecked(settings->value(APP_CFG_MESSAGES, "clear_read_on_exit", false).toBool());
m_ui->m_checkAutoUpdate->setChecked(settings->value(APP_CFG_FEEDS, "auto_update_enabled", false).toBool());
m_ui->m_spinAutoUpdateInterval->setValue(settings->value(APP_CFG_FEEDS, "auto_update_interval", DEFAULT_AUTO_UPDATE_INTERVAL).toInt());
- m_ui->m_spinFeedUpdateTimeout->setValue(settings->value(APP_CFG_FEEDS, UPDATE_TIMEOUT, DEFAULT_VALUE(UPDATE_TIMEOUT)).toInt());
+ m_ui->m_spinFeedUpdateTimeout->setValue(settings->value(APP_CFG_FEEDS, SETTING(Feeds::UpdateTimeout)).toInt());
m_ui->m_checkUpdateAllFeedsOnStartup->setChecked(settings->value(APP_CFG_FEEDS, "feeds_update_on_startup", false).toBool());
m_ui->m_cmbCountsFeedList->addItems(QStringList() << "(%unread)" << "[%unread]" << "%unread/%all" << "%unread-%all" << "[%unread|%all]");
m_ui->m_cmbCountsFeedList->setEditText(settings->value(APP_CFG_FEEDS, "count_format", "(%unread)").toString());
@@ -216,7 +216,7 @@ void FormSettings::saveFeedsMessages() {
settings->setValue(APP_CFG_MESSAGES, "clear_read_on_exit", m_ui->m_checkRemoveReadMessagesOnExit->isChecked());
settings->setValue(APP_CFG_FEEDS, "auto_update_enabled", m_ui->m_checkAutoUpdate->isChecked());
settings->setValue(APP_CFG_FEEDS, "auto_update_interval", m_ui->m_spinAutoUpdateInterval->value());
- settings->setValue(APP_CFG_FEEDS, UPDATE_TIMEOUT, m_ui->m_spinFeedUpdateTimeout->value());
+ settings->setValue(APP_CFG_FEEDS, Feeds::UpdateTimeout, m_ui->m_spinFeedUpdateTimeout->value());
settings->setValue(APP_CFG_FEEDS, "feeds_update_on_startup", m_ui->m_checkUpdateAllFeedsOnStartup->isChecked());
settings->setValue(APP_CFG_FEEDS, "count_format", m_ui->m_cmbCountsFeedList->currentText());
settings->setValue(APP_CFG_MESSAGES, "use_custom_date", m_ui->m_checkMessagesDateTimeFormat->isChecked());
diff --git a/src/gui/formupdate.cpp b/src/gui/formupdate.cpp
index f5ccc6ac7..32e8c483a 100755
--- a/src/gui/formupdate.cpp
+++ b/src/gui/formupdate.cpp
@@ -93,7 +93,7 @@ void FormUpdate::checkForUpdates() {
bool is_self_update_for_this_system = isUpdateForThisSystem() && isSelfUpdateSupported();
- if (update.first.m_availableVersion > APP_VERSION) {
+ if (SystemFactory::isUpdateNewer(update.first.m_availableVersion)) {
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Ok,
tr("New release available."),
tr("This is new version which can be\ndownloaded and installed."));
diff --git a/src/miscellaneous/databasefactory.cpp b/src/miscellaneous/databasefactory.cpp
index 59aef9068..8f5a311d3 100755
--- a/src/miscellaneous/databasefactory.cpp
+++ b/src/miscellaneous/databasefactory.cpp
@@ -104,8 +104,7 @@ void DatabaseFactory::finishRestoration() {
if (QFile::exists(backup_database_file)) {
qWarning("Backup database file '%s' was detected. Restoring it.", qPrintable(QDir::toNativeSeparators(backup_database_file)));
- if (IOFactory::copyFile(backup_database_file,
- m_sqliteDatabaseFilePath + QDir::separator() + APP_DB_SQLITE_FILE)) {
+ if (IOFactory::copyFile(backup_database_file, m_sqliteDatabaseFilePath + QDir::separator() + APP_DB_SQLITE_FILE)) {
QFile::remove(backup_database_file);
qDebug("Database file was restored successully.");
}
@@ -132,8 +131,7 @@ QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
database.setDatabaseName(":memory:");
if (!database.open()) {
- qFatal("In-memory SQLite database was NOT opened. Delivered error message: '%s'",
- qPrintable(database.lastError().text()));
+ qFatal("In-memory SQLite database was NOT opened. Delivered error message: '%s'", qPrintable(database.lastError().text()));
}
else {
QSqlQuery query_db(database);
@@ -191,9 +189,7 @@ QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
copy_contents.exec(QString("ATTACH DATABASE '%1' AS 'storage';").arg(file_database.databaseName()));
// Copy all stuff.
- QStringList tables; tables << "Information" << "Categories" <<
- "Feeds" << "FeedsData" <<
- "Messages";
+ QStringList tables; tables << "Information" << "Categories" << "Feeds" << "FeedsData" << "Messages";
foreach (const QString &table, tables) {
copy_contents.exec(QString("INSERT INTO main.%1 SELECT * FROM storage.%1;").arg(table));
diff --git a/src/miscellaneous/databasefactory.h b/src/miscellaneous/databasefactory.h
index 1c8f796b6..128060598 100755
--- a/src/miscellaneous/databasefactory.h
+++ b/src/miscellaneous/databasefactory.h
@@ -80,6 +80,7 @@ class DatabaseFactory : public QObject {
// Copies selected backup database (file) to active database path.
bool initiateRestoration(const QString &database_backup_file_path);
+ // Finishes restoration from backup file.
void finishRestoration();
//
@@ -96,6 +97,7 @@ class DatabaseFactory : public QObject {
// Otherwise returns MySQL-specific error code.
MySQLError mysqlTestConnection(const QString &hostname, int port, const QString &username, const QString &password);
+ // Interprets MySQL error code.
QString mysqlInterpretErrorCode(MySQLError error_code);
private:
@@ -107,6 +109,7 @@ class DatabaseFactory : public QObject {
// application session.
void determineDriver();
+ // Updates DB schema if necessary.
bool updateDatabaseSchema(QSqlDatabase database, const QString &source_db_schema_version);
// Holds the type of currently activated database backend.
diff --git a/src/miscellaneous/settings.h b/src/miscellaneous/settings.h
index 42eff0c23..3a77aa398 100755
--- a/src/miscellaneous/settings.h
+++ b/src/miscellaneous/settings.h
@@ -24,14 +24,47 @@
#include
-#define DEFAULT_VALUE(x) x##_DEF
+#define KEY static const char*
+#define VALUE(x) static const x
+#define SETTING(x) x, x##Def
// Feeds.
-#define UPDATE_TIMEOUT "feed_update_timeout"
-#define UPDATE_TIMEOUT_DEF DOWNLOAD_TIMEOUT
+namespace Feeds {
+ KEY UpdateTimeout = "feed_update_timeout";
+ VALUE(int) UpdateTimeoutDef = DOWNLOAD_TIMEOUT;
-#define COUNT_FORMAT "count_format"
-#define COUNT_FORMAT_DEF "(%unread)"
+ KEY CountFormat = "count_format";
+ VALUE(char*) CountFormatDef = "(%unread)";
+}
+
+// Messages.
+namespace Messages {
+ KEY UseCustomDate = "use_custom_date";
+ VALUE(bool) UseCustomDateDef = false;
+
+ KEY CustomDateFormat = "custom_date_format";
+ VALUE(char*) CustomDateFormatDef = "";
+
+ KEY ClearReadOnExit = "clear_read_on_exit";
+ VALUE(bool) ClearReadOnExitDef = false;
+}
+
+// GUI.
+namespace GUI {
+ KEY SplitterFeeds = "splitter_feeds";
+ VALUE(char*) SplitterFeedsDef = "";
+
+ KEY SplitterMessages = "splitter_messages";
+ VALUE(char*) SplitterMessagesDef = "";
+
+ KEY ToolbarStyle = "toolbar_style";
+ VALUE(Qt::ToolButtonStyle) ToolbarStyleDef = Qt::ToolButtonIconOnly;
+}
+
+// General.
+namespace General {
+
+}
class Settings : public QSettings {
diff --git a/src/miscellaneous/systemfactory.cpp b/src/miscellaneous/systemfactory.cpp
index 837e8e7d1..ab2e4c1a0 100755
--- a/src/miscellaneous/systemfactory.cpp
+++ b/src/miscellaneous/systemfactory.cpp
@@ -183,6 +183,31 @@ QPair SystemFactory::checkForUpdates()
return result;
}
+bool SystemFactory::isUpdateNewer(const QString &update_version) {
+ QStringList current_version_tkn = QString(APP_VERSION).split('.');
+ QStringList new_version_tkn = update_version.split('.');
+
+ while (!current_version_tkn.isEmpty() && !new_version_tkn.isEmpty()) {
+ int current_number = current_version_tkn.takeFirst().toInt();
+ int new_number = new_version_tkn.takeFirst().toInt();
+
+ if (new_number > current_number) {
+ // New version is indeed higher thatn current version.
+ return true;
+ }
+ }
+
+ // Versions are either the same or they have unequal sizes.
+ if (current_version_tkn.isEmpty() && new_version_tkn.isEmpty()) {
+ // Versions are the same.
+ return false;
+ }
+ else {
+ // Version are not the same length. New version is really higher if it is longer + its last digit is not 0.
+ return !new_version_tkn.isEmpty() && new_version_tkn.takeFirst().toInt() != 0;
+ }
+}
+
UpdateInfo SystemFactory::parseUpdatesFile(const QByteArray &updates_file) {
UpdateInfo update;
QDomDocument document; document.setContent(updates_file, false);
@@ -235,7 +260,7 @@ void SystemFactory::handleBackgroundUpdatesCheck() {
QFutureWatcher *future_watcher = static_cast*>(sender());
UpdateCheck updates = future_watcher->result();
- if (updates.second == QNetworkReply::NoError && updates.first.m_availableVersion > APP_VERSION) {
+ if (updates.second == QNetworkReply::NoError && isUpdateNewer(updates.first.m_availableVersion)) {
if (SystemTrayIcon::isSystemTrayActivated()) {
qApp->trayIcon()->showMessage(tr("New version available"),
tr("Click the bubble for more information."),
diff --git a/src/miscellaneous/systemfactory.h b/src/miscellaneous/systemfactory.h
index 1083b251d..5405541f8 100644
--- a/src/miscellaneous/systemfactory.h
+++ b/src/miscellaneous/systemfactory.h
@@ -92,6 +92,8 @@ class SystemFactory : public QObject {
// Tries to download list with new updates.
QPair checkForUpdates();
+ static bool isUpdateNewer(const QString &update_version);
+
public slots:
// Performs asynchronous check for updates, result is emitted via updateCheckedAsynchronously(...) signal.
void checkForUpdatesAsynchronously();