mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-23 20:14:05 +00:00
fix: highlight fts search result (#792)
* fix: highlight fts search result * 🎨 apply clang-format changes * remove accent/diacritic handler used in fts search * header file adjustment * fix: qt5.15 compile * fix: code smell use const reference variable * fix: code smell * fix: code smell * fix: code smell * fix: code smell * 🎨 apply clang-format changes * fix: code smells 🎨 apply clang-format changes * opt: fix code smells remove unused parameters from function `ftsIndexIsOldOrBad` 🎨 apply clang-format changes --------- Co-authored-by: xiaoyifang <xiaoyifang@users.noreply.github.com>
This commit is contained in:
parent
e37e66b330
commit
5899aa7c94
|
@ -318,8 +318,7 @@ AardDictionary::AardDictionary( string const & id,
|
|||
|
||||
ftsIdxName = indexFile + Dictionary::getFtsSuffix();
|
||||
|
||||
if( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName )
|
||||
&& !FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) )
|
||||
if ( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName ) && !FtsHelpers::ftsIndexIsOldOrBad( this ) )
|
||||
FTS_index_completed.ref();
|
||||
}
|
||||
|
||||
|
@ -575,11 +574,11 @@ QString const& AardDictionary::getDescription()
|
|||
|
||||
void AardDictionary::makeFTSIndex( QAtomicInt & isCancelled, bool firstIteration )
|
||||
{
|
||||
if( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) ) )
|
||||
if ( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( this ) ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
if( haveFTSIndex() )
|
||||
if ( haveFTSIndex() )
|
||||
return;
|
||||
|
||||
if( ensureInitDone().size() )
|
||||
|
|
|
@ -286,8 +286,8 @@ namespace
|
|||
|
||||
ftsIdxName = indexFile + Dictionary::getFtsSuffix();
|
||||
|
||||
if( !Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
&& !FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) )
|
||||
if ( !Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
&& !FtsHelpers::ftsIndexIsOldOrBad( this ) )
|
||||
FTS_index_completed.ref();
|
||||
}
|
||||
|
||||
|
@ -451,8 +451,8 @@ namespace
|
|||
|
||||
void BglDictionary::makeFTSIndex( QAtomicInt & isCancelled, bool firstIteration )
|
||||
{
|
||||
if( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) ) )
|
||||
if ( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( this ) ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
if( haveFTSIndex() )
|
||||
|
|
|
@ -180,8 +180,7 @@ DictdDictionary::DictdDictionary( string const & id,
|
|||
|
||||
ftsIdxName = indexFile + Dictionary::getFtsSuffix();
|
||||
|
||||
if( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName )
|
||||
&& !FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) )
|
||||
if ( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName ) && !FtsHelpers::ftsIndexIsOldOrBad( this ) )
|
||||
FTS_index_completed.ref();
|
||||
}
|
||||
|
||||
|
@ -460,11 +459,11 @@ QString const& DictdDictionary::getDescription()
|
|||
|
||||
void DictdDictionary::makeFTSIndex( QAtomicInt & isCancelled, bool firstIteration )
|
||||
{
|
||||
if( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) ) )
|
||||
if ( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( this ) ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
if( haveFTSIndex() )
|
||||
if ( haveFTSIndex() )
|
||||
return;
|
||||
|
||||
if( ensureInitDone().size() )
|
||||
|
|
|
@ -287,8 +287,7 @@ DslDictionary::DslDictionary( string const & id,
|
|||
|
||||
ftsIdxName = indexFile + Dictionary::getFtsSuffix();
|
||||
|
||||
if( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName )
|
||||
&& !FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) )
|
||||
if ( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName ) && !FtsHelpers::ftsIndexIsOldOrBad( this ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
// Read the dictionary name
|
||||
|
@ -1216,12 +1215,12 @@ QString DslDictionary::getMainFilename() { return getDictionaryFilenames()[ 0 ].
|
|||
|
||||
void DslDictionary::makeFTSIndex( QAtomicInt & isCancelled, bool firstIteration )
|
||||
{
|
||||
if( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) ) )
|
||||
if ( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( this ) ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
|
||||
if( haveFTSIndex() )
|
||||
if ( haveFTSIndex() )
|
||||
return;
|
||||
|
||||
if( ensureInitDone().size() )
|
||||
|
|
|
@ -258,8 +258,7 @@ EpwingDictionary::EpwingDictionary( string const & id,
|
|||
|
||||
ftsIdxName = indexFile + Dictionary::getFtsSuffix();
|
||||
|
||||
if( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName )
|
||||
&& !FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) )
|
||||
if ( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName ) && !FtsHelpers::ftsIndexIsOldOrBad( this ) )
|
||||
FTS_index_completed.ref();
|
||||
}
|
||||
|
||||
|
@ -461,8 +460,8 @@ QString const& EpwingDictionary::getDescription()
|
|||
|
||||
void EpwingDictionary::makeFTSIndex( QAtomicInt & isCancelled, bool firstIteration )
|
||||
{
|
||||
if( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) ) )
|
||||
if ( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( this ) ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
|
||||
|
|
|
@ -499,8 +499,7 @@ GlsDictionary::GlsDictionary( string const & id,
|
|||
|
||||
ftsIdxName = indexFile + Dictionary::getFtsSuffix();
|
||||
|
||||
if( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName )
|
||||
&& !FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) )
|
||||
if ( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName ) && !FtsHelpers::ftsIndexIsOldOrBad( this ) )
|
||||
FTS_index_completed.ref();
|
||||
}
|
||||
|
||||
|
@ -570,8 +569,8 @@ QString GlsDictionary::getMainFilename() { return getDictionaryFilenames()[ 0 ].
|
|||
|
||||
void GlsDictionary::makeFTSIndex( QAtomicInt & isCancelled, bool firstIteration )
|
||||
{
|
||||
if( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) ) )
|
||||
if ( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( this ) ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
if( haveFTSIndex() )
|
||||
|
|
|
@ -336,8 +336,7 @@ MdxDictionary::MdxDictionary( string const & id, string const & indexFile, vecto
|
|||
|
||||
ftsIdxName = indexFile + Dictionary::getFtsSuffix();
|
||||
|
||||
if( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName )
|
||||
&& !FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) )
|
||||
if ( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName ) && !FtsHelpers::ftsIndexIsOldOrBad( this ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
cacheDirName = QDir::tempPath() + QDir::separator()
|
||||
|
@ -461,8 +460,8 @@ void MdxDictionary::doDeferredInit()
|
|||
|
||||
void MdxDictionary::makeFTSIndex( QAtomicInt & isCancelled, bool firstIteration )
|
||||
{
|
||||
if( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) ) )
|
||||
if ( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( this ) ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
if( haveFTSIndex() )
|
||||
|
|
|
@ -220,8 +220,7 @@ SdictDictionary::SdictDictionary( string const & id,
|
|||
|
||||
ftsIdxName = indexFile + Dictionary::getFtsSuffix();
|
||||
|
||||
if( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName )
|
||||
&& !FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) )
|
||||
if ( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName ) && !FtsHelpers::ftsIndexIsOldOrBad( this ) )
|
||||
FTS_index_completed.ref();
|
||||
}
|
||||
|
||||
|
@ -405,11 +404,11 @@ void SdictDictionary::loadArticle( uint32_t address,
|
|||
|
||||
void SdictDictionary::makeFTSIndex( QAtomicInt & isCancelled, bool firstIteration )
|
||||
{
|
||||
if( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) ) )
|
||||
if ( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( this ) ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
if( haveFTSIndex() )
|
||||
if ( haveFTSIndex() )
|
||||
return;
|
||||
|
||||
if( ensureInitDone().size() )
|
||||
|
|
|
@ -707,8 +707,7 @@ SlobDictionary::SlobDictionary( string const & id,
|
|||
|
||||
ftsIdxName = indexFile + Dictionary::getFtsSuffix();
|
||||
|
||||
if( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName )
|
||||
&& !FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) )
|
||||
if ( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName ) && !FtsHelpers::ftsIndexIsOldOrBad( this ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
texCgiPath = Config::getProgramDataDir() + "/mimetex.cgi";
|
||||
|
@ -1112,7 +1111,7 @@ void SlobDictionary::sortArticlesOffsetsForFTS( QVector< uint32_t > & offsets, Q
|
|||
void SlobDictionary::makeFTSIndex( QAtomicInt & isCancelled, bool firstIteration )
|
||||
{
|
||||
if ( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) ) )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( this ) ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
if ( haveFTSIndex() )
|
||||
|
|
|
@ -275,8 +275,7 @@ StardictDictionary::StardictDictionary( string const & id,
|
|||
|
||||
ftsIdxName = indexFile + Dictionary::getFtsSuffix();
|
||||
|
||||
if( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName )
|
||||
&& !FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) )
|
||||
if ( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName ) && !FtsHelpers::ftsIndexIsOldOrBad( this ) )
|
||||
FTS_index_completed.ref();
|
||||
}
|
||||
|
||||
|
@ -1155,11 +1154,11 @@ QString StardictDictionary::getMainFilename() { return getDictionaryFilenames()[
|
|||
|
||||
void StardictDictionary::makeFTSIndex( QAtomicInt & isCancelled, bool firstIteration )
|
||||
{
|
||||
if( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) ) )
|
||||
if ( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( this ) ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
if( haveFTSIndex() )
|
||||
if ( haveFTSIndex() )
|
||||
return;
|
||||
|
||||
if( ensureInitDone().size() )
|
||||
|
|
|
@ -311,8 +311,7 @@ XdxfDictionary::XdxfDictionary( string const & id,
|
|||
|
||||
ftsIdxName = indexFile + Dictionary::getFtsSuffix();
|
||||
|
||||
if( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName )
|
||||
&& !FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) )
|
||||
if ( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName ) && !FtsHelpers::ftsIndexIsOldOrBad( this ) )
|
||||
FTS_index_completed.ref();
|
||||
}
|
||||
|
||||
|
@ -384,11 +383,11 @@ QString XdxfDictionary::getMainFilename() { return getDictionaryFilenames()[ 0 ]
|
|||
|
||||
void XdxfDictionary::makeFTSIndex( QAtomicInt & isCancelled, bool firstIteration )
|
||||
{
|
||||
if( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) ) )
|
||||
if ( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( this ) ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
if( haveFTSIndex() )
|
||||
if ( haveFTSIndex() )
|
||||
return;
|
||||
|
||||
if( ensureInitDone().size() )
|
||||
|
|
|
@ -266,8 +266,7 @@ ZimDictionary::ZimDictionary( string const & id, string const & indexFile, vecto
|
|||
|
||||
ftsIdxName = indexFile + Dictionary::getFtsSuffix();
|
||||
|
||||
if ( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName )
|
||||
&& !FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) )
|
||||
if ( !Dictionary::needToRebuildIndex( dictionaryFiles, ftsIdxName ) && !FtsHelpers::ftsIndexIsOldOrBad( this ) )
|
||||
FTS_index_completed.ref();
|
||||
}
|
||||
|
||||
|
@ -473,8 +472,8 @@ QString const& ZimDictionary::getDescription()
|
|||
|
||||
void ZimDictionary::makeFTSIndex( QAtomicInt & isCancelled, bool firstIteration )
|
||||
{
|
||||
if( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( ftsIdxName, this ) ) )
|
||||
if ( !( Dictionary::needToRebuildIndex( getDictionaryFilenames(), ftsIdxName )
|
||||
|| FtsHelpers::ftsIndexIsOldOrBad( this ) ) )
|
||||
FTS_index_completed.ref();
|
||||
|
||||
if( haveFTSIndex() )
|
||||
|
|
|
@ -31,18 +31,16 @@ namespace FtsHelpers
|
|||
// finished reversed dehsinif
|
||||
const static std::string finish_mark = std::string( "dehsinif" );
|
||||
|
||||
bool ftsIndexIsOldOrBad( string const & indexFile,
|
||||
BtreeIndexing::BtreeDictionary * dict )
|
||||
bool ftsIndexIsOldOrBad( BtreeIndexing::BtreeDictionary * dict )
|
||||
{
|
||||
try
|
||||
{
|
||||
try {
|
||||
Xapian::WritableDatabase db( dict->ftsIndexName() );
|
||||
auto docid = db.get_lastdocid();
|
||||
auto document = db.get_document(docid);
|
||||
auto docid = db.get_lastdocid();
|
||||
auto document = db.get_document( docid );
|
||||
|
||||
qDebug()<<document.get_data().c_str();
|
||||
qDebug() << document.get_data().c_str();
|
||||
//use a special document to mark the end of the index.
|
||||
return document.get_data()!=finish_mark;
|
||||
return document.get_data() != finish_mark;
|
||||
}
|
||||
catch( Xapian::Error & e )
|
||||
{
|
||||
|
@ -55,7 +53,6 @@ bool ftsIndexIsOldOrBad( string const & indexFile,
|
|||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static QString makeHiliteRegExpString( QStringList const & words,
|
||||
|
|
|
@ -21,8 +21,7 @@
|
|||
namespace FtsHelpers
|
||||
{
|
||||
|
||||
bool ftsIndexIsOldOrBad( std::string const & indexFile,
|
||||
BtreeIndexing::BtreeDictionary * dict );
|
||||
bool ftsIndexIsOldOrBad( BtreeIndexing::BtreeDictionary * dict );
|
||||
|
||||
bool parseSearchString( QString const & str, QStringList & IndexWords,
|
||||
QStringList & searchWords,
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "articleview.hh"
|
||||
#include "dict/programs.hh"
|
||||
#include "folding.hh"
|
||||
#include "fulltextsearch.hh"
|
||||
#include "gddebug.hh"
|
||||
#include "gestures.hh"
|
||||
#include "globalbroadcaster.hh"
|
||||
|
@ -30,6 +29,7 @@
|
|||
#include <QWebEngineScriptCollection>
|
||||
#include <QWebEngineSettings>
|
||||
#include <map>
|
||||
#include <QApplication>
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0) && QT_VERSION < QT_VERSION_CHECK(6,0,0))
|
||||
#include <QWebEngineContextMenuData>
|
||||
|
@ -37,7 +37,8 @@
|
|||
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||
#include <QtCore5Compat/QRegExp>
|
||||
#include <QWebEngineContextMenuRequest>
|
||||
#include <QWebEngineFindTextResult>
|
||||
#include <QWebEngineFindTextResult>
|
||||
#include <utility>
|
||||
#endif
|
||||
#ifdef Q_OS_WIN32
|
||||
#include <windows.h>
|
||||
|
@ -47,122 +48,6 @@
|
|||
using std::map;
|
||||
using std::list;
|
||||
|
||||
/// AccentMarkHandler class
|
||||
///
|
||||
/// Remove accent marks from text
|
||||
/// and mirror position in normalized text to original text
|
||||
|
||||
class AccentMarkHandler
|
||||
{
|
||||
protected:
|
||||
QString normalizedString;
|
||||
QVector< int > accentMarkPos;
|
||||
public:
|
||||
AccentMarkHandler() = default;
|
||||
virtual ~AccentMarkHandler() = default;
|
||||
static QChar accentMark()
|
||||
{ return QChar( 0x301 ); }
|
||||
|
||||
/// Create text without accent marks
|
||||
/// and store mark positions
|
||||
virtual void setText( QString const & baseString )
|
||||
{
|
||||
accentMarkPos.clear();
|
||||
normalizedString.clear();
|
||||
int pos = 0;
|
||||
QChar mark = accentMark();
|
||||
|
||||
for ( auto const & str : baseString ) {
|
||||
if ( str == mark ) {
|
||||
accentMarkPos.append( pos );
|
||||
continue;
|
||||
}
|
||||
normalizedString.append( str );
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
/// Return text without accent marks
|
||||
QString const & normalizedText() const
|
||||
{ return normalizedString; }
|
||||
|
||||
/// Convert position into position in original text
|
||||
int mirrorPosition( int const & pos ) const
|
||||
{
|
||||
int newPos = pos;
|
||||
for( auto const accentPos: accentMarkPos)
|
||||
{
|
||||
if ( accentPos < pos )
|
||||
newPos++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return newPos;
|
||||
}
|
||||
};
|
||||
|
||||
/// End of DslAccentMark class
|
||||
|
||||
/// DiacriticsHandler class
|
||||
///
|
||||
/// Remove diacritics from text
|
||||
/// and mirror position in normalized text to original text
|
||||
|
||||
class DiacriticsHandler : public AccentMarkHandler
|
||||
{
|
||||
public:
|
||||
DiacriticsHandler() = default;
|
||||
~DiacriticsHandler() = default;
|
||||
|
||||
/// Create text without diacriticss
|
||||
/// and store diacritic marks positions
|
||||
void setText( QString const & baseString ) override
|
||||
{
|
||||
accentMarkPos.clear();
|
||||
normalizedString.clear();
|
||||
|
||||
gd::wstring baseText = gd::toWString( baseString );
|
||||
gd::wstring normText;
|
||||
|
||||
int pos = 0;
|
||||
normText.reserve( baseText.size() );
|
||||
|
||||
gd::wchar const * nextChar = baseText.data();
|
||||
size_t consumed;
|
||||
|
||||
for( size_t left = baseText.size(); left; )
|
||||
{
|
||||
if( *nextChar >= 0x10000U )
|
||||
{
|
||||
// Will be translated into surrogate pair
|
||||
normText.push_back( *nextChar );
|
||||
pos += 2;
|
||||
nextChar++; left--;
|
||||
continue;
|
||||
}
|
||||
|
||||
gd::wchar ch = *nextChar;
|
||||
|
||||
if( Folding::isCombiningMark( ch ) )
|
||||
{
|
||||
accentMarkPos.append( pos );
|
||||
nextChar++; left--;
|
||||
continue;
|
||||
}
|
||||
|
||||
normText.push_back( ch );
|
||||
pos += 1;
|
||||
nextChar += 1;
|
||||
left -= 1;
|
||||
}
|
||||
normalizedString = QString::fromStdU32String( normText );
|
||||
}
|
||||
};
|
||||
/// End of DiacriticsHandler class
|
||||
|
||||
void ArticleView::emitJavascriptFinished(){
|
||||
emit notifyJavascriptFinished();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -176,7 +61,7 @@ bool isScrollTo( QString const & id )
|
|||
QString dictionaryIdFromScrollTo( QString const & scrollTo )
|
||||
{
|
||||
Q_ASSERT( isScrollTo( scrollTo ) );
|
||||
const int scrollToPrefixLength = 7;
|
||||
constexpr int scrollToPrefixLength = 7;
|
||||
return scrollTo.mid( scrollToPrefixLength );
|
||||
}
|
||||
|
||||
|
@ -361,8 +246,7 @@ ArticleView::ArticleView( QWidget * parent, ArticleNetworkAccessManager & nm, Au
|
|||
// Variable name for store current selection range
|
||||
rangeVarName = QString( "sr_%1" ).arg( QString::number( (quint64)this, 16 ) );
|
||||
|
||||
const bool fromMainWindow = parent && parent->objectName() == "MainWindow";
|
||||
if ( fromMainWindow ) {
|
||||
if ( const bool fromMainWindow = parent && parent->objectName() == "MainWindow" ) {
|
||||
connect( GlobalBroadcaster::instance(),
|
||||
&GlobalBroadcaster::dictionaryChanges,
|
||||
this,
|
||||
|
@ -437,9 +321,7 @@ void ArticleView::showDefinition( QString const & word, unsigned group,
|
|||
delayedHighlightText.clear();
|
||||
}
|
||||
|
||||
Contexts::Iterator pos = contexts.find( "gdanchor" );
|
||||
if( pos != contexts.end() )
|
||||
{
|
||||
if ( Contexts::Iterator pos = contexts.find( "gdanchor" ); pos != contexts.end() ) {
|
||||
Utils::Url::addQueryItem( req, "gdanchor", contexts[ "gdanchor" ] );
|
||||
contexts.erase( pos );
|
||||
}
|
||||
|
@ -591,10 +473,7 @@ void ArticleView::handleUrlChanged( QUrl const & url )
|
|||
{
|
||||
QIcon icon;
|
||||
|
||||
unsigned group = getGroup( url );
|
||||
|
||||
if ( group )
|
||||
{
|
||||
if ( unsigned group = getGroup( url ) ) {
|
||||
// Find the group's instance corresponding to the fragment value
|
||||
for ( auto const & g : groups ) {
|
||||
if ( g.id == group ) {
|
||||
|
@ -632,17 +511,15 @@ void ArticleView::setActiveArticleId(QString const & dictId){
|
|||
|
||||
QString ArticleView::getCurrentArticle()
|
||||
{
|
||||
QString dictId=getActiveArticleId();
|
||||
const QString dictId = getActiveArticleId();
|
||||
return scrollToFromDictionaryId( dictId );
|
||||
}
|
||||
|
||||
void ArticleView::jumpToDictionary( QString const & id, bool force )
|
||||
{
|
||||
QString targetArticle = scrollToFromDictionaryId( id );
|
||||
|
||||
// jump only if neceessary, or when forced
|
||||
if ( force || targetArticle != getCurrentArticle() )
|
||||
{
|
||||
if ( const QString targetArticle = scrollToFromDictionaryId( id ); force || targetArticle != getCurrentArticle() ) {
|
||||
setCurrentArticle( targetArticle, true );
|
||||
}
|
||||
}
|
||||
|
@ -845,7 +722,7 @@ bool ArticleView::eventFilter( QObject * obj, QEvent * ev )
|
|||
|
||||
if( obj == webview ) {
|
||||
if( ev->type() == QEvent::MouseButtonPress ) {
|
||||
QMouseEvent * event = static_cast< QMouseEvent * >( ev );
|
||||
auto event = static_cast< QMouseEvent * >( ev );
|
||||
if ( event->button() == Qt::XButton1 ) {
|
||||
back();
|
||||
return true;
|
||||
|
@ -858,7 +735,7 @@ bool ArticleView::eventFilter( QObject * obj, QEvent * ev )
|
|||
else
|
||||
if ( ev->type() == QEvent::KeyPress )
|
||||
{
|
||||
QKeyEvent * keyEvent = static_cast< QKeyEvent * >( ev );
|
||||
auto keyEvent = static_cast< QKeyEvent * >( ev );
|
||||
|
||||
if ( keyEvent->modifiers() &
|
||||
( Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier ) )
|
||||
|
@ -920,17 +797,15 @@ QString ArticleView::getMutedForGroup( unsigned group )
|
|||
|
||||
if ( groupInstance )
|
||||
{
|
||||
for( unsigned x = 0; x < groupInstance->dictionaries.size(); ++x )
|
||||
{
|
||||
QString id = QString::fromStdString(
|
||||
groupInstance->dictionaries[ x ]->getId() );
|
||||
for ( const auto & dictionarie : groupInstance->dictionaries ) {
|
||||
QString id = QString::fromStdString( dictionarie->getId() );
|
||||
|
||||
if ( mutedDictionaries->contains( id ) )
|
||||
mutedDicts.append( id );
|
||||
}
|
||||
}
|
||||
|
||||
if ( mutedDicts.size() )
|
||||
if ( !mutedDicts.empty() )
|
||||
return mutedDicts.join( "," );
|
||||
}
|
||||
|
||||
|
@ -955,8 +830,8 @@ QStringList ArticleView::getMutedDictionaries(unsigned group) {
|
|||
QStringList mutedDicts;
|
||||
|
||||
if (groupInstance) {
|
||||
for (unsigned x = 0; x < groupInstance->dictionaries.size(); ++x) {
|
||||
QString id = QString::fromStdString(groupInstance->dictionaries[x]->getId());
|
||||
for ( const auto & dictionarie : groupInstance->dictionaries ) {
|
||||
QString id = QString::fromStdString( dictionarie->getId() );
|
||||
|
||||
if (mutedDictionaries->contains(id))
|
||||
mutedDicts.append(id);
|
||||
|
@ -1161,11 +1036,9 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref, QString const &
|
|||
{
|
||||
// Link to other dictionary
|
||||
QString dictName( Utils::Url::queryItemValue( url, "dict" ) );
|
||||
for( unsigned i = 0; i < allDictionaries.size(); i++ )
|
||||
{
|
||||
if( dictName.compare( QString::fromUtf8( allDictionaries[ i ]->getName().c_str() ) ) == 0 )
|
||||
{
|
||||
newScrollTo = scrollToFromDictionaryId( QString::fromUtf8( allDictionaries[ i ]->getId().c_str() ) );
|
||||
for ( const auto & allDictionarie : allDictionaries ) {
|
||||
if ( dictName.compare( QString::fromUtf8( allDictionarie->getName().c_str() ) ) == 0 ) {
|
||||
newScrollTo = scrollToFromDictionaryId( QString::fromUtf8( allDictionarie->getId().c_str() ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1208,14 +1081,13 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref, QString const &
|
|||
|
||||
unsigned currentGroup = getGroup( ref );
|
||||
|
||||
std::vector< sptr< Dictionary::Class > > const * activeDicts = 0;
|
||||
std::vector< sptr< Dictionary::Class > > const * activeDicts = nullptr;
|
||||
|
||||
if ( groups.size() )
|
||||
{
|
||||
for( unsigned x = 0; x < groups.size(); ++x )
|
||||
if ( groups[ x ].id == currentGroup )
|
||||
{
|
||||
activeDicts = &( groups[ x ].dictionaries );
|
||||
for ( const auto & group : groups )
|
||||
if ( group.id == currentGroup ) {
|
||||
activeDicts = &( group.dictionaries );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1351,11 +1223,8 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref, QString const &
|
|||
// Program. Run it.
|
||||
QString id( url.host() );
|
||||
|
||||
for( Config::Programs::const_iterator i = cfg.programs.begin();
|
||||
i != cfg.programs.end(); ++i )
|
||||
{
|
||||
if ( i->id == id )
|
||||
{
|
||||
for ( const auto & program : cfg.programs ) {
|
||||
if ( program.id == id ) {
|
||||
// Found the corresponding program.
|
||||
Programs::RunInstance * req = new Programs::RunInstance;
|
||||
|
||||
|
@ -1364,8 +1233,7 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref, QString const &
|
|||
QString error;
|
||||
|
||||
// Delete the request if it fails to start
|
||||
if ( !req->start( *i, url.path().mid( 1 ), error ) )
|
||||
{
|
||||
if ( !req->start( program, url.path().mid( 1 ), error ) ) {
|
||||
delete req;
|
||||
|
||||
QMessageBox::critical( this, "GoldenDict",
|
||||
|
@ -1426,14 +1294,13 @@ ResourceToSaveHandler * ArticleView::saveResource( const QUrl & url, const QUrl
|
|||
|
||||
unsigned currentGroup = getGroup( ref );
|
||||
|
||||
std::vector< sptr< Dictionary::Class > > const * activeDicts = 0;
|
||||
std::vector< sptr< Dictionary::Class > > const * activeDicts = nullptr;
|
||||
|
||||
if ( groups.size() )
|
||||
{
|
||||
for( unsigned x = 0; x < groups.size(); ++x )
|
||||
if ( groups[ x ].id == currentGroup )
|
||||
{
|
||||
activeDicts = &( groups[ x ].dictionaries );
|
||||
for ( const auto & group : groups )
|
||||
if ( group.id == currentGroup ) {
|
||||
activeDicts = &( group.dictionaries );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1454,14 +1321,12 @@ ResourceToSaveHandler * ArticleView::saveResource( const QUrl & url, const QUrl
|
|||
if( preferredName.compare( QString::fromUtf8( (*activeDicts)[ x ]->getName().c_str() ) ) == 0 )
|
||||
{
|
||||
preferred = x;
|
||||
sptr< Dictionary::DataRequest > req =
|
||||
(*activeDicts)[ x ]->getResource(
|
||||
url.path().mid( 1 ).toUtf8().data() );
|
||||
sptr< Dictionary::DataRequest > data_request =
|
||||
( *activeDicts )[ x ]->getResource( url.path().mid( 1 ).toUtf8().data() );
|
||||
|
||||
handler->addRequest( req );
|
||||
handler->addRequest( data_request );
|
||||
|
||||
if( req->isFinished() && req->dataSize() > 0 )
|
||||
{
|
||||
if ( data_request->isFinished() && data_request->dataSize() > 0 ) {
|
||||
handler->downloadFinished();
|
||||
return handler;
|
||||
}
|
||||
|
@ -1694,20 +1559,20 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
|
|||
QWebEnginePage * r = webview->page();
|
||||
QMenu menu( this );
|
||||
|
||||
QAction * followLink = 0;
|
||||
QAction * followLinkExternal = 0;
|
||||
QAction * followLinkNewTab = 0;
|
||||
QAction * lookupSelection = 0;
|
||||
QAction * lookupSelectionGr = 0;
|
||||
QAction * lookupSelectionNewTab = 0;
|
||||
QAction * lookupSelectionNewTabGr = 0;
|
||||
QAction * maxDictionaryRefsAction = 0;
|
||||
QAction * addWordToHistoryAction = 0;
|
||||
QAction * addHeaderToHistoryAction = 0;
|
||||
QAction * sendWordToInputLineAction = 0;
|
||||
QAction * saveImageAction = 0;
|
||||
QAction * saveSoundAction = 0;
|
||||
QAction * saveBookmark = 0;
|
||||
QAction * followLink = nullptr;
|
||||
QAction * followLinkExternal = nullptr;
|
||||
QAction * followLinkNewTab = nullptr;
|
||||
QAction * lookupSelection = nullptr;
|
||||
QAction * lookupSelectionGr = nullptr;
|
||||
QAction * lookupSelectionNewTab = nullptr;
|
||||
QAction * lookupSelectionNewTabGr = nullptr;
|
||||
QAction * maxDictionaryRefsAction = nullptr;
|
||||
QAction * addWordToHistoryAction = nullptr;
|
||||
QAction * addHeaderToHistoryAction = nullptr;
|
||||
QAction * sendWordToInputLineAction = nullptr;
|
||||
QAction * saveImageAction = nullptr;
|
||||
QAction * saveSoundAction = nullptr;
|
||||
QAction * saveBookmark = nullptr;
|
||||
|
||||
#if( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
|
||||
const QWebEngineContextMenuData * menuData = &(r->contextMenuData());
|
||||
|
@ -1798,7 +1663,7 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
|
|||
Instances::Group const * altGroup =
|
||||
( groupComboBox && groupComboBox->getCurrentGroup() != getGroup( webview->url() ) ) ?
|
||||
groups.findGroup( groupComboBox->getCurrentGroup() ) :
|
||||
0;
|
||||
nullptr;
|
||||
|
||||
if ( altGroup )
|
||||
{
|
||||
|
@ -1879,7 +1744,7 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
|
|||
{
|
||||
if ( allDictionaries[ x ]->getId() == i->toUtf8().data() )
|
||||
{
|
||||
QAction * action = 0;
|
||||
QAction * action = nullptr;
|
||||
if ( refsAdded == cfg.preferences.maxDictionaryRefsInContextMenu )
|
||||
{
|
||||
// Enough! Or the menu would become too large.
|
||||
|
@ -2364,7 +2229,7 @@ bool ArticleView::closeSearch()
|
|||
else
|
||||
if( ftsSearchIsOpened )
|
||||
{
|
||||
allMatches.clear();
|
||||
firstAvailableText.clear();
|
||||
uniqueMatches.clear();
|
||||
ftsPosition = 0;
|
||||
ftsSearchIsOpened = false;
|
||||
|
@ -2405,153 +2270,95 @@ void ArticleView::copyAsText()
|
|||
void ArticleView::highlightFTSResults()
|
||||
{
|
||||
closeSearch();
|
||||
|
||||
// Clear any current selection
|
||||
if( webview->selectedText().size() ) {
|
||||
webview->page()->runJavaScript( "window.getSelection().removeAllRanges();_=0;" );
|
||||
webview->findText( "" );
|
||||
QString regString = Utils::Url::queryItemValue( webview->url(), "regexp" );
|
||||
if ( regString.isEmpty() )
|
||||
return;
|
||||
|
||||
//<div><i>watch</i>out</div> to plainText will return "watchout".
|
||||
//if application goes here,that means the article text must contains the search text.
|
||||
//whole word match regString will contain \b . can not match the above senario.
|
||||
//workaround ,remove \b from the regstring="(\bwatch\b)"
|
||||
regString.remove( QRegularExpression( "\\\\b" ) );
|
||||
|
||||
//webengine support diacritic text searching.
|
||||
auto parts = regString.split( " ", Qt::SkipEmptyParts );
|
||||
//get first part of string.
|
||||
for ( auto const & p : parts ) {
|
||||
if ( p.startsWith( "-" ) )
|
||||
continue;
|
||||
|
||||
firstAvailableText = p;
|
||||
break;
|
||||
}
|
||||
|
||||
webview->page()->toPlainText(
|
||||
[ & ]( const QString pageText ) {
|
||||
const QUrl & url = webview->url();
|
||||
if ( firstAvailableText.isEmpty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString regString = Utils::Url::queryItemValue( url, "regexp" );
|
||||
if( regString.isEmpty() )
|
||||
return;
|
||||
|
||||
bool ignoreDiacritics = Utils::Url::hasQueryItem( url, "ignore_diacritics" );
|
||||
//remove possible wildcard character.
|
||||
auto cleaned = firstAvailableText.split( QRegularExpression( "\\p{P}" ) );
|
||||
|
||||
if( ignoreDiacritics )
|
||||
regString = QString::fromStdU32String( Folding::applyDiacriticsOnly( gd::toWString( regString ) ) );
|
||||
else
|
||||
regString = regString.remove( AccentMarkHandler::accentMark() );
|
||||
if ( cleaned.empty() )
|
||||
return;
|
||||
|
||||
//<div><i>watch</i>out</div> to plainText will return "watchout".
|
||||
//if application goes here,that means the article text must contains the search text.
|
||||
//whole word match regString will contain \b . can not match the above senario.
|
||||
//workaround ,remove \b from the regstring="(\bwatch\b)"
|
||||
regString.remove( QRegularExpression( "\\\\b" ) );
|
||||
firstAvailableText = cleaned.at( 0 );
|
||||
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
|
||||
webview->findText( firstAvailableText,
|
||||
QWebEnginePage::FindBackward,
|
||||
[ & ]( const QWebEngineFindTextResult & result ) {
|
||||
qInfo() << result.activeMatch() << "of" << result.numberOfMatches() << "matches";
|
||||
|
||||
QRegularExpression regexp;
|
||||
if( Utils::Url::hasQueryItem( url, "wildcards" ) )
|
||||
regexp.setPattern( wildcardsToRegexp( regString ) );
|
||||
else
|
||||
regexp.setPattern( regString );
|
||||
if ( result.numberOfMatches() == 0 ) {
|
||||
ftsSearchPanel->statusLabel->setText( searchStatusMessageNoMatches() );
|
||||
}
|
||||
else {
|
||||
ftsSearchPanel->statusLabel->setText(
|
||||
searchStatusMessage( result.activeMatch(), result.numberOfMatches() ) );
|
||||
}
|
||||
|
||||
QRegularExpression::PatternOptions patternOptions =
|
||||
QRegularExpression::DotMatchesEverythingOption | QRegularExpression::UseUnicodePropertiesOption |
|
||||
QRegularExpression::MultilineOption | QRegularExpression::InvertedGreedinessOption;
|
||||
if( !Utils::Url::hasQueryItem( url, "matchcase" ) )
|
||||
patternOptions |= QRegularExpression::CaseInsensitiveOption;
|
||||
regexp.setPatternOptions( patternOptions );
|
||||
ftsSearchPanel->show();
|
||||
ftsSearchPanel->previous->setEnabled( result.numberOfMatches() > 1 );
|
||||
ftsSearchPanel->next->setEnabled( result.numberOfMatches() > 1 );
|
||||
|
||||
if( regexp.pattern().isEmpty() || !regexp.isValid() )
|
||||
return;
|
||||
sptr< AccentMarkHandler > marksHandler = ignoreDiacritics ? std::make_shared<DiacriticsHandler>() : std::make_shared<AccentMarkHandler>();
|
||||
|
||||
marksHandler->setText( pageText );
|
||||
|
||||
QRegularExpressionMatchIterator it = regexp.globalMatch( marksHandler->normalizedText() );
|
||||
while( it.hasNext() )
|
||||
{
|
||||
QRegularExpressionMatch match = it.next();
|
||||
|
||||
// Mirror pos and matched length to original string
|
||||
int pos = match.capturedStart();
|
||||
int spos = marksHandler->mirrorPosition( pos );
|
||||
int matched = marksHandler->mirrorPosition( pos + match.capturedLength() ) - spos;
|
||||
|
||||
// Add mark pos (if presented)
|
||||
while( spos + matched < pageText.length() && pageText[ spos + matched ].category() == QChar::Mark_NonSpacing )
|
||||
matched++;
|
||||
|
||||
if( matched > FTS::MaxMatchLengthForHighlightResults )
|
||||
{
|
||||
gdWarning( "ArticleView::highlightFTSResults(): Too long match - skipped (matched length %i, allowed %i)",
|
||||
match.capturedLength(),
|
||||
FTS::MaxMatchLengthForHighlightResults );
|
||||
}
|
||||
else
|
||||
allMatches.append( pageText.mid( spos, matched ) );
|
||||
}
|
||||
|
||||
ftsSearchMatchCase = Utils::Url::hasQueryItem( url, "matchcase" );
|
||||
|
||||
QWebEnginePage::FindFlags flags( QWebEnginePage::FindBackward );
|
||||
|
||||
if( ftsSearchMatchCase )
|
||||
flags |= QWebEnginePage::FindCaseSensitively;
|
||||
|
||||
if( allMatches.isEmpty() )
|
||||
ftsSearchPanel->statusLabel->setText( searchStatusMessageNoMatches() );
|
||||
else {
|
||||
// highlightAllFtsOccurences( flags );
|
||||
webview->findText( allMatches.at( 0 ), flags );
|
||||
// if( webview->findText( allMatches.at( 0 ), flags ) )
|
||||
// {
|
||||
// webview->page()->runJavaScript(
|
||||
// QString( "%1=window.getSelection().getRangeAt(0);_=0;" ).arg( rangeVarName ) );
|
||||
// }
|
||||
Q_ASSERT( ftsPosition == 0 );
|
||||
ftsSearchPanel->statusLabel->setText( searchStatusMessage( 1, allMatches.size() ) );
|
||||
}
|
||||
|
||||
|
||||
ftsSearchPanel->show();
|
||||
ftsSearchPanel->previous->setEnabled( false );
|
||||
ftsSearchPanel->next->setEnabled( allMatches.size() > 1 );
|
||||
|
||||
ftsSearchIsOpened = true;
|
||||
} );
|
||||
ftsSearchIsOpened = true;
|
||||
} );
|
||||
#else
|
||||
webview->findText( firstAvailableText, QWebEnginePage::FindBackward, [ this ]( bool res ) {
|
||||
ftsSearchPanel->previous->setEnabled( res );
|
||||
if ( !ftsSearchPanel->next->isEnabled() )
|
||||
ftsSearchPanel->next->setEnabled( res );
|
||||
} );
|
||||
#endif
|
||||
}
|
||||
|
||||
void ArticleView::highlightAllFtsOccurences( QWebEnginePage::FindFlags flags )
|
||||
void ArticleView::setActiveDictIds( const ActiveDictIds & ad )
|
||||
{
|
||||
// Usually allMatches contains mostly duplicates. Thus searching for each element of
|
||||
// allMatches to highlight them takes a long time => collect unique elements into a
|
||||
// set and search for them instead.
|
||||
// Don't use QList::toSet() or QSet's range constructor because they reserve space
|
||||
// for QList::size() elements, whereas the final QSet size is likely 1 or 2.
|
||||
QSet< QString > uniqueMatches;
|
||||
for( int x = 0; x < allMatches.size(); ++x )
|
||||
{
|
||||
QString const & match = allMatches.at( x );
|
||||
// Consider words that differ only in case equal if the search is case-insensitive.
|
||||
uniqueMatches.insert( ftsSearchMatchCase ? match : match.toLower() );
|
||||
if ( ( ad.word == currentWord && ad.groupId == getCurrentGroup() ) || historyMode ) {
|
||||
// ignore all other signals.
|
||||
qDebug() << "receive dicts, current word:" << currentWord << ad.word << ":" << ad.dictIds;
|
||||
currentActiveDictIds << ad.dictIds;
|
||||
currentActiveDictIds.removeDuplicates();
|
||||
emit updateFoundInDictsList();
|
||||
}
|
||||
|
||||
for( QSet< QString >::const_iterator it = uniqueMatches.constBegin(); it != uniqueMatches.constEnd(); ++it )
|
||||
webview->findText( *it, flags );
|
||||
}
|
||||
|
||||
void ArticleView::setActiveDictIds(ActiveDictIds ad) {
|
||||
if ( ( ad.word == currentWord && ad.groupId == getCurrentGroup() ) || historyMode)
|
||||
{
|
||||
// ignore all other signals.
|
||||
qDebug() << "receive dicts, current word:" << currentWord << ad.word << ":" << ad.dictIds;
|
||||
currentActiveDictIds << ad.dictIds;
|
||||
currentActiveDictIds.removeDuplicates();
|
||||
emit updateFoundInDictsList();
|
||||
}
|
||||
}
|
||||
|
||||
void ArticleView::dictionaryClear( ActiveDictIds ad )
|
||||
void ArticleView::dictionaryClear( const ActiveDictIds & ad )
|
||||
{
|
||||
// ignore all other signals.
|
||||
if( ad.word == currentWord && ad.groupId==getCurrentGroup() )
|
||||
{
|
||||
if ( ad.word == currentWord && ad.groupId == getCurrentGroup() ) {
|
||||
qDebug() << "clear current dictionaries:" << currentWord;
|
||||
currentActiveDictIds.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//todo ,futher refinement?
|
||||
void ArticleView::performFtsFindOperation( bool backwards )
|
||||
{
|
||||
if( !ftsSearchIsOpened )
|
||||
return;
|
||||
|
||||
if( allMatches.isEmpty() ) {
|
||||
if ( firstAvailableText.isEmpty() ) {
|
||||
ftsSearchPanel->statusLabel->setText( searchStatusMessageNoMatches() );
|
||||
ftsSearchPanel->next->setEnabled( false );
|
||||
ftsSearchPanel->previous->setEnabled( false );
|
||||
|
@ -2568,12 +2375,9 @@ void ArticleView::performFtsFindOperation( bool backwards )
|
|||
webview->page()->runJavaScript(
|
||||
QString( "var sel=window.getSelection();sel.removeAllRanges();sel.addRange(%1);_=0;" ).arg( rangeVarName ) );
|
||||
|
||||
if( backwards ) {
|
||||
if( ftsPosition > 0 ) {
|
||||
ftsPosition -= 1;
|
||||
}
|
||||
if ( backwards ) {
|
||||
#if( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
|
||||
webview->findText( allMatches.at( ftsPosition ),
|
||||
webview->findText( firstAvailableText,
|
||||
flags | QWebEnginePage::FindBackward,
|
||||
[ this ]( const QWebEngineFindTextResult & result ) {
|
||||
if( result.numberOfMatches() == 0 )
|
||||
|
@ -2581,9 +2385,12 @@ void ArticleView::performFtsFindOperation( bool backwards )
|
|||
ftsSearchPanel->previous->setEnabled( true );
|
||||
if( !ftsSearchPanel->next->isEnabled() )
|
||||
ftsSearchPanel->next->setEnabled( true );
|
||||
|
||||
ftsSearchPanel->statusLabel->setText(
|
||||
searchStatusMessage( result.activeMatch(), result.numberOfMatches() ) );
|
||||
} );
|
||||
#else
|
||||
webview->findText( allMatches.at( ftsPosition ), flags | QWebEnginePage::FindBackward, [ this ]( bool res ) {
|
||||
webview->findText( firstAvailableText, flags | QWebEnginePage::FindBackward, [ this ]( bool res ) {
|
||||
ftsSearchPanel->previous->setEnabled( res );
|
||||
if( !ftsSearchPanel->next->isEnabled() )
|
||||
ftsSearchPanel->next->setEnabled( res );
|
||||
|
@ -2591,30 +2398,26 @@ void ArticleView::performFtsFindOperation( bool backwards )
|
|||
#endif
|
||||
}
|
||||
else {
|
||||
if( ftsPosition < allMatches.size() - 1 ) {
|
||||
ftsPosition += 1;
|
||||
}
|
||||
#if( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
|
||||
webview->findText( allMatches.at( ftsPosition ), flags, [ this ]( const QWebEngineFindTextResult & result ) {
|
||||
webview->findText( firstAvailableText, flags, [ this ]( const QWebEngineFindTextResult & result ) {
|
||||
if( result.numberOfMatches() == 0 )
|
||||
return;
|
||||
ftsSearchPanel->next->setEnabled( true );
|
||||
if( !ftsSearchPanel->previous->isEnabled() )
|
||||
ftsSearchPanel->previous->setEnabled( true );
|
||||
|
||||
ftsSearchPanel->statusLabel->setText( searchStatusMessage( result.activeMatch(), result.numberOfMatches() ) );
|
||||
} );
|
||||
}
|
||||
#else
|
||||
|
||||
webview->findText( allMatches.at( ftsPosition ), flags, [ this ]( bool res ) {
|
||||
webview->findText( firstAvailableText, flags, [ this ]( bool res ) {
|
||||
ftsSearchPanel->next->setEnabled( res );
|
||||
if( !ftsSearchPanel->previous->isEnabled() )
|
||||
if ( !ftsSearchPanel->previous->isEnabled() )
|
||||
ftsSearchPanel->previous->setEnabled( res );
|
||||
} );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ftsSearchPanel->statusLabel->setText( searchStatusMessage( ftsPosition + 1, allMatches.size() ) );
|
||||
}
|
||||
}
|
||||
|
||||
void ArticleView::on_ftsSearchPrevious_clicked()
|
||||
|
@ -2627,18 +2430,17 @@ void ArticleView::on_ftsSearchNext_clicked()
|
|||
performFtsFindOperation( false );
|
||||
}
|
||||
|
||||
ResourceToSaveHandler::ResourceToSaveHandler(ArticleView * view, QString const & fileName ) :
|
||||
ResourceToSaveHandler::ResourceToSaveHandler( ArticleView * view, QString fileName ):
|
||||
QObject( view ),
|
||||
fileName( fileName ),
|
||||
fileName( std::move( fileName ) ),
|
||||
alreadyDone( false )
|
||||
{
|
||||
connect( this, &ResourceToSaveHandler::statusBarMessage, view, &ArticleView::statusBarMessage );
|
||||
}
|
||||
|
||||
void ResourceToSaveHandler::addRequest( sptr< Dictionary::DataRequest > req )
|
||||
void ResourceToSaveHandler::addRequest( const sptr< Dictionary::DataRequest > & req )
|
||||
{
|
||||
if( !alreadyDone )
|
||||
{
|
||||
if ( !alreadyDone ) {
|
||||
downloadRequests.push_back( req );
|
||||
|
||||
connect( req.get(), &Dictionary::Request::finished, this, &ResourceToSaveHandler::downloadFinished );
|
||||
|
@ -2651,22 +2453,18 @@ void ResourceToSaveHandler::downloadFinished()
|
|||
return; // Stray signal
|
||||
|
||||
// Find any finished resources
|
||||
for( list< sptr< Dictionary::DataRequest > >::iterator i =
|
||||
downloadRequests.begin(); i != downloadRequests.end(); )
|
||||
{
|
||||
if ( (*i)->isFinished() )
|
||||
{
|
||||
if ( (*i)->dataSize() >= 0 && !alreadyDone )
|
||||
{
|
||||
for ( auto i = downloadRequests.begin(); i != downloadRequests.end(); ) {
|
||||
if ( ( *i )->isFinished() ) {
|
||||
if ( ( *i )->dataSize() >= 0 && !alreadyDone ) {
|
||||
QByteArray resourceData;
|
||||
vector< char > const & data = (*i)->getFullData();
|
||||
resourceData = QByteArray( data.data(), data.size() );
|
||||
vector< char > const & data = ( *i )->getFullData();
|
||||
resourceData = QByteArray( data.data(), data.size() );
|
||||
|
||||
// Write data to file
|
||||
|
||||
if ( !fileName.isEmpty() )
|
||||
{
|
||||
QFileInfo fileInfo( fileName );
|
||||
const QFileInfo fileInfo( fileName );
|
||||
QDir().mkpath( fileInfo.absoluteDir().absolutePath() );
|
||||
|
||||
QFile file( fileName );
|
||||
|
|
|
@ -84,7 +84,7 @@ class ArticleView: public QWidget
|
|||
QString activeDictId;
|
||||
|
||||
/// Search in results of full-text search
|
||||
QStringList allMatches;
|
||||
QString firstAvailableText;
|
||||
QStringList uniqueMatches;
|
||||
bool ftsSearchIsOpened = false;
|
||||
bool ftsSearchMatchCase = false;
|
||||
|
@ -93,7 +93,6 @@ class ArticleView: public QWidget
|
|||
QString delayedHighlightText;
|
||||
|
||||
void highlightFTSResults();
|
||||
void highlightAllFtsOccurences( QWebEnginePage::FindFlags flags );
|
||||
void performFtsFindOperation( bool backwards );
|
||||
|
||||
public:
|
||||
|
@ -127,8 +126,6 @@ public:
|
|||
/// Returns "gdfrom-" + dictionaryId.
|
||||
static QString scrollToFromDictionaryId( QString const & dictionaryId );
|
||||
|
||||
void emitJavascriptFinished();
|
||||
|
||||
/// Shows the definition of the given word with the given group.
|
||||
/// scrollTo can be optionally set to a "gdfrom-xxxx" identifier to position
|
||||
/// the page to that article on load.
|
||||
|
@ -380,9 +377,9 @@ private slots:
|
|||
/// Copy current selection as plain text
|
||||
void copyAsText();
|
||||
|
||||
void setActiveDictIds(ActiveDictIds);
|
||||
void setActiveDictIds( const ActiveDictIds & ad );
|
||||
|
||||
void dictionaryClear( ActiveDictIds ad );
|
||||
void dictionaryClear( const ActiveDictIds & ad );
|
||||
|
||||
private:
|
||||
|
||||
|
@ -417,7 +414,7 @@ private:
|
|||
/// Attempts removing last temporary file created.
|
||||
void cleanupTemp();
|
||||
|
||||
bool eventFilter( QObject * obj, QEvent * ev );
|
||||
bool eventFilter( QObject * obj, QEvent * ev ) override;
|
||||
|
||||
void performFindOperation( bool restart, bool backwards, bool checkHighlight = false );
|
||||
|
||||
|
@ -428,9 +425,8 @@ private:
|
|||
QStringList getMutedDictionaries(unsigned group);
|
||||
|
||||
protected:
|
||||
// We need this to hide the search bar when we're showed
|
||||
void showEvent( QShowEvent * );
|
||||
|
||||
// We need this to hide the search bar when we're showed
|
||||
void showEvent( QShowEvent * ) override;
|
||||
};
|
||||
|
||||
class ResourceToSaveHandler: public QObject
|
||||
|
@ -438,10 +434,12 @@ class ResourceToSaveHandler: public QObject
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ResourceToSaveHandler( ArticleView * view, QString const & fileName );
|
||||
void addRequest( sptr< Dictionary::DataRequest > req );
|
||||
explicit ResourceToSaveHandler( ArticleView * view, QString fileName );
|
||||
void addRequest( const sptr< Dictionary::DataRequest > & req );
|
||||
bool isEmpty()
|
||||
{ return downloadRequests.empty(); }
|
||||
{
|
||||
return downloadRequests.empty();
|
||||
}
|
||||
|
||||
signals:
|
||||
void done();
|
||||
|
@ -462,7 +460,7 @@ class ArticleViewAgent : public QObject
|
|||
ArticleView * articleView;
|
||||
|
||||
public:
|
||||
ArticleViewAgent( ArticleView * articleView );
|
||||
explicit ArticleViewAgent( ArticleView * articleView );
|
||||
|
||||
|
||||
public slots:
|
||||
|
|
Loading…
Reference in a new issue