mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-23 20:14:05 +00:00
Compare commits
8 commits
2d0a5752c1
...
677745ba09
Author | SHA1 | Date | |
---|---|---|---|
677745ba09 | |||
8fd5b37335 | |||
4758f9e972 | |||
608016208b | |||
1e3b22ebd0 | |||
720f66c781 | |||
acbfef0870 | |||
d4db51f278 |
|
@ -17,7 +17,6 @@ Checks: >
|
|||
portability-*,
|
||||
readability-*,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-reserved-identifier,
|
||||
-cppcoreguidelines-owning-memory,
|
||||
-cppcoreguidelines-prefer-member-initializer,
|
||||
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
||||
|
@ -26,6 +25,7 @@ Checks: >
|
|||
-google-default-arguments,
|
||||
-google-readability-casting,
|
||||
-hicpp-deprecated-headers,
|
||||
-hicpp-no-array-decay,
|
||||
-misc-const-correctness,
|
||||
-misc-include-cleaner,
|
||||
-misc-non-private-member-variables-in-classes,
|
||||
|
@ -43,5 +43,11 @@ CheckOptions:
|
|||
value: 1
|
||||
- key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
|
||||
value: 1
|
||||
- key: modernize-avoid-c-arrays.AllowStringArrays
|
||||
value: 1
|
||||
- key: cppcoreguidelines-avoid-c-arrays.AllowStringArrays
|
||||
value: 1
|
||||
- key: hicpp-avoid-c-arrays.AllowStringArrays
|
||||
value: 1
|
||||
...
|
||||
|
||||
|
|
|
@ -4,22 +4,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <fmt/format.h>
|
||||
|
||||
// clang-format off
|
||||
|
||||
/// A way to declare an exception class fast
|
||||
/// Do like this:
|
||||
/// DEF_EX( exErrorInFoo, "An error in foo encountered", std::exception )
|
||||
/// DEF_EX( exFooNotFound, "Foo was not found", exErrorInFoo )
|
||||
|
||||
#define DEF_EX( exName, exDescription, exParent ) \
|
||||
class exName: public exParent \
|
||||
{ \
|
||||
public: \
|
||||
virtual const char * what() const noexcept \
|
||||
{ \
|
||||
return ( exDescription ); \
|
||||
} \
|
||||
virtual ~exName() noexcept {} \
|
||||
};
|
||||
#define DEF_EX( exName, exDescription, exParent ) \
|
||||
constexpr static char ExStr_## exName[] = exDescription; \
|
||||
using exName = defineEx< exParent, ExStr_## exName >;
|
||||
|
||||
/// Same as DEF_EX, but takes a runtime string argument, which gets concatenated
|
||||
/// with the description.
|
||||
|
@ -29,20 +24,36 @@
|
|||
/// throw exCantOpen( "example.txt" );
|
||||
///
|
||||
/// what() would return "can't open file example.txt"
|
||||
///
|
||||
#define DEF_EX_STR( exName, exDescription, exParent ) \
|
||||
constexpr static char ExStr_## exName[] = exDescription; \
|
||||
using exName = defineExStr< exParent, ExStr_## exName >;
|
||||
|
||||
#define DEF_EX_STR( exName, exDescription, exParent ) \
|
||||
class exName: public exParent \
|
||||
{ \
|
||||
std::string value; \
|
||||
\
|
||||
public: \
|
||||
explicit exName( std::string const & value_ ): \
|
||||
value( std::string( exDescription ) + " " + value_ ) \
|
||||
{ \
|
||||
} \
|
||||
virtual const char * what() const noexcept \
|
||||
{ \
|
||||
return value.c_str(); \
|
||||
} \
|
||||
virtual ~exName() noexcept {} \
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
template< typename ParentEx, const char * description >
|
||||
class defineEx: public ParentEx
|
||||
{
|
||||
public:
|
||||
virtual const char * what() const noexcept
|
||||
{
|
||||
return description;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename ParentEx, const char * description >
|
||||
class defineExStr: public ParentEx
|
||||
{
|
||||
public:
|
||||
explicit defineExStr( std::string const & message_ ):
|
||||
message( fmt::format( "{} {}", description, message_ ) )
|
||||
{
|
||||
}
|
||||
virtual const char * what() const noexcept
|
||||
{
|
||||
return message.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string message;
|
||||
};
|
||||
|
|
|
@ -197,9 +197,6 @@ Preferences::Preferences():
|
|||
hideSingleTab( false ),
|
||||
mruTabOrder( false ),
|
||||
hideMenubar( false ),
|
||||
enableTrayIcon( true ),
|
||||
startToTray( false ),
|
||||
closeToTray( true ),
|
||||
autoStart( false ),
|
||||
doubleClickTranslates( true ),
|
||||
selectWordBySingleClick( false ),
|
||||
|
@ -903,10 +900,11 @@ Class load()
|
|||
c.preferences.hideSingleTab = ( preferences.namedItem( "hideSingleTab" ).toElement().text() == "1" );
|
||||
c.preferences.mruTabOrder = ( preferences.namedItem( "mruTabOrder" ).toElement().text() == "1" );
|
||||
c.preferences.hideMenubar = ( preferences.namedItem( "hideMenubar" ).toElement().text() == "1" );
|
||||
|
||||
#ifndef Q_OS_MACOS // // macOS uses the dock menu instead of the tray icon
|
||||
c.preferences.enableTrayIcon = ( preferences.namedItem( "enableTrayIcon" ).toElement().text() == "1" );
|
||||
c.preferences.startToTray = ( preferences.namedItem( "startToTray" ).toElement().text() == "1" );
|
||||
c.preferences.closeToTray = ( preferences.namedItem( "closeToTray" ).toElement().text() == "1" );
|
||||
#endif
|
||||
c.preferences.autoStart = ( preferences.namedItem( "autoStart" ).toElement().text() == "1" );
|
||||
c.preferences.alwaysOnTop = ( preferences.namedItem( "alwaysOnTop" ).toElement().text() == "1" );
|
||||
c.preferences.searchInDock = ( preferences.namedItem( "searchInDock" ).toElement().text() == "1" );
|
||||
|
|
|
@ -341,9 +341,17 @@ struct Preferences
|
|||
bool hideSingleTab;
|
||||
bool mruTabOrder;
|
||||
bool hideMenubar;
|
||||
bool enableTrayIcon;
|
||||
bool startToTray;
|
||||
bool closeToTray;
|
||||
|
||||
#ifdef Q_OS_MACOS // macOS uses the dock menu instead of the tray icon
|
||||
bool closeToTray = false;
|
||||
bool enableTrayIcon = false;
|
||||
bool startToTray = false;
|
||||
#else
|
||||
bool enableTrayIcon = true;
|
||||
bool closeToTray = true;
|
||||
bool startToTray = false;
|
||||
#endif
|
||||
|
||||
bool autoStart;
|
||||
bool doubleClickTranslates;
|
||||
bool selectWordBySingleClick;
|
||||
|
|
|
@ -46,10 +46,6 @@ using BtreeIndexing::IndexInfo;
|
|||
|
||||
namespace {
|
||||
|
||||
DEF_EX_STR( exNotAardFile, "Not an AARD file", Dictionary::Ex )
|
||||
DEF_EX_STR( exWordIsTooLarge, "Enountered a word that is too large:", Dictionary::Ex )
|
||||
DEF_EX_STR( exSuddenEndOfFile, "Sudden end of file", Dictionary::Ex )
|
||||
|
||||
#pragma pack( push, 1 )
|
||||
|
||||
/// AAR file header
|
||||
|
|
|
@ -169,10 +169,6 @@ void addEntryToIndex( string & word,
|
|||
indexedWords.addWord( Utf8::decode( word ), articleOffset );
|
||||
}
|
||||
|
||||
|
||||
DEF_EX( exFailedToDecompressArticle, "Failed to decompress article's body", Dictionary::Ex )
|
||||
DEF_EX( exChunkIndexOutOfRange, "Chunk index is out of range", Dictionary::Ex )
|
||||
|
||||
class BglDictionary: public BtreeIndexing::BtreeDictionary
|
||||
{
|
||||
QMutex idxMutex;
|
||||
|
|
|
@ -301,7 +301,6 @@ namespace {
|
|||
////////////////// GLS Dictionary
|
||||
|
||||
using Dictionary::exCantReadFile;
|
||||
DEF_EX( exUserAbort, "User abort", Dictionary::Ex )
|
||||
DEF_EX_STR( exDictzipError, "DICTZIP error", Dictionary::Ex )
|
||||
|
||||
enum {
|
||||
|
|
|
@ -264,14 +264,12 @@ bool MdictParser::parseCompressedBlock( qint64 compressedBlockSize,
|
|||
|
||||
case 0x02000000:
|
||||
// zlib compression
|
||||
decompressedBlock = zlibDecompress( buf, size );
|
||||
|
||||
if ( !checkAdler32( decompressedBlock.constData(), decompressedBlock.size(), checksum ) ) {
|
||||
gdWarning( "MDict: parseCompressedBlock: zlib: checksum does not match" );
|
||||
decompressedBlock = zlibDecompress( buf, size, checksum );
|
||||
if ( decompressedBlock.isEmpty() ) {
|
||||
gdWarning( "MDict: parseCompressedBlock: zlib: failed to decompress or checksum does not match" );
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
gdWarning( "MDict: parseCompressedBlock: unknown type" );
|
||||
return false;
|
||||
|
|
|
@ -64,14 +64,11 @@ DEF_EX( exNotAnIfoFile, "Not an .ifo file", Dictionary::Ex )
|
|||
DEF_EX_STR( exBadFieldInIfo, "Bad field in .ifo file encountered:", Dictionary::Ex )
|
||||
DEF_EX_STR( exNoIdxFile, "No corresponding .idx file was found for", Dictionary::Ex )
|
||||
DEF_EX_STR( exNoDictFile, "No corresponding .dict file was found for", Dictionary::Ex )
|
||||
DEF_EX_STR( exNoSynFile, "No corresponding .syn file was found for", Dictionary::Ex )
|
||||
|
||||
DEF_EX( ex64BitsNotSupported, "64-bit indices are not presently supported, sorry", Dictionary::Ex )
|
||||
DEF_EX( exDicttypeNotSupported, "Dictionaries with dicttypes are not supported, sorry", Dictionary::Ex )
|
||||
|
||||
using Dictionary::exCantReadFile;
|
||||
DEF_EX_STR( exWordIsTooLarge, "Enountered a word that is too large:", Dictionary::Ex )
|
||||
DEF_EX_STR( exSuddenEndOfFile, "Sudden end of file", Dictionary::Ex )
|
||||
DEF_EX_STR( exDictzipError, "DICTZIP error", Dictionary::Ex )
|
||||
|
||||
DEF_EX_STR( exIncorrectOffset, "Incorrect offset encountered in file", Dictionary::Ex )
|
||||
|
|
|
@ -3,20 +3,21 @@
|
|||
#include <bzlib.h>
|
||||
#include <lzma.h>
|
||||
|
||||
#define CHUNK_SIZE 2048
|
||||
using std::string;
|
||||
|
||||
QByteArray zlibDecompress( const char * bufptr, unsigned length )
|
||||
static constexpr qsizetype CHUNK_SIZE = 2048;
|
||||
|
||||
QByteArray zlibDecompress( const char * bufptr, unsigned length, uLong adler32_checksum )
|
||||
{
|
||||
z_stream zs;
|
||||
char buf[ CHUNK_SIZE ];
|
||||
z_stream zs{};
|
||||
QByteArray str;
|
||||
int res;
|
||||
memset( &zs, 0, sizeof( zs ) );
|
||||
int res = Z_OK;
|
||||
zs.next_in = (Bytef *)bufptr;
|
||||
zs.avail_in = length;
|
||||
res = inflateInit( &zs );
|
||||
|
||||
if ( res == Z_OK ) {
|
||||
char buf[ CHUNK_SIZE ];
|
||||
while ( res != Z_STREAM_END ) {
|
||||
zs.next_out = (Bytef *)buf;
|
||||
zs.avail_out = CHUNK_SIZE;
|
||||
|
@ -27,9 +28,7 @@ QByteArray zlibDecompress( const char * bufptr, unsigned length )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
inflateEnd( &zs );
|
||||
if ( res != Z_STREAM_END ) {
|
||||
if ( inflateEnd( &zs ) != Z_OK || res != Z_STREAM_END || ( adler32_checksum != 0 && zs.adler != adler32_checksum ) ) {
|
||||
str.clear();
|
||||
}
|
||||
return str;
|
||||
|
@ -37,7 +36,7 @@ QByteArray zlibDecompress( const char * bufptr, unsigned length )
|
|||
|
||||
string decompressZlib( const char * bufptr, unsigned length )
|
||||
{
|
||||
QByteArray b = zlibDecompress( bufptr, length );
|
||||
QByteArray b = zlibDecompress( bufptr, length, 0 );
|
||||
return string( b.constData(), b.size() );
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,11 @@
|
|||
#include <QByteArray>
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
/// @param adler32_checksum 0 to skip checksum
|
||||
QByteArray zlibDecompress( const char * bufptr, unsigned length, unsigned long adler32_checksum );
|
||||
|
||||
QByteArray zlibDecompress( const char * bufptr, unsigned length );
|
||||
std::string decompressZlib( const char * bufptr, unsigned length );
|
||||
|
||||
string decompressZlib( const char * bufptr, unsigned length );
|
||||
std::string decompressBzip2( const char * bufptr, unsigned length );
|
||||
|
||||
string decompressBzip2( const char * bufptr, unsigned length );
|
||||
|
||||
string decompressLzma2( const char * bufptr, unsigned length, bool raw_decoder = false );
|
||||
std::string decompressLzma2( const char * bufptr, unsigned length, bool raw_decoder = false );
|
||||
|
|
|
@ -81,7 +81,6 @@ namespace {
|
|||
|
||||
using Dictionary::exCantReadFile;
|
||||
DEF_EX_STR( exNotXdxfFile, "The file is not an XDXF file:", Dictionary::Ex )
|
||||
DEF_EX( exCorruptedIndex, "The index file is corrupted", Dictionary::Ex )
|
||||
DEF_EX_STR( exDictzipError, "DICTZIP error", Dictionary::Ex )
|
||||
|
||||
enum {
|
||||
|
|
|
@ -402,15 +402,18 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
|||
connect( wordsZoomOut, &QAction::triggered, this, &MainWindow::doWordsZoomOut );
|
||||
connect( wordsZoomBase, &QAction::triggered, this, &MainWindow::doWordsZoomBase );
|
||||
|
||||
// tray icon
|
||||
connect( trayIconMenu.addAction( tr( "Show &Main Window" ) ),
|
||||
&QAction::triggered,
|
||||
this,
|
||||
&MainWindow::showMainWindow );
|
||||
// tray icon
|
||||
#ifndef Q_OS_MACOS // macOS uses the dock menu instead of the tray icon
|
||||
connect( trayIconMenu.addAction( tr( "Show &Main Window" ) ), &QAction::triggered, this, [ this ] {
|
||||
this->toggleMainWindow( true );
|
||||
} );
|
||||
#endif
|
||||
trayIconMenu.addAction( enableScanningAction );
|
||||
|
||||
#ifndef Q_OS_MACOS // macOS uses the dock menu instead of the tray icon
|
||||
trayIconMenu.addSeparator();
|
||||
connect( trayIconMenu.addAction( tr( "&Quit" ) ), &QAction::triggered, this, &MainWindow::quitApp );
|
||||
#endif
|
||||
|
||||
addGlobalAction( &escAction, [ this ]() {
|
||||
handleEsc();
|
||||
|
@ -1426,6 +1429,11 @@ void MainWindow::updateAppearances( QString const & addonStyle,
|
|||
|
||||
void MainWindow::trayIconUpdateOrInit()
|
||||
{
|
||||
#ifdef Q_OS_MACOS
|
||||
trayIconMenu.setAsDockMenu();
|
||||
ui.actionCloseToTray->setVisible( false );
|
||||
#else
|
||||
|
||||
if ( !cfg.preferences.enableTrayIcon ) {
|
||||
if ( trayIcon ) {
|
||||
delete trayIcon;
|
||||
|
@ -1449,6 +1457,7 @@ void MainWindow::trayIconUpdateOrInit()
|
|||
// The 'Close to tray' action is associated with the tray icon, so we hide
|
||||
// or show it here.
|
||||
ui.actionCloseToTray->setVisible( cfg.preferences.enableTrayIcon );
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::wheelEvent( QWheelEvent * ev )
|
||||
|
@ -2542,7 +2551,7 @@ void MainWindow::handleEsc()
|
|||
}
|
||||
|
||||
if ( cfg.preferences.escKeyHidesMainWindow ) {
|
||||
toggleMainWindow();
|
||||
toggleMainWindow( false );
|
||||
}
|
||||
else {
|
||||
focusTranslateLine();
|
||||
|
@ -2883,7 +2892,7 @@ void MainWindow::showTranslationForDicts( QString const & inWord,
|
|||
ignoreDiacritics );
|
||||
}
|
||||
|
||||
void MainWindow::toggleMainWindow( bool onlyShow )
|
||||
void MainWindow::toggleMainWindow( bool ensureShow )
|
||||
{
|
||||
bool shown = false;
|
||||
|
||||
|
@ -2916,7 +2925,7 @@ void MainWindow::toggleMainWindow( bool onlyShow )
|
|||
}
|
||||
shown = true;
|
||||
}
|
||||
else if ( !onlyShow ) {
|
||||
else if ( !ensureShow ) {
|
||||
|
||||
// On Windows and Linux, a hidden window won't show a task bar icon
|
||||
// When trayicon is enabled, the duplication is unneeded
|
||||
|
@ -3000,7 +3009,7 @@ void MainWindow::installHotKeys()
|
|||
void MainWindow::hotKeyActivated( int hk )
|
||||
{
|
||||
if ( !hk ) {
|
||||
toggleMainWindow();
|
||||
toggleMainWindow( false );
|
||||
}
|
||||
else if ( scanPopup ) {
|
||||
#ifdef HAVE_X11
|
||||
|
@ -3085,7 +3094,7 @@ void MainWindow::trayIconActivated( QSystemTrayIcon::ActivationReason r )
|
|||
switch ( r ) {
|
||||
case QSystemTrayIcon::Trigger:
|
||||
// Left click toggles the visibility of main window
|
||||
toggleMainWindow();
|
||||
toggleMainWindow( false );
|
||||
break;
|
||||
|
||||
case QSystemTrayIcon::MiddleClick:
|
||||
|
@ -3098,10 +3107,6 @@ void MainWindow::trayIconActivated( QSystemTrayIcon::ActivationReason r )
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::showMainWindow()
|
||||
{
|
||||
toggleMainWindow( true );
|
||||
}
|
||||
|
||||
void MainWindow::visitHomepage()
|
||||
{
|
||||
|
@ -3741,13 +3746,6 @@ void MainWindow::wordReceived( const QString & word )
|
|||
respondToTranslationRequest( word, false );
|
||||
}
|
||||
|
||||
void MainWindow::headwordReceived( const QString & word, const QString & ID )
|
||||
{
|
||||
toggleMainWindow( true );
|
||||
setInputLineText( word, WildcardPolicy::EscapeWildcards, NoPopupChange );
|
||||
respondToTranslationRequest( word, false, ArticleView::scrollToFromDictionaryId( ID ), false );
|
||||
}
|
||||
|
||||
void MainWindow::updateFavoritesMenu()
|
||||
{
|
||||
if ( ui.favoritesPane->isVisible() ) {
|
||||
|
@ -4152,7 +4150,13 @@ void MainWindow::showDictionaryHeadwords( Dictionary::Class * dict )
|
|||
headwordsDlg = new DictHeadwords( this, cfg, dict );
|
||||
addGlobalActionsToDialog( headwordsDlg );
|
||||
addGroupComboBoxActionsToDialog( headwordsDlg, groupList );
|
||||
connect( headwordsDlg, &DictHeadwords::headwordSelected, this, &MainWindow::headwordReceived );
|
||||
connect( headwordsDlg,
|
||||
&DictHeadwords::headwordSelected,
|
||||
this,
|
||||
[ this ]( QString const & headword, QString const & dictID ) {
|
||||
setInputLineText( headword, WildcardPolicy::EscapeWildcards, NoPopupChange );
|
||||
respondToTranslationRequest( headword, false, ArticleView::scrollToFromDictionaryId( dictID ), false );
|
||||
} );
|
||||
connect( headwordsDlg,
|
||||
&DictHeadwords::closeDialog,
|
||||
this,
|
||||
|
|
|
@ -67,7 +67,6 @@ public slots:
|
|||
void messageFromAnotherInstanceReceived( QString const & );
|
||||
void showStatusBarMessage( QString const &, int, QPixmap const & );
|
||||
void wordReceived( QString const & );
|
||||
void headwordReceived( QString const &, QString const & );
|
||||
void headwordFromFavorites( QString const &, QString const & );
|
||||
void quitApp();
|
||||
|
||||
|
@ -226,9 +225,8 @@ private:
|
|||
/// group, or to all dictionaries if there are no groups.
|
||||
vector< sptr< Dictionary::Class > > const & getActiveDicts();
|
||||
|
||||
/// Brings the main window to front if it's not currently, or hides it
|
||||
/// otherwise. The hiding part is omitted if onlyShow is true.
|
||||
void toggleMainWindow( bool onlyShow = false );
|
||||
/// @param ensureShow only ensure the window will be shown and no "toggling"
|
||||
void toggleMainWindow( bool ensureShow );
|
||||
|
||||
/// Creates hotkeyWrapper and hooks the currently set keys for it
|
||||
void installHotKeys();
|
||||
|
@ -399,8 +397,6 @@ private slots:
|
|||
|
||||
void setAutostart( bool );
|
||||
|
||||
void showMainWindow();
|
||||
|
||||
void visitHomepage();
|
||||
void visitForum();
|
||||
void openConfigFolder();
|
||||
|
|
|
@ -174,6 +174,11 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ):
|
|||
ui.hideSingleTab->setChecked( p.hideSingleTab );
|
||||
ui.mruTabOrder->setChecked( p.mruTabOrder );
|
||||
ui.enableTrayIcon->setChecked( p.enableTrayIcon );
|
||||
|
||||
#ifdef Q_OS_MACOS // macOS uses the dock menu instead of the tray icon
|
||||
ui.enableTrayIcon->hide();
|
||||
#endif
|
||||
|
||||
ui.startToTray->setChecked( p.startToTray );
|
||||
ui.closeToTray->setChecked( p.closeToTray );
|
||||
ui.cbAutostart->setChecked( p.autoStart );
|
||||
|
|
Loading…
Reference in a new issue