1 /*
2     SPDX-FileCopyrightText: 2008 Pino Toscano <pino@kde.org>
3 
4     SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "tts.h"
8 
9 #include <QSet>
10 
11 #include <KLocalizedString>
12 
13 #include "settings.h"
14 
15 /* Private storage. */
16 class OkularTTS::Private
17 {
18 public:
Private(OkularTTS * qq)19     explicit Private(OkularTTS *qq)
20         : q(qq)
21         , speech(new QTextToSpeech(Okular::Settings::ttsEngine()))
22     {
23     }
24 
~Private()25     ~Private()
26     {
27         delete speech;
28         speech = nullptr;
29     }
30 
31     OkularTTS *q;
32     QTextToSpeech *speech;
33     // Which speech engine was used when above object was created.
34     // When the setting changes, we need to stop speaking and recreate.
35     QString speechEngine;
36 };
37 
OkularTTS(QObject * parent)38 OkularTTS::OkularTTS(QObject *parent)
39     : QObject(parent)
40     , d(new Private(this))
41 {
42     // Initialize speechEngine so we can reinitialize if it changes.
43     d->speechEngine = Okular::Settings::ttsEngine();
44     connect(d->speech, &QTextToSpeech::stateChanged, this, &OkularTTS::slotSpeechStateChanged);
45     connect(Okular::Settings::self(), &KConfigSkeleton::configChanged, this, &OkularTTS::slotConfigChanged);
46 }
47 
~OkularTTS()48 OkularTTS::~OkularTTS()
49 {
50     delete d;
51 }
52 
say(const QString & text)53 void OkularTTS::say(const QString &text)
54 {
55     if (text.isEmpty())
56         return;
57 
58     d->speech->say(text);
59 }
60 
stopAllSpeechs()61 void OkularTTS::stopAllSpeechs()
62 {
63     if (!d->speech)
64         return;
65 
66     d->speech->stop();
67 }
68 
pauseResumeSpeech()69 void OkularTTS::pauseResumeSpeech()
70 {
71     if (!d->speech)
72         return;
73 
74     if (d->speech->state() == QTextToSpeech::Speaking)
75         d->speech->pause();
76     else
77         d->speech->resume();
78 }
79 
slotSpeechStateChanged(QTextToSpeech::State state)80 void OkularTTS::slotSpeechStateChanged(QTextToSpeech::State state)
81 {
82     if (state == QTextToSpeech::Speaking) {
83         emit isSpeaking(true);
84         emit canPauseOrResume(true);
85     } else {
86         emit isSpeaking(false);
87         if (state == QTextToSpeech::Paused)
88             emit canPauseOrResume(true);
89         else
90             emit canPauseOrResume(false);
91     }
92 }
93 
slotConfigChanged()94 void OkularTTS::slotConfigChanged()
95 {
96     const QString engine = Okular::Settings::ttsEngine();
97     if (engine != d->speechEngine) {
98         d->speech->stop();
99         delete d->speech;
100         d->speech = new QTextToSpeech(engine);
101         connect(d->speech, &QTextToSpeech::stateChanged, this, &OkularTTS::slotSpeechStateChanged);
102         d->speechEngine = engine;
103     }
104 }
105