1
From: Modestas Vainius <modax@debian.org>
2
Subject: Properly support permanent storage of kttsd talker settings, jobmgr fixes.
4
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=599825
5
Last-Update: 2010-12-04
8
This patch builds on top of the upstream jobmgr patch (commits 1072198,
11
1) adds support for permanent storage (to config file) of talker settings in
12
both KTTS daemon and its configuration GUI. This includes saving and loading of
14
2) brings job manager GUI to a usable state rather than half-ported and hardly
15
working bunch of GUI elements. Not entirely bug-free, but usable (i.e. should
18
--- a/kcmkttsmgr/kcmkttsmgr.cpp
19
+++ b/kcmkttsmgr/kcmkttsmgr.cpp
20
@@ -498,6 +498,10 @@ void KCMKttsMgr::load()
23
m_suppressConfigChanged = false;
25
+ // load the first talker into job manager
26
+ if (m_jobMgrWidget && m_talkerListModel.rowCount() > 0)
27
+ m_jobMgrWidget->load(m_talkerListModel.getRow(0));
31
@@ -592,12 +596,16 @@ void KCMKttsMgr::save()
35
- // apply changes in the jobs page if it exists
36
+ // schedule apply of the changes in the jobs page once kttsd restarts
39
- m_jobMgrWidget->save();
40
+ m_jobMgrWidget->setSavePending(true);
41
+ //m_jobMgrWidget->save();
44
+ // Restart kttsd in order to pick up talker changes from config file
45
+ m_kspeech->reinit();
47
// If we automatically unchecked the Enable KTTSD checkbox, stop KTTSD.
48
if (enableKttsdWasToggled)
49
slotEnableKttsd_toggled(false);
50
@@ -1033,6 +1041,9 @@ void KCMKttsMgr::updateTalkerButtons(){
51
configureTalkerButton->setEnabled(true);
52
higherTalkerPriorityButton->setEnabled(modelIndex.row() != 0);
53
lowerTalkerPriorityButton->setEnabled(modelIndex.row() < (m_talkerListModel.rowCount() - 1));
54
+ // Update output module and language in jobMgrWidget
56
+ m_jobMgrWidget->load(m_talkerListModel.getRow(modelIndex.row()));
58
removeTalkerButton->setEnabled(false);
59
configureTalkerButton->setEnabled(false);
60
@@ -1140,6 +1151,13 @@ void KCMKttsMgr::kttsdStarted()
61
// Check/Uncheck the Enable KTTSD check box.
64
+ bool reinit = false;
65
+ if (m_kspeech) { // already connected, reinit called
67
+ disconnect( QDBusConnection::sessionBus().interface(), 0, this, 0 );
71
enableKttsdCheckBox->setChecked(true);
72
m_kspeech = new OrgKdeKSpeechInterface("org.kde.kttsd", "/KSpeech", QDBusConnection::sessionBus());
73
m_kspeech->setParent(this);
74
@@ -1157,6 +1175,8 @@ void KCMKttsMgr::kttsdStarted()
76
kttsdVersion->setText(i18n("KTTSD Version: %1", m_kspeech->version()));
79
+ m_jobMgrWidget->load(TalkerCode());
81
enableKttsdCheckBox->setChecked(false);
83
--- a/kcmkttsmgr/kttsjobmgr.cpp
84
+++ b/kcmkttsmgr/kttsjobmgr.cpp
86
#include "selecttalkerdlg.h"
88
KttsJobMgr::KttsJobMgr(QWidget *parent) :
91
+ m_savePending(false)
93
m_ui = new Ui::kttsjobmgr;
95
@@ -77,7 +78,7 @@ KttsJobMgr::KttsJobMgr(QWidget *parent)
96
connect (m_ui->volumeSlider, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
98
connect (m_ui->moduleComboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(slot_moduleChanged(const QString &)));
99
- connect (m_ui->languageComboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(slot_languageChanged(const QString &)));
100
+ connect (m_ui->languageComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slot_languageChanged(int)));
101
connect (m_ui->voiceComboBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
103
m_ui->stopButton->setIcon(KIcon("media-playback-stop"));
104
@@ -139,25 +140,104 @@ void KttsJobMgr::slot_resume()
106
void KttsJobMgr::save()
108
+ if (m_ui->moduleComboBox->currentIndex() > -1)
109
+ m_kspeech->setOutputModule(m_ui->moduleComboBox->currentText());
110
+ if (m_ui->languageComboBox->currentIndex() > -1)
112
+ int langIndex = m_ui->languageComboBox->currentIndex();
113
+ m_kspeech->setLanguage(m_ui->languageComboBox->itemData(langIndex).toString());
115
m_kspeech->setSpeed(m_ui->speedSlider->value());
116
m_kspeech->setPitch(m_ui->pitchSlider->value());
117
m_kspeech->setVolume(m_ui->volumeSlider->value());
118
m_kspeech->setVoiceType(m_ui->voiceComboBox->currentIndex() + 1);
120
+ m_savePending = false;
123
+void KttsJobMgr::load(const TalkerCode & tc, bool complete)
125
+ m_ui->moduleComboBox->clear();
126
+ bool wasSet = false;
127
+ QStringList modules = m_kspeech->outputModules();
130
+ foreach (const QString module, modules)
132
+ m_ui->moduleComboBox->addItem(module);
133
+ if (module == tc.outputModule())
135
+ m_ui->moduleComboBox->setCurrentIndex(i);
143
+ loadLanguages(tc.language());
144
+ m_ui->voiceComboBox->setCurrentIndex(tc.voiceType()-1);
145
+ m_ui->speedSlider->setValue(tc.rate());
146
+ m_ui->pitchSlider->setValue(tc.pitch());
147
+ m_ui->volumeSlider->setValue(tc.volume());
152
+ m_ui->moduleComboBox->setCurrentIndex(-1);
156
-void KttsJobMgr::load()
157
+void KttsJobMgr::loadLanguages(const QString & selectedLanguage)
159
+ QString module = m_ui->moduleComboBox->currentText();
160
+ m_ui->languageComboBox->clear();
161
+ if (!module.isEmpty())
164
+ bool wasSet = false;
165
+ QStringList languages = m_kspeech->languagesByModule(module);
166
+ foreach (const QString language, languages)
168
+ QString langName = TalkerCode::languageCodeToLanguage(language);
169
+ QString langLabel = (langName.isEmpty()) ? language :
170
+ QString("%1 (%2)").arg(langName).arg(language);
171
+ m_ui->languageComboBox->addItem(langLabel, language);
172
+ if (language == selectedLanguage)
174
+ m_ui->languageComboBox->setCurrentIndex(i);
179
+ if (!wasSet) m_ui->languageComboBox->setCurrentIndex(-1);
183
void KttsJobMgr::slot_moduleChanged(const QString & module)
185
+ if (module.isEmpty()) {
186
+ m_ui->languageComboBox->clear();
190
kDebug() << "changing the output module to " << module;
191
m_kspeech->setOutputModule(module);
193
+ QString fullLanguageCode = KGlobal::locale()->defaultLanguage();
194
+ QString languageCode, countryCode;
195
+ TalkerCode::splitFullLanguageCode(fullLanguageCode, languageCode, countryCode);
196
+ loadLanguages(languageCode);
198
emit configChanged();
201
-void KttsJobMgr::slot_languageChanged(const QString & language)
202
+void KttsJobMgr::slot_languageChanged(int index)
207
+ QString language = m_ui->languageComboBox->itemData(index).toString();
208
kDebug() << "changing the language to " << language;
209
m_kspeech->setLanguage(language);
210
emit configChanged();
211
@@ -261,6 +341,16 @@ QString KttsJobMgr::cachedTalkerCodeToTa
215
+void KttsJobMgr::setSavePending(bool value)
217
+ m_savePending = value;
220
+bool KttsJobMgr::isSavePending()
222
+ return m_savePending;
225
/** Slots connected to DBUS Signals emitted by KTTSD. */
228
@@ -268,4 +358,6 @@ QString KttsJobMgr::cachedTalkerCodeToTa
230
Q_SCRIPTABLE void KttsJobMgr::kttsdStarted()
232
+ if (isSavePending())
235
--- a/kcmkttsmgr/kttsjobmgr.h
236
+++ b/kcmkttsmgr/kttsjobmgr.h
237
@@ -37,6 +37,7 @@ class KPushButton;
238
class KttsJobMgrBrowserExtension;
240
class JobInfoListModel;
245
@@ -54,7 +55,10 @@ public:
246
/** apply current settings, i.e. speech-dispatcher what to do */
248
/** get the current settings from speech-dispatcher */
250
+ void load(const TalkerCode & tc, bool complete = true);
252
+ void setSavePending(bool value);
253
+ bool isSavePending();
256
void configChanged();
257
@@ -83,7 +87,7 @@ private slots:
260
void slot_moduleChanged(const QString & module);
261
- void slot_languageChanged(const QString & language);
262
+ void slot_languageChanged(int index);
266
@@ -98,6 +102,8 @@ private:
268
QString cachedTalkerCodeToTalkerID(const QString& talkerCode);
270
+ void loadLanguages(const QString & selectedLanguage);
275
@@ -107,6 +113,8 @@ private:
276
* Cache mapping Talker Codes to Talker IDs.
278
QMap<QString,QString> m_talkerCodesToTalkerIDs;
280
+ bool m_savePending;
283
#endif // KTTSJOBMGR_H
284
--- a/kttsd/kspeech.cpp
285
+++ b/kttsd/kspeech.cpp
286
@@ -436,6 +436,7 @@ void KSpeech::init()
287
new KSpeechAdaptor(this);
289
QDBusConnection::sessionBus().registerObject("/KSpeech", this, QDBusConnection::ExportAdaptors);
290
+ emit kttsdStarted();
294
@@ -450,6 +451,7 @@ void KSpeech::reinit()
295
QDBusConnection::sessionBus().unregisterObject("/KSpeech");
297
QDBusConnection::sessionBus().registerObject("/KSpeech", this, QDBusConnection::ExportAdaptors);
298
+ emit kttsdStarted();
302
@@ -477,7 +479,6 @@ bool KSpeech::ready()
303
if (!initializeSpeaker())
305
announceEvent("ready", "kttsdStarted");
306
- emit kttsdStarted();
310
--- a/kttsd/speaker.cpp
311
+++ b/kttsd/speaker.cpp
313
#include "talkercode.h"
316
-//#include "talkermgr.h"
317
+#include "talkermgr.h"
318
#include "ssmlconvert.h"
321
@@ -103,7 +103,8 @@ class SpeakerPrivate
327
+ currentTalker(QString())
329
if (!ConnectToSpeechd())
330
kError() << "could not get a connection to speech-dispatcher"<< endl;
331
@@ -112,6 +113,8 @@ class SpeakerPrivate
334
config = new KConfig("kttsdrc");
336
+ TalkerMgr::Instance()->loadTalkers(config);
340
@@ -195,6 +198,8 @@ protected:
344
+ QString currentTalker;
348
/* Public Methods ==========================================================*/
349
@@ -256,6 +261,14 @@ void Speaker::init()
351
d->filterMgr = new FilterMgr();
352
d->filterMgr->init();
354
+ if (d->config) delete d->config;
355
+ d->config = new KConfig("kttsdrc");
356
+ TalkerMgr::Instance()->loadTalkers(d->config);
358
+ QString defTalker = TalkerMgr::Instance()->userDefaultTalker();
359
+ if (!defTalker.isEmpty())
360
+ activateTalker(defTalker);
363
AppData* Speaker::getAppData(const QString& appId) const
364
@@ -330,6 +343,13 @@ int Speaker::say(const QString& appId, c
365
//kDebug() << "Running: Speaker::say appId = " << appId << " text = " << text;
366
//QString talker = appData->defaultTalker();
368
+ // Activate another talker if requested
369
+ if (!appData->defaultTalker().isEmpty() &&
370
+ appData->defaultTalker() != d->currentTalker)
372
+ activateTalker(appData->defaultTalker());
375
SPDPriority spdpriority = SPD_PROGRESS; // default to least priority
378
@@ -406,7 +426,7 @@ int Speaker::say(const QString& appId, c
381
//// Note: Set state last so job is fully populated when jobStateChanged signal is emitted.
382
- appData->jobList()->append(jobNum);
383
+ //appData->jobList()->append(jobNum);
387
@@ -449,6 +469,19 @@ bool Speaker::isSpeaking()
388
return true; // TODO: ask speech-dispatcher somehow?
391
+void Speaker::activateTalker(const QString & talker)
393
+ TalkerCode tc(talker);
394
+ setOutputModule(tc.outputModule());
395
+ setLanguage(tc.language());
396
+ setVoiceType(tc.voiceType());
397
+ setSpeed(tc.rate());
398
+ setPitch(tc.pitch());
399
+ setVolume(tc.volume());
401
+ d->currentTalker = talker;
404
int Speaker::getCurrentJobNum()
406
return 0;// TODO: ask speech dispatcher if it's needed...
407
@@ -819,6 +852,9 @@ QStringList Speaker::outputModules()
409
QStringList Speaker::languagesByModule(const QString & module)
411
+ if (module.isEmpty())
412
+ return QStringList();
414
QStringList languages;
415
if (spd_set_output_module(d->connection, module.toUtf8().data()) == 0)
417
@@ -850,12 +886,18 @@ void Speaker::setVolume(int volume)
419
void Speaker::setOutputModule(const QString & module)
421
+ if (module.isEmpty())
424
int result = spd_set_output_module(d->connection, module.toUtf8().data());
425
// discard result for now, TODO: add error reporting
428
void Speaker::setLanguage(const QString & language)
430
+ if (language.isEmpty())
433
int result = spd_set_language(d->connection, language.toUtf8().data());
434
// discard result for now, TODO: add error reporting
436
--- a/kttsd/speaker.h
437
+++ b/kttsd/speaker.h
438
@@ -380,6 +380,8 @@ public:
439
void setLanguage(const QString & language);
440
void setVoiceType(int voiceType);
442
+ void activateTalker(const QString & talker);
446
* Emitted when a marker is processed.
447
--- a/kttsd/talkermgr.cpp
448
+++ b/kttsd/talkermgr.cpp
449
@@ -239,12 +239,7 @@ void TalkerMgr::loadTalkers(KConfig* c)
451
QStringList TalkerMgr::getTalkers()
453
- QStringList talkerList;
454
- //for (int ndx = 0; ndx < int(m_loadedPlugIns.count()); ++ndx)
456
- // talkerList.append(m_loadedTalkerCodes[ndx].getTalkerCode());
459
+ return m_loadedTalkerIds;
463
@@ -340,7 +335,8 @@ QString TalkerMgr::talkerCodeToTalkerId(
465
QString TalkerMgr::userDefaultTalker() const
467
- return m_loadedTalkerCodes[0].getTalkerCode();
468
+ return (m_loadedTalkerCodes.isEmpty()) ? QString() :
469
+ m_loadedTalkerCodes[0].getTalkerCode();