diff --git a/goldendict.pro b/goldendict.pro index 7600ed97..fbcf7fb6 100644 --- a/goldendict.pro +++ b/goldendict.pro @@ -369,6 +369,7 @@ HEADERS += \ src/metadata.hh \ src/multimediaaudioplayer.hh \ src/parsecmdline.hh \ + src/pronounceengine.hh \ src/resourceschemehandler.hh \ src/splitfile.hh \ src/termination.hh \ @@ -492,6 +493,7 @@ SOURCES += \ src/metadata.cc \ src/multimediaaudioplayer.cc \ src/parsecmdline.cc \ + src/pronounceengine.cc \ src/resourceschemehandler.cc \ src/splitfile.cc \ src/termination.cc \ diff --git a/src/audiolink.cc b/src/audiolink.cc index 480d41be..0d1b0339 100644 --- a/src/audiolink.cc +++ b/src/audiolink.cc @@ -2,13 +2,17 @@ * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ #include "audiolink.hh" +#include "globalbroadcaster.hh" std::string addAudioLink( std::string const & url, std::string const & dictionaryId ) { - return std::string( "" ); + if ( url.empty() || url.length() < 2 ) + return {}; + GlobalBroadcaster::instance()->pronounce_engine.sendAudio( + QString::fromStdString( url.substr( 1, url.length() - 2 ) ) ); + + return std::string( "" ); } std::string makeAudioLinkScript( std::string const & url, @@ -18,9 +22,7 @@ std::string makeAudioLinkScript( std::string const & url, std::string ref; bool escaped = false; - for( unsigned x = 0; x < url.size(); x++ ) - { - char ch = url[ x ]; + for ( const char ch : url ) { if( escaped ) { ref += ch; @@ -33,7 +35,13 @@ std::string makeAudioLinkScript( std::string const & url, escaped = ( ch == '\\' ); } - std::string audioLinkForDict = "gdAudioLinks['" + dictionaryId + "']"; - return "gdAudioLinks.first = gdAudioLinks.first || " + ref + ";" + - audioLinkForDict + " = " + audioLinkForDict + " || " + ref + ";"; + const std::string audioLinkForDict = QString::fromStdString( R"( +if(!gdAudioMap.has('%1')){ + gdAudioMap.set('%1',%2); +} +)" ).arg( + QString::fromStdString( dictionaryId ), + QString::fromStdString( url ) ).toStdString(); + return "gdAudioLinks.first = gdAudioLinks.first || " + ref + ";" + + audioLinkForDict ; } diff --git a/src/common/globalbroadcaster.hh b/src/common/globalbroadcaster.hh index 9ac7e6a7..4dfd7ba3 100644 --- a/src/common/globalbroadcaster.hh +++ b/src/common/globalbroadcaster.hh @@ -4,6 +4,7 @@ #include #include #include "config.hh" +#include "pronounceengine.hh" struct ActiveDictIds { @@ -17,10 +18,11 @@ struct ActiveDictIds } }; + class GlobalBroadcaster : public QObject { Q_OBJECT -private: + Config::Preferences * preference; QSet whitelist; @@ -37,7 +39,7 @@ public: QSet< QString > collapsedDicts; QMap< QString, QSet< QString > > folderFavoritesMap; QMap< unsigned, QString > groupFolderMap; - + PronounceEngine pronounce_engine; signals: void dictionaryChanges( ActiveDictIds ad ); diff --git a/src/pronounceengine.cc b/src/pronounceengine.cc new file mode 100644 index 00000000..e8a2c241 --- /dev/null +++ b/src/pronounceengine.cc @@ -0,0 +1,22 @@ +#include "pronounceengine.hh" + +PronounceEngine::PronounceEngine( QObject * parent ): + QObject{ parent } +{ +} + + +void PronounceEngine::reset() +{ + QMutexLocker _( &mutex ); + state = PronounceState::AVAILABLE; +} + +void PronounceEngine::sendAudio( QString audioLink ) +{ + QMutexLocker _( &mutex ); + if ( state == PronounceState::OCCUPIED ) + return; + state = PronounceState::OCCUPIED; + emit emitAudio( audioLink ); +} diff --git a/src/pronounceengine.hh b/src/pronounceengine.hh new file mode 100644 index 00000000..0db5b699 --- /dev/null +++ b/src/pronounceengine.hh @@ -0,0 +1,29 @@ +#ifndef PRONOUNCEENGINE_HH +#define PRONOUNCEENGINE_HH + +#include +#include +#include + + +enum class PronounceState { + AVAILABLE, + OCCUPIED +}; + +class PronounceEngine: public QObject +{ + Q_OBJECT + PronounceState state = PronounceState::AVAILABLE; + QMutex mutex; + +public: + explicit PronounceEngine( QObject * parent = nullptr ); + void reset(); + void sendAudio( QString audioLink ); + +signals: + void emitAudio( QString audioLink ); +}; + +#endif // PRONOUNCEENGINE_HH diff --git a/src/scripts/gd-builtin.js b/src/scripts/gd-builtin.js index 184ddc39..16f6ce19 100644 --- a/src/scripts/gd-builtin.js +++ b/src/scripts/gd-builtin.js @@ -4,6 +4,9 @@ var gdAudioLinks = { "current": null }; +//store dictionary audio link. +var gdAudioMap= new Map(); + function gdMakeArticleActive(newId,noEvent) { var gdCurrentArticle = $_$(".gdactivearticle").attr("id") if (gdCurrentArticle !== 'gdfrom-' + newId) { diff --git a/src/ui/articleview.cc b/src/ui/articleview.cc index 6252dc88..e0234eae 100644 --- a/src/ui/articleview.cc +++ b/src/ui/articleview.cc @@ -294,6 +294,7 @@ void ArticleView::showDefinition( QString const & word, unsigned group, QString const & scrollTo, Contexts const & contexts_ ) { + GlobalBroadcaster::instance()->pronounce_engine.reset(); currentWord = word.trimmed(); if( currentWord.isEmpty() ) return; @@ -1479,7 +1480,7 @@ void ArticleView::reload() { webview->reload(); } void ArticleView::hasSound( const std::function< void( bool ) > & callback ) { - webview->page()->runJavaScript( "if(typeof(gdAudioLinks)!=\"undefined\") gdAudioLinks.first", + webview->page()->runJavaScript( R"(if(typeof(gdAudioLinks)!="undefined") gdAudioLinks.first)", [ callback ]( const QVariant & v ) { bool has = false; if( v.type() == QVariant::String ) @@ -1491,11 +1492,11 @@ void ArticleView::hasSound( const std::function< void( bool ) > & callback ) //use webengine javascript to playsound void ArticleView::playSound() { - QString variable = " (function(){ var link=gdAudioLinks[gdAudioLinks.current]; " - " if(link==undefined){ " - " link=gdAudioLinks.first; " - " } " - " return link;})(); "; + QString variable = R"( (function(){ var link=gdAudioMap.get(gdAudioLinks.current); + if(link==undefined){ + link=gdAudioLinks.first; + } + return link;})(); )"; webview->page()->runJavaScript( variable, [ this ]( const QVariant & result ) { if( result.type() == QVariant::String ) { diff --git a/src/ui/mainwindow.cc b/src/ui/mainwindow.cc index 9a886afb..1aade01a 100644 --- a/src/ui/mainwindow.cc +++ b/src/ui/mainwindow.cc @@ -685,6 +685,15 @@ MainWindow::MainWindow( Config::Class & cfg_ ): this, &MainWindow::showFTSIndexingName ); + connect( &GlobalBroadcaster::instance()->pronounce_engine, + &PronounceEngine::emitAudio, + this, + [ this ]( auto audioUrl ) { + auto view = getCurrentArticleView(); + if ( cfg.preferences.pronounceOnLoadMain && view != nullptr ) { + view->openLink( QUrl::fromEncoded( audioUrl.toUtf8() ), {} ); + } + } ); applyProxySettings(); //set webengineview font @@ -1915,12 +1924,7 @@ void MainWindow::pageLoaded( ArticleView * view ) return; // It was background action updateBackForwardButtons(); - updatePronounceAvailability(); - - if ( cfg.preferences.pronounceOnLoadMain && view != nullptr ) { - view->playSound(); - } } void MainWindow::showStatusBarMessage( QString const & message, int timeout, QPixmap const & icon )