ProcessDocument.cpp
1/*
2 This file is part of the KDE project
3 Copyright (C) 2001, 2002, 2004 Nicolas GOUTTE <goutte@kde.org>
4 Copyright (c) 2001 IABG mbH. All rights reserved.
5 Contact: Wolf-Michael Bolle <Bolle@IABG.de>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21*/
22
23/*
24 This file is based on the old file:
25 /home/kde/koffice/filters/kword/ascii/asciiexport.cpp
26
27 The old file was copyrighted by
28 Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
29 Copyright (c) 2000 ID-PRO Deutschland GmbH. All rights reserved.
30 Contact: Wolf-Michael Bolle <Wolf-Michael.Bolle@GMX.de>
31
32 The old file was licensed under the terms of the GNU Library General Public
33 License version 2.
34*/
35
36/*
37 Part of the code is based on code licensed under the terms of the
38 GNU Library General Public License version 2:
39 Copyright 2001 Michael Johnson <mikej@xnet.com>
40*/
41
42#include <tqdom.h>
43#include <tqvaluelist.h>
44
45#include <kdebug.h>
46
47#include "KWEFStructures.h"
48#include "TagProcessing.h"
49#include "ProcessDocument.h"
50#include "KWEFKWordLeader.h"
51
52
53// == KOFFICE DOCUMENT INFORMATION ==
54
55// TODO: verify that all document info is read!
56
57void ProcessTextTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
58{
59 TQString *tagText = (TQString *) tagData;
60
61 *tagText = myNode.toElement().text(); // Get the text, also from a CDATA section
62
63 TQValueList<TagProcessing> tagProcessingList;
64 tagProcessingList.append ( TagProcessing ( "xml:space" ) );
65 ProcessSubtags (myNode, tagProcessingList, leader);
66
67 AllowNoSubtags (myNode, leader);
68}
69
70static void ProcessAboutTag ( TQDomNode myNode,
71 void *tagData,
72 KWEFKWordLeader *leader )
73{
74 KWEFDocumentInfo *docInfo = (KWEFDocumentInfo *) tagData;
75
76 AllowNoAttributes (myNode);
77
78 TQValueList<TagProcessing> tagProcessingList;
79 tagProcessingList.append ( TagProcessing ( "title", ProcessTextTag, &docInfo->title ) );
80 tagProcessingList.append ( TagProcessing ( "abstract", ProcessTextTag, &docInfo->abstract ) );
81 tagProcessingList.append ( TagProcessing ( "keyword", ProcessTextTag, &docInfo->keywords ) );
82 tagProcessingList.append ( TagProcessing ( "subject", ProcessTextTag, &docInfo->subject ) );
83 ProcessSubtags (myNode, tagProcessingList, leader);
84}
85
86
87static void ProcessAuthorTag ( TQDomNode myNode,
88 void *tagData,
89 KWEFKWordLeader *leader )
90{
91 KWEFDocumentInfo *docInfo = (KWEFDocumentInfo *) tagData;
92
93 AllowNoAttributes (myNode);
94
95 TQValueList<TagProcessing> tagProcessingList;
96 tagProcessingList.append ( TagProcessing ( "full-name", ProcessTextTag, &docInfo->fullName ) );
97 tagProcessingList.append ( TagProcessing ( "title", ProcessTextTag, &docInfo->jobTitle ) );
98 tagProcessingList.append ( TagProcessing ( "company", ProcessTextTag, &docInfo->company ) );
99 tagProcessingList.append ( TagProcessing ( "email", ProcessTextTag, &docInfo->email ) );
100 tagProcessingList.append ( TagProcessing ( "telephone", ProcessTextTag, &docInfo->telephone ) );
101 tagProcessingList.append ( TagProcessing ( "telephone-work", ProcessTextTag, &docInfo->telephonework ) );
102 tagProcessingList.append ( TagProcessing ( "fax", ProcessTextTag, &docInfo->fax ) );
103 tagProcessingList.append ( TagProcessing ( "country", ProcessTextTag, &docInfo->country ) );
104 tagProcessingList.append ( TagProcessing ( "postal-code", ProcessTextTag, &docInfo->postalCode ) );
105 tagProcessingList.append ( TagProcessing ( "city", ProcessTextTag, &docInfo->city ) );
106 tagProcessingList.append ( TagProcessing ( "street", ProcessTextTag, &docInfo->street ) );
107 tagProcessingList.append ( TagProcessing ( "initial", ProcessTextTag, &docInfo->initial ) );
108 tagProcessingList.append ( TagProcessing ( "position", ProcessTextTag, &docInfo->position ) );
109 ProcessSubtags (myNode, tagProcessingList, leader);
110}
111
112
113void ProcessDocumentInfoTag ( TQDomNode myNode,
114 void *,
115 KWEFKWordLeader *leader )
116{
117 AllowNoAttributes (myNode);
118
119 KWEFDocumentInfo docInfo;
120
121 TQValueList<TagProcessing> tagProcessingList;
122 tagProcessingList.append ( TagProcessing ( "log" ) );
123 tagProcessingList.append ( TagProcessing ( "author", ProcessAuthorTag, &docInfo ) );
124 tagProcessingList.append ( TagProcessing ( "about", ProcessAboutTag, &docInfo ) );
125 ProcessSubtags (myNode, tagProcessingList, leader);
126
127 leader->doFullDocumentInfo (docInfo);
128}
129
130
131// == KWORD ==
132
133// Every tag has its own processing function. All of those functions
134// have the same parameters since the functions are passed to
135// ProcessSubtags throuch the TagProcessing class. The top level
136// function is ProcessDocTag and can be called with the node returned
137// by TQDomDocument::documentElement (). The tagData argument can be
138// used to either pass variables down to the subtags or to allow
139// subtags to return values. As a bare minimum the tag processing
140// functions must handle the tag's attributes and the tag's subtags
141// (which it can choose to ignore). Currently implemented is
142// processing for the following tags and attributes:
143//
144// TODO: make this list up-to-date
145//
146// DOC
147// FRAMESETS
148// FRAMESET
149// PARAGRAPH
150// TEXT - Text Element
151// FORMATS
152// FORMAT id=1 pos= len=
153// LAYOUT
154// NAME value=
155
156
157// --------------------------------------------------------------------------------
158
159
160static void ProcessOneAttrTag ( TQDomNode myNode,
161 TQString attrName,
162 TQString attrType,
163 void *attrData,
164 KWEFKWordLeader *leader )
165{
166 TQValueList<AttrProcessing> attrProcessingList;
167 attrProcessingList << AttrProcessing (attrName, attrType, attrData);
168 ProcessAttributes (myNode, attrProcessingList);
169
170 AllowNoSubtags (myNode, leader);
171}
172
173
174static void ProcessColorAttrTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader * )
175{
176 TQColor *attrValue = (TQColor *) tagData;
177
178 int red, green, blue;
179
180 TQValueList<AttrProcessing> attrProcessingList;
181 attrProcessingList << AttrProcessing ( "red", red );
182 attrProcessingList << AttrProcessing ( "green", green );
183 attrProcessingList << AttrProcessing ( "blue", blue );
184 ProcessAttributes (myNode, attrProcessingList);
185
186 attrValue->setRgb (red, green, blue);
187}
188
189
190static void ProcessBoolIntAttrTag ( TQDomNode myNode,
191 TQString attrName,
192 void *attrData,
193 KWEFKWordLeader *leader )
194{
195 ProcessOneAttrTag (myNode, attrName, "bool", attrData, leader);
196}
197
198
199// --------------------------------------------------------------------------------
200
201
202static void ProcessIntValueTag (TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
203{
204 ProcessOneAttrTag (myNode, "value", "int", tagData, leader);
205}
206
207
208static void ProcessBoolIntValueTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
209{
210 ProcessBoolIntAttrTag (myNode, "value", tagData, leader);
211}
212
213
214static void ProcessStringValueTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
215{
216 ProcessOneAttrTag (myNode, "value", "TQString", tagData, leader);
217}
218
219static void ProcessStringNameTag (TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
220{
221 ProcessOneAttrTag (myNode, "name", "TQString", tagData, leader);
222}
223
224
225// --------------------------------------------------------------------------------
226
227
228static void ProcessOldLayoutChildTag (TQDomNode myNode, void *tagData, KWEFKWordLeader* /*leader*/)
229{
230 TQValueList<AttrProcessing> attrProcessingList;
231
232 double* d = (double*) ( tagData );
233 *d = 0.0; // Put a sensible default
234
235 attrProcessingList
236 << AttrProcessing ( "pt", *d )
237 << AttrProcessing ( "inch" )
238 << AttrProcessing ( "mm" )
239 ;
240 ProcessAttributes (myNode, attrProcessingList);
241}
242
243static void ProcessUnderlineTag (TQDomNode myNode, void *tagData, KWEFKWordLeader* /*leader*/ )
244{
245 TextFormatting* text=(TextFormatting*) tagData;
246 TQString str,style;
247 TQString strColor;
248
249 text->underlineWord = false;
250
251 TQValueList<AttrProcessing> attrProcessingList;
252
253 attrProcessingList
254 << AttrProcessing ( "value", str )
255 << AttrProcessing ( "styleline", style )
256 << AttrProcessing ( "wordbyword", text->underlineWord )
257 << AttrProcessing ( "underlinecolor", strColor )
258 ;
259 ProcessAttributes (myNode, attrProcessingList);
260
261 str=str.stripWhiteSpace();
262 text->underlineValue=str;
263 if ( (str=="0") || (str.isEmpty()) )
264 {
265 text->underline=false;
266 }
267 else
268 {
269 // We assume that anything else is underlined
270 text->underline=true;
271 text->underlineStyle = style;
272 text->underlineColor.setNamedColor(strColor);
273 }
274}
275
276static void ProcessStrikeoutTag (TQDomNode myNode, void *tagData, KWEFKWordLeader* /*leader*/ )
277{
278 TextFormatting* text=(TextFormatting*) tagData;
279 TQString type, linestyle;
280
281 text->strikeoutWord = false;
282
283 TQValueList<AttrProcessing> attrProcessingList;
284 attrProcessingList << AttrProcessing ("value" , type );
285 attrProcessingList << AttrProcessing ("styleline" , linestyle );
286 attrProcessingList << AttrProcessing ( "wordbyword", text->strikeoutWord );
287 ProcessAttributes (myNode, attrProcessingList);
288
289 if( type.isEmpty() || ( type == "0" ) )
290 text->strikeout = false;
291 else
292 {
293 text->strikeout = true;
294 text->strikeoutType = type;
295 text->strikeoutLineStyle = linestyle;
296 if( text->strikeoutType == "1" )
297 text->strikeoutType = "single";
298 if( text->strikeoutLineStyle.isEmpty() )
299 text->strikeoutLineStyle = "solid";
300 }
301}
302
303
304void ProcessAnchorTag ( TQDomNode myNode,
305 void *tagData,
306 KWEFKWordLeader *leader )
307{
308 TQString *instance = (TQString *) tagData;
309
310 TQString type;
311 *instance = TQString();
312 TQValueList<AttrProcessing> attrProcessingList;
313 attrProcessingList << AttrProcessing ( "type", type )
314 << AttrProcessing ( "instance", "TQString", instance );
315 ProcessAttributes (myNode, attrProcessingList);
316
317 if ( type != "frameset" )
318 {
319 kdWarning (30508) << "Unknown ANCHOR type " << type << "!" << endl;
320 }
321
322 if ( (*instance).isEmpty () )
323 {
324 kdWarning (30508) << "Bad ANCHOR instance name!" << endl;
325 }
326
327 AllowNoSubtags (myNode, leader);
328}
329
330
331static void ProcessLinkTag (TQDomNode myNode, void *tagData, KWEFKWordLeader *)
332{
333 VariableData *variable = (VariableData *) tagData;
334
335 TQString linkName, hrefName;
336
337 TQValueList<AttrProcessing> attrProcessingList;
338 attrProcessingList.append ( AttrProcessing ("linkName", linkName) );
339 attrProcessingList.append ( AttrProcessing ("hrefName", hrefName) );
340 ProcessAttributes (myNode, attrProcessingList);
341
342 variable->setLink(linkName, hrefName);
343}
344
345
346static void ProcessPgNumTag (TQDomNode myNode, void *tagData, KWEFKWordLeader *)
347{
348 VariableData *variable = (VariableData *) tagData;
349
350 TQString subtype, value;
351
352 TQValueList<AttrProcessing> attrProcessingList;
353 attrProcessingList.append ( AttrProcessing ("subtype", subtype) );
354 attrProcessingList.append ( AttrProcessing ("value", value ) );
355 ProcessAttributes (myNode, attrProcessingList);
356
357 variable->setPgNum(subtype, value);
358}
359
360
361static void ProcessTypeTag (TQDomNode myNode, void *tagData, KWEFKWordLeader *)
362{
363 VariableData *variable = (VariableData *) tagData;
364
365 TQValueList<AttrProcessing> attrProcessingList;
366 attrProcessingList.append ( AttrProcessing ("key", variable->m_key ) );
367 attrProcessingList.append ( AttrProcessing ("text", variable->m_text) );
368 attrProcessingList.append ( AttrProcessing ("type", variable->m_type) );
369 ProcessAttributes (myNode, attrProcessingList);
370}
371
372static void ProcessFieldTag (TQDomNode myNode, void *tagData, KWEFKWordLeader *)
373{
374 VariableData *variable = (VariableData *) tagData;
375 int subtype;
376 TQString name, value;
377
378 TQValueList<AttrProcessing> attrProcessingList;
379 attrProcessingList.append ( AttrProcessing ("subtype", subtype) );
380 attrProcessingList.append ( AttrProcessing ("value", value ) );
381 ProcessAttributes (myNode, attrProcessingList);
382
383 switch( subtype )
384 {
385 case 0: name = "fileName"; break;
386 case 1: name = "dirName"; break;
387 case 2: name = "authorName"; break;
388 case 3: name = "authorEmail"; break;
389 case 4: name = "authorCompany"; break;
390 case 10: name = "docTitle"; break;
391 case 11: name = "docAbstract"; break;
392 case 16: name = "authorInitial"; break;
393 default: break;
394 }
395
396 if(!name.isEmpty())
397 variable->setField(name, value);
398}
399
400static void ProcessFootnoteTag (TQDomNode myNode, void *tagData, KWEFKWordLeader *leader)
401{
402 VariableData *variable = (VariableData *) tagData;
403 TQString frameset, value, numberingtype, notetype;
404
405 TQValueList<AttrProcessing> attrProcessingList;
406 attrProcessingList
407 << AttrProcessing ( "value", value )
408 << AttrProcessing ( "numberingtype", numberingtype )
409 << AttrProcessing ( "frameset", frameset )
410 << AttrProcessing ( "notetype", notetype )
411 ;
412 ProcessAttributes (myNode, attrProcessingList);
413
414 // search for frameset in the footnoteList
415 for(unsigned i=0;i<leader->footnoteList.count();i++)
416 {
417 if( leader->footnoteList[i].frameName == frameset )
418 {
419 variable->setFootnote( notetype, numberingtype, value, &leader->footnoteList[i].para );
420 break;
421 }
422 }
423}
424
425static void ProcessNoteTag (TQDomNode myNode, void *tagData, KWEFKWordLeader *leader)
426{
427 VariableData *variable = (VariableData *) tagData;
428
429 TQString note;
430
431 TQValueList<AttrProcessing> attrProcessingList;
432 attrProcessingList
433 << AttrProcessing ( "note", note )
434 ;
435 ProcessAttributes (myNode, attrProcessingList);
436
437 // set it even if note is empty
438 variable->setGenericData( "note", note );
439}
440
441// ### TODO: some files have not a <VARIABLE> tag but its supposed children are directly children of <FORMAT id="4">
442static void ProcessVariableTag (TQDomNode myNode, void* tagData, KWEFKWordLeader* leader)
443{
444 VariableData *variable = (VariableData *) tagData;
445
446 TQValueList<TagProcessing> tagProcessingList;
447 // "TYPE|PGNUM|DATE|TIME|CUSTOM|SERIALLETTER|FIELD|LINK|NOTE"
448 tagProcessingList
449 << TagProcessing ( "TYPE", ProcessTypeTag, variable )
450 << TagProcessing ( "PGNUM", ProcessPgNumTag, variable )
451 << TagProcessing ( "DATE" )
452 << TagProcessing ( "TIME" )
453 << TagProcessing ( "CUSTOM" )
454 << TagProcessing ( "SERIALLETTER" )
455 << TagProcessing ( "FIELD", ProcessFieldTag, variable )
456 << TagProcessing ( "LINK", ProcessLinkTag, variable )
457 << TagProcessing ( "NOTE", ProcessNoteTag, variable )
458 << TagProcessing ( "FOOTNOTE", ProcessFootnoteTag, variable )
459 ;
460 ProcessSubtags (myNode, tagProcessingList, leader);
461}
462
463static void AppendTagProcessingFormatOne(TQValueList<TagProcessing>& tagProcessingList, FormatData& formatData)
464{
465 tagProcessingList
466 << TagProcessing ( "COLOR", ProcessColorAttrTag, &formatData.text.fgColor )
467 << TagProcessing ( "FONT", ProcessStringNameTag, &formatData.text.fontName )
468 << TagProcessing ( "SIZE", ProcessIntValueTag, &formatData.text.fontSize )
469 << TagProcessing ( "WEIGHT", ProcessIntValueTag, &formatData.text.weight )
470 << TagProcessing ( "ITALIC", ProcessBoolIntValueTag, &formatData.text.italic )
471 << TagProcessing ( "UNDERLINE", ProcessUnderlineTag, &formatData.text )
472 << TagProcessing ( "STRIKEOUT", ProcessStrikeoutTag, &formatData.text )
473 << TagProcessing ( "VERTALIGN", ProcessIntValueTag, &formatData.text.verticalAlignment )
474 << TagProcessing ( "SHADOW" )
475 << TagProcessing ( "FONTATTRIBUTE", ProcessStringValueTag, &formatData.text.fontAttribute )
476 << TagProcessing ( "LANGUAGE", ProcessStringValueTag, &formatData.text.language )
477 << TagProcessing ( "ANCHOR" )
478 << TagProcessing ( "IMAGE" )
479 << TagProcessing ( "PICTURE" )
480 << TagProcessing ( "VARIABLE" )
481 << TagProcessing ( "TEXTBACKGROUNDCOLOR", ProcessColorAttrTag, &formatData.text.bgColor )
482 << TagProcessing ( "OFFSETFROMBASELINE" )
483 << TagProcessing ( "CHARSET" ) // Old KWord documents or KWord's RTF import filter
484 ;
485
486 if ( formatData.text.language == "xx" )
487 {
488 // The text language should have been named "x-test" or so to follow the specification
489 // As it does not, we need to convert it.
490 formatData.text.language = "en_US";
491 }
492}
493
494
495static void SubProcessFormatOneTag(TQDomNode myNode,
496 ValueListFormatData *formatDataList, int formatPos, int formatLen,
497 KWEFKWordLeader *leader)
498{
499 if ( formatPos == -1 || formatLen == -1 )
500 {
501 // We have no position and no length defined
502 // It can happen in a child of <STYLE>, just put secure values
503 formatPos=0;
504 formatLen=0;
505 kdDebug (30508) << "Missing formatting! Style? "
506 << myNode.nodeName()
507 << " = " << myNode.nodeValue()
508 << endl;
509
510 // In the old syntax (KWord 0.8), the comment would be displayed for each paragraph, so do not show it.
511 if ( ! leader->m_oldSyntax )
512 kdDebug (30508) << "Missing formatting for <FORMAT> (style or syntax version 1 ?)" << endl;
513 }
514
515 FormatData formatData(1, formatPos, formatLen);
516 TQValueList<TagProcessing> tagProcessingList;
517 AppendTagProcessingFormatOne(tagProcessingList,formatData);
518 ProcessSubtags (myNode, tagProcessingList, leader);
519
520 (*formatDataList) << formatData;
521}
522
523
524static void SubProcessFormatTwoTag(TQDomNode myNode,
525 ValueListFormatData *formatDataList, int formatPos, int formatLen,
526 KWEFKWordLeader *leader)
527{
528 if ( (formatPos == -1) )
529 {
530 // We have no position defined
531 kdWarning(30508) << "Missing text image position!" << endl;
532 return;
533 }
534 // In KWord 0.8, the len attribute was not defined
535 if (formatLen == -1)
536 formatLen = 1;
537
538 FormatData formatData(2, formatPos, formatLen);
539 TQValueList<TagProcessing> tagProcessingList;
540
541 TQString fileName; // KWord 0.8
542 KoPictureKey key; // Re-saved by KWord 1.2 or KWord 1.3
543 tagProcessingList.append(TagProcessing( "FILENAME", ProcessStringValueTag, &fileName));
544 tagProcessingList.append(TagProcessing( "PICTURE", ProcessImageTag, &key ));
545 ProcessSubtags (myNode, tagProcessingList, leader);
546
547 if ( !fileName.isEmpty() )
548 {
549 kdDebug(30508) << "KWord 0.8 text image: " << fileName << endl;
550 key = KoPictureKey( fileName );
551 }
552 else
553 {
554 kdDebug(30508) << "KWord 1.2/1.3 text image: " << key.toString() << endl;
555 }
556
557 formatData.frameAnchor.key = key;
558 formatData.frameAnchor.picture.key = key;
559
560 (*formatDataList) << formatData;
561}
562
563
564static void SubProcessFormatThreeTag(TQDomNode myNode,
565 ValueListFormatData *formatDataList, int formatPos, int /*formatLen*/,
566 KWEFKWordLeader *leader)
567{
568 if ( (formatPos == -1) ) // formatLen is never there but is 1.
569 {
570 // We have no position and no length defined
571 kdWarning(30508) << "Missing variable formatting!" << endl;
572 return;
573 }
574 AllowNoSubtags (myNode, leader);
575
576 const FormatData formatData(3, formatPos, 1);
577 (*formatDataList) << formatData;
578}
579
580static void SubProcessFormatFourTag(TQDomNode myNode,
581 ValueListFormatData *formatDataList, int formatPos, int formatLen,
582 KWEFKWordLeader *leader)
583{
584 if ( (formatPos == -1) || (formatLen == -1) )
585 {
586 // We have no position and no length defined
587 kdWarning(30508) << "Missing variable formatting!" << endl;
588 return;
589 }
590 FormatData formatData(4, formatPos, formatLen);
591 TQValueList<TagProcessing> tagProcessingList;
592 tagProcessingList.append(TagProcessing("VARIABLE", ProcessVariableTag, &formatData.variable));
593 // As variables can have a formating too, we have to process formating
594 AppendTagProcessingFormatOne(tagProcessingList,formatData);
595 ProcessSubtags (myNode, tagProcessingList, leader);
596
597 (*formatDataList) << formatData;
598}
599
600
601static void SubProcessFormatSixTag(TQDomNode myNode,
602 ValueListFormatData *formatDataList, int formatPos, int formatLen,
603 KWEFKWordLeader *leader)
604{
605 if ( formatPos != -1 && formatLen != -1 )
606 {
607 TQString instance;
608
609 TQValueList<TagProcessing> tagProcessingList;
610 // TODO: We can have all layout information as in regular texts
611 // They simply apply to the table frames
612 // FONT is just the first that we've come across so far
613 tagProcessingList << TagProcessing ( "FONT" )
614 << TagProcessing ( "ANCHOR", ProcessAnchorTag, &instance );
615 ProcessSubtags (myNode, tagProcessingList, leader);
616#if 0
617 kdDebug (30508) << "DEBUG: Adding frame anchor " << instance << endl;
618#endif
619
620 (*formatDataList) << FormatData ( formatPos, formatLen, FrameAnchor (instance) );
621 }
622 else
623 {
624 kdWarning (30508) << "Missing or bad anchor formatting!" << endl;
625 }
626}
627
628static void ProcessFormatTag (TQDomNode myNode, void *tagData, KWEFKWordLeader *leader)
629{
630 ValueListFormatData *formatDataList = (ValueListFormatData *) tagData;
631 int formatId = -1;
632 int formatPos = -1;
633 int formatLen = -1;
634
635 TQValueList<AttrProcessing> attrProcessingList;
636 attrProcessingList << AttrProcessing ( "id", formatId );
637 attrProcessingList << AttrProcessing ( "pos", formatPos );
638 attrProcessingList << AttrProcessing ( "len", formatLen );
639 ProcessAttributes (myNode, attrProcessingList);
640
641 if ( ( formatId == -1 ) && ( leader->m_oldSyntax ) )
642 {
643 formatId = 1; // KWord 0.8 did not define it in <LAYOUT>
644 }
645
646 switch ( formatId )
647 {
648 case 1: // regular texts
649 {
650 SubProcessFormatOneTag(myNode, formatDataList, formatPos, formatLen, leader);
651 break;
652 }
653 case 2: // text image (KWord 0.8)
654 {
655 SubProcessFormatTwoTag(myNode, formatDataList, formatPos, formatLen, leader);
656 break;
657 }
658 case 3: // KWord 0.8 tabulator
659 {
660 SubProcessFormatThreeTag(myNode, formatDataList, formatPos, formatLen, leader);
661 break;
662 }
663 case 4: // variables
664 {
665 SubProcessFormatFourTag(myNode, formatDataList, formatPos, formatLen, leader);
666 break;
667 }
668 case 6: // anchors
669 {
670 SubProcessFormatSixTag(myNode, formatDataList, formatPos, formatLen, leader);
671 break;
672 }
673 case -1:
674 {
675 kdWarning (30508) << "FORMAT attribute id value not set!" << endl;
676 AllowNoSubtags (myNode, leader);
677 break;
678 }
679 case 5: // KWord 0.8 footnote
680 default:
681 kdWarning(30508) << "Unexpected FORMAT attribute id value " << formatId << endl;
682 AllowNoSubtags (myNode, leader);
683 }
684
685}
686
687
688void ProcessFormatsTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
689{
690 ValueListFormatData *formatDataList = (ValueListFormatData *) tagData;
691
692 AllowNoAttributes (myNode);
693
694 (*formatDataList).clear ();
695 TQValueList<TagProcessing> tagProcessingList;
696 tagProcessingList << TagProcessing ( "FORMAT", ProcessFormatTag, formatDataList );
697 ProcessSubtags (myNode, tagProcessingList, leader);
698}
699
700
701// --------------------------------------------------------------------------------
702
703
704static void ProcessCounterTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
705{
706 CounterData *counter = (CounterData *) tagData;
707
708 // Be extra careful with data declared as enum (it could be very different from an int)
709 int counterStyle = counter->style;
710 int counterNumbering = counter->numbering;
711
712 TQValueList<AttrProcessing> attrProcessingList;
713 attrProcessingList << AttrProcessing ( "type", counterStyle );
714 attrProcessingList << AttrProcessing ( "depth", counter->depth );
715 attrProcessingList << AttrProcessing ( "bullet", counter->customCharacter );
716 attrProcessingList << AttrProcessing ( "start", counter->start );
717 attrProcessingList << AttrProcessing ( "numberingtype", counterNumbering );
718 attrProcessingList << AttrProcessing ( "lefttext", counter->lefttext );
719 attrProcessingList << AttrProcessing ( "righttext", counter->righttext );
720 attrProcessingList << AttrProcessing ( "bulletfont", counter->customFont );
721 attrProcessingList << AttrProcessing ( "customdef" );
722 attrProcessingList << AttrProcessing ( "text", counter->text );
723 attrProcessingList << AttrProcessing ( "display-levels" );
724 attrProcessingList << AttrProcessing ( "align" );
725 ProcessAttributes (myNode, attrProcessingList);
726
727 counter->style = CounterData::Style( counterStyle );
728 counter->numbering = CounterData::Numbering( counterNumbering );
729
730 AllowNoSubtags (myNode, leader);
731}
732
733
734static void ProcessLayoutTabulatorTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
735{
736 TabulatorList* tabulatorList = (TabulatorList*) tagData;
737
738 TabulatorData tabulator;
739
740 TQValueList<AttrProcessing> attrProcessingList;
741
742 attrProcessingList
743 << AttrProcessing ( "ptpos", tabulator.m_ptpos )
744 << AttrProcessing ( "type", tabulator.m_type )
745 << AttrProcessing ( "filling", tabulator.m_filling )
746 << AttrProcessing ( "width", tabulator.m_width )
747 << AttrProcessing ( "alignchar" )
748 ;
749
750 if ( leader->m_oldSyntax )
751 {
752 // Avoid too many warning
753 attrProcessingList
754 << AttrProcessing ( "mmpos" )
755 << AttrProcessing ( "inchpos" ) // Never ever use it, as this value is mostly wrong (e.g. 1.1009e+15)
756 ;
757 }
758
759 ProcessAttributes (myNode, attrProcessingList);
760 tabulatorList->append(tabulator);
761
762 AllowNoSubtags (myNode, leader);
763}
764
765
766static void ProcessIndentsTag (TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
767{
768 LayoutData *layout = (LayoutData *) tagData;
769
770 TQValueList<AttrProcessing> attrProcessingList;
771 attrProcessingList << AttrProcessing ("first" , layout->indentFirst );
772 attrProcessingList << AttrProcessing ("left" , layout->indentLeft );
773 attrProcessingList << AttrProcessing ("right" , layout->indentRight );
774 ProcessAttributes (myNode, attrProcessingList);
775
776 AllowNoSubtags (myNode, leader);
777}
778
779
780static void ProcessLayoutOffsetTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
781{
782 LayoutData *layout = (LayoutData *) tagData;
783
784 TQValueList<AttrProcessing> attrProcessingList;
785 attrProcessingList << AttrProcessing ("after" , layout->marginBottom );
786 attrProcessingList << AttrProcessing ("before" , layout->marginTop );
787 ProcessAttributes (myNode, attrProcessingList);
788
789 AllowNoSubtags (myNode, leader);
790}
791
792
793static void ProcessLineBreakingTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
794{
795 LayoutData *layout = (LayoutData *) tagData;
796
797 TQString strBefore, strAfter;
798
799 TQValueList<AttrProcessing> attrProcessingList;
800 attrProcessingList << AttrProcessing ( "linesTogether", layout->keepLinesTogether );
801 attrProcessingList << AttrProcessing ( "hardFrameBreak", layout->pageBreakBefore );
802 attrProcessingList << AttrProcessing ( "hardFrameBreakAfter", layout->pageBreakAfter );
803 attrProcessingList << AttrProcessing ( "keepWithNext" ); // RTF import filter
804 ProcessAttributes (myNode, attrProcessingList);
805
806 AllowNoSubtags (myNode, leader);
807}
808
809
810static void ProcessShadowTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader *leader)
811{
812 LayoutData *layout = (LayoutData *) tagData;
813
814 int red=0;
815 int green=0;
816 int blue=0;
817
818 TQValueList<AttrProcessing> attrProcessingList;
819 attrProcessingList << AttrProcessing ( "distance", layout->shadowDistance );
820 attrProcessingList << AttrProcessing ( "direction", layout->shadowDirection );
821 attrProcessingList << AttrProcessing ( "red", red );
822 attrProcessingList << AttrProcessing ( "green", green );
823 attrProcessingList << AttrProcessing ( "blue", blue );
824 ProcessAttributes (myNode, attrProcessingList);
825
826 layout->shadowColor.setRgb(red,green,blue);
827
828 AllowNoSubtags (myNode, leader);
829}
830
831static void ProcessAnyBorderTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
832{
833 BorderData *border = static_cast <BorderData*> (tagData);
834
835 int red=0;
836 int green=0;
837 int blue=0;
838
839 TQValueList<AttrProcessing> attrProcessingList;
840 attrProcessingList << AttrProcessing ( "red", red );
841 attrProcessingList << AttrProcessing ( "green", green );
842 attrProcessingList << AttrProcessing ( "blue", blue );
843 attrProcessingList << AttrProcessing ( "style", border->style );
844 attrProcessingList << AttrProcessing ( "width", border->width );
845 ProcessAttributes (myNode, attrProcessingList);
846
847 border->color.setRgb(red,green,blue);
848
849 AllowNoSubtags (myNode, leader);
850}
851
852static void ProcessFollowingTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
853{
854 ProcessOneAttrTag (myNode, "name", "TQString", tagData, leader);
855}
856
857static void ProcessLinespacingTag (TQDomNode myNode, void *tagData, KWEFKWordLeader* /*leader*/ )
858{
859 LayoutData *layout = (LayoutData *) tagData;
860 TQString oldValue, spacingType;
861 double spacingValue;
862
863 TQValueList<AttrProcessing> attrProcessingList;
864 attrProcessingList << AttrProcessing ("value" , oldValue );
865 attrProcessingList << AttrProcessing ("type" , spacingType );
866 attrProcessingList << AttrProcessing ("spacingvalue" , spacingValue );
867 ProcessAttributes (myNode, attrProcessingList);
868
869 // KWord pre-1.2 uses only the "value" attribute (stored in oldValue)
870 // while 1.2 uses mainly "type" and "spacingvalue", while keeping "value" for compatibility
871
872 if ( spacingType.isEmpty() )
873 {
874 // for old format
875 if( oldValue == "oneandhalf" )
876 layout->lineSpacingType = LayoutData::LS_ONEANDHALF;
877 else if ( oldValue == "double" )
878 layout->lineSpacingType = LayoutData::LS_DOUBLE;
879 else
880 {
881 bool ok = false;
882 const double size = oldValue.toDouble( &ok );
883 if ( ok && ( size >= 0.0 ) ) // 0 is allowed but negative values are not
884 {
885 // We have a valid size
886 layout->lineSpacingType = LayoutData::LS_CUSTOM; // set to custom
887 layout->lineSpacing = size;
888 }
889 else
890 layout->lineSpacingType = LayoutData::LS_SINGLE; // assume single linespace
891 }
892 }
893 else
894 {
895 // for new format
896 if( spacingType == "oneandhalf" )
897 layout->lineSpacingType = LayoutData::LS_ONEANDHALF;
898 else if ( spacingType == "double" )
899 layout->lineSpacingType = LayoutData::LS_DOUBLE;
900 else if ( spacingType == "custom" )
901 layout->lineSpacingType = LayoutData::LS_CUSTOM;
902 else if ( spacingType == "atleast" )
903 layout->lineSpacingType = LayoutData::LS_ATLEAST;
904 else if ( spacingType == "multiple" )
905 layout->lineSpacingType = LayoutData::LS_MULTIPLE;
906 else if ( spacingType == "fixed" )
907 layout->lineSpacingType = LayoutData::LS_FIXED;
908 else
909 layout->lineSpacingType = LayoutData::LS_SINGLE; // assume single linespace
910 layout->lineSpacing = spacingValue;
911 }
912}
913
914static void ProcessLineSpaceTag (TQDomNode myNode, void *tagData, KWEFKWordLeader* /*leader*/ )
915{
916 // <LINESPACE> is an old tag, of before syntax 1
917 LayoutData *layout = (LayoutData *) tagData;
918 double spacingValue = 0.0;
919
920 TQValueList<AttrProcessing> attrProcessingList;
921 attrProcessingList << AttrProcessing ( "pt", spacingValue );
922 attrProcessingList << AttrProcessing ( "mm" );
923 attrProcessingList << AttrProcessing ( "inch" );
924 ProcessAttributes (myNode, attrProcessingList);
925
926 layout->lineSpacingType = LayoutData::LS_CUSTOM; // set to custom
927 layout->lineSpacing = spacingValue;
928}
929
930static void ProcessFlowTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
931{
932 LayoutData *layout = (LayoutData *) tagData;
933
934 TQString oldAlign, normalAlign;
935
936 TQValueList<AttrProcessing> attrProcessingList;
937 if ( leader->m_oldSyntax )
938 {
939 // KWord 0.8
940 attrProcessingList << AttrProcessing ( "value", oldAlign ); // KWord 0.8
941 }
942 // New syntax and some files from syntax 1
943 attrProcessingList << AttrProcessing ( "align", normalAlign );
944 attrProcessingList << AttrProcessing ( "dir" ); // ### TODO
945 ProcessAttributes (myNode, attrProcessingList);
946
947 if ( leader->m_oldSyntax && normalAlign.isEmpty() )
948 {
949 if ( oldAlign.isEmpty() )
950 {
951 layout->alignment = "left"; // KWord 0.8 did not support right-to-left
952 }
953 else
954 {
955 const int align = oldAlign.toInt();
956 if ( ( align < 0 ) || ( align > 3) )
957 {
958 kdWarning(30508) << "KWord 0.8 flow unknown: " << oldAlign << endl;
959 layout->alignment = "left"; // Unknown, so assume left
960 }
961 else
962 {
963 const char* flows[]={"left", "right", "center", "justify" };
964 layout->alignment = flows[ align ];
965 }
966 }
967 kdDebug(30508) << "KWord 0.8 flow: " << oldAlign << " corrected: " << layout->alignment << endl;
968 }
969 else
970 {
971 layout->alignment = normalAlign;
972 }
973
974}
975
976
977void ProcessLayoutTag ( TQDomNode myNode, void *tagData, KWEFKWordLeader *leader )
978// Processes <LAYOUT> and <STYLE>
979{
980 TQValueList<AttrProcessing> attrProcessingList;
981 attrProcessingList << AttrProcessing ( "outline" ); // Only in <STYLE>
982 ProcessAttributes (myNode, attrProcessingList);
983
984 LayoutData *layout = (LayoutData *) tagData;
985
986 ValueListFormatData formatDataList;
987
988 TQValueList<TagProcessing> tagProcessingList;
989 tagProcessingList << TagProcessing ( "NAME", ProcessStringValueTag, &layout->styleName );
990 tagProcessingList << TagProcessing ( "FOLLOWING", ProcessFollowingTag, &layout->styleFollowing );
991 tagProcessingList << TagProcessing ( "FLOW", ProcessFlowTag, layout );
992 tagProcessingList << TagProcessing ( "INDENTS", ProcessIndentsTag, layout );
993 tagProcessingList << TagProcessing ( "OFFSETS", ProcessLayoutOffsetTag, layout );
994 tagProcessingList << TagProcessing ( "LINESPACING", ProcessLinespacingTag, layout );
995 tagProcessingList << TagProcessing ( "PAGEBREAKING", ProcessLineBreakingTag, layout );
996 tagProcessingList << TagProcessing ( "LEFTBORDER", ProcessAnyBorderTag, &layout->leftBorder );
997 tagProcessingList << TagProcessing ( "RIGHTBORDER", ProcessAnyBorderTag, &layout->rightBorder );
998 tagProcessingList << TagProcessing ( "TOPBORDER", ProcessAnyBorderTag, &layout->topBorder );
999 tagProcessingList << TagProcessing ( "BOTTOMBORDER", ProcessAnyBorderTag, &layout->bottomBorder );
1000 tagProcessingList << TagProcessing ( "COUNTER", ProcessCounterTag, &layout->counter );
1001 tagProcessingList << TagProcessing ( "FORMAT", ProcessFormatTag, &formatDataList );
1002 tagProcessingList << TagProcessing ( "TABULATOR", ProcessLayoutTabulatorTag, &layout->tabulatorList );
1003 tagProcessingList << TagProcessing ( "SHADOW", ProcessShadowTag, layout );
1004
1005 if ( leader->m_oldSyntax )
1006 {
1007 layout->indentLeft = 0.0; // ### TODO: needed or not?
1008 tagProcessingList
1009 << TagProcessing ( "OHEAD", ProcessOldLayoutChildTag, &layout->marginTop )
1010 << TagProcessing ( "OFOOT", ProcessOldLayoutChildTag, &layout->marginBottom )
1011 << TagProcessing ( "ILEFT", ProcessOldLayoutChildTag, &layout->indentLeft )
1012 << TagProcessing ( "IFIRST", ProcessOldLayoutChildTag, &layout->indentFirst )
1013 << TagProcessing ( "LINESPACE", ProcessLineSpaceTag, layout )
1014 ;
1015 }
1016
1017 ProcessSubtags (myNode, tagProcessingList, leader);
1018
1019
1020 if ( formatDataList.isEmpty () )
1021 {
1022 kdWarning (30508) << "No FORMAT tag within LAYOUT/STYLE!" << endl;
1023 }
1024 else
1025 {
1026 layout->formatData = formatDataList.first ();
1027
1028 if ( formatDataList.count () > 1 )
1029 {
1030 kdWarning (30508) << "More than one FORMAT tag within LAYOUT/STYLE!" << endl;
1031 }
1032 }
1033
1034 if ( layout->styleName.isEmpty () )
1035 {
1036 layout->styleName = "Standard";
1037 kdWarning (30508) << "Empty layout name!" << endl;
1038 }
1039
1040}
1041
1042
1043static void ProcessImageKeyTag ( TQDomNode myNode,
1044 void *tagData, KWEFKWordLeader *)
1045{
1046 KoPictureKey *key = (KoPictureKey*) tagData;
1047
1048 // Let KoPicture do the loading
1049 key->loadAttributes(myNode.toElement());
1050}
1051
1052void ProcessImageTag ( TQDomNode myNode,
1053 void *tagData, KWEFKWordLeader *leader )
1054{ // <PICTURE>
1055 TQValueList<AttrProcessing> attrProcessingList;
1056 attrProcessingList << AttrProcessing ( "keepAspectRatio" );
1057 ProcessAttributes (myNode, attrProcessingList);
1058
1059 TQValueList<TagProcessing> tagProcessingList;
1060 tagProcessingList << TagProcessing ( "KEY", ProcessImageKeyTag, tagData );
1061 ProcessSubtags (myNode, tagProcessingList, leader);
1062}
1063
The class AttrProcessing and the two functions ProcessAttributes () and AllowNoSubtags () allow for e...
Counter structure, for LayoutData.
TQString text
text at the time of saving (no formatting info though)
This is basically <FRAMESET> tag.
Paragraph layout.
double lineSpacing
Space between lines in pt, if lineSpacingType==0.
int shadowDirection
direction of <SHADOW>
TabulatorList tabulatorList
List of tabulators.
TQColor shadowColor
red, green, blue of <SHADOW>
double indentFirst
indentation correction of first line (can be negative!)
double indentRight
right indentation (a negative value means invalid)
double shadowDistance
distance of <SHADOW>
double indentLeft
left indentation (a negative value means invalid)
TQString alignment
left, right, center, justify
int lineSpacingType
0=custom, 10=one line, 15=one and half lines, 20= 2 lines
double marginTop
space before the paragraph (a negative value means invalid)
double marginBottom
space after the paragraph (a negative value means invalid)
Tabulator (see also <TABULATOR> element in KWord's DTD)
List of tabulators.
The class TagProcessing and the two functions ProcessSubtags () and AllowNoSubtags () allow for easin...
TextFormatting is a container for data retrieved from the <FORMAT> tag and its subtags to be used in ...
bool underlineWord
true if word-by-word (i.e spaces are not underlined)
bool underline
Any underline? (If true, we do not know if simple or double or what else)
TQColor underlineColor
color of the line
bool strikeout
true if strikeout
TQString underlineStyle
underline style: solid, dash, dot dash, ....
TQString underlineValue
"value" of the underline: single, double, bold-single...
TQString strikeoutLineStyle
type of the strikeout line: solid, dash, dot, ....
TQString strikeoutType
type of strikeout: single, bold, double
Data of variables.
void setLink(const TQString &linkName, const TQString &hrefName)
Set parameters of a LINK element.
void setGenericData(const TQString &key, const TQString &data)
Set generic variable data.
void setField(const TQString &subtype, const TQString &value)
Set parameters of a FIELD element.
void setFootnote(const TQString &notetype, const TQString &automatic, const TQString &value, TQValueList< ParaData > *para)
Set parameters of a <FOOTNOTE> element.
void setPgNum(const TQString &subtype, const TQString &value)
Set parameters of a PGNUM element.