Fix translator using new backends

This commit is contained in:
luisangelsm
2026-03-05 15:16:26 +01:00
parent e699237c44
commit b3048f0bff
6 changed files with 39 additions and 108 deletions

View File

@ -66,13 +66,14 @@ jobs:
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y libunarr-dev libgl-dev libgles2-mesa-dev \ sudo apt-get install -y libunarr-dev libgl-dev libgles2-mesa-dev \
libfontconfig1-dev libfreetype-dev libxkbcommon-dev libpoppler-qt6-dev libfontconfig1-dev libfreetype-dev libxkbcommon-dev libpoppler-qt6-dev \
libspeechd-dev
- name: Install Qt - name: Install Qt
uses: jurplel/install-qt-action@v4 uses: jurplel/install-qt-action@v4
with: with:
version: '6.9.3' version: '6.9.3'
modules: 'qt5compat qtmultimedia qtimageformats qtshadertools' modules: 'qt5compat qtmultimedia qtimageformats qtshadertools qtspeech'
cache: true cache: true
- name: Build - name: Build
@ -98,13 +99,14 @@ jobs:
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y libgl-dev libgles2-mesa-dev \ sudo apt-get install -y libgl-dev libgles2-mesa-dev \
libfontconfig1-dev libfreetype-dev libxkbcommon-dev libpoppler-qt6-dev libfontconfig1-dev libfreetype-dev libxkbcommon-dev libpoppler-qt6-dev \
libspeechd-dev
- name: Install Qt - name: Install Qt
uses: jurplel/install-qt-action@v4 uses: jurplel/install-qt-action@v4
with: with:
version: '6.9.3' version: '6.9.3'
modules: 'qt5compat qtmultimedia qtimageformats qtshadertools' modules: 'qt5compat qtmultimedia qtimageformats qtshadertools qtspeech'
cache: true cache: true
- name: Build - name: Build
@ -134,7 +136,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
pip3 install --break-system-packages aqtinstall pip3 install --break-system-packages aqtinstall
python3 -m aqt install-qt mac desktop 6.9.3 -m qt5compat qtmultimedia qtimageformats qtshadertools python3 -m aqt install-qt mac desktop 6.9.3 -m qt5compat qtmultimedia qtimageformats qtshadertools qtspeech
echo "${{ github.workspace }}/6.9.3/macos/bin" >> $GITHUB_PATH echo "${{ github.workspace }}/6.9.3/macos/bin" >> $GITHUB_PATH
npm install -g appdmg npm install -g appdmg
@ -189,7 +191,7 @@ jobs:
pip install -U pip pip install -U pip
pip install aqtinstall pip install aqtinstall
mkdir C:\Qt mkdir C:\Qt
python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_64 -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_64 -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools qtspeech
dir C:\Qt\6.9.3\msvc2022_64\bin dir C:\Qt\6.9.3\msvc2022_64\bin
curl.exe -L --retry 5 --retry-delay 5 --retry-all-errors "https://aka.ms/vs/17/release/vc_redist.x64.exe" -o "%GITHUB_WORKSPACE%\vc_redist.x64.exe" curl.exe -L --retry 5 --retry-delay 5 --retry-all-errors "https://aka.ms/vs/17/release/vc_redist.x64.exe" -o "%GITHUB_WORKSPACE%\vc_redist.x64.exe"
where iscc where iscc
@ -333,8 +335,8 @@ jobs:
run: | run: |
pip install aqtinstall pip install aqtinstall
mkdir C:\Qt mkdir C:\Qt
python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_64 -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_64 -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools qtspeech
python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_arm64_cross_compiled -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_arm64_cross_compiled -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools qtspeech
dir C:\Qt\6.9.3\msvc2022_arm64\bin dir C:\Qt\6.9.3\msvc2022_arm64\bin
curl.exe -L --retry 5 --retry-delay 5 --retry-all-errors "https://aka.ms/vs/17/release/vc_redist.arm64.exe" -o "%GITHUB_WORKSPACE%\vc_redist.arm64.exe" curl.exe -L --retry 5 --retry-delay 5 --retry-all-errors "https://aka.ms/vs/17/release/vc_redist.arm64.exe" -o "%GITHUB_WORKSPACE%\vc_redist.arm64.exe"
where iscc where iscc

