Compare commits

..

12 commits

Author SHA1 Message Date
xiaoyifang b0de4e1d5d
Merge 15b918eb6a into c7d0feb2e8 2024-11-15 16:18:07 -05:00
shenleban tongying c7d0feb2e8 fix: macOS libzim <-> icu4c again and make mismatch a fatal error
Some checks are pending
SonarCloud / Build and analyze (push) Waiting to run
2024-11-15 15:41:44 -05:00
shenleban tongying c5d682c993
clean: fix some issues found by the code analysis of Visual Studio
Some checks failed
SonarCloud / Build and analyze (push) Has been cancelled
2024-11-14 12:24:46 +00:00
shenleban tongying 0f71f32ad4
refactor: move most of the Windows specific code out of hotkeywrapper.cc 2024-11-14 11:12:17 +00:00
shenleban tongying 5cc43a3dc8
fix: windows global hotkey Win/Meta and 1-9 doesn't work 2024-11-14 09:06:23 +00:00
shenleban tongying beef6dd138 clean: delete most Qt5 & <=6.3 conditional compiled code (QT_VERSION)
Some checks are pending
SonarCloud / Build and analyze (push) Waiting to run
2024-11-14 00:07:15 -05:00
shenleban tongying ccf70cdfb6 doc: various updates
Some checks failed
SonarCloud / Build and analyze (push) Waiting to run
deploy_website / deploy (push) Has been cancelled
2024-11-13 23:05:40 -05:00
shenleban tongying 6865b02547 fix: a DICT crash caused by string out of bound access
Some checks are pending
SonarCloud / Build and analyze (push) Waiting to run
2024-11-13 17:18:04 -05:00
shenleban tongying fbec70e41a opt: simplify Folding::apply
Some checks are pending
SonarCloud / Build and analyze (push) Waiting to run
2024-11-12 23:47:20 -05:00
shenleban tongying 20fcea33e1
Merge pull request #1946 from shenlebantongying/clean/rm-gd-toWstring
Some checks are pending
SonarCloud / Build and analyze (push) Waiting to run
clean: remove redundant gd::toWString
2024-11-12 19:57:36 -05:00
shenleban tongying 9db5867ce8 dev: ignore last commit 2024-11-12 19:49:44 -05:00
shenleban tongying c8af0450f1 clean: remove redundant gd::toWString 2024-11-12 19:32:13 -05:00
55 changed files with 499 additions and 703 deletions

View file

@ -15,3 +15,6 @@ a11c9e3aeca4329e1982d8fe26bacbb21ab50ddf
# mass apply clang-tidy's modernize-use-using # mass apply clang-tidy's modernize-use-using
d15081e723756eef053550dc9e06e31d7828dec3 d15081e723756eef053550dc9e06e31d7828dec3
# remove gd::toWString
c8af0450f1f7f8188004db96e3f53e7e33e2ccad

View file

@ -3,11 +3,6 @@
if (APPLE) if (APPLE)
# old & new homebrew's include paths # old & new homebrew's include paths
target_include_directories(${GOLDENDICT} PRIVATE /usr/local/include /opt/homebrew/include) target_include_directories(${GOLDENDICT} PRIVATE /usr/local/include /opt/homebrew/include)
# libzim depends on ICU, but the ICU from homebrew is "key-only", we need to manually prioritize it
# See `brew info icu4c` if this no longer works
# Note: Remove icu4c@75 if it fails again
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/opt/icu4c@75/lib/pkgconfig:/opt/homebrew/opt/icu4c@75/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig:/opt/homebrew/opt/icu4c/lib/pkgconfig")
endif () endif ()
target_include_directories(${GOLDENDICT} PRIVATE target_include_directories(${GOLDENDICT} PRIVATE
@ -82,13 +77,31 @@ if (WITH_EPWING_SUPPORT)
endif () endif ()
if (WITH_ZIM) if (WITH_ZIM)
if (APPLE)
# ICU from homebrew is "key-only", we need to manually prioritize it -> see `brew info icu4c`
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/opt/icu4c@76/lib/pkgconfig:/opt/homebrew/opt/icu4c@76/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig:/opt/homebrew/opt/icu4c/lib/pkgconfig")
endif ()
pkg_check_modules(ZIM REQUIRED IMPORTED_TARGET libzim) pkg_check_modules(ZIM REQUIRED IMPORTED_TARGET libzim)
target_link_libraries(${GOLDENDICT} PRIVATE PkgConfig::ZIM) target_link_libraries(${GOLDENDICT} PRIVATE PkgConfig::ZIM)
if (APPLE) if (APPLE)
# For some reason, icu4c as transitive dependency of libzim may not be copied into app bundle, # icu4c as transitive dependency of libzim may not be copied into app bundle, so we directly depends on it to assist macdeployqt
# so we directly depends on it to help macdeployqt or whatever # Why such complexities: 1) System or XCode SDKS's icu exists 2) icu itself is depended by various stuffs and homebrew may need multiple versions of it
pkg_check_modules(BREW_ICU_FOR_LIBZIM_FORCE_LINK REQUIRED IMPORTED_TARGET icu-i18n icu-uc) pkg_check_modules(BREW_ICU REQUIRED IMPORTED_TARGET icu-i18n icu-uc)
target_link_libraries(${GOLDENDICT} PUBLIC PkgConfig::BREW_ICU_FOR_LIBZIM_FORCE_LINK) target_link_libraries(${GOLDENDICT} PUBLIC PkgConfig::BREW_ICU)
# Verify icu <-> zim matches
message("Zim include dirs -> ${ZIM_INCLUDE_DIRS}")
message("Homebrew icu include dirs-> ${BREW_ICU_INCLUDE_DIRS}")
list(GET BREW_ICU_INCLUDE_DIRS 0 ONE_OF_BREW_ICU_INCLUDE_DIR)
if (ONE_OF_BREW_ICU_INCLUDE_DIR IN_LIST ZIM_INCLUDE_DIRS)
message("ZIM OK!")
else ()
message(FATAL_ERROR "!!!! ZIM <-> icu error -> check `brew info libzim` and `brew list libzim`")
endif ()
# TODO: get rid of these 💩, how?
endif () endif ()
endif () endif ()

View file

@ -521,7 +521,7 @@ void ArticleRequest::altSearchFinished()
vector< wstring > altsVector( alts.begin(), alts.end() ); vector< wstring > altsVector( alts.begin(), alts.end() );
wstring wordStd = gd::toWString( word ); wstring wordStd = word.toStdU32String();
if ( activeDicts.size() <= 1 ) { if ( activeDicts.size() <= 1 ) {
articleSizeLimit = -1; // Don't collapse article if only one dictionary presented articleSizeLimit = -1; // Don't collapse article if only one dictionary presented

View file

@ -6,11 +6,7 @@
#include <QWaitCondition> #include <QWaitCondition>
#include <QCoreApplication> #include <QCoreApplication>
#include <QThreadPool> #include <QThreadPool>
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
#include <QAudioOutput>
#else
#include <QAudioSink> #include <QAudioSink>
#endif
#include <QtGlobal> #include <QtGlobal>
#include <QBuffer> #include <QBuffer>
@ -23,18 +19,7 @@ static QAudioFormat format( int sampleRate, int channelCount )
out.setSampleRate( sampleRate ); out.setSampleRate( sampleRate );
out.setChannelCount( channelCount ); out.setChannelCount( channelCount );
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
out.setByteOrder( QAudioFormat::LittleEndian );
out.setCodec( QLatin1String( "audio/pcm" ) );
#endif
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
out.setSampleSize( 16 );
out.setSampleType( QAudioFormat::SignedInt );
#else
out.setSampleFormat( QAudioFormat::Int16 ); out.setSampleFormat( QAudioFormat::Int16 );
#endif
return out; return out;
} }
@ -50,11 +35,8 @@ public:
QFuture< void > audioPlayFuture; QFuture< void > audioPlayFuture;
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
using AudioOutput = QAudioOutput;
#else
using AudioOutput = QAudioSink; using AudioOutput = QAudioSink;
#endif
AudioOutput * audioOutput = nullptr; AudioOutput * audioOutput = nullptr;
QByteArray buffer; QByteArray buffer;
qint64 offset = 0; qint64 offset = 0;
@ -185,11 +167,7 @@ AudioOutput::AudioOutput( QObject * parent ):
QObject( parent ), QObject( parent ),
d_ptr( new AudioOutputPrivate ) d_ptr( new AudioOutputPrivate )
{ {
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
d_ptr->audioPlayFuture = QtConcurrent::run( &d_ptr->threadPool, d_ptr.data(), &AudioOutputPrivate::doPlayAudio );
#else
d_ptr->audioPlayFuture = QtConcurrent::run( &d_ptr->threadPool, &AudioOutputPrivate::doPlayAudio, d_ptr.data() ); d_ptr->audioPlayFuture = QtConcurrent::run( &d_ptr->threadPool, &AudioOutputPrivate::doPlayAudio, d_ptr.data() );
#endif
} }
void AudioOutput::setAudioFormat( int sampleRate, int channels ) void AudioOutput::setAudioFormat( int sampleRate, int channels )

View file

@ -2,27 +2,14 @@
#include "audiooutput.hh" #include "audiooutput.hh"
#include "ffmpegaudio.hh" #include "ffmpegaudio.hh"
#include <errno.h>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include "libswresample/swresample.h"
}
#include <QString>
#include <QDataStream>
#include <vector>
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 2, 0 ) )
#include <QMediaDevices>
#include <QAudioDevice>
#endif
#include "gddebug.hh" #include "gddebug.hh"
#include "utils.hh" #include "utils.hh"
#include <QAudioDevice>
#include <QDataStream>
#include <QMediaDevices>
#include <QString>
#include <errno.h>
#include <vector>
using std::vector; using std::vector;
@ -284,14 +271,11 @@ void DecoderContext::closeCodec()
bool DecoderContext::openOutputDevice( QString & errorString ) bool DecoderContext::openOutputDevice( QString & errorString )
{ {
// only check device when qt version is greater than 6.2
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 2, 0 ) )
QAudioDevice m_outputDevice = QMediaDevices::defaultAudioOutput(); QAudioDevice m_outputDevice = QMediaDevices::defaultAudioOutput();
if ( m_outputDevice.isNull() ) { if ( m_outputDevice.isNull() ) {
errorString += QString( "Can not found default audio output device" ); errorString += QString( "Can not found default audio output device" );
return false; return false;
} }
#endif
if ( audioOutput == nullptr ) { if ( audioOutput == nullptr ) {
errorString += QStringLiteral( "Failed to create audioOutput." ); errorString += QStringLiteral( "Failed to create audioOutput." );

View file

@ -1,27 +1,24 @@
#pragma once #pragma once
#ifdef MAKE_FFMPEG_PLAYER #ifdef MAKE_FFMPEG_PLAYER
#include "audiooutput.hh"
#include <QObject>
#include <QMutex>
#include <QByteArray>
#include <QThread>
extern "C" { extern "C" {
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
#include <libavutil/avutil.h> #include <libavutil/avutil.h>
#include "libswresample/swresample.h" #include "libswresample/swresample.h"
} }
#include "audiooutput.hh"
#include <QString> #include <QObject>
#include <QDataStream> #include <QMutex>
#include <QByteArray>
#include <vector> #include <QThread>
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 2, 0 ) )
#include <QMediaDevices>
#include <QAudioDevice> #include <QAudioDevice>
#endif #include <QDataStream>
#include <QMediaDevices>
#include <QString>
#include <vector>
using std::vector; using std::vector;
namespace Ffmpeg { namespace Ffmpeg {
class DecoderThread; class DecoderThread;

View file

@ -4,29 +4,18 @@
#ifdef MAKE_QTMULTIMEDIA_PLAYER #ifdef MAKE_QTMULTIMEDIA_PLAYER
#include <QByteArray> #include <QByteArray>
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
#include <QMediaContent>
#endif
#if ( QT_VERSION > QT_VERSION_CHECK( 6, 2, 0 ) )
#include <QAudioDevice> #include <QAudioDevice>
#endif
#include "multimediaaudioplayer.hh" #include "multimediaaudioplayer.hh"
#include <QDebug> #include <QDebug>
MultimediaAudioPlayer::MultimediaAudioPlayer() MultimediaAudioPlayer::MultimediaAudioPlayer()
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
:
player( 0, QMediaPlayer::StreamPlayback )
#endif
{ {
player.setAudioOutput( &audioOutput ); player.setAudioOutput( &audioOutput );
connect( &player, &QMediaPlayer::errorChanged, this, &MultimediaAudioPlayer::onMediaPlayerError ); connect( &player, &QMediaPlayer::errorChanged, this, &MultimediaAudioPlayer::onMediaPlayerError );
#if ( QT_VERSION > QT_VERSION_CHECK( 6, 2, 0 ) )
connect( &mediaDevices, &QMediaDevices::audioOutputsChanged, this, &MultimediaAudioPlayer::audioOutputChange ); connect( &mediaDevices, &QMediaDevices::audioOutputsChanged, this, &MultimediaAudioPlayer::audioOutputChange );
#endif
} }
void MultimediaAudioPlayer::audioOutputChange() void MultimediaAudioPlayer::audioOutputChange()
@ -42,15 +31,11 @@ QString MultimediaAudioPlayer::play( const char * data, int size )
if ( !audioBuffer->open( QIODevice::ReadOnly ) ) { if ( !audioBuffer->open( QIODevice::ReadOnly ) ) {
return tr( "Couldn't open audio buffer for reading." ); return tr( "Couldn't open audio buffer for reading." );
} }
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
player.setSourceDevice( audioBuffer ); player.setSourceDevice( audioBuffer );
#if ( QT_VERSION > QT_VERSION_CHECK( 6, 2, 0 ) )
audioOutput.setDevice( QMediaDevices::defaultAudioOutput() ); audioOutput.setDevice( QMediaDevices::defaultAudioOutput() );
player.setAudioOutput( &audioOutput ); player.setAudioOutput( &audioOutput );
#endif
#else
player.setMedia( QMediaContent(), audioBuffer );
#endif
player.play(); player.play();
return {}; return {};
} }
@ -58,9 +43,7 @@ QString MultimediaAudioPlayer::play( const char * data, int size )
void MultimediaAudioPlayer::stop() void MultimediaAudioPlayer::stop()
{ {
player.stop(); player.stop();
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
player.setMedia( QMediaContent() ); // Forget about audioBuffer.
#endif
if ( audioBuffer ) { if ( audioBuffer ) {
audioBuffer->close(); audioBuffer->close();
audioBuffer->setData( QByteArray() ); // Free memory. audioBuffer->setData( QByteArray() ); // Free memory.

View file

@ -5,15 +5,11 @@
#ifdef MAKE_QTMULTIMEDIA_PLAYER #ifdef MAKE_QTMULTIMEDIA_PLAYER
#include <QBuffer>
#include <QMediaPlayer>
#include "audioplayerinterface.hh" #include "audioplayerinterface.hh"
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
#include <QAudioOutput> #include <QAudioOutput>
#endif #include <QBuffer>
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 2, 0 ) )
#include <QMediaDevices> #include <QMediaDevices>
#endif #include <QMediaPlayer>
#include <QPointer> #include <QPointer>
class MultimediaAudioPlayer: public AudioPlayerInterface class MultimediaAudioPlayer: public AudioPlayerInterface
@ -34,12 +30,8 @@ private slots:
private: private:
QPointer< QBuffer > audioBuffer; QPointer< QBuffer > audioBuffer;
QMediaPlayer player; ///< Depends on audioBuffer. QMediaPlayer player; ///< Depends on audioBuffer.
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 2, 0 ) )
QAudioOutput audioOutput; QAudioOutput audioOutput;
#endif
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 2, 0 ) )
QMediaDevices mediaDevices; QMediaDevices mediaDevices;
#endif
}; };
#endif // MAKE_QTMULTIMEDIA_PLAYER #endif // MAKE_QTMULTIMEDIA_PLAYER

