From 9583f6e99d5124fc1d59d7a407b21b2967fa9de1 Mon Sep 17 00:00:00 2001 From: Eric Pignet Date: Fri, 1 Jul 2005 19:33:52 +0000 Subject: [PATCH] Added first version of the new document classes. There are still many things to do. svn path=/branches/work/kwordquiz/src/keduvocexpression.h; revision=430557 --- kwordquiz/MultipleChoice.cpp | 119 +++ kwordquiz/MultipleChoice.h | 74 ++ kwordquiz/grammarmanager.cpp | 503 +++++++++ kwordquiz/grammarmanager.h | 215 ++++ kwordquiz/keduvocdocument.cpp | 1052 +++++++++++++++++++ kwordquiz/keduvocdocument.h | 677 ++++++++++++ kwordquiz/keduvocexpression.cpp | 792 ++++++++++++++ kwordquiz/keduvocexpression.h | 456 ++++++++ kwordquiz/keduvockvtmlreader.cpp | 1692 ++++++++++++++++++++++++++++++ kwordquiz/keduvockvtmlreader.h | 121 +++ kwordquiz/keduvockvtmlwriter.cpp | 950 +++++++++++++++++ kwordquiz/keduvockvtmlwriter.h | 99 ++ 12 files changed, 6750 insertions(+) create mode 100644 kwordquiz/MultipleChoice.cpp create mode 100644 kwordquiz/MultipleChoice.h create mode 100644 kwordquiz/grammarmanager.cpp create mode 100644 kwordquiz/grammarmanager.h create mode 100644 kwordquiz/keduvocdocument.cpp create mode 100644 kwordquiz/keduvocdocument.h create mode 100644 kwordquiz/keduvocexpression.cpp create mode 100644 kwordquiz/keduvocexpression.h create mode 100644 kwordquiz/keduvockvtmlreader.cpp create mode 100644 kwordquiz/keduvockvtmlreader.h create mode 100644 kwordquiz/keduvockvtmlwriter.cpp create mode 100644 kwordquiz/keduvockvtmlwriter.h diff --git a/kwordquiz/MultipleChoice.cpp b/kwordquiz/MultipleChoice.cpp new file mode 100644 index 0000000..e73f358 --- /dev/null +++ b/kwordquiz/MultipleChoice.cpp @@ -0,0 +1,119 @@ +/*************************************************************************** + + manage multiple choice suggestions for queries + + ----------------------------------------------------------------------- + + begin : Mon Oct 29 18:09:29 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. * + * * + ***************************************************************************/ + +#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/kwordquiz/MultipleChoice.h b/kwordquiz/MultipleChoice.h new file mode 100644 index 0000000..99bc56e --- /dev/null +++ b/kwordquiz/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 + (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 MultipleChoice_included +#define MultipleChoice_included + +#include + +#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/kwordquiz/grammarmanager.cpp b/kwordquiz/grammarmanager.cpp new file mode 100644 index 0000000..e586a97 --- /dev/null +++ b/kwordquiz/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 + (C) 2001 The KDE-EDU team + (C) 2004-2005 Peter Hedlund + + ----------------------------------------------------------------------- + + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 + +Conjugation::conjug_name_t +Conjugation::names [] = +{ + { CONJ_SIMPLE_PRESENT, I18N_NOOP("Simple Present") }, + { CONJ_PRESENT_PROGR, I18N_NOOP("Preset Progressive") }, + { CONJ_PRESENT_PERFECT, I18N_NOOP("Preset 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 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 Conjugation::getRelation () +{ + vector 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 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/kwordquiz/grammarmanager.h b/kwordquiz/grammarmanager.h new file mode 100644 index 0000000..1b9cfe7 --- /dev/null +++ b/kwordquiz/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 + +#include +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 getRelation (); + static void setTenseNames (vector 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 conjugations; + + static conjug_name_t names []; + static vector userTenses; +}; + + +#endif // grammarmanager_included + diff --git a/kwordquiz/keduvocdocument.cpp b/kwordquiz/keduvocdocument.cpp new file mode 100644 index 0000000..ba9f546 --- /dev/null +++ b/kwordquiz/keduvocdocument.cpp @@ -0,0 +1,1052 @@ +/*************************************************************************** + Vocabulary Document for KDE Edu + ----------------------------------------------------------------------- + copyright : (C) 1999-2001 Ewald Arnold + (C) 2001 The KDE-EDU team + (C) 2005 Peter Hedlung + email : peter@peterandlinda.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 "keduvocdocument.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +using namespace std; + +#include + +#include + +#include "keduvockvtmlwriter.h" +#include "keduvockvtmlreader.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 () +{ + +//TODO setVersion (QString::fromUtf8(KVOCTRAIN_VERSION_STRING)); + lesson_descr.clear(); + type_descr.clear(); + tense_descr.clear(); + langs.clear(); + extraSizehints.clear(); + sizehints.clear(); + vocabulary.clear(); + dirty = false; + sort_allowed = true; + unknown_attr = false; + unknown_elem = false; + sort_lesson = false; + for (int i = 0; i < (int) langs.size(); i++) + sort_lang.push_back(false); + setCurrentLesson (0); + queryorg = ""; + querytrans = ""; + doc_url.setFileName(i18n("Untitled")); + doctitle = ""; + author = ""; +} + + +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("Cannot open file
%1
").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, QString title, FileType ft) +{ + connect( this, SIGNAL(progressChanged(KEduVocDocument*,int)), parent, SLOT(slotProgress(KEduVocDocument*,int)) ); + + KURL tmp (url); + if (title == i18n("Untitled")) + title = QString::null; + if (title == doc_url.fileName()) + title = QString::null; + + 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("Cannot write to file
%1
").arg(tmp.path())); + return false; + } + + QApplication::setOverrideCursor( waitCursor ); + switch (ft) { + case kvtml: { + //TODO handle title + KEduVocKvtmlWriter kvtmlWriter(&f); + saved = kvtmlWriter.writeDoc(this); + } + 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::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 +{ + +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 +{ + +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 +{ + +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 +{ + +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 +{ + +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; +} + + +class resetAll : public unary_function +{ + +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 +{ + +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(""); + + if (idx <= 0 || idx > (int) lesson_descr.size() ) + return ""; + + return lesson_descr[idx-1]; +} + + +vector KEduVocDocument::getLessonsInQuery() const +{ + vector iqvec; + for (unsigned i = 0; i < lessons_in_query.size(); i++) + if (lessons_in_query[i]) { + iqvec.push_back(i+1); // Offset +// cout << "getliq: " << i+1 << endl; + } + return iqvec; +} + + +void KEduVocDocument::setLessonsInQuery(vector 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 +// 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 shadow; + vector 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; +} diff --git a/kwordquiz/keduvocdocument.h b/kwordquiz/keduvocdocument.h new file mode 100644 index 0000000..0036ef5 --- /dev/null +++ b/kwordquiz/keduvocdocument.h @@ -0,0 +1,677 @@ +/*************************************************************************** + Vocabulary Document for KDE Edu + ----------------------------------------------------------------------- + copyright : (C) 1999-2001 Ewald Arnold + (C) 2001 The KDE-EDU team + (C) 2005 Peter Hedlung + email : peter@peterandlinda.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 KEDUVOCDOCUMENT_H +#define KEDUVOCDOCUMENT_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include + +#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 + +/* + + My type 1 + My type 2 + +*/ + +#define KV_TYPE_GRP "type" // type descriptor group +#define KV_TYPE_DESC "desc" // type descriptor +#define KV_TYPE_NO "no" // type descriptor number + +/* + + My usage 1 + My usage 2 + +*/ + +#define KV_USAGE_GRP "usage" // usage descriptor group +#define KV_USAGE_DESC "desc" // usage descriptor +#define KV_USAGE_NO "no" // usage descriptor number + +/* + + Lesson #1 + Lesson #2 + +*/ + +#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 + +/* + + user tense #1 + user tense #2 + +*/ + +#define KV_TENSE_GRP "tense" // tense descriptor group +#define KV_TENSE_DESC "desc" // tense descriptor +#define KV_TENSE_NO "no" // tense descriptor number + +/* + + + +*/ + +#define KV_OPTION_GRP "options" // internal options group +#define KV_OPT_SORT "sort" // allow sorting +#define KV_BOOL_FLAG "on" // general boolean flag + +/* +
+ lang determines also lang order in entries !! + eine which must NOT differ + die + ein + der + ein + das + +
+*/ + +#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 + +/* + + good + better + best + +*/ + +#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 + +/* + + good + better + best + best 2 + best 3 + +*/ + +#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 + +/* + used in header for definiton of "prefix" + lang determines also lang order in entries !! + I which must NOT differ in subsequent -tags + you<2> + he + she + it + we + you + they + they + they + + + + and in entry for definition of tenses of (irreg.) verbs + + go + go + goes + goes + goes + go + go + go + go + go + + +*/ + +#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; + +/************************************************************* + * 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 getTypeDescr() const { return type_descr; } + + /** sets descr of types */ + inline void setTypeDescr(vector 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 getTenseDescr() const { return tense_descr; } + + /** sets descr of tenses */ + inline void setTenseDescr(vector 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 getUsageDescr() const { return usage_descr; } + + /** sets descr of usages */ + inline void setUsageDescr(vector 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, QString title, FileType ft); + + /** 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 getLessonsInQuery() const; + + /** sets lessons in current query */ + void setLessonsInQuery(vector); + + inline vector getLessonDescr() const { return lesson_descr; } + + inline int numLessons () const {return (int) lesson_descr.size(); } + + /** sets descr of lesson */ + inline void setLessonDescr(vector 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 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 sort_lang; + bool sort_lesson; + bool unknown_attr; + bool unknown_elem; + bool sort_allowed; + + // save these to document + vector langs; //0= origin, 1,.. translations + int cols, + lines; + int current_lesson; + vector extraSizehints; + vector sizehints; + QString generator; + QString queryorg, + querytrans; + vector vocabulary; + vector lessons_in_query; + vector lesson_descr; + vector type_descr; + vector tense_descr; + vector usage_descr; + QString doctitle; + QString author; + QString license; + QString doc_remark; + QString doc_version; + + vector
articles; + vector conjugations; +}; + + +#endif // KEDUVOCDOCUMENT_H diff --git a/kwordquiz/keduvocexpression.cpp b/kwordquiz/keduvocexpression.cpp new file mode 100644 index 0000000..df0342a --- /dev/null +++ b/kwordquiz/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@peterandlinda.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 "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/kwordquiz/keduvocexpression.h b/kwordquiz/keduvocexpression.h new file mode 100644 index 0000000..615d561 --- /dev/null +++ b/kwordquiz/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@peterandlinda.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 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 +#include +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 exprtypes; + vector translations; + vector remarks; + vector usageLabels; + vector paraphrases; + vector fauxAmi; + vector rev_fauxAmi; + vector synonym; + vector example; + vector antonym; + vector pronunces; + vector grades; + vector rev_grades; + vector qcounts; + vector rev_qcounts; + vector bcounts; + vector rev_bcounts; + vector qdates; + vector rev_qdates; + vector conjugations; + vector comparisons; + vector mcs; + + int lesson; + bool inquery; + bool active; +}; + +#endif // KEduVocExpression_H + diff --git a/kwordquiz/keduvockvtmlreader.cpp b/kwordquiz/keduvockvtmlreader.cpp new file mode 100644 index 0000000..abd35c8 --- /dev/null +++ b/kwordquiz/keduvockvtmlreader.cpp @@ -0,0 +1,1692 @@ +/*************************************************************************** + 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 +#include +#include +#include + +#include +#include + +#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) +/* +
+ lang determines also lang order in entries !! + eine which must NOT differ + die + ein + der + ein + das + +
+*/ +{ + 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 &curr_conjug, + const QString &entry_tag) +/* + used in header for definiton of "prefix" + lang determines also lang order in entries !! + I which must NOT differ + you<2> + he + she + it + we + you + they + they + they + + + + and in entry for definition of tenses of (irreg.) verbs + + go + go + goes + goes + goes + go + go + go + go + go + + +*/ +{ + 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) +/* + + good + better + best + +*/ +{ + 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) +/* + + good + better + best + best 2 + best 3 + +*/ + +{ + 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 ¶phrase) +{ + 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; + int width; + QString type; + QString faux_ami_f; + QString faux_ami_t; + QString synonym; + QString example; + QString antonym; + QString usage; + QString paraphrase; + vector 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(); + + QDomAttr domAttrInactive = domElementParent.attributeNode(KV_INACTIVE); + if (!domAttrInactive.isNull()) + active = !domAttrInactive.value().toInt(); + + 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 + + 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; + } + + 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; + } + + 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.text(); + 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 + + 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; + } + + 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; + } + + 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.text(); + 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(); +} + +//#include "KEduVocKvtmlReader.moc" diff --git a/kwordquiz/keduvockvtmlreader.h b/kwordquiz/keduvockvtmlreader.h new file mode 100644 index 0000000..df96d28 --- /dev/null +++ b/kwordquiz/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 +#include + +#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 &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 ¶phrase); + 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/kwordquiz/keduvockvtmlwriter.cpp b/kwordquiz/keduvockvtmlwriter.cpp new file mode 100644 index 0000000..4569efd --- /dev/null +++ b/kwordquiz/keduvockvtmlwriter.cpp @@ -0,0 +1,950 @@ +/*************************************************************************** + 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 +#include +#include + +#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 &curr_conjug) +{ +/* + used in header for definiton of "prefix" + lang determines also lang order in entries !! + I which must NOT differ + you<2> + he + she + it + we + you + they + they + they + + + +*/ + 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) +/* + + good + better + best + +*/ +{ + 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) +/* + + good + better + best + best 2 + best 3 + +*/ +{ + 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) +/* + in entry for definition of tenses of (irreg.) verbs + + go + go + goes + goes + goes + go + go + go + go + go + + +*/ +{ + 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) +/* +
+ lang determines also lang order in entries !! + eine which must NOT differ + die + ein + der + ein + das + +
+*/ +{ + 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) +{ + bool first_expr = true; + + m_doc = doc; + + QDomDocument domDoc( "KEduVocDocument" ); + QDomElement domElementKvtml = domDoc.createElement( "kvtml" ); + + QString head( "" ); + 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, (QString) "kwordquiz");// TODO EPT KVD_VERS_PREFIX KVOCTRAIN_VERSION_STRING); + domElementKvtml.setAttribute(KV_COLS, m_doc->numLangs() ); + domElementKvtml.setAttribute(KV_LINES, m_doc->numEntries() ); +/* TODO EPT add title management + if (!title.isEmpty()) + { + domElementKvtml.setAttribute(KV_TITLE, m_doc->getTitle() ); + m_doc->doctitle = title; + } + else */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::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 << domDoc.toString(); + +// TODO setModified (false); +} diff --git a/kwordquiz/keduvockvtmlwriter.h b/kwordquiz/keduvockvtmlwriter.h new file mode 100644 index 0000000..ca1f1f6 --- /dev/null +++ b/kwordquiz/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 +#include + +//#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); + + 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 &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 -- 2.47.3