File indexing completed on 2024-04-21 03:51:02

0001 /*
0002     SPDX-FileCopyrightText: 2021 Andreas Cord-Landwehr <cordlandwehr@kde.org>
0003     SPDX-License-Identifier: LGPL-2.1-or-later
0004 */
0005 
0006 #ifndef TRANSLATESHELLADAPTER_H
0007 #define TRANSLATESHELLADAPTER_H
0008 
0009 #include <QFuture>
0010 #include <QProcessEnvironment>
0011 #include <QStringList>
0012 
0013 /**
0014  * @brief Adapter to online translation services
0015  *
0016  * This class can be used to obtain translations of words via translatorshell.
0017  * It is important to keep in mind that the whole integration is a best-effort integration. Always check first that
0018  * translateshell is available and give reasonable information to the user. Moreover, some of the translateshell
0019  * online APIs stop answering translation requests after a short time, which then leads to empty translation results,
0020  * because no error responses are available.
0021  */
0022 class TranslateShellAdapter
0023 {
0024 public:
0025     /**
0026      * @brief Result object of a translation request
0027      */
0028     struct Translation {
0029         QStringList m_suggestions;
0030         QStringList m_synonyms;
0031         QString phonetic;
0032         bool m_error{false};
0033     };
0034 
0035     /**
0036      * @brief Check if translateshell is supported
0037      *
0038      * Note that this call starts the translateshell --version option and thus you might not run this call in UI thread.
0039      *
0040      * @return true if application can be found, otherwise false
0041      */
0042     bool isTranslateShellAvailable() const;
0043 
0044     static TranslateShellAdapter::Translation parseTranslateShellResult(const QString &output);
0045 
0046     /**
0047      * @brief Asynchronous call to translate method
0048      *
0049      * This should be the preferred way to request translations. By using a watcher object the future object can be
0050      * monitored in the main thread and it can be acted upon the availability of the translation without blocking UI.
0051      *
0052      * It is expected to check first if translateshell is available and supported with isTranslateShellAvailable().
0053      * If process cannout be found or aborts, the result just provides an error flag.
0054      *
0055      * @param word the string that shall be translated, can also be a sequence of words
0056      * @param sourceLanguage the source language identifier as ISO-639-1 language code
0057      * @param targetLanguage the target language identifier as ISO-639-1 language code
0058      * @return returns a list of available translations
0059      */
0060     static QFuture<Translation> translateAsync(const QString &word, const QString &sourceLanguage, const QString &targetLanguage);
0061 
0062     /**
0063      * @brief Synchronous call to translate method
0064      *
0065      * Note that calling this method blocks the calling thread.
0066      *
0067      * It is expected to check first if translateshell is available and supported with isTranslateShellAvailable().
0068      * If process cannout be found or aborts, the result just provides an error flag.
0069      *
0070      * @param word the string that shall be translated, can also be a sequence of words
0071      * @param sourceLanguage the source language identifier as ISO-639-1 language code
0072      * @param targetLanguage the target language identifier as ISO-639-1 language code
0073      * @return returns a list of available translations
0074      */
0075     static TranslateShellAdapter::Translation translate(const QString &word, const QString &sourceLanguage, const QString &targetLanguage);
0076 
0077     /**
0078      * @brief Asynchronous download of sound file for given phrase
0079      *
0080      */
0081     static QFuture<bool> downloadSoundFile(const QString &word, const QString &language, const QString &filePath);
0082 
0083 private:
0084     mutable bool m_translateShellAvailable{false};
0085 };
0086 
0087 #endif