View file

@ -20,41 +20,23 @@ bool isCombiningMark( wchar ch )
wstring apply( wstring const & in, bool preserveWildcards ) wstring apply( wstring const & in, bool preserveWildcards )
{ {
//remove space and accent; // remove diacritics (normalization), white space, punt,
auto withPunc = QString::fromStdU32String( in ) auto temp = QString::fromStdU32String( in )
.normalized( QString::NormalizationForm_KD ) .normalized( QString::NormalizationForm_KD )
.remove( RX::markSpace ) .remove( RX::markSpace )
.removeIf( [ preserveWildcards ]( const QChar & ch ) -> bool {
return ch.isPunct()
&& !( preserveWildcards && ( ch == '\\' || ch == '?' || ch == '*' || ch == '[' || ch == ']' ) );
} )
.toStdU32String(); .toStdU32String();
// case folding
//First, strip diacritics and apply ws/punctuation removal std::u32string caseFolded;
wstring withoutDiacritics; caseFolded.reserve( temp.size() );
withoutDiacritics.reserve( withPunc.size() );
for ( auto const & ch : withPunc ) {
if ( !isPunct( ch )
|| ( preserveWildcards && ( ch == '\\' || ch == '?' || ch == '*' || ch == '[' || ch == ']' ) ) ) {
withoutDiacritics.push_back( ch );
}
}
// Now, fold the case
wstring caseFolded;
caseFolded.reserve( withoutDiacritics.size() * foldCaseMaxOut );
wchar const * nextChar = withoutDiacritics.data();
wchar buf[ foldCaseMaxOut ]; wchar buf[ foldCaseMaxOut ];
for ( const char32_t ch : temp ) {
for ( size_t left = withoutDiacritics.size(); left--; ) { auto n = foldCase( ch, buf );
caseFolded.append( buf, foldCase( *nextChar++, buf ) ); caseFolded.append( buf, n );
} }
return caseFolded; return caseFolded;
} }

View file

