1 /*
2  * export a KEduVocDocument to a KVTML file
3  * SPDX-FileCopyrightText: 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de>
4  * SPDX-FileCopyrightText: 2005 Eric Pignet <eric at erixpage.com>
5  * SPDX-FileCopyrightText: 2007 Peter Hedlund <peter.hedlund@kdemail.net>
6  * SPDX-FileCopyrightText: 2007 Frederik Gladhorn <frederik.gladhorn@kdemail.net>
7  * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 
10 #include "keduvockvtmlwriter.h"
11 
12 #include <QLatin1String>
13 #include <QTextStream>
14 
15 #include <QDebug>
16 
17 #include "keduvocdocument.h"
18 #include "keduvocgrade.h"
19 #include "keduvoclesson.h"
20 #include "keduvocexpression.h"
21 #include "kvtmldefs.h"
22 #include "keduvoccommon_p.h"
23 
KEduVocKvtmlWriter(QFile * file)24 KEduVocKvtmlWriter::KEduVocKvtmlWriter( QFile *file )
25 {
26     // the file must be already open
27     m_outputFile = file;
28 }
29 
30 
writeDoc(KEduVocDocument * doc,const QString & generator)31 bool KEduVocKvtmlWriter::writeDoc( KEduVocDocument *doc, const QString &generator )
32 {
33     bool first_expr = true;
34 
35     m_doc = doc;
36 
37     m_domDoc = QDomDocument( "kvtml SYSTEM \"kvoctrain.dtd\"" );
38     m_domDoc.appendChild( m_domDoc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
39     QDomElement domElementKvtml = m_domDoc.createElement( "kvtml" );
40     m_domDoc.appendChild( domElementKvtml );
41 
42     domElementKvtml.setAttribute( KV_ENCODING, ( QString ) "UTF-8" );
43     domElementKvtml.setAttribute( KV_GENERATOR, generator );
44     domElementKvtml.setAttribute( KV_COLS, m_doc->identifierCount() );
45     domElementKvtml.setAttribute( KV_LINES, m_doc->entryCount() );
46 
47     if ( !m_doc->title().isEmpty() )
48         domElementKvtml.setAttribute( KV_TITLE, m_doc->title() );
49 
50     if ( !m_doc->author().isEmpty() )
51         domElementKvtml.setAttribute( KV_AUTHOR, m_doc->author() );
52 
53     if ( !m_doc->license().isEmpty() )
54         domElementKvtml.setAttribute( KV_LICENSE, m_doc->license() );
55 
56     if ( !m_doc->documentComment().isEmpty() )
57         domElementKvtml.setAttribute( KV_DOC_REM, m_doc->documentComment() );
58 
59     if ( !writeLesson( domElementKvtml ) )
60         return false;
61 
62     if ( !writeArticle( domElementKvtml ) )
63         return false;
64 
65     QList<KEduVocPersonalPronoun> pronouns;
66     for ( int i = 0; i < m_doc->identifierCount(); i++ )
67         pronouns.append( m_doc->identifier(i).personalPronouns() );
68     if ( pronouns.count() > 0 ) {
69         if ( !writePersonalPronouns(domElementKvtml, pronouns ) )
70             return false;
71     }
72 
73     if ( !writeType( domElementKvtml ) )
74         return false;
75 
76     if ( !writeTense( domElementKvtml ) )
77         return false;
78 
79     if ( !writeUsage( domElementKvtml ) )
80         return false;
81 
82     QString q_org, q_trans;
83     m_doc->queryIdentifier( q_org, q_trans );
84 
85     int entryCount = m_doc->entryCount();
86 
87     for ( int i = 0; i < entryCount; i++ ) {
88         KEduVocExpression *entry = m_doc->entry( i );
89         QDomElement domElementExpression = m_domDoc.createElement( KV_EXPR );
90 
91         if ( entry->lesson() != 0 ) {
92             int lm = entry->lesson();
93             if ( lm > m_doc->lessonCount() ) {
94                 // should not be
95                 qCritical() << "index of lesson member too high: " << lm << endl;
96                 lm = 0;
97             }
98             domElementExpression.setAttribute( KV_LESS_MEMBER, lm );
99         }
100 
101 // Sorry, but we don't support this any more.
102 //         if ( entry->isInQuery() )
103 //             domElementExpression.setAttribute( KV_SELECTED, 1 );
104 
105         if ( !entry->isActive() )
106             domElementExpression.setAttribute( KV_INACTIVE, 1 );
107 
108         QDomElement domElementOriginal = m_domDoc.createElement( KV_ORG );
109         if ( first_expr ) {
110             // save space, only tell language in first entry
111             QString s;
112             domElementOriginal.setAttribute( KV_SIZEHINT, m_doc->sizeHint( 0 ) );
113 
114             s = m_doc->identifier( 0 ).name().simplified();
115             if ( s.isEmpty() )
116                 s = "original";
117             domElementOriginal.setAttribute( KV_LANG, s );
118             if ( s == q_org )
119                 domElementOriginal.setAttribute( KV_QUERY, ( QString ) KV_O );
120             else if ( s == q_trans )
121                 domElementOriginal.setAttribute( KV_QUERY, ( QString ) KV_T );
122         }
123 
124         if ( !entry->translation( 0 ).comment().isEmpty() )
125             domElementOriginal.setAttribute( KV_REMARK, entry->translation( 0 ).comment() );
126 
127         if ( !entry->translation( 0 ).synonym().isEmpty() )
128             domElementOriginal.setAttribute( KV_SYNONYM, entry->translation( 0 ).synonym() );
129 
130         if ( !entry->translation( 0 ).example().isEmpty() )
131             domElementOriginal.setAttribute( KV_EXAMPLE, entry->translation( 0 ).example() );
132 ///@todo enable writing of usages in old format
133         /*
134             if (!entry->translation(0).usageLabel().isEmpty() )
135               domElementOriginal.setAttribute(KV_USAGE, entry->translation(0).usageLabel());
136         */
137         if ( !entry->translation( 0 ).paraphrase().isEmpty() )
138             domElementOriginal.setAttribute( KV_PARAPHRASE, entry->translation( 0 ).paraphrase() );
139 
140         if ( !entry->translation( 0 ).antonym().isEmpty() )
141             domElementOriginal.setAttribute( KV_ANTONYM, entry->translation( 0 ).antonym() );
142 
143         if ( !entry->translation( 0 ).pronunciation().isEmpty() )
144             domElementOriginal.setAttribute( KV_PRONUNCE, entry->translation( 0 ).pronunciation() );
145 
146         if ( !entry->translation( 0 ).type().isEmpty() )
147             domElementOriginal.setAttribute( KV_EXPRTYPE, m_compability.oldType( entry->translation( 0 ).type(), entry->translation( 0 ).subType() ) );
148 
149         if ( !writeMultipleChoice(domElementOriginal, entry->translation( 0 ).multipleChoice() ) )
150             return false;
151 
152         QString s;
153         QString entype = s = entry->translation( 0 ).type();
154         int pos = s.indexOf( QM_TYPE_DIV );
155         if ( pos >= 0 )
156             entype = s.left( pos );
157         else
158             entype = s;
159 
160         if ( entype == QM_VERB ) {
161                 // conjugation
162             if ( !writeConjugEntry(domElementOriginal, entry->translation( 0 )) ) {
163                     return false;
164             }
165 
166 
167         } else if ( entype == QM_ADJ && !entry->translation( 0 ).comparison().isEmpty() ) {
168             KEduVocComparison comp = entry->translation( 0 ).comparison();
169             if ( !writeComparison(domElementOriginal, comp ) )
170                 return false;
171         }
172 
173         QDomText domTextOriginal = m_domDoc.createTextNode( entry->translation( 0 ).text() );
174         domElementOriginal.appendChild( domTextOriginal );
175         domElementExpression.appendChild( domElementOriginal );
176 
177         int trans = 1;
178         while ( trans < m_doc->identifierCount() ) {
179             QDomElement domElementTranslation = m_domDoc.createElement( KV_TRANS );
180             if ( first_expr ) {
181                 // save space, only tell language in first entry
182                 QString s;
183                 domElementTranslation.setAttribute( KV_SIZEHINT, m_doc->sizeHint( trans ) );
184 
185                 s = m_doc->identifier( trans ).name().simplified();
186                 if ( s.isEmpty() ) {
187                     s.setNum( trans );
188                     s.prepend( QLatin1String("translation ") );
189                 }
190                 domElementTranslation.setAttribute( KV_LANG, s );
191                 if ( s == q_org )
192                     domElementTranslation.setAttribute( KV_QUERY, ( QString ) KV_O );
193                 else if ( s == q_trans )
194                     domElementTranslation.setAttribute( KV_QUERY, ( QString ) KV_T );
195             }
196 
197             if ( entry->translation( trans ).gradeFrom( 0 ).grade() != 0 || entry->translation( 0 ).gradeFrom( trans ).grade() != 0 )
198                 domElementTranslation.setAttribute( KV_GRADE, QString::number( entry->translation( trans ).gradeFrom( 0 ).grade() ) + ';' + QString::number( entry->translation( 0 ).gradeFrom( trans ).grade() ) );
199 
200             if ( entry->translation( trans ).gradeFrom( 0 ).practiceCount() != 0 || entry->translation( 0 ).gradeFrom( trans ).practiceCount() != 0 )
201                 domElementTranslation.setAttribute( KV_COUNT, QString::number( entry->translation( trans ).gradeFrom( 0 ).practiceCount() ) + ';' + QString::number( entry->translation( 0 ).gradeFrom( trans ).practiceCount() ) );
202 
203             if ( entry->translation( trans ).gradeFrom( 0 ).badCount() != 0 || entry->translation( 0 ).gradeFrom( trans ).badCount() != 0 )
204                 domElementTranslation.setAttribute( KV_BAD, QString::number( entry->translation( trans ).gradeFrom( 0 ).badCount() ) + ';' + QString::number( entry->translation( 0 ).gradeFrom( trans ).badCount() ) );
205 
206             if ( entry->translation( trans ).gradeFrom( 0 ).practiceDate().toTime_t() != 0 || entry->translation( 0 ).gradeFrom( trans ).practiceDate().toTime_t() != 0 )
207                 domElementTranslation.setAttribute( KV_DATE, QString::number( entry->translation( trans ).gradeFrom( 0 ).practiceDate().toTime_t() ) + ';' + QString::number( entry->translation( 0 ).gradeFrom( trans ).practiceDate().toTime_t() ) );
208 
209             if ( !entry->translation( trans ).comment().isEmpty() )
210                 domElementTranslation.setAttribute( KV_REMARK, entry->translation( trans ).comment() );
211 
212             if ( !entry->translation( trans ).falseFriend( 0 ).isEmpty() )
213                 domElementTranslation.setAttribute( KV_FAUX_AMI_F, entry->translation( trans ).falseFriend( 0 ) );
214 
215             if ( !entry->translation( 0 ).falseFriend( trans ).isEmpty() )
216                 domElementTranslation.setAttribute( KV_FAUX_AMI_T, entry->translation( 0 ).falseFriend( trans ) );
217 
218             if ( !entry->translation( trans ).synonym().isEmpty() )
219                 domElementTranslation.setAttribute( KV_SYNONYM, entry->translation( trans ).synonym() );
220 
221             if ( !entry->translation( trans ).example().isEmpty() )
222                 domElementTranslation.setAttribute( KV_EXAMPLE, entry->translation( trans ).example() );
223 
224 ///@todo enable writing of usages in old format
225             /*
226                   if (!entry->translation(trans).usageLabel().isEmpty() )
227                     domElementTranslation.setAttribute(KV_USAGE, entry->translation(trans).usageLabel());
228             */
229             if ( !entry->translation( trans ).paraphrase().isEmpty() )
230                 domElementTranslation.setAttribute( KV_PARAPHRASE, entry->translation( trans ).paraphrase() );
231 
232             if ( !entry->translation( trans ).antonym().isEmpty() )
233                 domElementTranslation.setAttribute( KV_ANTONYM, entry->translation( trans ).antonym() );
234 
235             if ( !entry->translation( trans ).pronunciation().isEmpty() )
236                 domElementTranslation.setAttribute( KV_PRONUNCE, entry->translation( trans ).pronunciation() );
237 
238             if ( !entry->translation( trans ).type().isEmpty() )
239                 domElementTranslation.setAttribute( KV_EXPRTYPE, m_compability.oldType( entry->translation( trans ).type(), entry->translation( trans ).subType() ) );
240 
241             if ( !writeMultipleChoice(domElementTranslation, entry->translation( trans ).multipleChoice() ) )
242                 return false;
243 
244             QString s;
245             QString entype = s = entry->translation( 0 ).type();
246             int pos = s.indexOf( QM_TYPE_DIV );
247             if ( pos >= 0 )
248                 entype = s.left( pos );
249             else
250                 entype = s;
251 
252             if ( entype == QM_VERB ) {
253                 if ( !writeConjugEntry(domElementTranslation, entry->translation( trans ) ) ) {
254                     return false;
255                 }
256             }
257 
258             if ( entype == QM_ADJ && !entry->translation( trans ).comparison().isEmpty() ) {
259                 KEduVocComparison comp = entry->translation( trans ).comparison();
260                 if ( !writeComparison(domElementTranslation, comp ) )
261                     return false;
262             }
263 
264             QDomText domTextTranslation = m_domDoc.createTextNode( entry->translation( trans ).text() );
265             domElementTranslation.appendChild( domTextTranslation );
266             domElementExpression.appendChild( domElementTranslation );
267 
268             trans++;
269         }
270 
271         domElementKvtml.appendChild( domElementExpression );
272 
273         first_expr = false;
274     }
275 
276     m_domDoc.appendChild( domElementKvtml );
277 
278     QTextStream ts( m_outputFile );
279     m_domDoc.save( ts, 2 );
280 
281     return true;
282 }
283 
284 
writeLesson(QDomElement & domElementParent)285 bool KEduVocKvtmlWriter::writeLesson( QDomElement &domElementParent )
286 {
287     if ( m_doc->lessonCount() == 0 )
288         return true;
289 
290     QDomElement domElementLesson = m_domDoc.createElement( KV_LESS_GRP );
291     domElementLesson.setAttribute( KV_SIZEHINT, m_doc->sizeHint( -1 ) );
292 
293     for ( int i = 0; i < m_doc->lessonCount(); ++i ) {
294         QDomElement domElementDesc = m_domDoc.createElement( KV_LESS_DESC );
295         QDomText domTextDesc = m_domDoc.createTextNode( m_doc->lesson(i).name() );
296 
297         domElementDesc.setAttribute( KV_LESS_NO, i );
298         if ( m_doc->currentLesson() == i ) {
299             domElementDesc.setAttribute( KV_LESS_CURR, 1 );
300         }
301         if ( m_doc->lesson(i).inPractice() ) {
302             domElementDesc.setAttribute( KV_LESS_QUERY, 1 );
303         }
304         domElementDesc.appendChild( domTextDesc );
305         domElementLesson.appendChild( domElementDesc );
306     }
307 
308     domElementParent.appendChild( domElementLesson );
309     return true;
310 }
311 
312 
writeArticle(QDomElement & domElementParent)313 bool KEduVocKvtmlWriter::writeArticle( QDomElement &domElementParent )
314 /*
315  <article>
316   <e l="de">    lang determines also lang order in entries !!
317    <fi>eine</fi>  which must NOT differ
318    <fd>die</fd>
319    <mi>ein</mi>
320    <md>der</md>
321    <ni>ein</ni>
322    <nd>das</nd>
323   </e>
324  </article>
325 */
326 {
327     QDomElement domElementArticle = m_domDoc.createElement( KV_ARTICLE_GRP );
328     QString def;
329     QString indef;
330     QString s;
331 
332     for ( int i = 0; i < m_doc->identifierCount(); i++ )
333     {
334         QDomElement domElementEntry = m_domDoc.createElement( KV_ART_ENTRY );
335         s = m_doc->identifier(i).name().simplified();
336         domElementEntry.setAttribute( KV_LANG, s );
337 
338         QString articleString;
339         // female
340         articleString = m_doc->identifier(i).article().article( KEduVocWordFlag::Singular | KEduVocWordFlag::Definite | KEduVocWordFlag::Feminine );
341         if ( !articleString.isEmpty() ) {
342             QDomElement domElementFD = m_domDoc.createElement( KV_ART_FD );
343             QDomText domTextFD = m_domDoc.createTextNode( articleString );
344 
345             domElementFD.appendChild( domTextFD );
346             domElementEntry.appendChild( domElementFD );
347         }
348         articleString = m_doc->identifier(i).article().article( KEduVocWordFlag::Singular | KEduVocWordFlag::Indefinite | KEduVocWordFlag::Feminine );
349         if ( !articleString.isEmpty() ) {
350             QDomElement domElementFI = m_domDoc.createElement( KV_ART_FI );
351             QDomText domTextFI = m_domDoc.createTextNode( articleString );
352 
353             domElementFI.appendChild( domTextFI );
354             domElementEntry.appendChild( domElementFI );
355         }
356 
357 
358         // male
359         articleString = m_doc->identifier(i).article().article( KEduVocWordFlag::Singular | KEduVocWordFlag::Definite | KEduVocWordFlag::Masculine );
360         if ( !articleString.isEmpty() ) {
361             QDomElement domElementMD = m_domDoc.createElement( KV_ART_MD );
362             QDomText domTextMD = m_domDoc.createTextNode( articleString );
363 
364             domElementMD.appendChild( domTextMD );
365             domElementEntry.appendChild( domElementMD );
366         }
367         articleString = m_doc->identifier(i).article().article( KEduVocWordFlag::Singular | KEduVocWordFlag::Indefinite | KEduVocWordFlag::Masculine );
368         if ( !articleString.isEmpty() ) {
369             QDomElement domElementMI = m_domDoc.createElement( KV_ART_MI );
370             QDomText domTextMI = m_domDoc.createTextNode( articleString );
371 
372             domElementMI.appendChild( domTextMI );
373             domElementEntry.appendChild( domElementMI );
374         }
375 
376         // neutral
377         articleString = m_doc->identifier(i).article().article( KEduVocWordFlag::Singular | KEduVocWordFlag::Definite | KEduVocWordFlag::Neutral );
378         if ( !articleString.isEmpty() ) {
379             QDomElement domElementND = m_domDoc.createElement( KV_ART_ND );
380             QDomText domTextND = m_domDoc.createTextNode( articleString );
381 
382             domElementND.appendChild( domTextND );
383             domElementEntry.appendChild( domElementND );
384         }
385         articleString = m_doc->identifier(i).article().article( KEduVocWordFlag::Singular | KEduVocWordFlag::Indefinite | KEduVocWordFlag::Neutral );
386         if ( !articleString.isEmpty() ) {
387             QDomElement domElementNI = m_domDoc.createElement( KV_ART_NI );
388             QDomText domTextNI = m_domDoc.createTextNode( articleString );
389 
390             domElementNI.appendChild( domTextNI );
391             domElementEntry.appendChild( domElementNI );
392         }
393 
394         domElementArticle.appendChild( domElementEntry );
395     }
396 
397     domElementParent.appendChild( domElementArticle );
398     return true;
399 }
400 
401 
writeType(QDomElement & domElementParent)402 bool KEduVocKvtmlWriter::writeType( QDomElement &domElementParent )
403 {
404     /** @todo port to new type handling */
405     /*
406       if (m_doc->typeDescriptions().isEmpty())
407         return true;
408 
409       QDomElement domElementType = m_domDoc.createElement(KV_TYPE_GRP);
410       int count = 1;
411 
412       foreach(const QString &type, m_doc->typeDescriptions())
413       {
414         if (!(type.isNull()) )
415         {
416           QDomElement domElementDesc = m_domDoc.createElement(KV_TYPE_DESC);
417           QDomText domTextDesc = m_domDoc.createTextNode(type);
418 
419           domElementDesc.setAttribute(KV_TYPE_NO, count);
420           domElementDesc.appendChild(domTextDesc);
421           domElementType.appendChild(domElementDesc);
422           count++;
423         }
424       }
425 
426       domElementParent.appendChild(domElementType);
427     */
428     return true;
429 }
430 
431 /*
432 bool KEduVocKvtmlWriter::writeTense( QDomElement &domElementParent )
433 {
434     if ( m_doc->tenseDescriptions().isEmpty() )
435         return true;
436 
437     QDomElement domElementTense = m_domDoc.createElement( KV_TENSE_GRP );
438     int count = 1;
439 
440     foreach( const QString &tense, m_doc->tenseDescriptions() ) {
441         if ( !( tense.isNull() ) ) {
442             QDomElement domElementDesc = m_domDoc.createElement( KV_TENSE_DESC );
443             QDomText domTextDesc = m_domDoc.createTextNode( tense );
444 
445             domElementDesc.setAttribute( KV_TENSE_NO, count );
446             domElementDesc.appendChild( domTextDesc );
447             domElementTense.appendChild( domElementDesc );
448             count++;
449         }
450     }
451 
452     domElementParent.appendChild( domElementTense );
453     return true;
454 }
455 */
456 
writeUsage(QDomElement & domElementParent)457 bool KEduVocKvtmlWriter::writeUsage( QDomElement &domElementParent )
458 {
459 
460 ///@todo usages
461     /*
462       if (m_doc->usageDescriptions().isEmpty())
463         return true;
464 
465       QDomElement domElementUsage = m_domDoc.createElement(KV_USAGE_GRP);
466       int count = 1;
467 
468       foreach(const QString &usage, m_doc->usageDescriptions())
469       {
470         if (!(usage.isNull()))
471         {
472           QDomElement domElementDesc = m_domDoc.createElement(KV_USAGE_DESC);
473           QDomText domTextDesc = m_domDoc.createTextNode(usage);
474 
475           domElementDesc.setAttribute(KV_USAGE_NO, count);
476           domElementDesc.appendChild(domTextDesc);
477           domElementUsage.appendChild(domElementDesc);
478           count++;
479         }
480       }
481 
482       domElementParent.appendChild(domElementUsage);
483     */
484     return true;
485 }
486 
487 
writeComparison(QDomElement & domElementParent,const KEduVocTranslation * translation)488 bool KEduVocKvtmlWriter::writeComparison( QDomElement &domElementParent, const KEduVocTranslation* translation )
489 /*
490  <comparison>
491    <l1>good</l1>
492    <l2>better</l2>
493    <l3>best</l3>
494  </comparison>
495 */
496 {
497     if ( translation.comparison().isEmpty() && translation.superlative().isEmpty() ) {
498         return true;
499     }
500 
501     QDomElement domElementComparison = m_domDoc.createElement( KV_COMPARISON_GRP );
502 
503     if ( !comp.l1().isEmpty() ) {
504         QDomElement domElementL1 = m_domDoc.createElement( KV_COMP_L1 );
505         QDomText domTextL1 = m_domDoc.createTextNode( comp.l1() );
506 
507         domElementL1.appendChild( domTextL1 );
508         domElementComparison.appendChild( domElementL1 );
509     }
510 
511     if ( !comp.l2().isEmpty() ) {
512         QDomElement domElementL2 = m_domDoc.createElement( KV_COMP_L2 );
513         QDomText domTextL2 = m_domDoc.createTextNode( comp.l2() );
514 
515         domElementL2.appendChild( domTextL2 );
516         domElementComparison.appendChild( domElementL2 );
517     }
518 
519     if ( !comp.l3().isEmpty() ) {
520         QDomElement domElementL3 = m_domDoc.createElement( KV_COMP_L3 );
521         QDomText domTextL3 = m_domDoc.createTextNode( comp.l3() );
522 
523         domElementL3.appendChild( domTextL3 );
524         domElementComparison.appendChild( domElementL3 );
525     }
526 
527     domElementParent.appendChild( domElementComparison );
528     return true;
529 }
530 
531 
writeMultipleChoice(QDomElement & domElementParent,const KEduVocMultipleChoice & mc)532 bool KEduVocKvtmlWriter::writeMultipleChoice( QDomElement &domElementParent, const KEduVocMultipleChoice &mc )
533 /*
534  <multiplechoice>
535    <mc1>good</mc1>
536    <mc2>better</mc2>
537    <mc3>best</mc3>
538    <mc4>best 2</mc4>
539    <mc5>best 3</mc5>
540  </multiplechoice>
541 */
542 {
543     if ( mc.isEmpty() )
544         return true;
545 
546     QDomElement domElementMC = m_domDoc.createElement( KV_MULTIPLECHOICE_GRP );
547 
548     if ( !mc.choice( 1 ).isEmpty() ) {
549         QDomElement domElementMC1 = m_domDoc.createElement( KV_MC_1 );
550         QDomText domTextMC1 = m_domDoc.createTextNode( mc.choice( 1 ) );
551 
552         domElementMC1.appendChild( domTextMC1 );
553         domElementMC.appendChild( domElementMC1 );
554     }
555 
556     if ( !mc.choice( 2 ).isEmpty() ) {
557         QDomElement domElementMC2 = m_domDoc.createElement( KV_MC_2 );
558         QDomText domTextMC2 = m_domDoc.createTextNode( mc.choice( 2 ) );
559 
560         domElementMC2.appendChild( domTextMC2 );
561         domElementMC.appendChild( domElementMC2 );
562     }
563 
564     if ( !mc.choice( 3 ).isEmpty() ) {
565         QDomElement domElementMC3 = m_domDoc.createElement( KV_MC_3 );
566         QDomText domTextMC3 = m_domDoc.createTextNode( mc.choice( 3 ) );
567 
568         domElementMC3.appendChild( domTextMC3 );
569         domElementMC.appendChild( domElementMC3 );
570     }
571 
572     if ( !mc.choice( 4 ).isEmpty() ) {
573         QDomElement domElementMC4 = m_domDoc.createElement( KV_MC_4 );
574         QDomText domTextMC4 = m_domDoc.createTextNode( mc.choice( 4 ) );
575 
576         domElementMC4.appendChild( domTextMC4 );
577         domElementMC.appendChild( domElementMC4 );
578     }
579 
580     if ( !mc.choice( 5 ).isEmpty() ) {
581         QDomElement domElementMC5 = m_domDoc.createElement( KV_MC_5 );
582         QDomText domTextMC5 = m_domDoc.createTextNode( mc.choice( 5 ) );
583 
584         domElementMC5.appendChild( domTextMC5 );
585         domElementMC.appendChild( domElementMC5 );
586     }
587 
588     domElementParent.appendChild( domElementMC );
589     return true;
590 }
591 
592 
writeConjugHeader(QDomElement & domElementParent,QList<KEduVocConjugation> & curr_conjug)593 bool KEduVocKvtmlWriter::writeConjugHeader( QDomElement &domElementParent, QList<KEduVocConjugation> &curr_conjug )
594 {
595     /*
596      <conjugation>    used in header for definition of "prefix"
597       <e l="de">      lang determines also lang order in entries !!
598        <s1>I</s1>     which must NOT differ
599        <s2>you<2>
600        <s3f common="0">he</s3f>
601        <s3m>she</s3m>
602        <s3n>it</s3n>
603        <p1>we</p1>
604        <p2>you</p2>
605        <p3f common="1">they</p3f>
606        <p3m>they</p3m>
607        <p3n>they</p3n>
608       </e>
609      </conjugation>
610 
611     */
612     if ( curr_conjug.size() == 0 )
613         return true;
614 
615     QDomElement domElementConjug = m_domDoc.createElement( KV_CONJUG_GRP );
616     QString s;
617 
618     for ( int ent = 0; ent < qMin( curr_conjug.count(), m_doc->identifierCount() ); ent++ ) {
619         QDomElement domElementEntry = m_domDoc.createElement( KV_CON_ENTRY );
620 
621         s = m_doc->identifier( ent ).name().simplified();
622         if ( s.isEmpty() ) {
623             s.setNum( ent );
624             s.prepend( QLatin1String("translation ") );
625         }
626 
627         domElementEntry.setAttribute( KV_LANG, s );
628         if ( !writeConjug(domElementEntry, curr_conjug[ent], "--" ) )
629             return false;
630 
631         domElementConjug.appendChild( domElementEntry );
632     }
633 
634     domElementParent.appendChild( domElementConjug );
635     return true;
636 }
637 
638 
writeConjugEntry(QDomElement & domElementParent,KEduVocTranslation & translation)639 bool KEduVocKvtmlWriter::writeConjugEntry( QDomElement &domElementParent, KEduVocTranslation &translation )
640 /*
641  <conjugation>    in entry for definition of tenses of (irreg.) verbs
642   <t n="sipa">
643    <s1>go</s1>
644    <s2>go</s2>
645    <s3f>goes</s3f>
646    <s3m>goes</s3m>
647    <s3n>goes</s3n>
648    <p1>go</p1>
649    <p2>go</p2>
650    <p3f>go</p3f>
651    <p3m>go</p3m>
652    <p3n>go</p3n>
653   </t>
654  </conjugation>
655 */
656 {
657 
658 //     curr_conjug.cleanUp();
659     QDomElement domElementConjug = m_domDoc.createElement( KV_CONJUG_GRP );
660 
661     foreach ( const QString &tense, translation.conjugationTenses() ) {
662         QDomElement domElementType = m_domDoc.createElement( KV_CON_TYPE );
663 
664         domElementType.setAttribute( KV_CON_NAME, m_compability.oldTense(tense) );
665 
666         if ( !writeConjug(domElementType, translation.conjugation(tense), m_compability.oldTense(tense) ) )
667             return false;
668 
669         domElementConjug.appendChild( domElementType );
670     }
671 
672     domElementParent.appendChild( domElementConjug );
673     return true;
674 }
675 
676 
writeConjug(QDomElement & domElementParent,const KEduVocConjugation & curr_conjug,const QString & type)677 bool KEduVocKvtmlWriter::writeConjug( QDomElement &domElementParent, const KEduVocConjugation &curr_conjug, const QString &type )
678 {
679 ///@todo if we are to enable the writer: port this!
680 /*
681     if ( !curr_conjug.pers1Singular().isEmpty() ) {
682         QDomElement domElementP1s = m_domDoc.createElement( KV_CON_P1S );
683         QDomText domTextP1s = m_domDoc.createTextNode( curr_conjug.pers1Singular() );
684 
685         domElementP1s.appendChild( domTextP1s );
686         domElementParent.appendChild( domElementP1s );
687     }
688 
689     if ( !curr_conjug.pers2Singular().isEmpty() ) {
690         QDomElement domElementP2s = m_domDoc.createElement( KV_CON_P2S );
691         QDomText domTextP2s = m_domDoc.createTextNode( curr_conjug.pers2Singular() );
692 
693         domElementP2s.appendChild( domTextP2s );
694         domElementParent.appendChild( domElementP2s );
695     }
696 
697     if ( !curr_conjug.pers3FemaleSingular().isEmpty() || curr_conjug.pers3SingularCommon() ) {
698         QDomElement domElementP3sf = m_domDoc.createElement( KV_CON_P3SF );
699         QDomText domTextP3sf = m_domDoc.createTextNode( curr_conjug.pers3FemaleSingular() );
700 
701         if ( curr_conjug.pers3SingularCommon() )
702             domElementP3sf.setAttribute( KV_CONJ_COMMON, 1 );
703 
704         domElementP3sf.appendChild( domTextP3sf );
705         domElementParent.appendChild( domElementP3sf );
706     }
707 
708     if ( !curr_conjug.pers3MaleSingular().isEmpty() ) {
709         QDomElement domElementP3sm = m_domDoc.createElement( KV_CON_P3SM );
710         QDomText domTextP3sm = m_domDoc.createTextNode( curr_conjug.pers3MaleSingular() );
711 
712         domElementP3sm.appendChild( domTextP3sm );
713         domElementParent.appendChild( domElementP3sm );
714     }
715 
716     if ( !curr_conjug.pers3NaturalSingular().isEmpty() ) {
717         QDomElement domElementP3sn = m_domDoc.createElement( KV_CON_P3SN );
718         QDomText domTextP3sn = m_domDoc.createTextNode( curr_conjug.pers3NaturalSingular() );
719 
720         domElementP3sn.appendChild( domTextP3sn );
721         domElementParent.appendChild( domElementP3sn );
722     }
723 
724     if ( !curr_conjug.pers1Plural().isEmpty() ) {
725         QDomElement domElementP1p = m_domDoc.createElement( KV_CON_P1P );
726         QDomText domTextP1p = m_domDoc.createTextNode( curr_conjug.pers1Plural() );
727 
728         domElementP1p.appendChild( domTextP1p );
729         domElementParent.appendChild( domElementP1p );
730     }
731 
732     if ( !curr_conjug.pers2Plural().isEmpty() ) {
733         QDomElement domElementP2p = m_domDoc.createElement( KV_CON_P2P );
734         QDomText domTextP2p = m_domDoc.createTextNode( curr_conjug.pers2Plural() );
735 
736         domElementP2p.appendChild( domTextP2p );
737         domElementParent.appendChild( domElementP2p );
738     }
739 
740     if ( !curr_conjug.pers3FemalePlural().isEmpty() || curr_conjug.pers3PluralCommon() ) {
741         QDomElement domElementP3pf = m_domDoc.createElement( KV_CON_P3PF );
742         QDomText domTextP3pf = m_domDoc.createTextNode( curr_conjug.pers3FemalePlural() );
743 
744         if ( curr_conjug.pers3PluralCommon() )
745             domElementP3pf.setAttribute( KV_CONJ_COMMON, 1 );
746 
747         domElementP3pf.appendChild( domTextP3pf );
748         domElementParent.appendChild( domElementP3pf );
749     }
750 
751     if ( !curr_conjug.pers3MalePlural().isEmpty() ) {
752         QDomElement domElementP3pm = m_domDoc.createElement( KV_CON_P3PM );
753         QDomText domTextP3pm = m_domDoc.createTextNode( curr_conjug.pers3MalePlural() );
754 
755         domElementP3pm.appendChild( domTextP3pm );
756         domElementParent.appendChild( domElementP3pm );
757     }
758 
759     if ( !curr_conjug.pers3NaturalPlural().isEmpty() ) {
760         QDomElement domElementP3pn = m_domDoc.createElement( KV_CON_P3PN );
761         QDomText domTextP3pn = m_domDoc.createTextNode( curr_conjug.pers3NaturalPlural() );
762 
763         domElementP3pn.appendChild( domTextP3pn );
764         domElementParent.appendChild( domElementP3pn );
765     }
766 
767     return true; */
768     qDebug() << "Implement me!";
769     return false;
770 }
771 
writePersonalPronouns(QDomElement & domElementParent,QList<KEduVocPersonalPronoun> & curr_conjug)772 bool KEduVocKvtmlWriter::writePersonalPronouns( QDomElement &domElementParent, QList<KEduVocPersonalPronoun> &curr_conjug )
773 {
774     /*
775      <conjugation>    used in header for definition of "prefix"
776       <e l="de">      lang determines also lang order in entries !!
777        <s1>I</s1>     which must NOT differ
778        <s2>you<2>
779        <s3f common="0">he</s3f>
780        <s3m>she</s3m>
781        <s3n>it</s3n>
782        <p1>we</p1>
783        <p2>you</p2>
784        <p3f common="1">they</p3f>
785        <p3m>they</p3m>
786        <p3n>they</p3n>
787       </e>
788      </conjugation>
789     */
790     const QString type = QString::fromLatin1("--");
791 
792     if ( curr_conjug.size() == 0 )
793         return true;
794 
795     QDomElement domElementConjug = m_domDoc.createElement( KV_CONJUG_GRP );
796     QString s;
797 
798     for ( int ent = 0; ent < qMin( curr_conjug.count(), m_doc->identifierCount() ); ent++ ) {
799         QDomElement domElementEntry = m_domDoc.createElement( KV_CON_ENTRY );
800 
801         s = m_doc->identifier( ent ).name().simplified();
802         if ( s.isEmpty() ) {
803             s.setNum( ent );
804             s.prepend( QLatin1String("translation ") );
805         }
806 
807         domElementEntry.setAttribute( KV_LANG, s );
808         if ( !writePersonalPronounChild(domElementEntry, curr_conjug[ent] ) )
809             return false;
810 
811         domElementConjug.appendChild( domElementEntry );
812     }
813 
814     domElementParent.appendChild( domElementConjug );
815     return true;
816 }
817 
818 
writePersonalPronounChild(QDomElement & domElementParent,const KEduVocPersonalPronoun & curr_conjug)819 bool KEduVocKvtmlWriter::writePersonalPronounChild( QDomElement &domElementParent, const KEduVocPersonalPronoun &curr_conjug )
820 {
821     // the old stuff only has singular
822     const KEduVocWordFlag::ConjugationNumber num = KEduVocWordFlag::Singular;
823 
824     if ( !curr_conjug.personalPronoun( KEduVocWordFlag::First, num ).isEmpty() ) {
825         domElementParent.appendChild( newTextElement( KV_CON_P1S, curr_conjug.personalPronoun( KEduVocWordFlag::First, num ) ) );
826     }
827 
828     if ( !curr_conjug.personalPronoun( KEduVocWordFlag::Second, num ).isEmpty() ) {
829         domElementParent.appendChild( newTextElement( KV_CON_P2S, curr_conjug.personalPronoun( KEduVocWordFlag::Second, num ) ) );
830     }
831 
832     ///@todo if the writer ever becomes enabled, write the other pronouns
833 /*
834     if ( !curr_conjug.pers2Singular().isEmpty() ) {
835         QDomElement domElementP2s = m_domDoc.createElement( KV_CON_P2S );
836         QDomText domTextP2s = m_domDoc.createTextNode( curr_conjug.pers2Singular() );
837 
838         domElementP2s.appendChild( domTextP2s );
839         domElementParent.appendChild( domElementP2s );
840     }
841 
842     if ( !curr_conjug.pers3FemaleSingular().isEmpty() || curr_conjug.pers3SingularCommon() ) {
843         QDomElement domElementP3sf = m_domDoc.createElement( KV_CON_P3SF );
844         QDomText domTextP3sf = m_domDoc.createTextNode( curr_conjug.pers3FemaleSingular() );
845 
846         if ( curr_conjug.pers3SingularCommon() )
847             domElementP3sf.setAttribute( KV_CONJ_COMMON, 1 );
848 
849         domElementP3sf.appendChild( domTextP3sf );
850         domElementParent.appendChild( domElementP3sf );
851     }
852 
853     if ( !curr_conjug.pers3MaleSingular().isEmpty() ) {
854         QDomElement domElementP3sm = m_domDoc.createElement( KV_CON_P3SM );
855         QDomText domTextP3sm = m_domDoc.createTextNode( curr_conjug.pers3MaleSingular() );
856 
857         domElementP3sm.appendChild( domTextP3sm );
858         domElementParent.appendChild( domElementP3sm );
859     }
860 
861     if ( !curr_conjug.pers3NaturalSingular().isEmpty() ) {
862         QDomElement domElementP3sn = m_domDoc.createElement( KV_CON_P3SN );
863         QDomText domTextP3sn = m_domDoc.createTextNode( curr_conjug.pers3NaturalSingular() );
864 
865         domElementP3sn.appendChild( domTextP3sn );
866         domElementParent.appendChild( domElementP3sn );
867     }
868 
869     if ( !curr_conjug.pers1Plural().isEmpty() ) {
870         QDomElement domElementP1p = m_domDoc.createElement( KV_CON_P1P );
871         QDomText domTextP1p = m_domDoc.createTextNode( curr_conjug.pers1Plural() );
872 
873         domElementP1p.appendChild( domTextP1p );
874         domElementParent.appendChild( domElementP1p );
875     }
876 
877     if ( !curr_conjug.pers2Plural().isEmpty() ) {
878         QDomElement domElementP2p = m_domDoc.createElement( KV_CON_P2P );
879         QDomText domTextP2p = m_domDoc.createTextNode( curr_conjug.pers2Plural() );
880 
881         domElementP2p.appendChild( domTextP2p );
882         domElementParent.appendChild( domElementP2p );
883     }
884 
885     if ( !curr_conjug.pers3FemalePlural().isEmpty() || curr_conjug.pers3PluralCommon() ) {
886         QDomElement domElementP3pf = m_domDoc.createElement( KV_CON_P3PF );
887         QDomText domTextP3pf = m_domDoc.createTextNode( curr_conjug.pers3FemalePlural() );
888 
889         if ( curr_conjug.pers3PluralCommon() )
890             domElementP3pf.setAttribute( KV_CONJ_COMMON, 1 );
891 
892         domElementP3pf.appendChild( domTextP3pf );
893         domElementParent.appendChild( domElementP3pf );
894     }
895 
896     if ( !curr_conjug.pers3MalePlural().isEmpty() ) {
897         QDomElement domElementP3pm = m_domDoc.createElement( KV_CON_P3PM );
898         QDomText domTextP3pm = m_domDoc.createTextNode( curr_conjug.pers3MalePlural() );
899 
900         domElementP3pm.appendChild( domTextP3pm );
901         domElementParent.appendChild( domElementP3pm );
902     }
903 
904     if ( !curr_conjug.pers3NaturalPlural().isEmpty() ) {
905         QDomElement domElementP3pn = m_domDoc.createElement( KV_CON_P3PN );
906         QDomText domTextP3pn = m_domDoc.createTextNode( curr_conjug.pers3NaturalPlural() );
907 
908         domElementP3pn.appendChild( domTextP3pn );
909         domElementParent.appendChild( domElementP3pn );
910     }*/
911 
912     return true;
913 }
914 
newTextElement(const QString & elementName,const QString & text)915 QDomElement KEduVocKvtmlWriter::newTextElement( const QString &elementName, const QString &text )
916 {
917     QDomElement retval = m_domDoc.createElement( elementName );
918     QDomText textNode = m_domDoc.createTextNode( text );
919     retval.appendChild( textNode );
920     return retval;
921 }
922 
923 
924