diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2880ce56a..f2a12dcea 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -364,6 +364,7 @@ set(APP_SOURCES
src/gui/formrestoredatabasesettings.cpp
src/gui/edittableview.cpp
src/gui/squeezelabel.cpp
+ src/gui/formdatabasecleanup.cpp
# DYNAMIC-SHORTCUTS sources.
src/dynamic-shortcuts/shortcutcatcher.cpp
@@ -384,6 +385,7 @@ set(APP_SOURCES
src/miscellaneous/iofactory.cpp
src/miscellaneous/autosaver.cpp
src/miscellaneous/mutex.cpp
+ src/miscellaneous/databasecleaner.cpp
# EXCEPTIONS sources.
src/exceptions/applicationexception.cpp
@@ -462,6 +464,7 @@ set(APP_HEADERS
src/gui/formrestoredatabasesettings.h
src/gui/edittableview.h
src/gui/squeezelabel.h
+ src/gui/formdatabasecleanup.h
# DYNAMIC-SHORTCUTS headers.
src/dynamic-shortcuts/dynamicshortcutswidget.h
@@ -478,6 +481,7 @@ set(APP_HEADERS
src/miscellaneous/skinfactory.h
src/miscellaneous/autosaver.h
src/miscellaneous/mutex.h
+ src/miscellaneous/databasecleaner.h
# CORE headers.
src/core/messagesmodel.h
@@ -513,6 +517,7 @@ set(APP_FORMS
src/gui/formimportexport.ui
src/gui/formbackupdatabasesettings.ui
src/gui/formrestoredatabasesettings.ui
+ src/gui/formdatabasecleanup.ui
src/network-web/downloadmanager.ui
src/network-web/downloaditem.ui
)
diff --git a/resources/graphics/icons/mini-kfaenza/defragment-database.png b/resources/graphics/icons/mini-kfaenza/cleanup-database.png
similarity index 100%
rename from resources/graphics/icons/mini-kfaenza/defragment-database.png
rename to resources/graphics/icons/mini-kfaenza/cleanup-database.png
diff --git a/resources/text/CHANGELOG b/resources/text/CHANGELOG
index 5ae621e0b..d2d0d764a 100644
--- a/resources/text/CHANGELOG
+++ b/resources/text/CHANGELOG
@@ -7,12 +7,15 @@ Added:
All feeds are by default checked when exporting/importing them.
Message previewer now displays MIME type of all podcasts too. This MIME type is also stored in DB.
Ability to fetch only new icon for feed from its online source.
+Message view now automatically scrolls to selected message when changing filter string.
+Some small memory footprint enhancements.
Option to search highlighted text in web browser via Google, available from context menu. (issue #72)
Fixed:
-- Reworked DB initialization scripts.
+- Threads for feed updating are created only when really needed.
+- Reworked DB initialization scripts which allow to use OPML to do initial feed population.
- Titles and descriptions of feeds are now fetched correctly in feed add/edit dialog.
diff --git a/src/gui/feedmessageviewer.cpp b/src/gui/feedmessageviewer.cpp
index 223374ea1..0b4df7a62 100755
--- a/src/gui/feedmessageviewer.cpp
+++ b/src/gui/feedmessageviewer.cpp
@@ -61,15 +61,13 @@ FeedMessageViewer::FeedMessageViewer(QWidget *parent)
m_messagesView(new MessagesView(this)),
m_feedsView(new FeedsView(this)),
m_messagesBrowser(new WebBrowser(this)),
- m_feedDownloaderThread(new QThread()),
- m_feedDownloader(new FeedDownloader()) {
+ m_dbCleanerThread(NULL),
+ m_feedDownloaderThread(NULL),
+ m_feedDownloader(NULL) {
initialize();
initializeViews();
createConnections();
- // Start the feed downloader thread.
- m_feedDownloaderThread->start();
-
// Now, update all feeds if user has set it.
m_feedsView->updateAllFeedsOnStartup();
}
@@ -125,12 +123,22 @@ void FeedMessageViewer::quit() {
// Quit the feeds view (stops auto-update timer etc.).
m_feedsView->quit();
- qDebug("Quitting feed downloader thread.");
- m_feedDownloaderThread->quit();
- m_feedDownloaderThread->wait();
+ if (m_feedDownloaderThread != NULL && m_feedDownloaderThread->isRunning()) {
+ qDebug("Quitting feed downloader thread.");
+ m_feedDownloaderThread->quit();
+ m_feedDownloaderThread->wait();
+ }
- qDebug("Feed downloader thread aborted. Deleting it from memory.");
- m_feedDownloader->deleteLater();
+ if (m_dbCleanerThread != NULL && m_dbCleanerThread->isRunning()) {
+ qDebug("Quitting database cleaner thread.");
+ m_dbCleanerThread->quit();
+ m_dbCleanerThread->wait();
+ }
+
+ if (m_feedDownloader != NULL) {
+ qDebug("Feed downloader thread aborted. Deleting it from memory.");
+ m_feedDownloader->deleteLater();
+ }
if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::ClearReadOnExit)).toBool()) {
m_feedsView->clearAllReadMessages();
@@ -161,7 +169,7 @@ void FeedMessageViewer::loadInitialFeeds() {
}
}
catch (ApplicationException &ex) {
- MessageBox::show(this, QMessageBox::Critical, tr("Error when loading initial feeds"), ex.message());
+ MessageBox::show(this, QMessageBox::Critical, tr("Error when loading initial feeds"), ex.message());
}
}
@@ -203,8 +211,8 @@ void FeedMessageViewer::onFeedUpdatesProgress(FeedsModelFeed *feed, int current,
// Some feed got updated.
m_feedsView->updateCountsOfParticularFeed(feed, true);
qApp->mainForm()->statusBar()->showProgressFeeds((current * 100.0) / total,
- //: Text display in status bar when particular feed is updated.
- tr("Updated feed '%1'").arg(feed->title()));
+ //: Text display in status bar when particular feed is updated.
+ tr("Updated feed '%1'").arg(feed->title()));
}
void FeedMessageViewer::onFeedUpdatesFinished() {
@@ -251,11 +259,7 @@ void FeedMessageViewer::createConnections() {
form_main->m_ui->m_tabWidget, SLOT(addBrowserWithMessages(QList)));
// Downloader connections.
- connect(m_feedDownloaderThread, SIGNAL(finished()), m_feedDownloaderThread, SLOT(deleteLater()));
- connect(m_feedsView, SIGNAL(feedsUpdateRequested(QList)), m_feedDownloader, SLOT(updateFeeds(QList)));
- connect(m_feedDownloader, SIGNAL(finished()), this, SLOT(onFeedUpdatesFinished()));
- connect(m_feedDownloader, SIGNAL(started()), this, SLOT(onFeedUpdatesStarted()));
- connect(m_feedDownloader, SIGNAL(progress(FeedsModelFeed*,int,int)), this, SLOT(onFeedUpdatesProgress(FeedsModelFeed*,int,int)));
+ connect(m_feedsView, SIGNAL(feedsUpdateRequested(QList)), this, SLOT(updateFeeds(QList)));
// Toolbar forwardings.
connect(form_main->m_ui->m_actionSwitchImportanceOfSelectedMessages,
@@ -318,8 +322,6 @@ void FeedMessageViewer::createConnections() {
SIGNAL(triggered()), m_messagesView, SLOT(selectNextItem()));
connect(form_main->m_ui->m_actionSelectPreviousMessage,
SIGNAL(triggered()), m_messagesView, SLOT(selectPreviousItem()));
- connect(form_main->m_ui->m_actionDefragmentDatabase,
- SIGNAL(triggered()), this, SLOT(vacuumDatabase()));
connect(form_main->m_ui->m_actionSwitchMessageListOrientation, SIGNAL(triggered()),
this, SLOT(switchMessageSplitterOrientation()));
}
@@ -339,9 +341,7 @@ void FeedMessageViewer::initialize() {
// Finish web/message browser setup.
m_messagesBrowser->setNavigationBarVisible(false);
- // Downloader setup.
- qRegisterMetaType >("QList");
- m_feedDownloader->moveToThread(m_feedDownloaderThread);
+ // Now refresh visual setup.
refreshVisualProperties();
}
@@ -435,3 +435,25 @@ void FeedMessageViewer::refreshVisualProperties() {
m_toolBarFeeds->setToolButtonStyle(button_style);
m_toolBarMessages->setToolButtonStyle(button_style);
}
+
+void FeedMessageViewer::updateFeeds(QList feeds) {
+ if (m_feedDownloader == NULL) {
+ m_feedDownloader = new FeedDownloader();
+ m_feedDownloaderThread = new QThread();
+
+ // Downloader setup.
+ qRegisterMetaType >("QList");
+ m_feedDownloader->moveToThread(m_feedDownloaderThread);
+
+ connect(this, SIGNAL(feedsUpdateRequested(QList)), m_feedDownloader, SLOT(updateFeeds(QList)));
+ connect(m_feedDownloaderThread, SIGNAL(finished()), m_feedDownloaderThread, SLOT(deleteLater()));
+ connect(m_feedDownloader, SIGNAL(finished()), this, SLOT(onFeedUpdatesFinished()));
+ connect(m_feedDownloader, SIGNAL(started()), this, SLOT(onFeedUpdatesStarted()));
+ connect(m_feedDownloader, SIGNAL(progress(FeedsModelFeed*,int,int)), this, SLOT(onFeedUpdatesProgress(FeedsModelFeed*,int,int)));
+
+ // Connections are made, start the feed downloader thread.
+ m_feedDownloaderThread->start();
+ }
+
+ emit feedsUpdateRequested(feeds);
+}
diff --git a/src/gui/feedmessageviewer.h b/src/gui/feedmessageviewer.h
index 13b0d32cb..08e89b08e 100644
--- a/src/gui/feedmessageviewer.h
+++ b/src/gui/feedmessageviewer.h
@@ -98,6 +98,8 @@ class FeedMessageViewer : public TabContent {
// Reloads some changeable visual settings.
void refreshVisualProperties();
+ void updateFeeds(QList feeds);
+
protected slots:
// Updates counts of messages for example in tray icon.
void updateTrayIconStatus(int unread_messages, int total_messages, bool any_unread_messages);
@@ -121,6 +123,10 @@ class FeedMessageViewer : public TabContent {
// Sets up connections.
void createConnections();
+ signals:
+ // Emitted if user/application requested updating of some feeds.
+ void feedsUpdateRequested(const QList feeds);
+
private:
bool m_toolBarsEnabled;
bool m_listHeadersEnabled;
@@ -137,6 +143,7 @@ class FeedMessageViewer : public TabContent {
WebBrowser *m_messagesBrowser;
QThread *m_feedDownloaderThread;
+ QThread *m_dbCleanerThread;
FeedDownloader *m_feedDownloader;
};
diff --git a/src/gui/formdatabasecleanup.cpp b/src/gui/formdatabasecleanup.cpp
new file mode 100644
index 000000000..e12881d0c
--- /dev/null
+++ b/src/gui/formdatabasecleanup.cpp
@@ -0,0 +1,27 @@
+#include "gui/formdatabasecleanup.h"
+
+#include "miscellaneous/application.h"
+#include "miscellaneous/iconfactory.h"
+
+
+FormDatabaseCleanup::FormDatabaseCleanup(QWidget *parent) : QDialog(parent), m_ui(new Ui::FormDatabaseCleanup) {
+ m_ui->setupUi(this);
+
+ // Set flags and attributes.
+ setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
+ setWindowIcon(qApp->icons()->fromTheme("cleanup-database"));
+
+
+ // TODO: Vytvořil jsem základ okna pro mazání.
+ // v tomto okně se nastaví parametry mazání - jak staré zprávy, zda přečtené, zda vakuovat db
+ // do třídy DatabaseCleaner se dodělají metody, které budou samotné mazání provádět
+ // ve FeedMessageViewer se udělá instance cleaneru stejně jako FeedDownloader (vlákno už tam mam
+ // deklarovano (m_dbCleanerThread). Po "OK" tady v tomdle dialogu se pošle signal
+ // do instance cleaneru ve feedmessagevieweru.
+ // před otevřením tohodle dialogu se zamkne hlavní lock, po oddělání dialogu se odemkne.
+ // databasecleaner by mohl reportovat i progress, poběží ve svém vlákně.
+}
+
+FormDatabaseCleanup::~FormDatabaseCleanup() {
+ delete m_ui;
+}
diff --git a/src/gui/formdatabasecleanup.h b/src/gui/formdatabasecleanup.h
new file mode 100644
index 000000000..fd3dee573
--- /dev/null
+++ b/src/gui/formdatabasecleanup.h
@@ -0,0 +1,24 @@
+#ifndef FORMDATABASECLEANUP_H
+#define FORMDATABASECLEANUP_H
+
+#include
+
+#include "ui_formdatabasecleanup.h"
+
+
+namespace Ui {
+ class FormDatabaseCleanup;
+}
+
+class FormDatabaseCleanup : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit FormDatabaseCleanup(QWidget *parent = 0);
+ virtual ~FormDatabaseCleanup();
+
+ private:
+ Ui::FormDatabaseCleanup *m_ui;
+};
+
+#endif // FORMDATABASECLEANUP_H
diff --git a/src/gui/formdatabasecleanup.ui b/src/gui/formdatabasecleanup.ui
new file mode 100644
index 000000000..9ff6ac44c
--- /dev/null
+++ b/src/gui/formdatabasecleanup.ui
@@ -0,0 +1,71 @@
+
+
+
+
+ FormDatabaseCleanup
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ Dialog
+
+
+
+
+ 30
+ 240
+ 341
+ 32
+
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ FormDatabaseCleanup
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ FormDatabaseCleanup
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/src/gui/formmain.cpp b/src/gui/formmain.cpp
index 1475ca50d..be8f39af3 100755
--- a/src/gui/formmain.cpp
+++ b/src/gui/formmain.cpp
@@ -132,7 +132,6 @@ QList FormMain::allActions() {
actions << m_ui->m_actionSelectPreviousFeedCategory;
actions << m_ui->m_actionSelectNextMessage;
actions << m_ui->m_actionSelectPreviousMessage;
- actions << m_ui->m_actionDefragmentDatabase;
// Add recycle bin actions.
actions << m_ui->m_actionRestoreRecycleBin;
@@ -214,7 +213,7 @@ void FormMain::setupIcons() {
m_ui->m_actionRestart->setIcon(icon_theme_factory->fromTheme("go-refresh"));
m_ui->m_actionAboutGuard->setIcon(icon_theme_factory->fromTheme("application-about"));
m_ui->m_actionCheckForUpdates->setIcon(icon_theme_factory->fromTheme("check-for-updates"));
- m_ui->m_actionDefragmentDatabase->setIcon(icon_theme_factory->fromTheme("defragment-database"));
+ m_ui->m_actionCleanupDatabase->setIcon(icon_theme_factory->fromTheme("cleanup-database"));
m_ui->m_actionReportBugGitHub->setIcon(icon_theme_factory->fromTheme("application-report-bug"));
m_ui->m_actionReportBugBitBucket->setIcon(icon_theme_factory->fromTheme("application-report-bug"));
m_ui->m_actionExportFeeds->setIcon(icon_theme_factory->fromTheme("document-export"));
@@ -369,12 +368,13 @@ void FormMain::createConnections() {
connect(m_ui->m_actionCloseCurrentTab, SIGNAL(triggered()), m_ui->m_tabWidget, SLOT(closeCurrentTab()));
connect(m_ui->m_actionAddBrowser, SIGNAL(triggered()), m_ui->m_tabWidget, SLOT(addEmptyBrowser()));
connect(m_ui->m_actionCloseAllTabs, SIGNAL(triggered()), m_ui->m_tabWidget, SLOT(closeAllTabsExceptCurrent()));
- connect(WebFactory::instance(), SIGNAL(imagesLoadingSwitched(bool)), m_ui->m_actionWebAutoloadImages, SLOT(setChecked(bool)));
- connect(WebFactory::instance(), SIGNAL(javascriptSwitched(bool)), m_ui->m_actionWebEnableJavascript, SLOT(setChecked(bool)));
- connect(WebFactory::instance(), SIGNAL(pluginsSwitched(bool)), m_ui->m_actionWebEnableExternalPlugins, SLOT(setChecked(bool)));
connect(m_ui->m_actionWebAutoloadImages, SIGNAL(toggled(bool)), WebFactory::instance(), SLOT(switchImages(bool)));
connect(m_ui->m_actionWebEnableExternalPlugins, SIGNAL(toggled(bool)), WebFactory::instance(), SLOT(switchPlugins(bool)));
connect(m_ui->m_actionWebEnableJavascript, SIGNAL(toggled(bool)), WebFactory::instance(), SLOT(switchJavascript(bool)));
+
+ connect(WebFactory::instance(), SIGNAL(imagesLoadingSwitched(bool)), m_ui->m_actionWebAutoloadImages, SLOT(setChecked(bool)));
+ connect(WebFactory::instance(), SIGNAL(javascriptSwitched(bool)), m_ui->m_actionWebEnableJavascript, SLOT(setChecked(bool)));
+ connect(WebFactory::instance(), SIGNAL(pluginsSwitched(bool)), m_ui->m_actionWebEnableExternalPlugins, SLOT(setChecked(bool)));
}
void FormMain::loadWebBrowserMenu(int index) {
diff --git a/src/gui/formmain.ui b/src/gui/formmain.ui
index bc6622594..ad0641e8c 100755
--- a/src/gui/formmain.ui
+++ b/src/gui/formmain.ui
@@ -99,7 +99,7 @@
-
+
diff --git a/src/gui/messagesview.cpp b/src/gui/messagesview.cpp
index 7c82d3e18..271cb1058 100755
--- a/src/gui/messagesview.cpp
+++ b/src/gui/messagesview.cpp
@@ -469,6 +469,10 @@ void MessagesView::searchMessages(const QString &pattern) {
if (selectionModel()->selectedRows().size() == 0) {
emit currentMessagesRemoved();
}
+ else {
+ // Scroll to selected message, it could become scrolled out due to filter change.
+ scrollTo(selectionModel()->selectedRows().at(0));
+ }
}
void MessagesView::filterMessages(MessagesModel::MessageFilter filter) {
diff --git a/src/gui/systemtrayicon.cpp b/src/gui/systemtrayicon.cpp
index ab8f52b6e..d2db3bf0f 100755
--- a/src/gui/systemtrayicon.cpp
+++ b/src/gui/systemtrayicon.cpp
@@ -100,6 +100,7 @@ void SystemTrayIcon::showPrivate() {
// Display the tray icon.
QSystemTrayIcon::show();
+ emit shown();
qDebug("Tray icon displayed.");
}
diff --git a/src/gui/systemtrayicon.h b/src/gui/systemtrayicon.h
index b9be20002..4bf725838 100755
--- a/src/gui/systemtrayicon.h
+++ b/src/gui/systemtrayicon.h
@@ -74,6 +74,9 @@ class SystemTrayIcon : public QSystemTrayIcon {
void showPrivate();
void onActivated(const QSystemTrayIcon::ActivationReason &reason);
+ signals:
+ void shown();
+
private:
QIcon m_normalIcon;
QPixmap m_plainPixmap;
diff --git a/src/miscellaneous/application.cpp b/src/miscellaneous/application.cpp
index 202b7b20f..cbb872ba3 100755
--- a/src/miscellaneous/application.cpp
+++ b/src/miscellaneous/application.cpp
@@ -143,6 +143,7 @@ void Application::processExecutionMessage(const QString &message) {
SystemTrayIcon *Application::trayIcon() {
if (m_trayIcon == NULL) {
m_trayIcon = new SystemTrayIcon(APP_ICON_PATH, APP_ICON_PLAIN_PATH, m_mainForm);
+ connect(m_trayIcon, SIGNAL(shown()), m_mainForm->tabWidget()->feedMessageViewer()->feedsView(), SLOT(notifyWithCounts()));
}
return m_trayIcon;
@@ -151,10 +152,6 @@ SystemTrayIcon *Application::trayIcon() {
void Application::showTrayIcon() {
qDebug("Showing tray icon.");
trayIcon()->show();
-
- if (m_mainForm != NULL) {
- m_mainForm->tabWidget()->feedMessageViewer()->feedsView()->notifyWithCounts();
- }
}
void Application::deleteTrayIcon() {
diff --git a/src/miscellaneous/databasecleaner.cpp b/src/miscellaneous/databasecleaner.cpp
new file mode 100644
index 000000000..309c75f22
--- /dev/null
+++ b/src/miscellaneous/databasecleaner.cpp
@@ -0,0 +1,26 @@
+// This file is part of RSS Guard.
+//
+// Copyright (C) 2011-2015 by Martin Rotter
+//
+// RSS Guard 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.
+//
+// RSS Guard 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 RSS Guard. If not, see .
+
+#include "miscellaneous/databasecleaner.h"
+
+
+DatabaseCleaner::DatabaseCleaner(QObject *parent) : QObject(parent) {
+}
+
+DatabaseCleaner::~DatabaseCleaner() {
+}
+
diff --git a/src/miscellaneous/databasecleaner.h b/src/miscellaneous/databasecleaner.h
new file mode 100644
index 000000000..c744d9435
--- /dev/null
+++ b/src/miscellaneous/databasecleaner.h
@@ -0,0 +1,36 @@
+// This file is part of RSS Guard.
+//
+// Copyright (C) 2011-2015 by Martin Rotter
+//
+// RSS Guard 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.
+//
+// RSS Guard 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 RSS Guard. If not, see .
+
+#ifndef DATABASECLEANER_H
+#define DATABASECLEANER_H
+
+#include
+
+
+class DatabaseCleaner : public QObject {
+ Q_OBJECT
+
+ public:
+ explicit DatabaseCleaner(QObject *parent = 0);
+ virtual ~DatabaseCleaner();
+
+ signals:
+
+ public slots:
+};
+
+#endif // DATABASECLEANER_H