resurrected sorting for pinned posts using a proxy model

This commit is contained in:
csoler 2018-11-27 15:15:54 +01:00
parent 02c6a92f48
commit 561db00255
No known key found for this signature in database
GPG key ID: 7BCA522266C0804C
4 changed files with 76 additions and 20 deletions

View file

@ -276,9 +276,7 @@ QVariant RsGxsForumModel::data(const QModelIndex &index, int role) const
if(role == Qt::FontRole) if(role == Qt::FontRole)
{ {
QFont font ; QFont font ;
font.setBold( (fmpe.mPostFlags & (ForumModelPostEntry::FLAG_POST_HAS_UNREAD_CHILDREN | ForumModelPostEntry::FLAG_POST_IS_PINNED)));
font.setBold(fmpe.mPostFlags & ForumModelPostEntry::FLAG_POST_HAS_UNREAD_CHILDREN);
return QVariant(font); return QVariant(font);
} }
@ -296,6 +294,7 @@ QVariant RsGxsForumModel::data(const QModelIndex &index, int role) const
case Qt::ToolTipRole: return toolTipRole (fmpe,index.column()) ; case Qt::ToolTipRole: return toolTipRole (fmpe,index.column()) ;
case Qt::UserRole: return userRole (fmpe,index.column()) ; case Qt::UserRole: return userRole (fmpe,index.column()) ;
case Qt::TextColorRole: return textColorRole (fmpe,index.column()) ; case Qt::TextColorRole: return textColorRole (fmpe,index.column()) ;
case Qt::BackgroundRole: return backgroundRole(fmpe,index.column()) ;
case ThreadPinnedRole: return pinnedRole (fmpe,index.column()) ; case ThreadPinnedRole: return pinnedRole (fmpe,index.column()) ;
case MissingRole: return missingRole (fmpe,index.column()) ; case MissingRole: return missingRole (fmpe,index.column()) ;
@ -310,7 +309,7 @@ QVariant RsGxsForumModel::textColorRole(const ForumModelPostEntry& fmpe,int colu
if( (fmpe.mPostFlags & ForumModelPostEntry::FLAG_POST_IS_MISSING)) if( (fmpe.mPostFlags & ForumModelPostEntry::FLAG_POST_IS_MISSING))
return QVariant(mTextColorMissing); return QVariant(mTextColorMissing);
if(IS_MSG_UNREAD(fmpe.mMsgStatus)) if(IS_MSG_UNREAD(fmpe.mMsgStatus) || (fmpe.mPostFlags & ForumModelPostEntry::FLAG_POST_IS_PINNED))
return QVariant(mTextColorUnread); return QVariant(mTextColorUnread);
else else
return QVariant(mTextColorRead); return QVariant(mTextColorRead);
@ -382,6 +381,13 @@ QVariant RsGxsForumModel::pinnedRole(const ForumModelPostEntry& fmpe,int column)
return QVariant(false); return QVariant(false);
} }
QVariant RsGxsForumModel::backgroundRole(const ForumModelPostEntry& fmpe,int column) const
{
if(fmpe.mPostFlags & ForumModelPostEntry::FLAG_POST_IS_PINNED)
return QVariant(QBrush(QColor(255,200,180)));
return QVariant();
}
QVariant RsGxsForumModel::sizeHintRole(int col) const QVariant RsGxsForumModel::sizeHintRole(int col) const
{ {
@ -393,6 +399,7 @@ QVariant RsGxsForumModel::sizeHintRole(int col) const
case COLUMN_THREAD_TITLE: return QVariant( QSize(factor * 170, factor*14 )); case COLUMN_THREAD_TITLE: return QVariant( QSize(factor * 170, factor*14 ));
case COLUMN_THREAD_DATE: return QVariant( QSize(factor * 75 , factor*14 )); case COLUMN_THREAD_DATE: return QVariant( QSize(factor * 75 , factor*14 ));
case COLUMN_THREAD_AUTHOR: return QVariant( QSize(factor * 75 , factor*14 )); case COLUMN_THREAD_AUTHOR: return QVariant( QSize(factor * 75 , factor*14 ));
case COLUMN_THREAD_DISTRIBUTION: return QVariant( QSize(factor * 15 , factor*14 ));
} }
} }

