Compare commits

...

11 commits

Author SHA1 Message Date
xiaoyifang 7626855556
Merge 15b918eb6a into 608016208b 2024-11-11 20:26:29 +08:00
shenleban tongying 608016208b
disable more staffs related to macOS trayicon -> dock icon
Some checks are pending
SonarCloud / Build and analyze (push) Waiting to run
2024-11-11 07:53:10 +00:00
shenleban tongying 1e3b22ebd0 fix: macOS -> replace the tray icon with a dock menu 2024-11-11 02:32:27 -05:00
shenleban tongying 720f66c781 clean: make toggleMainWindow reasonable
Some checks are pending
SonarCloud / Build and analyze (push) Waiting to run
2024-11-11 00:18:02 -05:00
shenleban tongying acbfef0870 opt: don't focus on the main window if word comes from headword dialog 2024-11-11 00:18:02 -05:00
shenleban tongying d4db51f278 opt: mdx -> avoid duplicated Adler-32 checksum in zlib decompression 2024-11-10 22:32:22 -05:00
shenleban tongying 160402e1d0 Consistently use README and no CRLF
Some checks are pending
SonarCloud / Build and analyze (push) Waiting to run
2024-11-10 17:39:43 -05:00
shenleban tongying fb48f66370 move audio files to src/audio
a
2024-11-10 17:39:43 -05:00
autofix-ci[bot] 15b918eb6a
[autofix.ci] apply automated fixes 2024-11-08 01:47:29 +00:00
xiaoyifang 27cbb7351b opt: add option about 2024-11-06 13:35:22 +08:00
xiaoyifang c787a08d2f opt: add option about 2024-11-06 12:07:23 +08:00
29 changed files with 170 additions and 136 deletions

View file

@ -26,6 +26,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,

3
src/audio/README.md Normal file
View file

@ -0,0 +1,3 @@
Code to support GD's internal/external audio players.
Only `audioplayerinterface.hh` is supposed to be used outside this folder.

View file

@ -197,13 +197,11 @@ Preferences::Preferences():
hideSingleTab( false ),
mruTabOrder( false ),
hideMenubar( false ),
enableTrayIcon( true ),
startToTray( false ),
closeToTray( true ),
autoStart( false ),
doubleClickTranslates( true ),
selectWordBySingleClick( false ),
autoScrollToTargetArticle( true ),
targetArticleAtFirst( false ),
escKeyHidesMainWindow( false ),
alwaysOnTop( false ),
searchInDock( false ),
@ -903,10 +901,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" );
@ -931,6 +930,11 @@ Class load()
( preferences.namedItem( "autoScrollToTargetArticle" ).toElement().text() == "1" );
}
if ( !preferences.namedItem( "targetArticleAtFirst" ).isNull() ) {
c.preferences.targetArticleAtFirst =
( preferences.namedItem( "targetArticleAtFirst" ).toElement().text() == "1" );
}
if ( !preferences.namedItem( "escKeyHidesMainWindow" ).isNull() ) {
c.preferences.escKeyHidesMainWindow =
( preferences.namedItem( "escKeyHidesMainWindow" ).toElement().text() == "1" );
@ -1868,6 +1872,10 @@ void save( Class const & c )
opt.appendChild( dd.createTextNode( c.preferences.autoScrollToTargetArticle ? "1" : "0" ) );
preferences.appendChild( opt );
opt = dd.createElement( "targetArticleAtFirst" );
opt.appendChild( dd.createTextNode( c.preferences.targetArticleAtFirst ? "1" : "0" ) );
preferences.appendChild( opt );
opt = dd.createElement( "escKeyHidesMainWindow" );
opt.appendChild( dd.createTextNode( c.preferences.escKeyHidesMainWindow ? "1" : "0" ) );
preferences.appendChild( opt );

View file

@ -341,13 +341,22 @@ 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;
bool autoScrollToTargetArticle;
bool targetArticleAtFirst;
bool escKeyHidesMainWindow;
bool alwaysOnTop;

View file

@ -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;

View file

@ -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() );
}

View file

@ -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 );

View file

@ -10,7 +10,7 @@
#include <QWebEngineView>
#include <list>
#include "article_netmgr.hh"
#include "audioplayerinterface.hh"
#include "audio/audioplayerinterface.hh"
#include "instances.hh"
#include "groupcombobox.hh"
#include "globalbroadcaster.hh"

View file

@ -401,15 +401,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();
@ -1421,6 +1424,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;
@ -1444,6 +1452,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 )
@ -2532,7 +2541,7 @@ void MainWindow::handleEsc()
}
if ( cfg.preferences.escKeyHidesMainWindow ) {
toggleMainWindow();
toggleMainWindow( false );
}
else {
focusTranslateLine();
@ -2873,7 +2882,7 @@ void MainWindow::showTranslationForDicts( QString const & inWord,
ignoreDiacritics );
}
void MainWindow::toggleMainWindow( bool onlyShow )
void MainWindow::toggleMainWindow( bool ensureShow )
{
bool shown = false;
@ -2906,7 +2915,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
@ -2990,7 +2999,7 @@ void MainWindow::installHotKeys()
void MainWindow::hotKeyActivated( int hk )
{
if ( !hk ) {
toggleMainWindow();
toggleMainWindow( false );
}
else if ( scanPopup ) {
#ifdef HAVE_X11
@ -3075,7 +3084,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:
@ -3088,10 +3097,6 @@ void MainWindow::trayIconActivated( QSystemTrayIcon::ActivationReason r )
}
}
void MainWindow::showMainWindow()
{
toggleMainWindow( true );
}
void MainWindow::visitHomepage()
{
@ -3730,13 +3735,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() ) {
@ -4141,7 +4139,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,

View file

@ -14,7 +14,7 @@
#include "config.hh"
#include "dict/dictionary.hh"
#include "article_netmgr.hh"
#include "audioplayerfactory.hh"
#include "audio/audioplayerfactory.hh"
#include "instances.hh"
#include "article_maker.hh"
#include "scanpopup.hh"
@ -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();
@ -398,8 +396,6 @@ private slots:
void setAutostart( bool );
void showMainWindow();
void visitHomepage();
void visitForum();
void openConfigFolder();

View file

@ -174,12 +174,18 @@ 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 );
ui.doubleClickTranslates->setChecked( p.doubleClickTranslates );
ui.selectBySingleClick->setChecked( p.selectWordBySingleClick );
ui.autoScrollToTargetArticle->setChecked( p.autoScrollToTargetArticle );
ui.targetArticleAtFirst->setChecked( p.targetArticleAtFirst );
ui.escKeyHidesMainWindow->setChecked( p.escKeyHidesMainWindow );
ui.darkMode->addItem( tr( "On" ), QVariant::fromValue( Config::Dark::On ) );
@ -436,6 +442,7 @@ Config::Preferences Preferences::getPreferences()
p.doubleClickTranslates = ui.doubleClickTranslates->isChecked();
p.selectWordBySingleClick = ui.selectBySingleClick->isChecked();
p.autoScrollToTargetArticle = ui.autoScrollToTargetArticle->isChecked();
p.targetArticleAtFirst = ui.targetArticleAtFirst->isChecked();
p.escKeyHidesMainWindow = ui.escKeyHidesMainWindow->isChecked();
p.darkMode = ui.darkMode->currentData().value< Config::Dark >();

View file

@ -169,6 +169,16 @@ however, the article from the topmost dictionary is shown.</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="targetArticleAtFirst">
<property name="text">
<string>Place the target article at the first place.</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="enableTrayIcon">
<property name="toolTip">