diff --git a/conf/okular.kcfg b/conf/okular.kcfg
index 66d667571..172e4780f 100644
--- a/conf/okular.kcfg
+++ b/conf/okular.kcfg
@@ -207,6 +207,9 @@
speechd
+
+
+
true
diff --git a/part/dlgaccessibility.cpp b/part/dlgaccessibility.cpp
index 46ab63209..67b70dcc5 100644
--- a/part/dlgaccessibility.cpp
+++ b/part/dlgaccessibility.cpp
@@ -147,19 +147,42 @@ DlgAccessibility::DlgAccessibility(QWidget *parent)
layout->addRow(new QLabel(this));
// BEGIN Text-to-speech section
- QComboBox *ttsEngine = new QComboBox(this);
+ m_ttsEngineBox = new QComboBox(this);
// Populate tts engines and use their names directly as key and item text:
const QStringList engines = QTextToSpeech::availableEngines();
for (const QString &engine : engines) {
- ttsEngine->addItem(engine);
+ m_ttsEngineBox->addItem(engine);
}
- ttsEngine->setProperty("kcfg_property", QByteArray("currentText"));
- ttsEngine->setObjectName(QStringLiteral("kcfg_ttsEngine"));
- layout->addRow(i18nc("@label:listbox Config dialog, accessibility page", "Text-to-speech engine:"), ttsEngine);
+ m_ttsEngineBox->setProperty("kcfg_property", QByteArray("currentText"));
+ m_ttsEngineBox->setObjectName(QStringLiteral("kcfg_ttsEngine"));
+ layout->addRow(i18nc("@label:listbox Config dialog, accessibility page", "Text-to-speech engine:"), m_ttsEngineBox);
+
+ connect(m_ttsEngineBox, qOverload(&QComboBox::currentIndexChanged), this, &DlgAccessibility::slotTTSEngineChanged);
+
+ m_ttsVoiceBox = new QComboBox(this);
+ m_ttsVoiceBox->setProperty("kcfg_property", QByteArray("currentText"));
+ m_ttsVoiceBox->setObjectName(QStringLiteral("kcfg_ttsVoice"));
+ layout->addRow(i18nc("&label:listbox Config dialog, accessibility page", "Text-to-speech voice:"), m_ttsVoiceBox);
+
+ slotTTSEngineChanged();
// END Text-to-speech section
#endif
}
+#ifdef HAVE_SPEECH
+void DlgAccessibility::slotTTSEngineChanged()
+{
+ QString engine = m_ttsEngineBox->currentText();
+ QTextToSpeech *ttsEngine = new QTextToSpeech(engine);
+ const QVector voices = ttsEngine->availableVoices();
+ m_ttsVoiceBox->clear();
+ for (const QVoice &voice : voices) {
+ m_ttsVoiceBox->addItem(voice.name());
+ }
+ delete ttsEngine;
+}
+#endif
+
void DlgAccessibility::slotColorModeSelected(int mode)
{
if (mode == Okular::Settings::EnumRenderMode::Paper) {
diff --git a/part/dlgaccessibility.h b/part/dlgaccessibility.h
index 302475869..8789a7a79 100644
--- a/part/dlgaccessibility.h
+++ b/part/dlgaccessibility.h
@@ -9,6 +9,7 @@
#include
+class QComboBox;
class QStackedWidget;
class DlgAccessibility : public QWidget
@@ -20,9 +21,16 @@ public:
protected Q_SLOTS:
void slotColorModeSelected(int mode);
+#ifdef HAVE_SPEECH
+ void slotTTSEngineChanged();
+#endif
protected:
QStackedWidget *m_colorModeConfigStack;
+#ifdef HAVE_SPEECH
+ QComboBox *m_ttsEngineBox;
+ QComboBox *m_ttsVoiceBox;
+#endif
};
#endif
diff --git a/part/tts.cpp b/part/tts.cpp
index 6357c70ef..11b4376ab 100644
--- a/part/tts.cpp
+++ b/part/tts.cpp
@@ -20,6 +20,13 @@ public:
: q(qq)
, speech(new QTextToSpeech(Okular::Settings::ttsEngine()))
{
+ const QVector voices = speech->availableVoices();
+ QString voiceName = Okular::Settings::ttsVoice();
+ for (const QVoice &voice : voices) {
+ if (voice.name() == voiceName) {
+ speech->setVoice(voice);
+ }
+ }
}
~Private()
@@ -42,7 +49,7 @@ OkularTTS::OkularTTS(QObject *parent)
// Initialize speechEngine so we can reinitialize if it changes.
d->speechEngine = Okular::Settings::ttsEngine();
connect(d->speech, &QTextToSpeech::stateChanged, this, &OkularTTS::slotSpeechStateChanged);
- connect(Okular::Settings::self(), &KConfigSkeleton::configChanged, this, &OkularTTS::slotConfigChanged);
+ connect(Okular::Settings::self(), &KCoreConfigSkeleton::configChanged, this, &OkularTTS::slotConfigChanged);
}
OkularTTS::~OkularTTS()
@@ -94,6 +101,7 @@ void OkularTTS::slotSpeechStateChanged(QTextToSpeech::State state)
void OkularTTS::slotConfigChanged()
{
const QString engine = Okular::Settings::ttsEngine();
+ const QString voiceName = Okular::Settings::ttsVoice();
if (engine != d->speechEngine) {
d->speech->stop();
delete d->speech;
@@ -101,4 +109,12 @@ void OkularTTS::slotConfigChanged()
connect(d->speech, &QTextToSpeech::stateChanged, this, &OkularTTS::slotSpeechStateChanged);
d->speechEngine = engine;
}
+
+ const QVector voices = d->speech->availableVoices();
+ for (const QVoice &voice : voices) {
+ if (voice.name() == voiceName) {
+ d->speech->setVoice(voice);
+ break;
+ }
+ }
}