[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);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.