From db432206e5d6410d82e78133119cdb1f8c16d162 Mon Sep 17 00:00:00 2001 From: Ryan Qian Date: Sun, 22 Jan 2023 19:23:53 +0800 Subject: [PATCH 1/7] fix: 'equals' built-in test function block the opening brace must stand on the same line as the condition, otherwise the condition will be invalid. --- goldendict.pro | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/goldendict.pro b/goldendict.pro index e188ba30..1cfbf418 100644 --- a/goldendict.pro +++ b/goldendict.pro @@ -673,8 +673,7 @@ TS_OUT = $$TRANSLATIONS TS_OUT ~= s/.ts/.qm/g PRE_TARGETDEPS += $$TS_OUT -equals(QT_VERSION,6.4.0) -{ +equals(QT_VERSION,6.4.0) { #QTBUG-105984 multimedia.files = $$[QT_PLUGIN_PATH]/multimedia/* multimedia.path = plugins/multimedia From 131cffbdb20c143dde1e7730e46b7044f8612318 Mon Sep 17 00:00:00 2001 From: Ryan Qian Date: Sun, 22 Jan 2023 20:06:05 +0800 Subject: [PATCH 2/7] fix: qtmultimedia dependency audiooutput.cpp includes the QAudioFormat unconditionally, but it looks like this file is only used by ffmpeg_player and qtmultimedia_player, so add an extra condition to append this file and its header. --- goldendict.pro | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/goldendict.pro b/goldendict.pro index 1cfbf418..0c07617e 100644 --- a/goldendict.pro +++ b/goldendict.pro @@ -62,6 +62,11 @@ DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x050F00 DEFINES += MAKE_FFMPEG_PLAYER } +contains(DEFINES, MAKE_QTMULTIMEDIA_PLAYER|MAKE_FFMPEG_PLAYER) { + HEADERS += audiooutput.h + SOURCES += audiooutput.cpp +} + # on windows platform ,only works in release build CONFIG( use_xapian ) { DEFINES += USE_XAPIAN @@ -267,7 +272,6 @@ HEADERS += folding.hh \ ankiconnector.h \ article_inspect.h \ articlewebpage.h \ - audiooutput.h \ base/globalregex.hh \ base_type.h \ globalbroadcaster.h \ @@ -413,7 +417,6 @@ SOURCES += folding.cc \ ankiconnector.cpp \ article_inspect.cpp \ articlewebpage.cpp \ - audiooutput.cpp \ base/globalregex.cc \ globalbroadcaster.cpp \ headwordsmodel.cpp \ From 8e2e6d8658ca2bb11a3de89a1735680f73248da5 Mon Sep 17 00:00:00 2001 From: Abs62 Date: Tue, 17 Jan 2023 20:59:13 +0300 Subject: [PATCH 3/7] Zim: One more check for Zim header --- zim.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/zim.cc b/zim.cc index 8fab4705..9057e29e 100644 --- a/zim.cc +++ b/zim.cc @@ -62,6 +62,7 @@ using BtreeIndexing::IndexInfo; DEF_EX_STR( exNotZimFile, "Not an Zim file", Dictionary::Ex ) DEF_EX_STR( exCantReadFile, "Can't read file", Dictionary::Ex ) +DEF_EX_STR( exInvalidZimHeader, "Invalid Zim header", Dictionary::Ex ) DEF_EX( exUserAbort, "User abort", Dictionary::Ex ) @@ -287,6 +288,9 @@ bool ZimFile::open() if( read( reinterpret_cast< char * >( &zimHeader ), sizeof( zimHeader ) ) != sizeof( zimHeader ) ) return false; + if( zimHeader.magicNumber != 0x44D495A || zimHeader.mimeListPos != sizeof( zimHeader ) ) + return false; + // Clusters in zim file may be placed in random order. // We create sorted offsets list to calculate clusters size. @@ -1567,11 +1571,15 @@ vector< sptr< Dictionary::Class > > makeDictionaries( df.open(); ZIM_header const & zh = df.header(); - bool new_namespaces = ( zh.majorVersion >= 6 && zh.minorVersion >= 1 ); if( zh.magicNumber != 0x44D495A ) throw exNotZimFile( i->c_str() ); + if( zh.mimeListPos != sizeof( ZIM_header ) ) + throw exInvalidZimHeader( i->c_str() ); + + bool new_namespaces = ( zh.majorVersion >= 6 && zh.minorVersion >= 1 ); + { int n = firstName.lastIndexOf( '/' ); initializing.indexingDictionary( firstName.mid( n + 1 ).toUtf8().constData() ); From 620346bfaad63f420a6eb3a2183a316cd9035c7d Mon Sep 17 00:00:00 2001 From: Abs62 Date: Wed, 18 Jan 2023 20:25:03 +0300 Subject: [PATCH 4/7] Remove 0xAD symbol (soft hyphen) for popup window search --- config.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.cc b/config.cc index 2660095a..d4ce380c 100644 --- a/config.cc +++ b/config.cc @@ -199,7 +199,7 @@ InputPhrase Preferences::sanitizeInputPhrase( QString const & inputPhrase ) cons return result; } - const QString withPunct = _phase.simplified(); + const QString withPunct = _phase.simplified().remove( QChar( 0xAD ) ); // Simplify whitespaces and remove soft hyphens; result.phrase = gd::toQString( Folding::trimWhitespaceOrPunct( gd::toWString( withPunct ) ) ); if ( !result.isValid() ) return result; // The suffix of an invalid input phrase must be empty. From cbdfa586d128d0388525e5db6afbb524c6c45961 Mon Sep 17 00:00:00 2001 From: Abs62 Date: Thu, 19 Jan 2023 17:57:47 +0300 Subject: [PATCH 5/7] XDXF: Add support for draft revision 034 (issue #1600) --- xdxf.cc | 72 ++++++++++++++++++++++++++++++++++++++++++---------- xdxf.hh | 2 ++ xdxf2html.cc | 31 ++++++++++++++++++++-- 3 files changed, 90 insertions(+), 15 deletions(-) diff --git a/xdxf.cc b/xdxf.cc index bea69777..6ccb2e16 100644 --- a/xdxf.cc +++ b/xdxf.cc @@ -63,6 +63,22 @@ using BtreeIndexing::WordArticleLink; using BtreeIndexing::IndexedWords; using BtreeIndexing::IndexInfo; +quint32 getLanguageId( const QString & lang ) +{ + QString lstr = lang.left( 3 ); + + if( lstr.endsWith( QChar( '-' ) ) ) + lstr.chop( 1 ); + + switch( lstr.size() ) + { + case 2: return LangCoder::code2toInt( lstr.toLatin1().data() ); + case 3: return LangCoder::findIdForLanguageCode3( lstr.toLatin1().data() ); + } + + return 0; +} + namespace { DEF_EX_STR( exCantReadFile, "Can't read file", Dictionary::Ex ) @@ -73,7 +89,7 @@ DEF_EX_STR( exDictzipError, "DICTZIP error", Dictionary::Ex ) enum { Signature = 0x46584458, // XDXF on little-endian, FXDX on big-endian - CurrentFormatVersion = 5 + BtreeIndexing::FormatVersion + Folding::Version + CurrentFormatVersion = 6 + BtreeIndexing::FormatVersion + Folding::Version }; enum ArticleFormat @@ -1208,25 +1224,19 @@ vector< sptr< Dictionary::Class > > makeDictionaries( // Read the xdxf string str = stream.attributes().value( "lang_from" ).toString().toLatin1().data(); - - if ( str.size() > 3 ) - str.resize( 3 ); - - idxHeader.langFrom = LangCoder::findIdForLanguageCode3( str.c_str() ); + if( !str.empty() ) + idxHeader.langFrom = getLanguageId( str.c_str() ); str = stream.attributes().value( "lang_to" ).toString().toLatin1().data(); - - if ( str.size() > 3 ) - str.resize( 3 ); - - idxHeader.langTo = LangCoder::findIdForLanguageCode3( str.c_str() ); - - bool isLogical = ( stream.attributes().value( "format" ) == u"logical" ); + if( !str.empty() ) + idxHeader.langTo = getLanguageId( str.c_str() ); QRegExp regNum( "\\d+" ); regNum.indexIn( stream.attributes().value( "revision" ).toString() ); idxHeader.revisionNumber = regNum.cap().toUInt(); + bool isLogical = ( stream.attributes().value( "format" ) == "logical" || idxHeader.revisionNumber >= 34 ); + idxHeader.articleFormat = isLogical ? Logical : Visual; unsigned articleCount = 0, wordCount = 0; @@ -1269,6 +1279,12 @@ vector< sptr< Dictionary::Class > > makeDictionaries( // todo implement adding other information to the description like , , , , , , , QString desc = readXhtmlData( stream ); + if( isLogical ) + { + desc = desc.simplified(); + desc.replace( QRegExp( "\\s*
" ), QChar( '\n' ) ); + } + if ( dictionaryDescription.isEmpty() ) { dictionaryDescription = desc; @@ -1286,6 +1302,36 @@ vector< sptr< Dictionary::Class > > makeDictionaries( } } else + if( stream.name() == "languages" ) + { + while( !( stream.isEndElement() && stream.name() == "languages" ) && !stream.atEnd() ) + { + if( !stream.readNext() ) + break; + if ( stream.isStartElement() ) + { + if( stream.name() == "from" ) + { + if( idxHeader.langFrom == 0 ) + { + QString lang = stream.attributes().value( "xml:lang" ).toString(); + idxHeader.langFrom = getLanguageId( lang ); + } + } + else if( stream.name() == "to" ) + { + if( idxHeader.langTo == 0 ) + { + QString lang = stream.attributes().value( "xml:lang" ).toString(); + idxHeader.langTo = getLanguageId( lang ); + } + } + } + else if ( stream.isEndElement() && stream.name() == "languages" ) + break; + } + } + else if ( stream.name() == u"abbreviations" ) { QString s; diff --git a/xdxf.hh b/xdxf.hh index c562a56a..c6a9e502 100644 --- a/xdxf.hh +++ b/xdxf.hh @@ -12,6 +12,8 @@ namespace Xdxf { using std::vector; using std::string; +quint32 getLanguageId( const QString & lang ); + vector< sptr< Dictionary::Class > > makeDictionaries( vector< string > const & fileNames, string const & indicesDir, diff --git a/xdxf2html.cc b/xdxf2html.cc index b5da8b66..c2570518 100644 --- a/xdxf2html.cc +++ b/xdxf2html.cc @@ -14,6 +14,7 @@ #include "htmlescape.hh" #include "utils.hh" #include +#include "xdxf.hh" #include @@ -231,8 +232,20 @@ string convert( string const & in, DICT_TYPE type, map < string, string > const el.setTagName( "div" ); el.setAttribute( "class", "xdxf_headwords" ); - if( dictPtr->isFromLanguageRTL() != dictPtr->isToLanguageRTL() ) - el.setAttribute( "dir", dictPtr->isFromLanguageRTL() ? "rtl" : "ltr" ); + bool isLanguageRtl = dictPtr->isFromLanguageRTL(); + if( el.hasAttribute( "xml:lang" ) ) + { + // Change xml-attribute "xml:lang" to html-attribute "lang" + QString lang = el.attribute( "xml:lang" ); + el.removeAttribute( "xml:lang" ); + el.setAttribute( "lang", lang ); + + quint32 langID = Xdxf::getLanguageId( lang ); + if( langID ) + isLanguageRtl = LangCoder::isLanguageRTL( langID ); + } + if( isLanguageRtl != dictPtr->isToLanguageRTL() ) + el.setAttribute( "dir", isLanguageRtl ? "rtl" : "ltr" ); } } @@ -327,6 +340,20 @@ string convert( string const & in, DICT_TYPE type, map < string, string > const QDomElement el = nodes.at( 0 ).toElement(); el.setTagName( "span" ); el.setAttribute( "class", "xdxf_def" ); + bool isLanguageRtl = dictPtr->isToLanguageRTL(); + if( el.hasAttribute( "xml:lang" ) ) + { + // Change xml-attribute "xml:lang" to html-attribute "lang" + QString lang = el.attribute( "xml:lang" ); + el.removeAttribute( "xml:lang" ); + el.setAttribute( "lang", lang ); + + quint32 langID = Xdxf::getLanguageId( lang ); + if( langID ) + isLanguageRtl = LangCoder::isLanguageRTL( langID ); + } + if( isLanguageRtl != dictPtr->isToLanguageRTL() ) + el.setAttribute( "dir", isLanguageRtl ? "rtl" : "ltr" ); } } From e4595fb6d9e00b0b7df75a9affc24a214f29e3da Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Tue, 24 Jan 2023 21:07:24 +0800 Subject: [PATCH 6/7] fix:bgl encoding convert exception --- iconv.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iconv.cc b/iconv.cc index c266440e..b534fda2 100644 --- a/iconv.cc +++ b/iconv.cc @@ -26,8 +26,10 @@ Iconv::~Iconv() QString Iconv::convert(void const* & inBuf, size_t& inBytesLeft) { - return codec->toUnicode(static_cast(inBuf), inBytesLeft); - + if( codec ) + return codec->toUnicode( static_cast< const char * >( inBuf ), inBytesLeft ); + QByteArray ba( static_cast< const char * >( inBuf ), inBytesLeft ); + return QString( ba ); } gd::wstring Iconv::toWstring( char const * fromEncoding, void const * fromData, From fabb9d6487ca05012633633aead570757fa19a5b Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Tue, 24 Jan 2023 20:37:34 +0800 Subject: [PATCH 7/7] fix:compile error after merge xdxf.cc changes --- xdxf.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/xdxf.cc b/xdxf.cc index 6ccb2e16..6fabadde 100644 --- a/xdxf.cc +++ b/xdxf.cc @@ -1235,7 +1235,7 @@ vector< sptr< Dictionary::Class > > makeDictionaries( regNum.indexIn( stream.attributes().value( "revision" ).toString() ); idxHeader.revisionNumber = regNum.cap().toUInt(); - bool isLogical = ( stream.attributes().value( "format" ) == "logical" || idxHeader.revisionNumber >= 34 ); + bool isLogical = ( stream.attributes().value( "format" ) == u"logical" || idxHeader.revisionNumber >= 34 ); idxHeader.articleFormat = isLogical ? Logical : Visual; @@ -1282,7 +1282,8 @@ vector< sptr< Dictionary::Class > > makeDictionaries( if( isLogical ) { desc = desc.simplified(); - desc.replace( QRegExp( "\\s*
" ), QChar( '\n' ) ); + QRegularExpression br( "\\s*
" ); + desc.replace( br, QString("\n") ); } if ( dictionaryDescription.isEmpty() ) @@ -1302,15 +1303,15 @@ vector< sptr< Dictionary::Class > > makeDictionaries( } } else - if( stream.name() == "languages" ) + if( stream.name() == u"languages" ) { - while( !( stream.isEndElement() && stream.name() == "languages" ) && !stream.atEnd() ) + while( !( stream.isEndElement() && stream.name() == u"languages" ) && !stream.atEnd() ) { if( !stream.readNext() ) break; if ( stream.isStartElement() ) { - if( stream.name() == "from" ) + if( stream.name() == u"from" ) { if( idxHeader.langFrom == 0 ) { @@ -1318,7 +1319,7 @@ vector< sptr< Dictionary::Class > > makeDictionaries( idxHeader.langFrom = getLanguageId( lang ); } } - else if( stream.name() == "to" ) + else if( stream.name() == u"to" ) { if( idxHeader.langTo == 0 ) { @@ -1327,7 +1328,7 @@ vector< sptr< Dictionary::Class > > makeDictionaries( } } } - else if ( stream.isEndElement() && stream.name() == "languages" ) + else if ( stream.isEndElement() && stream.name() == u"languages" ) break; } }