From 607a53adc5b713d89e5425835208bf3e6d8c3662 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Wed, 18 Dec 2013 08:51:35 +0100 Subject: [PATCH] Dynamic unread/all message counting. --- src/core/feedsmodel.cpp | 9 +++++- src/core/feedsmodel.h | 5 ++++ src/core/feedsmodelfeed.cpp | 44 +++++++++++++++++++++++++++-- src/core/feedsmodelfeed.h | 12 +++++--- src/core/feedsmodelstandardfeed.cpp | 21 ++++++++++++++ src/core/messagesmodel.cpp | 13 ++++++--- src/core/messagesmodel.h | 2 ++ src/gui/feedmessageviewer.cpp | 2 ++ src/gui/feedsview.cpp | 12 ++++++++ src/gui/feedsview.h | 4 +++ src/gui/messagesview.cpp | 6 +--- src/gui/messagesview.h | 6 ++-- 12 files changed, 118 insertions(+), 18 deletions(-) diff --git a/src/core/feedsmodel.cpp b/src/core/feedsmodel.cpp index 5ee2c295f..e5a7f5ee7 100644 --- a/src/core/feedsmodel.cpp +++ b/src/core/feedsmodel.cpp @@ -173,6 +173,11 @@ FeedsModelRootItem *FeedsModel::itemForIndex(const QModelIndex &index) { } } +void FeedsModel::changeLayout() { + emit layoutAboutToBeChanged(); + emit layoutChanged(); +} + void FeedsModel::loadFromDatabase() { // Delete all childs of the root node and clear them from the memory. qDeleteAll(m_rootItem->childItems()); @@ -225,7 +230,9 @@ void FeedsModel::loadFromDatabase() { switch (type) { case FeedsModelFeed::StandardAtom: case FeedsModelFeed::StandardRdf: - case FeedsModelFeed::StandardRss: { + case FeedsModelFeed::StandardRss0X: + case FeedsModelFeed::StandardRss1X: + case FeedsModelFeed::StandardRss2X: { FeedAssignmentItem pair; pair.first = query_feeds.value(FDS_DB_CATEGORY_INDEX).toInt(); pair.second = FeedsModelStandardFeed::loadFromRecord(query_feeds.record()); diff --git a/src/core/feedsmodel.h b/src/core/feedsmodel.h index 6a303f198..e64ecd2e8 100644 --- a/src/core/feedsmodel.h +++ b/src/core/feedsmodel.h @@ -49,6 +49,11 @@ class FeedsModel : public QAbstractItemModel { // null if index is invalid. FeedsModelRootItem *itemForIndex(const QModelIndex &index); + public slots: + // Signals that ALL data of this model need + // to be reloaded by ALL attached views. + void changeLayout(); + protected: // Loads feed/categories from the database. void loadFromDatabase(); diff --git a/src/core/feedsmodelfeed.cpp b/src/core/feedsmodelfeed.cpp index 87246d04f..47e35227b 100755 --- a/src/core/feedsmodelfeed.cpp +++ b/src/core/feedsmodelfeed.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "core/databasefactory.h" #include "core/feedsmodelfeed.h" @@ -43,6 +44,45 @@ void FeedsModelFeed::setType(const Type &type) { m_type = type; } -void FeedsModelFeed::updateCounts() { - //QSqlDatabase database = DatabaseFactory::getInstance()-> +QString FeedsModelFeed::typeToString(FeedsModelFeed::Type type) { + switch (type) { + case StandardAtom: + return QObject::tr("ATOM 1.0"); + + case StandardRdf: + return QObject::tr("RDF 1.0"); + + case StandardRss0X: + return QObject::tr("RSS 0.X"); + + case StandardRss1X: + return QObject::tr("RSS 1.X"); + + case StandardRss2X: + default: + return QObject::tr("RSS 2.X"); + } } + +void FeedsModelFeed::updateCounts(bool including_total_count) { + QSqlDatabase database = DatabaseFactory::getInstance()->addConnection("FeedsModelFeed"); + + if (including_total_count) { + // Obtain count of all messages. + QSqlQuery query_all = database.exec(QString("SELECT count() FROM messages " + "WHERE feed = %1 AND deleted = 0;").arg(id())); + if (query_all.next()){ + m_totalCount = query_all.value(0).toInt(); + } + } + + // Obtain count of unread messages. + QSqlQuery query_unread = database.exec(QString("SELECT count() FROM messages " + "WHERE feed = %1 AND deleted = 0 AND read = 0;").arg(id())); + if (query_unread.next()) { + m_unreadCount = query_unread.value(0).toInt(); + } +} + + + diff --git a/src/core/feedsmodelfeed.h b/src/core/feedsmodelfeed.h index 465510783..ffa56ae6a 100755 --- a/src/core/feedsmodelfeed.h +++ b/src/core/feedsmodelfeed.h @@ -11,9 +11,11 @@ class FeedsModelFeed : public FeedsModelRootItem { // Describes possible types of feeds. // NOTE: This is equivalent to attribute Feeds(type). enum Type { - StandardRss = 0, - StandardRdf = 1, - StandardAtom = 2 + StandardRss0X = 0, + StandardRss1X = 1, + StandardRss2X = 2, + StandardRdf = 3, + StandardAtom = 4 }; // Constructors and destructors. @@ -36,9 +38,11 @@ class FeedsModelFeed : public FeedsModelRootItem { Type type() const; void setType(const Type &type); + static QString typeToString(Type type); + public slots: // Updates counts of all/unread messages for this feed. - void updateCounts(); + void updateCounts(bool including_total_count = true); protected: Type m_type; diff --git a/src/core/feedsmodelstandardfeed.cpp b/src/core/feedsmodelstandardfeed.cpp index 6a3f112f4..3d3f8c5fb 100755 --- a/src/core/feedsmodelstandardfeed.cpp +++ b/src/core/feedsmodelstandardfeed.cpp @@ -30,6 +30,7 @@ FeedsModelStandardFeed *FeedsModelStandardFeed::loadFromRecord(const QSqlRecord feed->setEncoding(record.value(FDS_DB_ENCODING_INDEX).toString()); feed->setUrl(record.value(FDS_DB_URL_INDEX).toString()); feed->setLanguage(record.value(FDS_DB_LANGUAGE_INDEX).toString()); + feed->updateCounts(); return feed; } @@ -85,6 +86,26 @@ QVariant FeedsModelStandardFeed::data(int column, int role) const { m_icon : QVariant(); + case Qt::ToolTipRole: + if (column == FDS_MODEL_TITLE_INDEX) { + return QObject::tr("%1\n\n" + "Feed type: %2\n" + "URL: %3\n" + "Encoding: %4\n" + "Language: %5").arg(m_title, + FeedsModelFeed::typeToString(m_type), + m_url, + m_encoding, + m_language.isEmpty() ? + "-" : + m_language); } + else if (column == FDS_MODEL_COUNTS_INDEX) { + return QObject::tr("%n unread message(s).", "", countOfUnreadMessages()); + } + else { + return QVariant(); + } + case Qt::TextAlignmentRole: if (column == FDS_MODEL_COUNTS_INDEX) { return Qt::AlignCenter; diff --git a/src/core/messagesmodel.cpp b/src/core/messagesmodel.cpp index b57ad1198..5b15623ef 100644 --- a/src/core/messagesmodel.cpp +++ b/src/core/messagesmodel.cpp @@ -55,11 +55,16 @@ void MessagesModel::setupFonts() { m_boldFont.setBold(true); } -void MessagesModel::loadMessages(const QList feed_ids) { - // Conversion of parameter. - m_currentFeeds = feed_ids; +QList MessagesModel::currentFeeds() const { + return m_currentFeeds; +} - setFilter(QString("feed IN (%1) AND deleted = 0").arg(textualFeeds().join(", "))); + +void MessagesModel::loadMessages(const QList feed_ids) { + // Conversion of parameter. + m_currentFeeds = feed_ids; + + setFilter(QString("feed IN (%1) AND deleted = 0").arg(textualFeeds().join(", "))); select(); fetchAll(); } diff --git a/src/core/messagesmodel.h b/src/core/messagesmodel.h index fc52677ae..6e7ab4751 100644 --- a/src/core/messagesmodel.h +++ b/src/core/messagesmodel.h @@ -44,6 +44,8 @@ class MessagesModel : public QSqlTableModel { Message messageAt(int row_index) const; int messageId(int row_index) const; + QList currentFeeds() const; + public slots: // To disable persistent changes submissions. bool submitAll(); diff --git a/src/gui/feedmessageviewer.cpp b/src/gui/feedmessageviewer.cpp index 5ff229989..4bacd8820 100644 --- a/src/gui/feedmessageviewer.cpp +++ b/src/gui/feedmessageviewer.cpp @@ -42,6 +42,8 @@ void FeedMessageViewer::createConnections() { SLOT(addLinkedBrowser(QString))); connect(m_feedsView, SIGNAL(feedsSelected(QList)), m_messagesView, SLOT(loadFeeds(QList))); + connect(m_messagesView, SIGNAL(feedCountsChanged()), + m_feedsView, SLOT(updateCountsOfSelectedFeeds())); // Toolbar forwardings. connect(FormMain::getInstance()->m_ui->m_actionSwitchImportanceOfSelectedMessages, diff --git a/src/gui/feedsview.cpp b/src/gui/feedsview.cpp index 571a0800b..19b407658 100644 --- a/src/gui/feedsview.cpp +++ b/src/gui/feedsview.cpp @@ -25,6 +25,18 @@ void FeedsView::setSortingEnabled(bool enable) { header()->setSortIndicatorShown(false); } +void FeedsView::updateCountsOfSelectedFeeds() { + QModelIndexList selected_rows = selectionModel()->selectedRows(); + QModelIndexList mapped_rows = m_proxyModel->mapListToSource(selected_rows); + QList feeds = m_sourceModel->feedsForIndexes(mapped_rows); + + foreach (FeedsModelFeed *feed, feeds) { + feed->updateCounts(); + } + + m_sourceModel->changeLayout(); +} + void FeedsView::setupAppearance() { #if QT_VERSION >= 0x050000 // Setup column resize strategies. diff --git a/src/gui/feedsview.h b/src/gui/feedsview.h index 1eaeff909..a759bb053 100644 --- a/src/gui/feedsview.h +++ b/src/gui/feedsview.h @@ -17,6 +17,10 @@ class FeedsView : public QTreeView { void setSortingEnabled(bool enable); + public slots: + // Reloads count for selected feeds. + void updateCountsOfSelectedFeeds(); + protected: void setupAppearance(); void selectionChanged(const QItemSelection &selected, diff --git a/src/gui/messagesview.cpp b/src/gui/messagesview.cpp index f45faee7e..acc360edd 100644 --- a/src/gui/messagesview.cpp +++ b/src/gui/messagesview.cpp @@ -95,11 +95,6 @@ void MessagesView::setupAppearance() { setSelectionMode(QAbstractItemView::ExtendedSelection); } -void MessagesView::selectionChanged(const QItemSelection &selected, - const QItemSelection &deselected) { - QTreeView::selectionChanged(selected, deselected); -} - void MessagesView::keyPressEvent(QKeyEvent *event) { QTreeView::keyPressEvent(event); @@ -175,6 +170,7 @@ void MessagesView::currentChanged(const QModelIndex ¤t, } emit currentMessageChanged(m_sourceModel->messageAt(mapped_current_index.row())); + emit feedCountsChanged(); } else { emit currentMessageRemoved(); diff --git a/src/gui/messagesview.h b/src/gui/messagesview.h index 7ba07b2ef..6358a4782 100755 --- a/src/gui/messagesview.h +++ b/src/gui/messagesview.h @@ -53,8 +53,6 @@ class MessagesView : public QTreeView { void keyPressEvent(QKeyEvent *event); void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); - void selectionChanged(const QItemSelection &selected, - const QItemSelection &deselected); signals: void openLinkMessageNewTabRequested(const QString &link); @@ -62,6 +60,10 @@ class MessagesView : public QTreeView { void currentMessageChanged(const Message &message); void currentMessageRemoved(); + // Emitted if counts of unread/total messages has changed + // because of user interaction with list of messages. + void feedCountsChanged(); + private: QMenu *m_contextMenu;