From ceeaa976258d2f97854637fa49cfa63be71207e6 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 17 Mar 2008 20:55:16 +0000 Subject: [PATCH] Allow individual grades for each conjugation form. Make reading and writing of conjugations much more elegant by using keduvoctext. svn path=/trunk/KDE/kdeedu/libkdeedu/; revision=786741 --- keduvocdocument/keduvocconjugation.cpp | 149 ++++++++++++-- keduvocdocument/keduvocconjugation.h | 27 ++- keduvocdocument/keduvoccontainer.cpp | 1 - keduvocdocument/keduvocdeclension.cpp | 6 +- keduvocdocument/keduvocdeclension.h | 7 +- keduvocdocument/keduvocgrammar.cpp | 12 +- keduvocdocument/keduvocgrammar.h | 15 +- keduvocdocument/keduvockvtml2reader.cpp | 194 ++++-------------- keduvocdocument/keduvockvtml2writer.cpp | 174 +++------------- keduvocdocument/keduvockvtml2writer.h | 8 - keduvocdocument/keduvocpersonalpronoun.cpp | 2 +- keduvocdocument/keduvoctext.cpp | 5 + keduvocdocument/keduvoctext.h | 6 + keduvocdocument/keduvoctranslation.cpp | 24 +++ keduvocdocument/kvtml2defs.h | 52 ++--- .../tests/keduvocdocumentvalidatortest.cpp | 20 ++ 16 files changed, 321 insertions(+), 381 deletions(-) diff --git a/keduvocdocument/keduvocconjugation.cpp b/keduvocdocument/keduvocconjugation.cpp index 325b01f..2e46e32 100644 --- a/keduvocdocument/keduvocconjugation.cpp +++ b/keduvocdocument/keduvocconjugation.cpp @@ -23,13 +23,16 @@ #include "keduvocconjugation.h" #include "keduvoccommon_p.h" +#include "kvtml2defs.h" + #include #include +#include class KEduVocConjugation::Private { public: - QMap m_conjugations; + QMap m_conjugations; }; @@ -50,7 +53,6 @@ KEduVocConjugation::~KEduVocConjugation() delete d; } - KEduVocConjugation& KEduVocConjugation::operator = ( const KEduVocConjugation& other ) { d->m_conjugations = other.d->m_conjugations; @@ -63,42 +65,32 @@ bool KEduVocConjugation::operator ==(const KEduVocConjugation& other) const } -QString KEduVocConjugation::conjugation(int index) const +KEduVocText& KEduVocConjugation::conjugation(int index) { - if ( d->m_conjugations.contains(index) ) { - return d->m_conjugations.value(index); - } - return QString(); + return d->m_conjugations[index]; } -QString KEduVocConjugation::conjugation(ConjugationPerson person, ConjugationNumber number) const +KEduVocText& KEduVocConjugation::conjugation(ConjugationPerson person, ConjugationNumber number) { return conjugation(indexOf(person, number)); } -void KEduVocConjugation::setConjugation(const QString & conjugation, ConjugationPerson person, ConjugationNumber number) +void KEduVocConjugation::setConjugation(const KEduVocText& conjugation, ConjugationPerson person, ConjugationNumber number) { setConjugation(conjugation, indexOf(person, number)); } -void KEduVocConjugation::setConjugation(const QString & conjugation, int index) +void KEduVocConjugation::setConjugation(const KEduVocText& conjugation, int index) { - if ( !conjugation.isEmpty() ) { - d->m_conjugations[index] = conjugation; - } else { - // if we received an empty string, remove the element. - if ( d->m_conjugations.contains(index) ) { - d->m_conjugations.remove(index); - } - } + d->m_conjugations[index] = conjugation; } int KEduVocConjugation::indexOf(ConjugationPerson person, ConjugationNumber number) { - return person + PersonMAX * number; + return person + (ThirdNeutralCommon+1) * number; } @@ -114,3 +106,122 @@ QList< int > KEduVocConjugation::keys() +void KEduVocConjugation::toKVTML2(QDomElement & parent, const QString &tense) +{ + if (isEmpty()) { + return; + } + + // write the tense tag + QDomDocument domDoc = parent.ownerDocument(); + QDomElement tenseElement = domDoc.createElement( KVTML_TENSE ); + tenseElement.appendChild( domDoc.createTextNode(tense) ); + parent.appendChild(tenseElement); + + for ( KEduVocConjugation::ConjugationNumber num = KEduVocConjugation::Singular; num <= KEduVocConjugation::Plural; num = KEduVocConjugation::ConjugationNumber(num +1) ) { + + QDomElement numberElement = domDoc.createElement( KVTML_GRAMMATICAL_NUMBER[num] ); + for ( KEduVocConjugation::ConjugationPerson person = KEduVocConjugation::First; person <= KEduVocConjugation::ThirdNeutralCommon; person = KEduVocConjugation::ConjugationPerson(person +1) ) { + + if (!conjugation(indexOf(person, num)).isEmpty()) { + QDomElement personElement = domDoc.createElement( KVTML_GRAMMATICAL_PERSON[person] ); + numberElement.appendChild(personElement); + conjugation(indexOf(person, num)).toKVTML2(personElement); + } + } + if (numberElement.hasChildNodes()) { + parent.appendChild( numberElement ); + } + } +} + +/* + + QString first = conjugation.conjugation( + KEduVocConjugation::First, num ); + QString second = conjugation.conjugation( + KEduVocConjugation::Second, num ); + QString third_male = conjugation.conjugation( + KEduVocConjugation::ThirdMale, num ); + QString third_female = conjugation.conjugation( + KEduVocConjugation::ThirdFemale, num ); + QString third_neutral = conjugation.conjugation( + KEduVocConjugation::ThirdNeutralCommon, num ); + + if ( !first.isEmpty() || !second.isEmpty() || !third_female.isEmpty() || + !third_male.isEmpty() || !third_neutral.isEmpty() ) { + QDomElement number; + switch (num) { + case KEduVocConjugation::Singular: + number = m_domDoc.createElement( KVTML_SINGULAR ); + break; + case KEduVocConjugation::Dual: + number = m_domDoc.createElement( KVTML_DUAL ); + break; + case KEduVocConjugation::Plural: + number = m_domDoc.createElement( KVTML_PLURAL ); + break; + } + + number.appendChild( newTextElement( KVTML_1STPERSON, first ) ); + number.appendChild( newTextElement( KVTML_2NDPERSON, second ) ); + number.appendChild( newTextElement( KVTML_THIRD_MALE, third_male ) ); + number.appendChild( newTextElement( KVTML_THIRD_FEMALE, third_female ) ); + number.appendChild( newTextElement( KVTML_THIRD_NEUTRAL_COMMON, third_neutral ) ); + + conjugationElement.appendChild( number ); + } + }*/ + + + /* + for ( KEduVocDeclension::DeclensionNumber num = KEduVocDeclension::Singular; num <= KEduVocDeclension::Plural; num = KEduVocDeclension::DeclensionNumber(num +1) ) { + QDomElement numberElement = domDoc.createElement( KVTML_GRAMMATICAL_NUMBER[num] ); + for ( KEduVocDeclension::DeclensionCase dcase = KEduVocDeclension::Nominative; dcase < KEduVocDeclension::DeclensionCaseMAX; dcase = KEduVocDeclension::DeclensionCase(dcase +1) ) { + QDomElement caseElement = domDoc.createElement( KVTML_DECLENSION_CASE[dcase] ); + declension(num, dcase).toKVTML2(caseElement); + + if (caseElement.hasChildNodes()) { + numberElement.appendChild(caseElement); + } + } + if (numberElement.hasChildNodes()) { + declensionElement.appendChild(numberElement); + } + } + + */ + + + +KEduVocConjugation* KEduVocConjugation::fromKVTML2(QDomElement & parent) +{ + // sanity check + if (parent.isNull()) { + return 0; + } + + KEduVocConjugation* conjugation = new KEduVocConjugation; + + for ( int num = KEduVocConjugation::Singular; num <= KEduVocConjugation::Plural; num++ ) { + QDomElement numberElement = parent.firstChildElement( KVTML_GRAMMATICAL_NUMBER[num] ); + + if (numberElement.hasChildNodes()) { + for (int person = KEduVocConjugation::First; person <= KEduVocConjugation::ThirdNeutralCommon; person++) { + QDomElement personElement = numberElement.firstChildElement( KVTML_GRAMMATICAL_PERSON[person] ); + if (!personElement.isNull()) { + KEduVocText text; + text.fromKVTML2(personElement); + if (text.text().isEmpty()) { + // compatibility for kde 4.0. There the text was directly below the person, not enabling grades per conjugation form. + text.setText(personElement.text()); + } + conjugation->setConjugation(text, ConjugationPerson(person), KEduVocConjugation::ConjugationNumber(num)); + } + } + } + } + return conjugation; +} + + diff --git a/keduvocdocument/keduvocconjugation.h b/keduvocdocument/keduvocconjugation.h index 33fa7b0..c81c76b 100644 --- a/keduvocdocument/keduvocconjugation.h +++ b/keduvocdocument/keduvocconjugation.h @@ -40,8 +40,7 @@ public: enum ConjugationNumber { Singular, Dual, - Plural, - NumberMAX + Plural }; // store third person neutral/common in the same sttr @@ -50,8 +49,7 @@ public: Second, ThirdMale, ThirdFemale, - ThirdNeutralCommon, - PersonMAX + ThirdNeutralCommon }; @@ -67,15 +65,28 @@ public: KEduVocConjugation& operator = ( const KEduVocConjugation& a ); bool operator == ( const KEduVocConjugation& a ) const; - QString conjugation(ConjugationPerson person, ConjugationNumber number) const; - QString conjugation(int index) const; - void setConjugation(const QString& conjugation, ConjugationPerson person, ConjugationNumber number); - void setConjugation(const QString& conjugation, int index); + KEduVocText& conjugation(ConjugationPerson person, ConjugationNumber number); + KEduVocText& conjugation(int index); + void setConjugation(const KEduVocText& conjugation, ConjugationPerson person, ConjugationNumber number); + void setConjugation(const KEduVocText& conjugation, int index); QList keys(); bool isEmpty(); + /** + * Create xml for this declension + * @param parent + */ + void toKVTML2(QDomElement& parent, const QString &tense); + + /** + * Reads a declension from xml, returns 0 if it is empty + * @param parent + * @return + */ + static KEduVocConjugation* fromKVTML2(QDomElement& parent); + static int indexOf(ConjugationPerson person, ConjugationNumber number); private: diff --git a/keduvocdocument/keduvoccontainer.cpp b/keduvocdocument/keduvoccontainer.cpp index 7d641d4..e46ce55 100644 --- a/keduvocdocument/keduvoccontainer.cpp +++ b/keduvocdocument/keduvoccontainer.cpp @@ -238,7 +238,6 @@ double KEduVocContainer::averageGrade(int translation) kDebug() << entry->translation(translation)->text() << entry->translation(translation)->grade(); } -kDebug() << "translation: " << translation << "sum: " << sum; // make that a percentage return (sum * 100.0/7.0)/entryCount(NotRecursive); } diff --git a/keduvocdocument/keduvocdeclension.cpp b/keduvocdocument/keduvocdeclension.cpp index 7822428..0b9d5fd 100644 --- a/keduvocdocument/keduvocdeclension.cpp +++ b/keduvocdocument/keduvocdeclension.cpp @@ -79,7 +79,7 @@ void KEduVocDeclension::setDeclension(const KEduVocText & declension, Declension int KEduVocDeclension::indexOf(DeclensionNumber number, DeclensionCase decCase) { - return number * DeclensionCaseMAX + decCase; + return number * (Vocative+1) + decCase; } bool KEduVocDeclension::isEmpty() @@ -97,7 +97,7 @@ void KEduVocDeclension::toKVTML2(QDomElement & parent) for ( KEduVocDeclension::DeclensionNumber num = KEduVocDeclension::Singular; num <= KEduVocDeclension::Plural; num = KEduVocDeclension::DeclensionNumber(num +1) ) { QDomElement numberElement = domDoc.createElement( KVTML_GRAMMATICAL_NUMBER[num] ); - for ( KEduVocDeclension::DeclensionCase dcase = KEduVocDeclension::Nominative; dcase < KEduVocDeclension::DeclensionCaseMAX; dcase = KEduVocDeclension::DeclensionCase(dcase +1) ) { + for ( KEduVocDeclension::DeclensionCase dcase = KEduVocDeclension::Nominative; dcase < (KEduVocDeclension::Vocative+1); dcase = KEduVocDeclension::DeclensionCase(dcase +1) ) { QDomElement caseElement = domDoc.createElement( KVTML_DECLENSION_CASE[dcase] ); declension(num, dcase).toKVTML2(caseElement); @@ -127,7 +127,7 @@ KEduVocDeclension* KEduVocDeclension::fromKVTML2(QDomElement & parent) for ( KEduVocDeclension::DeclensionNumber num = KEduVocDeclension::Singular; num <= KEduVocDeclension::Plural; num = KEduVocDeclension::DeclensionNumber(num +1) ) { QDomElement numberElement = declensionElement.firstChildElement( KVTML_GRAMMATICAL_NUMBER[num] ); if (!numberElement.isNull()) { - for ( KEduVocDeclension::DeclensionCase dcase = KEduVocDeclension::Nominative; dcase < KEduVocDeclension::DeclensionCaseMAX; dcase = KEduVocDeclension::DeclensionCase(dcase +1) ) { + for ( KEduVocDeclension::DeclensionCase dcase = KEduVocDeclension::Nominative; dcase <= KEduVocDeclension::Vocative; dcase = DeclensionCase(dcase +1) ) { QDomElement caseElement = numberElement.firstChildElement( KVTML_DECLENSION_CASE[dcase] ); if (!caseElement.isNull()) { KEduVocText text; diff --git a/keduvocdocument/keduvocdeclension.h b/keduvocdocument/keduvocdeclension.h index b9b9ede..ff6eeb0 100644 --- a/keduvocdocument/keduvocdeclension.h +++ b/keduvocdocument/keduvocdeclension.h @@ -47,8 +47,7 @@ public: Accusative, Ablative, Locative, - Vocative, - DeclensionCaseMAX + Vocative }; /** @@ -98,6 +97,10 @@ public: bool isEmpty(); + /** + * Create xml for this declension + * @param parent + */ void toKVTML2(QDomElement& parent); /** diff --git a/keduvocdocument/keduvocgrammar.cpp b/keduvocdocument/keduvocgrammar.cpp index 51fa2bf..b357fc4 100644 --- a/keduvocdocument/keduvocgrammar.cpp +++ b/keduvocdocument/keduvocgrammar.cpp @@ -79,13 +79,17 @@ QString KEduVocArticle::article(ArticleNumber number, ArticleDefiniteness defini void KEduVocArticle::setArticle(const QString & article, ArticleNumber number, ArticleDefiniteness definite, ArticleGender gender) { - kDebug() << article << "#" << number << "def" << definite << "indef" << gender << "index" << indexOf(number, definite, gender); - d->m_articles[indexOf(number, definite, gender)] = article; + setArticle(article, indexOf(number, definite, gender)); +} + +void KEduVocArticle::setArticle(const QString & article, int index) +{ + d->m_articles[index] = article; } int KEduVocArticle::indexOf(ArticleNumber number, ArticleDefiniteness definite, ArticleGender gender) { - return number + (definite * NumberMAX) + (gender * NumberMAX * DefinitenessMAX); + return number + (definite * (Plural+1)) + (gender * (Plural+1) * (Indefinite+1)); } bool KEduVocArticle::isArticle(const QString & article) const @@ -98,3 +102,5 @@ bool KEduVocArticle::isEmpty() return d->m_articles.isEmpty(); } + + diff --git a/keduvocdocument/keduvocgrammar.h b/keduvocdocument/keduvocgrammar.h index d1a0b60..9473215 100644 --- a/keduvocdocument/keduvocgrammar.h +++ b/keduvocdocument/keduvocgrammar.h @@ -43,21 +43,18 @@ public: enum ArticleNumber { Singular, Dual, - Plural, - NumberMAX + Plural }; enum ArticleGender { Masculine, Feminine, - Neutral, - GenderMAX + Neutral }; enum ArticleDefiniteness { Definite, - Indefinite, - DefinitenessMAX + Indefinite }; @@ -87,7 +84,6 @@ public: */ ~KEduVocArticle(); - /** * assignment operator for d-pointer copying */ @@ -98,12 +94,13 @@ public: void setArticle(const QString& article, ArticleNumber number, ArticleDefiniteness definite, ArticleGender gender); + void setArticle(const QString& article, int index); + bool isArticle(const QString& article) const; bool isEmpty(); -private: - int indexOf(ArticleNumber number, ArticleDefiniteness definite, ArticleGender gender); + static int indexOf(ArticleNumber number, ArticleDefiniteness definite, ArticleGender gender); class Private; Private * const d; diff --git a/keduvocdocument/keduvockvtml2reader.cpp b/keduvocdocument/keduvockvtml2reader.cpp index 08f6d6e..f288e7d 100644 --- a/keduvocdocument/keduvockvtml2reader.cpp +++ b/keduvocdocument/keduvockvtml2reader.cpp @@ -307,6 +307,7 @@ bool KEduVocKvtml2Reader::readEntry( QDomElement &entryElement ) bool KEduVocKvtml2Reader::readTranslation( QDomElement &translationElement, KEduVocExpression *expr, int index ) { + // read the text, grade, declension and conjugation expr->translation(index)->fromKVTML2(translationElement); // @@ -316,18 +317,6 @@ bool KEduVocKvtml2Reader::readTranslation( QDomElement &translationElement, expr->translation(index)->setFalseFriend( fromid, currentElement.text() ); } - // conjugations - currentElement = translationElement.firstChildElement( KVTML_CONJUGATION ); - while ( !currentElement.isNull() ) { - // read any conjugations (NOTE: this will overwrite any conjugations of the same type for this - // translation, as the type is used as the key - QDomElement tenseElement = currentElement.firstChildElement( KVTML_TENSE ); - QString tense = tenseElement.text(); - - readConjugation( currentElement, expr->translation(index)->conjugation(tense) ); - currentElement = currentElement.nextSiblingElement( KVTML_CONJUGATION ); - } - // comparisons currentElement = translationElement.firstChildElement( KVTML_COMPARISON ); if ( !currentElement.isNull() ) { @@ -396,64 +385,42 @@ bool KEduVocKvtml2Reader::readLesson( KEduVocLesson* parentLesson, QDomElement & bool KEduVocKvtml2Reader::readArticle( QDomElement &articleElement, int identifierNum ) /*
- - der - die - das - - - ein - eine - ein - + + + der + die + das + + + ein + eine + ein + + + +
*/ { - QString fem_def = ""; - QString mal_def = ""; - QString nat_def = ""; - QString fem_indef = ""; - QString mal_indef = ""; - QString nat_indef = ""; - - QDomElement currentElement = articleElement.firstChildElement( KVTML_SINGULAR ).firstChildElement( KVTML_DEFINITE ); - if ( !currentElement.isNull() ) - { - QDomElement subElement = currentElement.firstChildElement( KVTML_MALE ); - if ( !subElement.isNull() ) { - mal_def = subElement.text(); - } - - subElement = currentElement.firstChildElement( KVTML_FEMALE ); - if ( !subElement.isNull() ) { - fem_def = subElement.text(); - } - - subElement = currentElement.firstChildElement( KVTML_NEUTRAL ); - if ( !subElement.isNull() ) { - nat_def = subElement.text(); - } - } - - currentElement = articleElement.firstChildElement( KVTML_SINGULAR ).firstChildElement( KVTML_INDEFINITE ); - if ( !currentElement.isNull() ) - { - QDomElement subElement = currentElement.firstChildElement( KVTML_MALE ); - if ( !subElement.isNull() ) { - mal_indef = subElement.text(); - } - - subElement = currentElement.firstChildElement( KVTML_FEMALE ); - if ( !subElement.isNull() ) { - fem_indef = subElement.text(); - } - - subElement = currentElement.firstChildElement( KVTML_NEUTRAL ); - if ( !subElement.isNull() ) { - nat_indef = subElement.text(); + // singular + for ( KEduVocArticle::ArticleNumber num = KEduVocArticle::Singular; num <= KEduVocArticle::Plural; num = KEduVocArticle::ArticleNumber(num+1) ) { + QDomElement numberElement = articleElement.firstChildElement( KVTML_GRAMMATICAL_NUMBER[num] ); + if (!numberElement.isNull()) { + // definite + for ( KEduVocArticle::ArticleDefiniteness def = KEduVocArticle::Definite; def <= KEduVocArticle::Indefinite; def = KEduVocArticle::ArticleDefiniteness(def+1) ) { + QDomElement defElement = numberElement.firstChildElement( KVTML_GRAMMATICAL_DEFINITENESS[def] ); + if (!defElement.isNull()) { + // male + for ( KEduVocArticle::ArticleGender gen = KEduVocArticle::Masculine; gen <= KEduVocArticle::Neutral; gen = KEduVocArticle::ArticleGender(gen+1) ) { + QDomElement genderElement = defElement.firstChildElement( KVTML_GRAMMATICAL_GENDER[gen] ); + if (!genderElement.isNull()) { + m_doc->identifier(identifierNum).article().setArticle( genderElement.text(), KEduVocArticle::indexOf(num, def, gen) ); + } + } + } + } } } - m_doc->identifier(identifierNum).setArticle( KEduVocArticle( fem_def, fem_indef, mal_def, mal_indef, nat_def, nat_indef ) ); return true; } @@ -607,75 +574,6 @@ bool KEduVocKvtml2Reader::readMultipleChoice( QDomElement &multipleChoiceElement return true; } -bool KEduVocKvtml2Reader::readConjugation( QDomElement &conjugElement, KEduVocConjugation &conjugation ) -/* - - Futurepastperfekt:) - - - - - - - - - - - - - - - - - -*/ -{ - QDomElement personElement = conjugElement.firstChildElement( KVTML_SINGULAR ); - if ( !personElement.isNull() ) - { - readConjugationPerson( personElement, conjugation, KEduVocConjugation::Singular ); - } - - personElement = conjugElement.firstChildElement( KVTML_DUAL ); - if ( !personElement.isNull() ) - { - readConjugationPerson( personElement, conjugation, KEduVocConjugation::Dual ); - } - - personElement = conjugElement.firstChildElement( KVTML_PLURAL ); - if ( !personElement.isNull() ) - { - readConjugationPerson( personElement, conjugation, KEduVocConjugation::Plural ); - } - - return true; -} - - -bool KEduVocKvtml2Reader::readConjugationPerson(QDomElement & personElement, KEduVocConjugation & conjugation, KEduVocConjugation::ConjugationNumber number) -{ - QDomElement currentElement = personElement.firstChildElement( KVTML_1STPERSON ); - conjugation.setConjugation( currentElement.text(), - KEduVocConjugation::First, number ); - - currentElement = personElement.firstChildElement( KVTML_2NDPERSON ); - conjugation.setConjugation( currentElement.text(), - KEduVocConjugation::Second, number ); - - currentElement = personElement.firstChildElement( KVTML_THIRD_MALE ); - conjugation.setConjugation( currentElement.text(), - KEduVocConjugation::ThirdMale, number ); - - currentElement = personElement.firstChildElement( KVTML_THIRD_FEMALE ); - conjugation.setConjugation( currentElement.text(), - KEduVocConjugation::ThirdFemale, number ); - - currentElement = personElement.firstChildElement( KVTML_THIRD_NEUTRAL_COMMON ); - conjugation.setConjugation( currentElement.text(), - KEduVocConjugation::ThirdNeutralCommon, number ); - return true; -} - bool KEduVocKvtml2Reader::readPersonalPronoun(QDomElement & pronounElement, KEduVocPersonalPronoun & pronoun) { @@ -686,17 +584,17 @@ bool KEduVocKvtml2Reader::readPersonalPronoun(QDomElement & pronounElement, KEdu pronoun.setDualExists( !pronounElement.firstChildElement( KVTML_DUAL_EXISTS).isNull() ); - QDomElement personElement = pronounElement.firstChildElement( KVTML_SINGULAR ); + QDomElement personElement = pronounElement.firstChildElement( KVTML_GRAMMATICAL_NUMBER[0] ); if ( !personElement.isNull() ) { readPersonalPronounChild( personElement, pronoun, KEduVocConjugation::Singular ); } - personElement = pronounElement.firstChildElement( KVTML_DUAL ); + personElement = pronounElement.firstChildElement( KVTML_GRAMMATICAL_NUMBER[1] ); if ( !personElement.isNull() ) { readPersonalPronounChild( personElement, pronoun, KEduVocConjugation::Dual ); } - personElement = pronounElement.firstChildElement( KVTML_PLURAL ); + personElement = pronounElement.firstChildElement( KVTML_GRAMMATICAL_NUMBER[2] ); if ( !personElement.isNull() ) { readPersonalPronounChild( personElement, pronoun, KEduVocConjugation::Plural ); } @@ -706,25 +604,11 @@ bool KEduVocKvtml2Reader::readPersonalPronoun(QDomElement & pronounElement, KEdu bool KEduVocKvtml2Reader::readPersonalPronounChild(QDomElement & personElement, KEduVocPersonalPronoun & pronoun, KEduVocConjugation::ConjugationNumber number) { - QDomElement currentElement = personElement.firstChildElement( KVTML_1STPERSON ); - pronoun.setPersonalPronoun( currentElement.text(), - KEduVocConjugation::First, number ); - - currentElement = personElement.firstChildElement( KVTML_2NDPERSON ); - pronoun.setPersonalPronoun( currentElement.text(), - KEduVocConjugation::Second, number ); - - currentElement = personElement.firstChildElement( KVTML_THIRD_MALE ); - pronoun.setPersonalPronoun( currentElement.text(), - KEduVocConjugation::ThirdMale, number ); - - currentElement = personElement.firstChildElement( KVTML_THIRD_FEMALE ); - pronoun.setPersonalPronoun( currentElement.text(), - KEduVocConjugation::ThirdFemale, number ); + for (int person = KEduVocConjugation::First; person <= KEduVocConjugation::ThirdNeutralCommon; person++) { + QDomElement currentElement = personElement.firstChildElement( KVTML_GRAMMATICAL_PERSON[person] ); + pronoun.setPersonalPronoun( currentElement.text(), KEduVocConjugation::ConjugationPerson(person), number ); + } - currentElement = personElement.firstChildElement( KVTML_THIRD_NEUTRAL_COMMON ); - pronoun.setPersonalPronoun( currentElement.text(), - KEduVocConjugation::ThirdNeutralCommon, number ); return true; } diff --git a/keduvocdocument/keduvockvtml2writer.cpp b/keduvocdocument/keduvockvtml2writer.cpp index d2ed9a5..7b8af38 100644 --- a/keduvocdocument/keduvockvtml2writer.cpp +++ b/keduvocdocument/keduvockvtml2writer.cpp @@ -196,68 +196,29 @@ bool KEduVocKvtml2Writer::writeLessons( KEduVocLesson *parentLesson, QDomElement } -bool KEduVocKvtml2Writer::writeArticle( QDomElement &articleElement, int article ) +bool KEduVocKvtml2Writer::writeArticle( QDomElement &articleElement, int language ) { - QDomElement number; - QString def; - QString indef; - - for( int i= KEduVocArticle::Singular; i <= KEduVocArticle::Plural; ++i) + ///@todo only write if not empty + for (int num = KEduVocArticle::Singular; num <= KEduVocArticle::Plural; num++) { - QDomElement definite = m_domDoc.createElement( KVTML_DEFINITE ); - QDomElement indefinite = m_domDoc.createElement( KVTML_INDEFINITE ); + QDomElement numberElement = m_domDoc.createElement( KVTML_GRAMMATICAL_NUMBER[num] ); - switch(i) { - case KEduVocArticle::Singular: - number = m_domDoc.createElement( KVTML_SINGULAR ); - break; - case KEduVocArticle::Plural: - number = m_domDoc.createElement( KVTML_PLURAL); - break; - case KEduVocArticle::Dual: - number = m_domDoc.createElement( KVTML_DUAL ); - break; - } + for (int def = KEduVocArticle::Definite; def <= KEduVocArticle::Indefinite; def++) { + QDomElement defElement = m_domDoc.createElement( KVTML_GRAMMATICAL_DEFINITENESS[def] ); - QString articleString; - articleString = m_doc->identifier(article).article().article( KEduVocArticle::ArticleNumber(i), KEduVocArticle::Definite, KEduVocArticle::Masculine ); - if ( !articleString.isEmpty() ) { - definite.appendChild( newTextElement( KVTML_MALE, articleString ) ); - } - articleString = m_doc->identifier(article).article().article(KEduVocArticle::ArticleNumber(i), KEduVocArticle::Indefinite, KEduVocArticle::Masculine ); - if ( !articleString.isEmpty() ) { - indefinite.appendChild( newTextElement( KVTML_MALE, articleString ) ); - } - - // female - articleString = m_doc->identifier(article).article().article( KEduVocArticle::ArticleNumber(i), KEduVocArticle::Definite, KEduVocArticle::Feminine ); - if ( !articleString.isEmpty() ) { - definite.appendChild( newTextElement( KVTML_FEMALE, articleString ) ); - } - articleString = m_doc->identifier(article).article().article( KEduVocArticle::ArticleNumber(i), KEduVocArticle::Indefinite, KEduVocArticle::Feminine ); - if ( !articleString.isEmpty() ) { - indefinite.appendChild( newTextElement( KVTML_FEMALE, articleString ) ); - } - - // neutral - articleString = m_doc->identifier(article).article().article( KEduVocArticle::ArticleNumber(i), KEduVocArticle::Definite, KEduVocArticle::Neutral ); - if ( !articleString.isEmpty() ) { - definite.appendChild( newTextElement( KVTML_NEUTRAL, articleString ) ); - } - articleString = m_doc->identifier(article).article().article( KEduVocArticle::ArticleNumber(i), KEduVocArticle::Indefinite, KEduVocArticle::Neutral ); - if ( !articleString.isEmpty() ) { - indefinite.appendChild( newTextElement( KVTML_NEUTRAL, articleString ) ); - } - - - if ( definite.hasChildNodes() ) { - number.appendChild( definite ); - } - if ( indefinite.hasChildNodes() ) { - number.appendChild( indefinite ); + for (int gen = KEduVocArticle::Masculine; gen <= KEduVocArticle::Neutral; gen++) + { + QString articleString = m_doc->identifier(language).article().article( KEduVocArticle::ArticleNumber(num), KEduVocArticle::ArticleDefiniteness(def), KEduVocArticle::ArticleGender(gen) ); + if ( !articleString.isEmpty() ) { + defElement.appendChild( newTextElement( KVTML_GRAMMATICAL_GENDER[gen], articleString ) ); + } + } + if ( defElement.hasChildNodes() ) { + numberElement.appendChild( defElement ); + } } - if ( number.hasChildNodes() ) { - articleElement.appendChild( number ); + if ( numberElement.hasChildNodes() ) { + articleElement.appendChild( numberElement ); } } return true; @@ -389,13 +350,6 @@ bool KEduVocKvtml2Writer::writeTranslation( QDomElement &translationElement, KEd } } - // conjugation - foreach ( const QString &tense, translation->conjugationTenses() ) { - QDomElement thisElement = m_domDoc.createElement( KVTML_CONJUGATION ); - writeConjugation( thisElement, translation->conjugation(tense), tense ); - translationElement.appendChild( thisElement ); - } - // comparison if ( !(translation->comparative().isEmpty() || translation->comparative().isEmpty())) { QDomElement comparisonElement = m_domDoc.createElement( KVTML_COMPARISON ); @@ -470,54 +424,9 @@ bool KEduVocKvtml2Writer::writeMultipleChoice( QDomElement &multipleChoiceElemen return true; } -bool KEduVocKvtml2Writer::writeConjugation( QDomElement &conjugationElement, - const KEduVocConjugation &conjugation, const QString &tense ) -{ - // write the tense tag - conjugationElement.appendChild( newTextElement(KVTML_TENSE, tense) ); - - for ( KEduVocConjugation::ConjugationNumber num = KEduVocConjugation::Singular; num < KEduVocConjugation::NumberMAX; num = KEduVocConjugation::ConjugationNumber(num +1) ) { - QString first = conjugation.conjugation( - KEduVocConjugation::First, num ); - QString second = conjugation.conjugation( - KEduVocConjugation::Second, num ); - QString third_male = conjugation.conjugation( - KEduVocConjugation::ThirdMale, num ); - QString third_female = conjugation.conjugation( - KEduVocConjugation::ThirdFemale, num ); - QString third_neutral = conjugation.conjugation( - KEduVocConjugation::ThirdNeutralCommon, num ); - - if ( !first.isEmpty() || !second.isEmpty() || !third_female.isEmpty() || - !third_male.isEmpty() || !third_neutral.isEmpty() ) { - QDomElement number; - switch (num) { - case KEduVocConjugation::Singular: - number = m_domDoc.createElement( KVTML_SINGULAR ); - break; - case KEduVocConjugation::Dual: - number = m_domDoc.createElement( KVTML_DUAL ); - break; - case KEduVocConjugation::Plural: - number = m_domDoc.createElement( KVTML_PLURAL ); - break; - } - - number.appendChild( newTextElement( KVTML_1STPERSON, first ) ); - number.appendChild( newTextElement( KVTML_2NDPERSON, second ) ); - number.appendChild( newTextElement( KVTML_THIRD_MALE, third_male ) ); - number.appendChild( newTextElement( KVTML_THIRD_FEMALE, third_female ) ); - number.appendChild( newTextElement( KVTML_THIRD_NEUTRAL_COMMON, third_neutral ) ); - - conjugationElement.appendChild( number ); - } - } - - return true; -} - QDomElement KEduVocKvtml2Writer::newTextElement( const QString &elementName, const QString &text ) { + kDebug() << "append: " << elementName << text; QDomElement retval = m_domDoc.createElement( elementName ); QDomText textNode = m_domDoc.createTextNode( text ); retval.appendChild( textNode ); @@ -537,47 +446,14 @@ bool KEduVocKvtml2Writer::writePersonalPronoun(QDomElement & pronounElement, con pronounElement.appendChild( m_domDoc.createElement( KVTML_DUAL_EXISTS ) ); } - for ( KEduVocConjugation::ConjugationNumber num = KEduVocConjugation::Singular; num < KEduVocConjugation::NumberMAX; num = KEduVocConjugation::ConjugationNumber(num +1) ) { - QString first = pronoun.personalPronoun( - KEduVocConjugation::First, num ); - QString second = pronoun.personalPronoun( - KEduVocConjugation::Second, num ); - QString third_male = pronoun.personalPronoun( - KEduVocConjugation::ThirdMale, num ); - QString third_female = pronoun.personalPronoun( - KEduVocConjugation::ThirdFemale, num ); - QString third_neutral = pronoun.personalPronoun( - KEduVocConjugation::ThirdNeutralCommon, num ); - - if ( !first.isEmpty() || !second.isEmpty() || !third_female.isEmpty() || - !third_male.isEmpty() || !third_neutral.isEmpty() ) { - QDomElement number; - switch (num) { - case KEduVocConjugation::Singular: - number = m_domDoc.createElement( KVTML_SINGULAR ); - break; - case KEduVocConjugation::Dual: - number = m_domDoc.createElement( KVTML_DUAL ); - break; - case KEduVocConjugation::Plural: - number = m_domDoc.createElement( KVTML_PLURAL ); - break; - } - - number.appendChild( newTextElement( KVTML_1STPERSON, first ) ); - number.appendChild( newTextElement( KVTML_2NDPERSON, second ) ); - number.appendChild( newTextElement( KVTML_THIRD_MALE, third_male ) ); - number.appendChild( newTextElement( KVTML_THIRD_FEMALE, third_female ) ); - number.appendChild( newTextElement( KVTML_THIRD_NEUTRAL_COMMON, third_neutral ) ); + // the actual pronouns + for ( int num = KEduVocConjugation::Singular; num <= KEduVocConjugation::Plural; num++ ) { + QDomElement numberElement = m_domDoc.createElement( KVTML_GRAMMATICAL_NUMBER[num] ); + for ( int person = KEduVocConjugation::First; person <= KEduVocConjugation::ThirdNeutralCommon; person++ ) { - if ( pronoun.maleFemaleDifferent() ) { - number.appendChild( m_domDoc.createElement( KVTML_THIRD_PERSON_MALE_FEMALE_DIFFERENT ) ); - } - if ( pronoun.neutralExists() ) { - number.appendChild( m_domDoc.createElement( KVTML_THIRD_PERSON_NEUTRAL_EXISTS ) ); - } - pronounElement.appendChild( number ); + numberElement.appendChild( newTextElement( KVTML_GRAMMATICAL_PERSON[person], pronoun.personalPronoun(KEduVocConjugation::ConjugationPerson(person), KEduVocConjugation::ConjugationNumber(num))) ); } + pronounElement.appendChild( numberElement ); } return true; } diff --git a/keduvocdocument/keduvockvtml2writer.h b/keduvocdocument/keduvockvtml2writer.h index 75f0113..4c7fe79 100644 --- a/keduvocdocument/keduvockvtml2writer.h +++ b/keduvocdocument/keduvockvtml2writer.h @@ -58,14 +58,6 @@ public: */ bool writeArticle( QDomElement &articleElement, int article ); - /** write conjugation - * @param conjugationElement QDomElement conjugation or personalpronouns to write to - * @param conjugation object to write - * @param type conjugation type - */ - bool writeConjugation( QDomElement &conjugationElement, const KEduVocConjugation &conjugation, - const QString &tense ); - bool writePersonalPronoun( QDomElement &pronounElement, const KEduVocPersonalPronoun &pronoun); /** write types * @param typesElement QDomElement types to write to diff --git a/keduvocdocument/keduvocpersonalpronoun.cpp b/keduvocdocument/keduvocpersonalpronoun.cpp index c167a60..aa66ab6 100644 --- a/keduvocdocument/keduvocpersonalpronoun.cpp +++ b/keduvocdocument/keduvocpersonalpronoun.cpp @@ -92,7 +92,7 @@ void KEduVocPersonalPronoun::setPersonalPronoun(const QString & personalpronoun, int KEduVocPersonalPronoun::indexOf(KEduVocConjugation::ConjugationPerson person, KEduVocConjugation::ConjugationNumber number) const { - return person + KEduVocConjugation::PersonMAX * number; + return person + (KEduVocConjugation::ThirdNeutralCommon+1) * number; } bool KEduVocPersonalPronoun::maleFemaleDifferent() const diff --git a/keduvocdocument/keduvoctext.cpp b/keduvocdocument/keduvoctext.cpp index 1c60a1c..02403c0 100644 --- a/keduvocdocument/keduvoctext.cpp +++ b/keduvocdocument/keduvoctext.cpp @@ -223,3 +223,8 @@ void KEduVocText::fromKVTML2(QDomElement & parent) } } } + +bool KEduVocText::isEmpty() +{ + return d->m_text.isEmpty(); +} diff --git a/keduvocdocument/keduvoctext.h b/keduvocdocument/keduvoctext.h index 5260a33..1d196c2 100644 --- a/keduvocdocument/keduvoctext.h +++ b/keduvocdocument/keduvoctext.h @@ -153,6 +153,12 @@ public: */ void setPracticeDate( const QDateTime & date ); + /** + * If the string inside is empty this returns true. + * @return + */ + bool isEmpty(); + void fromKVTML2(QDomElement& parent); void toKVTML2(QDomElement& parent); diff --git a/keduvocdocument/keduvoctranslation.cpp b/keduvocdocument/keduvoctranslation.cpp index 7165561..12bf5aa 100644 --- a/keduvocdocument/keduvoctranslation.cpp +++ b/keduvocdocument/keduvoctranslation.cpp @@ -360,11 +360,23 @@ void KEduVocTranslation::setDeclension(KEduVocDeclension * declension) void KEduVocTranslation::toKVTML2(QDomElement & parent) { + // text and grade KEduVocText::toKVTML2(parent); + + // declension if (d->m_declension) { d->m_declension->toKVTML2(parent); } + // conjugation + QDomElement conjugationElement = parent.ownerDocument().createElement( KVTML_CONJUGATION ); + foreach ( const QString &tense, conjugationTenses() ) { + conjugation(tense).toKVTML2(conjugationElement, tense); + } + if (conjugationElement.hasChildNodes()) { + parent.appendChild( conjugationElement ); + } + // KEduVocKvtml2Writer::appendTextElement( parent, KVTML_COMMENT, comment() ); @@ -406,5 +418,17 @@ void KEduVocTranslation::fromKVTML2(QDomElement & parent) // setParaphrase( parent.firstChildElement( KVTML_PARAPHRASE ).text() ); + + // conjugations + QDomElement conjugationElement = parent.firstChildElement( KVTML_CONJUGATION ); + while ( !conjugationElement.isNull() ) { + QDomElement tenseElement = conjugationElement.firstChildElement( KVTML_TENSE ); + QString tense = tenseElement.text(); + KEduVocConjugation *conjugation = KEduVocConjugation::fromKVTML2(conjugationElement); + setConjugation(tense, *conjugation); + delete conjugation; + conjugationElement = conjugationElement.nextSiblingElement( KVTML_CONJUGATION ); + } + } diff --git a/keduvocdocument/kvtml2defs.h b/keduvocdocument/kvtml2defs.h index 97c232a..4a23b93 100644 --- a/keduvocdocument/kvtml2defs.h +++ b/keduvocdocument/kvtml2defs.h @@ -39,11 +39,13 @@ // articles #define KVTML_ARTICLE "article" -#define KVTML_DEFINITE "definite" -#define KVTML_INDEFINITE "indefinite" -// declension +// conjugation, declension and personal pronouns +#define KVTML_CONJUGATION "conjugation" +#define KVTML_CONJUGATIONTYPE "conjugationtype" +#define KVTML_PERSONALPRONOUNS "personalpronouns" #define KVTML_DECLENSION "declension" + static const QString KVTML_DECLENSION_CASE[] = { "nominative", "genitive", @@ -51,30 +53,34 @@ static const QString KVTML_DECLENSION_CASE[] = { "accusative", "ablative", "locative", - "vocative" }; + "vocative" +}; static const QString KVTML_GRAMMATICAL_NUMBER[] = { "singular", - "dual", - "plural" }; - -// conjugation and personal pronouns -#define KVTML_CONJUGATION "conjugation" -#define KVTML_CONJUGATIONTYPE "conjugationtype" -#define KVTML_PERSONALPRONOUNS "personalpronouns" + "dual", // dual is the case where there's a special form for exactly two + "plural" +}; + +static const QString KVTML_GRAMMATICAL_GENDER[] = { + "male", + "female", + "neutral" +}; + +static const QString KVTML_GRAMMATICAL_PERSON[] = { + "firstperson", + "secondperson", + "thirdpersonmale", + "thirdpersonfemale", + "thirdpersonneutralcommon" +}; + +static const QString KVTML_GRAMMATICAL_DEFINITENESS[] = { + "definite", + "indefinite" +}; -#define KVTML_MALE "male" -#define KVTML_FEMALE "female" -#define KVTML_NEUTRAL "neutral" -#define KVTML_SINGULAR "singular" -// dual is the case where there's a special form for exactly two -#define KVTML_DUAL "dual" -#define KVTML_PLURAL "plural" -#define KVTML_1STPERSON "firstperson" -#define KVTML_2NDPERSON "secondperson" -#define KVTML_THIRD_MALE "thirdpersonmale" -#define KVTML_THIRD_FEMALE "thirdpersonfemale" -#define KVTML_THIRD_NEUTRAL_COMMON "thirdpersonneutralcommon" // for the personal pronuns: // if this tag exists, in a conjugation male/female are different diff --git a/keduvocdocument/tests/keduvocdocumentvalidatortest.cpp b/keduvocdocument/tests/keduvocdocumentvalidatortest.cpp index 303ea3a..5080999 100644 --- a/keduvocdocument/tests/keduvocdocumentvalidatortest.cpp +++ b/keduvocdocument/tests/keduvocdocumentvalidatortest.cpp @@ -32,6 +32,7 @@ #include #include +#include class KEduVocDocumentValidatorTest : public QObject @@ -43,6 +44,7 @@ private slots: void testLessons(); void testWordTypes(); void testTranslations(); + void testConjugations(); void testDeclensions(); }; @@ -186,6 +188,24 @@ void KEduVocDocumentValidatorTest::testDeclensions() QCOMPARE(translation.declension(), declension); } +void KEduVocDocumentValidatorTest::testConjugations() +{ + KEduVocConjugation conjugation; + conjugation.setConjugation(KEduVocText("first-singular"), KEduVocConjugation::First, KEduVocConjugation::Singular); + QCOMPARE(conjugation.conjugation(KEduVocConjugation::First, KEduVocConjugation::Singular).text(), QString("first-singular")); + + QDomDocument doc = QDomDocument("test doc"); + QDomElement root = doc.createElement( "kvtml" ); + doc.appendChild(root); + conjugation.toKVTML2(root, "tense"); + + qDebug() << root.text(); + + KEduVocConjugation *con2 = KEduVocConjugation::fromKVTML2(root); + + QCOMPARE(conjugation.conjugation(KEduVocConjugation::First, KEduVocConjugation::Singular).text(), con2->conjugation(KEduVocConjugation::First, KEduVocConjugation::Singular).text()); + delete con2; +} QTEST_KDEMAIN_CORE( KEduVocDocumentValidatorTest ) -- 2.47.3