@ -1,14 +1,10 @@
/* This file is (c) 2013 Abs62 /* This file is (c) 2013 Abs62
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#include <QString>
#include "gddebug.hh" #include "gddebug.hh"
#include <QDebug> #include <QDebug>
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) ) #include <QString>
#include <QtCore5Compat/QTextCodec> #include <QtCore5Compat/QTextCodec>
#else
#include <QTextCodec>
#endif
QFile * logFilePtr; QFile * logFilePtr;

View file

@ -93,7 +93,7 @@ gd::wstring Iconv::toWstring( char const * fromEncoding, void const * fromData,
Iconv ic( fromEncoding ); Iconv ic( fromEncoding );
QString outStr = ic.convert( fromData, dataSize ); QString outStr = ic.convert( fromData, dataSize );
return gd::toWString( outStr ); return outStr.toStdU32String();
} }
std::string Iconv::toUtf8( char const * fromEncoding, void const * fromData, size_t dataSize ) std::string Iconv::toUtf8( char const * fromEncoding, void const * fromData, size_t dataSize )

View file

@ -9,11 +9,6 @@
QString wildcardsToRegexp( const QString & wc_str ) QString wildcardsToRegexp( const QString & wc_str )
{ {
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) // The "anchored" version will enclose the output with \A...\z.
//qt 5.X does not offer an unanchored version. the default output is enclosed between \A \z.
auto anchorPattern = QRegularExpression::wildcardToRegularExpression( wc_str );
return anchorPattern.mid( 2, anchorPattern.length() - 4 );
#else
return QRegularExpression::wildcardToRegularExpression( wc_str, QRegularExpression::UnanchoredWildcardConversion ); return QRegularExpression::wildcardToRegularExpression( wc_str, QRegularExpression::UnanchoredWildcardConversion );
#endif
} }

View file

@ -2,10 +2,6 @@
#include <QList> #include <QList>
namespace gd { namespace gd {
wstring toWString( QString const & in )
{
return in.toStdU32String();
}
// When convert non-BMP characters to wstring,the ending char maybe \0 .This method remove the tailing \0 from the wstring // When convert non-BMP characters to wstring,the ending char maybe \0 .This method remove the tailing \0 from the wstring
// as \0 is sensitive in the index. This method will be only used with index related operations like store/query. // as \0 is sensitive in the index. This method will be only used with index related operations like store/query.
@ -35,7 +31,7 @@ wstring removeTrailingZero( QString const & in )
wstring normalize( const wstring & str ) wstring normalize( const wstring & str )
{ {
return toWString( QString::fromStdU32String( str ).normalized( QString::NormalizationForm_C ) ); return QString::fromStdU32String( str ).normalized( QString::NormalizationForm_C ).toStdU32String();
} }

View file

@ -10,7 +10,6 @@
#include <QString> #include <QString>
namespace gd { namespace gd {
wstring toWString( QString const & );
wstring removeTrailingZero( wstring const & v ); wstring removeTrailingZero( wstring const & v );
wstring removeTrailingZero( QString const & in ); wstring removeTrailingZero( QString const & in );
wstring normalize( wstring const & ); wstring normalize( wstring const & );

View file

@ -493,7 +493,7 @@ struct WebSite
QString id, name, url; QString id, name, url;
bool enabled; bool enabled;
QString iconFilename; QString iconFilename;
bool inside_iframe; bool inside_iframe = false;
WebSite(): WebSite():
enabled( false ) enabled( false )
@ -699,7 +699,7 @@ struct Transliteration
struct Lingua struct Lingua
{ {
bool enable; bool enable = false;
QString languageCodes; QString languageCodes;
bool operator==( Lingua const & other ) const bool operator==( Lingua const & other ) const
@ -738,13 +738,16 @@ struct Forvo
struct Program struct Program
{ {
bool enabled; bool enabled;
// NOTE: the value of this enum is used for config
enum Type { enum Type {
Audio, Invalid = -1, // Init value
PlainText, Audio = 0,
Html, PlainText = 1,
PrefixMatch, Html = 2,
MaxTypeValue PrefixMatch = 3,
} type; MaxTypeValue = 4
};
Type type = Invalid;
QString id, name, commandLine; QString id, name, commandLine;
QString iconFilename; QString iconFilename;
@ -893,7 +896,7 @@ struct Class
QString articleSavePath; // Path to save articles QString articleSavePath; // Path to save articles
bool pinPopupWindow; // Last pin status bool pinPopupWindow; // Last pin status
bool popupWindowAlwaysOnTop; // Last status of pinned popup window bool popupWindowAlwaysOnTop = false; // Last status of pinned popup window
QByteArray mainWindowState; // Binary state saved by QMainWindow QByteArray mainWindowState; // Binary state saved by QMainWindow
QByteArray mainWindowGeometry; // Geometry saved by QMainWindow QByteArray mainWindowGeometry; // Geometry saved by QMainWindow
@ -930,7 +933,7 @@ struct Class
Group const * getGroup( unsigned id ) const; Group const * getGroup( unsigned id ) const;
//disable tts dictionary. does not need to save to persistent file //disable tts dictionary. does not need to save to persistent file
bool notts = false; bool notts = false;
bool resetState; bool resetState = false;
}; };
/// Configuration-specific events. Some parts of the program need to react /// Configuration-specific events. Some parts of the program need to react

View file

@ -45,9 +45,9 @@ DEF_EX( exCorruptedChainData, "Corrupted chain data in the leaf of a btree encou
struct WordArticleLink struct WordArticleLink
{ {
string word, prefix; // in utf8 string word, prefix; // in utf8
uint32_t articleOffset; uint32_t articleOffset = 0;
WordArticleLink() {} WordArticleLink() = default;
WordArticleLink( string const & word_, uint32_t articleOffset_, string const & prefix_ = string() ): WordArticleLink( string const & word_, uint32_t articleOffset_, string const & prefix_ = string() ):
word( word_ ), word( word_ ),

View file

@ -424,7 +424,7 @@ public:
if ( countn ) { if ( countn ) {
QMutexLocker _( &dataMutex ); QMutexLocker _( &dataMutex );
for ( int x = 0; x < countn; x++ ) { for ( int x = 0; x < countn; x++ ) {
matches.emplace_back( gd::toWString( matchesList.at( x ) ) ); matches.emplace_back( matchesList.at( x ).toStdU32String() );
} }
} }
finish(); finish();
@ -538,12 +538,14 @@ void DictServerWordSearchRequest::readMatchData( QByteArray & reply )
if ( word.endsWith( '\"' ) ) { if ( word.endsWith( '\"' ) ) {
word.chop( 1 ); word.chop( 1 );
} }
if ( word[ 0 ] == '\"' ) { if ( word.startsWith( '\"' ) ) {
word = word.mid( 1 ); word = word.remove( 0, 1 );
} }
if ( !word.isEmpty() ) {
this->addMatchedWord( word ); this->addMatchedWord( word );
} }
}
reply = this->dictImpl->socket.readLine(); reply = this->dictImpl->socket.readLine();

View file

@ -540,7 +540,7 @@ void DslDictionary::loadArticle( uint32_t address,
if ( !articleBody ) { if ( !articleBody ) {
// throw exCantReadFile( getDictionaryFilenames()[ 0 ] ); // throw exCantReadFile( getDictionaryFilenames()[ 0 ] );
articleData = U"\n\r\t" + gd::toWString( QString( "DICTZIP error: " ) + dict_error_str( dz ) ); articleData = U"\n\r\tDICTZIP error: " + QString( dict_error_str( dz ) ).toStdU32String();
} }
else { else {
try { try {
@ -966,7 +966,7 @@ string DslDictionary::nodeToHtml( ArticleDom::Node const & node )
if ( n >= 0 ) { if ( n >= 0 ) {
int n2 = attr.indexOf( '\"', n + 6 ); int n2 = attr.indexOf( '\"', n + 6 );
if ( n2 > 0 ) { if ( n2 > 0 ) {
quint32 id = dslLanguageToId( gd::toWString( attr.mid( n + 6, n2 - n - 6 ) ) ); quint32 id = dslLanguageToId( attr.mid( n + 6, n2 - n - 6 ).toStdU32String() );
langcode = LangCoder::intToCode2( id ).toStdString(); langcode = LangCoder::intToCode2( id ).toStdString();
} }
} }
@ -1089,7 +1089,7 @@ QString const & DslDictionary::getDescription()
for ( ;; ) { for ( ;; ) {
data.clear(); data.clear();
langStr = str.mid( 10 ).replace( '\"', ' ' ).trimmed(); langStr = str.mid( 10 ).replace( '\"', ' ' ).trimmed();
annLang = LangCoder::findIdForLanguage( gd::toWString( langStr ) ); annLang = LangCoder::findIdForLanguage( langStr.toStdU32String() );
do { do {
str = annStream.readLine(); str = annStream.readLine();
if ( str.left( 10 ).compare( "#LANGUAGE " ) == 0 ) { if ( str.left( 10 ).compare( "#LANGUAGE " ) == 0 ) {
@ -1391,7 +1391,7 @@ void DslDictionary::getArticleText( uint32_t articleAddress, QString & headword,
if ( haveInsidedCards ) { if ( haveInsidedCards ) {
// Use base DSL parser for articles with insided cards // Use base DSL parser for articles with insided cards
ArticleDom dom( gd::toWString( text ), getName(), articleHeadword ); ArticleDom dom( text.toStdU32String(), getName(), articleHeadword );
text = QString::fromStdU32String( dom.root.renderAsText( true ) ); text = QString::fromStdU32String( dom.root.renderAsText( true ) );
} }
else { else {

View file

@ -9,11 +9,7 @@
#include <zlib.h> #include <zlib.h>
#include "dictionary.hh" #include "dictionary.hh"
#include "iconv.hh" #include "iconv.hh"
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
#include <QtCore5Compat/QTextCodec> #include <QtCore5Compat/QTextCodec>
#else
#include <QTextCodec>
#endif
#include <QByteArray> #include <QByteArray>
#include "utf8.hh" #include "utf8.hh"

View file

@ -994,7 +994,7 @@ void EpwingWordSearchRequest::findMatches()
QMutexLocker _( &dataMutex ); QMutexLocker _( &dataMutex );
for ( const auto & headword : headwords ) for ( const auto & headword : headwords )
addMatch( gd::toWString( headword ) ); addMatch( headword.toStdU32String() );
break; break;
} }
@ -1047,7 +1047,7 @@ void addWordToChunks( Epwing::Book::EpwingHeadword & head,
chunks.addToBlock( &head.page, sizeof( head.page ) ); chunks.addToBlock( &head.page, sizeof( head.page ) );
chunks.addToBlock( &head.offset, sizeof( head.offset ) ); chunks.addToBlock( &head.offset, sizeof( head.offset ) );
wstring hw = gd::toWString( head.headword ); wstring hw = head.headword.toStdU32String();
indexedWords.addWord( hw, offset ); indexedWords.addWord( hw, offset );
wordCount++; wordCount++;

View file

@ -541,11 +541,7 @@ bool EpwingBook::setSubBook( int book_nom )
QFile f( fileName ); QFile f( fileName );
if ( f.open( QFile::ReadOnly | QFile::Text ) ) { if ( f.open( QFile::ReadOnly | QFile::Text ) ) {
QTextStream ts( &f ); QTextStream ts( &f );
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
ts.setCodec( "UTF-8" );
#else
ts.setEncoding( QStringConverter::Utf8 ); ts.setEncoding( QStringConverter::Utf8 );
#endif
QString line = ts.readLine(); QString line = ts.readLine();
while ( !line.isEmpty() ) { while ( !line.isEmpty() ) {
@ -1141,7 +1137,7 @@ void EpwingBook::fixHeadword( QString & headword )
// return; // return;
//} //}
gd::wstring folded = Folding::applyPunctOnly( gd::toWString( fixed ) ); gd::wstring folded = Folding::applyPunctOnly( fixed.toStdU32String() );
//fixed = QString::fromStdU32String( folded ); //fixed = QString::fromStdU32String( folded );
//if( isHeadwordCorrect( fixed ) ) //if( isHeadwordCorrect( fixed ) )

View file

@ -16,12 +16,7 @@
#endif #endif
#include <QString> #include <QString>
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
#include <QtCore5Compat/QTextCodec> #include <QtCore5Compat/QTextCodec>
#else
#include <QTextCodec>
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
#include <stub_msvc.h> #include <stub_msvc.h>

View file

@ -32,11 +32,8 @@
#include <QBuffer> #include <QBuffer>
#include <QRegularExpression> #include <QRegularExpression>
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
#include <QtCore5Compat/QTextCodec> #include <QtCore5Compat/QTextCodec>
#else
#include <QTextCodec>
#endif
#include <string> #include <string>
#include <list> #include <list>
#include <map> #include <map>

View file

@ -413,7 +413,7 @@ QList< wstring > suggest( wstring & word, QMutex & hunspellMutex, Hunspell & hun
auto match = cutStem.match( suggestion.trimmed() ); auto match = cutStem.match( suggestion.trimmed() );
if ( match.hasMatch() ) { if ( match.hasMatch() ) {
wstring alt = gd::toWString( match.captured( 1 ) ); wstring alt = match.captured( 1 ).toStdU32String();
if ( Folding::applySimpleCaseOnly( alt ) != lowercasedWord ) // No point in providing same word if ( Folding::applySimpleCaseOnly( alt ) != lowercasedWord ) // No point in providing same word
{ {
@ -643,7 +643,7 @@ wstring decodeFromHunspell( Hunspell & hunspell, char const * str )
size_t outLeft = result.size() * sizeof( wchar ); size_t outLeft = result.size() * sizeof( wchar );
QString convStr = conv.convert( in, inLeft ); QString convStr = conv.convert( in, inLeft );
return gd::toWString( convStr ); return convStr.toStdU32String();
} }
} // namespace } // namespace

View file

@ -32,11 +32,8 @@
#include <QDomDocument> #include <QDomDocument>
#include <QTextDocumentFragment> #include <QTextDocumentFragment>
#include <QDataStream> #include <QDataStream>
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
#include <QtCore5Compat/QTextCodec> #include <QtCore5Compat/QTextCodec>
#else
#include <QTextCodec>
#endif
#include "decompress.hh" #include "decompress.hh"
#include "gddebug.hh" #include "gddebug.hh"
#include "ripemd.hh" #include "ripemd.hh"

View file

@ -785,7 +785,7 @@ void MddResourceRequest::run()
data.push_back( '\0' ); data.push_back( '\0' );
QString target = QString target =
MdictParser::toUtf16( "UTF-16LE", &data.front() + sizeof( pattern ), data.size() - sizeof( pattern ) ); MdictParser::toUtf16( "UTF-16LE", &data.front() + sizeof( pattern ), data.size() - sizeof( pattern ) );
resourceName = gd::toWString( target.trimmed() ); resourceName = target.trimmed().toStdU32String();
continue; continue;
} }
} }
@ -1200,7 +1200,7 @@ QString MdxDictionary::getCachedFileName( QString filename )
data.push_back( '\0' ); data.push_back( '\0' );
QString target = QString target =
MdictParser::toUtf16( "UTF-16LE", &data.front() + sizeof( pattern ), data.size() - sizeof( pattern ) ); MdictParser::toUtf16( "UTF-16LE", &data.front() + sizeof( pattern ), data.size() - sizeof( pattern ) );
resourceName = gd::toWString( target.trimmed() ); resourceName = target.trimmed().toStdU32String();
continue; continue;
} }
break; break;
@ -1249,14 +1249,14 @@ static void addEntryToIndex( QString const & word, uint32_t offset, IndexedWords
{ {
// Strip any leading or trailing whitespaces // Strip any leading or trailing whitespaces
QString wordTrimmed = word.trimmed(); QString wordTrimmed = word.trimmed();
indexedWords.addWord( gd::toWString( wordTrimmed ), offset ); indexedWords.addWord( wordTrimmed.toStdU32String(), offset );
} }
static void addEntryToIndexSingle( QString const & word, uint32_t offset, IndexedWords & indexedWords ) static void addEntryToIndexSingle( QString const & word, uint32_t offset, IndexedWords & indexedWords )
{ {
// Strip any leading or trailing whitespaces // Strip any leading or trailing whitespaces
QString wordTrimmed = word.trimmed(); QString wordTrimmed = word.trimmed();
indexedWords.addSingleWord( gd::toWString( wordTrimmed ), offset ); indexedWords.addSingleWord( wordTrimmed.toStdU32String(), offset );
} }
class ArticleHandler: public MdictParser::RecordHandler class ArticleHandler: public MdictParser::RecordHandler

View file

@ -223,7 +223,7 @@ void MediaWikiWordSearchRequest::downloadFinished()
qDebug() << "matches" << matches.size(); qDebug() << "matches" << matches.size();
for ( int x = 0; x < nl.length(); ++x ) { for ( int x = 0; x < nl.length(); ++x ) {
matches.emplace_back( gd::toWString( nl.item( x ).toElement().attribute( "title" ) ) ); matches.emplace_back( nl.item( x ).toElement().attribute( "title" ).toStdU32String() );
} }
} }
} }

View file

@ -334,7 +334,7 @@ void ProgramWordSearchRequest::instanceFinished( QByteArray output, QString erro
QStringList result = QString::fromUtf8( output ).split( "\n", Qt::SkipEmptyParts ); QStringList result = QString::fromUtf8( output ).split( "\n", Qt::SkipEmptyParts );
for ( const auto & x : result ) { for ( const auto & x : result ) {
matches.push_back( Dictionary::WordMatch( gd::toWString( x ) ) ); matches.push_back( Dictionary::WordMatch( x.toStdU32String() ) );
} }
if ( !error.isEmpty() ) { if ( !error.isEmpty() ) {

View file

@ -1,36 +1,31 @@
/* This file is (c) 2008-2012 Konstantin Isakov <ikm@goldendict.org> /* This file is (c) 2008-2012 Konstantin Isakov <ikm@goldendict.org>
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#include "sdict.hh"
#include "btreeidx.hh" #include "btreeidx.hh"
#include "folding.hh"
#include "utf8.hh"
#include "chunkedstorage.hh" #include "chunkedstorage.hh"
#include "langcoder.hh"
#include "gddebug.hh"
#include "decompress.hh" #include "decompress.hh"
#include "htmlescape.hh" #include "folding.hh"
#include "ftshelpers.hh" #include "ftshelpers.hh"
#include "gddebug.hh"
#include "htmlescape.hh"
#include "langcoder.hh"
#include "sdict.hh"
#include "utf8.hh"
#include <map> #include <map>
#include <QAtomicInt>
#include <QRegularExpression>
#include <QSemaphore>
#include <QString>
#include <set> #include <set>
#include <string> #include <string>
#include "utils.hh"
#ifdef _MSC_VER #ifdef _MSC_VER
#include <stub_msvc.h> #include <stub_msvc.h>
#endif #endif
#include <QString>
#include <QSemaphore>
#include <QAtomicInt>
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
#include <QtCore5Compat>
#endif
#include <QRegularExpression>
#include "utils.hh"
namespace Sdict { namespace Sdict {
using std::map; using std::map;

View file

@ -1315,10 +1315,10 @@ vector< sptr< Dictionary::Class > > makeDictionaries( vector< string > const & f
|| contentType.startsWith( "text/plain", Qt::CaseInsensitive ) ) { || contentType.startsWith( "text/plain", Qt::CaseInsensitive ) ) {
//Article //Article
if ( maxHeadwordsToExpand && entries > maxHeadwordsToExpand ) { if ( maxHeadwordsToExpand && entries > maxHeadwordsToExpand ) {
indexedWords.addSingleWord( gd::toWString( refEntry.key ), offsets[ i ].second ); indexedWords.addSingleWord( refEntry.key.toStdU32String(), offsets[ i ].second );
} }
else { else {
indexedWords.addWord( gd::toWString( refEntry.key ), offsets[ i ].second ); indexedWords.addWord( refEntry.key.toStdU32String(), offsets[ i ].second );
} }
wordCount += 1; wordCount += 1;
@ -1330,7 +1330,7 @@ vector< sptr< Dictionary::Class > > makeDictionaries( vector< string > const & f
} }
} }
else { else {
indexedResources.addSingleWord( gd::toWString( refEntry.key ), offsets[ i ].second ); indexedResources.addSingleWord( refEntry.key.toStdU32String(), offsets[ i ].second );
} }
} }
sf.clearRefOffsets(); sf.clearRefOffsets();

View file

@ -409,7 +409,7 @@ void addDir( QDir const & baseDir,
const uint32_t articleOffset = chunks.startNewBlock(); const uint32_t articleOffset = chunks.startNewBlock();
chunks.addToBlock( fileName.c_str(), fileName.size() + 1 ); chunks.addToBlock( fileName.c_str(), fileName.size() + 1 );
wstring name = gd::toWString( i->fileName() ); wstring name = i->fileName().toStdU32String();
const wstring::size_type pos = name.rfind( L'.' ); const wstring::size_type pos = name.rfind( L'.' );

View file

@ -8,11 +8,8 @@
#include "utf8.hh" #include "utf8.hh"
#include "iconv.hh" #include "iconv.hh"
#include "wstring_qt.hh" #include "wstring_qt.hh"
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
#include <QtCore5Compat/QTextCodec> #include <QtCore5Compat/QTextCodec>
#else
#include <QTextCodec>
#endif
#include <QMutexLocker> #include <QMutexLocker>
using namespace BtreeIndexing; using namespace BtreeIndexing;
@ -214,7 +211,7 @@ bool IndexedZip::indexFile( BtreeIndexing::IndexedWords & zipFileNames, quint32
// System locale // System locale
if ( localeCodec ) { if ( localeCodec ) {
QString name = localeCodec->toUnicode( entry.fileName.constData(), entry.fileName.size() ); QString name = localeCodec->toUnicode( entry.fileName.constData(), entry.fileName.size() );
nameInSystemLocale = gd::toWString( name ); nameInSystemLocale = name.toStdU32String();
if ( !nameInSystemLocale.empty() ) { if ( !nameInSystemLocale.empty() ) {
zipFileNames.addSingleWord( nameInSystemLocale, entry.localHeaderOffset ); zipFileNames.addSingleWord( nameInSystemLocale, entry.localHeaderOffset );

View file

@ -903,7 +903,7 @@ void indexArticle( GzippedFile & gzFile,
// Add words to index // Add words to index
for ( const auto & word : words ) { for ( const auto & word : words ) {
indexedWords.addWord( gd::toWString( word ), offset ); indexedWords.addWord( word.toStdU32String(), offset );
} }
++articleCount; ++articleCount;
@ -1226,7 +1226,7 @@ vector< sptr< Dictionary::Class > > makeDictionaries( vector< string > const & f
while ( !( stream.isEndElement() && stream.name() == u"abbr_def" ) || !stream.atEnd() ) { while ( !( stream.isEndElement() && stream.name() == u"abbr_def" ) || !stream.atEnd() ) {
if ( stream.isStartElement() && stream.name() == u"abbr_k" ) { if ( stream.isStartElement() && stream.name() == u"abbr_k" ) {
s = readElementText( stream ); s = readElementText( stream );
keys.push_back( gd::toWString( s ) ); keys.push_back( s.toStdU32String() );
} }
else if ( stream.isStartElement() && stream.name() == u"abbr_v" ) { else if ( stream.isStartElement() && stream.name() == u"abbr_v" ) {
s = readElementText( stream ); s = readElementText( stream );
@ -1246,7 +1246,7 @@ vector< sptr< Dictionary::Class > > makeDictionaries( vector< string > const & f
while ( !( stream.isEndElement() && stream.name() == u"abr_def" ) || !stream.atEnd() ) { while ( !( stream.isEndElement() && stream.name() == u"abr_def" ) || !stream.atEnd() ) {
if ( stream.isStartElement() && stream.name() == u"k" ) { if ( stream.isStartElement() && stream.name() == u"k" ) {
s = readElementText( stream ); s = readElementText( stream );
keys.push_back( gd::toWString( s ) ); keys.push_back( s.toStdU32String() );
} }
else if ( stream.isStartElement() && stream.name() == u"v" ) { else if ( stream.isStartElement() && stream.name() == u"v" ) {
s = readElementText( stream ); s = readElementText( stream );

View file

@ -102,8 +102,7 @@ string convert( string const & in,
} }
break; break;
} }
// Fall-through [[fallthrough]];
default: default:
inConverted.push_back( i ); inConverted.push_back( i );
afterEol = false; afterEol = false;
@ -630,7 +629,7 @@ string convert( string const & in,
// if( type == XDXF && dictPtr != NULL && !el.hasAttribute( "start" ) ) // if( type == XDXF && dictPtr != NULL && !el.hasAttribute( "start" ) )
if ( dictPtr != NULL && !el.hasAttribute( "start" ) ) { if ( dictPtr != NULL && !el.hasAttribute( "start" ) ) {
string filename = Utf8::encode( gd::toWString( el.text() ) ); string filename = Utf8::encode( el.text().toStdU32String() );
if ( Filetype::isNameOfPicture( filename ) ) { if ( Filetype::isNameOfPicture( filename ) ) {
QUrl url; QUrl url;

View file

@ -1,17 +1,10 @@
#ifdef __WIN32 // Q_OS_WIN32 isn't available at this point
#define _WIN32_WINNT 0x0430
#include <windows.h>
#endif
#include "hotkeywrapper.hh" #include "hotkeywrapper.hh"
#include "gddebug.hh" #include "gddebug.hh"
#include <QSessionManager>
#include <QTimer> #include <QTimer>
#include <QSessionManager>
#include <QWidget> #include <QWidget>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include "mainwindow.hh" #include <windows.h>
#endif #endif
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -100,11 +93,6 @@ HotkeyStruct::HotkeyStruct( quint32 key_, quint32 key2_, quint32 modifier_, int
modifier( modifier_ ), modifier( modifier_ ),
handle( handle_ ), handle( handle_ ),
id( id_ ) id( id_ )
#ifdef Q_OS_MAC
,
hkRef( 0 ),
hkRef2( 0 )
#endif
{ {
} }
@ -115,14 +103,7 @@ HotkeyWrapper::HotkeyWrapper( QObject * parent ):
QThread( parent ), QThread( parent ),
state2( false ) state2( false )
{ {
#ifdef Q_OS_WIN
hwnd = (HWND)( ( static_cast< QMainWindow * >( parent ) )->winId() );
gdDebug( "Handle global hotkeys via RegisterHotkey()" );
#else
init(); init();
#endif
( static_cast< QHotkeyApplication * >( qApp ) )->registerWrapper( this ); ( static_cast< QHotkeyApplication * >( qApp ) )->registerWrapper( this );
} }
@ -164,7 +145,8 @@ bool HotkeyWrapper::checkState( quint32 vk, quint32 mod )
if ( hs.key == vk && hs.modifier == mod ) { if ( hs.key == vk && hs.modifier == mod ) {
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
// If that was a copy-to-clipboard shortcut, re-emit it back so it could
// reach its original destination so it could be acted upon.
if ( hs.key2 != 0 || ( mod == MOD_CONTROL && ( vk == VK_INSERT || vk == 'c' || vk == 'C' ) ) ) { if ( hs.key2 != 0 || ( mod == MOD_CONTROL && ( vk == VK_INSERT || vk == 'c' || vk == 'C' ) ) ) {
// Pass-through first part of compound hotkey or clipdoard copy command // Pass-through first part of compound hotkey or clipdoard copy command
@ -270,262 +252,8 @@ bool HotkeyWrapper::checkState( quint32 vk, quint32 mod )
return false; return false;
} }
//////////////////////////////////////////////////////////////////////////
#ifdef Q_OS_WIN #ifndef Q_OS_WIN
void HotkeyWrapper::init()
{
QWidget * root = qApp->topLevelWidgets().value( 0 );
hwnd = (HWND)root->winId();
}
bool HotkeyWrapper::setGlobalKey( QKeySequence const & seq, int handle )
{
Config::HotKey hk( seq );
return setGlobalKey( hk.key1, hk.key2, hk.modifiers, handle );
}
bool HotkeyWrapper::setGlobalKey( int key, int key2, Qt::KeyboardModifiers modifier, int handle )
{
if ( !key )
return false; // We don't monitor empty combinations
static int id = 0;
if ( id > 0xBFFF - 1 )
id = 0;
quint32 mod = 0;
if ( modifier & Qt::CTRL )
mod |= MOD_CONTROL;
if ( modifier & Qt::ALT )
mod |= MOD_ALT;
if ( modifier & Qt::SHIFT )
mod |= MOD_SHIFT;
if ( modifier & Qt::META )
mod |= MOD_WIN;
quint32 vk = nativeKey( key );
quint32 vk2 = key2 ? nativeKey( key2 ) : 0;
hotkeys.append( HotkeyStruct( vk, vk2, mod, handle, id ) );
if ( !RegisterHotKey( hwnd, id++, mod, vk ) )
return false;
if ( key2 && key2 != key )
return RegisterHotKey( hwnd, id++, mod, vk2 );
return true;
}
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
bool HotkeyWrapper::winEvent( MSG * message, long * result )
#else
bool HotkeyWrapper::winEvent( MSG * message, qintptr * result )
#endif
{
(void)result;
if ( message->message == WM_HOTKEY )
return checkState( ( message->lParam >> 16 ), ( message->lParam & 0xffff ) );
return false;
}
quint32 HotkeyWrapper::nativeKey( int key )
{
if ( key >= Qt::Key_0 && key <= Qt::Key_9 )
return VK_NUMPAD0 + ( key - Qt::Key_0 );
if ( key >= Qt::Key_A && key <= Qt::Key_Z )
return key;
switch ( key ) {
case Qt::Key_Space:
return VK_SPACE;
case Qt::Key_Asterisk:
return VK_MULTIPLY;
case Qt::Key_Plus:
return VK_ADD;
case Qt::Key_Comma:
return VK_SEPARATOR;
case Qt::Key_Minus:
return VK_SUBTRACT;
case Qt::Key_Slash:
return VK_DIVIDE;
case Qt::Key_Tab:
case Qt::Key_Backtab:
return VK_TAB;
case Qt::Key_Backspace:
return VK_BACK;
case Qt::Key_Return:
case Qt::Key_Escape:
return VK_ESCAPE;
case Qt::Key_Enter:
return VK_RETURN;
case Qt::Key_Insert:
return VK_INSERT;
case Qt::Key_Delete:
return VK_DELETE;
case Qt::Key_Pause:
return VK_PAUSE;
case Qt::Key_Print:
return VK_PRINT;
case Qt::Key_Clear:
return VK_CLEAR;
case Qt::Key_Home:
return VK_HOME;
case Qt::Key_End:
return VK_END;
case Qt::Key_Up:
return VK_UP;
case Qt::Key_Down:
return VK_DOWN;
case Qt::Key_Left:
return VK_LEFT;
case Qt::Key_Right:
return VK_RIGHT;
case Qt::Key_PageUp:
return VK_PRIOR;
case Qt::Key_PageDown:
return VK_NEXT;
case Qt::Key_F1:
return VK_F1;
case Qt::Key_F2:
return VK_F2;
case Qt::Key_F3:
return VK_F3;
case Qt::Key_F4:
return VK_F4;
case Qt::Key_F5:
return VK_F5;
case Qt::Key_F6:
return VK_F6;
case Qt::Key_F7:
return VK_F7;
case Qt::Key_F8:
return VK_F8;
case Qt::Key_F9:
return VK_F9;
case Qt::Key_F10:
return VK_F10;
case Qt::Key_F11:
return VK_F11;
case Qt::Key_F12:
return VK_F12;
case Qt::Key_F13:
return VK_F13;
case Qt::Key_F14:
return VK_F14;
case Qt::Key_F15:
return VK_F15;
case Qt::Key_F16:
return VK_F16;
case Qt::Key_F17:
return VK_F17;
case Qt::Key_F18:
return VK_F18;
case Qt::Key_F19:
return VK_F19;
case Qt::Key_F20:
return VK_F20;
case Qt::Key_F21:
return VK_F21;
case Qt::Key_F22:
return VK_F22;
case Qt::Key_F23:
return VK_F23;
case Qt::Key_F24:
return VK_F24;
case Qt::Key_Colon:
case Qt::Key_Semicolon:
return VK_OEM_1;
case Qt::Key_Question:
return VK_OEM_2;
case Qt::Key_AsciiTilde:
case Qt::Key_QuoteLeft:
return VK_OEM_3;
case Qt::Key_BraceLeft:
case Qt::Key_BracketLeft:
return VK_OEM_4;
case Qt::Key_Bar:
case Qt::Key_Backslash:
return VK_OEM_5;
case Qt::Key_BraceRight:
case Qt::Key_BracketRight:
return VK_OEM_6;
case Qt::Key_QuoteDbl:
case Qt::Key_Apostrophe:
return VK_OEM_7;
case Qt::Key_Less:
return VK_OEM_COMMA;
case Qt::Key_Greater:
return VK_OEM_PERIOD;
case Qt::Key_Equal:
return VK_OEM_PLUS;
case Qt::Key_ParenRight:
return 0x30;
case Qt::Key_Exclam:
return 0x31;
case Qt::Key_At:
return 0x32;
case Qt::Key_NumberSign:
return 0x33;
case Qt::Key_Dollar:
return 0x34;
case Qt::Key_Percent:
return 0x35;
case Qt::Key_AsciiCircum:
return 0x36;
case Qt::Key_Ampersand:
return 0x37;
case Qt::Key_copyright:
return 0x38;
case Qt::Key_ParenLeft:
return 0x39;
case Qt::Key_Underscore:
return VK_OEM_MINUS;
default:;
}
return key;
}
void HotkeyWrapper::unregister()
{
for ( int i = 0; i < hotkeys.count(); i++ ) {
HotkeyStruct const & hk = hotkeys.at( i );
UnregisterHotKey( hwnd, hk.id );
if ( hk.key2 && hk.key2 != hk.key )
UnregisterHotKey( hwnd, hk.id + 1 );
}
( static_cast< QHotkeyApplication * >( qApp ) )->unregisterWrapper( this );
}
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
bool QHotkeyApplication::nativeEventFilter( const QByteArray & /*eventType*/, void * message, long * result )
#else
bool QHotkeyApplication::nativeEventFilter( const QByteArray & /*eventType*/, void * message, qintptr * result )
#endif
{
MSG * msg = reinterpret_cast< MSG * >( message );
if ( msg->message == WM_HOTKEY ) {
for ( int i = 0; i < hotkeyWrappers.size(); i++ ) {
if ( hotkeyWrappers.at( i )->winEvent( msg, result ) )
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
#else
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View file

@ -1,5 +1,12 @@
#pragma once #pragma once
/// @file
/// Handling global hotkeys and some tricks
/// Part of this header are implmented in
/// + `winhotkeywrapper.cc`
/// + `machotkeywrapper.hh`
///
#include <QGuiApplication> #include <QGuiApplication>
#include <QThread> #include <QThread>
@ -37,15 +44,17 @@
struct HotkeyStruct struct HotkeyStruct
{ {
HotkeyStruct() {} HotkeyStruct() = default;
HotkeyStruct( quint32 key, quint32 key2, quint32 modifier, int handle, int id ); HotkeyStruct( quint32 key, quint32 key2, quint32 modifier, int handle, int id );
quint32 key, key2; quint32 key = 0;
quint32 modifier; quint32 key2 = 0;
int handle; quint32 modifier = 0;
int id; int handle = 0;
int id = 0;
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
EventHotKeyRef hkRef, hkRef2; EventHotKeyRef hkRef = 0;
EventHotKeyRef hkRef2 = 0;
#endif #endif
}; };
@ -98,15 +107,11 @@ private:
HotkeyStruct state2waiter; HotkeyStruct state2waiter;
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
virtual bool winEvent( MSG * message, long * result );
#else
virtual bool winEvent( MSG * message, qintptr * result ); virtual bool winEvent( MSG * message, qintptr * result );
#endif
HWND hwnd; HWND hwnd;
#endif
#elif defined( Q_OS_MAC ) #ifdef Q_OS_MAC
public: public:
void activated( int hkId ); void activated( int hkId );
@ -117,9 +122,9 @@ private:
static EventHandlerUPP hotKeyFunction; static EventHandlerUPP hotKeyFunction;
quint32 keyC; quint32 keyC;
EventHandlerRef handlerRef; EventHandlerRef handlerRef;
#endif
#else #ifdef HAVE_X11
static void recordEventCallback( XPointer, XRecordInterceptData * ); static void recordEventCallback( XPointer, XRecordInterceptData * );
/// Called by recordEventCallback() /// Called by recordEventCallback()
@ -205,16 +210,10 @@ protected:
void registerWrapper( HotkeyWrapper * wrapper ); void registerWrapper( HotkeyWrapper * wrapper );
void unregisterWrapper( HotkeyWrapper * wrapper ); void unregisterWrapper( HotkeyWrapper * wrapper );
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
virtual bool nativeEventFilter( const QByteArray & eventType, void * message, long * result );
#else
virtual bool nativeEventFilter( const QByteArray & eventType, void * message, qintptr * result ); virtual bool nativeEventFilter( const QByteArray & eventType, void * message, qintptr * result );
#endif #endif
protected:
#endif // Q_OS_WIN32
QList< HotkeyWrapper * > hotkeyWrappers; QList< HotkeyWrapper * > hotkeyWrappers;
}; };

View file

@ -105,15 +105,8 @@ void IframeSchemeHandler::requestStarted( QWebEngineUrlRequestJob * requestJob )
buffer->setData( articleString.toUtf8() ); buffer->setData( articleString.toUtf8() );
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
requestJob->reply( "text/html; charset=utf-8", buffer ); requestJob->reply( "text/html; charset=utf-8", buffer );
#else
#if defined( Q_OS_WIN32 ) || defined( Q_OS_MAC )
requestJob->reply( contentType, buffer );
#else
requestJob->reply( "text/html", buffer );
#endif
#endif
}; };
connect( reply, &QNetworkReply::finished, requestJob, finishAction ); connect( reply, &QNetworkReply::finished, requestJob, finishAction );

