Added check of how many items have to be read.

Leonardo Robol [2011-10-24 17:02]
Added check of how many items have to be read.
Filename
Larss.pro
include/feedproxymodel.h
include/rssparser.h
larss/feedproxymodel.cpp
larss/mainwindow.cpp
larss/rssparser.cpp
diff --git a/Larss.pro b/Larss.pro
index 35dafc4..95761ad 100644
--- a/Larss.pro
+++ b/Larss.pro
@@ -16,14 +16,16 @@ SOURCES += larss/main.cpp\
     larss/rssparser.cpp \
     larss/feedpoller.cpp \
     larss/editfeeddialog.cpp \
-    larss/editcategorydialog.cpp
+    larss/editcategorydialog.cpp \
+    larss/feedproxymodel.cpp

 HEADERS  += include/mainwindow.h \
     include/feedmodel.h \
     include/rssparser.h \
     include/feedpoller.h \
     include/editfeeddialog.h \
-    include/editcategorydialog.h
+    include/editcategorydialog.h \
+    include/feedproxymodel.h

 FORMS    += ui/mainwindow.ui \
     ui/editfeeddialog.ui \
diff --git a/include/feedproxymodel.h b/include/feedproxymodel.h
new file mode 100644
index 0000000..ee4b5f4
--- /dev/null
+++ b/include/feedproxymodel.h
@@ -0,0 +1,30 @@
+#ifndef FEEDPROXYMODEL_H
+#define FEEDPROXYMODEL_H
+
+#include <QObject>
+#include <QProxyModel>
+#include "rssparser.h"
+
+namespace Larss {
+
+    class FeedProxyModel : public QProxyModel
+    {
+        Q_OBJECT
+    public:
+        explicit FeedProxyModel(QObject *parent = 0);
+        QVariant data (const QModelIndex &index, int role) const;
+        void setParser (RssParser * parser);
+
+    private:
+        RssParser *parser;
+
+    signals:
+
+    public slots:
+        void onRssParserDataChanged (QModelIndex index, QModelIndex index2);
+
+    };
+
+}
+
+#endif // FEEDPROXYMODEL_H
diff --git a/include/rssparser.h b/include/rssparser.h
index 1070b43..a240e38 100644
--- a/include/rssparser.h
+++ b/include/rssparser.h
@@ -52,6 +52,12 @@ namespace Larss {
         QString getTitle (const QModelIndex& index);

         /**
+         * @brief Get the number of unread post for the feed pointed by
+         * the given QModelIndex.
+         */
+        quint32 getUnreadCount (const QModelIndex& index);
+
+        /**
          * @brief Set the read status on a news.
          */
         void setReadStatus (const QModelIndex& index, bool read);
diff --git a/larss/feedproxymodel.cpp b/larss/feedproxymodel.cpp
new file mode 100644
index 0000000..db8f21e
--- /dev/null
+++ b/larss/feedproxymodel.cpp
@@ -0,0 +1,60 @@
+#include "include/feedproxymodel.h"
+#include <QFont>
+#include <QSqlRecord>
+
+using namespace Larss;
+
+FeedProxyModel::FeedProxyModel(QObject *parent) :
+    QProxyModel(parent)
+{
+
+}
+
+QVariant
+FeedProxyModel::data(const QModelIndex &index, int role) const
+{
+    // Check if this is  a feed, and in that case check the number of unread items.
+    if (index.internalId() > FEEDMODEL_MAX_CATEGORIES)
+    {
+        if (role == Qt::DisplayRole)
+        {
+            QString feedName = this->model()->data(index, role).toString();
+            quint32 unreadCount = parser->getUnreadCount(index);
+            if (unreadCount > 0)
+                return QString("%1 (%2)").arg(feedName).arg(unreadCount);
+            else
+                return feedName;
+        }
+        else if (role == Qt::FontRole)
+        {
+            quint32 unreadCount = parser->getUnreadCount(index);
+            QFont font = this->model()->data(index, role).toString();
+            if (unreadCount > 0)
+                font.setBold(true);
+            return font;
+        }
+
+        return this->model()->data(index, role);
+    }
+    else
+        return this->model()->data(index, role);
+}
+
+void
+FeedProxyModel::setParser(RssParser *parser)
+{
+    this->parser = parser;
+    parser->connect(parser, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+                    this, SLOT(onRssParserDataChanged(QModelIndex,QModelIndex)));
+}
+
+void
+FeedProxyModel::onRssParserDataChanged(QModelIndex index, QModelIndex index2)
+{
+    Q_UNUSED(index);
+    Q_UNUSED(index2);
+    // We need to get the feed where the news is, so we can emit dataChanged
+    // for it. For now we simply propagate the change.
+    QModelIndex rootIndex = this->model()->index(1, 1, QModelIndex());
+    dataChanged(rootIndex, rootIndex);
+}
diff --git a/larss/mainwindow.cpp b/larss/mainwindow.cpp
index 8e0610a..5ad4a06 100644
--- a/larss/mainwindow.cpp
+++ b/larss/mainwindow.cpp
@@ -2,6 +2,7 @@
 #include "ui_mainwindow.h"
 #include "editfeeddialog.h"
 #include "editcategorydialog.h"
+#include "feedproxymodel.h"
 #include <QDebug>
 #include <QtGui>

@@ -24,10 +25,15 @@ MainWindow::MainWindow(QWidget *parent) :

     // Load feedModel that will wrap the SQLite database
     feedModel = new FeedModel(db, this);
-    ui->feedTreeView->setModel(feedModel);
+    rssParser = new RssParser(db, feedModel, this);
+
+    FeedProxyModel *proxyModel = new FeedProxyModel(this);
+    proxyModel->setModel(feedModel);
+    proxyModel->setParser(rssParser);
+
+    ui->feedTreeView->setModel(proxyModel);

     // Load the RSSParser, hiding the unnecessary columns
-    rssParser = new RssParser(db, feedModel, this);
     ui->newsTableView->setModel(rssParser);
     ui->newsTableView->setSelectionBehavior(QAbstractItemView::SelectRows);
     ui->newsTableView->setColumnHidden(0, true); // ID
diff --git a/larss/rssparser.cpp b/larss/rssparser.cpp
index 44eb20b..f6f84ac 100644
--- a/larss/rssparser.cpp
+++ b/larss/rssparser.cpp
@@ -115,6 +115,7 @@ Larss::RssParser::setReadStatus(const QModelIndex& index, bool read)
     setData(read_index, read ? 1 : 0);
     if (!submitAll())
         qDebug() << "Error while setting the read flag";
+    dataChanged (index, index);
 }

 quint64
@@ -141,6 +142,25 @@ Larss::RssParser::getTitle(const QModelIndex &index)
     return data(title_index, Qt::DisplayRole).toString();
 }

+quint32
+Larss::RssParser::getUnreadCount(const QModelIndex &index)
+{
+    quint64 feedId = getFeed(index);
+    QSqlQuery query(db);
+    query.prepare ("SELECT id from news WHERE read=0 AND feed=:feed;");
+    query.bindValue("feed", feedId);
+    if (query.exec())
+    {
+        quint32 count = 1;
+        if (!query.first())
+            return 0;
+        while (query.next())
+            count++;
+        return count;
+    }
+    return 0;
+}
+
 void
 Larss::RssParser::selectActiveFeed(quint64 feed_id)
 {
ViewGit