diff --git a/articleview.cc b/articleview.cc index 96e32df6..0eb1c7e9 100644 --- a/articleview.cc +++ b/articleview.cc @@ -13,6 +13,7 @@ #include #include "folding.hh" #include "wstring_qt.hh" +#include "webmultimediadownload.hh" #include @@ -390,7 +391,10 @@ bool ArticleView::isExternalLink( QUrl const & url ) void ArticleView::tryMangleWebsiteClickedUrl( QUrl & url, Contexts & contexts ) { - if( url.scheme() == "http" || url.scheme() == "https" ) + // Don't try mangling audio urls, even if they are from the framed websites + + if( ( url.scheme() == "http" || url.scheme() == "https" ) + && ! Dictionary::WebMultimediaDownload::isAudioUrl( url ) ) { // Maybe a link inside a website was clicked? @@ -598,7 +602,8 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref, getGroup( ref ), scrollTo, contexts ); } else - if ( url.scheme() == "bres" || url.scheme() == "gdau" ) + if ( url.scheme() == "bres" || url.scheme() == "gdau" || + Dictionary::WebMultimediaDownload::isAudioUrl( url ) ) { // Download it @@ -608,6 +613,17 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref, resourceDownloadUrl = url; + if ( Dictionary::WebMultimediaDownload::isAudioUrl( url ) ) + { + sptr< Dictionary::DataRequest > req = + new Dictionary::WebMultimediaDownload( url, articleNetMgr ); + + resourceDownloadRequests.push_back( req ); + + connect( req.get(), SIGNAL( finished() ), + this, SLOT( resourceDownloadFinished() ) ); + } + else if ( url.scheme() == "gdau" && url.host() == "search" ) { // Since searches should be limited to current group, we just do them @@ -975,7 +991,8 @@ void ArticleView::resourceDownloadFinished() vector< char > const & data = (*i)->getFullData(); - if ( resourceDownloadUrl.scheme() == "gdau" ) + if ( resourceDownloadUrl.scheme() == "gdau" || + Dictionary::WebMultimediaDownload::isAudioUrl( resourceDownloadUrl ) ) { // Audio data diff --git a/config.cc b/config.cc index d50a553b..410b6e0b 100644 --- a/config.cc +++ b/config.cc @@ -146,6 +146,7 @@ WebSites makeDefaultWebSites() { WebSites ws; + ws.push_back( WebSite( "b88cb2898e634c6638df618528284c2d", "Google En-En (Collins)", "http://www.google.com/dictionary?aq=f&langpair=en|en&q=%GDWORD%&hl=en", false ) ); ws.push_back( WebSite( "f376365a0de651fd7505e7e5e683aa45", "Urban Dictionary", "http://www.urbandictionary.com/define.php?term=%GDWORD%", false ) ); ws.push_back( WebSite( "324ca0306187df7511b26d3847f4b07c", "Multitran (En)", "http://multitran.ru/c/m.exe?CL=1&l1=1&s=%GD1251%", false ) ); ws.push_back( WebSite( "924db471b105299c82892067c0f10787", "Lingvo (En-Ru)", "http://www.abbyyonline.ru/translate.aspx?LingvoAction=translate&Ln=1&words=%GDWORD%", false ) ); diff --git a/goldendict.pro b/goldendict.pro index b6faa616..b2a3f949 100644 --- a/goldendict.pro +++ b/goldendict.pro @@ -140,7 +140,8 @@ HEADERS += folding.hh \ zipfile.hh \ indexedzip.hh \ termination.hh \ - greektranslit.hh + greektranslit.hh \ + webmultimediadownload.hh FORMS += groups.ui \ dictgroupwidget.ui \ mainwindow.ui \ @@ -218,7 +219,8 @@ SOURCES += folding.cc \ zipfile.cc \ indexedzip.cc \ termination.cc \ - greektranslit.cc + greektranslit.cc \ + webmultimediadownload.cc win32 { SOURCES += mouseover_win32/ThTypes.c HEADERS += mouseover_win32/ThTypes.h diff --git a/webmultimediadownload.cc b/webmultimediadownload.cc new file mode 100644 index 00000000..57f8ec83 --- /dev/null +++ b/webmultimediadownload.cc @@ -0,0 +1,52 @@ +#include "webmultimediadownload.hh" +#include "filetype.hh" + +namespace Dictionary { + +WebMultimediaDownload::WebMultimediaDownload( QUrl const & url, + QNetworkAccessManager & mgr ) +{ + connect( &mgr, SIGNAL(finished(QNetworkReply*)), + this, SLOT(replyFinished(QNetworkReply*)), Qt::QueuedConnection ); + + reply = mgr.get( QNetworkRequest( url ) ); +} + +void WebMultimediaDownload::cancel() +{ + reply.reset(); + + finish(); +} + +void WebMultimediaDownload::replyFinished( QNetworkReply * r ) +{ + if ( r != reply.get() ) + return; // Not our reply + + if ( reply->error() == QNetworkReply::NoError ) + { + QByteArray all = reply->readAll(); + + Mutex::Lock _( dataMutex ); + + data.resize( all.size() ); + + memcpy( data.data(), all.data(), all.size() ); + + hasAnyData = true; + } + else + setErrorString( reply->errorString() ); + + finish(); + + reply.reset(); +} + +bool WebMultimediaDownload::isAudioUrl( QUrl const & url ) +{ + return url.scheme() == "http" && Filetype::isNameOfSound( url.path().toUtf8().data() ); +} + +} diff --git a/webmultimediadownload.hh b/webmultimediadownload.hh new file mode 100644 index 00000000..e70bafa8 --- /dev/null +++ b/webmultimediadownload.hh @@ -0,0 +1,33 @@ +#ifndef WEBMULTIMEDIADOWNLOAD_HH +#define WEBMULTIMEDIADOWNLOAD_HH + +#include "dictionary.hh" +#include + +namespace Dictionary { + +/// Downloads data from the web, wrapped as a dictionary's DataRequest. This +/// is useful for multimedia files, like sounds and pronunciations. +class WebMultimediaDownload: public DataRequest +{ + Q_OBJECT + + sptr< QNetworkReply > reply; + +public: + + WebMultimediaDownload( QUrl const &, QNetworkAccessManager & ); + + /// Checks if the given url is an http request for an audio file. + static bool isAudioUrl( QUrl const & ); + + virtual void cancel(); + +private slots: + + void replyFinished( QNetworkReply * ); +}; + +} + +#endif // WEBMULTIMEDIADOWNLOAD_HH