File indexing completed on 2024-05-12 12:43:09
0001 /* 0002 SPDX-FileCopyrightText: 2014-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "texttospeech.h" 0008 #include "texttospeechutil.h" 0009 0010 #include <KConfig> 0011 #include <KConfigGroup> 0012 #include <QLocale> 0013 #include <QTextToSpeech> 0014 #include <QVector> 0015 0016 class TextEditTextToSpeech::TextToSpeechPrivate 0017 { 0018 public: 0019 QString mDefaultEngine; 0020 QTextToSpeech *mTextToSpeech = nullptr; 0021 }; 0022 0023 using namespace TextEditTextToSpeech; 0024 TextToSpeech::TextToSpeech(QObject *parent) 0025 : QObject(parent) 0026 , d(new TextEditTextToSpeech::TextToSpeechPrivate) 0027 { 0028 reloadSettings(); 0029 } 0030 0031 TextToSpeech::~TextToSpeech() = default; 0032 0033 void TextToSpeech::reloadSettings() 0034 { 0035 const TextEditTextToSpeech::TextToSpeechUtil::TextToSpeechSettings settings = TextEditTextToSpeech::TextToSpeechUtil::loadSettings(); 0036 0037 const QString engineName = settings.engineName; 0038 if (d->mDefaultEngine != engineName) { 0039 if (d->mTextToSpeech) { 0040 #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) 0041 if (d->mTextToSpeech && (d->mTextToSpeech->engine() != engineName)) 0042 #endif 0043 { 0044 disconnect(d->mTextToSpeech, &QTextToSpeech::stateChanged, this, &TextToSpeech::slotStateChanged); 0045 delete d->mTextToSpeech; 0046 d->mTextToSpeech = nullptr; 0047 } 0048 } 0049 } 0050 if (!d->mTextToSpeech) { 0051 d->mTextToSpeech = new QTextToSpeech(engineName, this); 0052 connect(d->mTextToSpeech, &QTextToSpeech::stateChanged, this, &TextToSpeech::slotStateChanged); 0053 } 0054 d->mDefaultEngine = engineName; 0055 const int rate = settings.rate; 0056 const double rateDouble = rate / 100.0; 0057 d->mTextToSpeech->setRate(rateDouble); 0058 const int pitch = settings.pitch; 0059 const double pitchDouble = pitch / 100.0; 0060 d->mTextToSpeech->setPitch(pitchDouble); 0061 const int volumeValue = settings.volumeValue; 0062 const double volumeDouble = volumeValue / 100.0; 0063 d->mTextToSpeech->setVolume(volumeDouble); 0064 d->mTextToSpeech->setLocale(QLocale(settings.localeName)); 0065 // It doesn't have api for it d->mTextToSpeech->setVoice(grp.readEntry("voice")); 0066 } 0067 0068 TextToSpeech *TextToSpeech::self() 0069 { 0070 static TextToSpeech s_self; 0071 return &s_self; 0072 } 0073 0074 void TextToSpeech::slotStateChanged() 0075 { 0076 TextToSpeech::State state; 0077 switch (d->mTextToSpeech->state()) { 0078 case QTextToSpeech::Ready: 0079 state = TextToSpeech::Ready; 0080 break; 0081 case QTextToSpeech::Speaking: 0082 state = TextToSpeech::Speaking; 0083 break; 0084 case QTextToSpeech::Paused: 0085 state = TextToSpeech::Paused; 0086 break; 0087 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0088 case QTextToSpeech::BackendError: 0089 state = TextToSpeech::BackendError; 0090 #else 0091 case QTextToSpeech::Error: 0092 state = TextToSpeech::BackendError; 0093 break; 0094 case QTextToSpeech::Synthesizing: 0095 state = TextToSpeech::Synthesizing; 0096 break; 0097 #endif 0098 } 0099 Q_EMIT stateChanged(state); 0100 } 0101 0102 bool TextToSpeech::isReady() const 0103 { 0104 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0105 return d->mTextToSpeech->state() != QTextToSpeech::BackendError; 0106 #else 0107 return d->mTextToSpeech->state() != QTextToSpeech::Error; 0108 #endif 0109 } 0110 0111 void TextToSpeech::say(const QString &text) 0112 { 0113 d->mTextToSpeech->say(text); 0114 } 0115 0116 void TextToSpeech::stop() 0117 { 0118 d->mTextToSpeech->stop(); 0119 } 0120 0121 void TextToSpeech::pause() 0122 { 0123 d->mTextToSpeech->pause(); 0124 } 0125 0126 void TextToSpeech::resume() 0127 { 0128 d->mTextToSpeech->resume(); 0129 } 0130 0131 void TextToSpeech::setRate(double rate) 0132 { 0133 d->mTextToSpeech->setRate(rate); 0134 } 0135 0136 void TextToSpeech::setPitch(double pitch) 0137 { 0138 d->mTextToSpeech->setPitch(pitch); 0139 } 0140 0141 void TextToSpeech::setVolume(double volume) 0142 { 0143 d->mTextToSpeech->setVolume(volume); 0144 } 0145 0146 double TextToSpeech::volume() const 0147 { 0148 return d->mTextToSpeech->volume(); 0149 } 0150 0151 QVector<QLocale> TextToSpeech::availableLocales() const 0152 { 0153 return d->mTextToSpeech->availableLocales(); 0154 } 0155 0156 QStringList TextToSpeech::availableVoices() const 0157 { 0158 QStringList lst; 0159 const QVector<QVoice> voices = d->mTextToSpeech->availableVoices(); 0160 lst.reserve(voices.count()); 0161 for (const QVoice &voice : voices) { 0162 lst << voice.name(); 0163 } 0164 return lst; 0165 } 0166 0167 QStringList TextToSpeech::availableEngines() const 0168 { 0169 return QTextToSpeech::availableEngines(); 0170 } 0171 0172 void TextToSpeech::setLocale(const QLocale &locale) const 0173 { 0174 d->mTextToSpeech->setLocale(locale); 0175 } 0176 0177 QLocale TextToSpeech::locale() const 0178 { 0179 return d->mTextToSpeech->locale(); 0180 } 0181 0182 #include "moc_texttospeech.cpp"