Fixed #99 and furrther optimizations of the code.

This commit is contained in:
Martin Rotter 2014-11-08 16:39:38 +01:00
parent c86c45ef13
commit b7ce81c404
16 changed files with 109 additions and 39 deletions

View File

@ -71,8 +71,8 @@ project(rssguard)
set(APP_NAME "RSS Guard") set(APP_NAME "RSS Guard")
set(APP_LOW_NAME "rssguard") set(APP_LOW_NAME "rssguard")
set(APP_VERSION "2.0.0.4") set(APP_VERSION "2.1")
set(FILE_VERSION "2,0,0,4") set(FILE_VERSION "2,1,0,0")
set(APP_AUTHOR "Martin Rotter") set(APP_AUTHOR "Martin Rotter")
set(APP_URL "http://bitbucket.org/skunkos/rssguard") set(APP_URL "http://bitbucket.org/skunkos/rssguard")
set(APP_URL_ISSUES "http://bitbucket.org/skunkos/rssguard/issues") set(APP_URL_ISSUES "http://bitbucket.org/skunkos/rssguard/issues")

View File

@ -1,4 +1,15 @@
<body> <body>
<center><h2>2.1</h2></center>
Fixed:
<ul>
</ul>
Added:
<ul>
</ul>
<hr/>
<center><h2>2.0.0.4</h2></center> <center><h2>2.0.0.4</h2></center>
Fixed: Fixed:

View File

