goldendict-ng/src/headwordsmodel.cc

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

196 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();
2023-04-17 12:55:39 +00:00
auto sr = _dict->prefixMatch( gd::removeTrailingZero( 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;
QMutexLocker _( &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;
QMutexLocker _( &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();
}