File indexing completed on 2025-04-27 03:58:38

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2018-02-22
0007  * Description : A text translator using web-services.
0008  *
0009  * SPDX-FileCopyrightText: 2018-2022 by Hennadii Chernyshchyk <genaloner at gmail dot com>
0010  * SPDX-FileCopyrightText: 2021-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #ifndef DIGIKAM_DONLINE_TRANSLATOR_H
0017 #define DIGIKAM_DONLINE_TRANSLATOR_H
0018 
0019 // Qt includes
0020 
0021 #include <QMap>
0022 #include <QPointer>
0023 #include <QVector>
0024 #include <QJsonObject>
0025 #include <QJsonArray>
0026 #include <QStringList>
0027 
0028 // Local includes
0029 
0030 #include "digikam_export.h"
0031 
0032 class QStateMachine;
0033 class QState;
0034 class QNetworkAccessManager;
0035 class QNetworkReply;
0036 
0037 namespace Digikam
0038 {
0039 
0040 /**
0041  * @brief Contains translation options for a single word
0042  *
0043  * Can be obtained from the QOnlineTranslator object.
0044  *
0045  * Example:
0046  * @code
0047  * QOnlineTranslator translator;
0048  * // Obtain translation
0049  *
0050  * QTextStream out(stdout);
0051  *
0052  * for (auto it = translator.translationOptions().cbegin() ; it != translator.translationOptions().cend() ; ++it)
0053  * {
0054  *     out << it.key() << ":" << endl;  // Output the type of speech with a colon
0055  *
0056  *     for (const auto &[word, gender, translations] : it.value())
0057  *     {
0058  *         out << "  " << word << ": "; // Print the word
0059  *         out << translations;         // Print translations
0060  *         out << endl;
0061  *     }
0062  *
0063  *     out << endl;
0064  * }
0065  * @endcode
0066  *
0067  * Possible output:
0068  * @code
0069  * // verb:
0070  * //  sagen: say, tell, speak, mean, utter
0071  * //  sprechen: speak, talk, say, pronounce, militate, discourse
0072  * //  meinen: think, mean, believe, say, opine, fancy
0073  * //  heißen: mean, be called, be named, bid, tell, be titled
0074  * //  äußern: express, comment, speak, voice, say, utter
0075  * //  aussprechen: express, pronounce, say, speak, voice, enunciate
0076  * //  vorbringen: make, put forward, raise, say, put, bring forward
0077  * //  aufsagen: recite, say, speak
0078  *
0079  * // noun:
0080  * //  Sagen: say
0081  * //  Mitspracherecht: say
0082  * @endcode
0083  */
0084 struct DIGIKAM_EXPORT DOnlineTranslatorOption
0085 {
0086     /**
0087      * @brief Word that specified for translation options.
0088      */
0089     QString     word;
0090 
0091     /**
0092      * @brief Gender of the word.
0093      */
0094     QString     gender;
0095 
0096     /**
0097      * @brief Associated translations for the word.
0098      */
0099     QStringList translations;
0100 
0101     /**
0102      * @brief Converts the object to JSON
0103      *
0104      * @return JSON representation
0105      */
0106     QJsonObject toJson() const
0107     {
0108         QJsonObject object
0109         {
0110             { QLatin1String("gender"),       gender                                   },
0111             { QLatin1String("translations"), QJsonArray::fromStringList(translations) },
0112             { QLatin1String("word"),         word                                     },
0113         };
0114 
0115         return object;
0116     }
0117 };
0118 
0119 // ------------------------------------------------------------------
0120 
0121 /**
0122  * @brief Provides translation data
0123  */
0124 class DIGIKAM_EXPORT DOnlineTranslator : public QObject
0125 {
0126     Q_OBJECT
0127     Q_DISABLE_COPY(DOnlineTranslator)
0128 
0129 public:
0130 
0131     /**
0132      * @brief Represents all languages for translation
0133      */
0134     enum Language
0135     {
0136         NoLanguage = -1,
0137         Auto,
0138         Afrikaans,
0139         Albanian,
0140         Amharic,
0141         Arabic,
0142         Armenian,
0143         Azerbaijani,
0144         Bashkir,
0145         Basque,
0146         Belarusian,
0147         Bengali,
0148         Bosnian,
0149         Bulgarian,
0150         Cantonese,
0151         Catalan,
0152         Cebuano,
0153         Chichewa,
0154         Corsican,
0155         Croatian,
0156         Czech,
0157         Danish,
0158         Dutch,
0159         English,
0160         Esperanto,
0161         Estonian,
0162         Fijian,
0163         Filipino,
0164         Finnish,
0165         French,
0166         Frisian,
0167         Galician,
0168         Georgian,
0169         German,
0170         Greek,
0171         Gujarati,
0172         HaitianCreole,
0173         Hausa,
0174         Hawaiian,
0175         Hebrew,
0176         HillMari,
0177         Hindi,
0178         Hmong,
0179         Hungarian,
0180         Icelandic,
0181         Igbo,
0182         Indonesian,
0183         Irish,
0184         Italian,
0185         Japanese,
0186         Javanese,
0187         Kannada,
0188         Kazakh,
0189         Khmer,
0190         Kinyarwanda,
0191         Klingon,
0192         KlingonPlqaD,
0193         Korean,
0194         Kurdish,
0195         Kyrgyz,
0196         Lao,
0197         Latin,
0198         Latvian,
0199         LevantineArabic,
0200         Lithuanian,
0201         Luxembourgish,
0202         Macedonian,
0203         Malagasy,
0204         Malay,
0205         Malayalam,
0206         Maltese,
0207         Maori,
0208         Marathi,
0209         Mari,
0210         Mongolian,
0211         Myanmar,
0212         Nepali,
0213         Norwegian,
0214         Oriya,
0215         Papiamento,
0216         Pashto,
0217         Persian,
0218         Polish,
0219         Portuguese,
0220         Punjabi,
0221         QueretaroOtomi,
0222         Romanian,
0223         Russian,
0224         Samoan,
0225         ScotsGaelic,
0226         SerbianCyrillic,
0227         SerbianLatin,
0228         Sesotho,
0229         Shona,
0230         SimplifiedChinese,
0231         Sindhi,
0232         Sinhala,
0233         Slovak,
0234         Slovenian,
0235         Somali,
0236         Spanish,
0237         Sundanese,
0238         Swahili,
0239         Swedish,
0240         Tagalog,
0241         Tahitian,
0242         Tajik,
0243         Tamil,
0244         Tatar,
0245         Telugu,
0246         Thai,
0247         Tongan,
0248         TraditionalChinese,
0249         Turkish,
0250         Turkmen,
0251         Udmurt,
0252         Uighur,
0253         Ukrainian,
0254         Urdu,
0255         Uzbek,
0256         Vietnamese,
0257         Welsh,
0258         Xhosa,
0259         Yiddish,
0260         Yoruba,
0261         YucatecMaya,
0262         Zulu
0263     };
0264     Q_ENUM(Language)
0265 
0266     /**
0267      * @brief Represents online engines
0268      */
0269     enum Engine
0270     {
0271         Google,
0272         Yandex,
0273         Bing,
0274         LibreTranslate,
0275         Lingva
0276     };
0277     Q_ENUM(Engine)
0278 
0279     /**
0280      * @brief Indicates all possible error conditions found during the processing of the translation
0281      */
0282     enum TranslationError
0283     {
0284         /**
0285          * No error condition
0286          */
0287         NoError,
0288 
0289         /**
0290          * Unsupported combination of parameters
0291          */
0292         ParametersError,
0293 
0294         /**
0295          * Network error
0296          */
0297         NetworkError,
0298 
0299         /**
0300          * Service unavailable or maximum number of requests
0301          */
0302         ServiceError,
0303 
0304         /**
0305          * The request could not be parsed (report a bug if you see this)
0306          */
0307         ParsingError
0308     };
0309     Q_ENUM(TranslationError)
0310 
0311     /**
0312      * @brief Create object
0313      *
0314      * Constructs an object with empty data and with parent.
0315      * You can use translate() to send text to object.
0316      *
0317      * @param parent the parent object
0318      */
0319     explicit DOnlineTranslator(QObject* const parent = nullptr);
0320     ~DOnlineTranslator() override;
0321 
0322     /**
0323      * @brief Translate text
0324      *
0325      * @param text the text to translate
0326      * @param engine online engine to use
0327      * @param translationLang language to translation
0328      * @param sourceLang language of the passed text
0329      * @param uiLang ui language to use for display
0330      */
0331     void translate(const QString& text,
0332                    Engine engine = Google,
0333                    Language translationLang = Auto,
0334                    Language sourceLang = Auto,
0335                    Language uiLang = Auto);
0336 
0337     /**
0338      * @brief Detect language
0339      *
0340      * @param text the text for language detection
0341      * @param engine the engine to use
0342      */
0343     void detectLanguage(const QString& text,
0344                         Engine engine = Google);
0345 
0346     /**
0347      * @brief Cancel translation operation (if any).
0348      */
0349     void abort();
0350 
0351     /**
0352      * @brief Check translation progress
0353      *
0354      * @return `true` when the translation is still processing and has not finished or was aborted yet.
0355      */
0356     bool isRunning() const;
0357 
0358     /**
0359      * @brief Converts the object to JSON
0360      *
0361      * @return JSON representation
0362      */
0363     QJsonDocument toJson() const;
0364 
0365     /**
0366      * @brief Source text
0367      *
0368      * @return source text
0369      */
0370     QString source() const;
0371 
0372     /**
0373      * @brief Source transliteration
0374      *
0375      * @return transliteration of the source text
0376      */
0377     QString sourceTranslit() const;
0378 
0379     /**
0380      * @brief Source transcription
0381      *
0382      * @return transcription of the source text
0383      */
0384     QString sourceTranscription() const;
0385 
0386     /**
0387      * @brief Source language name
0388      *
0389      * @return language name of the source text
0390      */
0391     QString sourceLanguageName() const;
0392 
0393     /**
0394      * @brief Source language
0395      *
0396      * @return language of the source text
0397      */
0398     Language sourceLanguage() const;
0399 
0400     /**
0401      * Return the engine literal name.
0402      */
0403     static QString engineName(Engine engine);
0404 
0405     //@{
0406     // Properties methods (donlinetranslator_properties.cpp)
0407 
0408     /**
0409      * Convert language RFC3066 to supported language code
0410      */
0411     static QString fromRFC3066(Engine engine, const QString& langCodeRFC3066);
0412 
0413     /**
0414      * Return a list of all supported language in RFC3066.
0415      */
0416     static QStringList supportedRFC3066(Engine engine);
0417 
0418     /**
0419      * @brief Translated text
0420      *
0421      * @return translated text.
0422      */
0423     QString translation() const;
0424 
0425     /**
0426      * @brief Translation transliteration
0427      *
0428      * @return transliteration of the translated text
0429      */
0430     QString translationTranslit() const;
0431 
0432     /**
0433      * @brief Translation language name
0434      *
0435      * @return language name of the translated text
0436      */
0437     QString translationLanguageName() const;
0438 
0439     /**
0440      * @brief Translation language
0441      *
0442      * @return language of the translated text
0443      */
0444     Language translationLanguage() const;
0445 
0446     /**
0447      * @brief Translation options
0448      *
0449      * @return QMap whose key represents the type of speech, and the value is a QVector of translation options
0450      * @sa DOnlineTranslatorOption
0451      */
0452     QMap<QString, QVector<DOnlineTranslatorOption> > translationOptions() const;
0453 
0454     /**
0455      * @brief Language code
0456      *
0457      * @param lang language
0458      * @return language code
0459      */
0460     static QString languageCode(Language lang);
0461 
0462     /**
0463      * @brief Returns general language code
0464      *
0465      * @param langCode code
0466      * @return language
0467      */
0468     static Language language(const QString& langCode);
0469 
0470     /**
0471      * @brief Last error
0472      *
0473      * Error that was found during the processing of the last translation.
0474      * If no error was found, returns DOnlineTranslator::NoError.
0475      * The text of the error can be obtained by errorString().
0476      *
0477      * @return last error
0478      */
0479     TranslationError error() const;
0480 
0481     /**
0482      * @brief Last error string
0483      *
0484      * A human-readable description of the last translation error that occurred.
0485      *
0486      * @return last error string
0487      */
0488     QString errorString() const;
0489 
0490     /**
0491      * @brief Check if source transliteration is enabled
0492      *
0493      * @return `true` if source transliteration is enabled
0494      */
0495     bool isSourceTranslitEnabled() const;
0496 
0497     /**
0498      * @brief Check if translation transliteration is enabled
0499      *
0500      * @return `true` if translation transliteration is enabled
0501      */
0502     bool isTranslationTranslitEnabled() const;
0503 
0504     /**
0505      * @brief Check if source transcription is enabled
0506      *
0507      * @return `true` if source transcription is enabled
0508      */
0509     bool isSourceTranscriptionEnabled() const;
0510 
0511     /**
0512      * @brief Check if translation options are enabled
0513      *
0514      * @return `true` if translation options are enabled
0515      * @sa DOnlineTranslatorOption
0516      */
0517     bool isTranslationOptionsEnabled() const;
0518 
0519     /**
0520      * @brief Enable or disable source transliteration
0521      *
0522      * @param enable whether to enable source transliteration
0523      */
0524     void setSourceTranslitEnabled(bool enable);
0525 
0526     /**
0527      * @brief Enable or disable translation transliteration
0528      *
0529      * @param enable whether to enable translation transliteration
0530      */
0531     void setTranslationTranslitEnabled(bool enable);
0532 
0533     /**
0534      * @brief Enable or disable source transcription
0535      *
0536      * @param enable whether to enable source transcription
0537      */
0538     void setSourceTranscriptionEnabled(bool enable);
0539 
0540     /**
0541      * @brief Enable or disable translation options
0542      *
0543      * @param enable whether to enable translation options
0544      * @sa DOnlineTranslatorOption
0545      */
0546     void setTranslationOptionsEnabled(bool enable);
0547 
0548     /**
0549      * @brief Set the URL engine
0550      *
0551      * Only affects LibreTranslate and Lingva because these engines have multiple instances.
0552      * You need to call this function to specify the URL of an instance for them.
0553      *
0554      * @param engine the engine to use
0555      * @param url engine url
0556      */
0557     void setEngineUrl(Engine engine, const QString& url);
0558 
0559     /**
0560      * @brief Set api key for engine
0561      *
0562      * Affects only LibreTranslate.
0563      *
0564      * @param engine the engine to use
0565      * @param apiKey your key for this particular instance
0566      */
0567     void setEngineApiKey(Engine engine, const QByteArray& apiKey);
0568 
0569     //@}
0570 
0571     //@{
0572     // Conversion tables (donlinetranslator_tables.cpp)
0573 
0574     /**
0575      * @brief Language
0576      *
0577      * @param locale the locale to use
0578      * @return language
0579      */
0580     static Language language(const QLocale& locale);
0581 
0582     /**
0583      * @brief Language name
0584      *
0585      * @param lang language
0586      * @return language name
0587      */
0588     static QString languageName(Language lang);
0589 
0590     /**
0591      * @brief Check if transliteration is supported
0592      *
0593      * @param engine the engine to use
0594      * @param lang language
0595      * @return `true` if the specified engine supports transliteration for specified language
0596      */
0597     static bool isSupportTranslation(Engine engine, Language lang);
0598 
0599 private:
0600 
0601     /**
0602      * Check for service support
0603      */
0604     static bool isSupportTranslit(Engine engine, Language lang);
0605     static bool isSupportDictionary(Engine engine, Language sourceLang, Language translationLang);
0606 
0607     //@}
0608 
0609 Q_SIGNALS:
0610 
0611     /**
0612      * @brief Translation finished
0613      *
0614      * This signal is emitted when the translation is complete.
0615      */
0616     void signalFinished();
0617 
0618 private Q_SLOTS:
0619 
0620     void slotSkipGarbageText();
0621 
0622     /**
0623      * NOTE: Engines have translation limit, so need to split all text into parts and make request sequentially.
0624      * Also Yandex and Bing requires several requests to get dictionary, transliteration etc.
0625      * We use state machine to rely async computation with signals and slots.
0626      */
0627 
0628     //@{
0629     /// Google Web service specific methods (donlinetranslator_google.cpp).
0630 
0631 private Q_SLOTS:
0632 
0633     void slotRequestGoogleTranslate();
0634     void slotParseGoogleTranslate();
0635 
0636 private:
0637 
0638     void buildGoogleStateMachine();
0639     void buildGoogleDetectStateMachine();
0640 
0641     //@}
0642 
0643     //@{
0644     /// Yandex Web service specific methods (donlinetranslator_yandex.cppp).
0645 
0646 private Q_SLOTS:
0647 
0648     void slotRequestYandexKey();
0649     void slotParseYandexKey();
0650 
0651     void slotRequestYandexTranslate();
0652     void slotParseYandexTranslate();
0653 
0654     void slotRequestYandexSourceTranslit();
0655     void slotParseYandexSourceTranslit();
0656 
0657     void slotRequestYandexTranslationTranslit();
0658     void slotParseYandexTranslationTranslit();
0659 
0660     void slotRequestYandexDictionary();
0661     void slotParseYandexDictionary();
0662 
0663 private:
0664 
0665     void buildYandexStateMachine();
0666     void buildYandexDetectStateMachine();
0667 
0668     /**
0669      * Helper functions for Yandex transliteration
0670      */
0671     void requestYandexTranslit(Language language);
0672     void parseYandexTranslit(QString& text);
0673 
0674     //@}
0675 
0676     //@{
0677     /// Bing Web service specific methods (donlinntranslator_bing.cpp).
0678 
0679 private Q_SLOTS:
0680 
0681     void slotRequestBingCredentials();
0682     void slotParseBingCredentials();
0683 
0684     void slotRequestBingTranslate();
0685     void slotParseBingTranslate();
0686 
0687     void slotRequestBingDictionary();
0688     void slotParseBingDictionary();
0689 
0690 private:
0691 
0692     void buildBingStateMachine();
0693     void buildBingDetectStateMachine();
0694 
0695     //@}
0696 
0697     //@{
0698     /// LibreTranslate Web service specific methods ()donlinetranslator_libretr.cpp).
0699 
0700 private Q_SLOTS:
0701 
0702     void slotRequestLibreLangDetection();
0703     void slotParseLibreLangDetection();
0704 
0705     void slotRequestLibreTranslate();
0706     void slotParseLibreTranslate();
0707 
0708 private:
0709 
0710     void buildLibreStateMachine();
0711     void buildLibreDetectStateMachine();
0712 
0713     //@}
0714 
0715     //@{
0716     /// Lingva Web service specific methods (donlinetranslator_lingva.cpp).
0717 
0718 private Q_SLOTS:
0719 
0720     void slotRequestLingvaTranslate();
0721     void slotParseLingvaTranslate();
0722 
0723 private:
0724 
0725     void buildLingvaStateMachine();
0726     void buildLingvaDetectStateMachine();
0727 
0728     //@}
0729 
0730 private:
0731 
0732     /**
0733      * Helper functions to build nested states
0734      */
0735     void buildSplitNetworkRequest(QState* const parent,
0736                                   void (DOnlineTranslator::*requestMethod)(),
0737                                   void (DOnlineTranslator::*parseMethod)(),
0738                                   const QString& text,
0739                                   int textLimit);
0740     void buildNetworkRequestState(QState* const parent,
0741                                   void (DOnlineTranslator::*requestMethod)(),
0742                                   void (DOnlineTranslator::*parseMethod)(),
0743                                   const QString& text = QString());
0744 
0745 
0746     void resetData(TranslationError error = NoError, const QString& errorString = QString());
0747 
0748 
0749     // Other
0750 
0751     /**
0752      * Returns engine-specific language code for translation
0753      */
0754     static QString languageApiCode(Engine engine, Language lang);
0755 
0756     /**
0757      * Parse language from response language code
0758      */
0759     static Language language(Engine engine, const QString& langCode);
0760     /**
0761      * Get split index of the text according to the limit
0762      */
0763     static int getSplitIndex(const QString& untranslatedText, int limit);
0764 
0765     static bool isContainsSpace(const QString& text);
0766 
0767     static void addSpaceBetweenParts(QString& text);
0768 
0769 private:
0770 
0771     class Private;
0772     Private* const d;
0773 
0774     friend class DOnlineTts;
0775 };
0776 
0777 // -------------------------------------------------------------------------------------------
0778 
0779 /**
0780  * @brief Provides TTS URL generation
0781  *
0782  * Example:
0783  * @code
0784  *
0785  * DOnlineTts tts;
0786  * tts.generateUrls(QLatin1String("Hello World!"), DOnlineTranslator::Google, DOnlineTranslator::English);
0787  *
0788  * // Get list of Urls to play with media player.
0789  * QList<QUrl> urls = tts.media();
0790  *
0791  * @endcode
0792  */
0793 class DIGIKAM_EXPORT DOnlineTts : public QObject
0794 {
0795     Q_OBJECT
0796     Q_DISABLE_COPY(DOnlineTts)
0797 
0798 public:
0799 
0800     /**
0801      * @brief Defines voice to use
0802      *
0803      * Used only by Yandex.
0804      */
0805     enum Voice
0806     {
0807         // All
0808         NoVoice = -1,
0809 
0810         // Yandex
0811         Zahar,
0812         Ermil,
0813         Jane,
0814         Oksana,
0815         Alyss,
0816         Omazh
0817     };
0818     Q_ENUM(Voice)
0819 
0820     /**
0821      * @brief Defines emotion to use
0822      *
0823      * Used only by Yandex.
0824      */
0825     enum Emotion
0826     {
0827         // All
0828         NoEmotion = -1,
0829 
0830         // Yandex
0831         Neutral,
0832         Good,
0833         Evil
0834     };
0835     Q_ENUM(Emotion)
0836 
0837     /**
0838      * @brief Indicates all possible error conditions found during the processing of the URLs generation
0839      */
0840     enum TtsError
0841     {
0842         /**
0843          * No error condition
0844          */
0845         NoError,
0846         /**
0847          * Specified engine does not support TTS
0848          */
0849         UnsupportedEngine,
0850         /**
0851          * Unsupported language by specified engine
0852          */
0853         UnsupportedLanguage,
0854         /**
0855          * Unsupported voice by specified engine
0856          */
0857         UnsupportedVoice,
0858         /**
0859          * Unsupported emotion by specified engine
0860          */
0861         UnsupportedEmotion,
0862     };
0863     Q_ENUM(TtsError)
0864 
0865     /**
0866      * @brief Create object
0867      *
0868      * Constructs an object with empty data and with parent.
0869      * You can use generateUrls() to create URLs for use in QMediaPlayer.
0870      *
0871      * @param parent the parent object
0872      */
0873     explicit DOnlineTts(QObject* const parent = nullptr);
0874     ~DOnlineTts() override;
0875 
0876     /**
0877      * @brief Create TTS urls
0878      *
0879      * Splits text into parts (engines have a limited number of characters per request) and returns list with the generated API URLs to play.
0880      *
0881      * @param text the text to speak
0882      * @param engine online translation engine
0883      * @param lang text language
0884      * @param voice the voice to use (used only by Yandex)
0885      * @param emotion the emotion to use (used only by Yandex)
0886      */
0887     void generateUrls(const QString& text,
0888                       DOnlineTranslator::Engine engine,
0889                       DOnlineTranslator::Language lang,
0890                       Voice voice = NoVoice,
0891                       Emotion emotion = NoEmotion);
0892 
0893     /**
0894      * @brief Generated media
0895      *
0896      * @return List of generated URLs
0897      */
0898     QList<QUrl> media() const;
0899 
0900     /**
0901      * @brief Last error
0902      *
0903      * Error that was found during the generating tts.
0904      * If no error was found, returns TtsError::NoError.
0905      * The text of the error can be obtained by errorString().
0906      *
0907      * @return last error
0908      */
0909     TtsError error() const;
0910 
0911     /**
0912      * @brief Last error string
0913      *
0914      * A human-readable description of the last tts URL generation error that occurred.
0915      *
0916      * @return last error string
0917      */
0918     QString errorString() const;
0919 
0920     /**
0921      * @brief Code of the voice
0922      *
0923      * @param voice the voice to use
0924      * @return code for voice
0925      */
0926     static QString voiceCode(Voice voice);
0927 
0928     /**
0929      * @brief Code of the emotion
0930      *
0931      * Used only by Yandex.
0932      *
0933      * @param emotion the emotion to use
0934      * @return code for emotion
0935      */
0936     static QString emotionCode(Emotion emotion);
0937 
0938     /**
0939      * @brief Emotion from code
0940      *
0941      * Used only by Yandex.
0942      *
0943      * @param emotionCode emotion code
0944      * @return corresponding emotion
0945      */
0946     static Emotion emotion(const QString& emotionCode);
0947 
0948     /**
0949      * @brief Voice from code
0950      *
0951      * Used only by Yandex.
0952      *
0953      * @param voiceCode voice code
0954      * @return corresponding voice
0955      */
0956     static Voice voice(const QString& voiceCode);
0957 
0958 private:
0959 
0960     void setError(TtsError error, const QString& errorString);
0961 
0962     QString languageApiCode(DOnlineTranslator::Engine engine, DOnlineTranslator::Language lang);
0963     QString voiceApiCode(DOnlineTranslator::Engine engine, Voice voice);
0964     QString emotionApiCode(DOnlineTranslator::Engine engine, Emotion emotion);
0965 
0966 private:
0967 
0968     class Private;
0969     Private* const d;
0970 };
0971 
0972 } // namespace Digikam
0973 
0974 #endif // DIGIKAM_DONLINE_TRANSLATOR_H