BibleTime
bttexttospeechsettings.cpp
Go to the documentation of this file.
1/*********
2*
3* In the name of the Father, and of the Son, and of the Holy Spirit.
4*
5* This file is part of BibleTime's source code, https://bibletime.info/
6*
7* Copyright 2025 by the BibleTime developers.
8* The BibleTime source code is licensed under the GNU General Public License
9* version 2.0.
10*
11**********/
12
13#ifdef BUILD_TEXT_TO_SPEECH
14
16
17#include <QComboBox>
18#include <QFormLayout>
19#include <QLabel>
20#include <QLocale>
21#include <QVoice>
22#include "../../backend/config/btconfig.h"
23#include "../../util/btconnect.h"
24#include "../../util/cresmgr.h"
25#include "../bibletime.h"
27
28namespace {
29
30QString formatLocale(const QLocale& locale) {
31 return QObject::tr("%1 (%2)", "Locale language and territory")
32 .arg(QLocale::languageToString(locale.language()),
33 QLocale::territoryToString(locale.territory()));
34}
35
36} // anonymous namespace
37
38BtTextToSpeechSettingsPage::BtTextToSpeechSettingsPage(CConfigurationDialog * parent)
39 : BtConfigDialog::Page(CResMgr::settings::speaker::icon(), parent) {
40
41 auto * const mainLayout = new QVBoxLayout(this);
42 auto * const formLayout = new QFormLayout();
43
44 auto const availableEngines = QTextToSpeech::availableEngines();
45 if (availableEngines.isEmpty()) {
46 m_infoNoPluginsLabel = new QLabel(this);
47 formLayout->addWidget(m_infoNoPluginsLabel);
48 }
49
50 m_ttsEngineLabel = new QLabel(this);
51 m_ttsEngineComboBox = new QComboBox(this);
52 m_ttsEngineLabel->setBuddy(m_ttsEngineComboBox);
53 formLayout->addRow(m_ttsEngineLabel, m_ttsEngineComboBox);
54
55 m_ttsLocaleLabel = new QLabel(this);
56 m_ttsLocaleComboBox = new QComboBox(this);
57 m_ttsLocaleComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
58 m_ttsLocaleLabel->setBuddy(m_ttsLocaleComboBox);
59 formLayout->addRow(m_ttsLocaleLabel, m_ttsLocaleComboBox);
60
61 m_ttsVoiceLabel = new QLabel(this);
62 m_ttsVoiceComboBox = new QComboBox(this);
63 m_ttsVoiceComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
64 m_ttsVoiceLabel->setBuddy(m_ttsVoiceComboBox);
65 formLayout->addRow(m_ttsVoiceLabel, m_ttsVoiceComboBox);
66
67 m_tts = BibleTime::createTextToSpeechInstance();
68
69 m_ttsEngineComboBox->addItems(availableEngines);
70 m_ttsEngineComboBox->setCurrentText(m_tts->engine());
71
72 updateLocales();
73
74 BT_CONNECT(m_ttsEngineComboBox, &QComboBox::currentIndexChanged,
75 this, &BtTextToSpeechSettingsPage::ttsEngineChanged);
76
77 BT_CONNECT(m_ttsLocaleComboBox, &QComboBox::currentIndexChanged,
78 this, &BtTextToSpeechSettingsPage::ttsLocaleChanged);
79
80 mainLayout->addLayout(formLayout);
81
82 retranslateUi();
83}
84
85void BtTextToSpeechSettingsPage::ttsEngineChanged() {
86 m_tts = std::make_unique<QTextToSpeech>(m_ttsEngineComboBox->currentText());
87 updateLocales();
88}
89
90void BtTextToSpeechSettingsPage::updateLocales() {
91 m_ttsLocaleComboBox->clear();
92
93 struct LocaleInfo {
94 QLocale locale;
95 QString displayText;
96 };
97 QList<LocaleInfo> localeInfos;
98 for (auto const & locale : m_tts->availableLocales())
99 localeInfos.push_back({locale, formatLocale(locale)});
100
101 std::sort(localeInfos.begin(), localeInfos.end(),
102 [](auto const & locale1, auto const & locale2) {
103 return QString::localeAwareCompare(locale1.displayText,
104 locale2.displayText) < 0;
105 });
106 for (auto const & localeInfo : std::as_const(localeInfos)) {
107 m_ttsLocaleComboBox->addItem(localeInfo.displayText, localeInfo.locale);
108 if (localeInfo.locale == m_tts->locale())
109 m_ttsLocaleComboBox->setCurrentIndex(m_ttsLocaleComboBox->count() - 1);
110 }
111
112 ttsLocaleChanged();
113}
114
115void BtTextToSpeechSettingsPage::retranslateUi() {
116 setHeaderText(tr("Text-to-speech"));
117 if (m_infoNoPluginsLabel)
118 m_infoNoPluginsLabel->setText(
119 tr("No Qt text-to-speech plug-ins were found. Please install a "
120 "plugin and restart the application."));
121 m_ttsEngineLabel->setText(tr("Text-to-speech engine:"));
122 m_ttsLocaleLabel->setText(tr("Text-to-speech language:"));
123 m_ttsVoiceLabel->setText(tr("Text-to-speech voice:"));
124}
125
126void BtTextToSpeechSettingsPage::ttsLocaleChanged() {
127 m_ttsVoiceComboBox->clear();
128
129 auto const userData = m_ttsLocaleComboBox->currentData();
130 if (!userData.canConvert<QLocale>())
131 return;
132
133 m_tts->setLocale(userData.toLocale());
134
135 for (auto const & voice : m_tts->availableVoices())
136 m_ttsVoiceComboBox->addItem(voice.name());
137
138 m_ttsVoiceComboBox->setCurrentText(m_tts->voice().name());
139}
140
141void BtTextToSpeechSettingsPage::save() const {
142 btConfig().setValue(QStringLiteral("GUI/ttsEngine"),
143 m_ttsEngineComboBox->currentText());
144 btConfig().setValue(QStringLiteral("GUI/ttsLocale"),
145 m_ttsLocaleComboBox->currentData().toLocale());
146 btConfig().setValue(QStringLiteral("GUI/ttsVoice"),
147 m_ttsVoiceComboBox->currentText());
148}
149
150#endif
BtConfig & btConfig()
This is a shortchand for BtConfig::getInstance().
Definition btconfig.h:305
#define BT_CONNECT(...)
Definition btconnect.h:20
void setValue(QString const &key, T const &value)
Sets a value for a key.