Heavy work on messages model, switching of importance.

This commit is contained in:
Martin Rotter 2015-11-20 10:33:38 +01:00
parent fab7d1e8b1
commit 6354910882
7 changed files with 45 additions and 66 deletions

View file

@ -106,6 +106,10 @@ int MessagesModel::messageId(int row_index) const {
return data(row_index, MSG_DB_ID_INDEX, Qt::EditRole).toInt(); return data(row_index, MSG_DB_ID_INDEX, Qt::EditRole).toInt();
} }
RootItem::Importance MessagesModel::messageImportance(int row_index) const {
return (RootItem::Importance) data(row_index, MSG_DB_IMPORTANT_INDEX, Qt::EditRole).toInt();
}
void MessagesModel::updateDateFormat() { void MessagesModel::updateDateFormat() {
if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::UseCustomDate)).toBool()) { if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::UseCustomDate)).toBool()) {
m_customDateFormat = qApp->settings()->value(GROUP(Messages), SETTING(Messages::CustomDateFormat)).toString(); m_customDateFormat = qApp->settings()->value(GROUP(Messages), SETTING(Messages::CustomDateFormat)).toString();
@ -254,104 +258,75 @@ bool MessagesModel::setMessageRead(int row_index, RootItem::ReadStatus read) {
return false; return false;
} }
QSqlDatabase db_handle = database();
if (!db_handle.transaction()) {
qWarning("Starting transaction for message read change.");
return false;
}
// Rewrite "visible" data in the model. // Rewrite "visible" data in the model.
bool working_change = setData(index(row_index, MSG_DB_READ_INDEX), read); bool working_change = setData(index(row_index, MSG_DB_READ_INDEX), 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.
qDebug("Setting of new data to the model failed for message read change."); qDebug("Setting of new data to the model failed for message read change.");
db_handle.rollback();
return false; return false;
} }
QSqlQuery query_read_msg(db_handle); QSqlQuery query_read_msg(database());
query_read_msg.setForwardOnly(true); query_read_msg.setForwardOnly(true);
if (!query_read_msg.prepare(QSL("UPDATE Messages SET is_read = :read WHERE id = :id;"))) { if (!query_read_msg.prepare(QSL("UPDATE Messages SET is_read = :read WHERE id = :id;"))) {
qWarning("Query preparation failed for message read change."); qWarning("Query preparation failed for message read change.");
db_handle.rollback();
return false; return false;
} }
query_read_msg.bindValue(QSL(":id"), message_id); query_read_msg.bindValue(QSL(":id"), message_id);
query_read_msg.bindValue(QSL(":read"), read); query_read_msg.bindValue(QSL(":read"), (int) read);
query_read_msg.exec();
// Commit changes. if (query_read_msg.exec()) {
if (db_handle.commit()) {
// If commit succeeded, then emit changes, so that view can reflect.
emit dataChanged(index(row_index, 0), index(row_index, columnCount() - 1));
return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, QList<int>() << message_id, read); return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, QList<int>() << message_id, read);
} }
else { else {
return db_handle.rollback();; return false;
} }
} }
bool MessagesModel::switchMessageImportance(int row_index) { bool MessagesModel::switchMessageImportance(int row_index) {
QModelIndex target_index = index(row_index, MSG_DB_IMPORTANT_INDEX); QModelIndex target_index = index(row_index, MSG_DB_IMPORTANT_INDEX);
RootItem::Importance current_importance = (RootItem::Importance) data(target_index, Qt::EditRole).toInt(); RootItem::Importance current_importance = (RootItem::Importance) data(target_index, Qt::EditRole).toInt();
RootItem::Importance next_importance = current_importance == RootItem::Important ?
RootItem::NotImportant : RootItem::Important;
int message_id = messageId(row_index); int message_id = messageId(row_index);
QPair<int,RootItem::Importance> pair(message_id, next_importance);
if (!m_selectedItem->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_selectedItem, if (!m_selectedItem->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_selectedItem,
message_id, QList<QPair<int,RootItem::Importance> >() << pair)) {
current_importance)) {
return false;
}
QSqlDatabase db_handle = database();
if (!db_handle.transaction()) {
qWarning("Starting transaction for message importance switch failed.");
return false; return false;
} }
// Rewrite "visible" data in the model. // Rewrite "visible" data in the model.
bool working_change = current_importance == RootItem::Important ? bool working_change = setData(target_index, next_importance);
setData(target_index, RootItem::NotImportant) :
setData(target_index, RootItem::Important);
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.
qDebug("Setting of new data to the model failed for message importance change."); qDebug("Setting of new data to the model failed for message importance change.");
db_handle.rollback();
return false; return false;
} }
QSqlQuery query_importance_msg(db_handle); QSqlQuery query_importance_msg(database());
query_importance_msg.setForwardOnly(true); query_importance_msg.setForwardOnly(true);
if (!query_importance_msg.prepare(QSL("UPDATE Messages SET is_important = :important WHERE id = :id;"))) { if (!query_importance_msg.prepare(QSL("UPDATE Messages SET is_important = :important WHERE id = :id;"))) {
qWarning("Query preparation failed for message importance switch."); qWarning("Query preparation failed for message importance switch.");
db_handle.rollback();
return false; return false;
} }
query_importance_msg.bindValue(QSL(":id"), message_id); query_importance_msg.bindValue(QSL(":id"), message_id);
query_importance_msg.bindValue(QSL(":important"), current_importance == 1 ? 0 : 1); query_importance_msg.bindValue(QSL(":important"), (int) next_importance);
query_importance_msg.exec();
// Commit changes. // Commit changes.
if (db_handle.commit()) { if (query_importance_msg.exec()) {
// If commit succeeded, then emit changes, so that view return m_selectedItem->getParentServiceRoot()->onAfterSwitchMessageImportance(m_selectedItem,
// can reflect. QList<QPair<int,RootItem::Importance> >() << pair);
emit dataChanged(index(row_index, 0), index(row_index, columnCount() - 1));
return m_selectedItem->getParentServiceRoot()->onAfterSwitchMessageImportance(m_selectedItem, message_id,
current_importance);
} }
else { else {
return db_handle.rollback(); return false;
} }
} }
@ -359,24 +334,27 @@ bool MessagesModel::switchBatchMessageImportance(const QModelIndexList &messages
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;
QList<int> message_ids_num; QList<QPair<int,RootItem::Importance> > message_states;
query_read_msg.setForwardOnly(true); query_read_msg.setForwardOnly(true);
// Obtain IDs of all desired messages. // Obtain IDs of all desired messages.
foreach (const QModelIndex &message, messages) { foreach (const QModelIndex &message, messages) {
int message_id = messageId(message.row()); int message_id = messageId(message.row());
RootItem::Importance message_importance = messageImportance((message.row()));
message_ids_num.append(message_id); message_states.append(QPair<int,RootItem::Importance>(message_id, message_importance));
message_ids.append(QString::number(message_id)); message_ids.append(QString::number(message_id));
} }
if (!m_selectedItem->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_selectedItem, message_states)) {
return false;
}
if (query_read_msg.exec(QString(QSL("UPDATE Messages SET is_important = NOT is_important WHERE id IN (%1);")) if (query_read_msg.exec(QString(QSL("UPDATE Messages SET is_important = NOT is_important WHERE id IN (%1);"))
.arg(message_ids.join(QSL(", "))))) { .arg(message_ids.join(QSL(", "))))) {
fetchAllData(); fetchAllData();
return m_selectedItem->getParentServiceRoot()->onAfterSwitchMessageImportance(m_selectedItem, message_states);
//emit messageCountsChanged(false);
return true;
} }
else { else {
return false; return false;

View file

@ -53,6 +53,7 @@ class MessagesModel : public QSqlTableModel {
// Returns message at given index. // Returns message at given index.
Message messageAt(int row_index) const; Message messageAt(int row_index) const;
int messageId(int row_index) const; int messageId(int row_index) const;
RootItem::Importance messageImportance(int row_index) const;
void updateDateFormat(); void updateDateFormat();
void reloadWholeLayout(); void reloadWholeLayout();

View file

@ -398,9 +398,11 @@ void MessagesView::switchSelectedMessagesImportance() {
current_index = m_proxyModel->mapFromSource(m_sourceModel->index(mapped_current_index.row(), current_index = m_proxyModel->mapFromSource(m_sourceModel->index(mapped_current_index.row(),
mapped_current_index.column())); mapped_current_index.column()));
m_batchUnreadSwitch = true;
setCurrentIndex(current_index); setCurrentIndex(current_index);
scrollTo(current_index); scrollTo(current_index);
reselectIndexes(selected_indexes); reselectIndexes(selected_indexes);
m_batchUnreadSwitch = false;
} }
void MessagesView::reselectIndexes(const QModelIndexList &indexes) { void MessagesView::reselectIndexes(const QModelIndexList &indexes) {

View file

@ -88,16 +88,16 @@ class ServiceRoot : public RootItem {
// This is the place to make some other changes like updating // This is the place to make some other changes like updating
// some ONLINE service or something. // some ONLINE service or something.
// //
// "important" is status which is ABOUT TO BE SET. // "changes" - list of pairs - <message (integer id), new status>
virtual bool onBeforeSwitchMessageImportance(RootItem *selected_item, int message_db_id, Importance important) = 0; virtual bool onBeforeSwitchMessageImportance(RootItem *selected_item, QList<QPair<int,RootItem::Importance> > changes) = 0;
// Called AFTER this importance switch update is stored in DB, // Called AFTER this importance switch update is stored in DB,
// when false is returned, change is aborted. // when false is returned, change is aborted.
// Here service root should inform (via signals) // Here service root should inform (via signals)
// which items are actually changed. // which items are actually changed.
// //
// "important" is status which is ABOUT TO BE SET. // "changes" - list of pairs - <message (integer id), new status>
virtual bool onAfterSwitchMessageImportance(RootItem *selected_item, int message_db_id, Importance important) = 0; virtual bool onAfterSwitchMessageImportance(RootItem *selected_item, QList<QPair<int,RootItem::Importance> > changes) = 0;
// Access to feed model. // Access to feed model.
FeedsModel *feedsModel() const; FeedsModel *feedsModel() const;

View file

@ -559,20 +559,18 @@ bool StandardServiceRoot::onAfterSetMessagesRead(RootItem *selected_item, QList<
return true; return true;
} }
bool StandardServiceRoot::onBeforeSwitchMessageImportance(RootItem *selected_item, int message_db_id, bool StandardServiceRoot::onBeforeSwitchMessageImportance(RootItem *selected_item,
RootItem::Importance important) { QList<QPair<int,RootItem::Importance> > changes) {
Q_UNUSED(message_db_id)
Q_UNUSED(important)
Q_UNUSED(selected_item) Q_UNUSED(selected_item)
Q_UNUSED(changes)
return true; return true;
} }
bool StandardServiceRoot::onAfterSwitchMessageImportance(RootItem *selected_item, int message_db_id, bool StandardServiceRoot::onAfterSwitchMessageImportance(RootItem *selected_item,
RootItem::Importance important) { QList<QPair<int,RootItem::Importance> > changes) {
Q_UNUSED(message_db_id)
Q_UNUSED(important)
Q_UNUSED(selected_item) Q_UNUSED(selected_item)
Q_UNUSED(changes)
return true; return true;
} }

View file

@ -63,8 +63,8 @@ class StandardServiceRoot : public ServiceRoot {
bool onBeforeSetMessagesRead(RootItem *selected_item, QList<int> message_db_ids, ReadStatus read); bool onBeforeSetMessagesRead(RootItem *selected_item, QList<int> message_db_ids, ReadStatus read);
bool onAfterSetMessagesRead(RootItem *selected_item, QList<int> message_db_ids, ReadStatus read); bool onAfterSetMessagesRead(RootItem *selected_item, QList<int> message_db_ids, ReadStatus read);
bool onBeforeSwitchMessageImportance(RootItem *selected_item, int message_db_id, Importance important); bool onBeforeSwitchMessageImportance(RootItem *selected_item, QList<QPair<int,RootItem::Importance> > changes);
bool onAfterSwitchMessageImportance(RootItem *selected_item, int message_db_id, Importance important); bool onAfterSwitchMessageImportance(RootItem *selected_item, QList<QPair<int,RootItem::Importance> > changes);
// Returns all standard categories which are lying under given root node. // Returns all standard categories which are lying under given root node.
// This does NOT include the root node even if the node is category. // This does NOT include the root node even if the node is category.

View file

@ -45,11 +45,11 @@ class TtRssServiceRoot : public ServiceRoot {
return false; return false;
} }
bool onBeforeSwitchMessageImportance(RootItem *selected_item, int message_db_id, Importance important) { bool onBeforeSwitchMessageImportance(RootItem *selected_item, QList<QPair<int,RootItem::Importance> > changes) {
return false; return false;
} }
bool onAfterSwitchMessageImportance(RootItem *selected_item, int message_db_id, Importance important) { bool onAfterSwitchMessageImportance(RootItem *selected_item, QList<QPair<int,RootItem::Importance> > changes) {
return false; return false;
} }
}; };