From 4c8e9a021e904230919d874394fef7644666511d Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Thu, 4 Jun 2015 08:07:48 +0200 Subject: [PATCH] Some work on optimizations and database cleaning. --- CMakeLists.txt | 5 ++ ...ment-database.png => cleanup-database.png} | Bin resources/text/CHANGELOG | 5 +- src/gui/feedmessageviewer.cpp | 68 +++++++++++------ src/gui/feedmessageviewer.h | 7 ++ src/gui/formdatabasecleanup.cpp | 27 +++++++ src/gui/formdatabasecleanup.h | 24 ++++++ src/gui/formdatabasecleanup.ui | 71 ++++++++++++++++++ src/gui/formmain.cpp | 10 +-- src/gui/formmain.ui | 18 ++--- src/gui/messagesview.cpp | 4 + src/gui/systemtrayicon.cpp | 1 + src/gui/systemtrayicon.h | 3 + src/miscellaneous/application.cpp | 5 +- src/miscellaneous/databasecleaner.cpp | 26 +++++++ src/miscellaneous/databasecleaner.h | 36 +++++++++ 16 files changed, 268 insertions(+), 42 deletions(-) rename resources/graphics/icons/mini-kfaenza/{defragment-database.png => cleanup-database.png} (100%) create mode 100644 src/gui/formdatabasecleanup.cpp create mode 100644 src/gui/formdatabasecleanup.h create mode 100644 src/gui/formdatabasecleanup.ui create mode 100644 src/miscellaneous/databasecleaner.cpp create mode 100644 src/miscellaneous/databasecleaner.h 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: 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 @@ - + @@ -405,14 +405,6 @@ Hides main window if it is visible and shows it if it is hidden. - - - &Defragment database - - - Defragment database file so that its size decreases. - - true @@ -649,6 +641,14 @@ Send selected message via e-mail + + + &Cleanup database + + + Ctrl+Shift+Del + + 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