[office/crow-translate] /: Add WITH_TTS build option to compile without text-to-speech
Maciej Bonin <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 675d054d8aa9ba42c3d710697d8f80823304a300 by Maciej Bonin, on behalf of Mauritius Clemens.
Committed on 16/08/2026 at 15:13.
Pushed by pillowtrucker into branch 'master'.
Add WITH_TTS build option to compile without text-to-speech
WITH_TTS=OFF drops the Mozhi and Qt TTS providers and the Qt6TextToSpeech
link dependency, leaving the Noop provider only; the play/pause/stop buttons
and voice/speaker combos are hidden in the main window and the popup, and the
TTS group in the settings dialog is hidden, giving back the compact pre-TTS
UI. WITH_PIPER_TTS now requires WITH_TTS.
Choosing the None provider at runtime likewise hides the playback controls.
M +17 -5 CMakeLists.txt
M +10 -3 src/cli.cpp
M +21 -0 src/mainwindow.cpp
M +4 -0 src/popupwindow.cpp
M +6 -0 src/settings/settingsdialog.cpp
M +5 -1 src/tts/attsprovider.cpp
https://invent.kde.org/office/crow-translate/-/commit/675d054d8aa9ba42c3d710697d8f80823304a300
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 436bbffe..6f262b0c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -72,6 +72,7 @@ endif()
option(WITH_KWAYLAND "Use KWayland for better Wayland integration" ON)
option(WITH_PIPER_TTS "Enable Piper neural TTS provider (requires onnxruntime and espeak-ng)" ON)
+option(WITH_TTS "Enable text-to-speech support (Mozhi and Qt providers, plus Piper if WITH_PIPER_TTS)" ON)
if(CMAKE_EXPORT_COMPILE_COMMANDS AND DEFINED ENV{NIX_CFLAGS_COMPILE})
@@ -213,10 +214,6 @@ add_library(${PROJECT_NAME}-lib STATIC
src/tts/voice.cpp
src/translator/atranslationprovider.h
src/translator/atranslationprovider.cpp
- src/tts/qtttsprovider.h
- src/tts/qtttsprovider.cpp
- src/tts/mozhittsprovider.h
- src/tts/mozhittsprovider.cpp
src/tts/noopttsprovider.h
src/tts/noopttsprovider.cpp
src/translator/copytranslationprovider.h
@@ -294,6 +291,20 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}-lib)
# Note: ONNX Runtime configuration moved after find_package(ONNXRuntime) below
# Handle espeak-ng submodule for Piper TTS
+if(WITH_TTS)
+ target_sources(${PROJECT_NAME}-lib PRIVATE
+ src/tts/qtttsprovider.h
+ src/tts/qtttsprovider.cpp
+ src/tts/mozhittsprovider.h
+ src/tts/mozhittsprovider.cpp
+ )
+ target_compile_definitions(${PROJECT_NAME}-lib PUBLIC WITH_TTS)
+else()
+ if(WITH_PIPER_TTS)
+ message(FATAL_ERROR "WITH_PIPER_TTS requires WITH_TTS")
+ endif()
+endif()
+
if(WITH_PIPER_TTS)
# Build espeak-ng from submodule
set(ESPEAKNG_BUILD_DIR ${CMAKE_BINARY_DIR}/espeak_ng)
@@ -429,9 +440,10 @@ target_link_libraries(${PROJECT_NAME}-lib PUBLIC
Qt6::Concurrent
Qt6::StateMachine
Tesseract::Tesseract
- Qt6::TextToSpeech
)
+target_link_libraries(${PROJECT_NAME}-lib PUBLIC Qt6::TextToSpeech)
+
# Link Piper dependencies if enabled
if(WITH_PIPER_TTS)
if(NOT ONNXRuntime_USE_STATIC)
diff --git a/src/cli.cpp b/src/cli.cpp
index 5b0bf240..c5a9072d 100644
--- a/src/cli.cpp
+++ b/src/cli.cpp
@@ -248,13 +248,20 @@ void Cli::process(const QCoreApplication &app)
const QString providerName = parser.value(ttsProvider).toLower();
if (providerName == "none") {
ttsBackend = ATTSProvider::ProviderBackend::None;
- } else if (providerName == "mozhi") {
+ }
+#ifdef WITH_TTS
+ else if (providerName == "mozhi") {
ttsBackend = ATTSProvider::ProviderBackend::Mozhi;
} else if (providerName == "qt") {
ttsBackend = ATTSProvider::ProviderBackend::Qt;
- } else if (providerName == "piper") {
+ }
+#endif
+#ifdef WITH_PIPER_TTS
+ else if (providerName == "piper") {
ttsBackend = ATTSProvider::ProviderBackend::Piper;
- } else {
+ }
+#endif
+ else {
qCritical() << tr("Error: Unknown TTS provider '%1'").arg(providerName) << '\n';
parser.showHelp(1);
}
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 021a4808..a6486ad9 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -1402,7 +1402,28 @@ void MainWindow::updateProviderUI()
ui->translationVoiceComboBox->setVisible(ttsReqs.requiredUIElements.contains("translationVoiceComboBox"));
ui->sourceSpeakerComboBox->setVisible(ttsReqs.requiredUIElements.contains("sourceSpeakerComboBox"));
ui->translationSpeakerComboBox->setVisible(ttsReqs.requiredUIElements.contains("translationSpeakerComboBox"));
+
+ // Hide playback controls entirely when the provider has no TTS UI (e.g. None)
+ const bool hasVoiceUI = !ttsReqs.requiredUIElements.isEmpty();
+ ui->sourcePlayPauseButton->setVisible(hasVoiceUI);
+ ui->sourceStopButton->setVisible(hasVoiceUI);
+ ui->translationPlayPauseButton->setVisible(hasVoiceUI);
+ ui->translationStopButton->setVisible(hasVoiceUI);
+ }
+#ifndef WITH_TTS
+ // Built without TTS support: no provider other than "None" exists, hide all TTS UI
+ for (QWidget *w : {static_cast<QWidget *>(ui->sourcePlayPauseButton),
+ static_cast<QWidget *>(ui->sourceStopButton),
+ static_cast<QWidget *>(ui->translationPlayPauseButton),
+ static_cast<QWidget *>(ui->translationStopButton),
+ static_cast<QWidget *>(ui->sourceVoiceComboBox),
+ static_cast<QWidget *>(ui->translationVoiceComboBox),
+ static_cast<QWidget *>(ui->sourceSpeakerComboBox),
+ static_cast<QWidget *>(ui->translationSpeakerComboBox)}) {
+ w->setVisible(false);
+ w->setEnabled(false);
}
+#endif
}
void MainWindow::updateVoiceComboBoxes()
diff --git a/src/popupwindow.cpp b/src/popupwindow.cpp
index a26712e8..201db679 100644
--- a/src/popupwindow.cpp
+++ b/src/popupwindow.cpp
@@ -50,15 +50,19 @@ PopupWindow::PopupWindow(MainWindow *parent)
// TTS buttons - copy icons and connect to MainWindow TTS methods
if (parent->sourcePlayPauseButton() != nullptr) {
ui->sourcePlayPauseButton->setIcon(parent->sourcePlayPauseButton()->icon());
+ ui->sourcePlayPauseButton->setVisible(parent->sourcePlayPauseButton()->isVisible());
}
if (parent->sourceStopButton() != nullptr) {
ui->sourceStopButton->setIcon(parent->sourceStopButton()->icon());
+ ui->sourceStopButton->setVisible(parent->sourceStopButton()->isVisible());
}
if (parent->translationPlayPauseButton() != nullptr) {
ui->translationPlayPauseButton->setIcon(parent->translationPlayPauseButton()->icon());
+ ui->translationPlayPauseButton->setVisible(parent->translationPlayPauseButton()->isVisible());
}
if (parent->translationStopButton() != nullptr) {
ui->translationStopButton->setIcon(parent->translationStopButton()->icon());
+ ui->translationStopButton->setVisible(parent->translationStopButton()->isVisible());
}
connect(ui->sourcePlayPauseButton, &QToolButton::clicked, parent, &MainWindow::sourcePlayPauseClicked);
connect(ui->sourceStopButton, &QToolButton::clicked, parent, &MainWindow::sourceStopClicked);
diff --git a/src/settings/settingsdialog.cpp b/src/settings/settingsdialog.cpp
index 0be92c80..7f4fbd64 100644
--- a/src/settings/settingsdialog.cpp
+++ b/src/settings/settingsdialog.cpp
@@ -152,8 +152,10 @@ SettingsDialog::SettingsDialog(MainWindow *parent)
// Populate TTS providers dynamically
ui->ttsProviderComboBox->addItem(tr("None"), QVariant::fromValue(ATTSProvider::ProviderBackend::None));
+#ifdef WITH_TTS
ui->ttsProviderComboBox->addItem("Mozhi", QVariant::fromValue(ATTSProvider::ProviderBackend::Mozhi));
ui->ttsProviderComboBox->addItem("Qt", QVariant::fromValue(ATTSProvider::ProviderBackend::Qt));
+#endif
#ifdef WITH_PIPER_TTS
ui->ttsProviderComboBox->addItem("Piper", QVariant::fromValue(ATTSProvider::ProviderBackend::Piper));
#endif
@@ -161,6 +163,10 @@ SettingsDialog::SettingsDialog(MainWindow *parent)
#ifdef WITH_PIPER_TTS
setupPiperVoicesPathUI();
#endif
+#ifndef WITH_TTS
+ // Built without TTS support: hide the whole TTS group box
+ ui->ttsGroupBox->setVisible(false);
+#endif
// Sort languages in comboboxes alphabetically
ui->primaryLangComboBox->model()->sort(0);
diff --git a/src/tts/attsprovider.cpp b/src/tts/attsprovider.cpp
index e5cd5dcb..caf8671f 100644
--- a/src/tts/attsprovider.cpp
+++ b/src/tts/attsprovider.cpp
@@ -5,9 +5,11 @@
#include "attsprovider.h"
-#include "tts/mozhittsprovider.h"
#include "tts/noopttsprovider.h"
+#ifdef WITH_TTS
+#include "tts/mozhittsprovider.h"
#include "tts/qtttsprovider.h"
+#endif
#ifdef WITH_PIPER_TTS
#include "tts/piperttsprovider.h"
#endif
@@ -24,10 +26,12 @@ ATTSProvider *ATTSProvider::createTTSProvider(QObject *parent, ATTSProvider::Pro
switch (chosenBackend) {
case ProviderBackend::None:
return new NoopTTSProvider(parent);
+#ifdef WITH_TTS
case ProviderBackend::Qt:
return new QtTTSProvider(parent);
case ProviderBackend::Mozhi:
return new MozhiTTSProvider(parent);
+#endif
case ProviderBackend::Piper:
#ifdef WITH_PIPER_TTS
return new PiperTTSProvider(parent);