mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-12-05 00:24:06 +00:00
b5349478cf
The next commit will add `.git-blame-ignore-revs` https://docs.github.com/en/repositories/working-with-files/using-files/viewing-a-file#ignore-commits-in-the-blame-view
196 lines
4.4 KiB
C++
196 lines
4.4 KiB
C++
#include "headwordsmodel.hh"
|
|
#include "wstring_qt.hh"
|
|
|
|
HeadwordListModel::HeadwordListModel( QObject * parent ):
|
|
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::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;
|
|
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;
|
|
}
|
|
}
|
|
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() )
|
|
return {};
|
|
|
|
if ( index.row() >= totalSize || index.row() < 0 || index.row() >= words.size() )
|
|
return {};
|
|
|
|
if ( role == Qt::DisplayRole ) {
|
|
return words.at( index.row() );
|
|
}
|
|
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() );
|
|
}
|
|
|
|
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();
|
|
}
|