mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 19:24:08 +00:00
opt: pronounce audio rewrite (#922)
* opt: pronounce audio rewrite
* 🎨 apply clang-format changes
* fix:use javscript Map to hold the dictionary audio url
* Update mainwindow.cc
---------
Co-authored-by: xiaoyifang <xiaoyifang@users.noreply.github.com>
This commit is contained in:
parent
2b1d91638e
commit
2ed7990531
|
@ -369,6 +369,7 @@ HEADERS += \
|
||||||
src/metadata.hh \
|
src/metadata.hh \
|
||||||
src/multimediaaudioplayer.hh \
|
src/multimediaaudioplayer.hh \
|
||||||
src/parsecmdline.hh \
|
src/parsecmdline.hh \
|
||||||
|
src/pronounceengine.hh \
|
||||||
src/resourceschemehandler.hh \
|
src/resourceschemehandler.hh \
|
||||||
src/splitfile.hh \
|
src/splitfile.hh \
|
||||||
src/termination.hh \
|
src/termination.hh \
|
||||||
|
@ -492,6 +493,7 @@ SOURCES += \
|
||||||
src/metadata.cc \
|
src/metadata.cc \
|
||||||
src/multimediaaudioplayer.cc \
|
src/multimediaaudioplayer.cc \
|
||||||
src/parsecmdline.cc \
|
src/parsecmdline.cc \
|
||||||
|
src/pronounceengine.cc \
|
||||||
src/resourceschemehandler.cc \
|
src/resourceschemehandler.cc \
|
||||||
src/splitfile.cc \
|
src/splitfile.cc \
|
||||||
src/termination.cc \
|
src/termination.cc \
|
||||||
|
|
|
@ -2,13 +2,17 @@
|
||||||
* 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 "audiolink.hh"
|
#include "audiolink.hh"
|
||||||
|
#include "globalbroadcaster.hh"
|
||||||
|
|
||||||
std::string addAudioLink( std::string const & url,
|
std::string addAudioLink( std::string const & url,
|
||||||
std::string const & dictionaryId )
|
std::string const & dictionaryId )
|
||||||
{
|
{
|
||||||
return std::string( "<script type=\"text/javascript\">" +
|
if ( url.empty() || url.length() < 2 )
|
||||||
makeAudioLinkScript( url, dictionaryId ) +
|
return {};
|
||||||
"</script>" );
|
GlobalBroadcaster::instance()->pronounce_engine.sendAudio(
|
||||||
|
QString::fromStdString( url.substr( 1, url.length() - 2 ) ) );
|
||||||
|
|
||||||
|
return std::string( "<script type=\"text/javascript\">" + makeAudioLinkScript( url, dictionaryId ) + "</script>" );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string makeAudioLinkScript( std::string const & url,
|
std::string makeAudioLinkScript( std::string const & url,
|
||||||
|
@ -18,9 +22,7 @@ std::string makeAudioLinkScript( std::string const & url,
|
||||||
|
|
||||||
std::string ref;
|
std::string ref;
|
||||||
bool escaped = false;
|
bool escaped = false;
|
||||||
for( unsigned x = 0; x < url.size(); x++ )
|
for ( const char ch : url ) {
|
||||||
{
|
|
||||||
char ch = url[ x ];
|
|
||||||
if( escaped )
|
if( escaped )
|
||||||
{
|
{
|
||||||
ref += ch;
|
ref += ch;
|
||||||
|
@ -33,7 +35,13 @@ std::string makeAudioLinkScript( std::string const & url,
|
||||||
escaped = ( ch == '\\' );
|
escaped = ( ch == '\\' );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string audioLinkForDict = "gdAudioLinks['" + dictionaryId + "']";
|
const std::string audioLinkForDict = QString::fromStdString( R"(
|
||||||
return "gdAudioLinks.first = gdAudioLinks.first || " + ref + ";" +
|
if(!gdAudioMap.has('%1')){
|
||||||
audioLinkForDict + " = " + audioLinkForDict + " || " + ref + ";";
|
gdAudioMap.set('%1',%2);
|
||||||
|
}
|
||||||
|
)" ).arg(
|
||||||
|
QString::fromStdString( dictionaryId ),
|
||||||
|
QString::fromStdString( url ) ).toStdString();
|
||||||
|
return "gdAudioLinks.first = gdAudioLinks.first || " + ref + ";" +
|
||||||
|
audioLinkForDict ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "config.hh"
|
#include "config.hh"
|
||||||
|
#include "pronounceengine.hh"
|
||||||
|
|
||||||
struct ActiveDictIds
|
struct ActiveDictIds
|
||||||
{
|
{
|
||||||
|
@ -17,10 +18,11 @@ struct ActiveDictIds
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class GlobalBroadcaster : public QObject
|
class GlobalBroadcaster : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
|
||||||
Config::Preferences * preference;
|
Config::Preferences * preference;
|
||||||
QSet<QString> whitelist;
|
QSet<QString> whitelist;
|
||||||
|
|
||||||
|
@ -37,7 +39,7 @@ public:
|
||||||
QSet< QString > collapsedDicts;
|
QSet< QString > collapsedDicts;
|
||||||
QMap< QString, QSet< QString > > folderFavoritesMap;
|
QMap< QString, QSet< QString > > folderFavoritesMap;
|
||||||
QMap< unsigned, QString > groupFolderMap;
|
QMap< unsigned, QString > groupFolderMap;
|
||||||
|
PronounceEngine pronounce_engine;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void dictionaryChanges( ActiveDictIds ad );
|
void dictionaryChanges( ActiveDictIds ad );
|
||||||
|
|
22
src/pronounceengine.cc
Normal file
22
src/pronounceengine.cc
Normal file
|
@ -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 );
|
||||||
|
}
|
29
src/pronounceengine.hh
Normal file
29
src/pronounceengine.hh
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef PRONOUNCEENGINE_HH
|
||||||
|
#define PRONOUNCEENGINE_HH
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
|
|
||||||
|
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
|
|
@ -4,6 +4,9 @@ var gdAudioLinks = {
|
||||||
"current": null
|
"current": null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//store dictionary audio link.
|
||||||
|
var gdAudioMap= new Map();
|
||||||
|
|
||||||
function gdMakeArticleActive(newId,noEvent) {
|
function gdMakeArticleActive(newId,noEvent) {
|
||||||
var gdCurrentArticle = $_$(".gdactivearticle").attr("id")
|
var gdCurrentArticle = $_$(".gdactivearticle").attr("id")
|
||||||
if (gdCurrentArticle !== 'gdfrom-' + newId) {
|
if (gdCurrentArticle !== 'gdfrom-' + newId) {
|
||||||
|
|
|
@ -294,6 +294,7 @@ void ArticleView::showDefinition( QString const & word, unsigned group,
|
||||||
QString const & scrollTo,
|
QString const & scrollTo,
|
||||||
Contexts const & contexts_ )
|
Contexts const & contexts_ )
|
||||||
{
|
{
|
||||||
|
GlobalBroadcaster::instance()->pronounce_engine.reset();
|
||||||
currentWord = word.trimmed();
|
currentWord = word.trimmed();
|
||||||
if( currentWord.isEmpty() )
|
if( currentWord.isEmpty() )
|
||||||
return;
|
return;
|
||||||
|
@ -1479,7 +1480,7 @@ void ArticleView::reload() { webview->reload(); }
|
||||||
|
|
||||||
void ArticleView::hasSound( const std::function< void( bool ) > & callback )
|
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 ) {
|
[ callback ]( const QVariant & v ) {
|
||||||
bool has = false;
|
bool has = false;
|
||||||
if( v.type() == QVariant::String )
|
if( v.type() == QVariant::String )
|
||||||
|
@ -1491,11 +1492,11 @@ void ArticleView::hasSound( const std::function< void( bool ) > & callback )
|
||||||
//use webengine javascript to playsound
|
//use webengine javascript to playsound
|
||||||
void ArticleView::playSound()
|
void ArticleView::playSound()
|
||||||
{
|
{
|
||||||
QString variable = " (function(){ var link=gdAudioLinks[gdAudioLinks.current]; "
|
QString variable = R"( (function(){ var link=gdAudioMap.get(gdAudioLinks.current);
|
||||||
" if(link==undefined){ "
|
if(link==undefined){
|
||||||
" link=gdAudioLinks.first; "
|
link=gdAudioLinks.first;
|
||||||
" } "
|
}
|
||||||
" return link;})(); ";
|
return link;})(); )";
|
||||||
|
|
||||||
webview->page()->runJavaScript( variable, [ this ]( const QVariant & result ) {
|
webview->page()->runJavaScript( variable, [ this ]( const QVariant & result ) {
|
||||||
if( result.type() == QVariant::String ) {
|
if( result.type() == QVariant::String ) {
|
||||||
|
|
|
@ -685,6 +685,15 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
||||||
this,
|
this,
|
||||||
&MainWindow::showFTSIndexingName );
|
&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();
|
applyProxySettings();
|
||||||
|
|
||||||
//set webengineview font
|
//set webengineview font
|
||||||
|
@ -1915,12 +1924,7 @@ void MainWindow::pageLoaded( ArticleView * view )
|
||||||
return; // It was background action
|
return; // It was background action
|
||||||
|
|
||||||
updateBackForwardButtons();
|
updateBackForwardButtons();
|
||||||
|
|
||||||
updatePronounceAvailability();
|
updatePronounceAvailability();
|
||||||
|
|
||||||
if ( cfg.preferences.pronounceOnLoadMain && view != nullptr ) {
|
|
||||||
view->playSound();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::showStatusBarMessage( QString const & message, int timeout, QPixmap const & icon )
|
void MainWindow::showStatusBarMessage( QString const & message, int timeout, QPixmap const & icon )
|
||||||
|
|
Loading…
Reference in a new issue