Dynamic unread/all message counting.

This commit is contained in:
Martin Rotter 2013-12-18 08:51:35 +01:00
parent e0e58dce96
commit 607a53adc5
12 changed files with 118 additions and 18 deletions

View File

@ -173,6 +173,11 @@ FeedsModelRootItem *FeedsModel::itemForIndex(const QModelIndex &index) {
} }
} }
void FeedsModel::changeLayout() {
emit layoutAboutToBeChanged();
emit layoutChanged();
}
void FeedsModel::loadFromDatabase() { void FeedsModel::loadFromDatabase() {
// Delete all childs of the root node and clear them from the memory. // Delete all childs of the root node and clear them from the memory.
qDeleteAll(m_rootItem->childItems()); qDeleteAll(m_rootItem->childItems());
@ -225,7 +230,9 @@ void FeedsModel::loadFromDatabase() {
switch (type) { switch (type) {
case FeedsModelFeed::StandardAtom: case FeedsModelFeed::StandardAtom:
case FeedsModelFeed::StandardRdf: case FeedsModelFeed::StandardRdf:
case FeedsModelFeed::StandardRss: { case FeedsModelFeed::StandardRss0X:
case FeedsModelFeed::StandardRss1X:
case FeedsModelFeed::StandardRss2X: {
FeedAssignmentItem pair; FeedAssignmentItem pair;
pair.first = query_feeds.value(FDS_DB_CATEGORY_INDEX).toInt(); pair.first = query_feeds.value(FDS_DB_CATEGORY_INDEX).toInt();
pair.second = FeedsModelStandardFeed::loadFromRecord(query_feeds.record()); pair.second = FeedsModelStandardFeed::loadFromRecord(query_feeds.record());

View File

@ -49,6 +49,11 @@ class FeedsModel : public QAbstractItemModel {
// null if index is invalid. // null if index is invalid.
FeedsModelRootItem *itemForIndex(const QModelIndex &index); 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: protected:
// Loads feed/categories from the database. // Loads feed/categories from the database.
void loadFromDatabase(); void loadFromDatabase();

View File

@ -1,6 +1,7 @@
#include <QSqlDatabase> #include <QSqlDatabase>
#include <QSqlQuery> #include <QSqlQuery>
#include <QSqlError> #include <QSqlError>
#include <QVariant>
#include "core/databasefactory.h" #include "core/databasefactory.h"
#include "core/feedsmodelfeed.h" #include "core/feedsmodelfeed.h"
@ -43,6 +44,45 @@ void FeedsModelFeed::setType(const Type &type) {
m_type = type; m_type = type;
} }
void FeedsModelFeed::updateCounts() { QString FeedsModelFeed::typeToString(FeedsModelFeed::Type type) {
//QSqlDatabase database = DatabaseFactory::getInstance()-> 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();
}
}

View File

@ -11,9 +11,11 @@ class FeedsModelFeed : public FeedsModelRootItem {
// Describes possible types of feeds. // Describes possible types of feeds.
// NOTE: This is equivalent to attribute Feeds(type). // NOTE: This is equivalent to attribute Feeds(type).
enum Type { enum Type {
StandardRss = 0, StandardRss0X = 0,
StandardRdf = 1, StandardRss1X = 1,
StandardAtom = 2 StandardRss2X = 2,
StandardRdf = 3,
StandardAtom = 4
}; };
// Constructors and destructors. // Constructors and destructors.
@ -36,9 +38,11 @@ class FeedsModelFeed : public FeedsModelRootItem {
Type type() const; Type type() const;
void setType(const Type &type); void setType(const Type &type);
static QString typeToString(Type type);
public slots: public slots:
// Updates counts of all/unread messages for this feed. // Updates counts of all/unread messages for this feed.
void updateCounts(); void updateCounts(bool including_total_count = true);
protected: protected:
Type m_type; Type m_type;

View File

@ -30,6 +30,7 @@ FeedsModelStandardFeed *FeedsModelStandardFeed::loadFromRecord(const QSqlRecord
feed->setEncoding(record.value(FDS_DB_ENCODING_INDEX).toString()); feed->setEncoding(record.value(FDS_DB_ENCODING_INDEX).toString());
feed->setUrl(record.value(FDS_DB_URL_INDEX).toString()); feed->setUrl(record.value(FDS_DB_URL_INDEX).toString());
feed->setLanguage(record.value(FDS_DB_LANGUAGE_INDEX).toString()); feed->setLanguage(record.value(FDS_DB_LANGUAGE_INDEX).toString());
feed->updateCounts();
return feed; return feed;
} }
@ -85,6 +86,26 @@ QVariant FeedsModelStandardFeed::data(int column, int role) const {
m_icon : m_icon :
QVariant(); 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: case Qt::TextAlignmentRole:
if (column == FDS_MODEL_COUNTS_INDEX) { if (column == FDS_MODEL_COUNTS_INDEX) {
return Qt::AlignCenter; return Qt::AlignCenter;

View File

@ -55,11 +55,16 @@ void MessagesModel::setupFonts() {
m_boldFont.setBold(true); m_boldFont.setBold(true);
} }
void MessagesModel::loadMessages(const QList<int> feed_ids) { QList<int> MessagesModel::currentFeeds() const {
// Conversion of parameter. return m_currentFeeds;
m_currentFeeds = feed_ids; }
setFilter(QString("feed IN (%1) AND deleted = 0").arg(textualFeeds().join(", ")));
void MessagesModel::loadMessages(const QList<int> feed_ids) {
// Conversion of parameter.
m_currentFeeds = feed_ids;
setFilter(QString("feed IN (%1) AND deleted = 0").arg(textualFeeds().join(", ")));
select(); select();
fetchAll(); fetchAll();
} }

View File

@ -44,6 +44,8 @@ class MessagesModel : public QSqlTableModel {
Message messageAt(int row_index) const; Message messageAt(int row_index) const;
int messageId(int row_index) const; int messageId(int row_index) const;
QList<int> currentFeeds() const;
public slots: public slots:
// To disable persistent changes submissions. // To disable persistent changes submissions.
bool submitAll(); bool submitAll();

View File

@ -42,6 +42,8 @@ void FeedMessageViewer::createConnections() {
SLOT(addLinkedBrowser(QString))); SLOT(addLinkedBrowser(QString)));
connect(m_feedsView, SIGNAL(feedsSelected(QList<int>)), connect(m_feedsView, SIGNAL(feedsSelected(QList<int>)),
m_messagesView, SLOT(loadFeeds(QList<int>))); m_messagesView, SLOT(loadFeeds(QList<int>)));
connect(m_messagesView, SIGNAL(feedCountsChanged()),
m_feedsView, SLOT(updateCountsOfSelectedFeeds()));
// Toolbar forwardings. // Toolbar forwardings.
connect(FormMain::getInstance()->m_ui->m_actionSwitchImportanceOfSelectedMessages, connect(FormMain::getInstance()->m_ui->m_actionSwitchImportanceOfSelectedMessages,

View File

@ -25,6 +25,18 @@ void FeedsView::setSortingEnabled(bool enable) {
header()->setSortIndicatorShown(false); header()->setSortIndicatorShown(false);
} }
void FeedsView::updateCountsOfSelectedFeeds() {
QModelIndexList selected_rows = selectionModel()->selectedRows();
QModelIndexList mapped_rows = m_proxyModel->mapListToSource(selected_rows);
QList<FeedsModelFeed*> feeds = m_sourceModel->feedsForIndexes(mapped_rows);
foreach (FeedsModelFeed *feed, feeds) {
feed->updateCounts();
}
m_sourceModel->changeLayout();
}
void FeedsView::setupAppearance() { void FeedsView::setupAppearance() {
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
// Setup column resize strategies. // Setup column resize strategies.

View File

@ -17,6 +17,10 @@ class FeedsView : public QTreeView {
void setSortingEnabled(bool enable); void setSortingEnabled(bool enable);
public slots:
// Reloads count for selected feeds.
void updateCountsOfSelectedFeeds();
protected: protected:
void setupAppearance(); void setupAppearance();
void selectionChanged(const QItemSelection &selected, void selectionChanged(const QItemSelection &selected,

View File

@ -95,11 +95,6 @@ void MessagesView::setupAppearance() {
setSelectionMode(QAbstractItemView::ExtendedSelection); setSelectionMode(QAbstractItemView::ExtendedSelection);
} }
void MessagesView::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected) {
QTreeView::selectionChanged(selected, deselected);
}
void MessagesView::keyPressEvent(QKeyEvent *event) { void MessagesView::keyPressEvent(QKeyEvent *event) {
QTreeView::keyPressEvent(event); QTreeView::keyPressEvent(event);
@ -175,6 +170,7 @@ void MessagesView::currentChanged(const QModelIndex &current,
} }
emit currentMessageChanged(m_sourceModel->messageAt(mapped_current_index.row())); emit currentMessageChanged(m_sourceModel->messageAt(mapped_current_index.row()));
emit feedCountsChanged();
} }
else { else {
emit currentMessageRemoved(); emit currentMessageRemoved();

View File

@ -53,8 +53,6 @@ class MessagesView : public QTreeView {
void keyPressEvent(QKeyEvent *event); void keyPressEvent(QKeyEvent *event);
void currentChanged(const QModelIndex &current, void currentChanged(const QModelIndex &current,
const QModelIndex &previous); const QModelIndex &previous);
void selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected);
signals: signals:
void openLinkMessageNewTabRequested(const QString &link); void openLinkMessageNewTabRequested(const QString &link);
@ -62,6 +60,10 @@ class MessagesView : public QTreeView {
void currentMessageChanged(const Message &message); void currentMessageChanged(const Message &message);
void currentMessageRemoved(); void currentMessageRemoved();
// Emitted if counts of unread/total messages has changed
// because of user interaction with list of messages.
void feedCountsChanged();
private: private:
QMenu *m_contextMenu; QMenu *m_contextMenu;