summaryrefslogtreecommitdiffstats
path: root/kmouth
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit00bb99ac80741fc50ef8a289719373032f2391eb (patch)
tree3a5a9bf72f942784b38bf77dd66c534662fab5f2 /kmouth
downloadtdeaccessibility-00bb99ac80741fc50ef8a289719373032f2391eb.tar.gz
tdeaccessibility-00bb99ac80741fc50ef8a289719373032f2391eb.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeaccessibility@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kmouth')
-rw-r--r--kmouth/AUTHORS2
-rw-r--r--kmouth/Makefile.am32
-rw-r--r--kmouth/books/Makefile.am9
-rw-r--r--kmouth/books/de-courteousness.phrasebook13
-rw-r--r--kmouth/books/de-greetings.phrasebook17
-rw-r--r--kmouth/books/de-howareyou.phrasebook13
-rw-r--r--kmouth/books/de-personal.phrasebook10
-rw-r--r--kmouth/books/de.desktop60
-rw-r--r--kmouth/books/en-courteousness.phrasebook15
-rw-r--r--kmouth/books/en-greetings.phrasebook15
-rw-r--r--kmouth/books/en-howareyou.phrasebook12
-rw-r--r--kmouth/books/en-personal.phrasebook10
-rw-r--r--kmouth/books/en.desktop61
-rw-r--r--kmouth/books/nl-courteousness.phrasebook13
-rw-r--r--kmouth/books/nl-greetings.phrasebook14
-rw-r--r--kmouth/books/nl-howareyou.phrasebook12
-rw-r--r--kmouth/books/nl-personal.phrasebook9
-rw-r--r--kmouth/books/nl.desktop50
-rw-r--r--kmouth/books/sv-courteousness.phrasebook12
-rw-r--r--kmouth/books/sv-greetings.phrasebook14
-rw-r--r--kmouth/books/sv-howareyou.phrasebook12
-rw-r--r--kmouth/books/sv-personal.phrasebook10
-rw-r--r--kmouth/books/sv.desktop61
-rw-r--r--kmouth/configwizard.cpp144
-rw-r--r--kmouth/configwizard.h59
-rw-r--r--kmouth/icons/Makefile.am11
-rw-r--r--kmouth/icons/app/Makefile.am1
-rw-r--r--kmouth/icons/app/hi16-app-kmouth.pngbin0 -> 219 bytes
-rw-r--r--kmouth/icons/app/hi22-app-kmouth.pngbin0 -> 285 bytes
-rw-r--r--kmouth/icons/app/hi32-app-kmouth.pngbin0 -> 383 bytes
-rw-r--r--kmouth/icons/app/hi48-app-kmouth.pngbin0 -> 563 bytes
-rw-r--r--kmouth/icons/app/lo16-app-kmouth.pngbin0 -> 219 bytes
-rw-r--r--kmouth/icons/app/lo22-app-kmouth.pngbin0 -> 285 bytes
-rw-r--r--kmouth/icons/app/lo32-app-kmouth.pngbin0 -> 383 bytes
-rw-r--r--kmouth/icons/hi16-action-speak.pngbin0 -> 219 bytes
-rw-r--r--kmouth/icons/hi22-action-speak.pngbin0 -> 285 bytes
-rw-r--r--kmouth/icons/hi32-action-speak.pngbin0 -> 383 bytes
-rw-r--r--kmouth/icons/hi48-action-speak.pngbin0 -> 563 bytes
-rw-r--r--kmouth/icons/history/Makefile.am9
-rw-r--r--kmouth/icons/history/hi16-action-phrasehistory_open.pngbin0 -> 765 bytes
-rw-r--r--kmouth/icons/history/hi16-action-phrasehistory_print.pngbin0 -> 914 bytes
-rw-r--r--kmouth/icons/history/hi16-action-phrasehistory_save.pngbin0 -> 893 bytes
-rw-r--r--kmouth/icons/history/hi22-action-phrasehistory_open.pngbin0 -> 1544 bytes
-rw-r--r--kmouth/icons/history/hi22-action-phrasehistory_print.pngbin0 -> 1608 bytes
-rw-r--r--kmouth/icons/history/hi22-action-phrasehistory_save.pngbin0 -> 1628 bytes
-rw-r--r--kmouth/icons/history/hi32-action-phrasehistory_open.pngbin0 -> 1923 bytes
-rw-r--r--kmouth/icons/history/hi32-action-phrasehistory_print.pngbin0 -> 2099 bytes
-rw-r--r--kmouth/icons/history/hi32-action-phrasehistory_save.pngbin0 -> 2147 bytes
-rw-r--r--kmouth/icons/phrase/Makefile.am9
-rw-r--r--kmouth/icons/phrase/hi16-action-phrase.pngbin0 -> 382 bytes
-rw-r--r--kmouth/icons/phrase/hi16-action-phrase_new.pngbin0 -> 454 bytes
-rw-r--r--kmouth/icons/phrase/hi16-action-phrase_open.pngbin0 -> 520 bytes
-rw-r--r--kmouth/icons/phrase/hi16-action-phrase_save.pngbin0 -> 705 bytes
-rw-r--r--kmouth/icons/phrase/hi22-action-phrase.pngbin0 -> 713 bytes
-rw-r--r--kmouth/icons/phrase/hi22-action-phrase_new.pngbin0 -> 803 bytes
-rw-r--r--kmouth/icons/phrase/hi22-action-phrase_open.pngbin0 -> 966 bytes
-rw-r--r--kmouth/icons/phrase/hi22-action-phrase_save.pngbin0 -> 1122 bytes
-rw-r--r--kmouth/icons/phrase/hi32-action-phrase.pngbin0 -> 1479 bytes
-rw-r--r--kmouth/icons/phrase/hi32-action-phrase_new.pngbin0 -> 1515 bytes
-rw-r--r--kmouth/icons/phrase/hi32-action-phrase_open.pngbin0 -> 1934 bytes
-rw-r--r--kmouth/icons/phrase/hi32-action-phrase_save.pngbin0 -> 2021 bytes
-rw-r--r--kmouth/icons/phrasebook/Makefile.am9
-rw-r--r--kmouth/icons/phrasebook/hi16-action-phrasebook.pngbin0 -> 549 bytes
-rw-r--r--kmouth/icons/phrasebook/hi16-action-phrasebook_closed.pngbin0 -> 538 bytes
-rw-r--r--kmouth/icons/phrasebook/hi16-action-phrasebook_new.pngbin0 -> 569 bytes
-rw-r--r--kmouth/icons/phrasebook/hi16-action-phrasebook_open.pngbin0 -> 621 bytes
-rw-r--r--kmouth/icons/phrasebook/hi16-action-phrasebook_save.pngbin0 -> 720 bytes
-rw-r--r--kmouth/icons/phrasebook/hi22-action-phrasebook.pngbin0 -> 1110 bytes
-rw-r--r--kmouth/icons/phrasebook/hi22-action-phrasebook_closed.pngbin0 -> 796 bytes
-rw-r--r--kmouth/icons/phrasebook/hi22-action-phrasebook_new.pngbin0 -> 1144 bytes
-rw-r--r--kmouth/icons/phrasebook/hi22-action-phrasebook_open.pngbin0 -> 1118 bytes
-rw-r--r--kmouth/icons/phrasebook/hi22-action-phrasebook_save.pngbin0 -> 1217 bytes
-rw-r--r--kmouth/icons/phrasebook/hi32-action-phrasebook.pngbin0 -> 1573 bytes
-rw-r--r--kmouth/icons/phrasebook/hi32-action-phrasebook_closed.pngbin0 -> 1160 bytes
-rw-r--r--kmouth/icons/phrasebook/hi32-action-phrasebook_new.pngbin0 -> 1627 bytes
-rw-r--r--kmouth/icons/phrasebook/hi32-action-phrasebook_open.pngbin0 -> 1967 bytes
-rw-r--r--kmouth/icons/phrasebook/hi32-action-phrasebook_save.pngbin0 -> 2127 bytes
-rw-r--r--kmouth/kmouth.cpp484
-rw-r--r--kmouth/kmouth.desktop80
-rw-r--r--kmouth/kmouth.h187
-rw-r--r--kmouth/kmouth.lsm14
-rw-r--r--kmouth/kmouthrc9
-rw-r--r--kmouth/kmouthui.rc93
-rw-r--r--kmouth/main.cpp73
-rw-r--r--kmouth/optionsdialog.cpp238
-rw-r--r--kmouth/optionsdialog.h88
-rw-r--r--kmouth/phrasebook/Makefile.am16
-rw-r--r--kmouth/phrasebook/buttonboxui.ui107
-rw-r--r--kmouth/phrasebook/phrasebook.cpp512
-rw-r--r--kmouth/phrasebook/phrasebook.h195
-rw-r--r--kmouth/phrasebook/phrasebookdialog.cpp758
-rw-r--r--kmouth/phrasebook/phrasebookdialog.h234
-rw-r--r--kmouth/phrasebook/phrasebookdialogui.rc64
-rw-r--r--kmouth/phrasebook/phrasebookparser.cpp112
-rw-r--r--kmouth/phrasebook/phrasebookparser.h73
-rw-r--r--kmouth/phrasebook/phrasetree.cpp556
-rw-r--r--kmouth/phrasebook/phrasetree.h108
-rw-r--r--kmouth/phraseedit.cpp57
-rw-r--r--kmouth/phraseedit.h36
-rw-r--r--kmouth/phraselist.cpp478
-rw-r--r--kmouth/phraselist.h110
-rw-r--r--kmouth/phraselistitem.cpp52
-rw-r--r--kmouth/phraselistitem.h43
-rw-r--r--kmouth/preferencesui.ui162
-rw-r--r--kmouth/speech.cpp242
-rw-r--r--kmouth/speech.h72
-rw-r--r--kmouth/texttospeechconfigurationui.ui170
-rw-r--r--kmouth/texttospeechconfigurationwidget.cpp86
-rw-r--r--kmouth/texttospeechconfigurationwidget.h51
-rw-r--r--kmouth/texttospeechsystem.cpp114
-rw-r--r--kmouth/texttospeechsystem.h55
-rw-r--r--kmouth/version.h8
-rw-r--r--kmouth/wordcompletion/Makefile.am13
-rw-r--r--kmouth/wordcompletion/creationsourcedetailsui.ui184
-rw-r--r--kmouth/wordcompletion/creationsourcedetailsui.ui.h37
-rw-r--r--kmouth/wordcompletion/creationsourceui.ui179
-rw-r--r--kmouth/wordcompletion/creationsourceui.ui.h26
-rw-r--r--kmouth/wordcompletion/dictionarycreationwizard.cpp376
-rw-r--r--kmouth/wordcompletion/dictionarycreationwizard.h110
-rw-r--r--kmouth/wordcompletion/kdedocsourceui.ui101
-rw-r--r--kmouth/wordcompletion/kdedocsourceui.ui.h19
-rw-r--r--kmouth/wordcompletion/klanguagebutton.cpp238
-rw-r--r--kmouth/wordcompletion/klanguagebutton.h93
-rw-r--r--kmouth/wordcompletion/klanguagebuttonhelper.cpp64
-rw-r--r--kmouth/wordcompletion/klanguagebuttonhelper.h28
-rw-r--r--kmouth/wordcompletion/wordcompletion.cpp224
-rw-r--r--kmouth/wordcompletion/wordcompletion.h77
-rw-r--r--kmouth/wordcompletion/wordcompletionui.ui293
-rw-r--r--kmouth/wordcompletion/wordcompletionui.ui.h35
-rw-r--r--kmouth/wordcompletion/wordcompletionwidget.cpp325
-rw-r--r--kmouth/wordcompletion/wordcompletionwidget.h80
-rw-r--r--kmouth/wordcompletion/wordlist.cpp550
-rw-r--r--kmouth/wordcompletion/wordlist.h92
133 files changed, 9599 insertions, 0 deletions
diff --git a/kmouth/AUTHORS b/kmouth/AUTHORS
new file mode 100644
index 0000000..f8aec9b
--- /dev/null
+++ b/kmouth/AUTHORS
@@ -0,0 +1,2 @@
+Author:
+Gunnar Schmidt <gunnar@schmi-dt.de>, 2002-2003 \ No newline at end of file
diff --git a/kmouth/Makefile.am b/kmouth/Makefile.am
new file mode 100644
index 0000000..a5314bf
--- /dev/null
+++ b/kmouth/Makefile.am
@@ -0,0 +1,32 @@
+bin_PROGRAMS = kmouth
+
+kmouth_SOURCES = preferencesui.ui texttospeechconfigurationui.ui texttospeechconfigurationwidget.cpp optionsdialog.cpp configwizard.cpp phraseedit.cpp phraselist.cpp speech.cpp texttospeechsystem.cpp phraselistitem.cpp kmouth.cpp main.cpp
+kmouth_LDADD = ./phrasebook/libphrasebook.a ./wordcompletion/libwordcompletion.a -lkdeprint $(LIB_KFILE) $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT) $(LIBSOCKET)
+
+SUBDIRS = icons phrasebook wordcompletion books .
+
+EXTRA_DIST = main.cpp version.h kmouth.cpp kmouth.h kmouthui.rc kmouth.desktop phraselistitem.cpp phraselistitem.h texttospeechsystem.cpp texttospeechsystem.h speech.cpp speech.h phraselist.cpp phraselist.h phraseedit.cpp phraseedit.h kmouthrc configwizard.cpp configwizard.h optionsdialog.cpp optionsdialog.h texttospeechconfigurationwidget.h texttospeechconfigurationwidget.cpp texttospeechconfigurationui.ui preferencesui.ui
+
+kde_conf_DATA = kmouthrc
+
+apps_DATA = kmouth.desktop
+appsdir = $(kde_appsdir)/Applications
+
+# set the include path for X, qt and KDE
+INCLUDES= -Iphrasebook -Iwordcompletion $(all_includes)
+
+METASOURCES = AUTO
+
+# the library search path.
+kmouth_LDFLAGS = $(all_libraries) -lkspell $(KDE_RPATH)
+
+rcdir = $(kde_datadir)/kmouth
+rc_DATA = kmouthui.rc
+
+messages: rc.cpp
+ $(EXTRACTRC) *.rc *.ui */*.ui >> ./rc.cpp
+ LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \
+ if test -n "$$LIST"; then \
+ $(XGETTEXT) $$LIST -o $(podir)/kmouth.pot; \
+ fi
+
diff --git a/kmouth/books/Makefile.am b/kmouth/books/Makefile.am
new file mode 100644
index 0000000..b289519
--- /dev/null
+++ b/kmouth/books/Makefile.am
@@ -0,0 +1,9 @@
+
+de_DATA = de.desktop de-courteousness.phrasebook de-greetings.phrasebook de-howareyou.phrasebook de-personal.phrasebook
+dedir = $(kde_datadir)/kmouth/books/de
+
+en_DATA = en.desktop en-courteousness.phrasebook en-greetings.phrasebook en-howareyou.phrasebook en-personal.phrasebook
+endir = $(kde_datadir)/kmouth/books/en
+
+sv_DATA = sv.desktop sv-courteousness.phrasebook sv-greetings.phrasebook sv-howareyou.phrasebook sv-personal.phrasebook
+svdir = $(kde_datadir)/kmouth/books/sv
diff --git a/kmouth/books/de-courteousness.phrasebook b/kmouth/books/de-courteousness.phrasebook
new file mode 100644
index 0000000..36aa51e
--- /dev/null
+++ b/kmouth/books/de-courteousness.phrasebook
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Freundlichkeit">
+<phrase shortcut="">bitte</phrase>
+<phrase shortcut="">bitte sch&#246;n</phrase>
+<phrase shortcut="">danke</phrase>
+<phrase shortcut="">danke sch&#246;n</phrase>
+<phrase shortcut="">gern geschehen</phrase>
+<phrase shortcut="">Guten Appetit</phrase>
+<phrase shortcut="">kein problem</phrase>
+<phrase shortcut="">entschuldigung</phrase>
+<phrase shortcut="">das tut mir leid</phrase>
+</phrasebook>
diff --git a/kmouth/books/de-greetings.phrasebook b/kmouth/books/de-greetings.phrasebook
new file mode 100644
index 0000000..a38547b
--- /dev/null
+++ b/kmouth/books/de-greetings.phrasebook
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Gr&#252;&#223;e">
+<phrase shortcut="">Hallo.</phrase>
+<phrase shortcut="">Hi!</phrase>
+<phrase shortcut="">Moin!</phrase>
+<phrase shortcut="">Guten Morgen.</phrase>
+<phrase shortcut="">Guten Tag.</phrase>
+<phrase shortcut="">Guten Nachmittag.</phrase>
+<phrase shortcut="">Guten Abend.</phrase>
+<phrase shortcut="">Tsch&#252;ss!</phrase>
+<phrase shortcut="">Auf Wiedersehen!</phrase>
+<phrase shortcut="">Mach's gut!</phrase>
+<phrase shortcut="">Bis bald!</phrase>
+<phrase shortcut="">Bis dann!</phrase>
+<phrase shortcut="">Pass auf dich auf!</phrase>
+</phrasebook>
diff --git a/kmouth/books/de-howareyou.phrasebook b/kmouth/books/de-howareyou.phrasebook
new file mode 100644
index 0000000..831179f
--- /dev/null
+++ b/kmouth/books/de-howareyou.phrasebook
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Wie geht's?">
+<phrase shortcut="">Wie geht es Ihnen?</phrase>
+<phrase shortcut="">Wie geht es euch?</phrase>
+<phrase shortcut="">Wie geht es dir?</phrase>
+<phrase shortcut="">Mir geht es gut.</phrase>
+<phrase shortcut="">Es ist heute ein sch&#246;ner Tag.</phrase>
+<phrase shortcut="">Ich f&#252;hle mich heute ziemlich schlapp.</phrase>
+<phrase shortcut="">Ich habe Schmerzen.</phrase>
+<phrase shortcut="">Mir ist langweilig, aber sonst geht es mir gut.</phrase>
+<phrase shortcut="">Irgendwie geht es mir heute ziemlich beschissen.</phrase>
+</phrasebook>
diff --git a/kmouth/books/de-personal.phrasebook b/kmouth/books/de-personal.phrasebook
new file mode 100644
index 0000000..2125526
--- /dev/null
+++ b/kmouth/books/de-personal.phrasebook
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Pers&#246;nliches">
+<phrase shortcut="">Ich kann leider nur &#252;ber diesen dummen Computer sprechen.</phrase>
+<phrase shortcut="">Ich bin sehr m&#252;de und m&#246;chte jetzt etwas schlafen.</phrase>
+<phrase shortcut="">Sch&#246;n, dass du da bist.</phrase>
+<phrase shortcut="">Es freut mich, dich zu sehen.</phrase>
+<phrase shortcut="">Schade, dass du schon gehen musst.</phrase>
+<phrase shortcut="">Wann sehen wir uns wieder?</phrase>
+</phrasebook>
diff --git a/kmouth/books/de.desktop b/kmouth/books/de.desktop
new file mode 100644
index 0000000..0b8708a
--- /dev/null
+++ b/kmouth/books/de.desktop
@@ -0,0 +1,60 @@
+[Desktop Entry]
+Name=German
+Name[ar]=ألمانية
+Name[bg]=Немски
+Name[br]=Alamaneg
+Name[bs]=Njemački
+Name[ca]=Alemany
+Name[cs]=Německy
+Name[cy]=Almaeneg
+Name[da]=Tysk
+Name[de]=Deutsch
+Name[el]=Γερμανικά
+Name[eo]=Germana
+Name[es]=Alemán
+Name[et]=Saksa
+Name[eu]=Alemaniera
+Name[fa]=آلمانی
+Name[fi]=Saksalainen
+Name[fr]=Allemand
+Name[ga]=Gearmáinis
+Name[gl]=Alemán
+Name[he]=גרמנית
+Name[hi]= जर्मनी
+Name[hu]=Német
+Name[is]=Þýska
+Name[it]=Tedesco
+Name[ja]=ドイツ語
+Name[ka]=გერმანული
+Name[km]= អាល្លឺម៉ង់
+Name[lt]=Vokiečių
+Name[mk]=Германски
+Name[ms]=Jerman
+Name[mt]=Ġermaniż
+Name[nb]=Tysk
+Name[nds]=Hoochdüütsch
+Name[ne]=जर्मनी
+Name[nl]=Duits
+Name[nn]=Tysk
+Name[pa]=ਜਰਮਨ
+Name[pl]=Niemiecka
+Name[pt]=Alemão
+Name[pt_BR]=Alemão
+Name[ro]=Germană
+Name[ru]=Немецкий
+Name[rw]=Ikidage
+Name[sk]=nemčina
+Name[sl]=nemško
+Name[sr]=Немачки
+Name[sr@Latn]=Nemački
+Name[sv]=Tyska
+Name[ta]=ஜெர்மன்
+Name[tg]=Немисӣ
+Name[th]=เยอรมัน
+Name[tr]=Almanca
+Name[uk]=Німецька
+Name[uz]=Nemischa
+Name[uz@cyrillic]=Немисча
+Name[vi]=Đức
+Name[zh_CN]=德语
+Name[zh_TW]=德語
diff --git a/kmouth/books/en-courteousness.phrasebook b/kmouth/books/en-courteousness.phrasebook
new file mode 100644
index 0000000..46daede
--- /dev/null
+++ b/kmouth/books/en-courteousness.phrasebook
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Courteousness">
+<phrase shortcut="">thanks</phrase>
+<phrase shortcut="">thank you</phrase>
+<phrase shortcut="">thank you very much</phrase>
+<phrase shortcut="">please</phrase>
+<phrase shortcut="">here you are</phrase>
+<phrase shortcut="">you are welcome</phrase>
+<phrase shortcut="">Have a nice meal</phrase>
+<phrase shortcut="">no problem</phrase>
+<phrase shortcut="">excuse me</phrase>
+<phrase shortcut="">sorry</phrase>
+<phrase shortcut="">i am sorry</phrase>
+</phrasebook>
diff --git a/kmouth/books/en-greetings.phrasebook b/kmouth/books/en-greetings.phrasebook
new file mode 100644
index 0000000..dfee73b
--- /dev/null
+++ b/kmouth/books/en-greetings.phrasebook
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Greetings">
+<phrase shortcut="">Hello.</phrase>
+<phrase shortcut="">Hi!</phrase>
+<phrase shortcut="">Good morning.</phrase>
+<phrase shortcut="">Good afternoon.</phrase>
+<phrase shortcut="">Good evening.</phrase>
+<phrase shortcut="">Bye!</phrase>
+<phrase shortcut="">Bye, bye!</phrase>
+<phrase shortcut="">Good bye!</phrase>
+<phrase shortcut="">Cheers!</phrase>
+<phrase shortcut="">See you later!</phrase>
+<phrase shortcut="">Take care!</phrase>
+</phrasebook>
diff --git a/kmouth/books/en-howareyou.phrasebook b/kmouth/books/en-howareyou.phrasebook
new file mode 100644
index 0000000..3c0164e
--- /dev/null
+++ b/kmouth/books/en-howareyou.phrasebook
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="How are you?">
+<phrase shortcut="">How are you?</phrase>
+<phrase shortcut="">How do you do?</phrase>
+<phrase shortcut="">I am fine.</phrase>
+<phrase shortcut="">It's a nice day.</phrase>
+<phrase shortcut="">I feel nerveless today.</phrase>
+<phrase shortcut="">I feel bored, but apart from that I am OK.</phrase>
+<phrase shortcut="">Today my pain is quite strong.</phrase>
+<phrase shortcut="">I really feel bad today.</phrase>
+</phrasebook>
diff --git a/kmouth/books/en-personal.phrasebook b/kmouth/books/en-personal.phrasebook
new file mode 100644
index 0000000..6b70229
--- /dev/null
+++ b/kmouth/books/en-personal.phrasebook
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Personal">
+<phrase shortcut="">I can only talk using this stupid machine.</phrase>
+<phrase shortcut="">Sorry, I am quite tired and need a rest now.</phrase>
+<phrase shortcut="">Thanks for your coming.</phrase>
+<phrase shortcut="">It is nice to see you.</phrase>
+<phrase shortcut="">It was very nice to chat with you.</phrase>
+<phrase shortcut="">When will you come again?</phrase>
+</phrasebook>
diff --git a/kmouth/books/en.desktop b/kmouth/books/en.desktop
new file mode 100644
index 0000000..5766e05
--- /dev/null
+++ b/kmouth/books/en.desktop
@@ -0,0 +1,61 @@
+# KDE Config File
+[Desktop Entry]
+Name=English
+Name[ar]=إنجليزية
+Name[bg]=Английски
+Name[br]=Saozneg
+Name[bs]=Engleski
+Name[ca]=Anglès
+Name[cs]=Anglicky
+Name[cy]=Saesneg
+Name[da]=Engelsk
+Name[de]=Englisch
+Name[el]=Αγγλικά
+Name[eo]=Angla
+Name[es]=Inglés
+Name[et]=Inglise
+Name[eu]=Ingelesa
+Name[fa]=انگلیسی
+Name[fi]=Englantilainen
+Name[fr]=Anglais
+Name[ga]=Béarla
+Name[gl]=Inglés
+Name[he]=אנגלית
+Name[hi]= अंग्रेजी
+Name[hu]=Angol
+Name[is]=Enska
+Name[it]=Inglese
+Name[ja]=英語
+Name[ka]=ინგლისური
+Name[km]= អង់គ្លេស​
+Name[lt]=Anglų
+Name[mk]=Англиски
+Name[ms]=Inggeris
+Name[mt]=Ingliż
+Name[nb]=Engelsk
+Name[nds]=Engelsch
+Name[ne]=अंग्रेजी
+Name[nl]=Engels
+Name[nn]=Engelsk
+Name[pa]=ਅੰਗਰੇਜ਼ੀ
+Name[pl]=Angielska
+Name[pt]=Inglês
+Name[pt_BR]=Inglês
+Name[ro]=Engleză
+Name[ru]=Английский
+Name[rw]=Icyongereza
+Name[sk]=angličtina
+Name[sl]=angleško
+Name[sr]=Енглески
+Name[sr@Latn]=Engleski
+Name[sv]=Engelska
+Name[ta]=ஆங்கிலம்
+Name[tg]=Англисӣ
+Name[th]=อังกฤษ
+Name[tr]=İngilizce
+Name[uk]=Англійська
+Name[uz]=Inglizcha
+Name[uz@cyrillic]=Инглизча
+Name[vi]=Anh
+Name[zh_CN]=英语
+Name[zh_TW]=英語
diff --git a/kmouth/books/nl-courteousness.phrasebook b/kmouth/books/nl-courteousness.phrasebook
new file mode 100644
index 0000000..609d7e3
--- /dev/null
+++ b/kmouth/books/nl-courteousness.phrasebook
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Hoffelijkheid">
+<phrase shortcut="">dank je</phrase>
+<phrase shortcut="">dankjewel</phrase>
+<phrase shortcut="">alsjeblieft</phrase>
+<phrase shortcut="">graag gedaan</phrase>
+<phrase shortcut="">eet smakelijk</phrase>
+<phrase shortcut="">geen probleem</phrase>
+<phrase shortcut="">neem me niet kwalijk</phrase>
+<phrase shortcut="">sorry</phrase>
+<phrase shortcut="">het spijt me</phrase>
+</phrasebook>
diff --git a/kmouth/books/nl-greetings.phrasebook b/kmouth/books/nl-greetings.phrasebook
new file mode 100644
index 0000000..6ea950e
--- /dev/null
+++ b/kmouth/books/nl-greetings.phrasebook
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Groeten">
+<phrase shortcut="">Hallo.</phrase>
+<phrase shortcut="">Hoi!</phrase>
+<phrase shortcut="">Goedemorgen.</phrase>
+<phrase shortcut="">Goedemiddag.</phrase>
+<phrase shortcut="">Goedenavond.</phrase>
+<phrase shortcut="">Dag!</phrase>
+<phrase shortcut="">Doei!</phrase>
+<phrase shortcut="">Tot ziens!</phrase>
+<phrase shortcut="">Later!</phrase>
+<phrase shortcut="">Kijk je uit?</phrase>
+</phrasebook>
diff --git a/kmouth/books/nl-howareyou.phrasebook b/kmouth/books/nl-howareyou.phrasebook
new file mode 100644
index 0000000..fb54408
--- /dev/null
+++ b/kmouth/books/nl-howareyou.phrasebook
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Hoe gaat het?">
+<phrase shortcut="">Hoe gaat het?</phrase>
+<phrase shortcut="">Hoe is het?</phrase>
+<phrase shortcut="">Met mij gaat het goed.</phrase>
+<phrase shortcut="">Het is lekker weer.</phrase>
+<phrase shortcut="">Ik voel me vandaag niet lekker.</phrase>
+<phrase shortcut="">Ik verveel me, maar verder gaat het wel.</phrase>
+<phrase shortcut="">Ik heb vandaag heel veel pijn.</phrase>
+<phrase shortcut="">Ik voel me vandaag ronduit slecht.</phrase>
+</phrasebook>
diff --git a/kmouth/books/nl-personal.phrasebook b/kmouth/books/nl-personal.phrasebook
new file mode 100644
index 0000000..ccb297d
--- /dev/null
+++ b/kmouth/books/nl-personal.phrasebook
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Persoonlijk">
+<phrase shortcut="">Ik kan alleen maar praten als ik deze stomme computer gebruik.</phrase>
+<phrase shortcut="">Sorry, ik ben moe. Ik ga slapen.</phrase>
+<phrase shortcut="">Leuk dat je even langsgekomen bent.</phrase>
+<phrase shortcut="">Leuk je te zien.</phrase>
+<phrase shortcut="">Wanneer zie ik je weer?</phrase>
+</phrasebook>
diff --git a/kmouth/books/nl.desktop b/kmouth/books/nl.desktop
new file mode 100644
index 0000000..e2ac386
--- /dev/null
+++ b/kmouth/books/nl.desktop
@@ -0,0 +1,50 @@
+# KDE Config File
+[Desktop Entry]
+Name=Dutch
+Name[bg]=Холандски
+Name[br]=Nederlandeg
+Name[bs]=Holandski
+Name[ca]=Holandès
+Name[cs]=Holandsky
+Name[cy]=Iseldireg
+Name[da]=Hollandsk
+Name[de]=Niederländisch
+Name[es]=Danés
+Name[et]=Hollandi
+Name[eu]=Nederlandera
+Name[fa]=هلندی
+Name[fi]=Tanskalainen
+Name[fr]=Hollandais
+Name[ga]=Ollainnis
+Name[gl]=Holandés
+Name[he]=דנית
+Name[hu]=Holland
+Name[is]=Hollenska
+Name[it]=Olandese
+Name[ja]=オランダ語
+Name[ka]=ჰოლანდიური
+Name[km]= ហុល្លង់​
+Name[lt]=Olandų
+Name[mk]=Холандски
+Name[ms]=Belanda
+Name[nb]=Nederlandsk
+Name[nds]=Nedderlannsch
+Name[ne]=डच
+Name[nl]=Nederlands
+Name[pa]=ਡੱਚ
+Name[pl]=Holenderska
+Name[pt]=Holandês
+Name[pt_BR]=Holandês
+Name[ru]=Голландский
+Name[rw]=Ikinyaholande
+Name[sk]=holandčina
+Name[sl]=Nizozemsko
+Name[sr]=Холандски
+Name[sr@Latn]=Holandski
+Name[sv]=Holländska
+Name[tg]=Немисӣ
+Name[tr]=Flemenkçe
+Name[uk]=Голландська
+Name[vi]=Hà Lan
+Name[zh_CN]=荷兰语
+Name[zh_TW]=荷蘭語
diff --git a/kmouth/books/sv-courteousness.phrasebook b/kmouth/books/sv-courteousness.phrasebook
new file mode 100644
index 0000000..9789cce
--- /dev/null
+++ b/kmouth/books/sv-courteousness.phrasebook
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Artighet">
+<phrase shortcut="">Tack</phrase>
+<phrase shortcut="">Tack så mycket</phrase>
+<phrase shortcut="">Varsågod</phrase>
+<phrase shortcut="">Smaklig måltid</phrase>
+<phrase shortcut="">Inga problem</phrase>
+<phrase shortcut="">Ursäkta mig</phrase>
+<phrase shortcut="">Ursäkta</phrase>
+<phrase shortcut="">Jag är ledsen</phrase>
+</phrasebook>
diff --git a/kmouth/books/sv-greetings.phrasebook b/kmouth/books/sv-greetings.phrasebook
new file mode 100644
index 0000000..6d8af9c
--- /dev/null
+++ b/kmouth/books/sv-greetings.phrasebook
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Hälsningar">
+<phrase shortcut="">Hallå.</phrase>
+<phrase shortcut="">Hej!</phrase>
+<phrase shortcut="">God morgon.</phrase>
+<phrase shortcut="">God eftermiddag.</phrase>
+<phrase shortcut="">God kväll.</phrase>
+<phrase shortcut="">Hej då!</phrase>
+<phrase shortcut="">Adjö!</phrase>
+<phrase shortcut="">Hejsan!</phrase>
+<phrase shortcut="">Vi ses!</phrase>
+<phrase shortcut="">Ha det bra!</phrase>
+</phrasebook>
diff --git a/kmouth/books/sv-howareyou.phrasebook b/kmouth/books/sv-howareyou.phrasebook
new file mode 100644
index 0000000..fd548ee
--- /dev/null
+++ b/kmouth/books/sv-howareyou.phrasebook
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Hur mår du?">
+<phrase shortcut="">Hur står det till?</phrase>
+<phrase shortcut="">Hur mår du?</phrase>
+<phrase shortcut="">Jag mår bra.</phrase>
+<phrase shortcut="">Det är en trevlig dag.</phrase>
+<phrase shortcut="">Jag är upprörd idag.</phrase>
+<phrase shortcut="">Jag är uttråkad, men annars mår jag bra.</phrase>
+<phrase shortcut="">Jag har riktigt ont idag.</phrase>
+<phrase shortcut="">Jag känner mig verkligt dålig idag.</phrase>
+</phrasebook>
diff --git a/kmouth/books/sv-personal.phrasebook b/kmouth/books/sv-personal.phrasebook
new file mode 100644
index 0000000..37f7636
--- /dev/null
+++ b/kmouth/books/sv-personal.phrasebook
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE phrasebook>
+<phrasebook name="Personligt">
+<phrase shortcut="">Jag kan bara prata med hjälp av den här dumma maskinen.</phrase>
+<phrase shortcut="">Tyvärr är jag ganska trött nu och behöver ta en paus.</phrase>
+<phrase shortcut="">Tack för att du kom.</phrase>
+<phrase shortcut="">Trevligt att se dig.</phrase>
+<phrase shortcut="">Det var roligt att prata med dig.</phrase>
+<phrase shortcut="">När kommer du tillbaka?</phrase>
+</phrasebook>
diff --git a/kmouth/books/sv.desktop b/kmouth/books/sv.desktop
new file mode 100644
index 0000000..46a8145
--- /dev/null
+++ b/kmouth/books/sv.desktop
@@ -0,0 +1,61 @@
+# KDE Config File
+[Desktop Entry]
+Name=Swedish
+Name[ar]=سويدية
+Name[bg]=Шведски
+Name[br]=Svedeg
+Name[bs]=Švedski
+Name[ca]=Suec
+Name[cs]=Švédsky
+Name[cy]=Swedeg
+Name[da]=Svensk
+Name[de]=Schwedisch
+Name[el]=Σουηδικά
+Name[eo]=Sveda
+Name[es]=Sueco
+Name[et]=Rootsi
+Name[eu]=Suediera
+Name[fa]=سوئدی
+Name[fi]=Ruotsalainen
+Name[fr]=Suédois
+Name[ga]=Sualainnis
+Name[gl]=Sueco
+Name[he]=שוודית
+Name[hi]=स्वीडिश
+Name[hu]=Svéd
+Name[is]=Sænska
+Name[it]=Svedese
+Name[ja]=スウェーデン語
+Name[ka]=შვედური
+Name[km]= ស៊ុយអែដ
+Name[lt]=Švedų
+Name[mk]=Шведски
+Name[ms]=Sweden
+Name[mt]=Svediż
+Name[nb]=Svensk
+Name[nds]=Sweedsch
+Name[ne]=स्वीडिस
+Name[nl]=Zweeds
+Name[nn]=Svensk
+Name[pa]=ਸਵੀਡਨੀ
+Name[pl]=Szwedzka
+Name[pt]=Sueco
+Name[pt_BR]=Suíço
+Name[ro]=Suedeză
+Name[ru]=Шведский
+Name[rw]=Ikinyasuwede
+Name[sk]=švédčina
+Name[sl]=švedsko
+Name[sr]=Шведски
+Name[sr@Latn]=Švedski
+Name[sv]=Svenska
+Name[ta]=ஸ்வீடிஷ்
+Name[tg]=Шведӣ
+Name[th]=สวีเดน
+Name[tr]=İsveççe
+Name[uk]=Шведська
+Name[uz]=Shvedcha
+Name[uz@cyrillic]=Шведча
+Name[vi]=Thuỵ Điển
+Name[zh_CN]=瑞典语
+Name[zh_TW]=瑞典語
diff --git a/kmouth/configwizard.cpp b/kmouth/configwizard.cpp
new file mode 100644
index 0000000..d22c463
--- /dev/null
+++ b/kmouth/configwizard.cpp
@@ -0,0 +1,144 @@
+/***************************************************************************
+ configwizard.cpp - description
+ -------------------
+ begin : Mit Nov 20 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#include "configwizard.h"
+#include <qlayout.h>
+#include <qlabel.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kstandarddirs.h>
+#include <ksconfig.h>
+#include <kconfig.h>
+
+#include "texttospeechconfigurationwidget.h"
+#include "phrasebook/phrasebookdialog.h"
+#include "wordcompletion/wordcompletion.h"
+#include "wordcompletion/dictionarycreationwizard.h"
+
+ConfigWizard::ConfigWizard (QWidget *parent, const char *name, KConfig *config)
+ : KWizard(parent, name, true)
+{
+ setCaption (i18n("Initial Configuration - KMouth"));
+
+ initCommandPage (config);
+ initBookPage ();
+ initCompletion (config);
+}
+
+ConfigWizard::~ConfigWizard() {
+}
+
+void ConfigWizard::initCommandPage(KConfig *config) {
+ config->setGroup("TTS System");
+ bool displayCommand = false;
+ if (!config->hasKey("Command")) displayCommand = true;
+ if (!config->hasKey("StdIn")) displayCommand = true;
+ if (!config->hasKey("Codec")) displayCommand = true;
+
+ if (displayCommand) {
+ commandWidget = new TextToSpeechConfigurationWidget (this, "ttsPage");
+ commandWidget->readOptions (config, "TTS System");
+ addPage (commandWidget, i18n("Text-to-Speech Configuration"));
+ setHelpEnabled (commandWidget, true);
+ setFinishEnabled (commandWidget, true);
+ }
+ else
+ commandWidget = 0;
+}
+
+void ConfigWizard::initBookPage() {
+ QString standardBook = KApplication::kApplication()->dirs()->findResource("appdata", "standard.phrasebook");
+ bool displayBook = (standardBook.isNull() || standardBook.isEmpty());
+
+ if (displayBook) {
+ bookWidget = new InitialPhraseBookWidget (this, "pbPage");
+ addPage (bookWidget, i18n("Initial Phrase Book"));
+ setHelpEnabled (bookWidget, true);
+ setFinishEnabled (bookWidget, true);
+ if (commandWidget != 0)
+ setFinishEnabled (commandWidget, false);
+ }
+ else
+ bookWidget = 0;
+}
+
+void ConfigWizard::initCompletion (KConfig *config) {
+ if (!WordCompletion::isConfigured()) {
+ QString dictionaryFile = KApplication::kApplication()->dirs()->findResource("appdata", "dictionary.txt");
+ QFile file(dictionaryFile);
+ if (file.exists()) {
+ // If there is a word completion dictionary but no entry in the
+ // configuration file, we need to add it there.
+ config->setGroup("Dictionary 0");
+ config->writeEntry ("Filename", "dictionary.txt");
+ config->writeEntry ("Name", "Default");
+ config->writeEntry ("Language", QString::null);
+ config->sync();
+ }
+ }
+
+ if (config->hasGroup("Completion")) {
+ completionWidget = 0;
+ return;
+ }
+
+ if (!WordCompletion::isConfigured()) {
+ completionWidget = new CompletionWizardWidget(this, "completionPage");
+ addPage (completionWidget, i18n("Word Completion"));
+ setHelpEnabled (completionWidget, true);
+ setFinishEnabled (completionWidget, true);
+
+ if (commandWidget != 0)
+ setFinishEnabled (commandWidget, false);
+ if (bookWidget != 0)
+ setFinishEnabled (bookWidget, false);
+ }
+ else
+ completionWidget = 0;
+}
+
+void ConfigWizard::saveConfig (KConfig *config) {
+ if (commandWidget != 0) {
+ commandWidget->ok();
+ commandWidget->saveOptions (config, "TTS System");
+ }
+
+ if (bookWidget != 0)
+ bookWidget->createBook();
+
+ if (completionWidget != 0)
+ completionWidget->ok (config);
+}
+
+bool ConfigWizard::requestConfiguration () {
+ if (commandWidget != 0 || bookWidget != 0 || completionWidget != 0)
+ return (exec() == QDialog::Accepted);
+ else
+ return false;
+}
+
+bool ConfigWizard::configurationNeeded () {
+ return (commandWidget != 0 || bookWidget != 0 || completionWidget != 0);
+}
+
+void ConfigWizard::help () {
+ KApplication::kApplication()->invokeHelp ("Wizard");
+}
+
+#include "configwizard.moc"
diff --git a/kmouth/configwizard.h b/kmouth/configwizard.h
new file mode 100644
index 0000000..8ddcb60
--- /dev/null
+++ b/kmouth/configwizard.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ configwizard.h - description
+ -------------------
+ begin : Mit Nov 20 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#ifndef CONFIGWIZARD_H
+#define CONFIGWIZARD_H
+
+#include <qwidget.h>
+
+#include <kwizard.h>
+
+class KConfig;
+class TextToSpeechConfigurationWidget;
+class InitialPhraseBookWidget;
+class CompletionWizardWidget;
+
+/**The class ConfigWizard is used when the user starts KMouth for the first
+ * time. It asks the user to provide a first set of configuration data.
+ *@author Gunnar Schmi Dt
+ */
+
+class ConfigWizard : public KWizard {
+ Q_OBJECT
+public:
+ ConfigWizard (QWidget *parent, const char *name, KConfig *config);
+ ~ConfigWizard();
+
+ bool configurationNeeded ();
+ bool requestConfiguration ();
+ void saveConfig (KConfig *config);
+
+protected:
+ void help();
+
+private:
+ void initCommandPage (KConfig *config);
+ void initBookPage();
+ void initCompletion (KConfig *config);
+
+ TextToSpeechConfigurationWidget *commandWidget;
+ InitialPhraseBookWidget *bookWidget;
+ CompletionWizardWidget *completionWidget;
+};
+
+#endif
diff --git a/kmouth/icons/Makefile.am b/kmouth/icons/Makefile.am
new file mode 100644
index 0000000..5830f8f
--- /dev/null
+++ b/kmouth/icons/Makefile.am
@@ -0,0 +1,11 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+SUBDIRS = history phrase phrasebook app
+
+EXTRA_DIST = hi16-action-speak.png hi32-action-speak.png hi48-action-speak.png hi22-action-speak.png
+
+####### kdevelop will overwrite this part!!! (end)############
+
+kmouthiconsdir = $(kde_datadir)/kmouth/icons
+kmouthicons_ICON = AUTO
+
diff --git a/kmouth/icons/app/Makefile.am b/kmouth/icons/app/Makefile.am
new file mode 100644
index 0000000..ff9afea
--- /dev/null
+++ b/kmouth/icons/app/Makefile.am
@@ -0,0 +1 @@
+KDE_ICON = kmouth
diff --git a/kmouth/icons/app/hi16-app-kmouth.png b/kmouth/icons/app/hi16-app-kmouth.png
new file mode 100644
index 0000000..69078b9
--- /dev/null
+++ b/kmouth/icons/app/hi16-app-kmouth.png
Binary files differ
diff --git a/kmouth/icons/app/hi22-app-kmouth.png b/kmouth/icons/app/hi22-app-kmouth.png
new file mode 100644
index 0000000..1052d56
--- /dev/null
+++ b/kmouth/icons/app/hi22-app-kmouth.png
Binary files differ
diff --git a/kmouth/icons/app/hi32-app-kmouth.png b/kmouth/icons/app/hi32-app-kmouth.png
new file mode 100644
index 0000000..617025f
--- /dev/null
+++ b/kmouth/icons/app/hi32-app-kmouth.png
Binary files differ
diff --git a/kmouth/icons/app/hi48-app-kmouth.png b/kmouth/icons/app/hi48-app-kmouth.png
new file mode 100644
index 0000000..26d22ce
--- /dev/null
+++ b/kmouth/icons/app/hi48-app-kmouth.png
Binary files differ
diff --git a/kmouth/icons/app/lo16-app-kmouth.png b/kmouth/icons/app/lo16-app-kmouth.png
new file mode 100644
index 0000000..69078b9
--- /dev/null
+++ b/kmouth/icons/app/lo16-app-kmouth.png
Binary files differ
diff --git a/kmouth/icons/app/lo22-app-kmouth.png b/kmouth/icons/app/lo22-app-kmouth.png
new file mode 100644
index 0000000..1052d56
--- /dev/null
+++ b/kmouth/icons/app/lo22-app-kmouth.png
Binary files differ
diff --git a/kmouth/icons/app/lo32-app-kmouth.png b/kmouth/icons/app/lo32-app-kmouth.png
new file mode 100644
index 0000000..617025f
--- /dev/null
+++ b/kmouth/icons/app/lo32-app-kmouth.png
Binary files differ
diff --git a/kmouth/icons/hi16-action-speak.png b/kmouth/icons/hi16-action-speak.png
new file mode 100644
index 0000000..69078b9
--- /dev/null
+++ b/kmouth/icons/hi16-action-speak.png
Binary files differ
diff --git a/kmouth/icons/hi22-action-speak.png b/kmouth/icons/hi22-action-speak.png
new file mode 100644
index 0000000..1052d56
--- /dev/null
+++ b/kmouth/icons/hi22-action-speak.png
Binary files differ
diff --git a/kmouth/icons/hi32-action-speak.png b/kmouth/icons/hi32-action-speak.png
new file mode 100644
index 0000000..617025f
--- /dev/null
+++ b/kmouth/icons/hi32-action-speak.png
Binary files differ
diff --git a/kmouth/icons/hi48-action-speak.png b/kmouth/icons/hi48-action-speak.png
new file mode 100644
index 0000000..26d22ce
--- /dev/null
+++ b/kmouth/icons/hi48-action-speak.png
Binary files differ
diff --git a/kmouth/icons/history/Makefile.am b/kmouth/icons/history/Makefile.am
new file mode 100644
index 0000000..abce34f
--- /dev/null
+++ b/kmouth/icons/history/Makefile.am
@@ -0,0 +1,9 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+EXTRA_DIST = hi16-action-phrasehistory_open.png hi16-action-phrasehistory_print.png hi16-action-phrasehistory_save.png hi22-action-phrasehistory_open.png hi22-action-phrasehistory_print.png hi22-action-phrasehistory_save.png hi32-action-phrasehistory_open.png hi32-action-phrasehistory_print.png hi32-action-phrasehistory_save.png
+
+####### kdevelop will overwrite this part!!! (end)############
+
+kmouthiconsdir = $(kde_datadir)/kmouth/icons
+kmouthicons_ICON = AUTO
diff --git a/kmouth/icons/history/hi16-action-phrasehistory_open.png b/kmouth/icons/history/hi16-action-phrasehistory_open.png
new file mode 100644
index 0000000..abb66a2
--- /dev/null
+++ b/kmouth/icons/history/hi16-action-phrasehistory_open.png
Binary files differ
diff --git a/kmouth/icons/history/hi16-action-phrasehistory_print.png b/kmouth/icons/history/hi16-action-phrasehistory_print.png
new file mode 100644
index 0000000..7b589b0
--- /dev/null
+++ b/kmouth/icons/history/hi16-action-phrasehistory_print.png
Binary files differ
diff --git a/kmouth/icons/history/hi16-action-phrasehistory_save.png b/kmouth/icons/history/hi16-action-phrasehistory_save.png
new file mode 100644
index 0000000..157602e
--- /dev/null
+++ b/kmouth/icons/history/hi16-action-phrasehistory_save.png
Binary files differ
diff --git a/kmouth/icons/history/hi22-action-phrasehistory_open.png b/kmouth/icons/history/hi22-action-phrasehistory_open.png
new file mode 100644
index 0000000..85bfc08
--- /dev/null
+++ b/kmouth/icons/history/hi22-action-phrasehistory_open.png
Binary files differ
diff --git a/kmouth/icons/history/hi22-action-phrasehistory_print.png b/kmouth/icons/history/hi22-action-phrasehistory_print.png
new file mode 100644
index 0000000..a1eec0a
--- /dev/null
+++ b/kmouth/icons/history/hi22-action-phrasehistory_print.png
Binary files differ
diff --git a/kmouth/icons/history/hi22-action-phrasehistory_save.png b/kmouth/icons/history/hi22-action-phrasehistory_save.png
new file mode 100644
index 0000000..db87121
--- /dev/null
+++ b/kmouth/icons/history/hi22-action-phrasehistory_save.png
Binary files differ
diff --git a/kmouth/icons/history/hi32-action-phrasehistory_open.png b/kmouth/icons/history/hi32-action-phrasehistory_open.png
new file mode 100644
index 0000000..475ddbd
--- /dev/null
+++ b/kmouth/icons/history/hi32-action-phrasehistory_open.png
Binary files differ
diff --git a/kmouth/icons/history/hi32-action-phrasehistory_print.png b/kmouth/icons/history/hi32-action-phrasehistory_print.png
new file mode 100644
index 0000000..d63635a
--- /dev/null
+++ b/kmouth/icons/history/hi32-action-phrasehistory_print.png
Binary files differ
diff --git a/kmouth/icons/history/hi32-action-phrasehistory_save.png b/kmouth/icons/history/hi32-action-phrasehistory_save.png
new file mode 100644
index 0000000..4a39a25
--- /dev/null
+++ b/kmouth/icons/history/hi32-action-phrasehistory_save.png
Binary files differ
diff --git a/kmouth/icons/phrase/Makefile.am b/kmouth/icons/phrase/Makefile.am
new file mode 100644
index 0000000..15f3677
--- /dev/null
+++ b/kmouth/icons/phrase/Makefile.am
@@ -0,0 +1,9 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+EXTRA_DIST = hi16-action-phrase.png hi16-action-phrase_new.png hi16-action-phrase_open.png hi16-action-phrase_save.png hi22-action-phrase.png hi22-action-phrase_new.png hi22-action-phrase_open.png hi22-action-phrase_save.png hi32-action-phrase.png hi32-action-phrase_new.png hi32-action-phrase_open.png hi32-action-phrase_save.png
+
+####### kdevelop will overwrite this part!!! (end)############
+
+kmouthiconsdir = $(kde_datadir)/kmouth/icons
+kmouthicons_ICON = AUTO
diff --git a/kmouth/icons/phrase/hi16-action-phrase.png b/kmouth/icons/phrase/hi16-action-phrase.png
new file mode 100644
index 0000000..709efd0
--- /dev/null
+++ b/kmouth/icons/phrase/hi16-action-phrase.png
Binary files differ
diff --git a/kmouth/icons/phrase/hi16-action-phrase_new.png b/kmouth/icons/phrase/hi16-action-phrase_new.png
new file mode 100644
index 0000000..b8eaa20
--- /dev/null
+++ b/kmouth/icons/phrase/hi16-action-phrase_new.png
Binary files differ
diff --git a/kmouth/icons/phrase/hi16-action-phrase_open.png b/kmouth/icons/phrase/hi16-action-phrase_open.png
new file mode 100644
index 0000000..2b87847
--- /dev/null
+++ b/kmouth/icons/phrase/hi16-action-phrase_open.png
Binary files differ
diff --git a/kmouth/icons/phrase/hi16-action-phrase_save.png b/kmouth/icons/phrase/hi16-action-phrase_save.png
new file mode 100644
index 0000000..4d42077
--- /dev/null
+++ b/kmouth/icons/phrase/hi16-action-phrase_save.png
Binary files differ
diff --git a/kmouth/icons/phrase/hi22-action-phrase.png b/kmouth/icons/phrase/hi22-action-phrase.png
new file mode 100644
index 0000000..4fbb2a9
--- /dev/null
+++ b/kmouth/icons/phrase/hi22-action-phrase.png
Binary files differ
diff --git a/kmouth/icons/phrase/hi22-action-phrase_new.png b/kmouth/icons/phrase/hi22-action-phrase_new.png
new file mode 100644
index 0000000..5885d76
--- /dev/null
+++ b/kmouth/icons/phrase/hi22-action-phrase_new.png
Binary files differ
diff --git a/kmouth/icons/phrase/hi22-action-phrase_open.png b/kmouth/icons/phrase/hi22-action-phrase_open.png
new file mode 100644
index 0000000..6556f6e
--- /dev/null
+++ b/kmouth/icons/phrase/hi22-action-phrase_open.png
Binary files differ
diff --git a/kmouth/icons/phrase/hi22-action-phrase_save.png b/kmouth/icons/phrase/hi22-action-phrase_save.png
new file mode 100644
index 0000000..652c506
--- /dev/null
+++ b/kmouth/icons/phrase/hi22-action-phrase_save.png
Binary files differ
diff --git a/kmouth/icons/phrase/hi32-action-phrase.png b/kmouth/icons/phrase/hi32-action-phrase.png
new file mode 100644
index 0000000..7b55281
--- /dev/null
+++ b/kmouth/icons/phrase/hi32-action-phrase.png
Binary files differ
diff --git a/kmouth/icons/phrase/hi32-action-phrase_new.png b/kmouth/icons/phrase/hi32-action-phrase_new.png
new file mode 100644
index 0000000..c3e1ff1
--- /dev/null
+++ b/kmouth/icons/phrase/hi32-action-phrase_new.png
Binary files differ
diff --git a/kmouth/icons/phrase/hi32-action-phrase_open.png b/kmouth/icons/phrase/hi32-action-phrase_open.png
new file mode 100644
index 0000000..1892548
--- /dev/null
+++ b/kmouth/icons/phrase/hi32-action-phrase_open.png
Binary files differ
diff --git a/kmouth/icons/phrase/hi32-action-phrase_save.png b/kmouth/icons/phrase/hi32-action-phrase_save.png
new file mode 100644
index 0000000..1634e7a
--- /dev/null
+++ b/kmouth/icons/phrase/hi32-action-phrase_save.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/Makefile.am b/kmouth/icons/phrasebook/Makefile.am
new file mode 100644
index 0000000..f5c9320
--- /dev/null
+++ b/kmouth/icons/phrasebook/Makefile.am
@@ -0,0 +1,9 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+EXTRA_DIST = hi16-action-phrasebook.png hi16-action-phrasebook_new.png hi16-action-phrasebook_open.png hi16-action-phrasebook_save.png hi22-action-phrasebook.png hi22-action-phrasebook_new.png hi22-action-phrasebook_open.png hi22-action-phrasebook_save.png hi32-action-phrasebook.png hi32-action-phrasebook_new.png hi32-action-phrasebook_open.png hi32-action-phrasebook_save.png hi16-action-phrasebook_closed.png hi22-action-phrasebook_closed.png hi32-action-phrasebook_closed.png
+
+####### kdevelop will overwrite this part!!! (end)############
+
+kmouthiconsdir = $(kde_datadir)/kmouth/icons
+kmouthicons_ICON = AUTO
diff --git a/kmouth/icons/phrasebook/hi16-action-phrasebook.png b/kmouth/icons/phrasebook/hi16-action-phrasebook.png
new file mode 100644
index 0000000..394f70e
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi16-action-phrasebook.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi16-action-phrasebook_closed.png b/kmouth/icons/phrasebook/hi16-action-phrasebook_closed.png
new file mode 100644
index 0000000..5f1fb19
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi16-action-phrasebook_closed.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi16-action-phrasebook_new.png b/kmouth/icons/phrasebook/hi16-action-phrasebook_new.png
new file mode 100644
index 0000000..2de13d1
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi16-action-phrasebook_new.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi16-action-phrasebook_open.png b/kmouth/icons/phrasebook/hi16-action-phrasebook_open.png
new file mode 100644
index 0000000..494e886
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi16-action-phrasebook_open.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi16-action-phrasebook_save.png b/kmouth/icons/phrasebook/hi16-action-phrasebook_save.png
new file mode 100644
index 0000000..6164045
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi16-action-phrasebook_save.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi22-action-phrasebook.png b/kmouth/icons/phrasebook/hi22-action-phrasebook.png
new file mode 100644
index 0000000..c7b7a79
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi22-action-phrasebook.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi22-action-phrasebook_closed.png b/kmouth/icons/phrasebook/hi22-action-phrasebook_closed.png
new file mode 100644
index 0000000..7d87220
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi22-action-phrasebook_closed.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi22-action-phrasebook_new.png b/kmouth/icons/phrasebook/hi22-action-phrasebook_new.png
new file mode 100644
index 0000000..37b9492
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi22-action-phrasebook_new.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi22-action-phrasebook_open.png b/kmouth/icons/phrasebook/hi22-action-phrasebook_open.png
new file mode 100644
index 0000000..c58cfdd
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi22-action-phrasebook_open.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi22-action-phrasebook_save.png b/kmouth/icons/phrasebook/hi22-action-phrasebook_save.png
new file mode 100644
index 0000000..c221ce3
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi22-action-phrasebook_save.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi32-action-phrasebook.png b/kmouth/icons/phrasebook/hi32-action-phrasebook.png
new file mode 100644
index 0000000..6d339b8
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi32-action-phrasebook.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi32-action-phrasebook_closed.png b/kmouth/icons/phrasebook/hi32-action-phrasebook_closed.png
new file mode 100644
index 0000000..2e65c88
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi32-action-phrasebook_closed.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi32-action-phrasebook_new.png b/kmouth/icons/phrasebook/hi32-action-phrasebook_new.png
new file mode 100644
index 0000000..4e3136f
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi32-action-phrasebook_new.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi32-action-phrasebook_open.png b/kmouth/icons/phrasebook/hi32-action-phrasebook_open.png
new file mode 100644
index 0000000..518cdb7
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi32-action-phrasebook_open.png
Binary files differ
diff --git a/kmouth/icons/phrasebook/hi32-action-phrasebook_save.png b/kmouth/icons/phrasebook/hi32-action-phrasebook_save.png
new file mode 100644
index 0000000..3f55caf
--- /dev/null
+++ b/kmouth/icons/phrasebook/hi32-action-phrasebook_save.png
Binary files differ
diff --git a/kmouth/kmouth.cpp b/kmouth/kmouth.cpp
new file mode 100644
index 0000000..c78a010
--- /dev/null
+++ b/kmouth/kmouth.cpp
@@ -0,0 +1,484 @@
+/***************************************************************************
+ kmouth.cpp - description
+ -------------------
+ begin : Mon Aug 26 15:41:23 CEST 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// include files for QT
+#include <qdir.h>
+#include <qpainter.h>
+
+// include files for KDE
+#include <kiconloader.h>
+#include <kmenubar.h>
+#include <kstatusbar.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kstdaction.h>
+#include <kprinter.h>
+#include <kpopupmenu.h>
+#include <kstandarddirs.h>
+
+// application specific includes
+#include "kmouth.h"
+#include "phraselist.h"
+#include "phrasebook/phrasebook.h"
+#include "phrasebook/phrasebookdialog.h"
+#include "optionsdialog.h"
+#include "configwizard.h"
+
+#define ID_STATUS_MSG 1
+
+KMouthApp::KMouthApp(QWidget* , const char* name):KMainWindow(0, name)
+{
+ isConfigured = false;
+ config=kapp->config();
+
+ ///////////////////////////////////////////////////////////////////
+ // call inits to invoke all other construction parts
+ initStatusBar();
+ initPhraseList();
+ initActions();
+ optionsDialog = new OptionsDialog(this);
+ connect (optionsDialog, SIGNAL(configurationChanged ()),
+ this, SLOT(slotConfigurationChanged ()));
+ connect (optionsDialog, SIGNAL(configurationChanged ()),
+ phraseList, SLOT(configureCompletion ()));
+
+ phrases = new KActionCollection (this);
+
+ readOptions();
+ ConfigWizard *wizard = new ConfigWizard (this, "ConfigWizard", config);
+ if (wizard->configurationNeeded ()) {
+ if (wizard->requestConfiguration ()) {
+ isConfigured = true;
+ saveOptions();
+ wizard->saveConfig (config);
+ readOptions();
+ }
+ else
+ isConfigured = false;
+ }
+ else
+ isConfigured = true;
+ delete wizard;
+
+ if (isConfigured) {
+ phraseList->configureCompletion();
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ // disable actions at startup
+ fileSaveAs->setEnabled(false);
+ filePrint->setEnabled(false);
+}
+
+KMouthApp::~KMouthApp()
+{
+
+}
+
+bool KMouthApp::configured() {
+ return isConfigured;
+}
+
+void KMouthApp::initActions() {
+// The "File" menu
+ fileOpen = new KAction(i18n("&Open as History..."), "phrasehistory_open", KStdAccel::open(), this, SLOT(slotFileOpen()), actionCollection(),"file_open");
+ fileOpen->setStatusText(i18n("Opens an existing file as history"));
+ fileOpen->setWhatsThis (i18n("Opens an existing file as history"));
+
+ fileSaveAs = new KAction(i18n("Save &History As..."), "phrasehistory_save", KStdAccel::save(), this, SLOT(slotFileSaveAs()), actionCollection(),"file_save_as");
+ fileSaveAs->setStatusText(i18n("Saves the actual history as..."));
+ fileSaveAs->setWhatsThis (i18n("Saves the actual history as..."));
+
+ filePrint = new KAction(i18n("&Print History..."), "phrasehistory_print", KStdAccel::print(), this, SLOT(slotFilePrint()), actionCollection(),"file_print");
+ filePrint->setStatusText(i18n("Prints out the actual history"));
+ filePrint->setWhatsThis (i18n("Prints out the actual history"));
+
+ fileQuit = KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection());
+ fileQuit->setStatusText(i18n("Quits the application"));
+ fileQuit->setWhatsThis (i18n("Quits the application"));
+
+// The "Edit" menu
+ editCut = KStdAction::cut(phraseList, SLOT(cut()), actionCollection());
+ editCut->setStatusText(i18n("Cuts the selected section and puts it to the clipboard"));
+ editCut->setWhatsThis (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. Otherwise the selected sentences in the history (if any) are placed on the clipboard."));
+
+ editCopy = KStdAction::copy(phraseList, SLOT(copy()), actionCollection());
+ editCopy->setStatusText(i18n("Copies the selected section to the clipboard"));
+ editCopy->setWhatsThis (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 selected sentences in the history (if any) are copied to the clipboard."));
+
+ editPaste = KStdAction::paste(phraseList, SLOT(paste()), actionCollection());
+ editPaste->setStatusText(i18n("Pastes the clipboard contents to actual position"));
+ editPaste->setWhatsThis (i18n("Pastes the clipboard contents at the current cursor position into the edit field."));
+
+ editSpeak = new KAction (i18n("&Speak"), "speak", 0, phraseList, SLOT(speak()), actionCollection(),"edit_speak");
+ editSpeak->setStatusText(i18n("Speaks the currently active sentence(s)"));
+ editSpeak->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."));
+
+// The "Phrase book" menu
+ phrasebookEdit = new KAction(i18n("&Edit..."), 0, 0, this, SLOT(slotEditPhrasebook()), actionCollection(),"phrasebook_edit");
+
+// The "Options" menu
+ viewMenuBar = KStdAction::showMenubar(this, SLOT(slotViewMenuBar()), actionCollection());
+ viewToolBar = KStdAction::showToolbar(this, SLOT(slotViewToolBar()), actionCollection());
+ viewToolBar->setStatusText(i18n("Enables/disables the toolbar"));
+ viewToolBar->setWhatsThis (i18n("Enables/disables the toolbar"));
+
+ viewPhrasebookBar = new KToggleAction (i18n("Show P&hrasebook Bar"), 0, 0, this, SLOT(slotViewPhrasebookBar()), actionCollection(), "showPhrasebookBar");
+ viewPhrasebookBar->setStatusText(i18n("Enables/disables the phrasebook bar"));
+ viewPhrasebookBar->setWhatsThis (i18n("Enables/disables the phrasebook bar"));
+
+ viewStatusBar = KStdAction::showStatusbar(this, SLOT(slotViewStatusBar()), actionCollection());
+ viewStatusBar->setStatusText(i18n("Enables/disables the statusbar"));
+ viewStatusBar->setWhatsThis (i18n("Enables/disables the statusbar"));
+
+ configureTTS = new KAction (i18n("&Configure KMouth..."), "configure", 0, this, SLOT(slotConfigureTTS()), actionCollection(), "configureTTS");
+ configureTTS->setStatusText(i18n("Opens the configuration dialog"));
+ configureTTS->setWhatsThis (i18n("Opens the configuration dialog"));
+
+// The "Help" menu
+ // The "Help" menu will automatically get created.
+
+// The popup menu of the list of spoken sentences
+ phraseListSpeak = new KAction (i18n("&Speak"), "speak", 0, phraseList, SLOT(speakListSelection()), actionCollection(), "phraselist_speak");
+ phraseListSpeak->setStatusText(i18n("Speaks the currently selected phrases in the history"));
+ phraseListSpeak->setWhatsThis (i18n("Speaks the currently selected phrases in the history"));
+
+ phraseListRemove = new KAction (i18n("&Delete"), "editdelete", 0, phraseList, SLOT(removeListSelection()), actionCollection(), "phraselist_remove");
+ phraseListRemove->setStatusText(i18n("Deletes the currently selected phrases from the history"));
+ phraseListRemove->setWhatsThis (i18n("Deletes the currently selected phrases from the history"));
+
+ phraseListCut = new KAction (i18n("Cu&t"), "editcut", 0, phraseList, SLOT(cutListSelection()), actionCollection(), "phraselist_cut");
+ phraseListCut->setStatusText(i18n("Cuts the currently selected phrases from the history and puts them to the clipboard"));
+ phraseListCut->setWhatsThis (i18n("Cuts the currently selected phrases from the history and puts them to the clipboard"));
+
+ phraseListCopy = new KAction (i18n("&Copy"), "editcopy", 0, phraseList, SLOT(copyListSelection()), actionCollection(), "phraselist_copy");
+ phraseListCut->setStatusText(i18n("Copies the currently selected phrases from the history to the clipboard"));
+ phraseListCut->setWhatsThis (i18n("Copies the currently selected phrases from the history to the clipboard"));
+
+ phraselistSelectAll = new KAction (i18n("Select &All Entries"), 0, 0, phraseList, SLOT(selectAllEntries()), actionCollection(),"phraselist_select_all");
+ phraselistSelectAll->setStatusText(i18n("Selects all phrases in the history"));
+ phraselistSelectAll->setWhatsThis (i18n("Selects all phrases in the history"));
+
+ phraselistDeselectAll = new KAction (i18n("D&eselect All Entries"), 0, 0, phraseList, SLOT(deselectAllEntries()), actionCollection(),"phraselist_deselect_all");
+ phraselistDeselectAll->setStatusText(i18n("Deselects all phrases in the history"));
+ phraselistDeselectAll->setWhatsThis (i18n("Deselects all phrases in the history"));
+
+// The popup menu of the edit field
+ // The popup menu of the edit field will automatically get created.
+
+ // use the absolute path to your kmouthui.rc file for testing purpose in createGUI();
+ createGUI();
+}
+
+void KMouthApp::initStatusBar()
+{
+ ///////////////////////////////////////////////////////////////////
+ // STATUSBAR
+ // TODO: add your own items you need for displaying current application status.
+ statusBar()->insertItem(i18n("Ready."), ID_STATUS_MSG);
+}
+
+void KMouthApp::initPhraseList()
+{
+ ////////////////////////////////////////////////////////////////////
+ // create the main widget here that is managed by KTMainWindow's view-region and
+ // connect the widget to your document to display document contents.
+
+ phraseList = new PhraseList(this);
+ setCentralWidget(phraseList);
+}
+
+void KMouthApp::openDocumentFile(const KURL& url)
+{
+ slotStatusMsg(i18n("Opening file..."));
+
+ phraseList->open (url);
+ slotStatusMsg(i18n("Ready."));
+}
+
+void KMouthApp::saveOptions() {
+ if (isConfigured) {
+ config->setGroup("General Options");
+ config->writeEntry("Geometry", size());
+ config->writeEntry("Show Menubar", viewMenuBar->isChecked());
+ config->writeEntry("Show Toolbar", viewToolBar->isChecked());
+ config->writeEntry("Show Phrasebook Bar", viewPhrasebookBar->isChecked());
+ config->writeEntry("Show Statusbar",viewStatusBar->isChecked());
+ config->writeEntry("ToolBarPos", (int) toolBar("mainToolBar")->barPos());
+
+ if (phraseList != 0)
+ phraseList->saveCompletionOptions(config);
+ optionsDialog->saveOptions(config);
+ toolBar("mainToolBar")->saveSettings (config, "mainToolBar");
+ toolBar("phrasebookBar")->saveSettings (config, "phrasebookBar");
+ }
+}
+
+
+void KMouthApp::readOptions()
+{
+ config->setGroup("General Options");
+
+ // bar status settings
+ bool bViewMenubar = config->readBoolEntry("Show Menubar", true);
+ viewMenuBar->setChecked(bViewMenubar);
+ slotViewMenuBar();
+
+ bool bViewToolbar = config->readBoolEntry("Show Toolbar", true);
+ viewToolBar->setChecked(bViewToolbar);
+ slotViewToolBar();
+
+ bool bViewPhrasebookbar = config->readBoolEntry("Show Phrasebook Bar", true);
+ viewPhrasebookBar->setChecked(bViewPhrasebookbar);
+
+ bool bViewStatusbar = config->readBoolEntry("Show Statusbar", true);
+ viewStatusBar->setChecked(bViewStatusbar);
+ slotViewStatusBar();
+
+
+ // bar position settings
+ KToolBar::BarPosition toolBarPos;
+ toolBarPos=(KToolBar::BarPosition) config->readNumEntry("ToolBarPos", KToolBar::Top);
+ toolBar("mainToolBar")->setBarPos(toolBarPos);
+
+ QSize size=config->readSizeEntry("Geometry");
+ if(!size.isEmpty())
+ {
+ resize(size);
+ }
+
+ optionsDialog->readOptions(config);
+
+ toolBar("mainToolBar")->applySettings (config, "mainToolBar");
+ toolBar("phrasebookBar")->applySettings (config, "phrasebookBar");
+
+ QString standardBook = KApplication::kApplication()->dirs()->findResource("appdata", "standard.phrasebook");
+ if (!standardBook.isEmpty()) {
+ PhraseBook book;
+ book.open(KURL::fromPathOrURL( standardBook ));
+ slotPhrasebookConfirmed(book);
+ }
+ if (phraseList != 0)
+ phraseList->readCompletionOptions(config);
+}
+
+bool KMouthApp::queryClose()
+{
+ return true;
+}
+
+bool KMouthApp::queryExit()
+{
+ saveOptions();
+ return true;
+}
+
+void KMouthApp::enableMenuEntries(bool existSelectedEntries, bool existDeselectedEntries) {
+ bool existEntries = existSelectedEntries | existDeselectedEntries;
+ fileSaveAs->setEnabled (existEntries);
+ filePrint->setEnabled (existEntries);
+
+ phraselistSelectAll->setEnabled (existDeselectedEntries);
+
+ phraselistDeselectAll->setEnabled (existSelectedEntries);
+ phraseListSpeak->setEnabled (existSelectedEntries);
+ phraseListRemove->setEnabled (existSelectedEntries);
+ phraseListCut->setEnabled (existSelectedEntries);
+ phraseListCopy->setEnabled (existSelectedEntries);
+}
+
+/////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATION
+/////////////////////////////////////////////////////////////////////
+
+void KMouthApp::slotFileOpen() {
+ slotStatusMsg(i18n("Opening file..."));
+
+ phraseList->open();
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void KMouthApp::slotFileSaveAs() {
+ slotStatusMsg(i18n("Saving history with a new filename..."));
+
+ phraseList->save();
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void KMouthApp::slotFilePrint()
+{
+ slotStatusMsg(i18n("Printing..."));
+
+ KPrinter printer;
+ if (printer.setup(this))
+ {
+ phraseList->print(&printer);
+ }
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void KMouthApp::slotFileQuit()
+{
+ slotStatusMsg(i18n("Exiting..."));
+ saveOptions();
+ // close the first window, the list makes the next one the first again.
+ // This ensures that queryClose() is called on each window to ask for closing
+ KMainWindow* w;
+ if (memberList)
+ {
+ for(w=memberList->first(); w!=0; w=memberList->first())
+ {
+ // only close the window if the closeEvent is accepted. If the user presses Cancel on the saveModified() dialog,
+ // the window and the application stay open.
+ if(!w->close())
+ break;
+ memberList->removeRef(w);
+ }
+ }
+}
+
+void KMouthApp::slotEditPhrasebook () {
+ PhraseBookDialog *phraseBookDialog = PhraseBookDialog::get();
+ // As we do not know whether the we are already connected to the slot,
+ // we first disconnect and then connect again.
+ disconnect (phraseBookDialog, SIGNAL(phrasebookConfirmed (PhraseBook &)),
+ this, SLOT(slotPhrasebookConfirmed (PhraseBook &)));
+ connect (phraseBookDialog, SIGNAL(phrasebookConfirmed (PhraseBook &)),
+ this, SLOT(slotPhrasebookConfirmed (PhraseBook &)));
+
+ // As we do not know whether the phrase book edit window is already open,
+ // we first open and then raise it, so that it is surely the top window.
+ phraseBookDialog->show();
+ phraseBookDialog->raise();
+}
+
+void KMouthApp::slotViewMenuBar() {
+ slotStatusMsg(i18n("Toggling menubar..."));
+
+ if(!viewMenuBar->isChecked())
+ menuBar()->hide();
+ else
+ menuBar()->show();
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void KMouthApp::slotViewToolBar()
+{
+ slotStatusMsg(i18n("Toggling toolbar..."));
+ ///////////////////////////////////////////////////////////////////
+ // turn Toolbar on or off
+ if(!viewToolBar->isChecked())
+ {
+ toolBar("mainToolBar")->hide();
+ }
+ else
+ {
+ toolBar("mainToolBar")->show();
+ }
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void KMouthApp::slotViewPhrasebookBar()
+{
+ slotStatusMsg(i18n("Toggling phrasebook bar..."));
+ ///////////////////////////////////////////////////////////////////
+ // turn Toolbar on or off
+ if(!viewPhrasebookBar->isChecked())
+ {
+ toolBar("phrasebookBar")->hide();
+ }
+ else
+ {
+ toolBar("phrasebookBar")->show();
+ }
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void KMouthApp::slotViewStatusBar()
+{
+ slotStatusMsg(i18n("Toggle the statusbar..."));
+ ///////////////////////////////////////////////////////////////////
+ //turn Statusbar on or off
+ if(!viewStatusBar->isChecked())
+ {
+ statusBar()->hide();
+ }
+ else
+ {
+ statusBar()->show();
+ }
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void KMouthApp::slotConfigureTTS() {
+ phraseList->saveWordCompletion();
+ optionsDialog->show();
+}
+
+
+void KMouthApp::slotStatusMsg(const QString &text)
+{
+ ///////////////////////////////////////////////////////////////////
+ // change status message permanently
+ statusBar()->clear();
+ statusBar()->changeItem(text, ID_STATUS_MSG);
+}
+
+void KMouthApp::slotPhrasebookConfirmed (PhraseBook &book) {
+ QString name = "phrasebooks";
+ QPopupMenu *popup = (QPopupMenu *)factory()->container(name, this);
+ KToolBar *toolbar = toolBar ("phrasebookBar");
+
+ KActionPtrList actions = phrases->actions ();
+ KActionPtrList::iterator iter;
+ for (iter = actions.begin(); iter != actions.end(); ++iter) {
+ (*iter)->unplugAll();
+ }
+ delete phrases;
+
+ phrases = new KActionCollection (this, actionCollection());
+ book.addToGUI (popup, toolbar, phrases, this, SLOT(slotPhraseSelected (const QString &)));
+
+ QString bookLocation = KApplication::kApplication()->dirs()->saveLocation ("appdata", "/");
+ if (!bookLocation.isNull() && !bookLocation.isEmpty()) {
+ book.save (KURL::fromPathOrURL( bookLocation + "standard.phrasebook" ));
+ }
+}
+
+void KMouthApp::slotConfigurationChanged()
+{
+ optionsDialog->saveOptions (config);
+}
+
+void KMouthApp::slotPhraseSelected (const QString &phrase) {
+ phraseList->insert (phrase);
+ if (optionsDialog->isSpeakImmediately())
+ phraseList->speak ();
+}
+
+TextToSpeechSystem *KMouthApp::getTTSSystem() const {
+ return optionsDialog->getTTSSystem();
+}
+
+#include "kmouth.moc"
diff --git a/kmouth/kmouth.desktop b/kmouth/kmouth.desktop
new file mode 100644
index 0000000..2ab68da
--- /dev/null
+++ b/kmouth/kmouth.desktop
@@ -0,0 +1,80 @@
+# KDE Config File
+[Desktop Entry]
+Type=Application
+Exec=kmouth -caption "%c" %i %m
+Icon=kmouth
+DocPath=kmouth/index.html
+Comment=
+Comment[ro]=Un utilitar de mărit zone ale ecranului
+Terminal=false
+Name=KMouth
+Name[ar]=برنامج KMouth
+Name[cy]=KCeg
+Name[eo]=KBuŝo
+Name[hi]=के-माउथ
+Name[is]=KMunnur
+Name[km]= KMouth
+Name[ne]=केडीई माउथ
+Name[pa]=ਕੇ-ਮੂੰਹ
+Name[ro]=Vorbitor
+Name[sv]=Kmouth
+Name[ta]=K வாய்
+Name[tg]=KДаҳон
+Name[tr]=Kmouth
+Name[vi]=Mồm K
+Name[zh_CN]=K 语音精灵
+GenericName=Speech Synthesizer Frontend
+GenericName[ar]=واجهة النَظام الصَوتي
+GenericName[bg]=Синтезатор на глас
+GenericName[bs]=Program za sintezu govora
+GenericName[ca]=Interfície per al sintetitzador de veu
+GenericName[cs]=Rozhraní hlasového syntetizátoru
+GenericName[cy]=Blaen-wyneb Syntheseisydd Lleferydd
+GenericName[da]=Forende til tale-synthesizer
+GenericName[de]=Oberfläche für Sprachsynthesizer
+GenericName[el]=Συνθέτης ομιλίας
+GenericName[en_GB]=Speech Synthesiser Frontend
+GenericName[eo]=Fasado Por Parolsintezilo
+GenericName[es]=Interfaz de usuario para síntesis de voz
+GenericName[et]=Kõnesüntesaator
+GenericName[eu]=Hizkera-sintetizadorearen interfazea
+GenericName[fa]=پایانۀ ترکیب‌دهندۀ گفتار
+GenericName[fi]=Puhesyntetisaattorin käyttöliittymä
+GenericName[fr]=Interface graphique de synthèse vocale
+GenericName[ga]=Clár tosaigh an sintéiseoir cainte
+GenericName[gl]=Interface para o Sintetizador de Voz
+GenericName[hi]=स्पीच सिंथेसाइज़र फ्रन्टएण्ड
+GenericName[hu]=Beszédszintetizátor
+GenericName[is]=Viðmót á talgerfilinn
+GenericName[it]=Interfaccia grafica per il sintetizzatore vocale
+GenericName[ja]=スピーチシンセサイザフロントエンド
+GenericName[ka]=საუბრის სინქრონიზაციის ინტერფეისი
+GenericName[km]= ផ្នែក​ខាង​មុខ​កម្មវិធី​សង្គ្រោះ​ការ​និយាយ
+GenericName[lt]=Kalbos sintezatoriaus naudotojo sąsaja
+GenericName[mk]=Преден крај на синтисајзерот за говор
+GenericName[ms]=Antaramuka Pensintesis Pertuturan
+GenericName[mt]=Programm Għall-Ħolqien ta' Diskors Artifiċjali
+GenericName[nb]=Brukerflate for talesystem
+GenericName[nds]=Böversiet för de Blicksnuut
+GenericName[ne]=संवाद सिन्थेसाइजर फ्रन्टइन्ड
+GenericName[nl]=Spraaksynthesizer
+GenericName[nn]=Grensesnitt for talesyntese
+GenericName[pa]=ਬੋਲੀ ਸੰਸਲੇਸ਼ਣ ਮੁੱਖ
+GenericName[pl]=Program obsługujący syntezator mowy
+GenericName[pt]=Sintetizador de Fala
+GenericName[pt_BR]=Interface do Sintetizador de Fala
+GenericName[ro]=Interfaţă pentru sinteză vocală
+GenericName[ru]=Интерфейс к синтезаторам речи
+GenericName[sk]=Rozhranie pre syntetizátor reči
+GenericName[sl]=Vmesnik za sintezo govora
+GenericName[sr]=Интерфејс за синтетизатор говора
+GenericName[sr@Latn]=Interfejs za sintetizator govora
+GenericName[sv]=Gränssnitt för talsyntes
+GenericName[tg]=Сухани Синтезатори Пешбуда
+GenericName[th]=ฟร้อนต์เอนด์สำหรับเครื่องสังเคราะห์คำพูด
+GenericName[tr]=Konuşma Sentezleyici Arayüzü
+GenericName[uk]=Графічний інтерфейс синтезатора мовлення
+GenericName[vi]=Giao diện Tổng hợp Giọng nói
+GenericName[zh_CN]=语音合成器前端
+GenericName[zh_TW]=語音合成器前端
+Categories=Qt;KDE;Utility;Accessibility;
diff --git a/kmouth/kmouth.h b/kmouth/kmouth.h
new file mode 100644
index 0000000..6ff6bad
--- /dev/null
+++ b/kmouth/kmouth.h
@@ -0,0 +1,187 @@
+/***************************************************************************
+ kmouth.h - description
+ -------------------
+ begin : Mon Aug 26 15:41:23 CEST 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#ifndef KMOUTH_H
+#define KMOUTH_H
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// include files for Qt
+
+// include files for KDE
+#include <kapplication.h>
+#include <kmainwindow.h>
+#include <kaccel.h>
+#include <kaction.h>
+#include <kurl.h>
+
+// forward declaration of the KMouth classes
+class PhraseList;
+class OptionsDialog;
+class TextToSpeechSystem;
+class PhraseBookDialog;
+class PhraseBook;
+
+/**
+ * The base class for KMouth application windows. It sets up the main
+ * window and reads the config file as well as providing a menubar, toolbar
+ * and statusbar.
+ * KMouthApp reimplements the methods that KMainWindow provides for main window handling and supports
+ * full session management as well as using KActions.
+ * @see KMainWindow
+ * @see KApplication
+ * @see KConfig
+ *
+ * @author Source Framework Automatically Generated by KDevelop, (c) The KDevelop Team.
+ * @version KDevelop version 1.2 code generation
+ */
+class KMouthApp : public KMainWindow
+{
+ Q_OBJECT
+
+ public:
+ /** construtor of KMouthApp, calls all init functions to create the application.
+ */
+ KMouthApp(QWidget* parent=0, const char* name=0);
+ ~KMouthApp();
+ /** Returns true if the configuration wizard was not needed or when it
+ * was successfully completed.
+ */
+ bool configured();
+ /** opens a file specified by commandline option
+ */
+ void openDocumentFile(const KURL& url=KURL());
+
+ TextToSpeechSystem *getTTSSystem() const;
+
+ /** called by PhraseList in order to enable or disable the actions depending
+ * on the contents of the phrase list.
+ */
+ void enableMenuEntries(bool existSelectedEntries, bool existDeselectedEntries);
+
+ protected:
+ /** save general Options like all bar positions and status as well as the geometry and the recent file list to the configuration
+ * file
+ */
+ void saveOptions();
+ /** read general Options again and initialize all variables like the recent file list
+ */
+ void readOptions();
+ /** initializes the phrase list */
+ void initPhraseList();
+ /** initializes the KActions of the application */
+ void initActions();
+ /** sets up the statusbar for the main window by initialzing a statuslabel.
+ */
+ void initStatusBar();
+ /** queryClose is called by KTMainWindow on each closeEvent of a window. Against the
+ * default implementation (only returns true), this calles saveModified() on the document object to ask if the document shall
+ * be saved if Modified; on cancel the closeEvent is rejected.
+ * @see KTMainWindow#queryClose
+ * @see KTMainWindow#closeEvent
+ */
+ virtual bool queryClose();
+ /** queryExit is called by KTMainWindow when the last window of the application is going to be closed during the closeEvent().
+ * Against the default implementation that just returns true, this calls saveOptions() to save the settings of the last window's
+ * properties.
+ * @see KTMainWindow#queryExit
+ * @see KTMainWindow#closeEvent
+ */
+ virtual bool queryExit();
+
+ public slots:
+ /** open a file and load it into the history */
+ void slotFileOpen();
+ /** save a document */
+ void slotFileSaveAs();
+ /** print the actual file */
+ void slotFilePrint();
+ /** closes all open windows by calling close() on each memberList item until the list is empty, then quits the application.
+ * If queryClose() returns false because the user canceled the saveModified() dialog, the closing breaks.
+ */
+ void slotFileQuit();
+ /** edits the phrase books
+ */
+ void slotEditPhrasebook ();
+ /** toggles the menu bar
+ */
+ void slotViewMenuBar();
+ /** toggles the toolbar
+ */
+ void slotViewToolBar();
+ /** toggles the phrasebook bar
+ */
+ void slotViewPhrasebookBar();
+ /** toggles the statusbar
+ */
+ void slotViewStatusBar();
+ /** configures the TTS system
+ */
+ void slotConfigureTTS();
+ /** changes the statusbar contents for the standard label permanently, used to indicate current actions.
+ * @param text the text that is displayed in the statusbar
+ */
+ void slotStatusMsg(const QString &text);
+
+ void slotPhrasebookConfirmed (PhraseBook &book);
+
+ void slotConfigurationChanged();
+
+ void slotPhraseSelected (const QString &phrase);
+
+ private:
+ bool isConfigured;
+ /** the configuration object of the application */
+ KConfig *config;
+ /** The phrase list */
+ PhraseList *phraseList;
+ /** The configuration dialog */
+ OptionsDialog *optionsDialog;
+
+ // KAction pointers to enable/disable actions
+ KAction* fileOpen;
+ KAction* fileSaveAs;
+ KAction* filePrint;
+ KAction* fileQuit;
+
+ KAction* editCut;
+ KAction* editCopy;
+ KAction* editPaste;
+ KAction* editSpeak;
+
+ KActionCollection *phrases;
+ KAction* phrasebookEdit;
+
+ KToggleAction* viewMenuBar;
+ KToggleAction* viewToolBar;
+ KToggleAction* viewPhrasebookBar;
+ KToggleAction* viewStatusBar;
+ KAction* configureTTS;
+
+ KAction* phraseListSpeak;
+ KAction* phraseListRemove;
+ KAction* phraseListCut;
+ KAction* phraseListCopy;
+ KAction* phraselistSelectAll;
+ KAction* phraselistDeselectAll;
+};
+
+#endif // KMOUTH_H
diff --git a/kmouth/kmouth.lsm b/kmouth/kmouth.lsm
new file mode 100644
index 0000000..0657065
--- /dev/null
+++ b/kmouth/kmouth.lsm
@@ -0,0 +1,14 @@
+Begin3
+Title: KMouth
+Version: 0.1
+Entered-date:
+Description: Lets your computer speak
+Keywords:
+Author: Gunnar Schmi Dt <kmouth@schmi-dt.de>
+Maintained-by: Gunnar Schmi Dt <kmouth@schmi-dt.de>
+Primary-site:
+Home-page: http://www.schmi-dt.de/kmouth/index.en.html
+Original-site:
+Platforms: Linux and other Unices
+Copying-policy: GNU Public License
+End
diff --git a/kmouth/kmouthrc b/kmouth/kmouthrc
new file mode 100644
index 0000000..2b82c9f
--- /dev/null
+++ b/kmouth/kmouthrc
@@ -0,0 +1,9 @@
+[General Options]
+Geometry=550,400
+
+[mainToolBar]
+Index=0
+
+[phrasebookBar]
+IconText=IconTextRight
+Index=1
diff --git a/kmouth/kmouthui.rc b/kmouth/kmouthui.rc
new file mode 100644
index 0000000..3a2ed82
--- /dev/null
+++ b/kmouth/kmouthui.rc
@@ -0,0 +1,93 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="kmouth" version="1">
+<MenuBar>
+ <Menu name="file" noMerge="1"><text>&amp;File</text>
+ <Action name="file_open"/>
+ <Action name="file_save_as"/>
+ <Action name="file_print"/>
+ <Separator />
+ <Action name="file_quit"/>
+ </Menu>
+ <Menu name="edit"><text>&amp;Edit</text>
+ <Action name="edit_speak"/>
+ </Menu>
+ <Menu name="phrasebooks"><text>&amp;Phrase Books</text>
+ <Action name="phrasebook_edit"/>
+ </Menu>
+ <Menu name="settings"><text>&amp;Settings</text>
+ <Action name="showPhrasebookBar" append="show_merge"/>
+ <Action name="configureTTS" append="configure_merge"/>
+ </Menu>
+</MenuBar>
+
+<Menu name="phraselist_selection_popup" noMerge="1">
+ <Action name="phraselist_speak"/>
+ <!-- Separator / -->
+ <!-- Action name="phraselist_into_phrasebook"/ -->
+ <Separator />
+ <Action name="phraselist_remove"/>
+ <Separator />
+ <Action name="phraselist_cut"/>
+ <Action name="phraselist_copy"/>
+ <Separator />
+ <Action name="phraselist_select_all"/>
+ <Action name="phraselist_deselect_all"/>
+ <Separator />
+ <Action name="file_open"/>
+ <Action name="file_save_as"/>
+</Menu>
+
+<Menu name="phraselist_popup" noMerge="1">
+ <Action name="phraselist_select_all"/>
+ <Action name="phraselist_deselect_all"/>
+ <Separator />
+ <Action name="file_open"/>
+ <Action name="file_save_as"/>
+</Menu>
+
+<Menu name="phrasebook_popup" noMerge="1">
+ <Action name="phrasebook_paste"/>
+ <Separator />
+ <Action name="phrasebook_add_chapter"/>
+ <Action name="phrasebook_add_phrase"/>
+ <Separator />
+ <Action name="phrasebook_import"/>
+ <Action name="phrasebook_import_standard_book"/>
+ <Action name="phrasebook_export"/>
+</Menu>
+
+<Menu name="phrasebook_book_popup" noMerge="1">
+ <Action name="phrasebook_remove"/>
+ <Separator />
+ <Action name="phrasebook_cut"/>
+ <Action name="phrasebook_copy"/>
+ <Action name="phrasebook_paste"/>
+ <Separator />
+ <Action name="phrasebook_add_chapter"/>
+ <Action name="phrasebook_add_phrase"/>
+ <Separator />
+ <Action name="phrasebook_import"/>
+ <Action name="phrasebook_import_standard_book"/>
+ <Action name="phrasebook_export"/>
+</Menu>
+
+<Menu name="phrasebook_phrase_popup" noMerge="1">
+ <Action name="phrasebook_remove"/>
+ <Separator />
+ <Action name="phrasebook_cut"/>
+ <Action name="phrasebook_copy"/>
+ <Separator />
+ <Action name="phrase_export"/>
+</Menu>
+
+<ToolBar name="mainToolBar" noMerge="1">
+ <Action name="file_open"/>
+ <Action name="file_open_history"/>
+ <Action name="file_save_as"/>
+ <Action name="file_print"/>
+ <Separator />
+ <Action name="edit_cut"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+</ToolBar>
+</kpartgui>
diff --git a/kmouth/main.cpp b/kmouth/main.cpp
new file mode 100644
index 0000000..0f9c875
--- /dev/null
+++ b/kmouth/main.cpp
@@ -0,0 +1,73 @@
+/***************************************************************************
+ main.cpp - description
+ -------------------
+ begin : Mon Aug 26 15:41:23 CEST 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <klocale.h>
+#include <kuniqueapplication.h>
+
+#include "kmouth.h"
+#include "version.h"
+
+static const char description[] =
+ I18N_NOOP("A type-and-say front end for speech synthesizers");
+// INSERT A DESCRIPTION FOR YOUR APPLICATION HERE
+
+
+static KCmdLineOptions options[] =
+{
+ { "+[File]", I18N_NOOP("History file to open"), 0 },
+ KCmdLineLastOption
+ // INSERT YOUR COMMANDLINE OPTIONS HERE
+};
+
+int main(int argc, char *argv[])
+{
+
+ KAboutData aboutData( "kmouth", I18N_NOOP("KMouth"),
+ KMOUTH_VERSION, description, KAboutData::License_GPL,
+ "(c) 2002/2003, Gunnar Schmi Dt", 0, "http://www.schmi-dt.de/kmouth/index.en.html", "kmouth@schmi-dt.de");
+ aboutData.addAuthor("Gunnar Schmi Dt",0, "kmouth@schmi-dt.de");
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
+
+ aboutData.addCredit("Olaf Schmidt", I18N_NOOP("Tips, extended phrase books"), 0, 0);
+ KApplication app;
+
+ if (app.isRestored())
+ {
+ RESTORE(KMouthApp);
+ }
+ else
+ {
+ KMouthApp *kmouth = new KMouthApp();
+ if (!kmouth->configured())
+ return 0;
+
+ kmouth->show();
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ if (args->count())
+ {
+ kmouth->openDocumentFile(args->url(0));
+ }
+ args->clear();
+ }
+ return app.exec();
+}
diff --git a/kmouth/optionsdialog.cpp b/kmouth/optionsdialog.cpp
new file mode 100644
index 0000000..4873167
--- /dev/null
+++ b/kmouth/optionsdialog.cpp
@@ -0,0 +1,238 @@
+/***************************************************************************
+ optionsdialog.cpp - description
+ -------------------
+ begin : Don Nov 21 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+#include <qgrid.h>
+#include <qtabwidget.h>
+#include <qpixmap.h>
+#include <qfile.h>
+
+#include <kcombobox.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kcmodule.h>
+#include <klibloader.h>
+#include <kparts/componentfactory.h>
+
+#include "optionsdialog.h"
+#include "wordcompletion/wordcompletionwidget.h"
+
+#include "texttospeechconfigurationwidget.h"
+#include "speech.h"
+
+PreferencesWidget::PreferencesWidget (QWidget *parent, const char *name)
+ : PreferencesUI (parent, name)
+{
+ speakCombo->setCurrentItem (1);
+ speak = false;
+
+ closeCombo->setCurrentItem (2);
+ save = 2;
+}
+
+PreferencesWidget::~PreferencesWidget() {
+}
+
+void PreferencesWidget::cancel() {
+ if (speak)
+ speakCombo->setCurrentItem (0);
+ else
+ speakCombo->setCurrentItem (1);
+ closeCombo->setCurrentItem (save);
+}
+
+void PreferencesWidget::ok() {
+ speak = speakCombo->currentItem () == 0;
+ save = closeCombo->currentItem ();
+}
+
+void PreferencesWidget::readOptions (KConfig *config) {
+ config->setGroup("Preferences");
+ if (config->hasKey("AutomaticSpeak"))
+ if (config->readEntry ("AutomaticSpeak") == "Yes")
+ speak = true;
+ else
+ speak = false;
+ else
+ speak = false;
+
+ config->setGroup("Notification Messages");
+ if (config->hasKey("AutomaticSave"))
+ if (config->readEntry ("AutomaticSave") == "Yes")
+ save = 0;
+ else
+ save = 1;
+ else
+ save = 2;
+
+ if (speak)
+ speakCombo->setCurrentItem (0);
+ else
+ speakCombo->setCurrentItem (1);
+ closeCombo->setCurrentItem (save);
+}
+
+void PreferencesWidget::saveOptions (KConfig *config) {
+ config->setGroup("Preferences");
+ if (speak)
+ config->writeEntry ("AutomaticSpeak", "Yes");
+ else
+ config->writeEntry ("AutomaticSpeak", "No");
+
+ config->setGroup("Notification Messages");
+ if (save == 0)
+ config->writeEntry ("AutomaticSave", "Yes");
+ else if (save == 1)
+ config->writeEntry ("AutomaticSave", "No");
+ else
+ config->deleteEntry ("AutomaticSave");
+}
+
+bool PreferencesWidget::isSpeakImmediately () {
+ return speak;
+}
+
+/***************************************************************************/
+
+OptionsDialog::OptionsDialog (QWidget *parent)
+ : KDialogBase(IconList, i18n("Configuration"), Ok|Apply|Cancel|Help, Ok,
+ parent, "configuration", false, true)
+{
+ setHelp ("config-dialog");
+
+ QPixmap iconGeneral = KGlobal::iconLoader()->loadIcon("configure", KIcon::NoGroup, KIcon::SizeMedium);
+ QGrid *pageGeneral = addGridPage (1, Qt::Horizontal, i18n("General Options"), QString::null, iconGeneral);
+
+ tabCtl = new QTabWidget (pageGeneral, "general");
+
+ behaviourWidget = new PreferencesWidget (tabCtl, "prefPage");
+ behaviourWidget->layout()->setMargin(KDialog::marginHint());
+ tabCtl->addTab (behaviourWidget, i18n("&Preferences"));
+
+ commandWidget = new TextToSpeechConfigurationWidget (tabCtl, "ttsTab");
+ commandWidget->layout()->setMargin(KDialog::marginHint());
+ tabCtl->addTab (commandWidget, i18n("&Text-to-Speech"));
+
+ QPixmap iconCompletion = KGlobal::iconLoader()->loadIcon("keyboard", KIcon::NoGroup, KIcon::SizeMedium);
+ QGrid *pageCompletion = addGridPage (1, Qt::Horizontal, i18n("Word Completion"), QString::null, iconCompletion);
+ completionWidget = new WordCompletionWidget(pageCompletion, "Word Completion widget");
+
+ kttsd = loadKttsd();
+ if (kttsd != 0) {
+ QPixmap iconKttsd = KGlobal::iconLoader()->loadIcon("multimedia", KIcon::NoGroup, KIcon::SizeMedium);
+ QGrid *pageKttsd = addGridPage (1, Qt::Horizontal, i18n("KTTSD Speech Service"),
+ i18n("KDE Text-to-Speech Daemon Configuration"), iconKttsd);
+
+ kttsd->reparent(pageKttsd,0,QPoint(0,0),true);
+ }
+}
+
+OptionsDialog::~OptionsDialog() {
+ unloadKttsd();
+}
+
+void OptionsDialog::slotCancel() {
+ KDialogBase::slotCancel();
+ commandWidget->cancel();
+ behaviourWidget->cancel();
+ completionWidget->load();
+ if (kttsd != 0)
+ kttsd->load ();
+}
+
+void OptionsDialog::slotOk() {
+ KDialogBase::slotOk();
+ commandWidget->ok();
+ behaviourWidget->ok();
+ completionWidget->save();
+ emit configurationChanged();
+ if (kttsd != 0)
+ kttsd->save ();
+
+}
+
+void OptionsDialog::slotApply() {
+ KDialogBase::slotApply();
+ commandWidget->ok();
+ behaviourWidget->ok();
+ completionWidget->save();
+ emit configurationChanged();
+ if (kttsd != 0)
+ kttsd->save ();
+}
+
+TextToSpeechSystem *OptionsDialog::getTTSSystem() const {
+ return commandWidget->getTTSSystem();
+}
+
+void OptionsDialog::readOptions (KConfig *config) {
+ commandWidget->readOptions (config, "TTS System");
+ behaviourWidget->readOptions (config);
+}
+
+void OptionsDialog::saveOptions (KConfig *config) {
+ commandWidget->saveOptions (config, "TTS System");
+ behaviourWidget->saveOptions (config);
+ config->sync();
+}
+
+bool OptionsDialog::isSpeakImmediately () {
+ return behaviourWidget->isSpeakImmediately ();
+}
+
+KCModule *OptionsDialog::loadKttsd () {
+ KLibLoader *loader = KLibLoader::self();
+
+ QString libname = "kcm_kttsd";
+ KLibrary *lib = loader->library(QFile::encodeName(libname));
+
+ if (lib == 0) {
+ libname = "libkcm_kttsd";
+ lib = loader->library(QFile::encodeName("libkcm_kttsd"));
+ }
+
+ if (lib != 0) {
+ QString initSym("init_");
+ initSym += libname;
+
+ if (lib->hasSymbol(QFile::encodeName(initSym))) {
+ // Reuse "lib" instead of letting createInstanceFromLibrary recreate it
+ KLibFactory *factory = lib->factory();
+ if (factory != 0) {
+ KCModule *module = KParts::ComponentFactory::createInstanceFromFactory<KCModule> (factory);
+ if (module)
+ return module;
+ }
+ }
+
+ lib->unload();
+ }
+ return 0;
+}
+
+void OptionsDialog::unloadKttsd () {
+ KLibLoader *loader = KLibLoader::self();
+ loader->unloadLibrary(QFile::encodeName("libkcm_kttsd"));
+ loader->unloadLibrary(QFile::encodeName("kcm_kttsd"));
+}
+
+#include "optionsdialog.moc"
diff --git a/kmouth/optionsdialog.h b/kmouth/optionsdialog.h
new file mode 100644
index 0000000..8597e70
--- /dev/null
+++ b/kmouth/optionsdialog.h
@@ -0,0 +1,88 @@
+/***************************************************************************
+ optionsdialog.h - description
+ -------------------
+ begin : Don Nov 21 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// $Id$
+
+#ifndef OPTIONSDIALOG_H
+#define OPTIONSDIALOG_H
+
+#include <qobject.h>
+#include "preferencesui.h"
+#include "texttospeechconfigurationwidget.h"
+class QTabWidget;
+class KCModule;
+class WordCompletionWidget;
+
+/**This class represents a configuration widget for user preferences.
+ *@author Gunnar Schmi Dt
+ */
+
+class PreferencesWidget : public PreferencesUI {
+ Q_OBJECT
+public:
+ PreferencesWidget(QWidget *parent, const char *name);
+ ~PreferencesWidget();
+
+ void readOptions (KConfig *config);
+ void saveOptions (KConfig *config);
+
+ void ok();
+ void cancel();
+
+ bool isSpeakImmediately();
+
+private:
+ bool speak;
+ int save;
+};
+
+/**This class represents a configuration dialog for the options of KMouth.
+ *@author Gunnar Schmi Dt
+ */
+
+class OptionsDialog : public KDialogBase {
+ Q_OBJECT
+public:
+ OptionsDialog(QWidget *parent);
+ ~OptionsDialog();
+
+ void slotCancel();
+ void slotOk();
+ void slotApply();
+
+ TextToSpeechSystem *getTTSSystem() const;
+
+ void readOptions (KConfig *config);
+ void saveOptions (KConfig *config);
+
+ bool isSpeakImmediately();
+
+signals:
+ void configurationChanged ();
+
+private:
+ QTabWidget *tabCtl;
+ TextToSpeechConfigurationWidget *commandWidget;
+ PreferencesWidget *behaviourWidget;
+ KCModule *kttsd;
+ WordCompletionWidget *completionWidget;
+
+ KCModule *loadKttsd ();
+ void unloadKttsd ();
+};
+
+#endif
diff --git a/kmouth/phrasebook/Makefile.am b/kmouth/phrasebook/Makefile.am
new file mode 100644
index 0000000..bc0b31c
--- /dev/null
+++ b/kmouth/phrasebook/Makefile.am
@@ -0,0 +1,16 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+noinst_LIBRARIES = libphrasebook.a
+
+INCLUDES = $(all_includes)
+
+libphrasebook_a_METASOURCES = AUTO
+
+libphrasebook_a_SOURCES = buttonboxui.ui phrasetree.cpp phrasebookparser.cpp phrasebookdialog.cpp phrasebook.cpp
+
+
+EXTRA_DIST = phrasebook.cpp phrasebook.h phrasebookdialog.cpp phrasebookdialog.h phrasebookparser.cpp phrasebookparser.h phrasetree.cpp phrasetree.h phrasebookdialogui.rc buttonboxui.ui
+
+####### kdevelop will overwrite this part!!! (end)############
+
+rcdir = $(kde_datadir)/kmouth
+rc_DATA = phrasebookdialogui.rc
diff --git a/kmouth/phrasebook/buttonboxui.ui b/kmouth/phrasebook/buttonboxui.ui
new file mode 100644
index 0000000..abc999b
--- /dev/null
+++ b/kmouth/phrasebook/buttonboxui.ui
@@ -0,0 +1,107 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>ButtonBoxUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ButtonBoxUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>278</width>
+ <height>141</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Currently Selected Phrase or Phrase Book</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>phrasebox</cstring>
+ </property>
+ <property name="title">
+ <string>&amp;Currently Selected Phrase or Phrase Book</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QWidget" row="3" column="2">
+ <property name="name">
+ <cstring>keyButtonPlace</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>lineEdit</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this line edit you define the name of a sub-phrasebook or the contents of a phrase.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="3" column="0">
+ <property name="name">
+ <cstring>noKey</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;None</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If you select this option then the selected phrase will not be reachable by a keyboard shortcut.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="3" column="1">
+ <property name="name">
+ <cstring>customKey</cstring>
+ </property>
+ <property name="text">
+ <string>C&amp;ustom</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If you select this option then the selected phrase will be reachable by a keyboard shortcut. You can change the shortcut with the button next to this option.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>shortcutLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Shortcut for the phrase:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Text of the &amp;phrase:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>lineEdit</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this line edit you define the name of a sub-phrasebook or the contents of a phrase.</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kmouth/phrasebook/phrasebook.cpp b/kmouth/phrasebook/phrasebook.cpp
new file mode 100644
index 0000000..0ec8da3
--- /dev/null
+++ b/kmouth/phrasebook/phrasebook.cpp
@@ -0,0 +1,512 @@
+/***************************************************************************
+ phrasebook.cpp - description
+ -------------------
+ begin : Don Sep 19 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qprinter.h>
+#include <qpainter.h>
+#include <qfile.h>
+#include <qxml.h>
+#include <qregexp.h>
+#include <qptrstack.h>
+
+#include <klocale.h>
+#include <kaction.h>
+#include <kpopupmenu.h>
+#include <ktoolbar.h>
+#include <ktempfile.h>
+#include <kio/netaccess.h>
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+#include <kglobalsettings.h>
+
+#include "phrasebookparser.h"
+#include "phrasebook.h"
+
+Phrase::Phrase() {
+ this->phrase = "";
+ this->shortcut = "";
+}
+
+Phrase::Phrase (const QString &phrase) {
+ this->phrase = phrase;
+ this->shortcut = "";
+}
+
+Phrase::Phrase (const QString &phrase, const QString &shortcut) {
+ this->phrase = phrase;
+ this->shortcut = shortcut;
+}
+
+QString Phrase::getPhrase() const {
+ return phrase;
+}
+
+QString Phrase::getShortcut() const {
+ return shortcut;
+}
+
+void Phrase::setPhrase (const QString &phrase) {
+ this->phrase = phrase;
+}
+
+void Phrase::setShortcut (const QString &shortcut) {
+ this->shortcut = shortcut;
+}
+
+// ***************************************************************************
+
+PhraseBookEntry::PhraseBookEntry () {
+ phrase = Phrase();
+ level = 1;
+ isPhraseValue = false;
+}
+
+PhraseBookEntry::PhraseBookEntry (Phrase phrase, int level, bool isPhrase) {
+ this->phrase = phrase;
+ this->level = level;
+ isPhraseValue = isPhrase;
+}
+
+bool PhraseBookEntry::isPhrase() const {
+ return isPhraseValue;
+}
+
+Phrase PhraseBookEntry::getPhrase() const {
+ return phrase;
+}
+
+int PhraseBookEntry::getLevel() const {
+ return level;
+}
+
+// ***************************************************************************
+
+void PhraseBook::print(KPrinter *pPrinter) {
+ QPainter printpainter;
+ printpainter.begin(pPrinter);
+
+ QRect size = printpainter.viewport ();
+ int x = size.x();
+ int y = size.y();
+ int w = size.width();
+ printpainter.setFont (QFont (KGlobalSettings::generalFont().family(), 12));
+ QFontMetrics metrics = printpainter.fontMetrics();
+
+ PhraseBookEntryList::iterator it;
+ for (it = begin(); it != end(); ++it) {
+ QRect rect = metrics.boundingRect (x+16*(*it).getLevel(), y,
+ w-16*(*it).getLevel(), 0,
+ Qt::AlignJustify | Qt::WordBreak,
+ (*it).getPhrase().getPhrase());
+
+ if (y+rect.height() > size.height()) {
+ pPrinter->newPage();
+ y = 0;
+ }
+ printpainter.drawText (x+16*(*it).getLevel(),y,
+ w-16*(*it).getLevel(),rect.height(),
+ Qt::AlignJustify | Qt::WordBreak,
+ (*it).getPhrase().getPhrase());
+ y += rect.height();
+ }
+
+ printpainter.end();
+}
+
+bool PhraseBook::decode (const QString &xml) {
+ QXmlInputSource source;
+ source.setData (xml);
+ return decode (source);
+}
+
+bool PhraseBook::decode (QXmlInputSource &source) {
+ PhraseBookParser parser;
+ QXmlSimpleReader reader;
+ reader.setFeature ("http://trolltech.com/xml/features/report-start-end-entity", true);
+ reader.setContentHandler (&parser);
+
+ if (reader.parse(source)) {
+ PhraseBookEntryList::clear();
+ *(PhraseBookEntryList *)this += parser.getPhraseList();
+ return true;
+ }
+ else
+ return false;
+}
+
+QCString encodeString (const QString str) {
+ QCString res = "";
+ for (int i = 0; i < (int)str.length(); i++) {
+ QChar ch = str.at(i);
+ ushort uc = ch.unicode();
+ QCString number; number.setNum(uc);
+ if ((uc>127) || (uc<32) || (ch=='<') || (ch=='>') || (ch=='&') || (ch==';'))
+ res = res + "&#" + number + ";";
+ else
+ res = res + (char)uc;
+ }
+ return res;
+}
+
+QString PhraseBook::encode () {
+ QString result;
+ result = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+ result += "<!DOCTYPE phrasebook>\n";
+ result += "<phrasebook>\n";
+
+ PhraseBookEntryList::iterator it;
+ int level = 0;
+ for (it = begin(); it != end(); ++it) {
+ int newLevel = (*it).getLevel();
+ while (level < newLevel) {
+ result += "<phrasebook>\n";
+ level++;
+ }
+ while (level > newLevel) {
+ result += "</phrasebook>\n";
+ level--;
+ }
+
+ if ((*it).isPhrase()) {
+ Phrase phrase = (*it).getPhrase();
+ result += "<phrase shortcut=\"" + encodeString(phrase.getShortcut());
+ result += "\">" + encodeString(phrase.getPhrase()) + "</phrase>\n";
+ }
+ else {
+ Phrase phrase = (*it).getPhrase();
+ result += "<phrasebook name=\"" + encodeString(phrase.getPhrase()) + "\">\n";
+ level++;
+ }
+ }
+ while (level > 0) {
+ result += "</phrasebook>\n";
+ level--;
+ }
+ result += "</phrasebook>";
+ return result;
+}
+
+QStringList PhraseBook::toStringList () {
+ QStringList result;
+
+ PhraseBook::iterator it;
+ for (it = begin(); it != end(); ++it) {
+ if ((*it).isPhrase())
+ result += (*it).getPhrase().getPhrase();
+ }
+ return result;
+}
+
+bool PhraseBook::save (const KURL &url) {
+ QRegExp pattern("*.phrasebook",true,true);
+ return save (url, pattern.exactMatch(url.filename()));
+}
+
+
+void PhraseBook::save (QTextStream &stream, bool asPhrasebook) {
+ if (asPhrasebook)
+ stream << encode();
+ else
+ stream << toStringList().join("\n");
+}
+
+bool PhraseBook::save (const KURL &url, bool asPhrasebook) {
+ if (url.isLocalFile()) {
+ QFile file(url.path());
+ if(!file.open(IO_WriteOnly))
+ return false;
+
+ QTextStream stream(&file);
+ save (stream, asPhrasebook);
+ file.close();
+
+ if (file.status() != IO_Ok)
+ return false;
+ else
+ return true;
+ }
+ else {
+ KTempFile tempFile;
+ tempFile.setAutoDelete(true);
+
+ save (*tempFile.textStream(), asPhrasebook);
+ tempFile.close();
+
+ return KIO::NetAccess::upload(tempFile.name(), url);
+ }
+}
+
+int PhraseBook::save (QWidget *parent, const QString &title, KURL &url, bool phrasebookFirst) {
+ // KFileDialog::getSaveURL(...) is not useful here as we need
+ // to know the requested file type.
+
+ QString filters;
+ if (phrasebookFirst)
+ filters = i18n("*.phrasebook|Phrase Books (*.phrasebook)\n*.txt|Plain Text Files (*.txt)\n*|All Files");
+ else
+ filters = i18n("*.txt|Plain Text Files (*.txt)\n*.phrasebook|Phrase Books (*.phrasebook)\n*|All Files");
+
+ KFileDialog fdlg(QString::null,filters, parent, "filedialog", true);
+ fdlg.setCaption(title);
+ fdlg.setOperationMode( KFileDialog::Saving );
+
+ if (fdlg.exec() != QDialog::Accepted) {
+ return 0;
+ }
+
+ url = fdlg.selectedURL();
+
+ if (url.isEmpty() || !url.isValid()) {
+ return -1;
+ }
+
+ if (KIO::NetAccess::exists(url)) {
+ if (KMessageBox::warningContinueCancel(0,QString("<qt>%1</qt>").arg(i18n("The file %1 already exists. "
+ "Do you want to overwrite it?").arg(url.url())),i18n("File Exists"),i18n("&Overwrite"))==KMessageBox::Cancel) {
+ return 0;
+ }
+ }
+
+ bool result;
+ if (fdlg.currentFilter() == "*.phrasebook") {
+ if (url.fileName (false).contains('.') == 0) {
+ url.setFileName (url.fileName(false) + ".phrasebook");
+ }
+ else if (url.fileName (false).right (11).contains (".phrasebook", false) == 0) {
+ int filetype = KMessageBox::questionYesNoCancel (0,QString("<qt>%1</qt>").arg(i18n("Your chosen filename <i>%1</i> has a different extension than <i>.phrasebook</i>. "
+ "Do you wish to add <i>.phrasebook</i> to the filename?").arg(url.filename())),i18n("File Extension"),i18n("Add"),i18n("Do Not Add"));
+ if (filetype == KMessageBox::Cancel) {
+ return 0;
+ }
+ if (filetype == KMessageBox::Yes) {
+ url.setFileName (url.fileName(false) + ".phrasebook");
+ }
+ }
+ result = save (url, true);
+ }
+ else if (fdlg.currentFilter() == "*.txt") {
+ if (url.fileName (false).right (11).contains (".phrasebook", false) == 0) {
+ result = save (url, false);
+ }
+ else {
+ int filetype = KMessageBox::questionYesNoCancel (0,QString("<qt>%1</qt>").arg(i18n("Your chosen filename <i>%1</i> has the extension <i>.phrasebook</i>. "
+ "Do you wish to save in phrasebook format?").arg(url.filename())),i18n("File Extension"),i18n("As Phrasebook"),i18n("As Plain Text"));
+ if (filetype == KMessageBox::Cancel) {
+ return 0;
+ }
+ if (filetype == KMessageBox::Yes) {
+ result = save (url, true);
+ }
+ else {
+ result = save (url, false);
+ }
+ }
+ }
+ else // file format "All files" requested, so decide by extension
+ result = save (url);
+
+ if (result)
+ return 1;
+ else
+ return -1;
+}
+
+bool PhraseBook::open (const KURL &url) {
+ QString tempFile;
+ KURL fileUrl = url;
+
+ QString protocol = fileUrl.protocol();
+ if (protocol.isEmpty() || protocol.isNull()) {
+ fileUrl.setProtocol ("file");
+ fileUrl.setPath (url.url());
+ }
+
+ if (KIO::NetAccess::download (fileUrl, tempFile)) {
+ QStringList list = QStringList();
+
+ // First: try to load it as a normal phrase book
+ QFile file(tempFile);
+ QXmlInputSource source (&file);
+ bool error = !decode (source);
+
+ // Second: if the file does not contain a phrase book, load it as
+ // a plain text file
+ if (error) {
+ // Load each line of the plain text file as a new phrase
+
+ QFile file(tempFile);
+ if (file.open(IO_ReadOnly)) {
+ QTextStream stream(&file);
+
+ while (!stream.atEnd()) {
+ QString s = stream.readLine();
+ if (!(s.isNull() || s.isEmpty()))
+ *this += PhraseBookEntry(Phrase(s, ""), 0, true);
+ }
+ file.close();
+ error = false;
+ }
+ else
+ error = true;
+ }
+ KIO::NetAccess::removeTempFile (tempFile);
+
+ return !error;
+ }
+ else
+ return false;
+}
+
+void PhraseBook::addToGUI (QPopupMenu *popup, KToolBar *toolbar, KActionCollection *phrases,
+ QObject *receiver, const char *slot) const {
+ if ((popup != 0) || (toolbar != 0)) {
+ QPtrStack<QWidget> stack;
+ QWidget *parent = popup;
+ int level = 0;
+
+ QValueListConstIterator<PhraseBookEntry> it;
+ for (it = begin(); it != end(); ++it) {
+ int newLevel = (*it).getLevel();
+ while (newLevel > level) {
+ KActionMenu *menu = new KActionMenu("", "phrasebook");
+ menu->setDelayed(false);
+ phrases->insert(menu);
+ menu->plug (parent);
+ if (parent == popup)
+ menu->plug (toolbar);
+ if (parent != 0)
+ stack.push (parent);
+ parent = menu->popupMenu();
+ level++;
+ }
+ while (newLevel < level && (parent != popup)) {
+ parent = stack.pop();
+ level--;
+ }
+ if ((*it).isPhrase()) {
+ Phrase phrase = (*it).getPhrase();
+ KAction *action = new PhraseAction (phrase.getPhrase(),
+ phrase.getShortcut(), receiver, slot, phrases);
+ if (parent == popup)
+ action->plug (toolbar);
+ if (parent != 0)
+ action->plug(parent);
+ }
+ else {
+ Phrase phrase = (*it).getPhrase();
+ KActionMenu *menu = new KActionMenu(phrase.getPhrase(), "phrasebook");
+ menu->setDelayed(false);
+ phrases->insert(menu);
+ if (parent == popup)
+ menu->plug (toolbar);
+ if (parent != 0)
+ menu->plug (parent);
+ stack.push (parent);
+ parent = menu->popupMenu();
+ level++;
+ }
+ }
+ }
+}
+
+void PhraseBook::insert (const QString &name, const PhraseBook &book) {
+ *this += PhraseBookEntry(Phrase(name), 0, false);
+
+ QValueListConstIterator<PhraseBookEntry> it;
+ for (it = book.begin(); it != book.end(); ++it) {
+ *this += PhraseBookEntry ((*it).getPhrase(), (*it).getLevel()+1, (*it).isPhrase());
+ }
+}
+
+// ***************************************************************************
+
+PhraseBookDrag::PhraseBookDrag (PhraseBook *book, QWidget *dragSource, const char *name)
+ : QDragObject (dragSource, name)
+{
+ setBook (book);
+}
+
+PhraseBookDrag::PhraseBookDrag (QWidget *dragSource, const char *name)
+ : QDragObject (dragSource, name)
+{
+ setBook (0);
+}
+
+PhraseBookDrag::~PhraseBookDrag () {
+}
+
+void PhraseBookDrag::setBook (PhraseBook *book) {
+ if (book == 0) {
+ isEmpty = true;
+ xmlphrasebook.setText(QString::null);
+ xml.setText(QString::null);
+ plain.setText(QString::null);
+ }
+ else {
+ isEmpty = false;
+ xmlphrasebook.setText(book->encode());
+ xml.setText(book->encode());
+ plain.setText(book->toStringList().join("\n"));
+ }
+ xmlphrasebook.setSubtype("x-xml-phrasebook");
+ xml.setSubtype("xml");
+ plain.setSubtype("plain");
+}
+
+const char *PhraseBookDrag::format (int i) const {
+ if (isEmpty)
+ return plain.format(i);
+ else if (i%3 == 0)
+ return plain.format(i/3);
+ else if (i%3 == 1)
+ return xml.format(i/3);
+ else
+ return xmlphrasebook.format(i/3);
+}
+
+QByteArray PhraseBookDrag::encodedData (const char* mime) const {
+ QCString m(mime);
+ m = m.lower();
+ if (m.contains("xml-phrasebook"))
+ return xmlphrasebook.encodedData(mime);
+ else if (m.contains("xml"))
+ return xml.encodedData(mime);
+ else
+ return plain.encodedData(mime);
+}
+
+bool PhraseBookDrag::canDecode (const QMimeSource* e) {
+ return QTextDrag::canDecode(e);
+}
+
+bool PhraseBookDrag::decode (const QMimeSource *e, PhraseBook *book) {
+ QString string;
+ QCString subtype1 = "x-xml-phrasebook";
+ QCString subtype2 = "xml";
+
+ if (!QTextDrag::decode(e, string, subtype1))
+ if (!QTextDrag::decode(e, string, subtype2)) {
+ if (QTextDrag::decode(e, string)) {
+ *book += PhraseBookEntry(Phrase(string, ""), 0, true);
+ return true;
+ }
+ else return false;
+ }
+
+ return book->decode(string);
+}
+
+#include "phrasebook.moc"
diff --git a/kmouth/phrasebook/phrasebook.h b/kmouth/phrasebook/phrasebook.h
new file mode 100644
index 0000000..83cb3a9
--- /dev/null
+++ b/kmouth/phrasebook/phrasebook.h
@@ -0,0 +1,195 @@
+/***************************************************************************
+ phrasebook.h - description
+ -------------------
+ begin : Don Sep 19 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef PHRASEBOOK_H
+#define PHRASEBOOK_H
+
+#include <qobject.h>
+#include <qdragobject.h>
+#include <qxml.h>
+
+#include <kaction.h>
+#include <kprinter.h>
+
+class KURL;
+
+/**
+ * The class Phrase represents one phrase in a phrase book.
+ * @author Gunnar Schmi Dt
+ */
+class Phrase {
+ friend class PhraseBookParser;
+public:
+ Phrase();
+ Phrase (const QString &phrase);
+ Phrase (const QString &phrase, const QString &shortcut);
+
+ QString getPhrase() const;
+ QString getShortcut() const;
+
+ void setPhrase (const QString &phrase);
+ void setShortcut (const QString &shortcut);
+
+private:
+ QString phrase;
+ QString shortcut;
+};
+
+/**
+ * The class PhraseBookEntry implements a phrase book entry. That can be either
+ * a phrase or a start tag a sub phrase book.
+ * @author Gunnar Schmi Dt
+ */
+class PhraseBookEntry {
+public:
+ PhraseBookEntry ();
+ PhraseBookEntry (Phrase phrase, int level = 1, bool isPhrase = true);
+ ~PhraseBookEntry () {};
+
+ void setPhrase (Phrase phrase, int level = 1, bool isPhrase = true);
+
+ bool isPhrase() const;
+ Phrase getPhrase() const;
+ int getLevel() const;
+
+private:
+ bool isPhraseValue;
+ Phrase phrase;
+ int level;
+};
+
+typedef QValueList<PhraseBookEntry> PhraseBookEntryList;
+
+/**
+ * The class PhraseBook implements a phrase book. It mainly stores a
+ * token list where each token is a phrase book entry (either a phrase
+ * or a sub phrase book). The entries are placed into a tree structure
+ * as follows:
+ *
+ * The level of each entry tells the level in the tree (level=0 is the top
+ * level), each sub book in level i directly or indirectly contains all
+ * following entries until an entry of level at most i or the end of the
+ * token list.
+ *
+ * @author Gunnar Schmi Dt
+ */
+class PhraseBook : public PhraseBookEntryList {
+public:
+ PhraseBook() : PhraseBookEntryList() {};
+ ~PhraseBook() {};
+
+ /** opens a file containing a phrase book. Returns true if successful. */
+ bool open (const KURL &url);
+
+ /** decodes a phrase book. Returns true if successful. */
+ bool decode (const QString &xml);
+
+ /** decodes a phrase book. Returns true if successful. */
+ bool decode (QXmlInputSource &source);
+
+ /** Writes the phrases to a file. Returns true if successful. */
+ bool save (const KURL &url);
+
+ /** Writes the phrases to a file. Returns true if successful. */
+ bool save (const KURL &url, bool asPhrasebook);
+
+ /** Writes the phrases to a QTextStream. */
+ void save (QTextStream &stream, bool asPhrasebook);
+
+ /** Prints the phrases. */
+ void print (KPrinter *pPrinter);
+
+ /** Shows a file selector and writes the phrases to a file.
+ * @return 1, if the file got successfully written,
+ * 0, if the user canceled the operation,
+ * -1, if there was an error when saving the file.
+ */
+ int save (QWidget *parent, const QString &title, KURL &url, bool phrasebookFirst = true);
+
+ /** encodes the phrase book. Returns the encoded xml code. */
+ QString encode ();
+
+ /** Stores all entries in a QStringList. All hierarchy information and all
+ * shortcuts are ignored during this operation.
+ */
+ QStringList toStringList();
+
+ /** Adds the entries of the book to both the given popup menu and the given
+ * toolbar. The corresponding actions will be inserted into phrases.
+ */
+ void addToGUI (QPopupMenu *popup, KToolBar *toolbar,
+ KActionCollection *phrases,
+ QObject *receiver, const char *slot) const;
+
+ /** Inserts book into a new sub phrase book.
+ * @param name the name of the new sub phrase book.
+ * @param book the phrase book to insert.
+ */
+ void insert (const QString &name, const PhraseBook &book);
+};
+
+/**
+ * The class PhraseBookDrag implements drag and drop support for phrase books.
+ * @author Gunnar Schmi Dt
+ */
+class PhraseBookDrag: public QDragObject {
+ Q_OBJECT
+public:
+ PhraseBookDrag (PhraseBook *book, QWidget *dragSource = 0, const char *name = 0);
+ PhraseBookDrag (QWidget *dragSource = 0, const char *name = 0);
+ ~PhraseBookDrag ();
+
+ virtual void setBook (PhraseBook *book);
+
+ const char *format (int i) const;
+ virtual QByteArray encodedData (const char *) const;
+
+ static bool canDecode (const QMimeSource *e);
+ static bool decode (const QMimeSource *e, PhraseBook *book);
+
+private:
+ bool isEmpty;
+ QTextDrag xmlphrasebook;
+ QTextDrag xml;
+ QTextDrag plain;
+};
+
+class PhraseAction : public KAction {
+ Q_OBJECT
+public:
+ PhraseAction (const QString& phrase, const QString& cut, const QObject* receiver, const char* slot, KActionCollection* parent)
+ : KAction (phrase, "phrase", KShortcut(cut), 0, 0, parent, phrase.latin1()) {
+ this->phrase = phrase;
+ connect (this, SIGNAL(slotActivated (const QString &)), receiver, slot);
+ };
+ ~PhraseAction () {
+ }
+
+public slots:
+ void slotActivated () {
+ KAction::slotActivated();
+ emit slotActivated (phrase);
+ }
+
+signals:
+ void slotActivated (const QString &phrase);
+
+private:
+ QString phrase;
+};
+
+#endif
diff --git a/kmouth/phrasebook/phrasebookdialog.cpp b/kmouth/phrasebook/phrasebookdialog.cpp
new file mode 100644
index 0000000..cc79d2f
--- /dev/null
+++ b/kmouth/phrasebook/phrasebookdialog.cpp
@@ -0,0 +1,758 @@
+/***************************************************************************
+ phrasebookdialog.cpp - description
+ -------------------
+ begin : Don Sep 19 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// include files for QT
+#include <qapplication.h>
+#include <qlayout.h>
+#include <qclipboard.h>
+#include <qradiobutton.h>
+#include <qevent.h>
+#include <qpainter.h>
+#include <qstyle.h>
+#include <qgroupbox.h>
+#include <qpopupmenu.h>
+#include <qvaluestack.h>
+#include <qptrstack.h>
+#include <qwhatsthis.h>
+
+// include files for KDE
+#include <kpopupmenu.h>
+#include <klocale.h>
+#include <kaction.h>
+#include <kapplication.h>
+#include <klistview.h>
+#include <kiconloader.h>
+#include <kguiitem.h>
+#include <kmessagebox.h>
+#include <kfiledialog.h>
+#include <kstandarddirs.h>
+#include <kdesktopfile.h>
+
+#include "phrasebookdialog.h"
+#include "buttonboxui.h"
+#include "phrasetree.h"
+
+namespace PhraseBookPrivate {
+ enum columns {
+ name = 1,
+ filename = 2
+ };
+}
+
+CheckBookItem::CheckBookItem (QListViewItem *parent, QListViewItem *last,
+ const QString &text, const QString &name, const QString &filename)
+ : QCheckListItem (parent, text, QCheckListItem::CheckBox)
+{
+ moveItem (last);
+ setText(PhraseBookPrivate::name, name);
+ setText(PhraseBookPrivate::filename, filename);
+ setSelectable(false);
+
+ if (filename.isNull() || filename.isEmpty())
+ numberOfBooks = 0;
+ else
+ numberOfBooks = 1;
+ selectedBooks = 0;
+ ((CheckBookItem*)parent)->childChange (numberOfBooks, selectedBooks);
+}
+
+CheckBookItem::CheckBookItem (QListView *parent, QListViewItem *last,
+ const QString &text, const QString &name, const QString &filename)
+ : QCheckListItem (parent, text, QCheckListItem::CheckBox)
+{
+ moveItem (last);
+ setText(PhraseBookPrivate::name, name);
+ setText(PhraseBookPrivate::filename, filename);
+ setSelectable(false);
+
+ if (filename.isNull() || filename.isEmpty())
+ numberOfBooks = 0;
+ else
+ numberOfBooks = 1;
+ selectedBooks = 0;
+}
+
+CheckBookItem::~CheckBookItem () {
+}
+
+void CheckBookItem::activate() {
+ QListView *lv = listView();
+
+ if ((lv != 0) && (!lv->isEnabled()) || (!isEnabled()))
+ return;
+
+ setOn (!isOn());
+ ignoreDoubleClick();
+}
+
+void CheckBookItem::stateChange (bool on) {
+ QListViewItem *item = firstChild();
+ if (item == 0) {
+ QListViewItem *parent = this->parent();
+ if (parent != 0) {
+ if (on)
+ ((CheckBookItem*)parent)->childChange (0, 1);
+ else
+ ((CheckBookItem*)parent)->childChange (0, -1);
+ }
+ }
+ else propagateStateChange();
+}
+
+void CheckBookItem::propagateStateChange () {
+ QListViewItem *item = firstChild();
+ while (item != 0) {
+ if (isOn() != ((QCheckListItem*)item)->isOn())
+ ((QCheckListItem*)item)->setOn (isOn());
+ else
+ ((CheckBookItem*)item)->propagateStateChange ();
+ item = item->nextSibling();
+ }
+}
+
+void CheckBookItem::childChange (int numberDiff, int selDiff) {
+ numberOfBooks += numberDiff;
+ selectedBooks += selDiff;
+ QListViewItem *parent = this->parent();
+ if (parent != 0)
+ ((CheckBookItem*)parent)->childChange (numberDiff, selDiff);
+
+ QString text = i18n(" (%1 of %2 books selected)");
+ text = text.arg(selectedBooks).arg(numberOfBooks);
+ setText(0, this->text(PhraseBookPrivate::name)+text);
+}
+
+/***************************************************************************/
+
+InitialPhraseBookWidget::InitialPhraseBookWidget (QWidget *parent, const char *name)
+ : QWidget(parent, name)
+{
+ QVBoxLayout *mainLayout = new QVBoxLayout (this, 0, KDialog::spacingHint());
+ QLabel *label = new QLabel (i18n("Please decide which phrase books you need:"), this, "booksTitle");
+ mainLayout->add (label);
+
+ books = new KListView (this, "books");
+ books->setSorting (-1);
+ books->setItemsMovable (false);
+ books->setDragEnabled (false);
+ books->setAcceptDrops (false);
+ books->addColumn (i18n("Book"));
+ books->setRootIsDecorated (true);
+ books->setAllColumnsShowFocus (true);
+ books->setSelectionMode (QListView::Multi);
+ mainLayout->add (books);
+
+ initStandardPhraseBooks();
+}
+
+InitialPhraseBookWidget::~InitialPhraseBookWidget () {
+}
+
+void InitialPhraseBookWidget::initStandardPhraseBooks() {
+ StandardBookList bookPaths = PhraseBookDialog::standardPhraseBooks();
+
+ QListViewItem *parent = 0;
+ QListViewItem *last = 0;
+ QStringList currentNamePath = "";
+ QPtrStack<QListViewItem> stack;
+ StandardBookList::iterator it;
+ for (it = bookPaths.begin(); it != bookPaths.end(); ++it) {
+ QString namePath = (*it).path;
+ QStringList dirs = QStringList::split("/", namePath);
+
+ QStringList::iterator it1=currentNamePath.begin();
+ QStringList::iterator it2=dirs.begin();
+ for (; (it1 != currentNamePath.end())
+ && (it1 != dirs.end()) && (*it1 == *it2); ++it1, ++it2);
+ for (; it1 != currentNamePath.end(); ++it1) {
+ last = parent;
+ parent = stack.pop();
+ }
+ for (; it2 != dirs.end(); ++it2) {
+ stack.push (parent);
+ QListViewItem *newParent;
+ if (parent == 0)
+ newParent = new CheckBookItem (books, last, *it2, *it2, QString::null);
+ else
+ newParent = new CheckBookItem (parent, last, *it2, *it2, QString::null);
+ parent = newParent;
+ last = 0;
+ }
+ currentNamePath = dirs;
+
+ QListViewItem *book;
+ if (parent == 0)
+ book = new CheckBookItem (books, last, (*it).name, (*it).name, (*it).filename);
+ else
+ book = new CheckBookItem (parent, last, (*it).name, (*it).name, (*it).filename);
+ last = book;
+ }
+}
+
+void InitialPhraseBookWidget::createBook () {
+ PhraseBook book;
+ QListViewItem *item = books->firstChild();
+ while (item != 0) {
+ if (item->firstChild() != 0) {
+ item = item->firstChild();
+ }
+ else {
+ if (((QCheckListItem*)item)->isOn()) {
+ PhraseBook localBook;
+ localBook.open(KURL( item->text(PhraseBookPrivate::filename )));
+ book += localBook;
+ }
+
+ while ((item != 0) && (item->nextSibling() == 0)) {
+ item = item->parent();
+ }
+ if (item != 0)
+ item = item->nextSibling();
+ }
+ }
+
+ QString bookLocation = KApplication::kApplication()->dirs()->saveLocation ("appdata", "/");
+ if (!bookLocation.isNull() && !bookLocation.isEmpty()) {
+ book.save (KURL( bookLocation + "standard.phrasebook" ));
+ }
+}
+
+/***************************************************************************/
+
+ButtonBoxWidget::ButtonBoxWidget (QWidget *parent, const char *name)
+: ButtonBoxUI (parent, name) {
+ keyButtonPlaceLayout = new QGridLayout (keyButtonPlace, 1, 1, 0, 0, "keyButtonPlaceLayout");
+
+ keyButton = new KKeyButton (keyButtonPlace, "key");
+ keyButtonPlaceLayout->addWidget (keyButton, 1,1);
+ QWhatsThis::add (keyButton, i18n("By clicking on this button you can select the keyboard shortcut associated with the selected phrase."));
+
+ group = new QButtonGroup (phrasebox);
+ group->hide();
+ group->setExclusive (true);
+ group->insert (noKey);
+ group->insert (customKey);
+}
+
+ButtonBoxWidget::~ButtonBoxWidget () {
+}
+
+/***************************************************************************/
+
+namespace PhraseBookPrivate {
+ PhraseBookDialog *instance = 0;
+}
+
+PhraseBookDialog::PhraseBookDialog ()
+ : KMainWindow (0, "phraseEditDialog")
+{
+ setCaption (i18n("Phrase Book"));
+ initGUI();
+ initActions();
+ initStandardPhraseBooks();
+ QString standardBook = KApplication::kApplication()->dirs()->findResource("appdata", "standard.phrasebook");
+ if (!standardBook.isNull() && !standardBook.isEmpty()) {
+ PhraseBook book;
+ book.open(KURL( standardBook ));
+ treeView->clear();
+ treeView->addBook(0, 0, &book);
+ treeView->setCurrentItem(treeView->firstChild());
+ selectionChanged();
+ phrasebookChanged = false;
+ }
+ // i18n("Edit Phrase Book")
+}
+
+PhraseBookDialog *PhraseBookDialog::get() {
+ if (PhraseBookPrivate::instance == 0)
+ PhraseBookPrivate::instance = new PhraseBookDialog();
+ return PhraseBookPrivate::instance;
+}
+
+PhraseBookDialog::~PhraseBookDialog() {
+ PhraseBookPrivate::instance = 0;
+}
+
+void PhraseBookDialog::initGUI () {
+ QWidget *page = new QWidget( this );
+ setCentralWidget(page);
+ QVBoxLayout *mainLayout = new QVBoxLayout (page, 0);
+
+ treeView = new PhraseTree (page, "phrasetree");
+ treeView->setSorting (-1);
+ treeView->setItemsMovable (true);
+ treeView->setDragEnabled (true);
+ treeView->setAcceptDrops (true);
+ treeView->addColumn (i18n("Phrase"));
+ treeView->addColumn (i18n("Shortcut"));
+ treeView->setRootIsDecorated (true);
+ treeView->setAllColumnsShowFocus (true);
+ treeView->setSelectionMode (QListView::Extended);
+ QWhatsThis::add (treeView, i18n("This list contains the current phrase book in a tree structure. You can select and modify individual phrases and sub phrase books"));
+ connect (treeView, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
+ connect (treeView, SIGNAL(contextMenuRequested (QListViewItem *, const QPoint &, int)), this, SLOT(contextMenuRequested (QListViewItem *, const QPoint &, int)));
+ connect (treeView, SIGNAL(dropped (QDropEvent *, QListViewItem *, QListViewItem *)), this, SLOT(slotDropped (QDropEvent *, QListViewItem *, QListViewItem *)));
+ connect (treeView, SIGNAL(moved (QListViewItem *, QListViewItem *, QListViewItem *)), this, SLOT(slotMoved (QListViewItem *, QListViewItem *, QListViewItem *)));
+ mainLayout->addWidget (treeView);
+
+ buttonBox = new ButtonBoxWidget (page, "buttonbox");
+ connect (buttonBox->lineEdit, SIGNAL(textChanged(const QString &)), SLOT(slotTextChanged(const QString &)));
+ connect (buttonBox->noKey, SIGNAL(clicked()), SLOT(slotNoKey()));
+ connect (buttonBox->customKey, SIGNAL(clicked()), SLOT(slotCustomKey()));
+ connect (buttonBox->keyButton, SIGNAL(capturedShortcut(const KShortcut&)), SLOT(capturedShortcut(const KShortcut&)));
+ mainLayout->addWidget (buttonBox);
+
+ treeView->setFocus();
+ selectionChanged();
+}
+
+void PhraseBookDialog::initActions() {
+// The file menu
+ fileNewPhrase = new KAction (i18n("&New Phrase"), "phrase_new", 0, this, SLOT(slotAddPhrase()), actionCollection(),"file_new_phrase");
+ fileNewPhrase->setStatusText(i18n("Adds a new phrase"));
+ fileNewPhrase->setWhatsThis (i18n("Adds a new phrase"));
+
+ fileNewBook = new KAction (i18n("New Phrase &Book"), "phrasebook_new", 0, this, SLOT(slotAddPhrasebook()), actionCollection(),"file_new_book");
+ fileNewBook->setStatusText(i18n("Adds a new phrase book into which other books and phrases can be placed"));
+ fileNewBook->setWhatsThis (i18n("Adds a new phrase book into which other books and phrases can be placed"));
+
+ fileSave = KStdAction::save(this, SLOT(slotSave()), actionCollection());
+ fileSave->setStatusText(i18n("Saves the phrase book onto the hard disk"));
+ fileSave->setWhatsThis (i18n("Saves the phrase book onto the hard disk"));
+
+ fileImport = new KAction (i18n("&Import..."), "phrasebook_open", 0, this, SLOT(slotImportPhrasebook()), actionCollection(),"file_import");
+ fileImport->setStatusText(i18n("Imports a file and adds its contents to the phrase book"));
+ fileImport->setWhatsThis (i18n("Imports a file and adds its contents to the phrase book"));
+
+ toolbarImport = new KToolBarPopupAction (i18n("&Import..."), "phrasebook_open", 0, this, SLOT(slotImportPhrasebook()), actionCollection(),"toolbar_import");
+ toolbarImport->setStatusText(i18n("Imports a file and adds its contents to the phrase book"));
+ toolbarImport->setWhatsThis (i18n("Imports a file and adds its contents to the phrase book"));
+
+ fileImportStandardBook = new KActionMenu (i18n("I&mport Standard Phrase Book"), "phrasebook_open", actionCollection(),"file_import_standard_book");
+ fileImportStandardBook->setStatusText(i18n("Imports a standard phrase book and adds its contents to the phrase book"));
+ fileImportStandardBook->setWhatsThis (i18n("Imports a standard phrase book and adds its contents to the phrase book"));
+
+ fileExport = new KAction (i18n("&Export..."), "phrasebook_save", 0, this, SLOT(slotExportPhrasebook()), actionCollection(),"file_export");
+ fileExport->setStatusText(i18n("Exports the currently selected phrase(s) or phrase book(s) into a file"));
+ fileExport->setWhatsThis (i18n("Exports the currently selected phrase(s) or phrase book(s) into a file"));
+
+ filePrint = KStdAction::print(this, SLOT(slotPrint()), actionCollection());
+ filePrint->setStatusText(i18n("Prints the currently selected phrase(s) or phrase book(s)"));
+ filePrint->setWhatsThis (i18n("Prints the currently selected phrase(s) or phrase book(s)"));
+
+ fileClose = KStdAction::close(this, SLOT(close()), actionCollection());
+ fileClose->setStatusText(i18n("Closes the window"));
+ fileClose->setWhatsThis (i18n("Closes the window"));
+
+// The edit menu
+ editCut = KStdAction::cut(this, SLOT(slotCut()), actionCollection());
+ editCut->setStatusText(i18n("Cuts the currently selected entries from the phrase book and puts it to the clipboard"));
+ editCut->setWhatsThis (i18n("Cuts the currently selected entries from the phrase book and puts it to the clipboard"));
+
+ editCopy = KStdAction::copy(this, SLOT(slotCopy()), actionCollection());
+ editCopy->setStatusText(i18n("Copies the currently selected entry from the phrase book to the clipboard"));
+ editCopy->setWhatsThis (i18n("Copies the currently selected entry from the phrase book to the clipboard"));
+
+ editPaste = KStdAction::paste(this, SLOT(slotPaste()), actionCollection());
+ editPaste->setStatusText(i18n("Pastes the clipboard contents to actual position"));
+ editPaste->setWhatsThis (i18n("Pastes the clipboard contents to actual position"));
+
+ editDelete = new KAction (i18n("&Delete"), "editdelete", 0, this, SLOT(slotRemove()), actionCollection(),"edit_delete");
+ editDelete->setStatusText(i18n("Deletes the selected entries from the phrase book"));
+ editDelete->setWhatsThis (i18n("Deletes the selected entries from the phrase book"));
+
+ // use the absolute path to your kmouthui.rc file for testing purpose in createGUI();
+ createGUI("phrasebookdialogui.rc");
+}
+
+QString PhraseBookDialog::displayPath (QString filename) {
+ QFileInfo file(filename);
+ QString path = file.dirPath();
+ QString dispPath = "";
+ uint position = path.find("/kmouth/books/")+QString("/kmouth/books/").length();
+
+ while (path.length() > position) {
+ file.setFile(path);
+
+ KDesktopFile *dirDesc = new KDesktopFile(path+"/.directory", true, "data");
+ QString name = dirDesc->readName();
+ delete dirDesc;
+
+ if (name.isNull() || name.isEmpty())
+ dispPath += "/" + file.fileName ();
+ else
+ dispPath += "/" + name;
+
+ path = file.dirPath();
+ }
+ return dispPath;
+}
+
+StandardBookList PhraseBookDialog::standardPhraseBooks() {
+ QStringList bookPaths = KGlobal::instance()->dirs()->findAllResources (
+ "data", "kmouth/books/*.phrasebook", true, true);
+ QStringList bookNames;
+ QMap<QString,StandardBook> bookMap;
+ QStringList::iterator it;
+ for (it = bookPaths.begin(); it != bookPaths.end(); ++it) {
+ PhraseBook pbook;
+ if (pbook.open (KURL( *it ))) {
+ StandardBook book;
+ book.name = (*pbook.begin()).getPhrase().getPhrase();
+
+ book.path = displayPath(*it);
+ book.filename = *it;
+
+ bookNames += book.path + "/" + book.name;
+ bookMap [book.path + "/" + book.name] = book;
+ }
+ }
+
+ bookNames.sort();
+
+ StandardBookList result;
+ for (it = bookNames.begin(); it != bookNames.end(); ++it)
+ result += bookMap [*it];
+
+ return result;
+}
+
+void PhraseBookDialog::initStandardPhraseBooks () {
+ StandardBookList bookPaths = standardPhraseBooks();
+
+ KActionMenu *parent = fileImportStandardBook;
+ QStringList currentNamePath = "x";
+ QPtrStack<KActionMenu> stack;
+ StandardBookList::iterator it;
+ for (it = bookPaths.begin(); it != bookPaths.end(); ++it) {
+ KURL url;
+ url.setPath((*it).filename);
+
+ QString namePath = "x/"+(*it).path;
+ QStringList dirs = QStringList::split("/", namePath);
+
+ QStringList::iterator it1=currentNamePath.begin();
+ QStringList::iterator it2=dirs.begin();
+ for (; (it1 != currentNamePath.end())
+ && (it1 != dirs.end()) && (*it1 == *it2); ++it1, ++it2);
+ for (; it1 != currentNamePath.end(); ++it1)
+ parent = stack.pop();
+ for (; it2 != dirs.end(); ++it2) {
+ stack.push (parent);
+ KActionMenu *newParent = new KActionMenu (*it2);
+ parent->insert(newParent);
+ if (parent == fileImportStandardBook)
+ newParent->plug(toolbarImport->popupMenu());
+ parent = newParent;
+ }
+ currentNamePath = dirs;
+
+ KAction *book = new StandardPhraseBookInsertAction (
+ url, (*it).name, this, SLOT(slotImportPhrasebook (const KURL &)), actionCollection());
+ parent->insert(book);
+ if (parent == fileImportStandardBook)
+ book->plug(toolbarImport->popupMenu());
+ }
+}
+
+PhraseTreeItem *selectedItem (QListView *treeView) {
+ PhraseTreeItem *currentItem = (PhraseTreeItem *)treeView->currentItem();
+ if ((currentItem == 0) || (!currentItem->isSelected()))
+ return 0;
+
+ QListViewItemIterator it(treeView);
+ while (it.current()) {
+ QListViewItem *item = it.current();
+ if (item->isSelected() && (item != currentItem))
+ return 0;
+ ++it;
+ }
+ return currentItem;
+}
+
+void PhraseBookDialog::selectionChanged () {
+ bool modified = phrasebookChanged;
+ PhraseTreeItem *currentItem = selectedItem (treeView);
+ if (currentItem == 0) {
+ buttonBox->textLabel->setText (i18n("Text of the &phrase:"));
+ buttonBox->textLabel->setEnabled(false);
+ buttonBox->group->setEnabled(false);
+ buttonBox->lineEdit->setText("");
+ buttonBox->lineEdit->setEnabled(false);
+ buttonBox->shortcutLabel->setEnabled(false);
+ buttonBox->keyButton->setShortcut("", false);
+ buttonBox->keyButton->setEnabled(false);
+ buttonBox->noKey->setChecked (false);
+ buttonBox->noKey->setEnabled (false);
+ buttonBox->customKey->setChecked (false);
+ buttonBox->customKey->setEnabled (false);
+ }
+ else if (currentItem->isPhrase()) {
+ buttonBox->textLabel->setText (i18n("Text of the &phrase:"));
+ buttonBox->textLabel->setEnabled(true);
+ buttonBox->group->setEnabled(true);
+ buttonBox->lineEdit->setText(currentItem->text(0));
+ buttonBox->lineEdit->setEnabled(true);
+ buttonBox->shortcutLabel->setEnabled(true);
+ QString shortcut = currentItem->text(1);
+ buttonBox->keyButton->setShortcut(currentItem->cut(), false);
+ if (shortcut.isEmpty() || shortcut.isNull()) {
+ buttonBox->noKey->setChecked (true);
+ buttonBox->customKey->setChecked (false);
+ }
+ else {
+ buttonBox->noKey->setChecked (false);
+ buttonBox->customKey->setChecked (true);
+ }
+ buttonBox->keyButton->setEnabled(true);
+ buttonBox->noKey->setEnabled(true);
+ buttonBox->customKey->setEnabled(true);
+ }
+ else {
+ buttonBox->textLabel->setText (i18n("Name of the &phrase book:"));
+ buttonBox->textLabel->setEnabled(true);
+ buttonBox->group->setEnabled(true);
+ buttonBox->lineEdit->setText(currentItem->text(0));
+ buttonBox->lineEdit->setEnabled(true);
+ buttonBox->shortcutLabel->setEnabled(false);
+ buttonBox->keyButton->setShortcut("", false);
+ buttonBox->keyButton->setEnabled(false);
+ buttonBox->noKey->setChecked (false);
+ buttonBox->noKey->setEnabled (false);
+ buttonBox->customKey->setChecked (false);
+ buttonBox->customKey->setEnabled (false);
+ }
+ phrasebookChanged = modified;
+}
+
+bool PhraseBookDialog::queryClose() {
+ if (phrasebookChanged) {
+ int answer = KMessageBox::questionYesNoCancel (this,
+ i18n("<qt>There are unsaved changes.<br>Do you want to apply the changes before closing the \"phrase book\" window or discard the changes?</qt>"),
+ i18n("Closing \"Phrase Book\" Window"),
+ KStdGuiItem::apply(), KStdGuiItem::discard(), "AutomaticSave");
+ if (answer == KMessageBox::Yes) {
+ slotSave();
+ return true;
+ }
+ return (answer == KMessageBox::No);
+ }
+ return true;
+}
+
+void PhraseBookDialog::slotTextChanged (const QString &s) {
+ PhraseTreeItem *currentItem = selectedItem (treeView);
+ if (currentItem != 0)
+ currentItem->setText(0, s);
+ phrasebookChanged = true;
+}
+
+void PhraseBookDialog::slotNoKey() {
+ buttonBox->noKey->setChecked (true);
+ buttonBox->customKey->setChecked (false);
+
+ PhraseTreeItem *currentItem = selectedItem (treeView);
+ if (currentItem != 0) {
+ currentItem->setCut (KShortcut(QString::null));
+ buttonBox->keyButton->setShortcut(currentItem->cut(), false);
+ }
+ phrasebookChanged = true;
+}
+
+void PhraseBookDialog::slotCustomKey() {
+ buttonBox->keyButton->captureShortcut();
+}
+
+void PhraseBookDialog::capturedShortcut (const KShortcut& cut) {
+ if (cut.isNull()) {
+ slotNoKey();
+ }
+ else
+ setShortcut (cut);
+ phrasebookChanged = true;
+}
+
+void PhraseBookDialog::setShortcut( const KShortcut& cut ) {
+ // Check whether the shortcut is valid
+ for (uint i = 0; i < cut.count(); i++) {
+ const KKeySequence& seq = cut.seq(i);
+ const KKey& key = seq.key(0);
+
+ if (key.modFlags() == 0 && key.sym() < 0x3000
+ && QChar(key.sym()).isLetterOrNumber())
+ {
+ QString s = i18n("In order to use the '%1' key as a shortcut, "
+ "it must be combined with the "
+ "Win, Alt, Ctrl, and/or Shift keys.").arg(QChar(key.sym()));
+ KMessageBox::sorry( this, s, i18n("Invalid Shortcut Key") );
+ return;
+ }
+ }
+
+ PhraseTreeItem *currentItem = selectedItem (treeView);
+ // If key isn't already in use,
+ if (!treeView->isKeyPresent (cut, currentItem, true)) {
+ // Set new key code
+ currentItem->setCut (cut);
+ // Update display
+ buttonBox->noKey->setChecked (false);
+ buttonBox->customKey->setChecked (true);
+ buttonBox->keyButton->setShortcut(currentItem->cut(), false);
+ }
+}
+
+QListViewItem *PhraseBookDialog::addBook (QListViewItem *parent, QListViewItem *after, PhraseBook *book) {
+ QListViewItem *newItem = treeView->addBook(parent, after, book);
+ if (newItem != 0) {
+ treeView->clearSelection();
+ treeView->ensureItemVisible(newItem);
+ treeView->setCurrentItem (newItem);
+ treeView->setSelected (newItem, true);
+ phrasebookChanged = true;
+ }
+ return newItem;
+}
+
+QListViewItem *PhraseBookDialog::addBook (QListViewItem *item, PhraseBook *book) {
+ if (item == 0)
+ return addBook(0, 0, book);
+ else if (((PhraseTreeItem *)item)->isPhrase() || !item->isOpen())
+ if (item->parent() != 0)
+ return addBook(item->parent(), item, book);
+ else
+ return addBook(0, item, book);
+ else
+ return addBook(item, 0, book);
+}
+
+void PhraseBookDialog::contextMenuRequested(QListViewItem *, const QPoint &pos, int) {
+ QString name;
+ if (treeView->hasSelectedItems())
+ name = "phrasebook_popup_sel";
+ else
+ name = "phrasebook_popup_nosel";
+
+ QPopupMenu *popup = (QPopupMenu *)factory()->container(name,this);
+ if (popup != 0) {
+ popup->popup(pos, 0);
+ }
+}
+
+void PhraseBookDialog::slotRemove () {
+ if (treeView->hasSelectedItems() != 0)
+ treeView->deleteSelectedItems();
+ selectionChanged();
+ phrasebookChanged = true;
+}
+
+void PhraseBookDialog::slotCut () {
+ slotCopy();
+ slotRemove();
+}
+
+void PhraseBookDialog::slotCopy () {
+ PhraseBook book;
+ treeView->fillBook (&book, true);
+ QApplication::clipboard()->setData(new PhraseBookDrag(&book));
+}
+
+void PhraseBookDialog::slotPaste () {
+ PhraseBook book;
+ if (PhraseBookDrag::decode(QApplication::clipboard()->data(), &book)) {
+ addBook (treeView->currentItem(), &book);
+ }
+}
+
+void PhraseBookDialog::slotDropped (QDropEvent *e, QListViewItem *parent, QListViewItem *after) {
+ PhraseBook book;
+ if (PhraseBookDrag::decode(e, &book)) {
+ addBook(parent, after, &book);
+ }
+}
+
+void PhraseBookDialog::slotMoved (QListViewItem *item, QListViewItem *, QListViewItem *) {
+ treeView->ensureItemVisible(item);
+ treeView->setSelected (item, true);
+ phrasebookChanged = true;
+}
+
+void PhraseBookDialog::slotAddPhrasebook () {
+ PhraseBook book;
+ Phrase phrase(i18n("(New Phrase Book)"), "");
+ book += PhraseBookEntry(phrase, 0, false);
+
+ QListViewItem *item = addBook (treeView->currentItem(), &book);
+ item->setOpen (true);
+ buttonBox->lineEdit->selectAll();
+ buttonBox->lineEdit->setFocus();
+}
+
+void PhraseBookDialog::slotAddPhrase () {
+ PhraseBook book;
+ Phrase phrase(i18n("(New Phrase)"), "");
+ book += PhraseBookEntry(phrase, 0, true);
+
+ addBook (treeView->currentItem(), &book);
+ buttonBox->lineEdit->selectAll();
+ buttonBox->lineEdit->setFocus();
+}
+
+void PhraseBookDialog::slotSave () {
+ book.clear();
+ treeView->fillBook (&book, false);
+ emit phrasebookConfirmed (book);
+ phrasebookChanged = false;
+}
+
+void PhraseBookDialog::slotImportPhrasebook () {
+ KURL url=KFileDialog::getOpenURL(QString::null,
+ i18n("*.phrasebook|Phrase Books (*.phrasebook)\n*.txt|Plain Text Files (*.txt)\n*|All Files"), this, i18n("Import Phrasebook"));
+
+ slotImportPhrasebook (url);
+}
+
+void PhraseBookDialog::slotImportPhrasebook (const KURL &url) {
+ if(!url.isEmpty()) {
+ PhraseBook book;
+ if (book.open (url))
+ addBook(treeView->currentItem(), &book);
+ else
+ KMessageBox::sorry(this,i18n("There was an error loading file\n%1").arg( url.url() ));
+ }
+}
+
+void PhraseBookDialog::slotExportPhrasebook () {
+ PhraseBook book;
+ treeView->fillBook (&book, treeView->hasSelectedItems());
+
+ KURL url;
+ if (book.save (this, i18n("Export Phrase Book"), url) == -1)
+ KMessageBox::sorry(this,i18n("There was an error saving file\n%1").arg( url.url() ));
+}
+
+void PhraseBookDialog::slotPrint()
+{
+ KPrinter printer;
+ if (printer.setup(this)) {
+ PhraseBook book;
+ treeView->fillBook (&book, treeView->hasSelectedItems());
+
+ book.print(&printer);
+ }
+}
+
+#include "phrasebookdialog.moc"
diff --git a/kmouth/phrasebook/phrasebookdialog.h b/kmouth/phrasebook/phrasebookdialog.h
new file mode 100644
index 0000000..774387f
--- /dev/null
+++ b/kmouth/phrasebook/phrasebookdialog.h
@@ -0,0 +1,234 @@
+/***************************************************************************
+ phrasebookdialog.h - description
+ -------------------
+ begin : Don Sep 19 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef PHRASEBOOKDIALOG_H
+#define PHRASEBOOKDIALOG_H
+
+#include <qbutton.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qlabel.h>
+#include <qlistview.h>
+#include <kmainwindow.h>
+#include <klineedit.h>
+#include <kkeybutton.h>
+#include <kurl.h>
+#include "phrasebook.h"
+#include "buttonboxui.h"
+
+class QListViewItem;
+class PhraseTreeItem;
+class PhraseTree;
+class QStringList;
+class QString;
+class KListView;
+
+struct StandardBook {
+ QString name;
+ QString path;
+ QString filename;
+};
+typedef QValueList<StandardBook> StandardBookList;
+
+/**The class PhraseTreeItem is an ListViewItem for either a phrase or a phrase book.
+ *@author Gunnar Schmi Dt
+ */
+
+class CheckBookItem : public QCheckListItem {
+public:
+ CheckBookItem (QListViewItem *parent, QListViewItem *last,
+ const QString &text, const QString &name, const QString &filename);
+ CheckBookItem (QListView *parent, QListViewItem *last,
+ const QString &text, const QString &name, const QString &filename);
+ ~CheckBookItem();
+
+protected:
+ virtual void activate ();
+ virtual void stateChange (bool);
+ virtual void propagateStateChange ();
+ virtual void childChange (int numberDiff, int selDiff);
+
+private:
+ int numberOfBooks;
+ int selectedBooks;
+};
+
+/**
+ * This class represents a widget for configuring the initial phrasebook.
+ * @author Gunnar Schmi Dt
+ */
+
+class InitialPhraseBookWidget : public QWidget {
+ Q_OBJECT
+public:
+ InitialPhraseBookWidget(QWidget *parent, const char *name);
+ ~InitialPhraseBookWidget();
+
+ void createBook();
+
+private:
+ /** initializes the list of standard phrase books */
+ void initStandardPhraseBooks ();
+
+ KListView *books;
+};
+
+/**
+ * The class StandardPhraseBookInsertAction implements an Action for
+ * inserting a standard phrase book.
+ * @author Gunnar Schmi Dt
+ */
+class StandardPhraseBookInsertAction : public KAction {
+ Q_OBJECT
+public:
+ StandardPhraseBookInsertAction (const KURL &url, const QString& name, const QObject* receiver, const char* slot, KActionCollection* parent)
+ : KAction (name, "phrasebook", 0, 0, 0, parent, 0) {
+ this->url = url;
+ connect (this, SIGNAL(slotActivated (const KURL &)), receiver, slot);
+ };
+ ~StandardPhraseBookInsertAction () {
+ };
+
+public slots:
+ void slotActivated () {
+ KAction::slotActivated();
+ emit slotActivated (url);
+ };
+
+signals:
+ void slotActivated (const KURL &url);
+
+private:
+ KURL url;
+};
+
+/**
+ * This class represents a widget holding the buttons of the phrase book
+ * edit window.
+ * @author Gunnar Schmi Dt
+ */
+class ButtonBoxWidget : public ButtonBoxUI {
+public:
+ ButtonBoxWidget (QWidget *parent = 0, const char *name = 0);
+ ~ButtonBoxWidget ();
+
+ KKeyButton *keyButton;
+ QButtonGroup *group;
+
+protected:
+ QGridLayout *keyButtonPlaceLayout;
+};
+
+/**
+ * The class PhraseBookDialog implements a dialog for editing phrase books.
+ * @author Gunnar Schmi Dt
+ */
+
+class PhraseBookDialog : public KMainWindow {
+ friend class InitialPhraseBookWidget;
+ Q_OBJECT
+private:
+ /** Constructor. It is private because this class implements the singleton
+ * pattern. For creating the instance of the dialog, use the get() method.
+ */
+ PhraseBookDialog ();
+
+ static QString displayPath (QString path);
+
+public:
+ /** Returns a pointer to the instance of this dialog. As a part off the
+ * singleton pattern it will make sure that there is at most one instance
+ * of the dialog at a given time.
+ */
+ static PhraseBookDialog *get();
+
+ /** Destructor. */
+ ~PhraseBookDialog();
+
+ bool queryClose ();
+
+public slots:
+ void slotTextChanged (const QString &s);
+ void slotNoKey();
+ void slotCustomKey();
+ void capturedShortcut (const KShortcut& cut);
+
+ void selectionChanged ();
+ void contextMenuRequested(QListViewItem *, const QPoint &pos, int);
+
+ void slotRemove ();
+ void slotCut ();
+ void slotCopy ();
+ void slotPaste ();
+
+ void slotAddPhrasebook ();
+ void slotAddPhrase ();
+
+ void slotSave ();
+ void slotImportPhrasebook ();
+ void slotImportPhrasebook (const KURL &url);
+ void slotExportPhrasebook ();
+ void slotPrint ();
+
+ void slotDropped (QDropEvent *e, QListViewItem *parent, QListViewItem *after);
+ void slotMoved (QListViewItem *item, QListViewItem *, QListViewItem *);
+
+signals:
+ void phrasebookConfirmed (PhraseBook &book);
+
+private:
+ static StandardBookList standardPhraseBooks ();
+
+ void initGUI();
+ /** initializes the KActions of the window */
+ void initActions();
+ /** initializes the list of standard phrase books */
+ void initStandardPhraseBooks ();
+
+ QListViewItem *addBook (QListViewItem *parent, QListViewItem *after, PhraseBook *book);
+ QListViewItem *addBook (QListViewItem *item, PhraseBook *book);
+
+ void setShortcut (const KShortcut &cut);
+
+ void _warning (const KKeySequence &cut, QString sAction, QString sTitle);
+
+ bool isGlobalKeyPresent (const KShortcut& cut, bool warnUser);
+ bool isPhraseKeyPresent (const KShortcut& cut, bool warnUser);
+ bool isKeyPresent (const KShortcut& cut, bool warnUser);
+
+ PhraseBook book;
+ bool phrasebookChanged;
+
+ PhraseTree *treeView;
+ ButtonBoxWidget *buttonBox;
+
+ KAction* fileNewPhrase;
+ KAction* fileNewBook;
+ KAction* fileSave;
+ KAction* fileImport;
+ KToolBarPopupAction* toolbarImport;
+ KActionMenu* fileImportStandardBook;
+ KAction* fileExport;
+ KAction* filePrint;
+ KAction* fileClose;
+ KAction* editCut;
+ KAction* editCopy;
+ KAction* editPaste;
+ KAction* editDelete;
+};
+
+#endif
diff --git a/kmouth/phrasebook/phrasebookdialogui.rc b/kmouth/phrasebook/phrasebookdialogui.rc
new file mode 100644
index 0000000..c5150fe
--- /dev/null
+++ b/kmouth/phrasebook/phrasebookdialogui.rc
@@ -0,0 +1,64 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="kmouth" version="1">
+
+<MenuBar>
+ <Menu name="file" noMerge="1"><text>&amp;File</text>
+ <Action name="file_new_phrase"/>
+ <Action name="file_new_book"/>
+ <Separator />
+ <Action name="file_save"/>
+ <Separator />
+ <Action name="file_import"/>
+ <Action name="file_import_standard_book"/>
+ <Action name="file_export"/>
+ <Separator />
+ <Action name="file_print"/>
+ <Separator />
+ <Action name="file_close"/>
+ </Menu>
+ <Menu name="edit"><text>&amp;Edit</text>
+ <Action name="edit_delete"/>
+ </Menu>
+</MenuBar>
+
+<Menu name="phrasebook_popup_nosel" noMerge="1">
+ <Action name="file_new_phrase"/>
+ <Action name="file_new_book"/>
+ <Separator />
+ <Action name="file_import"/>
+ <Action name="file_import_standard_book"/>
+ <Action name="file_export"/>
+ <Separator />
+ <Action name="edit_paste"/>
+</Menu>
+
+<Menu name="phrasebook_popup_sel" noMerge="1">
+ <Action name="file_new_phrase"/>
+ <Action name="file_new_book"/>
+ <Separator />
+ <Action name="file_import"/>
+ <Action name="file_import_standard_book"/>
+ <Action name="file_export"/>
+ <Separator />
+ <Action name="edit_cut"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+ <Separator />
+ <Action name="edit_delete"/>
+</Menu>
+
+<ToolBar name="mainToolBar" noMerge="1">
+ <Action name="file_new_phrase"/>
+ <Action name="file_new_book"/>
+ <Action name="file_save"/>
+ <Action name="toolbar_import"/>
+ <Action name="file_export"/>
+ <Action name="file_print"/>
+ <Separator />
+ <Action name="edit_cut"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+ <Action name="edit_delete"/>
+</ToolBar>
+
+</kpartgui>
diff --git a/kmouth/phrasebook/phrasebookparser.cpp b/kmouth/phrasebook/phrasebookparser.cpp
new file mode 100644
index 0000000..9883e49
--- /dev/null
+++ b/kmouth/phrasebook/phrasebookparser.cpp
@@ -0,0 +1,112 @@
+/***************************************************************************
+ phrasebookparser.cpp - description
+ -------------------
+ begin : Don Sep 12 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "phrasebookparser.h"
+
+PhraseBookParser::PhraseBookParser() {
+}
+
+PhraseBookParser::~PhraseBookParser() {
+}
+
+bool PhraseBookParser::warning (const QXmlParseException &) {
+ return false;
+}
+
+bool PhraseBookParser::error (const QXmlParseException &) {
+ return false;
+}
+
+bool PhraseBookParser::fatalError (const QXmlParseException &) {
+ return false;
+}
+
+QString PhraseBookParser::errorString() {
+ return "";
+}
+
+bool PhraseBookParser::startDocument() {
+ list.clear ();
+ isInPhrase = false;
+ level = 0;
+ offset = 0;
+ starting = true;
+ return true;
+}
+
+bool PhraseBookParser::startElement (const QString &, const QString &,
+ const QString &name,
+ const QXmlAttributes &attributes)
+{
+ if (name == "phrase") {
+ if (isInPhrase)
+ return false;
+
+ phrase.phrase = "";
+ phrase.shortcut = attributes.value("shortcut");
+ isInPhrase = true;
+ }
+ else if (name == "phrasebook") {
+ if (isInPhrase)
+ return false;
+
+ phrase.phrase = attributes.value("name");
+ phrase.shortcut = "";
+ if ((phrase.phrase.isNull() || phrase.phrase.isEmpty()) && starting)
+ offset = -1;
+ else {
+ list += PhraseBookEntry (phrase, level, false);
+ level++;
+ }
+ starting = false;
+ }
+ return true;
+}
+
+bool PhraseBookParser::characters (const QString &ch) {
+ phrase.phrase += ch;
+ return true;
+}
+
+bool PhraseBookParser::ignorableWhitespace (const QString &ch) {
+ phrase.phrase += ch;
+ return true;
+}
+
+bool PhraseBookParser::endElement (const QString &, const QString &,
+ const QString &name)
+{
+ if (name == "phrase") {
+ list += PhraseBookEntry (phrase, level, true);
+ isInPhrase = false;
+ }
+ else if (name == "phrasebook") {
+ if (level == offset)
+ return false;
+
+ level--;
+ }
+ return true;
+}
+
+bool PhraseBookParser::endDocument() {
+ return (level == offset);
+}
+
+PhraseBookEntryList PhraseBookParser::getPhraseList() {
+ return list;
+}
diff --git a/kmouth/phrasebook/phrasebookparser.h b/kmouth/phrasebook/phrasebookparser.h
new file mode 100644
index 0000000..a6e436a
--- /dev/null
+++ b/kmouth/phrasebook/phrasebookparser.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ phrasebookparser.h - description
+ -------------------
+ begin : Don Sep 12 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef PHRASEBOOKPARSER_H
+#define PHRASEBOOKPARSER_H
+
+#include <qxml.h>
+#include <qvaluestack.h>
+#include "phrasebook.h"
+
+/**
+ * This class implements a parser for both the phrase list and for phrase
+ * books. It is intended to be used together with the Qt SAX2 framework.
+ * @author Gunnar Schmi Dt
+ */
+
+class PhraseBookParser : public QXmlDefaultHandler {
+public:
+ PhraseBookParser();
+ ~PhraseBookParser();
+
+ bool warning (const QXmlParseException &exception);
+ bool error (const QXmlParseException &exception);
+ bool fatalError (const QXmlParseException &exception);
+ QString errorString();
+
+ /** Processes the start of the document. */
+ bool startDocument();
+
+ /** Processes the start tag of an element. */
+ bool startElement (const QString &, const QString &, const QString &name,
+ const QXmlAttributes &attributes);
+
+ /** Processes a chunk of normal character data. */
+ bool characters (const QString &ch);
+
+ /** Processes whitespace. */
+ bool ignorableWhitespace (const QString &ch);
+
+ /** Processes the end tag of an element. */
+ bool endElement (const QString &, const QString &, const QString &name);
+
+ /** Processes the end of the document. */
+ bool endDocument();
+
+ /** returns a list of phrase book entries */
+ PhraseBookEntryList getPhraseList();
+
+private:
+ bool isInPhrase;
+ bool starting;
+ int offset;
+ Phrase phrase;
+
+ PhraseBookEntryList list;
+ int level;
+};
+
+#endif
diff --git a/kmouth/phrasebook/phrasetree.cpp b/kmouth/phrasebook/phrasetree.cpp
new file mode 100644
index 0000000..57d4f5e
--- /dev/null
+++ b/kmouth/phrasebook/phrasetree.cpp
@@ -0,0 +1,556 @@
+/***************************************************************************
+ phrasetree.cpp - description
+ -------------------
+ begin : Don Okt 24 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kaction.h>
+#include <kstdaccel.h>
+#include <kshortcutlist.h>
+#include <kactionshortcutlist.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+
+#include "phrasetree.h"
+#include "phrasebookdialog.h"
+#include "phrasebook.h"
+
+PhraseTreeItem::PhraseTreeItem (QListView *parent, QListViewItem *after, QString phrase, KShortcut shortcut, QPixmap icon)
+ : KListViewItem (parent, after, phrase)
+{
+ isPhraseValue = true;
+ cutValue = shortcut;
+ setText(1, cutValue.toString());
+ setPixmap(0, icon);
+ setExpandable (false);
+}
+
+PhraseTreeItem::PhraseTreeItem (QListViewItem *parent, QListViewItem *after, QString phrase, KShortcut shortcut, QPixmap icon)
+ : KListViewItem (parent, after, phrase)
+{
+ isPhraseValue = true;
+ cutValue = shortcut;
+ setText(1, cutValue.toString());
+ setPixmap(0, icon);
+ setExpandable (false);
+}
+PhraseTreeItem::PhraseTreeItem (QListView *parent, QListViewItem *after, QString name, QPixmap icon)
+ : KListViewItem (parent, after, name)
+{
+ isPhraseValue = false;
+ setPixmap(0, icon);
+ setExpandable (true);
+}
+PhraseTreeItem::PhraseTreeItem (QListViewItem *parent, QListViewItem *after, QString name, QPixmap icon)
+ : KListViewItem (parent, after, name)
+{
+ isPhraseValue = false;
+ setPixmap(0, icon);
+ setExpandable (true);
+}
+bool PhraseTreeItem::isPhrase () {
+ return isPhraseValue;
+}
+KShortcut PhraseTreeItem::cut () {
+ return cutValue;
+}
+void PhraseTreeItem::setCut (KShortcut cut) {
+ cutValue = cut;
+ setText(1, cut.toString());
+}
+
+// ***************************************************************************
+
+PhraseTree::PhraseTree (QWidget *parent, const char *name)
+ : KListView (parent, name)
+{
+ phrasebook_open = KGlobal::iconLoader()->loadIcon("phrasebook", KIcon::Small);
+ phrasebook_closed = KGlobal::iconLoader()->loadIcon("phrasebook_closed", KIcon::Small);
+ phrase = KGlobal::iconLoader()->loadIcon("phrase", KIcon::Small);
+
+ connect (this, SIGNAL(expanded (QListViewItem *)), this, SLOT(itemExpanded (QListViewItem *)));
+ connect (this, SIGNAL(collapsed (QListViewItem *)), this, SLOT(itemCollapsed (QListViewItem *)));
+}
+
+PhraseTree::~PhraseTree (){
+}
+
+namespace PhraseTreePrivate {
+ QListViewItem *prevSibling (QListViewItem *item) {
+ QListViewItem *parent = item->parent();
+ QListViewItem *above = item->itemAbove();
+
+ if (above == parent)
+ return 0;
+
+ while (above->parent() != parent)
+ above = above->parent();
+
+ return above;
+ }
+
+ bool findAbovePosition (QListViewItem *item,
+ QListViewItem **newParent,
+ QListViewItem **newAbove)
+ {
+ if (item == 0)
+ return false;
+
+ QListViewItem *parent = item->parent();
+ QListViewItem *above = item->itemAbove();
+
+ if (above == 0)
+ return false;
+ else if (above == parent) {
+ *newParent = parent->parent();
+ *newAbove = prevSibling (parent);
+ return true;
+ }
+ else if (above->parent() == parent) {
+ *newParent = parent;
+ *newAbove = prevSibling (above);
+ return true;
+ }
+ else {
+ while (above->parent()->parent() != parent)
+ above = above->parent();
+ *newParent = above->parent();
+ *newAbove = above;
+ return true;
+ }
+ }
+
+ bool findBelowPosition (QListViewItem *item,
+ QListViewItem **newParent,
+ QListViewItem **newAbove)
+ {
+ if (item == 0)
+ return false;
+
+ QListViewItem *parent = item->parent();
+ QListViewItem *below = item->nextSibling();
+
+ if (parent == 0 && below == 0)
+ return false;
+ else if (parent != 0 && below == 0) {
+ *newParent = parent->parent();
+ *newAbove = parent;
+ return true;
+ }
+ else if (below->isOpen()) {
+ *newParent = below;
+ *newAbove = 0;
+ return true;
+ }
+ else {
+ *newParent = parent;
+ *newAbove = below;
+ return true;
+ }
+ }
+
+ bool findRightPosition (QListViewItem *item,
+ QListViewItem **newParent,
+ QListViewItem **newAbove)
+ {
+ if (item == 0)
+ return false;
+
+ QListViewItem *above = prevSibling (item);
+
+ if (above == 0)
+ return false;
+ else if (((PhraseTreeItem *)above)->isPhrase())
+ return false;
+ else {
+ above->setOpen(true);
+ *newParent = above;
+ *newAbove = 0;
+ above = (*newParent)->firstChild();
+ while (above != 0) {
+ *newAbove = above;
+ above = above->nextSibling();
+ }
+ return true;
+ }
+ }
+
+ bool findLeftPosition (QListViewItem *item,
+ QListViewItem **newParent,
+ QListViewItem **newAbove)
+ {
+ if (item == 0)
+ return false;
+
+ QListViewItem *parent = item->parent();
+
+ if (parent == 0)
+ return false;
+ else {
+ *newParent = parent->parent();
+ *newAbove = parent;
+ return true;
+ }
+ }
+}
+
+void PhraseTree::moveItem (QListViewItem *item,
+ QListViewItem *parent,
+ QListViewItem *above)
+{
+ if (item != 0) {
+ if (item->parent() == 0)
+ takeItem (item);
+ else
+ item->parent()->takeItem (item);
+
+ if (parent == 0)
+ insertItem (item);
+ else
+ parent->insertItem (item);
+
+ item->moveItem(above);
+ }
+}
+
+bool PhraseTree::hasSelectedItems() {
+ QListViewItem *i = firstChild();
+ if ( !i )
+ return false;
+ int level = 0;
+ do {
+ if (i->isSelected())
+ return true;
+
+ if (i->firstChild() != 0) {
+ i = i->firstChild();
+ level++;
+ }
+ else {
+ while ((i != 0) && (i->nextSibling() == 0)) {
+ i = i->parent();
+ level--;
+ }
+ if (i != 0)
+ i = i->nextSibling();
+ }
+ }
+ while (i != 0);
+
+ return false;
+}
+
+void PhraseTree::deleteSelectedItems() {
+ QListViewItem *i = firstChild();
+ if ( !i )
+ return;
+ QListViewItem *deleteItem = 0;
+ do {
+ if (i->isSelected())
+ deleteItem = i;
+
+ if ((i->firstChild() != 0) && (!i->isSelected())) {
+ i = i->firstChild();
+ }
+ else {
+ while ((i != 0) && (i->nextSibling() == 0)) {
+ i = i->parent();
+ }
+ if (i != 0)
+ i = i->nextSibling();
+ }
+ if (deleteItem != 0) {
+ delete deleteItem;
+ deleteItem = 0;
+ }
+ }
+ while (i != 0);
+}
+
+void PhraseTree::keyPressEvent (QKeyEvent *e) {
+ if ((e->state() & Qt::KeyButtonMask) == Qt::AltButton) {
+ if (e->key() == Qt::Key_Up) {
+ QListViewItem *item = currentItem();
+ if ((item != 0) && (item->isSelected())) {
+ QListViewItem *parent;
+ QListViewItem *above;
+
+ if (PhraseTreePrivate::findAbovePosition (item, &parent, &above)) {
+ moveItem(item, parent, above);
+ setCurrentItem (item);
+ item->setSelected(true);
+ }
+ }
+ e->accept();
+ return;
+ }
+ else if (e->key() == Qt::Key_Down) {
+ QListViewItem *item = currentItem();
+ if ((item != 0) && (item->isSelected())) {
+ QListViewItem *parent;
+ QListViewItem *above;
+
+ if (PhraseTreePrivate::findBelowPosition (item, &parent, &above)) {
+ moveItem(item, parent, above);
+ setCurrentItem (item);
+ item->setSelected(true);
+ }
+ }
+ e->accept();
+ return;
+ }
+ else if (e->key() == Qt::Key_Left) {
+ QListViewItem *item = currentItem();
+ if ((item != 0) && (item->isSelected())) {
+ QListViewItem *parent;
+ QListViewItem *above;
+
+ if (PhraseTreePrivate::findLeftPosition (item, &parent, &above)) {
+ moveItem(item, parent, above);
+ setCurrentItem (item);
+ item->setSelected(true);
+ }
+ }
+ e->accept();
+ return;
+ }
+ else if (e->key() == Qt::Key_Right) {
+ QListViewItem *item = currentItem();
+ if ((item != 0) && (item->isSelected())) {
+ QListViewItem *parent;
+ QListViewItem *above;
+
+ if (PhraseTreePrivate::findRightPosition (item, &parent, &above)) {
+ moveItem(item, parent, above);
+ setCurrentItem (item);
+ item->setSelected(true);
+ }
+ }
+ e->accept();
+ return;
+ }
+ }
+ KListView::keyPressEvent(e);
+}
+
+PhraseTreeItem *PhraseTree::insertPhrase (QListViewItem *parent, QListViewItem *after, QString phrase, QString shortcut) {
+ KShortcut cut = KShortcut(shortcut);
+ if (isKeyPresent (cut, 0, false))
+ cut = KShortcut(QString::null);
+
+ if (parent == 0)
+ return new PhraseTreeItem (this, after, phrase, cut, this->phrase);
+ else
+ return new PhraseTreeItem (parent, after, phrase, cut, this->phrase);
+}
+
+PhraseTreeItem *PhraseTree::insertBook (QListViewItem *parent, QListViewItem *after, QString name) {
+ if (parent == 0)
+ return new PhraseTreeItem (this, after, name, phrasebook_closed);
+ else
+ return new PhraseTreeItem (parent, after, name, phrasebook_closed);
+}
+
+QListViewItem *PhraseTree::addBook (QListViewItem *parent, QListViewItem *after, PhraseBook *book) {
+ QListViewItem *last = after;
+ int level = 0;
+ PhraseBookEntryList::iterator it;
+ for (it = book->begin(); it != book->end(); ++it) {
+ int newLevel = (*it).getLevel();
+ while (level < newLevel) {
+ parent = insertBook(parent, last, "");
+ last = 0;
+ level++;
+ }
+ while (level > newLevel) {
+ last = parent;
+ if (parent != 0)
+ parent = parent->parent();
+ level--;
+ }
+
+ if ((*it).isPhrase()) {
+ Phrase phrase = (*it).getPhrase();
+ last = insertPhrase (parent, last, phrase.getPhrase(), phrase.getShortcut());
+ }
+ else {
+ Phrase phrase = (*it).getPhrase();
+ parent = insertBook(parent, last, phrase.getPhrase());
+ last = 0;
+ level++;
+ }
+ }
+ while (level > 0) {
+ last = parent;
+ if (parent != 0)
+ parent = parent->parent();
+ level--;
+ }
+ return last;
+}
+
+void PhraseTree::fillBook (PhraseBook *book, bool respectSelection) {
+ QListViewItem *i = firstChild();
+ int level = 0;
+ if ( !i )
+ return;
+ do {
+ if (i->isSelected() || !respectSelection || level > 0) {
+ PhraseTreeItem *it = (PhraseTreeItem *)i;
+ Phrase phrase(it->text(0), it->cut().toStringInternal());
+ *book += PhraseBookEntry(phrase, level, it->isPhrase());
+ }
+
+ if (i->firstChild() != 0) {
+ if (i->isSelected() || !respectSelection || level > 0)
+ level++;
+ i = i->firstChild();
+ }
+ else {
+ while ((i != 0) && (i->nextSibling() == 0)) {
+ i = i->parent();
+ if (level > 0)
+ level--;
+ }
+ if (i != 0)
+ i = i->nextSibling();
+ }
+ }
+ while (i != 0);
+}
+
+QDragObject *PhraseTree::dragObject () {
+ return dragObject (true);
+}
+
+QDragObject *PhraseTree::dragObject (bool isDependent) {
+ PhraseBook book;
+ fillBook (&book, true);
+ if (isDependent)
+ return new PhraseBookDrag(&book, viewport());
+ return new PhraseBookDrag(&book);
+}
+
+bool PhraseTree::acceptDrag (QDropEvent* event) const {
+ if (KListView::acceptDrag (event))
+ return true;
+ else
+ return PhraseBookDrag::canDecode(event);
+}
+
+// Returns iSeq index if cut2 has a sequence of equal or higher priority
+// to a sequence in cut, else -1
+static int keyConflict (const KShortcut& cut, const KShortcut& cut2) {
+ for (uint iSeq = 0; iSeq < cut.count(); iSeq++) {
+ for (uint iSeq2 = 0; iSeq2 <= iSeq && iSeq2 < cut2.count(); iSeq2++) {
+ if (cut.seq(iSeq) == cut2.seq(iSeq2))
+ return iSeq;
+ }
+ }
+ return -1;
+}
+
+void PhraseTree::_warning (const KKeySequence& cut, QString sAction, QString sTitle) {
+ sAction = sAction.stripWhiteSpace();
+
+ QString s =
+ i18n("The '%1' key combination has already been allocated "
+ "to %2.\n"
+ "Please choose a unique key combination.").
+ arg(cut.toString()).arg(sAction);
+
+ KMessageBox::sorry( this, s, sTitle );
+}
+
+bool PhraseTree::isStdAccelPresent (const KShortcut& cut, bool warnUser) {
+ for (uint iSeq = 0; iSeq < cut.count(); iSeq++) {
+ const KKeySequence& seq = cut.seq(iSeq);
+
+ KStdAccel::StdAccel id = KStdAccel::findStdAccel( seq );
+ if( id != KStdAccel::AccelNone
+ && keyConflict (cut, KStdAccel::shortcut(id)) > -1)
+ {
+ if (warnUser)
+ _warning (cut.seq(iSeq),
+ i18n("the standard \"%1\" action").arg(KStdAccel::label(id)),
+ i18n("Conflict with Standard Application Shortcut"));
+ return true;
+ }
+ }
+ return false;
+}
+
+bool PhraseTree::isGlobalKeyPresent (const KShortcut& cut, bool warnUser) {
+ QMap<QString, QString> mapEntry = KGlobal::config()->entryMap ("Global Shortcuts");
+ QMap<QString, QString>::Iterator it;
+ for (it = mapEntry.begin(); it != mapEntry.end(); ++it) {
+ int iSeq = keyConflict (cut, KShortcut(*it));
+ if (iSeq > -1) {
+ if (warnUser)
+ _warning (cut.seq(iSeq),
+ i18n("the global \"%1\" action").arg(it.key()),
+ i18n("Conflict with Global Shortcuts"));
+ return true;
+ }
+ }
+ return false;
+}
+
+bool PhraseTree::isPhraseKeyPresent (const KShortcut& cut, PhraseTreeItem* cutItem, bool warnUser) {
+ for (QListViewItemIterator it(this); it.current(); ++it) {
+ PhraseTreeItem* item = dynamic_cast<PhraseTreeItem*>(it.current());
+ if ((item != 0) && (item != cutItem)) {
+ int iSeq = keyConflict (cut, item->cut());
+ if (iSeq > -1) {
+ if (warnUser)
+ _warning (cut.seq(iSeq),
+ i18n("an other phrase"),
+ i18n("Key Conflict"));
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool PhraseTree::isKeyPresent (const KShortcut& cut, PhraseTreeItem* cutItem, bool warnUser) {
+ if (isStdAccelPresent (cut, warnUser))
+ return true;
+
+ if (isGlobalKeyPresent (cut, warnUser))
+ return true;
+
+ if (isPhraseKeyPresent (cut, cutItem, warnUser))
+ return true;
+
+ return false;
+}
+
+void PhraseTree::itemExpanded (QListViewItem *item) {
+ PhraseTreeItem *i = (PhraseTreeItem *)item;
+ if (!i->isPhrase())
+ i->setPixmap(0, phrasebook_open);
+}
+
+void PhraseTree::itemCollapsed (QListViewItem *item) {
+ PhraseTreeItem *i = (PhraseTreeItem *)item;
+ if (!i->isPhrase())
+ i->setPixmap(0, phrasebook_closed);
+}
+
+// ***************************************************************************
+
+#include "phrasetree.moc"
diff --git a/kmouth/phrasebook/phrasetree.h b/kmouth/phrasebook/phrasetree.h
new file mode 100644
index 0000000..bd0e1f5
--- /dev/null
+++ b/kmouth/phrasebook/phrasetree.h
@@ -0,0 +1,108 @@
+/***************************************************************************
+ phrasetree.h - description
+ -------------------
+ begin : Don Okt 24 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef PHRASETREE_H
+#define PHRASETREE_H
+
+#include <qpixmap.h>
+#include <kshortcut.h>
+#include <klistview.h>
+
+class PhraseBook;
+class PhraseShortcutRequest;
+
+/**The class PhraseTreeItem is an ListViewItem for either a phrase or a phrase book.
+ *@author Gunnar Schmi Dt
+ */
+
+class PhraseTreeItem : public KListViewItem {
+ friend class PhraseTree;
+private:
+ /** Creates a phrase item within a sub phrase book */
+ PhraseTreeItem (QListView *parent, QListViewItem *after, QString phrase, KShortcut shortcut, QPixmap icon);
+ /** Creates a phrase item at the top level */
+ PhraseTreeItem (QListViewItem *parent, QListViewItem *after, QString phrase, KShortcut shortcut, QPixmap icon);
+ /** Creates a phrase book item within a sub phrase book */
+ PhraseTreeItem (QListView *parent, QListViewItem *after, QString name, QPixmap icon);
+ /** Creates a phrase book item at the top level */
+ PhraseTreeItem (QListViewItem *parent, QListViewItem *after, QString name, QPixmap icon);
+
+public:
+ bool isPhrase();
+ KShortcut cut();
+ void setCut(KShortcut cut);
+
+private:
+ bool isPhraseValue;
+ KShortcut cutValue;
+};
+
+/**
+ * The class PhraseTree represents the ListView of the phrase book edit
+ * dialog. It extends KListView for providing better drag-and-drop support.
+ * @author Gunnar Schmi Dt
+ */
+
+class PhraseTree : public KListView {
+ friend class PhraseTreeItem;
+ Q_OBJECT
+public:
+ PhraseTree (QWidget *parent = 0, const char *name = 0);
+ ~PhraseTree ();
+
+ void keyPressEvent (QKeyEvent *e);
+
+ PhraseTreeItem *insertPhrase (QListViewItem *parent, QListViewItem *after, QString phrase, QString shortcut);
+ PhraseTreeItem *insertBook (QListViewItem *parent, QListViewItem *after, QString name);
+
+ QListViewItem *addBook (QListViewItem *parent, QListViewItem *after, PhraseBook *book);
+ void fillBook (PhraseBook *book, bool respectSelection);
+
+ QDragObject *dragObject ();
+ QDragObject *dragObject (bool isDependent);
+
+ void moveItem (QListViewItem *item, QListViewItem *parent, QListViewItem *above);
+
+ bool hasSelectedItems();
+ void deleteSelectedItems();
+
+protected:
+ bool acceptDrag (QDropEvent* event) const;
+
+private:
+ void _warning (const KKeySequence& cut, QString sAction, QString sTitle);
+ bool isStdAccelPresent (const KShortcut& cut, bool warnUser);
+ bool isGlobalKeyPresent (const KShortcut& cut, bool warnUser);
+ bool isApplicationKeyPresent (const KShortcut& cut, bool warnUser);
+ bool isPhraseKeyPresent (const KShortcut& cut, PhraseTreeItem* cutItem, bool warnUser);
+public:
+ bool isKeyPresent (const KShortcut& cut, PhraseTreeItem* cutItem, bool warnUser);
+
+public slots:
+ void itemExpanded (QListViewItem *item);
+ void itemCollapsed (QListViewItem *item);
+
+signals:
+ void shortcutRequest (PhraseShortcutRequest *request);
+
+private:
+ QPixmap phrasebook_open;
+ QPixmap phrasebook_closed;
+ QPixmap phrase;
+};
+
+#endif
diff --git a/kmouth/phraseedit.cpp b/kmouth/phraseedit.cpp
new file mode 100644
index 0000000..0f2e319
--- /dev/null
+++ b/kmouth/phraseedit.cpp
@@ -0,0 +1,57 @@
+/***************************************************************************
+ phraseedit.cpp - description
+ -------------------
+ begin : Don Sep 26 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "phraseedit.h"
+
+PhraseEdit::PhraseEdit(const QString &string, QWidget *parent)
+ : KLineEdit (string, parent) {
+}
+
+PhraseEdit::~PhraseEdit() {
+}
+
+void PhraseEdit::keyPressEvent (QKeyEvent *e) {
+ if ((e->state() & Qt::KeyButtonMask) == Qt::ControlButton) {
+ if (e->key() == Qt::Key_C) {
+ if (!this->hasSelectedText()) {
+ e->ignore();
+ return;
+ }
+ }
+ else if (e->key() == Qt::Key_Insert) {
+ if (!hasSelectedText()) {
+ e->ignore();
+ return;
+ }
+ }
+ else if (e->key() == Qt::Key_X) {
+ if (!hasSelectedText()) {
+ e->ignore();
+ return;
+ }
+ }
+ }
+ else if ((e->state() & Qt::KeyButtonMask) == Qt::ShiftButton) {
+ if (e->key() == Qt::Key_Delete) {
+ if (!hasSelectedText()) {
+ e->ignore();
+ return;
+ }
+ }
+ }
+ KLineEdit::keyPressEvent(e);
+}
diff --git a/kmouth/phraseedit.h b/kmouth/phraseedit.h
new file mode 100644
index 0000000..a7a065e
--- /dev/null
+++ b/kmouth/phraseedit.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ phraseedit.h - description
+ -------------------
+ begin : Don Sep 26 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef PHRASEEDIT_H
+#define PHRASEEDIT_H
+
+#include <klineedit.h>
+
+/**
+ * This class extends a KLineEdit by consuming fewer unused key presses.
+ *@author Gunnar Schmi Dt
+ */
+
+class PhraseEdit : public KLineEdit {
+public:
+ PhraseEdit(const QString &string, QWidget *parent);
+ virtual ~PhraseEdit();
+
+ void keyPressEvent (QKeyEvent *e);
+};
+
+#endif
diff --git a/kmouth/phraselist.cpp b/kmouth/phraselist.cpp
new file mode 100644
index 0000000..d57682a
--- /dev/null
+++ b/kmouth/phraselist.cpp
@@ -0,0 +1,478 @@
+/***************************************************************************
+ phraselist.cpp - description
+ -------------------
+ begin : Mit Sep 11 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// include files for Qt
+#include <qprinter.h>
+#include <qpainter.h>
+#include <qlayout.h>
+#include <qwhatsthis.h>
+#include <qpopupmenu.h>
+#include <qclipboard.h>
+
+// include files for KDE
+#include <klistbox.h>
+#include <klineedit.h>
+#include <kaudioplayer.h>
+#include <kcursor.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kfiledialog.h>
+#include <kcombobox.h>
+#include <kmessagebox.h>
+
+#include <stdlib.h>
+
+// application specific includes
+#include "phraselistitem.h"
+#include "phraselist.h"
+#include "phraseedit.h"
+#include "kmouth.h"
+#include "texttospeechsystem.h"
+#include "phrasebook/phrasebook.h"
+#include "wordcompletion/wordcompletion.h"
+
+PhraseList::PhraseList(QWidget *parent, const char *name) : QWidget(parent,name) {
+ isInSlot = false;
+ setBackgroundMode(PaletteBase);
+ QVBoxLayout *layout = new QVBoxLayout (this);
+
+ listBox = new KListBox (this);
+ listBox->setFocusPolicy(QWidget::NoFocus);
+ listBox->setSelectionMode (QListBox::Extended);
+ QWhatsThis::add (listBox, i18n("This list contains the history of spoken sentences. You can select sentences and press the speak button for re-speaking."));
+ layout->addWidget(listBox);
+
+ QHBoxLayout *rowLayout = new QHBoxLayout ();
+ layout->addLayout(rowLayout);
+
+ completion = new WordCompletion();
+
+ dictionaryCombo = new KComboBox (this, "Dictionary Combo");
+ configureCompletionCombo(completion->wordLists());
+ rowLayout->addWidget(dictionaryCombo);
+
+ lineEdit = new PhraseEdit ("", this);
+ lineEdit->setFocusPolicy(QWidget::StrongFocus);
+ lineEdit->setFrame(true);
+ lineEdit->setEchoMode(QLineEdit::Normal);
+ lineEdit->setCompletionObject (completion);
+ lineEdit->setAutoDeleteCompletionObject(true);
+ 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."));
+ rowLayout->addWidget(lineEdit);
+ lineEdit->setFocus();
+
+ QIconSet icon = KGlobal::iconLoader()->loadIconSet("speak", KIcon::Small);
+ speakButton = new QPushButton (icon, i18n("&Speak"), this);
+ speakButton->setFocusPolicy(QWidget::NoFocus);
+ speakButton->setAutoDefault(false);
+ 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."));
+ rowLayout->addWidget(speakButton);
+
+ connect(dictionaryCombo, SIGNAL (activated (const QString &)), completion, SLOT (setWordList(const QString &)));
+ connect(completion, SIGNAL (wordListsChanged (const QStringList &)), this, SLOT (configureCompletionCombo (const QStringList &)));
+ connect(listBox, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
+ connect(listBox, SIGNAL(contextMenuRequested (QListBoxItem *, const QPoint &)), SLOT(contextMenuRequested (QListBoxItem *, const QPoint &)));
+ connect(lineEdit, SIGNAL(returnPressed(const QString &)), SLOT(lineEntered(const QString &)));
+ connect(lineEdit, SIGNAL(textChanged (const QString &)), SLOT(textChanged(const QString &)));
+ connect(speakButton, SIGNAL( clicked ()), SLOT(speak()));
+}
+
+PhraseList::~PhraseList() {
+ delete speakButton;
+ delete listBox;
+ delete lineEdit;
+}
+
+void PhraseList::print(KPrinter *pPrinter) {
+ PhraseBook book;
+ for (QListBoxItem *item = listBox->firstItem(); item != 0; item = item->next()) {
+ book += PhraseBookEntry(Phrase(item->text()));
+ }
+
+ book.print (pPrinter);
+}
+
+QStringList PhraseList::getListSelection() {
+ QStringList res = QStringList();
+
+ for (QListBoxItem *item = listBox->firstItem(); item != 0; item = item->next()) {
+ if (item->isSelected())
+ res += item->text();
+ }
+
+ return res;
+}
+
+bool PhraseList::existListSelection() {
+ for (QListBoxItem *item = listBox->firstItem(); item != 0; item = item->next()) {
+ if (item->isSelected())
+ return true;
+ }
+
+ return false;
+}
+
+bool PhraseList::existEditSelection() {
+ return lineEdit->hasSelectedText();
+}
+
+void PhraseList::enableMenuEntries() {
+ bool deselected = false;
+ bool selected = false;
+ for (QListBoxItem *item = listBox->firstItem(); item != 0; item = item->next()) {
+ if (item->isSelected())
+ selected = true;
+ else
+ deselected = true;
+ }
+ KMouthApp *theApp=(KMouthApp *) parentWidget();
+ theApp->enableMenuEntries (selected, deselected);
+}
+
+void PhraseList::configureCompletion() {
+ completion->configure();
+}
+
+void PhraseList::configureCompletionCombo(const QStringList &list) {
+ QString current = completion->currentWordList();
+ dictionaryCombo->clear();
+ if (list.isEmpty())
+ dictionaryCombo->hide();
+ else if (list.count() == 1) {
+ dictionaryCombo->insertStringList (list);
+ dictionaryCombo->setCurrentItem (0);
+ dictionaryCombo->hide();
+ }
+ else {
+ dictionaryCombo->insertStringList (list);
+ dictionaryCombo->show();
+
+ QStringList::ConstIterator it;
+ int i = 0;
+ for (it = list.begin(), i = 0; it != list.end(); ++it, ++i) {
+ if (current == *it) {
+ dictionaryCombo->setCurrentItem (i);
+ return;
+ }
+ }
+ }
+}
+
+void PhraseList::saveCompletionOptions(KConfig *config) {
+ config->setGroup("General Options");
+ config->writeEntry("Show speak button", speakButton->isVisible() || !lineEdit->isVisible());
+
+ config->setGroup("Completion");
+ config->writeEntry("Mode", static_cast<int>(lineEdit->completionMode()));
+ config->writeEntry("List", completion->currentWordList());
+}
+
+void PhraseList::readCompletionOptions(KConfig *config) {
+ config->setGroup("General Options");
+ if (!config->readBoolEntry("Show speak button", true))
+ speakButton->hide();
+
+ if (config->hasGroup ("Completion")) {
+ config->setGroup("Completion");
+ int mode = config->readNumEntry ("Mode", KGlobalSettings::completionMode());
+ lineEdit->setCompletionMode (static_cast<KGlobalSettings::Completion>(mode));
+
+ QString current = config->readEntry ("List", QString::null);
+ QStringList list = completion->wordLists();
+ QStringList::ConstIterator it;
+ int i = 0;
+ for (it = list.begin(), i = 0; it != list.end(); ++it, ++i) {
+ if (current == *it) {
+ dictionaryCombo->setCurrentItem (i);
+ return;
+ }
+ }
+ }
+}
+
+void PhraseList::saveWordCompletion () {
+ completion->save();
+}
+
+
+void PhraseList::selectAllEntries () {
+ listBox->selectAll (true);
+}
+
+void PhraseList::deselectAllEntries () {
+ listBox->selectAll (false);
+}
+
+void PhraseList::speak () {
+ QString phrase = lineEdit->text();
+ if (phrase.isNull() || phrase.isEmpty())
+ speakListSelection();
+ else {
+ insertIntoPhraseList (phrase, true);
+ speakPhrase (phrase);
+ }
+}
+
+void PhraseList::cut() {
+ if (lineEdit->hasSelectedText())
+ lineEdit->cut();
+ else
+ cutListSelection();
+}
+
+void PhraseList::copy() {
+ if (lineEdit->hasSelectedText())
+ lineEdit->copy();
+ else
+ copyListSelection();
+}
+
+void PhraseList::paste() {
+ lineEdit->paste();
+}
+
+void PhraseList::insert (const QString &s) {
+ setEditLineText(s);
+}
+
+void PhraseList::speakListSelection () {
+ speakPhrase(getListSelection().join ("\n"));
+}
+
+void PhraseList::removeListSelection () {
+ QListBoxItem *next;
+ for (QListBoxItem *item = listBox->firstItem(); item != 0; item = next) {
+ next = item->next();
+
+ if (item->isSelected()) {
+ listBox->removeItem(listBox->index(item));
+ }
+ }
+ enableMenuEntries ();
+}
+
+void PhraseList::cutListSelection () {
+ copyListSelection ();
+ removeListSelection ();
+}
+
+void PhraseList::copyListSelection () {
+ QApplication::clipboard()->setText (getListSelection().join ("\n"));
+}
+
+void PhraseList::lineEntered (const QString &phrase) {
+ if (phrase.isNull() || phrase.isEmpty())
+ speakListSelection();
+ else {
+ insertIntoPhraseList (phrase, true);
+ speakPhrase (phrase);
+ }
+}
+
+void PhraseList::speakPhrase (const QString &phrase) {
+ QApplication::setOverrideCursor (KCursor::WaitCursor, false);
+ KMouthApp *theApp=(KMouthApp *) parentWidget();
+ QString language = completion->languageOfWordList (completion->currentWordList());
+ theApp->getTTSSystem()->speak(phrase, language);
+ QApplication::restoreOverrideCursor ();
+}
+
+void PhraseList::insertIntoPhraseList (const QString &phrase, bool clearEditLine) {
+ int lastLine = listBox->count() - 1;
+ if ((lastLine == -1) || (phrase != listBox->text(lastLine))) {
+ listBox->insertItem(new PhraseListItem(phrase));
+ if (clearEditLine)
+ completion->addSentence (phrase);
+ }
+
+ if (clearEditLine) {
+ lineEdit->selectAll();
+ line = "";
+ }
+ enableMenuEntries ();
+}
+
+void PhraseList::contextMenuRequested (QListBoxItem *, const QPoint &pos) {
+ QString name;
+ if (existListSelection())
+ name = "phraselist_selection_popup";
+ else
+ name = "phraselist_popup";
+
+ KMouthApp *theApp=(KMouthApp *) parentWidget();
+ KXMLGUIFactory *factory = theApp->factory();
+ QPopupMenu *popup = (QPopupMenu *)factory->container(name,theApp);
+ if (popup != 0) {
+ popup->popup(pos, 0);
+ }
+}
+
+void PhraseList::textChanged (const QString &s) {
+ if (!isInSlot) {
+ isInSlot = true;
+ line = s;
+ listBox->setCurrentItem (listBox->count() - 1);
+ listBox->clearSelection ();
+ isInSlot = false;
+ }
+}
+
+void PhraseList::selectionChanged () {
+ if (!isInSlot) {
+ isInSlot = true;
+
+ QStringList sel = getListSelection();
+
+ if (sel.empty())
+ setEditLineText(line);
+ else if (sel.count() == 1)
+ setEditLineText(sel.first());
+ else {
+ setEditLineText("");
+ }
+ isInSlot = false;
+ }
+ enableMenuEntries ();
+}
+
+void PhraseList::setEditLineText(const QString &s) {
+ lineEdit->end(false);
+ while (!(lineEdit->text().isNull() || lineEdit->text().isEmpty()))
+ lineEdit->backspace();
+ lineEdit->insert(s);
+}
+
+void PhraseList::keyPressEvent (QKeyEvent *e) {
+ if (e->key() == Qt::Key_Up) {
+ bool selected = false;
+ for (QListBoxItem *item = listBox->firstItem(); item != 0; item = item->next()) {
+ if (item->isSelected()) {
+ selected = true;
+ }
+ }
+
+ if (!selected) {
+ listBox->setCurrentItem (listBox->count() - 1);
+ listBox->setSelected (listBox->count() - 1, true);
+ listBox->ensureCurrentVisible ();
+ }
+ else {
+ int curr = listBox->currentItem();
+
+ if (curr == -1) {
+ isInSlot = true;
+ listBox->clearSelection();
+ isInSlot = false;
+ curr = listBox->count() - 1;
+ listBox->setCurrentItem (curr);
+ listBox->setSelected (curr, true);
+ listBox->ensureCurrentVisible ();
+ }
+ else if (curr != 0) {
+ isInSlot = true;
+ listBox->clearSelection();
+ isInSlot = false;
+ listBox->setCurrentItem (curr - 1);
+ listBox->setSelected (curr - 1, true);
+ listBox->ensureCurrentVisible ();
+ }
+ }
+
+ e->accept();
+ }
+ else if (e->key() == Qt::Key_Down) {
+ bool selected = false;
+ for (QListBoxItem *item = listBox->firstItem(); item != 0; item = item->next()) {
+ if (item->isSelected()) {
+ selected = true;
+ }
+ }
+
+ if (selected) {
+ int curr = listBox->currentItem();
+
+ if (curr == (int)listBox->count() - 1) {
+ listBox->clearSelection();
+ }
+ else if (curr != -1) {
+ isInSlot = true;
+ listBox->clearSelection();
+ isInSlot = false;
+ listBox->setCurrentItem (curr + 1);
+ listBox->setSelected (curr + 1, true);
+ listBox->ensureCurrentVisible ();
+ }
+ }
+ e->accept();
+ }
+ else if ((e->state() & Qt::KeyButtonMask) == Qt::ControlButton) {
+ if (e->key() == Qt::Key_C) {
+ copy();
+ e->accept();
+ }
+ else if (e->key() == Qt::Key_X) {
+ cut();
+ e->accept();
+ }
+ }
+ else
+ e->ignore();
+}
+
+void PhraseList::save () {
+ // We want to save a history of spoken sentences here. However, as
+ // the class PhraseBook does already provide a method for saving
+ // phrase books in both the phrase book format and plain text file
+ // format we use that method here.
+
+ PhraseBook book;
+ for (QListBoxItem *item = listBox->firstItem(); item != 0; item = item->next()) {
+ book += PhraseBookEntry(Phrase(item->text()));
+ }
+
+ KURL url;
+ if (book.save (this, i18n("Save As"), url, false) == -1)
+ KMessageBox::sorry(this,i18n("There was an error saving file\n%1").arg( url.url() ));
+}
+
+void PhraseList::open () {
+ KURL url=KFileDialog::getOpenURL(QString::null,
+ i18n("*|All Files\n*.phrasebook|Phrase Books (*.phrasebook)\n*.txt|Plain Text Files (*.txt)"), this, i18n("Open File as History"));
+
+ if(!url.isEmpty())
+ open (url);
+}
+
+void PhraseList::open (KURL url) {
+ // We want to open a history of spoken sentences here. However, as
+ // the class PhraseBook does already provide a method for opening
+ // both phrase books and plain text files we use that method here.
+
+ PhraseBook book;
+ if (book.open (url)) {
+ // convert PhraseBookEntryList -> QStringList
+ QStringList list = book.toStringList();
+ listBox->clear();
+ QStringList::iterator it;
+ for (it = list.begin(); it != list.end(); ++it)
+ insertIntoPhraseList (*it, false);
+ }
+ else
+ KMessageBox::sorry(this,i18n("There was an error loading file\n%1").arg( url.url() ));
+}
+
+#include "phraselist.moc"
diff --git a/kmouth/phraselist.h b/kmouth/phraselist.h
new file mode 100644
index 0000000..7f56306
--- /dev/null
+++ b/kmouth/phraselist.h
@@ -0,0 +1,110 @@
+/***************************************************************************
+ phraselist.h - description
+ -------------------
+ begin : Mon Aug 26 15:41:23 CEST 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef PHRASELIST_H
+#define PHRASELIST_H
+
+// include files for KDE
+#include <klistbox.h>
+#include <klineedit.h>
+#include <kprinter.h>
+
+// include files for Qt
+#include <qwidget.h>
+#include <qpushbutton.h>
+
+class WordCompletion;
+
+/**
+ * This class represents a phrase list. It contains methods for manipulating
+ * the phraselist and also methods for viewing the list.
+ * The phrase list consists of an edit field for entering phrases and a list
+ * box for the spoken phrases.
+ *
+ * @author Gunnar Schmi Dt
+ */
+
+class PhraseList : public QWidget {
+ Q_OBJECT
+public:
+ PhraseList(QWidget *parent=0, const char *name=0);
+ ~PhraseList();
+
+ /** contains the implementation for printing functionality */
+ void print(KPrinter *pPrinter);
+
+ QStringList getListSelection();
+
+ bool existListSelection();
+ bool existEditSelection();
+
+public slots:
+ /** Called whenever the user wants the contents of the edit line to be spoken. */
+ void speak ();
+
+ void cut();
+ void copy();
+ void paste();
+
+ /** Insert s into the edit field. */
+ void insert (const QString &s);
+
+ /** Called whenever the user wants the selected list entries to be spoken. */
+ void speakListSelection ();
+
+ void removeListSelection ();
+ void cutListSelection ();
+ void copyListSelection ();
+
+ void save ();
+ void open ();
+ void open (KURL url);
+
+ void selectAllEntries ();
+ void deselectAllEntries ();
+
+ void configureCompletion();
+ void saveWordCompletion();
+ void saveCompletionOptions(KConfig *config);
+ void readCompletionOptions(KConfig *config);
+
+protected slots:
+ void lineEntered (const QString &phrase);
+ void contextMenuRequested (QListBoxItem *, const QPoint &pos);
+ void textChanged (const QString &s);
+ void selectionChanged ();
+ void keyPressEvent (QKeyEvent *e);
+ void configureCompletionCombo(const QStringList &list);
+
+private:
+ KListBox *listBox;
+ KComboBox *dictionaryCombo;
+ KLineEdit *lineEdit;
+ QPushButton *speakButton;
+ QString line;
+ WordCompletion *completion;
+
+ bool isInSlot;
+
+ void speakPhrase (const QString &phrase);
+ void setEditLineText(const QString &s);
+ void insertIntoPhraseList (const QString &phrase, bool clearEditLine);
+
+ void enableMenuEntries ();
+};
+
+#endif
diff --git a/kmouth/phraselistitem.cpp b/kmouth/phraselistitem.cpp
new file mode 100644
index 0000000..6156054
--- /dev/null
+++ b/kmouth/phraselistitem.cpp
@@ -0,0 +1,52 @@
+/***************************************************************************
+ phraselistitem.cpp - description
+ -------------------
+ begin : Fre Sep 6 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "phraselistitem.h"
+#include <qstyle.h>
+#include <qpainter.h>
+
+PhraseListItem::PhraseListItem (const QString & text)
+ : QListBoxText::QListBoxText(text) {
+}
+
+PhraseListItem::~PhraseListItem() {
+}
+
+bool PhraseListItem::drawCursor() const {
+ if ((QListBoxItem *)this != listBox()->item (listBox()->currentItem()))
+ return false;
+
+ for (QListBoxItem *item = listBox()->firstItem(); item != 0; item = item->next() ) {
+ if (item->isSelected())
+ return true;
+ }
+ return false;
+}
+
+int PhraseListItem::rtti() const {
+ return RTTI;
+}
+
+void PhraseListItem::paint (QPainter *p) {
+ QListBoxText::paint (p);
+
+ if (drawCursor()) {
+ QRect r (0, 0, listBox()->maxItemWidth(), height (listBox()));
+ listBox()->style().drawPrimitive (QStyle::PE_FocusRect, p, r,
+ listBox()->colorGroup());
+ }
+}
diff --git a/kmouth/phraselistitem.h b/kmouth/phraselistitem.h
new file mode 100644
index 0000000..24d5e49
--- /dev/null
+++ b/kmouth/phraselistitem.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ phraselistitem.h - description
+ -------------------
+ begin : Fre Sep 6 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef PHRASELISTITEM_H
+#define PHRASELISTITEM_H
+
+#include <qlistbox.h>
+
+/**
+ * This class represents a phrase in the list of spoken phrases. It extends
+ * QListBoxText for providing support for a visible list cursor.
+ * @author Gunnar Schmi Dt
+ */
+
+class PhraseListItem : public QListBoxText {
+public:
+ PhraseListItem (const QString & text);
+ ~PhraseListItem();
+
+ bool drawCursor() const;
+
+ int rtti() const;
+ static const int RTTI = 982734;
+
+protected:
+ void paint( QPainter * );
+};
+
+#endif
diff --git a/kmouth/preferencesui.ui b/kmouth/preferencesui.ui
new file mode 100644
index 0000000..a718b9d
--- /dev/null
+++ b/kmouth/preferencesui.ui
@@ -0,0 +1,162 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>PreferencesUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>PreferencesUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>339</width>
+ <height>148</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>Preferences</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>speakLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Selection of phrases in the phrase book:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>speakCombo</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This combo box specifies whether selected phrases of the phrase book are immediately spoken or just inserted into the edit field.</string>
+ </property>
+ </widget>
+ <widget class="KComboBox">
+ <item>
+ <property name="text">
+ <string>Speak Immediately</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Insert Into Edit Field</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>speakCombo</cstring>
+ </property>
+ <property name="currentItem">
+ <number>1</number>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This combo box specifies whether selected phrases of the phrase book are immediately spoken or just inserted into the edit field.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>closeLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Closing the phrase &amp;book edit window:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>closeCombo</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This combo box specifies whether the phrase book is automatically saved when the edit window is closed.</string>
+ </property>
+ </widget>
+ <widget class="KComboBox">
+ <item>
+ <property name="text">
+ <string>Save Phrase Book</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Discard Changes</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Ask Whether to Save</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>closeCombo</cstring>
+ </property>
+ <property name="currentItem">
+ <number>2</number>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This combo box specifies whether the phrase book is automatically saved when the edit window is closed.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kmouth/speech.cpp b/kmouth/speech.cpp
new file mode 100644
index 0000000..d2f7db8
--- /dev/null
+++ b/kmouth/speech.cpp
@@ -0,0 +1,242 @@
+/***************************************************************************
+ speech.cpp - description
+ -------------------
+ begin : Son Sep 8 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "speech.h"
+#include <qstring.h>
+#include <qvaluelist.h>
+#include <qvaluestack.h>
+#include <qstringlist.h>
+#include <qregexp.h>
+#include <qtextcodec.h>
+#include <qfile.h>
+#include <kdebug.h>
+
+#include <kdeversion.h>
+#ifdef KDE_IS_VERSION
+#if KDE_IS_VERSION(3,2,0)
+ #define macroExpander
+ #include <kmacroexpander.h>
+#endif
+#endif
+
+Speech::Speech() {
+}
+
+Speech::~Speech() {
+}
+
+QString Speech::prepareCommand (QString command, const QString &text,
+ const QString &filename, const QString &language) {
+#ifdef macroExpander
+ QMap<QChar,QString> map;
+ map['t'] = text;
+ map['f'] = filename;
+ map['l'] = language;
+ return KMacroExpander::expandMacrosShellQuote (command, map);
+#else
+ QValueStack<bool> stack; // saved isdoublequote values during parsing of braces
+ bool issinglequote=false; // inside '...' ?
+ bool isdoublequote=false; // inside "..." ?
+ int noreplace=0; // nested braces when within ${...}
+ QString escText = KShellProcess::quote(text);
+
+ // character sequences that change the state or need to be otherwise processed
+ QRegExp re_singlequote("('|%%|%t|%f|%l)");
+ QRegExp re_doublequote("(\"|\\\\|`|\\$\\(|\\$\\{|%%|%t|%f|%l)");
+ QRegExp re_noquote ("('|\"|\\\\|`|\\$\\(|\\$\\{|\\(|\\{|\\)|\\}|%%|%t|%f|%l)");
+
+ // parse the command:
+ for (int i = re_noquote.search(command);
+ i != -1;
+ i = (issinglequote?re_singlequote.search(command,i)
+ :isdoublequote?re_doublequote.search(command,i)
+ :re_noquote.search(command,i))
+ )
+ // while there are character sequences that need to be processed
+ {
+ if ((command[i]=='(') || (command[i]=='{')) { // (...) or {...}
+ // assert(isdoublequote == false)
+ stack.push(isdoublequote);
+ if (noreplace > 0)
+ // count nested braces when within ${...}
+ noreplace++;
+ i++;
+ }
+ else if (command[i]=='$') { // $(...) or ${...}
+ stack.push(isdoublequote);
+ isdoublequote = false;
+ if ((noreplace > 0) || (command[i+1]=='{'))
+ // count nested braces when within ${...}
+ noreplace++;
+ i+=2;
+ }
+ else if ((command[i]==')') || (command[i]=='}')) {
+ // $(...) or (...) or ${...} or {...}
+ if (!stack.isEmpty())
+ isdoublequote = stack.pop();
+ else
+ qWarning("Parse error.");
+ if (noreplace > 0)
+ // count nested braces when within ${...}
+ noreplace--;
+ i++;
+ }
+ else if (command[i]=='\'') {
+ issinglequote=!issinglequote;
+ i++;
+ }
+ else if (command[i]=='"') {
+ isdoublequote=!isdoublequote;
+ i++;
+ }
+ else if (command[i]=='\\')
+ i+=2;
+ else if (command[i]=='`') {
+ // Replace all `...` with safer $(...)
+ command.replace (i, 1, "$(");
+ QRegExp re_backticks("(`|\\\\`|\\\\\\\\|\\\\\\$)");
+ for (int i2=re_backticks.search(command,i+2);
+ i2!=-1;
+ i2=re_backticks.search(command,i2)
+ )
+ {
+ if (command[i2] == '`') {
+ command.replace (i2, 1, ")");
+ i2=command.length(); // leave loop
+ }
+ else {
+ // remove backslash and ignore following character
+ command.remove (i2, 1);
+ i2++;
+ }
+ }
+ // Leave i unchanged! We need to process "$("
+ }
+ else if (noreplace > 0) { // do not replace macros within ${...}
+ if (issinglequote)
+ i+=re_singlequote.matchedLength();
+ else if (isdoublequote)
+ i+=re_doublequote.matchedLength();
+ else
+ i+=re_noquote.matchedLength();
+ }
+ else { // replace macro
+ QString match, v;
+
+ // get match
+ if (issinglequote)
+ match=re_singlequote.cap();
+ else if (isdoublequote)
+ match=re_doublequote.cap();
+ else
+ match=re_noquote.cap();
+
+ // substitute %variables
+ if (match=="%t")
+ v = escText;
+ else if (match=="%f")
+ v = filename;
+ else if (match=="%%")
+ v = "%";
+ else if (match=="%l")
+ v = language;
+
+ // %variable inside of a quote?
+ if (isdoublequote)
+ v='"'+v+'"';
+ else if (issinglequote)
+ v="'"+v+"'";
+
+ command.replace (i, match.length(), v);
+ i+=v.length();
+ }
+ }
+ return command;
+#endif
+}
+
+void Speech::speak(QString command, bool stdIn, const QString &text, const QString &language, int encoding, QTextCodec *codec) {
+ if (text.length () > 0) {
+ // 1. prepare the text:
+ // 1.a) encode the text
+ QTextStream ts (encText, IO_WriteOnly);
+ if (encoding == Local)
+ ts.setEncoding (QTextStream::Locale);
+ else if (encoding == Latin1)
+ ts.setEncoding (QTextStream::Latin1);
+ else if (encoding == Unicode)
+ ts.setEncoding (QTextStream::Unicode);
+ else
+ ts.setCodec (codec);
+ ts << text;
+
+ // 1.b) create a temporary file for the text
+ tempFile.setAutoDelete(true);
+ QTextStream* fs = tempFile.textStream();
+ if (encoding == Local)
+ fs->setEncoding (QTextStream::Locale);
+ else if (encoding == Latin1)
+ fs->setEncoding (QTextStream::Latin1);
+ else if (encoding == Unicode)
+ fs->setEncoding (QTextStream::Unicode);
+ else
+ fs->setCodec (codec);
+ *fs << text;
+ *fs << endl;
+ QString filename = tempFile.file()->name();
+ tempFile.close();
+
+ // 2. prepare the command:
+ command = prepareCommand (command, encText, filename, language);
+
+
+ // 3. create a new process
+ process << command;
+ connect(&process, SIGNAL(processExited(KProcess *)), this, SLOT(processExited(KProcess *)));
+ connect(&process, SIGNAL(wroteStdin(KProcess *)), this, SLOT(wroteStdin(KProcess *)));
+ connect(&process, SIGNAL(receivedStdout(KProcess *, char *, int)), this, SLOT(receivedStdout(KProcess *, char *, int)));
+ connect(&process, SIGNAL(receivedStderr(KProcess *, char *, int)), this, SLOT(receivedStderr(KProcess *, char *, int)));
+
+ // 4. start the process
+ if (stdIn) {
+ process.start(KProcess::NotifyOnExit, KProcess::All);
+ if (encText.size() > 0)
+ process.writeStdin(encText, encText.size());
+ else
+ process.closeStdin();
+ }
+ else
+ process.start(KProcess::NotifyOnExit, KProcess::AllOutput);
+ }
+}
+
+void Speech::receivedStdout (KProcess *, char *buffer, int buflen) {
+ kdDebug() << QString::fromLatin1(buffer, buflen) + "\n";
+}
+void Speech::receivedStderr (KProcess *, char *buffer, int buflen) {
+ kdDebug() << QString::fromLatin1(buffer, buflen) + "\n";
+}
+
+void Speech::wroteStdin(KProcess *) {
+ process.closeStdin();
+}
+
+void Speech::processExited(KProcess *) {
+ delete this;
+}
+
+#include "speech.moc"
diff --git a/kmouth/speech.h b/kmouth/speech.h
new file mode 100644
index 0000000..83c728c
--- /dev/null
+++ b/kmouth/speech.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ speech.h - description
+ -------------------
+ begin : Son Sep 8 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SPEECH_H
+#define SPEECH_H
+
+#include <qobject.h>
+#include <qstring.h>
+#include <kprocess.h>
+#include <ktempfile.h>
+
+/**This class is used internally by TextToSpeechSystem in order to do the actual speaking.
+ *@author Gunnar Schmi Dt
+ */
+
+class Speech : public QObject {
+ Q_OBJECT
+public:
+ enum CharacterCodec {
+ Local = 0,
+ Latin1 = 1,
+ Unicode = 2,
+ UseCodec = 3
+ };
+
+ Speech();
+ ~Speech();
+
+ /**
+ * Speaks the given text.
+ * @param command the program that shall be executed for speaking
+ * @param stdin true if the program shall receive its data via standard input
+ * @param text The text that shall be spoken
+ */
+ void speak(QString command, bool use_stdin, const QString &text, const QString &language, int encoding, QTextCodec *codec);
+
+ /**
+ * Prepares a command for being executed. During the preparation the
+ * command is parsed and occurrences of "%t" are replaced by text.
+ * @param command the command that shall be executed for speaking
+ * @param text the quoted text that can be inserted into the command
+ */
+ QString prepareCommand (QString command, const QString &text,
+ const QString &filename, const QString &language);
+
+public slots:
+ void wroteStdin (KProcess *p);
+ void processExited (KProcess *p);
+ void receivedStdout (KProcess *proc, char *buffer, int buflen);
+ void receivedStderr (KProcess *proc, char *buffer, int buflen);
+
+private:
+ KShellProcess process;
+ QByteArray encText;
+ KTempFile tempFile;
+};
+
+#endif
diff --git a/kmouth/texttospeechconfigurationui.ui b/kmouth/texttospeechconfigurationui.ui
new file mode 100644
index 0000000..de393ce
--- /dev/null
+++ b/kmouth/texttospeechconfigurationui.ui
@@ -0,0 +1,170 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>texttospeechconfigurationui</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>texttospeechconfigurationui</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>391</width>
+ <height>222</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Text-to-Speech</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout4</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>urlLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>C&amp;ommand for speaking texts:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>urlReq</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This field specifies both the command used for speaking texts and its parameters. KMouth knows the following placeholders:
+%t -- the text that should be spoken
+%f -- the name of a file containing the text
+%l -- the language code
+%% -- a percent sign</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>urlReq</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This field specifies both the command used for speaking texts and its parameters. KMouth knows the following placeholders:
+%t -- the text that should be spoken
+%f -- the name of a file containing the text
+%l -- the language code
+%% -- a percent sign</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout5</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>characterCodingLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Character &amp;encoding:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>characterCodingBox</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This combo box specifies which character encoding is used for passing the text.</string>
+ </property>
+ </widget>
+ <widget class="KComboBox">
+ <property name="name">
+ <cstring>characterCodingBox</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This combo box specifies which character encoding is used for passing the text.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>stdInButton</cstring>
+ </property>
+ <property name="text">
+ <string>Send the data as standard &amp;input</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This check box specifies whether the text is sent as standard input to the speech synthesizer.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>useKttsd</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Use KTTSD speech service if possible</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This check box specifies KMouth tries to use the KTTSD speech service prior to calling the speech synthesizer directly. The KTTSD speech service is a KDE daemon which gives KDE applications a standardized interface for speech synthesis and is currently developed in CVS.</string>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+<signals>
+ <signal>configurationChanged()</signal>
+</signals>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kcombobox.h</includehint>
+</includehints>
+</UI>
diff --git a/kmouth/texttospeechconfigurationwidget.cpp b/kmouth/texttospeechconfigurationwidget.cpp
new file mode 100644
index 0000000..f697061
--- /dev/null
+++ b/kmouth/texttospeechconfigurationwidget.cpp
@@ -0,0 +1,86 @@
+/***************************************************************************
+ texttospeechconfigurationdialog.cpp - description
+ -------------------
+ begin : Son Sep 8 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#include "texttospeechconfigurationwidget.h"
+#include <kconfig.h>
+#include <qtextcodec.h>
+#include <qptrlist.h>
+#include <qlayout.h>
+#include <qwhatsthis.h>
+#include <kcombobox.h>
+#include <klocale.h>
+#include <qlabel.h>
+#include "speech.h"
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qcheckbox.h>
+#include <kurlrequester.h>
+
+TextToSpeechConfigurationWidget::TextToSpeechConfigurationWidget (QWidget *parent, const char *name)
+ : texttospeechconfigurationui (parent, name)
+{
+ ttsSystem = new TextToSpeechSystem();
+
+ urlReq->setShowLocalProtocol (false);
+ buildCodecList();
+}
+
+TextToSpeechConfigurationWidget::~TextToSpeechConfigurationWidget() {
+}
+
+void TextToSpeechConfigurationWidget::buildCodecList () {
+ QString local = i18n("Local")+" (";
+ local += QTextCodec::codecForLocale()->name();
+ local += ")";
+ characterCodingBox->insertItem (local, Speech::Local);
+ characterCodingBox->insertItem (i18n("Latin1"), Speech::Latin1);
+ characterCodingBox->insertItem (i18n("Unicode"), Speech::Unicode);
+ for (uint i = 0; i < ttsSystem->codecList->count(); i++ )
+ characterCodingBox->insertItem (ttsSystem->codecList->at(i)->name(), Speech::UseCodec + i);
+}
+
+void TextToSpeechConfigurationWidget::cancel() {
+ urlReq->setURL (ttsSystem->ttsCommand);
+ stdInButton->setChecked (ttsSystem->stdIn);
+ characterCodingBox->setCurrentItem(ttsSystem->codec);
+ useKttsd->setChecked (ttsSystem->useKttsd);
+}
+
+void TextToSpeechConfigurationWidget::ok() {
+ ttsSystem->ttsCommand = urlReq->url();
+ ttsSystem->stdIn = stdInButton->isChecked();
+ ttsSystem->codec = characterCodingBox->currentItem();
+ ttsSystem->useKttsd = useKttsd->isChecked();
+}
+
+TextToSpeechSystem *TextToSpeechConfigurationWidget::getTTSSystem() const {
+ return ttsSystem;
+}
+
+void TextToSpeechConfigurationWidget::readOptions (KConfig *config, const QString &langGroup) {
+ ttsSystem->readOptions (config, langGroup);
+ urlReq->setURL (ttsSystem->ttsCommand);
+ stdInButton->setChecked (ttsSystem->stdIn);
+ characterCodingBox->setCurrentItem(ttsSystem->codec);
+ useKttsd->setChecked (ttsSystem->useKttsd);
+}
+
+void TextToSpeechConfigurationWidget::saveOptions (KConfig *config, const QString &langGroup) {
+ ttsSystem->saveOptions (config, langGroup);
+}
+
diff --git a/kmouth/texttospeechconfigurationwidget.h b/kmouth/texttospeechconfigurationwidget.h
new file mode 100644
index 0000000..439ae4f
--- /dev/null
+++ b/kmouth/texttospeechconfigurationwidget.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ texttospeechconfigurationdialog.h - description
+ -------------------
+ begin : Son Sep 8 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#ifndef TEXTTOSPEECHCONFIGURATIONDIALOG_H
+#define TEXTTOSPEECHCONFIGURATIONDIALOG_H
+
+#include <kdialogbase.h>
+#include "texttospeechconfigurationui.h"
+#include "texttospeechsystem.h"
+
+/**This class represents a configuration widget for the text-to-speech system.
+ *@author Gunnar Schmi Dt
+ */
+
+class TextToSpeechConfigurationWidget : public texttospeechconfigurationui {
+ friend class TextToSpeechConfigurationDialog;
+public:
+ TextToSpeechConfigurationWidget(QWidget *parent, const char *name);
+ ~TextToSpeechConfigurationWidget();
+
+ TextToSpeechSystem *getTTSSystem() const;
+
+ void readOptions (KConfig *config, const QString &langGroup);
+ void saveOptions (KConfig *config, const QString &langGroup);
+
+ void ok();
+ void cancel();
+
+private:
+ void buildCodecList ();
+
+ TextToSpeechSystem *ttsSystem;
+};
+
+#endif
+
diff --git a/kmouth/texttospeechsystem.cpp b/kmouth/texttospeechsystem.cpp
new file mode 100644
index 0000000..4aeb0f9
--- /dev/null
+++ b/kmouth/texttospeechsystem.cpp
@@ -0,0 +1,114 @@
+/***************************************************************************
+ texttospeechsystem.cpp - description
+ -------------------
+ begin : Son Sep 8 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#include "texttospeechsystem.h"
+#include <qregexp.h>
+#include <qtextcodec.h>
+#include <qptrlist.h>
+#include <stdlib.h>
+
+#include <kapplication.h>
+#include <dcopclient.h>
+#include <kconfig.h>
+
+#include "speech.h"
+
+TextToSpeechSystem::TextToSpeechSystem() {
+ ttsCommand = "";
+ stdIn = true;
+ useKttsd = true;
+ codec = Speech::Local; // local encoding;
+ buildCodecList();
+}
+
+TextToSpeechSystem::~TextToSpeechSystem() {
+ delete codecList;
+}
+
+bool kttsdSay (const QString &text, const QString &language) {
+ DCOPClient *client = kapp->dcopClient();
+ QByteArray data;
+ QCString replyType;
+ QByteArray replyData;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << text << language;
+ return client->call("kttsd", "KSpeech", "sayWarning(QString,QString)",
+ data, replyType, replyData, true);
+}
+
+void TextToSpeechSystem::speak (const QString &text, const QString &language) {
+ if (text.length() > 0) {
+ if (useKttsd) {
+ if (kttsdSay(text, language))
+ return;
+ }
+
+ if (codec < Speech::UseCodec)
+ (new Speech())->speak(ttsCommand, stdIn, text, language, codec, 0);
+ else
+ (new Speech())->speak(ttsCommand, stdIn, text, language, Speech::UseCodec,
+ codecList->at (codec - Speech::UseCodec));
+ }
+}
+
+void TextToSpeechSystem::readOptions (KConfig *config, const QString &langGroup) {
+ config->setGroup(langGroup);
+ ttsCommand = config->readPathEntry("Command");
+ stdIn = config->readBoolEntry("StdIn", true);
+ useKttsd = config->readBoolEntry("useKttsd", true);
+
+ QString codecString = config->readEntry("Codec", "Local");
+ if (codecString == "Local")
+ codec = Speech::Local;
+ else if (codecString == "Latin1")
+ codec = Speech::Latin1;
+ else if (codecString == "Unicode")
+ codec = Speech::Unicode;
+ else {
+ codec = Speech::Local;
+ for (uint i = 0; i < codecList->count(); i++ )
+ if (codecString == codecList->at(i)->name())
+ codec = Speech::UseCodec + i;
+ }
+}
+
+void TextToSpeechSystem::saveOptions (KConfig *config, const QString &langGroup) {
+ config->setGroup(langGroup);
+ config->writePathEntry("Command", ttsCommand);
+ config->writeEntry("StdIn", stdIn);
+ config->writeEntry("useKttsd", useKttsd);
+ if (codec == Speech::Local)
+ config->writeEntry("Codec", "Local");
+ else if (codec == Speech::Latin1)
+ config->writeEntry("Codec", "Latin1");
+ else if (codec == Speech::Unicode)
+ config->writeEntry("Codec", "Unicode");
+ else config->writeEntry("Codec",
+ codecList->at (codec-Speech::UseCodec)->name());
+
+}
+
+void TextToSpeechSystem::buildCodecList () {
+ codecList = new QPtrList<QTextCodec>;
+ QTextCodec *codec;
+ int i;
+ for (i = 0; (codec = QTextCodec::codecForIndex(i)); i++)
+ codecList->append (codec);
+}
+
+#include "texttospeechsystem.moc"
diff --git a/kmouth/texttospeechsystem.h b/kmouth/texttospeechsystem.h
new file mode 100644
index 0000000..fc9b018
--- /dev/null
+++ b/kmouth/texttospeechsystem.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ texttospeechsystem.h - description
+ -------------------
+ begin : Son Sep 8 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#ifndef TEXTTOSPEECHSYSTEM_H
+#define TEXTTOSPEECHSYSTEM_H
+
+#include <qstring.h>
+#include <qobject.h>
+#include <qptrlist.h>
+
+class KConfig;
+
+/**This class represents a text-to-speech system.
+ *@author Gunnar Schmi Dt
+ */
+
+class TextToSpeechSystem : public QObject{
+ Q_OBJECT
+ friend class TextToSpeechConfigurationWidget;
+public:
+ TextToSpeechSystem();
+ ~TextToSpeechSystem();
+
+ void readOptions (KConfig *config, const QString &langGroup);
+ void saveOptions (KConfig *config, const QString &langGroup);
+
+public slots:
+ void speak (const QString &text, const QString &language);
+
+private:
+ void buildCodecList ();
+
+ QPtrList<QTextCodec> *codecList;
+ int codec;
+ QString ttsCommand;
+ bool stdIn;
+ bool useKttsd;
+};
+
+#endif
diff --git a/kmouth/version.h b/kmouth/version.h
new file mode 100644
index 0000000..0f5fa60
--- /dev/null
+++ b/kmouth/version.h
@@ -0,0 +1,8 @@
+// KMouth Version Information
+//
+#ifndef kmouth_version_h
+#define kmouth_version_h
+
+#define KMOUTH_VERSION "1.1.1"
+
+#endif /*version_h*/
diff --git a/kmouth/wordcompletion/Makefile.am b/kmouth/wordcompletion/Makefile.am
new file mode 100644
index 0000000..8926f41
--- /dev/null
+++ b/kmouth/wordcompletion/Makefile.am
@@ -0,0 +1,13 @@
+noinst_LIBRARIES = libwordcompletion.a
+
+INCLUDES = $(all_includes)
+
+libwordcompletion_a_METASOURCES = AUTO
+
+libwordcompletion_a_SOURCES = wordcompletionui.ui creationsourceui.ui creationsourcedetailsui.ui kdedocsourceui.ui \
+ wordlist.cpp wordcompletion.cpp wordcompletionwidget.cpp dictionarycreationwizard.cpp klanguagebutton.cpp klanguagebuttonhelper.cpp
+
+EXTRA_DIST = wordcompletionui.ui creationsourceui.ui creationsourcedetailsui.ui kdedocsourceui.ui \
+ creationsourceui.ui.h creationsourcedetailsui.ui.h kdedocsourceui.ui.h \
+ wordlist.cpp wordcompletion.cpp wordcompletionwidget.cpp dictionarycreationwizard.cpp klanguagebutton.cpp klanguagebuttonhelper.cpp \
+ wordlist.h wordcompletion.h wordcompletionwidget.h dictionarycreationwizard.h klanguagebutton.h klanguagebuttonhelper.h
diff --git a/kmouth/wordcompletion/creationsourcedetailsui.ui b/kmouth/wordcompletion/creationsourcedetailsui.ui
new file mode 100644
index 0000000..1a1f61b
--- /dev/null
+++ b/kmouth/wordcompletion/creationsourcedetailsui.ui
@@ -0,0 +1,184 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>CreationSourceDetailsUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>CreationSourceDetailsUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>421</width>
+ <height>189</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="3" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spellCheckBox</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Compare to OpenOffice.org dictionary:</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If you select this check box the words are spell-checked before they are inserted into the new dictionary.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>encodingLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Character &amp;encoding:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>encodingCombo</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this combo box you select the character encoding used to load text files. This combo box is not used for XML files or for dictionary files.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>urlLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Filename:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>url</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this input field you specify which file you want to load for creating the new dictionary.</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester" row="0" column="1">
+ <property name="name">
+ <cstring>url</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this input field you specify which file you want to load for creating the new dictionary.</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="1" column="1">
+ <property name="name">
+ <cstring>encodingCombo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this combo box you select the character encoding used to load text files. This combo box is not used for XML files or for dictionary files.</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester" row="4" column="1">
+ <property name="name">
+ <cstring>ooDictURL</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this input field you select the OpenOffice.org directory that will be used to spellcheck the words of the new dictionary.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>languageLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Language:</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this combo box you decide which language should be associated with the new dictionary.</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>spellCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>ooDictURL</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="global" impldecl="in implementation">kinputdialog.h</include>
+ <include location="local" impldecl="in implementation">klanguagebutton.h</include>
+ <include location="local" impldecl="in implementation">klanguagebuttonhelper.h</include>
+ <include location="local" impldecl="in implementation">creationsourcedetailsui.ui.h</include>
+</includes>
+<forwards>
+ <forward>class KLanguageButton</forward>
+</forwards>
+<variables>
+ <variable access="public">KLanguageButton *languageButton;</variable>
+</variables>
+<slots>
+ <slot access="protected" specifier="non virtual">languageButton_activated( int index )</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kinputdialog.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>kinputdialog.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kmouth/wordcompletion/creationsourcedetailsui.ui.h b/kmouth/wordcompletion/creationsourcedetailsui.ui.h
new file mode 100644
index 0000000..956f021
--- /dev/null
+++ b/kmouth/wordcompletion/creationsourcedetailsui.ui.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+** ui.h extension file, included from the uic-generated form implementation.
+**
+** If you wish to add, delete or rename functions or slots use
+** Qt Designer which will update this file, preserving your code. Create an
+** init() function in place of a constructor, and a destroy() function in
+** place of a destructor.
+*****************************************************************************/
+
+
+void CreationSourceDetailsUI::init() {
+ languageButton = new KLanguageButton (this, "languageButton");
+ CreationSourceDetailsUILayout->addWidget (languageButton, 2, 1);
+ languageLabel->setBuddy (languageButton);
+ QWhatsThis::add (languageButton, i18n("With this combo box you decide which language should be associated with the new dictionary."));
+
+ loadLanguageList(languageButton);
+ languageButton->insertLanguage("??", i18n("Other"), QString::fromLatin1("l10n/"), QString::null);
+
+ connect (languageButton, SIGNAL(activated(int)), this, SLOT(languageButton_activated(int)));
+}
+
+void CreationSourceDetailsUI::languageButton_activated (int) {
+ if (languageButton->currentTag() == "??") {
+ QString customLanguage = KInputDialog::getText(i18n("Create Custom Language"), i18n("Please enter the code for the custom language:"));
+
+ if (languageButton->containsTag(customLanguage)) {
+ languageButton->setCurrentItem(customLanguage);
+ }
+ else {
+ languageButton->insertLanguage(customLanguage, i18n("without name"), QString::fromLatin1("l10n/"), QString::null);
+ languageButton->setCurrentItem(customLanguage);
+ }
+ }
+}
+
+
diff --git a/kmouth/wordcompletion/creationsourceui.ui b/kmouth/wordcompletion/creationsourceui.ui
new file mode 100644
index 0000000..13a7c06
--- /dev/null
+++ b/kmouth/wordcompletion/creationsourceui.ui
@@ -0,0 +1,179 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>CreationSourceUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>CreationSourceUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>318</width>
+ <height>223</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>createButton</cstring>
+ </property>
+ <property name="text">
+ <string>C&amp;reate new dictionary:</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If you select this box a new dictionary is created by either loading a dictionary file or by counting the individual words in a text.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="4" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>mergeButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Merge dictionaries</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If you select this box a new dictionary is created by merging existing dictionaries.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="2" column="1">
+ <property name="name">
+ <cstring>fileButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>From &amp;file</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If you select this box a new dictionary is created by loading a file. You may either select an XML file, a standard text file or a file containing a word completion dictionary. If you select a standard text file or an XML file the frequentness of the individual words is detected by simply counting the occurrences of each word.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="1">
+ <property name="name">
+ <cstring>kdeDocButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>From &amp;KDE documentation</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If you select this box a new dictionary is created by parsing the KDE documentation. The frequentness of the individual words is detect by simply counting the occurrences of each word.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="3" column="1">
+ <property name="name">
+ <cstring>directoryButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>From f&amp;older</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If you select this box a new dictionary is created by loading all files in a folder and its subdirectories.</string>
+ </property>
+ </widget>
+ <spacer row="1" column="0" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QRadioButton" row="5" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>emptyButton</cstring>
+ </property>
+ <property name="text">
+ <string>Create an &amp;empty wordlist</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If you select this box a blank dictionary without any entries is created. As KMouth automatically adds newly typed words to the dictionaries it will learn your vocabulary with the time.</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>createButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>kdeDocButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>createButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>fileButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>createButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>directoryButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="global" impldecl="in implementation">qbuttongroup.h</include>
+ <include location="local" impldecl="in implementation">creationsourceui.ui.h</include>
+</includes>
+<forwards>
+ <forward>class QButtonGroup</forward>
+</forwards>
+<variables>
+ <variable access="public">QButtonGroup *group2;</variable>
+ <variable access="public">QButtonGroup *group1;</variable>
+</variables>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+ <function access="private" specifier="non virtual">destroy()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kmouth/wordcompletion/creationsourceui.ui.h b/kmouth/wordcompletion/creationsourceui.ui.h
new file mode 100644
index 0000000..d78a439
--- /dev/null
+++ b/kmouth/wordcompletion/creationsourceui.ui.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+** ui.h extension file, included from the uic-generated form implementation.
+**
+** If you wish to add, delete or rename functions or slots use
+** Qt Designer which will update this file, preserving your code. Create an
+** init() function in place of a constructor, and a destroy() function in
+** place of a destructor.
+*****************************************************************************/
+
+
+void CreationSourceUI::init() {
+ group1 = new QButtonGroup (0);
+ group1->insert (createButton);
+ group1->insert (mergeButton);
+ group1->insert (emptyButton);
+ group2 = new QButtonGroup (0);
+ group2->insert (kdeDocButton);
+ group2->insert (fileButton);
+ group2->insert (directoryButton);
+}
+
+
+void CreationSourceUI::destroy() {
+ delete group1;
+ delete group2;
+}
diff --git a/kmouth/wordcompletion/dictionarycreationwizard.cpp b/kmouth/wordcompletion/dictionarycreationwizard.cpp
new file mode 100644
index 0000000..a0711ce
--- /dev/null
+++ b/kmouth/wordcompletion/dictionarycreationwizard.cpp
@@ -0,0 +1,376 @@
+/***************************************************************************
+ wordcompletionwidget.cpp - description
+ -------------------
+ begin : Tue Apr 29 2003
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <qtextcodec.h>
+#include <qwhatsthis.h>
+
+#include <klistview.h>
+#include <klineedit.h>
+#include <kurlrequester.h>
+#include <klocale.h>
+#include <kcombobox.h>
+#include <ksconfig.h>
+#include <kapplication.h>
+#include <kstandarddirs.h>
+#include <kprogress.h>
+#include <kconfig.h>
+
+#include "dictionarycreationwizard.h"
+#include "klanguagebutton.h"
+#include "creationsourceui.h"
+#include "creationsourcedetailsui.h"
+#include "kdedocsourceui.h"
+#include "wordlist.h"
+
+DictionaryCreationWizard::DictionaryCreationWizard (QWidget *parent, const char *name,
+ QStringList dictionaryNames, QStringList dictionaryFiles,
+ QStringList dictionaryLanguages)
+ : KWizard (parent, name)
+{
+ buildCodecList ();
+
+ creationSource = new CreationSourceUI (this, "source page");
+ addPage (creationSource, i18n("Source of New Dictionary (1)"));
+ setHelpEnabled (creationSource, false);
+ setFinishEnabled (creationSource, false);
+
+ fileWidget= new CreationSourceDetailsUI (this, "file source page");
+ addPage (fileWidget, i18n("Source of New Dictionary (2)"));
+ buildCodecCombo (fileWidget->encodingCombo);
+
+ dirWidget= new CreationSourceDetailsUI (this, "directory source page");
+ addPage (dirWidget, i18n("Source of New Dictionary (2)"));
+ dirWidget->urlLabel->setText (i18n("&Directory:"));
+ QWhatsThis::add (dirWidget->urlLabel, i18n("With this input field you specify which directory you want to load for creating the new dictionary."));
+ dirWidget->url->setMode(KFile::Directory);
+ QWhatsThis::add (dirWidget->url, i18n("With this input field you specify which directory you want to load for creating the new dictionary."));
+ buildCodecCombo (dirWidget->encodingCombo);
+
+ kdeDocWidget= new KDEDocSourceUI (this, "KDE documentation source page");
+ addPage (kdeDocWidget, i18n("Source of New Dictionary (2)"));
+
+ mergeWidget = new MergeWidget (this, "merge source page", dictionaryNames, dictionaryFiles, dictionaryLanguages);
+ addPage (mergeWidget, i18n("Source of New Dictionary (2)"));
+
+ connect (creationSource->fileButton, SIGNAL (toggled(bool)), this, SLOT(calculateAppropriate(bool)) );
+ connect (creationSource->directoryButton,SIGNAL(toggled(bool)), this, SLOT(calculateAppropriate(bool)) );
+ connect (creationSource->kdeDocButton, SIGNAL (toggled(bool)), this, SLOT(calculateAppropriate(bool)) );
+ connect (creationSource->mergeButton, SIGNAL (toggled(bool)), this, SLOT(calculateAppropriate(bool)) );
+ connect (creationSource->emptyButton, SIGNAL (toggled(bool)), this, SLOT(calculateAppropriate(bool)) );
+
+ calculateAppropriate (true);
+}
+
+DictionaryCreationWizard::~DictionaryCreationWizard () {
+ delete codecList;
+ removePage (fileWidget); delete fileWidget;
+ removePage (dirWidget); delete dirWidget;
+ removePage (kdeDocWidget); delete kdeDocWidget;
+ removePage (mergeWidget); delete mergeWidget;
+}
+
+void DictionaryCreationWizard::buildCodecList () {
+ codecList = new QPtrList<QTextCodec>;
+ QTextCodec *codec;
+ int i;
+ for (i = 0; (codec = QTextCodec::codecForIndex(i)); i++)
+ codecList->append (codec);
+}
+
+void DictionaryCreationWizard::buildCodecCombo (QComboBox *combo) {
+ QString local = i18n("Local")+" (";
+ local += QTextCodec::codecForLocale()->name();
+ local += ")";
+ combo->insertItem (local, 0);
+ combo->insertItem (i18n("Latin1"), 1);
+ combo->insertItem (i18n("Unicode"), 2);
+ for (uint i = 0; i < codecList->count(); i++ )
+ combo->insertItem (codecList->at(i)->name(), i+3);
+}
+
+void DictionaryCreationWizard::calculateAppropriate (bool) {
+ if (creationSource->mergeButton->isChecked()) {
+ setFinishEnabled (creationSource, false);
+ removePage (fileWidget);
+ removePage (dirWidget);
+ removePage (kdeDocWidget);
+ addPage (mergeWidget, i18n("Source of New Dictionary (2)"));
+ setHelpEnabled (mergeWidget, false);
+ setFinishEnabled (mergeWidget, true);
+ }
+ else if (creationSource->emptyButton->isChecked()) {
+ removePage (fileWidget);
+ removePage (dirWidget);
+ removePage (kdeDocWidget);
+ removePage (mergeWidget);
+ setFinishEnabled (creationSource, true);
+ }
+ else if (creationSource->fileButton->isChecked()) {
+ setFinishEnabled (creationSource, false);
+ removePage (dirWidget);
+ removePage (kdeDocWidget);
+ removePage (mergeWidget);
+ addPage (fileWidget, i18n("Source of New Dictionary (2)"));
+ setHelpEnabled (fileWidget, false);
+ setFinishEnabled (fileWidget, true);
+ }
+ else if (creationSource->directoryButton->isChecked()) {
+ setFinishEnabled (creationSource, false);
+ removePage (fileWidget);
+ removePage (kdeDocWidget);
+ removePage (mergeWidget);
+ addPage (dirWidget, i18n("Source of New Dictionary (2)"));
+ setHelpEnabled (dirWidget, false);
+ setFinishEnabled (dirWidget, true);
+ }
+ else { // creationSource->kdeDocButton must be checked
+ setFinishEnabled (creationSource, false);
+ removePage (fileWidget);
+ removePage (dirWidget);
+ removePage (mergeWidget);
+ addPage (kdeDocWidget, i18n("Source of New Dictionary (2)"));
+ setHelpEnabled (kdeDocWidget, false);
+ setFinishEnabled (kdeDocWidget, true);
+ }
+}
+
+QString DictionaryCreationWizard::createDictionary() {
+ WordList::WordMap map;
+ QString dicFile = "";
+ KProgressDialog *pdlg = WordList::progressDialog();
+
+ if (creationSource->mergeButton->isChecked()) {
+ map = WordList::mergeFiles (mergeWidget->mergeParameters(), pdlg);
+ dicFile = QString::null;
+ }
+ else if (creationSource->emptyButton->isChecked()) {
+ dicFile = QString::null;
+ }
+ else if (creationSource->fileButton->isChecked()) {
+ QString filename = fileWidget->url->url();
+ int encoding = fileWidget->encodingCombo->currentItem();
+ if (fileWidget->spellCheckBox->isChecked())
+ dicFile = fileWidget->ooDictURL->url();
+ switch (encoding) {
+ case 0:
+ map = WordList::parseFile (filename, QTextStream::Locale, 0, pdlg);
+ break;
+ case 1:
+ map = WordList::parseFile (filename, QTextStream::Latin1, 0, pdlg);
+ break;
+ case 2:
+ map = WordList::parseFile (filename, QTextStream::Unicode, 0, pdlg);
+ break;
+ default:
+ map = WordList::parseFile (filename, (QTextStream::Encoding)0, codecList->at(encoding-3), pdlg);
+ }
+ }
+ else if (creationSource->directoryButton->isChecked()) {
+ QString directory = dirWidget->url->url();
+ int encoding = dirWidget->encodingCombo->currentItem();
+ if (dirWidget->spellCheckBox->isChecked())
+ dicFile = dirWidget->ooDictURL->url();
+ switch (encoding) {
+ case 0:
+ map = WordList::parseDir (directory, QTextStream::Locale, 0, pdlg);
+ break;
+ case 1:
+ map = WordList::parseDir (directory, QTextStream::Latin1, 0, pdlg);
+ break;
+ case 2:
+ map = WordList::parseDir (directory, QTextStream::Unicode, 0, pdlg);
+ break;
+ default:
+ map = WordList::parseDir (directory, (QTextStream::Encoding)0, codecList->at(encoding-3), pdlg);
+ }
+ }
+ else { // creationSource->kdeDocButton must be checked
+ QString language = kdeDocWidget->languageButton->currentTag();
+ if (kdeDocWidget->spellCheckBox->isChecked())
+ dicFile = kdeDocWidget->ooDictURL->url();
+ map = WordList::parseKDEDoc (language, pdlg);
+ }
+
+ if (!dicFile.isEmpty() && !dicFile.isNull())
+ map = WordList::spellCheck (map, dicFile, pdlg);
+ pdlg->close();
+ delete pdlg;
+
+ int dictnumber = 0;
+ QString filename;
+ QString dictionaryFile;
+ do {
+ dictnumber++;
+ filename = QString("wordcompletion%1.dict").arg(dictnumber);
+ dictionaryFile = KApplication::kApplication()->dirs()->findResource("appdata", filename);
+ }
+ while (KStandardDirs::exists(dictionaryFile));
+
+ dictionaryFile = KApplication::kApplication()->dirs()->saveLocation ("appdata", "/") + filename;
+ if (WordList::saveWordList (map, dictionaryFile))
+ return filename;
+ else
+ return "";
+}
+
+QString DictionaryCreationWizard::name() {
+ if (creationSource->mergeButton->isChecked()) {
+ return i18n("Merge result");
+ }
+ else if (creationSource->emptyButton->isChecked()) {
+ return i18n("In the sense of a blank word list", "Empty list");
+ }
+ else if (creationSource->fileButton->isChecked()) {
+ return fileWidget->url->url();
+ }
+ else if (creationSource->directoryButton->isChecked()) {
+ return dirWidget->url->url();
+ }
+ else { // creationSource->kdeDocButton must be checked
+ return i18n("KDE Documentation");
+ }
+}
+
+QString DictionaryCreationWizard::language() {
+ if (creationSource->mergeButton->isChecked()) {
+ return mergeWidget->language();
+ }
+ else if (creationSource->emptyButton->isChecked()) {
+ if (KGlobal::locale())
+ return KGlobal::locale()->language();
+ else
+ return KLocale::defaultLanguage();
+ }
+ else if (creationSource->fileButton->isChecked()) {
+ return fileWidget->languageButton->currentTag();
+ }
+ else if (creationSource->directoryButton->isChecked()) {
+ return dirWidget->languageButton->currentTag();
+ }
+ else { // creationSource->kdeDocButton must be checked
+ return kdeDocWidget->languageButton->currentTag();
+ }
+}
+
+/***************************************************************************/
+
+MergeWidget::MergeWidget(KWizard *parent, const char *name,
+ QStringList dictionaryNames, QStringList dictionaryFiles,
+ QStringList dictionaryLanguages)
+: QScrollView (parent, name) {
+ dictionaries.setAutoDelete (false);
+ weights.setAutoDelete (false);
+
+ QWidget *contents = new QWidget(viewport());
+ addChild(contents);
+ QGridLayout *layout = new QGridLayout (contents);
+ setResizePolicy (QScrollView::AutoOneFit);
+ layout->setColStretch (0, 0);
+ layout->setColStretch (1, 1);
+
+ int row = 0;
+ QStringList::Iterator nIt = dictionaryNames.begin();
+ QStringList::Iterator fIt = dictionaryFiles.begin();
+ QStringList::Iterator lIt = dictionaryLanguages.begin();
+ for (; nIt != dictionaryNames.end(); ++nIt, ++fIt, ++lIt) {
+ QCheckBox *checkbox = new QCheckBox(*nIt, contents);
+ KIntNumInput *numInput = new KIntNumInput(contents);
+ layout->addWidget (checkbox, row, 0);
+ layout->addWidget (numInput, row, 1);
+
+ checkbox->setChecked (true);
+ numInput->setRange (1, 100, 10, true);
+ numInput->setValue (100);
+ connect (checkbox, SIGNAL (toggled(bool)), numInput, SLOT(setEnabled(bool)));
+
+ dictionaries.insert(*fIt, checkbox);
+ weights.insert(*fIt, numInput);
+ languages [*fIt] = *lIt;
+ row++;
+ }
+}
+
+MergeWidget::~MergeWidget() {
+}
+
+QMap <QString, int> MergeWidget::mergeParameters () {
+ QMap <QString, int> files;
+ QDictIterator<QCheckBox> it(dictionaries);
+ for (; it.current(); ++it) {
+ if (it.current()->isChecked()) {
+ QString name = it.currentKey();
+ QString dictionaryFile = KApplication::kApplication()->dirs()->findResource("appdata", name);
+ files[dictionaryFile] = weights[name]->value();
+ }
+ }
+
+ return files;
+}
+
+QString MergeWidget::language () {
+ QDictIterator<QCheckBox> it(dictionaries);
+ for (; it.current(); ++it) {
+ if (it.current()->isChecked()) {
+ return languages [it.currentKey()];
+ }
+ }
+
+ return QString::null;
+}
+
+/***************************************************************************/
+
+CompletionWizardWidget::CompletionWizardWidget (KWizard *parent, const char *name)
+ : KDEDocSourceUI (parent, name) {
+}
+
+CompletionWizardWidget::~CompletionWizardWidget() {
+}
+
+void CompletionWizardWidget::ok (KConfig *config) {
+ WordList::WordMap map;
+ KProgressDialog *pdlg = WordList::progressDialog();
+
+ QString language = languageButton->currentTag();
+ map = WordList::parseKDEDoc (language, pdlg);
+
+ if (spellCheckBox->isChecked())
+ map = WordList::spellCheck (map, ooDictURL->url(), pdlg);
+
+ pdlg->close();
+ delete pdlg;
+
+ QString filename;
+ QString dictionaryFile;
+
+ dictionaryFile = KApplication::kApplication()->dirs()->saveLocation ("appdata", "/") + "wordcompletion1.dict";
+ if (WordList::saveWordList (map, dictionaryFile)) {
+ config->setGroup("Dictionary 0");
+ config->writeEntry ("Filename", "wordcompletion1.dict");
+ config->writeEntry ("Name", i18n("Default"));
+ config->writeEntry ("Language", language);
+ config->sync();
+ }
+}
+
+#include "dictionarycreationwizard.moc"
diff --git a/kmouth/wordcompletion/dictionarycreationwizard.h b/kmouth/wordcompletion/dictionarycreationwizard.h
new file mode 100644
index 0000000..18928e1
--- /dev/null
+++ b/kmouth/wordcompletion/dictionarycreationwizard.h
@@ -0,0 +1,110 @@
+/***************************************************************************
+ dictionarycreationwizard.h - description
+ -------------------
+ begin : Tue Apr 29 2003
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// $Id$
+
+#ifndef DICTIONARYCREATIONWIZARD_H
+#define DICTIONARYCREATIONWIZARD_H
+
+#include <qptrlist.h>
+#include <qmap.h>
+
+#include <kwizard.h>
+#include <knuminput.h>
+#include "kdedocsourceui.h"
+
+class CreationSourceUI;
+class CompletionWizardWidget;
+class CreationSourceDetailsUI;
+class KDEDocSourceUI;
+class QTextCodec;
+class QComboBox;
+class MergeWidget;
+
+/**
+ * This class represents a wizard that is used in order to gather all
+ * necessary information for creating a new dictionary for the word
+ * completion.
+ */
+class DictionaryCreationWizard : public KWizard {
+ Q_OBJECT
+public:
+ DictionaryCreationWizard (QWidget *parent, const char *name,
+ QStringList dictionaryNames,
+ QStringList dictionaryFiles,
+ QStringList dictionaryLanguages);
+ ~DictionaryCreationWizard();
+
+ QString createDictionary();
+ QString name();
+ QString language();
+
+private slots:
+ void calculateAppropriate (bool);
+
+private:
+ void buildCodecList ();
+ void buildCodecCombo (QComboBox *combo);
+
+ CreationSourceUI *creationSource;
+ CreationSourceDetailsUI *fileWidget;
+ CreationSourceDetailsUI *dirWidget;
+ KDEDocSourceUI *kdeDocWidget;
+ MergeWidget *mergeWidget;
+
+ QPtrList<QTextCodec> *codecList;
+};
+
+/**
+ * This class represents a widget for creating an initial dictionary from the
+ * KDE documentation.
+ * @author Gunnar Schmi Dt
+ */
+class MergeWidget : public QScrollView {
+ Q_OBJECT
+public:
+ MergeWidget(KWizard *parent, const char *name,
+ QStringList dictionaryNames,
+ QStringList dictionaryFiles,
+ QStringList dictionaryLanguages);
+ ~MergeWidget();
+
+ QMap <QString, int> mergeParameters ();
+ QString language ();
+
+private:
+ QDict<QCheckBox> dictionaries;
+ QDict<KIntNumInput> weights;
+ QMap<QString,QString> languages;
+};
+
+/**
+ * This class represents a widget for creating an initial dictionary from the
+ * KDE documentation.
+ * @author Gunnar Schmi Dt
+ */
+class CompletionWizardWidget : public KDEDocSourceUI {
+ Q_OBJECT
+ friend class ConfigWizard;
+public:
+ CompletionWizardWidget(KWizard *parent, const char *name);
+ ~CompletionWizardWidget();
+
+ void ok (KConfig *config);
+};
+
+#endif
diff --git a/kmouth/wordcompletion/kdedocsourceui.ui b/kmouth/wordcompletion/kdedocsourceui.ui
new file mode 100644
index 0000000..21ce02a
--- /dev/null
+++ b/kmouth/wordcompletion/kdedocsourceui.ui
@@ -0,0 +1,101 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>KDEDocSourceUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>KDEDocSourceUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>272</width>
+ <height>100</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spellCheckBox</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Compare to OpenOffice.org dictionary:</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If you select this check box the words from the KDE documentation are spell-checked before they are inserted into the new dictionary.</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester" row="2" column="1">
+ <property name="name">
+ <cstring>ooDictURL</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this input field you select the OpenOffice.org directory that will be used to spellcheck the words of the new dictionary.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>languageLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Language:</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this combo box you select which of the installed languages is used for creating the new dictionary. KMouth will only parse documentation files of this language.</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>spellCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>ooDictURL</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">klanguagebutton.h</include>
+ <include location="local" impldecl="in implementation">klanguagebuttonhelper.h</include>
+ <include location="local" impldecl="in implementation">kdedocsourceui.ui.h</include>
+</includes>
+<forwards>
+ <forward>class KLanguageButton</forward>
+</forwards>
+<variables>
+ <variable access="public">KLanguageButton *languageButton;</variable>
+</variables>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kmouth/wordcompletion/kdedocsourceui.ui.h b/kmouth/wordcompletion/kdedocsourceui.ui.h
new file mode 100644
index 0000000..4c42b32
--- /dev/null
+++ b/kmouth/wordcompletion/kdedocsourceui.ui.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+** ui.h extension file, included from the uic-generated form implementation.
+**
+** If you wish to add, delete or rename functions or slots use
+** Qt Designer which will update this file, preserving your code. Create an
+** init() function in place of a constructor, and a destroy() function in
+** place of a destructor.
+*****************************************************************************/
+
+void KDEDocSourceUI::init() {
+ languageButton = new KLanguageButton (this, "languageButton");
+ KDEDocSourceUILayout->addWidget (languageButton, 0, 1);
+ languageLabel->setBuddy (languageButton);
+ QWhatsThis::add (languageButton, i18n("With this combo box you select which of the installed languages is used for creating the new dictionary. KMouth will only parse documentation files of this language."));
+
+ loadLanguageList(languageButton);
+
+ ooDictURL->setFilter ("*.dic");
+}
diff --git a/kmouth/wordcompletion/klanguagebutton.cpp b/kmouth/wordcompletion/klanguagebutton.cpp
new file mode 100644
index 0000000..72182d4
--- /dev/null
+++ b/kmouth/wordcompletion/klanguagebutton.cpp
@@ -0,0 +1,238 @@
+/*
+ * klanguagebutton.cpp - Adds some methods for inserting languages.
+ *
+ * Copyright (c) 1999-2000 Hans Petter Bieker <bieker@kde.org>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.trolltech.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#define INCLUDE_MENUITEM_DEF
+#include <qpopupmenu.h>
+#include <kstandarddirs.h>
+
+#include "klanguagebutton.h"
+
+#include <kdebug.h>
+
+
+static inline void checkInsertPos( QPopupMenu *popup, const QString & str,
+ int &index )
+{
+ if ( index == -2 )
+ index = popup->count();
+ if ( index != -1 )
+ return;
+
+ int a = 0;
+ int b = popup->count();
+ while ( a <= b )
+ {
+ int w = ( a + b ) / 2;
+
+ int id = popup->idAt( w );
+ int j = str.localeAwareCompare( popup->text( id ) );
+
+ if ( j > 0 )
+ a = w + 1;
+ else
+ b = w - 1;
+ }
+
+ index = a; // it doesn't really matter ... a == b here.
+}
+
+static inline QPopupMenu * checkInsertIndex( QPopupMenu *popup,
+ const QStringList *tags, const QString &submenu )
+{
+ int pos = tags->findIndex( submenu );
+
+ QPopupMenu *pi = 0;
+ if ( pos != -1 )
+ {
+ QMenuItem *p = popup->findItem( pos );
+ pi = p ? p->popup() : 0;
+ }
+ if ( !pi )
+ pi = popup;
+
+ return pi;
+}
+
+
+KLanguageButton::~KLanguageButton()
+{
+ delete m_tags;
+}
+
+KLanguageButton::KLanguageButton( QWidget * parent, const char *name )
+: QPushButton( parent, name ),
+ m_popup( 0 ),
+ m_oldPopup( 0 )
+{
+ m_tags = new QStringList;
+
+ clear();
+}
+
+void KLanguageButton::insertItem( const QIconSet& icon, const QString &text,
+ const QString &tag, const QString &submenu, int index )
+{
+ QPopupMenu *pi = checkInsertIndex( m_popup, m_tags, submenu );
+ checkInsertPos( pi, text, index );
+ pi->insertItem( icon, text, count(), index );
+ m_tags->append( tag );
+}
+
+void KLanguageButton::insertItem( const QString &text, const QString &tag,
+ const QString &submenu, int index )
+{
+ QPopupMenu *pi = checkInsertIndex( m_popup, m_tags, submenu );
+ checkInsertPos( pi, text, index );
+ pi->insertItem( text, count(), index );
+ m_tags->append( tag );
+}
+
+void KLanguageButton::insertSeparator( const QString &submenu, int index )
+{
+ QPopupMenu *pi = checkInsertIndex( m_popup, m_tags, submenu );
+ pi->insertSeparator( index );
+ m_tags->append( QString::null );
+}
+
+void KLanguageButton::insertSubmenu( const QString &text, const QString &tag,
+ const QString &submenu, int index )
+{
+ QPopupMenu *pi = checkInsertIndex( m_popup, m_tags, submenu );
+ QPopupMenu *p = new QPopupMenu( pi );
+ checkInsertPos( pi, text, index );
+ pi->insertItem( text, p, count(), index );
+ m_tags->append( tag );
+ connect( p, SIGNAL( activated( int ) ),
+ SLOT( slotActivated( int ) ) );
+ connect( p, SIGNAL( highlighted( int ) ), this,
+ SIGNAL( highlighted( int ) ) );
+}
+
+void KLanguageButton::insertLanguage( const QString& path, const QString& name,
+ const QString& sub, const QString &submenu, int index )
+{
+ QString output = name + QString::fromLatin1( " (" ) + path +
+ QString::fromLatin1( ")" );
+#if 0
+ // Nooooo ! Country != language
+ QPixmap flag( locate( "locale", sub + path +
+ QString::fromLatin1( "/flag.png" ) ) );
+#endif
+ insertItem( output, path, submenu, index );
+}
+
+void KLanguageButton::slotActivated( int index )
+{
+ // Update caption and iconset:
+ if ( m_current == index )
+ return;
+
+ setCurrentItem( index );
+
+ // Forward event from popup menu as if it was emitted from this widget:
+ emit activated( index );
+}
+
+int KLanguageButton::count() const
+{
+ return m_tags->count();
+}
+
+void KLanguageButton::clear()
+{
+ m_tags->clear();
+
+ delete m_oldPopup;
+ m_oldPopup = m_popup;
+ m_popup = new QPopupMenu( this );
+
+ setPopup( m_popup );
+
+ connect( m_popup, SIGNAL( activated( int ) ),
+ SLOT( slotActivated( int ) ) );
+ connect( m_popup, SIGNAL( highlighted( int ) ),
+ SIGNAL( highlighted( int ) ) );
+
+ setText( QString::null );
+ setIconSet( QIconSet() );
+}
+
+/*void KLanguageButton::changeLanguage( const QString& name, int i )
+{
+ if ( i < 0 || i >= count() )
+ return;
+ QString output = name + QString::fromLatin1( " (" ) + tag( i ) +
+ QString::fromLatin1( ")" );
+ changeItem( output, i );
+}*/
+
+bool KLanguageButton::containsTag( const QString &str ) const
+{
+ return m_tags->contains( str ) > 0;
+}
+
+QString KLanguageButton::currentTag() const
+{
+ return *m_tags->at( currentItem() );
+}
+
+QString KLanguageButton::tag( int i ) const
+{
+ if ( i < 0 || i >= count() )
+ {
+ kdDebug() << "KLanguageButton::tag(), unknown tag " << i << endl;
+ return QString::null;
+ }
+ return *m_tags->at( i );
+}
+
+int KLanguageButton::currentItem() const
+{
+ return m_current;
+}
+
+void KLanguageButton::setCurrentItem( int i )
+{
+ if ( i < 0 || i >= count() )
+ return;
+ m_current = i;
+
+ setText( m_popup->text( m_current ) );
+ QIconSet *icon = m_popup->iconSet( m_current );
+ if( icon )
+ setIconSet( *icon );
+ else
+ setIconSet( QPixmap() );
+}
+
+void KLanguageButton::setCurrentItem( const QString &code )
+{
+ int i = m_tags->findIndex( code );
+ if ( code.isNull() )
+ i = 0;
+ if ( i != -1 )
+ setCurrentItem( i );
+}
+
+#include "klanguagebutton.moc"
diff --git a/kmouth/wordcompletion/klanguagebutton.h b/kmouth/wordcompletion/klanguagebutton.h
new file mode 100644
index 0000000..ee1d58f
--- /dev/null
+++ b/kmouth/wordcompletion/klanguagebutton.h
@@ -0,0 +1,93 @@
+/*
+ * klangbutton.h - Button with language selection drop down menu.
+ * Derived from the KLangCombo class by Hans Petter Bieker.
+ *
+ * Copyright (c) 1999-2000 Hans Petter Bieker <bieker@kde.org>
+ * (c) 2001 Martijn Klingens <mklingens@yahoo.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifndef __KLANGBUTTON_H__
+#define __KLANGBUTTON_H__
+
+#include "kpushbutton.h"
+
+/*
+ * Extended QPushButton that shows a menu with submenu for language selection.
+ * Essentially just a combo box with a 2-D dataset, but using a real
+ * QComboBox will produce ugly results.
+ *
+ * Combined version of KTagCombo and KLanguageCombo but using a QPushButton
+ * instead.
+ */
+class KLanguageButton : public QPushButton
+{
+ Q_OBJECT
+
+public:
+ KLanguageButton(QWidget *parent=0, const char *name=0);
+ ~KLanguageButton();
+
+ void insertItem( const QIconSet& icon, const QString &text,
+ const QString &tag, const QString &submenu = QString::null,
+ int index = -1 );
+ void insertItem( const QString &text, const QString &tag,
+ const QString &submenu = QString::null, int index = -1 );
+ void insertSeparator( const QString &submenu = QString::null,
+ int index = -1 );
+ void insertSubmenu( const QString &text, const QString &tag,
+ const QString &submenu = QString::null, int index = -1);
+
+ int count() const;
+ void clear();
+
+ void insertLanguage( const QString& path, const QString& name,
+ const QString& sub = QString::null,
+ const QString &submenu = QString::null, int index = -1);
+
+ /*
+ * Tag of the selected item
+ */
+ QString currentTag() const;
+ QString tag( int i ) const;
+ bool containsTag( const QString &str ) const;
+
+ /*
+ * Set the current item
+ */
+ int currentItem() const;
+ void setCurrentItem( int i );
+ void setCurrentItem( const QString &code );
+
+signals:
+ void activated( int index );
+ void highlighted( int index );
+
+private slots:
+ void slotActivated( int );
+
+private:
+ // work space for the new class
+ QStringList *m_tags;
+ QPopupMenu *m_popup, *m_oldPopup;
+ int m_current;
+};
+
+#endif
diff --git a/kmouth/wordcompletion/klanguagebuttonhelper.cpp b/kmouth/wordcompletion/klanguagebuttonhelper.cpp
new file mode 100644
index 0000000..918553e
--- /dev/null
+++ b/kmouth/wordcompletion/klanguagebuttonhelper.cpp
@@ -0,0 +1,64 @@
+/*
+ * klanguagebuttonhelper.cpp - Methods that help filling the KLanguageButton with data.
+ *
+ * Copyright (c) 2003 Gunnar Schmi Dt <gunnar@schmi-dt.de>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.trolltech.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "klanguagebuttonhelper.h"
+
+#include <kglobal.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <ksimpleconfig.h>
+#include "klanguagebutton.h"
+
+QString languageName (QString languageCode) {
+ QString filename = KGlobal::dirs()->findResource("locale",
+ languageCode + QString::fromLatin1("/entry.desktop"));
+
+ KSimpleConfig entry(filename);
+ entry.setGroup(QString::fromLatin1("KCM Locale"));
+ return entry.readEntry(QString::fromLatin1("Name"), i18n("without name"));
+}
+
+void loadLanguageList(KLanguageButton *combo)
+// This function was taken from kdebase/kcontrol/kdm/kdm-appear.cpp
+{
+ QStringList langlist = KGlobal::dirs()->findAllResources("locale",
+ QString::fromLatin1("*/entry.desktop"));
+ langlist.sort();
+ for ( QStringList::ConstIterator it = langlist.begin();
+ it != langlist.end(); ++it )
+ {
+ QString fpath = (*it).left((*it).length() - 14);
+ int index = fpath.findRev('/');
+ QString nid = fpath.mid(index + 1);
+
+ KSimpleConfig entry(*it);
+ entry.setGroup(QString::fromLatin1("KCM Locale"));
+ QString name = entry.readEntry(QString::fromLatin1("Name"), i18n("without name"));
+ combo->insertLanguage(nid, name, QString::fromLatin1("l10n/"), QString::null);
+ }
+
+ if (KGlobal::locale())
+ combo->setCurrentItem (KGlobal::locale()->language());
+ else
+ combo->setCurrentItem (KLocale::defaultLanguage());
+}
diff --git a/kmouth/wordcompletion/klanguagebuttonhelper.h b/kmouth/wordcompletion/klanguagebuttonhelper.h
new file mode 100644
index 0000000..9bee5f7
--- /dev/null
+++ b/kmouth/wordcompletion/klanguagebuttonhelper.h
@@ -0,0 +1,28 @@
+/*
+ * klanguagebuttonhelper.h - Methods that help filling the KLanguageButton with data.
+ *
+ * Copyright (c) 2003 Gunnar Schmi Dt <gunnar@schmi-dt.de>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+class QString;
+class KLanguageButton;
+
+QString languageName (QString languageCode);
+void loadLanguageList(KLanguageButton *combo);
diff --git a/kmouth/wordcompletion/wordcompletion.cpp b/kmouth/wordcompletion/wordcompletion.cpp
new file mode 100644
index 0000000..d4ae651
--- /dev/null
+++ b/kmouth/wordcompletion/wordcompletion.cpp
@@ -0,0 +1,224 @@
+#include <qregexp.h>
+#include <qfile.h>
+
+#include <kapplication.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+
+#include "wordcompletion.h"
+
+class WordCompletion::WordCompletionPrivate {
+friend class WordCompletion;
+private:
+ typedef QMap<QString,int> WordMap;
+ struct DictionaryDetails {
+ QString filename;
+ QString language;
+ };
+
+ QString lastText;
+ QMap<QString,int> map;
+ QMap<QString,int> addedWords;
+ QMap<QString,DictionaryDetails> dictDetails;
+ QStringList dictionaries;
+ QString current;
+ bool blockCurrentListSignal;
+ bool wordsToSave;
+};
+
+WordCompletion::WordCompletion() : KCompletion () {
+ d = new WordCompletionPrivate();
+ d->blockCurrentListSignal = false;
+ d->wordsToSave = false;
+ configure ();
+}
+
+WordCompletion::~WordCompletion() {
+ save ();
+ delete d;
+}
+
+typedef QPair<int,QString> Match;
+typedef QValueList<Match> MatchList;
+
+QString WordCompletion::makeCompletion(const QString &text) {
+ if (d->lastText != text) {
+ d->lastText = text;
+ KCompletion::clear();
+
+ int border = text.findRev(QRegExp("\\W"));
+ QString suffix = text.right (text.length() - border - 1).lower();
+ QString prefix = text.left (border + 1);
+
+ if (suffix.length() > 0) {
+ MatchList matches;
+ QMap<QString,int>::ConstIterator it;
+ for (it = d->map.begin(); it != d->map.end(); ++it)
+ if (it.key().startsWith(suffix))
+ matches += Match (-it.data(), it.key());
+ qHeapSort(matches);
+
+ MatchList::ConstIterator iter = matches.begin();
+ for (int count = 0; (iter != matches.end()) && (count < 10); ++iter, ++count) {
+ int length = (*iter).second.length() + prefix.length() - text.length();
+ KCompletion::addItem(text + (*iter).second.right(length), -(*iter).first);
+ }
+ }
+ }
+
+ // call the KCompletion::makeCompletion(...) method
+ return KCompletion::makeCompletion (text);
+}
+
+QStringList WordCompletion::wordLists() {
+ return d->dictionaries;
+}
+
+QStringList WordCompletion::wordLists(const QString &language) {
+ QStringList result;
+ for (QStringList::Iterator it = d->dictionaries.begin();
+ it != d->dictionaries.end(); ++it)
+ if (d->dictDetails[*it].language == language)
+ result += *it;
+ return result;
+}
+
+QString WordCompletion::languageOfWordList(const QString &wordlist) {
+ if (d->dictDetails.contains(wordlist))
+ return d->dictDetails[wordlist].language;
+ else
+ return QString::null;
+}
+
+QString WordCompletion::currentWordList() {
+ return d->current;
+}
+
+bool WordCompletion::isConfigured() {
+ KConfig *config = new KConfig("kmouthrc");
+ bool result = config->hasGroup("Dictionary 0");
+ delete config;
+
+ return result;
+}
+
+void WordCompletion::configure() {
+ if (d->wordsToSave)
+ save ();
+ d->wordsToSave = false;
+
+ d->dictionaries.clear();
+ d->dictDetails.clear();
+
+ KConfig *config = new KConfig("kmouthrc");
+ QStringList groups = config->groupList();
+ for (QStringList::Iterator it = groups.begin(); it != groups.end(); ++it)
+ if ((*it).startsWith ("Dictionary ")) {
+ config->setGroup(*it);
+ WordCompletionPrivate::DictionaryDetails details;
+ details.filename = config->readEntry("Filename");
+ details.language = config->readEntry("Language");
+ QString name = config->readEntry("Name");
+ d->dictDetails[name] = details;
+ d->dictionaries += name;
+ }
+ delete config;
+
+ d->blockCurrentListSignal = true;
+ setWordList(d->current);
+ d->blockCurrentListSignal = false;
+ emit wordListsChanged (wordLists());
+ emit currentListChanged (d->current);
+}
+
+bool WordCompletion::setWordList(const QString &wordlist) {
+ if (d->wordsToSave)
+ save ();
+ d->wordsToSave = false;
+
+ d->map.clear();
+ bool result = d->dictDetails.contains (wordlist);
+ if (result)
+ d->current = wordlist;
+ else
+ d->current = d->dictionaries[0];
+
+ QString filename = d->dictDetails[d->current].filename;
+ QString dictionaryFile = KApplication::kApplication()->dirs()->findResource("appdata", filename);
+ QFile file(dictionaryFile);
+ if (file.exists() && file.open(IO_ReadOnly)) {
+ QTextStream stream(&file);
+ stream.setEncoding (QTextStream::UnicodeUTF8);
+ if (!stream.atEnd()) {
+ if (stream.readLine() == "WPDictFile") {
+ while (!stream.atEnd()) {
+ QString s = stream.readLine();
+ if (!(s.isNull() || s.isEmpty())) {
+ QStringList list = QStringList::split("\t", s);
+ bool ok;
+ int weight = list[1].toInt(&ok);
+ if (ok && (weight > 0))
+ d->map [list[0]] = weight;
+ }
+ }
+ }
+ }
+ file.close();
+ }
+ if (!d->blockCurrentListSignal)
+ emit currentListChanged (d->current);
+ d->lastText = "";
+ d->wordsToSave = false;
+ return result;
+}
+
+void WordCompletion::addSentence (const QString &sentence) {
+ QStringList words = QStringList::split(QRegExp("\\W"), sentence);
+
+ QStringList::ConstIterator it;
+ for (it = words.begin(); it != words.end(); ++it) {
+ if (!(*it).contains(QRegExp("\\d|_"))) {
+ QString key = (*it).lower();
+ if (d->map.contains(key))
+ d->map[key] += 1;
+ else
+ d->map[key] = 1;
+ if (d->addedWords.contains(key))
+ d->addedWords[key] += 1;
+ else
+ d->addedWords[key] = 1;
+ }
+ }
+ d->wordsToSave = true;
+}
+
+void WordCompletion::save () {
+ if (d->wordsToSave) {
+ QString filename = d->dictDetails[d->current].filename;
+ QString dictionaryFile = KApplication::kApplication()->dirs()->findResource("appdata", filename);
+ QFile file(dictionaryFile);
+ if (!file.exists())
+ return;
+ if (!file.open(IO_WriteOnly))
+ return;
+
+ QTextStream stream(&file);
+ stream.setEncoding (QTextStream::UnicodeUTF8);
+
+ stream << "WPDictFile\n";
+ QMap<QString,int>::ConstIterator it;
+ for (it = d->map.begin(); it != d->map.end(); ++it) {
+ if (d->addedWords.contains(it.key())) {
+ stream << it.key() << "\t" << d->addedWords[it.key()] << "\t1\n";
+ stream << it.key() << "\t" << it.data() - d->addedWords[it.key()] << "\t2\n";
+ }
+ else
+ stream << it.key() << "\t" << it.data() << "\t2\n";
+ }
+ file.close();
+ d->wordsToSave = false;
+ }
+}
+
+#include "wordcompletion.moc"
+
diff --git a/kmouth/wordcompletion/wordcompletion.h b/kmouth/wordcompletion/wordcompletion.h
new file mode 100644
index 0000000..f0cb812
--- /dev/null
+++ b/kmouth/wordcompletion/wordcompletion.h
@@ -0,0 +1,77 @@
+#ifndef WORDCOMPLETION_H
+#define WORDCOMPLETION_H
+
+#include <kcompletion.h>
+
+/**
+ * This class does completion based on a dictionary of words.
+ */
+class WordCompletion : public KCompletion {
+ friend class WordListWidget;
+ Q_OBJECT
+public:
+ WordCompletion();
+ virtual ~WordCompletion();
+
+ /**
+ * Returns the names for the available word lists
+ */
+ QStringList wordLists();
+
+ /**
+ * Returns the names for those word lists that contain
+ * words of a given language.
+ */
+ QStringList wordLists(const QString &language);
+
+ /**
+ * Returns the language of a given word list.
+ */
+ QString languageOfWordList(const QString &wordlist);
+
+ /**
+ * Returns the name of the currently active word list.
+ */
+ QString currentWordList();
+
+ /**
+ * Finds completions to the given text.
+ */
+ virtual QString makeCompletion(const QString&);
+
+ static bool isConfigured();
+
+ /**
+ * Adds the words from the given sentence to the list of words.
+ */
+ void addSentence (const QString &sentence);
+
+public slots:
+ /**
+ * Re-reads the configuration.
+ */
+ void configure();
+
+ /**
+ * Specify which word list gets used for the actual word completion.
+ * If there is no word list with the given name the first configured
+ * list gets used.
+ * The method returns true if the specified word list was found.
+ */
+ bool setWordList(const QString &wordlist);
+
+ /**
+ * Saves the added words to disk.
+ */
+ void save ();
+
+signals:
+ void wordListsChanged (const QStringList &wordLists);
+ void currentListChanged (const QString &wordList);
+
+private:
+ class WordCompletionPrivate;
+ WordCompletionPrivate *d;
+};
+
+#endif // KURLCOMPLETION_H
diff --git a/kmouth/wordcompletion/wordcompletionui.ui b/kmouth/wordcompletion/wordcompletionui.ui
new file mode 100644
index 0000000..8036272
--- /dev/null
+++ b/kmouth/wordcompletion/wordcompletionui.ui
@@ -0,0 +1,293 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>WordCompletionUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>WordCompletionUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>552</width>
+ <height>252</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>addButton</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Add D&amp;ictionary...</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this button you can add a new dictionary to the list of available dictionaries.</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>deleteButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Delete Dictionary</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this button you delete the selected dictionary.</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>moveUpButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Move &amp;Up</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this button you move the selected dictionary up.</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>moveDownButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Move Down</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this button you move the selected dictionary down.</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>exportButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Export Dictionary...</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this button you export the selected dictionary to a file.</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>240</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KListView">
+ <column>
+ <property name="text">
+ <string>Dictionary</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Language</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>dictionaryList</cstring>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This list contains all available dictionaries for the word completion. KMouth will display a combo box next to the edit field in the main window if this list contains more than one dictionary. You can use this combo box in order to select the dictionary that actually gets used for the word completion.</string>
+ </property>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>selectedDictionaryDetails</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>&amp;Selected Dictionary</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>languageLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Language:</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this combo box you select the language associated with the selected dictionary.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>dictionaryNameLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>dictionaryName</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this input field you specify the name of the selected dictionary.</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>dictionaryName</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>With this input field you specify the name of the selected dictionary.</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+</widget>
+<tabstops>
+ <tabstop>dictionaryList</tabstop>
+ <tabstop>addButton</tabstop>
+ <tabstop>deleteButton</tabstop>
+ <tabstop>moveUpButton</tabstop>
+ <tabstop>moveDownButton</tabstop>
+ <tabstop>exportButton</tabstop>
+ <tabstop>selectedDictionaryDetails</tabstop>
+</tabstops>
+<includes>
+ <include location="global" impldecl="in implementation">kinputdialog.h</include>
+ <include location="local" impldecl="in implementation">klanguagebutton.h</include>
+ <include location="local" impldecl="in implementation">klanguagebuttonhelper.h</include>
+ <include location="local" impldecl="in implementation">wordcompletionui.ui.h</include>
+</includes>
+<forwards>
+ <forward>class KLanguageButton</forward>
+</forwards>
+<variables>
+ <variable access="public">KLanguageButton *languageButton;</variable>
+</variables>
+<slots>
+ <slot access="protected" specifier="non virtual">languageButton_activated( int index )</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>klistview.h</includehint>
+ <includehint>kinputdialog.h</includehint>
+</includehints>
+</UI>
diff --git a/kmouth/wordcompletion/wordcompletionui.ui.h b/kmouth/wordcompletion/wordcompletionui.ui.h
new file mode 100644
index 0000000..96878da
--- /dev/null
+++ b/kmouth/wordcompletion/wordcompletionui.ui.h
@@ -0,0 +1,35 @@
+/****************************************************************************
+** ui.h extension file, included from the uic-generated form implementation.
+**
+** If you wish to add, delete or rename functions or slots use
+** Qt Designer which will update this file, preserving your code. Create an
+** init() function in place of a constructor, and a destroy() function in
+** place of a destructor.
+*****************************************************************************/
+
+
+void WordCompletionUI::init() {
+ languageButton = new KLanguageButton (selectedDictionaryDetails, "languageButton");
+ selectedDictionaryDetailsLayout->addWidget (languageButton, 1, 1);
+ languageLabel->setBuddy (languageButton);
+ QWhatsThis::add (languageButton, i18n("With this combo box you select the language associated with the selected dictionary."));
+
+ loadLanguageList(languageButton);
+ languageButton->insertLanguage("??", i18n("Other"), QString::fromLatin1("l10n/"), QString::null);
+
+ connect (languageButton, SIGNAL(activated(int)), this, SLOT(languageButton_activated(int)));
+}
+
+void WordCompletionUI::languageButton_activated (int) {
+ if (languageButton->currentTag() == "??") {
+ QString customLanguage = KInputDialog::getText(i18n("Create Custom Language"), i18n("Please enter the code for the custom language:"));
+
+ if (languageButton->containsTag(customLanguage)) {
+ languageButton->setCurrentItem(customLanguage);
+ }
+ else {
+ languageButton->insertLanguage(customLanguage, i18n("without name"), QString::fromLatin1("l10n/"), QString::null);
+ languageButton->setCurrentItem(customLanguage);
+ }
+ }
+}
diff --git a/kmouth/wordcompletion/wordcompletionwidget.cpp b/kmouth/wordcompletion/wordcompletionwidget.cpp
new file mode 100644
index 0000000..e5eab23
--- /dev/null
+++ b/kmouth/wordcompletion/wordcompletionwidget.cpp
@@ -0,0 +1,325 @@
+/***************************************************************************
+ wordcompletionwidget.cpp - description
+ -------------------
+ begin : Tue Apr 29 2003
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qlineedit.h>
+
+#include <klistview.h>
+#include <klineedit.h>
+#include <kurlrequester.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+#include <ksimpleconfig.h>
+#include <kfiledialog.h>
+#include <kio/netaccess.h>
+#include <kmessagebox.h>
+
+#include "dictionarycreationwizard.h"
+#include "wordcompletionwidget.h"
+#include "wordcompletion.h"
+#include "klanguagebutton.h"
+
+class DictionaryListItem : public KListViewItem {
+public:
+ DictionaryListItem (QListView *parent, QString filename, QString name, QString language, QString languageCode)
+ : KListViewItem (parent, name) {
+ setFilename (filename);
+ setLanguage (language, languageCode);
+ };
+ DictionaryListItem (QListView *parent, QString filename, QString name, QString languageCode)
+ : KListViewItem (parent, name) {
+ setFilename (filename);
+ setLanguage (languageCode);
+ };
+ DictionaryListItem (QListView *parent, QListViewItem *after, QString filename, QString name, QString languageCode)
+ : KListViewItem (parent, after, name) {
+ setFilename (filename);
+ setLanguage (languageCode);
+ };
+ ~DictionaryListItem () {
+ };
+
+ QString filename() {
+ return myFilename;
+ }
+
+ QString languageCode() {
+ return myLanguageCode;
+ }
+
+ void setFilename(QString filename) {
+ myFilename = filename;
+ }
+
+ void setLanguage (QString languageCode) {
+ QString filename = KGlobal::dirs()->findResource("locale",
+ languageCode + QString::fromLatin1("/entry.desktop"));
+
+ KSimpleConfig entry(filename);
+ entry.setGroup(QString::fromLatin1("KCM Locale"));
+ QString name = entry.readEntry(QString::fromLatin1("Name"), i18n("without name"));
+ setLanguage (name + " (" + languageCode + ")", languageCode);
+ }
+
+ void setLanguage (QString name, QString languageCode) {
+ myLanguageCode = languageCode;
+ setText (1, name);
+ }
+
+private:
+ QString myFilename;
+ QString myLanguageCode;
+};
+
+/***************************************************************************/
+
+WordCompletionWidget::WordCompletionWidget(QWidget *parent, const char *name) : WordCompletionUI (parent, name) {
+ dictionaryList->setSorting (-1); // no sorted list
+
+ // Connect the signals from hte KCMKTTSDWidget to this class
+ connect (addButton, SIGNAL (clicked()), this, SLOT(addDictionary()) );
+ connect (deleteButton, SIGNAL (clicked()), this, SLOT (deleteDictionary()) );
+ connect (moveUpButton, SIGNAL (clicked()), this, SLOT (moveUp()) );
+ connect (moveDownButton, SIGNAL (clicked()), this, SLOT (moveDown()) );
+ connect (exportButton, SIGNAL (clicked()), this, SLOT (exportDictionary()) );
+
+ connect (dictionaryList, SIGNAL (selectionChanged()), this, SLOT (selectionChanged()) );
+ connect (dictionaryName, SIGNAL (textChanged (const QString &)), this, SLOT (nameChanged (const QString &)) );
+ connect (languageButton, SIGNAL (activated (int)), this, SLOT (languageSelected(int)) );
+
+ // Object for the KCMKTTSD configuration
+ config = new KConfig("kmouthrc");
+
+ // Load the configuration from the file
+ load();
+}
+
+/**
+ * Destructor
+ */
+WordCompletionWidget::~WordCompletionWidget() {
+ delete config;
+}
+
+/***************************************************************************/
+
+void WordCompletionWidget::load() {
+ dictionaryList->clear();
+
+ // Set the group general for the configuration of kttsd itself (no plug ins)
+ QStringList groups = config->groupList();
+ DictionaryListItem *last = 0;
+ for (QStringList::Iterator it = groups.begin(); it != groups.end(); ++it)
+ if ((*it).startsWith ("Dictionary ")) {
+ config->setGroup(*it);
+ QString languageTag = config->readEntry("Language");
+ last = new DictionaryListItem (dictionaryList, last,
+ config->readEntry("Filename"),
+ config->readEntry("Name"),
+ languageTag);
+ if (!languageButton->containsTag(languageTag))
+ languageButton->insertLanguage(languageTag, i18n("without name"), QString::fromLatin1("l10n/"), QString::null);
+ }
+
+ // Clean up disc space
+ for (QStringList::Iterator it = newDictionaryFiles.begin(); it != newDictionaryFiles.end(); ++it) {
+ QString filename = KGlobal::dirs()->findResource ("appdata", *it);
+ if (!filename.isEmpty() && !filename.isNull())
+ QFile::remove (filename);
+ }
+ newDictionaryFiles.clear();
+}
+
+void WordCompletionWidget::save() {
+ QStringList groups = config->groupList();
+ for (QStringList::Iterator it = groups.begin(); it != groups.end(); ++it)
+ if ((*it).startsWith ("Dictionary "))
+ config->deleteGroup (*it);
+
+ int number = 0;
+ QListViewItemIterator it(dictionaryList);
+ while (it.current()) {
+ DictionaryListItem *item = dynamic_cast<DictionaryListItem*>(it.current());
+ if (item != 0) {
+ config->setGroup(QString("Dictionary %1").arg(number));
+ config->writeEntry ("Filename", item->filename());
+ config->writeEntry ("Name", item->text (0));
+ config->writeEntry ("Language", item->languageCode());
+ number++;
+ }
+ ++it;
+ }
+ config->sync();
+
+ // Clean up disc space
+ for (QStringList::Iterator it = removedDictionaryFiles.begin(); it != removedDictionaryFiles.end(); ++it) {
+ QString filename = KGlobal::dirs()->findResource ("appdata", *it);
+ if (!filename.isEmpty() && !filename.isNull())
+ QFile::remove (filename);
+ }
+ removedDictionaryFiles.clear();
+}
+
+/***************************************************************************/
+
+void WordCompletionWidget::addDictionary() {
+ QStringList dictionaryNames;
+ QStringList dictionaryFiles;
+ QStringList dictionaryLanguages;
+ QListViewItemIterator it(dictionaryList);
+ while (it.current()) {
+ DictionaryListItem *item = dynamic_cast<DictionaryListItem*>(it.current());
+ if (item != 0) {
+ dictionaryNames += item->text (0);
+ dictionaryFiles += item->filename();
+ dictionaryLanguages += item->languageCode();
+ }
+ ++it;
+ }
+ DictionaryCreationWizard *wizard = new DictionaryCreationWizard (this, "Dictionary creation wizard", dictionaryNames, dictionaryFiles, dictionaryLanguages);
+ if (wizard->exec() == QDialog::Accepted) {
+ QString filename = wizard->createDictionary();
+ newDictionaryFiles += filename;
+ QString languageTag = wizard->language();
+ if (!languageButton->containsTag(languageTag)) {
+ languageButton->insertLanguage(languageTag, i18n("without name"), QString::fromLatin1("l10n/"), QString::null);
+ }
+ KListViewItem *item = new DictionaryListItem (dictionaryList,
+ filename, wizard->name(), languageTag);
+ dictionaryList->setSelected(item, true);
+ }
+ delete wizard;
+}
+
+void WordCompletionWidget::deleteDictionary() {
+ DictionaryListItem *item = dynamic_cast<DictionaryListItem*>(dictionaryList->selectedItem ());
+
+ if (item != 0) {
+ removedDictionaryFiles += item->filename();
+ delete item;
+ }
+}
+
+void WordCompletionWidget::moveUp() {
+ QListViewItem *item = dictionaryList->selectedItem ();
+
+ if (item != 0) {
+ QListViewItem *above = item->itemAbove();
+
+ if (above != 0) {
+ above->moveItem (item);
+ }
+ }
+}
+
+void WordCompletionWidget::moveDown() {
+ QListViewItem *item = dictionaryList->selectedItem ();
+
+ if (item != 0) {
+ QListViewItem *next = item->itemBelow();
+
+ if (next != 0) {
+ item->moveItem (next);
+ }
+ }
+}
+
+void WordCompletionWidget::exportDictionary() {
+ DictionaryListItem *item = dynamic_cast<DictionaryListItem*>(dictionaryList->selectedItem ());
+
+ if (item != 0) {
+ KURL url = KFileDialog::getSaveURL(QString::null, QString::null, this, i18n("Export Dictionary"));
+ if (url.isEmpty() || !url.isValid())
+ return;
+
+ if (KIO::NetAccess::exists(url, false, this)) {
+ if (KMessageBox::warningContinueCancel(0,QString("<qt>%1</qt>").arg(i18n("The file %1 already exists. "
+ "Do you want to overwrite it?").arg(url.url())),i18n("File Exists"),i18n("&Overwrite"))==KMessageBox::Cancel) {
+ return;
+ }
+ }
+ KURL src;
+ src.setPath( KGlobal::dirs()->findResource ("appdata", item->filename()) );
+ KIO::NetAccess::copy (src, url, this);
+ }
+}
+
+void WordCompletionWidget::selectionChanged() {
+ DictionaryListItem *item = dynamic_cast<DictionaryListItem*>(dictionaryList->selectedItem ());
+
+ if (item != 0) {
+ deleteButton->setEnabled(true);
+ moveUpButton->setEnabled(true);
+ moveDownButton->setEnabled(true);
+ exportButton->setEnabled(true);
+ selectedDictionaryDetails->setEnabled(true);
+ languageLabel->setEnabled(true);
+ dictionaryNameLabel->setEnabled(true);
+ dictionaryName->setEnabled(true);
+ languageButton->setEnabled(true);
+
+ dictionaryName->setText(item->text(0));
+ languageButton->setCurrentItem(item->languageCode());
+ }
+ else {
+ deleteButton->setEnabled(false);
+ moveUpButton->setEnabled(false);
+ moveDownButton->setEnabled(false);
+ exportButton->setEnabled(false);
+ selectedDictionaryDetails->setEnabled(false);
+ languageLabel->setEnabled(false);
+ dictionaryNameLabel->setEnabled(false);
+ dictionaryName->setEnabled(false);
+ languageButton->setEnabled(false);
+
+ dictionaryName->setText("");
+ languageButton->setText("");
+ }
+}
+
+void WordCompletionWidget::nameChanged (const QString &text) {
+ QListViewItem *item = dictionaryList->selectedItem ();
+
+ if (item != 0) {
+ QString old = item->text(0);
+
+ if (old != text) {
+ item->setText(0, text);
+ emit changed(true);
+ }
+ }
+}
+
+void WordCompletionWidget::languageSelected (int) {
+ DictionaryListItem *item = dynamic_cast<DictionaryListItem*>(dictionaryList->selectedItem ());
+
+ if (item != 0) {
+ QString old = item->text(1);
+ QString text = languageButton->currentTag();
+
+ if (old != text) {
+ item->setLanguage(languageButton->text(), text);
+ emit changed(true);
+ }
+ }
+}
+
+#include "wordcompletionwidget.moc"
diff --git a/kmouth/wordcompletion/wordcompletionwidget.h b/kmouth/wordcompletion/wordcompletionwidget.h
new file mode 100644
index 0000000..574a4e9
--- /dev/null
+++ b/kmouth/wordcompletion/wordcompletionwidget.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ wordcompletionwidget.h - description
+ -------------------
+ begin : Tue Apr 29 2003
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// $Id$
+
+#ifndef WORDCOMPLETIONWIDGET_H
+#define WORDCOMPLETIONWIDGET_H
+
+#include "wordcompletionui.h"
+class WordCompletion;
+class KLanguageButton;
+
+/**
+ * This class represents a configuration widget for managing dictionaries.
+ * @author Gunnar Schmi Dt
+ */
+class WordCompletionWidget : public WordCompletionUI {
+ Q_OBJECT
+public:
+ WordCompletionWidget(QWidget *parent, const char *name);
+ ~WordCompletionWidget();
+
+ /**
+ * This method is invoked whenever the widget should read its configuration
+ * from a config file and update the user interface.
+ */
+ void load();
+
+ /**
+ * This function gets called when the user wants to save the settings in
+ * the user interface, updating the config files.
+ */
+ void save();
+
+signals:
+ void changed (bool);
+
+private slots:
+ void addDictionary();
+ void deleteDictionary();
+ void moveUp();
+ void moveDown();
+ void exportDictionary();
+
+ void selectionChanged();
+ void nameChanged (const QString &text);
+ void languageSelected (int);
+
+ /**
+ * This slot is used to emit the signal changed when any widget changes
+ * the configuration
+ */
+ void configChanged() {
+ emit changed(true);
+ };
+
+private:
+ /**
+ * Object holding all the configuration
+ */
+ KConfig *config;
+ QStringList newDictionaryFiles;
+ QStringList removedDictionaryFiles;
+};
+
+#endif
diff --git a/kmouth/wordcompletion/wordlist.cpp b/kmouth/wordcompletion/wordlist.cpp
new file mode 100644
index 0000000..67f05d8
--- /dev/null
+++ b/kmouth/wordcompletion/wordlist.cpp
@@ -0,0 +1,550 @@
+/***************************************************************************
+ wordlist.cpp - description
+ -------------------
+ begin : Don Sep 12 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// $Id$
+
+#include <qregexp.h>
+#include <qdir.h>
+
+#include <kapplication.h>
+#include <kstandarddirs.h>
+#include <kprogress.h>
+#include <klocale.h>
+
+#include "wordlist.h"
+
+namespace WordList {
+void addWords (WordMap &map, QString line);
+
+XMLParser::XMLParser() {
+}
+
+XMLParser::~XMLParser() {
+}
+
+bool XMLParser::warning (const QXmlParseException &) {
+ return false;
+}
+
+bool XMLParser::error (const QXmlParseException &) {
+ return false;
+}
+
+bool XMLParser::fatalError (const QXmlParseException &) {
+ return false;
+}
+
+QString XMLParser::errorString() {
+ return "";
+}
+
+bool XMLParser::startDocument() {
+ text = QString::null;
+ return true;
+}
+
+bool XMLParser::startElement (const QString &, const QString &,
+ const QString &,
+ const QXmlAttributes &)
+{
+ if (!text.isNull() && !text.isEmpty()) {
+ addWords (list, text);
+ text = QString::null;
+ }
+ return true;
+}
+
+bool XMLParser::characters (const QString &ch) {
+ text += ch;
+ return true;
+}
+
+bool XMLParser::ignorableWhitespace (const QString &) {
+ if (!text.isNull() && !text.isEmpty()) {
+ addWords (list, text);
+ text = QString::null;
+ }
+ return true;
+}
+
+bool XMLParser::endElement (const QString &, const QString &,
+ const QString &)
+{
+ if (!text.isNull() && !text.isEmpty()) {
+ addWords (list, text);
+ text = QString::null;
+ }
+ return true;
+}
+
+bool XMLParser::endDocument() {
+ if (!text.isNull() && !text.isEmpty()) {
+ addWords (list, text);
+ text = QString::null;
+ }
+ return true;
+}
+
+WordMap XMLParser::getList() {
+ return list;
+}
+
+/***************************************************************************/
+
+KProgressDialog *progressDialog() {
+ KProgressDialog *pdlg = new KProgressDialog(0, "progressDialog", i18n("Creating Word List"), i18n("Parsing the KDE documentation..."), false);
+ pdlg->setAllowCancel (false);
+ pdlg->showCancelButton (false);
+ pdlg->setAutoReset(false);
+ pdlg->setAutoClose(false);
+ pdlg->progressBar()->setTotalSteps(100);
+ pdlg->progressBar()->setProgress(0);
+ return pdlg;
+}
+
+bool saveWordList (WordMap map, QString filename) {
+ QFile file(filename);
+ if(!file.open(IO_WriteOnly))
+ return false;
+
+ QTextStream stream(&file);
+ stream.setEncoding (QTextStream::UnicodeUTF8);
+
+ stream << "WPDictFile\n";
+ WordMap::ConstIterator it;
+ for (it = map.begin(); it != map.end(); ++it)
+ stream << it.key() << "\t" << it.data() << "\t2\n";
+ file.close();
+ return true;
+}
+
+/***************************************************************************/
+
+void addWords (WordMap &map, QString line) {
+ QStringList words = QStringList::split(QRegExp("\\W"), line);
+
+ QStringList::ConstIterator it;
+ for (it = words.begin(); it != words.end(); ++it) {
+ if (!(*it).contains(QRegExp("\\d|_"))) {
+ QString key = (*it).lower();
+ if (map.contains(key))
+ map[key] += 1;
+ else
+ map[key] = 1;
+ }
+ }
+}
+
+void addWords (WordMap &map, WordMap add) {
+ WordList::WordMap::ConstIterator it;
+ for (it = add.begin(); it != add.end(); ++it)
+ if (map.contains(it.key()))
+ map[it.key()] += it.data();
+ else
+ map[it.key()] = it.data();
+}
+
+void addWordsFromFile (WordMap &map, QString filename, QTextStream::Encoding encoding, QTextCodec *codec) {
+ QFile xmlfile(filename);
+ QXmlInputSource source (&xmlfile);
+ XMLParser parser;
+ QXmlSimpleReader reader;
+ reader.setFeature ("http://trolltech.com/xml/features/report-start-end-entity", true);
+ reader.setContentHandler (&parser);
+
+ WordMap words;
+ if (reader.parse(source)) // try to load the file as an xml-file
+ addWords(map, parser.getList());
+ else {
+ QFile wpdfile(filename);
+ if (wpdfile.open(IO_ReadOnly)) {
+ QTextStream stream(&wpdfile);
+ stream.setEncoding (QTextStream::UnicodeUTF8);
+
+ if (!stream.atEnd()) {
+ QString s = stream.readLine();
+ if (s == "WPDictFile") { // Contains the file a weighted word list?
+ // We can assume that weighted word lists are always UTF8 coded.
+ while (!stream.atEnd()) {
+ QString s = stream.readLine();
+ if (!(s.isNull() || s.isEmpty())) {
+ QStringList list = QStringList::split("\t", s);
+ bool ok;
+ int weight = list[1].toInt(&ok);
+ if (ok && (weight > 0)) {
+ if (map.contains(list[0]))
+ map[list[0]] += weight;
+ else
+ map[list[0]] = weight;
+ }
+ }
+ }
+ }
+ else { // Count the words in an ordinary text file
+ QFile file(filename);
+ if (file.open(IO_ReadOnly)) {
+ QTextStream stream(&file);
+ if (codec != 0)
+ stream.setCodec (codec);
+ else
+ stream.setEncoding (encoding);
+ while (!stream.atEnd())
+ addWords (map, stream.readLine());
+ }
+ }
+ }
+ }
+ }
+}
+
+}
+#include <kdebug.h>
+namespace WordList {
+
+WordMap parseFiles (QStringList files, QTextStream::Encoding encoding, QTextCodec *codec, KProgressDialog *pdlg) {
+ int progress = 0;
+ int steps = files.count();
+ int percent = 0;
+
+ WordMap map;
+ QStringList::ConstIterator it;
+ for (progress = 1, it = files.begin(); it != files.end(); ++progress, ++it) {
+ addWordsFromFile (map, *it, encoding, codec);
+
+ if (steps != 0 && progress*100/steps > percent) {
+ percent = progress*100/steps;
+ pdlg->progressBar()->setProgress(percent);
+ qApp->processEvents (20);
+ }
+ }
+ return map;
+}
+
+WordMap mergeFiles (QMap<QString,int> files, KProgressDialog *pdlg) {
+ pdlg->setLabel (i18n("Merging dictionaries..."));
+ pdlg->show();
+ qApp->processEvents (20);
+
+ int progress = 0;
+ int steps = files.count();
+ int percent = 0;
+ float totalWeight = 0;
+ long long maxWeight = 0;
+
+ QMap<QString,float> map;
+ QMap<QString,int>::ConstIterator it;
+ for (progress = 1, it = files.begin(); it != files.end(); ++progress, ++it) {
+ WordMap fileMap;
+ addWordsFromFile (fileMap, it.key(), QTextStream::UnicodeUTF8, 0);
+
+ long long weight = 0;
+ WordMap::ConstIterator iter;
+ for (iter = fileMap.begin(); iter != fileMap.end(); ++iter)
+ weight += iter.data();
+ float factor = 1.0 * it.data() / weight;
+ totalWeight += it.data();
+ if (weight > maxWeight)
+ maxWeight = weight;
+
+ for (iter = fileMap.begin(); iter != fileMap.end(); ++iter)
+ if (map.contains(iter.key()))
+ map[iter.key()] += iter.data() * factor;
+ else
+ map[iter.key()] = iter.data() * factor;
+
+ if (steps != 0 && progress*100/steps > percent) {
+ percent = progress*100/steps;
+ pdlg->progressBar()->setProgress(percent);
+ qApp->processEvents (20);
+ }
+ }
+
+ float factor;
+ if (1.0 * maxWeight * totalWeight > 1000000000)
+ factor = 1000000000 / totalWeight;
+ else
+ factor = 1.0 * maxWeight;
+
+ WordMap resultMap;
+ QMap<QString,float>::ConstIterator iter;
+ for (iter = map.begin(); iter != map.end(); ++iter)
+ resultMap[iter.key()] = (int)(factor * iter.data() + 0.5);
+
+ return resultMap;
+}
+
+WordMap parseKDEDoc (QString language, KProgressDialog *pdlg) {
+ pdlg->setLabel (i18n("Parsing the KDE documentation..."));
+ pdlg->show();
+ qApp->processEvents (20);
+
+ QStringList files = KApplication::kApplication()->dirs()->findAllResources ("html", language + "/*.docbook", true, true);
+ if ((files.count() == 0) && (language.length() == 5)) {
+ language = language.left(2);
+ files = KApplication::kApplication()->dirs()->findAllResources ("html", language + "/*.docbook", true, true);
+ }
+
+ return parseFiles (files, QTextStream::UnicodeUTF8, 0, pdlg);
+}
+
+WordMap parseFile (QString filename, QTextStream::Encoding encoding, QTextCodec *codec, KProgressDialog *pdlg) {
+ pdlg->setLabel (i18n("Parsing file..."));
+ pdlg->show();
+ qApp->processEvents (20);
+
+ QStringList files = filename;
+
+ return parseFiles (files, encoding, codec, pdlg);
+}
+
+WordMap parseDir (QString directory, QTextStream::Encoding encoding, QTextCodec *codec, KProgressDialog *pdlg) {
+ pdlg->setLabel (i18n("Parsing directory..."));
+ pdlg->show();
+ qApp->processEvents (20);
+
+ QStringList directories;
+ directories += directory;
+ QStringList files;
+ for (QStringList::Iterator it = directories.begin(); it != directories.end(); it = directories.remove(it)) {
+ QDir dir(*it);
+ const QFileInfoList *entries = dir.entryInfoList ("*", QDir::Dirs | QDir::Files | QDir::NoSymLinks | QDir::Readable);
+ if (entries != 0) {
+ QFileInfoListIterator iter (*entries);
+ while ((iter.current()) != 0) {
+ QString name = iter.current()->fileName();
+ if (name != "." && name != "..") {
+ if (iter.current()->isDir())
+ directories += iter.current()->filePath ();
+ else
+ files += iter.current()->filePath ();
+ }
+ ++iter;
+ }
+ }
+ }
+
+ return parseFiles (files, encoding, codec, pdlg);
+}
+
+/***************************************************************************/
+
+/* Structures used for storing *.aff files (part of OpenOffice.org dictionaries)
+ */
+struct AffEntry {
+ bool cross;
+ int charsToRemove;
+ QString add;
+ QStringList condition;
+};
+typedef QValueList<AffEntry> AffList;
+typedef QMap<QChar,AffList> AffMap;
+
+/** Loads an *.aff file (part of OpenOffice.org dictionaries)
+ */
+void loadAffFile(const QString &filename, AffMap &prefixes, AffMap &suffixes) {
+ bool cross = false;
+
+ QFile afile(filename);
+ if (afile.open(IO_ReadOnly)) {
+ QTextStream stream(&afile);
+ while (!stream.atEnd()) {
+ QString s = stream.readLine();
+ QStringList fields = QStringList::split(QRegExp("\\s"), s);
+
+ if (fields.count() == 4) {
+ cross = (fields[2] == "Y");
+ }
+ else {
+ if (fields.count() >= 5) {
+ AffEntry e;
+ e.cross = cross;
+ if (fields[2] == "0")
+ e.charsToRemove = 0;
+ else
+ e.charsToRemove = fields[2].length();
+ e.add = fields[3];
+
+ if (fields[4] != ".") {
+ QString condition = fields[4];
+ for (uint idx = 0; idx < condition.length(); ++idx) {
+ if (condition[idx] == '[') {
+ QString code;
+ for (++idx; (idx < condition.length()) && condition[idx] != ']'; ++idx)
+ code += condition[idx];
+ e.condition << code;
+ }
+ else
+ e.condition << QString(condition[idx]);
+ }
+ }
+
+ if (s.startsWith("PFX")) {
+ AffList list;
+ if (prefixes.contains (fields[1][0]))
+ list = prefixes[fields[1][0]];
+ list << e;
+ prefixes[fields[1][0]] = list;
+ }
+ else if (s.startsWith("SFX")) {
+ AffList list;
+ if (suffixes.contains (fields[1][0]))
+ list = suffixes[fields[1][0]];
+ list << e;
+ suffixes[fields[1][0]] = list;
+ }
+ }
+ }
+ }
+ }
+}
+
+/** Checks if the given word matches the given condition. Each entry of the
+ * QStringList "condition" describes one character of the word. (If the word
+ * has more characters than condition entries only the last characters are
+ * compared).
+ * Each entry contains either all valid characters (if it does _not_ start
+ * with "^") or all invalid characters (if it starts with "^").
+ */
+inline bool checkCondition (const QString &word, const QStringList &condition) {
+ if (condition.count() == 0)
+ return true;
+
+ if (word.length() < condition.count())
+ return false;
+
+ QStringList::ConstIterator it;
+ int idx;
+ for (it = condition.begin(), idx = word.length()-condition.count();
+ it != condition.end();
+ ++it, ++idx)
+ {
+ if ((*it).contains(word[idx]) == ((*it)[0] == '^'))
+ return false;
+ }
+ return true;
+}
+
+/** Constructs words by adding suffixes to the given word, and copies the
+ * resulting words from map to checkedMap.
+ * @param modifiers discribes which suffixes are valid
+ * @param cross true if the word has a prefix
+ */
+inline void checkWord(const QString &word, const QString &modifiers, bool cross, const WordMap &map, WordMap &checkedMap, const AffMap &suffixes) {
+ for (uint i = 0; i < modifiers.length(); i++) {
+ if (suffixes.contains(modifiers[i])) {
+ AffList sList = suffixes[modifiers[i]];
+
+ AffList::ConstIterator sIt;
+ for (sIt = sList.begin(); sIt != sList.end(); ++sIt) {
+ if (((*sIt).cross || !cross)
+ && (checkCondition(word, (*sIt).condition)))
+ {
+ QString sWord = word.left(word.length()-(*sIt).charsToRemove) + (*sIt).add;
+ if (map.contains(sWord))
+ checkedMap[sWord] = map[sWord];
+ }
+ }
+ }
+ }
+}
+
+/** Constructs words by adding pre- and suffixes to the given word, and
+ * copies the resulting words from map to checkedMap.
+ * @param modifiers discribes which pre- and suffixes are valid
+ */
+void checkWord (const QString &word, const QString &modifiers, const WordMap &map, WordMap &checkedMap, const AffMap &prefixes, const AffMap &suffixes) {
+ if (map.contains(word))
+ checkedMap[word] = map[word];
+
+ checkWord(word, modifiers, true, map, checkedMap, suffixes);
+
+ for (uint i = 0; i < modifiers.length(); i++) {
+ if (prefixes.contains(modifiers[i])) {
+ AffList pList = prefixes[modifiers[i]];
+
+ AffList::ConstIterator pIt;
+ for (pIt = pList.begin(); pIt != pList.end(); ++pIt) {
+ QString pWord = (*pIt).add + word;
+ if (map.contains(pWord))
+ checkedMap[pWord] = map[pWord];
+
+ checkWord(pWord, modifiers, false, map, checkedMap, suffixes);
+ }
+ }
+ }
+}
+
+WordMap spellCheck (WordMap map, QString dictionary, KProgressDialog *pdlg) {
+
+ if (dictionary.endsWith(".dic")) {
+ AffMap prefixes;
+ AffMap suffixes;
+ WordMap checkedMap;
+ loadAffFile (dictionary.left(dictionary.length()-4) + ".aff", prefixes, suffixes);
+
+ pdlg->progressBar()->reset();
+ pdlg->setAllowCancel (false);
+ pdlg->showCancelButton (false);
+ pdlg->setAutoReset(false);
+ pdlg->setAutoClose(false);
+ pdlg->setLabel (i18n("Performing spell check..."));
+ pdlg->progressBar()->setTotalSteps(100);
+ pdlg->progressBar()->setProgress(0);
+ qApp->processEvents (20);
+ int progress = 0;
+ int steps = 0;
+ int percent = 0;
+
+ QFile dfile(dictionary);
+ if (dfile.open(IO_ReadOnly)) {
+ QTextStream stream(&dfile);
+
+ if (!stream.atEnd()) {
+ QString s = stream.readLine(); // Number of words
+ steps = s.toInt();
+ }
+
+ while (!stream.atEnd()) {
+ QString s = stream.readLine();
+ if (s.contains("/")) {
+ QString word = s.left(s.find("/")).lower();
+ QString modifiers = s.right(s.length() - s.find("/"));
+
+ checkWord(word, modifiers, map, checkedMap, prefixes, suffixes);
+ }
+ else {
+ if (!s.isEmpty() && !s.isNull() && map.contains(s.lower()))
+ checkedMap[s.lower()] = map[s.lower()];
+ }
+
+ progress++;
+ if (steps != 0 && progress*100/steps > percent) {
+ percent = progress*100/steps;
+ pdlg->progressBar()->setProgress(percent);
+ qApp->processEvents (20);
+ }
+ }
+ }
+
+ return checkedMap;
+ }
+ else
+ return map;
+}
+
+}
+
diff --git a/kmouth/wordcompletion/wordlist.h b/kmouth/wordcompletion/wordlist.h
new file mode 100644
index 0000000..d2f85ac
--- /dev/null
+++ b/kmouth/wordcompletion/wordlist.h
@@ -0,0 +1,92 @@
+/***************************************************************************
+ wordlist.h - description
+ -------------------
+ begin : Don Sep 12 2002
+ copyright : (C) 2002 by Gunnar Schmi Dt
+ email : kmouth@schmi-dt.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// $Id$
+
+#ifndef WORDLIST_H
+#define WORDLIST_H
+
+#include <qxml.h>
+#include <qvaluestack.h>
+#include <qstring.h>
+#include <qobject.h>
+#include <qmap.h>
+
+class QTextCodec;
+class KProgressDialog;
+
+namespace WordList {
+
+typedef QMap<QString,int> WordMap;
+
+KProgressDialog *progressDialog();
+
+WordMap parseKDEDoc (QString language, KProgressDialog *pdlg);
+WordMap parseFile (QString filename, QTextStream::Encoding encoding, QTextCodec *codec, KProgressDialog *pdlg);
+WordMap parseDir (QString directory, QTextStream::Encoding encoding, QTextCodec *codec, KProgressDialog *pdlg);
+WordMap mergeFiles (QMap<QString,int> files, KProgressDialog *pdlg);
+
+WordMap spellCheck (WordMap wordlist, QString dictionary, KProgressDialog *pdlg);
+
+bool saveWordList (WordMap map, QString filename);
+
+/**
+ * This class implements a parser for reading docbooks and generating word
+ * lists. It is intended to be used together with the Qt SAX2 framework.
+ * @author Gunnar Schmi Dt
+ */
+
+class XMLParser : public QXmlDefaultHandler {
+public:
+ XMLParser();
+ ~XMLParser();
+
+ bool warning (const QXmlParseException &exception);
+ bool error (const QXmlParseException &exception);
+ bool fatalError (const QXmlParseException &exception);
+ QString errorString();
+
+ /** Processes the start of the document. */
+ bool startDocument();
+
+ /** Processes the start tag of an element. */
+ bool startElement (const QString &, const QString &, const QString &name,
+ const QXmlAttributes &attributes);
+
+ /** Processes a chunk of normal character data. */
+ bool characters (const QString &ch);
+
+ /** Processes whitespace. */
+ bool ignorableWhitespace (const QString &ch);
+
+ /** Processes the end tag of an element. */
+ bool endElement (const QString &, const QString &, const QString &name);
+
+ /** Processes the end of the document. */
+ bool endDocument();
+
+ /** returns a list of words */
+ WordMap getList();
+
+private:
+ WordMap list;
+ QString text;
+};
+
+}
+
+#endif