10#include "keduvockvtml2reader.h"
12#include <KLocalizedString>
18#include "keduvoccommon_p.h"
19#include "keduvockvtmlreader.h"
20#include "keduvocleitnerbox.h"
21#include "keduvoclesson.h"
22#include "keduvocwordtype.h"
23#include "kvtml2defs.h"
55 qDebug() <<
"Unable to load document.Parse error in line " << parseResult.errorLine <<
", col " << parseResult.errorColumn <<
": "
56 << qPrintable(parseResult.errorMessage);
61 if (domElementKvtml.
tagName() != KVTML_TAG) {
62 m_errorMessage =
i18n(
"This is not a KDE Vocabulary document.");
87 if (!readInformation(info))
91 bool result = readGroups(domElementKvtml);
96bool KEduVocKvtml2Reader::readInformation(
QDomElement &informationElement)
100 if (!currentElement.
isNull()) {
111 if (!currentElement.
isNull()) {
112 m_doc->setTitle(currentElement.
text());
117 if (!currentElement.
isNull()) {
118 m_doc->setAuthor(currentElement.
text());
122 if (!currentElement.
isNull()) {
123 m_doc->setAuthorContact(currentElement.
text());
128 if (!currentElement.
isNull()) {
129 m_doc->setLicense(currentElement.
text());
134 if (!currentElement.
isNull()) {
135 m_doc->setDocumentComment(currentElement.
text());
140 if (!currentElement.
isNull()) {
141 m_doc->setCategory(currentElement.
text());
147bool KEduVocKvtml2Reader::readGroups(
QDomElement &domElementParent)
151 QDomElement groupElement = domElementParent.
firstChildElement(KVTML_IDENTIFIERS);
153 QDomElement currentElement;
157 QStringList tensesCompability;
159 if (!groupElement.
isNull()) {
160 tensesCompability = readTenses(groupElement);
164 if (!groupElement.
isNull()) {
166 if (entryList.
length() <= 0) {
167 m_errorMessage =
i18n(
"missing identifier elements from identifiers tag");
171 for (
int i = 0; i < entryList.
count(); ++i) {
173 if (currentElement.
parentNode() == groupElement) {
174 result = readIdentifier(currentElement);
178 if (!tensesCompability.
isEmpty()) {
179 m_doc->identifier(i).setTenseList(tensesCompability);
186 if (!groupElement.
isNull()) {
188 for (
int i = 0; i < entryList.
count(); ++i) {
190 if (currentElement.
parentNode() == groupElement) {
191 result = readEntry(currentElement);
198 readSynonymsAntonymsFalseFriends(domElementParent);
201 if (!groupElement.
isNull()) {
202 readChildWordTypes(m_doc->wordTypeContainer(), groupElement);
206 if (!groupElement.
isNull()) {
207 readLeitner(m_doc->leitnerContainer(), groupElement);
211 if (!groupElement.
isNull()) {
212 readChildLessons(m_doc->lesson(), groupElement);
216 KEduVocLesson *defaultLesson =
new KEduVocLesson(
i18n(
"Default Lesson"), m_doc->lesson());
219 foreach (KEduVocExpression *entry, m_allEntries) {
226 m_doc->lesson()->appendChildContainer(defaultLesson);
228 delete defaultLesson;
234bool KEduVocKvtml2Reader::readIdentifier(
QDomElement &identifierElement)
239 m_errorMessage =
i18n(
"identifier missing id");
244 for (
int i = m_doc->identifierCount(); i <=
id; i++) {
245 m_doc->appendIdentifier(KEduVocIdentifier());
250 m_doc->identifier(
id).setName(currentElement.
text());
253 m_doc->identifier(
id).setLocale(currentElement.
text());
256 if (!currentElement.
isNull()) {
262 if (!currentElement.
isNull()) {
263 readArticle(currentElement,
id);
267 if (!currentElement.
isNull()) {
268 KEduVocPersonalPronoun personalPronoun;
269 readPersonalPronoun(currentElement, personalPronoun);
270 m_doc->identifier(
id).setPersonalPronouns(personalPronoun);
273 QStringList tenses = readTenses(identifierElement);
275 m_doc->identifier(
id).setTenseList(tenses);
280bool KEduVocKvtml2Reader::readEntry(
QDomElement &entryElement)
282 QDomElement currentElement;
288 m_errorMessage =
i18n(
"entry missing id");
292 KEduVocExpression *expr =
new KEduVocExpression;
296 if (!currentElement.
isNull()) {
298 if (currentElement.
text() == KVTML_TRUE) {
306 QDomNodeList translationList = entryElement.
elementsByTagName(KVTML_TRANSLATION);
308 for (
int i = 0; i < translationList.
count(); ++i) {
310 if (currentElement.
parentNode() == entryElement) {
311 result = readTranslation(currentElement, expr, i);
317 if (expr->translationIndices().
size() == 0) {
318 qDebug() <<
"Found entry with no words in it." << id;
326 m_allEntries[id] = expr;
334 QDomElement currentElement;
338 if (!currentElement.
isNull()) {
340 article.fromKVTML2(currentElement);
346 if (!currentElement.
isNull()) {
347 readComparison(currentElement, expr->
translation(index));
352 if (!currentElement.
isNull()) {
353 readMultipleChoice(currentElement, expr->
translation(index));
358 if (!currentElement.
isNull()) {
359 QUrl imageUrl(currentElement.
text());
368 if (!currentElement.
isNull()) {
369 QUrl soundUrl(currentElement.
text());
382 while (!currentElement.
isNull()) {
383 readLesson(parentLesson, currentElement);
393 KEduVocLesson *lesson =
new KEduVocLesson(currentElement.
text(), parentLesson);
394 parentLesson->appendChildContainer(lesson);
396 readChildLessons(lesson, lessonElement);
400 lesson->setInPractice(currentElement.
text() == KVTML_TRUE);
404 while (!currentElement.
isNull()) {
408 if (m_allEntries[entryId]) {
417bool KEduVocKvtml2Reader::readSynonymsAntonymsFalseFriends(
QDomElement &rootElement)
419 QDomElement pairElement;
420 for (
int type = KEduVocTranslation::Synonym;
type <= KEduVocTranslation::FalseFriend;
type++) {
422 case KEduVocTranslation::Synonym:
425 case KEduVocTranslation::Antonym:
428 case KEduVocTranslation::FalseFriend:
434 while (!pairElement.
isNull()) {
439 QDomElement translationElement = entryElement.
firstChildElement(KVTML_TRANSLATION);
440 int firstTranslationId = translationElement.
attribute(KVTML_ID).
toInt();
446 int secondTranslationId = translationElement.
attribute(KVTML_ID).
toInt();
449 KEduVocTranslation *first = m_allEntries[firstEntryId]->translation(firstTranslationId);
450 KEduVocTranslation *second = m_allEntries[secondEntryId]->translation(secondTranslationId);
453 case KEduVocTranslation::Synonym:
457 case KEduVocTranslation::Antonym:
461 case KEduVocTranslation::FalseFriend:
472bool KEduVocKvtml2Reader::readArticle(
QDomElement &articleElement,
int identifierNum)
492 QMap<int, KEduVocWordFlag::Flags> numbers;
493 numbers[0] = KEduVocWordFlag::Singular;
494 numbers[1] = KEduVocWordFlag::Dual;
495 numbers[2] = KEduVocWordFlag::Plural;
496 QMap<int, KEduVocWordFlag::Flags> genders;
497 genders[0] = KEduVocWordFlag::Masculine;
498 genders[1] = KEduVocWordFlag::Feminine;
499 genders[2] = KEduVocWordFlag::Neuter;
500 QMap<int, KEduVocWordFlag::Flags> defs;
501 defs[0] = KEduVocWordFlag::Definite;
502 defs[1] = KEduVocWordFlag::Indefinite;
504 for (
int num = 0; num <= 2; ++num) {
505 QDomElement numberElement = articleElement.
firstChildElement(KVTML_GRAMMATICAL_NUMBER[num]);
506 if (!numberElement.
isNull()) {
508 for (
int def = 0; def <= 1; ++def) {
509 QDomElement defElement = numberElement.
firstChildElement(KVTML_GRAMMATICAL_DEFINITENESS[def]);
510 if (!defElement.
isNull()) {
512 for (
int gen = 0; gen <= 2; ++gen) {
513 QDomElement genderElement = defElement.
firstChildElement(KVTML_GRAMMATICAL_GENDER[gen]);
514 if (!genderElement.
isNull()) {
515 m_doc->identifier(identifierNum).article().setArticle(genderElement.
text(), numbers[num] | defs[def] | genders[gen]);
529 while (!currentElement.
isNull()) {
530 readWordType(parentContainer, currentElement);
538 QDomElement leitnerElement = leitnerParentElement.
firstChildElement(KVTML_CONTAINER);
539 while (!leitnerElement.
isNull()) {
542 KEduVocLeitnerBox *leitner =
new KEduVocLeitnerBox(name, parentContainer);
543 parentContainer->appendChildContainer(leitner);
548 while (!entryElement.
isNull()) {
551 QDomElement translationElement = entryElement.
firstChildElement(KVTML_TRANSLATION);
552 while (!translationElement.
isNull()) {
554 int translationId = translationElement.
attribute(KVTML_ID).
toInt();
555 m_allEntries.value(entryId)->translation(translationId)->setLeitnerBox(leitner);
570 KEduVocWordType *wordTypeContainer =
new KEduVocWordType(typeName, parentContainer);
571 parentContainer->appendChildContainer(wordTypeContainer);
576 if (specialType == KVTML_SPECIALWORDTYPE_NOUN) {
577 wordTypeContainer->
setWordType(KEduVocWordFlag::Noun);
579 if (specialType == KVTML_SPECIALWORDTYPE_VERB) {
580 wordTypeContainer->
setWordType(KEduVocWordFlag::Verb);
582 if (specialType == KVTML_SPECIALWORDTYPE_ADVERB) {
583 wordTypeContainer->
setWordType(KEduVocWordFlag::Adverb);
585 if (specialType == KVTML_SPECIALWORDTYPE_ADJECTIVE) {
586 wordTypeContainer->
setWordType(KEduVocWordFlag::Adjective);
588 if (specialType == KVTML_SPECIALWORDTYPE_NOUN_MALE) {
589 wordTypeContainer->
setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Masculine);
591 if (specialType == KVTML_SPECIALWORDTYPE_NOUN_FEMALE) {
592 wordTypeContainer->
setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Feminine);
594 if (specialType == KVTML_SPECIALWORDTYPE_NOUN_NEUTRAL) {
595 wordTypeContainer->
setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Neuter);
597 if (specialType == KVTML_SPECIALWORDTYPE_CONJUNCTION) {
598 wordTypeContainer->
setWordType(KEduVocWordFlag::Conjunction);
604 while (!entryElement.
isNull()) {
607 QDomElement translationElement = entryElement.
firstChildElement(KVTML_TRANSLATION);
608 while (!translationElement.
isNull()) {
610 int translationId = translationElement.
attribute(KVTML_ID).
toInt();
611 m_allEntries.value(entryId)->translation(translationId)->setWordType(wordTypeContainer);
617 readChildWordTypes(wordTypeContainer, typeElement);
627 for (
int i = 0; i < tenseNodes.
count(); ++i) {
629 if (currentElement.
parentNode() == tensesElement) {
645 QDomElement currentElement;
648 if (!currentElement.
isNull()) {
649 KEduVocText comparative;
650 comparative.fromKVTML2(currentElement);
656 translation->setComparativeForm(comparative);
660 if (!currentElement.
isNull()) {
661 KEduVocText superlative;
662 superlative.fromKVTML2(currentElement);
668 translation->setSuperlativeForm(superlative);
684 QDomElement currentElement;
685 QDomNodeList choiceNodes = multipleChoiceElement.
elementsByTagName(KVTML_CHOICE);
686 for (
int i = 0; i < choiceNodes.
count(); ++i) {
688 if (currentElement.
parentNode() == multipleChoiceElement) {
699 pronoun.setMaleFemaleDifferent(!pronounElement.
firstChildElement(KVTML_THIRD_PERSON_MALE_FEMALE_DIFFERENT).
isNull());
703 QDomElement personElement = pronounElement.
firstChildElement(KVTML_GRAMMATICAL_NUMBER[0]);
704 if (!personElement.
isNull()) {
705 readPersonalPronounChild(personElement, pronoun, KEduVocWordFlag::Singular);
709 if (!personElement.
isNull()) {
710 readPersonalPronounChild(personElement, pronoun, KEduVocWordFlag::Dual);
714 if (!personElement.
isNull()) {
715 readPersonalPronounChild(personElement, pronoun, KEduVocWordFlag::Plural);
722 QMap<int, KEduVocWordFlag::Flags> persons;
723 persons[0] = KEduVocWordFlag::First;
724 persons[1] = KEduVocWordFlag::Second;
725 persons[2] = (KEduVocWordFlag::Flags)((
int)KEduVocWordFlag::Third | (
int)KEduVocWordFlag::Masculine);
726 persons[3] = (KEduVocWordFlag::Flags)((
int)KEduVocWordFlag::Third | (
int)KEduVocWordFlag::Feminine);
727 persons[4] = (KEduVocWordFlag::Flags)((
int)KEduVocWordFlag::Third | (
int)KEduVocWordFlag::Neuter);
729 for (
int person = 0; person < 5; person++) {
730 QDomElement currentElement = personElement.
firstChildElement(KVTML_GRAMMATICAL_PERSON[person]);
731 pronoun.setPersonalPronoun(currentElement.
text(), persons[person] | number);
737#include "moc_keduvockvtml2reader.cpp"
The primary entry point to the hierarchy of objects describing vocabularies.
void setGenerator(const QString &generator)
Sets the generator of the file.
ErrorCode
the return code when opening/saving
@ InvalidXml
malformed xml or bad file formatting
@ FileTypeUnknown
unknown file type
@ FileReaderFailed
file reader failed
FileType
known vocabulary file types
QString generator() const
void setVersion(const QString &ver)
Sets version of the loaded file.
This class contains one vocabulary expression as an original with one or more translations.
void setTranslation(int index, const QString &expression)
Add a translation to this expression.
KEduVocLesson * lesson() const
return the lesson
void setActive(bool flag=true)
set entry active (enabled for queries)
KEduVocTranslation * translation(int index)
Get a pointer to the translation.
bool isParsable() override
Can this reader parse this file.
KEduVocDocument::ErrorCode read(KEduVocDocument &doc) override
Parse file and write into doc.
KEduVocDocument::FileType fileTypeHandled() override
returns the KEduVocDocument::FileType that this reader handles
KEduVocKvtml2Reader(QIODevice &file)
constructor
virtual QString errorMessage() const
an error message.
virtual KEduVocDocument::ErrorCode read(KEduVocDocument &doc)
Parse file and write into doc.
Leitner Boxes are an alternative grading system.
class to store information about a lesson
int entryCount(EnumEntriesRecursive recursive=NotRecursive) override
get the number of entries in the lesson
void appendEntry(KEduVocExpression *entry)
append an entry to the lesson
The conjugation of a verb.
QString text() const
The translation as string (the word itself)
void setText(const QString &expr)
Sets the translation.
void setSoundUrl(const QUrl &url)
Set the sound url for this translation.
QStringList getMultipleChoice() const
Returns multiple choice if available.
void addAntonym(KEduVocTranslation *antonym)
Add a antonym.
void addFalseFriend(KEduVocTranslation *falseFriend)
Add a false friend.
void setMultipleChoice(const QStringList &choices)
Sets multiple choice.
void addSynonym(KEduVocTranslation *synonym)
Add a synonym.
void fromKVTML2(QDomElement &parent)
void setImageUrl(const QUrl &url)
Set the image url for this translation.
class to store translation word types
void setWordType(KEduVocWordFlags flags)
assignment operator
QString i18n(const char *text, const TYPE &arg...)
Type type(const QSqlDatabase &db)
QString typeName(const QJsonObject &obj)
QString name(const QVariant &location)
bool isRelativePath(const QString &path)
QDomElement documentElement() const const
ParseResult setContent(QAnyStringView text, ParseOptions options)
QString attribute(const QString &name, const QString &defValue) const const
QDomNodeList elementsByTagName(const QString &tagname) const const
QString tagName() const const
QString text() const const
QDomElement firstChildElement(const QString &tagName, const QString &namespaceURI) const const
bool isNull() const const
QDomElement nextSiblingElement(const QString &tagName, const QString &namespaceURI) const const
QDomNode parentNode() const const
QDomElement toElement() const const
QDomNode item(int index) const const
void append(QList< T > &&value)
bool isEmpty() const const
qsizetype size() const const
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
qsizetype lastIndexOf(QChar ch, Qt::CaseSensitivity cs) const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
float toFloat(bool *ok) const const
int toInt(bool *ok, int base) const const
QString readLine(qint64 maxlen)