File indexing completed on 2024-03-24 03:51:03
0001 /* 0002 * read a KEduVocDocument from a KVTML file 0003 * SPDX-FileCopyrightText: 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de> 0004 * SPDX-FileCopyrightText: 2005 Eric Pignet <eric at erixpage.com> 0005 * SPDX-FileCopyrightText: 2007 Peter Hedlund <peter.hedlund@kdemail.net> 0006 * SPDX-FileCopyrightText: 2007-2010 Frederik Gladhorn <gladhorn@kde.org> 0007 * SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include "keduvockvtml2reader.h" 0011 0012 #include <KLocalizedString> 0013 #include <QDir> 0014 #include <QIODevice> 0015 #include <QList> 0016 #include <QTextStream> 0017 0018 #include "keduvoccommon_p.h" 0019 #include "keduvockvtmlreader.h" 0020 #include "keduvocleitnerbox.h" 0021 #include "keduvoclesson.h" 0022 #include "keduvocwordtype.h" 0023 #include "kvtml2defs.h" 0024 0025 #include <QDebug> 0026 0027 KEduVocKvtml2Reader::KEduVocKvtml2Reader(QIODevice &file) 0028 : m_inputFile(&file) 0029 { 0030 } 0031 0032 bool KEduVocKvtml2Reader::isParsable() 0033 { 0034 QTextStream ts(m_inputFile); 0035 QString line1(ts.readLine()); 0036 QString line2(ts.readLine()); 0037 0038 m_inputFile->seek(0); 0039 return ((line1.startsWith(QLatin1String("<?xml"))) && (line2.indexOf(KVTML_TAG, 0) > 0)); 0040 } 0041 0042 KEduVocDocument::FileType KEduVocKvtml2Reader::fileTypeHandled() 0043 { 0044 return KEduVocDocument::Kvtml; 0045 } 0046 0047 KEduVocDocument::ErrorCode KEduVocKvtml2Reader::read(KEduVocDocument &doc) 0048 { 0049 m_doc = &doc; 0050 0051 QDomDocument domDoc(QStringLiteral("KEduVocDocument")); 0052 0053 if (!domDoc.setContent(m_inputFile, &m_errorMessage)) 0054 return KEduVocDocument::InvalidXml; 0055 0056 QDomElement domElementKvtml = domDoc.documentElement(); 0057 if (domElementKvtml.tagName() != KVTML_TAG) { 0058 m_errorMessage = i18n("This is not a KDE Vocabulary document."); 0059 return KEduVocDocument::FileTypeUnknown; 0060 } 0061 0062 if (domElementKvtml.attribute(KVTML_VERSION).toFloat() < 2.0) { 0063 // read the file with the old format 0064 0065 // first reset the file to the beginning 0066 m_inputFile->seek(0); 0067 KEduVocKvtmlReader oldFormat(*m_inputFile); 0068 0069 // get the return value 0070 KEduVocDocument::ErrorCode retval = oldFormat.read(doc); 0071 0072 // pass the errormessage up 0073 m_errorMessage = oldFormat.errorMessage(); 0074 return retval; 0075 } 0076 0077 //------------------------------------------------------------------------- 0078 // Information 0079 //------------------------------------------------------------------------- 0080 0081 QDomElement info = domElementKvtml.firstChildElement(KVTML_INFORMATION); 0082 if (!info.isNull()) { 0083 if (!readInformation(info)) 0084 return KEduVocDocument::FileReaderFailed; 0085 } 0086 0087 bool result = readGroups(domElementKvtml); // read sub-groups 0088 0089 return result ? KEduVocDocument::NoError : KEduVocDocument::FileReaderFailed; 0090 } 0091 0092 bool KEduVocKvtml2Reader::readInformation(QDomElement &informationElement) 0093 { 0094 // read the generator 0095 QDomElement currentElement = informationElement.firstChildElement(KVTML_GENERATOR); 0096 if (!currentElement.isNull()) { 0097 m_doc->setGenerator(currentElement.text()); 0098 // add the version if it's there 0099 int pos = m_doc->generator().lastIndexOf(KVD_VERS_PREFIX); 0100 if (pos >= 0) { 0101 m_doc->setVersion(m_doc->generator().remove(0, pos + 2)); 0102 } 0103 } 0104 0105 // read the title 0106 currentElement = informationElement.firstChildElement(KVTML_TITLE); 0107 if (!currentElement.isNull()) { 0108 m_doc->setTitle(currentElement.text()); 0109 } 0110 0111 // read the author 0112 currentElement = informationElement.firstChildElement(KVTML_AUTHOR); 0113 if (!currentElement.isNull()) { 0114 m_doc->setAuthor(currentElement.text()); 0115 } 0116 0117 currentElement = informationElement.firstChildElement(KVTML_AUTHORCONTACT); 0118 if (!currentElement.isNull()) { 0119 m_doc->setAuthorContact(currentElement.text()); 0120 } 0121 0122 // read the license 0123 currentElement = informationElement.firstChildElement(KVTML_LICENSE); 0124 if (!currentElement.isNull()) { 0125 m_doc->setLicense(currentElement.text()); 0126 } 0127 0128 // read the comment 0129 currentElement = informationElement.firstChildElement(KVTML_COMMENT); 0130 if (!currentElement.isNull()) { 0131 m_doc->setDocumentComment(currentElement.text()); 0132 } 0133 0134 // read the category 0135 currentElement = informationElement.firstChildElement(KVTML_CATEGORY); 0136 if (!currentElement.isNull()) { 0137 m_doc->setCategory(currentElement.text()); 0138 } 0139 0140 return true; 0141 } 0142 0143 bool KEduVocKvtml2Reader::readGroups(QDomElement &domElementParent) 0144 { 0145 bool result = false; 0146 0147 QDomElement groupElement = domElementParent.firstChildElement(KVTML_IDENTIFIERS); 0148 0149 QDomElement currentElement; 0150 0151 // ensure backwards compatibility - in kde 4.1 and earlier tenses were direct properties of the document class. 0152 // now they are moved into the individual identifiers 0153 QStringList tensesCompability; 0154 groupElement = groupElement.firstChildElement(KVTML_TENSES); 0155 if (!groupElement.isNull()) { 0156 tensesCompability = readTenses(groupElement); 0157 } 0158 0159 groupElement = domElementParent.firstChildElement(KVTML_IDENTIFIERS); 0160 if (!groupElement.isNull()) { 0161 QDomNodeList entryList = groupElement.elementsByTagName(KVTML_IDENTIFIER); 0162 if (entryList.length() <= 0) { 0163 m_errorMessage = i18n("missing identifier elements from identifiers tag"); 0164 return false; 0165 } 0166 0167 for (int i = 0; i < entryList.count(); ++i) { 0168 currentElement = entryList.item(i).toElement(); 0169 if (currentElement.parentNode() == groupElement) { 0170 result = readIdentifier(currentElement); 0171 if (!result) { 0172 return false; 0173 } 0174 if (!tensesCompability.isEmpty()) { 0175 m_doc->identifier(i).setTenseList(tensesCompability); 0176 } 0177 } 0178 } 0179 } 0180 0181 groupElement = domElementParent.firstChildElement(KVTML_ENTRIES); 0182 if (!groupElement.isNull()) { 0183 QDomNodeList entryList = groupElement.elementsByTagName(KVTML_ENTRY); 0184 for (int i = 0; i < entryList.count(); ++i) { 0185 currentElement = entryList.item(i).toElement(); 0186 if (currentElement.parentNode() == groupElement) { 0187 result = readEntry(currentElement); 0188 if (!result) 0189 return false; 0190 } 0191 } 0192 } 0193 0194 readSynonymsAntonymsFalseFriends(domElementParent); 0195 0196 groupElement = domElementParent.firstChildElement(KVTML_WORDTYPES); 0197 if (!groupElement.isNull()) { 0198 readChildWordTypes(m_doc->wordTypeContainer(), groupElement); 0199 } 0200 0201 groupElement = domElementParent.firstChildElement(KVTML_LEITNERBOXES); 0202 if (!groupElement.isNull()) { 0203 readLeitner(m_doc->leitnerContainer(), groupElement); 0204 } 0205 0206 groupElement = domElementParent.firstChildElement(KVTML_LESSONS); 0207 if (!groupElement.isNull()) { 0208 readChildLessons(m_doc->lesson(), groupElement); 0209 } 0210 0211 // Additional cleanup: Put orphaned entries without a lesson into a default lesson. 0212 KEduVocLesson *defaultLesson = new KEduVocLesson(i18n("Default Lesson"), m_doc->lesson()); 0213 0214 // now make sure we don't have any orphan entries 0215 foreach (KEduVocExpression *entry, m_allEntries) { 0216 if (!entry->lesson()) { 0217 defaultLesson->appendEntry(entry); 0218 } 0219 } 0220 0221 if (defaultLesson->entryCount() > 0) { 0222 m_doc->lesson()->appendChildContainer(defaultLesson); 0223 } else { 0224 delete defaultLesson; 0225 } 0226 0227 return true; 0228 } 0229 0230 bool KEduVocKvtml2Reader::readIdentifier(QDomElement &identifierElement) 0231 { 0232 bool result = true; 0233 int id = identifierElement.attribute(KVTML_ID).toInt(&result); 0234 if (!result) { 0235 m_errorMessage = i18n("identifier missing id"); 0236 return false; 0237 } 0238 0239 // generate empty identifiers in the doc 0240 for (int i = m_doc->identifierCount(); i <= id; i++) { 0241 m_doc->appendIdentifier(KEduVocIdentifier()); 0242 } 0243 0244 // the first element, create the identifier, even if empty 0245 QDomElement currentElement = identifierElement.firstChildElement(KVTML_NAME); 0246 m_doc->identifier(id).setName(currentElement.text()); 0247 0248 currentElement = identifierElement.firstChildElement(KVTML_LOCALE); 0249 m_doc->identifier(id).setLocale(currentElement.text()); 0250 0251 currentElement = identifierElement.firstChildElement(KVTML_IDENTIFIERTYPE); 0252 if (!currentElement.isNull()) { 0253 // TODO: do something with the type 0254 } 0255 0256 // read sub-parts 0257 currentElement = identifierElement.firstChildElement(KVTML_ARTICLE); 0258 if (!currentElement.isNull()) { 0259 readArticle(currentElement, id); 0260 } 0261 0262 currentElement = identifierElement.firstChildElement(KVTML_PERSONALPRONOUNS); 0263 if (!currentElement.isNull()) { 0264 KEduVocPersonalPronoun personalPronoun; 0265 readPersonalPronoun(currentElement, personalPronoun); 0266 m_doc->identifier(id).setPersonalPronouns(personalPronoun); 0267 } 0268 0269 QStringList tenses = readTenses(identifierElement); 0270 0271 m_doc->identifier(id).setTenseList(tenses); 0272 0273 return result; 0274 } 0275 0276 bool KEduVocKvtml2Reader::readEntry(QDomElement &entryElement) 0277 { 0278 QDomElement currentElement; 0279 bool result = true; 0280 0281 // get entry id 0282 int id = entryElement.attribute(KVTML_ID).toInt(&result); 0283 if (!result) { 0284 m_errorMessage = i18n("entry missing id"); 0285 return false; 0286 } 0287 0288 KEduVocExpression *expr = new KEduVocExpression; 0289 0290 // read info tags: inactive, inquery, and sizehint 0291 currentElement = entryElement.firstChildElement(KVTML_DEACTIVATED); 0292 if (!currentElement.isNull()) { 0293 // set the active state of the expression 0294 if (currentElement.text() == KVTML_TRUE) { 0295 expr->setActive(false); 0296 } else { 0297 expr->setActive(true); 0298 } 0299 } 0300 0301 // read translation children 0302 QDomNodeList translationList = entryElement.elementsByTagName(KVTML_TRANSLATION); 0303 0304 for (int i = 0; i < translationList.count(); ++i) { 0305 currentElement = translationList.item(i).toElement(); 0306 if (currentElement.parentNode() == entryElement) { 0307 result = readTranslation(currentElement, expr, i); 0308 if (!result) 0309 return false; 0310 } 0311 } 0312 0313 if (expr->translationIndices().size() == 0) { 0314 qDebug() << "Found entry with no words in it." << id; 0315 expr->setTranslation(0, QString()); 0316 } 0317 0318 Q_ASSERT(expr); 0319 0320 // TODO: probably should insert at id position with a check to see if it exists 0321 // may be useful for detecting corrupt documents 0322 m_allEntries[id] = expr; 0323 return result; 0324 } 0325 0326 bool KEduVocKvtml2Reader::readTranslation(QDomElement &translationElement, KEduVocExpression *expr, int index) 0327 { 0328 // read the text, grade, declension and conjugation 0329 expr->translation(index)->fromKVTML2(translationElement); 0330 QDomElement currentElement; 0331 0332 // article grade 0333 currentElement = translationElement.firstChildElement(KVTML_ARTICLE); 0334 if (!currentElement.isNull()) { 0335 KEduVocText article; 0336 article.fromKVTML2(currentElement); 0337 expr->translation(index)->setArticle(article); 0338 } 0339 0340 // comparisons 0341 currentElement = translationElement.firstChildElement(KVTML_COMPARISON); 0342 if (!currentElement.isNull()) { 0343 readComparison(currentElement, expr->translation(index)); 0344 } 0345 0346 // multiple choice 0347 currentElement = translationElement.firstChildElement(KVTML_MULTIPLECHOICE); 0348 if (!currentElement.isNull()) { 0349 readMultipleChoice(currentElement, expr->translation(index)); 0350 } 0351 0352 // image 0353 currentElement = translationElement.firstChildElement(KVTML_IMAGE); 0354 if (!currentElement.isNull()) { 0355 QUrl imageUrl(currentElement.text()); 0356 if (imageUrl.isLocalFile() && QDir::isRelativePath(imageUrl.toLocalFile())) { 0357 imageUrl = QUrl(m_doc->url().toString(QUrl::RemoveFilename) + imageUrl.toLocalFile()); 0358 } 0359 expr->translation(index)->setImageUrl(imageUrl); 0360 } 0361 0362 // sound 0363 currentElement = translationElement.firstChildElement(KVTML_SOUND); 0364 if (!currentElement.isNull()) { 0365 QUrl soundUrl(currentElement.text()); 0366 if (soundUrl.isLocalFile() && QDir::isRelativePath(soundUrl.toLocalFile())) { 0367 soundUrl = QUrl(m_doc->url().toString(QUrl::RemoveFilename) + soundUrl.toLocalFile()); 0368 } 0369 expr->translation(index)->setSoundUrl(soundUrl); 0370 } 0371 0372 return true; 0373 } 0374 0375 bool KEduVocKvtml2Reader::readChildLessons(KEduVocLesson *parentLesson, QDomElement &lessonElement) 0376 { 0377 QDomElement currentElement = lessonElement.firstChildElement(KVTML_CONTAINER); 0378 while (!currentElement.isNull()) { 0379 readLesson(parentLesson, currentElement); 0380 currentElement = currentElement.nextSiblingElement(KVTML_CONTAINER); 0381 } 0382 return true; 0383 } 0384 0385 bool KEduVocKvtml2Reader::readLesson(KEduVocLesson *parentLesson, QDomElement &lessonElement) 0386 { 0387 //<name>Lesson name</name> 0388 QDomElement currentElement = lessonElement.firstChildElement(KVTML_NAME); 0389 KEduVocLesson *lesson = new KEduVocLesson(currentElement.text(), parentLesson); 0390 parentLesson->appendChildContainer(lesson); 0391 0392 readChildLessons(lesson, lessonElement); 0393 0394 //<query>true</query> 0395 currentElement = lessonElement.firstChildElement(KVTML_INPRACTICE); 0396 lesson->setInPractice(currentElement.text() == KVTML_TRUE); 0397 0398 //<entry id="123"/> 0399 currentElement = lessonElement.firstChildElement(KVTML_ENTRY); 0400 while (!currentElement.isNull()) { 0401 bool result = false; 0402 int entryId = currentElement.attribute(KVTML_ID).toInt(&result); 0403 if (result) { 0404 if (m_allEntries[entryId]) { 0405 lesson->appendEntry(m_allEntries[entryId]); 0406 } 0407 } 0408 currentElement = currentElement.nextSiblingElement(KVTML_ENTRY); 0409 } 0410 return true; 0411 } 0412 0413 bool KEduVocKvtml2Reader::readSynonymsAntonymsFalseFriends(QDomElement &rootElement) 0414 { 0415 QDomElement pairElement; 0416 for (int type = KEduVocTranslation::Synonym; type <= KEduVocTranslation::FalseFriend; type++) { 0417 switch (type) { 0418 case KEduVocTranslation::Synonym: 0419 pairElement = rootElement.firstChildElement(KVTML_SYNONYM); 0420 break; 0421 case KEduVocTranslation::Antonym: 0422 pairElement = rootElement.firstChildElement(KVTML_ANTONYM); 0423 break; 0424 case KEduVocTranslation::FalseFriend: 0425 pairElement = rootElement.firstChildElement(KVTML_FALSEFRIEND); 0426 break; 0427 } 0428 // pair 0429 pairElement = pairElement.firstChildElement(KVTML_PAIR); 0430 while (!pairElement.isNull()) { 0431 //<entry id="123"/> 0432 QDomElement entryElement = pairElement.firstChildElement(KVTML_ENTRY); 0433 int firstEntryId = entryElement.attribute(KVTML_ID).toInt(); 0434 0435 QDomElement translationElement = entryElement.firstChildElement(KVTML_TRANSLATION); 0436 int firstTranslationId = translationElement.attribute(KVTML_ID).toInt(); 0437 0438 // second entry 0439 entryElement = entryElement.nextSiblingElement(KVTML_ENTRY); 0440 int secondEntryId = entryElement.attribute(KVTML_ID).toInt(); 0441 translationElement = entryElement.firstChildElement(KVTML_TRANSLATION); 0442 int secondTranslationId = translationElement.attribute(KVTML_ID).toInt(); 0443 0444 // pair them up 0445 KEduVocTranslation *first = m_allEntries[firstEntryId]->translation(firstTranslationId); 0446 KEduVocTranslation *second = m_allEntries[secondEntryId]->translation(secondTranslationId); 0447 0448 switch (type) { 0449 case KEduVocTranslation::Synonym: 0450 first->addSynonym(second); 0451 second->addSynonym(first); 0452 break; 0453 case KEduVocTranslation::Antonym: 0454 first->addAntonym(second); 0455 second->addAntonym(first); 0456 break; 0457 case KEduVocTranslation::FalseFriend: 0458 first->addFalseFriend(second); 0459 second->addFalseFriend(first); 0460 break; 0461 } 0462 pairElement = pairElement.nextSiblingElement(KVTML_PAIR); 0463 } 0464 } 0465 return true; 0466 } 0467 0468 bool KEduVocKvtml2Reader::readArticle(QDomElement &articleElement, int identifierNum) 0469 /* 0470 <article> 0471 <singlular> 0472 <definite> 0473 <male>der</male> 0474 <female>die</female> 0475 <neutral>das</neutral> 0476 </definite> 0477 <indefinite> 0478 <male>ein</male> 0479 <female>eine</female> 0480 <neutral>ein</neutral> 0481 </indefinite> 0482 </singular> 0483 <dual> 0484 </dual> 0485 </article> 0486 */ 0487 { 0488 QMap<int, KEduVocWordFlag::Flags> numbers; 0489 numbers[0] = KEduVocWordFlag::Singular; 0490 numbers[1] = KEduVocWordFlag::Dual; 0491 numbers[2] = KEduVocWordFlag::Plural; 0492 QMap<int, KEduVocWordFlag::Flags> genders; 0493 genders[0] = KEduVocWordFlag::Masculine; 0494 genders[1] = KEduVocWordFlag::Feminine; 0495 genders[2] = KEduVocWordFlag::Neuter; 0496 QMap<int, KEduVocWordFlag::Flags> defs; 0497 defs[0] = KEduVocWordFlag::Definite; 0498 defs[1] = KEduVocWordFlag::Indefinite; 0499 0500 for (int num = 0; num <= 2; ++num) { 0501 QDomElement numberElement = articleElement.firstChildElement(KVTML_GRAMMATICAL_NUMBER[num]); 0502 if (!numberElement.isNull()) { 0503 // definite 0504 for (int def = 0; def <= 1; ++def) { 0505 QDomElement defElement = numberElement.firstChildElement(KVTML_GRAMMATICAL_DEFINITENESS[def]); 0506 if (!defElement.isNull()) { 0507 // male 0508 for (int gen = 0; gen <= 2; ++gen) { 0509 QDomElement genderElement = defElement.firstChildElement(KVTML_GRAMMATICAL_GENDER[gen]); 0510 if (!genderElement.isNull()) { 0511 m_doc->identifier(identifierNum).article().setArticle(genderElement.text(), numbers[num] | defs[def] | genders[gen]); 0512 } 0513 } 0514 } 0515 } 0516 } 0517 } 0518 0519 return true; 0520 } 0521 0522 bool KEduVocKvtml2Reader::readChildWordTypes(KEduVocWordType *parentContainer, QDomElement &lessonElement) 0523 { 0524 QDomElement currentElement = lessonElement.firstChildElement(KVTML_CONTAINER); 0525 while (!currentElement.isNull()) { 0526 readWordType(parentContainer, currentElement); 0527 currentElement = currentElement.nextSiblingElement(KVTML_CONTAINER); 0528 } 0529 return true; 0530 } 0531 0532 bool KEduVocKvtml2Reader::readLeitner(KEduVocLeitnerBox *parentContainer, QDomElement &leitnerParentElement) 0533 { 0534 QDomElement leitnerElement = leitnerParentElement.firstChildElement(KVTML_CONTAINER); 0535 while (!leitnerElement.isNull()) { 0536 QString name = leitnerElement.firstChildElement(KVTML_NAME).text(); 0537 0538 KEduVocLeitnerBox *leitner = new KEduVocLeitnerBox(name, parentContainer); 0539 parentContainer->appendChildContainer(leitner); 0540 // for leitner we only allow a flat list, no sub boxes. 0541 0542 // read entries 0543 QDomElement entryElement = leitnerElement.firstChildElement(KVTML_ENTRY); 0544 while (!entryElement.isNull()) { 0545 // read <entry id="123"></entryid> 0546 int entryId = entryElement.attribute(KVTML_ID).toInt(); 0547 QDomElement translationElement = entryElement.firstChildElement(KVTML_TRANSLATION); 0548 while (!translationElement.isNull()) { 0549 // <translation id="234"/> 0550 int translationId = translationElement.attribute(KVTML_ID).toInt(); 0551 m_allEntries.value(entryId)->translation(translationId)->setLeitnerBox(leitner); 0552 translationElement = translationElement.nextSiblingElement(KVTML_TRANSLATION); 0553 } 0554 entryElement = entryElement.nextSiblingElement(KVTML_ENTRY); 0555 } 0556 leitnerElement = leitnerElement.nextSiblingElement(KVTML_CONTAINER); 0557 } 0558 return true; 0559 } 0560 0561 bool KEduVocKvtml2Reader::readWordType(KEduVocWordType *parentContainer, QDomElement &typeElement) 0562 { 0563 // set type and specialtype 0564 QString typeName = typeElement.firstChildElement(KVTML_NAME).text(); 0565 0566 KEduVocWordType *wordTypeContainer = new KEduVocWordType(typeName, parentContainer); 0567 parentContainer->appendChildContainer(wordTypeContainer); 0568 0569 QString specialType = typeElement.firstChildElement(KVTML_SPECIALWORDTYPE).text(); 0570 if (!specialType.isEmpty()) { 0571 // get the localized version 0572 if (specialType == KVTML_SPECIALWORDTYPE_NOUN) { 0573 wordTypeContainer->setWordType(KEduVocWordFlag::Noun); 0574 } 0575 if (specialType == KVTML_SPECIALWORDTYPE_VERB) { 0576 wordTypeContainer->setWordType(KEduVocWordFlag::Verb); 0577 } 0578 if (specialType == KVTML_SPECIALWORDTYPE_ADVERB) { 0579 wordTypeContainer->setWordType(KEduVocWordFlag::Adverb); 0580 } 0581 if (specialType == KVTML_SPECIALWORDTYPE_ADJECTIVE) { 0582 wordTypeContainer->setWordType(KEduVocWordFlag::Adjective); 0583 } 0584 if (specialType == KVTML_SPECIALWORDTYPE_NOUN_MALE) { 0585 wordTypeContainer->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Masculine); 0586 } 0587 if (specialType == KVTML_SPECIALWORDTYPE_NOUN_FEMALE) { 0588 wordTypeContainer->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Feminine); 0589 } 0590 if (specialType == KVTML_SPECIALWORDTYPE_NOUN_NEUTRAL) { 0591 wordTypeContainer->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Neuter); 0592 } 0593 if (specialType == KVTML_SPECIALWORDTYPE_CONJUNCTION) { 0594 wordTypeContainer->setWordType(KEduVocWordFlag::Conjunction); 0595 } 0596 } // special type 0597 0598 // read entries 0599 QDomElement entryElement = typeElement.firstChildElement(KVTML_ENTRY); 0600 while (!entryElement.isNull()) { 0601 // read <entry id="123"></entryid> 0602 int entryId = entryElement.attribute(KVTML_ID).toInt(); 0603 QDomElement translationElement = entryElement.firstChildElement(KVTML_TRANSLATION); 0604 while (!translationElement.isNull()) { 0605 // <translation id="234"/> 0606 int translationId = translationElement.attribute(KVTML_ID).toInt(); 0607 m_allEntries.value(entryId)->translation(translationId)->setWordType(wordTypeContainer); 0608 translationElement = translationElement.nextSiblingElement(KVTML_TRANSLATION); 0609 } 0610 entryElement = entryElement.nextSiblingElement(KVTML_ENTRY); 0611 } 0612 0613 readChildWordTypes(wordTypeContainer, typeElement); 0614 0615 return true; 0616 } 0617 0618 QStringList KEduVocKvtml2Reader::readTenses(QDomElement &tensesElement) 0619 { 0620 QStringList tenses; 0621 0622 QDomNodeList tenseNodes = tensesElement.elementsByTagName(KVTML_TENSE); 0623 for (int i = 0; i < tenseNodes.count(); ++i) { 0624 QDomElement currentElement = tenseNodes.item(i).toElement(); 0625 if (currentElement.parentNode() == tensesElement) { 0626 tenses.append(currentElement.text()); 0627 } 0628 } 0629 0630 return tenses; 0631 } 0632 0633 bool KEduVocKvtml2Reader::readComparison(QDomElement &domElementParent, KEduVocTranslation *translation) 0634 /* 0635 <comparison> 0636 <comparative>better</comparative> 0637 <superlative>best</superlative> 0638 </comparison> 0639 */ 0640 { 0641 QDomElement currentElement; 0642 0643 currentElement = domElementParent.firstChildElement(KVTML_COMPARATIVE); 0644 if (!currentElement.isNull()) { 0645 KEduVocText comparative; 0646 comparative.fromKVTML2(currentElement); 0647 0648 // be compatible for KDE < 4.5 0649 if (comparative.text().isEmpty()) { 0650 comparative.setText(currentElement.text()); 0651 } 0652 translation->setComparativeForm(comparative); 0653 } 0654 0655 currentElement = domElementParent.firstChildElement(KVTML_SUPERLATIVE); 0656 if (!currentElement.isNull()) { 0657 KEduVocText superlative; 0658 superlative.fromKVTML2(currentElement); 0659 0660 // be compatible for KDE < 4.5 0661 if (superlative.text().isEmpty()) { 0662 superlative.setText(currentElement.text()); 0663 } 0664 translation->setSuperlativeForm(superlative); 0665 } 0666 return true; 0667 } 0668 0669 bool KEduVocKvtml2Reader::readMultipleChoice(QDomElement &multipleChoiceElement, KEduVocTranslation *translation) 0670 /* 0671 <multiplechoice> 0672 <choice>good</choice> 0673 <choice>better</choice> 0674 <choice>best</choice> 0675 <choice>best 2</choice> 0676 <choice>best 3</choice> 0677 </multiplechoice> 0678 */ 0679 { 0680 QDomElement currentElement; 0681 QDomNodeList choiceNodes = multipleChoiceElement.elementsByTagName(KVTML_CHOICE); 0682 for (int i = 0; i < choiceNodes.count(); ++i) { 0683 currentElement = choiceNodes.item(i).toElement(); 0684 if (currentElement.parentNode() == multipleChoiceElement) { 0685 QStringList choices = translation->getMultipleChoice(); 0686 choices.append(currentElement.text()); 0687 translation->setMultipleChoice(choices); 0688 } 0689 } 0690 return true; 0691 } 0692 0693 bool KEduVocKvtml2Reader::readPersonalPronoun(QDomElement &pronounElement, KEduVocPersonalPronoun &pronoun) 0694 { 0695 pronoun.setMaleFemaleDifferent(!pronounElement.firstChildElement(KVTML_THIRD_PERSON_MALE_FEMALE_DIFFERENT).isNull()); 0696 pronoun.setNeutralExists(!pronounElement.firstChildElement(KVTML_THIRD_PERSON_NEUTRAL_EXISTS).isNull()); 0697 pronoun.setDualExists(!pronounElement.firstChildElement(KVTML_DUAL_EXISTS).isNull()); 0698 0699 QDomElement personElement = pronounElement.firstChildElement(KVTML_GRAMMATICAL_NUMBER[0]); 0700 if (!personElement.isNull()) { 0701 readPersonalPronounChild(personElement, pronoun, KEduVocWordFlag::Singular); 0702 } 0703 0704 personElement = pronounElement.firstChildElement(KVTML_GRAMMATICAL_NUMBER[1]); 0705 if (!personElement.isNull()) { 0706 readPersonalPronounChild(personElement, pronoun, KEduVocWordFlag::Dual); 0707 } 0708 0709 personElement = pronounElement.firstChildElement(KVTML_GRAMMATICAL_NUMBER[2]); 0710 if (!personElement.isNull()) { 0711 readPersonalPronounChild(personElement, pronoun, KEduVocWordFlag::Plural); 0712 } 0713 return true; 0714 } 0715 0716 bool KEduVocKvtml2Reader::readPersonalPronounChild(QDomElement &personElement, KEduVocPersonalPronoun &pronoun, KEduVocWordFlags number) 0717 { 0718 QMap<int, KEduVocWordFlag::Flags> persons; 0719 persons[0] = KEduVocWordFlag::First; 0720 persons[1] = KEduVocWordFlag::Second; 0721 persons[2] = (KEduVocWordFlag::Flags)((int)KEduVocWordFlag::Third | (int)KEduVocWordFlag::Masculine); 0722 persons[3] = (KEduVocWordFlag::Flags)((int)KEduVocWordFlag::Third | (int)KEduVocWordFlag::Feminine); 0723 persons[4] = (KEduVocWordFlag::Flags)((int)KEduVocWordFlag::Third | (int)KEduVocWordFlag::Neuter); 0724 0725 for (int person = 0; person < 5; person++) { 0726 QDomElement currentElement = personElement.firstChildElement(KVTML_GRAMMATICAL_PERSON[person]); 0727 pronoun.setPersonalPronoun(currentElement.text(), persons[person] | number); 0728 } 0729 0730 return true; 0731 } 0732 0733 #include "moc_keduvockvtml2reader.cpp"