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
28 #include <QtGui/QPainter>
29 #include <QtGui/QLayout>
30 #include <QtGui/QApplication>
31 #include <QtGui/QMenu>
32 #include <QtGui/QClipboard>
33 #include <QtGui/QVBoxLayout>
34 #include <QtGui/QHBoxLayout>
35 #include <QtGui/QKeyEvent>
37 // include files for KDE
38 #include <klineedit.h>
40 #include <kiconloader.h>
42 #include <kfiledialog.h>
43 #include <kcombobox.h>
44 #include <kmessagebox.h>
45 #include <kxmlguifactory.h>
50 PhraseList::PhraseList(QWidget
*parent
, const char *name
) : QWidget(parent
) {
53 // FIXME: Remove or change PaletteBase to Qt::OpaqueMode?
54 // setBackgroundMode(PaletteBase);
55 QVBoxLayout
*layout
= new QVBoxLayout (this);
57 listBox
= new K3ListBox (this);
58 listBox
->setFocusPolicy(Qt::NoFocus
);
59 listBox
->setSelectionMode (Q3ListBox::Extended
);
60 listBox
->setWhatsThis( i18n("This list contains the history of spoken sentences. You can select sentences and press the speak button for re-speaking."));
61 layout
->addWidget(listBox
);
63 QHBoxLayout
*rowLayout
= new QHBoxLayout ();
64 layout
->addLayout(rowLayout
);
66 completion
= new WordCompletion();
68 dictionaryCombo
= new KComboBox (this);
69 configureCompletionCombo(completion
->wordLists());
70 rowLayout
->addWidget(dictionaryCombo
);
72 lineEdit
= new PhraseEdit ("", this);
73 lineEdit
->setFocusPolicy(Qt::StrongFocus
);
74 lineEdit
->setFrame(true);
75 lineEdit
->setEchoMode(QLineEdit::Normal
);
76 lineEdit
->setCompletionObject (completion
);
77 lineEdit
->setAutoDeleteCompletionObject(true);
78 lineEdit
->setWhatsThis( i18n("Into this edit field you can type a phrase. Click on the speak button in order to speak the entered phrase."));
79 rowLayout
->addWidget(lineEdit
);
82 QIcon icon
= KIconLoader::global()->loadIconSet("speak", KIconLoader::Small
);
83 speakButton
= new QPushButton (icon
, i18n("&Speak"), this);
84 speakButton
->setFocusPolicy(Qt::NoFocus
);
85 speakButton
->setAutoDefault(false);
86 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."));
87 rowLayout
->addWidget(speakButton
);
89 connect(dictionaryCombo
, SIGNAL (activated (const QString
&)), completion
, SLOT (setWordList(const QString
&)));
90 connect(completion
, SIGNAL (wordListsChanged (const QStringList
&)), this, SLOT (configureCompletionCombo (const QStringList
&)));
91 connect(listBox
, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
92 connect(listBox
, SIGNAL(contextMenuRequested (Q3ListBoxItem
*, const QPoint
&)), SLOT(contextMenuRequested (Q3ListBoxItem
*, const QPoint
&)));
93 connect(lineEdit
, SIGNAL(returnPressed(const QString
&)), SLOT(lineEntered(const QString
&)));
94 connect(lineEdit
, SIGNAL(textChanged (const QString
&)), SLOT(textChanged(const QString
&)));
95 connect(speakButton
, SIGNAL( clicked ()), SLOT(speak()));
98 PhraseList::~PhraseList() {
104 void PhraseList::print(QPrinter
*pPrinter
) {
106 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
107 book
+= PhraseBookEntry(Phrase(item
->text()));
110 book
.print (pPrinter
);
113 QStringList
PhraseList::getListSelection() {
114 QStringList res
= QStringList();
116 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
117 if (item
->isSelected())
124 bool PhraseList::existListSelection() {
125 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
126 if (item
->isSelected())
133 bool PhraseList::existEditSelection() {
134 return lineEdit
->hasSelectedText();
137 void PhraseList::enableMenuEntries() {
138 bool deselected
= false;
139 bool selected
= false;
140 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
141 if (item
->isSelected())
146 KMouthApp
*theApp
=(KMouthApp
*) parentWidget();
147 theApp
->enableMenuEntries (selected
, deselected
);
150 void PhraseList::configureCompletion() {
151 completion
->configure();
154 void PhraseList::configureCompletionCombo(const QStringList
&list
) {
155 QString current
= completion
->currentWordList();
156 dictionaryCombo
->clear();
158 dictionaryCombo
->hide();
159 else if (list
.count() == 1) {
160 dictionaryCombo
->addItems (list
);
161 dictionaryCombo
->setCurrentIndex (0);
162 dictionaryCombo
->hide();
165 dictionaryCombo
->addItems (list
);
166 dictionaryCombo
->show();
168 QStringList::ConstIterator it
;
170 for (it
= list
.begin(), i
= 0; it
!= list
.end(); ++it
, ++i
) {
171 if (current
== *it
) {
172 dictionaryCombo
->setCurrentIndex (i
);
179 void PhraseList::saveCompletionOptions(KConfig
*config
) {
180 KConfigGroup
cg(config
,"General Options");
181 cg
.writeEntry("Show speak button", speakButton
->isVisible() || !lineEdit
->isVisible());
183 KConfigGroup
cg2(config
,"Completion");
184 cg2
.writeEntry("Mode", static_cast<int>(lineEdit
->completionMode()));
185 cg2
.writeEntry("List", completion
->currentWordList());
188 void PhraseList::readCompletionOptions(KConfig
*config
) {
189 KConfigGroup
cg(config
,"General Options");
190 if (!cg
.readEntry("Show speak button", true))
193 if (config
->hasGroup ("Completion")) {
194 KConfigGroup
cg2(config
, "Completion");
195 int mode
= cg2
.readEntry ("Mode", int(KGlobalSettings::completionMode()));
196 lineEdit
->setCompletionMode (static_cast<KGlobalSettings::Completion
>(mode
));
198 QString current
= cg2
.readEntry ("List", QString());
199 const QStringList list
= completion
->wordLists();
200 QStringList::ConstIterator it
;
202 for (it
= list
.constBegin(), i
= 0; it
!= list
.constEnd(); ++it
, ++i
) {
203 if (current
== *it
) {
204 dictionaryCombo
->setCurrentIndex (i
);
211 void PhraseList::saveWordCompletion () {
216 void PhraseList::selectAllEntries () {
217 listBox
->selectAll (true);
220 void PhraseList::deselectAllEntries () {
221 listBox
->selectAll (false);
224 void PhraseList::speak () {
225 QString phrase
= lineEdit
->text();
226 if (phrase
.isNull() || phrase
.isEmpty())
227 speakListSelection();
229 insertIntoPhraseList (phrase
, true);
230 speakPhrase (phrase
);
234 void PhraseList::cut() {
235 if (lineEdit
->hasSelectedText())
241 void PhraseList::copy() {
242 if (lineEdit
->hasSelectedText())
248 void PhraseList::paste() {
252 void PhraseList::insert (const QString
&s
) {
256 void PhraseList::speakListSelection () {
257 speakPhrase(getListSelection().join ("\n"));
260 void PhraseList::removeListSelection () {
262 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= next
) {
265 if (item
->isSelected()) {
266 listBox
->removeItem(listBox
->index(item
));
269 enableMenuEntries ();
272 void PhraseList::cutListSelection () {
273 copyListSelection ();
274 removeListSelection ();
277 void PhraseList::copyListSelection () {
278 QApplication::clipboard()->setText (getListSelection().join ("\n"));
281 void PhraseList::lineEntered (const QString
&phrase
) {
282 if (phrase
.isNull() || phrase
.isEmpty())
283 speakListSelection();
285 insertIntoPhraseList (phrase
, true);
286 speakPhrase (phrase
);
290 void PhraseList::speakPhrase (const QString
&phrase
) {
291 // QApplication::setOverrideCursor (KCursor::WaitCursor, false);
292 QApplication::setOverrideCursor (Qt::WaitCursor
);
293 KMouthApp
*theApp
=(KMouthApp
*) parentWidget();
294 QString language
= completion
->languageOfWordList (completion
->currentWordList());
295 theApp
->getTTSSystem()->speak(phrase
, language
);
296 QApplication::restoreOverrideCursor ();
299 void PhraseList::insertIntoPhraseList (const QString
&phrase
, bool clearEditLine
) {
300 int lastLine
= listBox
->count() - 1;
301 if ((lastLine
== -1) || (phrase
!= listBox
->text(lastLine
))) {
302 listBox
->insertItem(new PhraseListItem(phrase
));
304 completion
->addSentence (phrase
);
308 lineEdit
->selectAll();
311 enableMenuEntries ();
314 void PhraseList::contextMenuRequested (Q3ListBoxItem
*, const QPoint
&pos
) {
316 if (existListSelection())
317 name
= "phraselist_selection_popup";
319 name
= "phraselist_popup";
321 KMouthApp
*theApp
=(KMouthApp
*) parentWidget();
322 KXMLGUIFactory
*factory
= theApp
->factory();
323 QMenu
*popup
= (QMenu
*)factory
->container(name
,theApp
);
329 void PhraseList::textChanged (const QString
&s
) {
333 listBox
->setCurrentItem (listBox
->count() - 1);
334 listBox
->clearSelection ();
339 void PhraseList::selectionChanged () {
343 QStringList sel
= getListSelection();
346 setEditLineText(line
);
347 else if (sel
.count() == 1)
348 setEditLineText(sel
.first());
354 enableMenuEntries ();
357 void PhraseList::setEditLineText(const QString
&s
) {
358 lineEdit
->end(false);
359 while (!(lineEdit
->text().isNull() || lineEdit
->text().isEmpty()))
360 lineEdit
->backspace();
364 void PhraseList::keyPressEvent (QKeyEvent
*e
) {
365 if (e
->key() == Qt::Key_Up
) {
366 bool selected
= false;
367 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
368 if (item
->isSelected()) {
374 listBox
->setCurrentItem (listBox
->count() - 1);
375 listBox
->setSelected (listBox
->count() - 1, true);
376 listBox
->ensureCurrentVisible ();
379 int curr
= listBox
->currentItem();
383 listBox
->clearSelection();
385 curr
= listBox
->count() - 1;
386 listBox
->setCurrentItem (curr
);
387 listBox
->setSelected (curr
, true);
388 listBox
->ensureCurrentVisible ();
390 else if (curr
!= 0) {
392 listBox
->clearSelection();
394 listBox
->setCurrentItem (curr
- 1);
395 listBox
->setSelected (curr
- 1, true);
396 listBox
->ensureCurrentVisible ();
402 else if (e
->key() == Qt::Key_Down
) {
403 bool selected
= false;
404 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
405 if (item
->isSelected()) {
411 int curr
= listBox
->currentItem();
413 if (curr
== (int)listBox
->count() - 1) {
414 listBox
->clearSelection();
416 else if (curr
!= -1) {
418 listBox
->clearSelection();
420 listBox
->setCurrentItem (curr
+ 1);
421 listBox
->setSelected (curr
+ 1, true);
422 listBox
->ensureCurrentVisible ();
427 else if (e
->modifiers() & Qt::ControlModifier
) {
428 if (e
->key() == Qt::Key_C
) {
432 else if (e
->key() == Qt::Key_X
) {
441 void PhraseList::save () {
442 // We want to save a history of spoken sentences here. However, as
443 // the class PhraseBook does already provide a method for saving
444 // phrase books in both the phrase book format and plain text file
445 // format we use that method here.
448 for (Q3ListBoxItem
*item
= listBox
->firstItem(); item
!= 0; item
= item
->next()) {
449 book
+= PhraseBookEntry(Phrase(item
->text()));
453 if (book
.save (this, i18n("Save As"), url
, false) == -1)
454 KMessageBox::sorry(this,i18n("There was an error saving file\n%1", url
.url() ));
457 void PhraseList::open () {
458 KUrl url
=KFileDialog::getOpenUrl(KUrl(),
459 i18n("*|All Files\n*.phrasebook|Phrase Books (*.phrasebook)\n*.txt|Plain Text Files (*.txt)"), this, i18n("Open File as History"));
465 void PhraseList::open (KUrl url
) {
466 // We want to open a history of spoken sentences here. However, as
467 // the class PhraseBook does already provide a method for opening
468 // both phrase books and plain text files we use that method here.
471 if (book
.open (url
)) {
472 // convert PhraseBookEntryList -> QStringList
473 QStringList list
= book
.toStringList();
475 QStringList::iterator it
;
476 for (it
= list
.begin(); it
!= list
.end(); ++it
)
477 insertIntoPhraseList (*it
, false);
480 KMessageBox::sorry(this,i18n("There was an error loading file\n%1", url
.url() ));
483 #include "phraselist.moc"