File indexing completed on 2024-04-28 16:00:58

0001 /*
0002    SPDX-FileCopyrightText: 2014-2023 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 #endif
0094         break;
0095     }
0096     Q_EMIT stateChanged(state);
0097 }
0098 
0099 bool TextToSpeech::isReady() const
0100 {
0101 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0102     return d->mTextToSpeech->state() != QTextToSpeech::BackendError;
0103 #else
0104     return d->mTextToSpeech->state() != QTextToSpeech::Error;
0105 #endif
0106 }
0107 
0108 void TextToSpeech::say(const QString &text)
0109 {
0110     d->mTextToSpeech->say(text);
0111 }
0112 
0113 void TextToSpeech::stop()
0114 {
0115     d->mTextToSpeech->stop();
0116 }
0117 
0118 void TextToSpeech::pause()
0119 {
0120     d->mTextToSpeech->pause();
0121 }
0122 
0123 void TextToSpeech::resume()
0124 {
0125     d->mTextToSpeech->resume();
0126 }
0127 
0128 void TextToSpeech::setRate(double rate)
0129 {
0130     d->mTextToSpeech->setRate(rate);
0131 }
0132 
0133 void TextToSpeech::setPitch(double pitch)
0134 {
0135     d->mTextToSpeech->setPitch(pitch);
0136 }
0137 
0138 void TextToSpeech::setVolume(double volume)
0139 {
0140     d->mTextToSpeech->setVolume(volume);
0141 }
0142 
0143 double TextToSpeech::volume() const
0144 {
0145     return d->mTextToSpeech->volume();
0146 }
0147 
0148 QVector<QLocale> TextToSpeech::availableLocales() const
0149 {
0150     return d->mTextToSpeech->availableLocales();
0151 }
0152 
0153 QStringList TextToSpeech::availableVoices() const
0154 {
0155     QStringList lst;
0156     const QVector<QVoice> voices = d->mTextToSpeech->availableVoices();
0157     lst.reserve(voices.count());
0158     for (const QVoice &voice : voices) {
0159         lst << voice.name();
0160     }
0161     return lst;
0162 }
0163 
0164 QStringList TextToSpeech::availableEngines() const
0165 {
0166     return QTextToSpeech::availableEngines();
0167 }
0168 
0169 void TextToSpeech::setLocale(const QLocale &locale) const
0170 {
0171     d->mTextToSpeech->setLocale(locale);
0172 }
0173 
0174 QLocale TextToSpeech::locale() const
0175 {
0176     return d->mTextToSpeech->locale();
0177 }
0178 
0179 #include "moc_texttospeech.cpp"