Compare commits

..

1 commit

Author SHA1 Message Date
xiaoyifang b0de4e1d5d
Merge 15b918eb6a into c7d0feb2e8 2024-11-15 16:18:07 -05:00
9 changed files with 144 additions and 158 deletions

View file

@ -67,7 +67,7 @@ jobs:
libzim \ libzim \
qt qt
wget https://github.com/mistydemeo/eb/releases/download/v4.4.3/eb-4.4.3.tar.bz2 wget ftp://ftp.sra.co.jp/pub/misc/eb/eb-4.4.3.tar.bz2
tar xvjf eb-4.4.3.tar.bz2 tar xvjf eb-4.4.3.tar.bz2
cd eb-4.4.3 && ./configure && make -j 8 && sudo make install && cd .. cd eb-4.4.3 && ./configure && make -j 8 && sudo make install && cd ..

View file

@ -3,39 +3,34 @@
#include <QScopedPointer> #include <QScopedPointer>
#include <QObject> #include <QObject>
#include <utility>
#include "audioplayerfactory.hh" #include "audioplayerfactory.hh"
#include "ffmpegaudioplayer.hh" #include "ffmpegaudioplayer.hh"
#include "multimediaaudioplayer.hh" #include "multimediaaudioplayer.hh"
#include "externalaudioplayer.hh" #include "externalaudioplayer.hh"
#include "gddebug.hh" #include "gddebug.hh"
AudioPlayerFactory::AudioPlayerFactory( bool useInternalPlayer, AudioPlayerFactory::AudioPlayerFactory( Config::Preferences const & p ):
InternalPlayerBackend internalPlayerBackend, useInternalPlayer( p.useInternalPlayer ),
QString audioPlaybackProgram ): internalPlayerBackend( p.internalPlayerBackend ),
useInternalPlayer( useInternalPlayer ), audioPlaybackProgram( p.audioPlaybackProgram )
internalPlayerBackend( std::move( internalPlayerBackend ) ),
audioPlaybackProgram( std::move( audioPlaybackProgram ) )
{ {
reset(); reset();
} }
void AudioPlayerFactory::setPreferences( bool new_useInternalPlayer, void AudioPlayerFactory::setPreferences( Config::Preferences const & p )
const InternalPlayerBackend & new_internalPlayerBackend,
const QString & new_audioPlaybackProgram )
{ {
if ( useInternalPlayer != new_useInternalPlayer ) { if ( p.useInternalPlayer != useInternalPlayer ) {
useInternalPlayer = new_useInternalPlayer; useInternalPlayer = p.useInternalPlayer;
internalPlayerBackend = new_internalPlayerBackend; internalPlayerBackend = p.internalPlayerBackend;
audioPlaybackProgram = new_audioPlaybackProgram; audioPlaybackProgram = p.audioPlaybackProgram;
reset(); reset();
} }
else if ( useInternalPlayer && internalPlayerBackend != new_internalPlayerBackend ) { else if ( useInternalPlayer && p.internalPlayerBackend != internalPlayerBackend ) {
internalPlayerBackend = new_internalPlayerBackend; internalPlayerBackend = p.internalPlayerBackend;
reset(); reset();
} }
else if ( !useInternalPlayer && new_audioPlaybackProgram != audioPlaybackProgram ) { else if ( !useInternalPlayer && p.audioPlaybackProgram != audioPlaybackProgram ) {
audioPlaybackProgram = new_audioPlaybackProgram; audioPlaybackProgram = p.audioPlaybackProgram;
ExternalAudioPlayer * const externalPlayer = qobject_cast< ExternalAudioPlayer * >( playerPtr.data() ); ExternalAudioPlayer * const externalPlayer = qobject_cast< ExternalAudioPlayer * >( playerPtr.data() );
if ( externalPlayer ) { if ( externalPlayer ) {
setAudioPlaybackProgram( *externalPlayer ); setAudioPlaybackProgram( *externalPlayer );
@ -55,7 +50,7 @@ void AudioPlayerFactory::reset()
// another object of the same type. // another object of the same type.
#ifdef MAKE_FFMPEG_PLAYER #ifdef MAKE_FFMPEG_PLAYER
Q_ASSERT( InternalPlayerBackend::defaultBackend().isFfmpeg() Q_ASSERT( Config::InternalPlayerBackend::defaultBackend().isFfmpeg()
&& "Adjust the code below after changing the default backend." ); && "Adjust the code below after changing the default backend." );
if ( !internalPlayerBackend.isQtmultimedia() ) { if ( !internalPlayerBackend.isQtmultimedia() ) {

View file

@ -4,7 +4,7 @@
#pragma once #pragma once
#include "audioplayerinterface.hh" #include "audioplayerinterface.hh"
#include "internalplayerbackend.hh" #include "config.hh"
class ExternalAudioPlayer; class ExternalAudioPlayer;
@ -13,12 +13,8 @@ class AudioPlayerFactory
Q_DISABLE_COPY( AudioPlayerFactory ) Q_DISABLE_COPY( AudioPlayerFactory )
public: public:
explicit AudioPlayerFactory( bool useInternalPlayer, explicit AudioPlayerFactory( Config::Preferences const & );
InternalPlayerBackend internalPlayerBackend, void setPreferences( Config::Preferences const & );
QString audioPlaybackProgram );
void setPreferences( bool new_useInternalPlayer,
const InternalPlayerBackend & new_internalPlayerBackend,
const QString & new_audioPlaybackProgram );
/// The returned reference to a smart pointer is valid as long as this object /// The returned reference to a smart pointer is valid as long as this object
/// exists. The pointer to the owned AudioPlayerInterface may change after the /// exists. The pointer to the owned AudioPlayerInterface may change after the
/// call to setPreferences(), but it is guaranteed to never be null. /// call to setPreferences(), but it is guaranteed to never be null.
@ -32,7 +28,7 @@ private:
void setAudioPlaybackProgram( ExternalAudioPlayer & externalPlayer ); void setAudioPlaybackProgram( ExternalAudioPlayer & externalPlayer );
bool useInternalPlayer; bool useInternalPlayer;
InternalPlayerBackend internalPlayerBackend; Config::InternalPlayerBackend internalPlayerBackend;
QString audioPlaybackProgram; QString audioPlaybackProgram;
AudioPlayerPtr playerPtr; AudioPlayerPtr playerPtr;
}; };

View file

@ -1,51 +0,0 @@
#include "internalplayerbackend.hh"
bool InternalPlayerBackend::anyAvailable()
{
#if defined( MAKE_FFMPEG_PLAYER ) || defined( MAKE_QTMULTIMEDIA_PLAYER )
return true;
#else
return false;
#endif
}
InternalPlayerBackend InternalPlayerBackend::defaultBackend()
{
#if defined( MAKE_FFMPEG_PLAYER )
return ffmpeg();
#elif defined( MAKE_QTMULTIMEDIA_PLAYER )
return qtmultimedia();
#else
return InternalPlayerBackend( QString() );
#endif
}
QStringList InternalPlayerBackend::nameList()
{
QStringList result;
#ifdef MAKE_FFMPEG_PLAYER
result.push_back( ffmpeg().uiName() );
#endif
#ifdef MAKE_QTMULTIMEDIA_PLAYER
result.push_back( qtmultimedia().uiName() );
#endif
return result;
}
bool InternalPlayerBackend::isFfmpeg() const
{
#ifdef MAKE_FFMPEG_PLAYER
return *this == ffmpeg();
#else
return false;
#endif
}
bool InternalPlayerBackend::isQtmultimedia() const
{
#ifdef MAKE_QTMULTIMEDIA_PLAYER
return *this == qtmultimedia();
#else
return false;
#endif
}

View file

@ -1,61 +0,0 @@
#pragma once
#include <QStringList>
/// Overly engineered dummy/helper/wrapper "backend", which is not, to manage backends.
class InternalPlayerBackend
{
public:
/// Returns true if at least one backend is available.
static bool anyAvailable();
/// Returns the default backend or null backend if none is available.
static InternalPlayerBackend defaultBackend();
/// Returns the name list of supported backends.
static QStringList nameList();
/// Returns true if built with FFmpeg player support and the name matches.
bool isFfmpeg() const;
/// Returns true if built with Qt Multimedia player support and the name matches.
bool isQtmultimedia() const;
QString const & uiName() const
{
return name;
}
void setUiName( QString const & name_ )
{
name = name_;
}
bool operator==( InternalPlayerBackend const & other ) const
{
return name == other.name;
}
bool operator!=( InternalPlayerBackend const & other ) const
{
return !operator==( other );
}
private:
#ifdef MAKE_FFMPEG_PLAYER
static InternalPlayerBackend ffmpeg()
{
return InternalPlayerBackend( "FFmpeg" );
}
#endif
#ifdef MAKE_QTMULTIMEDIA_PLAYER
static InternalPlayerBackend qtmultimedia()
{
return InternalPlayerBackend( "Qt Multimedia" );
}
#endif
explicit InternalPlayerBackend( QString const & name_ ):
name( name_ )
{
}
QString name;
};

View file

@ -119,6 +119,57 @@ QKeySequence HotKey::toKeySequence() const
; ;
} }
bool InternalPlayerBackend::anyAvailable()
{
#if defined( MAKE_FFMPEG_PLAYER ) || defined( MAKE_QTMULTIMEDIA_PLAYER )
return true;
#else
return false;
#endif
}
InternalPlayerBackend InternalPlayerBackend::defaultBackend()
{
#if defined( MAKE_FFMPEG_PLAYER )
return ffmpeg();
#elif defined( MAKE_QTMULTIMEDIA_PLAYER )
return qtmultimedia();
#else
return InternalPlayerBackend( QString() );
#endif
}
QStringList InternalPlayerBackend::nameList()
{
QStringList result;
#ifdef MAKE_FFMPEG_PLAYER
result.push_back( ffmpeg().uiName() );
#endif
#ifdef MAKE_QTMULTIMEDIA_PLAYER
result.push_back( qtmultimedia().uiName() );
#endif
return result;
}
bool InternalPlayerBackend::isFfmpeg() const
{
#ifdef MAKE_FFMPEG_PLAYER
return *this == ffmpeg();
#else
return false;
#endif
}
bool InternalPlayerBackend::isQtmultimedia() const
{
#ifdef MAKE_QTMULTIMEDIA_PLAYER
return *this == qtmultimedia();
#else
return false;
#endif
}
QString Preferences::sanitizeInputPhrase( QString const & inputWord ) const QString Preferences::sanitizeInputPhrase( QString const & inputWord ) const
{ {
QString result = inputWord; QString result = inputWord;

View file

@ -3,20 +3,19 @@
#pragma once #pragma once
#include "audio/internalplayerbackend.hh"
#include "ex.hh"
#include <QDateTime>
#include <QDomDocument>
#include <QKeySequence>
#include <QList>
#include <QLocale>
#include <QMetaType>
#include <QObject> #include <QObject>
#include <QSet> #include <QList>
#include <QSize>
#include <QString> #include <QString>
#include <QThread> #include <QSize>
#include <QDateTime>
#include <QKeySequence>
#include <QSet>
#include <QMetaType>
#include "ex.hh"
#include <QDomDocument>
#include <QLocale>
#include <optional> #include <optional>
#include <QThread>
/// Special group IDs /// Special group IDs
enum GroupId : unsigned { enum GroupId : unsigned {
@ -270,6 +269,66 @@ struct CustomFonts
} }
}; };
/// This class encapsulates supported backend preprocessor logic,
/// discourages duplicating backend names in code, which is error-prone.
class InternalPlayerBackend
{
public:
/// Returns true if at least one backend is available.
static bool anyAvailable();
/// Returns the default backend or null backend if none is available.
static InternalPlayerBackend defaultBackend();
/// Returns the name list of supported backends.
static QStringList nameList();
/// Returns true if built with FFmpeg player support and the name matches.
bool isFfmpeg() const;
/// Returns true if built with Qt Multimedia player support and the name matches.
bool isQtmultimedia() const;
QString const & uiName() const
{
return name;
}
void setUiName( QString const & name_ )
{
name = name_;
}
bool operator==( InternalPlayerBackend const & other ) const
{
return name == other.name;
}
bool operator!=( InternalPlayerBackend const & other ) const
{
return !operator==( other );
}
private:
#ifdef MAKE_FFMPEG_PLAYER
static InternalPlayerBackend ffmpeg()
{
return InternalPlayerBackend( "FFmpeg" );
}
#endif
#ifdef MAKE_QTMULTIMEDIA_PLAYER
static InternalPlayerBackend qtmultimedia()
{
return InternalPlayerBackend( "Qt Multimedia" );
}
#endif
explicit InternalPlayerBackend( QString const & name_ ):
name( name_ )
{
}
QString name;
};
/// Various user preferences /// Various user preferences
struct Preferences struct Preferences
{ {

View file

@ -167,8 +167,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
cfg.preferences.disallowContentFromOtherSites, cfg.preferences.disallowContentFromOtherSites,
cfg.preferences.hideGoldenDictHeader ), cfg.preferences.hideGoldenDictHeader ),
dictNetMgr( this ), dictNetMgr( this ),
audioPlayerFactory( audioPlayerFactory( cfg.preferences ),
cfg.preferences.useInternalPlayer, cfg.preferences.internalPlayerBackend, cfg.preferences.audioPlaybackProgram ),
wordFinder( this ), wordFinder( this ),
wordListSelChanged( false ), wordListSelChanged( false ),
wasMaximized( false ), wasMaximized( false ),
@ -2357,9 +2356,7 @@ void MainWindow::editPreferences()
#endif #endif
} }
audioPlayerFactory.setPreferences( cfg.preferences.useInternalPlayer, audioPlayerFactory.setPreferences( cfg.preferences );
cfg.preferences.internalPlayerBackend,
cfg.preferences.audioPlaybackProgram );
trayIconUpdateOrInit(); trayIconUpdateOrInit();
applyProxySettings(); applyProxySettings();

View file

@ -295,7 +295,7 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ):
ui.pronounceOnLoadMain->setChecked( p.pronounceOnLoadMain ); ui.pronounceOnLoadMain->setChecked( p.pronounceOnLoadMain );
ui.pronounceOnLoadPopup->setChecked( p.pronounceOnLoadPopup ); ui.pronounceOnLoadPopup->setChecked( p.pronounceOnLoadPopup );
ui.internalPlayerBackend->addItems( InternalPlayerBackend::nameList() ); ui.internalPlayerBackend->addItems( Config::InternalPlayerBackend::nameList() );
// Make sure that exactly one radio button in the group is checked and that // Make sure that exactly one radio button in the group is checked and that
// on_useExternalPlayer_toggled() is called. // on_useExternalPlayer_toggled() is called.
@ -307,7 +307,7 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ):
int index = ui.internalPlayerBackend->findText( p.internalPlayerBackend.uiName() ); int index = ui.internalPlayerBackend->findText( p.internalPlayerBackend.uiName() );
if ( index < 0 ) { // The specified backend is unavailable. if ( index < 0 ) { // The specified backend is unavailable.
index = ui.internalPlayerBackend->findText( InternalPlayerBackend::defaultBackend().uiName() ); index = ui.internalPlayerBackend->findText( Config::InternalPlayerBackend::defaultBackend().uiName() );
} }
Q_ASSERT( index >= 0 && "Logic error: the default backend must be present in the backend name list." ); Q_ASSERT( index >= 0 && "Logic error: the default backend must be present in the backend name list." );
ui.internalPlayerBackend->setCurrentIndex( index ); ui.internalPlayerBackend->setCurrentIndex( index );