summaryrefslogtreecommitdiffstats
path: root/kanagram
diff options
context:
space:
mode:
Diffstat (limited to 'kanagram')
-rw-r--r--kanagram/DATA_FILE_TRANSLATION.readme26
-rw-r--r--kanagram/Doxyfile275
-rw-r--r--kanagram/Makefile.am1
-rw-r--r--kanagram/TODO31
-rw-r--r--kanagram/data/Makefile.am2
-rw-r--r--kanagram/data/animals.kvtml185
-rw-r--r--kanagram/data/clothing.kvtml116
-rw-r--r--kanagram/data/computers.kvtml107
-rw-r--r--kanagram/data/currencies.kvtml128
-rw-r--r--kanagram/data/fruits.kvtml137
-rw-r--r--kanagram/data/inventions.kvtml149
-rw-r--r--kanagram/data/objects.kvtml152
-rw-r--r--kanagram/data/people.kvtml116
-rw-r--r--kanagram/data/professions.kvtml185
-rw-r--r--kanagram/data/space.kvtml152
-rw-r--r--kanagram/data/sports.kvtml158
-rw-r--r--kanagram/data/transportation.kvtml128
-rw-r--r--kanagram/data/vegetables.kvtml152
-rw-r--r--kanagram/data/worldcapitals.kvtml221
-rw-r--r--kanagram/icons/Makefile.am1
-rw-r--r--kanagram/icons/hi128-app-kanagram.pngbin0 -> 17002 bytes
-rw-r--r--kanagram/icons/hi16-app-kanagram.pngbin0 -> 848 bytes
-rw-r--r--kanagram/icons/hi22-app-kanagram.pngbin0 -> 1381 bytes
-rw-r--r--kanagram/icons/hi32-app-kanagram.pngbin0 -> 2389 bytes
-rw-r--r--kanagram/icons/hi48-app-kanagram.pngbin0 -> 4297 bytes
-rw-r--r--kanagram/icons/hisc-app-kanagram.svgzbin0 -> 9983 bytes
-rw-r--r--kanagram/images/Makefile.am2
-rw-r--r--kanagram/images/appicon.pngbin0 -> 1308 bytes
-rw-r--r--kanagram/images/appiconover.pngbin0 -> 1204 bytes
-rw-r--r--kanagram/images/arrow.pngbin0 -> 496 bytes
-rw-r--r--kanagram/images/arrowover.pngbin0 -> 461 bytes
-rw-r--r--kanagram/images/basicarrow.pngbin0 -> 340 bytes
-rw-r--r--kanagram/images/basicarrowover.pngbin0 -> 236 bytes
-rw-r--r--kanagram/images/card.pngbin0 -> 1412 bytes
-rw-r--r--kanagram/images/config.pngbin0 -> 1104 bytes
-rw-r--r--kanagram/images/configover.pngbin0 -> 1150 bytes
-rw-r--r--kanagram/images/eyes1.pngbin0 -> 3964 bytes
-rw-r--r--kanagram/images/eyes2.pngbin0 -> 3944 bytes
-rw-r--r--kanagram/images/eyes3.pngbin0 -> 4005 bytes
-rw-r--r--kanagram/images/eyes4.pngbin0 -> 3949 bytes
-rw-r--r--kanagram/images/eyes5.pngbin0 -> 4214 bytes
-rw-r--r--kanagram/images/eyes6.pngbin0 -> 4488 bytes
-rw-r--r--kanagram/images/eyes7.pngbin0 -> 4029 bytes
-rw-r--r--kanagram/images/eyes8.pngbin0 -> 3857 bytes
-rw-r--r--kanagram/images/graphics_sources.tar.gzbin0 -> 61901 bytes
-rw-r--r--kanagram/images/handbookicon.pngbin0 -> 1131 bytes
-rw-r--r--kanagram/images/handbookiconover.pngbin0 -> 975 bytes
-rw-r--r--kanagram/images/help.pngbin0 -> 1272 bytes
-rw-r--r--kanagram/images/helpover.pngbin0 -> 1309 bytes
-rw-r--r--kanagram/images/hint.pngbin0 -> 3948 bytes
-rw-r--r--kanagram/images/kanagram.pngbin0 -> 22547 bytes
-rw-r--r--kanagram/images/kicon.pngbin0 -> 1685 bytes
-rw-r--r--kanagram/images/kiconover.pngbin0 -> 1493 bytes
-rw-r--r--kanagram/images/next.pngbin0 -> 749 bytes
-rw-r--r--kanagram/images/nextover.pngbin0 -> 766 bytes
-rw-r--r--kanagram/images/quit.pngbin0 -> 1604 bytes
-rw-r--r--kanagram/images/quitover.pngbin0 -> 1705 bytes
-rw-r--r--kanagram/images/up.pngbin0 -> 478 bytes
-rw-r--r--kanagram/images/updisabled.pngbin0 -> 483 bytes
-rw-r--r--kanagram/images/upover.pngbin0 -> 357 bytes
-rw-r--r--kanagram/sounds/Makefile.am2
-rw-r--r--kanagram/sounds/chalk.oggbin0 -> 56048 bytes
-rw-r--r--kanagram/sounds/right.oggbin0 -> 18874 bytes
-rw-r--r--kanagram/sounds/wrong.oggbin0 -> 13093 bytes
-rw-r--r--kanagram/src/Makefile.am43
-rw-r--r--kanagram/src/fontutils.cpp24
-rw-r--r--kanagram/src/fontutils.h18
-rw-r--r--kanagram/src/grammarmanager.cpp503
-rw-r--r--kanagram/src/grammarmanager.h215
-rw-r--r--kanagram/src/kanagram.cpp787
-rw-r--r--kanagram/src/kanagram.desktop120
-rw-r--r--kanagram/src/kanagram.h134
-rw-r--r--kanagram/src/kanagram.kcfg26
-rw-r--r--kanagram/src/kanagramgame.cpp209
-rw-r--r--kanagram/src/kanagramgame.h65
-rw-r--r--kanagram/src/kanagramsettings.kcfgc4
-rw-r--r--kanagram/src/keduvocdocument.cpp1111
-rw-r--r--kanagram/src/keduvocdocument.h687
-rw-r--r--kanagram/src/keduvocexpression.cpp792
-rw-r--r--kanagram/src/keduvocexpression.h456
-rw-r--r--kanagram/src/keduvockvtmlreader.cpp1695
-rw-r--r--kanagram/src/keduvockvtmlreader.h121
-rw-r--r--kanagram/src/keduvockvtmlwriter.cpp949
-rw-r--r--kanagram/src/keduvockvtmlwriter.h99
-rw-r--r--kanagram/src/leitnerbox.cpp70
-rw-r--r--kanagram/src/leitnerbox.h49
-rw-r--r--kanagram/src/leitnersystem.cpp192
-rw-r--r--kanagram/src/leitnersystem.h67
-rw-r--r--kanagram/src/leitnersystemview.cpp216
-rw-r--r--kanagram/src/leitnersystemview.h57
-rw-r--r--kanagram/src/main.cpp63
-rw-r--r--kanagram/src/mainsettings.cpp161
-rw-r--r--kanagram/src/mainsettings.h52
-rw-r--r--kanagram/src/mainsettingswidget.ui182
-rw-r--r--kanagram/src/multiplechoice.cpp120
-rw-r--r--kanagram/src/multiplechoice.h74
-rw-r--r--kanagram/src/newstuff.cpp29
-rw-r--r--kanagram/src/newstuff.h18
-rw-r--r--kanagram/src/newstuffdialog.cpp35
-rw-r--r--kanagram/src/newstuffdialog.h17
-rw-r--r--kanagram/src/newstuffwidget.ui62
-rw-r--r--kanagram/src/vocabedit.cpp199
-rw-r--r--kanagram/src/vocabedit.h57
-rw-r--r--kanagram/src/vocabeditwidget.ui228
-rw-r--r--kanagram/src/vocabsettings.cpp93
-rw-r--r--kanagram/src/vocabsettings.h26
-rw-r--r--kanagram/src/vocabsettingswidget.ui117
107 files changed, 12668 insertions, 0 deletions
diff --git a/kanagram/DATA_FILE_TRANSLATION.readme b/kanagram/DATA_FILE_TRANSLATION.readme
new file mode 100644
index 00000000..ffac7de6
--- /dev/null
+++ b/kanagram/DATA_FILE_TRANSLATION.readme
@@ -0,0 +1,26 @@
+In addition to its messages, Kanagram's
+data files need to be translated. You can find these data files (in English)
+in SVN in branches/KDE/3.5/kdeedu/kanagram/data. Please note the
+"translations" don't have to be direct translations. You can add words,
+remove words, translate words, add new files, etc. What is important is to
+have files in every language, not necessarily that they are exact equivalents
+to the English versions.
+
+* Instructions regarding creating translations *
+
+Make a directory called l10n/yourLanguageCode/data/kdeedu/kanagram, and add to
+it the translated .kvtml files and a Makefile.am containing the following
+lines:
+
+txt_DATA = file1.kvtml file2.kvtml file3.kvtml (obviously, replacing the fake
+filenames with the actual filenames of the files you create)
+
+txtdir = $(kde_datadir)/kanagram/data/yourLanguageCode
+
+EXTRA_DIST = $(txt_DATA)
+
+Thanks for your faithful translation efforts. They are greatly appreciated.
+
+--
+Joshua Keel
+Code is poetry.
diff --git a/kanagram/Doxyfile b/kanagram/Doxyfile
new file mode 100644
index 00000000..27b7cf29
--- /dev/null
+++ b/kanagram/Doxyfile
@@ -0,0 +1,275 @@
+# Doxyfile 1.4.1-KDevelop
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = kanagram.kdevelop
+PROJECT_NUMBER = 0.1
+OUTPUT_DIRECTORY =
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = /
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+TAB_SIZE = 8
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = YES
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = /home/joshua/kanagram
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.mm \
+ *.dox \
+ *.C \
+ *.CC \
+ *.C++ \
+ *.II \
+ *.I++ \
+ *.H \
+ *.HH \
+ *.H++ \
+ *.CS \
+ *.PHP \
+ *.PHP3 \
+ *.M \
+ *.MM \
+ *.C \
+ *.H \
+ *.tlh \
+ *.diff \
+ *.patch \
+ *.moc \
+ *.xpm \
+ *.dox
+RECURSIVE = yes
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS = *
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+VERBATIM_HEADERS = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = YES
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = yes
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE = kanagram.tag
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1024
+MAX_DOT_GRAPH_HEIGHT = 1024
+MAX_DOT_GRAPH_DEPTH = 1000
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
diff --git a/kanagram/Makefile.am b/kanagram/Makefile.am
new file mode 100644
index 00000000..5bcc3e71
--- /dev/null
+++ b/kanagram/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = data images src icons sounds
diff --git a/kanagram/TODO b/kanagram/TODO
new file mode 100644
index 00000000..b52ff56d
--- /dev/null
+++ b/kanagram/TODO
@@ -0,0 +1,31 @@
+TODO items for Kanagram:
+------------
+3.5
+------------
+make the gap to the board edge and text smaller?
+have separate position settings for chalk font (different font dynamics move font off position)
+finish khotstuff server, add to app
+
+only have "edit" button if editable vocab selected (not on page initialise, as at present)
+only have active "save" button if changes are to be saved
+on new word press, blank entry box?
+
+------------
+4.0
+------------
+keyboard shortcuts (skip word 'ctrl-n', etc.)
+more words for vocabs!
+different themes (whiteboard, etc)
+animated (quickly) rising folder?
+Warn "want to save?" on vocab editor close
+
+redesign vocab editor dialog
+
+on reveal word, display hint - help learn words: hide on next word button press?
+info of vocab?
+
+shared "kdeedu" dir for kvtml files?
+
+many descriptions for one word? (to prevent memorisation of words, more interesting)?
+
+speak hints using kde text-to-speech engine!?! \ No newline at end of file
diff --git a/kanagram/data/Makefile.am b/kanagram/data/Makefile.am
new file mode 100644
index 00000000..9a99f949
--- /dev/null
+++ b/kanagram/data/Makefile.am
@@ -0,0 +1,2 @@
+txt_DATA = objects.kvtml worldcapitals.kvtml computers.kvtml animals.kvtml sports.kvtml people.kvtml inventions.kvtml currencies.kvtml fruits.kvtml vegetables.kvtml space.kvtml professions.kvtml clothing.kvtml transportation.kvtml
+txtdir = $(kde_datadir)/kanagram/data/en
diff --git a/kanagram/data/animals.kvtml b/kanagram/data/animals.kvtml
new file mode 100644
index 00000000..674ae1ec
--- /dev/null
+++ b/kanagram/data/animals.kvtml
@@ -0,0 +1,185 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="Animals" remark="Animals from across the planet" cols="0" generator="kanagram" lines="11" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e>
+ <o width="150" l="original" r="Large heavy animal with thick fur" >bear</o>
+ </e>
+ <e>
+ <o r="Sea mammal" >dolphin</o>
+ </e>
+ <e>
+ <o r="African animal with black and white stripes" >zebra</o>
+ </e>
+ <e>
+ <o r="Australian jumping animal" >kangaroo</o>
+ </e>
+ <e>
+ <o r="Very large sea mammal" >whale</o>
+ </e>
+ <e>
+ <o r="Four-legged animal used for riding" >horse</o>
+ </e>
+ <e>
+ <o r="Closely related to humans" >monkey</o>
+ </e>
+ <e>
+ <o r="Bird that drills through wood" >woodpecker</o>
+ </e>
+ <e>
+ <o r="Reptile with no legs" >snake</o>
+ </e>
+ <e>
+ <o r="Long-necked African animal" >giraffe</o>
+ </e>
+ <e>
+ <o r="Largest living land animal with a trunk" >elephant</o>
+ </e>
+ <e>
+ <o r="Small rodent with a long tail" >mouse</o>
+ </e>
+ <e>
+ <o r="Animal with no backbone or limbs" >worm</o>
+ </e>
+ <e>
+ <o r="Large insect with transparent wings" >dragonfly</o>
+ </e>
+ <e>
+ <o r="Sea bird of the Antarctic regions" >penguin</o>
+ </e>
+ <e>
+ <o r="Burrowing animal with long ears" >rabbit</o>
+ </e>
+ <e>
+ <o r="Small mouse-like rodent, kept as pets" >hamster</o>
+ </e>
+ <e>
+ <o r="Fierce, wild animal of the dog family" >wolf</o>
+ </e>
+ <e>
+ <o r="Large, powerful animal of the cat family" >lion</o>
+ </e>
+ <e>
+ <o r="Large Asian animal of the cat family" >tiger</o>
+ </e>
+ <e>
+ <o r="Sea animal with eight long tentacles" >octopus</o>
+ </e>
+ <e>
+ <o r="Large, thick-skinned animal of Africa" >rhinoceros</o>
+ </e>
+ <e>
+ <o r="Small, with a back covered in stiff spines" >hedgehog</o>
+ </e>
+ <e>
+ <o r="Deer with large antlers" >reindeer</o>
+ </e>
+ <e>
+ <o r="Small tree-climbing animal with a bushy tail" >squirrel</o>
+ </e>
+ <e>
+ <o r="A slow-moving, four-footed reptile" >tortoise</o>
+ </e>
+ <e>
+ <o r="Large African river animal" >hippopotamus</o>
+ </e>
+ <e>
+ <o r="Extinct reptile" >dinosaur</o>
+ </e>
+ <e>
+ <o r="Large bird of prey" >eagle</o>
+ </e>
+ <e>
+ <o r="Large sea fish with a triangular fin" >shark</o>
+ </e>
+ <e>
+ <o r="Swimming bird" >duck</o>
+ </e>
+ <e>
+ <o r="Live in water" >fish</o>
+ </e>
+ <e>
+ <o r="Can repeat your words" >parrot</o>
+ </e>
+ <e>
+ <o r="Small green jumping animal" >frog</o>
+ </e>
+ <e>
+ <o r="Slow-moving, has a spiral shell" >snail</o>
+ </e>
+ <e>
+ <o r="Can survive a long time in the desert" >camel</o>
+ </e>
+ <e>
+ <o r="Reptile of the crocodile family" >alligator</o>
+ </e>
+ <e>
+ <o r="Its bite spreads malaria" >mosquito</o>
+ </e>
+ <e>
+ <o r="Grass-eating animal with a thick fleecy coat" >sheep</o>
+ </e>
+ <e>
+ <o r="Water animal that has a shell" >shellfish</o>
+ </e>
+</kvtml> \ No newline at end of file
diff --git a/kanagram/data/clothing.kvtml b/kanagram/data/clothing.kvtml
new file mode 100644
index 00000000..6d8e4afb
--- /dev/null
+++ b/kanagram/data/clothing.kvtml
@@ -0,0 +1,116 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="Clothing" remark="Things humans wear" cols="0" generator="kanagram" lines="16" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e>
+ <o width="150" l="original" r="Athletic shoes" >sneakers</o>
+ </e>
+ <e>
+ <o r="Shoes meant for working" >boots</o>
+ </e>
+ <e>
+ <o r="Leg coverings" >pants</o>
+ </e>
+ <e>
+ <o r="Short leg coverings" >shorts</o>
+ </e>
+ <e>
+ <o r="The bottom half of a dress" >skirt</o>
+ </e>
+ <e>
+ <o r="A full-body covering" >dress</o>
+ </e>
+ <e>
+ <o r="A cold-weather full-body covering" >parka</o>
+ </e>
+ <e>
+ <o r="A light upper-body warmer" >jacket</o>
+ </e>
+ <e>
+ <o r="Heavy upper-body covering" >coat</o>
+ </e>
+ <e>
+ <o r="A head covering" >hat</o>
+ </e>
+ <e>
+ <o r="Cold-weather head covering" >tobogan</o>
+ </e>
+ <e>
+ <o r="Ear warmer" >earmuffs</o>
+ </e>
+ <e>
+ <o r="Sunny weather eyewear" >sunglasses</o>
+ </e>
+ <e>
+ <o r="Foot protection" >socks</o>
+ </e>
+ <e>
+ <o r="Beach footwear" >sandals</o>
+ </e>
+ <e>
+ <o r="Warmers for the hands" >gloves</o>
+ </e>
+ <e>
+ <o r="Keeps your pants from falling down" >belt</o>
+ </e>
+</kvtml>
diff --git a/kanagram/data/computers.kvtml b/kanagram/data/computers.kvtml
new file mode 100644
index 00000000..57d2f822
--- /dev/null
+++ b/kanagram/data/computers.kvtml
@@ -0,0 +1,107 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="Computers" remark="Items surrounding your computer" cols="0" generator="kanagram" lines="11" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e>
+ <o width="150" l="original" r="A device to visualize bits" >monitor</o>
+ </e>
+ <e>
+ <o r="Creates waves through the air" >speakers</o>
+ </e>
+ <e>
+ <o r="Used to visualize bits on paper" >printer</o>
+ </e>
+ <e>
+ <o r="A way to instruct a computer" >mouse</o>
+ </e>
+ <e>
+ <o r="A standard input device" >keyboard</o>
+ </e>
+ <e>
+ <o r="Input device used for games" >joystick</o>
+ </e>
+ <e>
+ <o r="Used to communicate over the Internet" >modem</o>
+ </e>
+ <e>
+ <o r="A substance ensuring alertness" >caffeine</o>
+ </e>
+ <e>
+ <o r="An ancient storage device" >floppy</o>
+ </e>
+ <e>
+ <o r="Used for software backups" >tape</o>
+ </e>
+ <e>
+ <o r="Creates a digital representation of a flat object" >scanner</o>
+ </e>
+ <e>
+ <o r="For listening to sound privately" >headphones</o>
+ </e>
+ <e>
+ <o r="Sends moving images over the Internet" >webcam</o>
+ </e>
+ <e>
+ <o r="Allows you to record sound" >microphone</o>
+ </e>
+</kvtml> \ No newline at end of file
diff --git a/kanagram/data/currencies.kvtml b/kanagram/data/currencies.kvtml
new file mode 100644
index 00000000..50023e71
--- /dev/null
+++ b/kanagram/data/currencies.kvtml
@@ -0,0 +1,128 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="Currencies" remark="Modern World currencies" cols="0" generator="kanagram" lines="11" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e>
+ <o width="150" l="original" r="Algeria, Bahrain, Kuwait, etc." >dinar</o>
+ </e>
+ <e>
+ <o r="USA, Canada, Australia, etc." >dollar</o>
+ </e>
+ <e>
+ <o r="Greece" >drachma</o>
+ </e>
+ <e>
+ <o r="12 European Union countries, etc." >euro</o>
+ </e>
+ <e>
+ <o r="France (until 1998), Switzerland, etc." >franc</o>
+ </e>
+ <e>
+ <o r="The Netherlands (until 1998)" >guilder</o>
+ </e>
+ <e>
+ <o r="Czech Republic, Slovakia" >koruna</o>
+ </e>
+ <e>
+ <o r="Sweden" >krona</o>
+ </e>
+ <e>
+ <o r="Denmark, Greenland, Norway" >krone</o>
+ </e>
+ <e>
+ <o r="Italy (until 1998)" >lira</o>
+ </e>
+ <e>
+ <o r="Germany (until 1998)" >mark</o>
+ </e>
+ <e>
+ <o r="Spain (until 1998)" >peseta</o>
+ </e>
+ <e>
+ <o r="Argentina, Chile, Mexico, Cuba, Colombia, etc." >peso</o>
+ </e>
+ <e>
+ <o r="UK, Cyprus, Egypt, etc." >pound</o>
+ </e>
+ <e>
+ <o r="South Africa" >rand</o>
+ </e>
+ <e>
+ <o r="China" >renminbi</o>
+ </e>
+ <e>
+ <o r="Russia, Belarus, etc." >ruble</o>
+ </e>
+ <e>
+ <o r="India, Pakistan, Sri Lanka, etc." >rupee</o>
+ </e>
+ <e>
+ <o r="Kenya, Tanzania, etc." >shilling</o>
+ </e>
+ <e>
+ <o r="Japan" >yen</o>
+ </e>
+ <e>
+ <o r="Poland" >zloty</o>
+ </e>
+</kvtml> \ No newline at end of file
diff --git a/kanagram/data/fruits.kvtml b/kanagram/data/fruits.kvtml
new file mode 100644
index 00000000..60a8881a
--- /dev/null
+++ b/kanagram/data/fruits.kvtml
@@ -0,0 +1,137 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="Fruits" remark="Fruits of the Earth" cols="0" generator="kanagram" lines="11" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e>
+ <o width="150" l="original" r="One a day keeps the doctor away" >apple</o>
+ </e>
+ <e>
+ <o r="Resembles a small Peach" >apricot</o>
+ </e>
+ <e>
+ <o r="A long yellow fruit that bends along its length" >banana</o>
+ </e>
+ <e>
+ <o r="A Shiny black berry" >blackberry</o>
+ </e>
+ <e>
+ <o r="Sweet edible dark-blue berries" >blueberry</o>
+ </e>
+ <e>
+ <o r="Red fruit with a single hard stone" >cherry</o>
+ </e>
+ <e>
+ <o r="Has a hard brown outer husk and creamy white flesh" >coconut</o>
+ </e>
+ <e>
+ <o r="A bright red berry" >cranberry</o>
+ </e>
+ <e>
+ <o r="Used to make wine" >grape</o>
+ </e>
+ <e>
+ <o r="Large yellow citrus fruit with acidic, juicy pulp" >grapefruit</o>
+ </e>
+ <e>
+ <o r="Fuzzy brown egg-shaped fruit with slightly green flesh" >kiwi</o>
+ </e>
+ <e>
+ <o r="Yellow oval fruit with juicy acidic flesh" >lemon</o>
+ </e>
+ <e>
+ <o r="Small, green citrus fruit that resembles a lemon" >lime</o>
+ </e>
+ <e>
+ <o r="Reddish-orange loose-skinned citrus of China" >mandarin</o>
+ </e>
+ <e>
+ <o r="Large oval smooth-skinned fruit from the tropics" >mango</o>
+ </e>
+ <e>
+ <o r="Small fruit with a high oil content" >olive</o>
+ </e>
+ <e>
+ <o r="Round citrus fruit, associated with a color" >orange</o>
+ </e>
+ <e>
+ <o r="Juicy fruit with sweet yellowish flesh" >peach</o>
+ </e>
+ <e>
+ <o r="Small, bell-shaped juicy, gritty-textured fruit" >pear</o>
+ </e>
+ <e>
+ <o r="Resembling a pine cone, with a tangy sweet taste" >pineapple</o>
+ </e>
+ <e>
+ <o r="Sweet, juicy, purple fruit with smooth skin" >plum</o>
+ </e>
+ <e>
+ <o r="Strongly-flavored berry of several colors" >raspberry</o>
+ </e>
+ <e>
+ <o r="Small, sweet and fleshy red fruit" >strawberry</o>
+ </e>
+ <e>
+ <o r="This melon from Africa has a moist red flesh" >watermelon</o>
+ </e>
+</kvtml> \ No newline at end of file
diff --git a/kanagram/data/inventions.kvtml b/kanagram/data/inventions.kvtml
new file mode 100644
index 00000000..721fb624
--- /dev/null
+++ b/kanagram/data/inventions.kvtml
@@ -0,0 +1,149 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="Inventions" remark="Greatest inventions of humans" cols="0" generator="kanagram" lines="11" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e>
+ <o width="150" l="original" r="Achieve flight through fixed wings" >aircraft</o>
+ </e>
+ <e>
+ <o r="Drugs that kill bacteria" >antibiotics</o>
+ </e>
+ <e>
+ <o r="A motor vehicle for passengers" >automobile</o>
+ </e>
+ <e>
+ <o r="Store electrical energy" >batteries</o>
+ </e>
+ <e>
+ <o r="Efficient human powered vehicle with 2 wheels" >bicycle</o>
+ </e>
+ <e>
+ <o r="When thrown, it returns" >boomerang</o>
+ </e>
+ <e>
+ <o r="Accurately displays the time" >clocks</o>
+ </e>
+ <e>
+ <o r="One is in front of you right now" >computers</o>
+ </e>
+ <e>
+ <o r="A powerful high explosive" >dynamite</o>
+ </e>
+ <e>
+ <o r="The flow of electrons" >electricity</o>
+ </e>
+ <e>
+ <o r="Allows for speedy vertical travels within tall buildings" >elevator</o>
+ </e>
+ <e>
+ <o r="Fast method of sending mail through the internet" >email</o>
+ </e>
+ <e>
+ <o r="Rotating blades on this craft allow flight" >helicopter</o>
+ </e>
+ <e>
+ <o r="Vessel that floats on a cushion of air" >hovercraft</o>
+ </e>
+ <e>
+ <o r="The global computer communications network" >internet</o>
+ </e>
+ <e>
+ <o r="Intense beam of light" >lasers</o>
+ </e>
+ <e>
+ <o r="Holds paper objects together temporarily" >paperclip</o>
+ </e>
+ <e>
+ <o r="Snapshots of moments in time" >photography</o>
+ </e>
+ <e>
+ <o r="Petroleum-based polymers with a range of properties" >plastics</o>
+ </e>
+ <e>
+ <o r="Radio waves provide the spatial location of objects" >radar</o>
+ </e>
+ <e>
+ <o r="Sound recieved from electromagnetic waves" >radio</o>
+ </e>
+ <e>
+ <o r="The pressure of water vapor drives this engine" >steamengine</o>
+ </e>
+ <e>
+ <o r="A vocal communication device" >telephone</o>
+ </e>
+ <e>
+ <o r="Electrical device that displays moving images" >television</o>
+ </e>
+ <e>
+ <o r="Puzzle game made famous by the Gameboy console" >tetris</o>
+ </e>
+ <e>
+ <o r="Foundation of modern electronics" >transistor</o>
+ </e>
+ <e>
+ <o r="Hook and loop fasteners" >velcro</o>
+ </e>
+ <e>
+ <o r="Circular object that allows for low-friction motion" >wheel</o>
+ </e>
+</kvtml> \ No newline at end of file
diff --git a/kanagram/data/objects.kvtml b/kanagram/data/objects.kvtml
new file mode 100644
index 00000000..d9e52eb1
--- /dev/null
+++ b/kanagram/data/objects.kvtml
@@ -0,0 +1,152 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="Objects" remark="Everyday objects from the home" cols="0" generator="kanagram" lines="20" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e i="1" >
+ <o width="150" l="original" r="Electrical device that displays moving images" >television</o>
+ </e>
+ <e i="1" >
+ <o r="For sitting down on" >chair</o>
+ </e>
+ <e i="1" >
+ <o r="Used to keep food items extra cold" >freezer</o>
+ </e>
+ <e i="1" >
+ <o r="To keep food cool" >fridge</o>
+ </e>
+ <e i="1" >
+ <o r="Used to cook food" >cooker</o>
+ </e>
+ <e i="1" >
+ <o r="Keep warm by flame in cold weather" >fireplace</o>
+ </e>
+ <e i="1" >
+ <o r="Holds items above the floor" >table</o>
+ </e>
+ <e i="1" >
+ <o r="Storage for personal items" >drawers</o>
+ </e>
+ <e i="1" >
+ <o r="Reflects the area in front of it" >mirror</o>
+ </e>
+ <e i="1" >
+ <o r="Keeps the time" >clock</o>
+ </e>
+ <e i="1" >
+ <o r="Stores clothing items upright" >wardrobe</o>
+ </e>
+ <e i="1" >
+ <o r="Storage for books" >bookcase</o>
+ </e>
+ <e i="1" >
+ <o r="Liquidates food items" >blender</o>
+ </e>
+ <e i="1" >
+ <o r="For comfortable seating" >settee</o>
+ </e>
+ <e i="1" >
+ <o r="To wash the hands and face" >washbasin</o>
+ </e>
+ <e i="1" >
+ <o r="To clean your body whilst standing" >shower</o>
+ </e>
+ <e i="1" >
+ <o r="To clean the body whilst lying horizontally" >bath</o>
+ </e>
+ <e i="1" >
+ <o r="Dedicated to boiling water" >kettle</o>
+ </e>
+ <e i="1" >
+ <o r="A vocal communication device" >telephone</o>
+ </e>
+ <e i="1" >
+ <o r="Increase the temperature of the house" >radiator</o>
+ </e>
+ <e i="1" >
+ <o r="Plays audio from the airwaves" >radio</o>
+ </e>
+ <e i="1" >
+ <o r="Interactive electronic device" >computer</o>
+ </e>
+ <e i="1" >
+ <o r="Alive, and often cuddly" >pets</o>
+ </e>
+ <e i="1" >
+ <o r="Images in frames" >pictures</o>
+ </e>
+ <e i="1" >
+ <o r="To brush teeth" >toothbrush</o>
+ </e>
+ <e i="1" >
+ <o r="Soft floor covering" >carpet</o>
+ </e>
+ <e i="1" >
+ <o r="Things to play with" >toys</o>
+ </e>
+ <e i="1" >
+ <o r="Objects with no obvious function" >ornaments</o>
+ </e>
+ <e i="1" >
+ <o r="Larger storage areas" >cupboards</o>
+ </e>
+</kvtml> \ No newline at end of file
diff --git a/kanagram/data/people.kvtml b/kanagram/data/people.kvtml
new file mode 100644
index 00000000..4514935a
--- /dev/null
+++ b/kanagram/data/people.kvtml
@@ -0,0 +1,116 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="People" remark="Infuential people of history" cols="0" generator="kanagram" lines="11" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e>
+ <o width="150" l="original" r="Influential Greek philosopher" >aristotle</o>
+ </e>
+ <e>
+ <o r="Composer" >beethoven</o>
+ </e>
+ <e>
+ <o r="This explorer discovered the Americas" >columbus</o>
+ </e>
+ <e>
+ <o r="Theory of Evolution" >darwin</o>
+ </e>
+ <e>
+ <o r="Inventor of the Light Bulb" >edison</o>
+ </e>
+ <e>
+ <o r="Theory of Relativity" >einstein</o>
+ </e>
+ <e>
+ <o r="Discovered Penicillin" >fleming</o>
+ </e>
+ <e>
+ <o r="'The Earth revolves around the Sun'" >galileo</o>
+ </e>
+ <e>
+ <o r="Non-violent independence for India" >gandhi</o>
+ </e>
+ <e>
+ <o r="Helped end Communism in USSR" >gorbachev</o>
+ </e>
+ <e>
+ <o r="Ended apartheid in South Africa" >mandela</o>
+ </e>
+ <e>
+ <o r="Inventor of radio" >marconi</o>
+ </e>
+ <e>
+ <o r="A painter, sculptor and architect" >michelangelo</o>
+ </e>
+ <e>
+ <o r="French conqueror" >napoleon</o>
+ </e>
+ <e>
+ <o r="Discovered Gravity" >newton</o>
+ </e>
+ <e>
+ <o r="Invented Vaccination" >pasteur</o>
+ </e>
+ <e>
+ <o r="First president of United States" >washington</o>
+ </e>
+</kvtml> \ No newline at end of file
diff --git a/kanagram/data/professions.kvtml b/kanagram/data/professions.kvtml
new file mode 100644
index 00000000..8baa0bb3
--- /dev/null
+++ b/kanagram/data/professions.kvtml
@@ -0,0 +1,185 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="Professions" remark="The jobs people do" cols="0" generator="kanagram" lines="21" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e s="1" >
+ <o width="150" l="original" r="One who helps the sick" >doctor</o>
+ </e>
+ <e s="1" >
+ <o r="One who puts out fires" >fireman</o>
+ </e>
+ <e s="1" >
+ <o r="A catcher of ocean creatures" >fisherman</o>
+ </e>
+ <e s="1" >
+ <o r="One who defends his country" >soldier</o>
+ </e>
+ <e>
+ <o r="An extra-terrestrial traveler" >astronaut</o>
+ </e>
+ <e>
+ <o r="A person that maintains an electrical system" >electrician</o>
+ </e>
+ <e>
+ <o r="Someone that repairs water systems" >plumber</o>
+ </e>
+ <e>
+ <o r="A doctor for the mind" >psychiatrist</o>
+ </e>
+ <e>
+ <o r="An officer of the law" >policeman</o>
+ </e>
+ <e>
+ <o r="One who writes for a living" >author</o>
+ </e>
+ <e>
+ <o r="A news writer" >journalist</o>
+ </e>
+ <e>
+ <o r="A maker of computer software" >programmer</o>
+ </e>
+ <e>
+ <o r="One who performs for an audience" >actor</o>
+ </e>
+ <e>
+ <o r="A player of music" >musician</o>
+ </e>
+ <e>
+ <o r="One who invokes laughter" >comedian</o>
+ </e>
+ <e>
+ <o r="Scientist who specializes in chemistry" >chemist</o>
+ </e>
+ <e>
+ <o r="One who instructs students" >teacher</o>
+ </e>
+ <e>
+ <o r="A person that repairs machinery" >mechanic</o>
+ </e>
+ <e>
+ <o r="Someone that grows crops" >farmer</o>
+ </e>
+ <e>
+ <o r="One who practices art" >artist</o>
+ </e>
+ <e>
+ <o r="A door-to-door seller" >salesman</o>
+ </e>
+ <e>
+ <o r="Makes and alteres clothes" >tailor</o>
+ </e>
+ <e>
+ <o r="Crafter of iron and steel" >blacksmith</o>
+ </e>
+ <e>
+ <o r="Specializes in oral medical care" >dentist</o>
+ </e>
+ <e>
+ <o r="Develops and communicates ideas" >designer</o>
+ </e>
+ <e>
+ <o r="Expert in an area of science" >scientist</o>
+ </e>
+ <e>
+ <o r="The first to think of or make something" >inventor</o>
+ </e>
+ <e>
+ <o r="Uses scientific knowledge to solve practical problems" >engineer</o>
+ </e>
+ <e>
+ <o r="Look after the finances in an organisastion" >accountant</o>
+ </e>
+ <e>
+ <o r="Bake bread" >baker</o>
+ </e>
+ <e>
+ <o r="Involved in the construction of buildings" >builder</o>
+ </e>
+ <e>
+ <o r="Crafts furniture" >carpenter</o>
+ </e>
+ <e>
+ <o r="Prepare and cook food" >chef</o>
+ </e>
+ <e>
+ <o r="Fixes machinery, especially automobiles" >mechanic</o>
+ </e>
+ <e>
+ <o r="Cut and style people's hair" >hairdresser</o>
+ </e>
+ <e>
+ <o r="Defend and prosecute people" >lawyer</o>
+ </e>
+ <e>
+ <o r="Look after people's eye sight" >optician</o>
+ </e>
+ <e>
+ <o r="Find and report the news" >reporter</o>
+ </e>
+ <e>
+ <o r="Arrange appointments and organise meetings" >secretary</o>
+ </e>
+ <e>
+ <o r="Designs the blueprints for new structures" >architect</o>
+ </e>
+</kvtml>
diff --git a/kanagram/data/space.kvtml b/kanagram/data/space.kvtml
new file mode 100644
index 00000000..97f6b813
--- /dev/null
+++ b/kanagram/data/space.kvtml
@@ -0,0 +1,152 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="Space" remark="Space objects, terms and missions" cols="0" generator="kanagram" lines="11" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e>
+ <o width="150" l="original" r="The American moon program" >apollo</o>
+ </e>
+ <e>
+ <o r="Small planetary body in orbit around the Sun" >asteroid</o>
+ </e>
+ <e>
+ <o r="Person from the USA who travels into space" >astronaut</o>
+ </e>
+ <e>
+ <o r="Russian reusable spacecraft program" >buran</o>
+ </e>
+ <e>
+ <o r="Medium-sized icy object orbiting the Sun" >comet</o>
+ </e>
+ <e>
+ <o r="Grouping of stars which can form a shape or pattern" >constellation</o>
+ </e>
+ <e>
+ <o r="Person from Russia who travels into space" >cosmonaut</o>
+ </e>
+ <e>
+ <o r="The planet on which we live" >earth</o>
+ </e>
+ <e>
+ <o r="When one celestial body obscures another" >eclipse</o>
+ </e>
+ <e>
+ <o r="Very large cluster of stars" >galaxy</o>
+ </e>
+ <e>
+ <o r="Fifth from the Sun, the largest planet" >jupiter</o>
+ </e>
+ <e>
+ <o r="Fourth planet from the Sun" >mars</o>
+ </e>
+ <e>
+ <o r="The smallest planet and nearest the Sun" >mercury</o>
+ </e>
+ <e>
+ <o r="Meteoroid that burns up in the Earth's atmosphere" >meteor</o>
+ </e>
+ <e>
+ <o r="Matter that has reached Earth from outer space" >meteorite</o>
+ </e>
+ <e>
+ <o r="Russian space station, launched in 1986" >mir</o>
+ </e>
+ <e>
+ <o r="The natural satellite of the Earth" >moon</o>
+ </e>
+ <e>
+ <o r="Giant planet, eighth from the sun" >neptune</o>
+ </e>
+ <e>
+ <o r="Path an object makes around another" >orbit</o>
+ </e>
+ <e>
+ <o r="Ninth planet from the Sun" >pluto</o>
+ </e>
+ <e>
+ <o r="An object that revolves around a planet" >satellite</o>
+ </e>
+ <e>
+ <o r="Giant planet with rings, sixth from the Sun" >saturn</o>
+ </e>
+ <e>
+ <o r="The first American space station, launched in 1973" >skylab</o>
+ </e>
+ <e>
+ <o r="The first artificial Earth satellite, launched in 1957" >sputnik</o>
+ </e>
+ <e>
+ <o r="The star at the center of the Solar System" >sun</o>
+ </e>
+ <e>
+ <o r="Person from China who travels into space" >taikonaut</o>
+ </e>
+ <e>
+ <o r="Seventh planet from the Sun" >uranus</o>
+ </e>
+ <e>
+ <o r="Second planet from the Sun" >venus</o>
+ </e>
+ <e>
+ <o r="Twin space probes launched in 1977" >voyager</o>
+ </e>
+</kvtml> \ No newline at end of file
diff --git a/kanagram/data/sports.kvtml b/kanagram/data/sports.kvtml
new file mode 100644
index 00000000..a267b98d
--- /dev/null
+++ b/kanagram/data/sports.kvtml
@@ -0,0 +1,158 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="Sports" remark="Events of the Olympics" cols="0" generator="kanagram" lines="11" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e>
+ <o width="150" l="original" r="Water sports" >aquatics</o>
+ </e>
+ <e>
+ <o r="Shooting arrows with a bow" >archery</o>
+ </e>
+ <e>
+ <o r="Track and field events" >athletics</o>
+ </e>
+ <e>
+ <o r="Hit the shuttlecock over the net" >badminton</o>
+ </e>
+ <e>
+ <o r="4 bases arranged in a diamond" >baseball</o>
+ </e>
+ <e>
+ <o r="Throw the ball through the hoop" >basketball</o>
+ </e>
+ <e>
+ <o r="Fighting with the fists" >boxing</o>
+ </e>
+ <e>
+ <o r="Small boat propelled with a paddle" >canoe</o>
+ </e>
+ <e>
+ <o r="Riding bicycles" >cycling</o>
+ </e>
+ <e>
+ <o r="Horseback riding" >equestrian</o>
+ </e>
+ <e>
+ <o r="Fighting with swords" >fencing</o>
+ </e>
+ <e>
+ <o r="Kick the ball into the opponent's goal" >football</o>
+ </e>
+ <e>
+ <o r="Graceful display of athletic ability" >gymnastics</o>
+ </e>
+ <e>
+ <o r="Using hands and a rubber ball" >handball</o>
+ </e>
+ <e>
+ <o r="Curved sticks and a ball or puck" >hockey</o>
+ </e>
+ <e>
+ <o r="A martial art" >judo</o>
+ </e>
+ <e>
+ <o r="5 athletic events" >pentathlon</o>
+ </e>
+ <e>
+ <o r="Propelling a boat with oars" >rowing</o>
+ </e>
+ <e>
+ <o r="Boating propelled by wind" >sailing</o>
+ </e>
+ <e>
+ <o r="Firing projectiles from a weapon" >shooting</o>
+ </e>
+ <e>
+ <o r="A game resembling baseball" >softball</o>
+ </e>
+ <e>
+ <o r="Korean martial art" >taekwondo</o>
+ </e>
+ <e>
+ <o r="Played with rackets on a court" >tennis</o>
+ </e>
+ <e>
+ <o r="3 athletic events" >triathlon</o>
+ </e>
+ <e>
+ <o r="Hit an inflated ball over a high net" >volleyball</o>
+ </e>
+ <e>
+ <o r="Lifting heavy weights" >weightlifting</o>
+ </e>
+ <e>
+ <o r="Grappling between 2 opponents" >wrestling</o>
+ </e>
+ <e>
+ <o r="A sled racing down an icy track" >bobsleigh</o>
+ </e>
+ <e>
+ <o r="Stones slid across ice" >curling</o>
+ </e>
+ <e>
+ <o r="Gliding on ice" >skating</o>
+ </e>
+ <e>
+ <o r="Downhill on snow using flat feet" >skiing</o>
+ </e>
+</kvtml> \ No newline at end of file
diff --git a/kanagram/data/transportation.kvtml b/kanagram/data/transportation.kvtml
new file mode 100644
index 00000000..b667c621
--- /dev/null
+++ b/kanagram/data/transportation.kvtml
@@ -0,0 +1,128 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="Transportation" remark="Ways of getting around" cols="0" generator="kanagram" lines="16" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e>
+ <o width="150" l="original" r="Four-wheeled vehicle" >automobile</o>
+ </e>
+ <e>
+ <o r="Motorized two-wheeled vehicle" >motorcycle</o>
+ </e>
+ <e>
+ <o r="A vehicle that travels on tracks" >train</o>
+ </e>
+ <e>
+ <o r="A flying machine" >airplane</o>
+ </e>
+ <e>
+ <o r="A vertical takeoff aircraft" >helicopter</o>
+ </e>
+ <e>
+ <o r="A two-wheeled human-powered vehicle" >bicycle</o>
+ </e>
+ <e>
+ <o r="An electrified bus" >streetcar</o>
+ </e>
+ <e>
+ <o r="It goes up, it comes down" >elevator</o>
+ </e>
+ <e>
+ <o r="A sea-faring vehicle" >ship</o>
+ </e>
+ <e>
+ <o r="For underwater transportation" >submarine</o>
+ </e>
+ <e>
+ <o r="Open-air bus" >trolley</o>
+ </e>
+ <e>
+ <o r="Heavy duty with four wheels" >truck</o>
+ </e>
+ <e>
+ <o r="For transporting several people at once" >bus</o>
+ </e>
+ <e>
+ <o r="An underground train" >subway</o>
+ </e>
+ <e>
+ <o r="A two-wheeled scooter" >moped</o>
+ </e>
+ <e>
+ <o r="Efficient human powered vehicle with 2 wheels" >bicycle</o>
+ </e>
+ <e>
+ <o r="A fast sea-faring vehicle" >speedboat</o>
+ </e>
+ <e>
+ <o r="Motorized transport over snow" >snowmobile</o>
+ </e>
+ <e>
+ <o r="Strap wheels to your feet" >rollerskates</o>
+ </e>
+ <e>
+ <o r="One-wheeled, often seen in the circus" >unicycle</o>
+ </e>
+ <e>
+ <o r="Filled with a lighter-than-air gas" >airship</o>
+ </e>
+</kvtml>
diff --git a/kanagram/data/vegetables.kvtml b/kanagram/data/vegetables.kvtml
new file mode 100644
index 00000000..b3356f3f
--- /dev/null
+++ b/kanagram/data/vegetables.kvtml
@@ -0,0 +1,152 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="Vegetables" remark="Vegetables of the Earth" cols="0" generator="kanagram" lines="11" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e>
+ <o width="150" l="original" r="Succulent young shoots" >asparagus</o>
+ </e>
+ <e>
+ <o r="Dense clusters of tight green buds grow from a thick stalk" >broccoli</o>
+ </e>
+ <e>
+ <o r="Has leaves that form a characteristic compact head" >cabbage</o>
+ </e>
+ <e>
+ <o r="Orange root vegetable that grows underground" >carrot</o>
+ </e>
+ <e>
+ <o r="Type of Cabbage, with bunches of creamy white florets" >cauliflower</o>
+ </e>
+ <e>
+ <o r="Crisp, green vegetable" >celery</o>
+ </e>
+ <e>
+ <o r="Also known as garbanzo beans, with a nut-like flavor" >chickpeas</o>
+ </e>
+ <e>
+ <o r="Long, green, cylinder-shaped vegetable" >cucumber</o>
+ </e>
+ <e>
+ <o r="A bulb made up of sections of cloves" >garlic</o>
+ </e>
+ <e>
+ <o r="Long narrow white bulb and long dark-green leaves" >leek</o>
+ </e>
+ <e>
+ <o r="Small brown beans that cook quickly" >lentils</o>
+ </e>
+ <e>
+ <o r="Leafy greens enjoyed in salads" >lettuce</o>
+ </e>
+ <e>
+ <o r="A type of fungi" >mushrooms</o>
+ </e>
+ <e>
+ <o r="Its odor can make you cry" >onion</o>
+ </e>
+ <e>
+ <o r="Spicy seasoning ground from red pepper" >paprika</o>
+ </e>
+ <e>
+ <o r="Fresh-flavored bright green herb" >parsley</o>
+ </e>
+ <e>
+ <o r="Root vegetable that looks like a white carrot" >parsnip</o>
+ </e>
+ <e>
+ <o r="Small light brown nuts, often served salted" >peanuts</o>
+ </e>
+ <e>
+ <o r="Small round green seed which grows in a pod" >peas</o>
+ </e>
+ <e>
+ <o r="Mid-sized, yellow, and grown underground" >potato</o>
+ </e>
+ <e>
+ <o r="Popular at Halloween" >pumpkin</o>
+ </e>
+ <e>
+ <o r="Celery-like vegetable" >rhubarb</o>
+ </e>
+ <e>
+ <o r="High-protein, used in tofu" >soybeans</o>
+ </e>
+ <e>
+ <o r="Crisp, dark green leafy vegetable" >spinach</o>
+ </e>
+ <e>
+ <o r="The yellow seeds of a type of maize" >sweetcorn</o>
+ </e>
+ <e>
+ <o r="Very hot red peppers" >tabasco</o>
+ </e>
+ <e>
+ <o r="Red, technically considered a fruit" >tomato</o>
+ </e>
+ <e>
+ <o r="Vegetable with a succulent, bulbous root" >turnip</o>
+ </e>
+ <e>
+ <o r="Green leafy little plant, only grows in running water" >watercress</o>
+ </e>
+</kvtml> \ No newline at end of file
diff --git a/kanagram/data/worldcapitals.kvtml b/kanagram/data/worldcapitals.kvtml
new file mode 100644
index 00000000..fbc8da9f
--- /dev/null
+++ b/kanagram/data/worldcapitals.kvtml
@@ -0,0 +1,221 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE kvtml SYSTEM "kvoctrain.dtd">
+<!--
+This is a machine generated file.
+Be careful when editing here.
+
+Short definition:
+
+lesson lesson group
+ desc name
+ %no its index
+ %query is in query selection
+ %current is current lesson
+type type group
+ desc name
+ %no its index
+e entry of dictionary
+ %s is selected
+ %m lesson member
+ %t common expression type
+ o original
+ %q in query ("o" is given, "t" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type (see QueryManager.h)
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+ t translation ..
+ %q in query ("t" is given, "o" is wanted)
+ %l language code
+ %r remark
+ %p pronunciation
+ %width column width
+ %t expression type
+ %tf false friend from
+ %ff false friend to
+ %a antonym
+ %y synonym
+ %x example
+ %u usage label
+ %h paraphrase
+
+ %d last query date (from;to)
+ %w dito, compressed and deprecated
+ %g grade (from;to)
+ %c count (from;to)
+ %b bad count (from;to)
+
+
+Valid xml means:
+ - Close all tags
+ - Keep proper hierarchy
+ - All attributes are quoted
+--><kvtml title="World Capitals" remark="Capital cities of the World" cols="0" generator="kanagram" lines="25" encoding="UTF-8" >
+ <options>
+ <sort on="1" />
+ </options>
+ <e i="1" >
+ <o width="150" l="original" r="Capital of England" >london</o>
+ </e>
+ <e i="1" >
+ <o r="Capital of France" >paris</o>
+ </e>
+ <e>
+ <o r="Capital of Germany" >berlin</o>
+ </e>
+ <e>
+ <o r="Capital of Ireland" >dublin</o>
+ </e>
+ <e>
+ <o r="Capital of Wales" >cardiff</o>
+ </e>
+ <e>
+ <o r="Capital of Spain" >madrid</o>
+ </e>
+ <e>
+ <o r="Capital of Russia" >moscow</o>
+ </e>
+ <e>
+ <o r="Capital of Afganistan" >kabul</o>
+ </e>
+ <e>
+ <o r="Capital of Sudan" >khartoum</o>
+ </e>
+ <e>
+ <o r="Capital of the USA" >washington</o>
+ </e>
+ <e>
+ <o r="Capital of Australia" >canberra</o>
+ </e>
+ <e>
+ <o r="Capital of Japan" >tokyo</o>
+ </e>
+ <e>
+ <o r="Capital of Portugal" >lisbon</o>
+ </e>
+ <e>
+ <o r="Capital of Scotland" >edinburgh</o>
+ </e>
+ <e>
+ <o r="Capital of Iraq" >baghdad</o>
+ </e>
+ <e>
+ <o r="Capital of China" >beijing</o>
+ </e>
+ <e>
+ <o r="Capital of South Korea" >seoul</o>
+ </e>
+ <e>
+ <o r="Capital of Iran" >tehran</o>
+ </e>
+ <e>
+ <o r="Capital of Canada" >ottawa</o>
+ </e>
+ <e>
+ <o r="Capital of Greece" >athens</o>
+ </e>
+ <e>
+ <o r="Capital of Sweden" >stockholm</o>
+ </e>
+ <e>
+ <o r="Capital of Norway" >oslo</o>
+ </e>
+ <e>
+ <o r="Capital of Bulgaria" >sofia</o>
+ </e>
+ <e>
+ <o r="Capital of the Netherlands" >amsterdam</o>
+ </e>
+ <e>
+ <o r="Capital of Italy" >rome</o>
+ </e>
+ <e>
+ <o r="Capital of Austria" >vienna</o>
+ </e>
+ <e>
+ <o r="Capital of Chile" >santiago</o>
+ </e>
+ <e>
+ <o r="Capital of Albania" >tirana</o>
+ </e>
+ <e>
+ <o r="Capital of Belgium" >brussels</o>
+ </e>
+ <e>
+ <o r="Capital of Croatia" >zagreb</o>
+ </e>
+ <e>
+ <o r="Capital of Estonia" >tallinn</o>
+ </e>
+ <e>
+ <o r="Capital of Finland" >helsinki</o>
+ </e>
+ <e>
+ <o r="Capital of Iceland" >reykjavik</o>
+ </e>
+ <e>
+ <o r="Capital of Hungary" >budapest</o>
+ </e>
+ <e>
+ <o r="Capital of Turkey" >ankara</o>
+ </e>
+ <e>
+ <o r="Capital of Indonesia" >jakarta</o>
+ </e>
+ <e>
+ <o r="Capital of Jamaica" >kingston</o>
+ </e>
+ <e>
+ <o r="Capital of Kenya" >nairobi</o>
+ </e>
+ <e>
+ <o r="Capital of Latvia" >riga</o>
+ </e>
+ <e>
+ <o r="Capital of Lebanon" >beirut</o>
+ </e>
+ <e>
+ <o r="Capital of Libya" >tripoli</o>
+ </e>
+ <e>
+ <o r="Capital of Macedonia" >skopje</o>
+ </e>
+ <e>
+ <o r="Capital of Nepal" >kathmandu</o>
+ </e>
+ <e>
+ <o r="Capital of Peru" >lima</o>
+ </e>
+ <e>
+ <o r="Capital of Poland" >warsaw</o>
+ </e>
+ <e>
+ <o r="Capital of Romania" >bucharest</o>
+ </e>
+ <e>
+ <o r="Capital of Slovakia" >bratislava</o>
+ </e>
+ <e>
+ <o r="Capital of Somalia" >mogadishu</o>
+ </e>
+ <e>
+ <o r="Capital of Syria" >damascus</o>
+ </e>
+ <e>
+ <o r="Capital of Switzerland" >bern</o>
+ </e>
+ <e>
+ <o r="Capital of Thailand" >bangkok</o>
+ </e>
+ <e>
+ <o r="Capital of Syria" >damascus</o>
+ </e>
+</kvtml> \ No newline at end of file
diff --git a/kanagram/icons/Makefile.am b/kanagram/icons/Makefile.am
new file mode 100644
index 00000000..56681824
--- /dev/null
+++ b/kanagram/icons/Makefile.am
@@ -0,0 +1 @@
+KDE_ICON=AUTO \ No newline at end of file
diff --git a/kanagram/icons/hi128-app-kanagram.png b/kanagram/icons/hi128-app-kanagram.png
new file mode 100644
index 00000000..340feaf5
--- /dev/null
+++ b/kanagram/icons/hi128-app-kanagram.png
Binary files differ
diff --git a/kanagram/icons/hi16-app-kanagram.png b/kanagram/icons/hi16-app-kanagram.png
new file mode 100644
index 00000000..c4423ba1
--- /dev/null
+++ b/kanagram/icons/hi16-app-kanagram.png
Binary files differ
diff --git a/kanagram/icons/hi22-app-kanagram.png b/kanagram/icons/hi22-app-kanagram.png
new file mode 100644
index 00000000..aaf9ef2c
--- /dev/null
+++ b/kanagram/icons/hi22-app-kanagram.png
Binary files differ
diff --git a/kanagram/icons/hi32-app-kanagram.png b/kanagram/icons/hi32-app-kanagram.png
new file mode 100644
index 00000000..d4e0b65a
--- /dev/null
+++ b/kanagram/icons/hi32-app-kanagram.png
Binary files differ
diff --git a/kanagram/icons/hi48-app-kanagram.png b/kanagram/icons/hi48-app-kanagram.png
new file mode 100644
index 00000000..02cf352a
--- /dev/null
+++ b/kanagram/icons/hi48-app-kanagram.png
Binary files differ
diff --git a/kanagram/icons/hisc-app-kanagram.svgz b/kanagram/icons/hisc-app-kanagram.svgz
new file mode 100644
index 00000000..0a85f06b
--- /dev/null
+++ b/kanagram/icons/hisc-app-kanagram.svgz
Binary files differ
diff --git a/kanagram/images/Makefile.am b/kanagram/images/Makefile.am
new file mode 100644
index 00000000..d10109ff
--- /dev/null
+++ b/kanagram/images/Makefile.am
@@ -0,0 +1,2 @@
+imagesdir = $(kde_datadir)/kanagram/images
+images_DATA = kanagram.png hint.png eyes1.png eyes2.png eyes3.png eyes4.png eyes5.png eyes6.png eyes7.png eyes8.png kicon.png kiconover.png appicon.png appiconover.png handbookiconover.png handbookicon.png card.png arrow.png arrowover.png basicarrow.png basicarrowover.png next.png nextover.png help.png helpover.png quit.png quitover.png config.png configover.png up.png upover.png updisabled.png
diff --git a/kanagram/images/appicon.png b/kanagram/images/appicon.png
new file mode 100644
index 00000000..a3972053
--- /dev/null
+++ b/kanagram/images/appicon.png
Binary files differ
diff --git a/kanagram/images/appiconover.png b/kanagram/images/appiconover.png
new file mode 100644
index 00000000..1bb8f05b
--- /dev/null
+++ b/kanagram/images/appiconover.png
Binary files differ
diff --git a/kanagram/images/arrow.png b/kanagram/images/arrow.png
new file mode 100644
index 00000000..9c5cc4b9
--- /dev/null
+++ b/kanagram/images/arrow.png
Binary files differ
diff --git a/kanagram/images/arrowover.png b/kanagram/images/arrowover.png
new file mode 100644
index 00000000..4ee68b92
--- /dev/null
+++ b/kanagram/images/arrowover.png
Binary files differ
diff --git a/kanagram/images/basicarrow.png b/kanagram/images/basicarrow.png
new file mode 100644
index 00000000..2d88482e
--- /dev/null
+++ b/kanagram/images/basicarrow.png
Binary files differ
diff --git a/kanagram/images/basicarrowover.png b/kanagram/images/basicarrowover.png
new file mode 100644
index 00000000..e1946e26
--- /dev/null
+++ b/kanagram/images/basicarrowover.png
Binary files differ
diff --git a/kanagram/images/card.png b/kanagram/images/card.png
new file mode 100644
index 00000000..119c99e0
--- /dev/null
+++ b/kanagram/images/card.png
Binary files differ
diff --git a/kanagram/images/config.png b/kanagram/images/config.png
new file mode 100644
index 00000000..1ca7dca1
--- /dev/null
+++ b/kanagram/images/config.png
Binary files differ
diff --git a/kanagram/images/configover.png b/kanagram/images/configover.png
new file mode 100644
index 00000000..c13c65a5
--- /dev/null
+++ b/kanagram/images/configover.png
Binary files differ
diff --git a/kanagram/images/eyes1.png b/kanagram/images/eyes1.png
new file mode 100644
index 00000000..553b58ab
--- /dev/null
+++ b/kanagram/images/eyes1.png
Binary files differ
diff --git a/kanagram/images/eyes2.png b/kanagram/images/eyes2.png
new file mode 100644
index 00000000..dce3c58b
--- /dev/null
+++ b/kanagram/images/eyes2.png
Binary files differ
diff --git a/kanagram/images/eyes3.png b/kanagram/images/eyes3.png
new file mode 100644
index 00000000..8f9be886
--- /dev/null
+++ b/kanagram/images/eyes3.png
Binary files differ
diff --git a/kanagram/images/eyes4.png b/kanagram/images/eyes4.png
new file mode 100644
index 00000000..39496911
--- /dev/null
+++ b/kanagram/images/eyes4.png
Binary files differ
diff --git a/kanagram/images/eyes5.png b/kanagram/images/eyes5.png
new file mode 100644
index 00000000..636adf1c
--- /dev/null
+++ b/kanagram/images/eyes5.png
Binary files differ
diff --git a/kanagram/images/eyes6.png b/kanagram/images/eyes6.png
new file mode 100644
index 00000000..1df29626
--- /dev/null
+++ b/kanagram/images/eyes6.png
Binary files differ
diff --git a/kanagram/images/eyes7.png b/kanagram/images/eyes7.png
new file mode 100644
index 00000000..22048c40
--- /dev/null
+++ b/kanagram/images/eyes7.png
Binary files differ
diff --git a/kanagram/images/eyes8.png b/kanagram/images/eyes8.png
new file mode 100644
index 00000000..8e995d1f
--- /dev/null
+++ b/kanagram/images/eyes8.png
Binary files differ
diff --git a/kanagram/images/graphics_sources.tar.gz b/kanagram/images/graphics_sources.tar.gz
new file mode 100644
index 00000000..c430a622
--- /dev/null
+++ b/kanagram/images/graphics_sources.tar.gz
Binary files differ
diff --git a/kanagram/images/handbookicon.png b/kanagram/images/handbookicon.png
new file mode 100644
index 00000000..be48d934
--- /dev/null
+++ b/kanagram/images/handbookicon.png
Binary files differ
diff --git a/kanagram/images/handbookiconover.png b/kanagram/images/handbookiconover.png
new file mode 100644
index 00000000..e592a4d3
--- /dev/null
+++ b/kanagram/images/handbookiconover.png
Binary files differ
diff --git a/kanagram/images/help.png b/kanagram/images/help.png
new file mode 100644
index 00000000..ebc6e53a
--- /dev/null
+++ b/kanagram/images/help.png
Binary files differ
diff --git a/kanagram/images/helpover.png b/kanagram/images/helpover.png
new file mode 100644
index 00000000..170010f9
--- /dev/null
+++ b/kanagram/images/helpover.png
Binary files differ
diff --git a/kanagram/images/hint.png b/kanagram/images/hint.png
new file mode 100644
index 00000000..1e8e2557
--- /dev/null
+++ b/kanagram/images/hint.png
Binary files differ
diff --git a/kanagram/images/kanagram.png b/kanagram/images/kanagram.png
new file mode 100644
index 00000000..e251b4a5
--- /dev/null
+++ b/kanagram/images/kanagram.png
Binary files differ
diff --git a/kanagram/images/kicon.png b/kanagram/images/kicon.png
new file mode 100644
index 00000000..128c5cb4
--- /dev/null
+++ b/kanagram/images/kicon.png
Binary files differ
diff --git a/kanagram/images/kiconover.png b/kanagram/images/kiconover.png
new file mode 100644
index 00000000..56645c14
--- /dev/null
+++ b/kanagram/images/kiconover.png
Binary files differ
diff --git a/kanagram/images/next.png b/kanagram/images/next.png
new file mode 100644
index 00000000..692ce82e
--- /dev/null
+++ b/kanagram/images/next.png
Binary files differ
diff --git a/kanagram/images/nextover.png b/kanagram/images/nextover.png
new file mode 100644
index 00000000..055e3cd8
--- /dev/null
+++ b/kanagram/images/nextover.png
Binary files differ
diff --git a/kanagram/images/quit.png b/kanagram/images/quit.png
new file mode 100644
index 00000000..e94a4d75
--- /dev/null
+++ b/kanagram/images/quit.png
Binary files differ
diff --git a/kanagram/images/quitover.png b/kanagram/images/quitover.png
new file mode 100644
index 00000000..b33e48ba
--- /dev/null
+++ b/kanagram/images/quitover.png
Binary files differ
diff --git a/kanagram/images/up.png b/kanagram/images/up.png
new file mode 100644
index 00000000..937c31c1
--- /dev/null
+++ b/kanagram/images/up.png
Binary files differ
diff --git a/kanagram/images/updisabled.png b/kanagram/images/updisabled.png
new file mode 100644
index 00000000..b8394284
--- /dev/null
+++ b/kanagram/images/updisabled.png
Binary files differ
diff --git a/kanagram/images/upover.png b/kanagram/images/upover.png
new file mode 100644
index 00000000..bfb0a366
--- /dev/null
+++ b/kanagram/images/upover.png
Binary files differ
diff --git a/kanagram/sounds/Makefile.am b/kanagram/sounds/Makefile.am
new file mode 100644
index 00000000..56a113f3
--- /dev/null
+++ b/kanagram/sounds/Makefile.am
@@ -0,0 +1,2 @@
+soundsdir = $(kde_datadir)/kanagram/sounds
+sounds_DATA = right.ogg wrong.ogg chalk.ogg
diff --git a/kanagram/sounds/chalk.ogg b/kanagram/sounds/chalk.ogg
new file mode 100644
index 00000000..52d00d39
--- /dev/null
+++ b/kanagram/sounds/chalk.ogg
Binary files differ
diff --git a/kanagram/sounds/right.ogg b/kanagram/sounds/right.ogg
new file mode 100644
index 00000000..2e164fa1
--- /dev/null
+++ b/kanagram/sounds/right.ogg
Binary files differ
diff --git a/kanagram/sounds/wrong.ogg b/kanagram/sounds/wrong.ogg
new file mode 100644
index 00000000..7ac4ce6a
--- /dev/null
+++ b/kanagram/sounds/wrong.ogg
Binary files differ
diff --git a/kanagram/src/Makefile.am b/kanagram/src/Makefile.am
new file mode 100644
index 00000000..40096ec0
--- /dev/null
+++ b/kanagram/src/Makefile.am
@@ -0,0 +1,43 @@
+if include_ARTS
+artslib = -lartskde
+else
+artslib =
+endif
+
+# set the include path for X, qt and KDE
+INCLUDES = $(all_includes)
+
+# these are the headers for your project
+noinst_HEADERS = kanagram.h kanagramgame.h fontutils.h vocabsettings.h vocabedit.h vocabsettingswidget.h vocabeditwidget.h mainsettingswidget.h mainsettings.h newstuffwidget.h newstuffdialog.h newstuff.h
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(EXTRACTRC) `find . -name \*.ui -o -name \*.rc` > rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kanagram.pot
+
+KDE_ICON = AUTO
+
+#########################################################################
+# APPLICATION SECTION
+#########################################################################
+# this is the program that gets installed. it's name is used for all
+# of the other Makefile.am variables
+bin_PROGRAMS = kanagram
+
+# the application source, library search path, and link libraries
+kanagram_SOURCES = main.cpp kanagram.cpp kanagramgame.cpp fontutils.cpp kanagramsettings.kcfgc mainsettingswidget.ui vocabsettingswidget.ui vocabeditwidget.ui mainsettings.cpp vocabsettings.cpp vocabedit.cpp keduvocdocument.cpp keduvocexpression.cpp keduvockvtmlreader.cpp keduvockvtmlwriter.cpp leitnerbox.cpp leitnersystem.cpp multiplechoice.cpp grammarmanager.cpp leitnersystemview.cpp newstuffwidget.ui newstuffdialog.cpp newstuff.cpp
+kanagram_LDFLAGS = $(KDE_RPATH) $(all_libraries)
+kanagram_LDADD = $(LIB_KDEUI) $(LIB_KNEWSTUFF) $(LIB_KIO) $(artslib)
+
+kde_kcfg_DATA=kanagram.kcfg
+
+
+# this is where the desktop file will go
+xdg_apps_DATA = kanagram.desktop
+
+# this is where the shell's XML-GUI resource file goes
+# TODO does this app need an ui.rc ? If it does put it here
+# shellrcdir = $(kde_datadir)/kanagram
+# shellrc_DATA = kanagramui.rc
diff --git a/kanagram/src/fontutils.cpp b/kanagram/src/fontutils.cpp
new file mode 100644
index 00000000..320f501f
--- /dev/null
+++ b/kanagram/src/fontutils.cpp
@@ -0,0 +1,24 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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 <qpainter.h>
+
+#include "fontutils.h"
+
+int fontUtils::fontSize(QPainter &p, const QString &s1, int w, int h)
+{
+ QRect aux1;
+ QFont f = p.font();
+ f.setPointSize(28);
+ p.setFont(f);
+
+ aux1 = p.boundingRect(QRect(), Qt::AlignAuto, s1);
+
+ return QMIN(w * 28 / aux1.width(), h * 28 / aux1.height());
+}
diff --git a/kanagram/src/fontutils.h b/kanagram/src/fontutils.h
new file mode 100644
index 00000000..b6bc9c97
--- /dev/null
+++ b/kanagram/src/fontutils.h
@@ -0,0 +1,18 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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 FONTUTILS_H
+#define FONTUTILS_H
+
+namespace fontUtils
+{
+ int fontSize(QPainter &p, const QString &s1, int w, int h);
+}
+
+#endif
diff --git a/kanagram/src/grammarmanager.cpp b/kanagram/src/grammarmanager.cpp
new file mode 100644
index 00000000..dd526fd5
--- /dev/null
+++ b/kanagram/src/grammarmanager.cpp
@@ -0,0 +1,503 @@
+/***************************************************************************
+
+ manage grammar parts (articles, conjugation)
+
+ -----------------------------------------------------------------------
+
+ begin : Sat Nov 27 09:50:53 MET 1999
+
+ copyright : (C) 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de>
+ (C) 2001 The KDE-EDU team
+ (C) 2004-2005 Peter Hedlund <peter.hedlund@kdemail.net>
+
+ -----------------------------------------------------------------------
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 "grammarmanager.h"
+
+#include <klocale.h>
+
+Conjugation::conjug_name_t
+Conjugation::names [] =
+{
+ { CONJ_SIMPLE_PRESENT, I18N_NOOP("Simple Present") },
+ { CONJ_PRESENT_PROGR, I18N_NOOP("Present Progressive") },
+ { CONJ_PRESENT_PERFECT, I18N_NOOP("Present Perfect") },
+
+ { CONJ_SIMPLE_PAST, I18N_NOOP("Simple Past") },
+ { CONJ_PAST_PROGR, I18N_NOOP("Past Progressive") },
+ { CONJ_PAST_PARTICIPLE, I18N_NOOP("Past Participle") },
+
+ { CONJ_FUTURE, I18N_NOOP("Future") }
+};
+
+
+vector<QString> Conjugation::userTenses;
+
+
+//================================================================
+
+Comparison::Comparison (
+ const QString &l1,
+ const QString &l2,
+ const QString &l3
+ )
+{
+ setL1 (l1);
+ setL2 (l2);
+ setL3 (l3);
+}
+
+
+bool Comparison::isEmpty() const
+{
+ return ls1.stripWhiteSpace().isEmpty()
+ && ls2.stripWhiteSpace().isEmpty()
+ && ls3.stripWhiteSpace().isEmpty();
+}
+
+
+void Comparison::clear()
+{
+ ls1 = "";
+ ls2 = "";
+ ls3 = "";
+}
+
+
+//=================================================================
+
+
+Article::Article
+ (const QString &fem_def, const QString &fem_indef,
+ const QString &mal_def, const QString &mal_indef,
+ const QString &nat_def, const QString &nat_indef
+ )
+{
+ setFemale (fem_def, fem_indef);
+ setMale (mal_def, mal_indef);
+ setNatural (nat_def, nat_indef);
+}
+
+
+void Article::setFemale
+ (const QString &def, const QString &indef)
+{
+ fem_def = def;
+ fem_indef = indef;
+}
+
+
+void Article::setMale
+ (const QString &def, const QString &indef)
+{
+ mal_def = def;
+ mal_indef = indef;
+}
+
+
+void Article::setNatural
+ (const QString &def, const QString &indef)
+{
+ nat_def = def;
+ nat_indef = indef;
+}
+
+
+void Article::female
+ (QString &def, QString &indef) const
+{
+ def = fem_def;
+ indef = fem_indef;
+}
+
+
+void Article::male
+ (QString &def, QString &indef) const
+{
+ def = mal_def;
+ indef = mal_indef;
+}
+
+
+void Article::natural
+ (QString &def, QString &indef) const
+{
+ def = nat_def;
+ indef = nat_indef;
+}
+
+
+
+//==============================================================
+
+
+int Conjugation::numEntries() const
+{
+ return conjugations.size();
+}
+
+
+vector<TenseRelation> Conjugation::getRelation ()
+{
+ vector<TenseRelation> vec;
+
+ for (int i = 0; i < numInternalNames(); i++) {
+ vec.push_back(TenseRelation(names[i].abbrev,
+ i18n(names[i].name)));
+ }
+
+ for (int i = 0; i < (int) userTenses.size(); i++) {
+ QString s;
+ s.setNum(i+1);
+ s.insert(0, UL_USER_TENSE);
+ vec.push_back(TenseRelation(s, userTenses[i]));
+ }
+
+ return vec;
+}
+
+
+void Conjugation::setTenseNames (vector<QString> names)
+{
+ userTenses = names;
+}
+
+
+QString Conjugation::getName (const QString &abbrev)
+{
+ if (abbrev.length() >= 2 && abbrev[0] == QString(UL_USER_TENSE)) {
+ QString s = abbrev;
+ s.remove(0, 1);
+ int i = s.toInt() - 1;
+
+ if (i < (int) userTenses.size() )
+ return userTenses[i];
+ else
+ return "";
+ }
+ else {
+ for (int i = 0; i < (int) numInternalNames(); i++)
+ if (names[i].abbrev == abbrev) {
+ return i18n(names[i].name);
+ }
+ }
+
+ return "";
+}
+
+
+QString Conjugation::getName (int idx)
+{
+ if (idx < numInternalNames() )
+ return i18n(names[idx].name);
+
+ else if (idx < numTenses() )
+ return userTenses[idx-numInternalNames()];
+
+ else
+ return "";
+}
+
+
+QString Conjugation::getAbbrev (const QString &name)
+{
+ for (int i = 0; i < (int) userTenses.size(); i++)
+ if (userTenses[i] == name) {
+ QString s;
+ s.setNum(i+1);
+ s.insert(0, UL_USER_TENSE);
+ return s;
+ }
+
+ for (int i = 0; i < (int) numInternalNames(); i++)
+ if (names[i].name == name)
+ return names[i].abbrev;
+
+ return "";
+}
+
+
+QString Conjugation::getAbbrev (int idx)
+{
+ if (idx < numInternalNames() )
+ return names[idx].abbrev;
+
+ else if (idx < numTenses() ) {
+ QString s;
+ s.setNum(idx-numInternalNames()+1);
+ s.insert(0, UL_USER_TENSE);
+ return s;
+ }
+
+ else
+ return "";
+}
+
+
+int Conjugation::numInternalNames()
+{
+ return sizeof(names) / sizeof(names[0]);
+}
+
+
+int Conjugation::numTenses()
+{
+ return numInternalNames()+userTenses.size();
+}
+
+
+QString Conjugation::getType (int idx)
+{
+ if (idx >= (int) conjugations.size() )
+ return "";
+
+ return conjugations[idx].type;
+}
+
+
+void Conjugation::setType (int idx, const QString & type)
+{
+ if (idx >= (int) conjugations.size() )
+ return;
+
+ conjugations[idx].type = type;
+}
+
+
+void Conjugation::cleanUp ()
+{
+ for (int i = (int)conjugations.size()-1; i >= 0; i--) {
+ const conjug_t *ctp = &conjugations[i];
+ if ( ctp->pers1_sing.stripWhiteSpace().isEmpty()
+ && ctp->pers2_sing.stripWhiteSpace().isEmpty()
+ && ctp->pers3_m_sing.stripWhiteSpace().isEmpty()
+ && ctp->pers3_f_sing.stripWhiteSpace().isEmpty()
+ && ctp->pers3_n_sing.stripWhiteSpace().isEmpty()
+ && ctp->pers1_plur.stripWhiteSpace().isEmpty()
+ && ctp->pers2_plur.stripWhiteSpace().isEmpty()
+ && ctp->pers3_m_plur.stripWhiteSpace().isEmpty()
+ && ctp->pers3_f_plur.stripWhiteSpace().isEmpty()
+ && ctp->pers3_n_plur.stripWhiteSpace().isEmpty()
+ )
+ conjugations.erase(conjugations.begin() + i);
+ }
+}
+
+
+bool Conjugation::isEmpty (int idx)
+{
+ if (idx < (int) conjugations.size()) {
+ const conjug_t *ctp = &conjugations[idx];
+ return ctp->pers1_sing.stripWhiteSpace().isEmpty()
+ && ctp->pers2_sing.stripWhiteSpace().isEmpty()
+ && ctp->pers3_m_sing.stripWhiteSpace().isEmpty()
+ && ctp->pers3_f_sing.stripWhiteSpace().isEmpty()
+ && ctp->pers3_n_sing.stripWhiteSpace().isEmpty()
+ && ctp->pers1_plur.stripWhiteSpace().isEmpty()
+ && ctp->pers2_plur.stripWhiteSpace().isEmpty()
+ && ctp->pers3_m_plur.stripWhiteSpace().isEmpty()
+ && ctp->pers3_f_plur.stripWhiteSpace().isEmpty()
+ && ctp->pers3_n_plur.stripWhiteSpace().isEmpty();
+ }
+ return true;
+}
+
+
+#define _GET_CON_(elem, type, default) \
+ for (int i = 0; i < (int) conjugations.size(); i++) \
+ if (conjugations[i].type == type) \
+ return conjugations[i].elem; \
+ return default;
+
+
+bool Conjugation::pers3SingularCommon(const QString &type) const
+{
+ _GET_CON_(s3common, type, false);
+}
+
+
+bool Conjugation::pers3PluralCommon(const QString &type) const
+{
+ _GET_CON_(p3common, type, false);
+}
+
+
+QString Conjugation::pers1Singular
+ (const QString &type) const
+{
+ _GET_CON_(pers1_sing, type, "");
+}
+
+
+QString Conjugation::pers2Singular
+ (const QString &type) const
+{
+ _GET_CON_(pers2_sing, type, "");
+}
+
+
+QString Conjugation::pers3FemaleSingular
+ (const QString &type) const
+{
+ _GET_CON_(pers3_f_sing, type, "");
+}
+
+
+QString Conjugation::pers3MaleSingular
+ (const QString &type) const
+{
+ _GET_CON_(pers3_m_sing, type, "");
+}
+
+
+QString Conjugation::pers3NaturalSingular
+ (const QString &type) const
+{
+ _GET_CON_(pers3_n_sing, type, "");
+}
+
+
+QString Conjugation::pers1Plural
+ (const QString &type) const
+{
+ _GET_CON_(pers1_plur, type, "");
+}
+
+
+QString Conjugation::pers2Plural
+ (const QString &type) const
+{
+ _GET_CON_(pers2_plur, type, "");
+}
+
+
+QString Conjugation::pers3FemalePlural
+ (const QString &type) const
+{
+ _GET_CON_(pers3_f_plur, type, "");
+}
+
+
+QString Conjugation::pers3MalePlural
+ (const QString &type) const
+{
+ _GET_CON_(pers3_m_plur, type, "");
+}
+
+
+QString Conjugation::pers3NaturalPlural
+ (const QString &type) const
+{
+ _GET_CON_(pers3_n_plur, type, "");
+}
+
+
+#undef _GET_CON_
+
+
+#define _SET_CON_(elem, type, str) \
+ for (int i = 0; i < (int) conjugations.size(); i++) \
+ if (conjugations[i].type == type) { \
+ conjugations[i].elem = str; \
+ return; \
+ } \
+ conjug_t ct; \
+ ct.type = type; \
+ ct.elem = str; \
+ conjugations.push_back(ct);
+
+
+void Conjugation::setPers3PluralCommon(const QString &type, bool f)
+{
+ _SET_CON_(p3common, type, f);
+}
+
+
+void Conjugation::setPers3SingularCommon(const QString &type, bool f)
+{
+ _SET_CON_(s3common, type, f);
+}
+
+
+void Conjugation::setPers1Singular
+ (const QString &type, const QString &str)
+{
+ _SET_CON_(pers1_sing, type, str);
+}
+
+
+void Conjugation::setPers2Singular
+ (const QString &type, const QString &str)
+{
+ _SET_CON_(pers2_sing, type, str);
+}
+
+
+void Conjugation::setPers3FemaleSingular
+ (const QString &type, const QString &str)
+{
+ _SET_CON_(pers3_f_sing, type, str);
+}
+
+
+void Conjugation::setPers3MaleSingular
+ (const QString &type, const QString &str)
+{
+ _SET_CON_(pers3_m_sing, type, str);
+}
+
+
+void Conjugation::setPers3NaturalSingular
+ (const QString &type, const QString &str)
+{
+ _SET_CON_(pers3_n_sing, type, str);
+}
+
+
+void Conjugation::setPers1Plural
+ (const QString &type, const QString &str)
+{
+ _SET_CON_(pers1_plur, type, str);
+}
+
+
+void Conjugation::setPers2Plural
+ (const QString &type, const QString &str)
+{
+ _SET_CON_(pers2_plur, type, str);
+}
+
+
+void Conjugation::setPers3FemalePlural
+ (const QString &type, const QString &str)
+{
+ _SET_CON_(pers3_f_plur, type, str);
+}
+
+
+void Conjugation::setPers3MalePlural
+ (const QString &type, const QString &str)
+{
+ _SET_CON_(pers3_m_plur, type, str);
+}
+
+
+void Conjugation::setPers3NaturalPlural
+ (const QString &type, const QString &str)
+{
+ _SET_CON_(pers3_n_plur, type, str);
+}
+
+#undef _SET_CON_
+
diff --git a/kanagram/src/grammarmanager.h b/kanagram/src/grammarmanager.h
new file mode 100644
index 00000000..1b9cfe76
--- /dev/null
+++ b/kanagram/src/grammarmanager.h
@@ -0,0 +1,215 @@
+/***************************************************************************
+
+ manage grammer parts (articles, conjugation)
+
+ -----------------------------------------------------------------------
+
+ begin : Sat Nov 27 09:50:53 MET 1999
+
+ copyright : (C) 1999-2001 Ewald Arnold
+ (C) 2001 The KDE-EDU team
+ email : kvoctrain@ewald-arnold.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 grammarmanager_included
+#define grammarmanager_included
+
+#include <qstring.h>
+
+#include <vector>
+using namespace std;
+
+#define CONJ_SIMPLE_PRESENT "PrSi" // I live at home what you frequently do
+#define CONJ_PRESENT_PROGR "PrPr" // I am working what you currently are doing
+#define CONJ_PRESENT_PERFECT "PrPe" // I have cleaned tell, #that# something has happened
+
+#define CONJ_SIMPLE_PAST "PaSi" // the train left 2 min ago when did it happen
+#define CONJ_PAST_PROGR "PaPr" // it was raining what happen at a given time in the past
+#define CONJ_PAST_PARTICIPLE "PaPa" // I cleaned tell, #that# it happened
+
+#define CONJ_FUTURE "FuSi"
+
+#define CONJ_PREFIX "--" // definition of prefixes (I, you, ..)
+
+#define UL_USER_TENSE "#" // designates number of user tense
+
+class Article
+{
+
+public:
+
+ Article() {}
+
+ Article (
+ const QString &fem_def, const QString &fem_indef,
+ const QString &mal_def, const QString &mal_indef,
+ const QString &nat_def, const QString &nat_indef
+ );
+
+ void setFemale (const QString &def, const QString &indef);
+ void setMale (const QString &def, const QString &indef);
+ void setNatural (const QString &def, const QString &indef);
+
+ void female (QString &def, QString &indef) const;
+ void male (QString &def, QString &indef) const;
+ void natural (QString &def, QString &indef) const;
+
+protected:
+
+ QString fem_def, fem_indef,
+ mal_def, mal_indef,
+ nat_def, nat_indef;
+};
+
+
+class Comparison
+{
+
+public:
+
+ Comparison() {}
+
+ Comparison (
+ const QString &l1,
+ const QString &l2,
+ const QString &l3
+ );
+
+ void setL1 (const QString &s) { ls1 = s; }
+ void setL2 (const QString &s) { ls2 = s; }
+ void setL3 (const QString &s) { ls3 = s; }
+
+ QString l1 () const { return ls1; }
+ QString l2 () const { return ls2; }
+ QString l3 () const { return ls3; }
+
+ bool isEmpty() const;
+ void clear();
+
+protected:
+
+ QString ls1, ls2, ls3;
+};
+
+
+class TenseRelation
+{
+ public:
+
+ TenseRelation (const QString & _short, const QString & _long)
+ : shortId (_short), longId(_long) {}
+
+ inline QString shortStr() const { return shortId; }
+ inline QString longStr() const { return longId; }
+
+ protected:
+
+ QString shortId, longId;
+};
+
+
+class Conjugation
+{
+
+public:
+
+ Conjugation () {}
+
+ int numEntries() const;
+
+ static vector<TenseRelation> getRelation ();
+ static void setTenseNames (vector<QString> names);
+
+ static QString getName (const QString &abbrev);
+ static QString getName (int index);
+ static QString getAbbrev (const QString &name);
+ static QString getAbbrev (int index);
+ static int numInternalNames();
+ static int numTenses();
+
+ QString getType (int index);
+ void setType (int index, const QString & type);
+ void cleanUp();
+ bool isEmpty (int idx);
+
+ QString pers1Singular(const QString &type) const;
+ QString pers2Singular(const QString &type) const;
+ bool pers3SingularCommon(const QString &type) const;
+ QString pers3FemaleSingular(const QString &type) const;
+ QString pers3MaleSingular(const QString &type) const;
+ QString pers3NaturalSingular(const QString &type) const;
+
+ QString pers1Plural(const QString &type) const;
+ QString pers2Plural(const QString &type) const;
+ bool pers3PluralCommon(const QString &type) const;
+ QString pers3FemalePlural(const QString &type) const;
+ QString pers3MalePlural(const QString &type) const;
+ QString pers3NaturalPlural(const QString &type) const;
+
+ void setPers1Singular(const QString &type, const QString &str);
+ void setPers2Singular(const QString &type, const QString &str);
+ void setPers3SingularCommon(const QString &type, bool f);
+ void setPers3FemaleSingular(const QString &type, const QString &str);
+ void setPers3MaleSingular(const QString &type, const QString &str);
+ void setPers3NaturalSingular(const QString &type, const QString &str);
+
+ void setPers1Plural(const QString &type, const QString &str);
+ void setPers2Plural(const QString &type, const QString &str);
+ void setPers3PluralCommon(const QString &type, bool f);
+ void setPers3FemalePlural(const QString &type, const QString &str);
+ void setPers3MalePlural(const QString &type, const QString &str);
+ void setPers3NaturalPlural(const QString &type, const QString &str);
+
+private:
+
+ struct conjug_t {
+
+ conjug_t() {
+ p3common = false;
+ s3common = false;
+ }
+
+ QString type;
+ bool p3common,
+ s3common;
+ QString pers1_sing,
+ pers2_sing,
+ pers3_m_sing,
+ pers3_f_sing,
+ pers3_n_sing,
+ pers1_plur,
+ pers2_plur,
+ pers3_m_plur,
+ pers3_f_plur,
+ pers3_n_plur;
+ };
+
+ struct conjug_name_t {
+ const char *abbrev;
+ const char *name;
+ };
+
+protected:
+
+ vector<conjug_t> conjugations;
+
+ static conjug_name_t names [];
+ static vector<QString> userTenses;
+};
+
+
+#endif // grammarmanager_included
+
diff --git a/kanagram/src/kanagram.cpp b/kanagram/src/kanagram.cpp
new file mode 100644
index 00000000..088453a2
--- /dev/null
+++ b/kanagram/src/kanagram.cpp
@@ -0,0 +1,787 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joshua Keel *
+ * joshuakeel@gmail.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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <iostream>
+using namespace std;
+
+#include <config.h>
+
+#include <qcursor.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qtimer.h>
+#include <qstring.h>
+#include <qfontmetrics.h>
+#include <qdir.h>
+
+#include <kaction.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <khelpmenu.h>
+#include <kinputdialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kpopupmenu.h>
+#include <kstandarddirs.h>
+#include <kconfigdialog.h>
+#include <kconfigskeleton.h>
+#include <krandomsequence.h>
+#include <kdebug.h>
+
+#include "kanagram.h"
+#include "kanagramsettings.h"
+#include "mainsettings.h"
+#include "vocabsettings.h"
+#include "newstuff.h"
+
+static const char* m_textRevealWord = I18N_NOOP("reveal word");
+static const char* m_textHint = I18N_NOOP("hint");
+
+Kanagram::Kanagram() : QWidget(0, 0, WStaticContents | WNoAutoErase), m_overNext(false), m_overConfig(false), m_overHelp(false), m_overQuit(false), m_overReveal(false), m_overHint(false), m_overUp(false), m_overHintBox(false), m_showHint(false)
+{
+ m_game = new KanagramGame(this);
+
+ m_back = new QPixmap(locate("appdata", "images/kanagram.png"));
+ m_aboutKDEOverlay = new QPixmap(locate("appdata", "images/kicon.png"));
+ m_aboutKDEOverlayOver = new QPixmap(locate("appdata", "images/kiconover.png"));
+ m_aboutAppOverlay = new QPixmap(locate("appdata", "images/appicon.png"));
+ m_aboutAppOverlayOver = new QPixmap(locate("appdata", "images/appiconover.png"));
+ m_handbookOverlay = new QPixmap(locate("appdata", "images/handbookicon.png"));
+ m_handbookOverlayOver = new QPixmap(locate("appdata", "images/handbookiconover.png"));
+ m_card = new QPixmap(locate("appdata", "images/card.png"));
+
+ m_next = new QPixmap(locate("appdata", "images/next.png"));
+ m_nextOver = new QPixmap(locate("appdata", "images/nextover.png"));
+ m_config = new QPixmap(locate("appdata", "images/config.png"));
+ m_configOver = new QPixmap(locate("appdata", "images/configover.png"));
+ m_help = new QPixmap(locate("appdata", "images/help.png"));
+ m_helpOver = new QPixmap(locate("appdata", "images/helpover.png"));
+ m_quit = new QPixmap(locate("appdata", "images/quit.png"));
+ m_quitOver = new QPixmap(locate("appdata", "images/quitover.png"));
+
+ m_up = new QPixmap(locate("appdata", "images/up.png"));
+ m_upOver = new QPixmap(locate("appdata", "images/upover.png"));
+ m_upDisabled = new QPixmap(locate("appdata", "images/updisabled.png"));
+
+ m_nextRect = QRect(477, 31, 134, 76);
+ m_configRect = QRect(477, 122, 134, 76);
+ m_helpRect = QRect(477, 212, 134, 76);
+ m_quitRect = QRect(453, 352, 182, 104);
+
+ m_hintBoxRect = QRect(446, 207, 171, 85);
+ m_upRect = QRect(341, 425, 55, 33);
+ m_aboutKDERect = QRect(567, 213, 44, 44);
+ m_aboutAppRect = QRect(522, 213, 44, 44);
+ m_handbookRect = QRect(478, 213, 44, 44);
+ m_arrowRect = QRect(380, 134, 13, 20);
+ m_logoRect = QRect(76, 24, 297, 50);
+
+ //blackboardRect intentionally wrong to make sure fonts align correctly
+ m_blackboardRect = QRect(41, 116, 366, 255);
+
+ setupRects();
+
+ setMouseTracking(true);
+ setFixedSize(650, 471);
+ show();
+
+ m_chalkColor = QColor(155, 155, 155);
+ m_chalkHighlightColor = QColor(255, 255, 255);
+ m_fillColor = QColor(45, 45, 45);
+ m_fontColor = QColor(55, 55, 55);
+ m_fontHighlightColor = QColor(99, 99, 99);
+
+ loadSettings();
+
+ m_hintTimer = new QTimer(this);
+
+ m_helpMenu = new KHelpMenu(this, kapp->aboutData());
+
+ m_inputBox = new QLineEdit(this);
+ m_inputBox->setGeometry(QRect(52, 427, 273, 29));
+ m_inputBox->setFrame(false);
+
+ connect(m_inputBox, SIGNAL(returnPressed()), this, SLOT(checkWord()));
+ connect(m_hintTimer, SIGNAL(timeout()), this, SLOT(hideHint()));
+ connect(m_inputBox, SIGNAL(textChanged(const QString &)), this, SLOT(update()));
+
+ QFont f = QFont();
+ f.setPointSize(17);
+ m_inputBox->setFont(f);
+ m_inputBox->show();
+
+ m_font = KGlobalSettings::generalFont();
+
+ //Initialize the sound server
+ #ifndef WITHOUT_ARTS
+ m_artsDispatcher = new KArtsDispatcher();
+ m_artsServer = new KArtsServer();
+ m_artsFactory = new KDE::PlayObjectFactory(m_artsServer->server());
+ #endif
+}
+
+Kanagram::~Kanagram()
+{
+}
+
+void Kanagram::loadSettings()
+{
+ QString hideTime = KanagramSettings::hintHideTime();
+ if(hideTime[0].isDigit())
+ m_hintHideTime = hideTime[0].digitValue();
+ else
+ m_hintHideTime = 0;
+
+ m_useSounds = KanagramSettings::useSounds();
+ m_useStandardFonts = KanagramSettings::useStandardFonts();
+
+ if(m_useStandardFonts)
+ {
+ m_blackboardFont = KGlobalSettings::generalFont();
+ m_arrow = new QPixmap(locate("appdata", "images/basicarrow.png"));
+ m_arrowOver = new QPixmap(locate("appdata", "images/basicarrowover.png"));
+ }
+ else
+ {
+ m_blackboardFont = QFont("squeaky chalk sound");
+ m_arrow = new QPixmap(locate("appdata", "images/arrow.png"));
+ m_arrowOver = new QPixmap(locate("appdata", "images/arrowover.png"));
+ }
+
+ m_game->refreshVocabList();
+}
+
+void Kanagram::setupRects()
+{
+ QPainter tmpp(this);
+ QFont font = m_blackboardFont;
+ font.setPointSize(14);
+ font.setBold(true);
+ tmpp.setFont(font);
+ int yOffset = 0;
+ //set appropriate yOffset for different fonts
+ if(m_useStandardFonts) yOffset = 6;
+ QRect r = innerRect(m_blackboardRect, 6, yOffset);
+ m_hintRect = tmpp.boundingRect(r, Qt::AlignBottom|Qt::AlignLeft, i18n(m_textHint));
+ m_revealRect = tmpp.boundingRect(r, Qt::AlignBottom|Qt::AlignRight, i18n(m_textRevealWord));
+ tmpp.end();
+}
+
+void Kanagram::paintEvent(QPaintEvent *)
+{
+ QPixmap buf(width(), height());
+ QPainter p(&buf);
+
+ p.drawPixmap(0, 0, *m_back);
+
+ if(m_overNext)
+ p.drawPixmap(525, 38, *m_nextOver);
+ else
+ p.drawPixmap(525, 38, *m_next);
+ if(m_overConfig)
+ p.drawPixmap(525, 130, *m_configOver);
+ else
+ p.drawPixmap(525, 130, *m_config);
+ if(m_overHelp)
+ p.drawPixmap(525, 218, *m_helpOver);
+ else
+ p.drawPixmap(525, 218, *m_help);
+ if(m_overQuit)
+ p.drawPixmap(520, 362, *m_quitOver);
+ else
+ p.drawPixmap(520, 362, *m_quit);
+
+ //draw main Anagram
+ drawTextNew(p, m_game->getAnagram(), Qt::AlignCenter, 10, 10, m_blackboardRect, true, 28);
+
+ int yOffset = 0;
+ //set appropriate yOffset for different fonts
+ if(m_useStandardFonts) yOffset = 6;
+ //draw text using appropriate yOffset
+ drawTextNew(p, i18n(m_textRevealWord), Qt::AlignBottom | Qt::AlignRight, 6, yOffset, m_blackboardRect, m_overReveal, 14);
+ drawTextNew(p, i18n(m_textHint), Qt::AlignBottom | Qt::AlignLeft, 6, yOffset, m_blackboardRect, m_overHint, 14);
+
+ //draw vocab switcher
+ drawSwitcher(p, 9, 8);
+
+ p.setPen(QPen(black, 3));
+
+ //Draw the border of the input box
+ QRect borderRect = m_inputBox->geometry();
+ borderRect.setLeft(borderRect.left() - 2);
+ borderRect.setTop(borderRect.top() - 2);
+ borderRect.setWidth(borderRect.width() + 2 * 1);
+ borderRect.setHeight(borderRect.height() + 2 * 1);
+ p.drawRoundRect(borderRect, 10, 5);
+
+ //Draw the border of the Up arrow
+ borderRect = m_upRect;
+ p.fillRect(borderRect, m_fillColor);
+ p.drawRoundRect(borderRect, 10, 5);
+
+ if(m_overUp && m_inputBox->text() != "")
+ p.drawPixmap(350, 431, *m_upOver);
+ else if(m_inputBox->text() == "")
+ p.drawPixmap(350, 431, *m_upDisabled);
+ else
+ p.drawPixmap(350, 431, *m_up);
+
+ if(m_showHint)
+ {
+ p.drawPixmap(439, 204, *m_hintOverlay);
+ QFont f = QFont(m_font);
+ f.setWeight(QFont::Bold);
+ f.setPointSize(10);
+ p.setFont(f);
+ p.drawText(459, 217, 148, 67, WordBreak | AlignCenter, m_game->getHint());
+ }
+
+ if(m_overHelp && !m_showHint)
+ {
+ p.drawPixmap(456, 275, *m_card);
+ if(m_overAboutApp)
+ {
+ p.drawPixmap(522, 213, *m_aboutAppOverlay);
+ drawHelpText(p, i18n("About Kanagram"));
+ }
+ else
+ p.drawPixmap(522, 213, *m_aboutAppOverlayOver);
+ if(m_overAboutKDE)
+ {
+ p.drawPixmap(567, 213, *m_aboutKDEOverlay);
+ drawHelpText(p, i18n("About KDE"));
+ }
+ else
+ p.drawPixmap(567, 213, *m_aboutKDEOverlayOver);
+ if(m_overHandbook)
+ {
+ p.drawPixmap(478, 213, *m_handbookOverlay);
+ drawHelpText(p, i18n("Kanagram Handbook"));
+ }
+ else
+ p.drawPixmap(478, 213, *m_handbookOverlayOver);
+ }
+ else if(m_overNext)
+ {
+ p.drawPixmap(456, 275, *m_card);
+ drawHelpText(p, i18n("Next Word"));
+ }
+ else if(m_overConfig)
+ {
+ p.drawPixmap(456, 275, *m_card);
+ drawHelpText(p, i18n("Configure Kanagram"));
+ }
+ else if(m_overQuit)
+ {
+ p.drawPixmap(456, 275, *m_card);
+ drawHelpText(p, i18n("Quit Kanagram"));
+ }
+
+ bitBlt(this, 0, 0, &buf);
+}
+
+void Kanagram::drawHelpText(QPainter &p, QString text)
+{
+ p.save();
+ QFont font = m_font;
+ font.setPointSize(12);
+ p.setFont(font);
+ p.rotate(-3.29);
+ p.setPen(black);
+ p.drawText(450, 340, text.section(' ', 0, 0));
+ p.drawText(450, 360, text.section(' ', 1));
+ p.restore();
+}
+
+void Kanagram::drawSwitcherText(QPainter &p, QString text)
+{
+ p.save();
+ QFont font = m_blackboardFont;
+ font.setPointSize(14);
+ QFontMetrics fm(font);
+ int width = fm.width(text);
+ int height = fm.height();
+ m_switcherRect = QRect(380 - width, 150 - height, width, height);
+ p.setFont(font);
+ if(!m_overSwitcher)
+ p.setPen(m_chalkColor);
+ else
+ p.setPen(m_chalkHighlightColor);
+ p.drawText(380 - width, 150, text);
+ p.restore();
+}
+
+void Kanagram::drawSwitcher(QPainter &p, const int xMargin, const int yMargin)
+{
+ const int padding = 5;
+ QString text = m_game->getDocTitle();
+ QFont font = m_blackboardFont;
+ font.setPointSize(14);
+ QFontMetrics fm(font);
+ QRect r = innerRect(m_blackboardRect, xMargin, yMargin);
+ r.normalize();
+ r.moveBy(- padding - (m_overSwitcher ? m_arrowOver : m_arrow )->width(), yMargin);
+ r.setHeight( (m_overSwitcher ? m_arrowOver : m_arrow )->height());
+ m_switcherRect = p.boundingRect(r, Qt::AlignVCenter|Qt::AlignRight, text);
+ p.setFont(font);
+ if (m_overSwitcher)
+ {
+ p.setPen(m_chalkHighlightColor);
+ p.drawPixmap(m_switcherRect.right() + padding, m_switcherRect.top(), *m_arrowOver);
+ }
+ else
+ {
+ p.setPen(m_chalkColor);
+ p.drawPixmap(m_switcherRect.right() + padding, m_switcherRect.top(), *m_arrow);
+ }
+ m_switcherRect.moveBy(0, -2);
+ p.drawText(m_switcherRect, Qt::AlignVCenter|Qt::AlignRight, text);
+}
+
+QRect Kanagram::innerRect(const QRect &rect, const int xMargin, const int yMargin)
+{
+ QRect r = rect;
+
+ if (xMargin>0)
+ {
+ r.setWidth(r.width() - 2 * xMargin);
+ r.moveBy(xMargin, 0);
+ }
+ if (yMargin>0)
+ {
+ r.setHeight(r.height() - 2 * yMargin);
+ r.moveBy(0, yMargin);
+ }
+
+ return r;
+}
+
+void Kanagram::mousePressEvent(QMouseEvent *e)
+{
+
+ if (m_nextRect.contains(e->pos()))
+ {
+ hideHint();
+ m_game->nextAnagram();
+ if(m_useSounds) play("chalk.ogg");
+ m_inputBox->unsetPalette();
+ update();
+ }
+
+ if(m_configRect.contains(e->pos()))
+ {
+ showSettings();
+ }
+
+ if(m_quitRect.contains(e->pos()))
+ {
+ kapp->quit();
+ }
+
+ if(m_revealRect.contains(e->pos()))
+ {
+ m_game->restoreWord();
+ update();
+ }
+
+ if(m_logoRect.contains(e->pos()))
+ {
+ m_helpMenu->aboutApplication();
+ }
+
+ if(!m_showHint && m_overHelp)
+ {
+ if(m_handbookRect.contains(e->pos()))
+ {
+ m_helpMenu->appHelpActivated();
+ }
+
+ if(m_aboutKDERect.contains(e->pos()))
+ {
+ m_helpMenu->aboutKDE();
+ }
+
+ if(m_aboutAppRect.contains(e->pos()))
+ {
+ m_helpMenu->aboutApplication();
+ }
+ }
+
+ if(m_hintBoxRect.contains(e->pos()))
+ {
+ hideHint();
+ }
+
+ if(m_switcherRect.contains(e->pos()) || m_arrowRect.contains(e->pos()))
+ {
+ if(!(e->button() == RightButton))
+ m_game->nextVocab();
+ else
+ m_game->previousVocab();
+ hideHint();
+ m_game->nextAnagram();
+ if(m_useSounds) play("chalk.ogg");
+ KanagramSettings::setDefaultVocab(m_game->getFilename());
+ KanagramSettings::writeConfig();
+ update();
+ }
+
+ if(m_hintRect.contains(e->pos()))
+ {
+ if(m_showHint == true) m_showHint = false;
+ else
+ {
+ if(m_hintHideTime)
+ {
+ m_hintTimer->start(m_hintHideTime * 1000, TRUE);
+ }
+ m_showHint = true;
+ randomHintImage();
+ }
+ update();
+ }
+
+ if(m_upRect.contains(e->pos()) && m_inputBox->text() != "")
+ {
+ if(m_inputBox->text().lower().stripWhiteSpace() == m_game->getWord())
+ {
+ if(m_useSounds) play("right.ogg");
+ m_inputBox->setPaletteBackgroundColor(QColor(0, 255, 0));
+ QTimer::singleShot(1000, this, SLOT(resetInputBox()));
+ m_inputBox->clear();
+ hideHint();
+ m_game->nextAnagram();
+ update();
+ }
+ else
+ {
+ if(m_useSounds) play("wrong.ogg");
+ m_inputBox->setPaletteBackgroundColor(QColor(255, 0, 0));
+ QTimer::singleShot(1000, this, SLOT(resetInputBox()));
+ m_inputBox->clear();
+ update();
+ }
+ }
+}
+
+void Kanagram::mouseMoveEvent(QMouseEvent *e)
+{
+ updateButtonHighlighting(e->pos());
+}
+
+void Kanagram::updateButtonHighlighting(const QPoint &p)
+{
+ bool haveToUpdate;
+ haveToUpdate = false;
+
+ if (m_nextRect.contains(p))
+ {
+ if (!m_overNext)
+ {
+ m_overNext = true;
+ haveToUpdate = true;
+ }
+ }
+ else if (m_overNext)
+ {
+ m_overNext = false;
+ haveToUpdate = true;
+ }
+
+ if(m_configRect.contains(p))
+ {
+ if(!m_overConfig)
+ {
+ m_overConfig = true;
+ haveToUpdate = true;
+ }
+ }
+ else if(m_overConfig)
+ {
+ m_overConfig = false;
+ haveToUpdate = true;
+ }
+
+ if(m_helpRect.contains(p))
+ {
+ if(!m_overHelp)
+ {
+ m_overHelp = true;
+ haveToUpdate = true;
+ }
+ }
+ else if(m_overHelp)
+ {
+ m_overHelp = false;
+ haveToUpdate = true;
+ }
+
+ if(m_quitRect.contains(p))
+ {
+ if(!m_overQuit)
+ {
+ m_overQuit = true;
+ haveToUpdate = true;
+ }
+ }
+ else if(m_overQuit)
+ {
+ m_overQuit = false;
+ haveToUpdate = true;
+ }
+
+ if(m_hintRect.contains(p))
+ {
+ if(!m_overHint)
+ {
+ m_overHint = true;
+ haveToUpdate = true;
+ }
+ }
+ else if(m_overHint)
+ {
+ m_overHint = false;
+ haveToUpdate = true;
+ }
+
+ if(m_hintBoxRect.contains(p))
+ {
+ if(!m_overHintBox)
+ {
+ m_overHintBox = true;
+ haveToUpdate = true;
+ }
+ }
+ else if(m_overHintBox)
+ {
+ m_overHintBox = false;
+ haveToUpdate = true;
+ }
+
+ if(m_revealRect.contains(p))
+ {
+ if(!m_overReveal)
+ {
+ m_overReveal = true;
+ haveToUpdate = true;
+ }
+ }
+ else if(m_overReveal)
+ {
+ m_overReveal = false;
+ haveToUpdate = true;
+ }
+
+ if(m_upRect.contains(p))
+ {
+ if(!m_overUp)
+ {
+ m_overUp = true;
+ haveToUpdate = true;
+ }
+ }
+ else if(m_overUp)
+ {
+ m_overUp = false;
+ haveToUpdate = true;
+ }
+
+ if(m_switcherRect.contains(p) || m_arrowRect.contains(p))
+ {
+ if(!m_overSwitcher)
+ {
+ m_overSwitcher = true;
+ haveToUpdate = true;
+ }
+ }
+ else if(m_overSwitcher)
+ {
+ m_overSwitcher = false;
+ haveToUpdate = true;
+ }
+
+ if(m_aboutAppRect.contains(p))
+ {
+ if(!m_overAboutApp)
+ {
+ m_overAboutApp = true;
+ haveToUpdate = true;
+ }
+ }
+ else if(m_overAboutApp)
+ {
+ m_overAboutApp = false;
+ haveToUpdate = true;
+ }
+
+ if(!m_showHint)
+ {
+ if(m_handbookRect.contains(p))
+ {
+ if(!m_overHandbook)
+ {
+ m_overHandbook = true;
+ haveToUpdate = true;
+ }
+ }
+ else if(m_overHandbook)
+ {
+ m_overHandbook = false;
+ haveToUpdate = true;
+ }
+
+ if(m_aboutKDERect.contains(p))
+ {
+ if(!m_overAboutKDE)
+ {
+ m_overAboutKDE = true;
+ haveToUpdate = true;
+ }
+ }
+ else if(m_overAboutKDE)
+ {
+ m_overAboutKDE = false;
+ haveToUpdate = true;
+ }
+ }
+
+ if(m_overAboutKDE || m_overHandbook || m_overSwitcher || m_overNext || m_overQuit || m_overConfig || m_overReveal || m_overHint || (m_overUp && m_inputBox->text() != "") || m_overAboutApp || m_overHintBox)
+ this->setCursor(PointingHandCursor);
+ else
+ this->unsetCursor();
+
+ if (haveToUpdate) update();
+}
+
+void Kanagram::drawText(QPainter &p, const QString &text, const QPoint &center, bool withMargin, int xMargin, int yMargin, QRect *rect, bool highlight, int fontSize)
+{
+ QRect r;
+ QFont font = m_blackboardFont;
+ font.setPointSize(fontSize);
+ font.setBold(true);
+ p.setFont(font);
+
+ r = p.boundingRect(QRect(), Qt::AlignAuto, text);
+ r = QRect(0, 0, r.width() + xMargin, r.height() + yMargin);
+ r.moveBy(center.x() - r.width() / 2, center.y() - r.height() / 2);
+
+ if (withMargin)
+ {
+ p.fillRect(r, m_fillColor);
+ p.setPen(QPen(black, 3));
+ p.drawRoundRect(r.left(), r.top(), r.width(), r.height(), 15, 15);
+ }
+
+ if (!highlight) p.setPen(m_chalkColor);
+ else p.setPen(m_chalkHighlightColor);
+ p.drawText(r, Qt::AlignCenter, text);
+
+ if(rect) *rect = r;
+}
+
+void Kanagram::drawTextNew(QPainter &p, const QString &text, int textAlign, int xMargin, int yMargin, const QRect &rect, bool highlight, int fontSize)
+{
+ QRect r = innerRect(rect, xMargin, yMargin);
+ QFont font = m_blackboardFont;
+ font.setPointSize(fontSize);
+ font.setBold(true);
+ p.setFont(font);
+
+ const bool withMargin = false;
+ if (withMargin)
+ {
+ p.fillRect(r, m_fillColor);
+ p.setPen(QPen(black, 3));
+ p.drawRoundRect(r.left(), r.top(), r.width(), r.height(), 15, 15);
+ }
+
+ if (highlight)
+ p.setPen(m_chalkHighlightColor);
+ else
+ p.setPen(m_chalkColor);
+ p.drawText(r, textAlign, text);
+}
+
+void Kanagram::checkWord()
+{
+ QPoint p = m_upRect.topLeft() + QPoint( 1, 1 );
+ QMouseEvent *e = new QMouseEvent( QEvent::MouseButtonPress, p, Qt::LeftButton, Qt::NoButton );
+ mousePressEvent(e);
+}
+
+void Kanagram::randomHintImage()
+{
+ unsigned long imageNum = m_randomImage.getLong(8);
+ QString dir = "images/eyes" + QString::number(imageNum + 1) + ".png";
+ m_hintOverlay = new QPixmap(locate("appdata", dir));
+}
+
+void Kanagram::showSettings()
+{
+ if(KConfigDialog::showDialog("settings"))
+ return;
+
+ KConfigDialog *configDialog = new KConfigDialog( this, "settings", KanagramSettings::self() );
+ configDialog->addPage( new MainSettings( configDialog ), i18n( "General" ), "configure" );
+ m_vocabSettings = new VocabSettings( configDialog );
+ configDialog->addPage( m_vocabSettings, i18n("Vocabularies"), "edit" );
+ configDialog->addPage( new NewStuff( configDialog ), i18n("New Stuff"), "knewstuff" );
+ connect(configDialog, SIGNAL(settingsChanged()), this, SLOT(loadSettings()));
+ connect(configDialog, SIGNAL(applyClicked()), this, SLOT(refreshVocabularies()));
+ configDialog->exec();
+ delete configDialog;
+}
+
+void Kanagram::hideHint()
+{
+ if(m_showHint == true) m_showHint = false;
+ update();
+}
+
+void Kanagram::resetInputBox()
+{
+ m_inputBox->unsetPalette();
+}
+
+void Kanagram::refreshVocabularies()
+{
+ kdDebug() << "Refreshing vocab list..." << endl;
+ m_game->refreshVocabList();
+ m_game->nextVocab();
+ hideHint();
+ m_game->nextAnagram();
+ if(m_useSounds) play("chalk.ogg");
+ KanagramSettings::setDefaultVocab(m_game->getFilename());
+ KanagramSettings::writeConfig();
+ m_vocabSettings->refreshView();
+}
+
+void Kanagram::play(QString filename)
+{
+ #ifndef WITHOUT_ARTS
+ KDE::PlayObject *playobj = m_artsFactory->createPlayObject(locate("appdata", "sounds/" + filename), true);
+ playobj->play();
+ #else
+ (void)filename;
+ #endif
+}
+
+#include "kanagram.moc"
diff --git a/kanagram/src/kanagram.desktop b/kanagram/src/kanagram.desktop
new file mode 100644
index 00000000..1cbaf73c
--- /dev/null
+++ b/kanagram/src/kanagram.desktop
@@ -0,0 +1,120 @@
+[Desktop Entry]
+Name=Kanagram
+Name[bn]=কে-অ্যানাগ্রাম
+Name[cy]=blinKen
+Name[eo]=Kanagramo
+Name[hr]=KAnagram
+Name[ne]=कानाग्राम
+Exec=kanagram
+Icon=kanagram
+Type=Application
+DocPath=kanagram/index.html
+Comment=KDE Letter Order Game
+Comment[be]=Гульня з перамяшчэннем літар
+Comment[bg]=Игра за подредба на букви
+Comment[bn]=কে.ডি.ই. উপস্থাপিত অক্ষর সাজানোর খেলা
+Comment[bs]=KDE igra slaganja slova
+Comment[ca]=Joc d'ordenació de lletres per a KDE
+Comment[cs]=Hra uspořádání písmen pro KDE
+Comment[csb]=Gra w ùkłôdanié słów
+Comment[da]=Bogstavsrækkefølgesspil for KDE
+Comment[de]=Ein KDE-Spiel, bei dem Buchstaben sortiert werden
+Comment[el]=Παιχνίδι σειράς γραμμάτων του KDE
+Comment[eo]=KDE literordiga ludo
+Comment[es]=Juego de ordenación de letras para KDE
+Comment[et]=KDE tähtede järjestamise mäng
+Comment[eu]=Letren ordenaren jokoa
+Comment[fa]=بازی ترتیب حروف KDE
+Comment[fi]=Kirjainten järjestyspeli
+Comment[fr]=Remettre les lettres dans le bon ordre
+Comment[gl]=Xogo de Ordenar Letras de KDE
+Comment[he]=משחק סידור מילים של KDE
+Comment[hr]=KDE igra premještanja slova
+Comment[hu]=KDE-alapú szókirakó játék
+Comment[it]=Gioco di anagrammi per KDE
+Comment[ja]=KDE 回文ゲーム
+Comment[ka]=KDE ასოების გადალაგების თამაში
+Comment[km]=ល្បែង​តម្រៀប​អក្សរ​របស់ KDE
+Comment[ms]=Permainan Susun Huruf KDE
+Comment[nb]=Ordlek med bokstavrekkefølge
+Comment[nds]=KDE-Bookstavenspeel
+Comment[ne]=KDE अक्षर क्रम खेल
+Comment[nl]=Letters ordenen
+Comment[nn]=Bokstavordningsspel for KDE
+Comment[pl]=Gra w układanie liter dla KDE
+Comment[pt]=Jogo de Ordenação de Letras do KDE
+Comment[pt_BR]= Jogo do KDE de ordenação de letras
+Comment[ru]=Игра с перестановкой букв
+Comment[sk]=KDE hra o usporiadaní písmen
+Comment[sl]=Igra vrstnega reda črk
+Comment[sr]=Игра редоследа слова за KDE
+Comment[sr@Latn]=Igra redosleda slova za KDE
+Comment[sv]=Bokstavsordningsspel för KDE
+Comment[tr]=Harf Sıralama Oyunu
+Comment[uk]=Гра з впорядкування літер
+Comment[vi]=Trò chơi Sắp xếp Chữ cái KDE
+Comment[zh_CN]=KDE 字母顺序游戏
+Comment[zh_TW]=KDE 字母排序遊戲
+GenericName=Letter Order Game
+GenericName[af]=Lettervolgorde Speletjie
+GenericName[ar]=لعبة ترتيب الاحرف
+GenericName[be]=Гульня з перамяшчэннем літар
+GenericName[bg]=Игра за подредба на букви
+GenericName[bn]=অক্ষর সাজানোর খেলা
+GenericName[bs]=Igra slaganja slova
+GenericName[ca]=Joc d'ordenació de lletres
+GenericName[cs]=Hra uspořádání písmen
+GenericName[csb]=Gra w ùkłôdanié słów
+GenericName[cy]=Gêm Trefn Llythrennau
+GenericName[da]=Bogstavrækkefølgespil
+GenericName[de]=Spielerisches Sortieren von Buchstaben
+GenericName[el]=Παιχνίδι σειράς γραμμάτων
+GenericName[eo]=Literordiga ludo
+GenericName[es]=Juego de ordenación de letras
+GenericName[et]=Tähtede järjestamine
+GenericName[eu]=Letren ordenaren jokoa
+GenericName[fa]=بازی ترتیب حرف
+GenericName[fi]=Kirjainten järjestyspeli
+GenericName[fr]=Remettre les lettres dans le bon ordre
+GenericName[gl]=Xogo de Ordenar Letras
+GenericName[he]=משחק סידור מילים
+GenericName[hi]=अक्षर अनुक्रम खेल
+GenericName[hr]=Igra rasporeda slova
+GenericName[hu]=Szókirakó játék
+GenericName[is]=Stafaröðunarleikur
+GenericName[it]=Gioco di anagrammi
+GenericName[ja]=回文ゲーム
+GenericName[ka]=ასოების გადალაგება
+GenericName[km]=ល្បែង​តម្រៀប​អក្សរ
+GenericName[lt]=Raidžių rūšiavimo žaidimas
+GenericName[lv]=Burtu Kārtības Spēle
+GenericName[mk]=Игра за пишување писма
+GenericName[mn]=Үсэг цэгцлэх тоглоом
+GenericName[ms]=Permainan Susun Huruf
+GenericName[nb]=Ordlek med bokstavrekkefølge
+GenericName[nds]=Bookstaven ornen
+GenericName[ne]=अक्षर क्रम खेल
+GenericName[nl]=Letters ordenen
+GenericName[nn]=Bokstavordningsspel
+GenericName[nso]=Papadi ya Otara ya Lengwalo
+GenericName[pl]=Gra w układanie słów
+GenericName[pt]=Jogo de Ordenação de Letras
+GenericName[pt_BR]= Um Jogo de ordenação de letras
+GenericName[ru]=Игра с перестановкой букв
+GenericName[se]=Bustávvaortnetspeallu
+GenericName[sk]=Hra o usporiadaní písmen
+GenericName[sl]=Igra vrstnega reda črk
+GenericName[sr]=Игра редоследа слова
+GenericName[sr@Latn]=Igra redosleda slova
+GenericName[sv]=Bokstavsordningsspel
+GenericName[ta]=எழுத்துவரிசை விளையாட்டு
+GenericName[tg]=Бозии Тартиби Ҳарф
+GenericName[tr]=Harf Sıralama Oyunu
+GenericName[uk]=Гра з впорядкування літер
+GenericName[ven]=Mutambo uno humbelwa nga lunwalo
+GenericName[vi]=Trò chơi Sắp xếp Chữ cái
+GenericName[xh]=Umdlalo Wolungelanisa Unobumba
+GenericName[zh_CN]=字母顺序游戏
+GenericName[zh_TW]=字母排序遊戲
+GenericName[zu]=Umdlalo Wokulandelanisa Kwencwadi
+Categories=Qt;KDE;Education;Languages;
diff --git a/kanagram/src/kanagram.h b/kanagram/src/kanagram.h
new file mode 100644
index 00000000..689495b8
--- /dev/null
+++ b/kanagram/src/kanagram.h
@@ -0,0 +1,134 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joshua Keel *
+ * joshuakeel@gmail.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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef KANAGRAM_H
+#define KANAGRAM_H
+
+#include <config.h>
+
+#include <qwidget.h>
+#include <qlineedit.h>
+
+#include <kxmlguiclient.h>
+
+#ifndef WITHOUT_ARTS
+#include <arts/kartsdispatcher.h>
+#include <arts/kartsserver.h>
+#include <arts/kplayobject.h>
+#include <arts/kplayobjectfactory.h>
+#else
+class KArtsDispatcher;
+class KArtsServer;
+namespace KDE
+{
+ class PlayObjectFactory;
+}
+#endif
+
+#include "kanagramgame.h"
+
+#include <iostream>
+
+using namespace std;
+
+class KHelpMenu;
+class KConfigDialog;
+class KRandomSequence;
+class KanagramGame;
+class VocabSettings;
+
+class Kanagram : public QWidget
+{
+Q_OBJECT
+ public:
+ Kanagram();
+ ~Kanagram();
+
+ private slots:
+ void checkWord();
+ void loadSettings();
+ void hideHint();
+ void resetInputBox();
+ void refreshVocabularies();
+
+ private:
+ void drawText(QPainter &p, const QString &text, const QPoint &center, bool withMargin, int xMargin, int yMargin, QRect *rect, bool highlight, int fontSize = 18);
+ void drawTextNew(QPainter &p, const QString &text, int textAlign, int xMargin, int yMargin, const QRect &rect, bool highlight, int fontSize = 18);
+
+ void setupRects();
+
+ void play(QString filename);
+
+ void paintEvent(QPaintEvent *);
+
+ void mousePressEvent(QMouseEvent *e);
+
+ void mouseMoveEvent(QMouseEvent *e);
+
+ void updateButtonHighlighting(const QPoint &p);
+
+ void randomHintImage();
+
+ void showSettings();
+
+ void drawHelpText(QPainter &p, QString text);
+
+ void drawSwitcherText(QPainter &p, QString text);
+ void drawSwitcher(QPainter &p, const int xMargin, const int yMargin);
+
+ QRect innerRect(const QRect &rect, const int xMargin, const int yMargin);
+
+ KanagramGame *m_game;
+
+ QPixmap *m_back, *m_hintOverlay, *m_aboutKDEOverlay, *m_aboutAppOverlay, *m_handbookOverlay, *m_aboutKDEOverlayOver, *m_aboutAppOverlayOver, *m_handbookOverlayOver, *m_card, *m_arrow, *m_arrowOver, *m_next, *m_nextOver, *m_config, *m_configOver, *m_help, *m_helpOver, *m_quit, *m_quitOver, *m_up, *m_upOver, *m_upDisabled;
+
+ //Deprecated
+ //QRect m_newWordRect, m_settingsRect, m_helpRect, m_quitRect;
+
+ QRect m_nextRect, m_configRect, m_helpRect, m_quitRect, m_revealRect, m_hintRect, m_upRect, m_aboutKDERect, m_aboutAppRect, m_handbookRect, m_switcherRect, m_arrowRect, m_logoRect, m_hintBoxRect, m_blackboardRect;
+
+ bool m_overNext, m_overConfig, m_overHelp, m_overQuit, m_overReveal, m_overHint, m_overUp, m_overAboutKDE, m_overAboutApp, m_overHandbook, m_overSwitcher, m_overHintBox;
+
+ bool m_showHint;
+
+ QColor m_fillColor, m_fontColor, m_fontHighlightColor, m_chalkColor, m_chalkHighlightColor;
+
+ //Values for settings
+ int m_hintHideTime;
+ bool m_useSounds, m_useStandardFonts;
+
+ QFont m_blackboardFont, m_font;
+
+ KHelpMenu *m_helpMenu;
+
+ QLineEdit *m_inputBox;
+
+ VocabSettings *m_vocabSettings;
+
+ KRandomSequence m_randomImage;
+
+ QTimer *m_hintTimer;
+
+ KArtsDispatcher *m_artsDispatcher;
+ KArtsServer *m_artsServer;
+ KDE::PlayObjectFactory *m_artsFactory;
+};
+
+#endif
diff --git a/kanagram/src/kanagram.kcfg b/kanagram/src/kanagram.kcfg
new file mode 100644
index 00000000..8681545f
--- /dev/null
+++ b/kanagram/src/kanagram.kcfg
@@ -0,0 +1,26 @@
+<kcfgfile name="kanagramrc">
+<group name="kanagram">
+<entry name="hintHideTime" type="String">
+ <label>This setting allows you to set how long Kanagram's hint bubble is shown.</label>
+ <default>5 seconds</default>
+</entry>
+<entry name="useSounds" type="Bool">
+ <label>Turns sounds on/off.</label>
+ <default>true</default>
+</entry>
+<entry name="useStandardFonts" type="Bool">
+ <label>Uses a standard font for the chalkboard/interface.</label>
+ <default>false</default>
+</entry>
+<entry name="defaultVocab" type="Path">
+ <label>Set the default vocabulary</label>
+ <default></default>
+</entry>
+<entry name="dataLanguage" type="String">
+ <label>Set the default translation</label>
+ <default></default>
+</entry>
+<entry name="justGotFont" type="Bool">
+</entry>
+</group>
+</kcfgfile>
diff --git a/kanagram/src/kanagramgame.cpp b/kanagram/src/kanagramgame.cpp
new file mode 100644
index 00000000..318c285e
--- /dev/null
+++ b/kanagram/src/kanagramgame.cpp
@@ -0,0 +1,209 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joshua Keel *
+ * joshuakeel@gmail.com *
+ * *
+ * Portions of this code taken from KMessedWords by Reuben Sutton *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <qfile.h>
+
+#include <kurl.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+#include <klocale.h>
+
+#include "kanagramgame.h"
+#include "keduvocdocument.h"
+#include "kanagramsettings.h"
+
+#include <stdlib.h>
+
+KanagramGame::KanagramGame(QWidget* parent) : m_index(0)
+{
+ m_parent = parent;
+ loadDefaultVocab();
+}
+
+KanagramGame::~KanagramGame()
+{
+}
+
+void KanagramGame::checkFile()
+{
+ if (!QFile::exists(locate("appdata", m_filename))) {
+ QString msg = i18n("File %1 cannot be found.\n Please ensure that Kanagram is properly installed.")
+ .arg(m_filename);
+ KMessageBox::sorry(m_parent, msg, i18n("Error"));
+ exit(0);
+ }
+}
+
+void KanagramGame::loadDefaultVocab()
+{
+ m_filename = KanagramSettings::defaultVocab();
+ if (m_filename.isEmpty())
+ {
+ // first run
+ m_filename = locate("appdata", "data/" + KanagramSettings::dataLanguage() + "/objects.kvtml");
+ if (m_filename.isEmpty())
+ {
+ refreshVocabList();
+ nextVocab();
+ }
+ }
+
+ kdDebug() << "in game " << m_filename <<endl;
+ KEduVocDocument *doc = new KEduVocDocument(this);
+ doc->open(KURL(locate("appdata", m_filename)), false);
+ m_docTitle = doc->getTitle();
+ kdDebug() << m_docTitle <<endl; //Animals
+ nextAnagram();
+}
+
+void KanagramGame::refreshVocabList()
+{
+ m_fileList = KGlobal::dirs()->findAllResources("appdata", "data/" + KanagramSettings::dataLanguage() + "/*.kvtml");
+ //nextVocab();
+ m_index = findIndex();
+}
+
+int KanagramGame::findIndex()
+{
+ //this m_filename is wrong
+ //you have to use KanagramSettings::defaultVocab() instead of m_filename which is used for something else
+ kdDebug() <<"m_filename " << m_filename << "\n" << endl;
+ int tempIndex = 0;
+ for(uint i = 0; i < m_fileList.size(); i++)
+ {
+ kdDebug() <<"m_file " << m_fileList[i]<<endl;
+ if(m_filename == m_fileList[i])
+ {
+ tempIndex = i;
+ }
+ }
+ kdDebug() << "index founded " << tempIndex <<endl;
+ return tempIndex;
+}
+
+void KanagramGame::previousVocab()
+{
+ m_index--;
+ if(m_index < 0)
+ m_index = m_fileList.size() - 1;
+ m_filename = m_fileList[m_index];
+ checkFile();
+ KEduVocDocument *doc = new KEduVocDocument(this);
+ doc->open(KURL(locate("appdata", m_filename)), false);
+ m_docTitle = doc->getTitle();
+ m_answeredWords.clear();
+}
+
+void KanagramGame::nextVocab()
+{
+ m_index++;
+ if((uint)m_index >= m_fileList.size())
+ m_index = 0;
+ m_filename = m_fileList[m_index];
+ checkFile();
+ KEduVocDocument *doc = new KEduVocDocument(this);
+ doc->open(KURL(locate("appdata", m_filename)), false);
+ m_docTitle = doc->getTitle();
+ m_answeredWords.clear();
+}
+
+void KanagramGame::nextAnagram()
+{
+ checkFile();
+ KEduVocDocument *doc = new KEduVocDocument(this);
+ doc->open(KURL(locate("appdata", m_filename)), false);
+ int totalWords = doc->numEntries();
+ int wordNumber = m_random.getLong(totalWords);
+ if(doc->numEntries() == (int)m_answeredWords.size())
+ {
+ m_answeredWords.clear();
+ }
+ while(m_answeredWords.findIndex(doc->getEntry(wordNumber)->getOriginal()) != -1)
+ {
+ wordNumber = m_random.getLong(totalWords);
+ }
+ m_originalWord = doc->getEntry(wordNumber)->getOriginal();
+ m_answeredWords.append(m_originalWord);
+ m_anagram = createAnagram(m_originalWord);
+ m_hint = doc->getEntry(wordNumber)->getRemark(0);
+}
+
+QString KanagramGame::getDocTitle()
+{
+ return m_docTitle;
+}
+
+QString KanagramGame::getFilename()
+{
+ if(m_fileList.empty())
+ return m_filename;
+ else
+ return m_fileList[m_index];
+}
+
+QString KanagramGame::getAnagram()
+{
+ return m_anagram;
+}
+
+QString KanagramGame::getHint()
+{
+ return m_hint;
+}
+
+QString KanagramGame::getWord()
+{
+ return m_originalWord;
+}
+
+void KanagramGame::restoreWord()
+{
+ m_anagram = m_originalWord;
+}
+
+QString KanagramGame::createAnagram(QString original)
+{
+ QStringList objData = QStringList::split(QString(""), original);
+ QString insaneData;
+ int count;
+
+ for(int i=0; count = objData.count(); i++)
+ {
+ int objChunk;
+ if((i == 0) && (count > 1))
+ objChunk = 1 + m_random.getLong(count - 1);
+ else
+ objChunk = m_random.getLong(count);
+
+ QStringList::Iterator it = objData.at(objChunk);
+ QString sd = *it;
+ objData.remove(it);
+ if (insaneData.isEmpty())
+ insaneData = sd;
+ else
+ insaneData += sd;
+ }
+ return insaneData;
+}
+
+#include "kanagramgame.moc"
diff --git a/kanagram/src/kanagramgame.h b/kanagram/src/kanagramgame.h
new file mode 100644
index 00000000..940fbd57
--- /dev/null
+++ b/kanagram/src/kanagramgame.h
@@ -0,0 +1,65 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joshua Keel *
+ * joshuakeel@gmail.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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef KANAGRAMGAME_H
+#define KANAGRAMGAME_H
+
+#include <qobject.h>
+
+#include <kstandarddirs.h>
+#include <krandomsequence.h>
+
+class QWidget;
+
+class KanagramGame : public QObject
+{
+Q_OBJECT
+ public:
+ KanagramGame(QWidget *parent);
+ ~KanagramGame();
+ void refreshVocabList();
+ void loadDefaultVocab();
+ int findIndex();
+ void nextAnagram();
+ void nextVocab();
+ void previousVocab();
+ QString getAnagram();
+ QString getHint();
+ QString getWord();
+ void restoreWord();
+ QString getDocTitle();
+ QString getFilename();
+ private:
+ QString createAnagram(QString original);
+ void checkFile();
+ QWidget *m_parent;
+ KRandomSequence m_random;
+ QString m_anagram;
+ QString m_hint;
+ QString m_originalWord;
+
+ int m_index;
+ QStringList m_fileList;
+ QStringList m_answeredWords;
+ QString m_docTitle;
+ QString m_filename;
+};
+
+#endif
diff --git a/kanagram/src/kanagramsettings.kcfgc b/kanagram/src/kanagramsettings.kcfgc
new file mode 100644
index 00000000..49630279
--- /dev/null
+++ b/kanagram/src/kanagramsettings.kcfgc
@@ -0,0 +1,4 @@
+File=kanagram.kcfg
+ClassName=KanagramSettings
+Mutators=true
+Singleton=true
diff --git a/kanagram/src/keduvocdocument.cpp b/kanagram/src/keduvocdocument.cpp
new file mode 100644
index 00000000..1af38f5a
--- /dev/null
+++ b/kanagram/src/keduvocdocument.cpp
@@ -0,0 +1,1111 @@
+/***************************************************************************
+ Vocabulary Document for KDE Edu
+ -----------------------------------------------------------------------
+ copyright : (C) 1999-2001 Ewald Arnold
+ (C) 2001 The KDE-EDU team
+ (C) 2005 Peter Hedlung
+ email : peter.hedlund@kdemail.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 "keduvocdocument.h"
+
+#include <kapplication.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kio/netaccess.h>
+
+#include <qfileinfo.h>
+
+#include <algorithm>
+#include <functional>
+#include <vector>
+using namespace std;
+
+#include <iostream>
+
+#include <float.h>
+
+#include "keduvockvtmlwriter.h"
+#include "keduvockvtmlreader.h"
+#include "leitnersystem.h"
+//#include "prefs.h"
+
+//********************************************************
+// KEduVocDocument
+//********************************************************
+
+KEduVocDocument::KEduVocDocument(QObject * /*parent*/)
+{
+ Init();
+}
+
+
+KEduVocDocument::~KEduVocDocument()
+{
+}
+
+
+void KEduVocDocument::setVersion (const QString & vers)
+{
+ doc_version = vers;
+}
+
+
+void KEduVocDocument::getVersion(int &, int &, int &)
+{
+}
+
+
+void KEduVocDocument::Init ()
+{
+ lesson_descr.clear();
+ type_descr.clear();
+ tense_descr.clear();
+ langs.clear();
+ sort_lang.clear();
+ extraSizehints.clear();
+ sizehints.clear();
+ vocabulary.clear();
+ dirty = false;
+ sort_allowed = true;
+ unknown_attr = false;
+ unknown_elem = false;
+ sort_lesson = false;
+ setCurrentLesson (0);
+ queryorg = "";
+ querytrans = "";
+ doc_url.setFileName(i18n("Untitled"));
+ doctitle = "";
+ author = "";
+
+ activeLeitnerSystem = false;
+ leitnerSystem = 0;
+}
+
+
+bool KEduVocDocument::open(const KURL& url, bool /*append*/)
+{
+ Init();
+ if (!url.isEmpty())
+ doc_url = url;
+
+ // TODO EPT connect( this, SIGNAL(progressChanged(KEduVocDocument*,int)), parent, SLOT(slotProgress(KEduVocDocument*,int)) );
+
+ QString tmpfile;
+ if (KIO::NetAccess::download( url, tmpfile, 0 ))
+ {
+ QFile f(tmpfile);
+ if (!f.open(IO_ReadOnly))
+ {
+ KMessageBox::error(0, i18n("<qt>Cannot open file<br><b>%1</b></qt>").arg(url.path()));
+ return false;
+ }
+
+ FileType ft = detectFT(url.path());
+
+ bool read = false;
+ while (!read) {
+
+ QApplication::setOverrideCursor( waitCursor );
+ switch (ft) {
+ case kvtml:
+ {
+ KEduVocKvtmlReader kvtmlReader(&f);
+ read = kvtmlReader.readDoc(this);
+ }
+ break;
+
+ case vt_lex:
+ {
+ QTextStream is (&f);
+ //TODO read = loadFromLex (is);
+ }
+ break;
+
+ case vt_vcb:
+ {
+ QTextStream is (&f);
+ //TODO read = loadFromVcb (is);
+ }
+ break;
+
+ case csv:
+ {
+ QTextStream is(&f);
+ //TODO read = loadFromCsv(is);
+ }
+ break;
+
+ default:
+ {
+ KEduVocKvtmlReader kvtmlReader(&f);
+ read = kvtmlReader.readDoc(this);
+ }
+ }
+
+ QApplication::restoreOverrideCursor();
+
+ if (!read) {
+ if (unknown_attr || unknown_elem ) {
+ Init();
+ return false;
+ }
+ // TODO new readers provide an explicite error message
+ // the two messages should be merged
+ QString format = i18n("Could not load \"%1\"\nDo you want to try again?");
+ QString msg = format.arg(url.path());
+ int result = KMessageBox::warningContinueCancel(0, msg,
+ kapp->makeStdCaption(i18n("I/O Failure")),
+ i18n("&Retry"));
+ if ( result == KMessageBox::Cancel ) {
+ Init();
+ return false;
+ }
+ }
+ }
+ f.close();
+ KIO::NetAccess::removeTempFile( tmpfile );
+ }
+ return true;
+}
+
+
+bool KEduVocDocument::saveAs(QObject * /*parent*/, const KURL & url, FileType ft, const QString & generator)
+{
+// connect( this, SIGNAL(progressChanged(KEduVocDocument*,int)), parent, SLOT(slotProgress(KEduVocDocument*,int)) );
+
+ KURL tmp (url);
+
+ if (ft == automatic)
+ {
+ if (tmp.path().right(strlen("." KVTML_EXT)) == "." KVTML_EXT)
+ ft = kvtml;
+ else if (tmp.path().right(strlen("." VT5_LEX_EXT)) == "." VT5_LEX_EXT)
+ ft = vt_lex;
+ else if (tmp.path().right(strlen("." VCB_EXT)) == "." VCB_EXT)
+ ft = vt_vcb;
+ else if (tmp.path().right(strlen("." CSV_EXT)) == "." CSV_EXT)
+ ft = csv;
+ else
+ {
+ tmp.setFileName(tmp.path() + "." KVTML_EXT);
+ ft = kvtml;
+ }
+ }
+
+ bool saved = false;
+ while (!saved)
+ {
+
+ QFile f(tmp.path());
+
+ if (!f.open(IO_WriteOnly))
+ {
+ KMessageBox::error(0, i18n("<qt>Cannot write to file<br><b>%1</b></qt>").arg(tmp.path()));
+ return false;
+ }
+
+ QApplication::setOverrideCursor( waitCursor );
+ switch (ft) {
+ case kvtml: {
+ KEduVocKvtmlWriter kvtmlWriter(&f);
+ saved = kvtmlWriter.writeDoc(this, generator);
+ }
+ break;
+
+ case vt_lex: {
+ QTextStream os( &f ); // serialize using f
+ //TODO saved = saveToLex(os, title);
+ }
+ break;
+
+ case vt_vcb: {
+ QTextStream os( &f ); // serialize using f
+ //TODO saved = saveToVcb(os, title);
+ }
+ break;
+
+ case csv: {
+ QTextStream os( &f ); // serialize using f
+ //TODO saved = saveToCsv(os, title);
+ }
+ break;
+
+ default: {
+ kdError() << "kvcotrainDoc::saveAs(): unknown filetype" << endl;
+ }
+ break;
+ }
+ f.close();
+ QApplication::restoreOverrideCursor();
+
+ if (!saved) {
+ // TODO new writers provide an explicite error message
+ // the two messages should be merged
+ QString format = i18n("Could not save \"%1\"\nDo you want to try again?");
+ QString msg = format.arg(tmp.path());
+ int result = KMessageBox::warningContinueCancel(0, msg,
+ kapp->makeStdCaption(i18n("I/O Failure")),
+ i18n("&Retry"));
+ if ( result == KMessageBox::Cancel ) return false;
+ }
+ }
+ doc_url = tmp;
+ dirty = false;
+ emit docModified(false);
+ return true;
+}
+
+
+KEduVocExpression *KEduVocDocument::getEntry(int index)
+{
+ if (index < 0 || index >= (int)vocabulary.size() )
+ return 0;
+ else
+ return &vocabulary[index];
+}
+
+
+void KEduVocDocument::removeEntry(int index)
+{
+ if (index >= 0 && index < (int)vocabulary.size() )
+ vocabulary.erase (vocabulary.begin() + index);
+}
+
+
+int KEduVocDocument::findIdent (const QString &lang) const
+{
+ vector<QString>::const_iterator first = langs.begin();
+ int count = 0;
+ while (first != langs.end()) {
+ if ( *first == lang)
+ return count;
+ first++;
+ count++;
+ }
+ return -1;
+}
+
+
+QString KEduVocDocument::getIdent (int index) const
+{
+ if (index >= (int)langs.size() || index < 1 )
+ return "";
+ else
+ return langs[index];
+}
+
+
+void KEduVocDocument::setIdent (int idx, const QString &id)
+{
+ if (idx < (int)langs.size() && idx >= 1 ) {
+ langs[idx] = id;
+ }
+}
+
+
+QString KEduVocDocument::getTypeName (int index) const
+{
+ if (index >= (int)type_descr.size())
+ return "";
+ else
+ return type_descr[index];
+}
+
+
+void KEduVocDocument::setTypeName (int idx, QString &id)
+{
+ if (idx >= (int)type_descr.size())
+ for (int i = (int)type_descr.size(); i <= idx; i++)
+ type_descr.push_back ("");
+
+ type_descr[idx] = id;
+}
+
+
+QString KEduVocDocument::getTenseName (int index) const
+{
+ if (index >= (int)tense_descr.size())
+ return "";
+ else
+ return tense_descr[index];
+}
+
+
+void KEduVocDocument::setTenseName (int idx, QString &id)
+{
+ if (idx >= (int)tense_descr.size())
+ for (int i = (int)tense_descr.size(); i <= idx; i++)
+ tense_descr.push_back ("");
+
+ tense_descr[idx] = id;
+}
+
+
+QString KEduVocDocument::getUsageName (int index) const
+{
+ if (index >= (int)usage_descr.size())
+ return "";
+ else
+ return usage_descr[index];
+}
+
+
+void KEduVocDocument::setUsageName (int idx, QString &id)
+{
+ if (idx >= (int)usage_descr.size())
+ for (int i = (int)usage_descr.size(); i <= idx; i++)
+ usage_descr.push_back ("");
+
+ usage_descr[idx] = id;
+}
+
+
+void KEduVocDocument::setConjugation (int idx, const Conjugation &con)
+{
+ if ( idx < 0) return;
+
+ // extend conjugation with empty elements
+ if ((int)conjugations.size() <= idx )
+ for (int i = conjugations.size(); i < idx+1; i++)
+ conjugations.push_back (Conjugation());
+
+ conjugations[idx] = con;
+}
+
+
+Conjugation KEduVocDocument::getConjugation (int idx) const
+{
+ if (idx >= (int)conjugations.size() || idx < 0) {
+ return Conjugation();
+ }
+ else {
+ return conjugations[idx];
+ }
+}
+
+
+void KEduVocDocument::setArticle (int idx, const Article &art)
+{
+ if ( idx < 0) return;
+
+ // extend conjugation with empty elements
+ if ((int)articles.size() <= idx )
+ for (int i = articles.size(); i < idx+1; i++)
+ articles.push_back (Article());
+
+ articles[idx] = art;
+}
+
+
+Article KEduVocDocument::getArticle (int idx) const
+{
+ if (idx >= (int)articles.size() || idx < 0) {
+ return Article();
+ }
+ else {
+ return articles[idx];
+ }
+}
+
+
+int KEduVocDocument::getSizeHint (int idx) const
+{
+ if (idx < 0) {
+ idx = -idx;
+ if (idx >= (int)extraSizehints.size() )
+ return 80; // make a good guess about column size
+ else {
+// cout << "gsh " << idx << " " << extraSizehints[idx] << endl;
+ return extraSizehints[idx];
+ }
+ }
+ else {
+ if (idx >= (int)sizehints.size() )
+ return 150; // make a good guess about column size
+ else {
+// cout << "gsh " << idx << " " << sizehints[idx] << endl;
+ return sizehints[idx];
+ }
+ }
+}
+
+
+void KEduVocDocument::setSizeHint (int idx, const int width)
+{
+// cout << "ssh " << idx << " " << width << endl;
+ if (idx < 0) {
+ idx = -idx;
+ if (idx >= (int)extraSizehints.size()) {
+ for (int i = (int)extraSizehints.size(); i <= idx; i++)
+ extraSizehints.push_back (80);
+ }
+ extraSizehints[idx] = width;
+
+ }
+ else {
+ if (idx >= (int)sizehints.size()) {
+ for (int i = (int)sizehints.size(); i <= idx; i++)
+ sizehints.push_back (150);
+ }
+ sizehints[idx] = width;
+ }
+}
+
+
+class eraseTrans : public unary_function<KEduVocExpression, void>
+{
+
+public:
+
+ eraseTrans (int idx)
+ : index (idx) {}
+
+ void operator() (KEduVocExpression& x) const
+ {
+ x.removeTranslation(index);
+ }
+
+ private:
+ int index;
+};
+
+
+void KEduVocDocument::removeIdent (int index)
+{
+ if (index < (int)langs.size() && index >= 1 ) {
+ langs.erase(langs.begin() + index);
+ for_each (vocabulary.begin(), vocabulary.end(), eraseTrans(index));
+ }
+}
+
+
+QString KEduVocDocument::getOriginalIdent () const
+{
+ if (langs.size() > 0)
+ return langs[0];
+ else
+ return "";
+}
+
+
+void KEduVocDocument::setOriginalIdent (const QString &id)
+{
+ if (langs.size() > 0) {
+ langs[0] = id;
+ }
+}
+
+
+class sortByOrg : public binary_function<KEduVocExpression, KEduVocExpression, bool>
+{
+
+public:
+
+ sortByOrg (bool _dir)
+ : dir (_dir) {}
+
+ bool operator() (const KEduVocExpression& x, const KEduVocExpression& y) const
+ {
+ return
+ !dir
+ ? (QString::compare(x.getOriginal().upper(),
+ y.getOriginal().upper() ) < 0)
+ : (QString::compare(x.getOriginal().upper(),
+ y.getOriginal().upper() ) > 0);
+ }
+
+ private:
+ bool dir;
+};
+
+
+class sortByLessonAndOrg_alpha
+ : public binary_function<KEduVocExpression, KEduVocExpression, bool>
+{
+
+public:
+
+ sortByLessonAndOrg_alpha (bool _dir, KEduVocDocument &_doc)
+ : dir (_dir), doc(_doc) {}
+
+ bool operator() (const KEduVocExpression& x, const KEduVocExpression& y) const
+ {
+ if (x.getLesson() != y.getLesson() )
+ return
+ !dir
+ ? (QString::compare(doc.getLessonDescr(x.getLesson()).upper(),
+ doc.getLessonDescr(y.getLesson()).upper() ) < 0)
+ : (QString::compare(doc.getLessonDescr(x.getLesson()).upper(),
+ doc.getLessonDescr(y.getLesson()).upper() ) > 0);
+ else
+ return
+ !dir
+ ? (QString::compare(x.getOriginal().upper(),
+ y.getOriginal().upper() ) < 0)
+ : (QString::compare(x.getOriginal().upper(),
+ y.getOriginal().upper() ) > 0);
+ }
+
+ private:
+ bool dir;
+ KEduVocDocument &doc;
+};
+
+
+class sortByLessonAndOrg_index
+ : public binary_function<KEduVocExpression, KEduVocExpression, bool>
+{
+
+public:
+
+ sortByLessonAndOrg_index (bool _dir, KEduVocDocument &_doc)
+ : dir (_dir), doc(_doc) {}
+
+ bool operator() (const KEduVocExpression& x, const KEduVocExpression& y) const
+ {
+ if (x.getLesson() != y.getLesson() )
+ return
+ !dir
+ ? x.getLesson() < y.getLesson()
+ : y.getLesson() < x.getLesson();
+ else
+ return
+ !dir
+ ? (QString::compare(x.getOriginal().upper(),
+ y.getOriginal().upper() ) < 0)
+ : (QString::compare(x.getOriginal().upper(),
+ y.getOriginal().upper() ) > 0);
+ }
+
+ private:
+ bool dir;
+ KEduVocDocument &doc;
+};
+
+
+class sortByTrans : public binary_function<KEduVocExpression, KEduVocExpression, bool>
+{
+
+public:
+
+ sortByTrans (int i, bool _dir)
+ : index(i), dir (_dir) {}
+
+ bool operator() (const KEduVocExpression& x, const KEduVocExpression& y) const
+ {
+ return
+ !dir
+ ? (QString::compare(x.getTranslation(index).upper(),
+ y.getTranslation(index).upper() ) < 0)
+ : (QString::compare(x.getTranslation(index).upper(),
+ y.getTranslation(index).upper() ) > 0);
+ }
+
+ private:
+ int index;
+ bool dir;
+};
+
+
+bool KEduVocDocument::sort (int index)
+{
+ if (!sort_allowed)
+ return false;
+
+ if (index >= numLangs())
+ return false;
+
+ if (sort_lang.size() < langs.size())
+ for (int i = sort_lang.size(); i < (int) langs.size(); i++)
+ sort_lang.push_back(false);
+
+ if (index == 0)
+ std::sort (vocabulary.begin(), vocabulary.end(), sortByOrg(sort_lang[0]));
+ else
+ std::sort (vocabulary.begin(), vocabulary.end(), sortByTrans(index, sort_lang[index]));
+ sort_lang[index] = !sort_lang[index];
+ return sort_lang[index];
+}
+
+
+bool KEduVocDocument::sortByLesson_alpha ()
+{
+ if (!sort_allowed)
+ return false;
+
+ std::sort (vocabulary.begin(), vocabulary.end(), sortByLessonAndOrg_alpha(sort_lesson, *this ));
+ sort_lesson = !sort_lesson;
+ return sort_lesson;
+}
+
+
+bool KEduVocDocument::sortByLesson_index ()
+{
+ if (!sort_allowed)
+ return false;
+
+ if (sort_lang.size() < langs.size())
+ for (int i = sort_lang.size(); i < (int) langs.size(); i++)
+ sort_lang.push_back(false);
+
+ std::sort (vocabulary.begin(), vocabulary.end(), sortByLessonAndOrg_index(sort_lesson, *this ));
+ sort_lesson = !sort_lesson;
+ sort_lang[0] = sort_lesson;
+ return sort_lesson;
+}
+
+bool KEduVocDocument::leitnerSystemActive()
+{
+ return activeLeitnerSystem;
+}
+
+void KEduVocDocument::setLeitnerSystemActive( bool yes )
+{
+ if( yes )
+ {
+ if( leitnerSystem == 0 )
+ createStandardLeitnerSystem(); //if nothing is loaded yet
+
+ activeLeitnerSystem = true;
+ }
+ else if( !yes )
+ activeLeitnerSystem = false;
+}
+
+void KEduVocDocument::createStandardLeitnerSystem()
+{
+ LeitnerSystem* tmpSystem = new LeitnerSystem();
+ QString name = "Standard";
+
+ tmpSystem->setSystemName( name );
+ tmpSystem->insertBox( "Box 1" );
+ tmpSystem->insertBox( "Box 2" );
+ tmpSystem->insertBox( "Box 3" );
+ tmpSystem->insertBox( "Box 4" );
+ tmpSystem->insertBox( "Box 5" );
+
+ tmpSystem->setCorrectBox( "Box 1", "Box 2" );
+ tmpSystem->setWrongBox( "Box 1", "Box 1" );
+
+ tmpSystem->setCorrectBox( "Box 2", "Box 3" );
+ tmpSystem->setWrongBox( "Box 2", "Box 1" );
+
+ tmpSystem->setCorrectBox( "Box 3", "Box 4" );
+ tmpSystem->setWrongBox( "Box 3", "Box 1" );
+
+ tmpSystem->setCorrectBox( "Box 4", "Box 5" );
+ tmpSystem->setWrongBox( "Box 4", "Box 1" );
+
+ tmpSystem->setCorrectBox( "Box 5", "Box 1" );
+ tmpSystem->setWrongBox( "Box 5", "Box 1" );
+
+ leitnerSystem = tmpSystem;
+}
+
+void KEduVocDocument::setLeitnerSystem( LeitnerSystem* system )
+{
+ leitnerSystem = system;
+
+ /*KWordQuizApp* app = (KWordQuizApp*) parent();
+ app->slotLeitnerSystem();*/
+}
+
+LeitnerSystem* KEduVocDocument::getLeitnerSystem()
+{
+ return leitnerSystem;
+}
+
+
+class resetAll : public unary_function<KEduVocExpression, void>
+{
+
+public:
+
+ resetAll (int less)
+ : lesson(less) {}
+
+ void operator() (KEduVocExpression& x)
+ {
+ for (int i = 0; i <= x.numTranslations(); i++) {
+ if (lesson == 0 || lesson == x.getLesson() ) {
+ x.setGrade(i, KV_NORM_GRADE, false);
+ x.setGrade(i, KV_NORM_GRADE, true);
+ x.setQueryCount (i, 0, true);
+ x.setQueryCount (i, 0, false);
+ x.setBadCount (i, 0, true);
+ x.setBadCount (i, 0, false);
+ x.setQueryDate (i, 0, true);
+ x.setQueryDate (i, 0, false);
+ }
+ }
+ }
+ private:
+ int lesson;
+};
+
+
+class resetOne : public unary_function<KEduVocExpression, void>
+{
+
+public:
+
+ resetOne (int idx, int less)
+ : index (idx), lesson(less) {}
+
+ void operator() (KEduVocExpression& x)
+ {
+ if (lesson == 0 || lesson == x.getLesson() ) {
+ x.setGrade(index, KV_NORM_GRADE, false);
+ x.setGrade(index, KV_NORM_GRADE, true);
+ x.setQueryCount (index, 0, true);
+ x.setQueryCount (index, 0, false);
+ x.setBadCount (index, 0, true);
+ x.setBadCount (index, 0, false);
+ x.setQueryDate (index, 0, true);
+ x.setQueryDate (index, 0, false);
+ }
+ }
+
+ private:
+ int index;
+ int lesson;
+};
+
+
+void KEduVocDocument::resetEntry (int index, int lesson)
+{
+ if (index < 0)
+ for_each (vocabulary.begin(), vocabulary.end(), resetAll(lesson) );
+ else
+ for_each (vocabulary.begin(), vocabulary.end(), resetOne(index, lesson) );
+}
+
+
+QString KEduVocDocument::getLessonDescr(int idx) const
+{
+ if (idx == 0)
+ return i18n("<no lesson>");
+
+ if (idx <= 0 || idx > (int) lesson_descr.size() )
+ return "";
+
+ return lesson_descr[idx-1];
+}
+
+
+vector<int> KEduVocDocument::getLessonsInQuery() const
+{
+ vector<int> iqvec;
+ for (unsigned i = 0; i < lessons_in_query.size(); i++)
+ if (lessons_in_query[i]) {
+ iqvec.push_back(i+1); // Offset <no lesson>
+// cout << "getliq: " << i+1 << endl;
+ }
+ return iqvec;
+}
+
+
+void KEduVocDocument::setLessonsInQuery(vector<int> lesson_iq)
+{
+ lessons_in_query.clear();
+ for (unsigned i = 0; i < lesson_descr.size(); i++)
+ lessons_in_query.push_back(false);
+
+ for (unsigned i = 0; i < lesson_iq.size(); i++)
+ if (lesson_iq[i] <= (int) lessons_in_query.size() ) {
+ lessons_in_query[lesson_iq[i]-1] = true; // Offset <no lesson>
+// cout << "setliq: " << lesson_iq[i] << " " << i << endl;
+ }
+}
+
+
+QString KEduVocDocument::getTitle() const
+{
+ if (doctitle.isEmpty())
+ return doc_url.fileName();
+ else
+ return doctitle;
+}
+
+
+QString KEduVocDocument::getAuthor() const
+{
+ return author;
+}
+
+
+QString KEduVocDocument::getLicense() const
+{
+ return license;
+}
+
+
+QString KEduVocDocument::getDocRemark() const
+{
+ return doc_remark;
+}
+
+
+void KEduVocDocument::setTitle(const QString & title)
+{
+ doctitle = title.stripWhiteSpace();
+}
+
+
+void KEduVocDocument::setAuthor(const QString & s)
+{
+ author = s.stripWhiteSpace();
+}
+
+
+void KEduVocDocument::setLicense(const QString & s)
+{
+ license = s.stripWhiteSpace();
+}
+
+
+void KEduVocDocument::setDocRemark(const QString & s)
+{
+ doc_remark = s.stripWhiteSpace();
+}
+
+
+int KEduVocDocument::search(QString substr, int id,
+ int first, int last,
+ bool word_start,
+ bool)
+{
+ if (last >= numEntries()
+ || last < 0 )
+ last = numEntries();
+
+ if (first < 0)
+ first = 0;
+
+ if (id >= numLangs()
+ || last < first
+ )
+ return -1;
+
+ if (id == 0) {
+ for (int i = first; i < last; i++) {
+ if (word_start) {
+ if (getEntry(i)->getOriginal().find (substr, 0, false) == 0) // case insensitive
+ return i;
+ }
+ else {
+ if (getEntry(i)->getOriginal().find (substr, 0, false) > -1) // case insensitive
+ return i;
+ }
+ }
+ }
+ else {
+ for (int i = first; i < last; i++) {
+ if (word_start) {
+ if (getEntry(i)->getTranslation(id).find (substr, 0, false) == 0) // case insensitive
+ return i;
+ }
+ else {
+ if (getEntry(i)->getTranslation(id).find (substr, 0, false) > -1) // case insensitive
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+#define _OFFSET 0x40
+#define _BITMASK 0x3F
+#define _BITUSED 6
+
+QString KEduVocDocument::compressDate(unsigned long l) const
+{
+ if (l == 0)
+ return "";
+
+ QString res;
+ if (l <= KVD_ZERO_TIME)
+ l = 1;
+ else
+ l -= KVD_ZERO_TIME;
+ while (l != 0) {
+ char c = _OFFSET + (l & _BITMASK);
+ res.insert (0, c);
+ l >>= _BITUSED;
+ }
+ return res;
+}
+
+
+unsigned long KEduVocDocument::decompressDate(QString s) const
+{
+ if (s.isEmpty())
+ return 0;
+
+ long res = 0;
+ unsigned incr = 0;
+ for (int i = s.length()-1; i >= 0; i--) {
+ char c = s.local8Bit()[i];
+ res += ((c - _OFFSET) & _BITMASK) << incr ;
+ incr += _BITUSED;
+ }
+ return res > 48 ? res+KVD_ZERO_TIME : 0; // early bug with "0"
+}
+
+
+KEduVocDocument::FileType KEduVocDocument::detectFT(const QString &filename)
+{
+ QFile f( filename );
+ if (!f.open( IO_ReadOnly ))
+ return csv;
+
+ QDataStream is( &f );
+
+ Q_INT8 c1, c2, c3, c4, c5;
+ is >> c1
+ >> c2
+ >> c3
+ >> c4
+ >> c5; // guess filetype by first x bytes
+
+ QTextStream ts (&f);
+ QString line;
+ line = ts.readLine();
+ line.insert (0, c5);
+ line.insert (0, c4);
+ line.insert (0, c3);
+ line.insert (0, c2);
+ line.insert (0, c1);
+ f.close();
+
+ bool stat = is.device()->status();
+ if (stat != IO_Ok)
+ return kvd_none;
+ if (c1 == '<' && c2 == '?' && c3 == 'x' && c4 == 'm' && c5 == 'l')
+ return kvtml;
+
+ if (line.find (VCB_SEPARATOR) >= 0)
+ return vt_vcb;
+
+ if (line == LEX_IDENT_50)
+ return vt_lex;
+
+ return csv;
+}
+
+
+class expRef {
+
+public:
+
+ expRef (KEduVocExpression *_exp, int _idx)
+ {
+ idx = _idx;
+ exp = _exp;
+ }
+
+ bool operator< (const expRef& y) const
+ {
+ QString s1 = exp->getOriginal();
+ QString s2 = y.exp->getOriginal();
+ int cmp = QString::compare(s1.upper(), s2.upper());
+ if (cmp != 0)
+ return cmp < 0;
+
+ for (int i = 1; i < (int) exp->numTranslations(); i++) {
+
+ s1 = exp->getTranslation(i);
+ s2 = y.exp->getTranslation(i);
+ cmp = QString::compare(s1.upper(), s2.upper() );
+ if (cmp != 0)
+ return cmp < 0;
+ }
+ return cmp < 0;
+ }
+
+ int idx;
+ KEduVocExpression *exp;
+};
+
+
+int KEduVocDocument::cleanUp()
+{
+ int count = 0;
+ KEduVocExpression *kve1, *kve2;
+ vector<expRef> shadow;
+ vector<int> to_delete;
+
+ for (int i = 0; i < (int) vocabulary.size(); i++)
+ shadow.push_back (expRef (getEntry(i), i));
+ std::sort(shadow.begin(), shadow.end());
+
+#ifdef CLEAN_BUG
+ ofstream sso ("shadow.out");
+ for (int i = shadow.size()-1; i > 0; i--) {
+ kve1 = shadow[i].exp;
+ sso << kve1->getOriginal() << " ";
+ for (int l = 1; l < (int) numLangs(); l++ )
+ sso << kve1->getTranslation(l) << " ";
+ sso << endl;
+ }
+#endif
+
+ int ent_no = 0;
+ int ent_percent = vocabulary.size () / 100;
+ float f_ent_percent = vocabulary.size () / 100.0;
+ emit progressChanged(this, 0);
+
+ for (int i = shadow.size()-1; i > 0; i--) {
+ kve1 = shadow[i].exp;
+ kve2 = shadow[i-1].exp;
+
+ ent_no++;
+ if (ent_percent != 0 && (ent_no % ent_percent) == 0 )
+ emit progressChanged(this, (int)((ent_no / f_ent_percent) / 2.0));
+
+ bool equal = true;
+ if (kve1->getOriginal() == kve2->getOriginal() ) {
+ for (int l = 1; equal && l < (int) numLangs(); l++ )
+ if (kve1->getTranslation(l) != kve2->getTranslation(l))
+ equal = false;
+
+ if (equal) {
+ to_delete.push_back(shadow[i-1].idx);
+ count++;
+ }
+ }
+ }
+
+ // removing might take very long
+ ent_no = 0;
+ ent_percent = to_delete.size () / 100;
+ f_ent_percent = to_delete.size () / 100.0;
+ emit progressChanged(this, 0);
+
+ std::sort (to_delete.begin(), to_delete.end() );
+ for (int i = (int) to_delete.size()-1; i >= 0; i--) {
+ ent_no++;
+ if (ent_percent != 0 && (ent_no % ent_percent) == 0 )
+ emit progressChanged(this, (int)(50 + ent_no / f_ent_percent / 2.0));
+#ifdef CLEAN_BUG
+ sso << getEntry(to_delete[i])->getOriginal() << endl;
+#endif
+ removeEntry (to_delete[i]);
+ setModified();
+ }
+
+ return count;
+}
+
+#include "keduvocdocument.moc"
diff --git a/kanagram/src/keduvocdocument.h b/kanagram/src/keduvocdocument.h
new file mode 100644
index 00000000..4e48e21b
--- /dev/null
+++ b/kanagram/src/keduvocdocument.h
@@ -0,0 +1,687 @@
+/***************************************************************************
+ Vocabulary Document for KDE Edu
+ -----------------------------------------------------------------------
+ copyright : (C) 1999-2001 Ewald Arnold
+ (C) 2001 The KDE-EDU team
+ (C) 2005 Peter Hedlung
+ email : peter.hedlund@kdemail.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 KEDUVOCDOCUMENT_H
+#define KEDUVOCDOCUMENT_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qobject.h>
+
+#include <kurl.h>
+
+#include "keduvocexpression.h"
+
+#define KVD_ZERO_TIME 934329599 // 1999-08-10 23:59:59, never change
+#define KVD_VERS_PREFIX " v" // kvoctrain v0.1.0
+
+/** XML tags and attribute names */
+
+#define KV_DOCTYPE "kvtml" // doctype
+#define KV_TITLE "title" // doc title
+#define KV_AUTHOR "author" // doc author
+#define KV_LICENSE "license" // doc license
+#define KV_DOC_REM "remark" // doc remark
+#define KV_LINES "lines" // entries
+#define KV_GENERATOR "generator" // who generated the doc
+#define KV_COLS "cols" // columns
+#define KV_ENCODING "encoding" // document encoding (obsolete!)
+
+#define KV_EXPR "e" // entry for one expression
+#define KV_ORG "o" // original expression in specified language
+#define KV_TRANS "t" // translated expression in specified language
+#define KV_LANG "l" // language: en, de, it, fr ...
+#define KV_QUERY "q" // query: org or translation
+#define KV_O "o" // org
+#define KV_T "t" // translation
+#define KV_GRADE "g" // grade of knowledge: 0=well known, x=not known for x times
+#define KV_LESS_MEMBER "m" // member of lesson 1 .. x
+#define KV_COUNT "c" // number of times queried
+#define KV_SIZEHINT "width" // recommended column width
+#define KV_CHARSET "charset" // recommended charset (obsolete!)
+#define KV_BAD "b" // number of times failed
+#define KV_DATE "d" // last query date
+#define KV_DATE2 "w" // last query date, compressed format
+#define KV_REMARK "r" // remark for this entry
+#define KV_FAUX_AMI_F "ff" // false friend of this entry from org
+#define KV_FAUX_AMI_T "tf" // false friend of this entry to org
+#define KV_SYNONYM "y" // synonym (same meaning) of expr
+#define KV_ANTONYM "a" // antonym (oppositite) of expr
+#define KV_PRONUNCE "p" // how to pronunce this expression
+#define KV_SELECTED "s" // entry selected for queries
+#define KV_INACTIVE "i" // entry inactive (for queries)
+#define KV_EXPRTYPE "t" // type of expression
+#define KV_EXAMPLE "x" // example string with word
+#define KV_USAGE "u" // usage label
+#define KV_PARAPHRASE "h" // paraphrase for expression
+
+/*
+ <type>
+ <desc no="1">My type 1</desc>
+ <desc no="2">My type 2</desc>
+ </type>
+*/
+
+#define KV_TYPE_GRP "type" // type descriptor group
+#define KV_TYPE_DESC "desc" // type descriptor
+#define KV_TYPE_NO "no" // type descriptor number
+
+/*
+ <usage>
+ <desc no="1">My usage 1</desc>
+ <desc no="2">My usage 2</desc>
+ </type>
+*/
+
+#define KV_USAGE_GRP "usage" // usage descriptor group
+#define KV_USAGE_DESC "desc" // usage descriptor
+#define KV_USAGE_NO "no" // usage descriptor number
+
+/*
+ <lesson width="138">
+ <desc no="1">Lesson #1</desc>
+ <desc no="2" query="1">Lesson #2</desc>
+ </lesson>
+*/
+
+#define KV_LESS_GRP "lesson" // lesson descriptor group
+#define KV_LESS_CURR "current" // is current lesson
+#define KV_LESS_DESC "desc" // lesson descriptor
+#define KV_LESS_QUERY "query" // lesson contained in query
+#define KV_LESS_NO "no" // lesson descriptor number
+
+/*
+ <tense>
+ <desc no="1">user tense #1</desc>
+ <desc no="2">user tense #2</desc>
+ </tense>
+*/
+
+#define KV_TENSE_GRP "tense" // tense descriptor group
+#define KV_TENSE_DESC "desc" // tense descriptor
+#define KV_TENSE_NO "no" // tense descriptor number
+
+/*
+ <options>
+ <sort on="1"/>
+ </options>
+*/
+
+#define KV_OPTION_GRP "options" // internal options group
+#define KV_OPT_SORT "sort" // allow sorting
+#define KV_BOOL_FLAG "on" // general boolean flag
+
+/*
+ <article>
+ <e l="de"> lang determines also lang order in entries !!
+ <fi>eine</fi> which must NOT differ
+ <fd>die</fd>
+ <mi>ein</mi>
+ <md>der</md>
+ <ni>ein</ni>
+ <nd>das</nd>
+ </e>
+ </article>
+*/
+
+#define KV_ARTICLE_GRP "article" // article descriptor group
+#define KV_ART_ENTRY "e" // article entry
+#define KV_ART_FD "fd" // female definite
+#define KV_ART_MD "md" // male definite
+#define KV_ART_ND "nd" // natural definite
+#define KV_ART_FI "fi" // female indefinite
+#define KV_ART_MI "mi" // male indefinite
+#define KV_ART_NI "ni" // natural indefinite
+
+/*
+ <comparison>
+ <l1>good</l1>
+ <l2>better</l2>
+ <l3>best</l3>
+ </comparison>
+*/
+
+#define KV_COMPARISON_GRP "comparison" // comparison descriptor group
+#define KV_COMP_L1 "l1" // base form
+#define KV_COMP_L2 "l2" // next form
+#define KV_COMP_L3 "l3" // last form
+
+/*
+ <multiplechoice>
+ <mc1>good</mc1>
+ <mc2>better</mc2>
+ <mc3>best</mc3>
+ <mc4>best 2</mc4>
+ <mc5>best 3</mc5>
+ </multiplechoice>
+*/
+
+#define KV_MULTIPLECHOICE_GRP "multiplechoice" // multiple choice descriptor group
+#define KV_MC_1 "mc1" // choice 1
+#define KV_MC_2 "mc2" // choice 2
+#define KV_MC_3 "mc3" // choice 3
+#define KV_MC_4 "mc4" // choice 4
+#define KV_MC_5 "mc5" // choice 5
+
+/*
+ <conjugation> used in header for definiton of "prefix"
+ <e l="de"> lang determines also lang order in entries !!
+ <s1>I</s1> which must NOT differ in subsequent <e>-tags
+ <s2>you<2>
+ <s3f>he</s3f>
+ <s3m>she</s3m>
+ <s3n>it</s3n>
+ <p1>we</p1>
+ <p2>you</p2>
+ <p3f>they</p3f>
+ <p3m>they</p3m>
+ <p3n>they</p3n>
+ </e>
+ </conjugation>
+
+ <conjugation> and in entry for definition of tenses of (irreg.) verbs
+ <t n="sipa">
+ <s1>go</s1>
+ <s2>go</s2>
+ <s3f>goes</s3f>
+ <s3m>goes</s3m>
+ <s3n>goes</s3n>
+ <p1>go</p1>
+ <p2>go</p2>
+ <p3f>go</p3f>
+ <p3m>go</p3m>
+ <p3n>go</p3n>
+ </t>
+ </conjugation>
+*/
+
+#define KV_CONJUG_GRP "conjugation" // conjugation descriptor group
+#define KV_CON_ENTRY "e" // conjugation entry (header)
+#define KV_CON_TYPE "t" // conjugation type (voc entries)
+#define KV_CON_NAME "n" // conjugation type name (voc entries)
+#define KV_CON_P1S "s1" // 1. person singular
+#define KV_CON_P2S "s2" // 2. person singular
+#define KV_CON_P3SF "s3f" // 3. person singular female
+#define KV_CON_P3SM "s3m" // 3. person singular male
+#define KV_CON_P3SN "s3n" // 3. person singular natural
+#define KV_CON_P1P "p1" // 1. person plural
+#define KV_CON_P2P "p2" // 2. person plural
+#define KV_CON_P3PF "p3f" // 3. person plural female
+#define KV_CON_P3PM "p3m" // 3. person plural male
+#define KV_CON_P3PN "p3n" // 3. person plural natural
+#define KV_CONJ_COMMON "common" // female contains common for all three
+
+#define LEX_IDENT_50 "Vocabulary Trainer V5.0"
+
+#define KVTML_EXT "kvtml"
+#define VT5_LEX_EXT "lex"
+#define QVOCAB_EXT "qvo"
+#define VCB_EXT "vocab"
+#define KVL_EXT "vl"
+#define CSV_EXT "csv"
+#define TXT_EXT "txt"
+
+#define VCB_SEPARATOR "__"
+
+class QTextStream;
+class QStringList;
+class MultipleChoice;
+class LeitnerSystem;
+
+/*************************************************************
+ * This class contains the expressions of your vocabulary
+ ************************************************************/
+
+class KEduVocDocument : public QObject
+{
+ Q_OBJECT
+ friend class KEduVocKvtmlWriter;
+ friend class KEduVocKvtmlReader;
+
+ public:
+
+ enum FileType { kvd_none, automatic,
+ kvtml,
+ kvtbin,
+ vt_lex, vt_vcb, csv /*, kvoclearn, qvocab*/ };
+
+ /** Constructor for the fileclass of the application
+ *
+ * @param obj calling object
+ */
+ KEduVocDocument(QObject* obj);
+
+ /** Destructor for the fileclass of the application */
+ ~KEduVocDocument();
+
+ /** indicates that doc is (not) modified
+ *
+ * @param dirty new state
+ */
+ inline void setModified (bool _dirty = true) { emit docModified(dirty = _dirty); }
+
+ /** appends another entry at the end
+ *
+ * @param expr expression to append
+ */
+ inline void appendEntry (KEduVocExpression *expr)
+ { vocabulary.push_back (*expr); dirty = true; }
+
+ /** insert an entry
+ *
+ * @param expr expression to append
+ * @param index index of entry
+ */
+ inline void insertEntry(KEduVocExpression *expr, int index)
+ { vocabulary.insert(vocabulary.begin()+index, *expr); dirty = true; }
+
+ /** removes entry from doc
+ *
+ * @param index index of entry
+ */
+ void removeEntry (int index);
+
+ /** sorts vocabulary alphabetically
+ *
+ * @param index index expression
+ * @result direction of sorting: true = ascending
+ */
+ bool sort (int index);
+
+ /** removes equal entries (orig + all translations)
+ *
+ * @result number of removed entries
+ */
+ int cleanUp();
+
+ /** sorts vocabulary by lesson indices
+ * @result direction of sorting: true = ascending
+ */
+ bool sortByLesson_index ();
+
+ /** sorts vocabulary by lesson name
+ * @result direction of sorting: true = ascending
+ */
+ bool sortByLesson_alpha ();
+
+ /** enables sorting
+ */
+ inline void allowSorting(bool allow) { sort_allowed = allow; }
+
+ /** enables sorting
+ */
+ inline bool isAllowedSorting() { return sort_allowed; }
+
+ /** returns the modification state of the doc */
+ inline bool isModified () const { return dirty; }
+
+ /** returns originals identifier
+ */
+ QString getOriginalIdent () const;
+
+ /** set originals identifier
+ */
+ void setOriginalIdent (const QString &id);
+
+ /** returns identifier of translation x
+ *
+ * @param index number of translation 1..x
+ * @result ident string: de=german, en=englisch, ..
+ */
+ QString getIdent (int index) const;
+
+ /** sets identifier of translation
+ *
+ * @param index number of translation 1..x
+ * @param lang ident string: de=german, en=englisch, ..
+ */
+ void setIdent (int index, const QString &lang);
+
+ /** removes identifier an the according translation in all entries
+ *
+ * @param index number of translation 1..x
+ */
+ void removeIdent (int index);
+
+ /** determines if given translation is available and where
+ *
+ * @param lang identifier of language
+ * @result index of translation, 0=original, -1=none
+ */
+ int findIdent (const QString &lang) const;
+
+ /** returns attribute string
+ *
+ * @param index number of attribute
+ * @result string
+ */
+ QString getTypeName (int index) const;
+
+ /** sets attribute string
+ *
+ * @param index number of attribute
+ * @param str name of attribute
+ */
+ void setTypeName (int index, QString &str);
+
+ /** gets descr of types */
+ inline vector<QString> getTypeDescr() const { return type_descr; }
+
+ /** sets descr of types */
+ inline void setTypeDescr(vector<QString> names) { type_descr = names; }
+
+ /** returns tense string
+ *
+ * @param index number of tense
+ * @result string
+ */
+ QString getTenseName (int index) const;
+
+ /** sets tense string
+ *
+ * @param index number of tense
+ * @param str name of tense
+ */
+ void setTenseName (int index, QString &str);
+
+ /** gets descr of tenses */
+ inline vector<QString> getTenseDescr() const { return tense_descr; }
+
+ /** sets descr of tenses */
+ inline void setTenseDescr(vector<QString> names) { tense_descr = names; }
+
+ /** returns usage string
+ *
+ * @param index number of usage
+ * @result string
+ */
+ QString getUsageName (int index) const;
+
+ /** sets usage string
+ *
+ * @param index number of usage
+ * @param str name of usage
+ */
+ void setUsageName (int index, QString &str);
+
+ /** gets descr of usages */
+ inline vector<QString> getUsageDescr() const { return usage_descr; }
+
+ /** sets descr of usages */
+ inline void setUsageDescr(vector<QString> names) { usage_descr = names; }
+
+ /** open a document file
+ *
+ * @param url
+ * @result true if successful
+ */
+ bool open(const KURL& url, bool append);
+
+ /** saves the data under the given name
+ *
+ * @param url if url is empty (or NULL) actual name is preserved
+ * @result true if successful
+ */
+ bool saveAs(QObject *parent, const KURL & url, FileType ft, const QString & generator);
+
+ /** returns count of entries
+ */
+ inline int numEntries() const { return vocabulary.size(); }
+
+ /** sets grades to KV_NORM_GRADE, counts to 0 ...
+ *
+ * @param index index of language 0..x, -1 = all
+ * @param lesson lesson id, if this is 0 all lesson are affected,
+ * otherwise only matching numbers
+ */
+ void resetEntry (int index = -1, int lesson = 0);
+
+ /** returns count of different languages
+ */
+ inline int numLangs() const { return langs.size(); } // org + translations
+
+ /** append new lang ident
+ */
+ inline void appendLang(const QString & id) { langs.push_back(id); }
+
+ /** returns pointer to expression object x
+ *
+ * @param index index of desired entry
+ * @result pointer to object or NULL if index out of range
+ */
+ KEduVocExpression *getEntry(int index);
+
+ /** search substring in vocabulary (case insensitive always)
+ *
+ * @param substr partial string to search
+ * @param id which language to search: 0=org, 1..x=translation
+ * @param first index from where to start
+ * @param last index of last entry, -1 goes till end
+ * @param word_start false: search partial string,
+ * true:always from beginning of word
+ * @param tolerant
+ * @result index of found entry, -1 if none
+ */
+ int search(QString substr, int id,
+ int first=0, int last=-1, bool word_start = false, bool tolerant=false);
+
+ /** returns url of xml file */
+ inline KURL URL() const {return doc_url; }
+
+ /** sets url of xml file */
+ inline void setURL(const KURL& url) {doc_url = url;}
+
+ /** returns title of xml file */
+ QString getTitle() const;
+
+ /** returns author of file */
+ QString getAuthor() const;
+
+ /** returns license of file */
+ QString getLicense() const;
+
+ /** returns remark of file */
+ QString getDocRemark() const;
+
+ inline void getQueryLang(QString &org, QString &trans) const
+ { org = queryorg; trans = querytrans; }
+
+ inline void setQueryLang(const QString &org, const QString &trans)
+ { queryorg = org; querytrans = trans; }
+
+ /** sets title of xml file */
+ void setTitle(const QString & title);
+
+ /** sets author of file */
+ void setAuthor(const QString & author);
+
+ /** sets license of file */
+ void setLicense(const QString & license);
+
+ /** sets remark of file */
+ void setDocRemark(const QString & rem);
+
+ /** gets version of loaded file */
+ void getVersion(int &major, int &minor, int &patch);
+
+ /** returns current lesson index */
+ inline int getCurrentLesson() const { return current_lesson; }
+
+ /** sets current lesson index
+ * @param lesson index of lesson
+ */
+ inline void setCurrentLesson(int lesson) { current_lesson = lesson; }
+
+ /** returns descr of lesson */
+ QString getLessonDescr(int index) const;
+
+ /** returns lessons in current query */
+ vector<int> getLessonsInQuery() const;
+
+ /** sets lessons in current query */
+ void setLessonsInQuery(vector<int>);
+
+ inline vector<QString> getLessonDescr() const { return lesson_descr; }
+
+ inline int numLessons () const {return (int) lesson_descr.size(); }
+
+ /** sets descr of lesson */
+ inline void setLessonDescr(vector<QString> names) { lesson_descr = names; }
+
+ /** returns pointer to conjugations if available
+ *
+ * @param index index of translation
+ */
+ Conjugation getConjugation(int index) const;
+
+ /** sets conjugations
+ *
+ * @param index index of translation
+ * @param con conjugation block
+ */
+ void setConjugation(int index, const Conjugation &con);
+
+ /** returns pointer to articles if available
+ *
+ * @param index index of translation
+ */
+ Article getArticle(int index) const;
+
+ /** sets articles
+ *
+ * @param index index of translation
+ * @param art article block
+ */
+ void setArticle(int index, const Article &art);
+
+ /** compress date */
+ QString compressDate(unsigned long) const;
+
+ /** decompress date */
+ unsigned long decompressDate(QString) const;
+
+ /** returns recommended size
+ *
+ * @param index number of expr, -1 = lesson
+ * @result width of column
+ */
+ int getSizeHint (int index) const;
+
+ /** sets recommended size
+ *
+ * @param index number of expr, -1 = lesson
+ * @param width width of column
+ */
+ void setSizeHint (int index, const int width);
+
+ bool leitnerSystemActive();
+ void setLeitnerSystemActive(bool yes);
+ void createStandardLeitnerSystem();
+ void setLeitnerSystem( LeitnerSystem* system );
+ LeitnerSystem* getLeitnerSystem();
+
+ bool unknownAttribute (int line, const QString &name, const QString &attr);
+ void unknownElement (int line, const QString &elem );
+ void errorKvtMl (int line, const QString &text );
+ void warningKvtMl (int line, const QString &text );
+
+ void errorLex (int line, const QString &text );
+
+ void errorCsv (int line, const QString &text );
+
+ FileType detectFT(const QString &filename);
+
+ friend class QueryManager;
+
+signals:
+ void progressChanged (KEduVocDocument *, int curr_percent);
+ void docModified (bool mod);
+
+protected:
+
+ void Init();
+
+ /** sets version of loaded file */
+ void setVersion(const QString & ver);
+
+ /* TODO
+ bool saveToLex (QTextStream& os, QString &title);
+ bool loadFromLex (QTextStream& is);
+ bool loadLessonLex (QTextStream& is);
+ bool saveLessonLex (QTextStream& os);
+ bool saveTypeNameLex (QTextStream& os);
+ bool loadTypeNameLex (QTextStream& is);
+
+ bool saveToCsv (QTextStream& os, QString &title);
+ bool loadFromCsv (QTextStream& is);
+ bool loadLessonCsv (QTextStream& is);
+ bool saveLessonCsv (QTextStream& os);
+ bool saveTypeNameCsv (QTextStream& os);
+ bool loadTypeNameCsv (QTextStream& is);
+
+ bool saveTypeNameVcb (QTextStream &os);
+ bool loadTypeNameVcb (QTextStream &is);
+ bool saveLessonVcb (QTextStream &os);
+ bool loadLessonVcb (QTextStream &is);
+ bool saveToVcb (QTextStream& os, QString &title);
+ bool loadFromVcb (QTextStream& is);
+ void errorVcb (int line, const QString &text );
+ */
+
+ private:
+ bool dirty;
+ KURL doc_url;
+ vector<bool> sort_lang;
+ bool sort_lesson;
+ bool unknown_attr;
+ bool unknown_elem;
+ bool sort_allowed;
+
+ // save these to document
+ vector<QString> langs; //0= origin, 1,.. translations
+ int cols,
+ lines;
+ int current_lesson;
+ vector<int> extraSizehints;
+ vector<int> sizehints;
+ QString generator;
+ QString queryorg,
+ querytrans;
+ vector<KEduVocExpression> vocabulary;
+ vector<bool> lessons_in_query;
+ vector<QString> lesson_descr;
+ vector<QString> type_descr;
+ vector<QString> tense_descr;
+ vector<QString> usage_descr;
+ QString doctitle;
+ QString author;
+ QString license;
+ QString doc_remark;
+ QString doc_version;
+
+ vector<Article> articles;
+ vector<Conjugation> conjugations;
+
+ LeitnerSystem* leitnerSystem;
+ bool activeLeitnerSystem;
+};
+
+
+#endif // KEDUVOCDOCUMENT_H
diff --git a/kanagram/src/keduvocexpression.cpp b/kanagram/src/keduvocexpression.cpp
new file mode 100644
index 00000000..9ac29894
--- /dev/null
+++ b/kanagram/src/keduvocexpression.cpp
@@ -0,0 +1,792 @@
+/***************************************************************************
+ Vocabulary Expression for KDE Edu
+ -----------------------------------------------------------------------
+ copyright : (C) 1999-2001 Ewald Arnold
+ (C) 2001 The KDE-EDU team
+ (C) 2005 Peter Hedlung
+ email : peter.hedlund@kdemail.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 "keduvocexpression.h"
+
+void KEduVocExpression::Init()
+{
+ grades.push_back(KV_NORM_GRADE);
+ rev_grades.push_back(KV_NORM_GRADE);
+ inquery = false;
+ active = true;
+ qcounts.push_back(0);
+ rev_qcounts.push_back(0);
+ bcounts.push_back(0);
+ rev_bcounts.push_back(0);
+ qdates.push_back(0);
+ rev_qdates.push_back(0);
+ lesson = 0;
+}
+
+
+KEduVocExpression::KEduVocExpression (QString &expr, int _lesson)
+{
+ Init();
+ setOriginal(expr.stripWhiteSpace() );
+ lesson = _lesson;
+}
+
+
+KEduVocExpression::KEduVocExpression ()
+{
+ Init();
+}
+
+
+KEduVocExpression::KEduVocExpression (QString &s, QString separator, int _lesson)
+{
+ Init();
+ QString se;
+ lesson = _lesson;
+
+ if (separator.length() ) {
+ int pos = s.find(separator);
+
+ if (pos == -1) {
+ setOriginal(s.stripWhiteSpace());
+ }
+ else {
+ se = s.left(pos).stripWhiteSpace();
+ setOriginal(se);
+ s.remove (0, pos+separator.length() );
+// s.stripWhiteSpace();
+
+ // gather all translations
+ while ((pos = s.find(separator)) != -1) {
+ se = s.left(pos).stripWhiteSpace();
+ addTranslation(se, KV_NORM_GRADE, KV_NORM_GRADE);
+ s.remove (0, pos+separator.length() );
+// s.stripWhiteSpace();
+ }
+ addTranslation(s.stripWhiteSpace(), KV_NORM_GRADE, KV_NORM_GRADE);
+ }
+ }
+}
+
+
+KEduVocExpression::~KEduVocExpression()
+{
+}
+
+
+int KEduVocExpression::numTranslations() const
+{
+ return translations.size();
+}
+
+
+QString KEduVocExpression::getRemark (int idx) const
+{
+ if (idx >= (int)remarks.size() || idx < 0) {
+ return "";
+ }
+ else {
+ return remarks[idx];
+ }
+}
+
+
+void KEduVocExpression::setRemark (int idx, const QString & expr)
+{
+ if ( idx < 0) return;
+
+ // extend remarks with empty strings if necessary
+ if ((int)remarks.size() <= idx )
+ for (int i = remarks.size(); i < idx+1; i++)
+ remarks.push_back ("");
+
+ remarks[idx] = expr.stripWhiteSpace();
+}
+
+
+void KEduVocExpression::setFauxAmi (int idx, const QString & expr, bool rev_ami)
+{
+ if (idx < 1) return;
+
+ if (rev_ami) {
+ // extend friend with empty strings if necessary
+ if ((int)rev_fauxAmi.size() <= idx )
+ for (int i = rev_fauxAmi.size(); i < idx+1; i++)
+ rev_fauxAmi.push_back ("");
+
+ rev_fauxAmi[idx] = expr.stripWhiteSpace();
+
+ }
+ else {
+ // extend friend with empty strings if necessary
+ if ((int)fauxAmi.size() <= idx )
+ for (int i = fauxAmi.size(); i < idx+1; i++)
+ fauxAmi.push_back ("");
+
+ fauxAmi[idx] = expr.stripWhiteSpace();
+ }
+}
+
+
+QString KEduVocExpression::getFauxAmi (int idx, bool rev_ami) const
+{
+ if (rev_ami) {
+ if (idx >= (int)rev_fauxAmi.size() || idx < 1 ) {
+ return "";
+ }
+
+ return rev_fauxAmi[idx];
+ }
+
+ if (idx >= (int)fauxAmi.size() || idx < 1 ) {
+ return "";
+ }
+
+ return fauxAmi[idx];
+}
+
+
+void KEduVocExpression::setSynonym (int idx, const QString & expr)
+{
+ if ( idx < 0) return;
+
+ // extend synonym with empty strings if necessary
+ if ((int)synonym.size() <= idx )
+ for (int i = synonym.size(); i < idx+1; i++)
+ synonym.push_back ("-");
+
+ synonym[idx] = expr.stripWhiteSpace();
+}
+
+
+QString KEduVocExpression::getSynonym (int idx) const
+{
+ if (idx >= (int)synonym.size() || idx < 0) {
+ return "";
+ }
+ else {
+ return synonym[idx];
+ }
+}
+
+
+void KEduVocExpression::setExample (int idx, const QString & expr)
+{
+ if ( idx < 0) return;
+
+ // extend exampls with empty strings if necessary
+ if ((int)example.size() <= idx )
+ for (int i = example.size(); i < idx+1; i++)
+ example.push_back ("");
+
+ example[idx] = expr.stripWhiteSpace();
+}
+
+
+QString KEduVocExpression::getExample (int idx) const
+{
+ if (idx >= (int)example.size() || idx < 0) {
+ return "";
+ }
+ else {
+ return example[idx];
+ }
+}
+
+
+void KEduVocExpression::setUsageLabel (int idx, const QString & expr)
+{
+ if ( idx < 0) return;
+
+ // extend labels with empty strings if necessary
+ if ((int)usageLabels.size() <= idx )
+ for (int i = usageLabels.size(); i < idx+1; i++)
+ usageLabels.push_back ("");
+
+ usageLabels[idx] = expr.stripWhiteSpace();
+}
+
+
+QString KEduVocExpression::getUsageLabel (int idx) const
+{
+ if (idx >= (int)usageLabels.size() || idx < 0) {
+ return "";
+ }
+ else {
+ return usageLabels[idx];
+ }
+}
+
+
+void KEduVocExpression::setParaphrase (int idx, const QString & expr)
+{
+ if ( idx < 0) return;
+
+ // extend phrase with empty strings if necessary
+ if ((int) paraphrases.size() <= idx )
+ for (int i = paraphrases.size(); i < idx+1; i++)
+ paraphrases.push_back ("");
+
+ paraphrases[idx] = expr.stripWhiteSpace();
+}
+
+
+QString KEduVocExpression::getParaphrase (int idx) const
+{
+ if (idx >= (int)paraphrases.size() || idx < 0) {
+ return "";
+ }
+ else {
+ return paraphrases[idx];
+ }
+}
+
+
+void KEduVocExpression::setAntonym (int idx, const QString & expr)
+{
+ if ( idx < 0) return;
+
+ // extend antonym with empty strings if necessary
+ if ((int)antonym.size() <= idx )
+ for (int i = antonym.size(); i < idx+1; i++)
+ antonym.push_back ("");
+
+ antonym[idx] = expr.stripWhiteSpace();
+}
+
+
+QString KEduVocExpression::getAntonym (int idx) const
+{
+ if (idx >= (int)antonym.size() || idx < 0) {
+ return "";
+ }
+ else {
+ return antonym[idx];
+ }
+}
+
+
+void KEduVocExpression::setConjugation (int idx, const Conjugation &con)
+{
+ if ( idx < 0) return;
+
+ // extend conjugation with empty elements
+ if ((int)conjugations.size() <= idx )
+ for (int i = conjugations.size(); i < idx+1; i++)
+ conjugations.push_back (Conjugation());
+
+ conjugations[idx] = con;
+}
+
+
+Conjugation KEduVocExpression::getConjugation (int idx) const
+{
+ if (idx >= (int)conjugations.size() || idx < 0) {
+ return Conjugation();
+ }
+ else {
+ return conjugations[idx];
+ }
+}
+
+
+void KEduVocExpression::setComparison (int idx, const Comparison &con)
+{
+ if ( idx < 0) return;
+
+ // extend comparison with empty elements
+ if ((int)comparisons.size() <= idx )
+ for (int i = comparisons.size(); i < idx+1; i++)
+ comparisons.push_back (Comparison());
+
+ comparisons[idx] = con;
+}
+
+
+Comparison KEduVocExpression::getComparison (int idx) const
+{
+ if (idx >= (int)comparisons.size() || idx < 0) {
+ return Comparison();
+ }
+ else {
+ return comparisons[idx];
+ }
+}
+
+
+void KEduVocExpression::setMultipleChoice (int idx, const MultipleChoice &mc)
+{
+ if ( idx < 0) return;
+
+ // extend comparison with empty elements
+ if ((int)mcs.size() <= idx )
+ for (int i = mcs.size(); i < idx+1; i++)
+ mcs.push_back (MultipleChoice());
+
+ mcs[idx] = mc;
+}
+
+
+MultipleChoice KEduVocExpression::getMultipleChoice (int idx) const
+{
+ if (idx >= (int)mcs.size() || idx < 0) {
+ return MultipleChoice();
+ }
+ else {
+ return mcs[idx];
+ }
+}
+
+
+QString KEduVocExpression::getPronunce (int idx) const
+{
+ if (idx >= (int)pronunces.size() || idx < 0) {
+ return "";
+ }
+ else {
+ return pronunces[idx];
+ }
+}
+
+
+void KEduVocExpression::setPronunce (int idx, const QString & expr)
+{
+ if ( idx < 0) return;
+
+ // extend with empty strings if necessary
+ if ((int)pronunces.size() <= idx )
+ for (int i = pronunces.size(); i < idx+1; i++)
+ pronunces.push_back ("");
+
+ pronunces[idx] = expr.stripWhiteSpace();
+}
+
+
+void KEduVocExpression::addTranslation (QString expr,
+ grade_t grade, grade_t rev_grade)
+{
+ if (grade > KV_MAX_GRADE)
+ grade = KV_MAX_GRADE;
+
+ if (rev_grade > KV_MAX_GRADE)
+ rev_grade = KV_MAX_GRADE;
+
+ grades.push_back (grade);
+ rev_grades.push_back (rev_grade);
+ translations.push_back (expr.stripWhiteSpace());
+}
+
+
+QString KEduVocExpression::getTranslation (int idx) const
+{
+ if (idx > (int)translations.size() || idx < 1)
+ return "";
+ else
+ return translations[idx-1];
+}
+
+
+void KEduVocExpression::removeTranslation (int idx)
+{
+ if (idx <= 0)
+ return;
+
+ if (idx <= numTranslations())
+ translations.erase (translations.begin() + idx-1);
+
+ if (idx < (int)remarks.size() )
+ remarks.erase (remarks.begin() + idx);
+
+ if (idx < (int)conjugations.size() )
+ conjugations.erase (conjugations.begin() + idx);
+
+ if (idx < (int)comparisons.size() )
+ comparisons.erase (comparisons.begin() + idx);
+
+ if (idx < (int)fauxAmi.size() )
+ fauxAmi.erase (fauxAmi.begin() + idx);
+
+ if (idx < (int)rev_fauxAmi.size() )
+ rev_fauxAmi.erase (rev_fauxAmi.begin() + idx);
+
+ if (idx < (int)synonym.size() )
+ synonym.erase (synonym.begin() + idx);
+
+ if (idx < (int)example.size() )
+ example.erase (example.begin() + idx);
+
+ if (idx < (int)usageLabels.size() )
+ usageLabels.erase (usageLabels.begin() + idx);
+
+ if (idx < (int)paraphrases.size() )
+ paraphrases.erase (paraphrases.begin() + idx);
+
+ if (idx < (int)antonym.size() )
+ antonym.erase (antonym.begin() + idx);
+
+ if (idx < (int)exprtypes.size() )
+ exprtypes.erase (exprtypes.begin() + idx);
+
+ if (idx < (int)pronunces.size() )
+ pronunces.erase (pronunces.begin() + idx);
+
+ if (idx < (int)grades.size() )
+ grades.erase (grades.begin() + idx);
+
+ if (idx < (int)rev_grades.size() )
+ rev_grades.erase (rev_grades.begin() + idx);
+
+ if (idx < (int)qcounts.size() )
+ qcounts.erase (qcounts.begin() + idx);
+
+ if (idx < (int)rev_qcounts.size() )
+ rev_qcounts.erase (rev_qcounts.begin() + idx);
+
+ if (idx < (int)bcounts.size() )
+ bcounts.erase (bcounts.begin() + idx);
+
+ if (idx < (int)rev_bcounts.size() )
+ rev_bcounts.erase (rev_bcounts.begin() + idx);
+
+ if (idx < (int)qdates.size() )
+ qdates.erase (qdates.begin() + idx);
+
+ if (idx < (int)rev_qdates.size() )
+ rev_qdates.erase (rev_qdates.begin() + idx);
+}
+
+
+void KEduVocExpression::setTranslation (int idx, const QString & expr)
+{
+ if ( idx <= 0) return;
+
+ // extend translations with empty strings if necessary
+ if ((int)translations.size() < idx )
+ for (int i = translations.size(); i < idx; i++)
+ translations.push_back ("");
+
+// if (idx <= (int)translations.size())
+ translations[idx-1] = expr.stripWhiteSpace();
+}
+
+
+QString KEduVocExpression::gradeStr (int idx, bool rev_grade) const
+{
+ QString s;
+ s.setNum(getGrade(idx, rev_grade));
+ return s;
+}
+
+
+grade_t KEduVocExpression::getGrade (int idx, bool rev_grade) const
+{
+ if (rev_grade) {
+ if (idx >= (int)rev_grades.size() || idx < 1 ) {
+ return KV_NORM_GRADE;
+ }
+ else if (rev_grades[idx] > KV_MAX_GRADE) {
+ return KV_MAX_GRADE;
+ }
+
+ return rev_grades[idx];
+
+ }
+ else {
+ if (idx >= (int)grades.size() || idx < 1 ) {
+ return KV_NORM_GRADE;
+ }
+ else if (grades[idx] > KV_MAX_GRADE) {
+ return KV_MAX_GRADE;
+ }
+
+ return grades[idx];
+ }
+}
+
+
+void KEduVocExpression::setGrade (int idx, grade_t grade, bool rev_grade)
+{
+ if (idx < 1) return;
+
+ if (grade > KV_MAX_GRADE)
+ grade = KV_MAX_GRADE;
+ if (grade < KV_MIN_GRADE)
+ grade = KV_MIN_GRADE;
+
+ if (rev_grade) {
+ // extend rev grades with standard grade if necessary
+ if ((int)rev_grades.size() <= idx )
+ for (int i = rev_grades.size(); i <= idx; i++) {
+ rev_grades.push_back (KV_NORM_GRADE);
+ }
+ rev_grades[idx] = grade;
+ }
+ else {
+ // extend grades with standard grade if necessary
+ if ((int)grades.size() <= idx )
+ for (int i = grades.size(); i <= idx; i++) {
+ grades.push_back (KV_NORM_GRADE);
+ }
+ grades[idx] = grade;
+ }
+}
+
+
+void KEduVocExpression::incGrade (int idx, bool rev_grade)
+{
+ if (idx < 1) return;
+
+ if (rev_grade) {
+ // extend rev grades with standard grade if necessary
+ if ((int)rev_grades.size() <= idx )
+ for (int i = rev_grades.size(); i <= idx; i++) {
+ rev_grades.push_back (KV_NORM_GRADE);
+ }
+ if (rev_grades[idx] < KV_MAX_GRADE)
+ rev_grades[idx]++;
+ }
+ else {
+ // extend grades with standard grade if necessary
+ if ((int)grades.size() <= idx )
+ for (int i = grades.size(); i <= idx; i++) {
+ grades.push_back (KV_NORM_GRADE);
+ }
+ if (grades[idx] < KV_MAX_GRADE)
+ grades[idx]++;
+ }
+}
+
+
+void KEduVocExpression::decGrade (int idx, bool rev_grade)
+{
+ if (idx < 1) return;
+
+ if (rev_grade) {
+ // extend rev grades with standard grade if necessary
+ if ((int)rev_grades.size() <= idx )
+ for (int i = rev_grades.size(); i <= idx; i++) {
+ rev_grades.push_back (KV_NORM_GRADE);
+ }
+ if (rev_grades[idx] > KV_MIN_GRADE)
+ rev_grades[idx]--;
+ }
+ else {
+ // extend grades with standard grade if necessary
+ if ((int)grades.size() <= idx )
+ for (int i = grades.size(); i <= idx; i++) {
+ grades.push_back (KV_NORM_GRADE);
+ }
+ if (grades[idx] > KV_MIN_GRADE)
+ grades[idx]--;
+ }
+}
+
+
+count_t KEduVocExpression::getQueryCount (int idx, bool rev_count) const
+{
+ if (rev_count) {
+ if (idx >= (int)rev_qcounts.size() || idx < 1 ) {
+ return 0;
+ }
+
+ return rev_qcounts[idx];
+ }
+
+ if (idx >= (int)qcounts.size() || idx < 1 ) {
+ return 0;
+ }
+
+ return qcounts[idx];
+}
+
+
+void KEduVocExpression::setQueryCount (int idx, count_t count, bool rev_count)
+{
+ if (idx < 1) return;
+
+ if (rev_count) {
+ // extend rev counts with 0 if necessary
+ if ((int)rev_qcounts.size() <= idx )
+ for (int i = rev_qcounts.size(); i <= idx; i++) {
+ rev_qcounts.push_back (0);
+ }
+
+ rev_qcounts[idx] = count;
+
+ }
+ else {
+ // extend counts with 0 if necessary
+ if ((int)qcounts.size() <= idx )
+ for (int i = qcounts.size(); i <= idx; i++) {
+ qcounts.push_back (0);
+ }
+ qcounts[idx] = count;
+ }
+}
+
+
+count_t KEduVocExpression::getBadCount (int idx, bool rev_count) const
+{
+ if (rev_count) {
+ if (idx >= (int)rev_bcounts.size() || idx < 1 ) {
+ return 0;
+ }
+
+ return rev_bcounts[idx];
+ }
+
+ if (idx >= (int)bcounts.size() || idx < 1 ) {
+ return 0;
+ }
+
+ return bcounts[idx];
+}
+
+
+void KEduVocExpression::setBadCount (int idx, count_t count, bool rev_count)
+{
+ if (idx < 1) return;
+
+ if (rev_count) {
+ // extend rev counts with 0 if necessary
+ if ((int)rev_bcounts.size() <= idx )
+ for (int i = rev_bcounts.size(); i <= idx; i++) {
+ rev_bcounts.push_back (0);
+ }
+
+ rev_bcounts[idx] = count;
+
+ }
+ else {
+ // extend counts with 0 if necessary
+ if ((int)bcounts.size() <= idx )
+ for (int i = bcounts.size(); i <= idx; i++) {
+ bcounts.push_back (0);
+ }
+ bcounts[idx] = count;
+ }
+}
+
+
+time_t KEduVocExpression::getQueryDate (int idx, bool rev_date) const
+{
+ if (rev_date) {
+ if (idx >= (int)rev_qdates.size() || idx < 1 ) {
+ return 0;
+ }
+
+ return rev_qdates[idx];
+ }
+
+ if (idx >= (int)qdates.size() || idx < 1 ) {
+ return 0;
+ }
+
+ return qdates[idx];
+}
+
+
+void KEduVocExpression::setQueryDate (int idx, time_t date, bool rev_date)
+{
+ if (idx < 1) return;
+
+ if (rev_date) {
+ // extend rev dates with 0 if necessary
+ if ((int)rev_qdates.size() <= idx )
+ for (int i = rev_qdates.size(); i <= idx; i++) {
+ rev_qdates.push_back (0);
+ }
+
+ rev_qdates[idx] = date;
+
+ }
+ else {
+ // extend dates with 0 if necessary
+ if ((int)qdates.size() <= idx )
+ for (int i = qdates.size(); i <= idx; i++) {
+ qdates.push_back (0);
+ }
+ qdates[idx] = date;
+ }
+}
+
+
+bool KEduVocExpression::uniqueType () const
+{
+ bool unique = true;
+ QString type0 = getType(0);
+ for (int i = 1; i < numTranslations(); i++)
+ if (type0 != getType(i) )
+ unique = false;
+ return unique;
+}
+
+
+QString KEduVocExpression::getType (int idx) const
+{
+ if (idx >= (int)exprtypes.size() || idx < 0) {
+ return "";
+ }
+ else {
+ return exprtypes[idx];
+ }
+}
+
+
+int KEduVocExpression::getLesson () const
+{
+ return lesson;
+}
+
+void KEduVocExpression::incQueryCount (int index, bool rev_count)
+{
+ setQueryCount (index, getQueryCount(index, rev_count)+1, rev_count);
+}
+
+
+void KEduVocExpression::incBadCount (int index, bool rev_count)
+{
+ setBadCount (index, getBadCount(index, rev_count)+1, rev_count);
+}
+
+
+void KEduVocExpression::setOriginal ( const QString & expr)
+{
+ origin = expr;
+}
+
+
+QString KEduVocExpression::getOriginal () const
+{
+ return origin;
+}
+
+
+void KEduVocExpression::setLesson (int l)
+{
+ lesson = l;
+}
+
+
+void KEduVocExpression::setType (int idx, const QString &type)
+{
+ if ( idx < 0) return;
+
+ // extend types with empty strings if necessary
+ if ((int)exprtypes.size() <= idx )
+ for (int i = exprtypes.size(); i < idx+1; i++)
+ exprtypes.push_back ("");
+
+ exprtypes[idx] = type.stripWhiteSpace();
+}
+
diff --git a/kanagram/src/keduvocexpression.h b/kanagram/src/keduvocexpression.h
new file mode 100644
index 00000000..64b2233b
--- /dev/null
+++ b/kanagram/src/keduvocexpression.h
@@ -0,0 +1,456 @@
+/***************************************************************************
+ Vocabulary Expression for KDE Edu
+ -----------------------------------------------------------------------
+ copyright : (C) 1999-2001 Ewald Arnold
+ (C) 2001 The KDE-EDU team
+ (C) 2005 Peter Hedlung
+ email : peter.hedlund@kdemail.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 KEDUVOCEXPRESSION_H
+#define KEDUVOCEXPRESSION_H
+
+#define KV_MAX_GRADE 7
+#define KV_MIN_GRADE 0
+
+#define KV_NORM_GRADE 0 // not queried yet
+#define KV_NORM_COLOR Qt::black
+#define KV_NORM_TEXT I18N_NOOP("Not Queried Yet")
+
+#define KV_LEV1_GRADE 1
+#define KV_LEV1_TEXT I18N_NOOP("Level 1")
+
+#define KV_LEV2_GRADE 2
+#define KV_LEV2_TEXT I18N_NOOP("Level 2")
+
+#define KV_LEV3_GRADE 3
+#define KV_LEV3_TEXT I18N_NOOP("Level 3")
+
+#define KV_LEV4_GRADE 4
+#define KV_LEV4_TEXT I18N_NOOP("Level 4")
+
+#define KV_LEV5_GRADE 5
+#define KV_LEV5_TEXT I18N_NOOP("Level 5")
+
+#define KV_LEV6_GRADE 6
+#define KV_LEV6_TEXT I18N_NOOP("Level 6")
+
+#define KV_LEV7_GRADE 7
+#define KV_LEV7_TEXT I18N_NOOP("Level 7")
+
+#include <time.h>
+#include <vector>
+using namespace std;
+
+#include "grammarmanager.h"
+#include "multiplechoice.h"
+
+typedef signed char grade_t;
+typedef unsigned short count_t;
+
+/***************************************************************
+ * This class contains one expression as original or in one
+ * translations
+ **************************************************************/
+
+class KEduVocExpression
+{
+ public:
+
+ /** default constructor for an expression in different languages
+ */
+ ~KEduVocExpression ();
+
+ KEduVocExpression ();
+
+ KEduVocExpression (QString &s, QString separator, int lesson = 0);
+
+ /** Constructor for an expression in different languages
+ *
+ * @param expr expression
+ */
+ KEduVocExpression (QString &expr, int lesson = 0);
+
+ /** adds a new translation of this entry
+ * @param expr translation
+ * @param grade grade of knowledge of this translation
+ * @param rev_grade dito, in opposite direction
+ */
+ void addTranslation (QString expr, grade_t grade=KV_NORM_GRADE,
+ grade_t rev_grade=KV_NORM_GRADE);
+
+ /** removes translation
+ *
+ * @param index number of translation 1..x
+ */
+ void removeTranslation (int index);
+
+ /** returns index of lesson (0 = none)
+ */
+ int getLesson () const;
+
+ /** sets index of lesson (0 = none)
+ */
+ void setLesson (int l);
+
+ /** returns original expression of this entry
+ */
+ QString getOriginal () const;
+
+ /** sets original expression of this entry
+ */
+ void setOriginal (const QString & expr);
+
+ /** returns number of max. translations of all expressions
+ */
+ int numTranslations() const;
+
+ /** returns flag if entry is "selected" for queries
+ */
+ bool isInQuery() const {return inquery; }
+
+ /** set entry "selected"
+ */
+ void setInQuery(bool flag = true) { inquery = flag; }
+
+ /** returns flag if entry is activated for queries
+ */
+ bool isActive() const {return active; }
+
+ /** set entry active (enabled for queries)
+ */
+ void setActive(bool flag = true) { active = flag; }
+
+ /** returns translation of this expression
+ *
+ * @param index number of translation
+ * @result expression or "" if no translation available
+ */
+ QString getTranslation (int index) const;
+
+ /** sets translation of this expression
+ *
+ * @param index number of translation
+ * @param expr expression of this index
+ */
+ void setTranslation (int index, const QString & expr);
+
+ /** sets remark of this expression
+ *
+ * @param index index of expression
+ * @param expr remark of this index
+ */
+ void setPronunce (int index, const QString & expr);
+
+ /** returns pronunciation of this expression
+ *
+ * @param index index of expression
+ * @result pronunciation or "" if none available
+ */
+ QString getPronunce (int index) const;
+
+ /** returns remarks of this expression
+ *
+ * @param index index of expression
+ * @result remark or "" if no remark available
+ */
+ QString getRemark (int index) const;
+
+ /** sets remark of this expression
+ *
+ * @param index index of expression
+ * @param expr remark of this index
+ */
+ void setRemark (int index, const QString & expr);
+
+
+ /** sets false friend of this expression
+ *
+ * @param index index of expression
+ * @param expr false friend of this index
+ * @param rev_grade dito, in opposite direction
+ */
+ void setFauxAmi (int index, const QString & expr, bool rev_ami = false);
+
+
+ /** returns false friend of this expression
+ *
+ * @param index index of expression
+ * @param rev_grade dito, in opposite direction
+ * @result false friend or "" if no string available
+ */
+ QString getFauxAmi (int index, bool rev_ami = false) const;
+
+ /** sets synonym this expression
+ *
+ * @param index index of expression
+ * @param expr synonym of this index
+ */
+ void setSynonym (int index, const QString & expr);
+
+
+ /** returns synonym of this expression
+ *
+ * @param index index of expression
+ * @result synonym or "" if no string available
+ */
+ QString getSynonym (int index) const;
+
+ /** sets example this expression
+ *
+ * @param index index of expression
+ * @param expr example of this index
+ */
+ void setExample (int index, const QString & expr);
+
+
+ /** returns example of this expression
+ *
+ * @param index index of expression
+ * @result example or "" if no string available
+ */
+ QString getExample (int index) const;
+
+ /** sets usage label this expression
+ *
+ * @param index index of expression
+ * @param usage usage label of this index
+ */
+ void setUsageLabel (int index, const QString & usage);
+
+
+ /** returns usage label of this expression
+ *
+ * @param index index of expression
+ * @result usage or "" if no string available
+ */
+ QString getUsageLabel (int index) const;
+
+ /** sets paraphrase of this expression
+ *
+ * @param index index of expression
+ * @param usage paraphrase of this index
+ */
+ void setParaphrase (int index, const QString & usage);
+
+
+ /** returns paraphrase of this expression
+ *
+ * @param index index of expression
+ * @result paraphrase or "" if no string available
+ */
+ QString getParaphrase (int index) const;
+
+ /** sets antonym this expression
+ *
+ * @param index index of expression
+ * @param expr antonym of this index
+ */
+ void setAntonym (int index, const QString & expr);
+
+
+ /** returns antonym of this expression
+ *
+ * @param index index of expression
+ * @result antonym or "" if no string available
+ */
+ QString getAntonym (int index) const;
+
+ /** returns type of this expression
+ *
+ * @result type or "" if no type available
+ */
+ QString getType (int index) const;
+
+ /** all langs have same type ?
+ *
+ * @result true if all have same type
+ */
+ bool uniqueType () const;
+
+ /** sets type of this expression
+ *
+ * @param index index of type
+ * @param type type of this expression ("" = none)
+ */
+ void setType (int index, const QString &type);
+
+ /** returns grade of given translation as string
+ *
+ * @param index index of expression
+ * @param rev_grade dito, in opposite direction
+ * @result number of knowlegde: 0=known, x=numbers not knows
+ */
+ QString gradeStr (int index, bool rev_grade = false) const;
+
+ /** sets grade of given translation
+ *
+ * @param index index of translation
+ * @param grade number of knowlegde: 0=known, x=numbers not knows
+ */
+ void setGrade (int index, grade_t grade, bool rev_grade = false);
+
+ /** returns grade of given translation as int
+ *
+ * @param index index of translation
+ * @param rev_grade dito, in opposite direction
+ * @result number of knowlegde: 0=known, x=numbers not knows
+ */
+ grade_t getGrade (int index, bool rev_grade = false) const;
+
+ /** increments grade of given translation
+ *
+ * @param index index of translation
+ * @param rev_grade dito, in opposite direction
+ */
+ void incGrade (int index, bool rev_grade = false);
+
+ /** decrements grade of given translation
+ *
+ * @param index index of translation
+ * @param rev_grade dito, in opposite direction
+ */
+ void decGrade (int index, bool rev_grade = false);
+
+ /** returns last query date of given translation as int
+ *
+ * @param index index of translation
+ * @param rev_date dito, in opposite direction
+ */
+ time_t getQueryDate (int index, bool rev_date = false) const;
+
+ /** set last query date of given translation as int
+ *
+ * @param index index of translation
+ * @param rev_date dito, in opposite direction
+ */
+ void setQueryDate (int index, time_t date, bool rev_date = false);
+
+ /** returns conjugations if available
+ *
+ * @param index index of translation
+ */
+ Conjugation getConjugation(int index) const;
+
+ /** sets conjugations
+ *
+ * @param index index of translation
+ * @param con conjugation block
+ */
+ void setConjugation(int index, const Conjugation &con);
+
+ /** returns comparison if available
+ *
+ * @param index index of translation
+ */
+ Comparison getComparison(int index) const;
+
+ /** sets comparison
+ *
+ * @param index index of translation
+ * @param con comparison block
+ */
+ void setComparison(int index, const Comparison &comp);
+
+ /** returns multiple choice if available
+ *
+ * @param index index of multiple choice
+ */
+ MultipleChoice getMultipleChoice(int index) const;
+
+ /** sets multiple choice
+ *
+ * @param index index of translation
+ * @param con multiple choice block
+ */
+ void setMultipleChoice(int index, const MultipleChoice &mc);
+
+ /** returns query count of given translation as int
+ *
+ * @param index index of translation
+ * @param rev_count dito, in opposite direction
+ */
+ count_t getQueryCount (int index, bool rev_count = false) const;
+
+ /** set query count of given translation as int
+ *
+ * @param index index of translation
+ * @param rev_count dito, in opposite direction
+ */
+ void setQueryCount (int index, count_t count, bool rev_count = false);
+
+ /** returns bad query count of given translation as int
+ *
+ * @param index index of translation
+ * @param rev_count dito, in opposite direction
+ */
+ count_t getBadCount (int index, bool rev_count = false) const;
+
+ /** set bad query count of given translation as int
+ *
+ * @param index index of translation
+ * @param rev_count dito, in opposite direction
+ */
+ void setBadCount (int index, count_t count, bool rev_count = false);
+
+ /** increment bad query count of given translation by 1
+ *
+ * @param index index of translation
+ * @param rev_count dito, in opposite direction
+ */
+ void incBadCount (int index, bool rev_count = false);
+
+ /** increment query count of given translation by 1
+ *
+ * @param index index of translation
+ * @param rev_count dito, in opposite direction
+ */
+ void incQueryCount (int index, bool rev_count = false);
+
+ protected:
+
+ void Init();
+
+ private:
+ QString origin;
+
+ // all these vectors must be deleted in removeTranslation()
+ vector<QString> exprtypes;
+ vector<QString> translations;
+ vector<QString> remarks;
+ vector<QString> usageLabels;
+ vector<QString> paraphrases;
+ vector<QString> fauxAmi;
+ vector<QString> rev_fauxAmi;
+ vector<QString> synonym;
+ vector<QString> example;
+ vector<QString> antonym;
+ vector<QString> pronunces;
+ vector<grade_t> grades;
+ vector<grade_t> rev_grades;
+ vector<count_t> qcounts;
+ vector<count_t> rev_qcounts;
+ vector<count_t> bcounts;
+ vector<count_t> rev_bcounts;
+ vector<time_t> qdates;
+ vector<time_t> rev_qdates;
+ vector<Conjugation> conjugations;
+ vector<Comparison> comparisons;
+ vector<MultipleChoice> mcs;
+
+ int lesson;
+ bool inquery;
+ bool active;
+};
+
+#endif // KEduVocExpression_H
+
diff --git a/kanagram/src/keduvockvtmlreader.cpp b/kanagram/src/keduvockvtmlreader.cpp
new file mode 100644
index 00000000..13e6f53a
--- /dev/null
+++ b/kanagram/src/keduvockvtmlreader.cpp
@@ -0,0 +1,1695 @@
+/***************************************************************************
+ read a KEduVocDocument from a KVTML file
+ -----------------------------------------------------------------------
+ copyright : (C) 1999-2001 Ewald Arnold
+ (C) 2001 The KDE-EDU team
+ (C) 2005 Eric Pignet
+ email : eric at erixpage.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. *
+ * *
+ ***************************************************************************/
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+#include <qdom.h>
+#include <qtextstream.h>
+
+#include "keduvockvtmlreader.h"
+#include "keduvocdocument.h"
+
+KEduVocKvtmlReader::KEduVocKvtmlReader(QFile *file)
+{
+ // the file must be already open
+ m_inputFile = file;
+}
+
+KEduVocKvtmlReader::~KEduVocKvtmlReader()
+{
+}
+
+
+bool KEduVocKvtmlReader::readLesson(QDomElement &domElementParent)
+{
+ QString s;
+ m_doc->lesson_descr.clear();
+
+ //-------------------------------------------------------------------------
+ // Attributes
+ //-------------------------------------------------------------------------
+
+ QDomAttr domAttrWidth = domElementParent.attributeNode(KV_SIZEHINT);
+ if (!domAttrWidth.isNull())
+ m_doc->setSizeHint(-1, domAttrWidth.value().toInt());
+
+ //-------------------------------------------------------------------------
+ // Children
+ //-------------------------------------------------------------------------
+
+ QDomElement domElementChild = domElementParent.firstChild().toElement();
+
+ while (!domElementChild.isNull())
+ {
+ if (domElementChild.tagName() == KV_LESS_DESC)
+ {
+ //-----------
+ // Attributes
+
+ int no = 0;
+ bool isCurr = false;
+
+ QDomAttr domAttrNo = domElementChild.attributeNode(KV_LESS_NO);
+ if (!domAttrNo.isNull())
+ no = domAttrNo.value().toInt();
+
+ QDomAttr domAttrCurrent = domElementChild.attributeNode(KV_LESS_CURR);
+ if (!domAttrCurrent.isNull())
+ isCurr = domAttrCurrent.value().toInt() != 0;
+
+ if (isCurr && no != 0)
+ m_doc->setCurrentLesson(no);
+
+ QDomAttr domAttrQuery = domElementChild.attributeNode(KV_LESS_QUERY);
+ if (!domAttrQuery.isNull())
+ m_doc->lessons_in_query.push_back(domAttrQuery.value().toInt() != 0);
+ else
+ m_doc->lessons_in_query.push_back(false);
+
+ //-----
+ // Text
+
+ s = domElementChild.text();
+ if (s.isNull())
+ s = "";
+ m_doc->lesson_descr.push_back(s);
+ }
+ else
+ {
+ domErrorUnknownElement(domElementChild.tagName());
+ return false;
+ }
+
+ domElementChild = domElementChild.nextSibling().toElement();
+ }
+
+ return true;
+}
+
+
+bool KEduVocKvtmlReader::readArticle(QDomElement &domElementParent)
+/*
+ <article>
+ <e l="de"> lang determines also lang order in entries !!
+ <fi>eine</fi> which must NOT differ
+ <fd>die</fd>
+ <mi>ein</mi>
+ <md>der</md>
+ <ni>ein</ni>
+ <nd>das</nd>
+ </e>
+ </article>
+*/
+{
+ bool endOfGroup = false;
+ bool inEntry = false;
+ int count = 0;
+ QString s;
+ m_doc->articles.clear();
+
+ QDomElement domElementEntry = domElementParent.firstChild().toElement();
+
+ while (!domElementEntry.isNull())
+ {
+ if (domElementEntry.tagName() != KV_ART_ENTRY)
+ {
+ domError(i18n("expected tag <%1>").arg(KV_ART_ENTRY));
+ return false;
+ }
+
+ //----------
+ // Attribute
+
+ QString lang;
+ QDomAttr domAttrLang = domElementEntry.attributeNode(KV_LANG);
+
+ if ((int)m_doc->langs.size() <= count)
+ {
+ // first entry
+ if (!domAttrLang.isNull()) // no definition in first entry
+ lang = domAttrLang.value();
+ else
+ lang = "original";
+ m_doc->langs.push_back(lang);
+ }
+ else
+ {
+ if (!domAttrLang.isNull() && domAttrLang.value() != m_doc->langs[count])
+ {
+ // different originals ?
+ domError(i18n("ambiguous definition of language code"));
+ return false;
+ }
+ }
+
+ //---------
+ // Children
+
+ QString fem_def = "";
+ QString mal_def = "";
+ QString nat_def = "";
+ QString fem_indef = "";
+ QString mal_indef = "";
+ QString nat_indef = "";
+
+ QDomElement domElementEntryChild = domElementEntry.firstChild().toElement();
+ while (!domElementEntryChild.isNull())
+ {
+ if (domElementEntryChild.tagName() == KV_ART_FD)
+ {
+ fem_def = domElementEntryChild.text();
+ if (fem_def.isNull())
+ fem_def = "";
+ }
+ else if (domElementEntryChild.tagName() == KV_ART_FI)
+ {
+ fem_indef = domElementEntryChild.text();
+ if (fem_indef.isNull())
+ fem_indef = "";
+ }
+ else if (domElementEntryChild.tagName() == KV_ART_MD)
+ {
+ mal_def = domElementEntryChild.text();
+ if (mal_def.isNull())
+ mal_def = "";
+ }
+ else if (domElementEntryChild.tagName() == KV_ART_MI)
+ {
+ mal_indef = domElementEntryChild.text();
+ if (mal_indef.isNull())
+ mal_indef = "";
+ }
+ else if (domElementEntryChild.tagName() == KV_ART_ND)
+ {
+ nat_def = domElementEntryChild.text();
+ if (nat_def.isNull())
+ nat_def = "";
+ }
+ else if (domElementEntryChild.tagName() == KV_ART_NI)
+ {
+ nat_indef = domElementEntryChild.text();
+ if (nat_indef.isNull())
+ nat_indef = "";
+ }
+ else
+ {
+ domErrorUnknownElement(domElementEntryChild.tagName());
+ return false;
+ }
+
+ domElementEntryChild = domElementEntryChild.nextSibling().toElement();
+ }
+
+ m_doc->articles.push_back(Article( fem_def, fem_indef,
+ mal_def, mal_indef,
+ nat_def, nat_indef));
+
+ domElementEntry = domElementEntry.nextSibling().toElement();
+ count++;
+ }
+
+ return true;
+}
+
+
+bool KEduVocKvtmlReader::readConjug(QDomElement &domElementParent,
+ vector<Conjugation> &curr_conjug,
+ const QString &entry_tag)
+/*
+ <conjugation> used in header for definiton of "prefix"
+ <e l="de"> lang determines also lang order in entries !!
+ <s1>I</s1> which must NOT differ
+ <s2>you<2>
+ <s3f>he</s3f>
+ <s3m>she</s3m>
+ <s3n>it</s3n>
+ <p1>we</p1>
+ <p2>you</p2>
+ <p3f>they</p3f>
+ <p3m>they</p3m>
+ <p3n>they</p3n>
+ </e>
+ </conjugation>
+
+ <conjugation> and in entry for definition of tenses of (irreg.) verbs
+ <t n="sipa">
+ <s1>go</s1>
+ <s2>go</s2>
+ <s3f>goes</s3f>
+ <s3m>goes</s3m>
+ <s3n>goes</s3n>
+ <p1>go</p1>
+ <p2>go</p2>
+ <p3f>go</p3f>
+ <p3m>go</p3m>
+ <p3n>go</p3n>
+ </t>
+ </conjugation>
+*/
+{
+ QString s;
+
+ curr_conjug.clear();
+
+ bool p3_common,
+ s3_common;
+ QString pers1_sing,
+ pers2_sing,
+ pers3_m_sing,
+ pers3_f_sing,
+ pers3_n_sing,
+ pers1_plur,
+ pers2_plur,
+ pers3_m_plur,
+ pers3_f_plur,
+ pers3_n_plur;
+
+ QString lang;
+ QString type;
+ int count = 0;
+ curr_conjug.push_back(Conjugation());
+
+ QDomElement domElementConjugChild = domElementParent.firstChild().toElement();
+ while (!domElementConjugChild.isNull())
+ {
+ if (domElementConjugChild.tagName() == KV_CON_ENTRY)
+ {
+ type = CONJ_PREFIX;
+
+ //----------
+ // Attribute
+
+ QString lang;
+ QDomAttr domAttrLang = domElementConjugChild.attributeNode(KV_LANG);
+
+ if ((int)m_doc->langs.size() <= count)
+ {
+ // first entry
+ if (!domAttrLang.isNull()) // no definition in first entry
+ lang = domAttrLang.value();
+ else
+ lang = "original";
+ m_doc->langs.push_back(lang);
+ }
+ else
+ {
+ if (!domAttrLang.isNull() && domAttrLang.value() != m_doc->langs[count])
+ {
+ // different originals ?
+ domError(i18n("ambiguous definition of language code"));
+ return false;
+ }
+ }
+ }
+ else if (domElementConjugChild.tagName() == KV_CON_TYPE)
+ {
+ //----------
+ // Attribute
+
+ QDomAttr domAttrLang = domElementConjugChild.attributeNode(KV_CON_NAME);
+ type = domAttrLang.value();
+ if (type.isNull())
+ type = "";
+
+ if (type.length() != 0 && type.left(1) == UL_USER_TENSE)
+ {
+ int num = QMIN(type.mid (1, 40).toInt(), 1000); // paranoia check
+ if( num > (int) m_doc->tense_descr.size() )
+ {
+ // description missing ?
+ QString s;
+ for (int i = m_doc->tense_descr.size(); i < num; i++)
+ {
+ s.setNum (i+1);
+ s.insert (0, "#"); // invent descr according to number
+ m_doc->tense_descr.push_back(s);
+ }
+ }
+ }
+ }
+
+ pers1_sing = "";
+ pers2_sing = "";
+ pers3_m_sing = "";
+ pers3_f_sing = "";
+ pers3_n_sing = "";
+ pers1_plur = "";
+ pers2_plur = "";
+ pers3_m_plur = "";
+ pers3_f_plur = "";
+ pers3_n_plur = "";
+ p3_common = false;
+ s3_common = false;
+
+ QDomElement domElementConjugGrandChild = domElementConjugChild.firstChild().toElement();
+ while (!domElementConjugGrandChild.isNull())
+ {
+ if (domElementConjugGrandChild.tagName() == KV_CON_P1S)
+ {
+ pers1_sing = domElementConjugGrandChild.text();
+ if (pers1_sing.isNull())
+ pers1_sing = "";
+ }
+ else if (domElementConjugGrandChild.tagName() == KV_CON_P2S)
+ {
+ pers2_sing = domElementConjugGrandChild.text();
+ if (pers2_sing.isNull())
+ pers2_sing = "";
+ }
+ else if (domElementConjugGrandChild.tagName() == KV_CON_P3SF)
+ {
+ QDomAttr domAttrCommon = domElementConjugGrandChild.attributeNode(KV_CONJ_COMMON);
+ if (!domAttrCommon.isNull())
+ s3_common = domAttrCommon.value().toInt(); // returns 0 if the conversion fails
+
+ pers3_f_sing = domElementConjugGrandChild.text();
+ if (pers3_f_sing.isNull())
+ pers3_f_sing = "";
+ }
+ else if (domElementConjugGrandChild.tagName() == KV_CON_P3SM)
+ {
+ pers3_m_sing = domElementConjugGrandChild.text();
+ if (pers3_m_sing.isNull())
+ pers3_m_sing = "";
+ }
+ else if (domElementConjugGrandChild.tagName() == KV_CON_P3SN)
+ {
+ pers3_n_sing = domElementConjugGrandChild.text();
+ if (pers3_n_sing.isNull())
+ pers3_n_sing = "";
+ }
+ else if (domElementConjugGrandChild.tagName() == KV_CON_P1P)
+ {
+ pers1_plur = domElementConjugGrandChild.text();
+ if (pers1_plur.isNull())
+ pers1_plur = "";
+ }
+ else if (domElementConjugGrandChild.tagName() == KV_CON_P2P)
+ {
+ pers2_plur = domElementConjugGrandChild.text();
+ if (pers2_plur.isNull())
+ pers2_plur = "";
+ }
+ else if (domElementConjugGrandChild.tagName() == KV_CON_P3PF)
+ {
+ QDomAttr domAttrCommon = domElementConjugGrandChild.attributeNode(KV_CONJ_COMMON);
+ if (!domAttrCommon.isNull())
+ p3_common = domAttrCommon.value().toInt(); // returns 0 if the conversion fails
+
+ pers3_f_plur = domElementConjugGrandChild.text();
+ if (pers3_f_plur.isNull())
+ pers3_f_plur = "";
+ }
+ else if (domElementConjugGrandChild.tagName() == KV_CON_P3PM)
+ {
+ pers3_m_plur = domElementConjugGrandChild.text();
+ if (pers3_m_plur.isNull())
+ pers3_m_plur = "";
+ }
+ else if (domElementConjugGrandChild.tagName() == KV_CON_P3PN)
+ {
+ pers3_n_plur = domElementConjugGrandChild.text();
+ if (pers3_n_plur.isNull())
+ pers3_n_plur = "";
+ }
+ else
+ {
+ domErrorUnknownElement(domElementConjugGrandChild.tagName());
+ return false;
+ }
+
+ domElementConjugGrandChild = domElementConjugGrandChild.nextSibling().toElement();
+ }
+
+ if (domElementConjugChild.tagName() == KV_CON_ENTRY)
+ while (count+1 > (int) curr_conjug.size() )
+ curr_conjug.push_back(Conjugation());
+
+ curr_conjug[count].setPers3SingularCommon(type, s3_common);
+ curr_conjug[count].setPers3PluralCommon(type, p3_common);
+ curr_conjug[count].setPers1Singular(type, pers1_sing);
+ curr_conjug[count].setPers2Singular(type, pers2_sing);
+ curr_conjug[count].setPers3FemaleSingular(type, pers3_f_sing);
+ curr_conjug[count].setPers3MaleSingular(type, pers3_m_sing);
+ curr_conjug[count].setPers3NaturalSingular(type, pers3_n_sing);
+ curr_conjug[count].setPers1Plural(type, pers1_plur);
+ curr_conjug[count].setPers2Plural(type, pers2_plur);
+ curr_conjug[count].setPers3FemalePlural(type, pers3_f_plur);
+ curr_conjug[count].setPers3MalePlural(type, pers3_m_plur);
+ curr_conjug[count].setPers3NaturalPlural(type, pers3_n_plur);
+
+ if (domElementConjugChild.tagName() == KV_CON_ENTRY)
+ count++;
+
+ domElementConjugChild = domElementConjugChild.nextSibling().toElement();
+ }
+
+ return true;
+}
+
+
+bool KEduVocKvtmlReader::readOptions(QDomElement &domElementParent)
+{
+ QDomElement domElementSort = domElementParent.firstChild().toElement();
+ while (!domElementSort.isNull())
+ {
+ if (domElementSort.tagName() == KV_OPT_SORT)
+ {
+ m_doc->sort_allowed = true;
+ QDomAttr domAttrOn = domElementSort.attributeNode(KV_BOOL_FLAG);
+ if (!domAttrOn.isNull())
+ {
+ bool ok = true;
+ m_doc->sort_allowed = domAttrOn.value().toInt(&ok); // returns 0 if the conversion fails
+ if (!ok)
+ m_doc->sort_allowed = true;
+ }
+ }
+
+ domElementSort = domElementSort.nextSibling().toElement();
+ }
+
+ return true;
+}
+
+
+bool KEduVocKvtmlReader::readType(QDomElement &domElementParent)
+{
+ QString s;
+ m_doc->type_descr.clear();
+
+ QDomElement domElementDesc = domElementParent.firstChild().toElement();
+
+ while (!domElementDesc.isNull())
+ {
+ if (domElementDesc.tagName() == KV_TYPE_DESC)
+ {
+ //-----------
+ // Attributes
+
+ int no = 0;
+ bool isCurr = false;
+
+ QDomAttr domAttrNo = domElementDesc.attributeNode(KV_TYPE_NO);
+ if (!domAttrNo.isNull())
+ no = domAttrNo.value().toInt();
+
+ // TODO use 'no' to sort types
+ // but 'no' seems useless, since types are already ordered by their position in the XML doc
+
+ s = domElementDesc.text();
+ if (s.isNull())
+ s = "";
+
+ m_doc->type_descr.push_back (s);
+ }
+ else
+ {
+ domErrorUnknownElement(domElementDesc.tagName());
+ return false;
+ }
+
+ domElementDesc = domElementDesc.nextSibling().toElement();
+ }
+
+ return true;
+}
+
+
+bool KEduVocKvtmlReader::readTense(QDomElement &domElementParent)
+{
+ QString s;
+ m_doc->tense_descr.clear();
+
+ QDomElement domElementDesc = domElementParent.firstChild().toElement();
+
+ while (!domElementDesc.isNull())
+ {
+ if (domElementDesc.tagName() == KV_TENSE_DESC)
+ {
+ //-----------
+ // Attributes
+
+ int no = 0;
+ bool isCurr = false;
+
+ QDomAttr domAttrNo = domElementDesc.attributeNode(KV_TENSE_NO);
+ if (!domAttrNo.isNull())
+ no = domAttrNo.value().toInt();
+
+ // TODO use 'no' to sort tenses
+ // but 'no' seems useless, since tenses are already ordered by their position in the XML doc
+
+ s = domElementDesc.text();
+ if (s.isNull())
+ s = "";
+
+ m_doc->tense_descr.push_back (s);
+ }
+ else
+ {
+ domErrorUnknownElement(domElementDesc.tagName());
+ return false;
+ }
+
+ domElementDesc = domElementDesc.nextSibling().toElement();
+ }
+
+ return true;
+}
+
+
+bool KEduVocKvtmlReader::readUsage(QDomElement &domElementParent)
+{
+ QString s;
+ m_doc->usage_descr.clear();
+
+ QDomElement domElementDesc = domElementParent.firstChild().toElement();
+
+ while (!domElementDesc.isNull())
+ {
+ if (domElementDesc.tagName() == KV_USAGE_DESC)
+ {
+ //-----------
+ // Attributes
+
+ int no = 0;
+ bool isCurr = false;
+
+ QDomAttr domAttrNo = domElementDesc.attributeNode(KV_USAGE_NO);
+ if (!domAttrNo.isNull())
+ no = domAttrNo.value().toInt();
+
+ // TODO use 'no' to sort usages
+ // but 'no' seems useless, since usages are already ordered by their position in the XML doc
+
+ s = domElementDesc.text();
+ if (s.isNull())
+ s = "";
+
+ m_doc->usage_descr.push_back (s);
+ }
+ else
+ {
+ domErrorUnknownElement(domElementDesc.tagName());
+ return false;
+ }
+
+ domElementDesc = domElementDesc.nextSibling().toElement();
+ }
+
+ return true;
+}
+
+
+bool KEduVocKvtmlReader::readComparison(QDomElement &domElementParent,
+ Comparison &comp)
+/*
+ <comparison>
+ <l1>good</l1>
+ <l2>better</l2>
+ <l3>best</l3>
+ </comparison>
+*/
+{
+ QString s;
+ comp.clear();
+
+ QDomElement domElementComparisonChild = domElementParent.firstChild().toElement();
+ while (!domElementComparisonChild.isNull())
+ {
+ if (domElementComparisonChild.tagName() == KV_COMP_L1)
+ {
+ s = domElementComparisonChild.text();
+ if (s.isNull())
+ s = "";
+ comp.setL1(s);
+ }
+
+ else if (domElementComparisonChild.tagName() == KV_COMP_L2)
+ {
+ s = domElementComparisonChild.text();
+ if (s.isNull())
+ s = "";
+ comp.setL2(s);
+ }
+
+ else if (domElementComparisonChild.tagName() == KV_COMP_L3)
+ {
+ s = domElementComparisonChild.text();
+ if (s.isNull())
+ s = "";
+ comp.setL3(s);
+ }
+
+ else
+ {
+ domErrorUnknownElement(domElementComparisonChild.tagName());
+ return false;
+ }
+
+ domElementComparisonChild = domElementComparisonChild.nextSibling().toElement();
+ }
+
+ return true;
+}
+
+
+bool KEduVocKvtmlReader::readMultipleChoice(QDomElement &domElementParent,
+ MultipleChoice &mc)
+/*
+ <multiplechoice>
+ <mc1>good</mc1>
+ <mc2>better</mc2>
+ <mc3>best</mc3>
+ <mc4>best 2</mc4>
+ <mc5>best 3</mc5>
+ </multiplechoice>
+*/
+
+{
+ QString s;
+ mc.clear();
+
+ QDomElement domElementChild = domElementParent.firstChild().toElement();
+ while (!domElementChild.isNull())
+ {
+ if (domElementChild.tagName() == KV_MC_1)
+ {
+ s = domElementChild.text();
+ if (s.isNull())
+ s = "";
+ mc.setMC1(s);
+ }
+
+ else if (domElementChild.tagName() == KV_MC_2)
+ {
+ s = domElementChild.text();
+ if (s.isNull())
+ s = "";
+ mc.setMC2(s);
+ }
+
+ else if (domElementChild.tagName() == KV_MC_3)
+ {
+ s = domElementChild.text();
+ if (s.isNull())
+ s = "";
+ mc.setMC3(s);
+ }
+
+ else if (domElementChild.tagName() == KV_MC_4)
+ {
+ s = domElementChild.text();
+ if (s.isNull())
+ s = "";
+ mc.setMC4(s);
+ }
+
+ else if (domElementChild.tagName() == KV_MC_5)
+ {
+ s = domElementChild.text();
+ if (s.isNull())
+ s = "";
+ mc.setMC5(s);
+ }
+
+ else
+ {
+ domErrorUnknownElement(domElementChild.tagName());
+ return false;
+ }
+
+ domElementChild = domElementChild.nextSibling().toElement();
+ }
+
+ mc.normalize();
+ return true;
+}
+
+
+bool KEduVocKvtmlReader::readExpressionChildAttributes( QDomElement &domElementExpressionChild,
+ QString &lang,
+ grade_t &grade, grade_t &rev_grade,
+ int &count, int &rev_count,
+ time_t &date, time_t &rev_date,
+ QString &remark,
+ int &bcount, int &rev_bcount,
+ QString &query_id,
+ QString &pronunce,
+ int &width,
+ QString &type,
+ QString &faux_ami_f,
+ QString &faux_ami_t,
+ QString &synonym,
+ QString &example,
+ QString &antonym,
+ QString &usage,
+ QString &paraphrase)
+{
+ int pos;
+
+ lang = "";
+ QDomAttr domAttrLang = domElementExpressionChild.attributeNode(KV_LANG);
+ if (!domAttrLang.isNull())
+ lang = domAttrLang.value();
+
+ width = -1;
+ QDomAttr domAttrWidth = domElementExpressionChild.attributeNode(KV_SIZEHINT);
+ if (!domAttrWidth.isNull())
+ width = domAttrWidth.value().toInt();
+
+ grade = KV_NORM_GRADE;
+ rev_grade = KV_NORM_GRADE;
+ QDomAttr domAttrGrade = domElementExpressionChild.attributeNode(KV_LANG);
+ if (!domAttrGrade.isNull())
+ {
+ QString s = domAttrGrade.value();
+ if ((pos = s.find(';')) >= 1)
+ {
+ grade = s.left(pos).toInt();
+ rev_grade = s.mid(pos+1, s.length()).toInt();
+ }
+ else
+ grade = s.toInt();
+ }
+
+ count = 0;
+ rev_count = 0;
+ QDomAttr domAttrCount = domElementExpressionChild.attributeNode(KV_COUNT);
+ if (!domAttrCount.isNull())
+ {
+ QString s = domAttrCount.value();
+ if ((pos = s.find(';')) >= 1)
+ {
+ count = s.left(pos).toInt();
+ rev_count = s.mid(pos+1, s.length()).toInt();
+ }
+ else
+ count = s.toInt();
+ }
+
+ bcount = 0;
+ rev_bcount = 0;
+ QDomAttr domAttrBad = domElementExpressionChild.attributeNode(KV_BAD);
+ if (!domAttrBad.isNull())
+ {
+ QString s = domAttrBad.value();
+ if ((pos = s.find(';')) >= 1)
+ {
+ bcount = s.left(pos).toInt();
+ rev_bcount = s.mid(pos+1, s.length()).toInt();
+ }
+ else
+ bcount = s.toInt();
+ }
+
+ date = 0;
+ rev_date = 0;
+ QDomAttr domAttrDate = domElementExpressionChild.attributeNode(KV_DATE);
+ if (!domAttrDate.isNull())
+ {
+ QString s = domAttrDate.value();
+ if ((pos = s.find(';')) >= 1)
+ {
+ date = s.left(pos).toInt();
+ rev_date = s.mid(pos+1, s.length()).toInt();
+ }
+ else
+ date = s.toInt();
+ }
+
+ QDomAttr domAttrDate2 = domElementExpressionChild.attributeNode(KV_DATE2);
+ if (!domAttrDate2.isNull())
+ {
+ QString s = domAttrDate2.value();
+ if ((pos = s.find(';')) >= 1)
+ {
+ date = m_doc->decompressDate(s.left(pos));
+ rev_date = m_doc->decompressDate(s.mid(pos+1, s.length()));
+ }
+ else
+ date = m_doc->decompressDate(s);
+ }
+
+ remark = "";
+ QDomAttr domAttrRemark = domElementExpressionChild.attributeNode(KV_REMARK);
+ if (!domAttrRemark.isNull())
+ remark = domAttrRemark.value();
+
+ faux_ami_f = "";
+ QDomAttr domAttrFauxAmiF = domElementExpressionChild.attributeNode(KV_FAUX_AMI_F);
+ if (!domAttrFauxAmiF.isNull())
+ faux_ami_f = domAttrFauxAmiF.value();
+
+ faux_ami_t = "";
+ QDomAttr domAttrFauxAmiT = domElementExpressionChild.attributeNode(KV_FAUX_AMI_T);
+ if (!domAttrFauxAmiT.isNull())
+ faux_ami_t = domAttrFauxAmiT.value();
+
+ synonym = "";
+ QDomAttr domAttrSynonym = domElementExpressionChild.attributeNode(KV_SYNONYM);
+ if (!domAttrSynonym.isNull())
+ synonym = domAttrSynonym.value();
+
+ example = "";
+ QDomAttr domAttrExample = domElementExpressionChild.attributeNode(KV_EXAMPLE);
+ if (!domAttrExample.isNull())
+ example = domAttrExample.value();
+
+ usage = "";
+ QDomAttr domAttrUsage = domElementExpressionChild.attributeNode(KV_USAGE);
+ if (!domAttrUsage.isNull())
+ {
+ usage = domAttrUsage.value();
+ if (usage.length() != 0 && usage.left(1) == UL_USER_USAGE)
+ {
+ int num = QMIN(usage.mid (1, 40).toInt(), 1000); // paranioa check
+ if( num > (int) m_doc->usage_descr.size() )
+ {
+ // description missing ?
+ QString s;
+ for (int i = m_doc->usage_descr.size(); i < num; i++)
+ {
+ s.setNum (i+1);
+ s.insert (0, "#"); // invent descr according to number
+ m_doc->usage_descr.push_back (s);
+ }
+ }
+ }
+ }
+
+ paraphrase = "";
+ QDomAttr domAttrParaphrase = domElementExpressionChild.attributeNode(KV_PARAPHRASE);
+ if (!domAttrParaphrase.isNull())
+ paraphrase = domAttrParaphrase.value();
+
+ antonym = "";
+ QDomAttr domAttrAntonym = domElementExpressionChild.attributeNode(KV_ANTONYM);
+ if (!domAttrAntonym.isNull())
+ antonym = domAttrAntonym.value();
+
+ QDomAttr domAttrExprType = domElementExpressionChild.attributeNode(KV_EXPRTYPE);
+ if (!domAttrExprType.isNull())
+ {
+ type = domAttrExprType.value();
+ if (type == "1")
+ type = QM_VERB;
+ else if (type == "2") // convert from pre-0.5 versions
+ type = QM_NOUN;
+ else if (type == "3")
+ type = QM_NAME;
+
+ if (type.length() != 0 && type.left(1) == QM_USER_TYPE)
+ {
+ int num = QMIN(type.mid (1, 40).toInt(), 1000); // paranoia check
+ if( num > (int) m_doc->type_descr.size() )
+ {
+ // description missing ?
+ QString s;
+ for (int i = m_doc->type_descr.size(); i < num; i++)
+ {
+ s.setNum (i+1);
+ s.insert (0, "#"); // invent descr according to number
+ m_doc->type_descr.push_back (s);
+ }
+ }
+ }
+ }
+
+ pronunce = "";
+ QDomAttr domAttrPronunce = domElementExpressionChild.attributeNode(KV_PRONUNCE);
+ if (!domAttrPronunce.isNull())
+ pronunce = domAttrPronunce.value();
+
+ query_id = "";
+ QDomAttr domAttrQuery = domElementExpressionChild.attributeNode(KV_QUERY);
+ if (!domAttrQuery.isNull())
+ query_id = domAttrQuery.value();
+
+ return true;
+}
+
+
+bool KEduVocKvtmlReader::readExpression(QDomElement &domElementParent)
+{
+ grade_t grade,
+ r_grade;
+ int qcount,
+ r_qcount;
+ int bcount,
+ r_bcount;
+ QString remark;
+ QString pronunce;
+ time_t qdate,
+ r_qdate;
+ bool inquery;
+ bool active;
+ QString lang;
+ QString textstr;
+ QString exprtype;
+ bool org_found = false;
+ QString q_org,
+ q_trans;
+ QString query_id;
+ KEduVocExpression expr;
+ int lesson = 0;
+ int width;
+ QString type;
+ QString faux_ami_f;
+ QString faux_ami_t;
+ QString synonym;
+ QString example;
+ QString antonym;
+ QString usage;
+ QString paraphrase;
+ vector<Conjugation> conjug;
+ Comparison comparison;
+ MultipleChoice mc;
+
+ //-------------------------------------------------------------------------
+ // Attributes
+ //-------------------------------------------------------------------------
+
+ QDomAttr domAttrMember = domElementParent.attributeNode(KV_LESS_MEMBER);
+ if (!domAttrMember.isNull())
+ lesson = domAttrMember.value().toInt();
+
+ QDomAttr domAttrSelected = domElementParent.attributeNode(KV_SELECTED);
+ if (!domAttrSelected.isNull())
+ inquery = domAttrSelected.value().toInt();
+ else
+ inquery = false;
+
+ QDomAttr domAttrInactive = domElementParent.attributeNode(KV_INACTIVE);
+ if (!domAttrInactive.isNull())
+ active = !domAttrInactive.value().toInt();
+ else
+ active = false;
+
+ QDomAttr domAttrType = domElementParent.attributeNode(KV_EXPRTYPE);
+ if (!domAttrType.isNull())
+ {
+ exprtype = !domAttrType.value().toInt();
+ if (exprtype == "1")
+ exprtype = QM_VERB;
+ else if (exprtype == "2") // convert from pre-0.5 versions
+ exprtype = QM_NOUN;
+ else if (exprtype == "3")
+ exprtype = QM_NAME;
+
+ if (exprtype.length() != 0 && exprtype.left(1) == QM_USER_TYPE)
+ {
+ int num = QMIN(exprtype.mid (1, 40).toInt(), 1000); // paranoia check
+ if( num > (int) m_doc->type_descr.size() )
+ {
+ // description missing ?
+ QString s;
+ for (int i = m_doc->type_descr.size(); i < num; i++)
+ {
+ s.setNum (i+1);
+ s.insert (0, "#"); // invent descr according to number
+ m_doc->type_descr.push_back (s);
+ }
+ }
+ }
+ }
+
+ if (lesson && lesson > (int) m_doc->lesson_descr.size() )
+ {
+ // description missing ?
+ QString s;
+ for (int i = m_doc->lesson_descr.size(); i < lesson; i++)
+ {
+ s.setNum (i+1);
+ s.insert (0, "#"); // invent descr according to number
+ m_doc->lesson_descr.push_back (s);
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ // Child 'Original'
+ //-------------------------------------------------------------------------
+
+ // now want "original" and one or more "translations"
+
+ QDomElement domElementExpressionChild = domElementParent.firstChild().toElement();
+
+ unsigned int count = 0;
+ org_found = false;
+
+ if (domElementExpressionChild.tagName() != KV_ORG)
+ {
+ // must be preceded by "original"
+ domError(i18n("starting tag <%1> is missing").arg(KV_ORG));
+ return false;
+ }
+
+ // found original <o>
+
+ org_found = true;
+
+ type = exprtype;
+
+ //-----------
+ // Attributes
+
+ if (!readExpressionChildAttributes( domElementExpressionChild,
+ lang,
+ grade, r_grade,
+ qcount, r_qcount,
+ qdate, r_qdate,
+ remark,
+ bcount, r_bcount,
+ query_id,
+ pronunce,
+ width,
+ type,
+ faux_ami_t,
+ faux_ami_f,
+ synonym,
+ example,
+ antonym,
+ usage,
+ paraphrase))
+ return false;
+
+
+ if (m_doc->vocabulary.size() == 0)
+ {
+ // only accept in first entry
+ if (width >= 0)
+ m_doc->setSizeHint (count, width);
+
+ if (query_id == KV_O)
+ q_org = lang;
+
+ if (query_id == KV_T)
+ q_trans = lang;
+ }
+
+ if (m_doc->langs.size() == 0)
+ {
+ // first entry
+ if (lang.isEmpty()) // no definition in first entry
+ lang = "original";
+ m_doc->langs.push_back(lang);
+
+ }
+ else
+ {
+ if (lang != m_doc->langs[0] && !lang.isEmpty())
+ {
+ // different originals ?
+ domError(i18n("ambiguous definition of language code"));
+ return false;
+ }
+ }
+ count = 0;
+
+ //---------
+ // Children
+
+ bool bConjug = false;
+ bool bComparison = false;
+ bool bMultipleChoice = false;
+
+ QDomElement domElementOriginalChild = domElementExpressionChild.firstChild().toElement();
+ while (!domElementOriginalChild.isNull())
+ {
+ if (domElementOriginalChild.tagName() == KV_CONJUG_GRP)
+ {
+ if (bConjug)
+ {
+ domError(i18n("repeated occurrence of tag <%1>").arg(domElementOriginalChild.tagName()));
+ return false;
+ }
+ bConjug = true;
+ conjug.clear();
+ if (!readConjug(domElementOriginalChild, conjug, (QString) KV_CON_TYPE))
+ return false;
+ }
+
+ else if (domElementOriginalChild.tagName() == KV_COMPARISON_GRP)
+ {
+ if (bComparison)
+ {
+ domError(i18n("repeated occurrence of tag <%1>").arg(domElementOriginalChild.tagName()));
+ return false;
+ }
+ bComparison = true;
+ comparison.clear();
+ if (!readComparison(domElementOriginalChild, comparison))
+ return false;
+ }
+
+ else if (domElementOriginalChild.tagName() == KV_MULTIPLECHOICE_GRP)
+ {
+ if (bMultipleChoice)
+ {
+ domError(i18n("repeated occurrence of tag <%1>").arg(domElementOriginalChild.tagName()));
+ return false;
+ }
+ bMultipleChoice = true;
+ mc.clear();
+ if (!readMultipleChoice(domElementOriginalChild, mc))
+ return false;
+ }
+
+ else
+ {
+ domErrorUnknownElement(domElementOriginalChild.tagName());
+ return false;
+ }
+
+ domElementOriginalChild = domElementOriginalChild.nextSibling().toElement();
+ }
+
+ textstr = domElementExpressionChild.lastChild().toText().data();
+ if (textstr.isNull())
+ textstr = "";
+
+ expr = KEduVocExpression(textstr);
+ expr.setLesson (lesson);
+ expr.setInQuery(inquery);
+ expr.setActive(active);
+
+ if (conjug.size() > 0)
+ {
+ expr.setConjugation(0, conjug[0]);
+ conjug.clear();
+ }
+ if (!comparison.isEmpty())
+ {
+ expr.setComparison(0, comparison);
+ comparison.clear();
+ }
+ if (!mc.isEmpty())
+ {
+ expr.setMultipleChoice(0, mc);
+ mc.clear();
+ }
+ if (!remark.isEmpty() )
+ expr.setRemark (0, remark);
+ if (!pronunce.isEmpty() )
+ expr.setPronunce (0, pronunce);
+ if (!type.isEmpty() )
+ expr.setType(0, type);
+ if (!synonym.isEmpty() )
+ expr.setSynonym(0, synonym);
+ if (!example.isEmpty() )
+ expr.setExample(0, example);
+ if (!usage.isEmpty() )
+ expr.setUsageLabel(0, usage);
+ if (!paraphrase.isEmpty() )
+ expr.setParaphrase(0, paraphrase);
+ if (!antonym.isEmpty() )
+ expr.setAntonym(0, antonym);
+
+
+ //-------------------------------------------------------------------------
+ // Children 'Translation'
+ //-------------------------------------------------------------------------
+
+ domElementExpressionChild = domElementExpressionChild.nextSibling().toElement();
+
+ while (!domElementExpressionChild.isNull())
+ {
+ if (domElementExpressionChild.tagName() != KV_TRANS)
+ {
+ // "original" must be followed by "translations"
+ domError(i18n("starting tag <%1> is missing").arg(KV_TRANS));
+ return false;
+ }
+
+ // found translation <t>
+
+ count++;
+ type = exprtype;
+
+ //-----------
+ // Attributes
+
+ if (!readExpressionChildAttributes( domElementExpressionChild,
+ lang,
+ grade, r_grade,
+ qcount, r_qcount,
+ qdate, r_qdate,
+ remark,
+ bcount, r_bcount,
+ query_id,
+ pronunce,
+ width,
+ type,
+ faux_ami_f,
+ faux_ami_t,
+ synonym,
+ example,
+ antonym,
+ usage,
+ paraphrase))
+ return false;
+
+ if (m_doc->vocabulary.size() == 0)
+ {
+ // only accept in first entry
+ if (width >= 0)
+ m_doc->setSizeHint (count, width);
+
+ if (query_id == KV_O)
+ q_org = lang;
+
+ if (query_id == KV_T)
+ q_trans = lang;
+
+ }
+
+ if (m_doc->langs.size() <= count)
+ {
+ // new translation
+ if (lang.isEmpty())
+ {
+ // no definition in first entry ?
+ lang.setNum (m_doc->langs.size() );
+ lang.insert (0, "translation ");
+ }
+ m_doc->langs.push_back(lang);
+
+ }
+ else
+ {
+ if (lang != m_doc->langs[count] && !lang.isEmpty())
+ { // different language ?
+ domError(i18n("ambiguous definition of language code"));
+ return false;
+ }
+ }
+
+ //---------
+ // Children
+
+ bool bConjug = false;
+ bool bComparison = false;
+ bool bMultipleChoice = false;
+
+ QDomElement domElementOriginalChild = domElementExpressionChild.firstChild().toElement();
+ while (!domElementOriginalChild.isNull())
+ {
+ if (domElementOriginalChild.tagName() == KV_CONJUG_GRP)
+ {
+ if (bConjug)
+ {
+ domError(i18n("repeated occurrence of tag <%1>").arg(domElementOriginalChild.tagName()));
+ return false;
+ }
+ bConjug = true;
+ conjug.clear();
+ if (!readConjug(domElementOriginalChild, conjug, (QString) KV_CON_TYPE))
+ return false;
+ }
+
+ else if (domElementOriginalChild.tagName() == KV_COMPARISON_GRP)
+ {
+ if (bComparison)
+ {
+ domError(i18n("repeated occurrence of tag <%1>").arg(domElementOriginalChild.tagName()));
+ return false;
+ }
+ bComparison = true;
+ comparison.clear();
+ if (!readComparison(domElementOriginalChild, comparison))
+ return false;
+ }
+
+ else if (domElementOriginalChild.tagName() == KV_MULTIPLECHOICE_GRP)
+ {
+ if (bMultipleChoice)
+ {
+ domError(i18n("repeated occurrence of tag <%1>").arg(domElementOriginalChild.tagName()));
+ return false;
+ }
+ bMultipleChoice = true;
+ mc.clear();
+ if (!readMultipleChoice(domElementOriginalChild, mc))
+ return false;
+ }
+
+ else
+ {
+ domErrorUnknownElement(domElementOriginalChild.tagName());
+ return false;
+ }
+
+ domElementOriginalChild = domElementOriginalChild.nextSibling().toElement();
+ }
+
+ textstr = domElementExpressionChild.lastChild().toText().data();
+ if (textstr.isNull())
+ textstr = "";
+
+ /*
+ if (qcount == 0)
+ {
+ grade = KV_NORM_GRADE;
+ }
+
+ if (r_qcount == 0)
+ {
+ r_grade = KV_NORM_GRADE;
+ }
+ */
+ expr.addTranslation (textstr, grade, r_grade);
+ expr.setQueryCount (count, qcount, false);
+ expr.setQueryCount (count, r_qcount, true);
+ expr.setBadCount (count, bcount, false);
+ expr.setBadCount (count, r_bcount, true);
+ expr.setQueryDate (count, qdate, false);
+ expr.setQueryDate (count, r_qdate, true);
+
+ if (conjug.size() > 0)
+ {
+ expr.setConjugation(count, conjug[0]);
+ conjug.clear();
+ }
+ if (!comparison.isEmpty())
+ {
+ expr.setComparison(count, comparison);
+ comparison.clear();
+ }
+ if (!mc.isEmpty())
+ {
+ expr.setMultipleChoice(count, mc);
+ mc.clear();
+ }
+ if (!type.isEmpty() )
+ expr.setType (count, type);
+ if (!remark.isEmpty() )
+ expr.setRemark (count, remark);
+ if (!pronunce.isEmpty() )
+ expr.setPronunce (count, pronunce);
+ if (!faux_ami_f.isEmpty() )
+ expr.setFauxAmi (count, faux_ami_f, false);
+ if (!faux_ami_t.isEmpty() )
+ expr.setFauxAmi (count, faux_ami_t, true);
+ if (!synonym.isEmpty() )
+ expr.setSynonym (count, synonym);
+ if (!example.isEmpty() )
+ expr.setExample (count, example);
+ if (!usage.isEmpty() )
+ expr.setUsageLabel (count, usage);
+ if (!paraphrase.isEmpty() )
+ expr.setParaphrase (count, paraphrase);
+ if (!antonym.isEmpty() )
+ expr.setAntonym (count, antonym);
+
+ domElementExpressionChild = domElementExpressionChild.nextSibling().toElement();
+ }
+ if (m_doc->numEntries() == 0)
+ m_doc->setQueryLang(q_org, q_trans);
+ m_doc->vocabulary.push_back(expr);
+
+ return true;
+}
+
+
+bool KEduVocKvtmlReader::readBody(QDomElement &domElementParent)
+{
+ bool lessgroup = false;
+ bool optgroup = false;
+ bool attrgroup = false;
+ bool tensegroup = false;
+ bool usagegroup = false;
+ bool articlegroup = false;
+ bool conjuggroup = false;
+
+ int ent_no = 0;
+ int ent_percent = (int) m_doc->lines / 100;
+ float f_ent_percent = (int) m_doc->lines / 100.0;
+/* TODO EPT
+if (lines != 0)
+ emit progressChanged(this, 0);
+*/
+
+ QDomElement domElementChild = domElementParent.firstChild().toElement();
+
+ while (!domElementChild.isNull())
+ {
+ if (domElementChild.tagName() == KV_LESS_GRP)
+ {
+ if (lessgroup)
+ {
+ domError(i18n("repeated occurrence of tag <%1>").arg(domElementChild.tagName()));
+ return false;
+ }
+ lessgroup = true;
+ if (!readLesson(domElementChild))
+ return false;
+ }
+
+ else if (domElementChild.tagName() == KV_ARTICLE_GRP)
+ {
+ if (articlegroup)
+ {
+ domError(i18n("repeated occurrence of tag <%1>").arg(domElementChild.tagName()));
+ return false;
+ }
+ articlegroup = true;
+ if (!readArticle(domElementChild))
+ return false;
+ }
+
+ else if (domElementChild.tagName() == KV_CONJUG_GRP)
+ {
+ if (conjuggroup)
+ {
+ domError(i18n("repeated occurrence of tag <%1>").arg(domElementChild.tagName()));
+ return false;
+ }
+ conjuggroup = true;
+ if (!readConjug(domElementChild, m_doc->conjugations, KV_CON_ENTRY))
+ return false;
+ }
+
+ else if (domElementChild.tagName() == KV_OPTION_GRP)
+ {
+ if (optgroup)
+ {
+ domError(i18n("repeated occurrence of tag <%1>").arg(domElementChild.tagName()));
+ return false;
+ }
+ optgroup = true;
+ if (!readOptions(domElementChild))
+ return false;
+ }
+
+ else if (domElementChild.tagName() == KV_TYPE_GRP)
+ {
+ if (attrgroup)
+ {
+ domError(i18n("repeated occurrence of tag <%1>").arg(domElementChild.tagName()));
+ return false;
+ }
+ attrgroup = true;
+ if (!readType(domElementChild))
+ return false;
+ }
+
+ else if (domElementChild.tagName() == KV_TENSE_GRP)
+ {
+ if (tensegroup)
+ {
+ domError(i18n("repeated occurrence of tag <%1>").arg(domElementChild.tagName()));
+ return false;
+ }
+ tensegroup = true;
+ if (!readTense(domElementChild))
+ return false;
+ }
+
+ else if (domElementChild.tagName() == KV_USAGE_GRP)
+ {
+ if (usagegroup)
+ {
+ domError(i18n("repeated occurrence of tag <%1>").arg(domElementChild.tagName()));
+ return false;
+ }
+ usagegroup = true;
+ if (!readUsage(domElementChild))
+ return false;
+ }
+
+ else if (domElementChild.tagName() == KV_EXPR)
+ {
+ /* TODO EPT
+ if (lines != 0)
+ {
+ ent_no++;
+ if (ent_percent != 0 && (ent_no % ent_percent) == 0 )
+ emit progressChanged(this, int(ent_no / f_ent_percent));
+ }*/
+ if (!readExpression(domElementChild))
+ return false;
+ }
+
+ else
+ {
+ domErrorUnknownElement(domElementChild.tagName());
+ return false;
+ }
+
+ domElementChild = domElementChild.nextSibling().toElement();
+ }
+
+ return true;
+}
+
+
+bool KEduVocKvtmlReader::readDoc(KEduVocDocument *doc)
+{
+ m_doc = doc;
+
+ QDomDocument domDoc("Kvtml" );
+ QString errorMsg;
+ if( !domDoc.setContent( m_inputFile, &errorMsg ) )
+ {
+ domError(errorMsg);
+ return false;
+ }
+
+ m_doc->langs.clear();
+ m_doc->vocabulary.clear();
+
+ m_doc->generator = "";
+ m_doc->cols = 0;
+ m_doc->lines = 0;
+ m_doc->doctitle = "";
+ m_doc->author = "";
+ m_doc->license = "";
+ m_doc->doc_remark = "";
+
+
+ QDomElement domElementKvtml = domDoc.documentElement();
+ if( domElementKvtml.tagName() != KV_DOCTYPE )
+ {
+ domError(i18n("Tag <%1> was expected "
+ "but tag <%2> was read." ).arg(KV_DOCTYPE).arg(domElementKvtml.tagName()));
+ return false;
+ }
+
+ //-------------------------------------------------------------------------
+ // Attributes
+ //-------------------------------------------------------------------------
+
+ QDomAttr domAttrEncoding = domElementKvtml.attributeNode(KV_ENCODING);
+ if (!domAttrEncoding.isNull())
+ {
+ // TODO handle old encodings
+ // Qt DOM API autodetects encoding, so is there anything to do ?
+ }
+
+ QDomAttr domAttrTitle = domElementKvtml.attributeNode(KV_TITLE);
+ if (!domAttrTitle.isNull())
+ {
+ m_doc->doctitle = domAttrTitle.value();
+ }
+
+ QDomAttr domAttrAuthor = domElementKvtml.attributeNode(KV_AUTHOR);
+ if (!domAttrAuthor.isNull())
+ {
+ m_doc->author = domAttrAuthor.value();
+ }
+
+ QDomAttr domAttrLicence = domElementKvtml.attributeNode(KV_LICENSE);
+ if (!domAttrLicence.isNull())
+ {
+ m_doc->license = domAttrLicence.value();
+ }
+
+ QDomAttr domAttrRemark = domElementKvtml.attributeNode(KV_DOC_REM);
+ if (!domAttrRemark.isNull())
+ {
+ m_doc->doc_remark = domAttrRemark.value();
+ }
+
+ QDomAttr domAttrGenerator = domElementKvtml.attributeNode(KV_GENERATOR);
+ if (!domAttrGenerator.isNull())
+ {
+ m_doc->generator = domAttrGenerator.value();
+ int pos = m_doc->generator.findRev (KVD_VERS_PREFIX);
+ if (pos >= 0)
+ {
+ m_doc->doc_version = m_doc->generator;
+ m_doc->doc_version.remove (0, pos+2);
+ }
+ }
+
+ QDomAttr domAttrCols = domElementKvtml.attributeNode(KV_COLS);
+ if (!domAttrCols.isNull())
+ {
+ m_doc->cols = domAttrCols.value().toInt();
+ }
+
+ QDomAttr domAttrLines = domElementKvtml.attributeNode(KV_LINES);
+ if (!domAttrLines.isNull())
+ {
+ m_doc->lines = domAttrLines.value().toInt();
+ }
+
+
+ //-------------------------------------------------------------------------
+ // Children
+ //-------------------------------------------------------------------------
+
+ bool result = readBody(domElementKvtml); // read vocabulary
+
+ // TODO EPT setModified (false);
+ return result;
+}
+
+
+void KEduVocKvtmlReader::domErrorUnknownElement(const QString &elem)
+{
+ QString ln = i18n("File:\t%1\n").arg(m_doc->URL().path());
+
+ QString format = i18n(
+ "Your document contains an unknown tag <%1>. " // keep trailing space
+ "Maybe your version of KVocTrain is too old, "
+ "or the document is damaged.\n"
+ "Loading is aborted because KVocTrain cannot "
+ "read documents with unknown elements.\n"
+ );
+ QString msg = format.arg(elem);
+ QApplication::setOverrideCursor( arrowCursor, true );
+ QString s = kapp->makeStdCaption(i18n("Unknown Element"));
+ KMessageBox::sorry(0, ln+msg, s);
+ QApplication::restoreOverrideCursor();
+}
+
+void KEduVocKvtmlReader::domError(const QString &text )
+{
+ QApplication::setOverrideCursor( arrowCursor, true );
+ QString s = kapp->makeStdCaption(i18n("Error"));
+ QString ln = i18n("File:\t%1\n").arg(m_doc->URL().path());
+ QString msg = text;
+ KMessageBox::error(0, ln+msg, s);
+ QApplication::restoreOverrideCursor();
+}
+
diff --git a/kanagram/src/keduvockvtmlreader.h b/kanagram/src/keduvockvtmlreader.h
new file mode 100644
index 00000000..9d902183
--- /dev/null
+++ b/kanagram/src/keduvockvtmlreader.h
@@ -0,0 +1,121 @@
+/***************************************************************************
+ read a KEduVocDocument from a KVTML file
+ -----------------------------------------------------------------------
+ copyright : (C) 1999-2001 Ewald Arnold
+ (C) 2001 The KDE-EDU team
+ (C) 2005 Eric Pignet
+ email : eric at erixpage.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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KEDUVOCKVTMLREADER_H
+#define KEDUVOCKVTMLREADER_H
+
+#include <qfile.h>
+#include <qdom.h>
+
+#include "keduvocdocument.h"
+#include "grammarmanager.h"
+#include "multiplechoice.h"
+
+class KEduVocDocument;
+
+// internal types, indented are subtypes
+
+#define QM_VERB "v" // go
+#define QM_VERB_IRR "ir"
+#define QM_VERB_REG "re"
+#define QM_NOUN "n" // table, coffee
+#define QM_NOUN_F "f"
+#define QM_NOUN_M "m"
+#define QM_NOUN_S "s"
+#define QM_NAME "nm"
+#define QM_ART "ar" // article
+#define QM_ART_DEF "def" // definite a/an
+#define QM_ART_IND "ind" // indefinite the
+#define QM_ADJ "aj" // adjective expensive, good
+#define QM_ADV "av" // adverb today, strongly
+#define QM_PRON "pr" // pronoun you, she
+#define QM_PRON_POS "pos" // possessive my, your
+#define QM_PRON_PER "per" // personal
+#define QM_PHRASE "ph"
+#define QM_NUM "num" // numeral
+#define QM_NUM_ORD "ord" // ordinal first, second
+#define QM_NUM_CARD "crd" // cardinal one, two
+#define QM_INFORMAL "ifm"
+#define QM_FIG "fig"
+#define QM_CON "con" // conjuncton and, but
+#define QM_PREP "pre" // preposition behind, between
+#define QM_QUEST "qu" // question who, what
+
+// type delimiters
+
+#define QM_USER_TYPE "#" // designates number of user type
+#define QM_TYPE_DIV ":" // divide main from subtype
+
+// usage delimiters (also declared in UsageManager.h)
+
+#define UL_USER_USAGE "#" // designates number of user type
+
+/**
+@author Eric Pignet
+*/
+class KEduVocKvtmlReader : public QObject
+{
+public:
+ KEduVocKvtmlReader(QFile *file);
+ ~KEduVocKvtmlReader();
+
+ bool readDoc(KEduVocDocument *doc);
+
+ bool readLesson(QDomElement &domElementParent);
+ bool readArticle(QDomElement &domElementParent);
+ bool readConjug(QDomElement &domElementParent,
+ vector<Conjugation> &curr_conjug,
+ const QString &entry_tag);
+ bool readOptions(QDomElement &domElementParent);
+ bool readType(QDomElement &domElementParent);
+ bool readTense(QDomElement &domElementParent);
+ bool readUsage(QDomElement &domElementParent);
+ bool readComparison(QDomElement &domElementParent,
+ Comparison &comp);
+ bool readMultipleChoice(QDomElement &domElementParent,
+ MultipleChoice &mc);
+ bool readExpressionChildAttributes( QDomElement &domElementExpressionChild,
+ QString &lang,
+ grade_t &grade, grade_t &rev_grade,
+ int &count, int &rev_count,
+ time_t &date, time_t &rev_date,
+ QString &remark,
+ int &bcount, int &rev_bcount,
+ QString &query_id,
+ QString &pronunce,
+ int &width,
+ QString &type,
+ QString &faux_ami_f,
+ QString &faux_ami_t,
+ QString &synonym,
+ QString &example,
+ QString &antonym,
+ QString &usage,
+ QString &paraphrase);
+ bool readExpression(QDomElement &domElementParent);
+ bool readBody(QDomElement &domElementParent);
+
+ void domErrorUnknownElement(const QString &elem);
+ void domError(const QString &text );
+
+private:
+ QFile *m_inputFile;
+ KEduVocDocument *m_doc;
+};
+
+#endif
diff --git a/kanagram/src/keduvockvtmlwriter.cpp b/kanagram/src/keduvockvtmlwriter.cpp
new file mode 100644
index 00000000..c859d828
--- /dev/null
+++ b/kanagram/src/keduvockvtmlwriter.cpp
@@ -0,0 +1,949 @@
+/***************************************************************************
+ export a KEduVocDocument to a KVTML file
+ -----------------------------------------------------------------------
+ copyright : (C) 1999-2001 Ewald Arnold
+ (C) 2001 The KDE-EDU team
+ (C) 2005 Eric Pignet
+ email : eric at erixpage.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. *
+ * *
+ ***************************************************************************/
+
+#include <kdebug.h>
+#include <qdom.h>
+#include <qtextstream.h>
+
+#include "keduvockvtmlwriter.h"
+#include "keduvocdocument.h"
+
+KEduVocKvtmlWriter::KEduVocKvtmlWriter(QFile *file)
+{
+ // the file must be already open
+ m_outputFile = file;
+}
+
+KEduVocKvtmlWriter::~KEduVocKvtmlWriter()
+{
+}
+
+bool KEduVocKvtmlWriter::saveTypeNameKvtMl (QDomDocument &domDoc, QDomElement &domElementParent)
+{
+ if (m_doc->type_descr.size() == 0)
+ return true;
+
+ QDomElement domElementType = domDoc.createElement(KV_TYPE_GRP);
+
+ for (int lfn = 0; lfn < (int) m_doc->type_descr.size(); lfn++)
+ {
+ if (!(m_doc->type_descr[lfn].isNull()) )
+ {
+ QDomElement domElementDesc = domDoc.createElement(KV_TYPE_DESC);
+ QDomText domTextDesc = domDoc.createTextNode(m_doc->type_descr[lfn]);
+
+ domElementDesc.setAttribute(KV_TYPE_NO, lfn+1);
+ domElementDesc.appendChild(domTextDesc);
+ domElementType.appendChild(domElementDesc);
+ }
+ }
+
+ domElementParent.appendChild(domElementType);
+ return true;
+}
+
+
+bool KEduVocKvtmlWriter::saveTenseNameKvtMl (QDomDocument &domDoc, QDomElement &domElementParent)
+{
+ if (m_doc->tense_descr.size() == 0)
+ return true;
+
+ QDomElement domElementTense = domDoc.createElement(KV_TENSE_GRP);
+
+ for (int lfn = 0; lfn < (int) m_doc->tense_descr.size(); lfn++)
+ {
+ if (!(m_doc->tense_descr[lfn].isNull()) ) {
+ QDomElement domElementDesc = domDoc.createElement(KV_TENSE_DESC);
+ QDomText domTextDesc = domDoc.createTextNode(m_doc->tense_descr[lfn]);
+
+ domElementDesc.setAttribute(KV_TENSE_NO, lfn+1);
+ domElementDesc.appendChild(domTextDesc);
+ domElementTense.appendChild(domElementDesc);
+ }
+ }
+
+ domElementParent.appendChild(domElementTense);
+ return true;
+}
+
+
+bool KEduVocKvtmlWriter::saveUsageNameKvtMl (QDomDocument &domDoc, QDomElement &domElementParent)
+{
+ if (m_doc->usage_descr.size() == 0)
+ return true;
+
+ QDomElement domElementUsage = domDoc.createElement(KV_USAGE_GRP);
+
+ for (int lfn = 0; lfn < (int) m_doc->usage_descr.size(); lfn++)
+ {
+ if (!(m_doc->usage_descr[lfn].isNull()) )
+ {
+ QDomElement domElementDesc = domDoc.createElement(KV_USAGE_DESC);
+ QDomText domTextDesc = domDoc.createTextNode(m_doc->usage_descr[lfn]);
+
+ domElementDesc.setAttribute(KV_USAGE_NO, lfn+1);
+ domElementDesc.appendChild(domTextDesc);
+ domElementUsage.appendChild(domElementDesc);
+ }
+ }
+
+ domElementParent.appendChild(domElementUsage);
+ return true;
+}
+
+
+bool KEduVocKvtmlWriter::saveLessonKvtMl (QDomDocument &domDoc, QDomElement &domElementParent)
+{
+ if (m_doc->lesson_descr.size() == 0)
+ return true;
+
+ QDomElement domElementLesson = domDoc.createElement(KV_LESS_GRP);
+ domElementLesson.setAttribute(KV_SIZEHINT, m_doc->getSizeHint(-1));
+
+ for (int lfn = 0; lfn < (int) m_doc->lesson_descr.size(); lfn++)
+ {
+ if (!(m_doc->lesson_descr[lfn].isNull()) )
+ {
+ QDomElement domElementDesc = domDoc.createElement(KV_LESS_DESC);
+ QDomText domTextDesc = domDoc.createTextNode(m_doc->lesson_descr[lfn]);
+
+ domElementDesc.setAttribute(KV_LESS_NO, lfn+1);
+ if (m_doc->getCurrentLesson() == lfn+1)
+ domElementDesc.setAttribute (KV_LESS_CURR, 1);
+ if (lfn < (int) m_doc->lessons_in_query.size() && m_doc->lessons_in_query[lfn])
+ domElementDesc.setAttribute (KV_LESS_QUERY, 1);
+
+ domElementDesc.appendChild(domTextDesc);
+ domElementLesson.appendChild(domElementDesc);
+ }
+ }
+
+ domElementParent.appendChild(domElementLesson);
+ return true;
+}
+
+
+bool KEduVocKvtmlWriter::saveConjug(QDomDocument &domDoc, QDomElement &domElementParent,
+ const Conjugation &curr_conjug, QString type)
+{
+ if (!curr_conjug.pers1Singular(type).isEmpty() )
+ {
+ QDomElement domElementP1s = domDoc.createElement(KV_CON_P1S);
+ QDomText domTextP1s = domDoc.createTextNode(curr_conjug.pers1Singular(type));
+
+ domElementP1s.appendChild(domTextP1s);
+ domElementParent.appendChild(domElementP1s);
+ }
+
+ if (!curr_conjug.pers2Singular(type).isEmpty() )
+ {
+ QDomElement domElementP2s = domDoc.createElement(KV_CON_P2S);
+ QDomText domTextP2s = domDoc.createTextNode(curr_conjug.pers2Singular(type));
+
+ domElementP2s.appendChild(domTextP2s);
+ domElementParent.appendChild(domElementP2s);
+ }
+
+ if (!curr_conjug.pers3FemaleSingular(type).isEmpty() ||
+ curr_conjug.pers3SingularCommon(type))
+ {
+ QDomElement domElementP3sf = domDoc.createElement(KV_CON_P3SF);
+ QDomText domTextP3sf = domDoc.createTextNode(curr_conjug.pers3FemaleSingular(type));
+
+ if (curr_conjug.pers3SingularCommon(type))
+ domElementP3sf.setAttribute(KV_CONJ_COMMON, 1);
+
+ domElementP3sf.appendChild(domTextP3sf);
+ domElementParent.appendChild(domElementP3sf);
+ }
+
+ if (!curr_conjug.pers3MaleSingular(type).isEmpty() )
+ {
+ QDomElement domElementP3sm = domDoc.createElement(KV_CON_P3SM);
+ QDomText domTextP3sm = domDoc.createTextNode(curr_conjug.pers3MaleSingular(type));
+
+ domElementP3sm.appendChild(domTextP3sm);
+ domElementParent.appendChild(domElementP3sm);
+ }
+
+ if (!curr_conjug.pers3NaturalSingular(type).isEmpty() )
+ {
+ QDomElement domElementP3sn = domDoc.createElement(KV_CON_P3SN);
+ QDomText domTextP3sn = domDoc.createTextNode(curr_conjug.pers3NaturalSingular(type));
+
+ domElementP3sn.appendChild(domTextP3sn);
+ domElementParent.appendChild(domElementP3sn);
+ }
+
+ if (!curr_conjug.pers1Plural(type).isEmpty() )
+ {
+ QDomElement domElementP1p = domDoc.createElement(KV_CON_P1P);
+ QDomText domTextP1p = domDoc.createTextNode(curr_conjug.pers1Plural(type));
+
+ domElementP1p.appendChild(domTextP1p);
+ domElementParent.appendChild(domElementP1p);
+ }
+
+ if (!curr_conjug.pers2Plural(type).isEmpty() )
+ {
+ QDomElement domElementP2p = domDoc.createElement(KV_CON_P2P);
+ QDomText domTextP2p = domDoc.createTextNode(curr_conjug.pers2Plural(type));
+
+ domElementP2p.appendChild(domTextP2p);
+ domElementParent.appendChild(domElementP2p);
+ }
+
+ if (!curr_conjug.pers3FemalePlural(type).isEmpty() ||
+ curr_conjug.pers3PluralCommon(type))
+ {
+ QDomElement domElementP3pf = domDoc.createElement(KV_CON_P3PF);
+ QDomText domTextP3pf = domDoc.createTextNode(curr_conjug.pers3FemalePlural(type));
+
+ if (curr_conjug.pers3PluralCommon(type))
+ domElementP3pf.setAttribute(KV_CONJ_COMMON, 1);
+
+ domElementP3pf.appendChild(domTextP3pf);
+ domElementParent.appendChild(domElementP3pf);
+ }
+
+ if (!curr_conjug.pers3MalePlural(type).isEmpty() )
+ {
+ QDomElement domElementP3pm = domDoc.createElement(KV_CON_P3PM);
+ QDomText domTextP3pm = domDoc.createTextNode(curr_conjug.pers3MalePlural(type));
+
+ domElementP3pm.appendChild(domTextP3pm);
+ domElementParent.appendChild(domElementP3pm);
+ }
+
+ if (!curr_conjug.pers3NaturalPlural(type).isEmpty() )
+ {
+ QDomElement domElementP3pn = domDoc.createElement(KV_CON_P3PN);
+ QDomText domTextP3pn = domDoc.createTextNode(curr_conjug.pers3NaturalPlural(type));
+
+ domElementP3pn.appendChild(domTextP3pn);
+ domElementParent.appendChild(domElementP3pn);
+ }
+
+ return true;
+}
+
+bool KEduVocKvtmlWriter::saveConjugHeader(QDomDocument &domDoc, QDomElement &domElementParent,
+ vector<Conjugation> &curr_conjug)
+{
+/*
+ <conjugation> used in header for definiton of "prefix"
+ <e l="de"> lang determines also lang order in entries !!
+ <s1>I</s1> which must NOT differ
+ <s2>you<2>
+ <s3f common="0">he</s3f>
+ <s3m>she</s3m>
+ <s3n>it</s3n>
+ <p1>we</p1>
+ <p2>you</p2>
+ <p3f common="1">they</p3f>
+ <p3m>they</p3m>
+ <p3n>they</p3n>
+ </e>
+ </conjugation>
+
+*/
+ if (curr_conjug.size() == 0)
+ return true;
+
+ QDomElement domElementConjug = domDoc.createElement(KV_CONJUG_GRP);
+ QString s;
+
+ for (int ent = 0; ent < QMIN((int) curr_conjug.size(), m_doc->numLangs()); ent++)
+ {
+ QDomElement domElementEntry = domDoc.createElement(KV_CON_ENTRY);
+
+ if (ent == 0)
+ {
+ s = m_doc->getOriginalIdent().stripWhiteSpace(); //EPT le Ident doit �re superflu
+ if (s.isEmpty() )
+ s = "original";
+ }
+ else
+ {
+ s = m_doc->getIdent(ent).stripWhiteSpace();
+ if (s.isEmpty() )
+ {
+ s.setNum(ent);
+ s.insert(0, "translation ");
+ }
+ }
+ domElementEntry.setAttribute(KV_LANG, s);
+
+ if (!saveConjug (domDoc, domElementEntry, curr_conjug[ent], CONJ_PREFIX))
+ return false;
+
+ domElementConjug.appendChild(domElementEntry);
+ }
+
+ domElementParent.appendChild(domElementConjug);
+ return true;
+}
+
+
+bool KEduVocKvtmlWriter::saveComparison(QDomDocument &domDoc, QDomElement &domElementParent,
+ const Comparison &comp)
+/*
+ <comparison>
+ <l1>good</l1>
+ <l2>better</l2>
+ <l3>best</l3>
+ </comparison>
+*/
+{
+ if (comp.isEmpty())
+ return true;
+
+ QDomElement domElementComparison = domDoc.createElement(KV_COMPARISON_GRP);
+
+ if (!comp.l1().isEmpty() )
+ {
+ QDomElement domElementL1 = domDoc.createElement(KV_COMP_L1);
+ QDomText domTextL1 = domDoc.createTextNode(comp.l1());
+
+ domElementL1.appendChild(domTextL1);
+ domElementComparison.appendChild(domElementL1);
+ }
+
+ if (!comp.l2().isEmpty() )
+ {
+ QDomElement domElementL2 = domDoc.createElement(KV_COMP_L2);
+ QDomText domTextL2 = domDoc.createTextNode(comp.l2());
+
+ domElementL2.appendChild(domTextL2);
+ domElementComparison.appendChild(domElementL2);
+ }
+
+ if (!comp.l3().isEmpty() )
+ {
+ QDomElement domElementL3 = domDoc.createElement(KV_COMP_L3);
+ QDomText domTextL3 = domDoc.createTextNode(comp.l3());
+
+ domElementL3.appendChild(domTextL3);
+ domElementComparison.appendChild(domElementL3);
+ }
+
+ domElementParent.appendChild(domElementComparison);
+ return true;
+}
+
+
+bool KEduVocKvtmlWriter::saveMultipleChoice(QDomDocument &domDoc, QDomElement &domElementParent,
+ const MultipleChoice &mc)
+/*
+ <multiplechoice>
+ <mc1>good</mc1>
+ <mc2>better</mc2>
+ <mc3>best</mc3>
+ <mc4>best 2</mc4>
+ <mc5>best 3</mc5>
+ </multiplechoice>
+*/
+{
+ if (mc.isEmpty())
+ return true;
+
+ QDomElement domElementMC = domDoc.createElement(KV_MULTIPLECHOICE_GRP);
+
+ if (!mc.mc1().isEmpty() )
+ {
+ QDomElement domElementMC1 = domDoc.createElement(KV_MC_1);
+ QDomText domTextMC1 = domDoc.createTextNode(mc.mc1());
+
+ domElementMC1.appendChild(domTextMC1);
+ domElementMC.appendChild(domElementMC1);
+ }
+
+ if (!mc.mc2().isEmpty() )
+ {
+ QDomElement domElementMC2 = domDoc.createElement(KV_MC_2);
+ QDomText domTextMC2 = domDoc.createTextNode(mc.mc2());
+
+ domElementMC2.appendChild(domTextMC2);
+ domElementMC.appendChild(domElementMC2);
+ }
+
+ if (!mc.mc3().isEmpty() )
+ {
+ QDomElement domElementMC3 = domDoc.createElement(KV_MC_3);
+ QDomText domTextMC3 = domDoc.createTextNode(mc.mc3());
+
+ domElementMC3.appendChild(domTextMC3);
+ domElementMC.appendChild(domElementMC3);
+ }
+
+ if (!mc.mc4().isEmpty() )
+ {
+ QDomElement domElementMC4 = domDoc.createElement(KV_MC_4);
+ QDomText domTextMC4 = domDoc.createTextNode(mc.mc4());
+
+ domElementMC4.appendChild(domTextMC4);
+ domElementMC.appendChild(domElementMC4);
+ }
+
+ if (!mc.mc5().isEmpty() )
+ {
+ QDomElement domElementMC5 = domDoc.createElement(KV_MC_5);
+ QDomText domTextMC5 = domDoc.createTextNode(mc.mc5());
+
+ domElementMC5.appendChild(domTextMC5);
+ domElementMC.appendChild(domElementMC5);
+ }
+
+ domElementParent.appendChild(domElementMC);
+ return true;
+}
+
+
+bool KEduVocKvtmlWriter::saveConjugEntry( QDomDocument &domDoc, QDomElement &domElementParent,
+ Conjugation &curr_conjug)
+/*
+ <conjugation> in entry for definition of tenses of (irreg.) verbs
+ <t n="sipa">
+ <s1>go</s1>
+ <s2>go</s2>
+ <s3f>goes</s3f>
+ <s3m>goes</s3m>
+ <s3n>goes</s3n>
+ <p1>go</p1>
+ <p2>go</p2>
+ <p3f>go</p3f>
+ <p3m>go</p3m>
+ <p3n>go</p3n>
+ </t>
+ </conjugation>
+*/
+{
+ curr_conjug.cleanUp();
+ if (curr_conjug.numEntries() == 0 )
+ return true;
+
+ QDomElement domElementConjug = domDoc.createElement(KV_CONJUG_GRP);
+ QString type;
+
+ for (int lfn = 0; lfn < (int) curr_conjug.numEntries(); lfn++)
+ {
+ QDomElement domElementType = domDoc.createElement(KV_CON_TYPE);
+
+ type = curr_conjug.getType(lfn);
+ domElementType.setAttribute(KV_CON_NAME, type);
+
+ if (!saveConjug (domDoc, domElementType, curr_conjug, curr_conjug.getType(lfn)) )
+ return false;
+
+ domElementConjug.appendChild(domElementType);
+ }
+
+ domElementParent.appendChild(domElementConjug);
+ return true;
+}
+
+
+bool KEduVocKvtmlWriter::saveArticleKvtMl(QDomDocument &domDoc, QDomElement &domElementParent)
+/*
+ <article>
+ <e l="de"> lang determines also lang order in entries !!
+ <fi>eine</fi> which must NOT differ
+ <fd>die</fd>
+ <mi>ein</mi>
+ <md>der</md>
+ <ni>ein</ni>
+ <nd>das</nd>
+ </e>
+ </article>
+*/
+{
+ if (m_doc->articles.size() == 0)
+ return true;
+
+ QDomElement domElementArticle = domDoc.createElement(KV_ARTICLE_GRP);
+ QString def, indef, s;
+
+ for (int lfn = 0; lfn < QMIN((int) m_doc->articles.size(), m_doc->numLangs()); lfn++)
+ {
+ QDomElement domElementEntry = domDoc.createElement(KV_ART_ENTRY);
+ if (lfn == 0)
+ {
+ s = m_doc->getOriginalIdent().stripWhiteSpace();
+ if (s.isEmpty() )
+ s = "original";
+ }
+ else
+ {
+ s = m_doc->getIdent(lfn).stripWhiteSpace();
+ if (s.isEmpty() )
+ {
+ s.setNum(lfn);
+ s.insert(0, "translation ");
+ }
+ }
+ domElementEntry.setAttribute(KV_LANG, s);
+
+ m_doc->articles[lfn].female(def, indef);
+ if (!def.isEmpty() )
+ {
+ QDomElement domElementFD = domDoc.createElement(KV_ART_FD);
+ QDomText domTextFD = domDoc.createTextNode(def);
+
+ domElementFD.appendChild(domTextFD);
+ domElementEntry.appendChild(domElementFD);
+ }
+ if (!indef.isEmpty() )
+ {
+ QDomElement domElementFI = domDoc.createElement(KV_ART_FI);
+ QDomText domTextFI = domDoc.createTextNode(indef);
+
+ domElementFI.appendChild(domTextFI);
+ domElementEntry.appendChild(domElementFI);
+ }
+
+ m_doc->articles[lfn].male(def, indef);
+ if (!def.isEmpty() )
+ {
+ QDomElement domElementMD = domDoc.createElement(KV_ART_MD);
+ QDomText domTextMD = domDoc.createTextNode(def);
+
+ domElementMD.appendChild(domTextMD);
+ domElementEntry.appendChild(domElementMD);
+ }
+ if (!indef.isEmpty() )
+ {
+ QDomElement domElementMI = domDoc.createElement(KV_ART_MI);
+ QDomText domTextMI = domDoc.createTextNode(indef);
+
+ domElementMI.appendChild(domTextMI);
+ domElementEntry.appendChild(domElementMI);
+ }
+
+ m_doc->articles[lfn].natural(def, indef);
+ if (!def.isEmpty() )
+ {
+ QDomElement domElementND = domDoc.createElement(KV_ART_ND);
+ QDomText domTextND = domDoc.createTextNode(def);
+
+ domElementND.appendChild(domTextND);
+ domElementEntry.appendChild(domElementND);
+ }
+ if (!indef.isEmpty() )
+ {
+ QDomElement domElementNI = domDoc.createElement(KV_ART_NI);
+ QDomText domTextNI = domDoc.createTextNode(indef);
+
+ domElementNI.appendChild(domTextNI);
+ domElementEntry.appendChild(domElementNI);
+ }
+
+ domElementArticle.appendChild(domElementEntry);
+ }
+
+ domElementParent.appendChild(domElementArticle);
+ return true;
+}
+
+
+bool KEduVocKvtmlWriter::saveOptionsKvtMl(QDomDocument &domDoc, QDomElement &domElementParent)
+{
+ QDomElement domElementOption = domDoc.createElement(KV_OPTION_GRP);
+ QDomElement domElementSort = domDoc.createElement(KV_OPT_SORT);
+
+ domElementSort.setAttribute(KV_BOOL_FLAG, (m_doc->sort_allowed?1:0));
+ domElementOption.appendChild(domElementSort);
+
+ domElementParent.appendChild(domElementOption);
+ return true;
+}
+
+
+bool KEduVocKvtmlWriter::writeDoc(KEduVocDocument *doc, const QString &generator)
+{
+ bool first_expr = true;
+
+ m_doc = doc;
+
+ QDomDocument domDoc( "KEduVocDocument" );
+ QDomElement domElementKvtml = domDoc.createElement( "kvtml" );
+
+ QString head( "<?xml version='1.0' encoding='UTF-8' ?><!DOCTYPE kvtml SYSTEM \"kvoctrain.dtd\">" );
+ domDoc.setContent( head );
+
+ QDomComment domComment = domDoc.createComment(QString(
+ "\nThis is a machine generated file.\n"
+ "Be careful when editing here.\n"
+ "\n"
+ "Short definition:\n"
+ "\n"
+ "lesson lesson group\n"
+ " desc name\n"
+ " %no its index\n"
+ " %query is in query selection\n"
+ " %current is current lesson\n"
+ "type type group\n"
+ " desc name\n"
+ " %no its index\n"
+ "e entry of dictionary\n"
+ " %s is selected\n"
+ " %m lesson member\n"
+ " %t common expression type\n"
+ " o original\n"
+ " %q in query (\"o\" is given, \"t\" is wanted)\n"
+ " %l language code\n"
+ " %r remark\n"
+ " %p pronunciation\n"
+ " %width column width\n"
+ " %t expression type (see QueryManager.h)\n"
+ " %tf false friend from\n"
+ " %ff false friend to\n"
+ " %a antonym\n"
+ " %y synonym\n"
+ " %x example\n"
+ " %u usage label\n"
+ " %h paraphrase\n"
+ " t translation ..\n"
+ " %q in query (\"t\" is given, \"o\" is wanted)\n"
+ " %l language code\n"
+ " %r remark\n"
+ " %p pronunciation\n"
+ " %width column width\n"
+ " %t expression type\n"
+ " %tf false friend from\n"
+ " %ff false friend to\n"
+ " %a antonym\n"
+ " %y synonym\n"
+ " %x example\n"
+ " %u usage label\n"
+ " %h paraphrase\n"
+ "\n"
+ " %d last query date (from;to)\n"
+ " %w dito, compressed and deprecated\n"
+ " %g grade (from;to)\n"
+ " %c count (from;to)\n"
+ " %b bad count (from;to)\n"
+ "\n"
+ "\nValid xml means:\n"
+ " - Close all tags\n"
+ " - Keep proper hierarchy\n"
+ " - All attributes are quoted\n"));
+
+ domDoc.appendChild(domComment);
+
+ domElementKvtml.setAttribute(KV_ENCODING, (QString)"UTF-8");
+
+ domElementKvtml.setAttribute(KV_GENERATOR, generator);
+ domElementKvtml.setAttribute(KV_COLS, m_doc->numLangs() );
+ domElementKvtml.setAttribute(KV_LINES, m_doc->numEntries() );
+
+ if (!m_doc->doctitle.isEmpty())
+ domElementKvtml.setAttribute(KV_TITLE, m_doc->doctitle);
+
+ if (!m_doc->author.isEmpty())
+ domElementKvtml.setAttribute(KV_AUTHOR, m_doc->getAuthor() );
+
+ if (!m_doc->license.isEmpty())
+ domElementKvtml.setAttribute(KV_LICENSE, m_doc->getLicense() );
+
+ if (!m_doc->doc_remark.isEmpty())
+ domElementKvtml.setAttribute(KV_DOC_REM, m_doc->getDocRemark() );
+
+ if (!saveLessonKvtMl(domDoc, domElementKvtml))
+ return false;
+
+ if (!saveArticleKvtMl(domDoc, domElementKvtml))
+ return false;
+
+ if (!saveConjugHeader(domDoc, domElementKvtml, m_doc->conjugations))
+ return false;
+
+ if (!saveOptionsKvtMl(domDoc, domElementKvtml))
+ return false;
+
+ if (!saveTypeNameKvtMl(domDoc, domElementKvtml))
+ return false;
+
+ if (!saveTenseNameKvtMl(domDoc, domElementKvtml))
+ return false;
+
+ if (!saveUsageNameKvtMl(domDoc, domElementKvtml))
+ return false;
+
+ QString q_org, q_trans;
+ vector<KEduVocExpression>::const_iterator first = m_doc->vocabulary.begin ();
+ m_doc->getQueryLang(q_org, q_trans);
+
+ int ent_no = 0;
+ int ent_percent = (int) m_doc->vocabulary.size () / 100;
+ float f_ent_percent = (int) m_doc->vocabulary.size () / 100.0;
+//TODO emit progressChanged(this, 0);
+
+ while (first != m_doc->vocabulary.end ())
+ {
+ QDomElement domElementExpression = domDoc.createElement(KV_EXPR);
+
+ ent_no++;
+ if (ent_percent != 0 && (ent_no % ent_percent) == 0 )
+//TODO emit progressChanged(this, ent_no / (int) f_ent_percent);
+
+ if ((*first).getLesson() != 0)
+ {
+ // entry belongs to lesson x
+ QString ls;
+ int lm = (*first).getLesson();
+ if (lm > (int) m_doc->lesson_descr.size() )
+ {
+ // should not be
+ kdError() << "index of lesson member too high: " << lm << endl;
+ lm = 0;
+ }
+ ls.setNum (lm);
+ domElementExpression.setAttribute (KV_LESS_MEMBER, ls);
+ }
+
+ if ((*first).isInQuery())
+ {
+ // entry was selected for query
+ domElementExpression.setAttribute (KV_SELECTED, (QString) "1");
+ }
+
+ if (!(*first).isActive())
+ {
+ // entry was inactive
+ domElementExpression.setAttribute (KV_INACTIVE, (QString) "1");
+ }
+
+ if ((*first).uniqueType() && !(*first).getType(0).isEmpty())
+ {
+ domElementExpression.setAttribute (KV_EXPRTYPE, (*first).getType(0));
+ }
+
+ QDomElement domElementOriginal = domDoc.createElement(KV_ORG);
+ if (first_expr)
+ {
+ // save space, only tell language in first entry
+ QString s;
+ s.setNum (m_doc->getSizeHint (0));
+ domElementOriginal.setAttribute(KV_SIZEHINT, s);
+
+ s = m_doc->getOriginalIdent().stripWhiteSpace();
+ if (s.isEmpty() )
+ s = "original";
+ domElementOriginal.setAttribute (KV_LANG, s);
+ if (s == q_org)
+ domElementOriginal.setAttribute(KV_QUERY, (QString) KV_O);
+ else if (s == q_trans)
+ domElementOriginal.setAttribute(KV_QUERY, (QString) KV_T);
+
+ }
+
+ if (!(*first).getRemark(0).isEmpty() )
+ domElementOriginal.setAttribute(KV_REMARK, (*first).getRemark(0));
+
+ if (!(*first).getSynonym(0).isEmpty() )
+ domElementOriginal.setAttribute(KV_SYNONYM, (*first).getSynonym(0));
+
+ if (!(*first).getExample(0).isEmpty() )
+ domElementOriginal.setAttribute(KV_EXAMPLE, (*first).getExample(0));
+
+ if (!(*first).getUsageLabel(0).isEmpty() )
+ domElementOriginal.setAttribute(KV_USAGE, (*first).getUsageLabel(0));
+
+ if (!(*first).getParaphrase(0).isEmpty() )
+ domElementOriginal.setAttribute(KV_PARAPHRASE, (*first).getParaphrase(0));
+
+ if (!(*first).getAntonym(0).isEmpty() )
+ domElementOriginal.setAttribute(KV_ANTONYM, (*first).getAntonym(0));
+
+ if (!(*first).getPronunce(0).isEmpty() )
+ domElementOriginal.setAttribute(KV_PRONUNCE, (*first).getPronunce(0));
+
+ if (!(*first).uniqueType() && !(*first).getType(0).isEmpty())
+ domElementOriginal.setAttribute(KV_EXPRTYPE, (*first).getType(0));
+
+ if (!saveMultipleChoice(domDoc, domElementOriginal, (*first).getMultipleChoice(0)))
+ return false;
+
+ QString s;
+ QString entype = s = (*first).getType(0);
+ int pos = s.find (QM_TYPE_DIV);
+ if (pos >= 0)
+ entype = s.left (pos);
+ else
+ entype = s;
+
+ if (entype == QM_VERB
+ && (*first).getConjugation(0).numEntries() > 0)
+ {
+ Conjugation conj = (*first).getConjugation(0);
+ if (!saveConjugEntry(domDoc, domElementOriginal, conj))
+ return false;
+ }
+ else if (entype == QM_ADJ
+ && !(*first).getComparison(0).isEmpty())
+ {
+ Comparison comp = (*first).getComparison(0);
+ if (!saveComparison(domDoc, domElementOriginal, comp))
+ return false;
+ }
+
+ QDomText domTextOriginal = domDoc.createTextNode((*first).getOriginal());
+ domElementOriginal.appendChild(domTextOriginal);
+ domElementExpression.appendChild(domElementOriginal);
+
+ int trans = 1;
+ while (trans < (int)m_doc->langs.size())
+ {
+ QDomElement domElementTranslation = domDoc.createElement(KV_TRANS);
+ if (first_expr)
+ {
+ // save space, only tell language in first entry
+ QString s;
+ s.setNum (m_doc->getSizeHint (trans));
+ domElementTranslation.setAttribute(KV_SIZEHINT, s);
+
+ s = m_doc->getIdent(trans).stripWhiteSpace();
+ if (s.isEmpty() )
+ {
+ s.setNum (trans);
+ s.insert (0, "translation ");
+ }
+ domElementTranslation.setAttribute(KV_LANG, s);
+ if (s == q_org)
+ domElementTranslation.setAttribute(KV_QUERY, (QString) KV_O);
+ else if (s == q_trans)
+ domElementTranslation.setAttribute(KV_QUERY, (QString) KV_T);
+ }
+
+ QString s1, s2;
+
+ if ((*first).getGrade(trans, false) != 0
+ ||(*first).getGrade(trans, true) != 0)
+ {
+ domElementTranslation.setAttribute(KV_GRADE, (*first).gradeStr(trans, false)
+ +';'
+ +(*first).gradeStr(trans, true));
+ }
+
+ if ((*first).getQueryCount(trans, false) != 0
+ ||(*first).getQueryCount(trans, true) != 0)
+ {
+ s1.setNum((*first).getQueryCount(trans, false));
+ s2.setNum((*first).getQueryCount(trans, true));
+ domElementTranslation.setAttribute(KV_COUNT, s1 +';' +s2);
+ }
+
+ if ((*first).getBadCount(trans, false) != 0
+ ||(*first).getBadCount(trans, true) != 0)
+ {
+ s1.setNum((*first).getBadCount(trans, false));
+ s2.setNum((*first).getBadCount(trans, true));
+ domElementTranslation.setAttribute(KV_BAD, s1 +';' +s2);
+ }
+
+ if ((*first).getQueryDate(trans, false) != 0
+ ||(*first).getQueryDate(trans, true) != 0)
+ {
+ s1.setNum((*first).getQueryDate(trans, false));
+ s2.setNum((*first).getQueryDate(trans, true));
+ domElementTranslation.setAttribute(KV_DATE, s1 +';' +s2);
+ }
+
+ if (!(*first).getRemark(trans).isEmpty() )
+ domElementTranslation.setAttribute(KV_REMARK, (*first).getRemark(trans));
+
+ if (!(*first).getFauxAmi(trans, false).isEmpty() )
+ domElementTranslation.setAttribute(KV_FAUX_AMI_F, (*first).getFauxAmi(trans, false));
+
+ if (!(*first).getFauxAmi(trans, true).isEmpty() )
+ domElementTranslation.setAttribute(KV_FAUX_AMI_T, (*first).getFauxAmi(trans, true));
+
+ if (!(*first).getSynonym(trans).isEmpty() )
+ domElementTranslation.setAttribute(KV_SYNONYM, (*first).getSynonym(trans));
+
+ if (!(*first).getExample(trans).isEmpty() )
+ domElementTranslation.setAttribute(KV_EXAMPLE, (*first).getExample(trans));
+
+ if (!(*first).getUsageLabel(trans).isEmpty() )
+ domElementTranslation.setAttribute(KV_USAGE, (*first).getUsageLabel(trans));
+
+ if (!(*first).getParaphrase(trans).isEmpty() )
+ domElementTranslation.setAttribute(KV_PARAPHRASE, (*first).getParaphrase(trans));
+
+ if (!(*first).getAntonym(trans).isEmpty() )
+ domElementTranslation.setAttribute(KV_ANTONYM, (*first).getAntonym(trans));
+
+ if (!(*first).getPronunce(trans).isEmpty() )
+ domElementTranslation.setAttribute(KV_PRONUNCE, (*first).getPronunce(trans));
+
+ if (!(*first).uniqueType() && !(*first).getType(trans).isEmpty())
+ domElementTranslation.setAttribute(KV_EXPRTYPE, (*first).getType(trans));
+
+ // only save conjugations when type == verb
+
+ if (!saveMultipleChoice(domDoc, domElementTranslation, (*first).getMultipleChoice(trans)))
+ return false;
+
+ QString s;
+ QString entype = s = (*first).getType(0);
+ int pos = s.find (QM_TYPE_DIV);
+ if (pos >= 0)
+ entype = s.left (pos);
+ else
+ entype = s;
+
+ if (entype == QM_VERB
+ && (*first).getConjugation(trans).numEntries() > 0)
+ {
+ Conjugation conj = (*first).getConjugation(trans);
+ if (!saveConjugEntry(domDoc, domElementTranslation, conj))
+ return false;
+ }
+
+ if (entype == QM_ADJ
+ && !(*first).getComparison(trans).isEmpty())
+ {
+ Comparison comp = (*first).getComparison(trans);
+ if (!saveComparison(domDoc, domElementTranslation, comp))
+ return false;
+ }
+
+ QDomText domTextTranslation = domDoc.createTextNode((*first).getTranslation(trans));
+ domElementTranslation.appendChild(domTextTranslation);
+ domElementExpression.appendChild(domElementTranslation);
+
+ trans++;
+ }
+
+ domElementKvtml.appendChild(domElementExpression);
+
+ first++;
+ first_expr = false;
+ }
+
+ domDoc.appendChild(domElementKvtml);
+
+ QTextStream ts( m_outputFile );
+ ts.setEncoding( QTextStream::UnicodeUTF8 );
+ ts << domDoc.toString();
+
+// TODO setModified (false);
+ return true;
+
+}
+
diff --git a/kanagram/src/keduvockvtmlwriter.h b/kanagram/src/keduvockvtmlwriter.h
new file mode 100644
index 00000000..dd9e6a78
--- /dev/null
+++ b/kanagram/src/keduvockvtmlwriter.h
@@ -0,0 +1,99 @@
+/***************************************************************************
+ export a KEduVocDocument to a KVTML file
+ -----------------------------------------------------------------------
+ copyright : (C) 1999-2001 Ewald Arnold
+ (C) 2001 The KDE-EDU team
+ (C) 2005 Eric Pignet
+ email : eric at erixpage.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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KEDUVOCKVTMLWRITER_H
+#define KEDUVOCKVTMLWRITER_H
+
+#include <qfile.h>
+#include <qdom.h>
+
+//#include "keduvocdocument.h"
+#include "grammarmanager.h"
+#include "multiplechoice.h"
+
+class KEduVocDocument;
+
+// internal types, indented are subtypes
+
+#define QM_VERB "v" // go
+#define QM_VERB_IRR "ir"
+#define QM_VERB_REG "re"
+#define QM_NOUN "n" // table, coffee
+#define QM_NOUN_F "f"
+#define QM_NOUN_M "m"
+#define QM_NOUN_S "s"
+#define QM_NAME "nm"
+#define QM_ART "ar" // article
+#define QM_ART_DEF "def" // definite a/an
+#define QM_ART_IND "ind" // indefinite the
+#define QM_ADJ "aj" // adjective expensive, good
+#define QM_ADV "av" // adverb today, strongly
+#define QM_PRON "pr" // pronoun you, she
+#define QM_PRON_POS "pos" // possessive my, your
+#define QM_PRON_PER "per" // personal
+#define QM_PHRASE "ph"
+#define QM_NUM "num" // numeral
+#define QM_NUM_ORD "ord" // ordinal first, second
+#define QM_NUM_CARD "crd" // cardinal one, two
+#define QM_INFORMAL "ifm"
+#define QM_FIG "fig"
+#define QM_CON "con" // conjuncton and, but
+#define QM_PREP "pre" // preposition behind, between
+#define QM_QUEST "qu" // question who, what
+
+// type delimiters
+
+#define QM_USER_TYPE "#" // designates number of user type
+#define QM_TYPE_DIV ":" // divide main from subtype
+
+/**
+@author Eric Pignet
+*/
+class KEduVocKvtmlWriter
+{
+public:
+ KEduVocKvtmlWriter(QFile *file);
+ ~KEduVocKvtmlWriter();
+
+ bool writeDoc(KEduVocDocument *doc, const QString &generator);
+
+ bool saveLessonKvtMl (QDomDocument &domDoc, QDomElement &domElementParent);
+ bool saveTypeNameKvtMl (QDomDocument &domDoc, QDomElement &domElementParent);
+ bool saveTenseNameKvtMl (QDomDocument &domDoc, QDomElement &domElementParent);
+ bool saveUsageNameKvtMl (QDomDocument &domDoc, QDomElement &domElementParent);
+ bool saveOptionsKvtMl (QDomDocument &domDoc, QDomElement &domElementParent);
+ bool saveArticleKvtMl (QDomDocument &domDoc, QDomElement &domElementParent);
+ bool saveConjugHeader (QDomDocument &domDoc, QDomElement &domElementParent,
+ vector<Conjugation> &curr_conjug);
+ bool saveConjug (QDomDocument &domDoc, QDomElement &domElementParent,
+ const Conjugation &curr_conjug, QString type);
+ bool saveConjugEntry (QDomDocument &domDoc, QDomElement &domElementParent,
+ Conjugation &curr_conjug);
+
+ bool saveComparison (QDomDocument &domDoc, QDomElement &domElementParent,
+ const Comparison &comp);
+
+ bool saveMultipleChoice(QDomDocument &domDoc, QDomElement &domElementParent,
+ const MultipleChoice &mc);
+
+private:
+ QFile *m_outputFile;
+ KEduVocDocument *m_doc;
+};
+
+#endif
diff --git a/kanagram/src/leitnerbox.cpp b/kanagram/src/leitnerbox.cpp
new file mode 100644
index 00000000..5a86d1fb
--- /dev/null
+++ b/kanagram/src/leitnerbox.cpp
@@ -0,0 +1,70 @@
+//
+// C++ Implementation: leitnerbox
+//
+// Description:
+//
+//
+// Author: Martin Pfeiffer <martin-pfeiffer-bensheim@web.de>, (C) 2005
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "leitnerbox.h"
+
+LeitnerBox::LeitnerBox()
+{
+}
+
+
+LeitnerBox::~LeitnerBox()
+{
+}
+
+int LeitnerBox::getVocabCount()
+{
+ return m_vocabCount;
+}
+
+void LeitnerBox::setVocabCount( int count )
+{
+ m_vocabCount = count;
+}
+
+const QString& LeitnerBox::getBoxName() const
+{
+ return m_name;
+}
+
+LeitnerBox* LeitnerBox::getCorrectWordBox()
+{
+ return m_correctWordBox;
+}
+
+LeitnerBox* LeitnerBox::getWrongWordBox()
+{
+ return m_wrongWordBox;
+}
+
+void LeitnerBox::setBoxName( const QString& name )
+{
+ m_name = name;
+}
+
+void LeitnerBox::setCorrectWordBox( LeitnerBox* correctWordBox )
+{
+ m_correctWordBox = correctWordBox;
+}
+
+void LeitnerBox::setWrongWordBox( LeitnerBox* wrongWordBox )
+{
+ m_wrongWordBox = wrongWordBox;
+}
+
+bool LeitnerBox::operator ==( const LeitnerBox& a ) const
+{
+ if( a.getBoxName() == getBoxName() )
+ return true;
+ else
+ return false;
+}
+
diff --git a/kanagram/src/leitnerbox.h b/kanagram/src/leitnerbox.h
new file mode 100644
index 00000000..bf20d6a6
--- /dev/null
+++ b/kanagram/src/leitnerbox.h
@@ -0,0 +1,49 @@
+//
+// C++ Interface: leitnerbox
+//
+// Description:
+//
+//
+// Author: Martin Pfeiffer <martin-pfeiffer-bensheim@web.de>, (C) 2005
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef LEITNERBOX_H
+#define LEITNERBOX_H
+
+#include <qstring.h>
+
+/**
+@author Martin Pfeiffer
+*/
+class LeitnerBox
+{
+public:
+ LeitnerBox();
+
+ ~LeitnerBox();
+
+ void setCorrectWordBox( LeitnerBox* ); //sets the correct word box
+ void setWrongWordBox( LeitnerBox* ); //sets the wrong word box
+ void setBoxName( const QString& ); //sets the boxes name
+
+ void setVocabCount( int count );
+ int getVocabCount();
+
+ LeitnerBox* getCorrectWordBox();
+ LeitnerBox* getWrongWordBox();
+ const QString& getBoxName() const;
+
+ bool operator == ( const LeitnerBox& a ) const;
+
+private:
+ QString m_name;
+
+ int m_vocabCount;
+
+ LeitnerBox* m_wrongWordBox;
+ LeitnerBox* m_correctWordBox;
+};
+
+#endif
diff --git a/kanagram/src/leitnersystem.cpp b/kanagram/src/leitnersystem.cpp
new file mode 100644
index 00000000..3f633526
--- /dev/null
+++ b/kanagram/src/leitnersystem.cpp
@@ -0,0 +1,192 @@
+//
+// C++ Implementation: leitnersystem
+//
+// Description:
+//
+//
+// Author: Martin Pfeiffer <martin-pfeiffer-bensheim@web.de>, (C) 2005
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "leitnersystem.h"
+#include <kdebug.h>
+
+LeitnerSystem::LeitnerSystem(QValueList<LeitnerBox>& boxes, QString name)
+{
+ if( !boxes.empty() )
+ m_boxes = boxes;
+
+ if( name.isNull() )
+ m_systemName = name;
+}
+
+LeitnerSystem::LeitnerSystem()
+{
+}
+
+LeitnerSystem::~LeitnerSystem()
+{
+}
+
+QStringList LeitnerSystem::getBoxNameList()
+{
+ QStringList boxNameList;
+ QValueList<LeitnerBox>::iterator it;
+
+
+ for(it = m_boxes.begin(); it != m_boxes.end(); ++it)
+ {
+ boxNameList.append((*it).getBoxName());
+ }
+
+ return boxNameList;
+}
+
+int LeitnerSystem::getNumberOfBoxes()
+{
+ return m_boxes.count();
+}
+
+LeitnerBox* LeitnerSystem::getBoxWithNumber( int number )
+{
+ return &m_boxes[ number ];
+}
+
+LeitnerBox* LeitnerSystem::getBoxWithName( const QString& name )
+{
+ QValueList<LeitnerBox>::iterator it;
+
+ for(it = m_boxes.begin(); it != m_boxes.end(); ++it)
+ {
+ if((*it).getBoxName() == name)
+ return &(*it);
+ }
+
+ return 0;
+}
+
+QString& LeitnerSystem::getSystemName()
+{
+ return m_systemName;
+}
+
+const QString& LeitnerSystem::getNextBox( QString& previousBox )
+{
+ for( int i = 0; i < m_boxes.count(); i++ )
+ {
+ if( m_boxes[i].getVocabCount() > 0 )
+ return getBox( i );
+ }
+
+ return QString::null;
+}
+
+const QString& LeitnerSystem::getCorrectBox( int box )
+{
+ return m_boxes[ box ].getCorrectWordBox()->getBoxName();
+}
+
+const QString& LeitnerSystem::getWrongBox( int box )
+{
+ return m_boxes[ box ].getWrongWordBox()->getBoxName();
+}
+
+int LeitnerSystem::getWrongBoxNumber( int box )
+{
+ return getNumber( m_boxes[ box ].getWrongWordBox() );
+}
+
+int LeitnerSystem::getCorrectBoxNumber( int box )
+{
+ return getNumber( m_boxes[ box ].getCorrectWordBox() );
+}
+
+void LeitnerSystem::deleteBox( int box )
+{
+ m_boxes.remove( m_boxes.at( box ) );
+}
+
+void LeitnerSystem::deleteBox( LeitnerBox* box )
+{
+ m_boxes.remove( *box );
+}
+
+bool LeitnerSystem::insertBox( const QString& name, int correctWordBox, int wrongWordBox )
+{
+ if( getBoxNameList().contains( name ) != 0 )
+ return false;
+
+ LeitnerBox tmpBox;
+ tmpBox.setBoxName( name );
+ tmpBox.setCorrectWordBox( getBoxWithNumber( correctWordBox ) );
+ tmpBox.setWrongWordBox( getBoxWithNumber( wrongWordBox ) );
+
+ m_boxes.append( tmpBox );
+ return true;
+}
+
+void LeitnerSystem::setSystemName( const QString& name )
+{
+ m_systemName = name;
+}
+
+int LeitnerSystem::getNumber( LeitnerBox* box )
+{
+ if( m_boxes.findIndex( *box ) == -1 )
+ kdDebug() << "muhaha" << endl;
+ return m_boxes.findIndex( *box );
+}
+
+bool LeitnerSystem::setBoxName( int box, const QString& name )
+{
+ if( getBoxWithName( name ) == 0 || getBoxWithName( name ) == getBoxWithNumber( box ) )
+ {
+ getBoxWithNumber( box )->setBoxName( name );
+
+ return true;
+ }
+ else
+ return false;
+}
+
+bool LeitnerSystem::setBoxName( LeitnerBox* box, const QString& name )
+{
+ if( getBoxWithName( name ) == 0 || getBoxWithName( name ) == box )
+ {
+ box->setBoxName( name );
+
+ return true;
+ }
+ else
+ return false;
+}
+
+bool LeitnerSystem::insertBox( const QString& name )
+{
+ if( getBoxNameList().contains( name ) != 0 )
+ return false;
+
+ LeitnerBox tmpBox;
+ tmpBox.setBoxName( name );
+ //tmpBox.setVocabCount( count );
+
+ m_boxes.append( tmpBox );
+ return true;
+}
+
+void LeitnerSystem::setCorrectBox( const QString& box, const QString& correctWordBox )
+{
+ getBoxWithName( box )->setCorrectWordBox( getBoxWithName( correctWordBox ) );
+}
+
+void LeitnerSystem::setWrongBox( const QString& box, const QString& wrongWordBox )
+{
+ getBoxWithName( box )->setWrongWordBox( getBoxWithName( wrongWordBox ) );
+}
+
+const QString& LeitnerSystem::getBox( int i )
+{
+ return getBoxWithNumber( i )->getBoxName();
+}
+
diff --git a/kanagram/src/leitnersystem.h b/kanagram/src/leitnersystem.h
new file mode 100644
index 00000000..87e583d9
--- /dev/null
+++ b/kanagram/src/leitnersystem.h
@@ -0,0 +1,67 @@
+//
+// C++ Interface: leitnersystem
+//
+// Description:
+//
+//
+// Author: Martin Pfeiffer <martin-pfeiffer-bensheim@web.de>, (C) 2005
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qvaluelist.h>
+#include "leitnerbox.h"
+
+#ifndef LEITNERSYSTEM_H
+#define LEITNERSYSTEM_H
+
+
+/**
+@author Martin Pfeiffer
+*/
+class LeitnerSystem
+{
+public:
+ LeitnerSystem();
+ LeitnerSystem( QValueList<LeitnerBox>& boxes, QString name );
+
+ ~LeitnerSystem();
+
+ int getNumberOfBoxes(); //returns the number of boxes in the system
+ QStringList getBoxNameList(); //returns a list with the boxes names
+
+ QString& getSystemName(); //returns the systems name
+ void setSystemName( const QString& name ); //sets the systems name
+
+ LeitnerBox* getBoxWithNumber( int number ); //returns box by number
+ LeitnerBox* getBoxWithName( const QString& name );//returns box by name
+ int getNumber( LeitnerBox* box );
+ const QString& getBox( int i );
+
+ const QString& getNextBox( QString& previousBox ); //returns the next box for the next question
+
+ const QString& getCorrectBox( int box ); //returns the correct word box of "int box"
+ const QString& getWrongBox( int box ); //returns the wrong word box of "int box"
+ int getWrongBoxNumber( int box );
+ int getCorrectBoxNumber( int box );
+ void setCorrectBox( const QString& box, const QString& correctWordBox );
+ void setWrongBox( const QString& box, const QString& wrongWordBox );
+ bool setBoxName( int box, const QString& name );
+ bool setBoxName( LeitnerBox* box, const QString& name );
+
+ //inserts a box with number, name, correct and wrong word box
+ bool insertBox( const QString& name, int correctWordBox, int wrongWordBox );
+ bool insertBox( const QString& name );
+ void deleteBox( int box );
+ void deleteBox( LeitnerBox* box );
+
+private:
+ QString m_systemName; //the systems name
+
+ QValueList<LeitnerBox> m_boxes;
+};
+
+#endif
diff --git a/kanagram/src/leitnersystemview.cpp b/kanagram/src/leitnersystemview.cpp
new file mode 100644
index 00000000..f8736471
--- /dev/null
+++ b/kanagram/src/leitnersystemview.cpp
@@ -0,0 +1,216 @@
+//
+// C++ Implementation: leitnersystemview
+//
+// Description:
+//
+//
+// Author: Martin Pfeiffer <martin-pfeiffer-bensheim@web.de>, (C) 2005
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "leitnersystemview.h"
+
+#include "leitnersystem.h"
+//#include "kwordquiz.h"
+
+#include <stdlib.h>
+#include <kiconloader.h>
+#include <qpainter.h>
+
+#include <kdebug.h>
+
+LeitnerSystemView::LeitnerSystemView(QWidget * parent, const char* name, WFlags f)
+ : QScrollView(parent, name, f)
+{
+ m_highlightedBox = -1;
+}
+
+
+LeitnerSystemView::~LeitnerSystemView()
+{
+}
+
+void LeitnerSystemView::drawSystem(QPainter* p)
+{
+ kdDebug() << "drawSystem( )" << endl;
+
+
+ //einarbeiten von m_selectedBox... aus prefLeitner
+
+ m_imageY = height() / 2 - 32;
+
+ //draw the boxes' icons
+ for(int i = 0; i < m_leitnerSystem->getNumberOfBoxes(); i++)
+ {
+ if(i == m_highlightedBox)
+ {
+ //p->drawPixmap(12 + i * 64 + i*10, m_imageY, KGlobal::iconLoader()->loadIcon("leitnerbox", KIcon::Panel));
+ p->drawRect(12 + i * 64 + i*10, m_imageY,64,64);
+ p->fillRect(12 + i * 64 + i*10, m_imageY,64,64, QBrush(red));
+ }
+ else
+ { //for each box 74 = 64(pixmap) + 10(distance between two boxes)
+ //p->drawPixmap(12 + i * 74, m_imageY, KGlobal::iconLoader()->loadIcon("leitnerbox", KIcon::Panel));
+ p->drawRect(12 + i * 64 + i*10, m_imageY,64,64);
+ }
+ }
+}
+
+void LeitnerSystemView::drawConnections(QPainter* p)
+{
+ //dist = number of boxes that are in between the two boxes
+ //width = width of the rect for the arc
+ int dist, width = 0;
+ int numberOfBoxes = m_leitnerSystem->getNumberOfBoxes();
+
+ p->setPen( QPen(green, 2) );
+
+ //paint the connections for the correct word boxes, above the boxes
+ for(int i = 0; i < numberOfBoxes; i++)
+ {
+ dist = m_leitnerSystem->getCorrectBoxNumber( i ) - i;
+
+ if(dist <= 0)
+ {
+ // (dist*(-1) -1)*64 == for each box in between take 64
+ // dist*(-1)*10 == the gaps in between
+ // 2*22; 2*21 == the distances of the endings on the picture
+ width = (dist*(-1) -1)*64 + dist*(-1)*10 + 2*22 + 2*21;
+
+ p->drawArc( 12 + (dist+i)*74 + 21, m_imageY-(width/3), width, /*(height()/2 - 12-32) *2*/ width/3*2, 0, 180*16);
+ }
+ else
+ {
+ width = (dist-1)*64 + dist*10 + 2*21;
+ p->drawArc(12 + i*74 + 21+22 ,m_imageY-(width/3) , width, /*(height()/2 - 12-32) *2*/width/3*2, 0, 180*16);
+ }
+
+ }
+
+ //paint the connections for the wrong word boxes, below the boxes
+ p->setPen(QPen(red, 2));
+
+ for(int i = 0; i < numberOfBoxes; i++)
+ {
+ dist = m_leitnerSystem->getWrongBoxNumber( i ) - i;
+
+ if(dist <= 0)
+ {
+ width = (dist*(-1) -1)*64 + dist*(-1)*10 + 2*22 + 2*21;
+ p->drawArc(12+ (dist+i)*74 + 21 ,m_imageY+64-width/3 , width, width/3*2 , 180*16, 180*16);
+ }
+ else
+ {
+ width = (dist-1)*64 + dist*10 + 2*21;
+ p->drawArc(12 + i*74 + 21+22 ,m_imageY+64-width/3 , width, width/3*2, 180*16, 180*16);
+ }
+ }
+
+}
+
+void LeitnerSystemView::setSystem(LeitnerSystem* leitnersystem)
+{
+ m_leitnerSystem = leitnersystem;
+
+ //calculate the new sizes
+ calculateSize();
+ updateContents();
+ //repaint
+ //update();
+ //QPainter* p = new QPainter(this);
+ //drawContents( p, 0, 0, 0, 0 );
+}
+
+void LeitnerSystemView::highlightBox(int box)
+{
+ m_highlightedBox = box;
+ updateContents();
+}
+
+void LeitnerSystemView::drawContents(QPainter* p, int clipx, int clipy, int clipw, int cliph)
+{
+ kdDebug() << "drawContents" << endl;
+ p->eraseRect(0,0,width(),height());
+
+ drawSystem( p );
+
+ drawConnections( p );
+}
+
+void LeitnerSystemView::calculateSize()
+{
+ //margin = 12
+ //distance between boxes = 10
+ //boxes = 64*64
+
+ int numberOfBoxes = m_leitnerSystem->getNumberOfBoxes();
+ QString x;
+ int height, dist, tmpMaxC, tmpMaxW;
+ tmpMaxC = 0;
+ tmpMaxW = 0;
+ height = 0;
+
+ for(int i = 0; i < numberOfBoxes; i++)
+ {
+ dist = m_leitnerSystem->getCorrectBoxNumber( i ) - i;
+
+ if( abs(dist) >= abs(tmpMaxC) )
+ tmpMaxC = dist;
+
+ dist = m_leitnerSystem->getWrongBoxNumber( i ) - i;
+
+ if( abs(dist) >= abs(tmpMaxW) )
+ tmpMaxW = dist;
+ }
+
+ if( tmpMaxC <= 0 )
+ height += (( abs(tmpMaxC) -1)*64 + abs(tmpMaxC)*10 + 2*22 + 2*21)/3;
+ else
+ height += (( tmpMaxC-1)*64 + tmpMaxC*10 + 2*21)/3;
+
+ if( tmpMaxW <= 0 )
+ height += (( abs(tmpMaxW) -1)*64 + abs(tmpMaxW)*10 + 2*22 + 2*21)/3;
+ else
+ height += (( tmpMaxW-1)*64 + tmpMaxW*10 + 2*21)/3;
+
+ height += 24+64;
+
+ resizeContents( numberOfBoxes * 64 + (numberOfBoxes - 1)*10 + 2 * 12, height );
+ setMinimumSize( numberOfBoxes * 64 + (numberOfBoxes - 1)*10 + 2 * 12, height );
+}
+
+void LeitnerSystemView::mousePressEvent(QMouseEvent* e)
+{
+ kdDebug() << "mouseClick" << endl;
+ //if the user has clicked into a box
+ if(e->y() > m_imageY && e->y() < m_imageY + 64 && e->x() < width()-13)
+ {
+ int d = (e->x()-12)/74;
+
+ if((e->x()-12-74*d) <= 64)
+ {
+ //signal for prefLeitner to set the comboboxes to the clicked box
+ emit boxClicked( d );
+ m_highlightedBox = d;
+
+ updateContents();
+ }
+ else
+ {
+ emit boxClicked( -1 );
+ m_highlightedBox = -1;
+
+ updateContents();
+ }
+ }
+ else
+ {
+ emit boxClicked( -1 );
+ m_highlightedBox = -1;
+
+ updateContents();
+ }
+}
+
+
diff --git a/kanagram/src/leitnersystemview.h b/kanagram/src/leitnersystemview.h
new file mode 100644
index 00000000..be52bc0b
--- /dev/null
+++ b/kanagram/src/leitnersystemview.h
@@ -0,0 +1,57 @@
+//
+// C++ Interface: leitnersystemview
+//
+// Description:
+//
+//
+// Author: Martin Pfeiffer <martin-pfeiffer-bensheim@web.de>, (C) 2005
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef LEITNERSYSTEMVIEW_H
+#define LEITNERSYSTEMVIEW_H
+
+#include <qscrollview.h>
+#include <qpixmap.h>
+
+class LeitnerSystem;
+
+
+/**
+@author Martin Pfeiffer
+*/
+
+class LeitnerSystemView : public QScrollView
+{
+ Q_OBJECT
+
+public:
+ LeitnerSystemView(QWidget* parent = 0, const char* name = 0, WFlags f = 0);
+
+ ~LeitnerSystemView();
+
+ void setSystem(LeitnerSystem* system); //set a new system to view on
+ void highlightBox(int box); //highlight a box
+
+signals:
+ void boxClicked(int box); //is emited if the user clicks on a box
+
+protected:
+ virtual void drawContents(QPainter* p, int clipx, int clipy, int clipw, int cliph);
+ virtual void mousePressEvent(QMouseEvent* e);
+
+private:
+ LeitnerSystem* m_leitnerSystem; //the system which is shown
+
+ void drawSystem(QPainter*); //paints the boxes
+ void drawConnections(QPainter*); //paints the arrows between the boxes
+ void calculateSize();
+
+ //QRect m_viewArea;
+ int m_imageY; //high border of the images
+ int m_distPixmap;
+ int m_highlightedBox; //the box which is currently highlighted
+};
+
+#endif
diff --git a/kanagram/src/main.cpp b/kanagram/src/main.cpp
new file mode 100644
index 00000000..ec0265b4
--- /dev/null
+++ b/kanagram/src/main.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joshua Keel *
+ * joshuakeel@gmail.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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kprocess.h>
+#include <kstandarddirs.h>
+
+#include "kanagram.h"
+#include "kanagramsettings.h"
+
+int main(int argc, char *argv[])
+{
+ KAboutData about("kanagram", I18N_NOOP("Kanagram"), "0.1", I18N_NOOP("An anagram game"), KAboutData::License_GPL, "© 2005 Joshua Keel\n© 2005 Danny Allen");
+ about.addAuthor("Joshua Keel", I18N_NOOP("Coding"), "joshuakeel@gmail.com");
+ about.addAuthor("Danny Allen", I18N_NOOP("Design, Graphics and many Vocabularies"), "danny@dannyallen.co.uk");
+ about.addCredit("Artemiy Pavlov", I18N_NOOP("Sound effects"), 0, "http://artemiolabs.com");
+ KCmdLineArgs::init(argc, argv, &about);
+ KApplication app;
+ app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
+
+ KanagramSettings::setJustGotFont(false);
+ QFont f("squeaky chalk sound");
+ if (!QFontInfo(f).exactMatch())
+ {
+ KanagramSettings::setUseStandardFonts(true);
+ }
+ if (KanagramSettings::dataLanguage().isEmpty())
+ {
+ QStringList userLanguagesCode = KGlobal::locale()->languageList();
+ QStringList::const_iterator itEnd = userLanguagesCode.end();
+ QStringList::const_iterator it = userLanguagesCode.begin();
+ for ( ; it != itEnd; ++it)
+ {
+ QStringList mdirs = KGlobal::dirs()->findDirs("appdata", "data/" + *it);
+ if (!mdirs.isEmpty()) break;
+ }
+ if (it == itEnd) KanagramSettings::setDataLanguage("en");
+ else KanagramSettings::setDataLanguage(*it);
+ }
+
+ app.setTopWidget(new Kanagram());
+ return app.exec();
+}
+
diff --git a/kanagram/src/mainsettings.cpp b/kanagram/src/mainsettings.cpp
new file mode 100644
index 00000000..660a1c5c
--- /dev/null
+++ b/kanagram/src/mainsettings.cpp
@@ -0,0 +1,161 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joshua Keel *
+ * joshuakeel@gmail.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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <qdir.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qpushbutton.h>
+
+#include <kdebug.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kconfigdialog.h>
+#include <kmessagebox.h>
+#include <kio/netaccess.h>
+
+#include "mainsettings.h"
+#include "kanagramsettings.h"
+
+MainSettings::MainSettings(QWidget *parent) : MainSettingsWidget(parent)
+{
+ m_parent = (KConfigDialog*)parent;
+
+ connect(parent, SIGNAL(applyClicked()), this, SLOT(slotChangeTranslation()));
+ connect(cboxTranslation, SIGNAL(activated(int)), this, SLOT(slotUpdateParent()));
+
+ setupTranslations();
+
+ QStringList languageNames = m_languageCodeMap.keys();
+ languageNames.sort();
+ cboxTranslation->insertStringList(languageNames);
+
+ //the language code/name
+ KConfig entry(locate("locale", "all_languages"));
+ QString code = KanagramSettings::dataLanguage();
+ entry.setGroup(code);
+ if (code == "sr")
+ cboxTranslation->setCurrentText(entry.readEntry("Name")+" ("+i18n("Cyrillic")+")");
+ else if (code == "sr@Latn")
+ {
+ entry.setGroup("sr");
+ cboxTranslation->setCurrentText(entry.readEntry("Name")+" ("+i18n("Latin")+")");
+ }
+ else
+ cboxTranslation->setCurrentText(entry.readEntry("Name"));
+
+ QFont f("squeaky chalk sound");
+ if (KanagramSettings::justGotFont())
+ {
+ getFontsButton->hide();
+ kcfg_useStandardFonts->setEnabled(false);
+ }
+ else
+ {
+ if (!QFontInfo(f).exactMatch())
+ {
+ kcfg_useStandardFonts->setEnabled(false);
+ connect(getFontsButton, SIGNAL(pressed()), this, SLOT(getAndInstallFont()));
+ }
+ else
+ {
+ getFontsButton->hide();
+ }
+ }
+}
+
+MainSettings::~MainSettings()
+{
+}
+
+void MainSettings::slotUpdateParent()
+{
+ m_parent->enableButtonApply(true);
+}
+
+void MainSettings::setupTranslations()
+{
+ m_languageCodeMap.clear();
+ QStringList languages, temp_languages;
+
+ //the program scans in kdereview/data/ to see what languages data is found
+ QStringList mdirs = KGlobal::dirs()->findDirs("appdata", "data/");
+
+ if (mdirs.isEmpty()) return;
+
+ for (QStringList::const_iterator it = mdirs.begin(); it != mdirs.end(); ++it )
+ {
+ QDir dir(*it);
+ temp_languages = dir.entryList(QDir::Dirs, QDir::Name);
+ temp_languages.remove(".");
+ temp_languages.remove("..");
+ for (QStringList::const_iterator it2 = temp_languages.begin(); it2 != temp_languages.end(); ++it2 )
+ {
+ if (!languages.contains(*it2)) languages.append(*it2);
+ }
+ }
+
+ if (languages.isEmpty())
+ return;
+
+ //the language code/name
+ KConfig entry(locate("locale", "all_languages"));
+ const QStringList::ConstIterator itEnd = languages.end();
+ for (QStringList::ConstIterator it = languages.begin(); it != itEnd; ++it) {
+ entry.setGroup(*it);
+ if (*it == "sr")
+ m_languageCodeMap.insert(entry.readEntry("Name")+" ("+i18n("Cyrillic")+")", "sr");
+ else if (*it == "sr@Latn")
+ {
+ entry.setGroup("sr");
+ m_languageCodeMap.insert(entry.readEntry("Name") + " ("+i18n("Latin")+")", "sr@Latn");
+ }
+ else
+ m_languageCodeMap.insert(entry.readEntry("Name"), *it);
+ }
+}
+
+void MainSettings::getAndInstallFont()
+{
+ bool success = KIO::NetAccess::copy("http://www.kde-edu.org/kanagram/chalk.ttf", "fonts:/Personal/", 0);
+ if (success)
+ {
+ getFontsButton->hide();
+ KMessageBox::information(this, i18n("Please restart Kanagram to activate the new font."));
+ kcfg_useStandardFonts->setChecked(false);
+ KanagramSettings::setUseStandardFonts(false);
+ KanagramSettings::setJustGotFont(true);
+ KanagramSettings::writeConfig();
+ }
+ else
+ {
+ KMessageBox::error(this, i18n("The font could not be installed. Please check that you are properly connected to the Internet."));
+ }
+}
+
+void MainSettings::slotChangeTranslation()
+{
+ kdDebug() << "Writing new default language: " << m_languageCodeMap[cboxTranslation->currentText()] << endl;
+ KanagramSettings::setDataLanguage(m_languageCodeMap[cboxTranslation->currentText()]);
+ KanagramSettings::writeConfig();
+}
+
+#include "mainsettings.moc"
diff --git a/kanagram/src/mainsettings.h b/kanagram/src/mainsettings.h
new file mode 100644
index 00000000..3763a047
--- /dev/null
+++ b/kanagram/src/mainsettings.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joshua Keel *
+ * joshuakeel@gmail.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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#ifndef MAINSETTINGS_H
+#define MAINSETTINGS_H
+
+#include "mainsettingswidget.h"
+
+class KConfigDialog;
+
+class MainSettings : public MainSettingsWidget
+{
+Q_OBJECT
+ public:
+ MainSettings(QWidget *parent);
+ ~MainSettings();
+
+ public slots:
+ void slotChangeTranslation();
+ void slotUpdateParent();
+
+ private slots:
+ void getAndInstallFont();
+
+ private:
+ QMap<QString, QString> m_languageCodeMap;
+ void setupTranslations();
+
+ KConfigDialog *m_parent;
+};
+
+#endif
+
diff --git a/kanagram/src/mainsettingswidget.ui b/kanagram/src/mainsettingswidget.ui
new file mode 100644
index 00000000..ef9d017e
--- /dev/null
+++ b/kanagram/src/mainsettingswidget.ui
@@ -0,0 +1,182 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>MainSettingsWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>MainSettingsWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>281</width>
+ <height>239</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>General</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This setting allows you to set the length of time that Kanagram's hint bubble is shown.</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Hints</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Auto-hide hints after:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>Do Not Auto-Hide Hints</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>3 Seconds</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>5 Seconds</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>7 Seconds</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>9 Seconds</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>kcfg_hintHideTime</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Vocabulary Options</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Play using:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>cboxTranslation</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>cboxTranslation</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_useStandardFonts</cstring>
+ </property>
+ <property name="text">
+ <string>Use standard fonts</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Uses a standard font for the chalkboard/interface.</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>getFontsButton</cstring>
+ </property>
+ <property name="text">
+ <string>Get Chalk Font</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_useSounds</cstring>
+ </property>
+ <property name="text">
+ <string>Use sou&amp;nds</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Turns sounds on/off.</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<tabstops>
+ <tabstop>kcfg_hintHideTime</tabstop>
+ <tabstop>kcfg_useSounds</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kanagram/src/multiplechoice.cpp b/kanagram/src/multiplechoice.cpp
new file mode 100644
index 00000000..b27350c3
--- /dev/null
+++ b/kanagram/src/multiplechoice.cpp
@@ -0,0 +1,120 @@
+/***************************************************************************
+
+ manage multiple choice suggestions for queries
+
+ -----------------------------------------------------------------------
+
+ begin : Mon Oct 29 18:09:29 1999
+
+ copyright : (C) 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de>
+ (C) 2001 The KDE-EDU team
+ (C) 2005 Peter Hedlund <peter.hedlund@kdemail.net>
+
+ -----------------------------------------------------------------------
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 "multiplechoice.h"
+
+MultipleChoice::MultipleChoice (
+ const QString &mc1,
+ const QString &mc2,
+ const QString &mc3,
+ const QString &mc4,
+ const QString &mc5
+ )
+{
+ setMC1 (mc1);
+ setMC2 (mc2);
+ setMC3 (mc3);
+ setMC4 (mc4);
+ setMC5 (mc5);
+}
+
+
+bool MultipleChoice::isEmpty() const
+{
+ return muc1.stripWhiteSpace().isEmpty()
+ && muc2.stripWhiteSpace().isEmpty()
+ && muc3.stripWhiteSpace().isEmpty()
+ && muc4.stripWhiteSpace().isEmpty()
+ && muc5.stripWhiteSpace().isEmpty();
+}
+
+
+void MultipleChoice::clear()
+{
+ muc1 = "";
+ muc2 = "";
+ muc3 = "";
+ muc4 = "";
+ muc5 = "";
+}
+
+
+QString MultipleChoice::mc (unsigned idx) const
+{
+ switch (idx) {
+ case 0: return muc1;
+ case 1: return muc2;
+ case 2: return muc3;
+ case 3: return muc4;
+ case 4: return muc5;
+ }
+ return "";
+}
+
+
+unsigned MultipleChoice::size()
+{
+ normalize();
+ unsigned num = 0;
+ if (!muc1.isEmpty() )
+ ++num;
+ if (!muc2.isEmpty() )
+ ++num;
+ if (!muc3.isEmpty() )
+ ++num;
+ if (!muc4.isEmpty() )
+ ++num;
+ if (!muc5.isEmpty() )
+ ++num;
+ return num;
+}
+
+
+void MultipleChoice::normalize()
+{
+ // fill from first to last
+
+ if (muc1.isEmpty()) {
+ muc1 = muc2;
+ muc2 = "";
+ }
+
+ if (muc2.isEmpty()) {
+ muc2 = muc3;
+ muc3 = "";
+ }
+
+ if (muc3.isEmpty()) {
+ muc3 = muc4;
+ muc4 = "";
+ }
+
+ if (muc4.isEmpty()) {
+ muc4 = muc5;
+ muc5 = "";
+ }
+
+}
+
diff --git a/kanagram/src/multiplechoice.h b/kanagram/src/multiplechoice.h
new file mode 100644
index 00000000..6a0b0500
--- /dev/null
+++ b/kanagram/src/multiplechoice.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+
+ manage multiple choice suggestions for queries
+
+ -----------------------------------------------------------------------
+
+ begin : Mon Oct 29 18:09:29 1999
+
+ copyright : (C) 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de>
+ (C) 2001 The KDE-EDU team
+ (C) 2005 Peter Hedlund <peter.hedlund@kdemail.net>
+
+ -----------------------------------------------------------------------
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 MultipleChoice_included
+#define MultipleChoice_included
+
+#include <qstring.h>
+
+#define MAX_MULTIPLE_CHOICE 5 // select one out of x
+
+class MultipleChoice
+{
+
+public:
+
+ MultipleChoice() {}
+
+ MultipleChoice (
+ const QString &mc1,
+ const QString &mc2,
+ const QString &mc3,
+ const QString &mc4,
+ const QString &mc5
+ );
+
+ void setMC1 (const QString &s) { muc1 = s; }
+ void setMC2 (const QString &s) { muc2 = s; }
+ void setMC3 (const QString &s) { muc3 = s; }
+ void setMC4 (const QString &s) { muc4 = s; }
+ void setMC5 (const QString &s) { muc5 = s; }
+
+ QString mc1 () const { return muc1; }
+ QString mc2 () const { return muc2; }
+ QString mc3 () const { return muc3; }
+ QString mc4 () const { return muc4; }
+ QString mc5 () const { return muc5; }
+
+ QString mc (unsigned idx) const;
+
+ bool isEmpty() const;
+ void normalize();
+ void clear();
+ unsigned size();
+
+protected:
+
+ QString muc1, muc2, muc3, muc4, muc5;
+};
+
+
+#endif // MultipleChoice_included
diff --git a/kanagram/src/newstuff.cpp b/kanagram/src/newstuff.cpp
new file mode 100644
index 00000000..19c28272
--- /dev/null
+++ b/kanagram/src/newstuff.cpp
@@ -0,0 +1,29 @@
+#include "newstuff.h"
+
+#include <qwidget.h>
+#include <qpushbutton.h>
+
+#include <kdebug.h>
+#include <knewstuff/downloaddialog.h>
+#include <knewstuff/knewstuff.h>
+#include <klocale.h>
+
+#include "kanagramsettings.h"
+#include "newstuffdialog.h"
+
+NewStuff::NewStuff(QWidget *parent) : NewStuffWidget(parent)
+{
+ connect(btnGetNew, SIGNAL(clicked()), this, SLOT(slotGetNewVocabs()));
+}
+
+NewStuff::~NewStuff()
+{
+}
+
+void NewStuff::slotGetNewVocabs()
+{
+ NewStuffDialog *nsd = new NewStuffDialog();
+ nsd->download();
+}
+
+#include "newstuff.moc"
diff --git a/kanagram/src/newstuff.h b/kanagram/src/newstuff.h
new file mode 100644
index 00000000..2429cca7
--- /dev/null
+++ b/kanagram/src/newstuff.h
@@ -0,0 +1,18 @@
+#ifndef NEWSTUFF_H
+#define NEWSTUFF_H
+
+#include "newstuffwidget.h"
+
+class NewStuff : public NewStuffWidget
+{
+Q_OBJECT
+ public:
+ NewStuff(QWidget *parent);
+ ~NewStuff();
+
+ private slots:
+ void slotGetNewVocabs();
+};
+
+#endif
+
diff --git a/kanagram/src/newstuffdialog.cpp b/kanagram/src/newstuffdialog.cpp
new file mode 100644
index 00000000..d58ad56d
--- /dev/null
+++ b/kanagram/src/newstuffdialog.cpp
@@ -0,0 +1,35 @@
+#include "newstuffdialog.h"
+
+#include <knewstuff/knewstuff.h>
+#include <knewstuff/entry.h>
+#include <klocale.h>
+#include <kio/netaccess.h>
+#include <kurl.h>
+#include <kstandarddirs.h>
+
+#include "kanagramsettings.h"
+
+NewStuffDialog::NewStuffDialog() : KNewStuff("kanagram/vocabulary", "http://kde-edu.org/kanagram/" + KanagramSettings::dataLanguage() + ".xml")
+{
+}
+
+NewStuffDialog::~NewStuffDialog()
+{
+}
+
+bool NewStuffDialog::install(const QString &fileName)
+{
+ return false;
+}
+
+QString NewStuffDialog::downloadDestination(KNS::Entry *entry)
+{
+ QString fileName = entry->payload().path();
+ fileName = fileName.section('/', -1);
+ return KGlobal::dirs()->saveLocation("data", "kanagram/data/" + KanagramSettings::dataLanguage()) + fileName;
+}
+
+bool NewStuffDialog::createUploadFile(const QString &fileName)
+{
+ return false;
+}
diff --git a/kanagram/src/newstuffdialog.h b/kanagram/src/newstuffdialog.h
new file mode 100644
index 00000000..f0441623
--- /dev/null
+++ b/kanagram/src/newstuffdialog.h
@@ -0,0 +1,17 @@
+#ifndef NEWSTUFFDIALOG_H
+#define NEWSTUFFDIALOG_H
+
+#include <knewstuff/knewstuff.h>
+
+class NewStuffDialog : public KNewStuff
+{
+ public:
+ NewStuffDialog();
+ ~NewStuffDialog();
+ bool install(const QString &fileName);
+ bool createUploadFile(const QString &fileName);
+ QString downloadDestination(KNS::Entry *entry);
+};
+
+#endif
+
diff --git a/kanagram/src/newstuffwidget.ui b/kanagram/src/newstuffwidget.ui
new file mode 100644
index 00000000..f1b1bb23
--- /dev/null
+++ b/kanagram/src/newstuffwidget.ui
@@ -0,0 +1,62 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>NewStuffWidget</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>NewStuffWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>347</width>
+ <height>301</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>New Stuff</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Kanagram allows you to download
+new data from the Internet.
+
+If you are connected to the Internet, press
+the button to get new vocabulary files.</string>
+ </property>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton" row="2" column="0">
+ <property name="name">
+ <cstring>btnGetNew</cstring>
+ </property>
+ <property name="text">
+ <string>Download New Vocabularies</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kanagram/src/vocabedit.cpp b/kanagram/src/vocabedit.cpp
new file mode 100644
index 00000000..7079e566
--- /dev/null
+++ b/kanagram/src/vocabedit.cpp
@@ -0,0 +1,199 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joshua Keel *
+ * joshuakeel@gmail.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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "vocabedit.h"
+
+#include <qpushbutton.h>
+#include <qlistbox.h>
+#include <qlineedit.h>
+#include <qfile.h>
+#include <qstring.h>
+#include <qvaluevector.h>
+
+#include <kstandarddirs.h>
+#include <kglobal.h>
+#include <kurl.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+
+#include "keduvocdocument.h"
+#include "keduvocexpression.h"
+#include "vocabsettings.h"
+#include "kanagramsettings.h"
+
+
+VocabEdit::VocabEdit(QWidget *parent, QString fileName) : VocabEditWidget(parent), m_fileName("")
+{
+ if(fileName != "")
+ {
+ m_fileName = fileName;
+ KEduVocDocument *doc = new KEduVocDocument(this);
+ doc->open(KURL(m_fileName), false);
+ for(int i = 0; i < doc->numEntries(); i++)
+ {
+ KEduVocExpression expr = *doc->getEntry(i);
+ m_vocabList.append(expr);
+ lboxWords->insertItem(doc->getEntry(i)->getOriginal());
+ }
+ txtVocabName->setText(doc->getTitle());
+ txtDescription->setText(doc->getDocRemark());
+ }
+
+ connect(btnSave, SIGNAL(clicked()), this, SLOT(slotSave()));
+ connect(btnNewWord, SIGNAL(clicked()), this, SLOT(slotNewWord()));
+ connect(btnRemoveWord, SIGNAL(clicked()), this, SLOT(slotRemoveWord()));
+ connect(btnClose, SIGNAL(clicked()), this, SLOT(slotClose()));
+
+ connect(txtWord, SIGNAL(textChanged(const QString &)), this, SLOT(slotWordTextChanged(const QString &)));
+ connect(txtHint, SIGNAL(textChanged(const QString &)), this, SLOT(slotHintTextChanged(const QString &)));
+
+ //Connect the name and description boxes to a general textChanged slot, so that we can keep track of
+ //whether they've been changed or not
+ connect(txtVocabName, SIGNAL(textChanged(const QString &)), this, SLOT(slotTextChanged(const QString &)));
+ connect(txtDescription, SIGNAL(textChanged(const QString &)), this, SLOT(slotTextChanged(const QString &)));
+
+ connect(lboxWords, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()));
+
+ //Has anything in the dialog changed?
+ m_textChanged = false;
+}
+
+VocabEdit::~VocabEdit()
+{
+}
+
+void VocabEdit::slotSave()
+{
+ KEduVocDocument *doc = new KEduVocDocument(this);
+ doc->setTitle(txtVocabName->text());
+ doc->setDocRemark(txtDescription->text());
+ for(uint i = 0; i < m_vocabList.size(); i++)
+ {
+ doc->appendEntry(&m_vocabList[i]);
+ }
+
+ QString fileName;
+ if(m_fileName == "")
+ {
+ fileName = KGlobal::dirs()->saveLocation("data", "kanagram/data/" + KanagramSettings::dataLanguage()) + txtVocabName->text().lower().replace(" ", "") + ".kvtml";
+ }
+ else
+ {
+ fileName = m_fileName;
+ }
+ doc->saveAs(this, KURL(fileName), KEduVocDocument::automatic, "kanagram");
+
+ VocabSettings *settings = (VocabSettings*)this->parentWidget();
+ settings->refreshView();
+
+ if(m_textChanged)
+ m_textChanged = false;
+}
+
+void VocabEdit::slotClose()
+{
+ //Has anything in the dialog changed?
+ if(m_textChanged && lboxWords->count() > 0)
+ {
+ int code = KMessageBox::warningYesNo(this, i18n("Would you like to save your changes?"), i18n("Save Changes Dialog"));
+ if(code == KMessageBox::Yes)
+ {
+ slotSave();
+ close();
+ }
+ else
+ close();
+ }
+ else
+ close();
+}
+
+void VocabEdit::slotNewWord()
+{
+ lboxWords->insertItem("New Item");
+ KEduVocExpression expr = KEduVocExpression();
+ m_vocabList.append(expr);
+
+ if(m_textChanged == false)
+ m_textChanged = true;
+}
+
+void VocabEdit::slotSelectionChanged()
+{
+ //A little hack to make things work right
+ disconnect(txtWord, SIGNAL(textChanged(const QString &)), this, SLOT(slotWordTextChanged(const QString &)));
+ disconnect(txtHint, SIGNAL(textChanged(const QString &)), this, SLOT(slotHintTextChanged(const QString &)));
+ if(lboxWords->currentItem() >= 0)
+ {
+ txtWord->setText(m_vocabList[lboxWords->currentItem()].getOriginal());
+ txtHint->setText(m_vocabList[lboxWords->currentItem()].getRemark(0));
+ }
+ connect(txtWord, SIGNAL(textChanged(const QString &)), this, SLOT(slotWordTextChanged(const QString &)));
+ connect(txtHint, SIGNAL(textChanged(const QString &)), this, SLOT(slotHintTextChanged(const QString &)));
+}
+
+void VocabEdit::slotWordTextChanged(const QString &changes)
+{
+ //Make sure there actually is a currentItem()
+ if(lboxWords->currentItem() != -1)
+ {
+ m_vocabList[lboxWords->currentItem()].setOriginal(changes);
+ lboxWords->changeItem(changes, lboxWords->currentItem());
+ }
+
+ if(m_textChanged == false)
+ m_textChanged = true;
+}
+
+void VocabEdit::slotHintTextChanged(const QString &changes)
+{
+ //Make sure there actually is a currentItem()
+ if(lboxWords->currentItem() != -1)
+ m_vocabList[lboxWords->currentItem()].setRemark(0, changes);
+
+ if(m_textChanged == false)
+ m_textChanged = true;
+}
+
+void VocabEdit::slotTextChanged(const QString &changes)
+{
+ //Make sure we know when text has been modified and not saved, so we
+ //can notify the user
+ if(m_textChanged == false)
+ m_textChanged = true;
+
+ //Make gcc happy
+ (void)changes;
+}
+
+void VocabEdit::slotRemoveWord()
+{
+ if (lboxWords->count()) {
+ m_vocabList.erase(m_vocabList.begin() + lboxWords->currentItem());
+ lboxWords->removeItem(lboxWords->currentItem());
+ }
+
+ if(m_textChanged == false)
+ m_textChanged = true;
+}
+
+#include "vocabedit.moc"
diff --git a/kanagram/src/vocabedit.h b/kanagram/src/vocabedit.h
new file mode 100644
index 00000000..342f71cb
--- /dev/null
+++ b/kanagram/src/vocabedit.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joshua Keel *
+ * joshuakeel@gmail.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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#ifndef VOCABEDIT_H
+#define VOCABEDIT_H
+
+#include "vocabeditwidget.h"
+
+#include <qvaluevector.h>
+
+class KEduVocExpression;
+
+class VocabEdit : public VocabEditWidget
+{
+Q_OBJECT
+ public:
+ VocabEdit(QWidget *parent);
+ VocabEdit(QWidget *parent, QString fileName);
+ ~VocabEdit();
+
+ public slots:
+ void slotSave();
+ void slotClose();
+ void slotNewWord();
+ void slotRemoveWord();
+ void slotSelectionChanged();
+ void slotWordTextChanged(const QString &changes);
+ void slotHintTextChanged(const QString &changes);
+ void slotTextChanged(const QString &changes);
+
+ private:
+ QValueVector<KEduVocExpression> m_vocabList;
+ QString m_fileName;
+ bool m_textChanged;
+};
+
+#endif
+
diff --git a/kanagram/src/vocabeditwidget.ui b/kanagram/src/vocabeditwidget.ui
new file mode 100644
index 00000000..d4d1229d
--- /dev/null
+++ b/kanagram/src/vocabeditwidget.ui
@@ -0,0 +1,228 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>VocabEditWidget</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>VocabEditWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>394</width>
+ <height>369</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Vocabulary Editor</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>btnSave</cstring>
+ </property>
+ <property name="text">
+ <string>Save</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>btnClose</cstring>
+ </property>
+ <property name="text">
+ <string>Close</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Description:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>txtDescription</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>The description of the vocabulary. If you're creating a new vocabulary, add a description so that users of your vocabulary will know what kinds of words it contains.</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>txtVocabName</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Vocabulary name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>txtVocabName</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>The name of the vocabulary you are editing.</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>txtDescription</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>btnRemoveWord</cstring>
+ </property>
+ <property name="text">
+ <string>Remove Word</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Removes the selected word.</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>btnNewWord</cstring>
+ </property>
+ <property name="text">
+ <string>New Word</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Creates a new word.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QListBox">
+ <property name="name">
+ <cstring>lboxWords</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>The list of words in the vocabulary.</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Word:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>txtWord</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>The selected word. This box allows you to edit the selected word.</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>txtHint</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>txtWord</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Hint:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>txtHint</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>The selected hint. Add a hint to aid in guessing the word.</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<tabstops>
+ <tabstop>txtVocabName</tabstop>
+ <tabstop>txtDescription</tabstop>
+ <tabstop>btnRemoveWord</tabstop>
+ <tabstop>btnNewWord</tabstop>
+ <tabstop>txtWord</tabstop>
+ <tabstop>txtHint</tabstop>
+ <tabstop>btnSave</tabstop>
+ <tabstop>btnClose</tabstop>
+ <tabstop>lboxWords</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kanagram/src/vocabsettings.cpp b/kanagram/src/vocabsettings.cpp
new file mode 100644
index 00000000..c7b41ba7
--- /dev/null
+++ b/kanagram/src/vocabsettings.cpp
@@ -0,0 +1,93 @@
+#include "vocabsettings.h"
+#include "vocabedit.h"
+
+#include <qpushbutton.h>
+
+#include <kdebug.h>
+#include <kstandarddirs.h>
+#include <qstringlist.h>
+#include <qlistview.h>
+#include <qvaluevector.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+
+#include <kurl.h>
+
+#include "keduvocdocument.h"
+#include "kanagramsettings.h"
+
+VocabSettings::VocabSettings(QWidget *parent) : VocabSettingsWidget(parent)
+{
+ connect(btnCreateNew, SIGNAL(clicked()), this, SLOT(slotCreateNew()));
+ connect(btnEdit, SIGNAL(clicked()), this, SLOT(slotEdit()));
+ connect(btnDelete, SIGNAL(clicked()), this, SLOT(slotDelete()));
+ connect(lviewVocab, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(slotSelectionChanged(QListViewItem *)));
+
+ refreshView();
+}
+
+VocabSettings::~VocabSettings()
+{
+}
+
+void VocabSettings::refreshView()
+{
+ lviewVocab->clear();
+
+ m_fileList = KGlobal::dirs()->findAllResources("appdata", "data/" + KanagramSettings::dataLanguage() + "/" + "*.kvtml");
+ for(uint i = 0; i < m_fileList.size(); i++)
+ {
+ KEduVocDocument *doc = new KEduVocDocument(this);
+ doc->open(KURL(m_fileList[i]), false);
+ QListViewItem *item = new QListViewItem(lviewVocab, 0);
+ item->setText( 0, doc->getTitle() );
+ item->setText( 1, doc->getDocRemark() );
+ m_itemMap[item] = i;
+ }
+}
+
+void VocabSettings::slotEdit()
+{
+ if(lviewVocab->selectedItem())
+ {
+ int index = m_itemMap[lviewVocab->selectedItem()];
+ VocabEdit *vocabEdit = new VocabEdit(this, m_fileList[index]);
+ vocabEdit->show();
+ }
+}
+
+void VocabSettings::slotDelete()
+{
+ if(lviewVocab->selectedItem())
+ {
+ int index = m_itemMap[lviewVocab->selectedItem()];
+ /*bool itWorked = */QFile::remove(m_fileList[index]);
+ }
+
+ refreshView();
+}
+
+void VocabSettings::slotCreateNew()
+{
+ VocabEdit *vocabEdit = new VocabEdit(this, "");
+ vocabEdit->show();
+}
+
+void VocabSettings::slotSelectionChanged(QListViewItem *item)
+{
+ int index = m_itemMap[item];
+ QFileInfo info = QFileInfo(m_fileList[index]);
+ if(!info.isWritable())
+ {
+ btnDelete->setEnabled(false);
+ btnEdit->setEnabled(false);
+ }
+ else
+ {
+ btnDelete->setEnabled(true);
+ btnEdit->setEnabled(true);
+ }
+}
+
+#include "vocabsettings.moc"
+
diff --git a/kanagram/src/vocabsettings.h b/kanagram/src/vocabsettings.h
new file mode 100644
index 00000000..d321ee2f
--- /dev/null
+++ b/kanagram/src/vocabsettings.h
@@ -0,0 +1,26 @@
+#ifndef VOCABSETTINGS_H
+#define VOCABSETTINGS_H
+
+#include "vocabsettingswidget.h"
+
+class VocabSettings : public VocabSettingsWidget
+{
+Q_OBJECT
+ public:
+ VocabSettings(QWidget *parent);
+ ~VocabSettings();
+ void refreshView();
+
+ private:
+ QStringList m_fileList;
+ QMap<const QListViewItem*, int> m_itemMap;
+
+ private slots:
+ void slotCreateNew();
+ void slotEdit();
+ void slotDelete();
+ void slotSelectionChanged(QListViewItem *item);
+};
+
+#endif
+
diff --git a/kanagram/src/vocabsettingswidget.ui b/kanagram/src/vocabsettingswidget.ui
new file mode 100644
index 00000000..b329da4e
--- /dev/null
+++ b/kanagram/src/vocabsettingswidget.ui
@@ -0,0 +1,117 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>VocabSettingsWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>VocabSettingsWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>456</width>
+ <height>338</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Vocabularies</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>btnCreateNew</cstring>
+ </property>
+ <property name="text">
+ <string>Create New</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Creates a new vocabulary.</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>btnEdit</cstring>
+ </property>
+ <property name="text">
+ <string>Edit</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Edits the selected vocabulary.</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>btnDelete</cstring>
+ </property>
+ <property name="text">
+ <string>Delete</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Deletes the selected vocabulary.</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QListView">
+ <column>
+ <property name="text">
+ <string>Title</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Description</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>lviewVocab</cstring>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>LastColumn</enum>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>The list of installed vocabularies.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+</widget>
+<slots>
+ <slot>createNew()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>