View File

@ -106,6 +106,7 @@ else()
Sql Sql
Svg Svg
Test Test
TextToSpeech
Widgets Widgets
) )
endif() endif()

View File

@ -89,6 +89,7 @@ target_link_libraries(YACReader PRIVATE
Qt::Network Qt::Network
Qt::Widgets Qt::Widgets
Qt::Multimedia Qt::Multimedia
Qt::TextToSpeech
Qt::Svg Qt::Svg
Qt::Core5Compat Qt::Core5Compat
comic_backend comic_backend

View File

@ -1,6 +1,6 @@
#include <QUrl> #include <QTextToSpeech>
#include <QJsonDocument>
#include <QMediaPlayer> #include <QJsonObject>
#include <QPushButton> #include <QPushButton>
#include <QPalette> #include <QPalette>
@ -26,8 +26,6 @@
#include <QMessageBox> #include <QMessageBox>
#define APPID "417CEAD93449502CC3C9B69FED26C54118E62BCC"
YACReaderTranslator::YACReaderTranslator(Viewer *parent) YACReaderTranslator::YACReaderTranslator(Viewer *parent)
: QWidget(parent), drag(false) : QWidget(parent), drag(false)
{ {
@ -155,7 +153,7 @@ YACReaderTranslator::YACReaderTranslator(Viewer *parent)
connect(speakButton, &QAbstractButton::pressed, this, &YACReaderTranslator::play); connect(speakButton, &QAbstractButton::pressed, this, &YACReaderTranslator::play);
connect(clearButton, &QAbstractButton::pressed, this, &YACReaderTranslator::clear); connect(clearButton, &QAbstractButton::pressed, this, &YACReaderTranslator::clear);
player = new QMediaPlayer; tts = new QTextToSpeech(this);
} }
void YACReaderTranslator::hideResults() void YACReaderTranslator::hideResults()
@ -179,20 +177,16 @@ void YACReaderTranslator::translate()
QString from = this->from->itemData(this->from->currentIndex()).toString(); QString from = this->from->itemData(this->from->currentIndex()).toString();
QString to = this->to->itemData(this->to->currentIndex()).toString(); QString to = this->to->itemData(this->to->currentIndex()).toString();
speakText = text;
speakLocale = from;
TranslationLoader *translationLoader = new TranslationLoader(text, from, to); TranslationLoader *translationLoader = new TranslationLoader(text, from, to);
connect(translationLoader, &TranslationLoader::requestFinished, this, &YACReaderTranslator::setTranslation); connect(translationLoader, &TranslationLoader::requestFinished, this, &YACReaderTranslator::setTranslation);
connect(translationLoader, &TranslationLoader::error, this, &YACReaderTranslator::error); connect(translationLoader, &TranslationLoader::error, this, &YACReaderTranslator::error);
connect(translationLoader, &TranslationLoader::timeOut, this, &YACReaderTranslator::error); connect(translationLoader, &TranslationLoader::timeOut, this, &YACReaderTranslator::error);
connect(translationLoader, &QThread::finished, translationLoader, &QObject::deleteLater); connect(translationLoader, &QThread::finished, translationLoader, &QObject::deleteLater);
TextToSpeachLoader *tts = new TextToSpeachLoader(text, from);
connect(tts, &TextToSpeachLoader::requestFinished, this, &YACReaderTranslator::setSpeak);
connect(tts, &TextToSpeachLoader::error, this, &YACReaderTranslator::error);
connect(tts, &TextToSpeachLoader::timeOut, this, &YACReaderTranslator::error);
connect(tts, &QThread::finished, tts, &QObject::deleteLater);
translationLoader->start(); translationLoader->start();
tts->start();
resultsTitle->setText(tr("Translation")); resultsTitle->setText(tr("Translation"));
@ -208,19 +202,12 @@ void YACReaderTranslator::error()
busyIndicator->hide(); busyIndicator->hide();
} }
void YACReaderTranslator::setSpeak(const QUrl &url)
{
resultsTitle->setHidden(false);
speakButton->setHidden(false);
ttsSource = url;
}
void YACReaderTranslator::setTranslation(const QString &string) void YACReaderTranslator::setTranslation(const QString &string)
{ {
resultText->setText(string); resultText->setText(string);
resultsTitle->setHidden(false); resultsTitle->setHidden(false);
speakButton->setHidden(false);
resultText->setHidden(false); resultText->setHidden(false);
busyIndicator->hide(); busyIndicator->hide();
} }
@ -236,8 +223,8 @@ void YACReaderTranslator::populateCombos()
combo->addItem("Arabic", "ar"); combo->addItem("Arabic", "ar");
combo->addItem("Bulgarian", "bg"); combo->addItem("Bulgarian", "bg");
combo->addItem("Catalan", "ca"); combo->addItem("Catalan", "ca");
combo->addItem("Chinese Simplified", "zh-CHS"); combo->addItem("Chinese Simplified", "zh-CN");
combo->addItem("Chinese Traditional", "zh-CHT"); combo->addItem("Chinese Traditional", "zh-TW");
combo->addItem("Czech", "cs"); combo->addItem("Czech", "cs");
combo->addItem("Danish", "da"); combo->addItem("Danish", "da");
combo->addItem("Dutch", "nl"); combo->addItem("Dutch", "nl");
@ -277,10 +264,8 @@ void YACReaderTranslator::populateCombos()
void YACReaderTranslator::play() void YACReaderTranslator::play()
{ {
tts->setLocale(QLocale(speakLocale));
player->setSource(ttsSource); tts->say(speakText);
player->play();
} }
void YACReaderTranslator::mousePressEvent(QMouseEvent *event) void YACReaderTranslator::mousePressEvent(QMouseEvent *event)
@ -324,10 +309,10 @@ void TranslationLoader::run()
connect(&tT, &QTimer::timeout, &q, &QEventLoop::quit); connect(&tT, &QTimer::timeout, &q, &QEventLoop::quit);
connect(&manager, &QNetworkAccessManager::finished, &q, &QEventLoop::quit); connect(&manager, &QNetworkAccessManager::finished, &q, &QEventLoop::quit);
QString url = "http://api.microsofttranslator.com/V2/Ajax.svc/Translate?appid=%1&from=%2&to=%3&text=%4&contentType=text/plain"; QString urlStr = QString("https://api.mymemory.translated.net/get?q=%1&langpair=%2|%3")
url = url.arg(APPID, from, to, text); .arg(QString::fromUtf8(QUrl::toPercentEncoding(text)), from, to);
QNetworkReply *reply = manager.get(QNetworkRequest(QUrl(url))); QNetworkReply *reply = manager.get(QNetworkRequest(QUrl(urlStr)));
tT.start(5000); // 5s timeout tT.start(5000); // 5s timeout
q.exec(); q.exec();
@ -335,55 +320,12 @@ void TranslationLoader::run()
if (tT.isActive()) { if (tT.isActive()) {
// download complete // download complete
if (reply->error() == QNetworkReply::NoError) { if (reply->error() == QNetworkReply::NoError) {
QString utf8 = QString::fromUtf8(reply->readAll()); QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
utf8 = utf8.remove(0, 1); QString translated = doc["responseData"]["translatedText"].toString();
utf8 = utf8.remove(utf8.count() - 1, 1); if (!translated.isEmpty())
QString translated(utf8);
emit requestFinished(translated); emit requestFinished(translated);
} else else
emit error(); emit error();
} else {
emit timeOut();
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
TextToSpeachLoader::TextToSpeachLoader(QString text, QString language)
: QThread(), text(text), language(language)
{
}
void TextToSpeachLoader::run()
{
QNetworkAccessManager manager;
QEventLoop q;
QTimer tT;
tT.setSingleShot(true);
connect(&tT, &QTimer::timeout, &q, &QEventLoop::quit);
connect(&manager, &QNetworkAccessManager::finished, &q, &QEventLoop::quit);
QString url = "http://api.microsofttranslator.com/V2/Ajax.svc/Speak?appid=%1&language=%2&text=%3&contentType=text/plain";
url = url.arg(APPID, language, text);
QNetworkReply *reply = manager.get(QNetworkRequest(QUrl(url)));
tT.start(5000); // 5s timeout
q.exec();
if (tT.isActive()) {
// download complete
if (reply->error() == QNetworkReply::NoError) {
QString utf8 = QString::fromUtf8(reply->readAll());
utf8 = utf8.remove(0, 1);
utf8 = utf8.remove(utf8.count() - 1, 1);
utf8 = utf8.replace("\\", "");
emit requestFinished(QUrl(utf8));
} else } else
emit error(); emit error();
} else { } else {

View File

@ -1,7 +1,6 @@
#ifndef __TRANSLATOR_H #ifndef __TRANSLATOR_H
#define __TRANSLATOR_H #define __TRANSLATOR_H
class QUrl;
class QMouseEvent; class QMouseEvent;
class QPoint; class QPoint;
class QTextEdit; class QTextEdit;
@ -9,14 +8,13 @@ class QComboBox;
class QLabel; class QLabel;
class QPushButton; class QPushButton;
class YACReaderBusyWidget; class YACReaderBusyWidget;
class QTextToSpeech;
#include <QWidget> #include <QWidget>
#include <QThread> #include <QThread>
#include <QUrl> #include <QUrl>
#include "viewer.h" #include "viewer.h"
class QMediaPlayer;
class YACReaderTranslator : public QWidget class YACReaderTranslator : public QWidget
{ {
Q_OBJECT Q_OBJECT
@ -28,7 +26,6 @@ public slots:
protected slots: protected slots:
void translate(); void translate();
void setSpeak(const QUrl &url);
void setTranslation(const QString &string); void setTranslation(const QString &string);
void error(); void error();
void clear(); void clear();
@ -44,7 +41,9 @@ protected:
QPoint click; QPoint click;
private: private:
QMediaPlayer *player; QTextToSpeech *tts;
QString speakText;
QString speakLocale;
QTextEdit *text; QTextEdit *text;
QComboBox *from; QComboBox *from;
@ -53,7 +52,6 @@ private:
QPushButton *speakButton; QPushButton *speakButton;
QLabel *resultText; QLabel *resultText;
YACReaderBusyWidget *busyIndicator; YACReaderBusyWidget *busyIndicator;
QUrl ttsSource;
QPushButton *clearButton; QPushButton *clearButton;
}; };
@ -74,19 +72,4 @@ private:
void run() override; void run() override;
}; };
class TextToSpeachLoader : public QThread
{
Q_OBJECT
public:
TextToSpeachLoader(QString text, QString language);
signals:
void requestFinished(QUrl);
void timeOut();
void error();
private:
QString text;
QString language;
void run() override;
};
#endif #endif

View File

@ -60,6 +60,7 @@ Source: Qt6QuickTemplates2.dll; DestDir: {app}
Source: Qt6QuickWidgets.dll; DestDir: {app} Source: Qt6QuickWidgets.dll; DestDir: {app}
Source: Qt6Sql.dll; DestDir: {app} Source: Qt6Sql.dll; DestDir: {app}
Source: Qt6Svg.dll; DestDir: {app} Source: Qt6Svg.dll; DestDir: {app}
Source: Qt6TextToSpeech.dll; DestDir: {app}
Source: opengl32sw.dll; DestDir: {app}; Flags: skipifsourcedoesntexist Source: opengl32sw.dll; DestDir: {app}; Flags: skipifsourcedoesntexist
Source: D3Dcompiler_47.dll; DestDir: {app}; Flags: skipifsourcedoesntexist Source: D3Dcompiler_47.dll; DestDir: {app}; Flags: skipifsourcedoesntexist
@ -74,6 +75,7 @@ Source:qml\*; DestDir: {app}\qml\; Flags: recursesubdirs
Source:qmltooling\*; DestDir: {app}\qmltooling\ Source:qmltooling\*; DestDir: {app}\qmltooling\
Source:sqldrivers\qsqlite.dll; DestDir: {app}\sqldrivers\ Source:sqldrivers\qsqlite.dll; DestDir: {app}\sqldrivers\
Source:styles\*; DestDir: {app}\styles\ Source:styles\*; DestDir: {app}\styles\
Source:texttospeech\*; DestDir: {app}\texttospeech\
Source:tls\*; DestDir: {app}\tls\ Source:tls\*; DestDir: {app}\tls\
Source:translations\*; DestDir: {app}\translations\ Source:translations\*; DestDir: {app}\translations\