From b5d005d3eddc0b9cc25e6127048ed7349169a7af Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Fri, 3 Jun 2022 12:32:27 +0800 Subject: [PATCH 01/10] opt: clear the delayedHighlight text earlier --- articleview.cc | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/articleview.cc b/articleview.cc index a5443044..e9e90d55 100644 --- a/articleview.cc +++ b/articleview.cc @@ -402,8 +402,11 @@ void ArticleView::showDefinition( Config::InputPhrase const & phrase, unsigned g if ( scrollTo.size() ) Utils::Url::addQueryItem( req, "scrollto", scrollTo ); - if(delayedHighlightText.size()) + if( delayedHighlightText.size() ) + { Utils::Url::addQueryItem( req, "regexp", delayedHighlightText ); + delayedHighlightText.clear(); + } Contexts::Iterator pos = contexts.find( "gdanchor" ); if( pos != contexts.end() ) @@ -582,12 +585,6 @@ void ArticleView::loadFinished( bool result ) } if( Utils::Url::hasQueryItem( ui.definition->url(), "regexp" ) ) highlightFTSResults(); - - if( !delayedHighlightText.isEmpty() ) - { - // findText( delayedHighlightText, QWebEnginePage::FindCaseSensitively ,[](bool){}); - delayedHighlightText.clear(); - } } void ArticleView::loadProgress(int ){ From c397af52419b8b67775a4d0c1ff6277b504da187 Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Fri, 3 Jun 2022 12:39:05 +0800 Subject: [PATCH 02/10] style: minor change .mdict css style remove .mdict's margin-top: 1em add .gddictnamebodyseparator with clear:both --- article-style-st-lingoes.css | 3 +-- article-style.css | 7 ++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/article-style-st-lingoes.css b/article-style-st-lingoes.css index fdae35d1..9f31b39e 100644 --- a/article-style-st-lingoes.css +++ b/article-style-st-lingoes.css @@ -95,7 +95,6 @@ body .gddictnamebodyseparator { - display: inline-block; - width: 100%; + clear: both; border-top: 1px solid #92b0dd; } diff --git a/article-style.css b/article-style.css index 071a1dc8..d53beb1e 100644 --- a/article-style.css +++ b/article-style.css @@ -41,6 +41,11 @@ pre /*background: #ffffdd;*/ } +.gddictnamebodyseparator +{ + clear: both; +} + /* The 'From ' string which precedes dictionary name in the heading */ .gdfromprefix { @@ -525,7 +530,7 @@ div.xdxf /************* MDict dictionaries **************/ .mdict { - margin-top: 1em; + /* margin-top: 1em; */ } .mdict a[name] From 7f62859b1f3c1615a56114748140ec62f88c4135 Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Fri, 3 Jun 2022 12:41:13 +0800 Subject: [PATCH 03/10] style: content-intrinsic-size increase to 600px --- article-style.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/article-style.css b/article-style.css index d53beb1e..0cd9103c 100644 --- a/article-style.css +++ b/article-style.css @@ -63,8 +63,8 @@ pre background: #fefdeb; /*fix for invalid blg*/ font-style:normal; - content-visibility:auto; - contain-intrinsic-size:400px; + content-visibility: auto; + contain-intrinsic-size: 600px; } /* CSS trick to prevent the floating elements to overflow From 0eb89a68cb589119dda74aabd47bbd7eebb8e03f Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Fri, 3 Jun 2022 12:50:59 +0800 Subject: [PATCH 04/10] pro file add date to version --- goldendict.pro | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/goldendict.pro b/goldendict.pro index d7fd2c34..440dda9a 100644 --- a/goldendict.pro +++ b/goldendict.pro @@ -15,11 +15,10 @@ system(git describe --tags --always --dirty): hasGit=1 win32{ # date /T output is locale aware. - DD=$$system(date /T) - DATE =$$replace(DD, / , ) + DATE=$$system(date /T) } else{ - DATE=$$system(date '+%y%m%d') + DATE=$$system(date '+%Y/%m/%d') } system(echo $${VERSION}.$${GIT_HASH} on $${DATE} > version.txt) From 80021a6328820c7a59238d48020302630f713b9f Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Fri, 3 Jun 2022 13:09:18 +0800 Subject: [PATCH 05/10] opt: findText will clear the last findText , so this line is useless it will override by the following findText --- articleview.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articleview.cc b/articleview.cc index e9e90d55..b1eace83 100644 --- a/articleview.cc +++ b/articleview.cc @@ -2569,7 +2569,7 @@ void ArticleView::highlightFTSResults() if( !allMatches.isEmpty() ) { - highlightAllFtsOccurences( flags ); +// highlightAllFtsOccurences( flags ); ui.definition->findText( allMatches.at( 0 ), flags ); // if( ui.definition->findText( allMatches.at( 0 ), flags ) ) { From e26db104f710d0c057d657e4e82c12cd53082e9e Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Fri, 3 Jun 2022 15:33:16 +0800 Subject: [PATCH 06/10] fix: regression introduce by replacing qBinaryFind --- btreeidx.cc | 2 +- fulltextsearch.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/btreeidx.cc b/btreeidx.cc index 39dad39a..0ce035cb 100644 --- a/btreeidx.cc +++ b/btreeidx.cc @@ -1402,7 +1402,7 @@ void BtreeIndex::getHeadwordsFromOffsets( QList & offsets, QList::Iterator it = std::lower_bound( begOffsets, endOffsets, articleOffset ); - if( it!=offsets.end()) + if( it != offsets.end() && *it == articleOffset ) { if( isCancelled && Utils::AtomicInt::loadAcquire( *isCancelled ) ) return; diff --git a/fulltextsearch.cc b/fulltextsearch.cc index 7ad1e5d2..57842817 100644 --- a/fulltextsearch.cc +++ b/fulltextsearch.cc @@ -621,7 +621,7 @@ Q_UNUSED( parent ); for( int x = 0; x < hws.length(); x++ ) { QList< FtsHeadword >::iterator it = std::lower_bound( headwords.begin(), headwords.end(), hws.at( x ) ); - if( it != headwords.end() ) + if( it != headwords.end() && *it == hws.at( x ) ) { it->dictIDs.push_back( hws.at( x ).dictIDs.front() ); for( QStringList::const_iterator itr = it->foundHiliteRegExps.constBegin(); From 647041cec3efa79394670795bc73015a8c02f6e5 Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Fri, 3 Jun 2022 15:19:58 +0800 Subject: [PATCH 07/10] feat:add cjk fulltext search --- btreeidx.cc | 5 +- ftshelpers.cc | 152 +++++++++++++++++++++++++++------------------- fulltextsearch.cc | 20 +++--- 3 files changed, 105 insertions(+), 72 deletions(-) diff --git a/btreeidx.cc b/btreeidx.cc index 0ce035cb..3f55f051 100644 --- a/btreeidx.cc +++ b/btreeidx.cc @@ -1399,6 +1399,7 @@ void BtreeIndex::getHeadwordsFromOffsets( QList & offsets, for( unsigned i = 0; i < result.size(); i++ ) { uint32_t articleOffset = result.at(i).articleOffset; + QList::Iterator it = std::lower_bound( begOffsets, endOffsets, articleOffset ); @@ -1407,7 +1408,9 @@ void BtreeIndex::getHeadwordsFromOffsets( QList & offsets, if( isCancelled && Utils::AtomicInt::loadAcquire( *isCancelled ) ) return; - headwords.append( QString::fromUtf8( ( result[ i ].prefix + result[ i ].word ).c_str() ) ); + auto word = QString::fromUtf8( ( result[ i ].prefix + result[ i ].word ).c_str() ); + + headwords.append( word ); offsets.erase( it); begOffsets = offsets.begin(); endOffsets = offsets.end(); diff --git a/ftshelpers.cc b/ftshelpers.cc index 1b7942cb..30517ae5 100644 --- a/ftshelpers.cc +++ b/ftshelpers.cc @@ -39,16 +39,26 @@ bool ftsIndexIsOldOrBad( string const & indexFile, static QString makeHiliteRegExpString( QStringList const & words, int searchMode, - int distanceBetweenWords ) + int distanceBetweenWords, bool hasCJK = false ) { QString searchString( "(" ); QString stripWords( "(?:\\W+\\w+){0," ); if( distanceBetweenWords >= 0 ) stripWords += QString::number( distanceBetweenWords ); - stripWords += "}\\W+"; + stripWords += "}"; + + if(!hasCJK) + { + stripWords += "\\W+"; + } QString boundWord( searchMode == FTS::WholeWords ? "\\b" : "(?:\\w*)"); + if(hasCJK) + { + //no boundary for CJK + boundWord.clear(); + } for( int x = 0; x < words.size(); x++ ) { @@ -62,6 +72,54 @@ static QString makeHiliteRegExpString( QStringList const & words, return searchString; } +void tokenizeCJK( QStringList & indexWords, QRegularExpression wordRegExp, QStringList list ) +{ + QStringList wordList, hieroglyphList; + for( int i = 0; i < list.size(); i ++ ) + { + QString word = list.at( i ); + + // Check for CJK symbols in word + bool parsed = false; + QString hieroglyph; + for( int x = 0; x < word.size(); x++ ) + if( isCJKChar( word.at( x ).unicode() ) ) + { + parsed = true; + hieroglyph.append( word[ x ] ); + + if( QChar( word.at( x ) ).isHighSurrogate() + && QChar( word[ x + 1 ] ).isLowSurrogate() ) + hieroglyph.append( word[ ++x ] ); + + hieroglyphList.append( hieroglyph ); + hieroglyph.clear(); + } + + // If word don't contains CJK symbols put it in list as is + if( !parsed ) + wordList.append( word ); + } + + indexWords = wordList.filter( wordRegExp ); + indexWords.removeDuplicates(); + + hieroglyphList.removeDuplicates(); + indexWords += hieroglyphList; +} + +bool containCJK( QString const & str) +{ + bool hasCJK = false; + for( int x = 0; x < str.size(); x++ ) + if( isCJKChar( str.at( x ).unicode() ) ) + { + hasCJK = true; + break; + } + return hasCJK; +} + bool parseSearchString( QString const & str, QStringList & indexWords, QStringList & searchWords, QRegExp & searchRegExp, int searchMode, @@ -76,38 +134,35 @@ bool parseSearchString( QString const & str, QStringList & indexWords, QRegularExpression setsRegExp( "\\[[^\\]]+\\]", QRegularExpression::CaseInsensitiveOption ); QRegularExpression regexRegExp( "\\\\[afnrtvdDwWsSbB]|\\\\x([0-9A-Fa-f]{4})|\\\\0([0-7]{3})", QRegularExpression::CaseInsensitiveOption); - hasCJK = false; - for( int x = 0; x < str.size(); x++ ) - if( isCJKChar( str.at( x ).unicode() ) ) - { - hasCJK = true; - break; - } + hasCJK = containCJK( str ); if( searchMode == FTS::WholeWords || searchMode == FTS::PlainText ) { - if( hasCJK ) - return false; - // Make words list for search in article text - searchWords = str.normalized( QString::NormalizationForm_C ) - .split( spacesRegExp, Qt::SkipEmptyParts ); - + searchWords = str.normalized( QString::NormalizationForm_C ).split( spacesRegExp, Qt::SkipEmptyParts ); // Make words list for index search - QStringList list = str.normalized( QString::NormalizationForm_C ) - .toLower().split( spacesRegExp, Qt::SkipEmptyParts ); - indexWords = list.filter( wordRegExp ); - indexWords.removeDuplicates(); + QStringList list = + str.normalized( QString::NormalizationForm_C ).toLower().split( spacesRegExp, Qt::SkipEmptyParts ); - // Make regexp for results hilite + QString searchString; + if( hasCJK ) + { + tokenizeCJK( indexWords, wordRegExp, list ); + // QStringList allWords = str.split( spacesRegExp, Qt::SkipEmptyParts ); + searchString = makeHiliteRegExpString( indexWords, searchMode, distanceBetweenWords, hasCJK ); + } + else + { + indexWords = list.filter( wordRegExp ); + indexWords.removeDuplicates(); - QStringList allWords = str.split( spacesRegExp, Qt::SkipEmptyParts ); - QString searchString = makeHiliteRegExpString( allWords, searchMode, distanceBetweenWords ); + // Make regexp for results hilite - searchRegExp = QRegExp( searchString, matchCase ? Qt::CaseSensitive : Qt::CaseInsensitive, - QRegExp::RegExp2 ); + QStringList allWords = str.split( spacesRegExp, Qt::SkipEmptyParts ); + searchString = makeHiliteRegExpString( allWords, searchMode, distanceBetweenWords ); + } + searchRegExp = QRegExp( searchString, matchCase ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::RegExp2 ); searchRegExp.setMinimal( true ); - return !indexWords.isEmpty(); } else @@ -128,38 +183,7 @@ bool parseSearchString( QString const & str, QStringList & indexWords, if( hasCJK ) { - QStringList wordList, hieroglyphList; - for( int i = 0; i < list.size(); i ++ ) - { - QString word = list.at( i ); - - // Check for CJK symbols in word - bool parsed = false; - QString hieroglyph; - for( int x = 0; x < word.size(); x++ ) - if( isCJKChar( word.at( x ).unicode() ) ) - { - parsed = true; - hieroglyph.append( word[ x ] ); - - if( QChar( word.at( x ) ).isHighSurrogate() - && QChar( word[ x + 1 ] ).isLowSurrogate() ) - hieroglyph.append( word[ ++x ] ); - - hieroglyphList.append( hieroglyph ); - hieroglyph.clear(); - } - - // If word don't contains CJK symbols put it in list as is - if( !parsed ) - wordList.append( word ); - } - - indexWords = wordList.filter( wordRegExp ); - indexWords.removeDuplicates(); - - hieroglyphList.removeDuplicates(); - indexWords += hieroglyphList; + tokenizeCJK( indexWords, wordRegExp, list ); } else { @@ -543,6 +567,7 @@ void FTSResultsRequest::checkArticles( QVector< uint32_t > const & offsets, int n; for( n = 0; n < parsedWords.size(); n++ ) { + auto parsed_word = parsedWords.at( n ); if( ignoreWordsOrder ) { int i; @@ -550,8 +575,8 @@ void FTSResultsRequest::checkArticles( QVector< uint32_t > const & offsets, { if( wordsList.at( i ).second ) { - if( ( searchMode == FTS::WholeWords && parsedWords.at( n ).compare( wordsList.at( i ).first, cs ) == 0 ) - || ( searchMode == FTS::PlainText && parsedWords.at( n ).contains( wordsList.at( i ).first, cs ) ) ) + if( ( searchMode == FTS::WholeWords && parsed_word.compare( wordsList.at( i ).first, cs ) == 0 ) + || ( searchMode == FTS::PlainText && parsed_word.contains( wordsList.at( i ).first, cs ) ) ) { wordsList[ i ].second = false; @@ -630,8 +655,13 @@ void FTSResultsRequest::checkArticles( QVector< uint32_t > const & offsets, } else { - if( ( searchMode == FTS::WholeWords && parsedWords.at( n ).compare( words.at( matchWordNom ), cs ) == 0 ) - || ( searchMode == FTS::PlainText && parsedWords.at( n ).contains( words.at( matchWordNom ), cs ) ) ) + //for cjk word, FTS::WholeWords and FTS::PlainText actually have same effect. + auto match_word = words.at( matchWordNom ); + bool hasCJK = containCJK( match_word ); + if( ( searchMode == FTS::WholeWords && + ( ( !hasCJK&& parsed_word.compare( match_word, cs ) == 0 ) || + ( hasCJK && parsed_word.contains( match_word, cs ) ) ) ) + || ( searchMode == FTS::PlainText && parsed_word.contains( match_word, cs ) ) ) { matchWordNom += 1; diff --git a/fulltextsearch.cc b/fulltextsearch.cc index 57842817..749a2a94 100644 --- a/fulltextsearch.cc +++ b/fulltextsearch.cc @@ -353,16 +353,16 @@ void FullTextSearchDialog::accept() distanceBetweenWords, hasCJK ) ) { - if( hasCJK && ( mode == WholeWords || mode == PlainText ) ) - { - QMessageBox message( QMessageBox::Warning, - "GoldenDict", - tr( "CJK symbols in search string are not compatible with search modes \"Whole words\" and \"Plain text\"" ), - QMessageBox::Ok, - this ); - message.exec(); - } - else +// if( hasCJK && ( mode == WholeWords || mode == PlainText ) ) +// { +// QMessageBox message( QMessageBox::Warning, +// "GoldenDict", +// tr( "CJK symbols in search string are not compatible with search modes \"Whole words\" and \"Plain text\"" ), +// QMessageBox::Ok, +// this ); +// message.exec(); +// } +// else { QMessageBox message( QMessageBox::Warning, "GoldenDict", From 5fc3bd8d833b31df9e39e9e3881509af9e8ae52c Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Fri, 3 Jun 2022 20:47:42 +0800 Subject: [PATCH 08/10] modify clang format --- .clang-format | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/.clang-format b/.clang-format index 5345366d..af33ee77 100644 --- a/.clang-format +++ b/.clang-format @@ -1,28 +1,30 @@ +# Format Style Options - Created with Clang Power Tools --- -BasedOnStyle: LLVM AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: AcrossComments AlignEscapedNewlines: Left -AllowAllArgumentsOnNextLine: 'false' -AllowShortBlocksOnASingleLine: 'false' +AlignOperands: Align +AllowAllArgumentsOnNextLine: false +AllowShortBlocksOnASingleLine: false AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: Never -BinPackArguments: 'false' -BinPackParameters: 'false' +BasedOnStyle: LLVM +BinPackArguments: false +BinPackParameters: false +BreakBeforeBinaryOperators: NonAssignment BreakBeforeBraces: Allman BreakConstructorInitializers: AfterColon -ColumnLimit: '120' -ConstructorInitializerAllOnOneLineOrOnePerLine: 'true' -ConstructorInitializerIndentWidth: '2' -ContinuationIndentWidth: '2' -MaxEmptyLinesToKeep: '1' +ColumnLimit: 120 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth : 2 +ContinuationIndentWidth: 2 +MaxEmptyLinesToKeep: 1 PointerAlignment: Middle -SortIncludes: 'false' -SortUsingDeclarations: 'false' +SortIncludes: false +SortUsingDeclarations: false SpaceBeforeParens: Never -SpacesInAngles: 'true' -SpacesInParentheses: 'true' -SpacesInSquareBrackets: 'true' +SpacesInAngles: true +SpacesInParentheses: true +SpacesInSquareBrackets: true UseTab: Never -AlignConsecutiveAssignments: AcrossComments - ... From ba10f68c1c4cb0e523f921ebe21520b66982aa68 Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Fri, 3 Jun 2022 21:28:41 +0800 Subject: [PATCH 09/10] clean code: replace throw() with noexcept --- aard.cc | 12 ++++++------ bgl.cc | 12 ++++++------ btreeidx.hh | 2 +- chinese.cc | 4 ++-- config.cc | 20 ++++++++++---------- config.hh | 20 ++++++++++---------- dictdfiles.cc | 12 ++++++------ dictionary.cc | 12 ++++++------ dictionary.hh | 28 ++++++++++++++-------------- dictserver.cc | 12 ++++++------ dsl.cc | 12 ++++++------ dsl_details.cc | 2 +- dsl_details.hh | 2 +- epwing.cc | 12 ++++++------ ex.hh | 8 ++++---- file.cc | 4 ++-- file.hh | 6 +++--- forvo.cc | 12 ++++++------ gls.cc | 16 ++++++++-------- hunspell.cc | 16 ++++++++-------- loaddictionaries.cc | 2 +- loaddictionaries.hh | 2 +- lsa.cc | 14 +++++++------- mdx.cc | 12 ++++++------ mediawiki.cc | 12 ++++++------ programs.cc | 12 ++++++------ sdict.cc | 12 ++++++------ slob.cc | 12 ++++++------ sounddir.cc | 12 ++++++------ stardict.cc | 12 ++++++------ transliteration.cc | 10 +++++----- transliteration.hh | 12 ++++++------ utf8.cc | 2 +- utf8.hh | 2 +- voiceengines.cc | 12 ++++++------ website.cc | 12 ++++++------ xdxf.cc | 12 ++++++------ zim.cc | 12 ++++++------ zipsounds.cc | 14 +++++++------- 39 files changed, 207 insertions(+), 207 deletions(-) diff --git a/aard.cc b/aard.cc index 5fe9e694..d6a4eab7 100644 --- a/aard.cc +++ b/aard.cc @@ -239,16 +239,16 @@ class AardDictionary: public BtreeIndexing::BtreeDictionary ~AardDictionary(); - virtual string getName() throw() + virtual string getName() noexcept { return dictionaryName; } - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.articleCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return idxHeader.wordCount; } inline virtual quint32 getLangFrom() const @@ -284,7 +284,7 @@ class AardDictionary: public BtreeIndexing::BtreeDictionary protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; private: @@ -338,7 +338,7 @@ AardDictionary::~AardDictionary() df.close(); } -void AardDictionary::loadIcon() throw() +void AardDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/bgl.cc b/bgl.cc index 569c2916..6d692dbd 100644 --- a/bgl.cc +++ b/bgl.cc @@ -198,16 +198,16 @@ namespace BglDictionary( string const & id, string const & indexFile, string const & dictionaryFile ); - virtual string getName() throw() + virtual string getName() noexcept { return dictionaryName; } - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.articleCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return idxHeader.wordCount; } inline virtual quint32 getLangFrom() const @@ -249,7 +249,7 @@ namespace protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; private: @@ -302,7 +302,7 @@ namespace FTS_index_completed.ref(); } - void BglDictionary::loadIcon() throw() + void BglDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/btreeidx.hh b/btreeidx.hh index deb3a6b6..a98e4841 100644 --- a/btreeidx.hh +++ b/btreeidx.hh @@ -155,7 +155,7 @@ public: BtreeDictionary( string const & id, vector< string > const & dictionaryFiles ); /// Btree-indexed dictionaries are usually a good source for compound searches. - virtual Dictionary::Features getFeatures() const throw() + virtual Dictionary::Features getFeatures() const noexcept { return Dictionary::SuitableForCompoundSearching; } /// This function does the search using the btree index. Derivatives usually diff --git a/chinese.cc b/chinese.cc index 400a0115..35a092f8 100644 --- a/chinese.cc +++ b/chinese.cc @@ -31,7 +31,7 @@ public: ~CharacterConversionDictionary(); std::vector< gd::wstring > getAlternateWritings( gd::wstring const & ) - throw(); + noexcept; }; CharacterConversionDictionary::CharacterConversionDictionary( std::string const & id, @@ -70,7 +70,7 @@ CharacterConversionDictionary::~CharacterConversionDictionary() } std::vector< gd::wstring > CharacterConversionDictionary::getAlternateWritings( gd::wstring const & str ) - throw() + noexcept { std::vector< gd::wstring > results; diff --git a/config.cc b/config.cc index f4311f55..a86e8c7c 100644 --- a/config.cc +++ b/config.cc @@ -2252,7 +2252,7 @@ QString getUserQtCssFileName() return getHomeDir().filePath( "qt-style.css" ); } -QString getProgramDataDir() throw() +QString getProgramDataDir() noexcept { if ( isPortableVersion() ) return QCoreApplication::applicationDirPath(); @@ -2264,12 +2264,12 @@ QString getProgramDataDir() throw() #endif } -QString getEmbedLocDir() throw() +QString getEmbedLocDir() noexcept { return ":/locale"; } -QString getLocDir() throw() +QString getLocDir() noexcept { if ( QDir( getProgramDataDir() ).cd( "locale" ) ) return getProgramDataDir() + "/locale"; @@ -2277,7 +2277,7 @@ QString getLocDir() throw() return QCoreApplication::applicationDirPath() + "/locale"; } -QString getHelpDir() throw() +QString getHelpDir() noexcept { if ( QDir( getProgramDataDir() ).cd( "help" ) ) return getProgramDataDir() + "/help"; @@ -2286,7 +2286,7 @@ QString getHelpDir() throw() } #ifdef MAKE_CHINESE_CONVERSION_SUPPORT -QString getOpenCCDir() throw() +QString getOpenCCDir() noexcept { #if defined( Q_OS_WIN ) if ( QDir( "opencc" ).exists() ) @@ -2305,7 +2305,7 @@ QString getOpenCCDir() throw() } #endif -bool isPortableVersion() throw() +bool isPortableVersion() noexcept { struct IsPortable { @@ -2320,7 +2320,7 @@ bool isPortableVersion() throw() return p.isPortable; } -QString getPortableVersionDictionaryDir() throw() +QString getPortableVersionDictionaryDir() noexcept { if ( isPortableVersion() ) return getProgramDataDir() + "/content"; @@ -2328,7 +2328,7 @@ QString getPortableVersionDictionaryDir() throw() return QString(); } -QString getPortableVersionMorphoDir() throw() +QString getPortableVersionMorphoDir() noexcept { if ( isPortableVersion() ) return getPortableVersionDictionaryDir() + "/morphology"; @@ -2348,7 +2348,7 @@ QString getStylesDir() return result.path() + QDir::separator(); } -QString getCacheDir() throw() +QString getCacheDir() noexcept { return isPortableVersion() ? portableHomeDirPath() + "/cache" #ifdef HAVE_X11 @@ -2358,7 +2358,7 @@ QString getCacheDir() throw() #endif } -QString getNetworkCacheDir() throw() +QString getNetworkCacheDir() noexcept { return getCacheDir() + "/network"; } diff --git a/config.hh b/config.hh index 9d1a0ae9..06d21ccf 100644 --- a/config.hh +++ b/config.hh @@ -808,40 +808,40 @@ QString getUserQtCssFileName() ; /// Returns the program's data dir. Under Linux that would be something like /// /usr/share/apps/goldendict, under Windows C:/Program Files/GoldenDict. -QString getProgramDataDir() throw(); +QString getProgramDataDir() noexcept; /// Returns the directory storing program localizized files (.qm). -QString getEmbedLocDir() throw(); -QString getLocDir() throw(); +QString getEmbedLocDir() noexcept; +QString getLocDir() noexcept; /// Returns the directory storing program help files (.qch). -QString getHelpDir() throw(); +QString getHelpDir() noexcept; #ifdef MAKE_CHINESE_CONVERSION_SUPPORT /// Returns the directory storing OpenCC configuration and dictionary files (.json and .ocd). -QString getOpenCCDir() throw(); +QString getOpenCCDir() noexcept; #endif /// Returns true if the program is configured as a portable version. In that /// mode, all the settings and indices are kept in the program's directory. -bool isPortableVersion() throw(); +bool isPortableVersion() noexcept; /// Returns directory with dictionaries for portable version. It is content/ /// in the application's directory. -QString getPortableVersionDictionaryDir() throw(); +QString getPortableVersionDictionaryDir() noexcept; /// Returns directory with morpgologies for portable version. It is /// content/morphology in the application's directory. -QString getPortableVersionMorphoDir() throw(); +QString getPortableVersionMorphoDir() noexcept; /// Returns the add-on styles directory. QString getStylesDir(); /// Returns the directory where user-specific non-essential (cached) data should be written. -QString getCacheDir() throw(); +QString getCacheDir() noexcept; /// Returns the article network disk cache directory. -QString getNetworkCacheDir() throw(); +QString getNetworkCacheDir() noexcept; } diff --git a/dictdfiles.cc b/dictdfiles.cc index f8607269..ab3fa777 100644 --- a/dictdfiles.cc +++ b/dictdfiles.cc @@ -100,19 +100,19 @@ public: ~DictdDictionary(); - virtual string getName() throw() + virtual string getName() noexcept { return dictionaryName; } - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.articleCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return idxHeader.wordCount; } - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; inline virtual quint32 getLangFrom() const { return idxHeader.langFrom; } @@ -215,7 +215,7 @@ string nameFromFileName( string const & indexFileName ) return Utf8::encode( FsEncoding::decode( string( sep + 1, dot - sep - 1 ) ) ); } -void DictdDictionary::loadIcon() throw() +void DictdDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/dictionary.cc b/dictionary.cc index 7ccc36e2..11b13c29 100644 --- a/dictionary.cc +++ b/dictionary.cc @@ -159,7 +159,7 @@ sptr< WordSearchRequest > Class::findHeadwordsForSynonym( wstring const & ) } vector< wstring > Class::getAlternateWritings( wstring const & ) - throw() + noexcept { return vector< wstring >(); } @@ -185,21 +185,21 @@ QString Class::getMainFilename() return QString(); } -QIcon const & Class::getIcon() throw() +QIcon const & Class::getIcon() noexcept { if( !dictionaryIconLoaded ) loadIcon(); return dictionaryIcon; } -QIcon const & Class::getNativeIcon() throw() +QIcon const & Class::getNativeIcon() noexcept { if( !dictionaryIconLoaded ) loadIcon(); return dictionaryNativeIcon; } -void Class::loadIcon() throw() +void Class::loadIcon() noexcept { dictionaryIconLoaded = true; } @@ -424,7 +424,7 @@ void Class::isolateCSS( QString & css, QString const & wrapperSelector ) css = newCSS; } -string makeDictionaryId( vector< string > const & dictionaryFiles ) throw() +string makeDictionaryId( vector< string > const & dictionaryFiles ) noexcept { std::vector< string > sortedList; @@ -470,7 +470,7 @@ string makeDictionaryId( vector< string > const & dictionaryFiles ) throw() // of a timestamp of the file, so we use here Qt anyway. It is supposed to // be fixed in the future when it's needed. bool needToRebuildIndex( vector< string > const & dictionaryFiles, - string const & indexFile ) throw() + string const & indexFile ) noexcept { unsigned long lastModified = 0; diff --git a/dictionary.hh b/dictionary.hh index b21933e2..08b9ff5a 100644 --- a/dictionary.hh +++ b/dictionary.hh @@ -270,7 +270,7 @@ protected: // Load user icon if it exist // By default set icon to empty - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; // Load icon from filename directly if isFullName == true // else treat filename as name without extension @@ -295,39 +295,39 @@ public: virtual void deferredInit(); /// Returns the dictionary's id. - string getId() throw() + string getId() noexcept { return id; } /// Returns the list of file names the dictionary consists of. - vector< string > const & getDictionaryFilenames() throw() + vector< string > const & getDictionaryFilenames() noexcept { return dictionaryFiles; } /// Returns the dictionary's full name, utf8. - virtual string getName() throw()=0; + virtual string getName() noexcept=0; /// Returns all the available properties, like the author's name, copyright, /// description etc. All strings are in utf8. - virtual map< Property, string > getProperties() throw()=0; + virtual map< Property, string > getProperties() noexcept=0; /// Returns the features the dictionary possess. See the Feature enum for /// their list. - virtual Features getFeatures() const throw() + virtual Features getFeatures() const noexcept { return NoFeatures; } /// Returns the number of articles in the dictionary. - virtual unsigned long getArticleCount() throw()=0; + virtual unsigned long getArticleCount() noexcept=0; /// Returns the number of words in the dictionary. This can be equal to /// the number of articles, or can be larger if some synonyms are present. - virtual unsigned long getWordCount() throw()=0; + virtual unsigned long getWordCount() noexcept=0; /// Returns the dictionary's icon. - virtual QIcon const & getIcon() throw(); + virtual QIcon const & getIcon() noexcept; /// Returns the dictionary's native icon. Dsl icons are usually rectangular, /// and are adapted by getIcon() to be square. This function allows getting /// the original icon with no geometry transformations applied. - virtual QIcon const & getNativeIcon() throw(); + virtual QIcon const & getNativeIcon() noexcept; /// Returns the dictionary's source language. virtual quint32 getLangFrom() const @@ -371,7 +371,7 @@ public: /// supposed to be very fast and simple, and the results are thus returned /// synchronously. virtual vector< wstring > getAlternateWritings( wstring const & ) - throw(); + noexcept; /// Returns a definition for the given word. The definition should /// be an html fragment (without html/head/body tags) in an utf8 encoding. @@ -454,7 +454,7 @@ public: /// dictionary is being indexed. Since indexing can take some time, this /// is useful to show in some kind of a splash screen. /// The dictionaryName is in utf8. - virtual void indexingDictionary( string const & dictionaryName ) throw()=0; + virtual void indexingDictionary( string const & dictionaryName ) noexcept=0; virtual ~Initializing() {} @@ -465,7 +465,7 @@ public: /// hashing the file names. This id should be used to identify dictionary /// and for the index file name, if one is needed. /// This function is supposed to be used by dictionary implementations. -string makeDictionaryId( vector< string > const & dictionaryFiles ) throw(); +string makeDictionaryId( vector< string > const & dictionaryFiles ) noexcept; /// Checks if it is needed to regenerate index file based on its timestamp /// and the timestamps of the dictionary files. If some files are newer than @@ -473,7 +473,7 @@ string makeDictionaryId( vector< string > const & dictionaryFiles ) throw(); /// dictionary files don't exist, returns true, too. /// This function is supposed to be used by dictionary implementations. bool needToRebuildIndex( vector< string > const & dictionaryFiles, - string const & indexFile ) throw(); + string const & indexFile ) noexcept; /// Returns a random dictionary id useful for interactively created /// dictionaries. diff --git a/dictserver.cc b/dictserver.cc index 65761655..70f3424b 100644 --- a/dictserver.cc +++ b/dictserver.cc @@ -209,16 +209,16 @@ public: strategies.append( "prefix" ); } - virtual string getName() throw() + virtual string getName() noexcept { return name; } - virtual map< Property, string > getProperties() throw() + virtual map< Property, string > getProperties() noexcept { return map< Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return 0; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return 0; } virtual sptr< WordSearchRequest > prefixMatch( wstring const &, @@ -237,7 +237,7 @@ public: virtual QString const & getDescription(); protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; void getServerDatabases(); @@ -245,7 +245,7 @@ protected: friend class DictServerArticleRequest; }; -void DictServerDictionary::loadIcon() throw() +void DictServerDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/dsl.cc b/dsl.cc index ae1e6b42..84bd687e 100644 --- a/dsl.cc +++ b/dsl.cc @@ -183,16 +183,16 @@ public: ~DslDictionary(); - virtual string getName() throw() + virtual string getName() noexcept { return dictionaryName; } - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.articleCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return idxHeader.wordCount; } inline virtual quint32 getLangFrom() const @@ -247,7 +247,7 @@ public: protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; private: @@ -466,7 +466,7 @@ void DslDictionary::doDeferredInit() } -void DslDictionary::loadIcon() throw() +void DslDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/dsl_details.cc b/dsl_details.cc index 5accaf57..465309ac 100644 --- a/dsl_details.cc +++ b/dsl_details.cc @@ -983,7 +983,7 @@ DslScanner::DslScanner( string const & fileName ) : readBufferLeft = 0; } -DslScanner::~DslScanner() throw() +DslScanner::~DslScanner() noexcept { gzclose( f ); } diff --git a/dsl_details.hh b/dsl_details.hh index 2349c349..1044a919 100644 --- a/dsl_details.hh +++ b/dsl_details.hh @@ -130,7 +130,7 @@ public: DEF_EX( exEncodingError, "Encoding error", Ex ) // Should never happen really DslScanner( string const & fileName ) ; - ~DslScanner() throw(); + ~DslScanner() noexcept; /// Returns the detected encoding of this file. Encoding getEncoding() const diff --git a/epwing.cc b/epwing.cc index 637e0b6c..2f9ef607 100644 --- a/epwing.cc +++ b/epwing.cc @@ -96,16 +96,16 @@ public: ~EpwingDictionary(); - virtual string getName() throw() + virtual string getName() noexcept { return bookName; } - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.articleCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return idxHeader.wordCount; } inline virtual quint32 getLangFrom() const @@ -163,7 +163,7 @@ public: protected: - void loadIcon() throw(); + void loadIcon() noexcept; private: @@ -244,7 +244,7 @@ EpwingDictionary::~EpwingDictionary() removeDirectory( cacheDirectory ); } -void EpwingDictionary::loadIcon() throw() +void EpwingDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/ex.hh b/ex.hh index cc76846a..13dd5fff 100644 --- a/ex.hh +++ b/ex.hh @@ -14,8 +14,8 @@ #define DEF_EX( exName, exDescription, exParent ) \ class exName: public exParent { \ public: \ -virtual const char * what() const throw() { return (exDescription); } \ -virtual ~exName() throw() {} }; +virtual const char * what() const noexcept { return (exDescription); } \ +virtual ~exName() noexcept {} }; /// Same as DEF_EX, but takes a runtime string argument, which gets concatenated /// with the description. @@ -31,7 +31,7 @@ class exName: public exParent { \ std::string value; \ public: \ exName( std::string const & value_ ): value( std::string( exDescription ) + " " + value_ ) {} \ -virtual const char * what() const throw() { return value.c_str(); } \ -virtual ~exName() throw() {} }; +virtual const char * what() const noexcept { return value.c_str(); } \ +virtual ~exName() noexcept {} }; #endif diff --git a/file.cc b/file.cc index 9391028a..6050eef3 100644 --- a/file.cc +++ b/file.cc @@ -65,7 +65,7 @@ void loadFromFile( std::string const & n, std::vector< char > & data ) f.read( &data.front(), data.size() ); } -bool exists( char const * filename ) throw() +bool exists( char const * filename ) noexcept { #ifdef __WIN32 #if defined(__WIN64) || defined(_MSC_VER) @@ -313,7 +313,7 @@ void Class::close() f.close(); } -Class::~Class() throw() +Class::~Class() noexcept { if ( f.isOpen() ) { diff --git a/file.hh b/file.hh index 81281647..c4c1c50d 100644 --- a/file.hh +++ b/file.hh @@ -30,9 +30,9 @@ bool tryPossibleZipName( std::string const & name, std::string & copyTo ); void loadFromFile( std::string const & n, std::vector< char > & data ); -bool exists( char const * filename ) throw(); +bool exists( char const * filename ) noexcept; -inline bool exists( std::string const & filename ) throw() +inline bool exists( std::string const & filename ) noexcept { return exists( filename.c_str() ); } class Class @@ -116,7 +116,7 @@ public: /// Closes the file. No further operations are valid. void close() ; - ~Class() throw(); + ~Class() noexcept; private: diff --git a/forvo.cc b/forvo.cc index a1d63f8d..cdfeecc5 100644 --- a/forvo.cc +++ b/forvo.cc @@ -42,16 +42,16 @@ public: { } - virtual string getName() throw() + virtual string getName() noexcept { return name; } - virtual map< Property, string > getProperties() throw() + virtual map< Property, string > getProperties() noexcept { return map< Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return 0; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return 0; } virtual sptr< WordSearchRequest > prefixMatch( wstring const & /*word*/, @@ -70,7 +70,7 @@ public: protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; }; @@ -90,7 +90,7 @@ sptr< DataRequest > ForvoDictionary::getArticle( wstring const & word, netMgr ); } -void ForvoDictionary::loadIcon() throw() +void ForvoDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/gls.cc b/gls.cc index 30d8cf23..48c5a0c5 100644 --- a/gls.cc +++ b/gls.cc @@ -88,7 +88,7 @@ public: DEF_EX( exEncodingError, "Encoding error", Ex ) // Should never happen really GlsScanner( string const & fileName ) ; - ~GlsScanner() throw(); + ~GlsScanner() noexcept; /// Returns the detected encoding of this file. Encoding getEncoding() const @@ -293,7 +293,7 @@ bool GlsScanner::readNextLine( wstring & out, size_t & offset ) } } -GlsScanner::~GlsScanner() throw() +GlsScanner::~GlsScanner() noexcept { gzclose( f ); } @@ -372,16 +372,16 @@ public: ~GlsDictionary(); - virtual string getName() throw() + virtual string getName() noexcept { return dictionaryName; } - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.articleCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return idxHeader.wordCount; } inline virtual quint32 getLangFrom() const @@ -425,7 +425,7 @@ public: } protected: - void loadIcon() throw(); + void loadIcon() noexcept; private: @@ -517,7 +517,7 @@ GlsDictionary::~GlsDictionary() dict_data_close( dz ); } -void GlsDictionary::loadIcon() throw() +void GlsDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/hunspell.cc b/hunspell.cc index c09638c3..70cb9d45 100644 --- a/hunspell.cc +++ b/hunspell.cc @@ -63,16 +63,16 @@ public: { } - virtual string getName() throw() + virtual string getName() noexcept { return name; } - virtual map< Property, string > getProperties() throw() + virtual map< Property, string > getProperties() noexcept { return map< Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return 0; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return 0; } virtual sptr< WordSearchRequest > prefixMatch( wstring const &, @@ -91,11 +91,11 @@ public: virtual bool isLocalDictionary() { return true; } - virtual vector< wstring > getAlternateWritings( const wstring & word ) throw(); + virtual vector< wstring > getAlternateWritings( const wstring & word ) noexcept; protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; private: @@ -142,7 +142,7 @@ bool containsWhitespace( wstring const & str ) return false; } -void HunspellDictionary::loadIcon() throw() +void HunspellDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; @@ -162,7 +162,7 @@ void HunspellDictionary::loadIcon() throw() dictionaryIconLoaded = true; } -vector< wstring > HunspellDictionary::getAlternateWritings( wstring const & word ) throw() +vector< wstring > HunspellDictionary::getAlternateWritings( wstring const & word ) noexcept { vector< wstring > results; diff --git a/loaddictionaries.cc b/loaddictionaries.cc index 24bdd1aa..38c88a1f 100644 --- a/loaddictionaries.cc +++ b/loaddictionaries.cc @@ -240,7 +240,7 @@ void LoadDictionaries::handlePath( Config::Path const & path ) #endif } -void LoadDictionaries::indexingDictionary( string const & dictionaryName ) throw() +void LoadDictionaries::indexingDictionary( string const & dictionaryName ) noexcept { emit indexingDictionarySignal( QString::fromUtf8( dictionaryName.c_str() ) ); } diff --git a/loaddictionaries.hh b/loaddictionaries.hh index 2c31f509..d9960c6a 100644 --- a/loaddictionaries.hh +++ b/loaddictionaries.hh @@ -46,7 +46,7 @@ signals: public: - virtual void indexingDictionary( std::string const & dictionaryName ) throw(); + virtual void indexingDictionary( std::string const & dictionaryName ) noexcept; private: diff --git a/lsa.cc b/lsa.cc index a6944a43..f30d1d6c 100644 --- a/lsa.cc +++ b/lsa.cc @@ -164,15 +164,15 @@ public: LsaDictionary( string const & id, string const & indexFile, vector< string > const & dictionaryFiles ); - virtual string getName() throw(); + virtual string getName() noexcept; - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.soundsCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return getArticleCount(); } virtual sptr< Dictionary::DataRequest > getArticle( wstring const &, @@ -186,10 +186,10 @@ public: protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; }; -string LsaDictionary::getName() throw() +string LsaDictionary::getName() noexcept { string result = FsEncoding::basename( getDictionaryFilenames()[ 0 ] ); @@ -498,7 +498,7 @@ sptr< Dictionary::DataRequest > LsaDictionary::getResource( string const & name return dr; } -void LsaDictionary::loadIcon() throw() +void LsaDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/mdx.cc b/mdx.cc index 757de69f..4165d0ab 100644 --- a/mdx.cc +++ b/mdx.cc @@ -266,22 +266,22 @@ public: virtual void deferredInit(); - virtual string getName() throw() + virtual string getName() noexcept { return dictionaryName; } - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.articleCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return idxHeader.wordCount; } @@ -327,7 +327,7 @@ public: protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; private: @@ -925,7 +925,7 @@ const QString & MdxDictionary::getDescription() return dictionaryDescription; } -void MdxDictionary::loadIcon() throw() +void MdxDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/mediawiki.cc b/mediawiki.cc index e0a62325..96998517 100644 --- a/mediawiki.cc +++ b/mediawiki.cc @@ -47,16 +47,16 @@ public: langId = LangCoder::code2toInt( url.mid( n - 2, 2 ).toLatin1().data() ); } - virtual string getName() throw() + virtual string getName() noexcept { return name; } - virtual map< Property, string > getProperties() throw() + virtual map< Property, string > getProperties() noexcept { return map< Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return 0; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return 0; } virtual sptr< WordSearchRequest > prefixMatch( wstring const &, @@ -73,11 +73,11 @@ public: protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; }; -void MediaWikiDictionary::loadIcon() throw() +void MediaWikiDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/programs.cc b/programs.cc index cd2b07df..f3a619ca 100644 --- a/programs.cc +++ b/programs.cc @@ -30,16 +30,16 @@ public: { } - virtual string getName() throw() + virtual string getName() noexcept { return prg.name.toUtf8().data(); } - virtual map< Property, string > getProperties() throw() + virtual map< Property, string > getProperties() noexcept { return map< Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return 0; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return 0; } virtual sptr< WordSearchRequest > prefixMatch( wstring const & word, @@ -53,7 +53,7 @@ public: protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; }; sptr< WordSearchRequest > ProgramsDictionary::prefixMatch( wstring const & word, @@ -118,7 +118,7 @@ sptr< Dictionary::DataRequest > ProgramsDictionary::getArticle( } } -void ProgramsDictionary::loadIcon() throw() +void ProgramsDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/sdict.cc b/sdict.cc index 0b1cb8a5..3162d838 100644 --- a/sdict.cc +++ b/sdict.cc @@ -143,16 +143,16 @@ class SdictDictionary: public BtreeIndexing::BtreeDictionary ~SdictDictionary(); - virtual string getName() throw() + virtual string getName() noexcept { return dictionaryName; } - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.articleCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return idxHeader.wordCount; } inline virtual quint32 getLangFrom() const @@ -187,7 +187,7 @@ class SdictDictionary: public BtreeIndexing::BtreeDictionary } protected: - void loadIcon() throw(); + void loadIcon() noexcept; private: @@ -240,7 +240,7 @@ SdictDictionary::~SdictDictionary() df.close(); } -void SdictDictionary::loadIcon() throw() +void SdictDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/slob.cc b/slob.cc index b66e061c..7851ebec 100644 --- a/slob.cc +++ b/slob.cc @@ -587,16 +587,16 @@ class SlobDictionary: public BtreeIndexing::BtreeDictionary ~SlobDictionary(); - virtual string getName() throw() + virtual string getName() noexcept { return dictionaryName; } - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.articleCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return idxHeader.wordCount; } inline virtual quint32 getLangFrom() const @@ -643,7 +643,7 @@ class SlobDictionary: public BtreeIndexing::BtreeDictionary protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; private: @@ -746,7 +746,7 @@ void SlobDictionary::removeDirectory( QString const & directory ) dir.rmdir( directory ); } -void SlobDictionary::loadIcon() throw() +void SlobDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/sounddir.cc b/sounddir.cc index 46b58749..095b3abf 100644 --- a/sounddir.cc +++ b/sounddir.cc @@ -79,16 +79,16 @@ public: vector< string > const & dictionaryFiles, QString const & iconFilename_ ); - virtual string getName() throw() + virtual string getName() noexcept { return name; } - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.soundsCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return getArticleCount(); } virtual sptr< Dictionary::DataRequest > getArticle( wstring const &, @@ -102,7 +102,7 @@ public: protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; }; SoundDirDictionary::SoundDirDictionary( string const & id, @@ -289,7 +289,7 @@ sptr< Dictionary::DataRequest > SoundDirDictionary::getArticle( wstring const & return ret; } -void SoundDirDictionary::loadIcon() throw() +void SoundDirDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/stardict.cc b/stardict.cc index 9c3f347e..34417f29 100644 --- a/stardict.cc +++ b/stardict.cc @@ -155,16 +155,16 @@ public: ~StardictDictionary(); - virtual string getName() throw() + virtual string getName() noexcept { return bookName; } - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.wordCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return idxHeader.wordCount + idxHeader.synWordCount; } inline virtual quint32 getLangFrom() const @@ -207,7 +207,7 @@ public: } protected: - void loadIcon() throw(); + void loadIcon() noexcept; private: @@ -292,7 +292,7 @@ StardictDictionary::~StardictDictionary() dict_data_close( dz ); } -void StardictDictionary::loadIcon() throw() +void StardictDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/transliteration.cc b/transliteration.cc index aefc13fd..fc8604ae 100644 --- a/transliteration.cc +++ b/transliteration.cc @@ -22,16 +22,16 @@ BaseTransliterationDictionary::BaseTransliterationDictionary( string const & id, dictionaryIconLoaded = true; } -string BaseTransliterationDictionary::getName() throw() +string BaseTransliterationDictionary::getName() noexcept { return name; } -map< Dictionary::Property, string > BaseTransliterationDictionary::getProperties() throw() +map< Dictionary::Property, string > BaseTransliterationDictionary::getProperties() noexcept { return map< Dictionary::Property, string >(); } -unsigned long BaseTransliterationDictionary::getArticleCount() throw() +unsigned long BaseTransliterationDictionary::getArticleCount() noexcept { return 0; } -unsigned long BaseTransliterationDictionary::getWordCount() throw() +unsigned long BaseTransliterationDictionary::getWordCount() noexcept { return 0; } sptr< Dictionary::WordSearchRequest > BaseTransliterationDictionary::prefixMatch( wstring const &, @@ -83,7 +83,7 @@ TransliterationDictionary::TransliterationDictionary( string const & id, } vector< wstring > TransliterationDictionary::getAlternateWritings( wstring const & str ) - throw() + noexcept { vector< wstring > results; diff --git a/transliteration.hh b/transliteration.hh index d6d96198..b35a9785 100644 --- a/transliteration.hh +++ b/transliteration.hh @@ -28,16 +28,16 @@ public: BaseTransliterationDictionary( string const & id, string const & name, QIcon icon, bool caseSensitive = true ); - virtual string getName() throw(); + virtual string getName() noexcept; - virtual map< Dictionary::Property, string > getProperties() throw(); + virtual map< Dictionary::Property, string > getProperties() noexcept; - virtual unsigned long getArticleCount() throw(); + virtual unsigned long getArticleCount() noexcept; - virtual unsigned long getWordCount() throw(); + virtual unsigned long getWordCount() noexcept; virtual vector< wstring > getAlternateWritings( wstring const & ) - throw() = 0; + noexcept = 0; virtual sptr< Dictionary::WordSearchRequest > findHeadwordsForSynonym( wstring const & ) ; @@ -85,7 +85,7 @@ public: bool caseSensitive = true ); virtual vector< wstring > getAlternateWritings( wstring const & ) - throw(); + noexcept; }; } diff --git a/utf8.cc b/utf8.cc index 91618f92..6a6949de 100644 --- a/utf8.cc +++ b/utf8.cc @@ -132,7 +132,7 @@ long decode( char const * in_, size_t inSize, wchar * out_ ) return out - out_; } -string encode( wstring const & in ) throw() +string encode( wstring const & in ) noexcept { if( in.size() == 0 ) return string(); diff --git a/utf8.hh b/utf8.hh index ce636276..75f96503 100644 --- a/utf8.hh +++ b/utf8.hh @@ -44,7 +44,7 @@ size_t encode( wchar const * in, size_t inSize, char * out ); long decode( char const * in, size_t inSize, wchar * out ); /// Versions for non time-critical code. -string encode( wstring const & ) throw(); +string encode( wstring const & ) noexcept; wstring decode( string const & ) ; /// Since the standard isspace() is locale-specific, we need something diff --git a/voiceengines.cc b/voiceengines.cc index 0582dd36..555c5532 100644 --- a/voiceengines.cc +++ b/voiceengines.cc @@ -44,16 +44,16 @@ public: { } - virtual string getName() throw() + virtual string getName() noexcept { return voiceEngine.name.toUtf8().data(); } - virtual map< Property, string > getProperties() throw() + virtual map< Property, string > getProperties() noexcept { return map< Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return 0; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return 0; } virtual sptr< WordSearchRequest > prefixMatch( wstring const & word, @@ -67,7 +67,7 @@ public: protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; }; sptr< WordSearchRequest > VoiceEnginesDictionary::prefixMatch( wstring const & /*word*/, @@ -110,7 +110,7 @@ sptr< Dictionary::DataRequest > VoiceEnginesDictionary::getArticle( return ret; } -void VoiceEnginesDictionary::loadIcon() throw() +void VoiceEnginesDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/website.cc b/website.cc index 6c62e19a..4091d198 100644 --- a/website.cc +++ b/website.cc @@ -53,16 +53,16 @@ public: dictionaryDescription = temp; } - virtual string getName() throw() + virtual string getName() noexcept { return name; } - virtual map< Property, string > getProperties() throw() + virtual map< Property, string > getProperties() noexcept { return map< Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return 0; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return 0; } virtual sptr< WordSearchRequest > prefixMatch( wstring const & word, @@ -79,7 +79,7 @@ public: protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; }; sptr< WordSearchRequest > WebSiteDictionary::prefixMatch( wstring const & /*word*/, @@ -526,7 +526,7 @@ sptr< Dictionary::DataRequest > WebSiteDictionary::getResource( string const & n return new WebSiteResourceRequest( link, netMgr, this ); } -void WebSiteDictionary::loadIcon() throw() +void WebSiteDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/xdxf.cc b/xdxf.cc index 585e8abe..e33fc55e 100644 --- a/xdxf.cc +++ b/xdxf.cc @@ -147,16 +147,16 @@ public: ~XdxfDictionary(); - virtual string getName() throw() + virtual string getName() noexcept { return dictionaryName; } - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.articleCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return idxHeader.wordCount; } inline virtual quint32 getLangFrom() const @@ -200,7 +200,7 @@ public: protected: - void loadIcon() throw(); + void loadIcon() noexcept; private: @@ -312,7 +312,7 @@ XdxfDictionary::~XdxfDictionary() dict_data_close( dz ); } -void XdxfDictionary::loadIcon() throw() +void XdxfDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/zim.cc b/zim.cc index 2de86d08..e054778d 100644 --- a/zim.cc +++ b/zim.cc @@ -669,16 +669,16 @@ class ZimDictionary: public BtreeIndexing::BtreeDictionary ~ZimDictionary(); - virtual string getName() throw() + virtual string getName() noexcept { return dictionaryName; } - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.articleCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return idxHeader.wordCount; } inline virtual quint32 getLangFrom() const @@ -725,7 +725,7 @@ class ZimDictionary: public BtreeIndexing::BtreeDictionary protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; private: @@ -792,7 +792,7 @@ ZimDictionary::~ZimDictionary() df.close(); } -void ZimDictionary::loadIcon() throw() +void ZimDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; diff --git a/zipsounds.cc b/zipsounds.cc index 95c903a4..07595c14 100644 --- a/zipsounds.cc +++ b/zipsounds.cc @@ -114,15 +114,15 @@ public: ZipSoundsDictionary( string const & id, string const & indexFile, vector< string > const & dictionaryFiles ); - virtual string getName() throw(); + virtual string getName() noexcept; - virtual map< Dictionary::Property, string > getProperties() throw() + virtual map< Dictionary::Property, string > getProperties() noexcept { return map< Dictionary::Property, string >(); } - virtual unsigned long getArticleCount() throw() + virtual unsigned long getArticleCount() noexcept { return idxHeader.soundsCount; } - virtual unsigned long getWordCount() throw() + virtual unsigned long getWordCount() noexcept { return getArticleCount(); } virtual sptr< Dictionary::DataRequest > getArticle( wstring const &, @@ -136,7 +136,7 @@ public: protected: - virtual void loadIcon() throw(); + virtual void loadIcon() noexcept; }; ZipSoundsDictionary::ZipSoundsDictionary( string const & id, @@ -164,7 +164,7 @@ ZipSoundsDictionary::ZipSoundsDictionary( string const & id, } -string ZipSoundsDictionary::getName() throw() +string ZipSoundsDictionary::getName() noexcept { string result = FsEncoding::basename( getDictionaryFilenames()[ 0 ] ); @@ -384,7 +384,7 @@ sptr< Dictionary::DataRequest > ZipSoundsDictionary::getResource( string const & return new Dictionary::DataRequestInstant( false ); } -void ZipSoundsDictionary::loadIcon() throw() +void ZipSoundsDictionary::loadIcon() noexcept { if ( dictionaryIconLoaded ) return; From 3e05e711e5ebab7ca5c4f34b30b90df225caaecf Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Fri, 3 Jun 2022 20:07:14 +0800 Subject: [PATCH 10/10] improve: fulltext search checkArticle optimize --- ftshelpers.cc | 355 ++++++++++++++-------------------------------- ftshelpers.hh | 3 +- fulltextsearch.cc | 2 +- utils.hh | 10 ++ 4 files changed, 120 insertions(+), 250 deletions(-) diff --git a/ftshelpers.cc b/ftshelpers.cc index 30517ae5..e1b51641 100644 --- a/ftshelpers.cc +++ b/ftshelpers.cc @@ -15,6 +15,7 @@ #include #include + #include "wildcard.hh" using std::vector; @@ -38,8 +39,7 @@ bool ftsIndexIsOldOrBad( string const & indexFile, } static QString makeHiliteRegExpString( QStringList const & words, - int searchMode, - int distanceBetweenWords, bool hasCJK = false ) + int searchMode, int distanceBetweenWords, bool hasCJK = false, bool ignoreWordsOrder = false ) { QString searchString( "(" ); @@ -63,9 +63,20 @@ static QString makeHiliteRegExpString( QStringList const & words, for( int x = 0; x < words.size(); x++ ) { if( x ) + { searchString += stripWords; + if(ignoreWordsOrder) + searchString += "("; + } searchString += boundWord + words[ x ] + boundWord; + + if( x ) + { + if( ignoreWordsOrder ) + searchString += ")?"; + } + } searchString += ")"; @@ -125,7 +136,8 @@ bool parseSearchString( QString const & str, QStringList & indexWords, QRegExp & searchRegExp, int searchMode, bool matchCase, int distanceBetweenWords, - bool & hasCJK ) + bool & hasCJK, + bool ignoreWordsOrder ) { searchWords.clear(); indexWords.clear(); @@ -149,7 +161,7 @@ bool parseSearchString( QString const & str, QStringList & indexWords, { tokenizeCJK( indexWords, wordRegExp, list ); // QStringList allWords = str.split( spacesRegExp, Qt::SkipEmptyParts ); - searchString = makeHiliteRegExpString( indexWords, searchMode, distanceBetweenWords, hasCJK ); + searchString = makeHiliteRegExpString( list, searchMode, distanceBetweenWords, hasCJK , ignoreWordsOrder); } else { @@ -159,7 +171,7 @@ bool parseSearchString( QString const & str, QStringList & indexWords, // Make regexp for results hilite QStringList allWords = str.split( spacesRegExp, Qt::SkipEmptyParts ); - searchString = makeHiliteRegExpString( allWords, searchMode, distanceBetweenWords ); + searchString = makeHiliteRegExpString( allWords, searchMode, distanceBetweenWords,false, ignoreWordsOrder ); } searchRegExp = QRegExp( searchString, matchCase ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::RegExp2 ); searchRegExp.setMinimal( true ); @@ -443,25 +455,23 @@ void FTSResultsRequest::checkArticles( QVector< uint32_t > const & offsets, QRegularExpression::UseUnicodePropertiesOption); QRegularExpression regSplit( "[^\\w\\p{M}]+", QRegularExpression::UseUnicodePropertiesOption ); + // RegExp mode + QRegularExpression searchRegularExpression; + if( searchMode == FTS::Wildcards ) + searchRegularExpression.setPattern( wildcardsToRegexp( searchRegexp.pattern() ) ); + else + searchRegularExpression.setPattern( searchRegexp.pattern() ); + QRegularExpression::PatternOptions patternOptions = + QRegularExpression::DotMatchesEverythingOption | QRegularExpression::UseUnicodePropertiesOption + | QRegularExpression::MultilineOption | QRegularExpression::InvertedGreedinessOption; + if( searchRegexp.caseSensitivity() == Qt::CaseInsensitive ) + patternOptions |= QRegularExpression::CaseInsensitiveOption; + searchRegularExpression.setPatternOptions( patternOptions ); + if( !searchRegularExpression.isValid() ) + searchRegularExpression.setPattern( "" ); if( searchMode == FTS::Wildcards || searchMode == FTS::RegExp ) { - // RegExp mode - - QRegularExpression searchRegularExpression; - if( searchMode == FTS::Wildcards ) - searchRegularExpression.setPattern( wildcardsToRegexp( searchRegexp.pattern() ) ); - else - searchRegularExpression.setPattern( searchRegexp.pattern() ); - QRegularExpression::PatternOptions patternOptions = QRegularExpression::DotMatchesEverythingOption - | QRegularExpression::UseUnicodePropertiesOption - | QRegularExpression::MultilineOption - | QRegularExpression::InvertedGreedinessOption; - if( searchRegexp.caseSensitivity() == Qt::CaseInsensitive ) - patternOptions |= QRegularExpression::CaseInsensitiveOption; - searchRegularExpression.setPatternOptions( patternOptions ); - if( !searchRegularExpression.isValid() ) - searchRegularExpression.setPattern( "" ); for( int i = 0; i < offsets.size(); i++ ) { if( Utils::AtomicInt::loadAcquire( isCancelled ) ) @@ -527,243 +537,92 @@ void FTSResultsRequest::checkArticles( QVector< uint32_t > const & offsets, if( ignoreDiacritics ) articleText = gd::toQString( Folding::applyDiacriticsOnly( gd::toWString( articleText ) ) ); - QStringList articleWords = articleText.split( needHandleBrackets ? splitWithBrackets : splitWithoutBrackets, - Qt::SkipEmptyParts ); + //QStringList articleWords = articleText.split( needHandleBrackets ? splitWithBrackets : splitWithoutBrackets, + // Qt::SkipEmptyParts ); - int wordsNum = articleWords.length(); - while ( pos < wordsNum ) + if(ignoreWordsOrder) { - QString s = articleWords[ pos ]; - bool breakSearch = false; - - QStringList parsedWords; - if( needHandleBrackets && ( s.indexOf( '(' ) >= 0 || s.indexOf( ')' ) >= 0 ) ) + bool allMatch = true; + foreach( QString word, words ) + { + if( containCJK( word ) || searchMode == FTS::PlainText ) { - // Handle brackets - QRegularExpressionMatch match_brackets = regBrackets.match( s ); - if( match_brackets.hasMatch() ) + if( !articleText.contains( word ) ) { - QStringList parts = match_brackets.capturedTexts(); - // Add empty strings for compatibility with QRegExp behaviour - for( int i = match_brackets.lastCapturedIndex() + 1; i < 6; i++ ) - parts.append( QString() ); - - QString word = parts[ 2 ] + parts[ 4 ]; // Brackets removed - parsedWords.append( word ); - - word = parts[ 1 ].remove( '(' ).remove( ')' ) - + parts[ 2 ] - + parts[ 3 ].remove( '(' ).remove( ')' ) - + parts[ 4 ] - + parts[ 5 ].remove( '(' ).remove( ')' ); // Brackets expansed - parsedWords.append( word ); + allMatch = false; + break; } + } + else if( searchMode == FTS::WholeWords) + { + QRegularExpression tmpReg( QString( "\b%1\b" ).arg( word ),QRegularExpression::CaseInsensitiveOption|QRegularExpression::UseUnicodePropertiesOption ); + if( !articleText.contains( tmpReg) ) + { + allMatch = false; + break; + } + } + + } + + if(!allMatch) + { + continue; + } + + if( distanceBetweenWords >= 0 ) + { + // the article text contains all the needed words. + // determine if distance restriction is meet + QRegularExpression replaceReg( QString( "(%1)" ).arg( words.join( '|' ) ), + QRegularExpression::CaseInsensitiveOption | + QRegularExpression::UseUnicodePropertiesOption ); + // use a string that could not be presented in the article. + articleText = articleText.replace( replaceReg, "=@XXXXX@=" ); + + auto hasCJK = false; + foreach(QString word,words) + { + if(containCJK( word )) + { + hasCJK = true; + break; + } + } + + //hascjk value ,perhaps should depend on each word + auto searchRegStr = makeHiliteRegExpString( Utils::repeat( "=@XXXXX@=", words.size() ), searchMode, distanceBetweenWords,hasCJK ); + QRegularExpression distanceOrderReg( searchRegStr, + QRegularExpression::CaseInsensitiveOption | + QRegularExpression::UseUnicodePropertiesOption ); + // use a string that could not be presented in the article. + if(articleText.contains(distanceOrderReg)) + { + if( headword.isEmpty() ) + offsetsForHeadwords.append( offsets.at( i ) ); else - parsedWords = s.split( regSplit, Qt::SkipEmptyParts ); + foundHeadwords->append( FTS::FtsHeadword( headword, id, QStringList(), matchCase ) ); + + results++; + if( maxResults > 0 && results >= maxResults ) + break; } - else - parsedWords.append( s ); - - int n; - for( n = 0; n < parsedWords.size(); n++ ) - { - auto parsed_word = parsedWords.at( n ); - if( ignoreWordsOrder ) - { - int i; - for( i = 0; i < wordsList.size(); i++ ) - { - if( wordsList.at( i ).second ) - { - if( ( searchMode == FTS::WholeWords && parsed_word.compare( wordsList.at( i ).first, cs ) == 0 ) - || ( searchMode == FTS::PlainText && parsed_word.contains( wordsList.at( i ).first, cs ) ) ) - { - wordsList[ i ].second = false; - - if( parsedWords.size() > 1 ) - { - QString wordToHilite = s; - while( !wordToHilite.isEmpty() && ( wordToHilite.at( 0 ) == '(' || wordToHilite.at( 0 ) == ')' ) ) - wordToHilite.remove( 0, 1 ); - while( !wordToHilite.isEmpty() && ( wordToHilite.endsWith( '(' ) || wordToHilite.endsWith( ')' ) ) ) - wordToHilite.chop( 1 ); - order.append( wordToHilite.replace( '(', "\\(" ).replace( ')', "\\)" ) ); - } - else - order.append( wordsList.at( i ).first ); - - break; - } - } - } - if( i < wordsList.size() ) - { - // Word found - - matchWordNom += 1; - - if( matchWordNom == 1 ) - { - // Store position to remake search if sequence will not be found - nextNotFoundPos = pos + 1; - } - - if( matchWordNom >= words.size() ) - { - // All words are found - // Store found words sequence and continue search - // It's nesessary for hilite search results - - // Check if such sequence already presented - int x; - for( x = 0; x < allOrders.size(); x++ ) - { - if( allOrders[ x ] == order ) - break; - } - if( x >= allOrders.size() ) - allOrders.append( order ); - - order.clear(); - - matchWordNom = 0; - unmatchWordNom = 0; - for( int i = 0; i < wordsList.size(); i++ ) - wordsList[ i ].second = true; - nextNotFoundPos = 0; - - break; - } - - unmatchWordNom = 0; - break; - } - else - if( matchWordNom > 0 && n >= parsedWords.size() - 1 ) - { - unmatchWordNom += 1; - if( distanceBetweenWords >= 0 && unmatchWordNom > distanceBetweenWords ) - { - // Sequence broken, clear all counters - matchWordNom = 0; - unmatchWordNom = 0; - for( int i = 0; i < wordsList.size(); i++ ) - wordsList[ i ].second = true; - order.clear(); - } - } - } - else - { - //for cjk word, FTS::WholeWords and FTS::PlainText actually have same effect. - auto match_word = words.at( matchWordNom ); - bool hasCJK = containCJK( match_word ); - if( ( searchMode == FTS::WholeWords && - ( ( !hasCJK&& parsed_word.compare( match_word, cs ) == 0 ) || - ( hasCJK && parsed_word.contains( match_word, cs ) ) ) ) - || ( searchMode == FTS::PlainText && parsed_word.contains( match_word, cs ) ) ) - { - matchWordNom += 1; - - if( matchWordNom == 1 ) - { - // Store position to remake search if sequence will not be found - nextNotFoundPos = pos + 1; - } - - if( needHandleBrackets ) - { - if( parsedWords.size() > 1 ) - { - QString wordToHilite = s; - while( !wordToHilite.isEmpty() && ( wordToHilite.at( 0 ) == '(' || wordToHilite.at( 0 ) == ')' ) ) - wordToHilite.remove( 0, 1 ); - while( !wordToHilite.isEmpty() && ( wordToHilite.endsWith( '(' ) || wordToHilite.endsWith( ')' ) ) ) - wordToHilite.chop( 1 ); - order.append( wordToHilite.replace( '(', "\\(" ).replace( ')', "\\)" ) ); - } - else - order.append( words.at( matchWordNom - 1 ) ); - } - - if( matchWordNom >= words.size() ) - { - // All words are found - if( needHandleBrackets ) - { - if( allOrders.isEmpty() ) - allOrders.append( words ); - - // Check if such sequence already presented - int x; - for( x = 0; x < allOrders.size(); x++ ) - { - if( allOrders[ x ] == order ) - break; - } - if( x >= allOrders.size() ) - allOrders.append( order ); - - matchWordNom = 0; - unmatchWordNom = 0; - order.clear(); - nextNotFoundPos = 0; - } - else - breakSearch = true; - break; - } - unmatchWordNom = 0; - break; - } - else - if( matchWordNom > 0 && n >= parsedWords.size() - 1 ) - { - unmatchWordNom += 1; - if( distanceBetweenWords >= 0 && unmatchWordNom > distanceBetweenWords ) - { - matchWordNom = 0; - unmatchWordNom = 0; - if( needHandleBrackets ) - order.clear(); - } - } - } - } - if( breakSearch ) - break; - if( nextNotFoundPos > 0 && matchWordNom == 0 ) - { - pos = nextNotFoundPos; - nextNotFoundPos = 0; - } - else - pos += 1; + } + } - - if( !allOrders.isEmpty() || matchWordNom >= words.size() ) + else { - QStringList hiliteReg; - if( !allOrders.isEmpty() ) + if( articleText.contains( searchRegularExpression ) ) { - for( int i = 0; i < allOrders.size(); i++ ) - { - QString hiliteStr = makeHiliteRegExpString( allOrders.at( i ), searchMode, distanceBetweenWords ); - hiliteReg.append( hiliteStr ); - } - allOrders.clear(); + if( headword.isEmpty() ) + offsetsForHeadwords.append( offsets.at( i ) ); + else + foundHeadwords->append( FTS::FtsHeadword( headword, id, QStringList(), matchCase ) ); + + results++; + if( maxResults > 0 && results >= maxResults ) + break; } - if( headword.isEmpty() ) - { - offsetsForHeadwords.append( offsets.at( i ) ); - hiliteRegExps.append( hiliteReg ); - } - else - foundHeadwords->append( FTS::FtsHeadword( headword, id, hiliteReg, matchCase ) ); - - results++; - if( maxResults > 0 && results >= maxResults ) - break; } } } @@ -1150,7 +1009,7 @@ void FTSResultsRequest::run() QRegExp searchRegExp; if( !FtsHelpers::parseSearchString( searchString, indexWords, searchWords, searchRegExp, - searchMode, matchCase, distanceBetweenWords, hasCJK ) ) + searchMode, matchCase, distanceBetweenWords, hasCJK, ignoreWordsOrder ) ) { finish(); return; diff --git a/ftshelpers.hh b/ftshelpers.hh index 6d0fa29a..f477016d 100644 --- a/ftshelpers.hh +++ b/ftshelpers.hh @@ -55,7 +55,8 @@ bool parseSearchString( QString const & str, QStringList & IndexWords, QRegExp & searchRegExp, int searchMode, bool matchCase, int distanceBetweenWords, - bool & hasCJK ); + bool & hasCJK, + bool ignoreWordsOrder = false ); void parseArticleForFts( uint32_t articleAddress, QString & articleText, QMap< QString, QVector< uint32_t > > & words, diff --git a/fulltextsearch.cc b/fulltextsearch.cc index 749a2a94..cb87124b 100644 --- a/fulltextsearch.cc +++ b/fulltextsearch.cc @@ -351,7 +351,7 @@ void FullTextSearchDialog::accept() searchRegExp, mode, ui.matchCase->isChecked(), distanceBetweenWords, - hasCJK ) ) + hasCJK, ignoreWordsOrder ) ) { // if( hasCJK && ( mode == WholeWords || mode == PlainText ) ) // { diff --git a/utils.hh b/utils.hh index bfd71a79..be5c2563 100644 --- a/utils.hh +++ b/utils.hh @@ -118,6 +118,16 @@ inline QString json2String( const QJsonObject & json ) return QString( QJsonDocument( json ).toJson( QJsonDocument::Compact ) ); } +inline QStringList repeat( const QString str, const int times ) +{ + QStringList list; + for( int i = 0; i < times; i++ ) + { + list << str; + } + return list; +} + namespace AtomicInt {