View file

@ -307,15 +307,7 @@ void processCommandLine( QCoreApplication * app, GDOptions * result )
// Handle cases where we get encoded URL // Handle cases where we get encoded URL
if ( result->word.startsWith( QStringLiteral( "xn--" ) ) ) { if ( result->word.startsWith( QStringLiteral( "xn--" ) ) ) {
// For `kde-open` or `gio` or others, URL are encoded into ACE or Punycode // For `kde-open` or `gio` or others, URL are encoded into ACE or Punycode
#if QT_VERSION >= QT_VERSION_CHECK( 6, 3, 0 )
result->word = QUrl::fromAce( result->word.toLatin1(), QUrl::IgnoreIDNWhitelist ); result->word = QUrl::fromAce( result->word.toLatin1(), QUrl::IgnoreIDNWhitelist );
#else
// Old Qt's fromAce only applies to whitelisted domains, so we add .com to bypass this restriction :)
// https://bugreports.qt.io/browse/QTBUG-29080
result->word.append( QStringLiteral( ".com" ) );
result->word = QUrl::fromAce( result->word.toLatin1() );
result->word.chop( 4 );
#endif
} }
else if ( result->word.startsWith( QStringLiteral( "%" ) ) ) { else if ( result->word.startsWith( QStringLiteral( "%" ) ) ) {
// For Firefox or other browsers where URL are percent encoded // For Firefox or other browsers where URL are percent encoded
@ -349,8 +341,11 @@ int main( int argc, char ** argv )
// attach the new console to this application's process // attach the new console to this application's process
if ( AttachConsole( ATTACH_PARENT_PROCESS ) ) { if ( AttachConsole( ATTACH_PARENT_PROCESS ) ) {
// reopen the std I/O streams to redirect I/O to the new console // reopen the std I/O streams to redirect I/O to the new console
freopen( "CON", "w", stdout ); auto ret1 = freopen( "CON", "w", stdout );
freopen( "CON", "w", stderr ); auto ret2 = freopen( "CON", "w", stderr );
if ( ret1 == nullptr || ret2 == nullptr ) {
qDebug() << "Attaching console stdout or stderr failed";
}
} }
qputenv( "QT_QPA_PLATFORM", "windows:darkmode=1" ); qputenv( "QT_QPA_PLATFORM", "windows:darkmode=1" );
@ -359,10 +354,6 @@ int main( int argc, char ** argv )
//high dpi screen support //high dpi screen support
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
QApplication::setAttribute( Qt::AA_EnableHighDpiScaling );
QApplication::setAttribute( Qt::AA_UseHighDpiPixmaps );
#endif
qputenv( "QT_ENABLE_HIGHDPI_SCALING", "1" ); qputenv( "QT_ENABLE_HIGHDPI_SCALING", "1" );
QApplication::setHighDpiScaleFactorRoundingPolicy( Qt::HighDpiScaleFactorRoundingPolicy::PassThrough ); QApplication::setHighDpiScaleFactorRoundingPolicy( Qt::HighDpiScaleFactorRoundingPolicy::PassThrough );

View file

@ -1,8 +1,6 @@
#include "article_inspect.hh" #include "article_inspect.hh"
#include <QCloseEvent> #include <QCloseEvent>
#if ( QT_VERSION > QT_VERSION_CHECK( 6, 0, 0 ) )
#include <QWebEngineContextMenuRequest> #include <QWebEngineContextMenuRequest>
#endif
ArticleInspector::ArticleInspector( QWidget * parent ): ArticleInspector::ArticleInspector( QWidget * parent ):
QWidget( parent, Qt::WindowType::Window ) QWidget( parent, Qt::WindowType::Window )
{ {
@ -39,9 +37,7 @@ void ArticleInspector::triggerAction( QWebEnginePage * page )
return; return;
} }
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) || QT_VERSION > QT_VERSION_CHECK( 6, 3, 0 ) )
page->triggerAction( QWebEnginePage::InspectElement ); page->triggerAction( QWebEnginePage::InspectElement );
#endif
} }
void ArticleInspector::closeEvent( QCloseEvent * ) void ArticleInspector::closeEvent( QCloseEvent * )

