added sorting/filtering to FriendListModel

This commit is contained in:
csoler 2019-08-06 22:52:07 +02:00
parent 6c534360f1
commit a4481b80f2
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
3 changed files with 127 additions and 105 deletions

View File

@ -367,30 +367,16 @@ QVariant RsFriendListModel::data(const QModelIndex &index, int role) const
case Qt::DisplayRole: return displayRole(entry,index.column()) ;
case Qt::FontRole: return fontRole(entry,index.column()) ;
case Qt::TextColorRole: return textColorRole(entry,index.column()) ;
case FilterRole: return filterRole(entry,index.column()) ;
default:
return QVariant();
}
// if(role == Qt::FontRole)
// {
// QFont font ;
// font.setBold(fmpe.msgflags & (RS_MSG_NEW | RS_MSG_UNREAD_BY_USER));
//
// return QVariant(font);
// }
// case Qt::DecorationRole: return decorationRole(fmpe,index.column()) ;
// case Qt::ToolTipRole: return toolTipRole (fmpe,index.column()) ;
// case Qt::UserRole: return userRole (fmpe,index.column()) ;
// case Qt::BackgroundRole: return backgroundRole(fmpe,index.column()) ;
//
// case FilterRole: return filterRole (fmpe,index.column()) ;
// case StatusRole: return statusRole (fmpe,index.column()) ;
// case SortRole: return sortRole (fmpe,index.column()) ;
// case MsgFlagsRole: return fmpe.msgflags ;
// case UnreadRole: return fmpe.msgflags & (RS_MSG_NEW | RS_MSG_UNREAD_BY_USER);
// case MsgIdRole: return QString::fromStdString(fmpe.msgId) ;
// case SrcIdRole: return QString::fromStdString(fmpe.srcId.toStdString()) ;
}
QVariant RsFriendListModel::textColorRole(const EntryIndex& fmpe,int column) const
@ -415,39 +401,37 @@ QVariant RsFriendListModel::statusRole(const EntryIndex& fmpe,int column) const
bool RsFriendListModel::passesFilter(const EntryIndex& e,int column) const
{
// QString s ;
// bool passes_strings = true ;
QString s ;
bool passes_strings = true ;
if(!mFilterStrings.empty())
{
switch(mFilterType)
{
case FILTER_TYPE_ID: s = displayRole(e,COLUMN_THREAD_ID).toString();
break;
case FILTER_TYPE_NAME: s = displayRole(e,COLUMN_THREAD_NAME).toString();
//case FILTER_TYPE_NAME: s = sortRole(fmpe,COLUMN_THREAD_AUTHOR).toString();
if(s.isNull())
passes_strings = false;
break;
};
}
if(!s.isNull())
for(auto iter(mFilterStrings.begin()); iter != mFilterStrings.end(); ++iter)
passes_strings = passes_strings && s.contains(*iter,Qt::CaseInsensitive);
// bool passes_quick_view =
// (mQuickViewFilter==QUICK_VIEW_ALL)
// || (std::find(fmpe.msgtags.begin(),fmpe.msgtags.end(),mQuickViewFilter) != fmpe.msgtags.end())
// || (mQuickViewFilter==QUICK_VIEW_STARRED && (fmpe.msgflags & RS_MSG_STAR))
// || (mQuickViewFilter==QUICK_VIEW_SYSTEM && (fmpe.msgflags & RS_MSG_SYSTEM));
//
// if(!mFilterStrings.empty())
// {
// switch(mFilterType)
// {
// case FILTER_TYPE_ID: s = displayRole(fmpe,COLUMN_THREAD_SUBJECT).toString();
// break;
//
// case FILTER_TYPE_NAME: s = sortRole(fmpe,COLUMN_THREAD_AUTHOR).toString();
// if(s.isNull())
// passes_strings = false;
// break;
// };
// }
//
// if(!s.isNull())
// for(auto iter(mFilterStrings.begin()); iter != mFilterStrings.end(); ++iter)
// passes_strings = passes_strings && s.contains(*iter,Qt::CaseInsensitive);
//
// bool passes_quick_view =
// (mQuickViewFilter==QUICK_VIEW_ALL)
// || (std::find(fmpe.msgtags.begin(),fmpe.msgtags.end(),mQuickViewFilter) != fmpe.msgtags.end())
// || (mQuickViewFilter==QUICK_VIEW_STARRED && (fmpe.msgflags & RS_MSG_STAR))
// || (mQuickViewFilter==QUICK_VIEW_SYSTEM && (fmpe.msgflags & RS_MSG_SYSTEM));
// #ifdef DEBUG_MESSAGE_MODEL
// std::cerr << "Passes filter: type=" << mFilterType << " s=\"" << s.toStdString() << "MsgFlags=" << fmpe.msgflags << " msgtags=" ;
// foreach(uint32_t i,fmpe.msgtags) std::cerr << i << " " ;
// std::cerr << "\" strings:" << passes_strings << " quick_view:" << passes_quick_view << std::endl;
// #endif
//
// return passes_quick_view && passes_strings;
// return passes_quick_view && passes_strings;
return passes_strings;
}
QVariant RsFriendListModel::filterRole(const EntryIndex& e,int column) const
@ -521,24 +505,25 @@ QVariant RsFriendListModel::sizeHintRole(int col) const
QVariant RsFriendListModel::sortRole(const EntryIndex& fmpe,int column) const
{
// switch(column)
// {
// case COLUMN_THREAD_DATE: return QVariant(QString::number(fmpe.ts)); // we should probably have leading zeroes here
return displayRole(fmpe,column);
// switch(column)
// {
// case COLUMN_THREAD_NAME: return QVariant(QString::number(fmpe.ts)); // we should probably have leading zeroes here
//
// case COLUMN_THREAD_READ: return QVariant((bool)IS_MESSAGE_UNREAD(fmpe.msgflags));
// case COLUMN_THREAD_ID: return QVariant((bool)IS_MESSAGE_UNREAD(fmpe.msgflags));
//
// case COLUMN_THREAD_STAR: return QVariant((fmpe.msgflags & RS_MSG_STAR)? 1:0);
// case COLUMN_THREAD_IP: return QVariant((fmpe.msgflags & RS_MSG_STAR)? 1:0);
//
// case COLUMN_THREAD_AUTHOR:{
// QString name;
// case COLUMN_THREAD_LAST_CONTACT:
// QString name;
//
// if(GxsIdTreeItemDelegate::computeName(RsGxsId(fmpe.srcId.toStdString()),name))
// return name;
// }
// default:
// return displayRole(fmpe,column);
// }
return QVariant();
// if(GxsIdTreeItemDelegate::computeName(RsGxsId(fmpe.srcId.toStdString()),name))
// return name;
// }
// default:
// }
// return QVariant();
}
QVariant RsFriendListModel::fontRole(const EntryIndex& e, int col) const

