summaryrefslogtreecommitdiffstats
path: root/kanagram/src
diff options
context:
space:
mode:
Diffstat (limited to 'kanagram/src')
-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
43 files changed, 10242 insertions, 0 deletions
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>