From ebea3e00295308493a9ba08f2fb1a268ffa39e71 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Thu, 19 Nov 2015 13:21:38 +0100 Subject: [PATCH] VERY initial and f*cking buggy implementation of some messages-realted operations - right now, there is added ability to display messages according to selection. --- CMakeLists.txt | 1 - src/core/feedsselection.cpp | 73 ------------------- src/core/feedsselection.h | 50 ------------- src/core/messagesmodel.cpp | 53 +++++++++----- src/core/messagesmodel.h | 8 +- src/gui/feedmessageviewer.cpp | 9 +-- src/gui/feedsview.cpp | 17 +++-- src/gui/feedsview.h | 10 +-- src/gui/messagesview.cpp | 4 +- src/gui/messagesview.h | 3 +- src/services/abstract/serviceroot.h | 10 +++ src/services/standard/standardserviceroot.cpp | 22 ++++++ src/services/standard/standardserviceroot.h | 3 + 13 files changed, 92 insertions(+), 171 deletions(-) delete mode 100755 src/core/feedsselection.cpp delete mode 100755 src/core/feedsselection.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9af5020df..ccf63113f 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -412,7 +412,6 @@ set(APP_SOURCES src/core/rootitem.cpp src/core/parsingfactory.cpp src/core/feeddownloader.cpp - src/core/feedsselection.cpp src/core/message.cpp # ABSTRACT service sources. diff --git a/src/core/feedsselection.cpp b/src/core/feedsselection.cpp deleted file mode 100755 index c21d6e0ac..000000000 --- a/src/core/feedsselection.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// 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 "core/feedsselection.h" - -#include "core/rootitem.h" -#include "services/standard/standardcategory.h" -#include "services/standard/standardfeed.h" -#include "definitions/definitions.h" - - -FeedsSelection::FeedsSelection(RootItem *root_of_selection) : m_selectedItem(root_of_selection) { -} - -FeedsSelection::FeedsSelection(const FeedsSelection &other) { - m_selectedItem = other.selectedItem(); -} - -FeedsSelection::~FeedsSelection() { -} - -FeedsSelection::SelectionMode FeedsSelection::mode() { - if (m_selectedItem == NULL) { - return FeedsSelection::NoMode; - } - - switch (m_selectedItem->kind()) { - case RootItemKind::Bin: - return FeedsSelection::MessagesFromRecycleBin; - - case RootItemKind::Category: - case RootItemKind::Feed: - return FeedsSelection::MessagesFromFeeds; - - default: - return FeedsSelection::NoMode; - } -} - -RootItem *FeedsSelection::selectedItem() const { - return m_selectedItem; -} - -QString FeedsSelection::generateListOfIds() { - if (m_selectedItem != NULL && - (m_selectedItem->kind() == RootItemKind::Feed || m_selectedItem->kind() == RootItemKind::Category)) { - QList children = m_selectedItem->getSubTreeFeeds(); - QStringList stringy_ids; - - foreach (Feed *child, children) { - stringy_ids.append(QString::number(child->id())); - } - - return stringy_ids.join(QSL(", ")); - } - else { - return QString(); - } -} diff --git a/src/core/feedsselection.h b/src/core/feedsselection.h deleted file mode 100755 index 1295bdffa..000000000 --- a/src/core/feedsselection.h +++ /dev/null @@ -1,50 +0,0 @@ -// 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 FEEDSSELECTION_H -#define FEEDSSELECTION_H - -#include -#include - - -class RootItem; -class StandardFeed; - -class FeedsSelection { - public: - enum SelectionMode { - NoMode, - MessagesFromFeeds, - MessagesFromRecycleBin - }; - - explicit FeedsSelection(RootItem *root_of_selection = NULL); - FeedsSelection(const FeedsSelection &other); - virtual ~FeedsSelection(); - - SelectionMode mode(); - RootItem *selectedItem() const; - QString generateListOfIds(); - - private: - RootItem *m_selectedItem; -}; - -Q_DECLARE_METATYPE(FeedsSelection::SelectionMode) - -#endif // FEEDSSELECTION_H diff --git a/src/core/messagesmodel.cpp b/src/core/messagesmodel.cpp index 49014e078..4064fb8cf 100755 --- a/src/core/messagesmodel.cpp +++ b/src/core/messagesmodel.cpp @@ -22,6 +22,8 @@ #include "miscellaneous/textfactory.h" #include "miscellaneous/databasefactory.h" #include "miscellaneous/iconfactory.h" +#include "gui/dialogs/formmain.h" +#include "services/abstract/serviceroot.h" #include #include @@ -42,7 +44,7 @@ MessagesModel::MessagesModel(QObject *parent) // via model, but via DIRECT SQL calls are used to do persistent messages. setEditStrategy(QSqlTableModel::OnManualSubmit); setTable(QSL("Messages")); - loadMessages(FeedsSelection()); + loadMessages(NULL); } MessagesModel::~MessagesModel() { @@ -69,17 +71,21 @@ void MessagesModel::setupFonts() { m_boldFont.setBold(true); } -void MessagesModel::loadMessages(const FeedsSelection &selection) { - m_currentSelection = selection; +void MessagesModel::loadMessages(RootItem *item) { + m_selectedItem = item; - if (m_currentSelection.mode() == FeedsSelection::MessagesFromRecycleBin) { - setFilter(QSL("is_deleted = 1 AND is_pdeleted = 0")); + if (item == NULL) { + setFilter("true != true"); } else { - QString assembled_ids = m_currentSelection.generateListOfIds(); - - setFilter(QString(QSL("feed IN (%1) AND is_deleted = 0")).arg(assembled_ids)); - qDebug("Loading messages from feeds: %s.", qPrintable(assembled_ids)); + if (!item->getParentServiceRoot()->loadMessagesForItem(item, this)) { + qWarning("Loading of messages from item '%s' failed.", qPrintable(item->title())); + qApp->showGuiMessage(tr("Loading of messages from item '%s' failed.").arg(item->title()), + tr("Loading of messages failed, maybe messages could not be downloaded."), + QSystemTrayIcon::Critical, + qApp->mainForm(), + true); + } } fetchAllData(); @@ -276,7 +282,10 @@ bool MessagesModel::setMessageRead(int row_index, int read) { // If commit succeeded, then emit changes, so that view // can reflect. emit dataChanged(index(row_index, 0), index(row_index, columnCount() - 1)); - emit messageCountsChanged(m_currentSelection.mode(), false, false); + emit messageCountsChanged(); + + // TODO: counts changed + //emit messageCountsChanged(m_selectedItem.mode(), false, false); return true; } else { @@ -374,7 +383,9 @@ bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages, int QString sql_delete_query; - if (m_currentSelection.mode() == FeedsSelection::MessagesFromFeeds) { + // TODO: todo + /* + if (m_selectedItem.mode() == FeedsSelection::MessagesFromFeeds) { sql_delete_query = QString(QSL("UPDATE Messages SET is_deleted = %2 WHERE id IN (%1);")).arg(message_ids.join(QSL(", ")), QString::number(deleted)); } @@ -382,11 +393,14 @@ bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages, int sql_delete_query = QString(QSL("UPDATE Messages SET is_pdeleted = %2 WHERE id IN (%1);")).arg(message_ids.join(QSL(", ")), QString::number(deleted)); } + */ if (query_read_msg.exec(sql_delete_query)) { fetchAllData(); + emit messageCountsChanged(); - emit messageCountsChanged(m_currentSelection.mode(), true, false); + // TODO: counts changed + //emit messageCountsChanged(m_selectedItem.mode(), true, false); return true; } else { @@ -411,7 +425,10 @@ bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, RootIt read == RootItem::Read ? QSL("1") : QSL("0")))) { fetchAllData(); - emit messageCountsChanged(m_currentSelection.mode(), false, false); + emit messageCountsChanged(); + + // TODO: counts changed + //emit messageCountsChanged(m_selectedItem.mode(), false, false); return true; } else { @@ -420,11 +437,6 @@ bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, RootIt } bool MessagesModel::setBatchMessagesRestored(const QModelIndexList &messages) { - if (m_currentSelection.mode() == FeedsSelection::MessagesFromFeeds) { - qDebug("Cannot restore non-deleted messages."); - return false; - } - QSqlDatabase db_handle = database(); QSqlQuery query_read_msg(db_handle); QStringList message_ids; @@ -441,7 +453,10 @@ bool MessagesModel::setBatchMessagesRestored(const QModelIndexList &messages) { if (query_read_msg.exec(sql_delete_query)) { fetchAllData(); - emit messageCountsChanged(m_currentSelection.mode(), true, true); + emit messageCountsChanged(); + + // TODO: counts changed + //emit messageCountsChanged(m_selectedItem.mode(), true, true); return true; } else { diff --git a/src/core/messagesmodel.h b/src/core/messagesmodel.h index d9b747502..f966a9bb2 100755 --- a/src/core/messagesmodel.h +++ b/src/core/messagesmodel.h @@ -20,7 +20,6 @@ #include "definitions/definitions.h" -#include "core/feedsselection.h" #include "core/message.h" #include "core/rootitem.h" @@ -81,13 +80,12 @@ class MessagesModel : public QSqlTableModel { // Filters messages void highlightMessages(MessageHighlighter highlight); - public slots: // Loads messages of given feeds. - void loadMessages(const FeedsSelection &selection); + void loadMessages(RootItem *item); signals: // Emitted if some persistent change is made which affects count of "unread/all" messages. - void messageCountsChanged(FeedsSelection::SelectionMode mode, bool total_msg_count_changed, bool any_msg_restored); + void messageCountsChanged(); private slots: // To disable persistent changes submissions. @@ -106,7 +104,7 @@ class MessagesModel : public QSqlTableModel { MessageHighlighter m_messageHighlighter; QString m_customDateFormat; - FeedsSelection m_currentSelection; + RootItem *m_selectedItem; QList m_headerData; QList m_tooltipData; diff --git a/src/gui/feedmessageviewer.cpp b/src/gui/feedmessageviewer.cpp index 32208b220..25bd3c04f 100755 --- a/src/gui/feedmessageviewer.cpp +++ b/src/gui/feedmessageviewer.cpp @@ -25,7 +25,6 @@ #include "miscellaneous/databasecleaner.h" #include "core/messagesproxymodel.h" #include "core/feeddownloader.h" -#include "core/feedsselection.h" #include "services/standard/standardserviceroot.h" #include "services/standard/standardfeed.h" #include "services/standard/standardfeedsimportexportmodel.h" @@ -321,16 +320,16 @@ void FeedMessageViewer::createConnections() { connect(m_messagesView, SIGNAL(currentMessagesRemoved()), this, SLOT(updateMessageButtonsAvailability())); connect(m_messagesView, SIGNAL(currentMessagesChanged(QList)), this, SLOT(updateMessageButtonsAvailability())); - connect(m_feedsView, SIGNAL(feedsSelected(FeedsSelection)), this, SLOT(updateFeedButtonsAvailability())); + connect(m_feedsView, SIGNAL(itemSelected(RootItem*)), this, SLOT(updateFeedButtonsAvailability())); connect(qApp->feedUpdateLock(), SIGNAL(locked()), this, SLOT(updateFeedButtonsAvailability())); connect(qApp->feedUpdateLock(), SIGNAL(unlocked()), this, SLOT(updateFeedButtonsAvailability())); // If user selects feeds, load their messages. - connect(m_feedsView, SIGNAL(feedsSelected(FeedsSelection)), m_messagesView, SLOT(loadFeeds(FeedsSelection))); + connect(m_feedsView, SIGNAL(itemSelected(RootItem*)), m_messagesView, SLOT(loadFeeds(RootItem*))); // If user changes status of some messages, recalculate message counts. - connect(m_messagesView->sourceModel(), SIGNAL(messageCountsChanged(FeedsSelection::SelectionMode,bool,bool)), - m_feedsView, SLOT(receiveMessageCountsChange(FeedsSelection::SelectionMode,bool,bool))); + connect(m_messagesView->sourceModel(), SIGNAL(messageCountsChanged()), + m_feedsView, SLOT(receiveMessageCountsChange())); // State of many messages is changed, then we need // to reload selections. diff --git a/src/gui/feedsview.cpp b/src/gui/feedsview.cpp index 654f54014..a0f473c1d 100755 --- a/src/gui/feedsview.cpp +++ b/src/gui/feedsview.cpp @@ -189,9 +189,12 @@ void FeedsView::clearAllFeeds() { emit feedsNeedToBeReloaded(true); } -void FeedsView::receiveMessageCountsChange(FeedsSelection::SelectionMode mode, - bool total_msg_count_changed, - bool any_msg_restored) { +void FeedsView::receiveMessageCountsChange() { + + // TODO: toto vymazat, prepocitani cisel unread/all + // a upozorneni na zmenu itemu provede ten item + // zde jen nechat tu invalidaci read filteru + // If the change came from recycle bin mode, then: // a) total count of message was changed AND no message was restored - some messages // were permanently deleted from recycle bin --> we need to update counts of @@ -207,7 +210,7 @@ void FeedsView::receiveMessageCountsChange(FeedsSelection::SelectionMode mode, // total counts. // b) total count of message was not changed - some messages switched state --> we need to update // counts of just selected feeds. - if (mode == FeedsSelection::MessagesFromRecycleBin) { + /*if (mode == FeedsSelection::MessagesFromRecycleBin) { if (total_msg_count_changed) { if (any_msg_restored) { updateCountsOfAllFeeds(true); @@ -222,7 +225,7 @@ void FeedsView::receiveMessageCountsChange(FeedsSelection::SelectionMode mode, } else { updateCountsOfSelectedFeeds(total_msg_count_changed); - } + }*/ invalidateReadFeedsFilter(); } @@ -582,7 +585,7 @@ void FeedsView::selectionChanged(const QItemSelection &selected, const QItemSele m_proxyModel->setSelectedItem(selected_item); QTreeView::selectionChanged(selected, deselected); - emit feedsSelected(FeedsSelection(selected_item)); + emit itemSelected(selected_item); invalidateReadFeedsFilter(); } @@ -610,8 +613,6 @@ void FeedsView::contextMenuEvent(QContextMenuEvent *event) { initializeContextMenuFeeds(clicked_item)->exec(event->globalPos()); } else { - // TODO: volaz specificke menu polozky? zobrazovat menu pro dalsi typy - // polozek jako odpadkovy kos atp. initializeContextMenuOtherItem(clicked_item)->exec(event->globalPos()); } } diff --git a/src/gui/feedsview.h b/src/gui/feedsview.h index 0d357c6a5..13b2e6878 100755 --- a/src/gui/feedsview.h +++ b/src/gui/feedsview.h @@ -18,13 +18,11 @@ #ifndef FEEDSVIEW_H #define FEEDSVIEW_H -#include #include -#include "core/messagesmodel.h" #include "core/feedsmodel.h" -#include "core/feedsselection.h" -#include "miscellaneous/settings.h" + +#include class FeedsProxyModel; @@ -98,7 +96,7 @@ class FeedsView : public QTreeView { // Is called when counts of messages are changed externally, // typically from message view. - void receiveMessageCountsChange(FeedsSelection::SelectionMode mode, bool total_msg_count_changed, bool any_msg_restored); + void receiveMessageCountsChange(); // Reloads counts for selected feeds. void updateCountsOfSelectedFeeds(bool update_total_too); @@ -155,7 +153,7 @@ class FeedsView : public QTreeView { void feedsNeedToBeReloaded(bool mark_current_index_read); // Emitted if user selects new feeds. - void feedsSelected(const FeedsSelection &selection); + void itemSelected(RootItem *item); // Requests opening of given messages in newspaper mode. void openMessagesInNewspaperView(const QList &messages); diff --git a/src/gui/messagesview.cpp b/src/gui/messagesview.cpp index ae2cd009f..1c224b7d7 100755 --- a/src/gui/messagesview.cpp +++ b/src/gui/messagesview.cpp @@ -225,8 +225,8 @@ void MessagesView::selectionChanged(const QItemSelection &selected, const QItemS QTreeView::selectionChanged(selected, deselected); } -void MessagesView::loadFeeds(const FeedsSelection &selection) { - m_sourceModel->loadMessages(selection); +void MessagesView::loadFeeds(RootItem *item) { + m_sourceModel->loadMessages(item); int col = qApp->settings()->value(GROUP(GUI), SETTING(GUI::DefaultSortColumnMessages)).toInt(); Qt::SortOrder ord = static_cast(qApp->settings()->value(GROUP(GUI), SETTING(GUI::DefaultSortOrderMessages)).toInt()); diff --git a/src/gui/messagesview.h b/src/gui/messagesview.h index 2e43e0dd8..ca94e4f83 100755 --- a/src/gui/messagesview.h +++ b/src/gui/messagesview.h @@ -20,7 +20,6 @@ #include "core/messagesmodel.h" -#include "core/feedsselection.h" #include "core/rootitem.h" #include @@ -58,7 +57,7 @@ class MessagesView : public QTreeView { void reloadSelections(bool mark_current_index_read); // Loads un-deleted messages from selected feeds. - void loadFeeds(const FeedsSelection &selection); + void loadFeeds(RootItem *item); // Message manipulators. void openSelectedSourceMessagesExternally(); diff --git a/src/services/abstract/serviceroot.h b/src/services/abstract/serviceroot.h index 08ecd307d..6a2cdb5ec 100755 --- a/src/services/abstract/serviceroot.h +++ b/src/services/abstract/serviceroot.h @@ -23,6 +23,7 @@ class FeedsModel; class QAction; +class QSqlTableModel; // THIS IS the root node of the service. // NOTE: The root usually contains some core functionality of the @@ -55,6 +56,15 @@ class ServiceRoot : public RootItem { virtual void start() = 0; virtual void stop() = 0; + // This method should prepare messages for given "item" (download them maybe?) + // into predefined "Messages" table + // and then use method QSqlTableModel::setFilter(....). + // NOTE: It would be more preferable if all messages are downloaded + // right when feeds are updated. + // TODO: toto možná udělat asynchronně, zobrazit + // "loading" dialog přes view a toto zavolat, nasledně signalovat + virtual bool loadMessagesForItem(RootItem *item, QSqlTableModel *model) = 0; + // Access to feed model. FeedsModel *feedsModel() const; diff --git a/src/services/standard/standardserviceroot.cpp b/src/services/standard/standardserviceroot.cpp index 2c274ccca..976c01369 100755 --- a/src/services/standard/standardserviceroot.cpp +++ b/src/services/standard/standardserviceroot.cpp @@ -40,6 +40,7 @@ #include #include #include +#include StandardServiceRoot::StandardServiceRoot(bool load_from_db, FeedsModel *feeds_model, RootItem *parent) @@ -518,6 +519,27 @@ QList StandardServiceRoot::serviceMenu() { return m_serviceMenu; } +bool StandardServiceRoot::loadMessagesForItem(RootItem *item, QSqlTableModel *model) { + if (item->kind() == RootItemKind::Bin) { + model->setFilter(QSL("is_deleted = 1 AND is_pdeleted = 0")); + } + else { + QList children = item->getSubTreeFeeds(); + QStringList stringy_ids; + + foreach (Feed *child, children) { + stringy_ids.append(QString::number(child->id())); + } + + QString filter_clause = stringy_ids.join(QSL(", ")); + + model->setFilter(QString(QSL("feed IN (%1) AND is_deleted = 0")).arg(filter_clause)); + qDebug("Loading messages from feeds: %s.", qPrintable(filter_clause)); + } + + return true; +} + void StandardServiceRoot::assembleCategories(CategoryAssignment categories) { QHash assignments; assignments.insert(NO_PARENT_CATEGORY, this); diff --git a/src/services/standard/standardserviceroot.h b/src/services/standard/standardserviceroot.h index 5cc7ab55b..75fbd12b2 100755 --- a/src/services/standard/standardserviceroot.h +++ b/src/services/standard/standardserviceroot.h @@ -57,6 +57,9 @@ class StandardServiceRoot : public ServiceRoot { // Return menu to be shown in "Services -> service" menu. QList serviceMenu(); + // Message stuff. + bool loadMessagesForItem(RootItem *item, QSqlTableModel *model); + // Returns all standard categories which are lying under given root node. // This does NOT include the root node even if the node is category. QHash categoriesForItem(RootItem *root);