From 98b37feac23cfdccf5408ba3fc54a1e9c7be09e5 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Fri, 4 Nov 2022 17:38:58 +0200 Subject: [PATCH 01/15] Print debug output with gdDebug() instead of av_log() Users can enable or disable av_log() output only by inserting a call to av_log_set_level() and recompiling GoldenDict. Blink browser engine shipped with Qt WebEngine sets the log level to AV_LOG_QUIET in chromium/media/base/media.cc and thus disables all output. So GoldenDict's custom AV_LOG_INFO messages are always printed in the Qt WebKit version and never in the Qt WebEngine version. In contrast, users have many ways to enable or disable QDebug output without recompilation since Qt 5. Furthermore, GoldenDict's command line option --log-to-file allows to redirect gdDebug() output to a log file. The two messages printed via av_log() are clearly debug messages, because they are printed each time a word or a phrase is pronounced. --- ffmpegaudio.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc index 5b81d102..a97d6dca 100644 --- a/ffmpegaudio.cc +++ b/ffmpegaudio.cc @@ -260,7 +260,7 @@ bool DecoderContext::openCodec( QString & errorString ) return false; } - av_log( NULL, AV_LOG_INFO, "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec_->long_name, + gdDebug( "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec_->long_name, codecContext_->channels, codecContext_->sample_rate, av_get_sample_fmt_name( codecContext_->sample_fmt ) ); if ( codecContext_->sample_fmt == AV_SAMPLE_FMT_S32 || @@ -363,7 +363,7 @@ bool DecoderContext::openOutputDevice( QString & errorString ) return false; } - av_log( NULL, AV_LOG_INFO, "ao_open_live(): %s: channels: %d, rate: %d, bits: %d\n", + gdDebug( "ao_open_live(): %s: channels: %d, rate: %d, bits: %d\n", aoDrvInfo->name, aoSampleFormat.channels, aoSampleFormat.rate, aoSampleFormat.bits ); aoDevice_ = ao_open_live( aoDriverId, &aoSampleFormat, NULL ); From 1d6b5efeac5c1f91ff0db57014ad33dc17d36282 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Sun, 28 Sep 2014 13:16:43 +0300 Subject: [PATCH 02/15] Disable GD_DPRINTF() output in Release builds on all systems Messages printed with GD_DPRINTF() are clearly debug messages. They flood GoldenDict's output with lines like these: some body finished one finished. erasing.. erase done.. one not finished. ====reading 16384 bytes Messages printed to stderr with GD_FDPRINTF() are more important and less frequent => leave them in Release builds. --- gddebug.hh | 12 ++++++++---- goldendict.pro | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/gddebug.hh b/gddebug.hh index e8148e0d..cc1f0b74 100644 --- a/gddebug.hh +++ b/gddebug.hh @@ -4,11 +4,15 @@ #include #ifdef NO_CONSOLE -#define GD_DPRINTF(...) do {} while( 0 ) -#define GD_FDPRINTF(...) do {} while( 0 ) + #define GD_DPRINTF(...) do {} while( 0 ) + #define GD_FDPRINTF(...) do {} while( 0 ) #else -#define GD_DPRINTF(...) printf(__VA_ARGS__) -#define GD_FDPRINTF(...) fprintf(__VA_ARGS__) + #ifdef NO_GD_DPRINTF + #define GD_DPRINTF(...) do {} while( 0 ) + #else + #define GD_DPRINTF(...) printf(__VA_ARGS__) + #endif + #define GD_FDPRINTF(...) fprintf(__VA_ARGS__) #endif void gdWarning(const char *, ...) /* print warning message */ diff --git a/goldendict.pro b/goldendict.pro index 241745f6..0f73c93e 100644 --- a/goldendict.pro +++ b/goldendict.pro @@ -23,7 +23,7 @@ isEmpty( hasGit ) { } CONFIG( release, debug|release ) { - DEFINES += NDEBUG + DEFINES += NDEBUG NO_GD_DPRINTF } # DEPENDPATH += . generators From fc9a48a113e39fbae715d2345319a138583b21e7 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Fri, 4 Nov 2022 18:31:04 +0200 Subject: [PATCH 03/15] Demote missing favorites file message from warning to debug This file is never created if the Favorites feature is not used. Fix a typo along the way: "favorities" => "favorites". --- favoritespanewidget.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/favoritespanewidget.cc b/favoritespanewidget.cc index 9a00d1c1..46bfdc58 100644 --- a/favoritespanewidget.cc +++ b/favoritespanewidget.cc @@ -627,7 +627,7 @@ void FavoritesModel::readData() QFile favoritesFile( m_favoritesFilename ); if( !favoritesFile.open( QFile::ReadOnly ) ) { - gdWarning( "No favorities file found" ); + gdDebug( "No favorites file found" ); return; } From 08ca40bd06f26dbef3b0134973f9ad00ee8b6b97 Mon Sep 17 00:00:00 2001 From: xiaoyifang <105986+xiaoyifang@users.noreply.github.com> Date: Sat, 5 Nov 2022 10:44:28 +0800 Subject: [PATCH 04/15] Update README.md --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c6c4714f..6339c468 100644 --- a/README.md +++ b/README.md @@ -35,10 +35,6 @@ sudo dnf install git pkg-config libzstd-devel opencc-devel xz-devel xz-lzma-comp libao-devel ffmpeg-devel libtiff-devel eb-devel qt5-qtx11extras-devel libXtst-devel \ libxkbcommon-devel qt5-qtbase qt5-qttools qt5-qtsvg-devl qt5-qtwebengine-devel qt5-qtmultimedia-devl -qmake-qt5 CONFIG+=release CONFIG+=no_extra_tiff_handler CONFIG+=no_epwing_support -make - - ``` ## How to build @@ -48,11 +44,18 @@ First, clone this repository, e.g.: git clone https://github.com/xiaoyifang/goldendict.git -### Linux +### Linux (fedora) And then invoke `qmake-qt5` and `make`: cd goldendict && qmake-qt5 && make +### ArchLinux + +on archlinux based os, you can use `yay` to install the community goldendict-webengine-git . + + pacman -S --needed git base-devel yay + yay -S goldendict-webengine-git + ### macOS ``` brew install qt # or use official offline installer From 652f1b25d37ec0c65299a23a8d3a865809f10eae Mon Sep 17 00:00:00 2001 From: xiaoyifang <105986+xiaoyifang@users.noreply.github.com> Date: Sat, 5 Nov 2022 10:46:52 +0800 Subject: [PATCH 05/15] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6339c468..21735eb9 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,9 @@ And then invoke `qmake-qt5` and `make`: on archlinux based os, you can use `yay` to install the community goldendict-webengine-git . + #(Manjaro distribution) pacman -S --needed git base-devel yay + yay -S goldendict-webengine-git ### macOS From c478065f535e951712f57d47514a01c28f87d3c8 Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Sat, 5 Nov 2022 14:52:50 +0800 Subject: [PATCH 06/15] goldendict ,fix QT_PLUGIN_PATH variable --- goldendict.pro | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/goldendict.pro b/goldendict.pro index 29e8914a..0ab34719 100644 --- a/goldendict.pro +++ b/goldendict.pro @@ -666,9 +666,10 @@ 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_INSTALL_PLUGINS]/multimedia/* + multimedia.files = $$[QT_PLUGIN_PATH]/multimedia/* multimedia.path = plugins/multimedia #multimedia.CONFIG += no_check_exist message("copy qt6.4.0 multimedia") From 80fdb8cb822652d0ab948be1c88b55793967d120 Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Sat, 5 Nov 2022 21:02:33 +0800 Subject: [PATCH 07/15] fix: right mouse on the history panel and favorite panel should not trigger the click event. which means the word should not send to the mainwindow and translated. --- favoritespanewidget.cc | 4 ++-- historypanewidget.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/favoritespanewidget.cc b/favoritespanewidget.cc index b3c9fae4..5eea16e0 100644 --- a/favoritespanewidget.cc +++ b/favoritespanewidget.cc @@ -208,12 +208,12 @@ void FavoritesPaneWidget::onSelectionChanged( QItemSelection const & selection ) return; itemSelectionChanged = true; - emitFavoritesItemRequested( selection.indexes().front() ); +// emitFavoritesItemRequested( selection.indexes().front() ); } void FavoritesPaneWidget::onItemClicked( QModelIndex const & idx ) { - if ( !itemSelectionChanged && m_favoritesTree->selectionModel()->selectedIndexes().size() == 1 ) +// if ( !itemSelectionChanged && m_favoritesTree->selectionModel()->selectedIndexes().size() == 1 ) { emitFavoritesItemRequested( idx ); } diff --git a/historypanewidget.cc b/historypanewidget.cc index 81216b94..2a47fdd9 100644 --- a/historypanewidget.cc +++ b/historypanewidget.cc @@ -202,14 +202,14 @@ void HistoryPaneWidget::onSelectionChanged( QItemSelection const & selection ) return; itemSelectionChanged = true; - emitHistoryItemRequested( selection.front().topLeft() ); +// emitHistoryItemRequested( selection.front().topLeft() ); } void HistoryPaneWidget::onItemClicked( QModelIndex const & idx ) { // qDebug() << "clicked"; - if ( !itemSelectionChanged ) +// if ( !itemSelectionChanged ) { emitHistoryItemRequested( idx ); } From d6696b0800760e05a999c30ff539672c010793af Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Sat, 5 Nov 2022 10:52:19 +0200 Subject: [PATCH 08/15] Expand unclosed tag DSL warning message The dictionary name, article and the tag name help to locate the issue. GD_FDPRINTF() => gdWarning() to improve flexibility and user options. --- dsl_details.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/dsl_details.cc b/dsl_details.cc index 682ef0a9..f4f61733 100644 --- a/dsl_details.cc +++ b/dsl_details.cc @@ -630,7 +630,19 @@ ArticleDom::ArticleDom( wstring const & str, string const & dictName, if ( stack.size() ) { - GD_FDPRINTF( stderr, "Warning: %u tags were unclosed.\n", (unsigned) stack.size() ); + unsigned const unclosedTagCount = stack.size(); + QByteArray const firstTagName = gd::toQString( stack.front()->tagName ).toUtf8(); + if( dictName.empty() ) + { + gdWarning( "Warning: %u tag(s) were unclosed, first tag name \"%s\".\n", + unclosedTagCount, firstTagName.constData() ); + } + else + { + gdWarning( "Warning: %u tag(s) were unclosed in \"%s\", article \"%s\", first tag name \"%s\".\n", + unclosedTagCount, dictName.c_str(), gd::toQString( headword ).toUtf8().constData(), + firstTagName.constData() ); + } } } From 7c0c586418d743a7f5c37b4bd1120200a78da4f8 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Sat, 5 Nov 2022 11:09:14 +0200 Subject: [PATCH 09/15] Extract is_mN() and isAnyM() --- dsl_details.cc | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/dsl_details.cc b/dsl_details.cc index f4f61733..9ddf9c9a 100644 --- a/dsl_details.cc +++ b/dsl_details.cc @@ -162,13 +162,26 @@ wstring ArticleDom::Node::renderAsText( bool stripTrsTag ) const return result; } -// Returns true if src == 'm' and dest is 'mX', where X is a digit -static inline bool checkM( wstring const & dest, wstring const & src ) +namespace { + +/// @return true if @p tagName equals "mN" where N is a digit +bool is_mN( wstring const & tagName ) { - return ( src == GD_NATIVE_TO_WS( L"m" ) && dest.size() == 2 && - dest[ 0 ] == L'm' && iswdigit( dest[ 1 ] ) ); + return tagName.size() == 2 && tagName[ 0 ] == L'm' && iswdigit( tagName[ 1 ] ); } +bool isAnyM( wstring const & tagName ) +{ + return tagName == GD_NATIVE_TO_WS( L"m" ) || is_mN( tagName ); +} + +bool checkM( wstring const & dest, wstring const & src ) +{ + return src == GD_NATIVE_TO_WS( L"m" ) && is_mN( dest ); +} + +} // unnamed namespace + ArticleDom::ArticleDom( wstring const & str, string const & dictName, wstring const & headword_): root( Node::Tag(), wstring(), wstring() ), stringPos( str.c_str() ), @@ -374,8 +387,7 @@ ArticleDom::ArticleDom( wstring const & str, string const & dictName, if ( !isClosing ) { - if ( name == GD_NATIVE_TO_WS( L"m" ) || - ( name.size() == 2 && name[ 0 ] == L'm' && iswdigit( name[ 1 ] ) ) ) + if( isAnyM( name ) ) { // Opening an 'mX' or 'm' tag closes any previous 'm' tag closeTag( GD_NATIVE_TO_WS( L"m" ), stack, false ); @@ -652,7 +664,7 @@ void ArticleDom::openTag( wstring const & name, { list< Node > nodesToReopen; - if( name == GD_NATIVE_TO_WS( L"m" ) || checkM( name, GD_NATIVE_TO_WS( L"m" ) ) ) + if( isAnyM( name ) ) { // All tags above [m] tag will be closed and reopened after // to avoid break this tag by closing some other tag. From 38f5fa6c908621b88e0a2ec329384e91704ee22c Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Sat, 5 Nov 2022 11:51:21 +0200 Subject: [PATCH 10/15] Don't warn about unclosed DSL [mN] tags According to DSL documentation, closing the [mN] tags is optional: unclosed [mN] tags affect formatting until the end of a card. As many dictionaries don't close the [mN] tags, GoldenDict printed multiple unclosed-tag warnings during each word lookup. --- dsl_details.cc | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/dsl_details.cc b/dsl_details.cc index 9ddf9c9a..ac0b1d91 100644 --- a/dsl_details.cc +++ b/dsl_details.cc @@ -13,6 +13,8 @@ #include #include +#include + namespace Dsl { namespace Details { @@ -180,6 +182,17 @@ bool checkM( wstring const & dest, wstring const & src ) return src == GD_NATIVE_TO_WS( L"m" ) && is_mN( dest ); } +/// Closing the [mN] tags is optional. Quote from https://documentation.help/ABBYY-Lingvo8/paragraph_form.htm: +/// Any paragraph from this tag until the end of card or until system meets an «[/m]» (margin shift toggle off) tag +struct MustTagBeClosed +{ + bool operator()( ArticleDom::Node const * tag ) const + { + Q_ASSERT( tag->isTag ); + return !isAnyM( tag->tagName ); + } +}; + } // unnamed namespace ArticleDom::ArticleDom( wstring const & str, string const & dictName, @@ -642,8 +655,13 @@ ArticleDom::ArticleDom( wstring const & str, string const & dictName, if ( stack.size() ) { - unsigned const unclosedTagCount = stack.size(); - QByteArray const firstTagName = gd::toQString( stack.front()->tagName ).toUtf8(); + list< Node * >::iterator it = std::find_if( stack.begin(), stack.end(), MustTagBeClosed() ); + if( it == stack.end() ) + return; // no unclosed tags that must be closed => nothing to warn about + QByteArray const firstTagName = gd::toQString( ( *it )->tagName ).toUtf8(); + ++it; + unsigned const unclosedTagCount = 1 + std::count_if( it, stack.end(), MustTagBeClosed() ); + if( dictName.empty() ) { gdWarning( "Warning: %u tag(s) were unclosed, first tag name \"%s\".\n", From fdcd6a377351a2ac7bb5519df279868adf601fa0 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Sat, 5 Nov 2022 16:10:24 +0200 Subject: [PATCH 11/15] Demote input phrase limit message from warning to debug Limiting input phrase length is disabled by default. The default length limit value is 1000. The user has to enable the option and lower the length limit in order to be surprised by missing translation. By making such configuration changes, the user should become aware of this feature and its effect. As the person who has implemented this feature and uses 100 as the length limit, I am never surprised or disappointed by missing translation. The only annoyance is this warning that floods my systemd journal. Apparently I accidentally select overly long phrases way too often. --- config.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.cc b/config.cc index 092a040d..fdc0ce1a 100644 --- a/config.cc +++ b/config.cc @@ -188,8 +188,8 @@ InputPhrase Preferences::sanitizeInputPhrase( QString const & inputPhrase ) cons if( limitInputPhraseLength && inputPhrase.size() > inputPhraseLengthLimit ) { - gdWarning( "Ignoring an input phrase %d symbols long. The configured maximum input phrase length is %d symbols.", - inputPhrase.size(), inputPhraseLengthLimit ); + gdDebug( "Ignoring an input phrase %d symbols long. The configured maximum input phrase length is %d symbols.", + inputPhrase.size(), inputPhraseLengthLimit ); return result; } From a321593ed1797774923354f0fd3e2432d9bbd83c Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Sat, 5 Nov 2022 18:05:11 +0200 Subject: [PATCH 12/15] Linux-specific: check correct X11 window ID translateLine->internalWinId() always equals 0. When the show/hide main window hotkey is triggered right after GoldenDict starts to system tray, `wh` equals MainWindow::internalWinId(). A few more experiments confirm that XGetInputFocus()'s output parameter `focus_return` is an ID of a top-level window, not of an embedded widget child. --- mainwindow.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mainwindow.cc b/mainwindow.cc index b41d6f57..f3bbff3d 100644 --- a/mainwindow.cc +++ b/mainwindow.cc @@ -3076,11 +3076,12 @@ void MainWindow::toggleMainWindow( bool onlyShow ) ftsDlg->show(); focusTranslateLine(); + #ifdef X11_MAIN_WINDOW_FOCUS_WORKAROUNDS Window wh = 0; int rev = 0; XGetInputFocus( QX11Info::display(), &wh, &rev ); - if( wh != translateLine->internalWinId() && !byIconClick ) + if( wh != internalWinId() && !byIconClick ) { QPoint const pointRelativeToRoot = mapToGlobal( QPoint( 0, 0 ) ); XEvent event; From 5f96f1f26ee2389b29d8059a74f3e0e61a52c6c2 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Sat, 5 Nov 2022 18:21:28 +0200 Subject: [PATCH 13/15] Linux-specific: don't force X11 focus unnecessarily Focus is already transferred to GoldenDict in toggleMainWindow() only the first time the main window is shown. At all subsequent requests to show the main window, focus has to be forced with the workaround. Checking focus asynchronously allows to resort to the workaround less often. Under Xfce: the timeout of 0 ms is almost always sufficient in the Qt 5 version, but is never enough in the Qt 4 version. The timeout of 4 ms is always sufficient in both versions. Under KDE Plasma: the timeout of 0 ms is rarely sufficient in the Qt 5 version. Unfortunately, with any timeout other than 0 ms, the Qt 5 version does not always get focus, which would be a serious regression, so no other timeout can be used. The Qt 4 version does not always get focus both with and without the timeout. --- mainwindow.cc | 60 +++++++++++++++++++++++++++++---------------------- mainwindow.hh | 4 ++++ 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/mainwindow.cc b/mainwindow.cc index f3bbff3d..a11c83c2 100644 --- a/mainwindow.cc +++ b/mainwindow.cc @@ -3078,36 +3078,44 @@ void MainWindow::toggleMainWindow( bool onlyShow ) focusTranslateLine(); #ifdef X11_MAIN_WINDOW_FOCUS_WORKAROUNDS - Window wh = 0; - int rev = 0; - XGetInputFocus( QX11Info::display(), &wh, &rev ); - if( wh != internalWinId() && !byIconClick ) - { - QPoint const pointRelativeToRoot = mapToGlobal( QPoint( 0, 0 ) ); - XEvent event; - memset( &event, 0, sizeof( event) ); - event.type = ButtonPress; - event.xbutton.x = 0; - event.xbutton.y = 0; - event.xbutton.x_root = pointRelativeToRoot.x(); - event.xbutton.y_root = pointRelativeToRoot.y(); - event.xbutton.window = internalWinId(); - event.xbutton.root = QX11Info::appRootWindow( QX11Info::appScreen() ); - event.xbutton.state = Button1Mask; - event.xbutton.button = Button1; - event.xbutton.same_screen = true; - event.xbutton.time = CurrentTime; - - XSendEvent( QX11Info::display(), internalWinId(), true, 0xfff, &event ); - XFlush( QX11Info::display() ); - event.type = ButtonRelease; - XSendEvent( QX11Info::display(), internalWinId(), true, 0xfff, &event ); - XFlush( QX11Info::display() ); - } + if( !byIconClick ) + QTimer::singleShot( 0, this, SLOT( forceX11Focus() ) ); #endif } } +#ifdef X11_MAIN_WINDOW_FOCUS_WORKAROUNDS +void MainWindow::forceX11Focus() +{ + Window wh = 0; + int rev = 0; + XGetInputFocus( QX11Info::display(), &wh, &rev ); + if( wh != internalWinId() ) + { + QPoint const pointRelativeToRoot = mapToGlobal( QPoint( 0, 0 ) ); + XEvent event; + memset( &event, 0, sizeof( event) ); + event.type = ButtonPress; + event.xbutton.x = 0; + event.xbutton.y = 0; + event.xbutton.x_root = pointRelativeToRoot.x(); + event.xbutton.y_root = pointRelativeToRoot.y(); + event.xbutton.window = internalWinId(); + event.xbutton.root = QX11Info::appRootWindow( QX11Info::appScreen() ); + event.xbutton.state = Button1Mask; + event.xbutton.button = Button1; + event.xbutton.same_screen = true; + event.xbutton.time = CurrentTime; + + XSendEvent( QX11Info::display(), internalWinId(), true, 0xfff, &event ); + XFlush( QX11Info::display() ); + event.type = ButtonRelease; + XSendEvent( QX11Info::display(), internalWinId(), true, 0xfff, &event ); + XFlush( QX11Info::display() ); + } +} +#endif + void MainWindow::installHotKeys() { hotkeyWrapper.reset(); // Remove the old one diff --git a/mainwindow.hh b/mainwindow.hh index b98cc85b..2fa3cd05 100644 --- a/mainwindow.hh +++ b/mainwindow.hh @@ -280,6 +280,10 @@ private: private slots: +#ifdef X11_MAIN_WINDOW_FOCUS_WORKAROUNDS + void forceX11Focus(); +#endif + void hotKeyActivated( int ); /// If new release checks are on, santizies the next check time and starts From 570949b9f94d2932ac274c472a6b6a3008448171 Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Sun, 6 Nov 2022 10:09:09 +0800 Subject: [PATCH 14/15] fix conflict with upstream as codebase has changed a lot --- dsl_details.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dsl_details.cc b/dsl_details.cc index 4424cd0d..569a2d55 100644 --- a/dsl_details.cc +++ b/dsl_details.cc @@ -170,17 +170,17 @@ namespace { /// @return true if @p tagName equals "mN" where N is a digit bool is_mN( wstring const & tagName ) { - return tagName.size() == 2 && tagName[ 0 ] == L'm' && iswdigit( tagName[ 1 ] ); + return tagName.size() == 2 && tagName[ 0 ] == U'm' && iswdigit( tagName[ 1 ] ); } bool isAnyM( wstring const & tagName ) { - return tagName == GD_NATIVE_TO_WS( L"m" ) || is_mN( tagName ); + return tagName == U"m" || is_mN( tagName ); } bool checkM( wstring const & dest, wstring const & src ) { - return src == GD_NATIVE_TO_WS( L"m" ) && is_mN( dest ); + return src == U"m" && is_mN( dest ); } /// Closing the [mN] tags is optional. Quote from https://documentation.help/ABBYY-Lingvo8/paragraph_form.htm: From 1554d026c5bae829e44564c9ab2268d185b8fe97 Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Sat, 12 Nov 2022 09:16:10 +0800 Subject: [PATCH 15/15] fix: crash on headword dialog lookup when the headword count is too small ,the application will crash . --- btreeidx.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/btreeidx.cc b/btreeidx.cc index cb4355d2..e0761c10 100644 --- a/btreeidx.cc +++ b/btreeidx.cc @@ -1353,9 +1353,16 @@ QSet BtreeIndex::findNodes() } char const * leaf = &rootNode.front(); - - vector< char > extLeaf; QSet leafOffset; + + uint32_t leafEntries; + leafEntries = *(uint32_t *)leaf; + if ( leafEntries != 0xffffFFFF ) + { + leafOffset.insert(rootOffset); + return leafOffset; + } + // the current the btree's implementation has the height = 2. // A node offset