goldendict-ng/src/headwordsmodel.cc

207 lines
4.4 KiB
C++
Raw Normal View History

#include "headwordsmodel.hh"
#include "wstring_qt.hh"
HeadwordListModel::HeadwordListModel( QObject * parent ) :
2023-04-22 05:32:10 +00:00
QAbstractListModel( parent ), filtering( false ), totalSize(0), index( 0 ),ptr( nullptr )
{
}
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() ), 500 );
connect( sr.get(), &Dictionary::Request::finished, this, &HeadwordListModel::requestFinished, Qt::QueuedConnection );
queuedRequests.push_back( sr );
}
void HeadwordListModel::appendWord( const QString & word )
{
hashedWords.insert( word );
words.append( word );
}
void HeadwordListModel::addMatches( QStringList matches)
{
QStringList filtered;
2023-04-22 05:32:10 +00:00
for ( auto const & w : matches ) {
if ( !containWord( w ) ) {
filtered << w;
}
}
if ( filtered.isEmpty() )
return;
beginInsertRows( QModelIndex(), words.size(), words.size() + filtered.count() - 1 );
for ( const auto & word : filtered ) {
appendWord( word );
}
endInsertRows();
}
void HeadwordListModel::requestFinished()
{
// See how many new requests have finished, and if we have any new results
for( auto 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( QString::fromStdU32String( match.word ) );
}
queuedRequests.erase( i++ );
}
else
++i;
}
if( queuedRequests.empty() )
{
QStringList filtered;
for( auto & w : filterWords )
{
if( !containWord( w ) )
{
filtered << w;
}
}
2022-10-05 07:42:08 +00:00
if( filtered.isEmpty() )
return;
beginInsertRows( QModelIndex(), words.size(), words.size() + filtered.count() - 1 );
for( const auto & word : filtered )
appendWord( word );
endInsertRows();
}
}
int HeadwordListModel::wordCount() const
{
return words.size();
}
QVariant HeadwordListModel::data( const QModelIndex & index, int role ) const
{
if( !index.isValid() )
2023-04-22 04:33:11 +00:00
return {};
if( index.row() >= totalSize || index.row() < 0 || index.row() >= words.size() )
2023-04-22 04:33:11 +00:00
return {};
if( role == Qt::DisplayRole )
{
return words.at( index.row() );
}
2023-04-22 04:33:11 +00:00
return {};
}
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( !containWord( word ) )
filtered.insert( word );
}
beginInsertRows( QModelIndex(), words.size(), words.size() + filtered.count() - 1 );
for( const auto & word : filtered )
{
appendWord( word );
}
endInsertRows();
emit numberPopulated( words.size() );
}
2023-04-22 04:33:11 +00:00
int HeadwordListModel::getCurrentIndex() const
{
return index;
}
bool HeadwordListModel::containWord( const QString & word )
{
return hashedWords.contains( word );
}
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( !containWord( word ) )
filtered.insert( word );
}
return filtered;
}
void HeadwordListModel::setDict( Dictionary::Class * dict )
{
_dict = dict;
totalSize = _dict->getWordCount();
}