goldendict-ng/headwordsmodel.cpp
2022-10-07 17:39:43 +08:00

177 lines
3.8 KiB
C++

#include "headwordsmodel.h"
#include "wstring_qt.hh"
HeadwordListModel::HeadwordListModel( QObject * parent ) :
QAbstractListModel( parent ), filtering( false ), totalSize(0), 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() )
{
filtering = false;
return;
}
filtering = true;
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;
}
}
if( filtered.isEmpty() )
return;
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() || filtering )
return false;
return ( words.size() < totalSize );
}
void HeadwordListModel::fetchMore( const QModelIndex & parent )
{
if( parent.isValid() || filtering )
return;
QSet< QString > headword;
Mutex::Lock _( lock );
_dict->findHeadWordsWithLenth( index, &headword, 1000 );
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();
}