1 /***************************************************************************
5 read big body of a kvtml document
7 -----------------------------------------------------------------------
9 begin : Thu Mar 11 20:50:53 MET 1999
11 copyright : (C) 1999-2001 Ewald Arnold
12 (C) 2001 The KDE-EDU team
13 email : kvoctrain@ewald-arnold.de
15 -----------------------------------------------------------------------
17 ***************************************************************************/
19 /***************************************************************************
21 * This program is free software; you can redistribute it and/or modify *
22 * it under the terms of the GNU General Public License as published by *
23 * the Free Software Foundation; either version 2 of the License, or *
24 * (at your option) any later version. *
26 ***************************************************************************/
29 #include "QueryManager.h"
30 #include "UsageManager.h"
32 #include <kapplication.h>
34 #include <kmessagebox.h>
36 bool kvoctrainDoc::extract_T_DESCR_attr (XmlReader
&xml
,
37 XmlElement
&elem
, int &no
)
40 list
<XmlAttribute
>::const_iterator first
= elem
.attributes ().begin ();
41 while (first
!= elem
.attributes ().end ()) {
42 if ((*first
).name () == KV_LESS_NO
)
43 no
= (*first
).intValue();
45 if (!unknownAttribute(xml
.lineNumber(), "descr", (*first
).name ()))
54 bool kvoctrainDoc::extract_T_GROUP_attr (XmlReader
&xml
,
57 list
<XmlAttribute
>::const_iterator first
= elem
.attributes ().begin ();
58 while (first
!= elem
.attributes ().end ()) {
60 if ((*first).name () == KV_SIZEHINT)
61 width = (*first).intValue();
63 if (!unknownAttribute(xml
.lineNumber(), "type", (*first
).name ()))
72 bool kvoctrainDoc::loadTypeNameKvtMl (XmlElement elem
, XmlReader
& xml
)
74 bool endOfGroup
= false;
78 if (!extract_T_GROUP_attr (xml
, elem
))
82 if (! xml
.readElement (elem
))
85 if (elem
.tag () == KV_TYPE_GRP
) {
86 if (! elem
.isEndTag ()) {
87 errorKvtMl (xml
.lineNumber(),
88 i18n("expected ending tag <%1>").arg(KV_TYPE_GRP
));
95 else if (elem
.tag () == KV_TYPE_DESC
&& !elem
.isEndTag() ) {
97 if (!extract_T_DESCR_attr (xml
, elem
, no
))
100 if (!xml
.readElement (elem
)) {
101 errorKvtMl (xml
.lineNumber(), i18n("I/O failure") );
105 if (elem
.tag() == "#PCDATA") { // element data
108 if (! xml
.readElement (elem
) ) {
109 errorKvtMl (xml
.lineNumber(), i18n("I/O failure") );
112 else if (elem
.tag() != KV_TYPE_DESC
|| !elem
.isEndTag() ) {
113 errorKvtMl (xml
.lineNumber(),
114 i18n("expected ending tag <%1>").arg(KV_TYPE_DESC
));
119 if (elem
.tag() != KV_TYPE_DESC
|| !elem
.isEndTag() ) {
120 errorKvtMl (xml
.lineNumber(),
121 i18n("expected ending tag <%1>").arg(KV_TYPE_DESC
));
127 type_descr
.push_back (s
);
130 if (elem
.isEndTag() ) {
131 errorKvtMl (xml
.lineNumber(),
132 i18n("unexpected ending tag <%1>" ).arg(elem
.tag()));
136 unknownElement (xml
.lineNumber(), elem
.tag() );
140 } while (! endOfGroup
);
146 bool kvoctrainDoc::loadTenseNameKvtMl (XmlElement elem
, XmlReader
& xml
)
148 bool endOfGroup
= false;
152 if (!extract_T_GROUP_attr (xml
, elem
))
156 if (! xml
.readElement (elem
))
159 if (elem
.tag () == KV_TENSE_GRP
) {
160 if (! elem
.isEndTag ()) {
161 errorKvtMl (xml
.lineNumber(),
162 i18n("expected ending tag <%1>").arg(KV_TENSE_GRP
));
169 else if (elem
.tag () == KV_TENSE_DESC
&& !elem
.isEndTag() ) {
171 if (!extract_T_DESCR_attr (xml
, elem
, no
))
174 if (!xml
.readElement (elem
)) {
175 errorKvtMl (xml
.lineNumber(), i18n("I/O failure") );
179 if (elem
.tag() == "#PCDATA") { // element data
182 if (! xml
.readElement (elem
) ) {
183 errorKvtMl (xml
.lineNumber(), i18n("I/O failure") );
186 else if (elem
.tag() != KV_TENSE_DESC
|| !elem
.isEndTag() ) {
187 errorKvtMl (xml
.lineNumber(),
188 i18n("expected ending tag <%1>").arg(KV_TENSE_DESC
));
193 if (elem
.tag() != KV_TENSE_DESC
|| !elem
.isEndTag() ) {
194 errorKvtMl (xml
.lineNumber(),
195 i18n("expected ending tag <%1>").arg(KV_TENSE_DESC
));
201 tense_descr
.push_back (s
);
204 if (elem
.isEndTag() ) {
205 errorKvtMl (xml
.lineNumber(),
206 i18n("unexpected ending tag <%1>" ).arg(elem
.tag()));
210 unknownElement (xml
.lineNumber(), elem
.tag() );
214 } while (! endOfGroup
);
220 bool kvoctrainDoc::loadUsageNameKvtMl (XmlElement elem
, XmlReader
& xml
)
222 bool endOfGroup
= false;
226 if (!extract_T_GROUP_attr (xml
, elem
))
230 if (! xml
.readElement (elem
))
233 if (elem
.tag () == KV_USAGE_GRP
) {
234 if (! elem
.isEndTag ()) {
235 errorKvtMl (xml
.lineNumber(),
236 i18n("expected ending tag <%1>").arg(KV_USAGE_GRP
));
243 else if (elem
.tag () == KV_USAGE_DESC
&& !elem
.isEndTag() ) {
245 if (!extract_T_DESCR_attr (xml
, elem
, no
))
248 if (!xml
.readElement (elem
)) {
249 errorKvtMl (xml
.lineNumber(), i18n("I/O failure") );
253 if (elem
.tag() == "#PCDATA") { // element data
256 if (! xml
.readElement (elem
) ) {
257 errorKvtMl (xml
.lineNumber(), i18n("I/O failure") );
260 else if (elem
.tag() != KV_USAGE_DESC
|| !elem
.isEndTag() ) {
261 errorKvtMl (xml
.lineNumber(),
262 i18n("expected ending tag <%1>").arg(KV_USAGE_DESC
));
267 if (elem
.tag() != KV_USAGE_DESC
|| !elem
.isEndTag() ) {
268 errorKvtMl (xml
.lineNumber(),
269 i18n("expected ending tag <%1>").arg(KV_USAGE_DESC
));
275 usage_descr
.push_back (s
);
278 if (elem
.isEndTag() ) {
279 errorKvtMl (xml
.lineNumber(),
280 i18n("unexpected ending tag <%1>" ).arg(elem
.tag()));
284 unknownElement (xml
.lineNumber(), elem
.tag() );
288 } while (! endOfGroup
);
294 bool kvoctrainDoc::extract_O_T_attr (
298 grade_t
&grade
, grade_t
&rev_grade
,
299 int &count
, int &rev_count
,
300 time_t &date
, time_t &rev_date
,
302 int &bcount
, int &rev_bcount
,
315 grade
= KV_NORM_GRADE
;
316 rev_grade
= KV_NORM_GRADE
;
336 list
<XmlAttribute
>::const_iterator first
= elem
.attributes ().begin ();
338 while (first
!= elem
.attributes ().end ()) {
340 if ((*first
).name () == KV_LANG
)
341 lang
= (*first
).stringValue();
343 else if ((*first
).name () == KV_SIZEHINT
)
344 width
= (*first
).intValue();
346 else if ((*first
).name () == KV_CHARSET
) {
349 else if ((*first
).name () == KV_GRADE
) {
350 QString s
= (*first
).stringValue();
352 if ((pos
= s
.find(';')) >= 1) {
353 grade
= s
.left(pos
).toInt();
354 rev_grade
= s
.mid(pos
+1, s
.length()).toInt();
360 else if ((*first
).name () == KV_COUNT
) {
361 QString s
= (*first
).stringValue();
362 if ((pos
= s
.find(';')) >= 1) {
363 count
= s
.left(pos
).toInt();
364 rev_count
= s
.mid(pos
+1, s
.length()).toInt();
370 else if ((*first
).name () == KV_BAD
) {
371 QString s
= (*first
).stringValue();
372 if ((pos
= s
.find(';')) >= 1) {
373 bcount
= s
.left(pos
).toInt();
374 rev_bcount
= s
.mid(pos
+1, s
.length()).toInt();
379 else if ((*first
).name () == KV_DATE
) {
380 QString s
= (*first
).stringValue();
381 if ((pos
= s
.find(';')) >= 1) {
382 date
= s
.left(pos
).toInt();
383 rev_date
= s
.mid(pos
+1, s
.length()).toInt();
390 else if ((*first
).name () == KV_DATE2
) {
391 QString s
= (*first
).stringValue();
392 if ((pos
= s
.find(';')) >= 1) {
393 date
= decompressDate (s
.left(pos
));
394 rev_date
= decompressDate (s
.mid(pos
+1, s
.length()));
397 date
= decompressDate (s
);
401 else if ((*first
).name () == KV_REMARK
) {
402 remark
= (*first
).stringValue();
405 else if ((*first
).name () == KV_FAUX_AMI_F
) {
406 faux_ami_f
= (*first
).stringValue();
409 else if ((*first
).name () == KV_FAUX_AMI_T
) {
410 faux_ami_t
= (*first
).stringValue();
413 else if ((*first
).name () == KV_SYNONYM
) {
414 synonym
= (*first
).stringValue();
417 else if ((*first
).name () == KV_EXAMPLE
) {
418 example
= (*first
).stringValue();
421 else if ((*first
).name () == KV_USAGE
) {
422 usage
= (*first
).stringValue();
424 if (usage
.length() != 0 && usage
.left(1) == UL_USER_USAGE
) {
425 int num
= QMIN(usage
.mid (1, 40).toInt(), 1000); // paranioa check
426 if( num
> (int) usage_descr
.size() ) { // description missing ?
428 for (int i
= usage_descr
.size(); i
< num
; i
++) {
430 s
.insert (0, "#"); // invent descr according to number
431 usage_descr
.push_back (s
);
437 else if ((*first
).name () == KV_PARAPHRASE
) {
438 paraphrase
= (*first
).stringValue();
441 else if ((*first
).name () == KV_ANTONYM
) {
442 antonym
= (*first
).stringValue();
445 else if ((*first
).name () == KV_EXPRTYPE
) {
446 type
= (*first
).stringValue();
449 else if (type
== "2") // convert from pre-0.5 versions
451 else if (type
== "3")
454 if (type
.length() != 0 && type
.left(1) == QM_USER_TYPE
) {
455 int num
= QMIN(type
.mid (1, 40).toInt(), 1000); // paranoia check
456 if( num
> (int) type_descr
.size() ) { // description missing ?
458 for (int i
= type_descr
.size(); i
< num
; i
++) {
460 s
.insert (0, "#"); // invent descr according to number
461 type_descr
.push_back (s
);
467 else if ((*first
).name () == KV_PRONUNCE
) {
468 pronunce
= (*first
).stringValue();
471 else if ((*first
).name () == KV_QUERY
) {
472 query_id
= (*first
).stringValue();
476 if (!unknownAttribute(xml
.lineNumber(), "o> or <t", (*first
).name ()))
486 bool kvoctrainDoc::extract_KVT_E_attr (
498 list
<XmlAttribute
>::const_iterator first
= elem
.attributes ().begin ();
499 while (first
!= elem
.attributes ().end ()) {
500 if ((*first
).name () == KV_LESS_MEMBER
)
501 lesson
= (*first
).intValue();
502 else if ((*first
).name () == KV_SELECTED
)
503 sel
= (*first
).intValue() != 0;
504 else if ((*first
).name () == KV_INACTIVE
)
505 active
= !(*first
).intValue() != 0;
506 else if ((*first
).name () == KV_EXPRTYPE
) {
507 type
= (*first
).stringValue();
510 else if (type
== "2") // convert from pre-0.5 versions
512 else if (type
== "3")
515 if (type
.length() != 0 && type
.left(1) == QM_USER_TYPE
) {
516 int num
= QMIN(type
.mid (1, 40).toInt(), 1000); // paranoia check
517 if( num
> (int) type_descr
.size() ) { // description missing ?
519 for (int i
= type_descr
.size(); i
< num
; i
++) {
521 s
.insert (0, "#"); // invent descr according to number
522 type_descr
.push_back (s
);
528 if (!unknownAttribute(xml
.lineNumber(), "e", (*first
).name ()))
537 bool kvoctrainDoc::loadComparison (Comparison
&comp
, XmlElement elem
,
547 bool endOfGroup
= false;
552 if (! xml
.readElement (elem
))
555 if (elem
.tag () == KV_COMPARISON_GRP
) {
556 if (! elem
.isEndTag ()) {
557 errorKvtMl (xml
.lineNumber(),
558 i18n("expected ending tag <%1>").arg(elem
.tag()));
566 else if (elem
.tag () == KV_COMP_L1
&& !elem
.isEndTag() ) {
567 if (!extract_simple_tag (KV_COMP_L1
, xml
, elem
, s
))
572 else if (elem
.tag () == KV_COMP_L2
&& !elem
.isEndTag() ) {
573 if (!extract_simple_tag (KV_COMP_L2
, xml
, elem
, s
))
578 else if (elem
.tag () == KV_COMP_L3
&& !elem
.isEndTag() ) {
579 if (!extract_simple_tag (KV_COMP_L3
, xml
, elem
, s
))
585 if (elem
.isEndTag() ) {
586 errorKvtMl (xml
.lineNumber(),
587 i18n("unexpected ending tag <%1>").arg(elem
.tag()));
591 unknownElement (xml
.lineNumber(), elem
.tag() );
595 } while (! endOfGroup
);
601 bool kvoctrainDoc::loadMultipleChoice (MultipleChoice
&mc
, XmlElement elem
,
614 bool endOfGroup
= false;
619 if (! xml
.readElement (elem
))
622 if (elem
.tag () == KV_MULTIPLECHOICE_GRP
) {
623 if (! elem
.isEndTag ()) {
624 errorKvtMl (xml
.lineNumber(),
625 i18n("expected ending tag <%1>").arg(elem
.tag()));
633 else if (elem
.tag () == KV_MC_1
&& !elem
.isEndTag() ) {
634 if (!extract_simple_tag (KV_MC_1
, xml
, elem
, s
))
639 else if (elem
.tag () == KV_MC_2
&& !elem
.isEndTag() ) {
640 if (!extract_simple_tag (KV_MC_2
, xml
, elem
, s
))
645 else if (elem
.tag () == KV_MC_3
&& !elem
.isEndTag() ) {
646 if (!extract_simple_tag (KV_MC_3
, xml
, elem
, s
))
651 else if (elem
.tag () == KV_MC_4
&& !elem
.isEndTag() ) {
652 if (!extract_simple_tag (KV_MC_4
, xml
, elem
, s
))
657 else if (elem
.tag () == KV_MC_5
&& !elem
.isEndTag() ) {
658 if (!extract_simple_tag (KV_MC_5
, xml
, elem
, s
))
664 if (elem
.isEndTag() ) {
665 errorKvtMl (xml
.lineNumber(),
666 i18n("unexpected ending tag <%1>").arg(elem
.tag()));
670 unknownElement (xml
.lineNumber(), elem
.tag() );
674 } while (! endOfGroup
);
681 bool kvoctrainDoc::parseBody_kvtml (XmlElement elem
, XmlReader
& xml
)
683 bool endOfBody
= false;
684 bool lessgroup
= false;
685 bool optgroup
= false;
686 bool attrgroup
= false;
687 bool tensegroup
= false;
688 bool usagegroup
= false;
689 bool articlegroup
= false;
690 bool conjuggroup
= false;
693 int ent_percent
= (int) lines
/ 100;
694 float f_ent_percent
= (int) lines
/ 100.0;
696 emit
progressChanged(this, 0);
699 if (! xml
.readElement (elem
) ) {
700 errorKvtMl (xml
.lineNumber(), i18n("I/O failure") );
704 if (elem
.tag () == KV_DOCTYPE
) {
705 if (! elem
.isEndTag ()) {
706 errorKvtMl (xml
.lineNumber(),
707 i18n("expected ending tag <%1>").arg(elem
.tag()));
714 else if (elem
.tag () == KV_LESS_GRP
&& !elem
.isEndTag() ) {
716 errorKvtMl (xml
.lineNumber(),
717 i18n("repeated occurrence of tag <%1>").arg(elem
.tag()));
721 if (!loadLessonKvtMl (elem
, xml
))
725 else if (elem
.tag () == KV_ARTICLE_GRP
&& !elem
.isEndTag() ) {
727 errorKvtMl (xml
.lineNumber(),
728 i18n("repeated occurrence of tag <%1>").arg(elem
.tag()));
732 if (!loadArticleKvtMl (elem
, xml
))
736 else if (elem
.tag () == KV_CONJUG_GRP
&& !elem
.isEndTag() ) {
738 errorKvtMl (xml
.lineNumber(),
739 i18n("repeated occurrence of tag <%1>").arg(elem
.tag()));
743 if (!loadConjugKvtMl (conjugations
, KV_CON_ENTRY
, elem
, xml
))
747 else if (elem
.tag () == KV_OPTION_GRP
&& !elem
.isEndTag() ) {
749 errorKvtMl (xml
.lineNumber(),
750 i18n("repeated occurrence of tag <%1>").arg(elem
.tag()));
754 if (!loadOptionsKvtMl (elem
, xml
))
758 else if (elem
.tag () == KV_TYPE_GRP
&& !elem
.isEndTag() ) {
760 errorKvtMl (xml
.lineNumber(),
761 i18n("repeated occurrence of tag <%1>").arg(elem
.tag()));
765 if (!loadTypeNameKvtMl (elem
, xml
))
769 else if (elem
.tag () == KV_TENSE_GRP
&& !elem
.isEndTag() ) {
771 errorKvtMl (xml
.lineNumber(),
772 i18n("repeated occurrence of tag <%1>").arg(elem
.tag()));
776 if (!loadTenseNameKvtMl (elem
, xml
))
778 // Conjugation::setTenseNames(tense_descr);
781 else if (elem
.tag () == KV_USAGE_GRP
&& !elem
.isEndTag() ) {
783 errorKvtMl (xml
.lineNumber(),
784 i18n("repeated occurrence of tag <%1>").arg(elem
.tag()));
788 if (!loadUsageNameKvtMl (elem
, xml
))
792 else if (elem
.tag () == KV_EXPR
&& !elem
.isEndTag() ) {
793 // found expression <e>
797 if (ent_percent
!= 0 && (ent_no
% ent_percent
) == 0 )
798 emit
progressChanged(this, ent_no
/ f_ent_percent
);
800 if (!parseBody_e (elem
, xml
)) return false;
804 if (elem
.isEndTag() ) {
805 errorKvtMl (xml
.lineNumber(),
806 i18n("unexpected ending tag <%1>" ).arg(elem
.tag()));
810 unknownElement (xml
.lineNumber(), elem
.tag());
815 } while (! endOfBody
);
821 bool kvoctrainDoc::unknownAttribute (int line
, const QString
&name
,
822 const QString
&attr
)
824 if (unknown_attr
) // show dialog only once
825 return true; // proceed
829 QString ln
= i18n("File:\t%1\nLine:\t%2\n").arg(URL().path()).arg(line
);
831 QString format
= i18n(
832 "Your document contains an unknown attribute <%1> " // keep trailing space
834 "Maybe your version of KVocTrain is too old, "
835 "or the document is damaged.\n"
836 "If you proceed and save afterwards you are likely to lose data;\n"
837 "do you want to proceed anyway?\n"
839 QString msg
= format
.arg(attr
).arg(name
);
841 QApplication::setOverrideCursor( arrowCursor
, true );
842 QString s
= kapp
->makeStdCaption(i18n("Unknown attribute"));
843 bool result
= (KMessageBox::warningContinueCancel(0, ln
+msg
, s
) == KMessageBox::Continue
);
844 QApplication::restoreOverrideCursor();
849 void kvoctrainDoc::unknownElement (int line
, const QString
&elem
)
853 QString ln
= i18n("File:\t%1\nLine:\t%2\n").arg(URL().path()).arg(line
);
855 QString format
= i18n(
856 "Your document contains an unknown tag <%1>. " // keep trailing space
857 "Maybe your version of KVocTrain is too old, "
858 "or the document is damaged.\n"
859 "Loading is aborted because KVocTrain cannot "
860 "read documents with unknown elements.\n"
862 QString msg
= format
.arg(elem
);
863 QApplication::setOverrideCursor( arrowCursor
, true );
864 QString s
= kapp
->makeStdCaption(i18n("Unknown element"));
865 KMessageBox::sorry(0, ln
+msg
, s
);
866 QApplication::restoreOverrideCursor();
870 void kvoctrainDoc::errorKvtMl (int line
, const QString
&text
)
872 QApplication::setOverrideCursor( arrowCursor
, true );
873 QString s
= kapp
->makeStdCaption(i18n("Error"));
874 QString ln
= i18n("File:\t%1\nLine:\t%2\n").arg(URL().path()).arg(line
);
877 KMessageBox::error(0, ln
+msg
, s
);
878 QApplication::restoreOverrideCursor();
882 void kvoctrainDoc::warningKvtMl (int line
, const QString
&text
)
884 QApplication::setOverrideCursor( arrowCursor
, true );
885 QString s
= kapp
->makeStdCaption(i18n("Warning"));
886 QString ln
= i18n("File:\t%1\nLine:\t%2\n").arg(URL().path()).arg(line
);
888 KMessageBox::information(0, ln
+msg
, s
);
889 QApplication::restoreOverrideCursor();