Many fixes in message model.

This commit is contained in:
Martin Rotter 2014-09-20 17:13:12 +02:00
parent 9d040f82bf
commit 1a9a121709
10 changed files with 73 additions and 84 deletions

View file

@ -29,7 +29,8 @@
MessagesModel::MessagesModel(QObject *parent) MessagesModel::MessagesModel(QObject *parent)
: QSqlTableModel(parent, qApp->database()->connection("MessagesModel", DatabaseFactory::FromSettings)) { : QSqlTableModel(parent, qApp->database()->connection("MessagesModel", DatabaseFactory::FromSettings)),
m_messageMode(MessagesFromFeeds), m_messageFilter(NoHighlighting) {
setObjectName("MessagesModel"); setObjectName("MessagesModel");
setupFonts(); setupFonts();
setupIcons(); setupIcons();
@ -69,9 +70,11 @@ void MessagesModel::loadMessages(const QList<int> feed_ids) {
m_currentFeeds = feed_ids; m_currentFeeds = feed_ids;
if (feed_ids.size() == 1 && feed_ids[0] == ID_RECYCLE_BIN) { if (feed_ids.size() == 1 && feed_ids[0] == ID_RECYCLE_BIN) {
m_messageMode = MessagesFromRecycleBin;
setFilter("is_deleted = 1"); setFilter("is_deleted = 1");
} }
else { else {
m_messageMode = MessagesFromFeeds;
QString assembled_ids = textualFeeds().join(", "); QString assembled_ids = textualFeeds().join(", ");
setFilter(QString("feed IN (%1) AND is_deleted = 0").arg(assembled_ids)); setFilter(QString("feed IN (%1) AND is_deleted = 0").arg(assembled_ids));
@ -82,8 +85,8 @@ void MessagesModel::loadMessages(const QList<int> feed_ids) {
fetchAll(); fetchAll();
} }
void MessagesModel::filterMessages(MessagesModel::DisplayFilter filter) { void MessagesModel::filterMessages(MessagesModel::MessageFilter filter) {
m_filter = filter; m_messageFilter = filter;
emit layoutAboutToBeChanged(); emit layoutAboutToBeChanged();
emit layoutChanged(); emit layoutChanged();
} }
@ -167,8 +170,7 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const {
return QSqlTableModel::data(index(idx.row(), MSG_DB_TITLE_INDEX, idx.parent())); return QSqlTableModel::data(index(idx.row(), MSG_DB_TITLE_INDEX, idx.parent()));
} }
*/ */
else if (index_column != MSG_DB_IMPORTANT_INDEX && else if (index_column != MSG_DB_IMPORTANT_INDEX && index_column != MSG_DB_READ_INDEX) {
index_column != MSG_DB_READ_INDEX) {
return QSqlTableModel::data(idx, role); return QSqlTableModel::data(idx, role);
} }
else { else {
@ -180,26 +182,17 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const {
return QSqlTableModel::data(idx, role); return QSqlTableModel::data(idx, role);
case Qt::FontRole: case Qt::FontRole:
return QSqlTableModel::data(index(idx.row(), return QSqlTableModel::data(index(idx.row(), MSG_DB_READ_INDEX)).toInt() == 1 ? m_normalFont : m_boldFont;
MSG_DB_READ_INDEX)).toInt() == 1 ?
m_normalFont :
m_boldFont;
case Qt::ForegroundRole: case Qt::ForegroundRole:
switch (m_filter) { switch (m_messageFilter) {
case DisplayImportant: case HighlightImportant:
return QSqlTableModel::data(index(idx.row(), return QSqlTableModel::data(index(idx.row(), MSG_DB_IMPORTANT_INDEX)).toInt() == 1 ? QColor(Qt::blue) : QVariant();
MSG_DB_IMPORTANT_INDEX)).toInt() == 1 ?
QColor(Qt::blue) :
QVariant();
case DisplayUnread: case HighlightUnread:
return QSqlTableModel::data(index(idx.row(), return QSqlTableModel::data(index(idx.row(), MSG_DB_READ_INDEX)).toInt() == 0 ? QColor(Qt::blue) : QVariant();
MSG_DB_READ_INDEX)).toInt() == 0 ?
QColor(Qt::blue) :
QVariant();
case DisplayAll: case NoHighlighting:
default: default:
return QVariant(); return QVariant();
} }
@ -208,14 +201,10 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const {
int index_column = idx.column(); int index_column = idx.column();
if (index_column == MSG_DB_READ_INDEX) { if (index_column == MSG_DB_READ_INDEX) {
return QSqlTableModel::data(idx).toInt() == 1 ? return QSqlTableModel::data(idx).toInt() == 1 ? m_readIcon : m_unreadIcon;
m_readIcon :
m_unreadIcon;
} }
else if (index_column == MSG_DB_IMPORTANT_INDEX) { else if (index_column == MSG_DB_IMPORTANT_INDEX) {
return QSqlTableModel::data(idx).toInt() == 1 ? return QSqlTableModel::data(idx).toInt() == 1 ? m_favoriteIcon : QVariant();
m_favoriteIcon :
QVariant();
} }
else { else {
return QVariant(); return QVariant();
@ -242,8 +231,7 @@ bool MessagesModel::setMessageRead(int row_index, int read) {
} }
// Rewrite "visible" data in the model. // Rewrite "visible" data in the model.
bool working_change = setData(index(row_index, MSG_DB_READ_INDEX), bool working_change = setData(index(row_index, MSG_DB_READ_INDEX), read);
read);
if (!working_change) { if (!working_change) {
// If rewriting in the model failed, then cancel all actions. // If rewriting in the model failed, then cancel all actions.
@ -257,8 +245,7 @@ bool MessagesModel::setMessageRead(int row_index, int read) {
QSqlQuery query_read_msg(db_handle); QSqlQuery query_read_msg(db_handle);
query_read_msg.setForwardOnly(true); query_read_msg.setForwardOnly(true);
if (!query_read_msg.prepare("UPDATE messages SET is_read = :read " if (!query_read_msg.prepare("UPDATE Messages SET is_read = :read WHERE id = :id;")) {
"WHERE id = :id")) {
qWarning("Query preparation failed for message read change."); qWarning("Query preparation failed for message read change.");
db_handle.rollback(); db_handle.rollback();
@ -313,8 +300,7 @@ bool MessagesModel::switchMessageImportance(int row_index) {
QSqlQuery query_importance_msg(db_handle); QSqlQuery query_importance_msg(db_handle);
query_importance_msg.setForwardOnly(true); query_importance_msg.setForwardOnly(true);
if (!query_importance_msg.prepare("UPDATE messages SET is_important = :important " if (!query_importance_msg.prepare("UPDATE Messages SET is_important = :important WHERE id = :id;")) {
"WHERE id = :id")) {
qWarning("Query preparation failed for message importance switch."); qWarning("Query preparation failed for message importance switch.");
db_handle.rollback(); db_handle.rollback();
@ -323,16 +309,14 @@ bool MessagesModel::switchMessageImportance(int row_index) {
message_id = messageId(row_index); message_id = messageId(row_index);
query_importance_msg.bindValue(":id", message_id); query_importance_msg.bindValue(":id", message_id);
query_importance_msg.bindValue(":important", query_importance_msg.bindValue(":important", current_importance == 1 ? 0 : 1);
current_importance == 1 ? 0 : 1);
query_importance_msg.exec(); query_importance_msg.exec();
// Commit changes. // Commit changes.
if (db_handle.commit()) { if (db_handle.commit()) {
// If commit succeeded, then emit changes, so that view // If commit succeeded, then emit changes, so that view
// can reflect. // can reflect.
emit dataChanged(index(row_index, 0), emit dataChanged(index(row_index, 0), index(row_index, columnCount() - 1));
index(row_index, columnCount() - 1));
return true; return true;
} }
else { else {
@ -352,8 +336,8 @@ bool MessagesModel::switchBatchMessageImportance(const QModelIndexList &messages
message_ids.append(QString::number(messageId(message.row()))); message_ids.append(QString::number(messageId(message.row())));
} }
if (query_read_msg.exec(QString("UPDATE messages SET is_important = NOT is_important " if (query_read_msg.exec(QString("UPDATE Messages SET is_important = NOT is_important "
"WHERE id IN (%1)").arg(message_ids.join(", ")))) { "WHERE id IN (%1);").arg(message_ids.join(", ")))) {
select(); select();
fetchAll(); fetchAll();
@ -365,8 +349,7 @@ bool MessagesModel::switchBatchMessageImportance(const QModelIndexList &messages
} }
} }
bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages, bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages, int deleted) {
int deleted) {
QSqlDatabase db_handle = database(); QSqlDatabase db_handle = database();
QSqlQuery query_read_msg(db_handle); QSqlQuery query_read_msg(db_handle);
QStringList message_ids; QStringList message_ids;
@ -378,9 +361,17 @@ bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages,
message_ids.append(QString::number(messageId(message.row()))); message_ids.append(QString::number(messageId(message.row())));
} }
if (query_read_msg.exec(QString("UPDATE messages SET is_deleted = %2 " QString sql_delete_query;
"WHERE id IN (%1)").arg(message_ids.join(", "),
QString::number(deleted)))) { if (m_messageMode == MessagesFromFeeds) {
sql_delete_query = QString("UPDATE Messages SET is_deleted = %2 WHERE id IN (%1);").arg(message_ids.join(", "),
QString::number(deleted));
}
else {
sql_delete_query = QString("DELETE FROM Messages WHERE id in (%1);").arg(message_ids.join(", "));
}
if (query_read_msg.exec(sql_delete_query)) {
select(); select();
fetchAll(); fetchAll();
@ -404,9 +395,8 @@ bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, int re
message_ids.append(QString::number(messageId(message.row()))); message_ids.append(QString::number(messageId(message.row())));
} }
if (query_read_msg.exec(QString("UPDATE messages SET is_read = %2 " if (query_read_msg.exec(QString("UPDATE Messages SET is_read = %2 "
"WHERE id IN (%1)").arg(message_ids.join(", "), "WHERE id IN (%1);").arg(message_ids.join(", "), QString::number(read)))) {
QString::number(read)))) {
select(); select();
fetchAll(); fetchAll();
@ -418,9 +408,7 @@ bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, int re
} }
} }
QVariant MessagesModel::headerData(int section, QVariant MessagesModel::headerData(int section, Qt::Orientation orientation, int role) const {
Qt::Orientation orientation,
int role) const {
Q_UNUSED(orientation) Q_UNUSED(orientation)
switch (role) { switch (role) {

View file

@ -50,10 +50,15 @@ class MessagesModel : public QSqlTableModel {
public: public:
// Enum which describes basic filtering schemes // Enum which describes basic filtering schemes
// for messages. // for messages.
enum DisplayFilter { enum MessageFilter {
DisplayAll = 100, NoHighlighting = 100,
DisplayUnread = 101, HighlightUnread = 101,
DisplayImportant = 102 HighlightImportant = 102
};
enum MessageMode {
MessagesFromFeeds,
MessagesFromRecycleBin
}; };
// Constructors and destructors. // Constructors and destructors.
@ -104,7 +109,7 @@ class MessagesModel : public QSqlTableModel {
// Loads messages of given feeds. // Loads messages of given feeds.
void loadMessages(const QList<int> feed_ids); void loadMessages(const QList<int> feed_ids);
void filterMessages(DisplayFilter filter); void filterMessages(MessageFilter filter);
signals: signals:
// Emitted if some persistent change is made which affects // Emitted if some persistent change is made which affects
@ -126,7 +131,8 @@ class MessagesModel : public QSqlTableModel {
void setupIcons(); void setupIcons();
private: private:
DisplayFilter m_filter; MessageMode m_messageMode;
MessageFilter m_messageFilter;
QList<int> m_currentFeeds; QList<int> m_currentFeeds;
QList<QString> m_headerData; QList<QString> m_headerData;
@ -140,6 +146,6 @@ class MessagesModel : public QSqlTableModel {
QIcon m_unreadIcon; QIcon m_unreadIcon;
}; };
Q_DECLARE_METATYPE(MessagesModel::DisplayFilter) Q_DECLARE_METATYPE(MessagesModel::MessageFilter)
#endif // MESSAGESMODEL_H #endif // MESSAGESMODEL_H

View file

@ -195,8 +195,8 @@ void FeedMessageViewer::createConnections() {
// Filtering & searching. // Filtering & searching.
connect(m_toolBarMessages, SIGNAL(messageSearchPatternChanged(QString)), connect(m_toolBarMessages, SIGNAL(messageSearchPatternChanged(QString)),
m_messagesView, SLOT(searchMessages(QString))); m_messagesView, SLOT(searchMessages(QString)));
connect(m_toolBarMessages, SIGNAL(messageFilterChanged(MessagesModel::DisplayFilter)), connect(m_toolBarMessages, SIGNAL(messageFilterChanged(MessagesModel::MessageFilter)),
m_messagesView, SLOT(filterMessages(MessagesModel::DisplayFilter))); m_messagesView, SLOT(filterMessages(MessagesModel::MessageFilter)));
// Message changers. // Message changers.
connect(m_messagesView, SIGNAL(currentMessagesRemoved()), m_messagesBrowser, SLOT(clear())); connect(m_messagesView, SIGNAL(currentMessagesRemoved()), m_messagesBrowser, SLOT(clear()));

View file

@ -561,29 +561,25 @@ void FeedsView::setupAppearance() {
void FeedsView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { void FeedsView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
QTreeView::selectionChanged(selected, deselected); QTreeView::selectionChanged(selected, deselected);
m_selectedFeeds.clear(); QList<FeedsModelFeed*> selected_feeds = selectedFeeds();
QList<int> selected_ids;
foreach (FeedsModelFeed *feed, selectedFeeds()) { if (!selected_feeds.isEmpty()) {
foreach (FeedsModelFeed *feed, selected_feeds) {
#if defined(DEBUG) #if defined(DEBUG)
QModelIndex index_for_feed = m_sourceModel->indexForItem(feed); QModelIndex index_for_feed = m_sourceModel->indexForItem(feed);
qDebug("Selecting feed '%s' (source index [%d, %d]).", qPrintable(feed->title()), index_for_feed.row(), index_for_feed.column()); qDebug("Selecting feed '%s' (source index [%d, %d]).", qPrintable(feed->title()), index_for_feed.row(), index_for_feed.column());
#endif #endif
m_selectedFeeds << feed->id(); selected_ids << feed->id();
}
if (m_selectedFeeds.isEmpty() && selectionModel()->selectedIndexes().size() > 0) {
QModelIndex selected_index = selectionModel()->selectedIndexes().at(0);
QModelIndex mapped_index = model()->mapToSource(selected_index);
FeedsModelRootItem *item = sourceModel()->itemForIndex(mapped_index);
if (item->kind() == FeedsModelRootItem::RecycleBin) {
m_selectedFeeds.append(ID_RECYCLE_BIN);
} }
} }
else if (selectedRecycleBin() != NULL) {
selected_ids << ID_RECYCLE_BIN;
}
emit feedsSelected(m_selectedFeeds); emit feedsSelected(selected_ids);
} }
void FeedsView::keyPressEvent(QKeyEvent *event) { void FeedsView::keyPressEvent(QKeyEvent *event) {

View file

@ -174,7 +174,6 @@ class FeedsView : public QTreeView {
QMenu *m_contextMenuEmptySpace; QMenu *m_contextMenuEmptySpace;
QMenu *m_contextMenuRecycleBin; QMenu *m_contextMenuRecycleBin;
QList<int> m_selectedFeeds;
FeedsModel *m_sourceModel; FeedsModel *m_sourceModel;
FeedsProxyModel *m_proxyModel; FeedsProxyModel *m_proxyModel;

View file

@ -224,7 +224,7 @@ void FormUpdate::startUpdate() {
// Initialie downloader. // Initialie downloader.
m_downloader = new Downloader(this); m_downloader = new Downloader(this);
connect(m_downloader, SIGNAL(progress(qint64,qint64)), this, SLOT(updateProgress(qint64,qint64))); //connect(m_downloader, SIGNAL(progress(qint64,qint64)), this, SLOT(updateProgress(qint64,qint64)));
connect(m_downloader, SIGNAL(completed(QNetworkReply::NetworkError,QByteArray)), this, SLOT(updateCompleted(QNetworkReply::NetworkError,QByteArray))); connect(m_downloader, SIGNAL(completed(QNetworkReply::NetworkError,QByteArray)), this, SLOT(updateCompleted(QNetworkReply::NetworkError,QByteArray)));
} }

View file

@ -106,7 +106,7 @@ void MessagesToolBar::handleMessageHighlighterChange(QAction *action) {
m_btnMessageHighlighter->setIcon(action->icon()); m_btnMessageHighlighter->setIcon(action->icon());
m_btnMessageHighlighter->setToolTip(action->text()); m_btnMessageHighlighter->setToolTip(action->text());
emit messageFilterChanged(action->data().value<MessagesModel::DisplayFilter>()); emit messageFilterChanged(action->data().value<MessagesModel::MessageFilter>());
} }
void MessagesToolBar::initializeSearchBox() { void MessagesToolBar::initializeSearchBox() {
@ -128,11 +128,11 @@ void MessagesToolBar::initializeSearchBox() {
void MessagesToolBar::initializeHighlighter() { void MessagesToolBar::initializeHighlighter() {
m_menuMessageHighlighter = new QMenu(tr("Menu for highlighting messages"), this); m_menuMessageHighlighter = new QMenu(tr("Menu for highlighting messages"), this);
m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme("mail-mark-read"), m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme("mail-mark-read"),
tr("No extra highlighting"))->setData(QVariant::fromValue(MessagesModel::DisplayAll)); tr("No extra highlighting"))->setData(QVariant::fromValue(MessagesModel::NoHighlighting));
m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme("mail-mark-unread"), m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme("mail-mark-unread"),
tr("Highlight unread messages"))->setData(QVariant::fromValue(MessagesModel::DisplayUnread)); tr("Highlight unread messages"))->setData(QVariant::fromValue(MessagesModel::HighlightUnread));
m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme("mail-mark-favorite"), m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme("mail-mark-favorite"),
tr("Highlight important messages"))->setData(QVariant::fromValue(MessagesModel::DisplayImportant)); tr("Highlight important messages"))->setData(QVariant::fromValue(MessagesModel::HighlightImportant));
m_btnMessageHighlighter = new QToolButton(this); m_btnMessageHighlighter = new QToolButton(this);
m_btnMessageHighlighter->setToolTip(tr("Display all messages")); m_btnMessageHighlighter->setToolTip(tr("Display all messages"));

View file

@ -56,7 +56,7 @@ class MessagesToolBar : public BaseToolBar {
void messageSearchPatternChanged(const QString &pattern); void messageSearchPatternChanged(const QString &pattern);
// Emitted if message filter is changed. // Emitted if message filter is changed.
void messageFilterChanged(MessagesModel::DisplayFilter filter); void messageFilterChanged(MessagesModel::MessageFilter filter);
private slots: private slots:
// Called when highlighter gets changed. // Called when highlighter gets changed.

View file

@ -420,7 +420,7 @@ void MessagesView::searchMessages(const QString &pattern) {
} }
} }
void MessagesView::filterMessages(MessagesModel::DisplayFilter filter) { void MessagesView::filterMessages(MessagesModel::MessageFilter filter) {
m_sourceModel->filterMessages(filter); m_sourceModel->filterMessages(filter);
} }

View file

@ -72,15 +72,15 @@ class MessagesView : public QTreeView {
void setSelectedMessagesReadStatus(int read); void setSelectedMessagesReadStatus(int read);
void markSelectedMessagesRead(); void markSelectedMessagesRead();
void markSelectedMessagesUnread(); void markSelectedMessagesUnread();
void deleteSelectedMessages();
void switchSelectedMessagesImportance(); void switchSelectedMessagesImportance();
void deleteSelectedMessages();
void selectNextItem(); void selectNextItem();
void selectPreviousItem(); void selectPreviousItem();
// Searchs the visible message according to given pattern. // Searchs the visible message according to given pattern.
void searchMessages(const QString &pattern); void searchMessages(const QString &pattern);
void filterMessages(MessagesModel::DisplayFilter filter); void filterMessages(MessagesModel::MessageFilter filter);
protected slots: protected slots:
// Marks given indexes as selected. // Marks given indexes as selected.