File indexing completed on 2023-05-30 10:39:35
0001 /*************************************************************************** 0002 * Copyright (C) 2002 by Gunnar Schmi Dt <kmouth@schmi-dt.de * 0003 * (C) 2015 by Jeremy Whiting <jpwhiting@kde.org> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 0019 ***************************************************************************/ 0020 0021 // application specific includes 0022 #include "kmouth.h" 0023 0024 // include files for Qt 0025 #include <QMenu> 0026 #include <QMenuBar> 0027 #include <QPrintDialog> 0028 #include <QStandardPaths> 0029 #include <QStatusBar> 0030 0031 // include files for KDE 0032 #include <KActionCollection> 0033 #include <KConfigGroup> 0034 #include <KLocalizedString> 0035 #include <KStandardAction> 0036 #include <KStandardShortcut> 0037 #include <KToggleAction> 0038 #include <KToolBar> 0039 #include <KXMLGUIFactory> 0040 0041 #include "phraselist.h" 0042 #include "phrasebook/phrasebook.h" 0043 #include "phrasebook/phrasebookdialog.h" 0044 #include "optionsdialog.h" 0045 #include "configwizard.h" 0046 0047 KMouthApp::KMouthApp(QWidget* , const QString& name): KXmlGuiWindow(nullptr) 0048 { 0049 setWindowIcon(QIcon::fromTheme(QStringLiteral("kmouth"))); 0050 setObjectName(name); 0051 isConfigured = false; 0052 0053 /////////////////////////////////////////////////////////////////// 0054 // call inits to invoke all other construction parts 0055 initStatusBar(); 0056 initPhraseList(); 0057 initActions(); 0058 optionsDialog = new OptionsDialog(this); 0059 connect(optionsDialog, &OptionsDialog::configurationChanged, 0060 this, &KMouthApp::slotConfigurationChanged); 0061 connect(optionsDialog, &OptionsDialog::configurationChanged, 0062 phraseList, &PhraseList::configureCompletion); 0063 0064 phrases = new KActionCollection(static_cast<QWidget*>(this)); 0065 0066 readOptions(); 0067 ConfigWizard *wizard = new ConfigWizard(this); 0068 if (wizard->configurationNeeded()) { 0069 if (wizard->requestConfiguration()) { 0070 isConfigured = true; 0071 saveOptions(); 0072 wizard->saveConfig(); 0073 readOptions(); 0074 } else 0075 isConfigured = false; 0076 } else 0077 isConfigured = true; 0078 delete wizard; 0079 0080 if (isConfigured) { 0081 phraseList->configureCompletion(); 0082 } 0083 0084 /////////////////////////////////////////////////////////////////// 0085 // disable actions at startup 0086 fileSaveAs->setEnabled(false); 0087 filePrint->setEnabled(false); 0088 0089 printer = nullptr; 0090 } 0091 0092 KMouthApp::~KMouthApp() 0093 { 0094 delete printer; 0095 } 0096 0097 bool KMouthApp::configured() 0098 { 0099 return isConfigured; 0100 } 0101 0102 void KMouthApp::initActions() 0103 { 0104 // The "File" menu 0105 fileOpen = actionCollection()->addAction(QStringLiteral("file_open")); 0106 fileOpen->setIcon(QIcon::fromTheme(QStringLiteral("document-open"))); 0107 fileOpen->setText(i18n("&Open as History...")); 0108 actionCollection()->setDefaultShortcuts(fileOpen, KStandardShortcut::open()); 0109 connect(fileOpen, &QAction::triggered, this, &KMouthApp::slotFileOpen); 0110 fileOpen->setToolTip(i18n("Opens an existing file as history")); 0111 fileOpen->setWhatsThis(i18n("Opens an existing file as history")); 0112 0113 fileSaveAs = actionCollection()->addAction(QStringLiteral("file_save_as")); 0114 fileSaveAs->setIcon(QIcon::fromTheme(QStringLiteral("document-save"))); 0115 fileSaveAs->setText(i18n("Save &History As...")); 0116 actionCollection()->setDefaultShortcuts(fileSaveAs, KStandardShortcut::save()); 0117 connect(fileSaveAs, &QAction::triggered, this, &KMouthApp::slotFileSaveAs); 0118 fileSaveAs->setToolTip(i18n("Saves the actual history as...")); 0119 fileSaveAs->setWhatsThis(i18n("Saves the actual history as...")); 0120 0121 filePrint = actionCollection()->addAction(QStringLiteral("file_print")); 0122 filePrint->setIcon(QIcon::fromTheme(QStringLiteral("document-print"))); 0123 filePrint->setText(i18n("&Print History...")); 0124 actionCollection()->setDefaultShortcuts(filePrint, KStandardShortcut::print()); 0125 connect(filePrint, &QAction::triggered, this, &KMouthApp::slotFilePrint); 0126 filePrint->setToolTip(i18n("Prints out the actual history")); 0127 filePrint->setWhatsThis(i18n("Prints out the actual history")); 0128 0129 fileQuit = KStandardAction::quit(this, SLOT(slotFileQuit()), actionCollection()); 0130 fileQuit->setToolTip(i18n("Quits the application")); 0131 fileQuit->setWhatsThis(i18n("Quits the application")); 0132 0133 // The "Edit" menu 0134 editCut = KStandardAction::cut(phraseList, SLOT(cut()), actionCollection()); 0135 editCut->setToolTip(i18n("Cuts the selected section and puts it to the clipboard")); 0136 editCut->setWhatsThis(i18n("Cuts the selected section and puts it to the clipboard. If there is some text selected in the edit field it is placed it on the clipboard. Otherwise the selected sentences in the history (if any) are placed on the clipboard.")); 0137 0138 editCopy = KStandardAction::copy(phraseList, SLOT(copy()), actionCollection()); 0139 editCopy->setToolTip(i18n("Copies the selected section to the clipboard")); 0140 editCopy->setWhatsThis(i18n("Copies the selected section to the clipboard. If there is some text selected in the edit field it is copied to the clipboard. Otherwise the selected sentences in the history (if any) are copied to the clipboard.")); 0141 0142 editPaste = KStandardAction::paste(phraseList, SLOT(paste()), actionCollection()); 0143 editPaste->setToolTip(i18n("Pastes the clipboard contents to current position")); 0144 editPaste->setWhatsThis(i18n("Pastes the clipboard contents at the current cursor position into the edit field.")); 0145 0146 editSpeak = actionCollection()->addAction(QStringLiteral("edit_speak")); 0147 editSpeak->setIcon(QIcon::fromTheme(QStringLiteral("text-speak"))); 0148 editSpeak->setText(i18nc("Start speaking", "&Speak")); 0149 connect(editSpeak, &QAction::triggered, phraseList, &PhraseList::speak); 0150 editSpeak->setToolTip(i18n("Speaks the currently active sentence(s)")); 0151 editSpeak->setWhatsThis(i18n("Speaks the currently active sentence(s). If there is some text in the edit field it is spoken. Otherwise the selected sentences in the history (if any) are spoken.")); 0152 0153 // The "Phrase book" menu 0154 phrasebookEdit = actionCollection()->addAction(QStringLiteral("phrasebook_edit")); 0155 phrasebookEdit->setText(i18n("&Edit...")); 0156 connect(phrasebookEdit, &QAction::triggered, this, &KMouthApp::slotEditPhrasebook); 0157 0158 // The "Options" menu 0159 viewMenuBar = KStandardAction::showMenubar(this, SLOT(slotViewMenuBar()), actionCollection()); 0160 // FIXME: Disable so it will compile. 0161 // viewToolBar = KStandardAction::showToolbar(this, SLOT(slotViewToolBar()), actionCollection()); 0162 // viewToolBar->setToolTip(i18n("Enables/disables the toolbar")); 0163 // viewToolBar->setWhatsThis (i18n("Enables/disables the toolbar")); 0164 0165 viewPhrasebookBar = actionCollection()->add<KToggleAction>(QStringLiteral("showPhrasebookBar")); 0166 viewPhrasebookBar->setText(i18n("Show P&hrasebook Bar")); 0167 connect(viewPhrasebookBar, &QAction::triggered, this, &KMouthApp::slotViewPhrasebookBar); 0168 viewPhrasebookBar->setToolTip(i18n("Enables/disables the phrasebook bar")); 0169 viewPhrasebookBar->setWhatsThis(i18n("Enables/disables the phrasebook bar")); 0170 0171 viewStatusBar = KStandardAction::showStatusbar(this, SLOT(slotViewStatusBar()), actionCollection()); 0172 viewStatusBar->setToolTip(i18n("Enables/disables the statusbar")); 0173 viewStatusBar->setWhatsThis(i18n("Enables/disables the statusbar")); 0174 0175 configureTTS = actionCollection()->addAction(QStringLiteral("configureTTS")); 0176 configureTTS->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); 0177 configureTTS->setText(i18n("&Configure KMouth...")); 0178 connect(configureTTS, &QAction::triggered, this, &KMouthApp::slotConfigureTTS); 0179 configureTTS->setToolTip(i18n("Opens the configuration dialog")); 0180 configureTTS->setWhatsThis(i18n("Opens the configuration dialog")); 0181 0182 // The "Help" menu 0183 // The "Help" menu will automatically get created. 0184 0185 // The popup menu of the list of spoken sentences 0186 phraseListSpeak = actionCollection()->addAction(QStringLiteral("phraselist_speak")); 0187 phraseListSpeak->setIcon(QIcon::fromTheme(QStringLiteral("text-speak"))); 0188 phraseListSpeak->setText(i18n("&Speak")); 0189 phraseListSpeak->setToolTip(i18n("Speaks the currently selected phrases in the history")); 0190 connect(phraseListSpeak, &QAction::triggered, phraseList, &PhraseList::speakListSelection); 0191 phraseListSpeak->setWhatsThis(i18n("Speaks the currently selected phrases in the history")); 0192 0193 phraseListRemove = actionCollection()->addAction(QStringLiteral("phraselist_remove")); 0194 phraseListRemove->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete"))); 0195 phraseListRemove->setText(i18n("&Delete")); 0196 connect(phraseListRemove, &QAction::triggered, phraseList, &PhraseList::removeListSelection); 0197 phraseListRemove->setToolTip(i18n("Deletes the currently selected phrases from the history")); 0198 phraseListRemove->setWhatsThis(i18n("Deletes the currently selected phrases from the history")); 0199 0200 phraseListCut = actionCollection()->addAction(QStringLiteral("phraselist_cut")); 0201 phraseListCut->setIcon(QIcon::fromTheme(QStringLiteral("edit-cut"))); 0202 phraseListCut->setText(i18n("Cu&t")); 0203 connect(phraseListCut, &QAction::triggered, phraseList, &PhraseList::cutListSelection); 0204 phraseListCut->setToolTip(i18n("Cuts the currently selected phrases from the history and puts them to the clipboard")); 0205 phraseListCut->setWhatsThis(i18n("Cuts the currently selected phrases from the history and puts them to the clipboard")); 0206 0207 phraseListCopy = actionCollection()->addAction(QStringLiteral("phraselist_copy")); 0208 phraseListCopy->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"))); 0209 phraseListCopy->setText(i18n("&Copy")); 0210 connect(phraseListCopy, &QAction::triggered, phraseList, &PhraseList::copyListSelection); 0211 phraseListCut->setToolTip(i18n("Copies the currently selected phrases from the history to the clipboard")); 0212 phraseListCut->setWhatsThis(i18n("Copies the currently selected phrases from the history to the clipboard")); 0213 0214 phraselistSelectAll = actionCollection()->addAction(QStringLiteral("phraselist_select_all")); 0215 phraselistSelectAll->setText(i18n("Select &All Entries")); 0216 connect(phraselistSelectAll, &QAction::triggered, phraseList, &PhraseList::selectAllEntries); 0217 phraselistSelectAll->setToolTip(i18n("Selects all phrases in the history")); 0218 phraselistSelectAll->setWhatsThis(i18n("Selects all phrases in the history")); 0219 0220 phraselistDeselectAll = actionCollection()->addAction(QStringLiteral("phraselist_deselect_all")); 0221 phraselistDeselectAll->setText(i18n("D&eselect All Entries")); 0222 connect(phraselistDeselectAll, &QAction::triggered, phraseList, &PhraseList::deselectAllEntries); 0223 phraselistDeselectAll->setToolTip(i18n("Deselects all phrases in the history")); 0224 phraselistDeselectAll->setWhatsThis(i18n("Deselects all phrases in the history")); 0225 0226 // The popup menu of the edit field 0227 // The popup menu of the edit field will automatically get created. 0228 0229 // use the absolute path to your kmouthui.rc file for testing purpose in createGUI(); 0230 createGUI(); 0231 } 0232 0233 void KMouthApp::initStatusBar() 0234 { 0235 /////////////////////////////////////////////////////////////////// 0236 // STATUSBAR 0237 // TODO: add your own items you need for displaying current application status. 0238 m_statusLabel = new QLabel(i18nc("The job is done", "Ready.")); 0239 statusBar()->addPermanentWidget(m_statusLabel); 0240 } 0241 0242 void KMouthApp::initPhraseList() 0243 { 0244 //////////////////////////////////////////////////////////////////// 0245 // create the main widget here that is managed by KTMainWindow's view-region and 0246 // connect the widget to your document to display document contents. 0247 0248 phraseList = new PhraseList(this); 0249 setCentralWidget(phraseList); 0250 } 0251 0252 void KMouthApp::openDocumentFile(const QUrl &url) 0253 { 0254 slotStatusMsg(i18n("Opening file...")); 0255 0256 phraseList->open(url); 0257 slotStatusMsg(i18nc("The job is done", "Ready.")); 0258 } 0259 0260 void KMouthApp::saveOptions() 0261 { 0262 if (isConfigured) { 0263 KConfigGroup cg(KSharedConfig::openConfig(), "General Options"); 0264 cg.writeEntry("Geometry", size()); 0265 cg.writeEntry("Show Menubar", viewMenuBar->isChecked()); 0266 // FIXME: Toolbar disabled so it will compile. 0267 // cg.writeEntry("Show Toolbar", viewToolBar->isChecked()); 0268 cg.writeEntry("Show Phrasebook Bar", viewPhrasebookBar->isChecked()); 0269 cg.writeEntry("Show Statusbar", viewStatusBar->isChecked()); 0270 // FIXME: KToolBar no longer has barPos() method. 0271 // cg.writeEntry("ToolBarPos", (int) toolBar("mainToolBar")->barPos()); 0272 0273 if (phraseList != nullptr) 0274 phraseList->saveCompletionOptions(); 0275 optionsDialog->saveOptions(); 0276 KConfigGroup cg2(KSharedConfig::openConfig(), "mainToolBar"); 0277 toolBar(QStringLiteral("mainToolBar"))->saveSettings(cg2); 0278 KConfigGroup cg3(KSharedConfig::openConfig(), "phrasebookBar"); 0279 toolBar(QStringLiteral("phrasebookBar"))->saveSettings(cg); 0280 } 0281 } 0282 0283 0284 void KMouthApp::readOptions() 0285 { 0286 KConfigGroup cg(KSharedConfig::openConfig(), "General Options"); 0287 0288 // bar status settings 0289 bool bViewMenubar = cg.readEntry("Show Menubar", true); 0290 viewMenuBar->setChecked(bViewMenubar); 0291 slotViewMenuBar(); 0292 0293 // FIXME: Toolbar disabled so it will compile. 0294 // bool bViewToolbar = cg.readEntry("Show Toolbar", QVariant(true)).toBool(); 0295 // viewToolBar->setChecked(bViewToolbar); 0296 // slotViewToolBar(); 0297 0298 bool bViewPhrasebookbar = cg.readEntry("Show Phrasebook Bar", true); 0299 viewPhrasebookBar->setChecked(bViewPhrasebookbar); 0300 0301 bool bViewStatusbar = cg.readEntry("Show Statusbar", true); 0302 viewStatusBar->setChecked(bViewStatusbar); 0303 slotViewStatusBar(); 0304 0305 // bar position settings 0306 // FIXME: 0307 // KToolBar::BarPosition toolBarPos; 0308 // toolBarPos=(KToolBar::BarPosition) cg.readEntry("ToolBarPos", int(KToolBar::Top)); 0309 // toolBar("mainToolBar")->setBarPos(toolBarPos); 0310 0311 QSize size = cg.readEntry("Geometry", QSize()); 0312 if (!size.isEmpty()) { 0313 resize(size); 0314 } 0315 0316 optionsDialog->readOptions(); 0317 0318 toolBar(QStringLiteral("mainToolBar"))->applySettings(KSharedConfig::openConfig()->group("mainToolBar")); 0319 toolBar(QStringLiteral("phrasebookBar"))->applySettings(KSharedConfig::openConfig()->group("phrasebookBar")); 0320 0321 slotPhrasebookConfirmed(); 0322 if (phraseList != nullptr) 0323 phraseList->readCompletionOptions(); 0324 } 0325 0326 bool KMouthApp::queryClose() 0327 { 0328 saveOptions(); 0329 return true; 0330 } 0331 0332 void KMouthApp::enableMenuEntries(bool existSelectedEntries, bool existDeselectedEntries) 0333 { 0334 bool existEntries = existSelectedEntries | existDeselectedEntries; 0335 fileSaveAs->setEnabled(existEntries); 0336 filePrint->setEnabled(existEntries); 0337 0338 phraselistSelectAll->setEnabled(existDeselectedEntries); 0339 0340 phraselistDeselectAll->setEnabled(existSelectedEntries); 0341 phraseListSpeak->setEnabled(existSelectedEntries); 0342 phraseListRemove->setEnabled(existSelectedEntries); 0343 phraseListCut->setEnabled(existSelectedEntries); 0344 phraseListCopy->setEnabled(existSelectedEntries); 0345 } 0346 0347 ///////////////////////////////////////////////////////////////////// 0348 // SLOT IMPLEMENTATION 0349 ///////////////////////////////////////////////////////////////////// 0350 0351 void KMouthApp::slotFileOpen() 0352 { 0353 slotStatusMsg(i18n("Opening file...")); 0354 0355 phraseList->open(); 0356 0357 slotStatusMsg(i18nc("The job is done", "Ready.")); 0358 } 0359 0360 void KMouthApp::slotFileSaveAs() 0361 { 0362 slotStatusMsg(i18n("Saving history with a new filename...")); 0363 0364 phraseList->save(); 0365 0366 slotStatusMsg(i18nc("The job is done", "Ready.")); 0367 } 0368 0369 void KMouthApp::slotFilePrint() 0370 { 0371 slotStatusMsg(i18n("Printing...")); 0372 0373 if (printer == nullptr) { 0374 printer = new QPrinter(); 0375 } 0376 0377 QPrintDialog *printDialog = new QPrintDialog(printer, nullptr); 0378 0379 if (printDialog->exec()) { 0380 phraseList->print(printer); 0381 } 0382 0383 slotStatusMsg(i18nc("The job is done", "Ready.")); 0384 } 0385 0386 void KMouthApp::slotFileQuit() 0387 { 0388 slotStatusMsg(i18nc("Shutting down the application", "Exiting...")); 0389 saveOptions(); 0390 // close the first window, the list makes the next one the first again. 0391 // This ensures that queryClose() is called on each window to ask for closing 0392 if (!memberList().isEmpty()) { 0393 for (int i = 0; i < memberList().size(); ++i) { 0394 // only close the window if the closeEvent is accepted. If the user presses Cancel on the saveModified() dialog, 0395 // the window and the application stay open. 0396 KMainWindow* w = memberList().at(i); 0397 if (!w->close()) 0398 break; 0399 #ifdef __GNUC__ 0400 #warning "kde4: how remove it ?.???" 0401 #endif 0402 //memberList()->removeRef(w); 0403 } 0404 } 0405 } 0406 0407 void KMouthApp::slotEditPhrasebook() 0408 { 0409 PhraseBookDialog *phraseBookDialog = PhraseBookDialog::get(); 0410 // As we do not know whether the we are already connected to the slot, 0411 // we first disconnect and then connect again. 0412 disconnect(phraseBookDialog, &PhraseBookDialog::phrasebookConfirmed, 0413 this, &KMouthApp::slotPhrasebookConfirmed); 0414 connect(phraseBookDialog, &PhraseBookDialog::phrasebookConfirmed, 0415 this, &KMouthApp::slotPhrasebookConfirmed); 0416 0417 // As we do not know whether the phrase book edit window is already open, 0418 // we first open and then raise it, so that it is surely the top window. 0419 phraseBookDialog->show(); 0420 phraseBookDialog->raise(); 0421 } 0422 0423 void KMouthApp::slotViewMenuBar() 0424 { 0425 slotStatusMsg(i18n("Toggling menubar...")); 0426 0427 if (!viewMenuBar->isChecked()) 0428 menuBar()->hide(); 0429 else 0430 menuBar()->show(); 0431 0432 slotStatusMsg(i18nc("The job is done", "Ready.")); 0433 } 0434 0435 void KMouthApp::slotViewToolBar() 0436 { 0437 slotStatusMsg(i18n("Toggling toolbar...")); 0438 /////////////////////////////////////////////////////////////////// 0439 // turn Toolbar on or off 0440 if (!viewToolBar->isChecked()) { 0441 toolBar(QStringLiteral("mainToolBar"))->hide(); 0442 } else { 0443 toolBar(QStringLiteral("mainToolBar"))->show(); 0444 } 0445 0446 slotStatusMsg(i18nc("The job is done", "Ready.")); 0447 } 0448 0449 void KMouthApp::slotViewPhrasebookBar() 0450 { 0451 slotStatusMsg(i18n("Toggling phrasebook bar...")); 0452 /////////////////////////////////////////////////////////////////// 0453 // turn Toolbar on or off 0454 if (!viewPhrasebookBar->isChecked()) { 0455 toolBar(QStringLiteral("phrasebookBar"))->hide(); 0456 } else { 0457 toolBar(QStringLiteral("phrasebookBar"))->show(); 0458 } 0459 0460 slotStatusMsg(i18nc("The job is done", "Ready.")); 0461 } 0462 0463 void KMouthApp::slotViewStatusBar() 0464 { 0465 slotStatusMsg(i18n("Toggle the statusbar...")); 0466 /////////////////////////////////////////////////////////////////// 0467 //turn Statusbar on or off 0468 if (!viewStatusBar->isChecked()) { 0469 statusBar()->hide(); 0470 } else { 0471 statusBar()->show(); 0472 } 0473 0474 slotStatusMsg(i18nc("The job is done", "Ready.")); 0475 } 0476 0477 void KMouthApp::slotConfigureTTS() 0478 { 0479 phraseList->saveWordCompletion(); 0480 optionsDialog->show(); 0481 } 0482 0483 0484 void KMouthApp::slotStatusMsg(const QString &text) 0485 { 0486 /////////////////////////////////////////////////////////////////// 0487 // change status message permanently 0488 m_statusLabel->setText(text); 0489 } 0490 0491 void KMouthApp::slotPhrasebookConfirmed() 0492 { 0493 QString standardBook = QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("standard.phrasebook")); 0494 if (!standardBook.isEmpty()) { 0495 PhraseBook book; 0496 book.open(QUrl::fromLocalFile(standardBook)); 0497 QString name = QStringLiteral("phrasebooks"); 0498 QMenu *popup = (QMenu *)factory()->container(name, this); 0499 KToolBar *toolbar = toolBar(QStringLiteral("phrasebookBar")); 0500 0501 delete phrases; 0502 phrases = new KActionCollection(actionCollection()); 0503 book.addToGUI(popup, toolbar, phrases, this, SLOT(slotPhraseSelected(QString))); 0504 } 0505 } 0506 0507 void KMouthApp::slotConfigurationChanged() 0508 { 0509 optionsDialog->saveOptions(); 0510 } 0511 0512 void KMouthApp::slotPhraseSelected(const QString &phrase) 0513 { 0514 phraseList->insert(phrase); 0515 if (optionsDialog->isSpeakImmediately()) 0516 phraseList->speak(); 0517 } 0518 0519 TextToSpeechSystem *KMouthApp::getTTSSystem() const 0520 { 0521 return optionsDialog->getTTSSystem(); 0522 } 0523