1 /***************************************************************************
2 phraselist.cpp - description
4 begin : Mit Sep 11 2002
5 copyright : (C) 2002 by Gunnar Schmi Dt
6 email : kmouth@schmi-dt.de
7 ***************************************************************************/
9 /***************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 ***************************************************************************/
18 // application specific includes
19 #include "phraselist.h"
20 #include "phraselistitem.h"
21 #include "phraseedit.h"
23 #include "texttospeechsystem.h"
24 #include "phrasebook/phrasebook.h"
25 #include "wordcompletion/wordcompletion.h"
27 // include files for Qt
31 #include <QApplication>
36 #include <QVBoxLayout>
37 #include <QHBoxLayout>
40 // include files for KDE
41 #include <klineedit.h>
43 #include <kiconloader.h>
45 #include <kfiledialog.h>
46 #include <kcombobox.h>
47 #include <kmessagebox.h>
48 #include <kxmlguifactory.h>
53 PhraseList::PhraseList(QWidget
*parent
, const char *name
) : QWidget(parent
) {
56 // FIXME: Remove or change PaletteBase to Qt::OpaqueMode?
57 // setBackgroundMode(PaletteBase);
58 QVBoxLayout
*layout
= new QVBoxLayout (this);
60 listBox
= new K3ListBox (this);
61 listBox
->setFocusPolicy(Qt::NoFocus
);
62 listBox
->setSelectionMode (Q3ListBox::Extended
);
63 listBox
->setWhatsThis( i18n("This list contains the history of spoken sentences. You can select sentences and press the speak button for re-speaking."));
64 layout
->addWidget(listBox
);
66 QHBoxLayout
*rowLayout
= new QHBoxLayout ();
67 layout
->addLayout(rowLayout
);
69 completion
= new WordCompletion();
71 dictionaryCombo
= new KComboBox (this);
72 configureCompletionCombo(completion
->wordLists());
73 rowLayout
->addWidget(dictionaryCombo
);
75 lineEdit
= new PhraseEdit ("", this);
76 lineEdit
->setFocusPolicy(Qt::StrongFocus
);
77 lineEdit
->setFrame(true);
78 lineEdit
->setEchoMode(QLineEdit::Normal
);
79 lineEdit
->setCompletionObject (completion
);
80 lineEdit
->setAutoDeleteCompletionObject(true);
81 lineEdit
->setWhatsThis( i18n("Into this edit field you can type a phrase. Click on the speak button in order to speak the entered phrase."));
82 rowLayout
->addWidget(lineEdit
);
85 QIcon icon
= KIconLoader::global()->loadIconSet("speak", K3Icon::Small
);
86 speakButton
= new QPushButton (icon
, i18n("&Speak"), this);
87 speakButton
->setFocusPolicy(Qt::NoFocus
);
88 speakButton
->setAutoDefault(false);
89 speakButton
->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."));
90 rowLayout
->addWidget(speakButton
);
92 connect(dictionaryCombo
, SIGNAL (activated (const QString
&)), completion
, SLOT (setWordList(const QString
&)));
93 connect(completion
, SIGNAL (wordListsChanged (const QStringList
&)), this, SLOT (configureCompletionCombo (const QStringList
&)));
94 connect(listBox
, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
95 connect(listBox
, SIGNAL(contextMenuRequested (Q3ListBoxItem
*, const QPoint
&)), SLOT(contextMenuRequested (Q3ListBoxItem
*, const QPoint
&)));
96 connect(lineEdit
, SIGNAL(returnPressed(const QString
&)), SLOT(lineEntered(const QString
&)));
97 connect(lineEdit
, SIGNAL(textChanged (const QString
&)), SLOT(textChanged(const QString
&)));
98 connect(speakButton
, SIGNAL( clicked ()), SLOT(speak()));
101 PhraseList::~PhraseList() {
107 void PhraseList::print(KPrinter
*pPrinter
) {
109 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
110 book
+= PhraseBookEntry(Phrase(item
->text()));
113 book
.print (pPrinter
);
116 QStringList
PhraseList::getListSelection() {
117 QStringList res
= QStringList();
119 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
120 if (item
->isSelected())
127 bool PhraseList::existListSelection() {
128 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
129 if (item
->isSelected())
136 bool PhraseList::existEditSelection() {
137 return lineEdit
->hasSelectedText();
140 void PhraseList::enableMenuEntries() {
141 bool deselected
= false;
142 bool selected
= false;
143 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
144 if (item
->isSelected())
149 KMouthApp
*theApp
=(KMouthApp
*) parentWidget();
150 theApp
->enableMenuEntries (selected
, deselected
);
153 void PhraseList::configureCompletion() {
154 completion
->configure();
157 void PhraseList::configureCompletionCombo(const QStringList
&list
) {
158 QString current
= completion
->currentWordList();
159 dictionaryCombo
->clear();
161 dictionaryCombo
->hide();
162 else if (list
.count() == 1) {
163 dictionaryCombo
->addItems (list
);
164 dictionaryCombo
->setCurrentIndex (0);
165 dictionaryCombo
->hide();
168 dictionaryCombo
->addItems (list
);
169 dictionaryCombo
->show();
171 QStringList::ConstIterator it
;
173 for (it
= list
.begin(), i
= 0; it
!= list
.end(); ++it
, ++i
) {
174 if (current
== *it
) {
175 dictionaryCombo
->setCurrentIndex (i
);
182 void PhraseList::saveCompletionOptions(KConfig
*config
) {
183 KConfigGroup
cg(config
,"General Options");
184 cg
.writeEntry("Show speak button", speakButton
->isVisible() || !lineEdit
->isVisible());
186 KConfigGroup
cg2(config
,"Completion");
187 cg2
.writeEntry("Mode", static_cast<int>(lineEdit
->completionMode()));
188 cg2
.writeEntry("List", completion
->currentWordList());
191 void PhraseList::readCompletionOptions(KConfig
*config
) {
192 KConfigGroup
cg(config
,"General Options");
193 if (!cg
.readEntry("Show speak button", true))
196 if (config
->hasGroup ("Completion")) {
197 KConfigGroup
cg2(config
, "Completion");
198 int mode
= cg2
.readEntry ("Mode", int(KGlobalSettings::completionMode()));
199 lineEdit
->setCompletionMode (static_cast<KGlobalSettings::Completion
>(mode
));
201 QString current
= cg2
.readEntry ("List", QString());
202 QStringList list
= completion
->wordLists();
203 QStringList::ConstIterator it
;
205 for (it
= list
.begin(), i
= 0; it
!= list
.end(); ++it
, ++i
) {
206 if (current
== *it
) {
207 dictionaryCombo
->setCurrentIndex (i
);
214 void PhraseList::saveWordCompletion () {
219 void PhraseList::selectAllEntries () {
220 listBox
->selectAll (true);
223 void PhraseList::deselectAllEntries () {
224 listBox
->selectAll (false);
227 void PhraseList::speak () {
228 QString phrase
= lineEdit
->text();
229 if (phrase
.isNull() || phrase
.isEmpty())
230 speakListSelection();
232 insertIntoPhraseList (phrase
, true);
233 speakPhrase (phrase
);
237 void PhraseList::cut() {
238 if (lineEdit
->hasSelectedText())
244 void PhraseList::copy() {
245 if (lineEdit
->hasSelectedText())
251 void PhraseList::paste() {
255 void PhraseList::insert (const QString
&s
) {
259 void PhraseList::speakListSelection () {
260 speakPhrase(getListSelection().join ("\n"));
263 void PhraseList::removeListSelection () {
265 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= next
) {
268 if (item
->isSelected()) {
269 listBox
->removeItem(listBox
->index(item
));
272 enableMenuEntries ();
275 void PhraseList::cutListSelection () {
276 copyListSelection ();
277 removeListSelection ();
280 void PhraseList::copyListSelection () {
281 QApplication::clipboard()->setText (getListSelection().join ("\n"));
284 void PhraseList::lineEntered (const QString
&phrase
) {
285 if (phrase
.isNull() || phrase
.isEmpty())
286 speakListSelection();
288 insertIntoPhraseList (phrase
, true);
289 speakPhrase (phrase
);
293 void PhraseList::speakPhrase (const QString
&phrase
) {
294 // QApplication::setOverrideCursor (KCursor::WaitCursor, false);
295 QApplication::setOverrideCursor (Qt::WaitCursor
);
296 KMouthApp
*theApp
=(KMouthApp
*) parentWidget();
297 QString language
= completion
->languageOfWordList (completion
->currentWordList());
298 theApp
->getTTSSystem()->speak(phrase
, language
);
299 QApplication::restoreOverrideCursor ();
302 void PhraseList::insertIntoPhraseList (const QString
&phrase
, bool clearEditLine
) {
303 int lastLine
= listBox
->count() - 1;
304 if ((lastLine
== -1) || (phrase
!= listBox
->text(lastLine
))) {
305 listBox
->insertItem(new PhraseListItem(phrase
));
307 completion
->addSentence (phrase
);
311 lineEdit
->selectAll();
314 enableMenuEntries ();
317 void PhraseList::contextMenuRequested (Q3ListBoxItem
*, const QPoint
&pos
) {
319 if (existListSelection())
320 name
= "phraselist_selection_popup";
322 name
= "phraselist_popup";
324 KMouthApp
*theApp
=(KMouthApp
*) parentWidget();
325 KXMLGUIFactory
*factory
= theApp
->factory();
326 QMenu
*popup
= (QMenu
*)factory
->container(name
,theApp
);
332 void PhraseList::textChanged (const QString
&s
) {
336 listBox
->setCurrentItem (listBox
->count() - 1);
337 listBox
->clearSelection ();
342 void PhraseList::selectionChanged () {
346 QStringList sel
= getListSelection();
349 setEditLineText(line
);
350 else if (sel
.count() == 1)
351 setEditLineText(sel
.first());
357 enableMenuEntries ();
360 void PhraseList::setEditLineText(const QString
&s
) {
361 lineEdit
->end(false);
362 while (!(lineEdit
->text().isNull() || lineEdit
->text().isEmpty()))
363 lineEdit
->backspace();
367 void PhraseList::keyPressEvent (QKeyEvent
*e
) {
368 if (e
->key() == Qt::Key_Up
) {
369 bool selected
= false;
370 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
371 if (item
->isSelected()) {
377 listBox
->setCurrentItem (listBox
->count() - 1);
378 listBox
->setSelected (listBox
->count() - 1, true);
379 listBox
->ensureCurrentVisible ();
382 int curr
= listBox
->currentItem();
386 listBox
->clearSelection();
388 curr
= listBox
->count() - 1;
389 listBox
->setCurrentItem (curr
);
390 listBox
->setSelected (curr
, true);
391 listBox
->ensureCurrentVisible ();
393 else if (curr
!= 0) {
395 listBox
->clearSelection();
397 listBox
->setCurrentItem (curr
- 1);
398 listBox
->setSelected (curr
- 1, true);
399 listBox
->ensureCurrentVisible ();
405 else if (e
->key() == Qt::Key_Down
) {
406 bool selected
= false;
407 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
408 if (item
->isSelected()) {
414 int curr
= listBox
->currentItem();
416 if (curr
== (int)listBox
->count() - 1) {
417 listBox
->clearSelection();
419 else if (curr
!= -1) {
421 listBox
->clearSelection();
423 listBox
->setCurrentItem (curr
+ 1);
424 listBox
->setSelected (curr
+ 1, true);
425 listBox
->ensureCurrentVisible ();
430 else if (e
->modifiers() & Qt::ControlModifier
) {
431 if (e
->key() == Qt::Key_C
) {
435 else if (e
->key() == Qt::Key_X
) {
444 void PhraseList::save () {
445 // We want to save a history of spoken sentences here. However, as
446 // the class PhraseBook does already provide a method for saving
447 // phrase books in both the phrase book format and plain text file
448 // format we use that method here.
451 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
452 book
+= PhraseBookEntry(Phrase(item
->text()));
456 if (book
.save (this, i18n("Save As"), url
, false) == -1)
457 KMessageBox::sorry(this,i18n("There was an error saving file\n%1", url
.url() ));
460 void PhraseList::open () {
461 KUrl url
=KFileDialog::getOpenUrl(KUrl(),
462 i18n("*|All Files\n*.phrasebook|Phrase Books (*.phrasebook)\n*.txt|Plain Text Files (*.txt)"), this, i18n("Open File as History"));
468 void PhraseList::open (KUrl url
) {
469 // We want to open a history of spoken sentences here. However, as
470 // the class PhraseBook does already provide a method for opening
471 // both phrase books and plain text files we use that method here.
474 if (book
.open (url
)) {
475 // convert PhraseBookEntryList -> QStringList
476 QStringList list
= book
.toStringList();
478 QStringList::iterator it
;
479 for (it
= list
.begin(); it
!= list
.end(); ++it
)
480 insertIntoPhraseList (*it
, false);
483 KMessageBox::sorry(this,i18n("There was an error loading file\n%1", url
.url() ));
486 #include "phraselist.moc"