goldendict-ng/headwordslistmodel.cpp
Xiao YiFang 4c8ec4e3f2 opt: improve headword dialog performance
especially when the dictionary has a very large collecton of headword.
include export function
2022-10-01 15:33:23 +08:00

162 lines
3.5 KiB
C++

#include "headwordslistmodel.h"
#include "wstring_qt.hh"
HeadwordListModel::HeadwordListModel(QObject *parent)
: QAbstractListModel(parent), index(0),ptr(0)
{}
int HeadwordListModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : words.size();
}
int HeadwordListModel::totalCount() const{
return totalSize;
}
bool HeadwordListModel::isFinish() const{
return words.size() >=totalSize;
}
//export headword
QString HeadwordListModel::getRow(int row)
{
if(fileSortedList.empty()){
fileSortedList<<words;
fileSortedList.sort();
}
return fileSortedList.at(row);
}
void HeadwordListModel::setFilter(QRegularExpression reg){
if(reg.pattern().isEmpty())
return;
filterWords.clear();
auto sr = _dict->prefixMatch(gd::toWString(reg.pattern()),30);
connect( sr.get(), SIGNAL( finished() ),
this, SLOT( requestFinished() ), Qt::QueuedConnection );
queuedRequests.push_back( sr );
}
void HeadwordListModel::requestFinished()
{
// See how many new requests have finished, and if we have any new results
for( std::list< sptr< Dictionary::WordSearchRequest > >::iterator i =
queuedRequests.begin(); i != queuedRequests.end(); )
{
if ( (*i)->isFinished() )
{
if ( !(*i)->getErrorString().isEmpty() )
{
qDebug()<<"error:"<<(*i)->getErrorString();
}
if ( (*i)->matchesCount() )
{
auto allmatches = (*i)->getAllMatches();
for(auto& match:allmatches)
filterWords.append(gd::toQString(match.word));
}
queuedRequests.erase( i++ );
}
else
++i;
}
if(queuedRequests.empty()){
QStringList filtered;
for(auto& w:filterWords){
if(!words.contains(w)){
filtered<<w;
}
}
beginInsertRows(QModelIndex(), words.size(), words.size() + filtered.count() - 1);
for(const auto & word:filtered)
words.append(word);
endInsertRows();
}
}
int HeadwordListModel::wordCount() const{
return words.size();
}
QVariant HeadwordListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row() >= totalSize || index.row() < 0 || index.row()>=words.size())
return QVariant();
if (role == Qt::DisplayRole) {
return words.at(index.row());
}
return QVariant();
}
bool HeadwordListModel::canFetchMore(const QModelIndex &parent) const
{
if (parent.isValid())
return false;
return (words.size() < totalSize);
}
void HeadwordListModel::fetchMore(const QModelIndex &parent)
{
if (parent.isValid())
return;
QSet<QString> headword;
Mutex::Lock _(lock);
_dict->findHeadWordsWithLenth(index,&headword,10000);
if(headword.isEmpty()){
return;
}
QSet<QString> filtered;
for(const auto & word:qAsConst(headword))
{
if(!words.contains(word))
filtered.insert(word);
}
beginInsertRows(QModelIndex(), words.size(), words.size() + filtered.count() - 1);
for(const auto & word:filtered)
{
words.append(word);
}
endInsertRows();
emit numberPopulated(words.size());
}
int HeadwordListModel::getCurrentIndex()
{
return index;
}
QSet<QString> HeadwordListModel::getRemainRows(int & nodeIndex)
{
QSet<QString> headword;
Mutex::Lock _(lock);
_dict->findHeadWordsWithLenth(nodeIndex, &headword,10000);
QSet<QString> filtered;
for(const auto & word:headword)
{
if(!words.contains(word))
filtered.insert(word);
}
return filtered;
}
void HeadwordListModel::setDict(Dictionary::Class * dict){
_dict = dict;
totalSize = _dict->getWordCount();
}