File indexing completed on 2024-04-14 03:39:03

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