@ -86,9 +86,9 @@ QVariant FeedsModelCategory::data(int column, int role) const {
return m_title; return m_title;
} }
else if (column == FDS_MODEL_COUNTS_INDEX) { else if (column == FDS_MODEL_COUNTS_INDEX) {
return qApp->settings()->value(APP_CFG_FEEDS, COUNT_FORMAT, DEFAULT_VALUE(COUNT_FORMAT)).toString() return qApp->settings()->value(APP_CFG_FEEDS, SETTING(Feeds::CountFormat)).toString()
.replace("%unread", QString::number(countOfUnreadMessages())) .replace(PLACEHOLDER_UNREAD_COUNTS, QString::number(countOfUnreadMessages()))
.replace("%all", QString::number(countOfAllMessages())); .replace(PLACEHOLDER_ALL_COUNTS, QString::number(countOfAllMessages()));
} }
else { else {
return QVariant(); return QVariant();

View File

@ -175,8 +175,7 @@ QPair<FeedsModelFeed*, QNetworkReply::NetworkError> FeedsModelFeed::guessFeed(co
QByteArray feed_contents; QByteArray feed_contents;
NetworkResult network_result = NetworkFactory::downloadFeedFile(url, NetworkResult network_result = NetworkFactory::downloadFeedFile(url,
qApp->settings()->value(APP_CFG_FEEDS, qApp->settings()->value(APP_CFG_FEEDS,
UPDATE_TIMEOUT, SETTING(Feeds::UpdateTimeout)).toInt(),
DEFAULT_VALUE(UPDATE_TIMEOUT)).toInt(),
feed_contents, feed_contents,
!username.isEmpty(), !username.isEmpty(),
username, username,
@ -288,9 +287,9 @@ QVariant FeedsModelFeed::data(int column, int role) const {
return m_title; return m_title;
} }
else if (column == FDS_MODEL_COUNTS_INDEX) { else if (column == FDS_MODEL_COUNTS_INDEX) {
return qApp->settings()->value(APP_CFG_FEEDS, COUNT_FORMAT, DEFAULT_VALUE(COUNT_FORMAT)).toString() return qApp->settings()->value(APP_CFG_FEEDS, SETTING(Feeds::CountFormat)).toString()
.replace("%unread", QString::number(countOfUnreadMessages())) .replace(PLACEHOLDER_UNREAD_COUNTS, QString::number(countOfUnreadMessages()))
.replace("%all", QString::number(countOfAllMessages())); .replace(PLACEHOLDER_ALL_COUNTS, QString::number(countOfAllMessages()));
} }
else { else {
return QVariant(); return QVariant();
@ -390,7 +389,7 @@ QVariant FeedsModelFeed::data(int column, int role) const {
void FeedsModelFeed::update() { void FeedsModelFeed::update() {
QByteArray feed_contents; 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; m_networkError = NetworkFactory::downloadFeedFile(url(), download_timeout, feed_contents, passwordProtected(), username(), password()).first;
if (m_networkError != QNetworkReply::NoError) { if (m_networkError != QNetworkReply::NoError) {

View File

@ -62,9 +62,9 @@ QVariant FeedsModelRecycleBin::data(int column, int role) const {
return m_title; return m_title;
} }
else if (column == FDS_MODEL_COUNTS_INDEX) { else if (column == FDS_MODEL_COUNTS_INDEX) {
return qApp->settings()->value(APP_CFG_FEEDS, COUNT_FORMAT, DEFAULT_VALUE(COUNT_FORMAT)).toString() return qApp->settings()->value(APP_CFG_FEEDS, SETTING(Feeds::CountFormat)).toString()
.replace("%unread", QString::number(countOfUnreadMessages())) .replace(PLACEHOLDER_UNREAD_COUNTS, QString::number(countOfUnreadMessages()))
.replace("%all", QString::number(countOfAllMessages())); .replace(PLACEHOLDER_ALL_COUNTS, QString::number(countOfAllMessages()));
} }
else { else {
return QVariant(); return QVariant();

View File

@ -108,8 +108,8 @@ int MessagesModel::messageId(int row_index) const {
} }
void MessagesModel::updateDateFormat() { void MessagesModel::updateDateFormat() {
if (qApp->settings()->value(APP_CFG_MESSAGES, "use_custom_date").toBool()) { if (qApp->settings()->value(APP_CFG_MESSAGES, SETTING(Messages::UseCustomDate)).toBool()) {
m_customDateFormat = qApp->settings()->value(APP_CFG_MESSAGES, "custom_date_format").toString(); m_customDateFormat = qApp->settings()->value(APP_CFG_MESSAGES, SETTING(Messages::CustomDateFormat)).toString();
} }
else { else {
m_customDateFormat = QString(); m_customDateFormat = QString();

View File

@ -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 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 MIME_TYPE_ITEM_POINTER "rssguard/itempointer"
#define PLACEHOLDER_UNREAD_COUNTS "%unread"
#define PLACEHOLDER_ALL_COUNTS "%all"
#define BACKUP_NAME_SETTINGS "config" #define BACKUP_NAME_SETTINGS "config"
#define BACKUP_SUFFIX_SETTINGS ".ini.backup" #define BACKUP_SUFFIX_SETTINGS ".ini.backup"
#define BACKUP_NAME_DATABASE "database" #define BACKUP_NAME_DATABASE "database"

View File

@ -44,7 +44,6 @@ void DynamicShortcuts::load(const QList<QAction*> actions) {
QString shortcut_for_action = settings->value(APP_CFG_CUTS, QString shortcut_for_action = settings->value(APP_CFG_CUTS,
action->objectName(), action->objectName(),
action->shortcut().toString(QKeySequence::PortableText)).toString(); action->shortcut().toString(QKeySequence::PortableText)).toString();
action->setShortcut(QKeySequence::fromString(shortcut_for_action, action->setShortcut(QKeySequence::fromString(shortcut_for_action, QKeySequence::PortableText));
QKeySequence::PortableText));
} }
} }

View File

@ -105,8 +105,8 @@ void FeedMessageViewer::loadSize() {
m_feedsView->loadExpandedStates(); m_feedsView->loadExpandedStates();
// Restore offsets of splitters. // Restore offsets of splitters.
m_feedSplitter->restoreState(QByteArray::fromBase64(settings->value(APP_CFG_GUI, "splitter_feeds").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, "splitter_messages").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. // Splitters are restored, now, restore widths of columns.
m_messagesView->setColumnWidth(MSG_DB_AUTHOR_INDEX, settings->value(APP_CFG_GUI, 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."); qDebug("Feed downloader thread aborted. Deleting it from memory.");
m_feedDownloader->deleteLater(); 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(); m_feedsView->clearAllReadMessages();
} }
} }
@ -397,8 +397,7 @@ void FeedMessageViewer::vacuumDatabase() {
void FeedMessageViewer::refreshVisualProperties() { void FeedMessageViewer::refreshVisualProperties() {
Qt::ToolButtonStyle button_style = static_cast<Qt::ToolButtonStyle>(qApp->settings()->value(APP_CFG_GUI, Qt::ToolButtonStyle button_style = static_cast<Qt::ToolButtonStyle>(qApp->settings()->value(APP_CFG_GUI,
"toolbar_style", SETTING(GUI::ToolbarStyle)).toInt());
Qt::ToolButtonIconOnly).toInt());
m_toolBarFeeds->setToolButtonStyle(button_style); m_toolBarFeeds->setToolButtonStyle(button_style);
m_toolBarMessages->setToolButtonStyle(button_style); m_toolBarMessages->setToolButtonStyle(button_style);

View File

@ -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_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_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_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_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->addItems(QStringList() << "(%unread)" << "[%unread]" << "%unread/%all" << "%unread-%all" << "[%unread|%all]");
m_ui->m_cmbCountsFeedList->setEditText(settings->value(APP_CFG_FEEDS, "count_format", "(%unread)").toString()); 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_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_enabled", m_ui->m_checkAutoUpdate->isChecked());
settings->setValue(APP_CFG_FEEDS, "auto_update_interval", m_ui->m_spinAutoUpdateInterval->value()); 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, "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_FEEDS, "count_format", m_ui->m_cmbCountsFeedList->currentText());
settings->setValue(APP_CFG_MESSAGES, "use_custom_date", m_ui->m_checkMessagesDateTimeFormat->isChecked()); settings->setValue(APP_CFG_MESSAGES, "use_custom_date", m_ui->m_checkMessagesDateTimeFormat->isChecked());

View File

@ -93,7 +93,7 @@ void FormUpdate::checkForUpdates() {
bool is_self_update_for_this_system = isUpdateForThisSystem() && isSelfUpdateSupported(); 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, m_ui->m_lblStatus->setStatus(WidgetWithStatus::Ok,
tr("New release available."), tr("New release available."),
tr("This is new version which can be\ndownloaded and installed.")); tr("This is new version which can be\ndownloaded and installed."));

View File

@ -104,8 +104,7 @@ void DatabaseFactory::finishRestoration() {
if (QFile::exists(backup_database_file)) { if (QFile::exists(backup_database_file)) {
qWarning("Backup database file '%s' was detected. Restoring it.", qPrintable(QDir::toNativeSeparators(backup_database_file))); qWarning("Backup database file '%s' was detected. Restoring it.", qPrintable(QDir::toNativeSeparators(backup_database_file)));
if (IOFactory::copyFile(backup_database_file, if (IOFactory::copyFile(backup_database_file, m_sqliteDatabaseFilePath + QDir::separator() + APP_DB_SQLITE_FILE)) {
m_sqliteDatabaseFilePath + QDir::separator() + APP_DB_SQLITE_FILE)) {
QFile::remove(backup_database_file); QFile::remove(backup_database_file);
qDebug("Database file was restored successully."); qDebug("Database file was restored successully.");
} }
@ -132,8 +131,7 @@ QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
database.setDatabaseName(":memory:"); database.setDatabaseName(":memory:");
if (!database.open()) { if (!database.open()) {
qFatal("In-memory SQLite database was NOT opened. Delivered error message: '%s'", qFatal("In-memory SQLite database was NOT opened. Delivered error message: '%s'", qPrintable(database.lastError().text()));
qPrintable(database.lastError().text()));
} }
else { else {
QSqlQuery query_db(database); 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_contents.exec(QString("ATTACH DATABASE '%1' AS 'storage';").arg(file_database.databaseName()));
// Copy all stuff. // Copy all stuff.
QStringList tables; tables << "Information" << "Categories" << QStringList tables; tables << "Information" << "Categories" << "Feeds" << "FeedsData" << "Messages";
"Feeds" << "FeedsData" <<
"Messages";
foreach (const QString &table, tables) { foreach (const QString &table, tables) {
copy_contents.exec(QString("INSERT INTO main.%1 SELECT * FROM storage.%1;").arg(table)); copy_contents.exec(QString("INSERT INTO main.%1 SELECT * FROM storage.%1;").arg(table));

View File

@ -80,6 +80,7 @@ class DatabaseFactory : public QObject {
// Copies selected backup database (file) to active database path. // Copies selected backup database (file) to active database path.
bool initiateRestoration(const QString &database_backup_file_path); bool initiateRestoration(const QString &database_backup_file_path);
// Finishes restoration from backup file.
void finishRestoration(); void finishRestoration();
// //
@ -96,6 +97,7 @@ class DatabaseFactory : public QObject {
// Otherwise returns MySQL-specific error code. // Otherwise returns MySQL-specific error code.
MySQLError mysqlTestConnection(const QString &hostname, int port, const QString &username, const QString &password); MySQLError mysqlTestConnection(const QString &hostname, int port, const QString &username, const QString &password);
// Interprets MySQL error code.
QString mysqlInterpretErrorCode(MySQLError error_code); QString mysqlInterpretErrorCode(MySQLError error_code);
private: private:
@ -107,6 +109,7 @@ class DatabaseFactory : public QObject {
// application session. // application session.
void determineDriver(); void determineDriver();
// Updates DB schema if necessary.
bool updateDatabaseSchema(QSqlDatabase database, const QString &source_db_schema_version); bool updateDatabaseSchema(QSqlDatabase database, const QString &source_db_schema_version);
// Holds the type of currently activated database backend. // Holds the type of currently activated database backend.

View File

@ -24,14 +24,47 @@
#include <QPointer> #include <QPointer>
#define DEFAULT_VALUE(x) x##_DEF #define KEY static const char*
#define VALUE(x) static const x
#define SETTING(x) x, x##Def
// Feeds. // Feeds.
#define UPDATE_TIMEOUT "feed_update_timeout" namespace Feeds {
#define UPDATE_TIMEOUT_DEF DOWNLOAD_TIMEOUT KEY UpdateTimeout = "feed_update_timeout";
VALUE(int) UpdateTimeoutDef = DOWNLOAD_TIMEOUT;
#define COUNT_FORMAT "count_format" KEY CountFormat = "count_format";
#define COUNT_FORMAT_DEF "(%unread)" 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 { class Settings : public QSettings {

View File

@ -183,6 +183,31 @@ QPair<UpdateInfo, QNetworkReply::NetworkError> SystemFactory::checkForUpdates()
return result; 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 SystemFactory::parseUpdatesFile(const QByteArray &updates_file) {
UpdateInfo update; UpdateInfo update;
QDomDocument document; document.setContent(updates_file, false); QDomDocument document; document.setContent(updates_file, false);
@ -235,7 +260,7 @@ void SystemFactory::handleBackgroundUpdatesCheck() {
QFutureWatcher<UpdateCheck> *future_watcher = static_cast<QFutureWatcher<UpdateCheck>*>(sender()); QFutureWatcher<UpdateCheck> *future_watcher = static_cast<QFutureWatcher<UpdateCheck>*>(sender());
UpdateCheck updates = future_watcher->result(); 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()) { if (SystemTrayIcon::isSystemTrayActivated()) {
qApp->trayIcon()->showMessage(tr("New version available"), qApp->trayIcon()->showMessage(tr("New version available"),
tr("Click the bubble for more information."), tr("Click the bubble for more information."),

View File

@ -92,6 +92,8 @@ class SystemFactory : public QObject {
// Tries to download list with new updates. // Tries to download list with new updates.
QPair<UpdateInfo, QNetworkReply::NetworkError> checkForUpdates(); QPair<UpdateInfo, QNetworkReply::NetworkError> checkForUpdates();
static bool isUpdateNewer(const QString &update_version);
public slots: public slots:
// Performs asynchronous check for updates, result is emitted via updateCheckedAsynchronously(...) signal. // Performs asynchronous check for updates, result is emitted via updateCheckedAsynchronously(...) signal.
void checkForUpdatesAsynchronously(); void checkForUpdatesAsynchronously();