A few new icons...
[kdeaccessibility.git] / kmouth / phraselist.cpp
blobd57682afc73358cb92c504c09a7f1887ee4a70d8
1 /***************************************************************************
2 phraselist.cpp - description
3 -------------------
4 begin : Mit Sep 11 2002
5 copyright : (C) 2002 by Gunnar Schmi Dt
6 email : kmouth@schmi-dt.de
7 ***************************************************************************/
9 /***************************************************************************
10 * *
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. *
15 * *
16 ***************************************************************************/
18 // include files for Qt
19 #include <qprinter.h>
20 #include <qpainter.h>
21 #include <qlayout.h>
22 #include <qwhatsthis.h>
23 #include <qpopupmenu.h>
24 #include <qclipboard.h>
26 // include files for KDE
27 #include <klistbox.h>
28 #include <klineedit.h>
29 #include <kaudioplayer.h>
30 #include <kcursor.h>
31 #include <kiconloader.h>
32 #include <klocale.h>
33 #include <kfiledialog.h>
34 #include <kcombobox.h>
35 #include <kmessagebox.h>
37 #include <stdlib.h>
39 // application specific includes
40 #include "phraselistitem.h"
41 #include "phraselist.h"
42 #include "phraseedit.h"
43 #include "kmouth.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) {
49 isInSlot = false;
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);
76 lineEdit->setFocus();
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() {
95 delete speakButton;
96 delete listBox;
97 delete lineEdit;
100 void PhraseList::print(KPrinter *pPrinter) {
101 PhraseBook book;
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())
114 res += item->text();
117 return res;
120 bool PhraseList::existListSelection() {
121 for (QListBoxItem *item = listBox->firstItem(); item != 0; item = item->next()) {
122 if (item->isSelected())
123 return true;
126 return false;
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())
138 selected = true;
139 else
140 deselected = true;
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();
153 if (list.isEmpty())
154 dictionaryCombo->hide();
155 else if (list.count() == 1) {
156 dictionaryCombo->insertStringList (list);
157 dictionaryCombo->setCurrentItem (0);
158 dictionaryCombo->hide();
160 else {
161 dictionaryCombo->insertStringList (list);
162 dictionaryCombo->show();
164 QStringList::ConstIterator it;
165 int i = 0;
166 for (it = list.begin(), i = 0; it != list.end(); ++it, ++i) {
167 if (current == *it) {
168 dictionaryCombo->setCurrentItem (i);
169 return;
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))
187 speakButton->hide();
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;
197 int i = 0;
198 for (it = list.begin(), i = 0; it != list.end(); ++it, ++i) {
199 if (current == *it) {
200 dictionaryCombo->setCurrentItem (i);
201 return;
207 void PhraseList::saveWordCompletion () {
208 completion->save();
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();
224 else {
225 insertIntoPhraseList (phrase, true);
226 speakPhrase (phrase);
230 void PhraseList::cut() {
231 if (lineEdit->hasSelectedText())
232 lineEdit->cut();
233 else
234 cutListSelection();
237 void PhraseList::copy() {
238 if (lineEdit->hasSelectedText())
239 lineEdit->copy();
240 else
241 copyListSelection();
244 void PhraseList::paste() {
245 lineEdit->paste();
248 void PhraseList::insert (const QString &s) {
249 setEditLineText(s);
252 void PhraseList::speakListSelection () {
253 speakPhrase(getListSelection().join ("\n"));
256 void PhraseList::removeListSelection () {
257 QListBoxItem *next;
258 for (QListBoxItem *item = listBox->firstItem(); item != 0; item = next) {
259 next = 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();
280 else {
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));
298 if (clearEditLine)
299 completion->addSentence (phrase);
302 if (clearEditLine) {
303 lineEdit->selectAll();
304 line = "";
306 enableMenuEntries ();
309 void PhraseList::contextMenuRequested (QListBoxItem *, const QPoint &pos) {
310 QString name;
311 if (existListSelection())
312 name = "phraselist_selection_popup";
313 else
314 name = "phraselist_popup";
316 KMouthApp *theApp=(KMouthApp *) parentWidget();
317 KXMLGUIFactory *factory = theApp->factory();
318 QPopupMenu *popup = (QPopupMenu *)factory->container(name,theApp);
319 if (popup != 0) {
320 popup->popup(pos, 0);
324 void PhraseList::textChanged (const QString &s) {
325 if (!isInSlot) {
326 isInSlot = true;
327 line = s;
328 listBox->setCurrentItem (listBox->count() - 1);
329 listBox->clearSelection ();
330 isInSlot = false;
334 void PhraseList::selectionChanged () {
335 if (!isInSlot) {
336 isInSlot = true;
338 QStringList sel = getListSelection();
340 if (sel.empty())
341 setEditLineText(line);
342 else if (sel.count() == 1)
343 setEditLineText(sel.first());
344 else {
345 setEditLineText("");
347 isInSlot = false;
349 enableMenuEntries ();
352 void PhraseList::setEditLineText(const QString &s) {
353 lineEdit->end(false);
354 while (!(lineEdit->text().isNull() || lineEdit->text().isEmpty()))
355 lineEdit->backspace();
356 lineEdit->insert(s);
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()) {
364 selected = true;
368 if (!selected) {
369 listBox->setCurrentItem (listBox->count() - 1);
370 listBox->setSelected (listBox->count() - 1, true);
371 listBox->ensureCurrentVisible ();
373 else {
374 int curr = listBox->currentItem();
376 if (curr == -1) {
377 isInSlot = true;
378 listBox->clearSelection();
379 isInSlot = false;
380 curr = listBox->count() - 1;
381 listBox->setCurrentItem (curr);
382 listBox->setSelected (curr, true);
383 listBox->ensureCurrentVisible ();
385 else if (curr != 0) {
386 isInSlot = true;
387 listBox->clearSelection();
388 isInSlot = false;
389 listBox->setCurrentItem (curr - 1);
390 listBox->setSelected (curr - 1, true);
391 listBox->ensureCurrentVisible ();
395 e->accept();
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()) {
401 selected = true;
405 if (selected) {
406 int curr = listBox->currentItem();
408 if (curr == (int)listBox->count() - 1) {
409 listBox->clearSelection();
411 else if (curr != -1) {
412 isInSlot = true;
413 listBox->clearSelection();
414 isInSlot = false;
415 listBox->setCurrentItem (curr + 1);
416 listBox->setSelected (curr + 1, true);
417 listBox->ensureCurrentVisible ();
420 e->accept();
422 else if ((e->state() & Qt::KeyButtonMask) == Qt::ControlButton) {
423 if (e->key() == Qt::Key_C) {
424 copy();
425 e->accept();
427 else if (e->key() == Qt::Key_X) {
428 cut();
429 e->accept();
432 else
433 e->ignore();
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.
442 PhraseBook book;
443 for (QListBoxItem *item = listBox->firstItem(); item != 0; item = item->next()) {
444 book += PhraseBookEntry(Phrase(item->text()));
447 KURL url;
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"));
456 if(!url.isEmpty())
457 open (url);
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.
465 PhraseBook book;
466 if (book.open (url)) {
467 // convert PhraseBookEntryList -> QStringList
468 QStringList list = book.toStringList();
469 listBox->clear();
470 QStringList::iterator it;
471 for (it = list.begin(); it != list.end(); ++it)
472 insertIntoPhraseList (*it, false);
474 else
475 KMessageBox::sorry(this,i18n("There was an error loading file\n%1").arg( url.url() ));
478 #include "phraselist.moc"