Added global recycle bin menu and ability to empty/restore individiual bins or all of them.

This commit is contained in:
Martin Rotter 2015-11-24 09:13:43 +01:00
parent d9435bed41
commit bd6c5390b4
15 changed files with 313 additions and 92 deletions

View File

@ -67,7 +67,6 @@ QString FeedDownloadResults::getOverview(int how_many_feeds) {
QStringList result;
// TODO: Maybe enhance the formatting of this output.
for (int i = 0, number_items_output = qMin(how_many_feeds, m_updatedFeeds.size()); i < number_items_output; i++) {
result.append(m_updatedFeeds.at(i).first + QSL(": ") + QString::number(m_updatedFeeds.at(i).second));
}

View File

@ -21,6 +21,7 @@
#include "services/abstract/feed.h"
#include "services/abstract/category.h"
#include "services/abstract/serviceroot.h"
#include "services/abstract/recyclebin.h"
#include "services/standard/standardserviceroot.h"
#include "miscellaneous/textfactory.h"
#include "miscellaneous/databasefactory.h"
@ -534,6 +535,7 @@ void FeedsModel::notifyWithCounts() {
void FeedsModel::onItemDataChanged(QList<RootItem*> items) {
if (items.size() > RELOAD_MODEL_BORDER_NUM) {
qDebug("There is request to reload feed model for more than %d items, reloading model fully.", RELOAD_MODEL_BORDER_NUM);
reloadWholeLayout();
}
else {
qDebug("There is request to reload feed model, reloading the %d items individually.", items.size());
@ -574,6 +576,34 @@ bool FeedsModel::addServiceAccount(ServiceRoot *root) {
return true;
}
bool FeedsModel::restoreAllBins() {
bool result = true;
foreach (ServiceRoot *root, serviceRoots()) {
RecycleBin *bin_of_root = root->recycleBin();
if (bin_of_root != NULL) {
result &= bin_of_root->restore();
}
}
return result;
}
bool FeedsModel::emptyAllBins() {
bool result = true;
foreach (ServiceRoot *root, serviceRoots()) {
RecycleBin *bin_of_root = root->recycleBin();
if (bin_of_root != NULL) {
result &= bin_of_root->empty();
}
}
return result;
}
void FeedsModel::loadActivatedServiceAccounts() {
// Iterate all globally available feed "service plugins".
foreach (ServiceEntryPoint *entry_point, qApp->feedServices()) {

View File

@ -145,6 +145,9 @@ class FeedsModel : public QAbstractItemModel {
bool addServiceAccount(ServiceRoot *root);
public slots:
bool restoreAllBins();
bool emptyAllBins();
// Feeds operations.
bool markItemRead(RootItem *item, RootItem::ReadStatus read);
bool markItemCleared(RootItem *item, bool clean_read_only);

View File

@ -40,6 +40,7 @@
#include "gui/dialogs/formrestoredatabasesettings.h"
#include "gui/notifications/notification.h"
#include "services/abstract/serviceroot.h"
#include "services/abstract/recyclebin.h"
#include "services/standard/gui/formstandardimportexport.h"
#include <QCloseEvent>
@ -185,8 +186,8 @@ void FormMain::updateAddItemMenu() {
if (root_actions.isEmpty()) {
QAction *no_action = new QAction(qApp->icons()->fromTheme(QSL("dialog-error")),
tr("No possible actions"),
m_ui->m_menuAddItem);
tr("No possible actions"),
m_ui->m_menuAddItem);
no_action->setEnabled(false);
root_menu->addAction(no_action);
}
@ -210,8 +211,8 @@ void FormMain::updateServicesMenu() {
if (root_actions.isEmpty()) {
QAction *no_action = new QAction(qApp->icons()->fromTheme(QSL("dialog-error")),
tr("No possible actions"),
m_ui->m_menuServices);
tr("No possible actions"),
m_ui->m_menuServices);
no_action->setEnabled(false);
root_menu->addAction(no_action);
}
@ -231,6 +232,49 @@ void FormMain::updateServicesMenu() {
m_ui->m_menuServices->addAction(m_ui->m_actionServiceDelete);
}
void FormMain::updateRecycleBinMenu() {
m_ui->m_menuRecycleBin->clear();
foreach (ServiceRoot *activated_root, tabWidget()->feedMessageViewer()->feedsView()->sourceModel()->serviceRoots()) {
QMenu *root_menu = new QMenu(activated_root->title(), m_ui->m_menuServices);
root_menu->setIcon(activated_root->icon());
root_menu->setToolTip(activated_root->description());
RecycleBin *bin = activated_root->recycleBin();
if (bin == NULL) {
QAction *no_action = new QAction(qApp->icons()->fromTheme(QSL("dialog-error")),
tr("No recycle bin"),
m_ui->m_menuRecycleBin);
no_action->setEnabled(false);
root_menu->addAction(no_action);
}
else {
QAction *restore_action = new QAction(qApp->icons()->fromTheme(QSL("recycle-bin-restore-all")),
tr("Restore recycle bin"),
m_ui->m_menuRecycleBin);
QAction *empty_action = new QAction(qApp->icons()->fromTheme(QSL("recycle-bin-empty")),
tr("Empty recycle bin"),
m_ui->m_menuRecycleBin);
connect(restore_action, SIGNAL(triggered()), bin, SLOT(restore()));
connect(empty_action, SIGNAL(triggered()), bin, SLOT(empty()));
root_menu->addAction(restore_action);
root_menu->addAction(empty_action);
}
m_ui->m_menuRecycleBin->addMenu(root_menu);
}
if (!m_ui->m_menuRecycleBin->isEmpty()) {
m_ui->m_menuRecycleBin->addSeparator();
}
m_ui->m_menuRecycleBin->addAction(m_ui->m_actionRestoreAllRecycleBins);
m_ui->m_menuRecycleBin->addAction(m_ui->m_actionEmptyAllRecycleBins);
}
void FormMain::switchVisibility(bool force_hide) {
if (force_hide || isVisible()) {
if (SystemTrayIcon::isSystemTrayActivated()) {
@ -324,6 +368,9 @@ void FormMain::setupIcons() {
m_ui->m_actionShowOnlyUnreadItems->setIcon(icon_theme_factory->fromTheme(QSL("mail-mark-unread")));
m_ui->m_actionExpandCollapseItem->setIcon(icon_theme_factory->fromTheme(QSL("expand-collapse")));
m_ui->m_actionRestoreSelectedMessages->setIcon(icon_theme_factory->fromTheme(QSL("recycle-bin-restore-one")));
m_ui->m_actionRestoreAllRecycleBins->setIcon(icon_theme_factory->fromTheme(QSL("recycle-bin-restore-all")));
m_ui->m_actionEmptyAllRecycleBins->setIcon(icon_theme_factory->fromTheme(QSL("recycle-bin-empty")));
// Setup icons for underlying components: opened web browsers...
foreach (WebBrowser *browser, WebBrowser::runningWebBrowsers()) {
@ -396,6 +443,7 @@ void FormMain::createConnections() {
connect(m_ui->m_menuAddItem, SIGNAL(aboutToShow()), this, SLOT(updateAddItemMenu()));
connect(m_ui->m_menuServices, SIGNAL(aboutToShow()), this, SLOT(updateServicesMenu()));
connect(m_ui->m_menuRecycleBin, SIGNAL(aboutToShow()), this, SLOT(updateRecycleBinMenu()));
// Menu "File" connections.
connect(m_ui->m_actionBackupDatabaseSettings, SIGNAL(triggered()), this, SLOT(backupDatabaseSettings()));

View File

@ -79,6 +79,7 @@ class FormMain : public QMainWindow {
private slots:
void updateAddItemMenu();
void updateServicesMenu();
void updateRecycleBinMenu();
// Loads web browser menu if user selects to change tabs.
void loadWebBrowserMenu(int index);

View File

@ -169,6 +169,7 @@
<addaction name="m_actionMarkSelectedMessagesAsUnread"/>
<addaction name="m_actionSwitchImportanceOfSelectedMessages"/>
<addaction name="m_actionDeleteSelectedMessages"/>
<addaction name="m_actionRestoreSelectedMessages"/>
</widget>
<widget class="QMenu" name="m_menuServices">
<property name="title">
@ -178,11 +179,19 @@
<addaction name="m_actionServiceEdit"/>
<addaction name="m_actionServiceDelete"/>
</widget>
<widget class="QMenu" name="m_menuRecycleBin">
<property name="title">
<string>&amp;Recycle bin</string>
</property>
<addaction name="m_actionRestoreAllRecycleBins"/>
<addaction name="m_actionEmptyAllRecycleBins"/>
</widget>
<addaction name="m_menuFile"/>
<addaction name="m_menuView"/>
<addaction name="m_menuServices"/>
<addaction name="m_menuFeeds"/>
<addaction name="m_menuMessages"/>
<addaction name="m_menuRecycleBin"/>
<addaction name="m_menuWebBrowser"/>
<addaction name="m_menuTools"/>
<addaction name="m_menuHelp"/>
@ -219,6 +228,9 @@
<property name="toolTip">
<string>Displays extra info about this application.</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
<property name="menuRole">
<enum>QAction::AboutRole</enum>
</property>
@ -255,6 +267,9 @@
<property name="toolTip">
<string>Close all tabs except current one.</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionCloseCurrentTab">
<property name="text">
@ -263,13 +278,16 @@
<property name="toolTip">
<string>Close current web browser tab.</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionUpdateAllItems">
<property name="text">
<string>Update &amp;all items</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+U</string>
<string notr="true">Ctrl+Shift+U</string>
</property>
</action>
<action name="m_actionUpdateSelectedItems">
@ -277,33 +295,48 @@
<string>Update &amp;selected items</string>
</property>
<property name="shortcut">
<string>Ctrl+U</string>
<string notr="true">Ctrl+U</string>
</property>
</action>
<action name="m_actionEditSelectedItem">
<property name="text">
<string>&amp;Edit selected item</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionDeleteSelectedItem">
<property name="text">
<string>&amp;Delete selected item</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionMarkSelectedMessagesAsRead">
<property name="text">
<string>Mark &amp;selected messages as &amp;read</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionMarkSelectedMessagesAsUnread">
<property name="text">
<string>Mark &amp;selected messages as &amp;unread</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionSwitchImportanceOfSelectedMessages">
<property name="text">
<string>Switch &amp;importance of selected messages</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionMarkSelectedItemsAsRead">
<property name="text">
@ -312,6 +345,9 @@
<property name="toolTip">
<string>Mark all messages (without message filters) from selected items as read.</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionMarkSelectedItemsAsUnread">
<property name="text">
@ -320,11 +356,17 @@
<property name="toolTip">
<string>Mark all messages (without message filters) from selected items as unread.</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionDeleteSelectedMessages">
<property name="text">
<string>&amp;Delete selected messages</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionClearSelectedItems">
<property name="text">
@ -333,21 +375,33 @@
<property name="toolTip">
<string>Deletes all messages from selected items.</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionOpenSelectedSourceArticlesExternally">
<property name="text">
<string>Open selected source articles in &amp;external browser</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionOpenSelectedMessagesInternally">
<property name="text">
<string>Open selected messages in &amp;internal browser</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionOpenSelectedSourceArticlesInternally">
<property name="text">
<string>Open selected source articles in &amp;internal browser</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionNoActions">
<property name="enabled">
@ -370,6 +424,9 @@
<property name="toolTip">
<string>Marks all messages in all items read. This does not take message filters into account.</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionViewSelectedItemsNewspaperMode">
<property name="text">
@ -378,6 +435,9 @@
<property name="toolTip">
<string>Displays all messages from selected item in a new &quot;newspaper mode&quot; tab. Note that messages are not set as read automatically.</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionSwitchMainWindow">
<property name="checked">
@ -389,6 +449,9 @@
<property name="toolTip">
<string>Hides main window if it is visible and shows it if it is hidden.</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionSwitchFeedsList">
<property name="checkable">
@ -412,7 +475,7 @@
<string>Deletes all messages from all items.</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+C</string>
<string notr="true">Ctrl+Shift+C</string>
</property>
</action>
<action name="m_actionSelectNextItem">
@ -420,7 +483,7 @@
<string>Select &amp;next item</string>
</property>
<property name="shortcut">
<string>S</string>
<string notr="true">S</string>
</property>
</action>
<action name="m_actionSelectPreviousItem">
@ -428,7 +491,7 @@
<string>Select &amp;previous item</string>
</property>
<property name="shortcut">
<string>A</string>
<string notr="true">A</string>
</property>
</action>
<action name="m_actionSelectNextMessage">
@ -454,6 +517,9 @@
<property name="toolTip">
<string>Check if new update for the application is available for download.</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionSwitchMainMenu">
<property name="checkable">
@ -556,26 +622,41 @@
<property name="text">
<string>&amp;Donate via PayPal</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionDisplayWiki">
<property name="text">
<string>Display &amp;wiki</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionRestart">
<property name="text">
<string>&amp;Restart</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionRestoreDatabaseSettings">
<property name="text">
<string>&amp;Restore database/settings</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionBackupDatabaseSettings">
<property name="text">
<string>&amp;Backup database/settings</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionSwitchMessageListOrientation">
<property name="text">
@ -589,11 +670,17 @@
<property name="text">
<string>&amp;Downloads</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionSendMessageViaEmail">
<property name="text">
<string>Send selected message via e-mail</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionCleanupDatabase">
<property name="text">
@ -619,13 +706,16 @@
<string>&amp;Expand/collapse selected item</string>
</property>
<property name="shortcut">
<string>E</string>
<string notr="true">E</string>
</property>
</action>
<action name="m_actionServiceAdd">
<property name="text">
<string>&amp;Add new service account</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionServiceDelete">
<property name="enabled">
@ -634,6 +724,9 @@
<property name="text">
<string>&amp;Delete selected service account</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionServiceEdit">
<property name="enabled">
@ -642,11 +735,30 @@
<property name="text">
<string>&amp;Edit selected service account</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionRestoreSelectedMessages">
<property name="text">
<string>&amp;Restore selected messages</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionRestoreAllRecycleBins">
<property name="text">
<string>&amp;Restore all recycle bins</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
<action name="m_actionEmptyAllRecycleBins">
<property name="text">
<string>&amp;Empty all recycle bins</string>
</property>
</action>
</widget>
<customwidgets>

View File

@ -179,9 +179,11 @@ void FeedMessageViewer::toggleShowOnlyUnreadFeeds() {
void FeedMessageViewer::updateMessageButtonsAvailability() {
bool one_message_selected = m_messagesView->selectionModel()->selectedRows().size() == 1;
bool atleast_one_message_selected = !m_messagesView->selectionModel()->selectedRows().isEmpty();
bool bin_loaded = m_messagesView->sourceModel()->loadedItem() != NULL && m_messagesView->sourceModel()->loadedItem()->kind() == RootItemKind::Bin;
FormMain *form_main = qApp->mainForm();
form_main->m_ui->m_actionDeleteSelectedMessages->setEnabled(atleast_one_message_selected);
form_main->m_ui->m_actionRestoreSelectedMessages->setEnabled(atleast_one_message_selected && bin_loaded);
form_main->m_ui->m_actionMarkSelectedMessagesAsRead->setEnabled(atleast_one_message_selected);
form_main->m_ui->m_actionMarkSelectedMessagesAsUnread->setEnabled(atleast_one_message_selected);
form_main->m_ui->m_actionOpenSelectedMessagesInternally->setEnabled(atleast_one_message_selected);
@ -214,6 +216,7 @@ void FeedMessageViewer::updateFeedButtonsAvailability() {
form_main->m_ui->m_actionViewSelectedItemsNewspaperMode->setEnabled(feed_selected || category_selected || service_selected);
form_main->m_ui->m_actionExpandCollapseItem->setEnabled(feed_selected || category_selected || service_selected);
form_main->m_ui->m_menuAddItem->setEnabled(!critical_action_running);
form_main->m_ui->m_menuRecycleBin->setEnabled(!critical_action_running);
}
void FeedMessageViewer::createConnections() {
@ -250,10 +253,6 @@ void FeedMessageViewer::createConnections() {
connect(m_feedsView, SIGNAL(openMessagesInNewspaperView(QList<Message>)),
form_main->m_ui->m_tabWidget, SLOT(addBrowserWithMessages(QList<Message>)));
// Downloader connections.
// TODO: přesunout všechny negui věci asi k modelům, tohle je
// hlavně GUI třída, takže přesunout aktualizace feedů do modelu
// Toolbar forwardings.
connect(form_main->m_ui->m_actionCleanupDatabase,
SIGNAL(triggered()), this, SLOT(showDbCleanupAssistant()));
@ -315,6 +314,10 @@ void FeedMessageViewer::createConnections() {
this, SLOT(toggleShowOnlyUnreadFeeds()));
connect(form_main->m_ui->m_actionRestoreSelectedMessages, SIGNAL(triggered()),
m_messagesView, SLOT(restoreSelectedMessages()));
connect(form_main->m_ui->m_actionRestoreAllRecycleBins, SIGNAL(triggered()),
m_feedsView->sourceModel(), SLOT(restoreAllBins()));
connect(form_main->m_ui->m_actionEmptyAllRecycleBins, SIGNAL(triggered()),
m_feedsView->sourceModel(), SLOT(emptyAllBins()));
}
void FeedMessageViewer::initialize() {

1
src/services/abstract/recyclebin.h Normal file → Executable file
View File

@ -30,6 +30,7 @@ class RecycleBin : public RootItem {
QVariant data(int column, int role) const;
public slots:
// Empties the bin - removes all messages from it (does not remove
// them from DB, just permanently hide them, so that they are not
// re-downloaded).

View File

@ -38,3 +38,7 @@ void ServiceRoot::itemChanged(QList<RootItem*> items) {
void ServiceRoot::requestReloadMessageList(bool mark_selected_messages_read) {
emit reloadMessageListRequested(mark_selected_messages_read);
}
void ServiceRoot::requestFeedReadFilterReload() {
emit readFeedsFilterInvalidationRequested();
}

View File

@ -26,6 +26,7 @@
class FeedsModel;
class RecycleBin;
class QAction;
class QSqlTableModel;
@ -52,6 +53,8 @@ class ServiceRoot : public RootItem {
// NOTE: Caller does NOT take ownership of created menu!
virtual QList<QAction*> serviceMenu() = 0;
virtual RecycleBin *recycleBin() = 0;
// Start/stop services.
// Start method is called when feed model gets initialized OR after user adds new service.
//
@ -125,6 +128,7 @@ class ServiceRoot : public RootItem {
// Obvious methods to wrap signals.
void itemChanged(QList<RootItem*> items);
void requestReloadMessageList(bool mark_selected_messages_read);
void requestFeedReadFilterReload();
signals:
// Emitted if data in any item belonging to this root are changed.

View File

@ -125,7 +125,7 @@ bool StandardCategory::removeItself() {
if (children_removed) {
// Children are removed, remove this standard category too.
QSqlDatabase database = qApp->database()->connection(QSL("Category"), DatabaseFactory::FromSettings);
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query_remove(database);
// Remove this category from database.
@ -142,7 +142,7 @@ bool StandardCategory::removeItself() {
bool StandardCategory::addItself(RootItem *parent) {
// Now, add category to persistent storage.
QSqlDatabase database = qApp->database()->connection(QSL("Category"), DatabaseFactory::FromSettings);
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query_add(database);
query_add.setForwardOnly(true);
@ -179,7 +179,7 @@ bool StandardCategory::addItself(RootItem *parent) {
}
bool StandardCategory::editItself(StandardCategory *new_category_data) {
QSqlDatabase database = qApp->database()->connection(QSL("Category"), DatabaseFactory::FromSettings);
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query_update_category(database);
StandardCategory *original_category = this;
RootItem *new_parent = new_category_data->parent();

View File

@ -129,7 +129,7 @@ bool StandardFeed::cleanMessages(bool clean_read_only) {
QList<Message> StandardFeed::undeletedMessages() const {
QList<Message> messages;
QSqlDatabase database = qApp->database()->connection("StandardFeed", DatabaseFactory::FromSettings);
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query_read_msg(database);
query_read_msg.setForwardOnly(true);
query_read_msg.prepare("SELECT title, url, author, date_created, contents "
@ -174,7 +174,7 @@ QString StandardFeed::typeToString(StandardFeed::Type type) {
}
void StandardFeed::updateCounts(bool including_total_count) {
QSqlDatabase database = qApp->database()->connection(QSL("Feed"), DatabaseFactory::FromSettings);
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query_all(database);
query_all.setForwardOnly(true);
@ -483,7 +483,7 @@ int StandardFeed::update() {
}
bool StandardFeed::removeItself() {
QSqlDatabase database = qApp->database()->connection(QSL("Feed"), DatabaseFactory::FromSettings);
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query_remove(database);
query_remove.setForwardOnly(true);
@ -505,7 +505,7 @@ bool StandardFeed::removeItself() {
bool StandardFeed::addItself(RootItem *parent) {
// Now, add feed to persistent storage.
QSqlDatabase database = qApp->database()->connection(QSL("Feed"), DatabaseFactory::FromSettings);
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query_add_feed(database);
query_add_feed.setForwardOnly(true);
@ -555,7 +555,7 @@ bool StandardFeed::addItself(RootItem *parent) {
}
bool StandardFeed::editItself(StandardFeed *new_feed_data) {
QSqlDatabase database = qApp->database()->connection(QSL("Feed"), DatabaseFactory::FromSettings);
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query_update_feed(database);
StandardFeed *original_feed = this;
RootItem *new_parent = new_feed_data->parent();
@ -611,7 +611,7 @@ bool StandardFeed::editItself(StandardFeed *new_feed_data) {
int StandardFeed::updateMessages(const QList<Message> &messages) {
int feed_id = id();
int updated_messages = 0;
QSqlDatabase database = qApp->database()->connection(QSL("Feed"), DatabaseFactory::FromSettings);
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
bool remove_duplicates = qApp->settings()->value(GROUP(Messages), SETTING(Messages::RemoveDuplicates)).toBool();
// Prepare queries.

View File

@ -51,61 +51,15 @@ bool StandardRecycleBin::markAsReadUnread(RootItem::ReadStatus status) {
}
bool StandardRecycleBin::empty() {
QSqlDatabase db_handle = qApp->database()->connection(QSL("RecycleBin"), DatabaseFactory::FromSettings);
if (!db_handle.transaction()) {
qWarning("Starting transaction for recycle bin emptying.");
return false;
}
QSqlQuery query_empty_bin(db_handle);
query_empty_bin.setForwardOnly(true);
if (!query_empty_bin.exec(QSL("UPDATE Messages SET is_pdeleted = 1 WHERE is_deleted = 1;"))) {
qWarning("Query execution failed for recycle bin emptying.");
db_handle.rollback();
return false;
}
// Commit changes.
if (db_handle.commit()) {
return true;
}
else {
return db_handle.rollback();
}
return serviceRoot()->emptyBin();
}
bool StandardRecycleBin::restore() {
QSqlDatabase db_handle = qApp->database()->connection(QSL("RecycleBin"), DatabaseFactory::FromSettings);
if (!db_handle.transaction()) {
qWarning("Starting transaction for recycle bin restoring.");
return false;
}
QSqlQuery query_empty_bin(db_handle);
query_empty_bin.setForwardOnly(true);
if (!query_empty_bin.exec(QSL("UPDATE Messages SET is_deleted = 0 WHERE is_deleted = 1 AND is_pdeleted = 0;"))) {
qWarning("Query execution failed for recycle bin restoring.");
db_handle.rollback();
return false;
}
// Commit changes.
if (db_handle.commit()) {
return true;
}
else {
return db_handle.rollback();
}
return serviceRoot()->restoreBin();
}
void StandardRecycleBin::updateCounts(bool update_total_count) {
QSqlDatabase database = qApp->database()->connection(QSL("RecycleBin"), DatabaseFactory::FromSettings);
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query_all(database);
query_all.setForwardOnly(true);

View File

@ -129,8 +129,12 @@ QVariant StandardServiceRoot::data(int column, int role) const {
}
}
RecycleBin *StandardServiceRoot::recycleBin() {
return m_recycleBin;
}
bool StandardServiceRoot::markFeedsReadUnread(QList<Feed*> items, ReadStatus read) {
QSqlDatabase db_handle = qApp->database()->connection(QSL("StandardServiceRoot"), DatabaseFactory::FromSettings);
QSqlDatabase db_handle = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
if (!db_handle.transaction()) {
qWarning("Starting transaction for feeds read change.");
@ -175,7 +179,7 @@ bool StandardServiceRoot::markFeedsReadUnread(QList<Feed*> items, ReadStatus rea
}
bool StandardServiceRoot::markRecycleBinReadUnread(RootItem::ReadStatus read) {
QSqlDatabase db_handle = qApp->database()->connection(QSL("StandardServiceRoot"), DatabaseFactory::FromSettings);
QSqlDatabase db_handle = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
if (!db_handle.transaction()) {
qWarning("Starting transaction for recycle bin read change.");
@ -213,7 +217,7 @@ bool StandardServiceRoot::markRecycleBinReadUnread(RootItem::ReadStatus read) {
}
bool StandardServiceRoot::cleanFeeds(QList<Feed*> items, bool clean_read_only) {
QSqlDatabase db_handle = qApp->database()->connection(QSL("StandardServiceRoot"), DatabaseFactory::FromSettings);
QSqlDatabase db_handle = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query_delete_msg(db_handle);
query_delete_msg.setForwardOnly(true);
@ -256,8 +260,69 @@ bool StandardServiceRoot::cleanFeeds(QList<Feed*> items, bool clean_read_only) {
}
}
bool StandardServiceRoot::restoreBin() {
QSqlDatabase db_handle = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
if (!db_handle.transaction()) {
qWarning("Starting transaction for recycle bin restoring.");
return false;
}
QSqlQuery query_empty_bin(db_handle);
query_empty_bin.setForwardOnly(true);
if (!query_empty_bin.exec(QSL("UPDATE Messages SET is_deleted = 0 WHERE is_deleted = 1 AND is_pdeleted = 0;"))) {
qWarning("Query execution failed for recycle bin restoring.");
db_handle.rollback();
return false;
}
// Commit changes.
if (db_handle.commit()) {
updateCounts(true);
itemChanged(getSubTree());
requestReloadMessageList(true);
requestFeedReadFilterReload();
return true;
}
else {
return db_handle.rollback();
}
}
bool StandardServiceRoot::emptyBin() {
QSqlDatabase db_handle = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
if (!db_handle.transaction()) {
qWarning("Starting transaction for recycle bin emptying.");
return false;
}
QSqlQuery query_empty_bin(db_handle);
query_empty_bin.setForwardOnly(true);
if (!query_empty_bin.exec(QSL("UPDATE Messages SET is_pdeleted = 1 WHERE is_deleted = 1;"))) {
qWarning("Query execution failed for recycle bin emptying.");
db_handle.rollback();
return false;
}
// Commit changes.
if (db_handle.commit()) {
m_recycleBin->updateCounts(true);
itemChanged(QList<RootItem*>() << m_recycleBin);
requestReloadMessageList(true);
return true;
}
else {
return db_handle.rollback();
}
}
void StandardServiceRoot::loadFromDatabase(){
QSqlDatabase database = qApp->database()->connection("StandardServiceRoot", DatabaseFactory::FromSettings);
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
CategoryAssignment categories;
FeedAssignment feeds;
@ -380,10 +445,6 @@ void StandardServiceRoot::assembleFeeds(FeedAssignment feeds) {
}
}
StandardRecycleBin *StandardServiceRoot::recycleBin() const {
return m_recycleBin;
}
bool StandardServiceRoot::mergeImportExportModel(FeedsImportExportModel *model, QString &output_message) {
QStack<RootItem*> original_parents; original_parents.push(this);
QStack<RootItem*> new_parents; new_parents.push(model->rootItem());
@ -566,8 +627,8 @@ bool StandardServiceRoot::onAfterSetMessagesRead(RootItem *selected_item, QList<
selected_item->updateCounts(false);
emit dataChanged(QList<RootItem*>() << selected_item);
emit readFeedsFilterInvalidationRequested();
itemChanged(QList<RootItem*>() << selected_item);
requestFeedReadFilterReload();
return true;
}
@ -601,15 +662,15 @@ bool StandardServiceRoot::onAfterMessagesDelete(RootItem *selected_item, QList<i
selected_item->updateCounts(true);
if (selected_item->kind() == RootItemKind::Bin) {
emit dataChanged(QList<RootItem*>() << m_recycleBin);
itemChanged(QList<RootItem*>() << m_recycleBin);
}
else {
m_recycleBin->updateCounts(true);
emit dataChanged(QList<RootItem*>() << selected_item << m_recycleBin);
itemChanged(QList<RootItem*>() << selected_item << m_recycleBin);
}
emit readFeedsFilterInvalidationRequested();
requestFeedReadFilterReload();
return true;
}
@ -624,9 +685,8 @@ bool StandardServiceRoot::onAfterMessagesRestoredFromBin(RootItem *selected_item
Q_UNUSED(message_db_ids)
updateCounts(true);
emit dataChanged(getSubTree());
emit readFeedsFilterInvalidationRequested();
itemChanged(getSubTree());
requestFeedReadFilterReload();
return true;
}

View File

@ -52,6 +52,8 @@ class StandardServiceRoot : public ServiceRoot {
bool canBeDeleted();
QVariant data(int column, int role) const;
RecycleBin *recycleBin();
// Return "add feed" and "add category" items.
QList<QAction*> addItemMenu();
@ -84,9 +86,6 @@ class StandardServiceRoot : public ServiceRoot {
// Returns context specific menu actions for given feed.
QList<QAction*> getContextMenuForFeed(StandardFeed *feed);
// Access to standard recycle bin.
StandardRecycleBin *recycleBin() const;
// Takes structure residing under given root item and adds feeds/categories from
// it to active structure.
// NOTE: This is used for import/export of the model.
@ -96,6 +95,9 @@ class StandardServiceRoot : public ServiceRoot {
bool markRecycleBinReadUnread(ReadStatus read);
bool cleanFeeds(QList<Feed*> items, bool clean_read_only);
bool restoreBin();
bool emptyBin();
// DB connection to be used by child items - feeds/categories.
QSqlDatabase dbConnection() const;