From fab7d1e8b1005dae4be81531a55b5cf3e72501db Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Fri, 20 Nov 2015 09:52:29 +0100 Subject: [PATCH] Draconic changes for messages, some methods added to interfaces, very experimental state now. --- src/core/feedsmodel.cpp | 19 +++- src/core/feedsmodel.h | 6 ++ src/core/feedsproxymodel.cpp | 26 ++++-- src/core/feedsproxymodel.h | 8 +- src/core/messagesmodel.cpp | 86 ++++++++++++------- src/core/messagesmodel.h | 11 +-- src/core/messagesproxymodel.h | 3 +- src/core/rootitem.h | 9 +- src/gui/feedmessageviewer.cpp | 8 +- src/gui/feedsview.cpp | 17 ++-- src/gui/feedsview.h | 2 - src/gui/messagesview.cpp | 6 +- src/gui/messagesview.h | 1 - src/miscellaneous/application.cpp | 3 +- src/services/abstract/serviceroot.cpp | 4 + src/services/abstract/serviceroot.h | 44 ++++++++++ src/services/standard/standardfeed.cpp | 2 +- src/services/standard/standardserviceroot.cpp | 37 ++++++++ src/services/standard/standardserviceroot.h | 6 ++ src/services/tt-rss/ttrssserviceroot.cpp | 1 - src/services/tt-rss/ttrssserviceroot.h | 16 ++++ 21 files changed, 231 insertions(+), 84 deletions(-) mode change 100644 => 100755 src/core/messagesproxymodel.h diff --git a/src/core/feedsmodel.cpp b/src/core/feedsmodel.cpp index e5ec5416d..28410b974 100755 --- a/src/core/feedsmodel.cpp +++ b/src/core/feedsmodel.cpp @@ -395,6 +395,11 @@ void FeedsModel::reloadChangedItem(RootItem *item) { reloadChangedLayout(QModelIndexList() << index_item); } +void FeedsModel::onItemDataChanged(RootItem *item) { + reloadChangedItem(item); + notifyWithCounts(); +} + QStringList FeedsModel::textualFeedIds(const QList &feeds) { QStringList stringy_ids; stringy_ids.reserve(feeds.size()); @@ -411,6 +416,17 @@ void FeedsModel::reloadWholeLayout() { emit layoutChanged(); } +bool FeedsModel::addServiceAccount(ServiceRoot *root) { + m_rootItem->appendChild(root); + + // Connect. + connect(root, SIGNAL(readFeedsFilterInvalidationRequested()), this, SIGNAL(readFeedsFilterInvalidationRequested())); + connect(root, SIGNAL(dataChanged(RootItem*)), this, SLOT(onItemDataChanged(RootItem*))); + + root->start(); + return true; +} + void FeedsModel::loadActivatedServiceAccounts() { // Iterate all globally available feed "service plugins". foreach (ServiceEntryPoint *entry_point, qApp->feedServices()) { @@ -418,8 +434,7 @@ void FeedsModel::loadActivatedServiceAccounts() { QList roots = entry_point->initializeSubtree(this); foreach (ServiceRoot *root, roots) { - m_rootItem->appendChild(root); - root->start(); + addServiceAccount(root); } } } diff --git a/src/core/feedsmodel.h b/src/core/feedsmodel.h index 48d612b39..8e6adc4ee 100755 --- a/src/core/feedsmodel.h +++ b/src/core/feedsmodel.h @@ -130,6 +130,8 @@ class FeedsModel : public QAbstractItemModel { // Does necessary job before quitting this component. void quit(); + bool addServiceAccount(ServiceRoot *root); + public slots: // Feeds operations. bool markItemRead(RootItem *item, RootItem::ReadStatus read); @@ -154,10 +156,14 @@ class FeedsModel : public QAbstractItemModel { } private slots: + void onItemDataChanged(RootItem *item); + // Is executed when next auto-update round could be done. void executeNextAutoUpdate(); signals: + void readFeedsFilterInvalidationRequested(); + // Emitted when model requests update of some feeds. void feedsUpdateRequested(const QList feeds); diff --git a/src/core/feedsproxymodel.cpp b/src/core/feedsproxymodel.cpp index d2b6fbd9f..a2dd06225 100755 --- a/src/core/feedsproxymodel.cpp +++ b/src/core/feedsproxymodel.cpp @@ -24,6 +24,8 @@ #include "services/standard/standardcategory.h" #include "services/standard/standardfeed.h" +#include + FeedsProxyModel::FeedsProxyModel(QObject *parent) : QSortFilterProxyModel(parent), m_selectedItem(NULL), m_showUnreadOnly(false) { @@ -37,6 +39,8 @@ FeedsProxyModel::FeedsProxyModel(QObject *parent) setFilterRole(Qt::EditRole); setDynamicSortFilter(false); setSourceModel(m_sourceModel); + + connect(m_sourceModel, SIGNAL(readFeedsFilterInvalidationRequested()), this, SLOT(invalidateReadFeedsFilter())); } FeedsProxyModel::~FeedsProxyModel() { @@ -45,18 +49,18 @@ FeedsProxyModel::~FeedsProxyModel() { QModelIndexList FeedsProxyModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const { QModelIndexList result; - uint matchType = flags & 0x0F; + uint match_type = flags & 0x0F; Qt::CaseSensitivity cs = Qt::CaseInsensitive; bool recurse = flags & Qt::MatchRecursive; bool wrap = flags & Qt::MatchWrap; - bool allHits = (hits == -1); + bool all_hits = (hits == -1); QString entered_text; QModelIndex p = parent(start); int from = start.row(); int to = rowCount(p); for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) { - for (int r = from; (r < to) && (allHits || result.count() < hits); ++r) { + for (int r = from; (r < to) && (all_hits || result.count() < hits); ++r) { QModelIndex idx = index(r, start.column(), p); if (!idx.isValid()) { @@ -64,10 +68,10 @@ QModelIndexList FeedsProxyModel::match(const QModelIndex &start, int role, const } QModelIndex mapped_idx = mapToSource(idx); - QVariant item_value = m_sourceModel->data(m_sourceModel->index(mapped_idx.row(), FDS_MODEL_TITLE_INDEX, mapped_idx.parent()), role); + QVariant item_value = m_sourceModel->itemForIndex(mapped_idx)->title(); // QVariant based matching. - if (matchType == Qt::MatchExactly) { + if (match_type == Qt::MatchExactly) { if (value == item_value) { result.append(idx); } @@ -80,7 +84,7 @@ QModelIndexList FeedsProxyModel::match(const QModelIndex &start, int role, const QString item_text = item_value.toString(); - switch (matchType) { + switch (match_type) { case Qt::MatchRegExp: if (QRegExp(entered_text, cs).exactMatch(item_text)) { result.append(idx); @@ -121,7 +125,7 @@ QModelIndexList FeedsProxyModel::match(const QModelIndex &start, int role, const } if (recurse && hasChildren(idx)) { - result += match(index(0, idx.column(), idx), role, (entered_text.isEmpty() ? value : entered_text), (allHits ? -1 : hits - result.count()), flags); + result += match(index(0, idx.column(), idx), role, (entered_text.isEmpty() ? value : entered_text), (all_hits ? -1 : hits - result.count()), flags); } } @@ -218,6 +222,14 @@ bool FeedsProxyModel::showUnreadOnly() const { return m_showUnreadOnly; } +void FeedsProxyModel::invalidateReadFeedsFilter(bool set_new_value, bool show_unread_only) { + if (set_new_value) { + setShowUnreadOnly(show_unread_only); + } + + QTimer::singleShot(0, this, SLOT(invalidateFilter())); +} + void FeedsProxyModel::setShowUnreadOnly(bool show_unread_only) { m_showUnreadOnly = show_unread_only; qApp->settings()->setValue(GROUP(Feeds), Feeds::ShowOnlyUnreadFeeds, show_unread_only); diff --git a/src/core/feedsproxymodel.h b/src/core/feedsproxymodel.h index aa000b94b..b8c1a6fef 100755 --- a/src/core/feedsproxymodel.h +++ b/src/core/feedsproxymodel.h @@ -38,6 +38,8 @@ class FeedsProxyModel : public QSortFilterProxyModel { return m_sourceModel; } + // Returns index list of items which "match" given value. + // Used for finding items according to entered title text. QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const; // Maps list of indexes. @@ -50,14 +52,16 @@ class FeedsProxyModel : public QSortFilterProxyModel { void setSelectedItem(RootItem *selected_item); public slots: + void invalidateReadFeedsFilter(bool set_new_value = false, bool show_unread_only = false); + + private slots: void invalidateFilter(); - protected: + private: // Compares two rows of data. bool lessThan(const QModelIndex &left, const QModelIndex &right) const; bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; - private: // Source model pointer. FeedsModel *m_sourceModel; diff --git a/src/core/messagesmodel.cpp b/src/core/messagesmodel.cpp index 60f64744c..1462aaea6 100755 --- a/src/core/messagesmodel.cpp +++ b/src/core/messagesmodel.cpp @@ -240,13 +240,20 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const { } } -bool MessagesModel::setMessageRead(int row_index, int read) { +bool MessagesModel::setMessageRead(int row_index, RootItem::ReadStatus read) { if (data(row_index, MSG_DB_READ_INDEX, Qt::EditRole).toInt() == read) { // Read status is the same is the one currently set. // In that case, no extra work is needed. return true; } + int message_id = messageId(row_index); + + if (!m_selectedItem->getParentServiceRoot()->onBeforeSetMessagesRead(m_selectedItem, QList() << message_id, read)) { + // Cannot change read status of the item. Abort. + return false; + } + QSqlDatabase db_handle = database(); if (!db_handle.transaction()) { @@ -265,7 +272,6 @@ bool MessagesModel::setMessageRead(int row_index, int read) { return false; } - int message_id; QSqlQuery query_read_msg(db_handle); query_read_msg.setForwardOnly(true); @@ -276,22 +282,15 @@ bool MessagesModel::setMessageRead(int row_index, int read) { return false; } - // Rewrite the actual data in the database itself. - message_id = messageId(row_index); query_read_msg.bindValue(QSL(":id"), message_id); query_read_msg.bindValue(QSL(":read"), read); query_read_msg.exec(); // Commit changes. if (db_handle.commit()) { - // If commit succeeded, then emit changes, so that view - // can reflect. + // If commit succeeded, then emit changes, so that view can reflect. emit dataChanged(index(row_index, 0), index(row_index, columnCount() - 1)); - emit messageCountsChanged(); - - // TODO: counts changed - //emit messageCountsChanged(m_selectedItem.mode(), false, false); - return true; + return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, QList() << message_id, read); } else { return db_handle.rollback();; @@ -299,6 +298,16 @@ bool MessagesModel::setMessageRead(int row_index, int read) { } bool MessagesModel::switchMessageImportance(int row_index) { + QModelIndex target_index = index(row_index, MSG_DB_IMPORTANT_INDEX); + RootItem::Importance current_importance = (RootItem::Importance) data(target_index, Qt::EditRole).toInt(); + int message_id = messageId(row_index); + + if (!m_selectedItem->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_selectedItem, + message_id, + current_importance)) { + return false; + } + QSqlDatabase db_handle = database(); if (!db_handle.transaction()) { @@ -306,11 +315,10 @@ bool MessagesModel::switchMessageImportance(int row_index) { return false; } - QModelIndex target_index = index(row_index, MSG_DB_IMPORTANT_INDEX); - int current_importance = data(target_index, Qt::EditRole).toInt(); - // Rewrite "visible" data in the model. - bool working_change = current_importance == 1 ? setData(target_index, 0) : setData(target_index, 1); + bool working_change = current_importance == RootItem::Important ? + setData(target_index, RootItem::NotImportant) : + setData(target_index, RootItem::Important); if (!working_change) { // If rewriting in the model failed, then cancel all actions. @@ -320,7 +328,6 @@ bool MessagesModel::switchMessageImportance(int row_index) { return false; } - int message_id; QSqlQuery query_importance_msg(db_handle); query_importance_msg.setForwardOnly(true); @@ -331,7 +338,6 @@ bool MessagesModel::switchMessageImportance(int row_index) { return false; } - message_id = messageId(row_index); query_importance_msg.bindValue(QSL(":id"), message_id); query_importance_msg.bindValue(QSL(":important"), current_importance == 1 ? 0 : 1); query_importance_msg.exec(); @@ -341,7 +347,8 @@ bool MessagesModel::switchMessageImportance(int row_index) { // If commit succeeded, then emit changes, so that view // can reflect. emit dataChanged(index(row_index, 0), index(row_index, columnCount() - 1)); - return true; + return m_selectedItem->getParentServiceRoot()->onAfterSwitchMessageImportance(m_selectedItem, message_id, + current_importance); } else { return db_handle.rollback(); @@ -352,12 +359,16 @@ bool MessagesModel::switchBatchMessageImportance(const QModelIndexList &messages QSqlDatabase db_handle = database(); QSqlQuery query_read_msg(db_handle); QStringList message_ids; + QList message_ids_num; query_read_msg.setForwardOnly(true); // Obtain IDs of all desired messages. foreach (const QModelIndex &message, messages) { - message_ids.append(QString::number(messageId(message.row()))); + int message_id = messageId(message.row()); + + message_ids_num.append(message_id); + message_ids.append(QString::number(message_id)); } if (query_read_msg.exec(QString(QSL("UPDATE Messages SET is_important = NOT is_important WHERE id IN (%1);")) @@ -376,12 +387,16 @@ bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages, int QSqlDatabase db_handle = database(); QSqlQuery query_read_msg(db_handle); QStringList message_ids; + QList message_ids_num; query_read_msg.setForwardOnly(true); // Obtain IDs of all desired messages. foreach (const QModelIndex &message, messages) { - message_ids.append(QString::number(messageId(message.row()))); + int message_id = messageId(message.row()); + + message_ids_num.append(message_id); + message_ids.append(QString::number(message_id)); } QString sql_delete_query; @@ -400,7 +415,9 @@ bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages, int if (query_read_msg.exec(sql_delete_query)) { fetchAllData(); - emit messageCountsChanged(); + + + //emit messageCountsChanged(); // TODO: counts changed //emit messageCountsChanged(m_selectedItem.mode(), true, false); @@ -412,27 +429,32 @@ bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages, int } bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, RootItem::ReadStatus read) { - QSqlDatabase db_handle = database(); - QSqlQuery query_read_msg(db_handle); QStringList message_ids; - - query_read_msg.setForwardOnly(true); + QList message_ids_num; // Obtain IDs of all desired messages. foreach (const QModelIndex &message, messages) { - message_ids.append(QString::number(messageId(message.row()))); + int message_id = messageId(message.row()); + + message_ids_num.append(message_id); + message_ids.append(QString::number(message_id)); } + if (!m_selectedItem->getParentServiceRoot()->onBeforeSetMessagesRead(m_selectedItem, message_ids_num, read)) { + return false; + } + + QSqlDatabase db_handle = database(); + QSqlQuery query_read_msg(db_handle); + + query_read_msg.setForwardOnly(true); + if (query_read_msg.exec(QString(QSL("UPDATE Messages SET is_read = %2 WHERE id IN (%1);")) .arg(message_ids.join(QSL(", ")), read == RootItem::Read ? QSL("1") : QSL("0")))) { fetchAllData(); - emit messageCountsChanged(); - - // TODO: counts changed - //emit messageCountsChanged(m_selectedItem.mode(), false, false); - return true; + return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, message_ids_num, read); } else { return false; @@ -456,7 +478,7 @@ bool MessagesModel::setBatchMessagesRestored(const QModelIndexList &messages) { if (query_read_msg.exec(sql_delete_query)) { fetchAllData(); - emit messageCountsChanged(); + //emit messageCountsChanged(); // TODO: counts changed //emit messageCountsChanged(m_selectedItem.mode(), true, true); diff --git a/src/core/messagesmodel.h b/src/core/messagesmodel.h index f966a9bb2..a56c6d20c 100755 --- a/src/core/messagesmodel.h +++ b/src/core/messagesmodel.h @@ -62,7 +62,7 @@ class MessagesModel : public QSqlTableModel { // NOTE: Model is NOT reset after one of these methods are applied // but changes ARE written to the database. bool switchMessageImportance(int row_index); - bool setMessageRead(int row_index, int read); + bool setMessageRead(int row_index, RootItem::ReadStatus read); // BATCH messages manipulators. // NOTE: These methods are used for changing of attributes of @@ -83,22 +83,13 @@ class MessagesModel : public QSqlTableModel { // Loads messages of given feeds. void loadMessages(RootItem *item); - signals: - // Emitted if some persistent change is made which affects count of "unread/all" messages. - void messageCountsChanged(); - private slots: // To disable persistent changes submissions. bool submitAll(); private: - // Sets up header data. void setupHeaderData(); - - // Creates "normal" and "bold" fonts. void setupFonts(); - - // Sets up all icons which are used directly by this model. void setupIcons(); MessageHighlighter m_messageHighlighter; diff --git a/src/core/messagesproxymodel.h b/src/core/messagesproxymodel.h old mode 100644 new mode 100755 index 35d7cef64..2b81ea652 --- a/src/core/messagesproxymodel.h +++ b/src/core/messagesproxymodel.h @@ -43,11 +43,10 @@ class MessagesProxyModel : public QSortFilterProxyModel { // Fix for matching indexes with respect to specifics of the message model. QModelIndexList match(const QModelIndex &start, int role, const QVariant &entered_value, int hits, Qt::MatchFlags flags) const; - protected: + private: // Compares two rows of data. bool lessThan(const QModelIndex &left, const QModelIndex &right) const; - private: // Source model pointer. MessagesModel *m_sourceModel; }; diff --git a/src/core/rootitem.h b/src/core/rootitem.h index d16f3a08a..0f36a8d6e 100755 --- a/src/core/rootitem.h +++ b/src/core/rootitem.h @@ -51,8 +51,13 @@ class RootItem : public QObject { public: enum ReadStatus { - Read, - Unread + Unread = 0, + Read = 1 + }; + + enum Importance { + NotImportant = 0, + Important = 1 }; enum CleanStatus { diff --git a/src/gui/feedmessageviewer.cpp b/src/gui/feedmessageviewer.cpp index 25bd3c04f..55809c6fe 100755 --- a/src/gui/feedmessageviewer.cpp +++ b/src/gui/feedmessageviewer.cpp @@ -25,6 +25,7 @@ #include "miscellaneous/databasecleaner.h" #include "core/messagesproxymodel.h" #include "core/feeddownloader.h" +#include "core/feedsproxymodel.h" #include "services/standard/standardserviceroot.h" #include "services/standard/standardfeed.h" #include "services/standard/standardfeedsimportexportmodel.h" @@ -260,10 +261,10 @@ void FeedMessageViewer::toggleShowOnlyUnreadFeeds() { QAction *origin = qobject_cast(sender()); if (origin == NULL) { - m_feedsView->invalidateReadFeedsFilter(true, false); + m_feedsView->model()->invalidateReadFeedsFilter(true, false); } else { - m_feedsView->invalidateReadFeedsFilter(true, origin->isChecked()); + m_feedsView->model()->invalidateReadFeedsFilter(true, origin->isChecked()); } } @@ -328,8 +329,7 @@ void FeedMessageViewer::createConnections() { 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()), - m_feedsView, SLOT(receiveMessageCountsChange())); + 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 a0f473c1d..a9da540bc 100755 --- a/src/gui/feedsview.cpp +++ b/src/gui/feedsview.cpp @@ -139,14 +139,6 @@ void FeedsView::loadExpandedStates() { } } -void FeedsView::invalidateReadFeedsFilter(bool set_new_value, bool show_unread_only) { - if (set_new_value) { - m_proxyModel->setShowUnreadOnly(show_unread_only); - } - - QTimer::singleShot(0, m_proxyModel, SLOT(invalidateFilter())); -} - void FeedsView::expandCollapseCurrentItem() { if (selectionModel()->selectedRows().size() == 1) { QModelIndex index = selectionModel()->selectedRows().at(0); @@ -210,7 +202,8 @@ void FeedsView::receiveMessageCountsChange() { // 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); @@ -227,7 +220,7 @@ void FeedsView::receiveMessageCountsChange() { updateCountsOfSelectedFeeds(total_msg_count_changed); }*/ - invalidateReadFeedsFilter(); + m_proxyModel->invalidateReadFeedsFilter(); } void FeedsView::editSelectedItem() { @@ -442,7 +435,7 @@ void FeedsView::updateCountsOfParticularFeed(Feed *feed, bool update_total_too) m_sourceModel->reloadChangedLayout(QModelIndexList() << index); } - invalidateReadFeedsFilter(); + m_proxyModel->invalidateReadFeedsFilter(); m_sourceModel->notifyWithCounts(); } @@ -586,7 +579,7 @@ void FeedsView::selectionChanged(const QItemSelection &selected, const QItemSele m_proxyModel->setSelectedItem(selected_item); QTreeView::selectionChanged(selected, deselected); emit itemSelected(selected_item); - invalidateReadFeedsFilter(); + m_proxyModel->invalidateReadFeedsFilter(); } void FeedsView::keyPressEvent(QKeyEvent *event) { diff --git a/src/gui/feedsview.h b/src/gui/feedsview.h index 13b2e6878..bcda5a42c 100755 --- a/src/gui/feedsview.h +++ b/src/gui/feedsview.h @@ -28,7 +28,6 @@ class FeedsProxyModel; class Feed; class Category; -class QTimer; class FeedsView : public QTreeView { Q_OBJECT @@ -65,7 +64,6 @@ class FeedsView : public QTreeView { void loadExpandedStates(); public slots: - void invalidateReadFeedsFilter(bool set_new_value = false, bool show_unread_only = false); void expandCollapseCurrentItem(); // Feed updating. diff --git a/src/gui/messagesview.cpp b/src/gui/messagesview.cpp index 1c224b7d7..64c83b451 100755 --- a/src/gui/messagesview.cpp +++ b/src/gui/messagesview.cpp @@ -192,10 +192,6 @@ void MessagesView::mousePressEvent(QMouseEvent *event) { } } -void MessagesView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { - QTreeView::currentChanged(current, previous); -} - void MessagesView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { QModelIndexList selected_rows = selectionModel()->selectedRows(); QModelIndex current_index = currentIndex(); @@ -209,7 +205,7 @@ void MessagesView::selectionChanged(const QItemSelection &selected, const QItemS if (!m_batchUnreadSwitch) { // Set this message as read only if current item // wasn't changed by "mark selected messages unread" action. - m_sourceModel->setMessageRead(mapped_current_index.row(), 1); + m_sourceModel->setMessageRead(mapped_current_index.row(), RootItem::Read); } emit currentMessagesChanged(QList() << m_sourceModel->messageAt(m_proxyModel->mapToSource(selected_rows.at(0)).row())); diff --git a/src/gui/messagesview.h b/src/gui/messagesview.h index ca94e4f83..e2d854132 100755 --- a/src/gui/messagesview.h +++ b/src/gui/messagesview.h @@ -114,7 +114,6 @@ class MessagesView : public QTreeView { void contextMenuEvent(QContextMenuEvent *event); void mousePressEvent(QMouseEvent *event); void keyPressEvent(QKeyEvent *event); - void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); QMenu *m_contextMenu; diff --git a/src/miscellaneous/application.cpp b/src/miscellaneous/application.cpp index b47449d5b..495d06042 100755 --- a/src/miscellaneous/application.cpp +++ b/src/miscellaneous/application.cpp @@ -170,7 +170,8 @@ 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())); + connect(m_trayIcon, SIGNAL(shown()), + m_mainForm->tabWidget()->feedMessageViewer()->feedsView()->sourceModel(), SLOT(notifyWithCounts())); } return m_trayIcon; diff --git a/src/services/abstract/serviceroot.cpp b/src/services/abstract/serviceroot.cpp index 516331c7d..31b710841 100755 --- a/src/services/abstract/serviceroot.cpp +++ b/src/services/abstract/serviceroot.cpp @@ -30,3 +30,7 @@ ServiceRoot::~ServiceRoot() { FeedsModel *ServiceRoot::feedsModel() const { return m_feedsModel; } + +void ServiceRoot::itemChanged(RootItem *item) { + emit dataChanged(item); +} diff --git a/src/services/abstract/serviceroot.h b/src/services/abstract/serviceroot.h index 6a2cdb5ec..1829cffcc 100755 --- a/src/services/abstract/serviceroot.h +++ b/src/services/abstract/serviceroot.h @@ -20,6 +20,8 @@ #include "core/rootitem.h" +#include "core/message.h" + class FeedsModel; class QAction; @@ -65,9 +67,51 @@ class ServiceRoot : public RootItem { // "loading" dialog přes view a toto zavolat, nasledně signalovat virtual bool loadMessagesForItem(RootItem *item, QSqlTableModel *model) = 0; + // Called BEFORE this read status update is stored in DB, + // when false is returned, change is aborted. + // This is the place to make some other changes like updating + // some ONLINE service or something. + // + // "read" is status which is ABOUT TO BE SET. + virtual bool onBeforeSetMessagesRead(RootItem *selected_item, QList message_db_ids, ReadStatus read) = 0; + + // Called AFTER this read status update is stored in DB, + // when false is returned, change is aborted. + // Here service root should inform (via signals) + // which items are actually changed. + // + // "read" is status which is ABOUT TO BE SET. + virtual bool onAfterSetMessagesRead(RootItem *selected_item, QList message_db_ids, ReadStatus read) = 0; + + // Called BEFORE this importance switch update is stored in DB, + // when false is returned, change is aborted. + // This is the place to make some other changes like updating + // some ONLINE service or something. + // + // "important" is status which is ABOUT TO BE SET. + virtual bool onBeforeSwitchMessageImportance(RootItem *selected_item, int message_db_id, Importance important) = 0; + + // Called AFTER this importance switch update is stored in DB, + // when false is returned, change is aborted. + // Here service root should inform (via signals) + // which items are actually changed. + // + // "important" is status which is ABOUT TO BE SET. + virtual bool onAfterSwitchMessageImportance(RootItem *selected_item, int message_db_id, Importance important) = 0; + // Access to feed model. FeedsModel *feedsModel() const; + // Obvious method to wrap dataChanged(...) signal + // which can be used by items themselves or any + // other component. + void itemChanged(RootItem *item); + + signals: + // Emitted if data in any item belonging to this root are changed. + void dataChanged(RootItem *item); + void readFeedsFilterInvalidationRequested(); + private: FeedsModel *m_feedsModel; }; diff --git a/src/services/standard/standardfeed.cpp b/src/services/standard/standardfeed.cpp index 8dbd7a42f..844bb8d67 100755 --- a/src/services/standard/standardfeed.cpp +++ b/src/services/standard/standardfeed.cpp @@ -215,7 +215,7 @@ void StandardFeed::fetchMetadataForItself() { // Notify the model about fact, that it needs to reload new information about // this item, particularly the icon. - serviceRoot()->feedsModel()->reloadChangedItem(this); + serviceRoot()->itemChanged(this); } else { qApp->showGuiMessage(tr("Metadata not fetched"), diff --git a/src/services/standard/standardserviceroot.cpp b/src/services/standard/standardserviceroot.cpp index 976c01369..b84bbf54f 100755 --- a/src/services/standard/standardserviceroot.cpp +++ b/src/services/standard/standardserviceroot.cpp @@ -540,6 +540,43 @@ bool StandardServiceRoot::loadMessagesForItem(RootItem *item, QSqlTableModel *mo return true; } +bool StandardServiceRoot::onBeforeSetMessagesRead(RootItem *selected_item, QList message_db_ids, RootItem::ReadStatus read) { + Q_UNUSED(message_db_ids) + Q_UNUSED(read) + Q_UNUSED(selected_item) + + return true; +} + +bool StandardServiceRoot::onAfterSetMessagesRead(RootItem *selected_item, QList message_db_ids, RootItem::ReadStatus read) { + Q_UNUSED(message_db_ids) + Q_UNUSED(read) + + selected_item->updateCounts(false); + + emit dataChanged(selected_item); + emit readFeedsFilterInvalidationRequested(); + return true; +} + +bool StandardServiceRoot::onBeforeSwitchMessageImportance(RootItem *selected_item, int message_db_id, + RootItem::Importance important) { + Q_UNUSED(message_db_id) + Q_UNUSED(important) + Q_UNUSED(selected_item) + + return true; +} + +bool StandardServiceRoot::onAfterSwitchMessageImportance(RootItem *selected_item, int message_db_id, + RootItem::Importance important) { + Q_UNUSED(message_db_id) + Q_UNUSED(important) + Q_UNUSED(selected_item) + + 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 75fbd12b2..52ead9463 100755 --- a/src/services/standard/standardserviceroot.h +++ b/src/services/standard/standardserviceroot.h @@ -60,6 +60,12 @@ class StandardServiceRoot : public ServiceRoot { // Message stuff. bool loadMessagesForItem(RootItem *item, QSqlTableModel *model); + bool onBeforeSetMessagesRead(RootItem *selected_item, QList message_db_ids, ReadStatus read); + bool onAfterSetMessagesRead(RootItem *selected_item, QList message_db_ids, ReadStatus read); + + bool onBeforeSwitchMessageImportance(RootItem *selected_item, int message_db_id, Importance important); + bool onAfterSwitchMessageImportance(RootItem *selected_item, int message_db_id, Importance important); + // 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); diff --git a/src/services/tt-rss/ttrssserviceroot.cpp b/src/services/tt-rss/ttrssserviceroot.cpp index e5a9b51a1..8efae22ec 100755 --- a/src/services/tt-rss/ttrssserviceroot.cpp +++ b/src/services/tt-rss/ttrssserviceroot.cpp @@ -64,4 +64,3 @@ QVariant TtRssServiceRoot::data(int column, int role) const { return ServiceRoot::data(column, role); } } - diff --git a/src/services/tt-rss/ttrssserviceroot.h b/src/services/tt-rss/ttrssserviceroot.h index 957517850..61749c1e3 100755 --- a/src/services/tt-rss/ttrssserviceroot.h +++ b/src/services/tt-rss/ttrssserviceroot.h @@ -36,6 +36,22 @@ class TtRssServiceRoot : public ServiceRoot { bool canBeDeleted(); bool editViaGui(); QVariant data(int column, int role) const; + + bool onBeforeSetMessagesRead(RootItem *selected_item, QList message_db_ids, ReadStatus read) { + return false; + } + + bool onAfterSetMessagesRead(RootItem *selected_item, QList message_db_ids, ReadStatus read) { + return false; + } + + bool onBeforeSwitchMessageImportance(RootItem *selected_item, int message_db_id, Importance important) { + return false; + } + + bool onAfterSwitchMessageImportance(RootItem *selected_item, int message_db_id, Importance important) { + return false; + } }; #endif // TTRSSSERVICEROOT_H