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 // include files for Qt
22 #include <qwhatsthis.h>
23 #include <qpopupmenu.h>
24 #include <qclipboard.h>
26 // include files for KDE
28 #include <klineedit.h>
29 #include <kaudioplayer.h>
31 #include <kiconloader.h>
33 #include <kfiledialog.h>
34 #include <kcombobox.h>
35 #include <kmessagebox.h>
39 // application specific includes
40 #include "phraselistitem.h"
41 #include "phraselist.h"
42 #include "phraseedit.h"
44 #include "texttospeechsystem.h"
45 #include "phrasebook/phrasebook.h"
46 #include "wordcompletion/wordcompletion.h"
48 PhraseList::PhraseList(QWidget
*parent
, const char *name
) : QWidget(parent
,name
) {
50 setBackgroundMode(PaletteBase
);
51 QVBoxLayout
*layout
= new QVBoxLayout (this);
53 listBox
= new KListBox (this);
54 listBox
->setFocusPolicy(QWidget::NoFocus
);
55 listBox
->setSelectionMode (QListBox::Extended
);
56 QWhatsThis::add (listBox
, i18n("This list contains the history of spoken sentences. You can select sentences and press the speak button for re-speaking."));
57 layout
->addWidget(listBox
);
59 QHBoxLayout
*rowLayout
= new QHBoxLayout ();
60 layout
->addLayout(rowLayout
);
62 completion
= new WordCompletion();
64 dictionaryCombo
= new KComboBox (this, "Dictionary Combo");
65 configureCompletionCombo(completion
->wordLists());
66 rowLayout
->addWidget(dictionaryCombo
);
68 lineEdit
= new PhraseEdit ("", this);
69 lineEdit
->setFocusPolicy(QWidget::StrongFocus
);
70 lineEdit
->setFrame(true);
71 lineEdit
->setEchoMode(QLineEdit::Normal
);
72 lineEdit
->setCompletionObject (completion
);
73 lineEdit
->setAutoDeleteCompletionObject(true);
74 QWhatsThis::add (lineEdit
, i18n("Into this edit field you can type a phrase. Click on the speak button in order to speak the entered phrase."));
75 rowLayout
->addWidget(lineEdit
);
78 QIconSet icon
= KGlobal::iconLoader()->loadIconSet("speak", KIcon::Small
);
79 speakButton
= new QPushButton (icon
, i18n("&Speak"), this);
80 speakButton
->setFocusPolicy(QWidget::NoFocus
);
81 speakButton
->setAutoDefault(false);
82 QWhatsThis::add (speakButton
, 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."));
83 rowLayout
->addWidget(speakButton
);
85 connect(dictionaryCombo
, SIGNAL (activated (const QString
&)), completion
, SLOT (setWordList(const QString
&)));
86 connect(completion
, SIGNAL (wordListsChanged (const QStringList
&)), this, SLOT (configureCompletionCombo (const QStringList
&)));
87 connect(listBox
, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
88 connect(listBox
, SIGNAL(contextMenuRequested (QListBoxItem
*, const QPoint
&)), SLOT(contextMenuRequested (QListBoxItem
*, const QPoint
&)));
89 connect(lineEdit
, SIGNAL(returnPressed(const QString
&)), SLOT(lineEntered(const QString
&)));
90 connect(lineEdit
, SIGNAL(textChanged (const QString
&)), SLOT(textChanged(const QString
&)));
91 connect(speakButton
, SIGNAL( clicked ()), SLOT(speak()));
94 PhraseList::~PhraseList() {
100 void PhraseList::print(KPrinter
*pPrinter
) {
102 for (QListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
103 book
+= PhraseBookEntry(Phrase(item
->text()));
106 book
.print (pPrinter
);
109 QStringList
PhraseList::getListSelection() {
110 QStringList res
= QStringList();
112 for (QListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
113 if (item
->isSelected())
120 bool PhraseList::existListSelection() {
121 for (QListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
122 if (item
->isSelected())
129 bool PhraseList::existEditSelection() {
130 return lineEdit
->hasSelectedText();
133 void PhraseList::enableMenuEntries() {
134 bool deselected
= false;
135 bool selected
= false;
136 for (QListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
137 if (item
->isSelected())
142 KMouthApp
*theApp
=(KMouthApp
*) parentWidget();
143 theApp
->enableMenuEntries (selected
, deselected
);
146 void PhraseList::configureCompletion() {
147 completion
->configure();
150 void PhraseList::configureCompletionCombo(const QStringList
&list
) {
151 QString current
= completion
->currentWordList();
152 dictionaryCombo
->clear();
154 dictionaryCombo
->hide();
155 else if (list
.count() == 1) {
156 dictionaryCombo
->insertStringList (list
);
157 dictionaryCombo
->setCurrentItem (0);
158 dictionaryCombo
->hide();
161 dictionaryCombo
->insertStringList (list
);
162 dictionaryCombo
->show();
164 QStringList::ConstIterator it
;
166 for (it
= list
.begin(), i
= 0; it
!= list
.end(); ++it
, ++i
) {
167 if (current
== *it
) {
168 dictionaryCombo
->setCurrentItem (i
);
175 void PhraseList::saveCompletionOptions(KConfig
*config
) {
176 config
->setGroup("General Options");
177 config
->writeEntry("Show speak button", speakButton
->isVisible() || !lineEdit
->isVisible());
179 config
->setGroup("Completion");
180 config
->writeEntry("Mode", static_cast<int>(lineEdit
->completionMode()));
181 config
->writeEntry("List", completion
->currentWordList());
184 void PhraseList::readCompletionOptions(KConfig
*config
) {
185 config
->setGroup("General Options");
186 if (!config
->readBoolEntry("Show speak button", true))
189 if (config
->hasGroup ("Completion")) {
190 config
->setGroup("Completion");
191 int mode
= config
->readNumEntry ("Mode", KGlobalSettings::completionMode());
192 lineEdit
->setCompletionMode (static_cast<KGlobalSettings::Completion
>(mode
));
194 QString current
= config
->readEntry ("List", QString::null
);
195 QStringList list
= completion
->wordLists();
196 QStringList::ConstIterator it
;
198 for (it
= list
.begin(), i
= 0; it
!= list
.end(); ++it
, ++i
) {
199 if (current
== *it
) {
200 dictionaryCombo
->setCurrentItem (i
);
207 void PhraseList::saveWordCompletion () {
212 void PhraseList::selectAllEntries () {
213 listBox
->selectAll (true);
216 void PhraseList::deselectAllEntries () {
217 listBox
->selectAll (false);
220 void PhraseList::speak () {
221 QString phrase
= lineEdit
->text();
222 if (phrase
.isNull() || phrase
.isEmpty())
223 speakListSelection();
225 insertIntoPhraseList (phrase
, true);
226 speakPhrase (phrase
);
230 void PhraseList::cut() {
231 if (lineEdit
->hasSelectedText())
237 void PhraseList::copy() {
238 if (lineEdit
->hasSelectedText())
244 void PhraseList::paste() {
248 void PhraseList::insert (const QString
&s
) {
252 void PhraseList::speakListSelection () {
253 speakPhrase(getListSelection().join ("\n"));
256 void PhraseList::removeListSelection () {
258 for (QListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= next
) {
261 if (item
->isSelected()) {
262 listBox
->removeItem(listBox
->index(item
));
265 enableMenuEntries ();
268 void PhraseList::cutListSelection () {
269 copyListSelection ();
270 removeListSelection ();
273 void PhraseList::copyListSelection () {
274 QApplication::clipboard()->setText (getListSelection().join ("\n"));
277 void PhraseList::lineEntered (const QString
&phrase
) {
278 if (phrase
.isNull() || phrase
.isEmpty())
279 speakListSelection();
281 insertIntoPhraseList (phrase
, true);
282 speakPhrase (phrase
);
286 void PhraseList::speakPhrase (const QString
&phrase
) {
287 QApplication::setOverrideCursor (KCursor::WaitCursor
, false);
288 KMouthApp
*theApp
=(KMouthApp
*) parentWidget();
289 QString language
= completion
->languageOfWordList (completion
->currentWordList());
290 theApp
->getTTSSystem()->speak(phrase
, language
);
291 QApplication::restoreOverrideCursor ();
294 void PhraseList::insertIntoPhraseList (const QString
&phrase
, bool clearEditLine
) {
295 int lastLine
= listBox
->count() - 1;
296 if ((lastLine
== -1) || (phrase
!= listBox
->text(lastLine
))) {
297 listBox
->insertItem(new PhraseListItem(phrase
));
299 completion
->addSentence (phrase
);
303 lineEdit
->selectAll();
306 enableMenuEntries ();
309 void PhraseList::contextMenuRequested (QListBoxItem
*, const QPoint
&pos
) {
311 if (existListSelection())
312 name
= "phraselist_selection_popup";
314 name
= "phraselist_popup";
316 KMouthApp
*theApp
=(KMouthApp
*) parentWidget();
317 KXMLGUIFactory
*factory
= theApp
->factory();
318 QPopupMenu
*popup
= (QPopupMenu
*)factory
->container(name
,theApp
);
320 popup
->popup(pos
, 0);
324 void PhraseList::textChanged (const QString
&s
) {
328 listBox
->setCurrentItem (listBox
->count() - 1);
329 listBox
->clearSelection ();
334 void PhraseList::selectionChanged () {
338 QStringList sel
= getListSelection();
341 setEditLineText(line
);
342 else if (sel
.count() == 1)
343 setEditLineText(sel
.first());
349 enableMenuEntries ();
352 void PhraseList::setEditLineText(const QString
&s
) {
353 lineEdit
->end(false);
354 while (!(lineEdit
->text().isNull() || lineEdit
->text().isEmpty()))
355 lineEdit
->backspace();
359 void PhraseList::keyPressEvent (QKeyEvent
*e
) {
360 if (e
->key() == Qt::Key_Up
) {
361 bool selected
= false;
362 for (QListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
363 if (item
->isSelected()) {
369 listBox
->setCurrentItem (listBox
->count() - 1);
370 listBox
->setSelected (listBox
->count() - 1, true);
371 listBox
->ensureCurrentVisible ();
374 int curr
= listBox
->currentItem();
378 listBox
->clearSelection();
380 curr
= listBox
->count() - 1;
381 listBox
->setCurrentItem (curr
);
382 listBox
->setSelected (curr
, true);
383 listBox
->ensureCurrentVisible ();
385 else if (curr
!= 0) {
387 listBox
->clearSelection();
389 listBox
->setCurrentItem (curr
- 1);
390 listBox
->setSelected (curr
- 1, true);
391 listBox
->ensureCurrentVisible ();
397 else if (e
->key() == Qt::Key_Down
) {
398 bool selected
= false;
399 for (QListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
400 if (item
->isSelected()) {
406 int curr
= listBox
->currentItem();
408 if (curr
== (int)listBox
->count() - 1) {
409 listBox
->clearSelection();
411 else if (curr
!= -1) {
413 listBox
->clearSelection();
415 listBox
->setCurrentItem (curr
+ 1);
416 listBox
->setSelected (curr
+ 1, true);
417 listBox
->ensureCurrentVisible ();
422 else if ((e
->state() & Qt::KeyButtonMask
) == Qt::ControlButton
) {
423 if (e
->key() == Qt::Key_C
) {
427 else if (e
->key() == Qt::Key_X
) {
436 void PhraseList::save () {
437 // We want to save a history of spoken sentences here. However, as
438 // the class PhraseBook does already provide a method for saving
439 // phrase books in both the phrase book format and plain text file
440 // format we use that method here.
443 for (QListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
444 book
+= PhraseBookEntry(Phrase(item
->text()));
448 if (book
.save (this, i18n("Save As"), url
, false) == -1)
449 KMessageBox::sorry(this,i18n("There was an error saving file\n%1").arg( url
.url() ));
452 void PhraseList::open () {
453 KURL url
=KFileDialog::getOpenURL(QString::null
,
454 i18n("*|All Files\n*.phrasebook|Phrase Books (*.phrasebook)\n*.txt|Plain Text Files (*.txt)"), this, i18n("Open File as History"));
460 void PhraseList::open (KURL url
) {
461 // We want to open a history of spoken sentences here. However, as
462 // the class PhraseBook does already provide a method for opening
463 // both phrase books and plain text files we use that method here.
466 if (book
.open (url
)) {
467 // convert PhraseBookEntryList -> QStringList
468 QStringList list
= book
.toStringList();
470 QStringList::iterator it
;
471 for (it
= list
.begin(); it
!= list
.end(); ++it
)
472 insertIntoPhraseList (*it
, false);
475 KMessageBox::sorry(this,i18n("There was an error loading file\n%1").arg( url
.url() ));
478 #include "phraselist.moc"