View File

@ -107,6 +107,36 @@
Q_DECLARE_METATYPE(ElidedLabel*)
class FriendListSortFilterProxyModel: public QSortFilterProxyModel
{
public:
FriendListSortFilterProxyModel(const QHeaderView *header,QObject *parent = NULL): QSortFilterProxyModel(parent),m_header(header) , m_sortingEnabled(false) {}
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override
{
return left.data(RsFriendListModel::SortRole) < right.data(RsFriendListModel::SortRole) ;
}
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override
{
return sourceModel()->index(source_row,0,source_parent).data(RsFriendListModel::FilterRole).toString() == RsFriendListModel::FilterString ;
}
void sort( int column, Qt::SortOrder order = Qt::AscendingOrder ) override
{
if(m_sortingEnabled)
return QSortFilterProxyModel::sort(column,order) ;
}
void setSortingEnabled(bool b) { m_sortingEnabled = b ; }
void setSortByState(bool b) { m_sortByState = b ; }
private:
const QHeaderView *m_header ;
bool m_sortingEnabled;
bool m_sortByState;
};
NewFriendList::NewFriendList(QWidget *parent) :
QWidget(parent),
ui(new Ui::NewFriendList()),
@ -135,24 +165,36 @@ NewFriendList::NewFriendList(QWidget *parent) :
ui->filterLineEdit->showFilterIcon();
mModel = new RsFriendListModel();
ui->peerTreeWidget->setModel(mModel);
mProxyModel = new FriendListSortFilterProxyModel(ui->peerTreeWidget->header(),this);
mProxyModel->setSourceModel(mModel);
mProxyModel->setSortRole(RsFriendListModel::SortRole);
mProxyModel->setDynamicSortFilter(false);
mProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
mProxyModel->setFilterRole(RsFriendListModel::FilterRole);
mProxyModel->setFilterRegExp(QRegExp(RsFriendListModel::FilterString));
ui->peerTreeWidget->setModel(mProxyModel);
connect(NotifyQt::getInstance(), SIGNAL(friendsChanged()), mModel, SLOT(updateInternalData()));
/* Add filter actions */
// QTreeWidgetItem *headerItem = ui->peerTreeWidget->headerItem();
// QString headerText = headerItem->text(COLUMN_NAME);
// ui->filterLineEdit->addFilter(QIcon(), headerText, COLUMN_NAME, QString("%1 %2").arg(tr("Search"), headerText));
// ui->filterLineEdit->addFilter(QIcon(), tr("ID"), COLUMN_ID, tr("Search ID"));
QString headerText = mModel->headerData(RsFriendListModel::COLUMN_THREAD_NAME,Qt::Horizontal,Qt::DisplayRole).toString();
ui->filterLineEdit->addFilter(QIcon(), headerText, RsFriendListModel::COLUMN_THREAD_NAME, QString("%1 %2").arg(tr("Search"), headerText));
ui->filterLineEdit->addFilter(QIcon(), tr("ID"), RsFriendListModel::COLUMN_THREAD_ID, tr("Search ID"));
mActionSortByState = new QAction(tr("Sort by state"), this);
mActionSortByState = new QAction(tr("Display online friends on top"), this);
mActionSortByState->setCheckable(true);
connect(mActionSortByState, SIGNAL(toggled(bool)), this, SLOT(sortByState(bool)));
// ui->peerTreeWidget->addContextMenuAction(mActionSortByState);
connect(mActionSortByState, SIGNAL(toggled(bool)), this, SLOT(toggleSortByState(bool)));
//setting default filter by column as subject
ui->filterLineEdit->setCurrentFilter(RsFriendListModel::COLUMN_THREAD_NAME);
ui->peerTreeWidget->setSortingEnabled(true);
/* Set sort */
sortByColumn(RsFriendListModel::COLUMN_THREAD_NAME, Qt::AscendingOrder);
sortByState(false);
toggleSortByState(false);
connect(ui->peerTreeWidget->header(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(sortColumn(int,Qt::SortOrder)));
// workaround for Qt bug, should be solved in next Qt release 4.7.0
// http://bugreports.qt.nokia.com/browse/QTBUG-8270
@ -194,6 +236,13 @@ NewFriendList::~NewFriendList()
delete ui;
}
void NewFriendList::sortColumn(int col,Qt::SortOrder so)
{
mProxyModel->setSortingEnabled(true);
mProxyModel->sort(col,so);
mProxyModel->setSortingEnabled(false);
}
void NewFriendList::headerContextMenuRequested(QPoint p)
{
QMenu displayMenu(tr("Show Items"), this);
@ -268,7 +317,7 @@ void NewFriendList::processSettings(bool load)
setShowGroups(Settings->value("showGroups", mShowGroups).toBool());
// sort
sortByState(Settings->value("sortByState", isSortByState()).toBool());
toggleSortByState(Settings->value("sortByState", isSortByState()).toBool());
// open groups
int arrayIndex = Settings->beginReadArray("Groups");
@ -311,6 +360,11 @@ void NewFriendList::processSettings(bool load)
}
}
void NewFriendList::toggleSortByState(bool sort)
{
mProxyModel->setSortByState(sort);
}
void NewFriendList::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
@ -329,7 +383,7 @@ void NewFriendList::changeEvent(QEvent *e)
*/
void NewFriendList::peerTreeWidgetCustomPopupMenu()
{
QModelIndex index = getCurrentIndex();
QModelIndex index = getCurrentSourceIndex();
RsFriendListModel::EntryType type = mModel->getType(index);
QMenu contextMenu(this);
@ -359,6 +413,7 @@ void NewFriendList::peerTreeWidgetCustomPopupMenu()
QWidgetAction *widgetAction = new QWidgetAction(this);
widgetAction->setDefaultWidget(widget);
contextMenu.addAction(widgetAction);
contextMenu.addAction(mActionSortByState);
// create menu entries
if(index.isValid())
@ -739,20 +794,20 @@ std::string NewFriendList::getSelectedGroupId() const
return ginfo.id.toStdString();
}
QModelIndex NewFriendList::getCurrentIndex() const
QModelIndex NewFriendList::getCurrentSourceIndex() const
{
QModelIndexList selectedIndexes = ui->peerTreeWidget->selectionModel()->selectedIndexes();
if(selectedIndexes.size() != RsFriendListModel::COLUMN_THREAD_NB_COLUMNS) // check that a single row is selected
return QModelIndex();
return *selectedIndexes.begin();
return mProxyModel->mapToSource(*selectedIndexes.begin());
}
bool NewFriendList::getCurrentGroup(RsGroupInfo& info) const
{
/* get the current, and extract the Id */
QModelIndex index = getCurrentIndex();
QModelIndex index = getCurrentSourceIndex();
if(!index.isValid())
return false;
@ -763,7 +818,7 @@ bool NewFriendList::getCurrentNode(RsFriendListModel::RsNodeDetails& prof) const
{
/* get the current, and extract the Id */
QModelIndex index = getCurrentIndex();
QModelIndex index = getCurrentSourceIndex();
if(!index.isValid())
return false;
@ -774,7 +829,7 @@ bool NewFriendList::getCurrentProfile(RsFriendListModel::RsProfileDetails& prof)
{
/* get the current, and extract the Id */
QModelIndex index = getCurrentIndex();
QModelIndex index = getCurrentSourceIndex();
if(!index.isValid())
return false;
@ -1367,27 +1422,6 @@ void NewFriendList::setShowState(bool show)
}
}
void NewFriendList::sortByState(bool sort)
{
// int columnCount = ui->peerTreeWidget->columnCount();
// for (int i = 0; i < columnCount; ++i) {
// mCompareRole->setRole(i, ROLE_SORT_GROUP);
// mCompareRole->addRole(i, ROLE_SORT_STANDARD_GROUP);
//
// if (sort) {
// mCompareRole->addRole(i, ROLE_SORT_STATE);
// mCompareRole->addRole(i, ROLE_SORT_NAME);
// } else {
// mCompareRole->addRole(i, ROLE_SORT_NAME);
// mCompareRole->addRole(i, ROLE_SORT_STATE);
// }
// }
//
// mActionSortByState->setChecked(sort);
//
// ui->peerTreeWidget->resort();
}
bool NewFriendList::isSortByState()
{
return mActionSortByState->isChecked();

View File

@ -35,16 +35,17 @@ namespace Ui {
class RSTreeWidgetItemCompareRole;
class QTreeWidgetItem;
class QToolButton;
class FriendListSortFilterProxyModel;
class NewFriendList: public QWidget
{
Q_OBJECT
Q_PROPERTY(QColor textColorGroup READ textColorGroup WRITE setTextColorGroup)
Q_PROPERTY(QColor textColorStatusOffline READ textColorStatusOffline WRITE setTextColorStatusOffline)
Q_PROPERTY(QColor textColorStatusAway READ textColorStatusAway WRITE setTextColorStatusAway)
Q_PROPERTY(QColor textColorStatusBusy READ textColorStatusBusy WRITE setTextColorStatusBusy)
Q_PROPERTY(QColor textColorStatusOnline READ textColorStatusOnline WRITE setTextColorStatusOnline)
Q_PROPERTY(QColor textColorGroup READ textColorGroup WRITE setTextColorGroup)
Q_PROPERTY(QColor textColorStatusOffline READ textColorStatusOffline WRITE setTextColorStatusOffline)
Q_PROPERTY(QColor textColorStatusAway READ textColorStatusAway WRITE setTextColorStatusAway)
Q_PROPERTY(QColor textColorStatusBusy READ textColorStatusBusy WRITE setTextColorStatusBusy)
Q_PROPERTY(QColor textColorStatusOnline READ textColorStatusOnline WRITE setTextColorStatusOnline)
Q_PROPERTY(QColor textColorStatusInactive READ textColorStatusInactive WRITE setTextColorStatusInactive)
public:
@ -80,7 +81,7 @@ public:
public slots:
void filterItems(const QString &text);
void sortByState(bool sort);
void toggleSortByState(bool sort);
void toggleColumnVisible();
void setShowGroups(bool show);
@ -89,6 +90,7 @@ public slots:
void headerContextMenuRequested(QPoint);
private slots:
void sortColumn(int col,Qt::SortOrder so);
protected:
void changeEvent(QEvent *e);
@ -99,7 +101,7 @@ private:
RsFriendListModel *mModel;
QAction *mActionSortByState;
QModelIndex getCurrentIndex() const;
QModelIndex getCurrentSourceIndex() const;
bool getCurrentNode(RsFriendListModel::RsNodeDetails& prof) const;
bool getCurrentGroup(RsGroupInfo& prof) const;
@ -123,6 +125,7 @@ private:
bool exportFriendlist(QString &fileName);
bool importFriendlist(QString &fileName, bool &errorPeers, bool &errorGroups);
FriendListSortFilterProxyModel *mProxyModel ;
private slots:
void groupsChanged();
void peerTreeWidgetCustomPopupMenu();