View file

@ -141,6 +141,7 @@ public:
QVariant sortRole (const ForumModelPostEntry& fmpe, int col) const; QVariant sortRole (const ForumModelPostEntry& fmpe, int col) const;
QVariant fontRole (const ForumModelPostEntry& fmpe, int col) const; QVariant fontRole (const ForumModelPostEntry& fmpe, int col) const;
QVariant textColorRole (const ForumModelPostEntry& fmpe, int col) const; QVariant textColorRole (const ForumModelPostEntry& fmpe, int col) const;
QVariant backgroundRole(const ForumModelPostEntry& fmpe, int col) const;
/*! /*!
* \brief debug_dump * \brief debug_dump

View file

@ -270,6 +270,41 @@ public:
} }
}; };
class ForumPostSortFilterProxyModel: public QSortFilterProxyModel
{
public:
ForumPostSortFilterProxyModel(const QHeaderView *header,QObject *parent = NULL): QSortFilterProxyModel(parent),m_header(header) {}
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override
{
bool left_is_not_pinned = ! left.data(ROLE_THREAD_PINNED).toBool();
bool right_is_not_pinned = !right.data(ROLE_THREAD_PINNED).toBool();
#ifdef DEBUG_PINNED_POST_SORTING
std::cerr << "Comparing item date \"" << data(RsGxsForumModel::COLUMN_THREAD_DATE,Qt::DisplayRole).toString().toStdString() << "\" ("
<< data(RsGxsForumModel::COLUMN_THREAD_DATE,ROLE_THREAD_SORT).toUInt() << ", \"" << data(RsGxsForumModel::COLUMN_THREAD_DATE,ROLE_THREAD_SORT).toString().toStdString() << "\" --> " << left_is_not_pinned << ") to \""
<< other.data(RsGxsForumModel::COLUMN_THREAD_DATE,Qt::DisplayRole).toString().toStdString() << "\" ("
<< other.data(RsGxsForumModel::COLUMN_THREAD_DATE,ROLE_THREAD_SORT).toUInt() << ", \"" << other.data(RsGxsForumModel::COLUMN_THREAD_DATE,ROLE_THREAD_SORT).toString().toStdString() << "\" --> " << right_is_not_pinned << ") ";
#endif
if(left_is_not_pinned ^ right_is_not_pinned)
{
#ifdef DEBUG_PINNED_POST_SORTING
std::cerr << "Local: " << ((m_header->sortIndicatorOrder()==Qt::AscendingOrder)?right_is_not_pinned:left_is_not_pinned) << std::endl;
#endif
return (m_header->sortIndicatorOrder()==Qt::AscendingOrder)?right_is_not_pinned:left_is_not_pinned ; // always put pinned posts on top
}
#ifdef DEBUG_PINNED_POST_SORTING
std::cerr << "Remote: " << GxsIdRSTreeWidgetItem::operator<(other) << std::endl;
#endif
return left.data(RsGxsForumModel::SortRole) < right.data(RsGxsForumModel::SortRole) ;
}
private:
const QHeaderView *m_header ;
};
void GxsForumThreadWidget::setTextColorRead (QColor color) { mTextColorRead = color; mThreadModel->setTextColorRead (color);} void GxsForumThreadWidget::setTextColorRead (QColor color) { mTextColorRead = color; mThreadModel->setTextColorRead (color);}
void GxsForumThreadWidget::setTextColorUnread (QColor color) { mTextColorUnread = color; mThreadModel->setTextColorUnread (color);} void GxsForumThreadWidget::setTextColorUnread (QColor color) { mTextColorUnread = color; mThreadModel->setTextColorUnread (color);}
void GxsForumThreadWidget::setTextColorUnreadChildren(QColor color) { mTextColorUnreadChildren = color; mThreadModel->setTextColorUnreadChildren(color);} void GxsForumThreadWidget::setTextColorUnreadChildren(QColor color) { mTextColorUnreadChildren = color; mThreadModel->setTextColorUnreadChildren(color);}
@ -329,11 +364,17 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
mInMsgAsReadUnread = false; mInMsgAsReadUnread = false;
mThreadCompareRole = new RSTreeWidgetItemCompareRole; //mThreadCompareRole = new RSTreeWidgetItemCompareRole;
mThreadCompareRole->setRole(RsGxsForumModel::COLUMN_THREAD_DATE, ROLE_THREAD_SORT); //mThreadCompareRole->setRole(RsGxsForumModel::COLUMN_THREAD_DATE, ROLE_THREAD_SORT);
ui->threadTreeWidget->setSortingEnabled(true);
mThreadModel = new RsGxsForumModel(this); mThreadModel = new RsGxsForumModel(this);
ui->threadTreeWidget->setModel(mThreadModel); mThreadProxyModel = new ForumPostSortFilterProxyModel(ui->threadTreeWidget->header(),this);
mThreadProxyModel->setSourceModel(mThreadModel);
ui->threadTreeWidget->setModel(mThreadProxyModel);
ui->threadTreeWidget->setItemDelegateForColumn(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION,new DistributionItemDelegate()) ; ui->threadTreeWidget->setItemDelegateForColumn(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION,new DistributionItemDelegate()) ;
ui->threadTreeWidget->setItemDelegateForColumn(RsGxsForumModel::COLUMN_THREAD_AUTHOR,new AuthorItemDelegate()) ; ui->threadTreeWidget->setItemDelegateForColumn(RsGxsForumModel::COLUMN_THREAD_AUTHOR,new AuthorItemDelegate()) ;
ui->threadTreeWidget->setItemDelegateForColumn(RsGxsForumModel::COLUMN_THREAD_READ,new ReadStatusItemDelegate()) ; ui->threadTreeWidget->setItemDelegateForColumn(RsGxsForumModel::COLUMN_THREAD_READ,new ReadStatusItemDelegate()) ;
@ -442,8 +483,8 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
#ifdef SUSPENDED_CODE #ifdef SUSPENDED_CODE
ui->threadTreeWidget->enableColumnCustomize(true); ui->threadTreeWidget->enableColumnCustomize(true);
ui->threadTreeWidget->sortItems(RsGxsForumModel::COLUMN_THREAD_DATE, Qt::DescendingOrder);
#endif #endif
ui->threadTreeWidget->sortByColumn(RsGxsForumModel::COLUMN_THREAD_DATE, Qt::DescendingOrder);
} }
void GxsForumThreadWidget::blank() void GxsForumThreadWidget::blank()
@ -671,7 +712,7 @@ bool GxsForumThreadWidget::getCurrentPost(ForumModelPostEntry& fmpe) const
if(!index.isValid()) if(!index.isValid())
return false ; return false ;
return mThreadModel->getPostData(index,fmpe); return mThreadModel->getPostData(mThreadProxyModel->mapToSource(index),fmpe);
} }
void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
@ -905,14 +946,16 @@ void GxsForumThreadWidget::changedThread(QModelIndex index)
return; return;
} }
mThreadId = mOrigThreadId = RsGxsMessageId(mThreadModel->data(index.sibling(index.row(),RsGxsForumModel::COLUMN_THREAD_MSGID),Qt::UserRole).toString().toStdString()); mThreadId = mOrigThreadId = RsGxsMessageId(index.sibling(index.row(),RsGxsForumModel::COLUMN_THREAD_MSGID).data(Qt::UserRole).toString().toStdString());
std::cerr << "Switched to new thread ID " << mThreadId << std::endl; std::cerr << "Switched to new thread ID " << mThreadId << std::endl;
//ui->postText->resetImagesStatus(Settings->getForumLoadEmbeddedImages()) ; //ui->postText->resetImagesStatus(Settings->getForumLoadEmbeddedImages()) ;
insertMessage(); insertMessage();
mThreadModel->setMsgReadStatus(index, true,false);
QModelIndex src_index = mThreadProxyModel->mapToSource(index);
mThreadModel->setMsgReadStatus(src_index, true,false);
} }
void GxsForumThreadWidget::clickedThread(QModelIndex index) void GxsForumThreadWidget::clickedThread(QModelIndex index)
@ -932,8 +975,11 @@ void GxsForumThreadWidget::clickedThread(QModelIndex index)
if (index.column() == RsGxsForumModel::COLUMN_THREAD_READ) if (index.column() == RsGxsForumModel::COLUMN_THREAD_READ)
{ {
ForumModelPostEntry fmpe; ForumModelPostEntry fmpe;
mThreadModel->getPostData(index,fmpe);
mThreadModel->setMsgReadStatus(index, IS_MSG_UNREAD(fmpe.mMsgStatus),false); QModelIndex src_index = mThreadProxyModel->mapToSource(index);
mThreadModel->getPostData(src_index,fmpe);
mThreadModel->setMsgReadStatus(src_index, IS_MSG_UNREAD(fmpe.mMsgStatus),false);
} }
else else
changedThread(index); changedThread(index);
@ -1837,7 +1883,7 @@ void GxsForumThreadWidget::insertMessage()
if (index.isValid()) if (index.isValid())
{ {
QModelIndex parentIndex = index.parent(); QModelIndex parentIndex = mThreadProxyModel->mapToSource(index).parent();
int curr_index = index.row(); int curr_index = index.row();
int count = mThreadModel->rowCount(parentIndex); int count = mThreadModel->rowCount(parentIndex);
@ -1950,15 +1996,15 @@ void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg)
if (IS_MSG_NEW(status)) { if (IS_MSG_NEW(status)) {
if (setToReadOnActive) { if (setToReadOnActive) {
/* set to read */ /* set to read */
mThreadModel->setMsgReadStatus(index,true,false); mThreadModel->setMsgReadStatus(mThreadProxyModel->mapToSource(index),true,false);
} else { } else {
/* set to unread by user */ /* set to unread by user */
mThreadModel->setMsgReadStatus(index,false,false); mThreadModel->setMsgReadStatus(mThreadProxyModel->mapToSource(index),false,false);
} }
} else { } else {
if (setToReadOnActive && IS_MSG_UNREAD(status)) { if (setToReadOnActive && IS_MSG_UNREAD(status)) {
/* set to read */ /* set to read */
mThreadModel->setMsgReadStatus(index, true,false); mThreadModel->setMsgReadStatus(mThreadProxyModel->mapToSource(index), true,false);
} }
} }
@ -2004,7 +2050,7 @@ void GxsForumThreadWidget::previousMessage()
if (index > 0) if (index > 0)
{ {
QModelIndex prevItem = mThreadModel->index(index - 1,0,parentIndex) ; QModelIndex prevItem = mThreadProxyModel->index(index - 1,0,parentIndex) ;
if (prevItem.isValid()) { if (prevItem.isValid()) {
ui->threadTreeWidget->setCurrentIndex(prevItem); ui->threadTreeWidget->setCurrentIndex(prevItem);
@ -2027,11 +2073,11 @@ void GxsForumThreadWidget::nextMessage()
QModelIndex parentIndex = current_index.parent(); QModelIndex parentIndex = current_index.parent();
int index = current_index.row(); int index = current_index.row();
int count = mThreadModel->rowCount(parentIndex) ; int count = mThreadProxyModel->rowCount(parentIndex);
if (index < count - 1) if (index < count - 1)
{ {
QModelIndex nextItem = mThreadModel->index(index + 1,0,parentIndex) ; QModelIndex nextItem = mThreadProxyModel->index(index + 1,0,parentIndex) ;
if (nextItem.isValid()) { if (nextItem.isValid()) {
ui->threadTreeWidget->setCurrentIndex(nextItem); ui->threadTreeWidget->setCurrentIndex(nextItem);

View file

@ -27,6 +27,7 @@
#include <retroshare/rsgxsforums.h> #include <retroshare/rsgxsforums.h>
#include "gui/gxs/GxsIdDetails.h" #include "gui/gxs/GxsIdDetails.h"
class QSortFilterProxyModel;
class QTreeWidgetItem; class QTreeWidgetItem;
class RSTreeWidgetItemCompareRole; class RSTreeWidgetItemCompareRole;
class RsGxsForumMsg; class RsGxsForumMsg;
@ -239,6 +240,7 @@ private:
QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > > mPostVersions ; // holds older versions of posts QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > > mPostVersions ; // holds older versions of posts
RsGxsForumModel *mThreadModel; RsGxsForumModel *mThreadModel;
QSortFilterProxyModel *mThreadProxyModel;
Ui::GxsForumThreadWidget *ui; Ui::GxsForumThreadWidget *ui;
}; };