LibKEduVocDocument

keduvockvtml2writer.cpp
1/*
2 * export a KEduVocDocument to a KVTML file
3 * SPDX-FileCopyrightText: 2007 Jeremy Whiting <jpwhiting@kde.org>
4 * SPDX-FileCopyrightText: 2007-2010 Frederik Gladhorn <gladhorn@kde.org>
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7#include "keduvockvtml2writer.h"
8
9#include <QTextStream>
10
11#include <QDebug>
12#include <QDir>
13
14#include "keduvocdocument.h"
15#include "keduvocexpression.h"
16#include "keduvocleitnerbox.h"
17#include "keduvoclesson.h"
18#include "keduvocwordtype.h"
19#include "kvtml2defs.h"
20#include <kio/global.h>
21
22KEduVocKvtml2Writer::KEduVocKvtml2Writer(QFile *file)
23{
24 // the file must be already open
25 m_outputFile = file;
26}
27
28bool KEduVocKvtml2Writer::writeDoc(KEduVocDocument *doc, const QString &generator)
29{
30 if (createXmlDocument(doc, generator)) {
31 QTextStream ts(m_outputFile);
32 m_domDoc.save(ts, 2);
33 return true;
34 }
35 return false;
36}
37
38QByteArray KEduVocKvtml2Writer::toByteArray(KEduVocDocument *doc, const QString &generator)
39{
40 if (createXmlDocument(doc, generator)) {
41 return m_domDoc.toByteArray();
42 }
43 return QByteArray();
44}
45
46bool KEduVocKvtml2Writer::createXmlDocument(KEduVocDocument *doc, const QString &generator)
47{
48 m_doc = doc;
49
50 m_domDoc = QDomDocument(QStringLiteral("kvtml PUBLIC \"kvtml2.dtd\" \"http://edu.kde.org/kvtml/kvtml2.dtd\""));
51 m_domDoc.appendChild(m_domDoc.createProcessingInstruction(QStringLiteral("xml"), QStringLiteral("version=\"1.0\" encoding=\"UTF-8\"")));
52 QDomElement domElementKvtml = m_domDoc.createElement(QStringLiteral("kvtml"));
53 m_domDoc.appendChild(domElementKvtml);
54
55 domElementKvtml.setAttribute(KVTML_VERSION, (QString)QStringLiteral("2.0"));
56
57 // information group
58 QDomElement currentElement = m_domDoc.createElement(KVTML_INFORMATION);
59 writeInformation(currentElement, generator);
60 domElementKvtml.appendChild(currentElement);
61
62 // identifiers
63 currentElement = m_domDoc.createElement(KVTML_IDENTIFIERS);
64 writeIdentifiers(currentElement);
65 domElementKvtml.appendChild(currentElement);
66
67 // entries
68 currentElement = m_domDoc.createElement(KVTML_ENTRIES);
69 if (!writeEntries(currentElement)) {
70 // at least one entry is required!
71 return false;
72 }
73 domElementKvtml.appendChild(currentElement);
74
75 // lessons
76 currentElement = m_domDoc.createElement(KVTML_LESSONS);
77 writeLessons(m_doc->lesson(), currentElement);
78 if (currentElement.hasChildNodes()) {
79 domElementKvtml.appendChild(currentElement);
80 }
81
82 // types
83 currentElement = m_domDoc.createElement(KVTML_WORDTYPES);
84 writeWordTypes(currentElement, m_doc->wordTypeContainer());
85 if (currentElement.hasChildNodes()) {
86 domElementKvtml.appendChild(currentElement);
87 }
88
89 // leitner boxes
90 currentElement = m_domDoc.createElement(KVTML_LEITNERBOXES);
91 writeLeitnerBoxes(currentElement, m_doc->leitnerContainer());
92 if (currentElement.hasChildNodes()) {
93 domElementKvtml.appendChild(currentElement);
94 }
95
96 writeSynonymAntonymFalseFriend(domElementKvtml);
97
98 m_domDoc.appendChild(domElementKvtml);
99
100 return true;
101}
102
103bool KEduVocKvtml2Writer::writeInformation(QDomElement &informationElement, const QString &generator)
104{
105 QDomElement currentElement;
106 QDomText textNode;
107
108 // generator
109 informationElement.appendChild(newTextElement(KVTML_GENERATOR, generator));
110
111 // title
112 if (!m_doc->title().isEmpty()) {
113 informationElement.appendChild(newTextElement(KVTML_TITLE, m_doc->title()));
114 }
115
116 // author
117 if (!m_doc->author().isEmpty()) {
118 informationElement.appendChild(newTextElement(KVTML_AUTHOR, m_doc->author()));
119 }
120
121 // author contact (mail/homepage)
122 if (!m_doc->authorContact().isEmpty()) {
123 informationElement.appendChild(newTextElement(KVTML_AUTHORCONTACT, m_doc->authorContact()));
124 }
125
126 // license
127 if (!m_doc->license().isEmpty()) {
128 informationElement.appendChild(newTextElement(KVTML_LICENSE, m_doc->license()));
129 }
130
131 // comment
132 if (!m_doc->documentComment().isEmpty()) {
133 informationElement.appendChild(newTextElement(KVTML_COMMENT, m_doc->documentComment()));
134 }
135
136 QDate today = QDate::currentDate();
137 informationElement.appendChild(newTextElement(KVTML_DATE, today.toString(QStringLiteral("yyyy-MM-dd"))));
138
139 // category
140 if (!m_doc->category().isEmpty()) {
141 informationElement.appendChild(newTextElement(KVTML_CATEGORY, m_doc->category()));
142 }
143
144 return true;
145}
146
147bool KEduVocKvtml2Writer::writeIdentifiers(QDomElement &identifiersElement)
148{
149 for (int i = 0; i < m_doc->identifierCount(); ++i) {
150 // create the node
151 QDomElement identifier = m_domDoc.createElement(KVTML_IDENTIFIER);
152
153 // set the id
154 identifier.setAttribute(KVTML_ID, QString::number(i));
155
156 // record the identifier as the locale for now
157 // TODO: when support for more parts of the identifier is in the document class (name, type, etc.) store those here as well
158 identifier.appendChild(newTextElement(KVTML_NAME, m_doc->identifier(i).name()));
159
160 identifier.appendChild(newTextElement(KVTML_LOCALE, m_doc->identifier(i).locale()));
161
162 // record articles
163 QDomElement article = m_domDoc.createElement(KVTML_ARTICLE);
164 writeArticle(article, i);
165 if (article.hasChildNodes()) {
166 identifier.appendChild(article);
167 }
168
169 // record personalpronouns
170 QDomElement personalpronouns = m_domDoc.createElement(KVTML_PERSONALPRONOUNS);
171 writePersonalPronoun(personalpronouns, m_doc->identifier(i).personalPronouns());
172 if (personalpronouns.hasChildNodes()) {
173 identifier.appendChild(personalpronouns);
174 }
175
176 // tenses
177 foreach (const QString &tense, m_doc->identifier(i).tenseList()) {
178 if (!(tense.isNull())) {
179 identifier.appendChild(newTextElement(KVTML_TENSE, tense));
180 }
181 }
182 // add this identifier to the group
183 identifiersElement.appendChild(identifier);
184 }
185 return true;
186}
187
188bool KEduVocKvtml2Writer::writeLessons(KEduVocLesson *parentLesson, QDomElement &lessonsElement)
189{
190 // iterate over child lessons.
191 // the first time this is called with the root lesson which does not have a <lesson> entry.
192 for (int i = 0; i < parentLesson->childContainerCount(); i++) {
193 KEduVocLesson *lesson = static_cast<KEduVocLesson *>(parentLesson->childContainer(i));
194 // make lesson element
195 QDomElement thisLessonElement = m_domDoc.createElement(KVTML_CONTAINER);
196
197 // add a name
198 thisLessonElement.appendChild(newTextElement(KVTML_NAME, lesson->name()));
199
200 // add a inquery tag
201 if (lesson->inPractice()) {
202 thisLessonElement.appendChild(newTextElement(KVTML_INPRACTICE, KVTML_TRUE));
203 }
204
205 // child lessons
206 writeLessons(lesson, thisLessonElement);
207
208 // child entries
209 foreach (KEduVocExpression *entry, lesson->entries()) {
210 QDomElement entryElement = m_domDoc.createElement(KVTML_ENTRY);
211 entryElement.setAttribute(KVTML_ID, QString::number(m_allEntries.indexOf(entry)));
212 thisLessonElement.appendChild(entryElement);
213 }
214 lessonsElement.appendChild(thisLessonElement);
215 }
216 return true;
217}
218
219void KEduVocKvtml2Writer::writeSynonymAntonymFalseFriend(QDomElement &parentElement)
220{
221 QList<KEduVocTranslation *> currentList;
222 QDomElement synonymElement;
223 // synonym, antonym, false friend
224 for (int type = KEduVocTranslation::Synonym; type <= KEduVocTranslation::FalseFriend; type++) {
225 switch (type) {
226 case KEduVocTranslation::Synonym:
227 synonymElement = m_domDoc.createElement(KVTML_SYNONYM);
228 currentList = m_synonyms;
229 break;
230 case KEduVocTranslation::Antonym:
231 synonymElement = m_domDoc.createElement(KVTML_ANTONYM);
232 currentList = m_antonyms;
233 break;
234 case KEduVocTranslation::FalseFriend:
235 synonymElement = m_domDoc.createElement(KVTML_FALSEFRIEND);
236 currentList = m_falseFriends;
237 break;
238 }
239
240 while (!currentList.isEmpty()) {
241 // after writing a translation, remove it from the list
242 KEduVocTranslation *translation = currentList.takeFirst();
243
244 QDomElement relatedElement;
246 switch (type) {
247 case KEduVocTranslation::Synonym:
248 list = translation->synonyms();
249 break;
250 case KEduVocTranslation::Antonym:
251 list = translation->antonyms();
252 break;
253 case KEduVocTranslation::FalseFriend:
254 list = translation->falseFriends();
255 break;
256 }
257 foreach (KEduVocTranslation *synonym, list) {
258 // if it is not in the list it has already been written and we can move on
259 if (currentList.contains(synonym)) {
260 relatedElement = m_domDoc.createElement(KVTML_PAIR);
261
262 // fill the entry element but only add later if it is valid
263 QDomElement entryElement = m_domDoc.createElement(KVTML_ENTRY);
264 entryElement.setAttribute(KVTML_ID, QString::number(m_allEntries.indexOf(translation->entry())));
265 // find out which id that is... silly
266 foreach (int index, translation->entry()->translationIndices()) {
267 if (translation->entry()->translation(index) == translation) {
268 // create <translation id="123">
269 QDomElement translationElement = m_domDoc.createElement(KVTML_TRANSLATION);
270 translationElement.setAttribute(KVTML_ID, QString::number(index));
271 entryElement.appendChild(translationElement);
272 break;
273 }
274 }
275
276 relatedElement.appendChild(entryElement);
277
278 QDomElement partnerElement = m_domDoc.createElement(KVTML_ENTRY);
279 partnerElement.setAttribute(KVTML_ID, QString::number(m_allEntries.indexOf(synonym->entry())));
280 // find out which id that is
281 foreach (int index, synonym->entry()->translationIndices()) {
282 if (synonym->entry()->translation(index) == synonym) {
283 // create <translation id="123">
284 QDomElement translationElement = m_domDoc.createElement(KVTML_TRANSLATION);
285 translationElement.setAttribute(KVTML_ID, QString::number(index));
286 partnerElement.appendChild(translationElement);
287 break;
288 }
289 }
290 relatedElement.appendChild(partnerElement);
291 synonymElement.appendChild(relatedElement);
292 }
293 }
294 }
295 if (synonymElement.hasChildNodes()) {
296 parentElement.appendChild(synonymElement);
297 }
298 } // iterate over types
299}
300/*
301bool KEduVocKvtml2Writer::writeRelated(QDomElement & parentElement, QList< KEduVocTranslation * > relatedList)
302{
303 foreach (KEduVocTranslation* synonym, translation->synonyms()) {
304 QDomElement entryElement = m_domDoc.createElement( KVTML_ENTRY );
305 entryElement.setAttribute( KVTML_ID, QString::number(m_allEntries.indexOf(translation->entry())) );
306
307 // find out which id that is... silly
308 foreach(int index, translation->entry()->translationIndices()) {
309 if (translation->entry()->translation(index) == translation) {
310 // create <translation id="123">
311 QDomElement translationElement = m_domDoc.createElement( KVTML_TRANSLATION );
312 translationElement.setAttribute( KVTML_ID, QString::number(index) );
313 entryElement.appendChild(translationElement);
314 }
315 }
316 parentElement.appendChild( entryElement );
317 }
318}*/
319
320bool KEduVocKvtml2Writer::writeArticle(QDomElement &articleElement, int language)
321{
322 ///@todo only write if not empty
324 numbers[0] = KEduVocWordFlag::Singular;
325 numbers[1] = KEduVocWordFlag::Dual;
326 numbers[2] = KEduVocWordFlag::Plural;
328 genders[0] = KEduVocWordFlag::Masculine;
329 genders[1] = KEduVocWordFlag::Feminine;
330 genders[2] = KEduVocWordFlag::Neuter;
332 defs[0] = KEduVocWordFlag::Definite;
333 defs[1] = KEduVocWordFlag::Indefinite;
334
335 for (int num = 0; num <= 2; num++) {
336 QDomElement numberElement = m_domDoc.createElement(KVTML_GRAMMATICAL_NUMBER[num]);
337
338 for (int def = 0; def <= 1; def++) {
339 QDomElement defElement = m_domDoc.createElement(KVTML_GRAMMATICAL_DEFINITENESS[def]);
340
341 for (int gen = 0; gen <= 2; gen++) {
342 QString articleString = m_doc->identifier(language).article().article(numbers[num] | genders[gen] | defs[def]);
343 if (!articleString.isEmpty()) {
344 defElement.appendChild(newTextElement(KVTML_GRAMMATICAL_GENDER[gen], articleString));
345 }
346 }
347 if (defElement.hasChildNodes()) {
348 numberElement.appendChild(defElement);
349 }
350 }
351 if (numberElement.hasChildNodes()) {
352 articleElement.appendChild(numberElement);
353 }
354 }
355 return true;
356}
357
358bool KEduVocKvtml2Writer::writeWordTypes(QDomElement &typesElement, KEduVocWordType *parentContainer)
359{
360 foreach (KEduVocContainer *container, parentContainer->childContainers()) {
361 KEduVocWordType *wordType = static_cast<KEduVocWordType *>(container);
362
363 QDomElement typeDefinitionElement = m_domDoc.createElement(KVTML_CONTAINER);
364 typeDefinitionElement.appendChild(newTextElement(KVTML_NAME, wordType->name()));
365
366 if (wordType->wordType().testFlag(KEduVocWordFlag::Noun)) {
367 if (wordType->wordType().testFlag(KEduVocWordFlag::Masculine))
368 typeDefinitionElement.appendChild(newTextElement(KVTML_SPECIALWORDTYPE, KVTML_SPECIALWORDTYPE_NOUN_MALE));
369
370 else if (wordType->wordType().testFlag(KEduVocWordFlag::Feminine))
371 typeDefinitionElement.appendChild(newTextElement(KVTML_SPECIALWORDTYPE, KVTML_SPECIALWORDTYPE_NOUN_FEMALE));
372
373 else if (wordType->wordType().testFlag(KEduVocWordFlag::Neuter))
374 typeDefinitionElement.appendChild(newTextElement(KVTML_SPECIALWORDTYPE, KVTML_SPECIALWORDTYPE_NOUN_NEUTRAL));
375 else
376 typeDefinitionElement.appendChild(newTextElement(KVTML_SPECIALWORDTYPE, KVTML_SPECIALWORDTYPE_NOUN));
377 } else if (wordType->wordType().testFlag(KEduVocWordFlag::Verb))
378 typeDefinitionElement.appendChild(newTextElement(KVTML_SPECIALWORDTYPE, KVTML_SPECIALWORDTYPE_VERB));
379
380 else if (wordType->wordType().testFlag(KEduVocWordFlag::Adjective))
381 typeDefinitionElement.appendChild(newTextElement(KVTML_SPECIALWORDTYPE, KVTML_SPECIALWORDTYPE_ADJECTIVE));
382
383 else if (wordType->wordType().testFlag(KEduVocWordFlag::Adverb))
384 typeDefinitionElement.appendChild(newTextElement(KVTML_SPECIALWORDTYPE, KVTML_SPECIALWORDTYPE_ADVERB));
385
386 else if (wordType->wordType().testFlag(KEduVocWordFlag::Conjunction))
387 typeDefinitionElement.appendChild(newTextElement(KVTML_SPECIALWORDTYPE, KVTML_SPECIALWORDTYPE_CONJUNCTION));
388
389 // child entries
390
391 // child entries
392 foreach (KEduVocExpression *entry, wordType->entries()) {
393 QDomElement entryElement = m_domDoc.createElement(KVTML_ENTRY);
394 entryElement.setAttribute(KVTML_ID, QString::number(m_allEntries.indexOf(entry)));
395 for (int translation = 0; translation < m_doc->identifierCount(); translation++) {
396 if (entry->translation(translation)->wordType() == wordType) {
397 QDomElement translationElement = m_domDoc.createElement(KVTML_TRANSLATION);
398 // create <translation id="123">
399 translationElement.setAttribute(KVTML_ID, QString::number(translation));
400 // append both
401 entryElement.appendChild(translationElement);
402 }
403 }
404 typeDefinitionElement.appendChild(entryElement);
405 }
406
407 writeWordTypes(typeDefinitionElement, wordType);
408
409 typesElement.appendChild(typeDefinitionElement);
410 }
411 return true;
412}
413
414bool KEduVocKvtml2Writer::writeLeitnerBoxes(QDomElement &leitnerParentElement, KEduVocLeitnerBox *parentContainer)
415{
416 foreach (KEduVocContainer *container, parentContainer->childContainers()) {
417 KEduVocLeitnerBox *leitnerBox = static_cast<KEduVocLeitnerBox *>(container);
418
419 QDomElement containerElement = m_domDoc.createElement(KVTML_CONTAINER);
420 containerElement.appendChild(newTextElement(KVTML_NAME, leitnerBox->name()));
421
422 // child entries
423 foreach (KEduVocExpression *entry, leitnerBox->entries()) {
424 QDomElement entryElement = m_domDoc.createElement(KVTML_ENTRY);
425 entryElement.setAttribute(KVTML_ID, QString::number(m_allEntries.indexOf(entry)));
426 for (int translation = 0; translation < m_doc->identifierCount(); translation++) {
427 if (entry->translation(translation)->leitnerBox() == leitnerBox) {
428 QDomElement translationElement = m_domDoc.createElement(KVTML_TRANSLATION);
429 // create <translation id="123">
430 translationElement.setAttribute(KVTML_ID, QString::number(translation));
431 // append both
432 entryElement.appendChild(translationElement);
433 }
434 }
435 containerElement.appendChild(entryElement);
436 }
437
438 leitnerParentElement.appendChild(containerElement);
439 }
440 return true;
441}
442
443bool KEduVocKvtml2Writer::writeEntries(QDomElement &entriesElement)
444{
445 m_allEntries = m_doc->lesson()->entries(KEduVocLesson::Recursive);
446
447 // loop through entries
448 for (int i = 0; i < m_allEntries.count(); ++i) {
449 KEduVocExpression *thisEntry = m_allEntries.value(i);
450
451 // write entry tag
452 QDomElement entryElement = m_domDoc.createElement(KVTML_ENTRY);
453
454 // add id
455 entryElement.setAttribute(KVTML_ID, QString::number(i));
456
457 // write deactivated
458 if (!thisEntry->isActive()) {
459 entryElement.appendChild(newTextElement(KVTML_DEACTIVATED, KVTML_TRUE));
460 }
461
462 // loop through translations
463 foreach (int trans, thisEntry->translationIndices()) {
464 // write translations
465 QDomElement translation = m_domDoc.createElement(KVTML_TRANSLATION);
466 translation.setAttribute(KVTML_ID, QString::number(trans));
467 writeTranslation(translation, thisEntry->translation(trans));
468 entryElement.appendChild(translation);
469 }
470 // add this entry to the entriesElement
471 entriesElement.appendChild(entryElement);
472 }
473 return true;
474}
475
476bool KEduVocKvtml2Writer::writeTranslation(QDomElement &translationElement, KEduVocTranslation *translation)
477{
478 // so far only for KEduVocWord - text and grades
479 translation->toKVTML2(translationElement);
480
481 // comparison
482 if (!(translation->comparativeForm().text().isEmpty() || translation->superlativeForm().text().isEmpty())) {
483 qDebug() << "Write comp";
484 QDomElement comparisonElement = m_domDoc.createElement(KVTML_COMPARISON);
485 translationElement.appendChild(comparisonElement);
486
487 QDomElement comparativeElement = m_domDoc.createElement(KVTML_COMPARATIVE);
488 comparisonElement.appendChild(comparativeElement);
489 translation->comparativeForm().toKVTML2(comparativeElement);
490
491 QDomElement superlativeElement = m_domDoc.createElement(KVTML_SUPERLATIVE);
492 comparisonElement.appendChild(superlativeElement);
493 translation->superlativeForm().toKVTML2(superlativeElement);
494 }
495
496 if (translation->article().practiceCount() != 0) {
497 QDomElement articleElement = m_domDoc.createElement(KVTML_ARTICLE);
498 translation->article().toKVTML2(articleElement);
499 translationElement.appendChild(articleElement);
500 }
501
502 // multiplechoice
503 if (!translation->getMultipleChoice().isEmpty()) {
504 QDomElement multipleChoiceElement = m_domDoc.createElement(KVTML_MULTIPLECHOICE);
505 writeMultipleChoice(multipleChoiceElement, translation);
506 translationElement.appendChild(multipleChoiceElement);
507 }
508
509 // image
510 if (!translation->imageUrl().isEmpty()) {
511 QString urlString;
512 const QUrl docDirUrl = m_doc->url().adjusted(QUrl::RemoveFilename);
513 if (docDirUrl.isParentOf(translation->imageUrl())) {
514 // try to save as relative url
515 const QDir dir(docDirUrl.toLocalFile());
516 urlString = QUrl::fromLocalFile(dir.relativeFilePath(translation->imageUrl().toLocalFile())).url();
517 } else {
518 urlString = translation->imageUrl().url();
519 }
520 translationElement.appendChild(newTextElement(KVTML_IMAGE, urlString));
521 }
522
523 // sound
524 if (!translation->soundUrl().isEmpty()) {
525 QString urlString;
526 const QUrl docDirUrl = m_doc->url().adjusted(QUrl::RemoveFilename);
527 if (docDirUrl.isParentOf(translation->soundUrl())) {
528 // try to save as relative url
529 const QDir dir(docDirUrl.toLocalFile());
530 urlString = QUrl::fromLocalFile(dir.relativeFilePath(translation->soundUrl().toLocalFile())).url();
531 } else {
532 urlString = translation->soundUrl().url();
533 }
534 translationElement.appendChild(newTextElement(KVTML_SOUND, urlString));
535 }
536
537 // synonym, antonym, false friend
538 // add to the list if it has any, write later since we want them separate
539 if (!translation->synonyms().isEmpty()) {
540 m_synonyms.append(translation);
541 }
542 if (!translation->antonyms().isEmpty()) {
543 m_antonyms.append(translation);
544 }
545 if (!translation->falseFriends().isEmpty()) {
546 m_falseFriends.append(translation);
547 }
548 return true;
549}
550
551///@todo write false friends
552// <falsefriend fromid="0"></falsefriend>
553// loop through the identifiers
554// for ( int i = 0; i < m_doc->identifierCount(); ++i ) {
555// // see if this identifier has a falsefriend in this translation
556// QString thisFriend = translation->falseFriend( i );
557// if ( !thisFriend.isEmpty() ) {
558// // if so, create it, and set the fromid to i
559// QDomElement thisFriendElement = newTextElement( KVTML_FALSEFRIEND, thisFriend );
560// thisFriendElement.setAttribute( KVTML_FROMID, QString::number( i ) );
561// translationElement.appendChild( thisFriendElement );
562// }
563// }
564
565bool KEduVocKvtml2Writer::writeMultipleChoice(QDomElement &multipleChoiceElement, KEduVocTranslation *translation)
566/*
567 <multiplechoice>
568 <choice>good</choice>
569 <choice>better</choice>
570 <choice>best</choice>
571 <choice>best 2</choice>
572 <choice>best 3</choice>
573 </multiplechoice>
574*/
575{
576 foreach (const QString &choice, translation->getMultipleChoice()) {
577 multipleChoiceElement.appendChild(newTextElement(KVTML_CHOICE, choice));
578 }
579 return true;
580}
581
582QDomElement KEduVocKvtml2Writer::newTextElement(const QString &elementName, const QString &text)
583{
584 QDomElement retval = m_domDoc.createElement(elementName);
585 QDomText textNode = m_domDoc.createTextNode(text);
586 retval.appendChild(textNode);
587 return retval;
588}
589
590bool KEduVocKvtml2Writer::writePersonalPronoun(QDomElement &pronounElement, const KEduVocPersonalPronoun &pronoun)
591{
592 // general pronoun properties
593 if (pronoun.maleFemaleDifferent()) {
594 pronounElement.appendChild(m_domDoc.createElement(KVTML_THIRD_PERSON_MALE_FEMALE_DIFFERENT));
595 }
596 if (pronoun.neutralExists()) {
597 pronounElement.appendChild(m_domDoc.createElement(KVTML_THIRD_PERSON_NEUTRAL_EXISTS));
598 }
599 if (pronoun.dualExists()) {
600 pronounElement.appendChild(m_domDoc.createElement(KVTML_DUAL_EXISTS));
601 }
602
604 numbers[0] = KEduVocWordFlag::Singular;
605 numbers[1] = KEduVocWordFlag::Dual;
606 numbers[2] = KEduVocWordFlag::Plural;
608 persons[0] = KEduVocWordFlag::First;
609 persons[1] = KEduVocWordFlag::Second;
610 persons[2] = (KEduVocWordFlag::Flags)((int)KEduVocWordFlag::Third | (int)KEduVocWordFlag::Masculine);
611 persons[3] = (KEduVocWordFlag::Flags)((int)KEduVocWordFlag::Third | (int)KEduVocWordFlag::Feminine);
612 persons[4] = (KEduVocWordFlag::Flags)((int)KEduVocWordFlag::Third | (int)KEduVocWordFlag::Neuter);
613
614 // the actual pronouns
615 for (int num = 0; num < 3; num++) {
616 QDomElement numberElement = m_domDoc.createElement(KVTML_GRAMMATICAL_NUMBER[num]);
617 for (int person = 0; person < 5; person++) {
618 QString pronounString = pronoun.personalPronoun(numbers[num] | persons[person]);
619 if (!pronounString.isEmpty()) {
620 numberElement.appendChild(newTextElement(KVTML_GRAMMATICAL_PERSON[person], pronounString));
621 }
622 }
623 if (numberElement.hasChildNodes()) {
624 pronounElement.appendChild(numberElement);
625 }
626 }
627 return true;
628}
629
630void KEduVocKvtml2Writer::appendTextElement(QDomElement &parent, const QString &elementName, const QString &text)
631{
632 // empty will never be written
633 if (text.isEmpty()) {
634 return;
635 }
636
637 QDomDocument domDoc = parent.ownerDocument();
638 QDomElement element = domDoc.createElement(elementName);
639 parent.appendChild(element);
640 QDomText textNode = domDoc.createTextNode(text);
641 element.appendChild(textNode);
642}
class to store information about a container - that can be a lesson or word types
int childContainerCount() const
Find a child container.
QString name()
get the container name
The primary entry point to the hierarchy of objects describing vocabularies.
int identifierCount() const
QString license() const
QString documentComment() const
KEduVocWordType * wordTypeContainer()
Returns the root word type object.
KEduVocLesson * lesson()
Get the lesson root object.
KEduVocLeitnerBox * leitnerContainer()
Returns the root Leitner container.
QString author() const
QString title() const
KEduVocIdentifier & identifier(int index)
Returns the identifier of translation index.
QString authorContact() const
QString category() const
This class contains one vocabulary expression as an original with one or more translations.
bool isActive() const
returns flag if entry is activated for queries
KEduVocTranslation * translation(int index)
Get a pointer to the translation.
KEduVocArticle & article() const
Articles (a, the in English, el, la,... in Spanish)
KEduVocPersonalPronoun & personalPronouns() const
Get the personal pronouns for this identifier.
QString name() const
Name of this identifier.
QString locale() const
The locale of the contents: en, de, es, ...
static void appendTextElement(QDomElement &parent, const QString &elementName, const QString &text)
Helper function, appends a new element AND a text child to parent Only appends if text is NOT empty.
Leitner Boxes are an alternative grading system.
QList< KEduVocExpression * > entries(EnumEntriesRecursive recursive=NotRecursive) override
get a list of all entries in the box
class to store information about a lesson
QList< KEduVocExpression * > entries(EnumEntriesRecursive recursive=NotRecursive) override
get a list of all entries in the lesson
The conjugation of a verb.
count_t practiceCount() const
returns how often this entry has been practiced as int
QString text() const
The translation as string (the word itself)
void toKVTML2(QDomElement &parent)
QStringList getMultipleChoice() const
Returns multiple choice if available.
KEduVocLeitnerBox * leitnerBox() const
Returns the leitner box of this translation.
QUrl soundUrl()
Get the sound url for this translation if it exists.
QList< KEduVocTranslation * > synonyms() const
Returns synonyms of this expression.
QList< KEduVocTranslation * > antonyms() const
Returns antonyms of this expression.
QList< KEduVocTranslation * > falseFriends() const
Returns false friends of this expression.
KEduVocWordType * wordType() const
Returns the word type of this expression, you will get a 0 pointer if wordtype is not set for the tra...
QUrl imageUrl()
Get the image url for this translation if it exists.
class to store translation word types
QList< KEduVocExpression * > entries(EnumEntriesRecursive recursive=NotRecursive) override
get a list of all entries in the lesson
KEduVocWordFlags wordType() const
Return the raw WordTypeFlags.
Type type(const QSqlDatabase &db)
KIOCORE_EXPORT QString dir(const QString &fileClass)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QDate currentDate()
QString toString(QStringView format, QCalendar cal) const const
QDomElement createElement(const QString &tagName)
QDomProcessingInstruction createProcessingInstruction(const QString &target, const QString &data)
QDomText createTextNode(const QString &value)
QByteArray toByteArray(int indent) const const
void setAttribute(const QString &name, const QString &value)
QDomNode appendChild(const QDomNode &newChild)
bool hasChildNodes() const const
QDomDocument ownerDocument() const const
void save(QTextStream &stream, int indent, EncodingPolicy encodingPolicy) const const
bool testFlag(Enum flag) const const
void append(QList< T > &&value)
bool contains(const AT &value) const const
qsizetype count() const const
qsizetype indexOf(const AT &value, qsizetype from) const const
bool isEmpty() const const
value_type takeFirst()
T value(qsizetype i) const const
bool isEmpty() const const
bool isNull() const const
QString number(double n, char format, int precision)
RemoveFilename
QUrl adjusted(FormattingOptions options) const const
QUrl fromLocalFile(const QString &localFile)
bool isEmpty() const const
bool isParentOf(const QUrl &childUrl) const const
QString toLocalFile() const const
QString url(FormattingOptions options) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:55:29 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.