View file

@ -31,15 +31,9 @@
#include <map> #include <map>
#include <QApplication> #include <QApplication>
#include <QRandomGenerator> #include <QRandomGenerator>
#if ( QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) && QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
#include <QWebEngineContextMenuData>
#endif
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
#include <QWebEngineContextMenuRequest> #include <QWebEngineContextMenuRequest>
#include <QWebEngineFindTextResult> #include <QWebEngineFindTextResult>
#include <utility> #include <utility>
#endif
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
#include <windows.h> #include <windows.h>
#include <QPainter> #include <QPainter>
@ -214,15 +208,7 @@ ArticleView::ArticleView( QWidget * parent,
QWebEngineSettings * settings = webview->settings(); QWebEngineSettings * settings = webview->settings();
settings->setUnknownUrlSchemePolicy( QWebEngineSettings::UnknownUrlSchemePolicy::DisallowUnknownUrlSchemes ); settings->setUnknownUrlSchemePolicy( QWebEngineSettings::UnknownUrlSchemePolicy::DisallowUnknownUrlSchemes );
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
settings->defaultSettings()->setAttribute( QWebEngineSettings::LocalContentCanAccessRemoteUrls, true );
settings->defaultSettings()->setAttribute( QWebEngineSettings::LocalContentCanAccessFileUrls, true );
settings->defaultSettings()->setAttribute( QWebEngineSettings::ErrorPageEnabled, false );
settings->defaultSettings()->setAttribute( QWebEngineSettings::LinksIncludedInFocusChain, false );
settings->defaultSettings()->setAttribute( QWebEngineSettings::PlaybackRequiresUserGesture, false );
settings->defaultSettings()->setAttribute( QWebEngineSettings::JavascriptCanAccessClipboard, true );
settings->defaultSettings()->setAttribute( QWebEngineSettings::PrintElementBackgrounds, false );
#else
settings->setAttribute( QWebEngineSettings::LocalContentCanAccessRemoteUrls, true ); settings->setAttribute( QWebEngineSettings::LocalContentCanAccessRemoteUrls, true );
settings->setAttribute( QWebEngineSettings::LocalContentCanAccessFileUrls, true ); settings->setAttribute( QWebEngineSettings::LocalContentCanAccessFileUrls, true );
settings->setAttribute( QWebEngineSettings::ErrorPageEnabled, false ); settings->setAttribute( QWebEngineSettings::ErrorPageEnabled, false );
@ -230,7 +216,6 @@ ArticleView::ArticleView( QWidget * parent,
settings->setAttribute( QWebEngineSettings::PlaybackRequiresUserGesture, false ); settings->setAttribute( QWebEngineSettings::PlaybackRequiresUserGesture, false );
settings->setAttribute( QWebEngineSettings::JavascriptCanAccessClipboard, true ); settings->setAttribute( QWebEngineSettings::JavascriptCanAccessClipboard, true );
settings->setAttribute( QWebEngineSettings::PrintElementBackgrounds, false ); settings->setAttribute( QWebEngineSettings::PrintElementBackgrounds, false );
#endif
auto html = articleNetMgr.getHtml( ResourceType::UNTITLE ); auto html = articleNetMgr.getHtml( ResourceType::UNTITLE );
@ -1329,12 +1314,10 @@ void ArticleView::print( QPrinter * printer ) const
result = success; result = success;
loop.quit(); loop.quit();
}; };
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
webview->page()->print( printer, std::move( printPreview ) );
#else
connect( webview, &QWebEngineView::printFinished, &loop, std::move( printPreview ) ); connect( webview, &QWebEngineView::printFinished, &loop, std::move( printPreview ) );
webview->print( printer ); webview->print( printer );
#endif
loop.exec(); loop.exec();
if ( !result ) { if ( !result ) {
qDebug() << "print failed"; qDebug() << "print failed";
@ -1363,11 +1346,7 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
QAction * saveSoundAction = nullptr; QAction * saveSoundAction = nullptr;
QAction * saveBookmark = nullptr; QAction * saveBookmark = nullptr;
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
const QWebEngineContextMenuData * menuData = &( r->contextMenuData() );
#else
QWebEngineContextMenuRequest * menuData = webview->lastContextMenuRequest(); QWebEngineContextMenuRequest * menuData = webview->lastContextMenuRequest();
#endif
QUrl targetUrl( menuData->linkUrl() ); QUrl targetUrl( menuData->linkUrl() );
Contexts contexts; Contexts contexts;
@ -1392,12 +1371,8 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
} }
QUrl imageUrl; QUrl imageUrl;
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
if ( !popupView && menuData->mediaType() == QWebEngineContextMenuData::MediaTypeImage ) if ( !popupView && menuData->mediaType() == QWebEngineContextMenuRequest::MediaType::MediaTypeImage ) {
#else
if ( !popupView && menuData->mediaType() == QWebEngineContextMenuRequest::MediaType::MediaTypeImage )
#endif
{
imageUrl = menuData->mediaUrl(); imageUrl = menuData->mediaUrl();
if ( !imageUrl.isEmpty() ) { if ( !imageUrl.isEmpty() ) {
menu.addAction( webview->pageAction( QWebEnginePage::CopyImageToClipboard ) ); menu.addAction( webview->pageAction( QWebEnginePage::CopyImageToClipboard ) );
@ -1905,7 +1880,7 @@ void ArticleView::doubleClicked( QPoint pos )
emit sendWordToInputLine( selectedText ); emit sendWordToInputLine( selectedText );
// Do some checks to make sure there's a sensible selection indeed // Do some checks to make sure there's a sensible selection indeed
if ( Folding::applyWhitespaceOnly( gd::toWString( selectedText ) ).size() && selectedText.size() < 60 ) { if ( Folding::applyWhitespaceOnly( selectedText.toStdU32String() ).size() && selectedText.size() < 60 ) {
// Initiate translation // Initiate translation
Qt::KeyboardModifiers kmod = QApplication::keyboardModifiers(); Qt::KeyboardModifiers kmod = QApplication::keyboardModifiers();
if ( kmod & ( Qt::ControlModifier | Qt::ShiftModifier ) ) { // open in new tab if ( kmod & ( Qt::ControlModifier | Qt::ShiftModifier ) ) { // open in new tab
@ -1955,19 +1930,12 @@ void ArticleView::findText( QString & text,
const QWebEnginePage::FindFlags & f, const QWebEnginePage::FindFlags & f,
const std::function< void( bool match ) > & callback ) const std::function< void( bool match ) > & callback )
{ {
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
webview->findText( text, f, [ callback ]( const QWebEngineFindTextResult & result ) { webview->findText( text, f, [ callback ]( const QWebEngineFindTextResult & result ) {
auto r = result.numberOfMatches() > 0; auto r = result.numberOfMatches() > 0;
if ( callback ) { if ( callback ) {
callback( r ); callback( r );
} }
} ); } );
#else
webview->findText( text, f, [ callback ]( bool result ) {
if ( callback )
callback( result );
} );
#endif
} }
bool ArticleView::closeSearch() bool ArticleView::closeSearch()
@ -2099,7 +2067,6 @@ void ArticleView::performFtsFindOperation( bool backwards )
QWebEnginePage::FindFlags flags( 0 ); QWebEnginePage::FindFlags flags( 0 );
if ( backwards ) { if ( backwards ) {
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
webview->findText( firstAvailableText, webview->findText( firstAvailableText,
flags | QWebEnginePage::FindBackward, flags | QWebEnginePage::FindBackward,
[ this ]( const QWebEngineFindTextResult & result ) { [ this ]( const QWebEngineFindTextResult & result ) {
@ -2114,16 +2081,8 @@ void ArticleView::performFtsFindOperation( bool backwards )
ftsSearchPanel->statusLabel->setText( ftsSearchPanel->statusLabel->setText(
searchStatusMessage( result.activeMatch(), result.numberOfMatches() ) ); searchStatusMessage( result.activeMatch(), result.numberOfMatches() ) );
} ); } );
#else
webview->findText( firstAvailableText, flags | QWebEnginePage::FindBackward, [ this ]( bool res ) {
ftsSearchPanel->previous->setEnabled( res );
if ( !ftsSearchPanel->next->isEnabled() )
ftsSearchPanel->next->setEnabled( res );
} );
#endif
} }
else { else {
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
webview->findText( firstAvailableText, flags, [ this ]( const QWebEngineFindTextResult & result ) { webview->findText( firstAvailableText, flags, [ this ]( const QWebEngineFindTextResult & result ) {
if ( result.numberOfMatches() == 0 ) { if ( result.numberOfMatches() == 0 ) {
return; return;
@ -2135,15 +2094,6 @@ void ArticleView::performFtsFindOperation( bool backwards )
ftsSearchPanel->statusLabel->setText( searchStatusMessage( result.activeMatch(), result.numberOfMatches() ) ); ftsSearchPanel->statusLabel->setText( searchStatusMessage( result.activeMatch(), result.numberOfMatches() ) );
} ); } );
#else
webview->findText( firstAvailableText, flags, [ this ]( bool res ) {
ftsSearchPanel->next->setEnabled( res );
if ( !ftsSearchPanel->previous->isEnabled() )
ftsSearchPanel->previous->setEnabled( res );
} );
#endif
} }
} }

View file

@ -420,10 +420,6 @@ void DictHeadwords::saveHeadersToFile()
// Write UTF-8 BOM // Write UTF-8 BOM
QTextStream out( &file ); QTextStream out( &file );
out.setGenerateByteOrderMark( true ); out.setGenerateByteOrderMark( true );
//qt 6 will use utf-8 default.
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
out.setCodec( "UTF-8" );
#endif
exportAllWords( progress, out ); exportAllWords( progress, out );

View file

@ -84,13 +84,13 @@ private slots:
private: private:
virtual bool eventFilter( QObject *, QEvent * ); virtual bool eventFilter( QObject *, QEvent * );
Config::Class * m_cfg; Config::Class * m_cfg = nullptr;
QTreeView * m_favoritesTree; QTreeView * m_favoritesTree = nullptr;
QMenu * m_favoritesMenu; QMenu * m_favoritesMenu = nullptr;
QAction * m_deleteSelectedAction; QAction * m_deleteSelectedAction = nullptr;
QAction * m_separator; QAction * m_separator = nullptr;
QAction * m_copySelectedToClipboard; QAction * m_copySelectedToClipboard = nullptr;
QAction * m_addFolder; QAction * m_addFolder = nullptr;
QWidget favoritesPaneTitleBar; QWidget favoritesPaneTitleBar;
QHBoxLayout favoritesPaneTitleBarLayout; QHBoxLayout favoritesPaneTitleBarLayout;

View file

@ -53,13 +53,13 @@ private slots:
private: private:
virtual bool eventFilter( QObject *, QEvent * ); virtual bool eventFilter( QObject *, QEvent * );
Config::Class * m_cfg; Config::Class * m_cfg = nullptr;
History * m_history; History * m_history = nullptr;
QListView * m_historyList; QListView * m_historyList = nullptr;
QMenu * m_historyMenu; QMenu * m_historyMenu = nullptr;
QAction * m_deleteSelectedAction; QAction * m_deleteSelectedAction = nullptr;
QAction * m_separator; QAction * m_separator = nullptr;
QAction * m_copySelectedToClipboard; QAction * m_copySelectedToClipboard = nullptr;
QWidget historyPaneTitleBar; QWidget historyPaneTitleBar;
QHBoxLayout historyPaneTitleBarLayout; QHBoxLayout historyPaneTitleBarLayout;

View file

@ -760,11 +760,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
#if defined( Q_OS_LINUX ) #if defined( Q_OS_LINUX )
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
defaultInterfaceStyle = QApplication::style()->name(); defaultInterfaceStyle = QApplication::style()->name();
#else
defaultInterfaceStyle = QApplication::style()->objectName();
#endif
#elif defined( Q_OS_MAC ) #elif defined( Q_OS_MAC )
defaultInterfaceStyle = "Fusion"; defaultInterfaceStyle = "Fusion";
#endif #endif

View file

@ -8,11 +8,6 @@
#include <QBitmap> #include <QBitmap>
#include <QMenu> #include <QMenu>
#include <QMouseEvent> #include <QMouseEvent>
#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) )
#include <QDesktopWidget>
#include <QScreen>
#include <QStringList>
#endif
#include "gddebug.hh" #include "gddebug.hh"
#include "gestures.hh" #include "gestures.hh"
@ -846,11 +841,7 @@ void ScanPopup::leaveEvent( QEvent * event )
} }
} }
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
void ScanPopup::enterEvent( QEnterEvent * event ) void ScanPopup::enterEvent( QEnterEvent * event )
#else
void ScanPopup::enterEvent( QEvent * event )
#endif
{ {
QMainWindow::enterEvent( event ); QMainWindow::enterEvent( event );

View file

@ -174,11 +174,7 @@ private:
virtual void mouseMoveEvent( QMouseEvent * ); virtual void mouseMoveEvent( QMouseEvent * );
virtual void mouseReleaseEvent( QMouseEvent * ); virtual void mouseReleaseEvent( QMouseEvent * );
virtual void leaveEvent( QEvent * event ); virtual void leaveEvent( QEvent * event );
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
virtual void enterEvent( QEnterEvent * event ); virtual void enterEvent( QEnterEvent * event );
#else
virtual void enterEvent( QEvent * event );
#endif
virtual void showEvent( QShowEvent * ); virtual void showEvent( QShowEvent * );
virtual void closeEvent( QCloseEvent * ); virtual void closeEvent( QCloseEvent * );
virtual void moveEvent( QMoveEvent * ); virtual void moveEvent( QMoveEvent * );

View file

@ -0,0 +1,256 @@
#include <QtGlobal>
#ifdef Q_OS_WIN
#include "hotkeywrapper.hh"
#include <windows.h>
#include <QWidget>
/// Implementation is pretty much using RegisterHotKey & UnregisterHotKey
/// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerhotkey
void HotkeyWrapper::init()
{
hwnd = (HWND)( ( static_cast< QWidget * >( this->parent() ) )->winId() );
}
bool HotkeyWrapper::setGlobalKey( QKeySequence const & seq, int handle )
{
Config::HotKey hk( seq );
return setGlobalKey( hk.key1, hk.key2, hk.modifiers, handle );
}
bool HotkeyWrapper::setGlobalKey( int key, int key2, Qt::KeyboardModifiers modifier, int handle )
{
if ( !key )
return false; // We don't monitor empty combinations
static int id = 0;
if ( id > 0xBFFF - 1 )
id = 0;
quint32 mod = 0;
if ( modifier & Qt::CTRL )
mod |= MOD_CONTROL;
if ( modifier & Qt::ALT )
mod |= MOD_ALT;
if ( modifier & Qt::SHIFT )
mod |= MOD_SHIFT;
if ( modifier & Qt::META )
mod |= MOD_WIN;
quint32 vk = nativeKey( key );
quint32 vk2 = key2 ? nativeKey( key2 ) : 0;
hotkeys.append( HotkeyStruct( vk, vk2, mod, handle, id ) );
if ( !RegisterHotKey( hwnd, id++, mod, vk ) )
return false;
if ( key2 && key2 != key )
return RegisterHotKey( hwnd, id++, mod, vk2 );
return true;
}
bool HotkeyWrapper::winEvent( MSG * message, qintptr * result )
{
Q_UNUSED( result );
if ( message->message == WM_HOTKEY )
return checkState( ( message->lParam >> 16 ), ( message->lParam & 0xffff ) );
return false;
}
void HotkeyWrapper::unregister()
{
for ( int i = 0; i < hotkeys.count(); i++ ) {
HotkeyStruct const & hk = hotkeys.at( i );
UnregisterHotKey( hwnd, hk.id );
if ( hk.key2 && hk.key2 != hk.key )
UnregisterHotKey( hwnd, hk.id + 1 );
}
( static_cast< QHotkeyApplication * >( qApp ) )->unregisterWrapper( this );
}
bool QHotkeyApplication::nativeEventFilter( const QByteArray & /*eventType*/, void * message, qintptr * result )
{
MSG * msg = reinterpret_cast< MSG * >( message );
if ( msg->message == WM_HOTKEY ) {
for ( int i = 0; i < hotkeyWrappers.size(); i++ ) {
if ( hotkeyWrappers.at( i )->winEvent( msg, result ) )
return true;
}
}
return false;
}
/// References:
/// https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
/// https://doc.qt.io/qt-6/qt.html#Key-enum
quint32 HotkeyWrapper::nativeKey( int key )
{
// Qt's 0-9 & A-Z overlaps with Windows's VK
if ( key >= Qt::Key_0 && key <= Qt::Key_9 || key >= Qt::Key_A && key <= Qt::Key_Z ) {
return key;
}
switch ( key ) {
case Qt::Key_Space:
return VK_SPACE;
case Qt::Key_Asterisk:
return VK_MULTIPLY;
case Qt::Key_Plus:
return VK_ADD;
case Qt::Key_Comma:
return VK_SEPARATOR;
case Qt::Key_Minus:
return VK_SUBTRACT;
case Qt::Key_Slash:
return VK_DIVIDE;
case Qt::Key_Tab:
case Qt::Key_Backtab:
return VK_TAB;
case Qt::Key_Backspace:
return VK_BACK;
case Qt::Key_Return:
case Qt::Key_Escape:
return VK_ESCAPE;
case Qt::Key_Enter:
return VK_RETURN;
case Qt::Key_Insert:
return VK_INSERT;
case Qt::Key_Delete:
return VK_DELETE;
case Qt::Key_Pause:
return VK_PAUSE;
case Qt::Key_Print:
return VK_PRINT;
case Qt::Key_Clear:
return VK_CLEAR;
case Qt::Key_Home:
return VK_HOME;
case Qt::Key_End:
return VK_END;
case Qt::Key_Up:
return VK_UP;
case Qt::Key_Down:
return VK_DOWN;
case Qt::Key_Left:
return VK_LEFT;
case Qt::Key_Right:
return VK_RIGHT;
case Qt::Key_PageUp:
return VK_PRIOR;
case Qt::Key_PageDown:
return VK_NEXT;
case Qt::Key_F1:
return VK_F1;
case Qt::Key_F2:
return VK_F2;
case Qt::Key_F3:
return VK_F3;
case Qt::Key_F4:
return VK_F4;
case Qt::Key_F5:
return VK_F5;
case Qt::Key_F6:
return VK_F6;
case Qt::Key_F7:
return VK_F7;
case Qt::Key_F8:
return VK_F8;
case Qt::Key_F9:
return VK_F9;
case Qt::Key_F10:
return VK_F10;
case Qt::Key_F11:
return VK_F11;
case Qt::Key_F12:
return VK_F12;
case Qt::Key_F13:
return VK_F13;
case Qt::Key_F14:
return VK_F14;
case Qt::Key_F15:
return VK_F15;
case Qt::Key_F16:
return VK_F16;
case Qt::Key_F17:
return VK_F17;
case Qt::Key_F18:
return VK_F18;
case Qt::Key_F19:
return VK_F19;
case Qt::Key_F20:
return VK_F20;
case Qt::Key_F21:
return VK_F21;
case Qt::Key_F22:
return VK_F22;
case Qt::Key_F23:
return VK_F23;
case Qt::Key_F24:
return VK_F24;
case Qt::Key_Colon:
case Qt::Key_Semicolon:
return VK_OEM_1;
case Qt::Key_Question:
return VK_OEM_2;
case Qt::Key_AsciiTilde:
case Qt::Key_QuoteLeft:
return VK_OEM_3;
case Qt::Key_BraceLeft:
case Qt::Key_BracketLeft:
return VK_OEM_4;
case Qt::Key_Bar:
case Qt::Key_Backslash:
return VK_OEM_5;
case Qt::Key_BraceRight:
case Qt::Key_BracketRight:
return VK_OEM_6;
case Qt::Key_QuoteDbl:
case Qt::Key_Apostrophe:
return VK_OEM_7;
case Qt::Key_Less:
return VK_OEM_COMMA;
case Qt::Key_Greater:
return VK_OEM_PERIOD;
case Qt::Key_Equal:
return VK_OEM_PLUS;
case Qt::Key_ParenRight:
return 0x30;
case Qt::Key_Exclam:
return 0x31;
case Qt::Key_At:
return 0x32;
case Qt::Key_NumberSign:
return 0x33;
case Qt::Key_Dollar:
return 0x34;
case Qt::Key_Percent:
return 0x35;
case Qt::Key_AsciiCircum:
return 0x36;
case Qt::Key_Ampersand:
return 0x37;
case Qt::Key_copyright:
return 0x38;
case Qt::Key_ParenLeft:
return 0x39;
case Qt::Key_Underscore:
return VK_OEM_MINUS;
case Qt::Key_Meta:
return VK_LWIN;
default:;
}
return key;
}
#endif

View file

@ -131,7 +131,7 @@ void WordFinder::startSearch()
allWordWritings.resize( 1 ); allWordWritings.resize( 1 );
} }
allWordWritings[ 0 ] = gd::toWString( inputWord ); allWordWritings[ 0 ] = inputWord.toStdU32String();
for ( const auto & inputDict : *inputDicts ) { for ( const auto & inputDict : *inputDicts ) {
vector< wstring > writings = inputDict->getAlternateWritings( allWordWritings[ 0 ] ); vector< wstring > writings = inputDict->getAlternateWritings( allWordWritings[ 0 ] );

View file

@ -3,10 +3,10 @@
With venv With venv
``` ```
cd ./website cd ./website
python -m venv ./venv/ python3 -m venv ./venv/
source ./venv/bin/activate source ./venv/bin/activate
# source ./venv/bin/activate.fish # source ./venv/bin/activate.fish
pip install mkdocs-material pip3 install mkdocs-material
``` ```
Then Then

View file

@ -46,3 +46,5 @@ will disable the current dictionary's full-text search.
You can check the full-text search status on each dictionary's info dialog. You can check the full-text search status on each dictionary's info dialog.
![](img/dictionary-info-fullindex.png) ![](img/dictionary-info-fullindex.png)
Note that it is possible to enable full text for a single dictionary by disabling full-text search in the Preferences dialog, and set `fts=true` for that dictionary.

View file

@ -1,4 +1,4 @@
Dictionaries management dialog can be opened via menu `Edit` -> `Dictionaries`. Dictionary management dialog can be opened via menu `Edit` -> `Dictionaries`.
To use local dictionaries, add them via `Sources` -> `Files`. To use local dictionaries, add them via `Sources` -> `Files`.
@ -34,7 +34,7 @@ Morphology dictionary uses Hunspell's morphological analysis to obtain word's va
You can specify a path that includes Hunspell format data files (`.aff` + `.dic`). GoldenDict scan this folder and create a list of available dictionaries. You can specify a path that includes Hunspell format data files (`.aff` + `.dic`). GoldenDict scan this folder and create a list of available dictionaries.
One possible source of Hunspell dictionaries is Libreoffice's [dictionaries](https://github.com/LibreOffice/dictionaries). One possible source of Hunspell dictionaries is LibreOffice's [dictionaries](https://github.com/LibreOffice/dictionaries).
The detailed document about the affix file (`.aff`) and the dict file (`.dic`) can be found at [hunspell.5](https://man.archlinux.org/man/hunspell.5.en). The detailed document about the affix file (`.aff`) and the dict file (`.dic`) can be found at [hunspell.5](https://man.archlinux.org/man/hunspell.5.en).

View file

@ -4,6 +4,7 @@ By creating `article-style.css` or `article-script.js` in GoldenDict's configura
. <- GD's configuration folder . <- GD's configuration folder
├── config ├── config
├── article-style.css ├── article-style.css
├── article-style-print.css (affecting styles when printing)
├── article-script.js ├── article-script.js
└── qt-style.css └── qt-style.css
``` ```

View file

@ -54,17 +54,3 @@
| F3 | Dictionaries dialog | | F3 | Dictionaries dialog |
| F4 | GoldenDict preferences | | F4 | GoldenDict preferences |
| F12 | Inspector | | F12 | Inspector |
# Solo mode in the dictionary bar
Ctrl+Click, Enter solo mode, toggle between single & all dictionaries
Shift+Click, Exit solo mode, restore the previous dictionaries.
For example, there are 4 dictionaries A,B,C,D with ABC selected.
| Cases| Note|
|--------|--------|
| Ctrl+Click A|select A only|
| Ctrl+Click A, Ctrl+Click B | select B only|
| Ctrl+Click A, Ctrl+Click A | A,B,C,D selected(all dictionaries selected)|
| Ctrl+Click A, Shift+Click any dictionary| A,B,C selected |

View file

@ -1,37 +1,56 @@
## Toolbar ## Toolbar
![toolbar](img/toolbar.webp) ![toolbar](img/toolbar.webp)
From left to right: Type your word in Search Box and press `Enter` to search word in the current selected group. You can also choose a variant from a matches list.
* Forward/Backward navigation buttons; Holding Ctrl or Shift will display the translation result in a new tab.
* Group selector
* Search Line
* Toggle Scanning
* Play the first pronunciation in found articles;
* Font scale buttons;
* Save the article as HTML
* Print article
* Add to Favorites;
Type your word in Search Box and press `Enter` to search word in the current selected group. You can also choose a variant from matches list.
If Ctrl or Shift key has been pressed the new tab for translation will be created.
### Wildcard matching ### Wildcard matching
The Search Line can contain wildcard symbols `?` (matches any one character), `*` (matches any characters number) or ranges of characters `[...]`. To find characters `?`, `*`, `[` and `]` it should be escaped with backslash like `\?`, `\*`, `\[`, `\]`. The search line can use wildcard or glob symbols for matching words.
| Wildcard | Description |
|----------|------------------------------------------------------------------------|
| `?` | Matches any single character. |
| `*` | Matches zero or more of any characters. |
| `[abc]` | Matches one character given in the bracket. |
| `[a-c]` | Matches one character from the range given in the bracket. |
| `[!abc]` | Matches one character that is not given in the bracket. |
| `[!a-c]` | Matches one character that is not from the range given in the bracket. |
| `\` | Escaping wildcard symbols, e.g. `\?` to search `?` |
!!! note !!! note
The wildcard symbol at first position in word leads to full headwords list scanning and it may take a long time for huge dictionaries. The wildcard symbol in the first character leads to scanning of every dictionary's every word and may take a long time.
More information about wildcard matching can be found in [Wikipedia's glob article](https://en.wikipedia.org/wiki/Glob_(programming)).
## Dictionary Bar ## Dictionary Bar
The dictionaries bar contains all dictionaries from current dictionaries group. Click the icons to disable/enable them. The dictionary bar contains all dictionaries from the current dictionaries group. Click the icons to disable/enable them.
Hold `Shift` and click dictionary bar will temporally focus on a single dictionary. Hold `Shift` and click again to defocus and restore the previous dictionaries bar state. ### "Solo" mode
Hold `Ctrl` and click dictionary bar will toggle between "Enable a single dictionary" and "Enable all dictionary". Temporally focus on a single dictionary and restore back to all dictionaries or previously selected dictionaries.
Note: The `Shift` and `Ctrl` interaction can also be used on "Found in dictionaries" panel To enter solo mode:
++ctrl+left-button++ -> Select a single dictionary.
To exit solo mode:
++ctrl+left-button++ -> Reselect all dictionaries.
++shift+left-button++ -> Reselect dictionaries that were previously selected before entering solo mode.
For example, there are 4 dictionaries A,B,C,D with ABC selected.
| Cases | Note |
|------------------------------------------|----------------------------------------------|
| Ctrl+Click A | select A only |
| Ctrl+Click A, Ctrl+Click B | select B only |
| Ctrl+Click A, Ctrl+Click A | A,B,C,D selected (all dictionaries selected) |
| Ctrl+Click A, Shift+Click any dictionary | A,B,C selected |
Note: This can also be used on the "Found in dictionaries" panel.

View file

@ -21,6 +21,7 @@ markdown_extensions:
- admonition - admonition
- pymdownx.details - pymdownx.details
- pymdownx.superfences - pymdownx.superfences
- pymdownx.keys
nav: nav:
- Getting started: index.md - Getting started: index.md
@ -33,7 +34,7 @@ nav:
- Popup Window: ui_popup.md - Popup Window: ui_popup.md
- Headwords Dialog: ui_headwords.md - Headwords Dialog: ui_headwords.md
- Full Text Search: ui_fulltextsearch.md - Full Text Search: ui_fulltextsearch.md
- ToolBar & DictBar: ui_toolbar.md - Tool & Dictionary Bar: ui_toolbar.md
- Favorites: ui_favorites.md - Favorites: ui_favorites.md
- Shortcuts: ui_shortcuts.md - Shortcuts: ui_shortcuts.md
- Advanced Usages: - Advanced Usages: