mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 15:24:05 +00:00
Support for Forvo online pronunciations added.
This commit is contained in:
parent
c33fa2c9cc
commit
9e43f86feb
|
@ -338,6 +338,47 @@ div.sdct_x
|
|||
clear:both;
|
||||
}
|
||||
|
||||
/************* Forvo **************/
|
||||
|
||||
.forvo_headword
|
||||
{
|
||||
margin-top: 15px;
|
||||
margin-bottom: 10px;
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
/* A table which contains a play icon and information about the sound */
|
||||
.forvo_play
|
||||
{
|
||||
margin-top: 8px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.forvo_user
|
||||
{
|
||||
text-decoration: none;
|
||||
color: green;
|
||||
}
|
||||
|
||||
.forvo_location
|
||||
{
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.forvo_positive_votes
|
||||
{
|
||||
font-weight: bold;
|
||||
color: green;
|
||||
}
|
||||
|
||||
.forvo_negative_votes
|
||||
{
|
||||
font-weight: bold;
|
||||
color: red;
|
||||
}
|
||||
|
||||
|
||||
/************* MediaWiki articles *****************
|
||||
The following consist of excerpts from different .css files edited
|
||||
with a .mwiki prepended to each record.
|
||||
|
|
32
config.cc
32
config.cc
|
@ -433,6 +433,19 @@ Class load() throw( exError )
|
|||
}
|
||||
}
|
||||
|
||||
QDomNode forvo = root.namedItem( "forvo" );
|
||||
|
||||
if ( !forvo.isNull() )
|
||||
{
|
||||
applyBoolOption( c.forvo.enable,
|
||||
forvo.namedItem( "enable" ) );
|
||||
|
||||
c.forvo.apiKey = forvo.namedItem( "apiKey" ).toElement().text();
|
||||
c.forvo.languageCodes = forvo.namedItem( "languageCodes" ).toElement().text();
|
||||
}
|
||||
else
|
||||
c.forvo.languageCodes = "en, ru"; // Default demo values
|
||||
|
||||
QDomNode mws = root.namedItem( "mediawikis" );
|
||||
|
||||
if ( !mws.isNull() )
|
||||
|
@ -783,6 +796,25 @@ void save( Class const & c ) throw( exError )
|
|||
romaji.appendChild( opt );
|
||||
}
|
||||
|
||||
{
|
||||
// Forvo
|
||||
|
||||
QDomElement forvo = dd.createElement( "forvo" );
|
||||
root.appendChild( forvo );
|
||||
|
||||
QDomElement opt = dd.createElement( "enable" );
|
||||
opt.appendChild( dd.createTextNode( c.forvo.enable ? "1":"0" ) );
|
||||
forvo.appendChild( opt );
|
||||
|
||||
opt = dd.createElement( "apiKey" );
|
||||
opt.appendChild( dd.createTextNode( c.forvo.apiKey ) );
|
||||
forvo.appendChild( opt );
|
||||
|
||||
opt = dd.createElement( "languageCodes" );
|
||||
opt.appendChild( dd.createTextNode( c.forvo.languageCodes ) );
|
||||
forvo.appendChild( opt );
|
||||
}
|
||||
|
||||
{
|
||||
QDomElement mws = dd.createElement( "mediawikis" );
|
||||
root.appendChild( mws );
|
||||
|
|
20
config.hh
20
config.hh
|
@ -278,6 +278,25 @@ struct Transliteration
|
|||
{}
|
||||
};
|
||||
|
||||
struct Forvo
|
||||
{
|
||||
bool enable;
|
||||
QString apiKey;
|
||||
QString languageCodes;
|
||||
|
||||
Forvo(): enable( false )
|
||||
{}
|
||||
|
||||
bool operator == ( Forvo const & other ) const
|
||||
{ return enable == other.enable &&
|
||||
apiKey == other.apiKey &&
|
||||
languageCodes == other.languageCodes;
|
||||
}
|
||||
|
||||
bool operator != ( Forvo const & other ) const
|
||||
{ return ! operator == ( other ); }
|
||||
};
|
||||
|
||||
/// Dictionaries which are temporarily disabled via the dictionary bar.
|
||||
typedef QSet< QString > MutedDictionaries;
|
||||
|
||||
|
@ -293,6 +312,7 @@ struct Class
|
|||
WebSites webSites;
|
||||
Hunspell hunspell;
|
||||
Transliteration transliteration;
|
||||
Forvo forvo;
|
||||
|
||||
unsigned lastMainGroupId; // Last used group in main window
|
||||
unsigned lastPopupGroupId; // Last used group in popup window
|
||||
|
|
298
country.cc
Normal file
298
country.cc
Normal file
|
@ -0,0 +1,298 @@
|
|||
/* This file is (c) 2008-2010 Konstantin Isakov <ikm@users.berlios.de>
|
||||
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
|
||||
|
||||
#include "country.hh"
|
||||
#include "folding.hh"
|
||||
#include <QtCore>
|
||||
#include "wstring_qt.hh"
|
||||
|
||||
namespace Country {
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Database: public QMap< QString, QString >
|
||||
{
|
||||
static Database const & instance()
|
||||
{ static Database db; return db; }
|
||||
|
||||
private:
|
||||
|
||||
Database();
|
||||
|
||||
void addCountry( QString const & country, QString const & code )
|
||||
{
|
||||
(*this)[ gd::toQString( Folding::apply( gd::toWString( country ) ) ) ] = code.toLower();
|
||||
}
|
||||
};
|
||||
|
||||
Database::Database()
|
||||
{
|
||||
addCountry( "Afghanistan", "AF" );
|
||||
addCountry( "Aland Islands", "AX" );
|
||||
addCountry( "Albania", "AL" );
|
||||
addCountry( "Algeria", "DZ" );
|
||||
addCountry( "American Samoa", "AS" );
|
||||
addCountry( "Andorra", "AD" );
|
||||
addCountry( "Angola", "AO" );
|
||||
addCountry( "Anguilla", "AI" );
|
||||
addCountry( "Antarctica", "AQ" );
|
||||
addCountry( "Antigua and Barbuda", "AG" );
|
||||
addCountry( "Argentina", "AR" );
|
||||
addCountry( "Armenia", "AM" );
|
||||
addCountry( "Aruba", "AW" );
|
||||
addCountry( "Australia", "AU" );
|
||||
addCountry( "Austria", "AT" );
|
||||
addCountry( "Azerbaijan", "AZ" );
|
||||
addCountry( "Bahamas", "BS" );
|
||||
addCountry( "Bahrain", "BH" );
|
||||
addCountry( "Bangladesh", "BD" );
|
||||
addCountry( "Barbados", "BB" );
|
||||
addCountry( "Belarus", "BY" );
|
||||
addCountry( "Belgium", "BE" );
|
||||
addCountry( "Belize", "BZ" );
|
||||
addCountry( "Benin", "BJ" );
|
||||
addCountry( "Bermuda", "BM" );
|
||||
addCountry( "Bhutan", "BT" );
|
||||
addCountry( "Bolivia, Plurinational State of", "BO" );
|
||||
addCountry( "Bolivia", "BO" );
|
||||
addCountry( "Bosnia and Herzegovina", "BA" );
|
||||
addCountry( "Botswana", "BW" );
|
||||
addCountry( "Bouvet Island", "BV" );
|
||||
addCountry( "Brazil", "BR" );
|
||||
addCountry( "British Indian Ocean Territory", "IO" );
|
||||
addCountry( "Brunei Darussalam", "BN" );
|
||||
addCountry( "Bulgaria", "BG" );
|
||||
addCountry( "Burkina Faso", "BF" );
|
||||
addCountry( "Burundi", "BI" );
|
||||
addCountry( "Cambodia", "KH" );
|
||||
addCountry( "Cameroon", "CM" );
|
||||
addCountry( "Canada", "CA" );
|
||||
addCountry( "Cape Verde", "CV" );
|
||||
addCountry( "Cayman Islands", "KY" );
|
||||
addCountry( "Central African Republic", "CF" );
|
||||
addCountry( "Chad", "TD" );
|
||||
addCountry( "Chile", "CL" );
|
||||
addCountry( "China", "CN" );
|
||||
addCountry( "Christmas Island", "CX" );
|
||||
addCountry( "Cocos (Keeling) Islands", "CC" );
|
||||
addCountry( "Colombia", "CO" );
|
||||
addCountry( "Comoros", "KM" );
|
||||
addCountry( "Congo", "CG" );
|
||||
addCountry( "Congo, the Democratic Republic of the", "CD" );
|
||||
addCountry( "Cook Islands", "CK" );
|
||||
addCountry( "Costa Rica", "CR" );
|
||||
addCountry( "Cote d'Ivoire", "CI" );
|
||||
addCountry( "Croatia", "HR" );
|
||||
addCountry( "Cuba", "CU" );
|
||||
addCountry( "Cyprus", "CY" );
|
||||
addCountry( "Czech Republic", "CZ" );
|
||||
addCountry( "Denmark", "DK" );
|
||||
addCountry( "Djibouti", "DJ" );
|
||||
addCountry( "Dominica", "DM" );
|
||||
addCountry( "Dominican Republic", "DO" );
|
||||
addCountry( "Ecuador", "EC" );
|
||||
addCountry( "Egypt", "EG" );
|
||||
addCountry( "El Salvador", "SV" );
|
||||
addCountry( "Equatorial Guinea", "GQ" );
|
||||
addCountry( "Eritrea", "ER" );
|
||||
addCountry( "Estonia", "EE" );
|
||||
addCountry( "Ethiopia", "ET" );
|
||||
addCountry( "Falkland Islands (Malvinas)", "FK" );
|
||||
addCountry( "Faroe Islands", "FO" );
|
||||
addCountry( "Fiji", "FJ" );
|
||||
addCountry( "Finland", "FI" );
|
||||
addCountry( "France", "FR" );
|
||||
addCountry( "French Guiana", "GF" );
|
||||
addCountry( "French Polynesia", "PF" );
|
||||
addCountry( "French Southern Territories", "TF" );
|
||||
addCountry( "Gabon", "GA" );
|
||||
addCountry( "Gambia", "GM" );
|
||||
addCountry( "Georgia", "GE" );
|
||||
addCountry( "Germany", "DE" );
|
||||
addCountry( "Ghana", "GH" );
|
||||
addCountry( "Gibraltar", "GI" );
|
||||
addCountry( "Greece", "GR" );
|
||||
addCountry( "Greenland", "GL" );
|
||||
addCountry( "Grenada", "GD" );
|
||||
addCountry( "Guadeloupe", "GP" );
|
||||
addCountry( "Guam", "GU" );
|
||||
addCountry( "Guatemala", "GT" );
|
||||
addCountry( "Guernsey", "GG" );
|
||||
addCountry( "Guinea", "GN" );
|
||||
addCountry( "Guinea-Bissau", "GW" );
|
||||
addCountry( "Guyana", "GY" );
|
||||
addCountry( "Haiti", "HT" );
|
||||
addCountry( "Heard Island and McDonald Islands", "HM" );
|
||||
addCountry( "Holy See (Vatican City State)", "VA" );
|
||||
addCountry( "Honduras", "HN" );
|
||||
addCountry( "Hong Kong", "HK" );
|
||||
addCountry( "Hungary", "HU" );
|
||||
addCountry( "Iceland", "IS" );
|
||||
addCountry( "India", "IN" );
|
||||
addCountry( "Indonesia", "ID" );
|
||||
addCountry( "Iran, Islamic Republic of", "IR" );
|
||||
addCountry( "Iran", "IR" );
|
||||
addCountry( "Iraq", "IQ" );
|
||||
addCountry( "Ireland", "IE" );
|
||||
addCountry( "Isle of Man", "IM" );
|
||||
addCountry( "Israel", "IL" );
|
||||
addCountry( "Italy", "IT" );
|
||||
addCountry( "Jamaica", "JM" );
|
||||
addCountry( "Japan", "JP" );
|
||||
addCountry( "Jersey", "JE" );
|
||||
addCountry( "Jordan", "JO" );
|
||||
addCountry( "Kazakhstan", "KZ" );
|
||||
addCountry( "Kenya", "KE" );
|
||||
addCountry( "Kiribati", "KI" );
|
||||
addCountry( "Korea, Democratic People's Republic of", "KP" );
|
||||
addCountry( "Korea, Republic of", "KR" );
|
||||
addCountry( "Korea", "KR" );
|
||||
addCountry( "Kuwait", "KW" );
|
||||
addCountry( "Kyrgyzstan", "KG" );
|
||||
addCountry( "Lao People's Democratic Republic", "LA" );
|
||||
addCountry( "Latvia", "LV" );
|
||||
addCountry( "Lebanon", "LB" );
|
||||
addCountry( "Lesotho", "LS" );
|
||||
addCountry( "Liberia", "LR" );
|
||||
addCountry( "Libyan Arab Jamahiriya", "LY" );
|
||||
addCountry( "Liechtenstein", "LI" );
|
||||
addCountry( "Lithuania", "LT" );
|
||||
addCountry( "Luxembourg", "LU" );
|
||||
addCountry( "Macao", "MO" );
|
||||
addCountry( "Macedonia, the former Yugoslav Republic of", "MK" );
|
||||
addCountry( "Macedonia", "MK" );
|
||||
addCountry( "Madagascar", "MG" );
|
||||
addCountry( "Malawi", "MW" );
|
||||
addCountry( "Malaysia", "MY" );
|
||||
addCountry( "Maldives", "MV" );
|
||||
addCountry( "Mali", "ML" );
|
||||
addCountry( "Malta", "MT" );
|
||||
addCountry( "Marshall Islands", "MH" );
|
||||
addCountry( "Martinique", "MQ" );
|
||||
addCountry( "Mauritania", "MR" );
|
||||
addCountry( "Mauritius", "MU" );
|
||||
addCountry( "Mayotte", "YT" );
|
||||
addCountry( "Mexico", "MX" );
|
||||
addCountry( "Micronesia, Federated States of", "FM" );
|
||||
addCountry( "Micronesia", "FM" );
|
||||
addCountry( "Moldova, Republic of", "MD" );
|
||||
addCountry( "Moldova", "MD" );
|
||||
addCountry( "Monaco", "MC" );
|
||||
addCountry( "Mongolia", "MN" );
|
||||
addCountry( "Montenegro", "ME" );
|
||||
addCountry( "Montserrat", "MS" );
|
||||
addCountry( "Morocco", "MA" );
|
||||
addCountry( "Mozambique", "MZ" );
|
||||
addCountry( "Myanmar", "MM" );
|
||||
addCountry( "Namibia", "NA" );
|
||||
addCountry( "Nauru", "NR" );
|
||||
addCountry( "Nepal", "NP" );
|
||||
addCountry( "Netherlands", "NL" );
|
||||
addCountry( "Netherlands Antilles", "AN" );
|
||||
addCountry( "New Caledonia", "NC" );
|
||||
addCountry( "New Zealand", "NZ" );
|
||||
addCountry( "Nicaragua", "NI" );
|
||||
addCountry( "Niger", "NE" );
|
||||
addCountry( "Nigeria", "NG" );
|
||||
addCountry( "Niue", "NU" );
|
||||
addCountry( "Norfolk Island", "NF" );
|
||||
addCountry( "Northern Mariana Islands", "MP" );
|
||||
addCountry( "Norway", "NO" );
|
||||
addCountry( "Oman", "OM" );
|
||||
addCountry( "Pakistan", "PK" );
|
||||
addCountry( "Palau", "PW" );
|
||||
addCountry( "Palestinian Territory, Occupied", "PS" );
|
||||
addCountry( "Panama", "PA" );
|
||||
addCountry( "Papua New Guinea", "PG" );
|
||||
addCountry( "Paraguay", "PY" );
|
||||
addCountry( "Peru", "PE" );
|
||||
addCountry( "Philippines", "PH" );
|
||||
addCountry( "Pitcairn", "PN" );
|
||||
addCountry( "Poland", "PL" );
|
||||
addCountry( "Portugal", "PT" );
|
||||
addCountry( "Puerto Rico", "PR" );
|
||||
addCountry( "Qatar", "QA" );
|
||||
addCountry( "Reunion", "RE" );
|
||||
addCountry( "Romania", "RO" );
|
||||
addCountry( "Russian Federation", "RU" );
|
||||
addCountry( "Russia", "RU" );
|
||||
addCountry( "Rwanda", "RW" );
|
||||
addCountry( "Saint Barthélemy", "BL" );
|
||||
addCountry( "Saint Helena, Ascension and Tristan da Cunha", "SH" );
|
||||
addCountry( "Saint Kitts and Nevis", "KN" );
|
||||
addCountry( "Saint Lucia", "LC" );
|
||||
addCountry( "Saint Martin (French part)", "MF" );
|
||||
addCountry( "Saint Pierre and Miquelon", "PM" );
|
||||
addCountry( "Saint Vincent and the Grenadines", "VC" );
|
||||
addCountry( "Samoa", "WS" );
|
||||
addCountry( "San Marino", "SM" );
|
||||
addCountry( "Sao Tome and Principe", "ST" );
|
||||
addCountry( "Saudi Arabia", "SA" );
|
||||
addCountry( "Senegal", "SN" );
|
||||
addCountry( "Serbia", "RS" );
|
||||
addCountry( "Seychelles", "SC" );
|
||||
addCountry( "Sierra Leone", "SL" );
|
||||
addCountry( "Singapore", "SG" );
|
||||
addCountry( "Slovakia", "SK" );
|
||||
addCountry( "Slovenia", "SI" );
|
||||
addCountry( "Solomon Islands", "SB" );
|
||||
addCountry( "Somalia", "SO" );
|
||||
addCountry( "South Africa", "ZA" );
|
||||
addCountry( "South Georgia and the South Sandwich Islands", "GS" );
|
||||
addCountry( "Spain", "ES" );
|
||||
addCountry( "Sri Lanka", "LK" );
|
||||
addCountry( "Sudan", "SD" );
|
||||
addCountry( "Suriname", "SR" );
|
||||
addCountry( "Svalbard and Jan Mayen", "SJ" );
|
||||
addCountry( "Swaziland", "SZ" );
|
||||
addCountry( "Sweden", "SE" );
|
||||
addCountry( "Switzerland", "CH" );
|
||||
addCountry( "Syrian Arab Republic", "SY" );
|
||||
addCountry( "Taiwan, Province of China", "TW" );
|
||||
addCountry( "Tajikistan", "TJ" );
|
||||
addCountry( "Tanzania, United Republic of", "TZ" );
|
||||
addCountry( "Tanzania", "TZ" );
|
||||
addCountry( "Thailand", "TH" );
|
||||
addCountry( "Timor-Leste", "TL" );
|
||||
addCountry( "Togo", "TG" );
|
||||
addCountry( "Tokelau", "TK" );
|
||||
addCountry( "Tonga", "TO" );
|
||||
addCountry( "Trinidad and Tobago", "TT" );
|
||||
addCountry( "Tunisia", "TN" );
|
||||
addCountry( "Turkey", "TR" );
|
||||
addCountry( "Turkmenistan", "TM" );
|
||||
addCountry( "Turks and Caicos Islands", "TC" );
|
||||
addCountry( "Tuvalu", "TV" );
|
||||
addCountry( "Uganda", "UG" );
|
||||
addCountry( "Ukraine", "UA" );
|
||||
addCountry( "United Arab Emirates", "AE" );
|
||||
addCountry( "United Kingdom", "GB" );
|
||||
addCountry( "United States", "US" );
|
||||
addCountry( "United States Minor Outlying Islands", "UM" );
|
||||
addCountry( "Uruguay", "UY" );
|
||||
addCountry( "Uzbekistan", "UZ" );
|
||||
addCountry( "Vanuatu", "VU" );
|
||||
addCountry( "Venezuela, Bolivarian Republic of", "VE" );
|
||||
addCountry( "Venezuela", "VE" );
|
||||
addCountry( "Viet Nam", "VN" );
|
||||
addCountry( "Virgin Islands, British", "VG" );
|
||||
addCountry( "Virgin Islands, U.S.", "VI" );
|
||||
addCountry( "Wallis and Futuna", "WF" );
|
||||
addCountry( "Western Sahara", "EH" );
|
||||
addCountry( "Yemen", "YE" );
|
||||
addCountry( "Zambia", "ZM" );
|
||||
addCountry( "Zimbabwe", "ZW" );
|
||||
}
|
||||
}
|
||||
|
||||
QString englishNametoIso2( QString const & name )
|
||||
{
|
||||
Database::const_iterator i = Database::instance().find( gd::toQString( Folding::apply( gd::toWString( name ) ) ) );
|
||||
|
||||
if ( i == Database::instance().end() )
|
||||
return QString();
|
||||
else
|
||||
return i.value();
|
||||
}
|
||||
|
||||
}
|
14
country.hh
Normal file
14
country.hh
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef COUNTRY_HH
|
||||
#define COUNTRY_HH
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace Country {
|
||||
|
||||
/// Attempts converting the given country name, in english, to its iso-3166-1
|
||||
/// 2-letter code. If fails, empty string is returned.
|
||||
QString englishNametoIso2( QString const & );
|
||||
|
||||
}
|
||||
|
||||
#endif // COUNTRY_HH
|
|
@ -16,7 +16,7 @@ EditDictionaries::EditDictionaries( QWidget * parent, Config::Class & cfg_,
|
|||
dictNetMgr( dictNetMgr_ ),
|
||||
origCfg( cfg ),
|
||||
sources( this, cfg.paths, cfg.soundDirs, cfg.hunspell, cfg.transliteration,
|
||||
cfg.mediawikis, cfg.webSites ),
|
||||
cfg.forvo, cfg.mediawikis, cfg.webSites ),
|
||||
orderAndProps( new OrderAndProps( this, cfg.dictionaryOrder, cfg.inactiveDictionaries,
|
||||
dictionaries ) ),
|
||||
groups( new Groups( this, dictionaries, cfg.groups, orderAndProps->getCurrentDictionaryOrder() ) ),
|
||||
|
@ -138,6 +138,7 @@ bool EditDictionaries::isSourcesChanged() const
|
|||
sources.getSoundDirs() != cfg.soundDirs ||
|
||||
sources.getHunspell() != cfg.hunspell ||
|
||||
sources.getTransliteration() != cfg.transliteration ||
|
||||
sources.getForvo() != cfg.forvo ||
|
||||
sources.getMediaWikis() != cfg.mediawikis ||
|
||||
sources.getWebSites() != cfg.webSites;
|
||||
}
|
||||
|
@ -154,6 +155,7 @@ void EditDictionaries::acceptChangedSources( bool rebuildGroups )
|
|||
cfg.soundDirs = sources.getSoundDirs();
|
||||
cfg.hunspell = sources.getHunspell();
|
||||
cfg.transliteration = sources.getTransliteration();
|
||||
cfg.forvo = sources.getForvo();
|
||||
cfg.mediawikis = sources.getMediaWikis();
|
||||
cfg.webSites = sources.getWebSites();
|
||||
|
||||
|
|
414
forvo.cc
Normal file
414
forvo.cc
Normal file
|
@ -0,0 +1,414 @@
|
|||
/* This file is (c) 2008-2010 Konstantin Isakov <ikm@users.berlios.de>
|
||||
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
|
||||
|
||||
#include "forvo.hh"
|
||||
#include "wstring_qt.hh"
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QUrl>
|
||||
#include <QtXml>
|
||||
#include <list>
|
||||
#include "audiolink.hh"
|
||||
#include "htmlescape.hh"
|
||||
#include "country.hh"
|
||||
#include "language.hh"
|
||||
#include "langcoder.hh"
|
||||
|
||||
namespace Forvo {
|
||||
|
||||
using namespace Dictionary;
|
||||
|
||||
namespace {
|
||||
|
||||
class ForvoDictionary: public Dictionary::Class
|
||||
{
|
||||
string name;
|
||||
QString apiKey, languageCode;
|
||||
QNetworkAccessManager & netMgr;
|
||||
|
||||
public:
|
||||
|
||||
ForvoDictionary( string const & id, string const & name_,
|
||||
QString const & apiKey_,
|
||||
QString const & languageCode_,
|
||||
QNetworkAccessManager & netMgr_ ):
|
||||
Dictionary::Class( id, vector< string >() ),
|
||||
name( name_ ),
|
||||
apiKey( apiKey_ ),
|
||||
languageCode( languageCode_ ),
|
||||
netMgr( netMgr_ )
|
||||
{
|
||||
}
|
||||
|
||||
virtual string getName() throw()
|
||||
{ return name; }
|
||||
|
||||
virtual map< Property, string > getProperties() throw()
|
||||
{ return map< Property, string >(); }
|
||||
|
||||
virtual unsigned long getArticleCount() throw()
|
||||
{ return 0; }
|
||||
|
||||
virtual unsigned long getWordCount() throw()
|
||||
{ return 0; }
|
||||
|
||||
virtual QIcon getIcon() throw();
|
||||
|
||||
virtual sptr< WordSearchRequest > prefixMatch( wstring const & word,
|
||||
unsigned long /*maxResults*/ ) throw( std::exception )
|
||||
{
|
||||
// Dummy
|
||||
sptr< WordSearchRequestInstant > sr = new WordSearchRequestInstant;
|
||||
|
||||
sr->getMatches().push_back( WordMatch( word, 1 ) );
|
||||
|
||||
return sr;
|
||||
}
|
||||
|
||||
virtual sptr< DataRequest > getArticle( wstring const &, vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception );
|
||||
};
|
||||
|
||||
class ForvoArticleRequest: public ForvoDataRequestSlots
|
||||
{
|
||||
typedef std::list< std::pair< sptr< QNetworkReply >, bool > > NetReplies;
|
||||
NetReplies netReplies;
|
||||
QString word, apiKey, languageCode;
|
||||
string dictionaryId;
|
||||
|
||||
public:
|
||||
|
||||
ForvoArticleRequest( wstring const & word, vector< wstring > const & alts,
|
||||
QString const & apiKey_,
|
||||
QString const & languageCode_,
|
||||
string const & dictionaryId_,
|
||||
QNetworkAccessManager & mgr );
|
||||
|
||||
virtual void cancel();
|
||||
|
||||
private:
|
||||
|
||||
void addQuery( QNetworkAccessManager & mgr, wstring const & word );
|
||||
|
||||
virtual void requestFinished( QNetworkReply * );
|
||||
};
|
||||
|
||||
void ForvoArticleRequest::cancel()
|
||||
{
|
||||
finish();
|
||||
}
|
||||
|
||||
ForvoArticleRequest::ForvoArticleRequest( wstring const & str,
|
||||
vector< wstring > const & /*alts*/,
|
||||
QString const & apiKey_,
|
||||
QString const & languageCode_,
|
||||
string const & dictionaryId_,
|
||||
QNetworkAccessManager & mgr ):
|
||||
word( gd::toQString( str ) ), apiKey( apiKey_ ),
|
||||
languageCode( languageCode_ ), dictionaryId( dictionaryId_ )
|
||||
{
|
||||
connect( &mgr, SIGNAL( finished( QNetworkReply * ) ),
|
||||
this, SLOT( requestFinished( QNetworkReply * ) ),
|
||||
Qt::QueuedConnection );
|
||||
|
||||
addQuery( mgr, str );
|
||||
|
||||
// Don't do alts for now -- the api onlu allows 1000 requests a day a key
|
||||
#if 0
|
||||
for( unsigned x = 0; x < alts.size(); ++x )
|
||||
addQuery( mgr, alts[ x ] );
|
||||
#endif
|
||||
}
|
||||
|
||||
void ForvoArticleRequest::addQuery( QNetworkAccessManager & mgr,
|
||||
wstring const & str )
|
||||
{
|
||||
printf( "Requesting article %ls\n", str.c_str() );
|
||||
|
||||
if ( apiKey.simplified().isEmpty() )
|
||||
{
|
||||
// Use the default api key. That's the key I have just registered myself.
|
||||
// It has a limit of 1000 requests a day, and may also get banned in the
|
||||
// future. Can't do much about it. Get your own key, it is simple.
|
||||
apiKey = "5efa5d045a16d10ad9c4705bd5d8e56a";
|
||||
}
|
||||
|
||||
QUrl reqUrl = QUrl::fromEncoded(
|
||||
QString( "http://apifree.forvo.com/key/%1/format/xml/action/word-pronunciations/word/%2/language/%3" )
|
||||
.arg( apiKey ).arg( QString::fromAscii( QUrl::toPercentEncoding( gd::toQString( str ) ) ) ).arg( languageCode ).toUtf8() );
|
||||
|
||||
printf( "req: %s\n", reqUrl.toEncoded().data() );
|
||||
|
||||
sptr< QNetworkReply > netReply = mgr.get( QNetworkRequest( reqUrl ) );
|
||||
|
||||
netReplies.push_back( std::make_pair( netReply, false ) );
|
||||
}
|
||||
|
||||
void ForvoArticleRequest::requestFinished( QNetworkReply * r )
|
||||
{
|
||||
printf( "Finished.\n" );
|
||||
|
||||
if ( isFinished() ) // Was cancelled
|
||||
return;
|
||||
|
||||
// Find this reply
|
||||
|
||||
bool found = false;
|
||||
|
||||
for( NetReplies::iterator i = netReplies.begin(); i != netReplies.end(); ++i )
|
||||
{
|
||||
if ( i->first.get() == r )
|
||||
{
|
||||
i->second = true; // Mark as finished
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found )
|
||||
{
|
||||
// Well, that's not our reply, don't do anything
|
||||
return;
|
||||
}
|
||||
|
||||
bool updated = false;
|
||||
|
||||
for( ; netReplies.size() && netReplies.front().second; netReplies.pop_front() )
|
||||
{
|
||||
sptr< QNetworkReply > netReply = netReplies.front().first;
|
||||
|
||||
if ( netReply->error() == QNetworkReply::NoError )
|
||||
{
|
||||
QDomDocument dd;
|
||||
|
||||
QString errorStr;
|
||||
int errorLine, errorColumn;
|
||||
|
||||
if ( !dd.setContent( netReply.get(), false, &errorStr, &errorLine, &errorColumn ) )
|
||||
{
|
||||
setErrorString( QString( tr( "XML parse error: %1 at %2,%3" ).
|
||||
arg( errorStr ).arg( errorLine ).arg( errorColumn ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "%s\n", dd.toByteArray().data() );
|
||||
|
||||
QDomNode items = dd.namedItem( "items" );
|
||||
|
||||
if ( !items.isNull() )
|
||||
{
|
||||
QDomNodeList nl = items.toElement().elementsByTagName( "item" );
|
||||
|
||||
if ( nl.count() )
|
||||
{
|
||||
string articleBody;
|
||||
|
||||
articleBody += "<div class='forvo_headword'>";
|
||||
articleBody += Html::escape( word.toUtf8().data() );
|
||||
articleBody += "</div>";
|
||||
|
||||
articleBody += "<table class=\"forvo_play\">";
|
||||
|
||||
for( unsigned x = 0; x < nl.length(); ++x )
|
||||
{
|
||||
QDomElement item = nl.item( x ).toElement();
|
||||
|
||||
QDomNode mp3 = item.namedItem( "pathmp3" );
|
||||
|
||||
if ( !mp3.isNull() )
|
||||
{
|
||||
articleBody += "<tr>";
|
||||
|
||||
QUrl url( mp3.toElement().text() );
|
||||
|
||||
string ref = string( "\"" ) + url.toEncoded().data() + "\"";
|
||||
|
||||
articleBody += addAudioLink( ref, dictionaryId ).c_str();
|
||||
|
||||
bool isMale = ( item.namedItem( "sex" ).toElement().text().toLower() != "f" );
|
||||
|
||||
QString user = item.namedItem( "username" ).toElement().text();
|
||||
QString country = item.namedItem( "country" ).toElement().text();
|
||||
|
||||
string userProfile = string( "http://www.forvo.com/user/" ) +
|
||||
QUrl::toPercentEncoding( user ).data() + "/";
|
||||
|
||||
int totalVotes = item.namedItem( "num_votes" ).toElement().text().toInt();
|
||||
int positiveVotes = item.namedItem( "num_positive_votes" ).toElement().text().toInt();
|
||||
int negativeVotes = totalVotes - positiveVotes;
|
||||
|
||||
string votes;
|
||||
|
||||
if ( positiveVotes || negativeVotes )
|
||||
{
|
||||
votes += " ";
|
||||
|
||||
if ( positiveVotes )
|
||||
{
|
||||
votes += "<span class='forvo_positive_votes'>+";
|
||||
votes += QByteArray::number( positiveVotes ).data();
|
||||
votes += "</span>";
|
||||
}
|
||||
|
||||
if ( negativeVotes )
|
||||
{
|
||||
if ( positiveVotes )
|
||||
votes += " ";
|
||||
|
||||
votes += "<span class='forvo_negative_votes'>-";
|
||||
votes += QByteArray::number( negativeVotes ).data();
|
||||
votes += "</span>";
|
||||
}
|
||||
}
|
||||
|
||||
string addTime =
|
||||
tr( "Added %1" ).arg( item.namedItem( "addtime" ).toElement().text() ).toUtf8().data();
|
||||
|
||||
articleBody += "<td><a href=" + ref + " title=\"" + Html::escape( addTime ) + "\"><img src=\"qrcx://localhost/icons/playsound.png\" border=\"0\" alt=\"Play\"/></a></td>";
|
||||
articleBody += string( "<td>" ) + tr( "by" ).toUtf8().data() + " <a class='forvo_user' href='"
|
||||
+ userProfile + "'>"
|
||||
+ Html::escape( user.toUtf8().data() )
|
||||
+ "</a> <span class='forvo_location'>("
|
||||
+ ( isMale ? tr( "Male" ) : tr( "Female" ) ).toUtf8().data()
|
||||
+ " "
|
||||
+ tr( "from" ).toUtf8().data()
|
||||
+ " "
|
||||
+ "<img src='qrcx://localhost/flags/" + Country::englishNametoIso2( country ).toUtf8().data()
|
||||
+ ".png'/> "
|
||||
+ Html::escape( country.toUtf8().data() )
|
||||
+ ")</span>"
|
||||
+ votes
|
||||
+ "</td>";
|
||||
articleBody += "</tr>";
|
||||
}
|
||||
}
|
||||
|
||||
articleBody += "</table>";
|
||||
|
||||
Mutex::Lock _( dataMutex );
|
||||
|
||||
size_t prevSize = data.size();
|
||||
|
||||
data.resize( prevSize + articleBody.size() );
|
||||
|
||||
memcpy( &data.front() + prevSize, articleBody.data(), articleBody.size() );
|
||||
|
||||
hasAnyData = true;
|
||||
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
QDomNode errors = dd.namedItem( "errors" );
|
||||
|
||||
if ( !errors.isNull() )
|
||||
setErrorString( errors.namedItem( "error" ).toElement().text() );
|
||||
}
|
||||
printf( "done.\n" );
|
||||
}
|
||||
else
|
||||
setErrorString( netReply->errorString() );
|
||||
}
|
||||
|
||||
if ( netReplies.empty() )
|
||||
finish();
|
||||
else
|
||||
if ( updated )
|
||||
update();
|
||||
}
|
||||
|
||||
sptr< DataRequest > ForvoDictionary::getArticle( wstring const & word,
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception )
|
||||
{
|
||||
if ( word.size() > 80 )
|
||||
{
|
||||
// Don't make excessively large queries -- they're fruitless anyway
|
||||
|
||||
return new DataRequestInstant( false );
|
||||
}
|
||||
else
|
||||
return new ForvoArticleRequest( word, alts, apiKey, languageCode, getId(),
|
||||
netMgr );
|
||||
}
|
||||
|
||||
QIcon ForvoDictionary::getIcon() throw()
|
||||
{
|
||||
// Experimental code to generate icon -- but the flags clutter the interface too
|
||||
// much and we're better with a single icon.
|
||||
#if 0
|
||||
if ( languageCode.size() == 2 )
|
||||
{
|
||||
QString countryCode = Language::countryCodeForId( LangCoder::code2toInt( languageCode.toAscii().data() ) );
|
||||
|
||||
if ( countryCode.size() )
|
||||
{
|
||||
QImage flag( QString( ":/flags/%1.png" ).arg( countryCode.toLower() ) );
|
||||
|
||||
if ( !flag.isNull() )
|
||||
{
|
||||
QImage img( ":/icons/forvo_icon_base.png" );
|
||||
|
||||
{
|
||||
QPainter painter( &img );
|
||||
painter.drawImage( QPoint( 5, 7 ), flag );
|
||||
}
|
||||
|
||||
return QIcon( QPixmap::fromImage( img ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return QIcon( ":/icons/forvo.png" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
vector< sptr< Dictionary::Class > > makeDictionaries(
|
||||
Dictionary::Initializing &,
|
||||
Config::Forvo const & forvo,
|
||||
QNetworkAccessManager & mgr )
|
||||
throw( std::exception )
|
||||
{
|
||||
vector< sptr< Dictionary::Class > > result;
|
||||
|
||||
if ( forvo.enable )
|
||||
{
|
||||
QStringList codes = forvo.languageCodes.split( ',', QString::SkipEmptyParts );
|
||||
|
||||
QSet< QString > usedCodes;
|
||||
|
||||
for( int x = 0; x < codes.size(); ++x )
|
||||
{
|
||||
QString code = codes[ x ].simplified();
|
||||
|
||||
if ( code.size() && !usedCodes.contains( code ) )
|
||||
{
|
||||
// Generate id
|
||||
|
||||
QCryptographicHash hash( QCryptographicHash::Md5 );
|
||||
|
||||
hash.addData( "Forvo source version 1.0" );
|
||||
hash.addData( code.toUtf8() );
|
||||
|
||||
QString displayedCode( code.toLower() );
|
||||
|
||||
if ( displayedCode.size() )
|
||||
displayedCode[ 0 ] = displayedCode[ 0 ].toUpper();
|
||||
|
||||
result.push_back(
|
||||
new ForvoDictionary( hash.result().toHex().data(),
|
||||
QString( "Forvo (%1)" ).arg( displayedCode ).toUtf8().data(),
|
||||
forvo.apiKey, code, mgr ) );
|
||||
|
||||
usedCodes.insert( code );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
36
forvo.hh
Normal file
36
forvo.hh
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* This file is (c) 2008-2010 Konstantin Isakov <ikm@users.berlios.de>
|
||||
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
|
||||
|
||||
#ifndef __FORVO_HH_INCLUDED__
|
||||
#define __FORVO_HH_INCLUDED__
|
||||
|
||||
#include "dictionary.hh"
|
||||
#include "config.hh"
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
/// Support for Forvo pronunciations, based on its API.
|
||||
namespace Forvo {
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
vector< sptr< Dictionary::Class > > makeDictionaries(
|
||||
Dictionary::Initializing &,
|
||||
Config::Forvo const &,
|
||||
QNetworkAccessManager & )
|
||||
throw( std::exception );
|
||||
|
||||
/// Exposed here for moc
|
||||
class ForvoDataRequestSlots: public Dictionary::DataRequest
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
protected slots:
|
||||
|
||||
virtual void requestFinished( QNetworkReply * )
|
||||
{}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -141,7 +141,9 @@ HEADERS += folding.hh \
|
|||
indexedzip.hh \
|
||||
termination.hh \
|
||||
greektranslit.hh \
|
||||
webmultimediadownload.hh
|
||||
webmultimediadownload.hh \
|
||||
forvo.hh \
|
||||
country.hh
|
||||
FORMS += groups.ui \
|
||||
dictgroupwidget.ui \
|
||||
mainwindow.ui \
|
||||
|
@ -220,7 +222,9 @@ SOURCES += folding.cc \
|
|||
indexedzip.cc \
|
||||
termination.cc \
|
||||
greektranslit.cc \
|
||||
webmultimediadownload.cc
|
||||
webmultimediadownload.cc \
|
||||
forvo.cc \
|
||||
country.cc
|
||||
win32 {
|
||||
SOURCES += mouseover_win32/ThTypes.c
|
||||
HEADERS += mouseover_win32/ThTypes.h
|
||||
|
|
BIN
icons/forvo.png
Normal file
BIN
icons/forvo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -16,6 +16,7 @@
|
|||
#include "german.hh"
|
||||
#include "greektranslit.hh"
|
||||
#include "website.hh"
|
||||
#include "forvo.hh"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
|
@ -220,6 +221,15 @@ void loadDictionaries( QWidget * parent, bool showInitially,
|
|||
dictionaries.insert( dictionaries.end(), dicts.begin(), dicts.end() );
|
||||
}
|
||||
|
||||
//// Forvo dictionaries
|
||||
|
||||
{
|
||||
vector< sptr< Dictionary::Class > > dicts =
|
||||
Forvo::makeDictionaries( loadDicts, cfg.forvo, dictNetMgr );
|
||||
|
||||
dictionaries.insert( dictionaries.end(), dicts.begin(), dicts.end() );
|
||||
}
|
||||
|
||||
printf( "Load done\n" );
|
||||
|
||||
// Remove any stale index files
|
||||
|
|
|
@ -39,5 +39,6 @@
|
|||
<file>article-style-st-lingvo.css</file>
|
||||
<file>icons/internet.png</file>
|
||||
<file>icons/icon_dsl_native.png</file>
|
||||
<file>icons/forvo.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
16
sources.cc
16
sources.cc
|
@ -12,6 +12,7 @@ Sources::Sources( QWidget * parent, Config::Paths const & paths,
|
|||
Config::SoundDirs const & soundDirs,
|
||||
Config::Hunspell const & hunspell,
|
||||
Config::Transliteration const & trs,
|
||||
Config::Forvo const & forvo,
|
||||
Config::MediaWikis const & mediawikis,
|
||||
Config::WebSites const & webSites ): QWidget( parent ),
|
||||
mediawikisModel( this, mediawikis ),
|
||||
|
@ -60,6 +61,10 @@ Sources::Sources( QWidget * parent, Config::Paths const & paths,
|
|||
ui.enableHiragana->setChecked( trs.romaji.enableHiragana );
|
||||
ui.enableKatakana->setChecked( trs.romaji.enableKatakana );
|
||||
|
||||
ui.forvoEnabled->setChecked( forvo.enable );
|
||||
ui.forvoApiKey->setText( forvo.apiKey );
|
||||
ui.forvoLanguageCodes->setText( forvo.languageCodes );
|
||||
|
||||
if ( Config::isPortableVersion() )
|
||||
{
|
||||
// Paths
|
||||
|
@ -248,6 +253,17 @@ Config::Transliteration Sources::getTransliteration() const
|
|||
return tr;
|
||||
}
|
||||
|
||||
Config::Forvo Sources::getForvo() const
|
||||
{
|
||||
Config::Forvo forvo;
|
||||
|
||||
forvo.enable = ui.forvoEnabled->isChecked();
|
||||
forvo.apiKey = ui.forvoApiKey->text();
|
||||
forvo.languageCodes = ui.forvoLanguageCodes->text();
|
||||
|
||||
return forvo;
|
||||
}
|
||||
|
||||
////////// MediaWikisModel
|
||||
|
||||
MediaWikisModel::MediaWikisModel( QWidget * parent,
|
||||
|
|
|
@ -169,6 +169,7 @@ public:
|
|||
Config::SoundDirs const &,
|
||||
Config::Hunspell const &,
|
||||
Config::Transliteration const &,
|
||||
Config::Forvo const & forvo,
|
||||
Config::MediaWikis const &,
|
||||
Config::WebSites const & );
|
||||
|
||||
|
@ -188,6 +189,8 @@ public:
|
|||
|
||||
Config::Transliteration getTransliteration() const;
|
||||
|
||||
Config::Forvo getForvo() const;
|
||||
|
||||
signals:
|
||||
|
||||
/// Emitted when a 'Rescan' button is clicked.
|
||||
|
|
192
sources.ui
192
sources.ui
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>578</width>
|
||||
<width>665</width>
|
||||
<height>336</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -334,6 +334,196 @@ of the appropriate groups to use them.</string>
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_5">
|
||||
<attribute name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/icons/forvo.png</normaloff>:/icons/forvo.png</iconset>
|
||||
</attribute>
|
||||
<attribute name="title">
|
||||
<string>Forvo</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;">
|
||||
<tr>
|
||||
<td style="border: none;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Live pronunciations from <a href="http://www.forvo.com/"><span style=" text-decoration: underline; color:#0057ae;">forvo.com</span></a>. The site allows people to record and share word pronunciations. You can listen to them from GoldenDict.</p></td></tr></table></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="forvoEnabled">
|
||||
<property name="title">
|
||||
<string>Enable pronunciations from Forvo</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||
<item>
|
||||
<spacer name="verticalSpacer_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>API Key:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="forvoApiKey">
|
||||
<property name="toolTip">
|
||||
<string>Use of Forvo currently requires an API key. Leave this field
|
||||
blank to use the default key, which may become unavailable
|
||||
in the future, or register on the site to get your own key.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>18</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<table style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;">
|
||||
<tr>
|
||||
<td style="border: none;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Get your own key <a href="http://api.forvo.com/key/"><span style=" text-decoration: underline; color:#0057ae;">here</span></a>, or leave blank to use the default one.</p></td></tr></table></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Language codes (comma-separated):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="forvoLanguageCodes">
|
||||
<property name="toolTip">
|
||||
<string>List of language codes you would like to have. Example: "en, ru".</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>18</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Full list of language codes is avaiable <a href="http://www.forvo.com/languages-codes/">here</a>.</string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacer_11">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_10">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>Transliteration</string>
|
||||
|
|
|
@ -46,7 +46,10 @@ void WebMultimediaDownload::replyFinished( QNetworkReply * r )
|
|||
|
||||
bool WebMultimediaDownload::isAudioUrl( QUrl const & url )
|
||||
{
|
||||
return url.scheme() == "http" && Filetype::isNameOfSound( url.path().toUtf8().data() );
|
||||
// Note: we check for forvo sound links explicitly, as they don't have extensions
|
||||
|
||||
return url.scheme() == "http" && (
|
||||
Filetype::isNameOfSound( url.path().toUtf8().data() ) || url.host() == "apifree.forvo.com" );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue