changed filtering model to a hand-made solution

This commit is contained in:
csoler 2020-06-10 22:04:34 +02:00
parent 85ce2c0f33
commit 8c3c973d02
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
4 changed files with 117 additions and 76 deletions

View File

@ -42,17 +42,18 @@ static std::ostream& operator<<(std::ostream& o, const QModelIndex& i);// define
RsGxsChannelPostFilesModel::RsGxsChannelPostFilesModel(QObject *parent) RsGxsChannelPostFilesModel::RsGxsChannelPostFilesModel(QObject *parent)
: QAbstractItemModel(parent) : QAbstractItemModel(parent)
{ {
initEmptyHierarchy(mFiles); initEmptyHierarchy();
mTimer = new QTimer; mTimer = new QTimer;
connect(mTimer,SIGNAL(timeout()),this,SLOT(update())); connect(mTimer,SIGNAL(timeout()),this,SLOT(update()));
} }
void RsGxsChannelPostFilesModel::initEmptyHierarchy(std::vector<RsGxsFile>& files) void RsGxsChannelPostFilesModel::initEmptyHierarchy()
{ {
preMods(); preMods();
mFiles.clear(); mFiles.clear();
mFilteredFiles.clear();
postMods(); postMods();
} }
@ -67,12 +68,12 @@ void RsGxsChannelPostFilesModel::postMods()
{ {
endResetModel(); endResetModel();
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mFiles.size(),COLUMN_FILES_NB_COLUMNS-1,(void*)NULL)); emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mFilteredFiles.size(),COLUMN_FILES_NB_COLUMNS-1,(void*)NULL));
} }
void RsGxsChannelPostFilesModel::update() void RsGxsChannelPostFilesModel::update()
{ {
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mFiles.size(),COLUMN_FILES_NB_COLUMNS-1,(void*)NULL)); emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mFilteredFiles.size(),COLUMN_FILES_NB_COLUMNS-1,(void*)NULL));
} }
int RsGxsChannelPostFilesModel::rowCount(const QModelIndex& parent) const int RsGxsChannelPostFilesModel::rowCount(const QModelIndex& parent) const
@ -80,11 +81,11 @@ int RsGxsChannelPostFilesModel::rowCount(const QModelIndex& parent) const
if(parent.column() > 0) if(parent.column() > 0)
return 0; return 0;
if(mFiles.empty()) // security. Should never happen. if(mFilteredFiles.empty()) // security. Should never happen.
return 0; return 0;
if(!parent.isValid()) if(!parent.isValid())
return mFiles.size(); // mFilteredPosts always has an item at 0, so size()>=1, and mColumn>=1 return mFilteredFiles.size(); // mFilteredPosts always has an item at 0, so size()>=1, and mColumn>=1
RsErr() << __PRETTY_FUNCTION__ << " rowCount cannot figure out the porper number of rows." << std::endl; RsErr() << __PRETTY_FUNCTION__ << " rowCount cannot figure out the porper number of rows." << std::endl;
return 0; return 0;
@ -116,7 +117,7 @@ bool RsGxsChannelPostFilesModel::getFileData(const QModelIndex& i,RsGxsFile& fmp
if(!convertRefPointerToTabEntry(ref,entry) || entry >= mFiles.size()) if(!convertRefPointerToTabEntry(ref,entry) || entry >= mFiles.size())
return false ; return false ;
fmpe = mFiles[entry]; fmpe = mFiles[mFilteredFiles[entry]];
return true; return true;
@ -214,7 +215,7 @@ quintptr RsGxsChannelPostFilesModel::getParentRow(quintptr ref,int& row) const
{ {
ChannelPostFilesModelIndex ref_entry; ChannelPostFilesModelIndex ref_entry;
if(!convertRefPointerToTabEntry(ref,ref_entry) || ref_entry >= mFiles.size()) if(!convertRefPointerToTabEntry(ref,ref_entry) || ref_entry >= mFilteredFiles.size())
return 0 ; return 0 ;
if(ref_entry == 0) if(ref_entry == 0)
@ -284,7 +285,7 @@ QVariant RsGxsChannelPostFilesModel::data(const QModelIndex &index, int role) co
return QVariant() ; return QVariant() ;
} }
if(!convertRefPointerToTabEntry(ref,entry) || entry >= mFiles.size()) if(!convertRefPointerToTabEntry(ref,entry) || entry >= mFilteredFiles.size())
{ {
#ifdef DEBUG_CHANNEL_MODEL #ifdef DEBUG_CHANNEL_MODEL
std::cerr << "Bad pointer: " << (void*)ref << std::endl; std::cerr << "Bad pointer: " << (void*)ref << std::endl;
@ -292,7 +293,7 @@ QVariant RsGxsChannelPostFilesModel::data(const QModelIndex &index, int role) co
return QVariant() ; return QVariant() ;
} }
const RsGxsFile& fmpe(mFiles[entry]); const RsGxsFile& fmpe(mFiles[mFilteredFiles[entry]]);
#ifdef TODO #ifdef TODO
if(role == Qt::FontRole) if(role == Qt::FontRole)
@ -331,6 +332,44 @@ QVariant RsGxsChannelPostFilesModel::data(const QModelIndex &index, int role) co
} }
} }
void RsGxsChannelPostFilesModel::setFilter(const QStringList& strings, uint32_t& count)
{
preMods();
beginRemoveRows(QModelIndex(),0,rowCount()-1);
endRemoveRows();
if(strings.empty())
{
mFilteredFiles.clear();
for(int i=0;i<mFiles.size();++i)
mFilteredFiles.push_back(i);
}
else
{
mFilteredFiles.clear();
//mFilteredPosts.push_back(0);
for(int i=0;i<mFiles.size();++i)
{
bool passes_strings = true;
for(auto& s:strings)
passes_strings = passes_strings && QString::fromStdString(mFiles[i].mName).contains(s,Qt::CaseInsensitive);
if(passes_strings)
mFilteredFiles.push_back(i);
}
}
count = mFilteredFiles.size();
std::cerr << "After filtering: " << count << " posts remain." << std::endl;
beginInsertRows(QModelIndex(),0,rowCount()-1);
endInsertRows();
postMods();
}
#ifdef TODO #ifdef TODO
QVariant RsGxsForumModel::textColorRole(const ForumModelPostEntry& fmpe,int /*column*/) const QVariant RsGxsForumModel::textColorRole(const ForumModelPostEntry& fmpe,int /*column*/) const
{ {
@ -613,8 +652,7 @@ void RsGxsChannelPostFilesModel::clear()
{ {
preMods(); preMods();
mFiles.clear(); initEmptyHierarchy();
initEmptyHierarchy(mFiles);
postMods(); postMods();
emit channelLoaded(); emit channelLoaded();
@ -624,15 +662,17 @@ void RsGxsChannelPostFilesModel::setFiles(const std::list<RsGxsFile>& files)
{ {
preMods(); preMods();
beginRemoveRows(QModelIndex(),0,mFiles.size()-1); beginRemoveRows(QModelIndex(),0,mFilteredFiles.size()-1);
endRemoveRows(); endRemoveRows();
mFiles.clear(); initEmptyHierarchy();
initEmptyHierarchy(mFiles);
for(auto& file:files) for(auto& file:files)
mFiles.push_back(file); mFiles.push_back(file);
for(uint32_t i=0;i<mFiles.size();++i)
mFilteredFiles.push_back(i);
#ifdef TODO #ifdef TODO
recursUpdateReadStatusAndTimes(0,has_unread_below,has_read_below) ; recursUpdateReadStatusAndTimes(0,has_unread_below,has_read_below) ;
recursUpdateFilterStatus(0,0,QStringList()); recursUpdateFilterStatus(0,0,QStringList());
@ -642,7 +682,7 @@ void RsGxsChannelPostFilesModel::setFiles(const std::list<RsGxsFile>& files)
// debug_dump(); // debug_dump();
#endif #endif
beginInsertRows(QModelIndex(),0,mFiles.size()-1); beginInsertRows(QModelIndex(),0,mFilteredFiles.size()-1);
endInsertRows(); endInsertRows();
postMods(); postMods();
@ -655,6 +695,7 @@ void RsGxsChannelPostFilesModel::setFiles(const std::list<RsGxsFile>& files)
mTimer->stop(); mTimer->stop();
} }
#ifdef DEBUG_FORUMMODEL
QModelIndex RsGxsChannelPostFilesModel::getIndexOfFile(const RsFileHash& hash) const QModelIndex RsGxsChannelPostFilesModel::getIndexOfFile(const RsFileHash& hash) const
{ {
// Brutal search. This is not so nice, so dont call that in a loop! If too costly, we'll use a map. // Brutal search. This is not so nice, so dont call that in a loop! If too costly, we'll use a map.
@ -671,7 +712,6 @@ QModelIndex RsGxsChannelPostFilesModel::getIndexOfFile(const RsFileHash& hash) c
return QModelIndex(); return QModelIndex();
} }
#ifdef DEBUG_FORUMMODEL
static void recursPrintModel(const std::vector<ForumModelPostEntry>& entries,ForumModelIndex index,int depth) static void recursPrintModel(const std::vector<ForumModelPostEntry>& entries,ForumModelIndex index,int depth)
{ {
const ForumModelPostEntry& e(entries[index]); const ForumModelPostEntry& e(entries[index]);

View File

@ -64,12 +64,13 @@ public:
#endif #endif
QModelIndex root() const{ return createIndex(0,0,(void*)NULL) ;} QModelIndex root() const{ return createIndex(0,0,(void*)NULL) ;}
QModelIndex getIndexOfFile(const RsFileHash& hash) const;
// This method will asynchroneously update the data // This method will asynchroneously update the data
void setFiles(const std::list<RsGxsFile>& files); void setFiles(const std::list<RsGxsFile>& files);
void setFilter(const QStringList &strings, uint32_t &count) ;
#ifdef TODO #ifdef TODO
QModelIndex getIndexOfFile(const RsFileHash& hash) const;
void setSortMode(SortMode mode) ; void setSortMode(SortMode mode) ;
void setTextColorRead (QColor color) { mTextColorRead = color;} void setTextColorRead (QColor color) { mTextColorRead = color;}
@ -77,7 +78,6 @@ public:
void setTextColorUnreadChildren(QColor color) { mTextColorUnreadChildren = color;} void setTextColorUnreadChildren(QColor color) { mTextColorUnreadChildren = color;}
void setTextColorNotSubscribed (QColor color) { mTextColorNotSubscribed = color;} void setTextColorNotSubscribed (QColor color) { mTextColorNotSubscribed = color;}
void setTextColorMissing (QColor color) { mTextColorMissing = color;} void setTextColorMissing (QColor color) { mTextColorMissing = color;}
void setFilter(int column, const QStringList &strings, uint32_t &count) ;
void setAuthorOpinion(const QModelIndex& indx,RsOpinion op); void setAuthorOpinion(const QModelIndex& indx,RsOpinion op);
#endif #endif
@ -149,8 +149,9 @@ private:
#ifdef TODO #ifdef TODO
static void generateMissingItem(const RsGxsMessageId &msgId,ChannelPostsModelPostEntry& entry); static void generateMissingItem(const RsGxsMessageId &msgId,ChannelPostsModelPostEntry& entry);
#endif #endif
void initEmptyHierarchy(std::vector<RsGxsFile> &files); void initEmptyHierarchy();
std::vector<int> mFilteredFiles ; // store the list of files for the post
std::vector<RsGxsFile> mFiles ; // store the list of files for the post std::vector<RsGxsFile> mFiles ; // store the list of files for the post
QTimer *mTimer; QTimer *mTimer;

View File

@ -240,39 +240,39 @@ QSize ChannelPostFilesDelegate::sizeHint(const QStyleOptionViewItem& option, con
} }
} }
class RsGxsChannelPostFilesProxyModel: public QSortFilterProxyModel // class RsGxsChannelPostFilesProxyModel: public QSortFilterProxyModel
{ // {
public: // public:
RsGxsChannelPostFilesProxyModel(QObject *parent = NULL): QSortFilterProxyModel(parent) {} // RsGxsChannelPostFilesProxyModel(QObject *parent = NULL): QSortFilterProxyModel(parent) {}
//
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override // bool lessThan(const QModelIndex& left, const QModelIndex& right) const override
{ // {
return left.data(RsGxsChannelPostFilesModel::SortRole) < right.data(RsGxsChannelPostFilesModel::SortRole) ; // return left.data(RsGxsChannelPostFilesModel::SortRole) < right.data(RsGxsChannelPostFilesModel::SortRole) ;
} // }
//
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override // bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override
{ // {
if(filter_list.empty()) // if(filter_list.empty())
return true; // return true;
//
QString name = sourceModel()->data(sourceModel()->index(source_row,RsGxsChannelPostFilesModel::COLUMN_FILES_NAME,source_parent)).toString(); // QString name = sourceModel()->data(sourceModel()->index(source_row,RsGxsChannelPostFilesModel::COLUMN_FILES_NAME,source_parent)).toString();
//
for(auto& s:filter_list) // for(auto& s:filter_list)
if(!name.contains(s,Qt::CaseInsensitive)) // if(!name.contains(s,Qt::CaseInsensitive))
return false; // return false;
//
return true; // return true;
} // }
//
void setFilterList(const QStringList& str) // void setFilterList(const QStringList& str)
{ // {
filter_list = str; // filter_list = str;
invalidateFilter(); // invalidateFilter();
} // }
//
private: // private:
QStringList filter_list; // QStringList filter_list;
}; // };
/** Constructor */ /** Constructor */
GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupId &channelId, QWidget *parent) : GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupId &channelId, QWidget *parent) :
@ -285,24 +285,25 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI
ui->postsTree->setModel(mChannelPostsModel = new RsGxsChannelPostsModel()); ui->postsTree->setModel(mChannelPostsModel = new RsGxsChannelPostsModel());
ui->postsTree->setItemDelegate(new ChannelPostDelegate()); ui->postsTree->setItemDelegate(new ChannelPostDelegate());
mChannelPostFilesModel = new RsGxsChannelPostFilesModel(this); ui->channelPostFiles_TV->setModel(mChannelPostFilesModel = new RsGxsChannelPostFilesModel(this));
mChannelPostFilesProxyModel = new RsGxsChannelPostFilesProxyModel(this);
mChannelPostFilesProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
mChannelPostFilesProxyModel->setSourceModel(mChannelPostFilesModel);
mChannelPostFilesProxyModel->setDynamicSortFilter(true);
ui->channelPostFiles_TV->setModel(mChannelPostFilesProxyModel);
ui->channelPostFiles_TV->setItemDelegate(new ChannelPostFilesDelegate()); ui->channelPostFiles_TV->setItemDelegate(new ChannelPostFilesDelegate());
ui->channelPostFiles_TV->setPlaceholderText(tr("Post files")); ui->channelPostFiles_TV->setPlaceholderText(tr("No files in this post, or no post selected"));
ui->channelPostFiles_TV->setSortingEnabled(true); ui->channelPostFiles_TV->setSortingEnabled(true);
ui->channelPostFiles_TV->sortByColumn(0, Qt::AscendingOrder); ui->channelPostFiles_TV->sortByColumn(0, Qt::AscendingOrder);
ui->channelFiles_TV->setPlaceholderText(tr("No files in the channel, or no channel selected")); // mChannelPostFilesProxyModel = new RsGxsChannelPostFilesProxyModel(this);
// mChannelPostFilesProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
// mChannelPostFilesProxyModel->setSourceModel(mChannelPostFilesModel);
// mChannelPostFilesProxyModel->setDynamicSortFilter(true);
ui->channelFiles_TV->setModel(mChannelFilesModel = new RsGxsChannelPostFilesModel()); ui->channelFiles_TV->setModel(mChannelFilesModel = new RsGxsChannelPostFilesModel());
ui->channelFiles_TV->setItemDelegate(new ChannelPostFilesDelegate()); ui->channelFiles_TV->setItemDelegate(new ChannelPostFilesDelegate());
ui->channelFiles_TV->setPlaceholderText(tr("No files in the channel, or no channel selected"));
ui->channelFiles_TV->setSortingEnabled(true);
ui->channelFiles_TV->sortByColumn(0, Qt::AscendingOrder);
//connect(ui->channelPostFiles_TV->header(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(sortColumn(int,Qt::SortOrder)));
connect(ui->channelPostFiles_TV->header(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(sortColumn(int,Qt::SortOrder)));
connect(ui->postsTree->selectionModel(),SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),this,SLOT(showPostDetails())); connect(ui->postsTree->selectionModel(),SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),this,SLOT(showPostDetails()));
connect(mChannelPostsModel,SIGNAL(channelLoaded()),this,SLOT(updateChannelFiles())); connect(mChannelPostsModel,SIGNAL(channelLoaded()),this,SLOT(updateChannelFiles()));
@ -364,11 +365,11 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI
}, mEventHandlerId, RsEventType::GXS_CHANNELS ); }, mEventHandlerId, RsEventType::GXS_CHANNELS );
} }
void GxsChannelPostsWidgetWithModel::sortColumn(int col,Qt::SortOrder so) //void GxsChannelPostsWidgetWithModel::sortColumn(int col,Qt::SortOrder so)
{ //{
std::cerr << "Sorting!!"<< std::endl; // std::cerr << "Sorting!!"<< std::endl;
mChannelPostFilesProxyModel->sort(col,so); // mChannelPostFilesProxyModel->sort(col,so);
} //}
void GxsChannelPostsWidgetWithModel::handlePostsTreeSizeChange(QSize s) void GxsChannelPostsWidgetWithModel::handlePostsTreeSizeChange(QSize s)
{ {
@ -469,7 +470,7 @@ void GxsChannelPostsWidgetWithModel::updateChannelFiles()
ui->channelFiles_TV->resizeColumnToContents(RsGxsChannelPostFilesModel::COLUMN_FILES_SIZE); ui->channelFiles_TV->resizeColumnToContents(RsGxsChannelPostFilesModel::COLUMN_FILES_SIZE);
ui->channelFiles_TV->setAutoSelect(true); ui->channelFiles_TV->setAutoSelect(true);
mChannelPostFilesProxyModel->sort(0, Qt::AscendingOrder); //mChannelPostFilesProxyModel->sort(0, Qt::AscendingOrder);
} }
void GxsChannelPostsWidgetWithModel::updateGroupData() void GxsChannelPostsWidgetWithModel::updateGroupData()
@ -786,10 +787,10 @@ void GxsChannelPostsWidgetWithModel::filterChanged(QString s)
QStringList ql = s.split(' ',QString::SkipEmptyParts); QStringList ql = s.split(' ',QString::SkipEmptyParts);
uint32_t count; uint32_t count;
mChannelPostsModel->setFilter(ql,count); mChannelPostsModel->setFilter(ql,count);
mChannelFilesModel->setFilter(ql,count);
mChannelPostFilesProxyModel->setFilterKeyColumn(RsGxsChannelPostFilesModel::COLUMN_FILES_NAME); //mChannelPostFilesProxyModel->setFilterKeyColumn(RsGxsChannelPostFilesModel::COLUMN_FILES_NAME);
mChannelPostFilesProxyModel->setFilterList(ql); //mChannelPostFilesProxyModel->setFilterRegExp(s) ;// triggers a re-display. s is actually not used.
mChannelPostFilesProxyModel->setFilterRegExp(s) ;// triggers a re-display. s is actually not used.
} }
#ifdef TODO #ifdef TODO

View File

@ -140,8 +140,8 @@ private slots:
void handlePostsTreeSizeChange(QSize s); void handlePostsTreeSizeChange(QSize s);
void updateChannelFiles(); void updateChannelFiles();
public slots: // public slots:
void sortColumn(int col,Qt::SortOrder so); // void sortColumn(int col,Qt::SortOrder so);
private: private:
void processSettings(bool load); void processSettings(bool load);
@ -164,7 +164,6 @@ private:
RsGxsChannelPostsModel *mChannelPostsModel; RsGxsChannelPostsModel *mChannelPostsModel;
RsGxsChannelPostFilesModel *mChannelPostFilesModel; RsGxsChannelPostFilesModel *mChannelPostFilesModel;
RsGxsChannelPostFilesModel *mChannelFilesModel; RsGxsChannelPostFilesModel *mChannelFilesModel;
RsGxsChannelPostFilesProxyModel *mChannelPostFilesProxyModel ;
/* UI - from Designer */ /* UI - from Designer */
Ui::GxsChannelPostsWidgetWithModel *ui; Ui::GxsChannelPostsWidgetWithModel *ui;