filters

ProcessDocument.cc

00001 /*
00002    This file is part of the KDE project
00003    Copyright (C) 2001, 2002, 2004 Nicolas GOUTTE <goutte@kde.org>
00004    Copyright (c) 2001 IABG mbH. All rights reserved.
00005                       Contact: Wolf-Michael Bolle <Bolle@IABG.de>
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Library General Public
00009    License as published by the Free Software Foundation; either
00010    version 2 of the License, or (at your option) any later version.
00011 
00012    This library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Library General Public License for more details.
00016 
00017    You should have received a copy of the GNU Library General Public License
00018    along with this library; see the file COPYING.LIB.  If not, write to
00019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  * Boston, MA 02110-1301, USA.
00021 */
00022 
00023 /*
00024    This file is based on the old file:
00025     /home/kde/koffice/filters/kword/ascii/asciiexport.cc
00026 
00027    The old file was copyrighted by
00028     Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
00029     Copyright (c) 2000 ID-PRO Deutschland GmbH. All rights reserved.
00030                        Contact: Wolf-Michael Bolle <Wolf-Michael.Bolle@GMX.de>
00031 
00032    The old file was licensed under the terms of the GNU Library General Public
00033    License version 2.
00034 */
00035 
00036 /*
00037    Part of the code is based on code licensed under the terms of the
00038    GNU Library General Public License version 2:
00039    Copyright 2001 Michael Johnson <mikej@xnet.com>
00040 */
00041 
00042 #include <qdom.h>
00043 #include <qvaluelist.h>
00044 
00045 #include <kdebug.h>
00046 
00047 #include "KWEFStructures.h"
00048 #include "TagProcessing.h"
00049 #include "ProcessDocument.h"
00050 #include "KWEFKWordLeader.h"
00051 
00052 
00053 // == KOFFICE DOCUMENT INFORMATION ==
00054 
00055 // TODO: verify that all document info is read!
00056 
00057 void ProcessTextTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00058 {
00059     QString *tagText = (QString *) tagData;
00060 
00061     *tagText = myNode.toElement().text(); // Get the text, also from a CDATA section
00062 
00063     QValueList<TagProcessing> tagProcessingList;
00064     tagProcessingList.append ( TagProcessing ( "xml:space" ) );
00065     ProcessSubtags (myNode, tagProcessingList, leader);
00066 
00067     AllowNoSubtags (myNode, leader);
00068 }
00069 
00070 static void ProcessAboutTag ( QDomNode         myNode,
00071                               void            *tagData,
00072                               KWEFKWordLeader *leader )
00073 {
00074     KWEFDocumentInfo *docInfo = (KWEFDocumentInfo *) tagData;
00075 
00076     AllowNoAttributes (myNode);
00077 
00078     QValueList<TagProcessing> tagProcessingList;
00079     tagProcessingList.append ( TagProcessing ( "title",    ProcessTextTag, &docInfo->title    ) );
00080     tagProcessingList.append ( TagProcessing ( "abstract", ProcessTextTag, &docInfo->abstract ) );
00081     tagProcessingList.append ( TagProcessing ( "keyword",    ProcessTextTag, &docInfo->keywords    ) );
00082     tagProcessingList.append ( TagProcessing ( "subject", ProcessTextTag, &docInfo->subject ) );
00083     ProcessSubtags (myNode, tagProcessingList, leader);
00084 }
00085 
00086 
00087 static void ProcessAuthorTag ( QDomNode         myNode,
00088                                void            *tagData,
00089                                KWEFKWordLeader *leader )
00090 {
00091     KWEFDocumentInfo *docInfo = (KWEFDocumentInfo *) tagData;
00092 
00093     AllowNoAttributes (myNode);
00094 
00095     QValueList<TagProcessing> tagProcessingList;
00096     tagProcessingList.append ( TagProcessing ( "full-name",   ProcessTextTag, &docInfo->fullName   ) );
00097     tagProcessingList.append ( TagProcessing ( "title",       ProcessTextTag, &docInfo->jobTitle   ) );
00098     tagProcessingList.append ( TagProcessing ( "company",     ProcessTextTag, &docInfo->company    ) );
00099     tagProcessingList.append ( TagProcessing ( "email",       ProcessTextTag, &docInfo->email      ) );
00100     tagProcessingList.append ( TagProcessing ( "telephone",   ProcessTextTag, &docInfo->telephone  ) );
00101     tagProcessingList.append ( TagProcessing ( "telephone-work",   ProcessTextTag, &docInfo->telephonework  ) );
00102     tagProcessingList.append ( TagProcessing ( "fax",         ProcessTextTag, &docInfo->fax        ) );
00103     tagProcessingList.append ( TagProcessing ( "country",     ProcessTextTag, &docInfo->country    ) );
00104     tagProcessingList.append ( TagProcessing ( "postal-code", ProcessTextTag, &docInfo->postalCode ) );
00105     tagProcessingList.append ( TagProcessing ( "city",        ProcessTextTag, &docInfo->city       ) );
00106     tagProcessingList.append ( TagProcessing ( "street",      ProcessTextTag, &docInfo->street     ) );
00107     tagProcessingList.append ( TagProcessing ( "initial",     ProcessTextTag, &docInfo->initial    ) );
00108     tagProcessingList.append ( TagProcessing ( "position",     ProcessTextTag, &docInfo->position    ) );
00109     ProcessSubtags (myNode, tagProcessingList, leader);
00110 }
00111 
00112 
00113 void ProcessDocumentInfoTag ( QDomNode         myNode,
00114                               void            *,
00115                               KWEFKWordLeader *leader )
00116 {
00117     AllowNoAttributes (myNode);
00118 
00119     KWEFDocumentInfo docInfo;
00120 
00121     QValueList<TagProcessing> tagProcessingList;
00122     tagProcessingList.append ( TagProcessing ( "log" ) );
00123     tagProcessingList.append ( TagProcessing ( "author", ProcessAuthorTag, &docInfo ) );
00124     tagProcessingList.append ( TagProcessing ( "about",  ProcessAboutTag,  &docInfo ) );
00125     ProcessSubtags (myNode, tagProcessingList, leader);
00126 
00127     leader->doFullDocumentInfo (docInfo);
00128 }
00129 
00130 
00131 // == KWORD ==
00132 
00133 // Every tag has its own processing function. All of those functions
00134 // have the same parameters since the functions are passed to
00135 // ProcessSubtags throuch the TagProcessing class.  The top level
00136 // function is ProcessDocTag and can be called with the node returned
00137 // by QDomDocument::documentElement (). The tagData argument can be
00138 // used to either pass variables down to the subtags or to allow
00139 // subtags to return values. As a bare minimum the tag processing
00140 // functions must handle the tag's attributes and the tag's subtags
00141 // (which it can choose to ignore). Currently implemented is
00142 // processing for the following tags and attributes:
00143 //
00144 // TODO: make this list up-to-date
00145 //
00146 // DOC
00147 //   FRAMESETS
00148 //     FRAMESET
00149 //       PARAGRAPH
00150 //          TEXT - Text Element
00151 //          FORMATS
00152 //            FORMAT id=1 pos= len=
00153 //          LAYOUT
00154 //            NAME value=
00155 
00156 
00157 // --------------------------------------------------------------------------------
00158 
00159 
00160 static void ProcessOneAttrTag ( QDomNode  myNode,
00161                                 QString   attrName,
00162                                 QString   attrType,
00163                                 void     *attrData,
00164                                 KWEFKWordLeader *leader )
00165 {
00166     QValueList<AttrProcessing> attrProcessingList;
00167     attrProcessingList << AttrProcessing (attrName, attrType, attrData);
00168     ProcessAttributes (myNode, attrProcessingList);
00169 
00170     AllowNoSubtags (myNode, leader);
00171 }
00172 
00173 
00174 static void ProcessColorAttrTag ( QDomNode myNode, void *tagData, KWEFKWordLeader * )
00175 {
00176     QColor *attrValue = (QColor *) tagData;
00177 
00178     int red, green, blue;
00179 
00180     QValueList<AttrProcessing> attrProcessingList;
00181     attrProcessingList << AttrProcessing ( "red",   red   );
00182     attrProcessingList << AttrProcessing ( "green", green );
00183     attrProcessingList << AttrProcessing ( "blue",  blue  );
00184     ProcessAttributes (myNode, attrProcessingList);
00185 
00186     attrValue->setRgb (red, green, blue);
00187 }
00188 
00189 
00190 static void ProcessBoolIntAttrTag ( QDomNode  myNode,
00191                                     QString   attrName,
00192                                     void     *attrData,
00193                                     KWEFKWordLeader *leader )
00194 {
00195     ProcessOneAttrTag (myNode, attrName, "bool", attrData, leader);
00196 }
00197 
00198 
00199 // --------------------------------------------------------------------------------
00200 
00201 
00202 static void ProcessIntValueTag (QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00203 {
00204     ProcessOneAttrTag (myNode, "value", "int", tagData, leader);
00205 }
00206 
00207 
00208 static void ProcessBoolIntValueTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00209 {
00210     ProcessBoolIntAttrTag (myNode, "value", tagData, leader);
00211 }
00212 
00213 
00214 static void ProcessStringValueTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00215 {
00216     ProcessOneAttrTag (myNode, "value", "QString", tagData, leader);
00217 }
00218 
00219 static void ProcessStringNameTag (QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00220 {
00221     ProcessOneAttrTag (myNode, "name", "QString", tagData, leader);
00222 }
00223 
00224 
00225 // --------------------------------------------------------------------------------
00226 
00227 
00228 static void ProcessOldLayoutChildTag (QDomNode myNode, void *tagData, KWEFKWordLeader* /*leader*/)
00229 {
00230     QValueList<AttrProcessing> attrProcessingList;
00231 
00232     double* d = (double*) ( tagData );
00233     *d = 0.0; // Put a sensible default
00234 
00235     attrProcessingList
00236         << AttrProcessing ( "pt", *d )
00237         << AttrProcessing ( "inch" )
00238         << AttrProcessing ( "mm" )
00239         ;
00240     ProcessAttributes (myNode, attrProcessingList);
00241 }
00242 
00243 static void ProcessUnderlineTag (QDomNode myNode, void *tagData, KWEFKWordLeader* /*leader*/ )
00244 {
00245     TextFormatting* text=(TextFormatting*) tagData;
00246     QString str,style;
00247     QString strColor;
00248 
00249     text->underlineWord = false;
00250 
00251     QValueList<AttrProcessing> attrProcessingList;
00252 
00253     attrProcessingList
00254         << AttrProcessing ( "value",   str )
00255         << AttrProcessing ( "styleline", style )
00256         << AttrProcessing ( "wordbyword", text->underlineWord )
00257         << AttrProcessing ( "underlinecolor",   strColor )
00258         ;
00259     ProcessAttributes (myNode, attrProcessingList);
00260 
00261     str=str.stripWhiteSpace();
00262     text->underlineValue=str;
00263     if ( (str=="0") || (str.isEmpty()) )
00264     {
00265         text->underline=false;
00266     }
00267     else
00268     {
00269         // We assume that anything else is underlined
00270         text->underline=true;
00271         text->underlineStyle = style;
00272         text->underlineColor.setNamedColor(strColor);
00273     }
00274 }
00275 
00276 static void ProcessStrikeoutTag (QDomNode myNode, void *tagData, KWEFKWordLeader* /*leader*/ )
00277 {
00278     TextFormatting* text=(TextFormatting*) tagData;
00279     QString type, linestyle;
00280 
00281     text->strikeoutWord = false;
00282 
00283     QValueList<AttrProcessing> attrProcessingList;
00284     attrProcessingList << AttrProcessing ("value" , type );
00285     attrProcessingList << AttrProcessing ("styleline" , linestyle );
00286     attrProcessingList << AttrProcessing ( "wordbyword", text->strikeoutWord );
00287     ProcessAttributes (myNode, attrProcessingList);
00288 
00289     if( type.isEmpty() || ( type == "0" ) )
00290         text->strikeout = false;
00291     else
00292     {
00293         text->strikeout = true;
00294         text->strikeoutType = type;
00295         text->strikeoutLineStyle = linestyle;
00296         if( text->strikeoutType == "1" )
00297             text->strikeoutType = "single";
00298         if( text->strikeoutLineStyle.isEmpty() )
00299             text->strikeoutLineStyle = "solid";
00300     }
00301 }
00302 
00303 
00304 void ProcessAnchorTag ( QDomNode       myNode,
00305                         void          *tagData,
00306                         KWEFKWordLeader *leader )
00307 {
00308     QString *instance = (QString *) tagData;
00309 
00310     QString type;
00311     *instance = QString::null;
00312     QValueList<AttrProcessing> attrProcessingList;
00313     attrProcessingList << AttrProcessing ( "type",     type    )
00314                        << AttrProcessing ( "instance", "QString", instance );
00315     ProcessAttributes (myNode, attrProcessingList);
00316 
00317     if ( type != "frameset" )
00318     {
00319         kdWarning (30508) << "Unknown ANCHOR type " << type << "!" << endl;
00320     }
00321 
00322     if ( (*instance).isEmpty () )
00323     {
00324         kdWarning (30508) << "Bad ANCHOR instance name!" << endl;
00325     }
00326 
00327     AllowNoSubtags (myNode, leader);
00328 }
00329 
00330 
00331 static void ProcessLinkTag (QDomNode myNode, void *tagData, KWEFKWordLeader *)
00332 {
00333     VariableData *variable = (VariableData *) tagData;
00334 
00335     QString linkName, hrefName;
00336 
00337     QValueList<AttrProcessing> attrProcessingList;
00338     attrProcessingList.append ( AttrProcessing ("linkName", linkName) );
00339     attrProcessingList.append ( AttrProcessing ("hrefName", hrefName) );
00340     ProcessAttributes (myNode, attrProcessingList);
00341 
00342     variable->setLink(linkName, hrefName);
00343 }
00344 
00345 
00346 static void ProcessPgNumTag (QDomNode myNode, void *tagData, KWEFKWordLeader *)
00347 {
00348     VariableData *variable = (VariableData *) tagData;
00349 
00350     QString subtype, value;
00351 
00352     QValueList<AttrProcessing> attrProcessingList;
00353     attrProcessingList.append ( AttrProcessing ("subtype", subtype) );
00354     attrProcessingList.append ( AttrProcessing ("value",   value  ) );
00355     ProcessAttributes (myNode, attrProcessingList);
00356 
00357     variable->setPgNum(subtype, value);
00358 }
00359 
00360 
00361 static void ProcessTypeTag (QDomNode myNode, void *tagData, KWEFKWordLeader *)
00362 {
00363     VariableData *variable = (VariableData *) tagData;
00364 
00365     QValueList<AttrProcessing> attrProcessingList;
00366     attrProcessingList.append ( AttrProcessing ("key",  variable->m_key ) );
00367     attrProcessingList.append ( AttrProcessing ("text", variable->m_text) );
00368     attrProcessingList.append ( AttrProcessing ("type", variable->m_type) );
00369     ProcessAttributes (myNode, attrProcessingList);
00370 }
00371 
00372 static void ProcessFieldTag (QDomNode myNode, void *tagData, KWEFKWordLeader *)
00373 {
00374     VariableData *variable = (VariableData *) tagData;
00375     int subtype;
00376     QString name, value;
00377 
00378     QValueList<AttrProcessing> attrProcessingList;
00379     attrProcessingList.append ( AttrProcessing ("subtype", subtype) );
00380     attrProcessingList.append ( AttrProcessing ("value", value ) );
00381     ProcessAttributes (myNode, attrProcessingList);
00382 
00383     switch( subtype )
00384     {
00385     case  0:  name = "fileName"; break;
00386     case  1:  name = "dirName"; break;
00387     case  2:  name = "authorName"; break;
00388     case  3:  name = "authorEmail"; break;
00389     case  4:  name = "authorCompany"; break;
00390     case 10:  name = "docTitle"; break;
00391     case 11:  name = "docAbstract"; break;
00392     case 16:  name = "authorInitial"; break;
00393     default: break;
00394     }
00395 
00396     if(!name.isEmpty())
00397         variable->setField(name, value);
00398 }
00399 
00400 static void ProcessFootnoteTag (QDomNode myNode, void *tagData, KWEFKWordLeader *leader)
00401 {
00402     VariableData *variable = (VariableData *) tagData;
00403     QString frameset, value, numberingtype, notetype;
00404 
00405     QValueList<AttrProcessing> attrProcessingList;
00406     attrProcessingList
00407         << AttrProcessing ( "value", value )
00408         << AttrProcessing ( "numberingtype", numberingtype )
00409         << AttrProcessing ( "frameset", frameset )
00410         << AttrProcessing ( "notetype", notetype )
00411         ;
00412     ProcessAttributes (myNode, attrProcessingList);
00413 
00414     // search for frameset in the footnoteList
00415     for(unsigned i=0;i<leader->footnoteList.count();i++)
00416     {
00417        if( leader->footnoteList[i].frameName == frameset )
00418        {
00419            variable->setFootnote( notetype, numberingtype, value, &leader->footnoteList[i].para );
00420            break;
00421        }
00422     }
00423 }
00424 
00425 static void ProcessNoteTag (QDomNode myNode, void *tagData, KWEFKWordLeader *leader)
00426 {
00427     VariableData *variable = (VariableData *) tagData;
00428 
00429     QString note;
00430 
00431     QValueList<AttrProcessing> attrProcessingList;
00432     attrProcessingList
00433         << AttrProcessing ( "note", note )
00434         ;
00435     ProcessAttributes (myNode, attrProcessingList);
00436 
00437     // set it even if note is empty
00438     variable->setGenericData( "note", note );
00439 }
00440 
00441 // ### TODO: some files have not a <VARIABLE> tag but its supposed children are directly children of <FORMAT id="4">
00442 static void ProcessVariableTag (QDomNode myNode, void* tagData, KWEFKWordLeader* leader)
00443 {
00444     VariableData *variable = (VariableData *) tagData;
00445 
00446     QValueList<TagProcessing> tagProcessingList;
00447     // "TYPE|PGNUM|DATE|TIME|CUSTOM|SERIALLETTER|FIELD|LINK|NOTE"
00448     tagProcessingList
00449         << TagProcessing ( "TYPE",          ProcessTypeTag,         variable )
00450         << TagProcessing ( "PGNUM",         ProcessPgNumTag,        variable )
00451         << TagProcessing ( "DATE" )
00452         << TagProcessing ( "TIME" )
00453         << TagProcessing ( "CUSTOM" )
00454         << TagProcessing ( "SERIALLETTER" )
00455         << TagProcessing ( "FIELD",         ProcessFieldTag,        variable )
00456         << TagProcessing ( "LINK",          ProcessLinkTag,         variable )
00457         << TagProcessing ( "NOTE",          ProcessNoteTag,         variable )
00458         << TagProcessing ( "FOOTNOTE",      ProcessFootnoteTag,     variable )
00459         ;
00460     ProcessSubtags (myNode, tagProcessingList, leader);
00461 }
00462 
00463 static void AppendTagProcessingFormatOne(QValueList<TagProcessing>& tagProcessingList, FormatData& formatData)
00464 {
00465     tagProcessingList
00466         << TagProcessing ( "COLOR",               ProcessColorAttrTag,    &formatData.text.fgColor           )
00467         << TagProcessing ( "FONT",                ProcessStringNameTag,   &formatData.text.fontName          )
00468         << TagProcessing ( "SIZE",                ProcessIntValueTag,     &formatData.text.fontSize          )
00469         << TagProcessing ( "WEIGHT",              ProcessIntValueTag,     &formatData.text.weight            )
00470         << TagProcessing ( "ITALIC",              ProcessBoolIntValueTag, &formatData.text.italic            )
00471         << TagProcessing ( "UNDERLINE",           ProcessUnderlineTag,    &formatData.text                   )
00472         << TagProcessing ( "STRIKEOUT",           ProcessStrikeoutTag,    &formatData.text                   )
00473         << TagProcessing ( "VERTALIGN",           ProcessIntValueTag,     &formatData.text.verticalAlignment )
00474         << TagProcessing ( "SHADOW" )
00475         << TagProcessing ( "FONTATTRIBUTE",       ProcessStringValueTag,  &formatData.text.fontAttribute     )
00476         << TagProcessing ( "LANGUAGE",            ProcessStringValueTag,  &formatData.text.language          )
00477         << TagProcessing ( "ANCHOR" )
00478         << TagProcessing ( "IMAGE" )
00479         << TagProcessing ( "PICTURE" )
00480         << TagProcessing ( "VARIABLE" )
00481         << TagProcessing ( "TEXTBACKGROUNDCOLOR", ProcessColorAttrTag,    &formatData.text.bgColor           )
00482         << TagProcessing ( "OFFSETFROMBASELINE" )
00483         << TagProcessing ( "CHARSET" ) // Old KWord documents or KWord's RTF import filter
00484         ;
00485 
00486     if ( formatData.text.language == "xx" )
00487     {
00488         // The text language should have been named "x-test" or so to follow the specification
00489         // As it does not, we need to convert it.
00490         formatData.text.language = "en_US";
00491     }
00492 }
00493 
00494 
00495 static void SubProcessFormatOneTag(QDomNode myNode,
00496     ValueListFormatData *formatDataList, int formatPos, int formatLen,
00497     KWEFKWordLeader *leader)
00498 {
00499     if ( formatPos == -1 || formatLen == -1 )
00500     {
00501         // We have no position and no length defined
00502         // It can happen in a child of <STYLE>, just put secure values
00503         formatPos=0;
00504         formatLen=0;
00505         kdDebug (30508) << "Missing formatting! Style? "
00506                         << myNode.nodeName()
00507                         << " = " << myNode.nodeValue()
00508                         << endl;
00509 
00510         // In the old syntax (KWord 0.8), the comment would be displayed for each paragraph, so do not show it.
00511         if ( ! leader->m_oldSyntax )
00512             kdDebug (30508) << "Missing formatting for <FORMAT> (style or syntax version 1 ?)" << endl;
00513     }
00514 
00515     FormatData formatData(1, formatPos, formatLen);
00516     QValueList<TagProcessing> tagProcessingList;
00517     AppendTagProcessingFormatOne(tagProcessingList,formatData);
00518     ProcessSubtags (myNode, tagProcessingList, leader);
00519 
00520     (*formatDataList) << formatData;
00521 }
00522 
00523 
00524 static void SubProcessFormatTwoTag(QDomNode myNode,
00525     ValueListFormatData *formatDataList, int formatPos, int formatLen,
00526     KWEFKWordLeader *leader)
00527 {
00528     if ( (formatPos == -1) )
00529     {
00530         // We have no position defined
00531         kdWarning(30508) << "Missing text image position!" << endl;
00532         return;
00533     }
00534     // In KWord 0.8, the len attribute was not defined
00535     if (formatLen == -1)
00536         formatLen = 1;
00537 
00538     FormatData formatData(2, formatPos, formatLen);
00539     QValueList<TagProcessing> tagProcessingList;
00540 
00541     QString fileName; // KWord 0.8
00542     KoPictureKey key; // Re-saved by KWord 1.2 or KWord 1.3
00543     tagProcessingList.append(TagProcessing( "FILENAME", ProcessStringValueTag, &fileName));
00544     tagProcessingList.append(TagProcessing( "PICTURE",  ProcessImageTag, &key ));
00545     ProcessSubtags (myNode, tagProcessingList, leader);
00546 
00547     if ( !fileName.isEmpty() )
00548     {
00549         kdDebug(30508) << "KWord 0.8 text image: " << fileName << endl;
00550         key = KoPictureKey( fileName );
00551     }
00552     else
00553     {
00554         kdDebug(30508) << "KWord 1.2/1.3 text image: " << key.toString() << endl;
00555     }
00556 
00557     formatData.frameAnchor.key = key;
00558     formatData.frameAnchor.picture.key = key;
00559 
00560     (*formatDataList) << formatData;
00561 }
00562 
00563 
00564 static void SubProcessFormatThreeTag(QDomNode myNode,
00565     ValueListFormatData *formatDataList, int formatPos, int /*formatLen*/,
00566     KWEFKWordLeader *leader)
00567 {
00568     if ( (formatPos == -1) ) // formatLen is never there but is 1.
00569     {
00570         // We have no position and no length defined
00571         kdWarning(30508) << "Missing variable formatting!" << endl;
00572         return;
00573     }
00574     AllowNoSubtags (myNode, leader);
00575 
00576     const FormatData formatData(3, formatPos, 1);
00577     (*formatDataList) << formatData;
00578 }
00579 
00580 static void SubProcessFormatFourTag(QDomNode myNode,
00581     ValueListFormatData *formatDataList, int formatPos, int formatLen,
00582     KWEFKWordLeader *leader)
00583 {
00584     if ( (formatPos == -1) || (formatLen == -1) )
00585     {
00586         // We have no position and no length defined
00587         kdWarning(30508) << "Missing variable formatting!" << endl;
00588         return;
00589     }
00590     FormatData formatData(4, formatPos, formatLen);
00591     QValueList<TagProcessing> tagProcessingList;
00592     tagProcessingList.append(TagProcessing("VARIABLE",   ProcessVariableTag, &formatData.variable));
00593     // As variables can have a formating too, we have to process formating
00594     AppendTagProcessingFormatOne(tagProcessingList,formatData);
00595     ProcessSubtags (myNode, tagProcessingList, leader);
00596 
00597     (*formatDataList) << formatData;
00598 }
00599 
00600 
00601 static void SubProcessFormatSixTag(QDomNode myNode,
00602     ValueListFormatData *formatDataList, int formatPos, int formatLen,
00603     KWEFKWordLeader *leader)
00604 {
00605     if ( formatPos != -1 && formatLen != -1 )
00606     {
00607         QString instance;
00608 
00609         QValueList<TagProcessing> tagProcessingList;
00610         // TODO: We can have all layout information as in regular texts
00611         //       They simply apply to the table frames
00612         //       FONT is just the first that we've come across so far
00613         tagProcessingList << TagProcessing ( "FONT" )
00614                             << TagProcessing ( "ANCHOR", ProcessAnchorTag, &instance );
00615         ProcessSubtags (myNode, tagProcessingList, leader);
00616 #if 0
00617         kdDebug (30508) << "DEBUG: Adding frame anchor " << instance << endl;
00618 #endif
00619 
00620         (*formatDataList) << FormatData ( formatPos, formatLen, FrameAnchor (instance) );
00621     }
00622     else
00623     {
00624         kdWarning (30508) << "Missing or bad anchor formatting!" << endl;
00625     }
00626 }
00627 
00628 static void ProcessFormatTag (QDomNode myNode, void *tagData, KWEFKWordLeader *leader)
00629 {
00630     ValueListFormatData *formatDataList = (ValueListFormatData *) tagData;
00631     int formatId  = -1;
00632     int formatPos = -1;
00633     int formatLen = -1;
00634 
00635     QValueList<AttrProcessing> attrProcessingList;
00636     attrProcessingList << AttrProcessing ( "id",  formatId  );
00637     attrProcessingList << AttrProcessing ( "pos", formatPos );
00638     attrProcessingList << AttrProcessing ( "len", formatLen );
00639     ProcessAttributes (myNode, attrProcessingList);
00640 
00641     if ( ( formatId == -1 ) && ( leader->m_oldSyntax ) )
00642     {
00643         formatId = 1; // KWord 0.8 did not define it in <LAYOUT>
00644     }
00645 
00646     switch ( formatId )
00647     {
00648     case 1: // regular texts
00649         {
00650             SubProcessFormatOneTag(myNode, formatDataList, formatPos, formatLen, leader);
00651             break;
00652         }
00653     case 2: // text image (KWord 0.8)
00654         {
00655             SubProcessFormatTwoTag(myNode, formatDataList, formatPos, formatLen, leader);
00656             break;
00657         }
00658     case 3: // KWord 0.8 tabulator
00659         {
00660             SubProcessFormatThreeTag(myNode, formatDataList, formatPos, formatLen, leader);
00661             break;
00662         }
00663     case 4: // variables
00664         {
00665             SubProcessFormatFourTag(myNode, formatDataList, formatPos, formatLen, leader);
00666             break;
00667         }
00668     case 6: // anchors
00669         {
00670             SubProcessFormatSixTag(myNode, formatDataList, formatPos, formatLen, leader);
00671             break;
00672         }
00673     case -1:
00674         {
00675             kdWarning (30508) << "FORMAT attribute id value not set!" << endl;
00676             AllowNoSubtags (myNode, leader);
00677             break;
00678         }
00679     case 5: // KWord 0.8 footnote
00680     default:
00681             kdWarning(30508) << "Unexpected FORMAT attribute id value " << formatId << endl;
00682             AllowNoSubtags (myNode, leader);
00683     }
00684 
00685 }
00686 
00687 
00688 void ProcessFormatsTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00689 {
00690     ValueListFormatData *formatDataList = (ValueListFormatData *) tagData;
00691 
00692     AllowNoAttributes (myNode);
00693 
00694     (*formatDataList).clear ();
00695     QValueList<TagProcessing> tagProcessingList;
00696     tagProcessingList << TagProcessing ( "FORMAT", ProcessFormatTag, formatDataList );
00697     ProcessSubtags (myNode, tagProcessingList, leader);
00698 }
00699 
00700 
00701 // --------------------------------------------------------------------------------
00702 
00703 
00704 static void ProcessCounterTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00705 {
00706     CounterData *counter = (CounterData *) tagData;
00707 
00708     // Be extra careful with data declared as enum (it could be very different from an int)
00709     int counterStyle = counter->style;
00710     int counterNumbering = counter->numbering;
00711 
00712     QValueList<AttrProcessing> attrProcessingList;
00713     attrProcessingList << AttrProcessing ( "type",            counterStyle );
00714     attrProcessingList << AttrProcessing ( "depth",           counter->depth           );
00715     attrProcessingList << AttrProcessing ( "bullet",          counter->customCharacter );
00716     attrProcessingList << AttrProcessing ( "start",           counter->start           );
00717     attrProcessingList << AttrProcessing ( "numberingtype",   counterNumbering );
00718     attrProcessingList << AttrProcessing ( "lefttext",        counter->lefttext        );
00719     attrProcessingList << AttrProcessing ( "righttext",       counter->righttext       );
00720     attrProcessingList << AttrProcessing ( "bulletfont",      counter->customFont      );
00721     attrProcessingList << AttrProcessing ( "customdef"  );
00722     attrProcessingList << AttrProcessing ( "text",            counter->text            );
00723     attrProcessingList << AttrProcessing ( "display-levels" );
00724     attrProcessingList << AttrProcessing ( "align" );
00725     ProcessAttributes (myNode, attrProcessingList);
00726 
00727     counter->style = CounterData::Style( counterStyle );
00728     counter->numbering = CounterData::Numbering( counterNumbering );
00729 
00730     AllowNoSubtags (myNode, leader);
00731 }
00732 
00733 
00734 static void ProcessLayoutTabulatorTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00735 {
00736     TabulatorList* tabulatorList = (TabulatorList*) tagData;
00737 
00738     TabulatorData tabulator;
00739 
00740     QValueList<AttrProcessing> attrProcessingList;
00741 
00742     attrProcessingList
00743         << AttrProcessing ( "ptpos",   tabulator.m_ptpos   )
00744         << AttrProcessing ( "type",    tabulator.m_type    )
00745         << AttrProcessing ( "filling", tabulator.m_filling )
00746         << AttrProcessing ( "width",   tabulator.m_width   )
00747         << AttrProcessing ( "alignchar" )
00748         ;
00749 
00750     if ( leader->m_oldSyntax )
00751     {
00752         // Avoid too many warning
00753         attrProcessingList
00754             << AttrProcessing ( "mmpos" )
00755             << AttrProcessing ( "inchpos" ) // Never ever use it, as this value is mostly wrong (e.g. 1.1009e+15)
00756         ;
00757     }
00758 
00759     ProcessAttributes (myNode, attrProcessingList);
00760     tabulatorList->append(tabulator);
00761 
00762     AllowNoSubtags (myNode, leader);
00763 }
00764 
00765 
00766 static void ProcessIndentsTag (QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00767 {
00768     LayoutData *layout = (LayoutData *) tagData;
00769 
00770     QValueList<AttrProcessing> attrProcessingList;
00771     attrProcessingList << AttrProcessing ("first" , layout->indentFirst );
00772     attrProcessingList << AttrProcessing ("left"  , layout->indentLeft  );
00773     attrProcessingList << AttrProcessing ("right" , layout->indentRight );
00774     ProcessAttributes (myNode, attrProcessingList);
00775 
00776     AllowNoSubtags (myNode, leader);
00777 }
00778 
00779 
00780 static void ProcessLayoutOffsetTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00781 {
00782     LayoutData *layout = (LayoutData *) tagData;
00783 
00784     QValueList<AttrProcessing> attrProcessingList;
00785     attrProcessingList << AttrProcessing ("after" ,  layout->marginBottom );
00786     attrProcessingList << AttrProcessing ("before" , layout->marginTop    );
00787     ProcessAttributes (myNode, attrProcessingList);
00788 
00789     AllowNoSubtags (myNode, leader);
00790 }
00791 
00792 
00793 static void ProcessLineBreakingTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00794 {
00795     LayoutData *layout = (LayoutData *) tagData;
00796 
00797     QString strBefore, strAfter;
00798 
00799     QValueList<AttrProcessing> attrProcessingList;
00800     attrProcessingList << AttrProcessing ( "linesTogether",       layout->keepLinesTogether  );
00801     attrProcessingList << AttrProcessing ( "hardFrameBreak",      layout->pageBreakBefore );
00802     attrProcessingList << AttrProcessing ( "hardFrameBreakAfter", layout->pageBreakAfter  );
00803     attrProcessingList << AttrProcessing ( "keepWithNext" ); // RTF import filter
00804     ProcessAttributes (myNode, attrProcessingList);
00805 
00806     AllowNoSubtags (myNode, leader);
00807 }
00808 
00809 
00810 static void ProcessShadowTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader)
00811 {
00812     LayoutData *layout = (LayoutData *) tagData;
00813 
00814     int red=0;
00815     int green=0;
00816     int blue=0;
00817 
00818     QValueList<AttrProcessing> attrProcessingList;
00819     attrProcessingList << AttrProcessing ( "distance", layout->shadowDistance );
00820     attrProcessingList << AttrProcessing ( "direction", layout->shadowDirection );
00821     attrProcessingList << AttrProcessing ( "red",      red   );
00822     attrProcessingList << AttrProcessing ( "green",    green );
00823     attrProcessingList << AttrProcessing ( "blue",     blue  );
00824     ProcessAttributes (myNode, attrProcessingList);
00825 
00826     layout->shadowColor.setRgb(red,green,blue);
00827 
00828     AllowNoSubtags (myNode, leader);
00829 }
00830 
00831 static void ProcessAnyBorderTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00832 {
00833     BorderData *border =  static_cast <BorderData*> (tagData);
00834 
00835     int red=0;
00836     int green=0;
00837     int blue=0;
00838 
00839     QValueList<AttrProcessing> attrProcessingList;
00840     attrProcessingList << AttrProcessing ( "red",   red   );
00841     attrProcessingList << AttrProcessing ( "green", green );
00842     attrProcessingList << AttrProcessing ( "blue",  blue  );
00843     attrProcessingList << AttrProcessing ( "style", border->style );
00844     attrProcessingList << AttrProcessing ( "width", border->width );
00845     ProcessAttributes (myNode, attrProcessingList);
00846 
00847     border->color.setRgb(red,green,blue);
00848 
00849     AllowNoSubtags (myNode, leader);
00850 }
00851 
00852 static void ProcessFollowingTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00853 {
00854     ProcessOneAttrTag (myNode, "name", "QString", tagData, leader);
00855 }
00856 
00857 static void ProcessLinespacingTag (QDomNode myNode, void *tagData, KWEFKWordLeader* /*leader*/ )
00858 {
00859     LayoutData *layout = (LayoutData *) tagData;
00860     QString oldValue, spacingType;
00861     double spacingValue;
00862 
00863     QValueList<AttrProcessing> attrProcessingList;
00864     attrProcessingList << AttrProcessing ("value" , oldValue );
00865     attrProcessingList << AttrProcessing ("type" , spacingType );
00866     attrProcessingList << AttrProcessing ("spacingvalue"  , spacingValue  );
00867     ProcessAttributes (myNode, attrProcessingList);
00868 
00869     // KWord pre-1.2 uses only the "value" attribute (stored in oldValue)
00870     // while 1.2 uses mainly "type" and "spacingvalue", while keeping "value" for compatibility
00871 
00872     if ( spacingType.isEmpty() )
00873     {
00874         // for old format
00875         if( oldValue == "oneandhalf" )
00876             layout->lineSpacingType = LayoutData::LS_ONEANDHALF;
00877         else if ( oldValue == "double" )
00878             layout->lineSpacingType = LayoutData::LS_DOUBLE;
00879         else
00880         {
00881             bool ok = false;
00882             const double size = oldValue.toDouble( &ok );
00883             if ( ok && ( size >= 0.0 ) ) // 0 is allowed but negative values are not
00884             {
00885                 // We have a valid size
00886                 layout->lineSpacingType = LayoutData::LS_CUSTOM; // set to custom
00887                 layout->lineSpacing     = size;
00888             }
00889             else
00890                layout->lineSpacingType = LayoutData::LS_SINGLE; // assume single linespace
00891          }
00892     }
00893     else
00894     {
00895         // for new format
00896         if( spacingType == "oneandhalf" )
00897             layout->lineSpacingType = LayoutData::LS_ONEANDHALF;
00898         else if ( spacingType == "double" )
00899             layout->lineSpacingType = LayoutData::LS_DOUBLE;
00900         else if ( spacingType == "custom" )
00901             layout->lineSpacingType = LayoutData::LS_CUSTOM;
00902         else if ( spacingType == "atleast" )
00903             layout->lineSpacingType = LayoutData::LS_ATLEAST;
00904         else if ( spacingType == "multiple" )
00905             layout->lineSpacingType = LayoutData::LS_MULTIPLE;
00906         else if ( spacingType == "fixed" )
00907             layout->lineSpacingType = LayoutData::LS_FIXED;
00908         else
00909              layout->lineSpacingType = LayoutData::LS_SINGLE; // assume single linespace
00910         layout->lineSpacing = spacingValue;
00911     }
00912 }
00913 
00914 static void ProcessLineSpaceTag (QDomNode myNode, void *tagData, KWEFKWordLeader* /*leader*/ )
00915 {
00916     // <LINESPACE> is an old tag, of before syntax 1
00917     LayoutData *layout = (LayoutData *) tagData;
00918     double spacingValue = 0.0;
00919 
00920     QValueList<AttrProcessing> attrProcessingList;
00921     attrProcessingList << AttrProcessing ( "pt", spacingValue );
00922     attrProcessingList << AttrProcessing ( "mm" );
00923     attrProcessingList << AttrProcessing ( "inch" );
00924     ProcessAttributes (myNode, attrProcessingList);
00925 
00926     layout->lineSpacingType = LayoutData::LS_CUSTOM; // set to custom
00927     layout->lineSpacing     = spacingValue;
00928 }
00929 
00930 static void ProcessFlowTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00931 {
00932     LayoutData *layout = (LayoutData *) tagData;
00933 
00934     QString oldAlign, normalAlign;
00935 
00936     QValueList<AttrProcessing> attrProcessingList;
00937     if ( leader->m_oldSyntax )
00938     {
00939         // KWord 0.8
00940         attrProcessingList << AttrProcessing ( "value", oldAlign ); // KWord 0.8
00941     }
00942     // New syntax and some files from syntax 1
00943     attrProcessingList << AttrProcessing ( "align", normalAlign );
00944     attrProcessingList << AttrProcessing ( "dir" ); // ### TODO
00945     ProcessAttributes (myNode, attrProcessingList);
00946 
00947     if ( leader->m_oldSyntax && normalAlign.isEmpty() )
00948     {
00949         if ( oldAlign.isEmpty() )
00950         {
00951             layout->alignment = "left"; // KWord 0.8 did not support right-to-left
00952         }
00953         else
00954         {
00955             const int align = oldAlign.toInt();
00956             if ( ( align < 0 ) || ( align > 3) )
00957             {
00958                 kdWarning(30508) << "KWord 0.8 flow unknown: " << oldAlign << endl;
00959                 layout->alignment = "left"; // Unknown, so assume left
00960             }
00961             else
00962             {
00963                 const char* flows[]={"left", "right", "center", "justify" };
00964                 layout->alignment = flows[ align ];
00965             }
00966         }
00967         kdDebug(30508) << "KWord 0.8 flow: " << oldAlign << " corrected: " << layout->alignment << endl;
00968     }
00969     else
00970     {
00971         layout->alignment = normalAlign;
00972     }
00973 
00974 }
00975 
00976 
00977 void ProcessLayoutTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00978 // Processes <LAYOUT> and <STYLE>
00979 {
00980     QValueList<AttrProcessing> attrProcessingList;
00981     attrProcessingList << AttrProcessing ( "outline" ); // Only in <STYLE>
00982     ProcessAttributes (myNode, attrProcessingList);
00983 
00984     LayoutData *layout = (LayoutData *) tagData;
00985 
00986     ValueListFormatData formatDataList;
00987 
00988     QValueList<TagProcessing> tagProcessingList;
00989     tagProcessingList << TagProcessing ( "NAME",         ProcessStringValueTag,       &layout->styleName           );
00990     tagProcessingList << TagProcessing ( "FOLLOWING",    ProcessFollowingTag,         &layout->styleFollowing      );
00991     tagProcessingList << TagProcessing ( "FLOW",         ProcessFlowTag,              layout );
00992     tagProcessingList << TagProcessing ( "INDENTS",      ProcessIndentsTag,           layout              );
00993     tagProcessingList << TagProcessing ( "OFFSETS",      ProcessLayoutOffsetTag,      layout              );
00994     tagProcessingList << TagProcessing ( "LINESPACING",  ProcessLinespacingTag,       layout              );
00995     tagProcessingList << TagProcessing ( "PAGEBREAKING", ProcessLineBreakingTag,      layout              );
00996     tagProcessingList << TagProcessing ( "LEFTBORDER",   ProcessAnyBorderTag,         &layout->leftBorder          );
00997     tagProcessingList << TagProcessing ( "RIGHTBORDER",  ProcessAnyBorderTag,         &layout->rightBorder         );
00998     tagProcessingList << TagProcessing ( "TOPBORDER",    ProcessAnyBorderTag,         &layout->topBorder           );
00999     tagProcessingList << TagProcessing ( "BOTTOMBORDER", ProcessAnyBorderTag,         &layout->bottomBorder        );
01000     tagProcessingList << TagProcessing ( "COUNTER",      ProcessCounterTag,           &layout->counter    );
01001     tagProcessingList << TagProcessing ( "FORMAT",       ProcessFormatTag,            &formatDataList     );
01002     tagProcessingList << TagProcessing ( "TABULATOR",    ProcessLayoutTabulatorTag,   &layout->tabulatorList       );
01003     tagProcessingList << TagProcessing ( "SHADOW",       ProcessShadowTag,            layout                       );
01004 
01005     if ( leader->m_oldSyntax )
01006     {
01007         layout->indentLeft = 0.0; // ### TODO: needed or not?
01008         tagProcessingList
01009             << TagProcessing ( "OHEAD",  ProcessOldLayoutChildTag, &layout->marginTop )
01010             << TagProcessing ( "OFOOT",  ProcessOldLayoutChildTag, &layout->marginBottom )
01011             << TagProcessing ( "ILEFT",  ProcessOldLayoutChildTag, &layout->indentLeft )
01012             << TagProcessing ( "IFIRST", ProcessOldLayoutChildTag, &layout->indentFirst )
01013             << TagProcessing ( "LINESPACE", ProcessLineSpaceTag,   layout )
01014             ;
01015     }
01016 
01017     ProcessSubtags (myNode, tagProcessingList, leader);
01018 
01019 
01020     if ( formatDataList.isEmpty () )
01021     {
01022         kdWarning (30508) << "No FORMAT tag within LAYOUT/STYLE!" << endl;
01023     }
01024     else
01025     {
01026         layout->formatData = formatDataList.first ();
01027 
01028         if ( formatDataList.count () > 1 )
01029         {
01030             kdWarning (30508) << "More than one FORMAT tag within LAYOUT/STYLE!" << endl;
01031         }
01032     }
01033 
01034     if ( layout->styleName.isEmpty () )
01035     {
01036         layout->styleName = "Standard";
01037         kdWarning (30508) << "Empty layout name!" << endl;
01038     }
01039 
01040 }
01041 
01042 
01043 static void ProcessImageKeyTag ( QDomNode myNode,
01044     void *tagData, KWEFKWordLeader *)
01045 {
01046     KoPictureKey *key = (KoPictureKey*) tagData;
01047 
01048     // Let KoPicture do the loading
01049     key->loadAttributes(myNode.toElement());
01050 }
01051 
01052 void ProcessImageTag ( QDomNode myNode,
01053     void *tagData, KWEFKWordLeader *leader )
01054 { // <PICTURE>
01055     QValueList<AttrProcessing> attrProcessingList;
01056     attrProcessingList << AttrProcessing ( "keepAspectRatio" );
01057     ProcessAttributes (myNode, attrProcessingList);
01058 
01059     QValueList<TagProcessing> tagProcessingList;
01060     tagProcessingList << TagProcessing ( "KEY", ProcessImageKeyTag, tagData );
01061     ProcessSubtags (myNode, tagProcessingList, leader);
01062 }
01063 
KDE Home | KDE Accessibility Home | Description of Access Keys