diff options
Diffstat (limited to 'kvoctrain/kvoctrain/kvt-core')
36 files changed, 11534 insertions, 0 deletions
diff --git a/kvoctrain/kvoctrain/kvt-core/LineList.cpp b/kvoctrain/kvoctrain/kvt-core/LineList.cpp new file mode 100644 index 00000000..5b79b3b9 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/LineList.cpp @@ -0,0 +1,95 @@ +/*************************************************************************** + + maintain list of lines from QMultiLineEdit + + ----------------------------------------------------------------------- + + begin : Sun Aug 13 10:00:53 MET 2000 + + 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 "LineList.h" + +#include <kdebug.h> + +LineList::LineList (const QString &multilines) +{ + setLines (multilines); +} + + +void LineList::setLines(const QString &the_lines ) +{ + multilines.clear(); + QString lines = the_lines; + int pos; + if ((pos = lines.find ('\n')) >= 0) { + while (pos >= 0) { + multilines.push_back(lines.left(pos)); + lines.remove (0, pos+1); + pos = lines.find ('\n'); + } + } + + if (lines.length() > 0) // empty string at end ==> not an entry! + multilines.push_back(lines); + + normalizeWS(); +} + + +void LineList::normalizeWS() +{ + for (int i = 0; i < (int) multilines.size(); i++) { + multilines[i] = multilines[i].stripWhiteSpace(); +// FIXME: more tolerance with WS? 2*SPC = 1*SPC... + } +} + + +int LineList::count() const +{ + return multilines.size(); +} + + +QString LineList::getLine (int index) const +{ + if (index < (int) multilines.size()) + return multilines[index]; + else { + kdError() << "LineList::getLine: index too big"; + return ""; + } +} + + +QString LineList::allLines() const +{ + QString ret; + if (multilines.size() > 0) + ret = multilines[0]; + + if (multilines.size() > 1) { + for (int i = 1; i < (int) multilines.size(); i++) + ret += "\n" + multilines[i]; + } + return ret; +} + diff --git a/kvoctrain/kvoctrain/kvt-core/LineList.h b/kvoctrain/kvoctrain/kvt-core/LineList.h new file mode 100644 index 00000000..b1d6f01f --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/LineList.h @@ -0,0 +1,49 @@ +/*************************************************************************** + + maintain list of lines from QMultiLineEdit + + ----------------------------------------------------------------------- + + begin : Sun Aug 13 10:00:53 MET 2000 + + 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 LineList_h +#define LineList_h + +#include <qstring.h> + +#include <vector> +using namespace std; + +class LineList { + public: + LineList (const QString &multilines = ""); + + void setLines(const QString &lines); + void normalizeWS(); + int count() const; + QString getLine (int index) const; + QString allLines() const; + + protected: + vector<QString> multilines; +}; + +#endif // LineList_h diff --git a/kvoctrain/kvoctrain/kvt-core/Makefile.am b/kvoctrain/kvoctrain/kvt-core/Makefile.am new file mode 100644 index 00000000..fe356907 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/Makefile.am @@ -0,0 +1,17 @@ +INCLUDES = -I$(srcdir)/.. -I../queryoption-dialogs \ + -I$(srcdir)/../queryoption-dialogs -I$(top_builddir)/kvoctrain/kvoctrain/common-dialogs $(all_includes) + +lib_LTLIBRARIES = libkvoctraincore.la + +METASOURCES = AUTO + +libkvoctraincore_la_SOURCES = langset.cpp LineList.cpp kvoctrainexpr.cpp \ + kvoctraindoc.cpp kvd_rh_kvtml.cpp kvd_rb_kvtml1.cpp kvd_rb_kvtml2.cpp kvd_wkvtml.cpp \ + kvd_csv.cpp kvd_lex.cpp kvd_vcb.cpp UsageManager.cpp QueryManager.cpp \ + MultipleChoice.cpp grammarmanager.cpp kvd_voc.cpp + +SUBDIRS = kvt-xml + +libkvoctraincore_la_LIBADD= kvt-xml/libkvtxml.la + +noinst_HEADERS = grammarmanager.h diff --git a/kvoctrain/kvoctrain/kvt-core/MultipleChoice.cpp b/kvoctrain/kvoctrain/kvt-core/MultipleChoice.cpp new file mode 100644 index 00000000..e73f358a --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/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/kvoctrain/kvoctrain/kvt-core/MultipleChoice.h b/kvoctrain/kvoctrain/kvt-core/MultipleChoice.h new file mode 100644 index 00000000..99bc56ea --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/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 <qstring.h> + +#define MAX_MULTIPLE_CHOICE 5 // select one out of x + +class MultipleChoice +{ + +public: + + MultipleChoice() {} + + MultipleChoice ( + const QString &mc1, + const QString &mc2, + const QString &mc3, + const QString &mc4, + const QString &mc5 + ); + + void setMC1 (const QString &s) { muc1 = s; } + void setMC2 (const QString &s) { muc2 = s; } + void setMC3 (const QString &s) { muc3 = s; } + void setMC4 (const QString &s) { muc4 = s; } + void setMC5 (const QString &s) { muc5 = s; } + + QString mc1 () const { return muc1; } + QString mc2 () const { return muc2; } + QString mc3 () const { return muc3; } + QString mc4 () const { return muc4; } + QString mc5 () const { return muc5; } + + QString mc (unsigned idx) const; + + bool isEmpty() const; + void normalize(); + void clear(); + unsigned size(); + +protected: + + QString muc1, muc2, muc3, muc4, muc5; +}; + + +#endif // MultipleChoice_included diff --git a/kvoctrain/kvoctrain/kvt-core/QueryManager.cpp b/kvoctrain/kvoctrain/kvt-core/QueryManager.cpp new file mode 100644 index 00000000..2c7b76ca --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/QueryManager.cpp @@ -0,0 +1,673 @@ +/*************************************************************************** + + manage queries + + ----------------------------------------------------------------------- + + begin : Sat Jul 11 20:50:53 MET 1999 + + copyright : (C) 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de> + (C) 2001 The KDE-EDU team + (C) 2005 Peter Hedlund <peter.hedlund@kdemail.net> + + ----------------------------------------------------------------------- + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <klocale.h> +#include <kconfig.h> + +#include <iostream> +#include <vector> +using namespace std; + +#include "QueryManager.h" +#include "kvoctraincore.h" +#include <prefs.h> + +vector<QString> QueryManager::userTypes; + +struct t_type_rel +{ + const char *short_ref; + const char *long_ref; +}; + +// types are hierarchical ! +// - . divides main from sub type +// - sub types must follow main type + +// user types are strings-references like this: #1 + +static t_type_rel InternalTypeRelations [] = +{ + { QM_ADJ, I18N_NOOP("Adjective") }, + + { QM_ADV, I18N_NOOP("Adverb") }, + + { QM_ART, I18N_NOOP("Article") }, + { QM_ART QM_TYPE_DIV QM_ART_DEF, I18N_NOOP("Article Definite") }, + { QM_ART QM_TYPE_DIV QM_ART_IND, I18N_NOOP("Article Indefinite") }, + + { QM_CON, I18N_NOOP("Conjunction") }, + + { QM_NAME, I18N_NOOP("Name") }, // old type "3" + + { QM_NOUN, I18N_NOOP("Noun") }, // old type "2" + { QM_NOUN QM_TYPE_DIV QM_NOUN_M, I18N_NOOP("Noun Male") }, + { QM_NOUN QM_TYPE_DIV QM_NOUN_F, I18N_NOOP("Noun Female") }, + { QM_NOUN QM_TYPE_DIV QM_NOUN_S, I18N_NOOP("Noun Neutral") }, + + { QM_NUM, I18N_NOOP("Numeral") }, + { QM_NUM QM_TYPE_DIV QM_NUM_ORD, I18N_NOOP("Numeral Ordinal") }, + { QM_NUM QM_TYPE_DIV QM_NUM_CARD, I18N_NOOP("Numeral Cardinal") }, + + { QM_PHRASE, I18N_NOOP("Phrase") }, + + { QM_PREP, I18N_NOOP("Preposition") }, + + { QM_PRON, I18N_NOOP("Pronoun") }, + { QM_PRON QM_TYPE_DIV QM_PRON_POS, I18N_NOOP("Pronoun Possessive") }, + { QM_PRON QM_TYPE_DIV QM_PRON_PER, I18N_NOOP("Pronoun Personal") }, + + { QM_QUEST, I18N_NOOP("Question") }, + + { QM_VERB, I18N_NOOP("Verb") }, // old type "1" + { QM_VERB QM_TYPE_DIV QM_VERB_IRR, I18N_NOOP("Verb Irregular") }, + { QM_VERB QM_TYPE_DIV QM_VERB_REG, I18N_NOOP("Verb Regular") }, + + { 0, 0 } // the end +}; + + +QString QueryManager::getSubType (const QString & type) +{ + int i; + QString t = type; + if ((i = t.find(QM_TYPE_DIV)) >= 0) { + t.remove(0, i+1); + return t; + } + else + return QString::null; +} + + +QString QueryManager::getMainType (const QString & type) +{ + int i; + if ((i = type.find(QM_TYPE_DIV)) >= 0) + return type.left(i); + else + return type; +} + + +QueryManager::QueryManager() +{ + lessonitems.clear(); +} + + +QuerySelection QueryManager::select(kvoctrainDoc *doc, int act_lesson, int oindex, int tindex) +{ + QuerySelection random; + random.resize(doc->numLessons()+1); + for (int i = 0; i < doc->numEntries(); i++) + doc->getEntry(i)->setInQuery(false); + + // selecting might take rather long + int ent_no = 0; + int ent_percent = doc->numEntries() / 100; + float f_ent_percent = doc->numEntries() / 100.0; + emit doc->progressChanged(doc, 0); + + //Note that Leitner style learning (altlearn) normally only uses 20 + //entries, we just ignore that here + for (int i = 0; i < doc->numEntries(); i++) { + ent_no++; + if (ent_percent != 0 && (ent_no % ent_percent) == 0 ) + emit doc->progressChanged(doc, int (ent_no / f_ent_percent)); + + kvoctrainExpr *expr = doc->getEntry(i); + unsigned int lessonno; + if (Prefs::altLearn()) + lessonno = 0; //We only use a single array in Leitner style + else + lessonno = expr->getLesson(); + + if (expr->isActive() ){ + if (Prefs::swapDirection()) { + if ( validate (expr, act_lesson, oindex, tindex) + || validate (expr, act_lesson, tindex, oindex)) { + random[lessonno].push_back (QueryEntryRef(expr, i)); + expr->setInQuery(true); + } + } + else { + if (validate (expr, act_lesson, oindex, tindex)) { + random[lessonno].push_back (QueryEntryRef(expr, i)); + expr->setInQuery(true); + } + } + } + } + + // remove empty lesson elements + for (int i = (int) random.size()-1; i >= 0; i--) + if (random[i].size() == 0) + random.erase(random.begin() + i); + return random; +} + + +bool QueryManager::validate(kvoctrainExpr *expr, int act_lesson, int oindex, int tindex) +{ + int index = tindex ? tindex : oindex; + if ((compareExpiring(expr->getGrade(index, oindex != 0), + expr->getQueryDate(index, oindex != 0), Prefs::expire()) + || + + ( + compareGrade ((CompType) Prefs::compType(Prefs::EnumType::Grade), expr->getGrade(index, oindex != 0), Prefs::gradeItem()) + && compareQuery ((CompType) Prefs::compType(Prefs::EnumType::Query), expr->getQueryCount(index, oindex != 0), Prefs::queryItem()) + && compareBad ((CompType) Prefs::compType(Prefs::EnumType::Bad), expr->getBadCount(index, oindex != 0), Prefs::badItem()) + && compareDate ((CompType) Prefs::compType(Prefs::EnumType::Date), expr->getQueryDate(index, oindex != 0), Prefs::dateItem()) + + && compareBlocking(expr->getGrade(index, oindex != 0), + expr->getQueryDate(index, oindex != 0), Prefs::block()) + ) + ) +// lesson + word type must ALWAYS match +// (and there must be a word on both sides) + && compareLesson ((CompType) Prefs::compType(Prefs::EnumType::Lesson), expr->getLesson(), lessonitems, act_lesson) + && compareType ((CompType) Prefs::compType(Prefs::EnumType::WordType), expr->getType(index), Prefs::typeItem()) + && !expr->getOriginal().stripWhiteSpace().isEmpty() + && !expr->getTranslation(index).stripWhiteSpace().isEmpty() + ) + return true; + else + return false; + +} + + +QuerySelection QueryManager::select(kvoctrainDoc *doc, int act_lesson, int idx, QString type) +{ + QuerySelection random; + random.resize(doc->numLessons()+1); + for (int i = 0; i < doc->numEntries(); i++) + doc->getEntry(i)->setInQuery(false); + + // selecting might take rather long + int ent_no = 0; + int ent_percent = doc->numEntries() / 100; + float f_ent_percent = doc->numEntries() / 100.0; + emit doc->progressChanged(doc, 0); + + for (int i = 0; i < doc->numEntries(); i++) { + ent_no++; + if (ent_percent != 0 && (ent_no % ent_percent) == 0 ) + emit doc->progressChanged(doc, int (ent_no / f_ent_percent)); + + kvoctrainExpr *expr = doc->getEntry(i); + if (expr->isActive() && validate (expr, act_lesson, idx, type)) { + random[expr->getLesson()].push_back (QueryEntryRef(expr, i)); + expr->setInQuery(true); + } + } + + // remove empty lesson elements + for (int i = (int) random.size()-1; i >= 0; i--) + if (random[i].size() == 0) + random.erase(random.begin() + i); + + return random; +} + + +bool QueryManager::validate(kvoctrainExpr *expr, int act_lesson, int idx, QString query_type) +{ + QString qtype; + int pos = query_type.find (QM_TYPE_DIV); + if (pos >= 0) + qtype = query_type.left (pos); + else + qtype = query_type; + + QString expr_type = expr->getType(idx); + bool type_ok = false; + if (qtype == QM_NOUN) { + type_ok = expr_type == QM_NOUN QM_TYPE_DIV QM_NOUN_S + || expr_type == QM_NOUN QM_TYPE_DIV QM_NOUN_M + || expr_type == QM_NOUN QM_TYPE_DIV QM_NOUN_F; + + } + else if (qtype == QM_VERB) { + type_ok = ( expr_type == QM_VERB + || expr_type == QM_VERB QM_TYPE_DIV QM_VERB_IRR + || expr_type == QM_VERB QM_TYPE_DIV QM_VERB_REG + ) + && expr->getConjugation(idx).numEntries() > 0; + + } + else if (qtype == QM_ADJ) { + type_ok = expr_type == QM_ADJ + && !expr->getComparison(idx).isEmpty(); + } + else + return false; + + if (compareLesson ((CompType) Prefs::compType(Prefs::EnumType::Lesson), expr->getLesson(), + lessonitems, act_lesson) + && type_ok) { + return true; + } + else { + return false; + } +} + + +QuerySelection QueryManager::select(kvoctrainDoc *doc, int act_lesson, int idx, QueryType type) +{ + QuerySelection random; + random.resize(doc->numLessons()+1); + for (int i = 0; i < doc->numEntries(); i++) + doc->getEntry(i)->setInQuery(false); + + // selecting might take rather long + int ent_no = 0; + int ent_percent = doc->numEntries() / 100; + float f_ent_percent = doc->numEntries() / 100.0; + emit doc->progressChanged(doc, 0); + + for (int i = 0; i < doc->numEntries(); i++) { + ent_no++; + if (ent_percent != 0 && (ent_no % ent_percent) == 0 ) + emit doc->progressChanged(doc, int (ent_no / f_ent_percent)); + + kvoctrainExpr *expr = doc->getEntry(i); + if (expr->isActive() && validate (expr, act_lesson, idx, type)) { + random[expr->getLesson()].push_back (QueryEntryRef(expr, i)); + expr->setInQuery(true); + } + } + + // remove empty lesson elements + for (int i = (int) random.size()-1; i >= 0; i--) + if (random[i].size() == 0) + random.erase(random.begin() + i); + + return random; +} + + +bool QueryManager::validate(kvoctrainExpr *expr, int act_lesson, int idx, QueryType query_type) +{ + bool type_ok = false; + if (query_type == QT_Synonym) { + type_ok = !expr->getSynonym(idx).stripWhiteSpace().isEmpty(); + } + else if (query_type == QT_Antonym) { + type_ok = !expr->getAntonym(idx).stripWhiteSpace().isEmpty(); + } + else if (query_type == QT_Paraphrase) { + type_ok = !expr->getParaphrase(idx).stripWhiteSpace().isEmpty(); + } + else if (query_type == QT_Example) { + type_ok = !expr->getExample(idx).stripWhiteSpace().isEmpty(); + } + + if (compareLesson ((CompType) Prefs::compType(Prefs::EnumType::Lesson), expr->getLesson(), + lessonitems, act_lesson) + && type_ok) + return true; + + return false; +} + + +QString QueryManager::compStr(Prefs::EnumCompType::type type) +{ + QString str = "???"; + switch (type) + { + case DontCare: str = i18n("Do not Care"); break; + case WorseThan: str = i18n("Worse Than"); break; + case WorseEqThan: str = i18n("Equal/Worse Than"); break; + case MoreThan: str = i18n(">"); break; + case MoreEqThan: str = i18n(">="); break; + case BetterEqThan: str = i18n("Equal/Better Than"); break; + case BetterThan: str = i18n("Better Than"); break; + case LessEqThan: str = i18n("<="); break; + case LessThan: str = i18n("<"); break; + + case EqualTo : str = i18n("Equal To"); break; + case NotEqual: str = i18n("Not Equal"); break; + + case OneOf : str = i18n("Contained In"); break; + case NotOneOf: str = i18n("Not Contained In"); break; + + case Within : str = i18n("Within Last"); break; + case Before : str = i18n("Before"); break; + case NotQueried: str = i18n("Not Queried"); break; + + case Current : return i18n("Current Lesson"); break; + case NotAssigned: return i18n("Not Assigned"); break; + default: + ; + } + return str; +} + + +QString QueryManager::gradeStr (int i) +{ + switch (i) { + case KV_NORM_GRADE: return i18n(KV_NORM_TEXT); break; + case KV_LEV1_GRADE: return i18n(KV_LEV1_TEXT); break; + case KV_LEV2_GRADE: return i18n(KV_LEV2_TEXT); break; + case KV_LEV3_GRADE: return i18n(KV_LEV3_TEXT); break; + case KV_LEV4_GRADE: return i18n(KV_LEV4_TEXT); break; + case KV_LEV5_GRADE: return i18n(KV_LEV5_TEXT); break; + case KV_LEV6_GRADE: return i18n(KV_LEV6_TEXT); break; + case KV_LEV7_GRADE: return i18n(KV_LEV7_TEXT); break; + default: return i18n(KV_LEV1_TEXT); break; + } +} + + +vector<TypeRelation> QueryManager::getRelation (bool only_maintypes) +{ + vector<TypeRelation> vec; + for (int i = 0; i < (int) userTypes.size(); i++) { + QString s; + s.setNum(i+1); + s.insert(0, QM_USER_TYPE); + vec.push_back(TypeRelation(s, userTypes[i])); + } + + + t_type_rel *type = InternalTypeRelations; + while (type->short_ref != 0) { + if (!only_maintypes || strstr (type->short_ref, QM_TYPE_DIV) == 0) + vec.push_back(TypeRelation(type->short_ref, i18n(type->long_ref))); + type++; + } + + return vec; +} + + +QString QueryManager::typeStr (const QString id) +{ + if (id.left(1) == QM_USER_TYPE) { + QString num = id; + num.remove (0, 1); + int i = num.toInt()-1; + if (i >= 0 && i < (int) userTypes.size() ) + return userTypes[i]; + else + return QString::null; + } + else { + t_type_rel *type = InternalTypeRelations; + while (type->short_ref != 0) { + if (type->short_ref == id) + return i18n(type->long_ref); + type++; + } + } + return QString::null; +} + + +bool QueryManager::compareBlocking (int grade, int date, bool use_it) +{ + time_t cmp = Prefs::blockItem(grade); + if (grade == KV_NORM_GRADE || cmp == 0 || !use_it) // don't care || all off + return true; + else { + time_t now = time(0); + return date+cmp < now; + } +} + + +bool QueryManager::compareExpiring (int grade, int date, bool use_it) +{ + time_t cmp = Prefs::expireItem(grade); + if (grade == KV_NORM_GRADE || cmp == 0 || !use_it) // don't care || all off + return false; + else { + time_t now = time(0); + return date+cmp < now; + } +} + + +bool QueryManager::compareDate (CompType type, time_t qd, time_t limit) +{ + time_t now = time(0); + bool erg = true; + switch (type) { + case DontCare: erg = true; + break; + + case Before: erg = qd == 0 || qd < now-limit; // never queried or older date + break; + + case Within: erg = qd >= now-limit; // newer date + break; + + case NotQueried: erg = qd == 0; + break; + + default: + ; + } + return erg; +} + + +bool QueryManager::compareQuery (CompType type, int qgrade, int limit) +{ + bool erg = true; + switch (type) { + case DontCare: erg = true; + break; + + case MoreThan: erg = qgrade > limit; // sel has higher query count + break; + + case MoreEqThan: erg = qgrade >= limit; + break; + + case EqualTo: erg = qgrade == limit; + break; + + case NotEqual: erg = qgrade != limit; + break; + + case LessEqThan: erg = qgrade <= limit; // sel has less count + break; + + case LessThan: erg = qgrade < limit; + break; + + default: + ; + } + return erg; +} + + +bool QueryManager::compareBad (CompType type, int bcount, int limit) +{ + bool erg = true; + switch (type) { + case DontCare: erg = true; + break; + + case MoreThan: erg = bcount > limit; // sel has higher bad count + break; + + case MoreEqThan: erg = bcount >= limit; + break; + + case EqualTo: erg = bcount == limit; + break; + + case NotEqual: erg = bcount != limit; + break; + + case LessEqThan: erg = bcount <= limit; // sel has less count + break; + + case LessThan: erg = bcount < limit; + break; + + default: + ; + } + return erg; +} + + +bool QueryManager::compareGrade (CompType type, grade_t qgrade, grade_t limit) +{ + bool erg = true; + switch (type) { + case DontCare: erg = true; + break; + + case WorseThan: erg = qgrade < limit; // sel has worse grade + break; + + case WorseEqThan: erg = qgrade <= limit; + break; + + case EqualTo: erg = qgrade == limit; + break; + + case NotEqual: erg = qgrade != limit; + break; + + case BetterEqThan: erg = qgrade >= limit; // sel has better grade + break; + + case BetterThan: erg = qgrade > limit; + break; + + default: + ; + } + return erg; +} + + +bool QueryManager::compareType (CompType type, const QString & exprtype, const QString & limit) +{ + bool erg = true; + switch (type) { + case DontCare: erg = true; + break; + + case EqualTo: erg = getMainType(exprtype) == getMainType(limit); // type is same + break; + + case NotEqual: erg = getMainType(exprtype) != getMainType(limit); // other type + break; + + default: + ; + } + return erg; +} + + +bool QueryManager::compareLesson (CompType type, int less, const vector<int> &limit, int current) +{ + bool erg = true; + switch (type) { + case DontCare: + erg = true; + break; + + case OneOf: + { + erg = false; + for (int i = 0; !erg && i < (int) limit.size(); i++) + if (limit[i] == less) + erg = true; + } + break; + + case NotOneOf: + { + erg = true; + for (int i = 0; erg && i < (int) limit.size(); i++) + if (limit[i] == less) + erg = false; + } + break; + + case Current: + erg = less == current; + break; + + case NotAssigned: + erg = less == 0; + break; + + default: + ; + } + return erg; +} + + +void QueryManager::setTypeNames (vector<QString> names) +{ + userTypes = names; +} + + +void QueryManager::setLessonItemStr (const QString & indices) +{ + int pos; + QString indices_copy = indices; + lessonitems.clear(); + while ((pos = indices_copy.find(' ')) >= 0) { + QString s = indices_copy.left(pos); + indices_copy.remove(0, pos+1); + lessonitems.push_back(s.toInt()); + } + if (indices_copy.length() != 0) { + lessonitems.push_back(indices_copy.toInt()); + } +} + + +QString QueryManager::lessonItemStr() const +{ + QString s, ret; + for (int i = 0; i < (int) lessonitems.size(); i++) { + s.setNum (lessonitems[i]); + if (i != 0) + ret += ' '; + ret += s; + } + return ret; +} + diff --git a/kvoctrain/kvoctrain/kvt-core/QueryManager.h b/kvoctrain/kvoctrain/kvt-core/QueryManager.h new file mode 100644 index 00000000..07567d22 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/QueryManager.h @@ -0,0 +1,223 @@ +/*************************************************************************** + + manage queries + + ----------------------------------------------------------------------- + + begin : Sat Jul 11 20:50:53 MET 1999 + + copyright : (C) 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de> + (C) 2001 The KDE-EDU team + (C) 2005 Peter Hedlund <peter.hedlund@kdemail.net> + + ----------------------------------------------------------------------- + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QueryManager_included +#define QueryManager_included + +#include <vector> +using namespace std; + +#include "kvoctraindoc.h" +#include "prefs.h" + +class kvoctrainDoc; +class KConfig; +class kvoctrainExpr; +class Prefs; + +// 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 + +//enum kvq_timeout_t { kvq_notimeout, kvq_show, kvq_cont }; + +enum QueryType { QT_Random, QT_Multiple, + QT_Articles, QT_Conjugation, QT_Comparison, + QT_Synonym, QT_Antonym, QT_Example, QT_Paraphrase }; + + +class TypeRelation +{ + public: + + TypeRelation (const QString & _short, const QString & _long) + : shortId (_short), longId(_long) {} + + QString shortStr() const { return shortId; } + QString longStr() const { return longId; } + + protected: + + QString shortId, longId; +}; + + +struct QueryEntryRef { + QueryEntryRef (kvoctrainExpr *_exp, + int _nr) + : exp(_exp), nr(_nr) {} + + + kvoctrainExpr *exp; + int nr; +}; + +typedef vector<vector<QueryEntryRef> > QuerySelection; + +class QueryManager +{ + public: + // don´t change the order/remove one of these, + // just APPEND new types + enum CompType { DontCare, + MoreEqThan, MoreThan, + Before, Within, + WorseThan, WorseEqThan, + EqualTo, NotEqual, + LessEqThan, LessThan, + BetterThan, BetterEqThan, + Current, NotAssigned, NotQueried, + Auto_Time, Auto_Count, + OneOf, NotOneOf + }; + + QueryManager (); + + //void loadConfig (KConfig *); + //void saveConfig (KConfig *); + + static vector<TypeRelation> getRelation (bool only_maintypes); + static void setTypeNames (vector<QString> names); + static QString getSubType (const QString & type); + static QString getMainType (const QString & type); + + static QString compStr(Prefs::EnumCompType::type type); + static QString gradeStr(int i); + static QString typeStr(const QString id); + + void setLessonItems(vector<int> indices) { lessonitems = indices; } + void setLessonItemStr(const QString & indices); + //void setDateItem (time_t time) { dateitem = time; } + //void setQueryItem (int query) { queryitem = query; } + //void setBadItem (int bad) { baditem = bad; } + //void setTypeItem (const QString & type) { typeitem = type; } + //void setGradeItem (grade_t grade) { gradeitem = grade; } + //void setBlockItem (int item, int grade); + //void setExpireItem (int item, int grade); + + vector<int> lessonItems() const { return lessonitems; } + QString lessonItemStr() const; + //time_t dateItem () const { return dateitem; } + //int queryItem () const { return queryitem; } + //int badItem () const { return baditem; } + //QString typeItem () const { return typeitem; } + //grade_t gradeItem () const { return gradeitem; } + //int blockItem (int grade) const; + //int expireItem (int grade) const; + + //void setDateComp (CompType time) { datecomp = time; } + //void setLessonComp (CompType less) { lessoncomp = less; } + //void setQueryComp (CompType query) { querycomp = query; } + //void setBadComp (CompType bad) { badcomp = bad; } + //void setTypeComp (CompType type) { typecomp = type; } + //void setGradeComp (CompType grade) { gradecomp = grade; } + + //CompType dateComp () const { return datecomp; } + //CompType lessonComp () const { return lessoncomp; } + //CompType queryComp () const { return querycomp; } + //CompType badComp () const { return badcomp; } + //CompType typeComp () const { return typecomp; } + //CompType gradeComp () const { return gradecomp; } + + bool validate(kvoctrainExpr *expr, int act_lesson, + int oindex, int tindex); + + QuerySelection select(kvoctrainDoc*, int act_lesson, + int oindex, int tindex); + + bool validate(kvoctrainExpr *expr, int act_lesson, + int index, QString type); + + QuerySelection select(kvoctrainDoc*, int act_lesson, + int index, QString type); + + bool validate(kvoctrainExpr *expr, int act_lesson, + int index, QueryType type); + + QuerySelection select(kvoctrainDoc*, int act_lesson, + int index, QueryType type); + + protected: + + bool compareBlocking (int grade, int limit, bool use_it); + bool compareExpiring (int grade, int limit, bool use_it); + bool compareDate (CompType, time_t, time_t); + bool compareQuery (CompType, int, int); + bool compareBad (CompType, int, int); + bool compareGrade (CompType, grade_t, grade_t); + bool compareType (CompType, const QString &, const QString &); + bool compareLesson (CompType type, int less, const vector<int> &limit, int current); + + /* CompType typecomp, + querycomp, + badcomp, + gradecomp, + lessoncomp, + datecomp;*/ + + //time_t dateitem; + //int queryitem, + // baditem; + //QString typeitem; + //grade_t gradeitem; + vector<int> lessonitems; + + //vector<int> blockItems, + // expireItems; + + private: + static vector<QString> userTypes; +}; + +#endif // QueryManager_included diff --git a/kvoctrain/kvoctrain/kvt-core/UsageManager.cpp b/kvoctrain/kvoctrain/kvt-core/UsageManager.cpp new file mode 100644 index 00000000..7f98665a --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/UsageManager.cpp @@ -0,0 +1,155 @@ +/*************************************************************************** + + manage usage labels + + ----------------------------------------------------------------------- + + begin : Fri Mar 31 20: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. * + * * + ***************************************************************************/ + +#include "UsageManager.h" + +#include <klocale.h> + + +#include <iostream> +#include <vector> +using namespace std; + +vector<QString> UsageManager::userUsages; + +// user usages are strings like this: #1 + +struct internalRelation_t +{ + const char *ident, + *context, + *shortid, + *longId; +}; + +#ifndef I18N_NOOP2 +#define I18N_NOOP2(context, str) context, str +#endif + +static internalRelation_t InternalUsageRelations [] = +{ + { UL_AM, 0, I18N_NOOP("Am."), I18N_NOOP("Americanism")}, + { UL_ABBR, 0, I18N_NOOP("abbr."), I18N_NOOP("abbreviation")}, + { UL_ANAT, 0, I18N_NOOP("anat."), I18N_NOOP("anatomy")}, + { UL_ASTR, 0, I18N_NOOP("astr."), I18N_NOOP("astronomy")}, + { UL_BIOL, 0, I18N_NOOP("biol."), I18N_NOOP("biology")}, + { UL_BS, 0, I18N_NOOP("b.s."), I18N_NOOP("bad sense")}, + { UL_CONTP, 0, I18N_NOOP("contp."), I18N_NOOP("contemptuously")}, + { UL_ECCL, 0, I18N_NOOP("eccl."), I18N_NOOP("ecclesiastical")}, + { UL_FIG, 0, I18N_NOOP("fig."), I18N_NOOP("figuratively")}, + { UL_GEOL, 0, I18N_NOOP("geol."), I18N_NOOP("geology")}, + { UL_HIST, 0, I18N_NOOP("hist."), I18N_NOOP("historical")}, + { UL_ICHT, 0, I18N_NOOP("icht."), I18N_NOOP("ichthyology")}, + { UL_IFML, 0, I18N_NOOP("ifml."), I18N_NOOP("informal")}, + { UL_IRONIC, 0, I18N_NOOP("iro."), I18N_NOOP("ironic")}, + { UL_IRR, 0, I18N_NOOP("irr."), I18N_NOOP("irregular")}, + { UL_LIT, 0, I18N_NOOP("lit."), I18N_NOOP("literary")}, + { UL_META, 0, I18N_NOOP("metall."), I18N_NOOP("metallurgy")}, + { UL_METEO, 0, I18N_NOOP("meteor."), I18N_NOOP("meteorology")}, + { UL_MIN, 0, I18N_NOOP("min."), I18N_NOOP("mineralogy")}, + { UL_MOT, 0, I18N_NOOP("mot."), I18N_NOOP("motoring")}, + { UL_MOUNT, 0, I18N_NOOP("mount."), I18N_NOOP("mountaineering")}, + { UL_MYT, 0, I18N_NOOP("myth."), I18N_NOOP("mythology")}, + { UL_NPR, 0, I18N_NOOP2("abbreviation: proper name", "npr."), I18N_NOOP("proper name")}, + { UL_OPT, 0, I18N_NOOP("opt."), I18N_NOOP("optics")}, + { UL_ORN, 0, I18N_NOOP("orn."), I18N_NOOP("ornithology")}, + { UL_OS, 0, I18N_NOOP("o.s."), I18N_NOOP("oneself")}, + { UL_P, 0, I18N_NOOP("pers."), I18N_NOOP("person")}, + { UL_PARL, 0, I18N_NOOP("parl."), I18N_NOOP("parliamentary")}, + { UL_PHARM, 0, I18N_NOOP("pharm."), I18N_NOOP("pharmacy")}, + { UL_PHLS, 0, I18N_NOOP("phls."), I18N_NOOP("philosophy")}, + { UL_PHOT, 0, I18N_NOOP("phot."), I18N_NOOP("photography")}, + { UL_PHYS, 0, I18N_NOOP("phys."), I18N_NOOP("physics")}, + { UL_PHYSIOL, 0, I18N_NOOP("physiol."), I18N_NOOP("physiology")}, + { UL_PL, 0, I18N_NOOP("pl."), I18N_NOOP("plural")}, + { UL_POET, 0, I18N_NOOP("poet."), I18N_NOOP("poetry")}, + { UL_POL, 0, I18N_NOOP("pol."), I18N_NOOP("politics")}, + { UL_PROV, 0, I18N_NOOP("prov."), I18N_NOOP("provincialism")}, + { UL_PSYCH, 0, I18N_NOOP("psych."), I18N_NOOP("psychology")}, + { UL_RHET, 0, I18N_NOOP("rhet."), I18N_NOOP("rhetoric")}, + { UL_SURV, 0, I18N_NOOP("surv."), I18N_NOOP("surveying")}, + { UL_TEL, 0, I18N_NOOP("tel."), I18N_NOOP("telegraphy")}, + { UL_TELEPH, 0, I18N_NOOP("teleph."), I18N_NOOP("telephony")}, + { UL_THEA, 0, I18N_NOOP("thea."), I18N_NOOP("theater")}, + { UL_TYP, 0, I18N_NOOP("typ."), I18N_NOOP("typography")}, + { UL_UNIV, 0, I18N_NOOP("univ."), I18N_NOOP("university")}, + { UL_VET, 0, I18N_NOOP("vet."), I18N_NOOP("veterinary medicine")}, + { UL_ZO, 0, I18N_NOOP("zo."), I18N_NOOP("zoology")}, +//{ UL_, 0, I18N_NOOP(""), I18N_NOOP("")}, + { 0, 0, 0, 0 } // the end +}; + + +UsageManager::UsageManager () +{ +} + + +vector<UsageRelation> UsageManager::getRelation () +{ + vector<UsageRelation> vec; + for (int i = 0; i < (int) userUsages.size(); i++) { + QString s; + s.setNum(i+1); + s.insert(0, UL_USER_USAGE); + vec.push_back(UsageRelation(s, userUsages[i], userUsages[i])); + } + + internalRelation_t *usage = InternalUsageRelations; + while (usage->ident != 0) { + QString s; + if (usage->context == 0) + s = i18n(usage->shortid); + else + s = i18n(usage->context, usage->shortid); + vec.push_back(UsageRelation(usage->ident, + s, + i18n(usage->longId))); + usage++; + } + + return vec; +} + + +bool UsageManager::contains (const QString& label, const QString& collection) +{ + QString s = collection; + int pos; + while ((pos = s.find(UL_USAGE_DIV)) >= 0) { + if (s.left(pos) == label) + return true; + s.remove (0, pos+1); + } + + return s == label; +} + + +void UsageManager::setUsageNames (vector<QString> names) +{ + userUsages = names; +} diff --git a/kvoctrain/kvoctrain/kvt-core/UsageManager.h b/kvoctrain/kvoctrain/kvt-core/UsageManager.h new file mode 100644 index 00000000..e49a6c85 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/UsageManager.h @@ -0,0 +1,127 @@ +/*************************************************************************** + + manage usage labels + + ----------------------------------------------------------------------- + + begin : Sun Dec 19 11:26: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 UsageManager_included +#define UsageManager_included + +#include <vector> +using namespace std; + +#include "kvoctraindoc.h" + +class kvoctrainDoc; +class KConfig; +class kvoctrainExpr; + +// internal usage labels, never change ! + +#define UL_AM "Am" +#define UL_ABBR "abbr" +#define UL_ANAT "anat" +#define UL_ASTR "astr" +#define UL_BIOL "biol" +#define UL_BS "bs" +#define UL_CONTP "contp" +#define UL_ECCL "eccl" +#define UL_FIG "fig" +#define UL_GEOL "geol" +#define UL_HIST "hist" +#define UL_ICHT "icht" +#define UL_IFML "ifm" +#define UL_IRONIC "iro" +#define UL_IRR "irr" +#define UL_LIT "lit" +#define UL_META "metal" +#define UL_METEO "meteo" +#define UL_MIN "miner" +#define UL_MOT "mot" +#define UL_MOUNT "mount" +#define UL_MYT "myth" +#define UL_NPR "npr" +#define UL_OPT "opt" +#define UL_ORN "orn" +#define UL_OS "os" +#define UL_P "p" +#define UL_PARL "parl" +#define UL_PHARM "pharm" +#define UL_PHLS "phls" +#define UL_PHOT "phot" +#define UL_PHYS "phys" +#define UL_PHYSIOL "physio" +#define UL_PL "pl" +#define UL_POET "poet" +#define UL_POL "pol" +#define UL_PROV "prov" +#define UL_PSYCH "psych" +#define UL_RHET "rhet" +#define UL_SURV "surv" +#define UL_TEL "telg" +#define UL_TELEPH "telph" +#define UL_THEA "thea" +#define UL_TYP "typo" +#define UL_UNIV "univ" +#define UL_VET "vet" +#define UL_ZO "zoo" + +// usage delimiters +#define UL_USER_USAGE "#" // designates number of user type +#define UL_USAGE_DIV ":" // divide different labels + +struct UsageRelation +{ + public: + + UsageRelation (const QString & id, const QString & shorty, const QString & longy) + :ident(id), shortId(shorty), longId(longy) {} + + QString identStr() const { return ident; } + QString shortStr() const { return shortId; } + QString longStr() const { return longId; } + + protected: + QString ident, + shortId, + longId; +}; + + +class UsageManager +{ + public: + + UsageManager (); + + static bool contains (const QString& label, const QString& collection); + static vector<UsageRelation> getRelation (); + static void setUsageNames (vector<QString> names); + + protected: + + private: + static vector<QString> userUsages; +}; + +#endif // UsageManager_included diff --git a/kvoctrain/kvoctrain/kvt-core/grammarmanager.cpp b/kvoctrain/kvoctrain/kvt-core/grammarmanager.cpp new file mode 100644 index 00000000..2c789890 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/grammarmanager.cpp @@ -0,0 +1,503 @@ +/*************************************************************************** + + manage grammar parts (articles, conjugation) + + ----------------------------------------------------------------------- + + begin : Sat Nov 27 09:50:53 MET 1999 + + copyright : (C) 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de> + (C) 2001 The KDE-EDU team + (C) 2004-2005 Peter Hedlund <peter.hedlund@kdemail.net> + + ----------------------------------------------------------------------- + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "grammarmanager.h" + +#include <klocale.h> + +Conjugation::conjug_name_t +Conjugation::names [] = +{ + { CONJ_SIMPLE_PRESENT, I18N_NOOP("Simple Present") }, + { CONJ_PRESENT_PROGR, I18N_NOOP("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<QString> Conjugation::userTenses; + + +//================================================================ + +Comparison::Comparison ( + const QString &l1, + const QString &l2, + const QString &l3 + ) +{ + setL1 (l1); + setL2 (l2); + setL3 (l3); +} + + +bool Comparison::isEmpty() const +{ + return ls1.stripWhiteSpace().isEmpty() + && ls2.stripWhiteSpace().isEmpty() + && ls3.stripWhiteSpace().isEmpty(); +} + + +void Comparison::clear() +{ + ls1 = ""; + ls2 = ""; + ls3 = ""; +} + + +//================================================================= + + +Article::Article + (const QString &fem_def, const QString &fem_indef, + const QString &mal_def, const QString &mal_indef, + const QString &nat_def, const QString &nat_indef + ) +{ + setFemale (fem_def, fem_indef); + setMale (mal_def, mal_indef); + setNatural (nat_def, nat_indef); +} + + +void Article::setFemale + (const QString &def, const QString &indef) +{ + fem_def = def; + fem_indef = indef; +} + + +void Article::setMale + (const QString &def, const QString &indef) +{ + mal_def = def; + mal_indef = indef; +} + + +void Article::setNatural + (const QString &def, const QString &indef) +{ + nat_def = def; + nat_indef = indef; +} + + +void Article::female + (QString &def, QString &indef) const +{ + def = fem_def; + indef = fem_indef; +} + + +void Article::male + (QString &def, QString &indef) const +{ + def = mal_def; + indef = mal_indef; +} + + +void Article::natural + (QString &def, QString &indef) const +{ + def = nat_def; + indef = nat_indef; +} + + + +//============================================================== + + +int Conjugation::numEntries() const +{ + return conjugations.size(); +} + + +vector<TenseRelation> Conjugation::getRelation () +{ + vector<TenseRelation> vec; + + for (int i = 0; i < numInternalNames(); i++) { + vec.push_back(TenseRelation(names[i].abbrev, + i18n(names[i].name))); + } + + for (int i = 0; i < (int) userTenses.size(); i++) { + QString s; + s.setNum(i+1); + s.insert(0, UL_USER_TENSE); + vec.push_back(TenseRelation(s, userTenses[i])); + } + + return vec; +} + + +void Conjugation::setTenseNames (vector<QString> names) +{ + userTenses = names; +} + + +QString Conjugation::getName (const QString &abbrev) +{ + if (abbrev.length() >= 2 && abbrev[0] == QString(UL_USER_TENSE)) { + QString s = abbrev; + s.remove(0, 1); + int i = s.toInt() - 1; + + if (i < (int) userTenses.size() ) + return userTenses[i]; + else + return ""; + } + else { + for (int i = 0; i < (int) numInternalNames(); i++) + if (names[i].abbrev == abbrev) { + return i18n(names[i].name); + } + } + + return ""; +} + + +QString Conjugation::getName (int idx) +{ + if (idx < numInternalNames() ) + return i18n(names[idx].name); + + else if (idx < numTenses() ) + return userTenses[idx-numInternalNames()]; + + else + return ""; +} + + +QString Conjugation::getAbbrev (const QString &name) +{ + for (int i = 0; i < (int) userTenses.size(); i++) + if (userTenses[i] == name) { + QString s; + s.setNum(i+1); + s.insert(0, UL_USER_TENSE); + return s; + } + + for (int i = 0; i < (int) numInternalNames(); i++) + if (names[i].name == name) + return names[i].abbrev; + + return ""; +} + + +QString Conjugation::getAbbrev (int idx) +{ + if (idx < numInternalNames() ) + return names[idx].abbrev; + + else if (idx < numTenses() ) { + QString s; + s.setNum(idx-numInternalNames()+1); + s.insert(0, UL_USER_TENSE); + return s; + } + + else + return ""; +} + + +int Conjugation::numInternalNames() +{ + return sizeof(names) / sizeof(names[0]); +} + + +int Conjugation::numTenses() +{ + return numInternalNames()+userTenses.size(); +} + + +QString Conjugation::getType (int idx) +{ + if (idx >= (int) conjugations.size() ) + return ""; + + return conjugations[idx].type; +} + + +void Conjugation::setType (int idx, const QString & type) +{ + if (idx >= (int) conjugations.size() ) + return; + + conjugations[idx].type = type; +} + + +void Conjugation::cleanUp () +{ + for (int i = (int)conjugations.size()-1; i >= 0; i--) { + const conjug_t *ctp = &conjugations[i]; + if ( ctp->pers1_sing.stripWhiteSpace().isEmpty() + && ctp->pers2_sing.stripWhiteSpace().isEmpty() + && ctp->pers3_m_sing.stripWhiteSpace().isEmpty() + && ctp->pers3_f_sing.stripWhiteSpace().isEmpty() + && ctp->pers3_n_sing.stripWhiteSpace().isEmpty() + && ctp->pers1_plur.stripWhiteSpace().isEmpty() + && ctp->pers2_plur.stripWhiteSpace().isEmpty() + && ctp->pers3_m_plur.stripWhiteSpace().isEmpty() + && ctp->pers3_f_plur.stripWhiteSpace().isEmpty() + && ctp->pers3_n_plur.stripWhiteSpace().isEmpty() + ) + conjugations.erase(conjugations.begin() + i); + } +} + + +bool Conjugation::isEmpty (int idx) +{ + if (idx < (int) conjugations.size()) { + const conjug_t *ctp = &conjugations[idx]; + return ctp->pers1_sing.stripWhiteSpace().isEmpty() + && ctp->pers2_sing.stripWhiteSpace().isEmpty() + && ctp->pers3_m_sing.stripWhiteSpace().isEmpty() + && ctp->pers3_f_sing.stripWhiteSpace().isEmpty() + && ctp->pers3_n_sing.stripWhiteSpace().isEmpty() + && ctp->pers1_plur.stripWhiteSpace().isEmpty() + && ctp->pers2_plur.stripWhiteSpace().isEmpty() + && ctp->pers3_m_plur.stripWhiteSpace().isEmpty() + && ctp->pers3_f_plur.stripWhiteSpace().isEmpty() + && ctp->pers3_n_plur.stripWhiteSpace().isEmpty(); + } + return true; +} + + +#define _GET_CON_(elem, type, default) \ + for (int i = 0; i < (int) conjugations.size(); i++) \ + if (conjugations[i].type == type) \ + return conjugations[i].elem; \ + return default; + + +bool Conjugation::pers3SingularCommon(const QString &type) const +{ + _GET_CON_(s3common, type, false); +} + + +bool Conjugation::pers3PluralCommon(const QString &type) const +{ + _GET_CON_(p3common, type, false); +} + + +QString Conjugation::pers1Singular + (const QString &type) const +{ + _GET_CON_(pers1_sing, type, ""); +} + + +QString Conjugation::pers2Singular + (const QString &type) const +{ + _GET_CON_(pers2_sing, type, ""); +} + + +QString Conjugation::pers3FemaleSingular + (const QString &type) const +{ + _GET_CON_(pers3_f_sing, type, ""); +} + + +QString Conjugation::pers3MaleSingular + (const QString &type) const +{ + _GET_CON_(pers3_m_sing, type, ""); +} + + +QString Conjugation::pers3NaturalSingular + (const QString &type) const +{ + _GET_CON_(pers3_n_sing, type, ""); +} + + +QString Conjugation::pers1Plural + (const QString &type) const +{ + _GET_CON_(pers1_plur, type, ""); +} + + +QString Conjugation::pers2Plural + (const QString &type) const +{ + _GET_CON_(pers2_plur, type, ""); +} + + +QString Conjugation::pers3FemalePlural + (const QString &type) const +{ + _GET_CON_(pers3_f_plur, type, ""); +} + + +QString Conjugation::pers3MalePlural + (const QString &type) const +{ + _GET_CON_(pers3_m_plur, type, ""); +} + + +QString Conjugation::pers3NaturalPlural + (const QString &type) const +{ + _GET_CON_(pers3_n_plur, type, ""); +} + + +#undef _GET_CON_ + + +#define _SET_CON_(elem, type, str) \ + for (int i = 0; i < (int) conjugations.size(); i++) \ + if (conjugations[i].type == type) { \ + conjugations[i].elem = str; \ + return; \ + } \ + conjug_t ct; \ + ct.type = type; \ + ct.elem = str; \ + conjugations.push_back(ct); + + +void Conjugation::setPers3PluralCommon(const QString &type, bool f) +{ + _SET_CON_(p3common, type, f); +} + + +void Conjugation::setPers3SingularCommon(const QString &type, bool f) +{ + _SET_CON_(s3common, type, f); +} + + +void Conjugation::setPers1Singular + (const QString &type, const QString &str) +{ + _SET_CON_(pers1_sing, type, str); +} + + +void Conjugation::setPers2Singular + (const QString &type, const QString &str) +{ + _SET_CON_(pers2_sing, type, str); +} + + +void Conjugation::setPers3FemaleSingular + (const QString &type, const QString &str) +{ + _SET_CON_(pers3_f_sing, type, str); +} + + +void Conjugation::setPers3MaleSingular + (const QString &type, const QString &str) +{ + _SET_CON_(pers3_m_sing, type, str); +} + + +void Conjugation::setPers3NaturalSingular + (const QString &type, const QString &str) +{ + _SET_CON_(pers3_n_sing, type, str); +} + + +void Conjugation::setPers1Plural + (const QString &type, const QString &str) +{ + _SET_CON_(pers1_plur, type, str); +} + + +void Conjugation::setPers2Plural + (const QString &type, const QString &str) +{ + _SET_CON_(pers2_plur, type, str); +} + + +void Conjugation::setPers3FemalePlural + (const QString &type, const QString &str) +{ + _SET_CON_(pers3_f_plur, type, str); +} + + +void Conjugation::setPers3MalePlural + (const QString &type, const QString &str) +{ + _SET_CON_(pers3_m_plur, type, str); +} + + +void Conjugation::setPers3NaturalPlural + (const QString &type, const QString &str) +{ + _SET_CON_(pers3_n_plur, type, str); +} + +#undef _SET_CON_ + diff --git a/kvoctrain/kvoctrain/kvt-core/grammarmanager.h b/kvoctrain/kvoctrain/kvt-core/grammarmanager.h new file mode 100644 index 00000000..1b9cfe76 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/grammarmanager.h @@ -0,0 +1,215 @@ +/*************************************************************************** + + manage grammer parts (articles, conjugation) + + ----------------------------------------------------------------------- + + begin : Sat Nov 27 09:50:53 MET 1999 + + copyright : (C) 1999-2001 Ewald Arnold + (C) 2001 The KDE-EDU team + email : kvoctrain@ewald-arnold.de + + ----------------------------------------------------------------------- + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#ifndef grammarmanager_included +#define grammarmanager_included + +#include <qstring.h> + +#include <vector> +using namespace std; + +#define CONJ_SIMPLE_PRESENT "PrSi" // I live at home what you frequently do +#define CONJ_PRESENT_PROGR "PrPr" // I am working what you currently are doing +#define CONJ_PRESENT_PERFECT "PrPe" // I have cleaned tell, #that# something has happened + +#define CONJ_SIMPLE_PAST "PaSi" // the train left 2 min ago when did it happen +#define CONJ_PAST_PROGR "PaPr" // it was raining what happen at a given time in the past +#define CONJ_PAST_PARTICIPLE "PaPa" // I cleaned tell, #that# it happened + +#define CONJ_FUTURE "FuSi" + +#define CONJ_PREFIX "--" // definition of prefixes (I, you, ..) + +#define UL_USER_TENSE "#" // designates number of user tense + +class Article +{ + +public: + + Article() {} + + Article ( + const QString &fem_def, const QString &fem_indef, + const QString &mal_def, const QString &mal_indef, + const QString &nat_def, const QString &nat_indef + ); + + void setFemale (const QString &def, const QString &indef); + void setMale (const QString &def, const QString &indef); + void setNatural (const QString &def, const QString &indef); + + void female (QString &def, QString &indef) const; + void male (QString &def, QString &indef) const; + void natural (QString &def, QString &indef) const; + +protected: + + QString fem_def, fem_indef, + mal_def, mal_indef, + nat_def, nat_indef; +}; + + +class Comparison +{ + +public: + + Comparison() {} + + Comparison ( + const QString &l1, + const QString &l2, + const QString &l3 + ); + + void setL1 (const QString &s) { ls1 = s; } + void setL2 (const QString &s) { ls2 = s; } + void setL3 (const QString &s) { ls3 = s; } + + QString l1 () const { return ls1; } + QString l2 () const { return ls2; } + QString l3 () const { return ls3; } + + bool isEmpty() const; + void clear(); + +protected: + + QString ls1, ls2, ls3; +}; + + +class TenseRelation +{ + public: + + TenseRelation (const QString & _short, const QString & _long) + : shortId (_short), longId(_long) {} + + inline QString shortStr() const { return shortId; } + inline QString longStr() const { return longId; } + + protected: + + QString shortId, longId; +}; + + +class Conjugation +{ + +public: + + Conjugation () {} + + int numEntries() const; + + static vector<TenseRelation> getRelation (); + static void setTenseNames (vector<QString> names); + + static QString getName (const QString &abbrev); + static QString getName (int index); + static QString getAbbrev (const QString &name); + static QString getAbbrev (int index); + static int numInternalNames(); + static int numTenses(); + + QString getType (int index); + void setType (int index, const QString & type); + void cleanUp(); + bool isEmpty (int idx); + + QString pers1Singular(const QString &type) const; + QString pers2Singular(const QString &type) const; + bool pers3SingularCommon(const QString &type) const; + QString pers3FemaleSingular(const QString &type) const; + QString pers3MaleSingular(const QString &type) const; + QString pers3NaturalSingular(const QString &type) const; + + QString pers1Plural(const QString &type) const; + QString pers2Plural(const QString &type) const; + bool pers3PluralCommon(const QString &type) const; + QString pers3FemalePlural(const QString &type) const; + QString pers3MalePlural(const QString &type) const; + QString pers3NaturalPlural(const QString &type) const; + + void setPers1Singular(const QString &type, const QString &str); + void setPers2Singular(const QString &type, const QString &str); + void setPers3SingularCommon(const QString &type, bool f); + void setPers3FemaleSingular(const QString &type, const QString &str); + void setPers3MaleSingular(const QString &type, const QString &str); + void setPers3NaturalSingular(const QString &type, const QString &str); + + void setPers1Plural(const QString &type, const QString &str); + void setPers2Plural(const QString &type, const QString &str); + void setPers3PluralCommon(const QString &type, bool f); + void setPers3FemalePlural(const QString &type, const QString &str); + void setPers3MalePlural(const QString &type, const QString &str); + void setPers3NaturalPlural(const QString &type, const QString &str); + +private: + + struct conjug_t { + + conjug_t() { + p3common = false; + s3common = false; + } + + QString type; + bool p3common, + s3common; + QString pers1_sing, + pers2_sing, + pers3_m_sing, + pers3_f_sing, + pers3_n_sing, + pers1_plur, + pers2_plur, + pers3_m_plur, + pers3_f_plur, + pers3_n_plur; + }; + + struct conjug_name_t { + const char *abbrev; + const char *name; + }; + +protected: + + vector<conjug_t> conjugations; + + static conjug_name_t names []; + static vector<QString> userTenses; +}; + + +#endif // grammarmanager_included + diff --git a/kvoctrain/kvoctrain/kvt-core/kvd_csv.cpp b/kvoctrain/kvoctrain/kvt-core/kvd_csv.cpp new file mode 100644 index 00000000..851e0ea9 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvd_csv.cpp @@ -0,0 +1,243 @@ +/*************************************************************************** + + maintain a document in text format + + ----------------------------------------------------------------------- + + begin : Sat Sep 06 11:00:53 MET 1999 + + copyright : (C) 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de> + (C) 2001 The KDE-EDU team + (C) 2005 Peter Hedlund <peter.hedlund@kdemail.net> + + ----------------------------------------------------------------------- + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <klocale.h> + +#include "kvoctrain.h" + +#include <qtextcodec.h> + +#include <vector> +using namespace std; + +bool kvoctrainDoc::saveTypeNameCsv (QTextStream &) +{ + return true; +} + + +bool kvoctrainDoc::loadTypeNameCsv (QTextStream &) +{ + return true; +} + + +bool kvoctrainDoc::saveLessonCsv (QTextStream &) +{ + return true; +} + + +bool kvoctrainDoc::loadLessonCsv (QTextStream &) +{ + return true; +} + +bool kvoctrainDoc::saveToCsv (QTextStream& os, QString &) +{ + QString separator = Prefs::separator(); + + saveTypeNameCsv (os); + saveLessonCsv (os); + + int ent_no = 0; + int ent_percent = (int) vocabulary.size () / 100; + float f_ent_percent = (int) vocabulary.size () / 100.0; + emit progressChanged(this, 0); + + os << i18n("! Title:") << separator << getTitle() << "\n"; + os << i18n("! Author:") << separator << getAuthor() << "\n"; + + vector <int> csv_order = kvoctrainApp::getCsvOrder(this); + + vector<kvoctrainExpr>::const_iterator first = vocabulary.begin (); + QString exp; + + os.setCodec(QTextCodec::codecForName("UTF-8")); + while (first != vocabulary.end ()) { + + ent_no++; + if (ent_percent != 0 && (ent_no % ent_percent) == 0 ) + emit progressChanged(this, ent_no / (int) f_ent_percent); + + exp = ""; + // now concat columns according to paste-order + bool sep = false; + for (int i = 0; i < (int) csv_order.size(); i++) { + if (!sep) + sep = true; + else + exp += separator; + + if (csv_order[i] >= 0) { + if (csv_order[i] == 0) + exp += (*first).getOriginal(); + else + exp += (*first).getTranslation(csv_order[i]); + } + } + + if (!exp.isEmpty()) + os << exp << "\n"; + + first++; + } + + setModified (false); + return os.device()->status() == IO_Ok; +} + + +bool kvoctrainDoc::loadFromCsv (QTextStream& is) +{ + QString separator = Prefs::separator(); + QStringList lang_order = Prefs::pasteOrder(); + + langs.clear(); + vocabulary.clear(); + loadTypeNameCsv (is); + loadLessonCsv (is); + + // autodetect utf8 + // FIXME: provide choice for Latinx? + is.setCodec(QTextCodec::codecForName("ISO 8859-1")); + is.setEncoding(QTextStream::Latin1); + + int size = is.device()->size (); + int ln = size / 20 / 100; // assume each line about 20 chars + float f_ent_percent = size / 100.0; + emit progressChanged (this, 0); + + bool utf8_mode = false; + int lang_num = 0; + for (int l = 0; !is.eof(); l++) { + QString s = is.readLine(); + + // autodetect utf8 + if (!utf8_mode) { + for (int i = 0; !utf8_mode && i < (int) s.length(); ++i) { + ushort trigger = s[i].unicode(); + if (trigger >= 0x80) { + int remain = s.length() - i; + if ((trigger & 0xE0) == 0xC0){ // 110x xxxx + if ( (remain > 1) + && (s[i+1].unicode() & 0xC0) == 0x80) + utf8_mode = true; + } + else if ((trigger & 0xF0) == 0xE0) { // 1110 xxxx + if ( remain > 2 + && s[i+1].unicode() & 0xC0 == 0x80 + && s[i+2].unicode() & 0xC0 == 0x80) + utf8_mode = true; + } + else if ((trigger & 0xF8) == 0xF0) { // 1111 0xxx + if ( remain > 3 + && s[i+1].unicode() & 0xC0 == 0x80 + && s[i+2].unicode() & 0xC0 == 0x80 + && s[i+3].unicode() & 0xC0 == 0x80) + utf8_mode = true; + } + else if ((trigger & 0xFC) == 0xF8) { // 1111 10xx + if ( remain > 4 + && s[i+1].unicode() & 0xC0 == 0x80 + && s[i+2].unicode() & 0xC0 == 0x80 + && s[i+3].unicode() & 0xC0 == 0x80 + && s[i+4].unicode() & 0xC0 == 0x80) + utf8_mode = true; + } + else if ((trigger & 0xFE) == 0xFC) { // 1111 110x + if ( remain > 5 + && s[i+1].unicode() & 0xC0 == 0x80 + && s[i+2].unicode() & 0xC0 == 0x80 + && s[i+3].unicode() & 0xC0 == 0x80 + && s[i+4].unicode() & 0xC0 == 0x80 + && s[i+5].unicode() & 0xC0 == 0x80) + utf8_mode = true; + } + } + } + + if (utf8_mode) { + is.setCodec(QTextCodec::codecForName("UTF-8")); + is.setEncoding(QTextStream::UnicodeUTF8); + s = QString::fromUtf8(s.ascii()); + } + + } + + ln--; + if (ln <= 0) { + ln = size / 20 / 100; // assume each line about 20 chars + emit progressChanged(this, is.device()->at() / (int) f_ent_percent); + } + + // similar in kva_clip.cpp::slotEditPaste() + + if (!s.stripWhiteSpace().isEmpty()) { + kvoctrainExpr bucket (s, separator); + kvoctrainExpr expr; + // now move columns according to paste-order + for (int i = 0; i < bucket.numTranslations()+1; i++) { + lang_num = QMAX (lang_num, bucket.numTranslations()+1); + if (i == 0) + expr.setOriginal(bucket.getOriginal()); + else { + QString ts = bucket.getTranslation(i); + expr.setTranslation(i, ts); + } + } + appendEntry (&expr); + } + } + + for (int j = 0; j < lang_num; j++) { + if (j < (int) lang_order.count() ) { + langs.push_back((lang_order)[j]); + } + else { + if (j == 0) + langs.push_back("org"); + else { + QString s; + s.setNum(j); + s.insert(0, "trans"); + langs.push_back(s); + } + } + } + setModified (false); + return is.device()->status() == IO_Ok; +} + + +void kvoctrainDoc::errorCsv (int /*line*/, const QString &text ) +{ + unknown_elem = true; + QApplication::setOverrideCursor( arrowCursor, true ); + QString s = kapp->makeStdCaption(i18n("Error in csv file")); + QString msg = text; + KMessageBox::error( 0, msg, s); + QApplication::restoreOverrideCursor(); +} diff --git a/kvoctrain/kvoctrain/kvt-core/kvd_lex.cpp b/kvoctrain/kvoctrain/kvt-core/kvd_lex.cpp new file mode 100644 index 00000000..feb160cf --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvd_lex.cpp @@ -0,0 +1,395 @@ +/*************************************************************************** + + maintain a *.lex document (vocabulary trainer for Win) + + ----------------------------------------------------------------------- + + begin : Sat Sep 04 11:00: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. * + * * + ***************************************************************************/ + +#include <kapplication.h> +#include <klocale.h> +#include <kmessagebox.h> + +#include "kvoctraindoc.h" + + +#include <vector> +using namespace std; + +#define LEX_MAX_ATTR 20 +#define LEX_MAX_LESSON 9 + +/* sample for a lex-file + +Vocabulary Trainer V5.0 +LEX|Deutsch|Englisch| 259 260 1 1 1 0 0 268 0 1 1 1 1 145 6 23 1999 255 1 1 653 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 1 1 0 0 | +-11 700 +System +Energie- und Automatisierungstechnik. V. Manuela Lutz. Danke. +1 1 der die das|he she it| +1 1 eine einer eines einen einem|has have had is be| +1 1 er sie es|his him her its| +1 1 wir ihr euch|in to into on at too| +1 1 in an auf bei|the a an| +1 1 zu um zur zum|out by with of off| +1 1 ist sind seid|something someone some| +1 1 dies dieser dieses|under below| +1 1 || +1 1 || +der die das ein eine einer eines einen einem|the a an| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +Sachgebiete| +| +| +| +| +| +| +| +| +32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 +1 0 255 255 255 255 255 255 0 0 1 Abbildung||||mapping|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +1 0 255 255 255 255 255 255 0 0 1 Abblendkappe||||anti-dazzle device|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +... +*/ + + +static QString extract (QString &line) +{ + QString ret; + int lim = line.find ("|"); + if (lim < 0) { + ret = line; + line = ""; + } + else { + ret = line.left(lim); + line.remove (0, lim+1); + } + + return ret; +} + + +bool kvoctrainDoc::saveTypeNameLex (QTextStream &os) +{ + int i; + for (i = 0; i < (int) type_descr.size() && i < LEX_MAX_ATTR; i++) + os << getTypeName(i) << "|\n"; + + while (i++ < LEX_MAX_ATTR) + os << "|\n"; + + return os.device()->status() == IO_Ok; +} + + +bool kvoctrainDoc::loadTypeNameLex (QTextStream &is) +{ + QString s; + QString attr; + + type_descr.clear(); + + for (int i = 0; i < LEX_MAX_ATTR; i++) { + s = is.readLine(); + attr = extract (s); +/* + if (attr.stripWhiteSpace().isEmpty()) { + attr.setNum (i+1); + attr.insert (0, "#"); + } +*/ + type_descr.push_back (attr); + } + + return is.device()->status() == IO_Ok; +} + + +bool kvoctrainDoc::saveLessonLex (QTextStream &os) +{ + int i; + for (i = 0; i < (int) lesson_descr.size() && i < LEX_MAX_LESSON; i++) + os << lesson_descr[i] << "|\n"; + + while (i++ < LEX_MAX_LESSON) + os << "|\n"; + + return os.device()->status() == IO_Ok; +} + + +bool kvoctrainDoc::loadLessonLex (QTextStream &is) +{ + QString s; + QString lesson; + + lesson_descr.clear(); + + for (int i = 0; i < LEX_MAX_LESSON; i++) { + s = is.readLine(); + lesson = extract (s); + if (lesson.stripWhiteSpace().isEmpty()) { + lesson = "#" + QString::number(i+1); + } + lesson_descr.push_back (lesson); + } + + return is.device()->status() == IO_Ok; +} + + +bool kvoctrainDoc::saveToLex (QTextStream& os, QString & /*title*/) +{ + os << LEX_IDENT_50 "\n"; + os << "LEX|" << getOriginalIdent() << "|" << getIdent(1) << "|" + << "259 260 1 1 1 0 0 268 0 1 1 1 1 "; + os << (int) vocabulary.size(); + os << " 9 5 1999 255 1 1 653 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 1 1 0 0 |#3" << "\n"; + os << "-11 700 0 0 0 0 0 0 0 0 0 0" << "\n"; + os << "System\n"; + os << getTitle() << "\n"; + os << "1 1 der die das|he she it|" << "\n"; + os << "1 1 eine einer eines einen einem|has have had is be|" << "\n"; + os << "1 1 er sie es|his him her its|" << "\n"; + os << "1 1 wir ihr euch|in to into on at too|" << "\n"; + os << "1 1 in an auf bei|the a an|" << "\n"; + os << "1 1 zu um zur zum|out by with of off|" << "\n"; + os << "1 1 ist sind seid|something someone some|" << "\n"; + os << "1 1 dies dieser dieses|under below|" << "\n"; + os << "1 1 ||" << "\n"; + os << "1 1 ||" << "\n"; + os << "der die das ein eine einer eines einen einem|the a an|" << "\n"; + + if (!saveTypeNameLex (os)) + return false; + + if (!saveLessonLex (os)) + return false; + + os << "32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32" << "\n"; + + int ent_no = 0; + int ent_percent = (int) vocabulary.size () / 100; + float f_ent_percent = (int) vocabulary.size () / 100.0; + emit progressChanged(this, 0); + + vector<kvoctrainExpr>::const_iterator first = vocabulary.begin (); + while (first != vocabulary.end ()) { + + ent_no++; + if (ent_percent != 0 && (ent_no % ent_percent) == 0 ) + emit progressChanged(this, int(ent_no / f_ent_percent)); + + os << "0" // type + << " " << "255 255 255 255 255 255 255" + << " " << QMIN (2, (*first).getGrade(false)) + << " " << QMIN (2, (*first).getGrade(true)) + << " " << (*first).getLesson() + << " " << (*first).getOriginal() + << " " << "||||" // synonyms + << (*first).getTranslation(1) + << "||||" // synonyms + << "||||||||||||||||||||||||||||||||||||||||||||||||||||||||" + << "\n"; + + first++; + } + + setModified (false); + return os.device()->status() == IO_Ok; +} + + +bool kvoctrainDoc::loadFromLex (QTextStream& is) +{ + + langs.clear(); + vocabulary.clear(); + QString version, + info1, + s_dummy, + title, + f_keys, + ident, + orgID, + transID; + + int i_dummy, + type, + f_grade, + t_grade, + lesson; + + int lines = 10000000; + + version = is.readLine(); + info1 = is.readLine(); + ident = extract (info1); + + orgID = extract (info1); + if (orgID.isEmpty()) + orgID = "original"; + + transID = extract (info1); + if (transID.isEmpty()) + transID = "translation"; + + if (ident != "LEX" || version != LEX_IDENT_50) { + errorLex (1, "invalid file format"); + return false; + } + + // first two chars usually give language code: + // english ==> en + // Deutsch ==> de + // italano ==> it + + langs.push_back (orgID.left(2).lower()); + langs.push_back (transID.left(2).lower()); + + QTextStream params (info1, IO_ReadOnly); + params >> i_dummy; + params >> i_dummy; + params >> i_dummy; + params >> i_dummy; + params >> i_dummy; + params >> i_dummy; + params >> i_dummy; + params >> i_dummy; + params >> i_dummy; + params >> i_dummy; + params >> i_dummy; + params >> i_dummy; + params >> i_dummy; + params >> lines; + + s_dummy = is.readLine(); // Font + s_dummy = is.readLine(); // Font + title = is.readLine(); + setTitle (title); + s_dummy = is.readLine(); + s_dummy = is.readLine(); + s_dummy = is.readLine(); + s_dummy = is.readLine(); + s_dummy = is.readLine(); + s_dummy = is.readLine(); + s_dummy = is.readLine(); + s_dummy = is.readLine(); + s_dummy = is.readLine(); + s_dummy = is.readLine(); + s_dummy = is.readLine(); + + if (!loadTypeNameLex (is)) + return false; + + if (!loadLessonLex (is)) + return false; + + f_keys = is.readLine(); + + int ent_percent = (int) lines / 100; + float f_ent_percent = (int) lines / 100.0; + emit progressChanged(this, 0); + + for (int i = 0; !is.eof() && i < lines; i++) { + if (ent_percent != 0 && (i % ent_percent) == 0 ) { + emit progressChanged(this, int(i / f_ent_percent)); + } + + is >> type; + is >> i_dummy; + is >> i_dummy; + is >> i_dummy; + is >> i_dummy; + is >> i_dummy; + is >> i_dummy; + is >> i_dummy; + is >> t_grade; + is >> f_grade; + is >> lesson; + + QString line = is.readLine(); + QString s; + + QString original = extract (line); + for (int i = 0; i < 3; i++) { + s = extract (line); + if (!s.isEmpty()) + original += ", " +s; + } + + QString translation = extract (line); + for (int i = 0; i < 3; i++) { + s = extract (line); + if (!s.isEmpty()) + translation += ", " +s; + } + +/* ignore rest + >> "||||||||||||||||||||||||||||||||||||||||||||||||||||||||" + >> "\n"; +*/ + kvoctrainExpr kve (original); + kve.setGrade (1, t_grade, false); + kve.setGrade (1, f_grade, true); + kve.setLesson (lesson); + kve.addTranslation (translation); + +// FIXME: convert attribute to word type ? + + vocabulary.push_back(kve); + + } + + setModified (false); + return is.device()->status() == IO_Ok; +} + + +void kvoctrainDoc::errorLex (int /*line*/, const QString &text ) +{ + unknown_elem = true; + QApplication::setOverrideCursor( arrowCursor, true ); + QString s = kapp->makeStdCaption(i18n("Error in lex file")); + QString msg = text; + KMessageBox::error(0, msg, s); + QApplication::restoreOverrideCursor(); +} diff --git a/kvoctrain/kvoctrain/kvt-core/kvd_rb_kvtml1.cpp b/kvoctrain/kvoctrain/kvt-core/kvd_rb_kvtml1.cpp new file mode 100644 index 00000000..4aea5283 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvd_rb_kvtml1.cpp @@ -0,0 +1,888 @@ +/*************************************************************************** + + read big body of a kvtml document + + ----------------------------------------------------------------------- + + begin : Thu Mar 11 20: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. * + * * + ***************************************************************************/ + + +#include "QueryManager.h" +#include "UsageManager.h" + +#include <kapplication.h> +#include <klocale.h> +#include <kmessagebox.h> + +bool kvoctrainDoc::extract_T_DESCR_attr (XmlReader &xml, + XmlElement &elem, int &no) +{ + no = 0; + list<XmlAttribute>::const_iterator first = elem.attributes ().begin (); + while (first != elem.attributes ().end ()) { + if ((*first).name () == KV_LESS_NO) + no = (*first).intValue(); + else { + if (!unknownAttribute(xml.lineNumber(), "descr", (*first).name ())) + return false; + } + first++; + } + return true; +} + + +bool kvoctrainDoc::extract_T_GROUP_attr (XmlReader &xml, + XmlElement &elem) +{ + list<XmlAttribute>::const_iterator first = elem.attributes ().begin (); + while (first != elem.attributes ().end ()) { +/* + if ((*first).name () == KV_SIZEHINT) + width = (*first).intValue(); + else */ { + if (!unknownAttribute(xml.lineNumber(), "type", (*first).name ())) + return false; + } + first++; + } + return true; +} + + +bool kvoctrainDoc::loadTypeNameKvtMl (XmlElement elem, XmlReader& xml) +{ + bool endOfGroup = false; + QString s; + type_descr.clear(); + + if (!extract_T_GROUP_attr (xml, elem)) + return false; + + do { + if (! xml.readElement (elem)) + break; + + if (elem.tag () == KV_TYPE_GRP) { + if (! elem.isEndTag ()) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_TYPE_GRP)); + return false; + } + else + endOfGroup = true; + + } + else if (elem.tag () == KV_TYPE_DESC && !elem.isEndTag() ) { + int no; + if (!extract_T_DESCR_attr (xml, elem, no)) + return false; + + if (!xml.readElement (elem)) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + + if (elem.tag() == "#PCDATA") { // element data + s = xml.getText(); + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + else if (elem.tag() != KV_TYPE_DESC || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_TYPE_DESC)); + return false; + } + } + else { + if (elem.tag() != KV_TYPE_DESC || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_TYPE_DESC)); + return false; + } + + s = ""; + } + type_descr.push_back (s); + } + else { + if (elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("unexpected ending tag <%1>" ).arg(elem.tag())); + return false; + } + else { + unknownElement (xml.lineNumber(), elem.tag() ); + return false; + } + } + } while (! endOfGroup); + + return true; +} + + +bool kvoctrainDoc::loadTenseNameKvtMl (XmlElement elem, XmlReader& xml) +{ + bool endOfGroup = false; + QString s; + tense_descr.clear(); + + if (!extract_T_GROUP_attr (xml, elem)) + return false; + + do { + if (! xml.readElement (elem)) + break; + + if (elem.tag () == KV_TENSE_GRP) { + if (! elem.isEndTag ()) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_TENSE_GRP)); + return false; + } + else + endOfGroup = true; + + } + else if (elem.tag () == KV_TENSE_DESC && !elem.isEndTag() ) { + int no; + if (!extract_T_DESCR_attr (xml, elem, no)) + return false; + + if (!xml.readElement (elem)) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + + if (elem.tag() == "#PCDATA") { // element data + s = xml.getText(); + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + else if (elem.tag() != KV_TENSE_DESC || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_TENSE_DESC)); + return false; + } + } + else { + if (elem.tag() != KV_TENSE_DESC || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_TENSE_DESC)); + return false; + } + + s = ""; + } + tense_descr.push_back (s); + } + else { + if (elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("unexpected ending tag <%1>" ).arg(elem.tag())); + return false; + } + else { + unknownElement (xml.lineNumber(), elem.tag() ); + return false; + } + } + } while (! endOfGroup); + + return true; +} + + +bool kvoctrainDoc::loadUsageNameKvtMl (XmlElement elem, XmlReader& xml) +{ + bool endOfGroup = false; + QString s; + usage_descr.clear(); + + if (!extract_T_GROUP_attr (xml, elem)) + return false; + + do { + if (! xml.readElement (elem)) + break; + + if (elem.tag () == KV_USAGE_GRP) { + if (! elem.isEndTag ()) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_USAGE_GRP)); + return false; + } + else + endOfGroup = true; + + } + else if (elem.tag () == KV_USAGE_DESC && !elem.isEndTag() ) { + int no; + if (!extract_T_DESCR_attr (xml, elem, no)) + return false; + + if (!xml.readElement (elem)) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + + if (elem.tag() == "#PCDATA") { // element data + s = xml.getText(); + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + else if (elem.tag() != KV_USAGE_DESC || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_USAGE_DESC)); + return false; + } + } + else { + if (elem.tag() != KV_USAGE_DESC || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_USAGE_DESC)); + return false; + } + + s = ""; + } + usage_descr.push_back (s); + } + else { + if (elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("unexpected ending tag <%1>" ).arg(elem.tag())); + return false; + } + else { + unknownElement (xml.lineNumber(), elem.tag() ); + return false; + } + } + } while (! endOfGroup); + + return true; +} + + +bool kvoctrainDoc::extract_O_T_attr ( + XmlReader &xml, + XmlElement &elem, + 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) +{ + grade = KV_NORM_GRADE; + rev_grade = KV_NORM_GRADE; + count = 0; + rev_count = 0; + bcount = 0; + rev_bcount = 0; + date = 0; + rev_date = 0; + remark = ""; + lang = ""; + query_id = ""; + pronunce = ""; + faux_ami_t = ""; + faux_ami_f = ""; + synonym = ""; + example = ""; + usage = ""; + paraphrase = ""; + antonym = ""; + width = -1; +//type = exprtype + list<XmlAttribute>::const_iterator first = elem.attributes ().begin (); + int pos; + while (first != elem.attributes ().end ()) { + + if ((*first).name () == KV_LANG) + lang = (*first).stringValue(); + + else if ((*first).name () == KV_SIZEHINT) + width = (*first).intValue(); + + else if ((*first).name () == KV_CHARSET) { + } + + else if ((*first).name () == KV_GRADE) { + QString s = (*first).stringValue(); + + if ((pos = s.find(';')) >= 1) { + grade = s.left(pos).toInt(); + rev_grade = s.mid(pos+1, s.length()).toInt(); + } + else + grade = s.toInt(); + } + + else if ((*first).name () == KV_COUNT) { + QString s = (*first).stringValue(); + if ((pos = s.find(';')) >= 1) { + count = s.left(pos).toInt(); + rev_count = s.mid(pos+1, s.length()).toInt(); + } + else + count = s.toInt(); + } + + else if ((*first).name () == KV_BAD) { + QString s = (*first).stringValue(); + if ((pos = s.find(';')) >= 1) { + bcount = s.left(pos).toInt(); + rev_bcount = s.mid(pos+1, s.length()).toInt(); + } else + bcount = s.toInt(); + } + + else if ((*first).name () == KV_DATE) { + QString s = (*first).stringValue(); + if ((pos = s.find(';')) >= 1) { + date = s.left(pos).toInt(); + rev_date = s.mid(pos+1, s.length()).toInt(); + } + else { + date = s.toInt(); + } + } + + else if ((*first).name () == KV_DATE2) { + QString s = (*first).stringValue(); + if ((pos = s.find(';')) >= 1) { + date = decompressDate (s.left(pos)); + rev_date = decompressDate (s.mid(pos+1, s.length())); + } + else { + date = decompressDate (s); + } + } + + else if ((*first).name () == KV_REMARK) { + remark = (*first).stringValue(); + } + + else if ((*first).name () == KV_FAUX_AMI_F) { + faux_ami_f = (*first).stringValue(); + } + + else if ((*first).name () == KV_FAUX_AMI_T) { + faux_ami_t = (*first).stringValue(); + } + + else if ((*first).name () == KV_SYNONYM) { + synonym = (*first).stringValue(); + } + + else if ((*first).name () == KV_EXAMPLE) { + example = (*first).stringValue(); + } + + else if ((*first).name () == KV_USAGE) { + usage = (*first).stringValue(); + + if (usage.length() != 0 && usage.left(1) == UL_USER_USAGE) { + int num = QMIN(usage.mid (1, 40).toInt(), 1000); // paranioa check + if( num > (int) usage_descr.size() ) { // description missing ? + QString s; + for (int i = usage_descr.size(); i < num; i++) { + s.setNum (i+1); + s.insert (0, "#"); // invent descr according to number + usage_descr.push_back (s); + } + } + } + } + + else if ((*first).name () == KV_PARAPHRASE) { + paraphrase = (*first).stringValue(); + } + + else if ((*first).name () == KV_ANTONYM) { + antonym = (*first).stringValue(); + } + + else if ((*first).name () == KV_EXPRTYPE) { + type = (*first).stringValue(); + 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) type_descr.size() ) { // description missing ? + QString s; + for (int i = type_descr.size(); i < num; i++) { + s.setNum (i+1); + s.insert (0, "#"); // invent descr according to number + type_descr.push_back (s); + } + } + } + } + + else if ((*first).name () == KV_PRONUNCE) { + pronunce = (*first).stringValue(); + } + + else if ((*first).name () == KV_QUERY) { + query_id = (*first).stringValue(); + } + + else { + if (!unknownAttribute(xml.lineNumber(), "o> or <t", (*first).name ())) + return false; + } + first++; + } + + return true; +} + + +bool kvoctrainDoc::extract_KVT_E_attr ( + XmlReader& xml, + XmlElement &elem, + int &lesson, + bool &sel, + bool &active, + QString &type) +{ + lesson = 0; + sel = false; + active = true; + type = ""; + list<XmlAttribute>::const_iterator first = elem.attributes ().begin (); + while (first != elem.attributes ().end ()) { + if ((*first).name () == KV_LESS_MEMBER) + lesson = (*first).intValue(); + else if ((*first).name () == KV_SELECTED) + sel = (*first).intValue() != 0; + else if ((*first).name () == KV_INACTIVE) + active = !(*first).intValue() != 0; + else if ((*first).name () == KV_EXPRTYPE) { + type = (*first).stringValue(); + 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) type_descr.size() ) { // description missing ? + QString s; + for (int i = type_descr.size(); i < num; i++) { + s.setNum (i+1); + s.insert (0, "#"); // invent descr according to number + type_descr.push_back (s); + } + } + } + } + else { + if (!unknownAttribute(xml.lineNumber(), "e", (*first).name ())) + return false; + } + first++; + } + return true; +} + + +bool kvoctrainDoc::loadComparison (Comparison &comp, XmlElement elem, + XmlReader &xml) +/* + <comparison> + <l1>good</l1> + <l2>better</l2> + <l3>best</l3> + </comparison> +*/ +{ + bool endOfGroup = false; + QString s; + comp.clear(); + + do { + if (! xml.readElement (elem)) + break; + + if (elem.tag () == KV_COMPARISON_GRP) { + if (! elem.isEndTag ()) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(elem.tag())); + return false; + } + else + endOfGroup = true; + + } + + else if (elem.tag () == KV_COMP_L1 && !elem.isEndTag() ) { + if (!extract_simple_tag (KV_COMP_L1, xml, elem, s)) + return false; + comp.setL1(s); + } + + else if (elem.tag () == KV_COMP_L2 && !elem.isEndTag() ) { + if (!extract_simple_tag (KV_COMP_L2, xml, elem, s)) + return false; + comp.setL2(s); + } + + else if (elem.tag () == KV_COMP_L3 && !elem.isEndTag() ) { + if (!extract_simple_tag (KV_COMP_L3, xml, elem, s)) + return false; + comp.setL3(s); + } + + else { + if (elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("unexpected ending tag <%1>").arg(elem.tag())); + return false; + } + else { + unknownElement (xml.lineNumber(), elem.tag() ); + return false; + } + } + } while (! endOfGroup); + + return true; +} + + +bool kvoctrainDoc::loadMultipleChoice (MultipleChoice &mc, XmlElement elem, + XmlReader &xml) +/* + <multiplechoice> + <mc1>good</mc1> + <mc2>better</mc2> + <mc3>best</mc3> + <mc4>best 2</mc4> + <mc5>best 3</mc5> + </multiplechoice> +*/ + +{ + bool endOfGroup = false; + QString s; + mc.clear(); + + do { + if (! xml.readElement (elem)) + break; + + if (elem.tag () == KV_MULTIPLECHOICE_GRP) { + if (! elem.isEndTag ()) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(elem.tag())); + return false; + } + else + endOfGroup = true; + + } + + else if (elem.tag () == KV_MC_1 && !elem.isEndTag() ) { + if (!extract_simple_tag (KV_MC_1, xml, elem, s)) + return false; + mc.setMC1(s); + } + + else if (elem.tag () == KV_MC_2 && !elem.isEndTag() ) { + if (!extract_simple_tag (KV_MC_2, xml, elem, s)) + return false; + mc.setMC2(s); + } + + else if (elem.tag () == KV_MC_3 && !elem.isEndTag() ) { + if (!extract_simple_tag (KV_MC_3, xml, elem, s)) + return false; + mc.setMC3(s); + } + + else if (elem.tag () == KV_MC_4 && !elem.isEndTag() ) { + if (!extract_simple_tag (KV_MC_4, xml, elem, s)) + return false; + mc.setMC4(s); + } + + else if (elem.tag () == KV_MC_5 && !elem.isEndTag() ) { + if (!extract_simple_tag (KV_MC_5, xml, elem, s)) + return false; + mc.setMC5(s); + } + + else { + if (elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("unexpected ending tag <%1>").arg(elem.tag())); + return false; + } + else { + unknownElement (xml.lineNumber(), elem.tag() ); + return false; + } + } + } while (! endOfGroup); + + mc.normalize(); + return true; +} + + +bool kvoctrainDoc::parseBody_kvtml (XmlElement elem, XmlReader& xml) +{ + bool endOfBody = false; + 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) lines / 100; + float f_ent_percent = (int) lines / 100.0; + if (lines != 0) + emit progressChanged(this, 0); + + do { + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + + if (elem.tag () == KV_DOCTYPE) { + if (! elem.isEndTag ()) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(elem.tag())); + return false; + } + else + endOfBody = true; + } + + else if (elem.tag () == KV_LESS_GRP && !elem.isEndTag() ) { + if (lessgroup) { + errorKvtMl (xml.lineNumber(), + i18n("repeated occurrence of tag <%1>").arg(elem.tag())); + return false; + } + lessgroup = true; + if (!loadLessonKvtMl (elem, xml)) + return false; + } + + else if (elem.tag () == KV_ARTICLE_GRP && !elem.isEndTag() ) { + if (articlegroup) { + errorKvtMl (xml.lineNumber(), + i18n("repeated occurrence of tag <%1>").arg(elem.tag())); + return false; + } + articlegroup = true; + if (!loadArticleKvtMl (elem, xml)) + return false; + } + + else if (elem.tag () == KV_CONJUG_GRP && !elem.isEndTag() ) { + if (conjuggroup) { + errorKvtMl (xml.lineNumber(), + i18n("repeated occurrence of tag <%1>").arg(elem.tag())); + return false; + } + conjuggroup = true; + if (!loadConjugKvtMl (conjugations, KV_CON_ENTRY, elem, xml)) + return false; + } + + else if (elem.tag () == KV_OPTION_GRP && !elem.isEndTag() ) { + if (optgroup) { + errorKvtMl (xml.lineNumber(), + i18n("repeated occurrence of tag <%1>").arg(elem.tag())); + return false; + } + optgroup = true; + if (!loadOptionsKvtMl (elem, xml)) + return false; + } + + else if (elem.tag () == KV_TYPE_GRP && !elem.isEndTag() ) { + if (attrgroup) { + errorKvtMl (xml.lineNumber(), + i18n("repeated occurrence of tag <%1>").arg(elem.tag())); + return false; + } + attrgroup = true; + if (!loadTypeNameKvtMl (elem, xml)) + return false; + } + + else if (elem.tag () == KV_TENSE_GRP && !elem.isEndTag() ) { + if (tensegroup) { + errorKvtMl (xml.lineNumber(), + i18n("repeated occurrence of tag <%1>").arg(elem.tag())); + return false; + } + tensegroup = true; + if (!loadTenseNameKvtMl (elem, xml)) + return false; +// Conjugation::setTenseNames(tense_descr); + } + + else if (elem.tag () == KV_USAGE_GRP && !elem.isEndTag() ) { + if (usagegroup) { + errorKvtMl (xml.lineNumber(), + i18n("repeated occurrence of tag <%1>").arg(elem.tag())); + return false; + } + usagegroup = true; + if (!loadUsageNameKvtMl (elem, xml)) + return false; + } + + else if (elem.tag () == KV_EXPR && !elem.isEndTag() ) { + // found expression <e> + + if (lines != 0) { + ent_no++; + if (ent_percent != 0 && (ent_no % ent_percent) == 0 ) + emit progressChanged(this, int(ent_no / f_ent_percent)); + } + if (!parseBody_e (elem, xml)) return false; + } + + else { + if (elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("unexpected ending tag <%1>" ).arg(elem.tag())); + return false; + } + else { + unknownElement (xml.lineNumber(), elem.tag()); + return false; + } + } + + } while (! endOfBody); + + return true; +} + + +bool kvoctrainDoc::unknownAttribute (int line, const QString &name, + const QString &attr ) +{ + if (unknown_attr) // show dialog only once + return true; // proceed + + unknown_attr = true; + + QString ln = i18n("File:\t%1\nLine:\t%2\n").arg(URL().path()).arg(line); + + QString format = i18n( + "Your document contains an unknown attribute <%1> " // keep trailing space + "in tag <%2>.\n" + "Maybe your version of KVocTrain is too old, " + "or the document is damaged.\n" + "If you proceed and save afterwards you are likely to lose data;\n" + "do you want to proceed anyway?\n" + ); + QString msg = format.arg(attr).arg(name); + + QApplication::setOverrideCursor( arrowCursor, true ); + QString s = kapp->makeStdCaption(i18n("Unknown attribute")); + bool result = (KMessageBox::warningContinueCancel(0, ln+msg, s) == KMessageBox::Continue); + QApplication::restoreOverrideCursor(); + return result; +} + + +void kvoctrainDoc::unknownElement (int line, const QString &elem ) +{ + unknown_elem = true; + + QString ln = i18n("File:\t%1\nLine:\t%2\n").arg(URL().path()).arg(line); + + 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 kvoctrainDoc::errorKvtMl (int line, const QString &text ) +{ + QApplication::setOverrideCursor( arrowCursor, true ); + QString s = kapp->makeStdCaption(i18n("Error")); + QString ln = i18n("File:\t%1\nLine:\t%2\n").arg(URL().path()).arg(line); + + QString msg = text; + KMessageBox::error(0, ln+msg, s); + QApplication::restoreOverrideCursor(); +} + + +void kvoctrainDoc::warningKvtMl (int line, const QString &text ) +{ + QApplication::setOverrideCursor( arrowCursor, true ); + QString s = kapp->makeStdCaption(i18n("Warning")); + QString ln = i18n("File:\t%1\nLine:\t%2\n").arg(URL().path()).arg(line); + QString msg = text; + KMessageBox::information(0, ln+msg, s); + QApplication::restoreOverrideCursor(); +} diff --git a/kvoctrain/kvoctrain/kvt-core/kvd_rb_kvtml2.cpp b/kvoctrain/kvoctrain/kvt-core/kvd_rb_kvtml2.cpp new file mode 100644 index 00000000..8179bfa6 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvd_rb_kvtml2.cpp @@ -0,0 +1,464 @@ +/*************************************************************************** + + read big body of a kvtml document + + ----------------------------------------------------------------------- + + begin : Thu Mar 11 20: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. * + * * + ***************************************************************************/ + + +#include "QueryManager.h" + +#include <klocale.h> + + +bool kvoctrainDoc::parseBody_e (XmlElement elem, XmlReader& xml) +{ + 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; + kvoctrainExpr 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<Conjugation> conjug; + Comparison comparison; + MultipleChoice mc; + + if (!extract_KVT_E_attr (xml, elem, lesson, inquery, active, exprtype)) + return false; + + if (lesson + && lesson > (int) lesson_descr.size() ) { // description missing ? + QString s; + for (int i = lesson_descr.size(); i < lesson; i++) { + s.setNum (i+1); + s.insert (0, "#"); // invent descr according to number + lesson_descr.push_back (s); + } + } + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + + if (elem.tag() == KV_EXPR && !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(elem.tag())); + return false; + } + + unsigned int count = 0; + org_found = false; + while (elem.tag() != KV_EXPR) { + + // now want "original" and one or more "translations" + + // found original <o> + + if (elem.tag() == KV_ORG && !elem.isEndTag() ) { + if (org_found) { + errorKvtMl (xml.lineNumber(), + i18n("repeated occurrence of tag <%1>").arg(elem.tag())); + return false; + } + org_found = true; + + type = exprtype; + if (!extract_O_T_attr ( + xml, + elem, + 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 (vocabulary.size() == 0) { // only accept in first entry + if (width >= 0) + setSizeHint (count, width); + + if (query_id == KV_O) + q_org = lang; + + if (query_id == KV_T) + q_trans = lang; + } + + if (langs.size() == 0) { // first entry + if (lang.isEmpty()) // no definition in first entry + lang = "original"; + langs.push_back(lang); + + } + else { + if (lang != langs[0] && !lang.isEmpty()) { // different originals ? + errorKvtMl (xml.lineNumber(), + i18n("ambiguous definition of language code")); + return false; + } + } + count = 0; + +//======================================== +// FIXME:: make loop for this + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + + if (elem.tag () == KV_CONJUG_GRP && !elem.isEndTag() ) { + if (!loadConjugKvtMl (conjug, (QString) KV_CON_TYPE, elem, xml)) + return false; + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + } + + comparison.clear(); + if (elem.tag () == KV_COMPARISON_GRP && !elem.isEndTag() ) { + if (!loadComparison (comparison, elem, xml)) + return false; + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + } + + mc.clear(); + if (elem.tag () == KV_MULTIPLECHOICE_GRP && !elem.isEndTag() ) { + if (!loadMultipleChoice (mc, elem, xml)) + return false; + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + } + + if (elem.tag() == "#PCDATA") { // element data + textstr = xml.getText(); + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + + if (elem.tag() != KV_ORG || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_ORG)); + return false; + } + } + else { + if (elem.tag() != KV_ORG || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_ORG)); + return false; + } + textstr = ""; + } + +//======================================== + + expr = kvoctrainExpr (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); + } + + // found translation <t> + + else if (elem.tag() == KV_TRANS && !elem.isEndTag() ) { + if (!org_found) { // must be preceded by "original" + errorKvtMl (xml.lineNumber(), + i18n("starting tag <%1> is missing").arg(KV_ORG)); + return false; + } + + count++; + type = exprtype; + if (!extract_O_T_attr ( + xml, + elem, + 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 (vocabulary.size() == 0) { // only accept in first entry + if (width >= 0) + setSizeHint (count, width); + + if (query_id == KV_O) + q_org = lang; + + if (query_id == KV_T) + q_trans = lang; + + } + + if (langs.size() <= count) { // new translation + if (lang.isEmpty()) { // no definition in first entry ? + lang.setNum (langs.size() ); + lang.insert (0, "translation "); + } + langs.push_back(lang); + + } + else { + if (lang != langs[count] && !lang.isEmpty()) { // different language ? + errorKvtMl (xml.lineNumber(), + i18n("ambiguous definition of language code")); + return false; + } + } + +//======================================== +// FIXME:: make loop for this + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + + if (elem.tag () == KV_CONJUG_GRP && !elem.isEndTag() ) { + if (!loadConjugKvtMl (conjug, (QString) KV_CON_TYPE, elem, xml)) + return false; + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + } + + comparison.clear(); + if (elem.tag () == KV_COMPARISON_GRP && !elem.isEndTag() ) { + if (!loadComparison (comparison, elem, xml)) + return false; + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + } + + mc.clear(); + if (elem.tag () == KV_MULTIPLECHOICE_GRP && !elem.isEndTag() ) { + if (!loadMultipleChoice (mc, elem, xml)) + return false; + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + } + + textstr = ""; + if (elem.tag() == "#PCDATA") { // element data + textstr = xml.getText(); + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + + if (elem.tag() != KV_TRANS || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_TRANS)); + return false; + } + // expr ... + } + else { + if (elem.tag() != KV_TRANS || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_TRANS)); + return false; + } + textstr = ""; + } + +//======================================== + + if (!org_found) { + errorKvtMl (xml.lineNumber(), + i18n("starting tag <%1> is missing").arg(KV_ORG)); + return false; + } +/* + 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); + } + else { + if (elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("unexpected ending tag <%1>" ).arg(elem.tag())); + return false; + } + else { + unknownElement (xml.lineNumber(), elem.tag()); + return false; + } + } + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + } + if (numEntries() == 0) + setQueryLang (q_org, q_trans); + vocabulary.push_back (expr); + + return true; +} + + diff --git a/kvoctrain/kvoctrain/kvt-core/kvd_rh_kvtml.cpp b/kvoctrain/kvoctrain/kvt-core/kvd_rh_kvtml.cpp new file mode 100644 index 00000000..e6588675 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvd_rh_kvtml.cpp @@ -0,0 +1,856 @@ +/*************************************************************************** + + read header parts of a kvtml document + + ----------------------------------------------------------------------- + + begin : Thu Mar 11 20: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. * + * * + ***************************************************************************/ + +#include "QueryManager.h" + +#include <klocale.h> + +#include <qtextcodec.h> + +bool kvoctrainDoc::loadFromKvtMl (QTextStream& is) +{ + // important, first action + // switch to actual encoding afterwards, otherwise blocked + is.setCodec(QTextCodec::codecForName("UTF-8")); + is.setEncoding(QTextStream::UnicodeUTF8); + + langs.clear(); + vocabulary.clear(); + XmlReader xml (is); + + if (! xml.validHeader ()) { + errorKvtMl (xml.lineNumber(), i18n("invalid xml file header") ); + return false; + } + + generator = ""; + cols = 0; + lines = 0; + doctitle = ""; + author = ""; + license = ""; + doc_remark = ""; + XmlElement elem; + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + + if (elem.tag () != KV_DOCTYPE) { + errorKvtMl (xml.lineNumber(), + i18n("Tag <%1> was expected " + "but tag <%2> was read." ).arg(KV_DOCTYPE).arg(elem.tag())); + return false; + } + + list<XmlAttribute>::const_iterator first = elem.attributes ().begin (); + doctitle = i18n("Untitled"); + while (first != elem.attributes ().end ()) { + + if ((*first).name () == KV_ENCODING) { + + if ((*first).stringValue().upper() == (QString)"UTF-8" ) { + is.setCodec(QTextCodec::codecForName("UTF-8")); + is.setEncoding(QTextStream::UnicodeUTF8); + } + else if ((*first).stringValue().upper() == (QString)"8BIT" ) { // old compatibility mode + is.setCodec(QTextCodec::codecForName("ISO 8859-1")); + is.setEncoding(QTextStream::Latin1); + } + else { + is.setCodec(QTextCodec::codecForName("ISO 8859-1")); + is.setEncoding(QTextStream::Latin1); + QString format = i18n("Unknown document encoding \"%1\" was encountered.\n\n" + "It will be ignored. Encoding is now \"%2\"."); + QString msg =format.arg((*first).stringValue ().upper()).arg("ISO 8859-1"); + warningKvtMl (xml.lineNumber(), msg); + } + + } + else if ((*first).name () == KV_TITLE) { + doctitle = (*first).stringValue (); + } + else if ((*first).name () == KV_AUTHOR) { + author = (*first).stringValue (); + } + else if ((*first).name () == KV_LICENSE) { + license = (*first).stringValue (); + } + else if ((*first).name () == KV_DOC_REM) { + doc_remark = (*first).stringValue (); + } + else if ((*first).name () == KV_GENERATOR) { + generator = (*first).stringValue (); + int pos = generator.findRev (KVD_VERS_PREFIX); + if (pos >= 0) { + doc_version = generator; + doc_version.remove (0, pos+2); + } + } + else if ((*first).name () == KV_COLS) { + cols = (*first).intValue (); + } + else if ((*first).name () == KV_LINES) { + lines = (*first).intValue (); + } + else { + if (!unknownAttribute(xml.lineNumber(), "kvtml", (*first).name ())) + return false; + } + + first++; + } + + bool result = parseBody_kvtml (elem, xml); // read vocabulary + + setModified (false); + return result; +} + + +bool kvoctrainDoc::extract_L_DESCR_attr (XmlReader &xml, + XmlElement &elem, int &no, + bool &isCurr, bool &inQuery) +{ + no = 0; + isCurr = false; + inQuery = false; + list<XmlAttribute>::const_iterator first = elem.attributes ().begin (); + while (first != elem.attributes ().end ()) { + if ((*first).name () == KV_LESS_NO) + no = (*first).intValue(); + else if ((*first).name () == KV_LESS_CURR) + isCurr = (*first).intValue() != 0; + else if ((*first).name () == KV_LESS_QUERY) + inQuery = (*first).intValue() != 0; + else { + if (!unknownAttribute(xml.lineNumber(), "descr", (*first).name ())) + return false; + } + first++; + } + return true; +} + + +bool kvoctrainDoc::check_Empty_attr (QString tag_name, + XmlReader &xml, + XmlElement &elem) +{ + list<XmlAttribute>::const_iterator first = elem.attributes ().begin (); + if (first != elem.attributes ().end ()) { + if (!unknownAttribute(xml.lineNumber(), tag_name, (*first).name ())) + return false; + } + return true; +} + + +bool kvoctrainDoc::extract_simple_tag (QString tag_name, + XmlReader& xml, + XmlElement &elem, + QString &data, + bool check_it) +{ + if (check_it) + if (!check_Empty_attr (tag_name, xml, elem)) + return false; + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + + if (elem.tag() == "#PCDATA") { // element data + data = xml.getText(); + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + else if (elem.tag() != tag_name || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), i18n("expected ending tag <%1>").arg(tag_name)); + return false; + } + } + else { + if (elem.tag() != tag_name || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), i18n("expected ending tag <%1>").arg(tag_name)); + return false; + } + data = ""; + } + + return true; +} + + +bool kvoctrainDoc::extract_CON_E_attr (XmlReader& xml, + XmlElement &elem, + QString &lang) +{ + lang = ""; + + list<XmlAttribute>::const_iterator first = elem.attributes ().begin (); + while (first != elem.attributes ().end ()) { + + if ((*first).name () == KV_LANG) + lang = (*first).stringValue(); + + else { + if (!unknownAttribute(xml.lineNumber(), "e", (*first).name ())) + return false; + } + first++; + } + return true; +} + + +bool kvoctrainDoc::loadArticleKvtMl (XmlElement elem, XmlReader& xml) + +/* + <article> + <e l="de"> lang determines also lang order in entries !! + <fi>eine</fi> which must NOT differ + <fd>die</fd> + <mi>ein</mi> + <md>der</md> + <ni>ein</ni> + <nd>das</nd> + </e> + </article> +*/ + +{ + bool endOfGroup = false; + bool inEntry = false; + QString s; + articles.clear(); + + if (!check_Empty_attr (KV_ARTICLE_GRP, xml, elem)) + return false; + + QString fem_def, + mal_def, + nat_def, + fem_indef, + mal_indef, + nat_indef; + QString lang; + int count = 0; + + do { + if (! xml.readElement (elem)) + break; + + if (elem.tag () == KV_ARTICLE_GRP) { + if (inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_ARTICLE_GRP)); + return false; + } + if (! elem.isEndTag ()) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_ARTICLE_GRP)); + return false; + } + else + endOfGroup = true; + } + else if (elem.tag () == KV_ART_ENTRY) { + if (! elem.isEndTag ()) { + if (inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_ART_ENTRY)); + return false; + } + inEntry = true; + + if (!extract_CON_E_attr (xml, elem, lang) ) + return false; + + if ((int)langs.size() <= count) { // first entry + if (lang.isEmpty()) // no definition in first entry + lang = "original"; + langs.push_back(lang); + } + else { + if (lang != langs[count] && !lang.isEmpty()) { // different originals ? + errorKvtMl (xml.lineNumber(), + i18n("ambiguous definition of language code")); + return false; + } + } + fem_def = ""; + mal_def = ""; + nat_def = ""; + fem_indef = ""; + mal_indef = ""; + nat_indef = ""; + } + else { + count++; + inEntry = false; + articles.push_back (Article(fem_def, fem_indef, + mal_def, mal_indef, + nat_def, nat_indef)); + } + } + else if (elem.tag () == KV_ART_FD && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_ART_FD)); + return false; + } + if (!extract_simple_tag (KV_ART_FD, xml, elem, fem_def)) + return false; + } + else if (elem.tag () == KV_ART_FI && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_ART_FI)); + return false; + } + if (!extract_simple_tag (KV_ART_FI, xml, elem, fem_indef)) + return false; + } + else if (elem.tag () == KV_ART_MD && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_ART_MD)); + return false; + } + if (!extract_simple_tag (KV_ART_MD, xml, elem, mal_def)) + return false; + } + else if (elem.tag () == KV_ART_MI && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_ART_MI)); + return false; + } + if (!extract_simple_tag (KV_ART_MI, xml, elem, mal_indef)) + return false; + } + else if (elem.tag () == KV_ART_ND && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_ART_ND)); + return false; + } + if (!extract_simple_tag (KV_ART_ND, xml, elem, nat_def)) + return false; + } + else if (elem.tag () == KV_ART_NI && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_ART_NI)); + return false; + } + if (!extract_simple_tag (KV_ART_NI, xml, elem, nat_indef)) + return false; + } + else { + if (elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("unexpected ending tag <%1>" ).arg(elem.tag())); + return false; + } + else { + unknownElement (xml.lineNumber(), elem.tag() ); + return false; + } + } + } while (! endOfGroup); + + return true; +} + + +bool kvoctrainDoc::extract_T_attr (XmlReader &xml, + XmlElement &elem, + QString &name) +{ + name = ""; + list<XmlAttribute>::const_iterator first = elem.attributes ().begin (); + while (first != elem.attributes ().end ()) { + + if ((*first).name () == KV_CON_NAME) + name = (*first).stringValue(); + + else { + if (!unknownAttribute(xml.lineNumber(), "e", (*first).name ())) + return false; + } + first++; + } + return true; +} + + +bool kvoctrainDoc::extract_BOOL_attr ( + XmlReader &xml, + XmlElement &elem, + const QString &tag_name, + const QString &attr_name, + bool &flag) +{ + list<XmlAttribute>::const_iterator first = elem.attributes ().begin (); + while (first != elem.attributes ().end ()) { + if ((*first).name () == attr_name) + flag = (bool) (*first).intValue(); + else { + if (!unknownAttribute(xml.lineNumber(), tag_name, (*first).name ())) + return false; + } + first++; + } + return true; +} + + +bool kvoctrainDoc::loadConjugKvtMl (vector<Conjugation> &curr_conjug, + const QString &entry_tag, + XmlElement elem, XmlReader& xml) + +/* + <conjugation> used in header for definiton of "prefix" + <e l="de"> lang determines also lang order in entries !! + <s1>I</s1> which must NOT differ + <s2>you<2> + <s3f>he</s3f> + <s3m>she</s3m> + <s3n>it</s3n> + <p1>we</p1> + <p2>you</p2> + <p3f>they</p3f> + <p3m>they</p3m> + <p3n>they</p3n> + </e> + </conjugation> + + <conjugation> and in entry for definition of tenses of (irreg.) verbs + <t n="sipa"> + <s1>go</s1> + <s2>go</s2> + <s3f>goes</s3f> + <s3m>goes</s3m> + <s3n>goes</s3n> + <p1>go</p1> + <p2>go</p2> + <p3f>go</p3f> + <p3m>go</p3m> + <p3n>go</p3n> + </t> + </conjugation> +*/ + +{ + bool endOfGroup = false; + bool inEntry = false; + QString s; + + curr_conjug.clear(); + + if (!check_Empty_attr (KV_CONJUG_GRP, xml, elem)) + return false; + + 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()); + + do { + if (! xml.readElement (elem)) + break; + + if (elem.tag () == KV_CONJUG_GRP) { + if (inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_CONJUG_GRP)); + return false; + } + if (! elem.isEndTag ()) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(elem.tag())); + return false; + } + else + endOfGroup = true; + } + else if (elem.tag () == entry_tag) { + if (! elem.isEndTag ()) { + if (inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(entry_tag)); + return false; + } + inEntry = true; + + if (entry_tag == KV_CON_ENTRY) { + type = CONJ_PREFIX; + if (!extract_CON_E_attr (xml, elem, lang) ) + return false; + + if ((int)langs.size() <= count) { // first entry + if (lang.isEmpty()) // no definition in first entry + lang = "original"; + langs.push_back(lang); + } + else { + if (lang != langs[count] && !lang.isEmpty()) { // different originals ? + errorKvtMl (xml.lineNumber(), + i18n("ambiguous definition of language code")); + return false; + } + } + } + else if (entry_tag == KV_CON_TYPE) { + if (!extract_T_attr (xml, elem, type)) + return false; + if (type.length() != 0 && type.left(1) == UL_USER_TENSE) { + int num = QMIN(type.mid (1, 40).toInt(), 1000); // paranoia check + if( num > (int) tense_descr.size() ) { // description missing ? + QString s; + for (int i = tense_descr.size(); i < num; i++) { + s.setNum (i+1); + s.insert (0, "#"); // invent descr according to number + 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; + } + else { + inEntry = false; + if (entry_tag == 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 (entry_tag == KV_CON_ENTRY) + count++; + } + } + else if (elem.tag () == KV_CON_P1S && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_CON_P1S)); + return false; + } + if (!extract_simple_tag (KV_CON_P1S, xml, elem, pers1_sing) ) + return false; + } + else if (elem.tag () == KV_CON_P2S && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_CON_P2S)); + return false; + } + if (!extract_simple_tag (KV_CON_P2S, xml, elem, pers2_sing)) + return false; + } + else if (elem.tag () == KV_CON_P3SF && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_CON_P3SF)); + return false; + } + + if (!extract_BOOL_attr (xml, elem,KV_CON_P3SF, KV_CONJ_COMMON, + s3_common)) + return false; + + if (!extract_simple_tag (KV_CON_P3SF, xml, elem, pers3_f_sing, false)) + return false; + } + else if (elem.tag () == KV_CON_P3SM && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_CON_P3SM)); + return false; + } + if (!extract_simple_tag (KV_CON_P3SM, xml, elem, pers3_m_sing)) + return false; + } + else if (elem.tag () == KV_CON_P3SN && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_CON_P3SN)); + return false; + } + if (!extract_simple_tag (KV_CON_P3SN, xml, elem, pers3_n_sing)) + return false; + } + else if (elem.tag () == KV_CON_P1P && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_CON_P1P)); + return false; + } + if (!extract_simple_tag (KV_CON_P1P, xml, elem, pers1_plur) ) + return false; + } + else if (elem.tag () == KV_CON_P2P && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_CON_P2P)); + return false; + } + if (!extract_simple_tag (KV_CON_P2P, xml, elem, pers2_plur)) + return false; + } + else if (elem.tag () == KV_CON_P3PF && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_CON_P3PF)); + return false; + } + + if (!extract_BOOL_attr (xml, elem, KV_CON_P3PF, KV_CONJ_COMMON, + p3_common)) + return false; + + if (!extract_simple_tag (KV_CON_P3PF, xml, elem, pers3_f_plur, false)) + return false; + } + else if (elem.tag () == KV_CON_P3PM && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_CON_P3PM)); + return false; + } + if (!extract_simple_tag (KV_CON_P3PM, xml, elem, pers3_m_plur)) + return false; + } + else if (elem.tag () == KV_CON_P3PN && !elem.isEndTag() ) { + if (!inEntry) { + errorKvtMl (xml.lineNumber(), + i18n("disallowed occurrence of tag <%1>").arg(KV_CON_P3PN)); + return false; + } + if (!extract_simple_tag (KV_CON_P3PN, xml, elem, pers3_n_plur)) + return false; + } + else { + if (elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("unexpected ending tag <%1>" ).arg(elem.tag())); + return false; + } + else { + unknownElement (xml.lineNumber(), elem.tag() ); + return false; + } + } + } while (! endOfGroup); + + return true; +} + + +bool kvoctrainDoc::extract_L_GROUP_attr (XmlReader &xml, + XmlElement &elem, + int &width) +{ + width = 0; + list<XmlAttribute>::const_iterator first = elem.attributes ().begin (); + while (first != elem.attributes ().end ()) { + if ((*first).name () == KV_SIZEHINT) + width = (*first).intValue(); + else { + if (!unknownAttribute(xml.lineNumber(), "lesson", (*first).name ())) + return false; + } + first++; + } + return true; +} + + +bool kvoctrainDoc::loadLessonKvtMl (XmlElement elem, XmlReader& xml) +{ + bool endOfGroup = false; + QString s; + bool isCurr; + bool inQuery = false; + lesson_descr.clear(); + int width; + + if (!extract_L_GROUP_attr (xml, elem, width)) + return false; + setSizeHint (-1, width); + + do { + if (! xml.readElement (elem)) + break; + + if (elem.tag () == KV_LESS_GRP) { + if (! elem.isEndTag ()) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(elem.tag())); + return false; + } + else + endOfGroup = true; + + } + else if (elem.tag () == KV_LESS_DESC && !elem.isEndTag() ) { + int no; + if (!extract_L_DESCR_attr (xml, elem, no, isCurr, inQuery)) + return false; + + lessons_in_query.push_back(inQuery); + + if (isCurr && no != 0) + setCurrentLesson (no); + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + + if (elem.tag() == "#PCDATA") { // element data + s = xml.getText(); + + if (! xml.readElement (elem) ) { + errorKvtMl (xml.lineNumber(), i18n("I/O failure") ); + return false; + } + + if (elem.tag() != KV_LESS_DESC || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_LESS_DESC)); + return false; + } + } + else { + if (elem.tag() != KV_LESS_DESC || !elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(KV_LESS_DESC)); + return false; + } + s = ""; + } + lesson_descr.push_back (s); + } + else { + if (elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("unexpected ending tag <%1>" ).arg(elem.tag())); + return false; + } + else { + unknownElement (xml.lineNumber(), elem.tag() ); + return false; + } + } + } while (! endOfGroup); + + return true; +} + + +bool kvoctrainDoc::loadOptionsKvtMl (XmlElement elem, XmlReader& xml) +{ + bool endOfGroup = false; + QString s; + + do { + if (! xml.readElement (elem)) + break; + + if (elem.tag () == KV_OPTION_GRP) { + if (! elem.isEndTag ()) { + errorKvtMl (xml.lineNumber(), + i18n("expected ending tag <%1>").arg(elem.tag())); + return false; + } + else + endOfGroup = true; + + } + else if (elem.tag () == KV_OPT_SORT) { + sort_allowed = true; + + if (!extract_BOOL_attr (xml, elem, KV_OPTION_GRP, KV_BOOL_FLAG, + sort_allowed)) + return false; + + } + else { + if (elem.isEndTag() ) { + errorKvtMl (xml.lineNumber(), + i18n("unexpected ending tag <%1>" ).arg(elem.tag())); + return false; + } + else { + unknownElement (xml.lineNumber(), elem.tag() ); + return false; + } + } + } while (! endOfGroup); + + return true; +} + diff --git a/kvoctrain/kvoctrain/kvt-core/kvd_vcb.cpp b/kvoctrain/kvoctrain/kvt-core/kvd_vcb.cpp new file mode 100644 index 00000000..2dfde3fe --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvd_vcb.cpp @@ -0,0 +1,199 @@ +/*************************************************************************** + + maintain a document in vocabbox format + + ----------------------------------------------------------------------- + + begin : Thr Mar 23 21:00:53 MET 1999 + + copyright : (C) 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de> + (C) 2001 The KDE-EDU team + (C) 2004 Peter Hedlund <peter.hedlund@kdemail.net> + + ----------------------------------------------------------------------- + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <klocale.h> +#include <kapplication.h> +#include <kmessagebox.h> + +#include "kvoctraindoc.h" +#include "kvoctraincore.h" + + + +bool kvoctrainDoc::saveTypeNameVcb (QTextStream &/*os*/) +{ + return true; +} + + +bool kvoctrainDoc::loadTypeNameVcb (QTextStream &/*is*/) +{ + return true; +} + + +bool kvoctrainDoc::saveLessonVcb (QTextStream &/*os*/) +{ + return true; +} + + +bool kvoctrainDoc::loadLessonVcb (QTextStream &/*is*/) +{ + return true; +} + + +bool kvoctrainDoc::saveToVcb (QTextStream& os, QString &/*title*/) +{ + saveTypeNameVcb (os); + saveLessonVcb (os); + + int ent_no = 0; + int ent_percent = (int) vocabulary.size () / 100; + float f_ent_percent = (int) vocabulary.size () / 100.0; + emit progressChanged(this, 0); + + vector<kvoctrainExpr>::const_iterator first = vocabulary.begin (); + while (first != vocabulary.end ()) { + + ent_no++; + if (ent_percent != 0 && (ent_no % ent_percent) == 0 ) + emit progressChanged(this, int(ent_no / f_ent_percent)); + + QString s, exp; + + exp = (*first).getOriginal()+VCB_SEPARATOR; + exp += (*first).getTranslation(1)+VCB_SEPARATOR; + + exp += (*first).gradeStr (1, false)+VCB_SEPARATOR; + exp += (*first).gradeStr (1, true)+VCB_SEPARATOR; + s.setNum ((*first).getQueryDate (1, false)); + exp += s+VCB_SEPARATOR; + s.setNum ((*first).getQueryDate (1, true)); + exp += s; + + os << exp << "\n"; + + first++; + } + + setModified (false); + return os.device()->status() == IO_Ok; +} + + +bool kvoctrainDoc::loadFromVcb (QTextStream& is) +{ + + langs.clear(); + vocabulary.clear(); + loadTypeNameVcb (is); + loadLessonVcb (is); + + int size = is.device()->size (); + int ln = size / 40 / 100; // assume each line about 40 chars + float f_ent_percent = size / 100.0; + emit progressChanged (this, 0); + + for (int l = 0; !is.eof(); l++) { + QString s = is.readLine(); + + ln--; + if (ln <= 0) { + ln = size / 40 / 100; // assume each line about 40 chars + emit progressChanged(this, int(is.device()->at() / f_ent_percent)); + } + + if (!s.stripWhiteSpace().isEmpty()) { + QString o, t; + grade_t ograde = KV_LEV1_GRADE, + tgrade = KV_LEV1_GRADE; + size_t odate = time(0), + tdate = time(0); + + int pos = s.find (VCB_SEPARATOR); + if (pos >= 0) { + o = s.left(pos); + s.remove (0, pos+QString(VCB_SEPARATOR).length()); + } + + pos = s.find (VCB_SEPARATOR); + if (pos >= 0) { + t = s.left(pos); + s.remove (0, pos+QString(VCB_SEPARATOR).length()); + } + else { + t = s; + } + + pos = s.find (VCB_SEPARATOR); + if (pos >= 0) { + ograde = s.left(pos).toInt(); + s.remove (0, pos+QString(VCB_SEPARATOR).length()); + } + + pos = s.find (VCB_SEPARATOR); + if (pos >= 0) { + tgrade = s.left(pos).toInt(); + s.remove (0, pos+QString(VCB_SEPARATOR).length()); + } + + pos = s.find (VCB_SEPARATOR); + if (pos >= 0) { + odate = s.left(pos).toInt(); + s.remove (0, pos+QString(VCB_SEPARATOR).length()); + } + + if (s.stripWhiteSpace().length() > 0) { + tdate = s.toInt(); + } + + kvoctrainExpr bucket; + bucket.setOriginal(o); + bucket.addTranslation(t); + + bucket.setGrade(1, ograde, false); + if (ograde != 0) + bucket.setQueryCount(1, 1, false); + + bucket.setGrade(1, tgrade, true); + if (tgrade != 0) + bucket.setQueryCount(1, 1, true); + + bucket.setQueryDate(1, odate, false); + bucket.setQueryDate(1, tdate, true); + + appendEntry (&bucket); + } + } + + langs.push_back("en"); + langs.push_back("en"); + + setModified (false); + return is.device()->status() == IO_Ok; +} + + +void kvoctrainDoc::errorVcb (int /*line*/, const QString &text ) +{ + unknown_elem = true; + QApplication::setOverrideCursor( arrowCursor, true ); + QString s = kapp->makeStdCaption(i18n("Error in vocabbox file")); + QString msg = text; + KMessageBox::error(0, msg, s); + QApplication::restoreOverrideCursor(); +} diff --git a/kvoctrain/kvoctrain/kvt-core/kvd_voc.cpp b/kvoctrain/kvoctrain/kvt-core/kvd_voc.cpp new file mode 100644 index 00000000..e99c2e31 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvd_voc.cpp @@ -0,0 +1,141 @@ +/*************************************************************************** + + maintain a document in Vokabletrainer format + + ----------------------------------------------------------------------- + + begin : Wed Jun 15 19:32:00 PDT 2005 + + copyright : (C) 2005 Peter Hedlund <peter.hedlund@kdemail.net> + + ----------------------------------------------------------------------- + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <klocale.h> +#include <kapplication.h> +#include <kmessagebox.h> +#include <kdebug.h> + +#include "kvoctraindoc.h" +#include "kvoctraincore.h" + + +bool kvoctrainDoc::loadFromVoc(QTextStream& is) +{ + author = "http://www.vokabeln.de"; //DO NOT translate + + langs.clear(); + vocabulary.clear(); + lesson_descr.clear(); + + QString title, + lang1, + lang2, + expression, + original, + translation, + lessonDescr, + temp; + + int i, + wordCount, + lesson; + + int lines = 10000; + + QStringList titles, + languages, + words; + + bool keepGoing = true; + + while (keepGoing) + { + temp = is.readLine(); + keepGoing = !(temp.find("\",") > 0); + title.append(temp); + if (keepGoing) + title.append(" "); + } + + titles = QStringList::split("\",", title); + doctitle = titles[0].mid(1); + wordCount = titles[1].section(',', 0, 0).toInt(); + + is.readLine(); + is.readLine(); + + lang1 = is.readLine(); + languages = QStringList::split("\",", lang1); + + langs.push_back(languages[0].mid(1)); + langs.push_back(languages[1].mid(1)); + + keepGoing = true; + while (keepGoing) + keepGoing = !(is.readLine().find("8. Lernhilfe") > 0); //DO NOT translate + + for (i = 0; i <= 14; i++) + is.readLine(); + + for (i = 0; i < wordCount - 1; i++) + { + int c = 0; + expression.setLength(0); + + while (c < 2) + { + temp = is.readLine(); + c+= temp.contains("\","); + expression.append(temp); + if (c < 2) + expression.append(" "); + } + + words = QStringList::split("\",", expression); + original = words[0].mid(1); + translation = words[1].mid(1); + lesson = words[2].toInt(); + + kvoctrainExpr kve; + kve.setOriginal(original); + kve.setGrade(1, 0, false); + kve.setGrade(1, 0, true); + kve.setLesson(lesson); + kve.addTranslation(translation); + + vocabulary.push_back(kve); + + is.readLine(); + is.readLine(); + } + + is.readLine(); + is.readLine(); + is.readLine(); + + for (int i = 0; !is.eof() && i < lines; i++) + { + lessonDescr = is.readLine(); + lessonDescr = lessonDescr.mid(1, lessonDescr.length() - 2); + if (!lessonDescr.isEmpty()) + lesson_descr.push_back(lessonDescr); + else + break; + is.readLine(); + } + + setModified(false); + doc_url.setFileName(i18n("Untitled")); + return is.device()->status() == IO_Ok; +} diff --git a/kvoctrain/kvoctrain/kvt-core/kvd_wkvtml.cpp b/kvoctrain/kvoctrain/kvt-core/kvd_wkvtml.cpp new file mode 100644 index 00000000..af0ba06d --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvd_wkvtml.cpp @@ -0,0 +1,960 @@ +/*************************************************************************** + + write a kvtml document + + ----------------------------------------------------------------------- + + begin : Thu Mar 11 20: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. * + * * + ***************************************************************************/ + +#include "kvoctraincore.h" +#include "QueryManager.h" + +#include <kdebug.h> + +#include <qtextcodec.h> + +bool kvoctrainDoc::saveTypeNameKvtMl (XmlWriter &xml) +{ + if (type_descr.size() == 0) + return true; + + xml.writeText(" "); + xml.startTag (KV_TYPE_GRP, true, false, true); + + for (int lfn = 0; lfn < (int) type_descr.size(); lfn++) { + if (!type_descr[lfn].isNull() ) { + xml.writeText(" "); + xml.startTag (KV_TYPE_DESC, false); + xml.addAttribute (KV_TYPE_NO, lfn+1 ); + xml.closeTag(); + xml.writeText (type_descr[lfn]); + xml.endTag (KV_TYPE_DESC, true); + } + } + + xml.writeText(" "); + xml.endTag (KV_TYPE_GRP, true); + xml.writeText("\n"); + return true; +} + + +bool kvoctrainDoc::saveTenseNameKvtMl (XmlWriter &xml) +{ + if (tense_descr.size() == 0) + return true; + + xml.writeText(" "); + xml.startTag (KV_TENSE_GRP, true, false, true); + + for (int lfn = 0; lfn < (int) tense_descr.size(); lfn++) { + if (!tense_descr[lfn].isNull() ) { + xml.writeText(" "); + xml.startTag (KV_TENSE_DESC, false); + xml.addAttribute (KV_TENSE_NO, lfn+1 ); + xml.closeTag(); + xml.writeText (tense_descr[lfn]); + xml.endTag (KV_TENSE_DESC, true); + } + } + + xml.writeText(" "); + xml.endTag (KV_TENSE_GRP, true); + xml.writeText("\n"); + return true; +} + + +bool kvoctrainDoc::saveUsageNameKvtMl (XmlWriter &xml) +{ + if (usage_descr.size() == 0) + return true; + + xml.writeText(" "); + xml.startTag (KV_USAGE_GRP, true, false, true); + + for (int lfn = 0; lfn < (int) usage_descr.size(); lfn++) { + if (!usage_descr[lfn].isNull() ) { + xml.writeText(" "); + xml.startTag (KV_USAGE_DESC, false); + xml.addAttribute (KV_USAGE_NO, lfn+1 ); + xml.closeTag(); + xml.writeText (usage_descr[lfn]); + xml.endTag (KV_USAGE_DESC, true); + } + } + + xml.writeText(" "); + xml.endTag (KV_USAGE_GRP, true); + xml.writeText("\n"); + return true; +} + + +bool kvoctrainDoc::saveLessonKvtMl (XmlWriter &xml) +{ + if (lesson_descr.size() == 0) + return true; + + xml.writeText(" "); // indent entry a bit + xml.startTag (KV_LESS_GRP, false); + xml.addAttribute (KV_SIZEHINT, getSizeHint (-1)); + xml.closeTag(false, true); + + for (int lfn = 0; lfn < (int) lesson_descr.size(); lfn++) { + if (!lesson_descr[lfn].isNull() ) { + xml.writeText(" "); + xml.startTag (KV_LESS_DESC, false); + xml.addAttribute (KV_LESS_NO, lfn+1 ); + if (getCurrentLesson() == lfn+1) + xml.addAttribute (KV_LESS_CURR, (QString) "1" ); + if (lfn < (int) lessons_in_query.size() && lessons_in_query[lfn]) + xml.addAttribute (KV_LESS_QUERY, (QString) "1" ); + xml.closeTag(); + xml.writeText (lesson_descr[lfn]); + xml.endTag (KV_LESS_DESC, true); + } + } + + xml.writeText(" "); + xml.endTag (KV_LESS_GRP, true); + xml.writeText("\n"); + return true; +} + + +bool kvoctrainDoc::saveConjug (const Conjugation &curr_conjug, QString type, + XmlWriter &xml, QString identstr) +{ + bool linefeed = type == CONJ_PREFIX; + if (linefeed) + identstr+" "; + else + identstr = ""; + + if (!curr_conjug.pers1Singular(type).isEmpty() ) { + xml.writeText(identstr); + xml.startTag (KV_CON_P1S, true, false, false); + xml.writeText (curr_conjug.pers1Singular(type)); + xml.endTag (KV_CON_P1S, linefeed); + } + + if (!curr_conjug.pers2Singular(type).isEmpty() ) { + xml.writeText(identstr); + xml.startTag (KV_CON_P2S, true, false, false); + xml.writeText (curr_conjug.pers2Singular(type)); + xml.endTag (KV_CON_P2S, linefeed); + } + + bool common = curr_conjug.pers3SingularCommon(type); + if (!curr_conjug.pers3FemaleSingular(type).isEmpty() + || common) { + xml.writeText(identstr); + xml.startTag (KV_CON_P3SF, false, false, false); + if (common) + xml.addAttribute (KV_CONJ_COMMON, common); + xml.closeTag(false, false); + xml.writeText (curr_conjug.pers3FemaleSingular(type)); + xml.endTag (KV_CON_P3SF, linefeed); + } + + if (!curr_conjug.pers3MaleSingular(type).isEmpty() ) { + xml.writeText(identstr); + xml.startTag (KV_CON_P3SM, true, false, false); + xml.writeText (curr_conjug.pers3MaleSingular(type)); + xml.endTag (KV_CON_P3SM, linefeed); + } + + if (!curr_conjug.pers3NaturalSingular(type).isEmpty() ) { + xml.writeText(identstr); + xml.startTag (KV_CON_P3SN, true, false, false); + xml.writeText (curr_conjug.pers3NaturalSingular(type)); + xml.endTag (KV_CON_P3SN, linefeed); + } + + if (!curr_conjug.pers1Plural(type).isEmpty() ) { + xml.writeText(identstr); + xml.startTag (KV_CON_P1P, true, false, false); + xml.writeText (curr_conjug.pers1Plural(type)); + xml.endTag (KV_CON_P1P, linefeed); + } + + if (!curr_conjug.pers2Plural(type).isEmpty() ) { + xml.writeText(identstr); + xml.startTag (KV_CON_P2P, true, false, false); + xml.writeText (curr_conjug.pers2Plural(type)); + xml.endTag (KV_CON_P2P, linefeed); + } + + common = curr_conjug.pers3PluralCommon(type); + if (!curr_conjug.pers3FemalePlural(type).isEmpty() + || common) { + xml.writeText(identstr); + xml.startTag (KV_CON_P3PF, false, false, false); + if (common) + xml.addAttribute (KV_CONJ_COMMON, common); + xml.closeTag(false, false); + xml.writeText (curr_conjug.pers3FemalePlural(type)); + xml.endTag (KV_CON_P3PF, linefeed); + } + + if (!curr_conjug.pers3MalePlural(type).isEmpty() ) { + xml.writeText(identstr); + xml.startTag (KV_CON_P3PM, true, false, false); + xml.writeText (curr_conjug.pers3MalePlural(type)); + xml.endTag (KV_CON_P3PM, linefeed); + } + + if (!curr_conjug.pers3NaturalPlural(type).isEmpty() ) { + xml.writeText(identstr); + xml.startTag (KV_CON_P3PN, true, false, false); + xml.writeText (curr_conjug.pers3NaturalPlural(type)); + xml.endTag (KV_CON_P3PN, linefeed); + } + + return true; + +} + +bool kvoctrainDoc::saveConjugHeader(vector<Conjugation> &curr_conjug, + XmlWriter &xml) +{ +/* + <conjugation> used in header for definiton of "prefix" + <e l="de"> lang determines also lang order in entries !! + <s1>I</s1> which must NOT differ + <s2>you<2> + <s3f common="0">he</s3f> + <s3m>she</s3m> + <s3n>it</s3n> + <p1>we</p1> + <p2>you</p2> + <p3f common="1">they</p3f> + <p3m>they</p3m> + <p3n>they</p3n> + </e> + </conjugation> + +*/ + if (curr_conjug.size() == 0) + return true; + + xml.writeText(" "); // indent entry a bit + xml.startTag (KV_CONJUG_GRP, false); + xml.closeTag(false, true); + + QString def, indef, s; + for (int ent = 0; ent < QMIN((int) curr_conjug.size(), numLangs()); ent++) { + xml.writeText(" "); // indent entry a bit + xml.startTag (KV_CON_ENTRY, false); + + if (ent == 0) { + s = getOriginalIdent().stripWhiteSpace(); + if (s.isEmpty() ) + s = "original"; + } + else { + s = getIdent(ent).stripWhiteSpace(); + if (s.isEmpty() ) { + s.setNum (ent); + s.insert (0, "translation "); + } + } + xml.addAttribute (KV_LANG, s); + xml.closeTag(false, true); + + if (!saveConjug (curr_conjug[ent], CONJ_PREFIX, xml, " ") ) + return false; + + xml.writeText(" "); + xml.endTag (KV_CON_ENTRY, true); + } + + xml.writeText(" "); + xml.endTag (KV_CONJUG_GRP, true); + xml.writeText("\n"); + return true; +} + + +bool kvoctrainDoc::saveComparison (const Comparison &comp, + XmlWriter &xml, int ident) + +/* + <comparison> + <l1>good</l1> + <l2>better</l2> + <l3>best</l3> + </comparison> +*/ + +{ + if (comp.isEmpty()) + return true; + + xml.writeText("\n"); + QString identstr; + identstr.fill (' ', ident+1); + + xml.writeText(identstr); + xml.startTag (KV_COMPARISON_GRP, false); + xml.closeTag(false, true); + xml.writeText(identstr+" "); + + if (!comp.l1().isEmpty() ) { + xml.startTag (KV_COMP_L1, true, false, false); + xml.writeText (comp.l1()); + xml.endTag (KV_COMP_L1, false); + } + + if (!comp.l2().isEmpty() ) { + xml.startTag (KV_COMP_L2, true, false, false); + xml.writeText (comp.l2()); + xml.endTag (KV_COMP_L2, false); + } + + if (!comp.l3().isEmpty() ) { + xml.startTag (KV_COMP_L3, true, false, false); + xml.writeText (comp.l3()); + xml.endTag (KV_COMP_L3, false); + } + + xml.writeText("\n"+identstr); + xml.endTag (KV_COMPARISON_GRP, true); + xml.writeText(identstr); // indent next element + return true; +} + + +bool kvoctrainDoc::saveMultipleChoice (const MultipleChoice &mc, + XmlWriter &xml, int ident) + +/* + <multiplechoice> + <mc1>good</mc1> + <mc2>better</mc2> + <mc3>best</mc3> + <mc4>best 2</mc4> + <mc5>best 3</mc5> + </multiplechoice> +*/ + +{ + if (mc.isEmpty()) + return true; + + xml.writeText("\n"); + QString identstr; + identstr.fill (' ', ident+1); + + xml.writeText(identstr); + xml.startTag (KV_MULTIPLECHOICE_GRP, false); + xml.closeTag(false, true); + xml.writeText(identstr+" "); + + if (!mc.mc1().isEmpty() ) { + xml.startTag (KV_MC_1, true, false, false); + xml.writeText (mc.mc1()); + xml.endTag (KV_MC_1, false); + } + + if (!mc.mc2().isEmpty() ) { + xml.startTag (KV_MC_2, true, false, false); + xml.writeText (mc.mc2()); + xml.endTag (KV_MC_2, false); + } + + if (!mc.mc3().isEmpty() ) { + xml.startTag (KV_MC_3, true, false, false); + xml.writeText (mc.mc3()); + xml.endTag (KV_MC_3, false); + } + + if (!mc.mc4().isEmpty() ) { + xml.startTag (KV_MC_4, true, false, false); + xml.writeText (mc.mc4()); + xml.endTag (KV_MC_4, false); + } + + if (!mc.mc5().isEmpty() ) { + xml.startTag (KV_MC_5, true, false, false); + xml.writeText (mc.mc5()); + xml.endTag (KV_MC_5, false); + } + + xml.writeText("\n"+identstr); + xml.endTag (KV_MULTIPLECHOICE_GRP, true); + xml.writeText(identstr); // indent next element + return true; +} + + +bool kvoctrainDoc::saveConjugEntry (Conjugation &curr_conjug, + XmlWriter &xml, + int ident) + +/* + <conjugation> in entry for definition of tenses of (irreg.) verbs + <t n="sipa"> + <s1>go</s1> + <s2>go</s2> + <s3f>goes</s3f> + <s3m>goes</s3m> + <s3n>goes</s3n> + <p1>go</p1> + <p2>go</p2> + <p3f>go</p3f> + <p3m>go</p3m> + <p3n>go</p3n> + </t> + </conjugation> +*/ +{ + curr_conjug.cleanUp(); + if (curr_conjug.numEntries() == 0 ) + return true; + + QString identstr; + identstr.fill (' ', ident+1); + xml.writeText("\n"); + + xml.writeText(identstr); // indent entry a bit + xml.startTag (KV_CONJUG_GRP, false); + xml.closeTag(false, true); + + QString def, indef, s; + QString type; + for (int lfn = 0; lfn < (int) curr_conjug.numEntries(); lfn++) { + xml.writeText(identstr+" "); // indent entry a bit + xml.startTag (KV_CON_TYPE, false); + type = curr_conjug.getType(lfn); + xml.addAttribute (KV_CON_NAME, type); + xml.closeTag(false, false); + + if (!saveConjug (curr_conjug, curr_conjug.getType(lfn), xml, identstr) ) + return false; + + xml.endTag (KV_CON_TYPE, true); + } + + xml.writeText(identstr); + xml.endTag (KV_CONJUG_GRP, true); + xml.writeText(identstr); // indent next element + return true; +} + + +bool kvoctrainDoc::saveArticleKvtMl (XmlWriter &xml) + +/* + <article> + <e l="de"> lang determines also lang order in entries !! + <fi>eine</fi> which must NOT differ + <fd>die</fd> + <mi>ein</mi> + <md>der</md> + <ni>ein</ni> + <nd>das</nd> + </e> + </article> +*/ + +{ + if (articles.size() == 0) + return true; + + xml.writeText(" "); // indent entry a bit + xml.startTag (KV_ARTICLE_GRP, false); + xml.closeTag(false, true); + + QString def, indef, s; + for (int lfn = 0; lfn < QMIN((int) articles.size(), numLangs()); lfn++) { + xml.writeText(" "); // indent entry a bit + xml.startTag (KV_ART_ENTRY, false); + if (lfn == 0) { + s = getOriginalIdent().stripWhiteSpace(); + if (s.isEmpty() ) + s = "original"; + } + else { + s = getIdent(lfn).stripWhiteSpace(); + if (s.isEmpty() ) { + s.setNum (lfn); + s.insert (0, "translation "); + } + } + xml.addAttribute (KV_LANG, s); + xml.closeTag(false, true); + + articles[lfn].female(def, indef); + if (!def.isEmpty() ) { + xml.writeText(" "); + xml.startTag (KV_ART_FD, true, false, false); + xml.writeText (def); + xml.endTag (KV_ART_FD, true); + } + if (!indef.isEmpty() ) { + xml.writeText(" "); + xml.startTag (KV_ART_FI, true, false, false); + xml.writeText (indef); + xml.endTag (KV_ART_FI, true); + } + + articles[lfn].male(def, indef); + if (!def.isEmpty() ) { + xml.writeText(" "); + xml.startTag (KV_ART_MD, true, false, false); + xml.writeText (def); + xml.endTag (KV_ART_MD, true); + } + if (!indef.isEmpty() ) { + xml.writeText(" "); + xml.startTag (KV_ART_MI, true, false, false); + xml.writeText (indef); + xml.endTag (KV_ART_MI, true); + } + + articles[lfn].natural(def, indef); + if (!def.isEmpty() ) { + xml.writeText(" "); + xml.startTag (KV_ART_ND, true, false, false); + xml.writeText (def); + xml.endTag (KV_ART_ND, true); + } + if (!indef.isEmpty() ) { + xml.writeText(" "); + xml.startTag (KV_ART_NI, true, false, false); + xml.writeText (indef); + xml.endTag (KV_ART_NI, true); + } + + xml.writeText(" "); + xml.endTag (KV_ART_ENTRY, true); + xml.writeText(""); + } + + xml.writeText(" "); + xml.endTag (KV_ARTICLE_GRP, true); + xml.writeText("\n"); + return true; +} + + +bool kvoctrainDoc::saveOptionsKvtMl (XmlWriter &xml) +{ + xml.writeText(" "); // indent entry a bit + xml.startTag (KV_OPTION_GRP, false); + xml.closeTag(false, true); + + xml.writeText(" "); + xml.startTag (KV_OPT_SORT, false); + xml.addAttribute (KV_BOOL_FLAG, sort_allowed ); + xml.closeTag (true, true); + + xml.writeText(" "); + xml.endTag (KV_OPTION_GRP, true); + xml.writeText("\n"); + return true; +} + + +bool kvoctrainDoc::saveToKvtMl (QTextStream& os, QString &title) { + bool first_expr = true; + + os.setCodec(QTextCodec::codecForName("UTF-8")); + + XmlWriter xml (os); + xml.setAutoEndl (false); + + xml.startTag ("!DOCTYPE", false); + xml.writeText (" kvtml SYSTEM \"kvoctrain.dtd\""); + xml.closeTag (false, true); + + xml.startTag ("!--", false, true, true); + xml.writeText ("\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" + "--"); + xml.closeTag (false, true); + + xml.writeText ("\n "); + xml.startTag (KV_DOCTYPE, false); + xml.writeText ("\n "); + xml.addAttribute (KV_ENCODING, (QString)"UTF-8"); + xml.writeText ("\n "); + + xml.addAttribute (KV_GENERATOR, (QString) "kvoctrain" KVD_VERS_PREFIX KVOCTRAIN_VERSION_STRING); + xml.writeText ("\n "); + xml.addAttribute (KV_COLS, numLangs() ); + xml.writeText ("\n "); + xml.addAttribute (KV_LINES, numEntries() ); + if (!title.isEmpty()) { + xml.writeText ("\n "); + xml.addAttribute (KV_TITLE, getTitle() ); + doctitle = title; + } + else if (!doctitle.isEmpty()) { + xml.writeText ("\n "); + xml.addAttribute (KV_TITLE, doctitle); + } + + if (!author.isEmpty()) { + xml.writeText ("\n "); + xml.addAttribute (KV_AUTHOR, getAuthor() ); + } + + if (!license.isEmpty()) { + xml.writeText ("\n "); + xml.addAttribute (KV_LICENSE, getLicense() ); + } + + if (!doc_remark.isEmpty()) { + xml.writeText ("\n "); + xml.addAttribute (KV_DOC_REM, getDocRemark() ); + } + + xml.closeTag (false, true); + xml.writeText ("\n"); + + if (!saveLessonKvtMl(xml)) + return false; + + if (!saveArticleKvtMl(xml)) + return false; + + if (!saveConjugHeader(conjugations, xml)) + return false; + + if (!saveOptionsKvtMl(xml)) + return false; + + if (!saveTypeNameKvtMl(xml)) + return false; + + if (!saveTenseNameKvtMl(xml)) + return false; + + if (!saveUsageNameKvtMl(xml)) + return false; + + QString q_org, q_trans; + vector<kvoctrainExpr>::const_iterator first = vocabulary.begin (); + getQueryLang (q_org, q_trans); + + int ent_no = 0; + int ent_percent = (int) vocabulary.size () / 100; + float f_ent_percent = (int) vocabulary.size () / 100.0; + emit progressChanged(this, 0); + + while (first != vocabulary.end ()) { + xml.writeText(" "); // indent entry a bit + xml.startTag (KV_EXPR, false); + + ent_no++; + if (ent_percent != 0 && (ent_no % ent_percent) == 0 ) + 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) lesson_descr.size() ) { // should not be + kdError() << "index of lesson member too high: " << lm << endl; + lm = 0; + } + ls.setNum (lm); + xml.addAttribute (KV_LESS_MEMBER, ls); + } + + if ((*first).isInQuery()) { // entry was selected for query + xml.addAttribute (KV_SELECTED, (QString) "1"); + } + + if (!(*first).isActive()) { // entry was inactive + xml.addAttribute (KV_INACTIVE, (QString) "1"); + } + + if ((*first).uniqueType() && !(*first).getType(0).isEmpty()) { + xml.addAttribute (KV_EXPRTYPE, (*first).getType(0)); + } + + xml.closeTag (); + xml.startTag (KV_ORG, false); + if (first_expr) { // save space, only tell language in first entry + QString s; + s.setNum (getSizeHint (0)); + xml.addAttribute (KV_SIZEHINT, s); + + s = getOriginalIdent().stripWhiteSpace(); + if (s.isEmpty() ) + s = "original"; + xml.addAttribute (KV_LANG, s); + if (s == q_org) + xml.addAttribute (KV_QUERY, (QString) KV_O); + else if (s == q_trans) + xml.addAttribute (KV_QUERY, (QString) KV_T); + + } + + if (!(*first).getRemark(0).isEmpty() ) { + xml.addAttribute (KV_REMARK, (*first).getRemark(0)); + } + + if (!(*first).getSynonym(0).isEmpty() ) { + xml.addAttribute (KV_SYNONYM, (*first).getSynonym(0)); + } + + if (!(*first).getExample(0).isEmpty() ) { + xml.addAttribute (KV_EXAMPLE, (*first).getExample(0)); + } + + if (!(*first).getUsageLabel(0).isEmpty() ) { + xml.addAttribute (KV_USAGE, (*first).getUsageLabel(0)); + } + + if (!(*first).getParaphrase(0).isEmpty() ) { + xml.addAttribute (KV_PARAPHRASE, (*first).getParaphrase(0)); + } + + if (!(*first).getAntonym(0).isEmpty() ) { + xml.addAttribute (KV_ANTONYM, (*first).getAntonym(0)); + } + + if (!(*first).getPronunce(0).isEmpty() ) { + xml.addAttribute (KV_PRONUNCE, (*first).getPronunce(0)); + } + + if (!(*first).uniqueType() && !(*first).getType(0).isEmpty()) { + xml.addAttribute (KV_EXPRTYPE, (*first).getType(0)); + } + + xml.closeTag (); + + if (!saveMultipleChoice ((*first).getMultipleChoice(0), xml, 1)) + 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(conj, xml, 1)) + return false; + } + else if (entype == QM_ADJ + && !(*first).getComparison(0).isEmpty()) { + Comparison comp = (*first).getComparison(0); + if (!saveComparison (comp, xml, 1)) + return false; + } + + xml.writeText( (*first).getOriginal()); + xml.endTag (KV_ORG); + + int trans = 1; + while (trans < (int)langs.size()) { + xml.startTag (KV_TRANS, false); + if (first_expr) { // save space, only tell language in first entry + QString s; + s.setNum (getSizeHint (trans)); + xml.addAttribute (KV_SIZEHINT, s); + + s = getIdent(trans).stripWhiteSpace(); + if (s.isEmpty() ) { + s.setNum (trans); + s.insert (0, "translation "); + } + xml.addAttribute (KV_LANG, s); + if (s == q_org) + xml.addAttribute (KV_QUERY, (QString) KV_O); + else if (s == q_trans) + xml.addAttribute (KV_QUERY, (QString) KV_T); + } + + QString s1, s2; + + if ((*first).getGrade(trans, false) != 0 + ||(*first).getGrade(trans, true) != 0) { + xml.addAttribute (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)); + xml.addAttribute (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)); + xml.addAttribute (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)); + xml.addAttribute (KV_DATE, s1 +';' +s2); + } + + if (!(*first).getRemark(trans).isEmpty() ) { + xml.addAttribute (KV_REMARK, (*first).getRemark(trans)); + } + + if (!(*first).getFauxAmi(trans, false).isEmpty() ) { + xml.addAttribute (KV_FAUX_AMI_F, (*first).getFauxAmi(trans, false)); + } + + if (!(*first).getFauxAmi(trans, true).isEmpty() ) { + xml.addAttribute (KV_FAUX_AMI_T, (*first).getFauxAmi(trans, true)); + } + + if (!(*first).getSynonym(trans).isEmpty() ) { + xml.addAttribute (KV_SYNONYM, (*first).getSynonym(trans)); + } + + if (!(*first).getExample(trans).isEmpty() ) { + xml.addAttribute (KV_EXAMPLE, (*first).getExample(trans)); + } + + if (!(*first).getUsageLabel(trans).isEmpty() ) { + xml.addAttribute (KV_USAGE, (*first).getUsageLabel(trans)); + } + + if (!(*first).getParaphrase(trans).isEmpty() ) { + xml.addAttribute (KV_PARAPHRASE, (*first).getParaphrase(trans)); + } + + if (!(*first).getAntonym(trans).isEmpty() ) { + xml.addAttribute (KV_ANTONYM, (*first).getAntonym(trans)); + } + + if (!(*first).getPronunce(trans).isEmpty() ) { + xml.addAttribute (KV_PRONUNCE, (*first).getPronunce(trans)); + } + + if (!(*first).uniqueType() && !(*first).getType(trans).isEmpty()) { + xml.addAttribute (KV_EXPRTYPE, (*first).getType(trans)); + } + + xml.closeTag (); + + // only save conjugations when type == verb + + if (!saveMultipleChoice ((*first).getMultipleChoice(trans), xml, 1)) + 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(conj, xml, 1+trans)) + return false; + } + + if ( entype == QM_ADJ + && !(*first).getComparison(trans).isEmpty()) { + Comparison comp = (*first).getComparison(trans); + if (!saveComparison (comp, xml, 1+trans)) + return false; + } + + xml.writeText((*first).getTranslation(trans)); + xml.endTag (KV_TRANS); + trans++; + } + xml.endTag (KV_EXPR, true); + first++; + first_expr = false; + } + xml.endTag (KV_DOCTYPE, true); + + setModified (false); + return os.device()->status() == IO_Ok; +} diff --git a/kvoctrain/kvoctrain/kvt-core/kvoctraincore.h b/kvoctrain/kvoctrain/kvt-core/kvoctraincore.h new file mode 100644 index 00000000..365882c6 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvoctraincore.h @@ -0,0 +1,115 @@ +/*************************************************************************** + + common #defines for kvoctrain core + + ----------------------------------------------------------------------- + + begin : Thu Nov 25 10: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 KVOCTRAINCORE_H +#define KVOCTRAINCORE_H + +/////////////////////////////////////////////////////////////////// +// Config file entries + +#define CFG_MODIFIED "Modified" +#define CFG_FILENAME "Filename" +#define CFG_TITLE "Title" + +#define CFG_APPEARANCE "Appearance" +#define CFG_XMLOPS_R "XmlOps_R" +#define CFG_XMLOPS_W "XmlOps_W" +#define CFG_XMLOPS_S "XmlOps_S" +#define CFG_IPA_FSIZE "IPAFontSize" +#define CFG_IPA_FFAMILY "IPAFontFamily" +#define CFG_FSIZE "FontSize" +#define CFG_FFAMILY "FontFamily" +#define CFG_FCHARSET "FontCharSet" +#define CFG_SHOW_TOOLBAR "ShowToolbar" +#define CFG_SHOW_STATUSBAR "ShowStatusbar" +#define CFG_TOOLBAR_POS "ToolBar_Pos" + +#define CFG_GENERAL "General" +#define CFG_LASTFILE "LastFile" +#define CFG_PASTEORDER "PasteOrder" +#define CFG_ENTRIESLESSON "EntriesPerLesson" +#define CFG_HEADER_RESIZER "HeaderResizer" +#define CFG_AUTOSAVEOPT "AutoSaveOptions" +#define CFG_ENTRYAUTOAPPLY "EntryAutomaticApply" + +#define CFG_LESSONSIZE "LessonSize" + +#define CFG_QUERYPROP "QueryProperties" +#define CFG_QUERYMODE "QueryMode" +#define CFG_DEFTRANS "DefaultTranslation" +#define CFG_DEFORG "DefaultOriginal" + +#define CFG_NUMLANGSET "NumLangSet" +#define CFG_L_SHORT "ShortId" +#define CFG_L_SHORT2 "Short2Id" +# define CFG_L_LANG "LongId_KDE2" +# define CFG_L_PIXMAP "Pixmap_KDE2" +#define CFG_L_KBLAYOUT "KeyboardLayout" +#define CFG_L_FONT "Font" +#define CFG_L_STDFONT "SpecialFont" + +#define CFG_QUERYMANAG "QueryManager" +#define CFG_QM_DATE_ITEM "DateItem" +#define CFG_QM_DATE_COMP "DateComp" +#define CFG_QM_QUERY_ITEM "QueryItem" +#define CFG_QM_QUERY_COMP "QueryComp" +#define CFG_QM_BAD_ITEM "BadItem" +#define CFG_QM_BAD_COMP "BadComp" +#define CFG_QM_TYPE_ITEM "TypeItem" +#define CFG_QM_TYPE_COMP "TypeComp" +#define CFG_QM_GRADE_ITEM "GradeItem" +#define CFG_QM_GRADE_COMP "GradeComp" +#define CFG_QM_LESSON_ITEM "LessonItem" +#define CFG_QM_LESSON_COMP "LessonComp" +#define CFG_QM_BLOCK_ITEM "BlockItem" +#define CFG_QM_EXPIRE_ITEM "ExpireItem" + +#define CFG_QUERY_PRESETTING "QueryPreSettings" +#define CFG_QP_NUM "NumPreSetting" +#define CFG_QP_NAME "Name" +#define CFG_QP_THRESH "Threshhold" +#define CFG_QP_BLOCK "Blocking" +#define CFG_QP_QUERY "Query" + +#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 "__" + +#define MAX_LESSON 25 +#define THRESH_LESSON KV_MIN_GRADE +#define MAX_LANGSET 100 + +#define KVTLIB_DEBUG_AREA 12003 +#define KVOCTRAIN_VERSION_STRING "0.8.3" // maybe split KVTLIB_VERSION/KVAPP_VERSION + +#endif // KVOCTRAINCORE_H diff --git a/kvoctrain/kvoctrain/kvt-core/kvoctraindoc.cpp b/kvoctrain/kvoctrain/kvt-core/kvoctraindoc.cpp new file mode 100644 index 00000000..f2701bed --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvoctraindoc.cpp @@ -0,0 +1,1061 @@ +/*************************************************************************** + + + maintain a kvoctrain document + + ----------------------------------------------------------------------- + + begin : Thu Mar 11 20: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. * + * * + ***************************************************************************/ + + +#include "kvoctraindoc.h" + +#include <kapplication.h> +#include <klocale.h> +#include <kdebug.h> +#include <kmessagebox.h> +#include <kio/netaccess.h> + +#include <qfileinfo.h> +#include <qregexp.h> + +#include <algorithm> +#include <functional> +#include <vector> +using namespace std; + +#include <iostream> + +#include <float.h> + +#include "kvoctraincore.h" +#include "prefs.h" + +//******************************************************** +// kvoctrainDoc +//******************************************************** + +void kvoctrainDoc::setVersion (const QString & vers) +{ + doc_version = vers; +} + + +void kvoctrainDoc::getVersion(int &, int &, int &) +{ +} + + +void kvoctrainDoc::Init () +{ + + 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 = ""; +} + + +kvoctrainDoc::kvoctrainDoc(QObject *parent, const KURL& url) +{ + Init(); + if (!url.isEmpty()) + doc_url = url; + + connect( this, SIGNAL(progressChanged(kvoctrainDoc*,int)), parent, SLOT(slotProgress(kvoctrainDoc*,int)) ); + + QString tmpfile; + if (KIO::NetAccess::download( url, tmpfile, 0 )) + { + QFile f(tmpfile); + if (!f.open(IO_ReadOnly)) + { + KMessageBox::error(0, i18n("<qt>Cannot open file<br><b>%1</b></qt>").arg(url.path())); + return; + } + + FileType ft = detectFT(tmpfile); + + bool read = false; + while (!read) { + + QApplication::setOverrideCursor( waitCursor ); + switch (ft) { + case kvtml: + { + QTextStream is (&f); + read = loadFromKvtMl (is); + } + break; + + case vt_lex: + { + QTextStream is (&f); + read = loadFromLex (is); + } + break; + + case vt_vcb: + { + QTextStream is (&f); + read = loadFromVcb (is); + } + break; + + case vt_voc: + { + QTextStream is (&f); + read = loadFromVoc(is); + } + break; + + case csv: + { + QTextStream is(&f); + read = loadFromCsv(is); + } + break; + + default: + { + QTextStream is (&f); + read = loadFromKvtMl (is); + } + } + + QApplication::restoreOverrideCursor(); + + if (!read) { + if (unknown_attr || unknown_elem ) { + Init(); + return; + } + 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; + } + } + } + f.close(); + KIO::NetAccess::removeTempFile( tmpfile ); + } +} + + +kvoctrainDoc::~kvoctrainDoc() +{ +} + + +bool kvoctrainDoc::saveAs (QObject *parent, const KURL & url, QString title, FileType ft) +{ + connect( this, SIGNAL(progressChanged(kvoctrainDoc*,int)), parent, SLOT(slotProgress(kvoctrainDoc*,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("<qt>Cannot write to file<br><b>%1</b></qt>").arg(tmp.path())); + return false; + } + + QApplication::setOverrideCursor( waitCursor ); + switch (ft) { + case kvtml: { + QTextStream os( &f ); // serialize using f + saved = saveToKvtMl(os, title); + } + break; + + case vt_lex: { + QTextStream os( &f ); // serialize using f + saved = saveToLex(os, title); + } + break; + + case vt_vcb: { + QTextStream os( &f ); // serialize using f + saved = saveToVcb(os, title); + } + break; + + case csv: { + QTextStream os( &f ); // serialize using f + saved = saveToCsv(os, title); + } + break; + + default: { + kdError() << "kvcotrainDoc::saveAs(): unknown filetype" << endl; + } + break; + } + f.close(); + QApplication::restoreOverrideCursor(); + + if (!saved) { + 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; +} + + +kvoctrainExpr *kvoctrainDoc::getEntry(int index) +{ + if (index < 0 || index >= (int)vocabulary.size() ) + return 0; + else + return &vocabulary[index]; +} + + +void kvoctrainDoc::removeEntry(int index) +{ + if (index >= 0 && index < (int)vocabulary.size() ) + vocabulary.erase (vocabulary.begin() + index); +} + + +int kvoctrainDoc::findIdent (const QString &lang) const +{ + vector<QString>::const_iterator first = langs.begin(); + int count = 0; + while (first != langs.end()) { + if ( *first == lang) + return count; + first++; + count++; + } + return -1; +} + + +QString kvoctrainDoc::getIdent (int index) const +{ + if (index >= (int)langs.size() || index < 1 ) + return ""; + else + return langs[index]; +} + + +void kvoctrainDoc::setIdent (int idx, const QString &id) +{ + if (idx < (int)langs.size() && idx >= 1 ) { + langs[idx] = id; + } +} + + +QString kvoctrainDoc::getTypeName (int index) const +{ + if (index >= (int)type_descr.size()) + return ""; + else + return type_descr[index]; +} + + +void kvoctrainDoc::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 kvoctrainDoc::getTenseName (int index) const +{ + if (index >= (int)tense_descr.size()) + return ""; + else + return tense_descr[index]; +} + + +void kvoctrainDoc::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 kvoctrainDoc::getUsageName (int index) const +{ + if (index >= (int)usage_descr.size()) + return ""; + else + return usage_descr[index]; +} + + +void kvoctrainDoc::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 kvoctrainDoc::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 kvoctrainDoc::getConjugation (int idx) const +{ + if (idx >= (int)conjugations.size() || idx < 0) { + return Conjugation(); + } + else { + return conjugations[idx]; + } +} + + +void kvoctrainDoc::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 kvoctrainDoc::getArticle (int idx) const +{ + if (idx >= (int)articles.size() || idx < 0) { + return Article(); + } + else { + return articles[idx]; + } +} + + +int kvoctrainDoc::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 kvoctrainDoc::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<kvoctrainExpr, void> +{ + +public: + + eraseTrans (int idx) + : index (idx) {} + + void operator() (kvoctrainExpr& x) const + { + x.removeTranslation(index); + } + + private: + int index; +}; + + +void kvoctrainDoc::removeIdent (int index) +{ + if (index < (int)langs.size() && index >= 1 ) { + langs.erase(langs.begin() + index); + for_each (vocabulary.begin(), vocabulary.end(), eraseTrans(index)); + } +} + + +QString kvoctrainDoc::getOriginalIdent () const +{ + if (langs.size() > 0) + return langs[0]; + else + return ""; +} + + +void kvoctrainDoc::setOriginalIdent (const QString &id) +{ + if (langs.size() > 0) { + langs[0] = id; + } +} + + +class sortByOrg : public binary_function<kvoctrainExpr, kvoctrainExpr, bool> +{ + +public: + + sortByOrg (bool _dir) + : dir (_dir) {} + + bool operator() (const kvoctrainExpr& x, const kvoctrainExpr& 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<kvoctrainExpr, kvoctrainExpr, bool> +{ + +public: + + sortByLessonAndOrg_alpha (bool _dir, kvoctrainDoc &_doc) + : dir (_dir), doc(_doc) {} + + bool operator() (const kvoctrainExpr& x, const kvoctrainExpr& 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; + kvoctrainDoc &doc; +}; + + +class sortByLessonAndOrg_index + : public binary_function<kvoctrainExpr, kvoctrainExpr, bool> +{ + +public: + + sortByLessonAndOrg_index (bool _dir, kvoctrainDoc &_doc) + : dir (_dir), doc(_doc) {} + + bool operator() (const kvoctrainExpr& x, const kvoctrainExpr& 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; + kvoctrainDoc &doc; +}; + + +class sortByTrans : public binary_function<kvoctrainExpr, kvoctrainExpr, bool> +{ + +public: + + sortByTrans (int i, bool _dir) + : index(i), dir (_dir) {} + + bool operator() (const kvoctrainExpr& x, const kvoctrainExpr& 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 kvoctrainDoc::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 kvoctrainDoc::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 kvoctrainDoc::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<kvoctrainExpr, void> +{ + +public: + + resetAll (int less) + : lesson(less) {} + + void operator() (kvoctrainExpr& 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<kvoctrainExpr, void> +{ + +public: + + resetOne (int idx, int less) + : index (idx), lesson(less) {} + + void operator() (kvoctrainExpr& 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 kvoctrainDoc::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 kvoctrainDoc::getLessonDescr(int idx) const +{ + if (idx == 0) + return i18n("<no lesson>"); + + if (idx <= 0 || idx > (int) lesson_descr.size() ) + return ""; + + return lesson_descr[idx-1]; +} + + +vector<int> kvoctrainDoc::getLessonsInQuery() const +{ + vector<int> iqvec; + for (unsigned i = 0; i < lessons_in_query.size(); i++) + if (lessons_in_query[i]) { + iqvec.push_back(i+1); // Offset <no lesson> +// cout << "getliq: " << i+1 << endl; + } + return iqvec; +} + + +void kvoctrainDoc::setLessonsInQuery(vector<int> lesson_iq) +{ + lessons_in_query.clear(); + for (unsigned i = 0; i < lesson_descr.size(); i++) + lessons_in_query.push_back(false); + + for (unsigned i = 0; i < lesson_iq.size(); i++) + if (lesson_iq[i] <= (int) lessons_in_query.size() ) { + lessons_in_query[lesson_iq[i]-1] = true; // Offset <no lesson> +// cout << "setliq: " << lesson_iq[i] << " " << i << endl; + } +} + + +QString kvoctrainDoc::getTitle() const +{ + if (doctitle.isEmpty()) + return doc_url.fileName(); + else + return doctitle; +} + + +QString kvoctrainDoc::getAuthor() const +{ + return author; +} + + +QString kvoctrainDoc::getLicense() const +{ + return license; +} + + +QString kvoctrainDoc::getDocRemark() const +{ + return doc_remark; +} + + +void kvoctrainDoc::setTitle(const QString & title) +{ + doctitle = title.stripWhiteSpace(); +} + + +void kvoctrainDoc::setAuthor(const QString & s) +{ + author = s.stripWhiteSpace(); +} + + +void kvoctrainDoc::setLicense(const QString & s) +{ + license = s.stripWhiteSpace(); +} + + +void kvoctrainDoc::setDocRemark(const QString & s) +{ + doc_remark = s.stripWhiteSpace(); +} + + +int kvoctrainDoc::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; + + for (int i = first; i < last; i++) { + if (word_start) { + + for (id = 0; id <= numLangs(); id++) + { + if (id == 0) + { + if (getEntry(i)->getOriginal().find (substr, 0, false) == 0) // case insensitive + return i; + } else { + if (getEntry(i)->getTranslation(id).find (substr, 0, false) == 0) // case insensitive + return i; + } + } + } + else { + for (id = 0; id <= numLangs(); id++){ + + if (id == 0) + { + if (getEntry(i)->getOriginal().find (substr, 0, false) > -1) // 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 kvoctrainDoc::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 kvoctrainDoc::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" +} + + +kvoctrainDoc::FileType kvoctrainDoc::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; + + if (c1 == '"' && (line.contains('"') == 1 || line.contains(QRegExp("\",[0-9]")))) + return vt_voc; + + return csv; +} + + +class expRef { + +public: + + expRef (kvoctrainExpr *_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; + kvoctrainExpr *exp; +}; + + +int kvoctrainDoc::cleanUp() +{ + int count = 0; + kvoctrainExpr *kve1, *kve2; + vector<expRef> shadow; + vector<int> to_delete; + + for (int i = 0; i < (int) vocabulary.size(); i++) + shadow.push_back (expRef (getEntry(i), i)); + std::sort(shadow.begin(), shadow.end()); + +#ifdef CLEAN_BUG + ofstream sso ("shadow.out"); + for (int i = shadow.size()-1; i > 0; i--) { + kve1 = shadow[i].exp; + sso << kve1->getOriginal() << " "; + for (int l = 1; l < (int) numLangs(); l++ ) + sso << kve1->getTranslation(l) << " "; + sso << endl; + } +#endif + + int ent_no = 0; + int ent_percent = vocabulary.size () / 100; + float f_ent_percent = vocabulary.size () / 100.0; + emit progressChanged(this, 0); + + for (int i = shadow.size()-1; i > 0; i--) { + kve1 = shadow[i].exp; + kve2 = shadow[i-1].exp; + + ent_no++; + if (ent_percent != 0 && (ent_no % ent_percent) == 0 ) + emit progressChanged(this, (int)((ent_no / f_ent_percent) / 2.0)); + + bool equal = true; + if (kve1->getOriginal() == kve2->getOriginal() ) { + for (int l = 1; equal && l < (int) numLangs(); l++ ) + if (kve1->getTranslation(l) != kve2->getTranslation(l)) + equal = false; + + if (equal) { + to_delete.push_back(shadow[i-1].idx); + count++; + } + } + } + + // removing might take very long + ent_no = 0; + ent_percent = to_delete.size () / 100; + f_ent_percent = to_delete.size () / 100.0; + emit progressChanged(this, 0); + + std::sort (to_delete.begin(), to_delete.end() ); + for (int i = (int) to_delete.size()-1; i >= 0; i--) { + ent_no++; + if (ent_percent != 0 && (ent_no % ent_percent) == 0 ) + emit progressChanged(this, (int)(50 + ent_no / f_ent_percent / 2.0)); +#ifdef CLEAN_BUG + sso << getEntry(to_delete[i])->getOriginal() << endl; +#endif + removeEntry (to_delete[i]); + setModified(); + } + + return count; +} +#include "kvoctraindoc.moc" diff --git a/kvoctrain/kvoctrain/kvt-core/kvoctraindoc.h b/kvoctrain/kvoctrain/kvt-core/kvoctraindoc.h new file mode 100644 index 00000000..d0defb5a --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvoctraindoc.h @@ -0,0 +1,747 @@ +/*************************************************************************** + + maintain a kvoctrain document + + ----------------------------------------------------------------------- + + begin : Thu Mar 11 20: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 KVOCTRAINDOC_H +#define KVOCTRAINDOC_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qobject.h> + +#include <kurl.h> + +#include "kvoctrainexpr.h" + +#include "kvt-xml/XmlReader.h" +#include "kvt-xml/XmlWriter.h" + +#define KVD_ZERO_TIME 934329599 // 1999-08-10 23:59:59, never change +#define KVD_VERS_PREFIX " v" // kvoctrain v0.1.0 + +/** XML tags and attribute names */ + +#define KV_DOCTYPE "kvtml" // doctype +#define KV_TITLE "title" // doc title +#define KV_AUTHOR "author" // doc author +#define KV_LICENSE "license" // doc license +#define KV_DOC_REM "remark" // doc remark +#define KV_LINES "lines" // entries +#define KV_GENERATOR "generator" // who generated the doc +#define KV_COLS "cols" // columns +#define KV_ENCODING "encoding" // document encoding (obsolete!) + +#define KV_EXPR "e" // entry for one expression +#define KV_ORG "o" // original expression in specified language +#define KV_TRANS "t" // translated expression in specified language +#define KV_LANG "l" // language: en, de, it, fr ... +#define KV_QUERY "q" // query: org or translation +#define KV_O "o" // org +#define KV_T "t" // translation +#define KV_GRADE "g" // grade of knowledge: 0=well known, x=not known for x times +#define KV_LESS_MEMBER "m" // member of lesson 1 .. x +#define KV_COUNT "c" // number of times queried +#define KV_SIZEHINT "width" // recommended column width +#define KV_CHARSET "charset" // recommended charset (obsolete!) +#define KV_BAD "b" // number of times failed +#define KV_DATE "d" // last query date +#define KV_DATE2 "w" // last query date, compressed format +#define KV_REMARK "r" // remark for this entry +#define KV_FAUX_AMI_F "ff" // false friend of this entry from org +#define KV_FAUX_AMI_T "tf" // false friend of this entry to org +#define KV_SYNONYM "y" // synonym (same meaning) of expr +#define KV_ANTONYM "a" // antonym (oppositite) of expr +#define KV_PRONUNCE "p" // how to pronunce this expression +#define KV_SELECTED "s" // entry selected for queries +#define KV_INACTIVE "i" // entry inactive (for queries) +#define KV_EXPRTYPE "t" // type of expression +#define KV_EXAMPLE "x" // example string with word +#define KV_USAGE "u" // usage label +#define KV_PARAPHRASE "h" // paraphrase for expression + +/* + <type> + <desc no="1">My type 1</desc> + <desc no="2">My type 2</desc> + </type> +*/ + +#define KV_TYPE_GRP "type" // type descriptor group +#define KV_TYPE_DESC "desc" // type descriptor +#define KV_TYPE_NO "no" // type descriptor number + +/* + <usage> + <desc no="1">My usage 1</desc> + <desc no="2">My usage 2</desc> + </type> +*/ + +#define KV_USAGE_GRP "usage" // usage descriptor group +#define KV_USAGE_DESC "desc" // usage descriptor +#define KV_USAGE_NO "no" // usage descriptor number + +/* + <lesson width="138"> + <desc no="1">Lesson #1</desc> + <desc no="2" query="1">Lesson #2</desc> + </lesson> +*/ + +#define KV_LESS_GRP "lesson" // lesson descriptor group +#define KV_LESS_CURR "current" // is current lesson +#define KV_LESS_DESC "desc" // lesson descriptor +#define KV_LESS_QUERY "query" // lesson contained in query +#define KV_LESS_NO "no" // lesson descriptor number + +/* + <tense> + <desc no="1">user tense #1</desc> + <desc no="2">user tense #2</desc> + </tense> +*/ + +#define KV_TENSE_GRP "tense" // tense descriptor group +#define KV_TENSE_DESC "desc" // tense descriptor +#define KV_TENSE_NO "no" // tense descriptor number + +/* + <options> + <sort on="1"/> + </options> +*/ + +#define KV_OPTION_GRP "options" // internal options group +#define KV_OPT_SORT "sort" // allow sorting +#define KV_BOOL_FLAG "on" // general boolean flag + +/* + <article> + <e l="de"> lang determines also lang order in entries !! + <fi>eine</fi> which must NOT differ + <fd>die</fd> + <mi>ein</mi> + <md>der</md> + <ni>ein</ni> + <nd>das</nd> + </e> + </article> +*/ + +#define KV_ARTICLE_GRP "article" // article descriptor group +#define KV_ART_ENTRY "e" // article entry +#define KV_ART_FD "fd" // female definite +#define KV_ART_MD "md" // male definite +#define KV_ART_ND "nd" // natural definite +#define KV_ART_FI "fi" // female indefinite +#define KV_ART_MI "mi" // male indefinite +#define KV_ART_NI "ni" // natural indefinite + +/* + <comparison> + <l1>good</l1> + <l2>better</l2> + <l3>best</l3> + </comparison> +*/ + +#define KV_COMPARISON_GRP "comparison" // comparison descriptor group +#define KV_COMP_L1 "l1" // base form +#define KV_COMP_L2 "l2" // next form +#define KV_COMP_L3 "l3" // last form + +/* + <multiplechoice> + <mc1>good</mc1> + <mc2>better</mc2> + <mc3>best</mc3> + <mc4>best 2</mc4> + <mc5>best 3</mc5> + </multiplechoice> +*/ + +#define KV_MULTIPLECHOICE_GRP "multiplechoice" // multiple choice descriptor group +#define KV_MC_1 "mc1" // choice 1 +#define KV_MC_2 "mc2" // choice 2 +#define KV_MC_3 "mc3" // choice 3 +#define KV_MC_4 "mc4" // choice 4 +#define KV_MC_5 "mc5" // choice 5 + +/* + <conjugation> used in header for definiton of "prefix" + <e l="de"> lang determines also lang order in entries !! + <s1>I</s1> which must NOT differ in subsequent <e>-tags + <s2>you<2> + <s3f>he</s3f> + <s3m>she</s3m> + <s3n>it</s3n> + <p1>we</p1> + <p2>you</p2> + <p3f>they</p3f> + <p3m>they</p3m> + <p3n>they</p3n> + </e> + </conjugation> + + <conjugation> and in entry for definition of tenses of (irreg.) verbs + <t n="sipa"> + <s1>go</s1> + <s2>go</s2> + <s3f>goes</s3f> + <s3m>goes</s3m> + <s3n>goes</s3n> + <p1>go</p1> + <p2>go</p2> + <p3f>go</p3f> + <p3m>go</p3m> + <p3n>go</p3n> + </t> + </conjugation> +*/ + +#define KV_CONJUG_GRP "conjugation" // conjugation descriptor group +#define KV_CON_ENTRY "e" // conjugation entry (header) +#define KV_CON_TYPE "t" // conjugation type (voc entries) +#define KV_CON_NAME "n" // conjugation type name (voc entries) +#define KV_CON_P1S "s1" // 1. person singular +#define KV_CON_P2S "s2" // 2. person singular +#define KV_CON_P3SF "s3f" // 3. person singular female +#define KV_CON_P3SM "s3m" // 3. person singular male +#define KV_CON_P3SN "s3n" // 3. person singular natural +#define KV_CON_P1P "p1" // 1. person plural +#define KV_CON_P2P "p2" // 2. person plural +#define KV_CON_P3PF "p3f" // 3. person plural female +#define KV_CON_P3PM "p3m" // 3. person plural male +#define KV_CON_P3PN "p3n" // 3. person plural natural +#define KV_CONJ_COMMON "common" // female contains common for all three + +#define LEX_IDENT_50 "Vocabulary Trainer V5.0" + + +class QTextStream; +class QStringList; +class MultipleChoice; + +/************************************************************* + * This class contains the expressions of your vocabulary + ************************************************************/ + +class kvoctrainDoc : public QObject +{ + Q_OBJECT + public: + + enum FileType { kvd_none, automatic, + kvtml, + kvtbin, + vt_lex, vt_vcb, csv, vt_voc /*, kvoclearn, qvocab*/ }; + + /** Constructor for the fileclass of the application + * + * @param obj calling object + * @param url URL of file to parse + */ + kvoctrainDoc(QObject* obj, const KURL& url); + + /** Destructor for the fileclass of the application */ + ~kvoctrainDoc(); + + /** 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 (kvoctrainExpr *expr) + { vocabulary.push_back (*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 original´s identifier + */ + QString getOriginalIdent () const; + + /** set original´s identifier + */ + void setOriginalIdent (const QString &id); + + /** returns identifier of translation x + * + * @param index number of translation 1..x + * @result ident string: de=german, en=englisch, .. + */ + QString getIdent (int index) const; + + /** sets identifier of translation + * + * @param index number of translation 1..x + * @param lang ident string: de=german, en=englisch, .. + */ + void setIdent (int index, const QString &lang); + + /** removes identifier an the according translation in all entries + * + * @param index number of translation 1..x + */ + void removeIdent (int index); + + /** determines if given translation is available and where + * + * @param lang identifier of language + * @result index of translation, 0=original, -1=none + */ + int findIdent (const QString &lang) const; + + /** returns attribute string + * + * @param index number of attribute + * @result string + */ + QString getTypeName (int index) const; + + /** sets attribute string + * + * @param index number of attribute + * @param str name of attribute + */ + void setTypeName (int index, QString &str); + + /** gets descr of types */ + inline vector<QString> getTypeDescr() const { return type_descr; } + + /** sets descr of types */ + inline void setTypeDescr(vector<QString> names) { type_descr = names; } + + /** returns tense string + * + * @param index number of tense + * @result string + */ + QString getTenseName (int index) const; + + /** sets tense string + * + * @param index number of tense + * @param str name of tense + */ + void setTenseName (int index, QString &str); + + /** gets descr of tenses */ + inline vector<QString> getTenseDescr() const { return tense_descr; } + + /** sets descr of tenses */ + inline void setTenseDescr(vector<QString> names) { tense_descr = names; } + + /** returns usage string + * + * @param index number of usage + * @result string + */ + QString getUsageName (int index) const; + + /** sets usage string + * + * @param index number of usage + * @param str name of usage + */ + void setUsageName (int index, QString &str); + + /** gets descr of usages */ + inline vector<QString> getUsageDescr() const { return usage_descr; } + + /** sets descr of usages */ + inline void setUsageDescr(vector<QString> names) { usage_descr = names; } + + + /** 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 + */ + kvoctrainExpr *getEntry(int index); + + /** search substring in vocabulary (case insensitive always) + * + * @param substr partial string to search + * @param id which language to search: 0=org, 1..x=translation + * @param first index from where to start + * @param last index of last entry, -1 goes till end + * @param word_start false: search partial string, + * true:always from beginning of word + * @param tolerant + * @result index of found entry, -1 if none + */ + int search(QString substr, int id, + int first=0, int last=-1, bool word_start = false, bool tolerant=false); + + /** returns url of xml file */ + inline KURL URL() const {return doc_url; } + + /** sets url of xml file */ + inline void setURL(const KURL& url) {doc_url = url;} + + /** returns title of xml file */ + QString getTitle() const; + + /** returns author of file */ + QString getAuthor() const; + + /** returns license of file */ + QString getLicense() const; + + /** returns remark of file */ + QString getDocRemark() const; + + inline void getQueryLang(QString &org, QString &trans) const + { org = queryorg; trans = querytrans; } + + inline void setQueryLang(const QString &org, const QString &trans) + { queryorg = org; querytrans = trans; } + + /** sets title of xml file */ + void setTitle(const QString & title); + + /** sets author of file */ + void setAuthor(const QString & author); + + /** sets license of file */ + void setLicense(const QString & license); + + /** sets remark of file */ + void setDocRemark(const QString & rem); + + /** gets version of loaded file */ + void getVersion(int &major, int &minor, int &patch); + + /** returns current lesson index */ + inline int getCurrentLesson() const { return current_lesson; } + + /** sets current lesson index + * @param lesson index of lesson + */ + inline void setCurrentLesson(int lesson) { current_lesson = lesson; } + + /** returns descr of lesson */ + QString getLessonDescr(int index) const; + + /** returns lessons in current query */ + vector<int> getLessonsInQuery() const; + + /** sets lessons in current query */ + void setLessonsInQuery(vector<int>); + + inline vector<QString> getLessonDescr() const { return lesson_descr; } + + inline int numLessons () const {return (int) lesson_descr.size(); } + + /** sets descr of lesson */ + inline void setLessonDescr(vector<QString> names) { lesson_descr = names; } + + /** returns pointer to conjugations if available + * + * @param index index of translation + */ + Conjugation getConjugation(int index) const; + + /** sets conjugations + * + * @param index index of translation + * @param con conjugation block + */ + void setConjugation(int index, const Conjugation &con); + + /** returns pointer to articles if available + * + * @param index index of translation + */ + Article getArticle(int index) const; + + /** sets articles + * + * @param index index of translation + * @param art article block + */ + void setArticle(int index, const Article &art); + + /** compress date */ + QString compressDate(unsigned long) const; + + /** decompress date */ + unsigned long decompressDate(QString) const; + + /** returns recommended size + * + * @param index number of expr, -1 = lesson + * @result width of column + */ + int getSizeHint (int index) const; + + /** sets recommended size + * + * @param index number of expr, -1 = lesson + * @param width width of column + */ + void setSizeHint (int index, const int width); + + bool 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 (kvoctrainDoc *, int curr_percent); + void docModified (bool mod); + +protected: + + void Init(); + + /** sets version of loaded file */ + void setVersion(const QString & ver); + + bool saveToKvtMl (QTextStream& os, QString &title); + bool loadFromKvtMl (QTextStream& is); + bool parseBody_kvtml (XmlElement elem, XmlReader& xml); + bool parseBody_e (XmlElement elem, XmlReader& xml); + bool extract_simple_tag (QString tag_name, XmlReader& xml, + XmlElement &elem, QString &data, + bool check_empty = true); + + bool extract_T_GROUP_attr (XmlReader &xml, + XmlElement &elem); + bool extract_T_DESCR_attr (XmlReader &xml, + XmlElement &elem, int &no); + bool extract_O_T_attr (XmlReader &xml, + XmlElement &elem, + 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 extract_L_DESCR_attr (XmlReader &xml, + XmlElement &elem, int &no, + bool &isCurr, bool &inQuery); + bool extract_KVT_E_attr (XmlReader& xml, + XmlElement &elem, + int &lesson, + bool &sel, + bool &active, + QString &type); + bool check_Empty_attr (QString tag_name, + XmlReader &xml, + XmlElement &elem); + bool extract_CON_E_attr (XmlReader& xml, + XmlElement &elem, + QString &lang); + bool extract_T_attr (XmlReader &xml, + XmlElement &elem, + QString &name); + bool extract_BOOL_attr (XmlReader &xml, + XmlElement &elem, + const QString &tag_name, + const QString &attr_name, + bool &flag); + bool extract_L_GROUP_attr (XmlReader &xml, + XmlElement &elem, + int &width); + + bool saveLessonKvtMl (XmlWriter &xml); + bool loadLessonKvtMl (XmlElement elem, XmlReader& xml); + bool saveTypeNameKvtMl (XmlWriter &xml); + bool loadTypeNameKvtMl (XmlElement elem, XmlReader& xml); + bool saveTenseNameKvtMl (XmlWriter &xml); + bool loadTenseNameKvtMl (XmlElement elem, XmlReader& xml); + bool saveUsageNameKvtMl (XmlWriter &xml); + bool loadUsageNameKvtMl (XmlElement elem, XmlReader& xml); + bool saveOptionsKvtMl (XmlWriter &xml); + bool loadOptionsKvtMl (XmlElement elem, XmlReader& xml); + bool saveArticleKvtMl (XmlWriter &xml); + bool loadArticleKvtMl (XmlElement elem, XmlReader& xml); + bool saveConjugHeader (vector<Conjugation> &curr_conjug, + XmlWriter &xml); + bool saveConjug (const Conjugation &curr_conjug, QString type, + XmlWriter &xml, QString identstr); + bool saveConjugEntry (Conjugation &curr_conjug, + XmlWriter &xml, int ident); + bool loadConjugKvtMl (vector<Conjugation> &curr_conjug, const QString &entry_tag, + XmlElement elem, XmlReader& xml); + + bool saveComparison (const Comparison &comp, XmlWriter &xml, int ident); + bool loadComparison (Comparison &comp, XmlElement elem, XmlReader &xml); + + bool saveMultipleChoice(const MultipleChoice &mc, XmlWriter &xml, int ident); + bool loadMultipleChoice(MultipleChoice &mc, XmlElement elem, XmlReader &xml); + + 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); + bool loadFromVoc(QTextStream& is); + void errorVcb (int line, const QString &text ); + + private: + bool dirty; + KURL doc_url; + vector<bool> sort_lang; + bool sort_lesson; + bool unknown_attr; + bool unknown_elem; + bool sort_allowed; + + // save these to document + vector<QString> langs; //0= origin, 1,.. translations + int cols, + lines; + int current_lesson; + vector<int> extraSizehints; + vector<int> sizehints; + QString generator; + QString queryorg, + querytrans; + vector<kvoctrainExpr> vocabulary; + vector<bool> lessons_in_query; + vector<QString> lesson_descr; + vector<QString> type_descr; + vector<QString> tense_descr; + vector<QString> usage_descr; + QString doctitle; + QString author; + QString license; + QString doc_remark; + QString doc_version; + + vector<Article> articles; + vector<Conjugation> conjugations; +}; + + +#endif // KVOCTRAINDOC_H diff --git a/kvoctrain/kvoctrain/kvt-core/kvoctrainexpr.cpp b/kvoctrain/kvoctrain/kvt-core/kvoctrainexpr.cpp new file mode 100644 index 00000000..2faba172 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvoctrainexpr.cpp @@ -0,0 +1,799 @@ +/*************************************************************************** + + maintain a kvoctrain expression + + ----------------------------------------------------------------------- + + begin : Thu Mar 11 20:50:53 MET 1999 + + copyright : (C) 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de> + (C) 2001 The KDE-EDU team + (C) 2005 Peter Hedlund <peter.hedlund@kdemail.net> + + ----------------------------------------------------------------------- + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kvoctrainexpr.h" + +void kvoctrainExpr::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; +} + + +kvoctrainExpr::kvoctrainExpr (QString &expr, int _lesson) +{ + Init(); + setOriginal(expr.stripWhiteSpace() ); + lesson = _lesson; +} + + +kvoctrainExpr::kvoctrainExpr () +{ + Init(); +} + + +kvoctrainExpr::kvoctrainExpr (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); + } + } +} + + +kvoctrainExpr::~kvoctrainExpr() +{ +} + + +int kvoctrainExpr::numTranslations() const +{ + return translations.size(); +} + + +QString kvoctrainExpr::getRemark (int idx) const +{ + if (idx >= (int)remarks.size() || idx < 0) { + return ""; + } + else { + return remarks[idx]; + } +} + + +void kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::getSynonym (int idx) const +{ + if (idx >= (int)synonym.size() || idx < 0) { + return ""; + } + else { + return synonym[idx]; + } +} + + +void kvoctrainExpr::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 kvoctrainExpr::getExample (int idx) const +{ + if (idx >= (int)example.size() || idx < 0) { + return ""; + } + else { + return example[idx]; + } +} + + +void kvoctrainExpr::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 kvoctrainExpr::getUsageLabel (int idx) const +{ + if (idx >= (int)usageLabels.size() || idx < 0) { + return ""; + } + else { + return usageLabels[idx]; + } +} + + +void kvoctrainExpr::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 kvoctrainExpr::getParaphrase (int idx) const +{ + if (idx >= (int)paraphrases.size() || idx < 0) { + return ""; + } + else { + return paraphrases[idx]; + } +} + + +void kvoctrainExpr::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 kvoctrainExpr::getAntonym (int idx) const +{ + if (idx >= (int)antonym.size() || idx < 0) { + return ""; + } + else { + return antonym[idx]; + } +} + + +void kvoctrainExpr::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 kvoctrainExpr::getConjugation (int idx) const +{ + if (idx >= (int)conjugations.size() || idx < 0) { + return Conjugation(); + } + else { + return conjugations[idx]; + } +} + + +void kvoctrainExpr::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 kvoctrainExpr::getComparison (int idx) const +{ + if (idx >= (int)comparisons.size() || idx < 0) { + return Comparison(); + } + else { + return comparisons[idx]; + } +} + + +void kvoctrainExpr::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 kvoctrainExpr::getMultipleChoice (int idx) const +{ + if (idx >= (int)mcs.size() || idx < 0) { + return MultipleChoice(); + } + else { + return mcs[idx]; + } +} + + +QString kvoctrainExpr::getPronunce (int idx) const +{ + if (idx >= (int)pronunces.size() || idx < 0) { + return ""; + } + else { + return pronunces[idx]; + } +} + + +void kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::getTranslation (int idx) const +{ + if (idx > (int)translations.size() || idx < 1) + return ""; + else + return translations[idx-1]; +} + + +void kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::gradeStr (int idx, bool rev_grade) const +{ + QString s; + s.setNum(getGrade(idx, rev_grade)); + return s; +} + + +grade_t kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::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 kvoctrainExpr::getType (int idx) const +{ + if (idx >= (int)exprtypes.size() || idx < 0) { + return ""; + } + else { + return exprtypes[idx]; + } +} + + +int kvoctrainExpr::getLesson () const +{ + return lesson; +} + +void kvoctrainExpr::incQueryCount (int index, bool rev_count) +{ + setQueryCount (index, getQueryCount(index, rev_count)+1, rev_count); +} + + +void kvoctrainExpr::incBadCount (int index, bool rev_count) +{ + setBadCount (index, getBadCount(index, rev_count)+1, rev_count); +} + + +void kvoctrainExpr::setOriginal ( const QString & expr) +{ + origin = expr; +} + + +QString kvoctrainExpr::getOriginal () const +{ + return origin; +} + + +void kvoctrainExpr::setLesson (int l) +{ + lesson = l; +} + + +void kvoctrainExpr::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/kvoctrain/kvoctrain/kvt-core/kvoctrainexpr.h b/kvoctrain/kvoctrain/kvt-core/kvoctrainexpr.h new file mode 100644 index 00000000..ecdefa4d --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvoctrainexpr.h @@ -0,0 +1,465 @@ +/*************************************************************************** + + maintain a kvoctrain expression + + ----------------------------------------------------------------------- + + begin : Thu Mar 11 20:50:53 MET 1999 + + copyright : (C) 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de> + (C) 2001 The KDE-EDU team + (C) 2005 Peter Hedlund <peter.hedlund@kdemail.net> + + ----------------------------------------------------------------------- + + *************************************************************************** + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KVOCTRAINEXPR_H +#define KVOCTRAINEXPR_H + +#include <klocale.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 +static const char *KV_NORM_TEXT = I18N_NOOP("Not Queried Yet"); + +#define KV_LEV1_GRADE 1 +static const char *KV_LEV1_TEXT = I18N_NOOP("Level 1"); + +#define KV_LEV2_GRADE 2 +static const char *KV_LEV2_TEXT = I18N_NOOP("Level 2"); + +#define KV_LEV3_GRADE 3 +static const char *KV_LEV3_TEXT = I18N_NOOP("Level 3"); + +#define KV_LEV4_GRADE 4 +static const char *KV_LEV4_TEXT = I18N_NOOP("Level 4"); + +#define KV_LEV5_GRADE 5 +static const char *KV_LEV5_TEXT = I18N_NOOP("Level 5"); + +#define KV_LEV6_GRADE 6 +static const char *KV_LEV6_TEXT = I18N_NOOP("Level 6"); + +#define KV_LEV7_GRADE 7 +static const char *KV_LEV7_TEXT = I18N_NOOP("Level 7"); + +#include <time.h> +#include <vector> +using namespace std; + +#include "grammarmanager.h" +#include "MultipleChoice.h" + +typedef signed char grade_t; +typedef unsigned short count_t; + +/*************************************************************** + * This class contains one expression as original or in one + * translations + **************************************************************/ + +class kvoctrainExpr +{ + public: + + /** default constructor for an expression in different languages + */ + ~kvoctrainExpr (); + + kvoctrainExpr (); + + kvoctrainExpr (QString &s, QString separator, int lesson = 0); + + /** Constructor for an expression in different languages + * + * @param expr expression + */ + kvoctrainExpr (QString &expr, int lesson = 0); + + /** adds a new translation of this entry + * @param expr translation + * @param grade grade of knowledge of this translation + * @param rev_grade dito, in opposite direction + */ + void addTranslation (QString expr, grade_t grade=KV_NORM_GRADE, + grade_t rev_grade=KV_NORM_GRADE); + + /** removes translation + * + * @param index number of translation 1..x + */ + void removeTranslation (int index); + + /** returns index of lesson (0 = none) + */ + int getLesson () const; + + /** sets index of lesson (0 = none) + */ + void setLesson (int l); + + /** returns original expression of this entry + */ + QString getOriginal () const; + + /** sets original expression of this entry + */ + void setOriginal (const QString & expr); + + /** returns number of max. translations of all expressions + */ + int numTranslations() const; + + /** returns flag if entry is "selected" for queries + */ + bool isInQuery() const {return inquery; } + + /** set entry "selected" + */ + void setInQuery(bool flag = true) { inquery = flag; } + + /** returns flag if entry is activated for queries + */ + bool isActive() const {return active; } + + /** set entry active (enabled for queries) + */ + void setActive(bool flag = true) { active = flag; } + + /** returns translation of this expression + * + * @param index number of translation + * @result expression or "" if no translation available + */ + QString getTranslation (int index) const; + + /** sets translation of this expression + * + * @param index number of translation + * @param expr expression of this index + */ + void setTranslation (int index, const QString & expr); + + /** sets remark of this expression + * + * @param index index of expression + * @param expr remark of this index + */ + void setPronunce (int index, const QString & expr); + + /** returns pronunciation of this expression + * + * @param index index of expression + * @result pronunciation or "" if none available + */ + QString getPronunce (int index) const; + + /** returns remarks of this expression + * + * @param index index of expression + * @result remark or "" if no remark available + */ + QString getRemark (int index) const; + + /** sets remark of this expression + * + * @param index index of expression + * @param expr remark of this index + */ + void setRemark (int index, const QString & expr); + + + /** sets false friend of this expression + * + * @param index index of expression + * @param expr false friend of this index + * @param rev_grade dito, in opposite direction + */ + void setFauxAmi (int index, const QString & expr, bool rev_ami = false); + + + /** returns false friend of this expression + * + * @param index index of expression + * @param rev_grade dito, in opposite direction + * @result false friend or "" if no string available + */ + QString getFauxAmi (int index, bool rev_ami = false) const; + + /** sets synonym this expression + * + * @param index index of expression + * @param expr synonym of this index + */ + void setSynonym (int index, const QString & expr); + + + /** returns synonym of this expression + * + * @param index index of expression + * @result synonym or "" if no string available + */ + QString getSynonym (int index) const; + + /** sets example this expression + * + * @param index index of expression + * @param expr example of this index + */ + void setExample (int index, const QString & expr); + + + /** returns example of this expression + * + * @param index index of expression + * @result example or "" if no string available + */ + QString getExample (int index) const; + + /** sets usage label this expression + * + * @param index index of expression + * @param usage usage label of this index + */ + void setUsageLabel (int index, const QString & usage); + + + /** returns usage label of this expression + * + * @param index index of expression + * @result usage or "" if no string available + */ + QString getUsageLabel (int index) const; + + /** sets paraphrase of this expression + * + * @param index index of expression + * @param usage paraphrase of this index + */ + void setParaphrase (int index, const QString & usage); + + + /** returns paraphrase of this expression + * + * @param index index of expression + * @result paraphrase or "" if no string available + */ + QString getParaphrase (int index) const; + + /** sets antonym this expression + * + * @param index index of expression + * @param expr antonym of this index + */ + void setAntonym (int index, const QString & expr); + + + /** returns antonym of this expression + * + * @param index index of expression + * @result antonym or "" if no string available + */ + QString getAntonym (int index) const; + + /** returns type of this expression + * + * @result type or "" if no type available + */ + QString getType (int index) const; + + /** all langs have same type ? + * + * @result true if all have same type + */ + bool uniqueType () const; + + /** sets type of this expression + * + * @param index index of type + * @param type type of this expression ("" = none) + */ + void setType (int index, const QString &type); + + /** returns grade of given translation as string + * + * @param index index of expression + * @param rev_grade dito, in opposite direction + * @result number of knowlegde: 0=known, x=numbers not knows + */ + QString gradeStr (int index, bool rev_grade = false) const; + + /** sets grade of given translation + * + * @param index index of translation + * @param grade number of knowlegde: 0=known, x=numbers not knows + */ + void setGrade (int index, grade_t grade, bool rev_grade = false); + + /** returns grade of given translation as int + * + * @param index index of translation + * @param rev_grade dito, in opposite direction + * @result number of knowlegde: 0=known, x=numbers not knows + */ + grade_t getGrade (int index, bool rev_grade = false) const; + + /** increments grade of given translation + * + * @param index index of translation + * @param rev_grade dito, in opposite direction + */ + void incGrade (int index, bool rev_grade = false); + + /** decrements grade of given translation + * + * @param index index of translation + * @param rev_grade dito, in opposite direction + */ + void decGrade (int index, bool rev_grade = false); + + /** returns last query date of given translation as int + * + * @param index index of translation + * @param rev_date dito, in opposite direction + */ + time_t getQueryDate (int index, bool rev_date = false) const; + + /** set last query date of given translation as int + * + * @param index index of translation + * @param rev_date dito, in opposite direction + */ + void setQueryDate (int index, time_t date, bool rev_date = false); + + /** returns conjugations if available + * + * @param index index of translation + */ + Conjugation getConjugation(int index) const; + + /** sets conjugations + * + * @param index index of translation + * @param con conjugation block + */ + void setConjugation(int index, const Conjugation &con); + + /** returns comparison if available + * + * @param index index of translation + */ + Comparison getComparison(int index) const; + + /** sets comparison + * + * @param index index of translation + * @param con comparison block + */ + void setComparison(int index, const Comparison &comp); + + /** returns multiple choice if available + * + * @param index index of multiple choice + */ + MultipleChoice getMultipleChoice(int index) const; + + /** sets multiple choice + * + * @param index index of translation + * @param con multiple choice block + */ + void setMultipleChoice(int index, const MultipleChoice &mc); + + /** returns query count of given translation as int + * + * @param index index of translation + * @param rev_count dito, in opposite direction + */ + count_t getQueryCount (int index, bool rev_count = false) const; + + /** set query count of given translation as int + * + * @param index index of translation + * @param rev_count dito, in opposite direction + */ + void setQueryCount (int index, count_t count, bool rev_count = false); + + /** returns bad query count of given translation as int + * + * @param index index of translation + * @param rev_count dito, in opposite direction + */ + count_t getBadCount (int index, bool rev_count = false) const; + + /** set bad query count of given translation as int + * + * @param index index of translation + * @param rev_count dito, in opposite direction + */ + void setBadCount (int index, count_t count, bool rev_count = false); + + /** increment bad query count of given translation by 1 + * + * @param index index of translation + * @param rev_count dito, in opposite direction + */ + void incBadCount (int index, bool rev_count = false); + + /** increment query count of given translation by 1 + * + * @param index index of translation + * @param rev_count dito, in opposite direction + */ + void incQueryCount (int index, bool rev_count = false); + + protected: + + void Init(); + + private: + QString origin; + + // all these vectors must be deleted in removeTranslation() + vector<QString> exprtypes; + vector<QString> translations; + vector<QString> remarks; + vector<QString> usageLabels; + vector<QString> paraphrases; + vector<QString> fauxAmi; + vector<QString> rev_fauxAmi; + vector<QString> synonym; + vector<QString> example; + vector<QString> antonym; + vector<QString> pronunces; + vector<grade_t> grades; + vector<grade_t> rev_grades; + vector<count_t> qcounts; + vector<count_t> rev_qcounts; + vector<count_t> bcounts; + vector<count_t> rev_bcounts; + vector<time_t> qdates; + vector<time_t> rev_qdates; + vector<Conjugation> conjugations; + vector<Comparison> comparisons; + vector<MultipleChoice> mcs; + + int lesson; + bool inquery; + bool active; +}; + +#endif // KVOCTRAINEXPR_H + diff --git a/kvoctrain/kvoctrain/kvt-core/kvt-xml/Makefile.am b/kvoctrain/kvoctrain/kvt-core/kvt-xml/Makefile.am new file mode 100644 index 00000000..f44e9fea --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvt-xml/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = -I$(top_srcdir)/kvoctrain \ + -I$(top_srcdir)/kvoctrain/kvoctrain \ + $(all_includes) + +noinst_LTLIBRARIES = libkvtxml.la + +libkvtxml_la_SOURCES = XmlReader.cpp XmlTokenizer.cpp XmlElement.cpp XmlWriter.cpp + +# CLEANFILES += *~ # This breaks badly with automake 1.5 + diff --git a/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlElement.cpp b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlElement.cpp new file mode 100644 index 00000000..7b070c4f --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlElement.cpp @@ -0,0 +1,99 @@ +/* -*- C++ -*- + + This file is part of KIllustrator. + Copyright (C) 1998 Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de) + + modified for kvoctrain by Ewald Arnold kvoctrain@ewald-arnold.dein April ´99 + + ----------------------------------------------------------------------- + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as + published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include <stdlib.h> +#include "XmlElement.h" + +XmlAttribute::XmlAttribute (const KOXML_STRING& n, const KOXML_STRING& v) : + aname (n), value (v) { +} + + +XmlAttribute::XmlAttribute (const XmlAttribute& attr) : + aname (attr.aname), value (attr.value) { +} + +XmlAttribute::~XmlAttribute () { +} + + +XmlAttribute& XmlAttribute::operator= (const XmlAttribute& attr) { + aname = attr.aname; + value = attr.value; + return *this; +} + + +float XmlAttribute::floatValue () const { +#ifndef KOXML_USE_STL + return atof (value.local8Bit()); +#else + return atof (value.data()); +#endif +} + + +int XmlAttribute::intValue () const { +#ifndef KOXML_USE_STL + return atoi (value.local8Bit()); +#else + return atoi (value.data()); +#endif +} + + +XmlElement::XmlElement () { + closed = false; + endTag = false; +} + + +XmlElement::XmlElement (const XmlElement& elem) : + tagId (elem.tagId), closed (elem.closed), endTag (elem.endTag), + attribs (elem.attribs) { +} + + +XmlElement::~XmlElement () { +} + + +void XmlElement::reset () { + tagId = ""; + closed = false; + endTag = false; + attribs.erase (attribs.begin (), attribs.end ()); +} + + +XmlElement& XmlElement::operator= (const XmlElement& elem) { + tagId = elem.tagId; + closed = elem.closed; + endTag = elem.endTag; + attribs = elem.attribs; + return *this; +} + diff --git a/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlElement.h b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlElement.h new file mode 100644 index 00000000..50bb8e42 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlElement.h @@ -0,0 +1,156 @@ +/* -*- C++ -*- + + This file is part of KIllustrator. + Copyright (C) 1998 Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de) + + modified for kvoctrain by Ewald Arnold kvoctrain@ewald-arnold.dein April ´99 + +*/ + +#ifndef XmlElement_h_ +#define XmlElement_h_ + +#include "koxml_config.h" +#include <list> + +/** + * An instance of XmlAttribute represents an attribute of + * XML elements. It provides methods for accessing the attribute + * value. + * + * @short A class for representing attributes of XML elements. + * @author Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de), modifications: Ewald Arnold (kvoctrain@ewald-arnold.de) + * @version 2000/07/02 + */ +class XmlAttribute { +public: + /** + * Construct an attribute from the given name and value. + * + * @param n The name of the attribute. + * @param v The attribute value. + */ + XmlAttribute (const KOXML_STRING& n, const KOXML_STRING& v); + + /** + * Copy constructor. + */ + XmlAttribute (const XmlAttribute& attr); + + /** + * Destructor. + */ + ~XmlAttribute (); + + /** + * The assignment operator. + */ + XmlAttribute& operator= (const XmlAttribute& attr); + + /** + * Return the name of the attribute. + * + * @return The attribute name. + */ + inline const KOXML_STRING& name () const { return aname; } + + /** + * Return a string representation of the attribute value. + * + * @return The attribute value as string. + */ + inline const KOXML_STRING& stringValue () const { return value; } + + /** + * Return a float representation of the attribute value. + * + * @return The attribute value as float. + */ + float floatValue () const; + + /** + * Return a integer representation of the attribute value. + * + * @return The attribute value as integer. + */ + int intValue () const; + +private: + KOXML_STRING aname, value; +}; + +/** + * An instance of XmlElement represents an element (object) of a XML + * document. The elements consists of the tag (element ID) and a list + * of attributes. + * + * @short A class for representing XML elements. + * @author Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de), modifications: Ewald Arnold (kvoctrain@ewald-arnold.de) + * @version 2000/07/02 + */ +class XmlElement { +friend class XmlReader; +public: + /** + * Construct a new XML element. + */ + XmlElement (); + + /** + * Copy constructor. + */ + XmlElement (const XmlElement& elem); + + /** + * Destructor. + */ + ~XmlElement (); + + void reset (); + + /** + * The assignment operator. + */ + XmlElement& operator= (const XmlElement& elem); + + /** + * Return the ID of the element. + * + * @return The element ID. + */ + inline const KOXML_STRING& tag () const { return tagId; } + + /** + * Return the attributes of the element. + * @see XmlAttribute + * + * @return The list of attributes. + */ + inline const std::list<XmlAttribute>& attributes () const { return attribs; } + + /** + * Return @p true if the element is closed. + * + * @return @p true for a closed element. + */ + inline bool isClosed () const { return closed; } + + /** + * Return @p true if the element is an end tag. + * + * @return @p true for an end tag. + */ + inline bool isEndTag () const { return endTag; } + +private: + KOXML_STRING tagId; + bool closed; + bool endTag; + std::list<XmlAttribute> attribs; +}; + +#endif + + + + diff --git a/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlReader.cpp b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlReader.cpp new file mode 100644 index 00000000..819d79a6 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlReader.cpp @@ -0,0 +1,264 @@ +/* -*- C++ -*- + + This file is part of KIllustrator. + Copyright (C) 1998 Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de) + + modified for kvoctrain by Ewald Arnold kvoctrain@ewald-arnold.dein April ´99 + + ----------------------------------------------------------------------- + + ----------------------------------------------------------------------- + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as + published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include <iostream> +using namespace std; +#include "XmlReader.h" + +XmlReader::XmlReader (KOXML_ISTREAM& is) + : tokenizer (is) +{ +} + +XmlReader::~XmlReader () { +} + +bool XmlReader::validHeader () { + // Check for: <? xml version="1.0" ?> + if (tokenizer.nextToken () != XmlTokenizer::Tok_Lt) + return false; + if (tokenizer.nextToken () != XmlTokenizer::Tok_QSign) + return false; + + if (tokenizer.nextToken () != XmlTokenizer::Tok_Symbol) + return false; + else if (tokenizer.element () != "xml") + return false; + + if (tokenizer.nextToken () != XmlTokenizer::Tok_Symbol) + return false; + else if (tokenizer.element () != "version") + return false; + if (tokenizer.nextToken () != XmlTokenizer::Tok_Eq) + return false; + if (tokenizer.nextToken () != XmlTokenizer::Tok_String) + return false; + else if (tokenizer.element () != "1.0") + return false; + + if (tokenizer.nextToken () != XmlTokenizer::Tok_QSign) + return false; + if (tokenizer.nextToken () != XmlTokenizer::Tok_Gt) + return false; + + // Check for: <(!)doctype symbol system string> + + if (tokenizer.nextToken () != XmlTokenizer::Tok_Lt) + return false; + + XmlTokenizer::Token token = tokenizer.nextToken (); + if (token == XmlTokenizer::Tok_Exclam) + token = tokenizer.nextToken (); + + if (token != XmlTokenizer::Tok_Symbol) + return false; + else if (tokenizer.element().lower() != "doctype") + return false; + + if (tokenizer.nextToken () != XmlTokenizer::Tok_Symbol) + return false; + s_dtype = tokenizer.element (); + + if (tokenizer.nextToken () != XmlTokenizer::Tok_Symbol) + return false; + else if (tokenizer.element().lower() != "system") + return false; + + if (tokenizer.nextToken () != XmlTokenizer::Tok_String) + return false; + s_dtd = tokenizer.element (); + + if (tokenizer.nextToken () != XmlTokenizer::Tok_Gt) + return false; + + return true; +} + +const KOXML_STRING& XmlReader::doctype () const { + return s_dtype; +} + +const KOXML_STRING& XmlReader::dtd () const { + return s_dtd; +} + +const KOXML_STRING& XmlReader::getText () { + return text; +} + +bool XmlReader::readElement (XmlElement& elem) { + XmlTokenizer::Token tok; + bool result = false; + bool ready = false; + + elem.reset (); + + while (! ready) { + tok = tokenizer.nextToken (); + if (tok == XmlTokenizer::Tok_Lt) { + tok = tokenizer.nextToken (); + if (tok == XmlTokenizer::Tok_Comment) { + // skip comment + } + else { + if (tok == XmlTokenizer::Tok_Slash) + result = parseEndElement (elem); + else if (tok == XmlTokenizer::Tok_Symbol) + result = parseElement (tokenizer.element (), elem); + else if (tok == XmlTokenizer::Tok_EOF) + result = false; + ready = true; + } + } + else if (tok == XmlTokenizer::Tok_Text) { + elem.tagId = "#PCDATA"; + text = tokenizer.element (); + result = true; + ready = true; + } + else + return false; + } + return result; +} + +bool XmlReader::parseEndElement (XmlElement& elem) { + bool result = false; + + XmlTokenizer::Token tok = tokenizer.nextToken (); + if (tok == XmlTokenizer::Tok_Symbol) { + KOXML_STRING tag = tokenizer.element (); + tok = tokenizer.nextToken (); + if (tok == XmlTokenizer::Tok_Gt) { + elem.tagId = tag; + elem.endTag = true; + elem.closed = true; + result = true; + } + } + return result; +} + +bool XmlReader::parseElement (const KOXML_STRING& id, XmlElement& elem) { + KOXML_STRING tag = id; + bool closed = false; + std::list<XmlAttribute> attrib_list; + + XmlTokenizer::Token tok = tokenizer.nextToken (); + while (tok != XmlTokenizer::Tok_Gt) { + if (tok == XmlTokenizer::Tok_Slash) { + if (closed) + return false; + else + closed = true; + } + else if (tok == XmlTokenizer::Tok_Symbol) { + if (! attrib_list.empty () || closed) + return false; + tokenizer.unget (); + if (! readAttributes (attrib_list)) + return false; + } + else + return false; + + tok = tokenizer.nextToken (); + } + elem.tagId = tag; + elem.endTag = false; + elem.closed = closed; + elem.attribs = attrib_list; + return true; +} + +bool XmlReader::readAttributes (std::list<XmlAttribute>& attrib_list) { + XmlTokenizer::Token tok = tokenizer.nextToken (); + + while (tok != XmlTokenizer::Tok_Gt) { + if (tok == XmlTokenizer::Tok_Symbol) { + KOXML_STRING id = tokenizer.element (); + if (tokenizer.nextToken () == XmlTokenizer::Tok_Eq) { + if (tokenizer.nextToken () == XmlTokenizer::Tok_String) { + + // un-escape dangerous characters in reverted order + KOXML_STRING val = tokenizer.element(); + int pos = 0; + while ((pos = val.find(""", pos)) >= 0) { + KOXML_STRING_REMOVE( val, pos, 6); + KOXML_STRING_INSERT( val, pos, "\""); + pos += 1; // skip " + } + pos = 0; + while ((pos = val.find("&lf;", pos)) >= 0) { + KOXML_STRING_REMOVE( val, pos, 4); + KOXML_STRING_INSERT( val, pos, "\r"); + pos += 1; // skip \r + } + pos = 0; + while ((pos = val.find("&nl;", pos)) >= 0) { + KOXML_STRING_REMOVE( val, pos, 4); + KOXML_STRING_INSERT( val, pos, "\n"); + pos += 1; // skip \n + } + pos = 0; + while ((pos = val.find("<", pos)) >= 0) { + KOXML_STRING_REMOVE( val, pos, 4); + KOXML_STRING_INSERT( val, pos, "<"); + pos += 1; // skip < + } + pos = 0; + while ((pos = val.find ("&", pos)) >= 0) { + KOXML_STRING_REMOVE( val, pos+1, 4); + pos += 1; // skip & + } + + XmlAttribute attrib (id, val); + attrib_list.push_back (attrib); + } + else { + cerr << "invalid attribute value" << endl; + return false; + } + } + else { + cerr << "missing '='" << endl; + return false; + } + } + else if (tok == XmlTokenizer::Tok_Slash) { + break; + } + else { + cerr << "invalid attribute name: " << (int) tok << endl; + return false; + } + tok = tokenizer.nextToken (); + } + tokenizer.unget (); + return true; +} diff --git a/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlReader.h b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlReader.h new file mode 100644 index 00000000..0c7904af --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlReader.h @@ -0,0 +1,104 @@ +/* -*- C++ -*- + + This file is part of KIllustrator. + Copyright (C) 1998 Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de) + + modified for kvoctrain by Ewald Arnold kvoctrain@ewald-arnold.dein April ´99 +*/ + +#ifndef XmlReader_h_ +#define XmlReader_h_ + +#include "XmlElement.h" +#include "XmlTokenizer.h" + +class KOXML_ISTREAM; + +/** + * The XMLReader class supports reading elements from a XML stream. + * + * @short A class for reading XML elements from a stream. + * @author Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de), modifications: Ewald Arnold (kvoctrain@ewald-arnold.de) + * @version 2000/07/02 + */ +class XmlReader { +public: + /** + * Construct a XmlReader instance for the given input stream. + * + * @param is The open input stream. + */ + XmlReader (KOXML_ISTREAM& is); + + /** + * Desctructor + */ + ~XmlReader (); + + /** + * Check the input stream for a valid XML header. + * A header should look like + * <pre> + * <?xml version="1.0"?> + * <!doctype dtype system dtd> + * </pre> + * where @p dtype and @p dtd are simple strings. + * + * @return @p true if the header conforms to XML, otherwise + * @p false. + */ + bool validHeader (); + + /** + * Return the document type. + * + * @return The name of the document type. + */ + const KOXML_STRING& doctype () const; + + /** + * Return the name of the document type definition. + * + * @return The name of the DTD. + */ + const KOXML_STRING& dtd () const; + + /** + * Read a XML element from the stream. If the content is plain text + * (no tag), an element with the pseudo ID @p #PCDATA is returned + * and the text is available via method getText. + * + * @see #getText + * + * @param elem The XML element which is initialized by the method. + * @return @p true for successful reading. + */ + bool readElement (XmlElement& elem); + + /** + * Read plain text from the stream. + * + * @return The text as a string. + */ + const KOXML_STRING& getText (); + + /** + * Returns current line number + * + * @return The current line number + */ + inline int lineNumber() { return tokenizer.lineNumber(); } + +protected: + bool parseEndElement (XmlElement& elem); + bool parseElement (const KOXML_STRING& id, XmlElement& elem); + bool readAttributes (std::list<XmlAttribute>& attrib_list); + +private: + XmlTokenizer tokenizer; + KOXML_STRING s_dtype, + s_dtd; + KOXML_STRING text; +}; + +#endif diff --git a/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlTokenizer.cpp b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlTokenizer.cpp new file mode 100644 index 00000000..b2fde685 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlTokenizer.cpp @@ -0,0 +1,411 @@ +/* -*- C++ -*- + + This file is part of KIllustrator. + Copyright (C) 1998 Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de) + + modified for kvoctrain by Ewald Arnold kvoctrain@ewald-arnold.dein April ´99 + + ----------------------------------------------------------------------- + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as + published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "XmlTokenizer.h" +#include <ctype.h> + +XmlTokenizer::XmlTokenizer (KOXML_ISTREAM& is) : + last_chars (""), istrm (is), use_last (false), is_open (false), lineno(1) { +} + +XmlTokenizer::~XmlTokenizer () { +} + + +/* +bool XmlTokenizer::hasMoreTokens () { + return ! istrm.eof (); +} +*/ + +void XmlTokenizer::skipWhitespace () { + KOXML_CHAR c; + do { + c = readchar (); + if (c == '\n') + lineno++; + if (! isspace (c)) { + putback (c); + return; + } + else if (istrm.eof ()) + return; + } while (1); +} + + +void XmlTokenizer::putback (KOXML_CHAR c) { + last_chars += c; +} + + +KOXML_CHAR XmlTokenizer::readchar () { + + KOXML_CHAR c; + + if (last_chars.length() > 0) { + c = last_chars[0]; + KOXML_STRING_REMOVE (last_chars, 0, 1); + } + else { + +# ifndef KOXML_USE_STL + istrm >> c; +# else + istrm.get(c); +# endif + } + + return c; +} + + +void XmlTokenizer::unget () { + use_last = true; +} + +XmlTokenizer::Token XmlTokenizer::nextToken () { + KOXML_CHAR c; + + if (use_last) { + use_last = false; + return last_tok; + } + + skipWhitespace (); + if (istrm.eof ()) + return last_tok = Tok_EOF; + + c = readchar (); + if (c == '\n') + lineno++; + + if (!is_open) { + if (c != '<') { + putback (c); + return last_tok = readText (); + } + } + switch (c) { + case '<': + is_open = true; + return last_tok = Tok_Lt; + break; + case '>': + is_open = false; + return last_tok = Tok_Gt; + break; + case '?': + return last_tok = Tok_QSign; + break; + case '/': + return last_tok = Tok_Slash; + break; + case '=': + return last_tok = Tok_Eq; + break; + case '(': + return last_tok = Tok_LParen; + break; + case ')': + return last_tok = Tok_RParen; + break; + case '[': + return last_tok = Tok_LBracket; + break; + case ']': + return last_tok = Tok_RBracket; + break; + case '|': + return last_tok = Tok_Bar; + break; + case '*': + return last_tok = Tok_Asterisk; + break; + case '+': + return last_tok = Tok_Plus; + break; + case ',': + return last_tok = Tok_Comma; + break; + case ';': + return last_tok = Tok_Semicolon; + break; + case '%': + return last_tok = Tok_Percent; + break; + case '#': + return last_tok = Tok_NSign; + break; + case '\'': + return last_tok = Tok_Apostr; + break; + case '"': + // String einlesen + return last_tok = readString (); + break; + default: + if (is_open) { + if (isalpha (c) || isdigit (c)) { + // Symbol (Element oder Attributbezeichner) + putback (c); + return last_tok = readSymbol (); + } + else if (c == '!') { + c = readchar (); + if (c == '\n') + lineno++; + putback (c); + if (c == '-') + return last_tok = readComment (); + else + return last_tok = Tok_Exclam; + } + else { + return last_tok = Tok_Invalid; + } + } + else { + putback (c); + return last_tok = readText (); + } + break; + } +} + + +const KOXML_STRING& XmlTokenizer::element () { + return elem; +} + + +XmlTokenizer::Token XmlTokenizer::readSymbol () { + KOXML_CHAR c; + elem = ""; + + while (1) { + c = readchar (); + if (c == '\n') + lineno++; + if (istrm.eof () || isspace (c)) + // Symbol ist abgeschlossen + break; + else if (c == '=' || c == '/' || c == '>' || c == '?' || c == '|' || + c == ')' || c == '\'' || c == ',' || c == ';') { + // Symbol ist abgeschlossen, das gelesene Zeichen wird + // aber noch benoetigt + putback (c); + break; + } + else if (isalnum (c) || c == '-' || (c == '_' && elem.length () > 0)) + // korrektes Zeichen -> anhaengen +// elem += tolower (c); ????????? + elem += c; + else { + // Zeichen nicht erlaubt ? + return Tok_Invalid; + } + } + // alle Grossbuchstaben in Kleinbuchstaben aendern !!!! + return Tok_Symbol; +} + + +XmlTokenizer::Token XmlTokenizer::readString () { + KOXML_CHAR c; + elem = ""; + + while (1) { + c = readchar (); + if (c == '\n') + lineno++; + + if (istrm.eof ()) + // String ist noch nicht abgeschlossen + return Tok_Invalid; + else if (c == '\\') { + // naechstes Zeichen quoten + } + else if (c == '"') { + // String ist abgeschlossen + return Tok_String; + } + else + elem += c; + } +} + +XmlTokenizer::Token XmlTokenizer::readComment () { + KOXML_CHAR c1, c2; + elem = ""; + + c1 = readchar (); + if (c1 == '\n') + lineno++; + c2 = readchar (); + if (c2 == '\n') + lineno++; + + if (c1 != '-' || c2 != '-' || istrm.eof ()) + return Tok_Invalid; + + while (1) { + c1 = readchar (); + if (istrm.eof ()) + return Tok_Invalid; + else if (c1 == '\n') + lineno++; + else if (c1 == '>') + return Tok_Comment; + else + elem += c1; + } +} + +XmlTokenizer::Token XmlTokenizer::readText () { + KOXML_CHAR c; + elem = ""; + + while (1) { + c = readchar (); + if (c == '\n') + lineno++; + + if (istrm.eof ()) + return Tok_EOF; + else if (c == '<') { + putback (c); + return Tok_Text; + } + else if (c == '&') { + KOXML_STRING s; + while (c != ';') { + s += c; + c = readchar (); + if (c == '\n') + lineno++; + if (istrm.eof ()) + return Tok_EOF; + } + if (s == "<") + elem += "<"; + else if (s == ">") + elem += ">"; + else if (s == "&") + elem += "&"; + else if (s == "&lf") + elem += "\r"; + else if (s == "&nl") + elem += "\n"; +// entities ? +// elem += "[" + s +";]"; + } + else + elem += c; + } +} + +#ifdef TEST +int main (int argc, char** argv) { + XmlTokenizer::Token tok; + + XmlTokenizer tokenizer (cin); + + while ((tok = tokenizer.nextToken ()) != XmlTokenizer::Tok_EOF) { + switch (tok) { + case XmlTokenizer::Tok_Exclam: + cout << "! "; + break; + case XmlTokenizer::Tok_Bar: + cout << "| "; + break; + case XmlTokenizer::Tok_LParen: + cout << "( "; + break; + case XmlTokenizer::Tok_RParen: + cout << ") "; + break; + case XmlTokenizer::Tok_LBracket: + cout << "[ "; + break; + case XmlTokenizer::Tok_RBracket: + cout << "] "; + break; + case XmlTokenizer::Tok_Plus: + cout << "+ "; + break; + case XmlTokenizer::Tok_Asterisk: + cout << "* "; + break; + case XmlTokenizer::Tok_Comma: + cout << ", "; + break; + case XmlTokenizer::Tok_Semicolon: + cout << "; "; + break; + case XmlTokenizer::Tok_NSign: + cout << "# "; + break; + case XmlTokenizer::Tok_Apostr: + cout << "' "; + break; + case XmlTokenizer::Tok_Percent: + cout << "% "; + break; + case XmlTokenizer::Tok_Lt: + cout << "< "; + break; + case XmlTokenizer::Tok_Gt: + cout << "> "; + break; + case XmlTokenizer::Tok_QSign: + cout << "? "; + break; + case XmlTokenizer::Tok_Slash: + cout << "/ "; + break; + case XmlTokenizer::Tok_Eq: + cout << "= "; + break; + case XmlTokenizer::Tok_Symbol: + cout << "SYMBOL(" << tokenizer.element () << ") "; + break; + case XmlTokenizer::Tok_String: + cout << "STRING(" << tokenizer.element () << ") "; + break; + case XmlTokenizer::Tok_Comment: + cout << "COMMENT > "; + break; + case XmlTokenizer::Tok_Text: + cout << "TEXT(" << tokenizer.element () << ") "; + break; + default: + cout << "INVALID(" << tok << ")" << endl; + return 1; + break; + } + } +} +#endif diff --git a/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlTokenizer.h b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlTokenizer.h new file mode 100644 index 00000000..d78b6c7e --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlTokenizer.h @@ -0,0 +1,108 @@ +/* -*- C++ -*- + + This file is part of KIllustrator. + Copyright (C) 1998 Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de) + + modified for kvoctrain by Ewald Arnold kvoctrain@ewald-arnold.dein April ´99 + +*/ + +#ifndef XmlTokenizer_h_ +#define XmlTokenizer_h_ + +#include "koxml_config.h" + +/** + * The XMLTokenizer class allows an application to break a XML stream + * into tokens. + * + * @short A class for tokenizing an XML stream. + * @author Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de), modifications: Ewald Arnold (kvoctrain@ewald-arnold.de) + * @version 2000/07/02 + */ +class XmlTokenizer { +public: + /** + * The expected tokens for a XML stream. + */ + enum Token { Tok_Invalid, /* 0 */ + Tok_EOF, /* 1 */ + Tok_Symbol, /* 2 */ + Tok_String, /* 3 */ + Tok_Text, /* 4 */ + Tok_Comment, /* 5 */ + Tok_Lt, /* < 6 */ + Tok_Gt, /* > 7 */ + Tok_QSign, /* ? 8 */ + Tok_Eq, /* = 9 */ + Tok_Slash, /* / 10 */ + Tok_Exclam, /* ! 11 */ + Tok_Bar, /* | 12 */ + Tok_LParen, /* ( 13 */ + Tok_RParen, /* ) 14 */ + Tok_LBracket, /* [ 15 */ + Tok_RBracket, /* ] 16 */ + Tok_Plus, /* + 17 */ + Tok_Asterisk, /* * 18 */ + Tok_Comma, /* , 19 */ + Tok_Semicolon,/* ; 20 */ + Tok_NSign, /* # 21 */ + Tok_Apostr, /* ' 22 */ + Tok_Percent /* % 23 */ + }; + + /** + * Create a XmlTokenizer instance for the given input stream. + * + * @param is The open input stream for reading. + */ + XmlTokenizer (KOXML_ISTREAM& is); + + /** + * Destructor. + */ + ~XmlTokenizer (); + + /** + * Return the next token from the stream. + * @return The next token from the stream. + */ + Token nextToken (); + + /** + * Return the string representation of the current token. + * + * @return The string representation. + */ + const KOXML_STRING& element (); + + KOXML_CHAR readchar (); + void putback (KOXML_CHAR c); + + /** + * Cause the next call to method @p nextToken of this tokenizer + * to return the current token. + */ + void unget (); + + inline int lineNumber() { return lineno; } + +protected: + void skipWhitespace (); + Token readString (); + Token readSymbol (); + Token readText (); + Token readComment (); + +private: +// QIODevice *strm; + KOXML_STRING last_chars; + KOXML_ISTREAM &istrm; + KOXML_STRING elem; + Token last_tok; + bool use_last; + bool is_open; + int lineno; +}; + +#endif diff --git a/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlWriter.cpp b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlWriter.cpp new file mode 100644 index 00000000..38dfdbf2 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlWriter.cpp @@ -0,0 +1,253 @@ +/* -*- C++ -*- + + This file is part of KIllustrator. + Copyright (C) 1998 Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de) + + modified for kvoctrain by Ewald Arnold kvoctrain@ewald-arnold.dein April ´99 + + ----------------------------------------------------------------------- + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as + published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "XmlWriter.h" + +XmlWriter::XmlWriter (KOXML_OSTREAM& os) + : strm (os) +{ + autoendl = true; + isapo = false; + apo = 0; + strm << "<?xml version=\"1.0\"?>" << endl; // "encoding=UTF8" +} + + +XmlWriter::~XmlWriter () { + flush (); +} + + +void XmlWriter::startTag (KOXML_STRING id, bool closeIt, bool empty, bool eol) +{ + if (!id) return; + + strm << "<" << id; + if (!empty) { + lastTags.push (id); + } + + if (closeIt) { + if (empty) + strm << "/"; + strm << ">"; + if (eol || autoendl) { + isapo = false; + apo = 0; + strm << endl; + } + } +} + + +void XmlWriter::endTag (KOXML_STRING id, bool eol) +{ + strm << "</"; + if (id.length() != 0) + strm << id; + else { + KOXML_STRING tag = lastTags.top (); + lastTags.pop (); + strm << tag; + } + strm << ">"; + if (eol || autoendl) { + isapo = false; + apo = 0; + strm << endl; + } +} + +void XmlWriter::closeTag (bool empty, bool eol) +{ + if (empty) { + strm << "/"; + lastTags.pop (); + } + strm << ">"; + if (eol || autoendl) { + isapo = false; + apo = 0; + strm << endl; + } +} + + +void XmlWriter::setAutoEndl (const bool flag) +{ + autoendl = flag; +} + + +void XmlWriter::endline() +{ + isapo = false; + apo = 0; + strm << endl; +} + + +void XmlWriter::addAttribute (KOXML_STRING name, const KOXML_STRING& value) +{ + if (!name) return; + + KOXML_STRING val = value; + // escape dangerous characters in sgml-style + int pos = 0; + while ((pos = val.find ('&', pos)) >= 0) { + KOXML_STRING_INSERT( val, pos+1, "amp;"); + pos += 5; // skip & + } + pos = 0; + while ((pos = val.find ('<', pos)) >= 0) { + KOXML_STRING_REMOVE( val, pos, 1); + KOXML_STRING_INSERT( val, pos, "<"); + pos += 4; // skip &nl; + } + pos = 0; + while ((pos = val.find ('\n', pos)) >= 0) { + KOXML_STRING_REMOVE( val, pos, 1); + KOXML_STRING_INSERT( val, pos, "&nl;"); + pos += 4; // skip &nl; + } + pos = 0; + while ((pos = val.find ('\r', pos)) >= 0) { + KOXML_STRING_REMOVE( val, pos, 1); + KOXML_STRING_INSERT( val, pos+1, "lf;"); + pos += 4; // skip &lf; + } + pos = 0; + while ((pos = val.find ('\"', pos)) >= 0) { + KOXML_STRING_REMOVE( val, pos, 1); + KOXML_STRING_INSERT( val, pos, """); + pos += 6; // skip &qout; + } + + strm << " "; + strm << name << "=\""; + strm << val; + strm << "\""; +} + + +void XmlWriter::addAttribute (KOXML_STRING name, int value) +{ + if (name.length() == 0) + return; + + strm << " "; + strm << name << "=\""; + strm << value; + strm << "\""; +} + + +void XmlWriter::addAttribute (KOXML_STRING name, float value) +{ + if (name.length() == 0) + return; + + strm << " "; + strm << name << "=\""; + strm << value; + strm << "\""; +} + + +void XmlWriter::addAttribute (KOXML_STRING name, double value) +{ + if (name.length() == 0) + return; + + strm << " "; + strm << name << "=\""; + strm << value; + strm << "\""; +} + + +void XmlWriter::writeText (KOXML_STRING c) +{ + int i = 0; + while (i < (int) c.length()) { + if (c[i] == '<') + strm << "<"; + else if (c[i] == '&') + strm << "&"; + else if (c[i] == '>') + strm << ">"; + else if (c[i] == '\"' || c[i] == '\'' || c[i] == '`') { + strm << c[i]; + if (isapo) { + if (apo == c[i]) + isapo = false; + } + else { + isapo = true; + apo = c[i]; + } + } + else if (c[i] == '\n') { + if (isapo) + strm << "&nl;"; + else + strm << c[i]; + } + else if (c[i] == '\r') { + if (isapo) + strm << "&lf;"; + else + strm << c[i]; + } + else + strm << c[i]; + i++; + } +} + + +void XmlWriter::indent (int i) +{ + for (; i > 0; i--) + strm << " "; +} + + +void XmlWriter::writeTag (KOXML_STRING s) +{ + strm << "<" + << s + << ">"; +} + + +void XmlWriter::flush () +{ +#ifndef KOXML_USE_STL + stream()->flush (); +#else + strm.flush(); +#endif +} diff --git a/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlWriter.h b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlWriter.h new file mode 100644 index 00000000..d73bce59 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvt-xml/XmlWriter.h @@ -0,0 +1,187 @@ +/* -*- C++ -*- + + This file is part of KIllustrator. + Copyright (C) 1998 Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de) + + modified for kvoctrain by Ewald Arnold kvoctrain@ewald-arnold.dein April ´99 + +*/ + +#ifndef XmlWriter_h_ +#define XmlWriter_h_ + +#if defined(stack) +#undef stack +#endif + +#include <stack> +#include <vector> +using namespace std; + +#include "koxml_config.h" + +class KOXML_OSTREAM; +/** + * The XMLWriter class provides support for writing XML streams. + * It contains methods for output XML elements with attributes. + * + * Sample code: + * <pre> + * KOXML_OSTREAM os (fname); + * XmlWriter xml (os); // writes the XML header + * + * xml.startTag ("head"); // writes <head> + * + * // write <layout format="a4" orientation="landscape"> + * xml.startTag ("layout", false); + * xml.addAttribute ("format", "a4"); + * xml.addAttribute ("orientation", "landscape"); + * xml.closeTag (true); + * </pre> + * + * @short A helper class for writing XML. + * @author Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de), modifications: Ewald Arnold (kvoctrain@ewald-arnold.de) + * @version 2000/07/02 + + */ +class XmlWriter { +public: + /** + * Create a XmlWriter instance for the given output stream. + * + * @param os The open output stream for writing. + */ + XmlWriter (KOXML_OSTREAM& os); + + /** + * Desctructor. + */ + ~XmlWriter (); + + /** + * Write an element with the given ID to the XML stream. Attributes + * can be added later. + * + * @param id The element ID. + * @param closeIt If @p true the tag is closed by >, + * otherwise not. + * @param empty If @p true an empty element is written, which + * is closed by />. + * @param eol If @p true an eol char is appended + * even if autoendl is false + */ + void startTag (KOXML_STRING id, bool closeIt = true, bool empty = false, bool eol = false); + + /** + * Write the end tag according to the given element ID or to the + * last opened element. + * + * @param id The element ID. If @p "" the last opened + * element is ended. (default). + * @param eol If @p true an eol char is appended + * even if autoendl is false + */ + void endTag (KOXML_STRING id = "", bool eol = false); + + /** + * flag, indicating to automatically append end-of-line character after + * closing bracket + * + * @param autoflag If @p true, append eol character. Otherwise caller has to do it + */ + void setAutoEndl (const bool autoflag = true); + + /** + * append end-of-line char to stream + */ + void endline (); + + /** + * Close the current open element. + * + * @param empty If @p true an empty element is closed. + * @param eol If @p true an eol char is appended + * even if autoendl is false + */ + void closeTag (bool empty = false, bool eol = false); + + /** + * Add an attribute with the given value to the current element. + * This method doesn't check, if an element is open. + * + * @param name The attribute name. + * @param value The string value of the attribute. + */ + void addAttribute (KOXML_STRING name, const KOXML_STRING& value); + + /** + * Add an attribute with the given value to the current element. + * This method doesn't check, if an element is open. + * + * @param name The attribute name. + * @param value The integer value of the attribute. + */ + void addAttribute (KOXML_STRING name, int value); + + /** + * Add an attribute with the given value to the current element. + * This method doesn't check, if an element is open. + * + * @param name The attribute name. + * @param value The float value od the attribute. + */ + void addAttribute (KOXML_STRING name, float value); + + /** + * Add an attribute with the given value to the current element. + * This method doesn't check, if an element is open. + * + * @param name The attribute name. + * @param value The double value of the attribute. + */ + void addAttribute (KOXML_STRING name, double value); + + /** + * Write text to the XML stream. The method encodes the special + * characters @p <, @p > and @p &. + * + * @param s The text. + */ + void writeText (KOXML_STRING s); + + /** + * Write a tag to the XML stream. + * + * @param s The tag without the brackets. + */ + void writeTag (KOXML_STRING s); + + /** + * indents next text string with some spaces + * + * @param i number of spaces to indent + */ + void indent (int i); + + /** + * Flush the XML output stream. + */ + void flush (); + +#ifndef KOXML_USE_STL + /** + * Get the raw output stream. + */ + inline QIODevice *stream () { return strm.device(); } +#endif + +private: + stack<KOXML_STRING, vector<KOXML_STRING> > lastTags; + + KOXML_OSTREAM &strm; + bool autoendl; + bool isapo; + KOXML_CHAR apo; +}; + +#endif diff --git a/kvoctrain/kvoctrain/kvt-core/kvt-xml/koxml_config.h b/kvoctrain/kvoctrain/kvt-core/kvt-xml/koxml_config.h new file mode 100644 index 00000000..2f0daecb --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/kvt-xml/koxml_config.h @@ -0,0 +1,47 @@ +//#define KOXML_USE_STL + +/* + ----------------------------------------------------------------------- + + ----------------------------------------------------------------------- +*/ + +#ifndef KOXML_USE_STL + +# include <qtextstream.h> +# define KOXML_ISTREAM QTextStream +# define KOXML_OSTREAM QTextStream + +# include <qstring.h> +# define KOXML_STRING QString + +// Unicode character +# define KOXML_CHAR QChar + +# define KOXML_STRING_REMOVE( string_var, pos, count) string_var.remove (pos, count) +# define KOXML_STRING_INSERT( string_var, pos, str) string_var.insert(pos, str) + +#else + +# include <iostream> +using namespace std; +# define KOXML_ISTREAM istream +# define KOXML_OSTREAM ostream + +# define KOXML_CHAR char // evtl. wchar + +//////////////////////////////////////////////////////// +//evtl. an MFC o.ä. anpassen +#ifdef __MFC_STRING_BENUTZT__ + +#else + +# include <string> +# define KOXML_STRING string // evtl. wstring + +# define KOXML_STRING_REMOVE( string_var, pos, count) string_var.erase (pos, count) +# define KOXML_STRING_INSERT( string_var, pos, str) string_var.insert(pos, (string)str) + +#endif + +#endif diff --git a/kvoctrain/kvoctrain/kvt-core/langset.cpp b/kvoctrain/kvoctrain/kvt-core/langset.cpp new file mode 100644 index 00000000..644878e7 --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/langset.cpp @@ -0,0 +1,220 @@ +/*************************************************************************** + + properties for a language + + ----------------------------------------------------------------------- + + begin : Wed Jun 30 20: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. * + * * + ***************************************************************************/ + + +#include "langset.h" + +// void LangSet::addSet (QString _shortId, QString _longId, +// QString _PixMapFile, const QString& keyboardLayout) +// { +// LangDef def; +// def.shortId = _shortId; +// def.shortId2 = ""; +// def.longId = _longId; +// def.PixMapFile = _PixMapFile; +// def.keyboardLayout = keyboardLayout; +// langs.push_back (def); +// } + + +void LangSet::addSet (QString _shortId, QString _longId, + QString _PixMapFile, const QString& _shortId2, + const QString& keyboardLayout) + +{ + LangDef def; + def.shortId = _shortId; + def.shortId2 = _shortId2; + def.longId = _longId; + def.PixMapFile = _PixMapFile; + def.keyboardLayout = keyboardLayout; + langs.push_back (def); +} + + +void LangSet::appendSet(const LangSet &set) +{ + for (int i = 0; i < (int) set.size(); ++i) { + addSet(set.langs[i].shortId, set.langs[i].longId, set.langs[i].PixMapFile, + set.langs[i].shortId2, set.langs[i].keyboardLayout); + } +} + + +void LangSet::clear() +{ + langs.clear(); +} + + +void LangSet::erase (int idx) +{ + if (idx >= 0 && idx < (int) langs.size() ) + langs.erase (langs.begin() + idx); +} + + +QString LangSet::shortId (int index) const +{ + if (index >= 0 && index < (int) langs.size() ) + return langs[index].shortId; + + return QString::null; +} + + +QString LangSet::shortId2 (int index) const +{ + if (index >= 0 && index < (int) langs.size() ) + return langs[index].shortId2; + + return QString::null; +} + + +QString LangSet::longId (int index) const +{ + if (index >= 0 && index < (int) langs.size() ) + return langs[index].longId; + + return QString::null; +} + + +QString LangSet::PixMapFile (int index) const +{ + if (index >= 0 && index < (int) langs.size() ) + return langs[index].PixMapFile; + return ""; +} + +QString LangSet::keyboardLayout (int index) const +{ + if (index >= 0 && index < (int) langs.size()) { + return langs[index].keyboardLayout; + } + else { + return QString::null; + } +} + + +QString LangSet::findShortId (const QString &_longId) const +{ + if (_longId.isEmpty()) + return ""; + + for (int i = 0; i < (int) langs.size(); i++ ) + if (_longId == langs[i].longId) + return langs[i].shortId; + + return QString::null; +} + + +QString LangSet::findLongId (const QString &_shortId) const +{ + if (_shortId.isEmpty()) + return ""; + + for (int i = 0; i < (int) langs.size(); i++ ) + if ( _shortId == langs[i].shortId + || _shortId == langs[i].shortId2) + return langs[i].longId; + + return QString::null; +} + + +int LangSet::indexShortId (QString _shortId) const +{ + if (_shortId.isEmpty()) + return -1; + + for (int i = 0; i < (int) langs.size(); i++) { + if ( langs[i].shortId == _shortId + ||langs[i].shortId2 == _shortId ) + return i; + } + return -1; +} + + +int LangSet::indexLongId (QString _longId) const +{ + if (_longId.isEmpty()) + return -1; + + for (int i = 0; i < (int) langs.size(); i++) { + if (langs[i].longId == _longId) + return i; + } + return -1; +} + + +int LangSet::indexPixMapFile (QString PixMapFile) const +{ + int id = -1; + for (int i = 0; i < (int) langs.size(); i++) + if (langs[i].PixMapFile == PixMapFile) + id = i; + return id; +} + +void LangSet::setShortId (const QString & s, int index) +{ + if (index < (int) langs.size() ) + langs[index].shortId = s; +} + + +void LangSet::setShortId2 (const QString & s, int index) +{ + if (index < (int) langs.size() ) + langs[index].shortId2 = s; +} + + +void LangSet::setLongId (const QString & s, int index) +{ + if (index < (int) langs.size() ) + langs[index].longId = s; +} + + +void LangSet::setPixMapFile (const QString & s, int index) +{ + if (index < (int) langs.size() ) + langs[index].PixMapFile = s; +} + +void LangSet::setKeyboardLayout(const QString& layout, int index) +{ + if (index < (int) langs.size()) { + langs[index].keyboardLayout = layout; + } +} diff --git a/kvoctrain/kvoctrain/kvt-core/langset.h b/kvoctrain/kvoctrain/kvt-core/langset.h new file mode 100644 index 00000000..f0da2a5a --- /dev/null +++ b/kvoctrain/kvoctrain/kvt-core/langset.h @@ -0,0 +1,92 @@ +/*************************************************************************** + + properties for a language + + ----------------------------------------------------------------------- + + begin : Thu Mar 11 20: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 langset_h +#define langset_h + +#include <vector> +using namespace std; + +#include <qstring.h> + + +class LangSet +{ + public: + + LangSet () {} + + void addSet (QString shortId, QString longId, QString PixMapFile, + const QString& shortId2 = QString::null, + const QString& keyboardLayout = QString::null); + +/* void addSet (QString shortId, QString shortId2, QString longId, */ +/* QString PixMapFile, */ +/* const QString& keyboardLayout = QString::null); */ + + void appendSet(const LangSet &set); + + unsigned int size () const { return langs.size(); } + void erase (int idx); + void clear (); + + QString shortId (int index) const; + QString shortId2 (int index) const; + QString longId (int index) const; + QString PixMapFile (int index) const; + QString keyboardLayout (int index) const; + + int indexShortId (QString shortId) const; + int indexLongId (QString longId) const; + int indexPixMapFile (QString PixMapFile) const; + // doesn't make sense for keyboard layouts since there is no 1-to-1 relation to languages + + void setShortId (const QString & shortId, int index); + void setShortId2 (const QString & shortId2, int index); + void setLongId (const QString & longId, int index); + void setPixMapFile (const QString & PixMapFile, int index); + void setKeyboardLayout(const QString & layout, int index); + + QString findShortId (const QString & longId) const; + QString findLongId (const QString & shortId) const; + + private: + + struct LangDef { + QString shortId, + shortId2, + longId, + PixMapFile, + keyboardLayout; + }; + + vector<LangDef> langs; +}; + + +#endif // langset_h |