filters

KWEFKWordLeader.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    Part of this code comes from 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 #include <qfile.h>
00037 #include <qdom.h>
00038 
00039 #include <kdebug.h>
00040 #include <klocale.h>
00041 #include <kmessagebox.h>
00042 
00043 #include <KoGlobal.h>
00044 #include <KoStore.h>
00045 
00046 #include "KWEFStructures.h"
00047 #include "TagProcessing.h"
00048 #include "ProcessDocument.h"
00049 #include "KWEFBaseWorker.h"
00050 #include "KWEFKWordLeader.h"
00051 
00052 KWEFKWordLeader::KWEFKWordLeader(void)
00053     : m_syntaxVersion(-1), m_oldSyntax(false), m_worker(NULL), m_chain(NULL), m_hType(0), m_fType(0)
00054 {
00055 }
00056 
00057 KWEFKWordLeader::KWEFKWordLeader(KWEFBaseWorker* newWorker)
00058     : m_syntaxVersion(-1), m_oldSyntax(false), m_worker(newWorker), m_chain(NULL)
00059 {
00060     if (newWorker) newWorker->registerKWordLeader(this);
00061 }
00062 
00063 KWEFKWordLeader::~KWEFKWordLeader(void)
00064 {
00065 }
00066 
00067 static FrameAnchor *findAnchor ( const KoPictureKey& key,
00068                                  QValueList<ParaData>& paraList )
00069 {
00070     kdDebug(30508) << "findAnchor " << key.toString() << endl;
00071     QValueList<ParaData>::Iterator paraIt;
00072 
00073     for ( paraIt = paraList.begin (); paraIt != paraList.end (); ++paraIt )
00074     {
00075         ValueListFormatData::Iterator formattingIt;
00076 
00077         for ( formattingIt = (*paraIt).formattingList.begin ();
00078               formattingIt != (*paraIt).formattingList.end ();
00079               formattingIt++ )
00080         {
00081             if ( (*formattingIt).id              == 6    &&
00082                  (*formattingIt).frameAnchor.key == key )
00083             {
00084                 kdDebug(30508) << "Found anchor " << (*formattingIt).frameAnchor.key.toString() << endl;
00085                 return &(*formattingIt).frameAnchor;
00086             }
00087         }
00088     }
00089 
00090     kdWarning(30508) << "findAnchor returning NULL!" << endl;
00091     return NULL;
00092 }
00093 
00094 static void ProcessHardBrkTag ( QDomNode myNode, void* tagData, KWEFKWordLeader* )
00095 {
00096     // <HARDBRK>
00097     bool* flag = (bool*) tagData;
00098     QValueList<AttrProcessing> attrProcessingList;
00099     attrProcessingList << AttrProcessing ( "frame", *flag );
00100     ProcessAttributes (myNode, attrProcessingList);
00101     if (*flag)
00102         kdDebug(30508) << "<HARDBRK frame=\"1\"> found" << endl;
00103 }
00104 
00105 static void InsertBookmarkFormatData (const int pos, const QString& name, const bool start,
00106     ValueListFormatData &paraFormatDataList)
00107 {
00108     ValueListFormatData::Iterator  paraFormatDataIt;
00109 
00110     FormatData book( start ? 1001 : 1002 , pos, 0 );
00111     book.variable.m_text = name;
00112 
00113     for (paraFormatDataIt = paraFormatDataList.begin ();
00114         paraFormatDataIt != paraFormatDataList.end ();
00115         paraFormatDataIt++)
00116     {
00117         if ( pos <= (*paraFormatDataIt).pos )
00118         {
00119             paraFormatDataList.insert ( paraFormatDataIt, book );
00120             return;
00121 
00122         }
00123         if ( ( pos > (*paraFormatDataIt).pos ) && ( pos < (*paraFormatDataIt).pos + (*paraFormatDataIt).len ) )
00124         {
00125             // Somewhere in the middle, we have to split the FormatData
00126             FormatData split ( *paraFormatDataIt );
00127             //const int oldlen = (*paraFormatDataIt).len;
00128             split.len = pos - (*paraFormatDataIt).pos;
00129             (*paraFormatDataIt).len -= split.len;
00130             (*paraFormatDataIt).pos = pos;
00131             paraFormatDataList.insert ( paraFormatDataIt, split );
00132             paraFormatDataList.insert ( paraFormatDataIt, book );
00133             return;
00134         }
00135     }
00136 
00137     // Still here? So we need to put the bookmark here:
00138     paraFormatDataList.append ( book );
00139 }
00140 
00141 
00142 void KWEFKWordLeader::createBookmarkFormatData( ParaData& paraData )
00143 {
00144     const int paraCount = m_paraCountMap[ m_currentFramesetName ];
00145 
00146     QValueList<Bookmark>::ConstIterator it;
00147     for (it = m_bookmarkList.begin(); it != m_bookmarkList.end(); ++it )
00148     {
00149         if ( (*(it)).m_frameset != m_currentFramesetName )
00150         {
00151             continue;
00152         }
00153         // As we always insert before, make first endings, then startings (problem is zero-length bookmark)
00154         if ( (*(it)).m_endparag == paraCount )
00155         {
00156             kdDebug(30508) << "Paragraph: " << paraCount << " end: " << (*(it)).m_name << endl;
00157             InsertBookmarkFormatData( (*(it)).m_cursorIndexEnd, (*(it)).m_name, false, paraData.formattingList);
00158 
00159         }
00160         if ( (*(it)).m_startparag == paraCount )
00161         {
00162             kdDebug(30508) << "Paragraph: " << paraCount << " begin: " << (*(it)).m_name << endl;
00163             InsertBookmarkFormatData( (*(it)).m_cursorIndexStart, (*(it)).m_name, true, paraData.formattingList);
00164         }
00165     }
00166 }
00167 
00168 static void ProcessParagraphTag ( QDomNode         myNode,
00169                                   void            *tagData,
00170                                   KWEFKWordLeader *leader )
00171 {
00172 #if 0
00173     kdDebug (30508) << "ProcessParagraphTag () - Begin" << endl;
00174 #endif
00175 
00176     QValueList<ParaData> *paraList = (QValueList<ParaData> *) tagData;
00177 
00178     AllowNoAttributes (myNode);
00179 
00180     // We need to adjust the paragraph number (0 if first)
00181     QMap<QString,int>::Iterator it = leader->m_paraCountMap.find( leader->m_currentFramesetName );
00182     if ( it == leader->m_paraCountMap.end() )
00183         leader->m_paraCountMap.insert( leader->m_currentFramesetName, 0 );
00184     else
00185         ++(*it);
00186     
00187     ParaData paraData;
00188 
00189     QValueList<TagProcessing> tagProcessingList;
00190     tagProcessingList << TagProcessing ( "TEXT",    ProcessTextTag,     &paraData.text           )
00191                       << TagProcessing ( "FORMATS", ProcessFormatsTag,  &paraData.formattingList )
00192                       << TagProcessing ( "LAYOUT",  ProcessLayoutTag,   &paraData.layout         );
00193     
00194     if ( leader->m_oldSyntax )
00195     {
00196         tagProcessingList.append( TagProcessing( "HARDBRK", ProcessHardBrkTag, &paraData.layout.pageBreakBefore ) );
00197     }
00198     ProcessSubtags (myNode, tagProcessingList, leader);
00199 
00200     leader->createBookmarkFormatData( paraData );
00201     CreateMissingFormatData (paraData.text, paraData.formattingList);
00202 
00203     // TODO/FIXME: why !paraData.text.isEmpty()
00204     if ( paraData.formattingList.isEmpty () && !paraData.text.isEmpty () )
00205     {
00206         if ( paraData.layout.formatData.id == 1 )
00207         {
00208             paraData.formattingList << paraData.layout.formatData;
00209         }
00210         else
00211         {
00212             kdWarning (30508) << "No useful FORMAT tag found for text in PARAGRAPH" << endl;
00213         }
00214     }
00215 
00216 
00217     *paraList << paraData;
00218 
00219 #if 0
00220     kdDebug (30508) << "ProcessParagraphTag () - End " << paraText << endl;
00221 #endif
00222 }
00223 
00224 
00225 static void ProcessFrameTag ( QDomNode myNode, void *tagData,
00226     KWEFKWordLeader *leader )
00227 {
00228     FrameAnchor* frameAnchor= (FrameAnchor*) tagData;
00229 
00230     int lRed=0, lBlue=0, lGreen=0;
00231     int rRed=0, rBlue=0, rGreen=0;
00232     int tRed=0, tBlue=0, tGreen=0;
00233     int bRed=0, bBlue=0, bGreen=0;
00234     int bkRed=255, bkBlue=255, bkGreen=255;
00235 
00236     frameAnchor->frame.lWidth=0.0;
00237     frameAnchor->frame.rWidth=0.0;
00238     frameAnchor->frame.tWidth=0.0;
00239     frameAnchor->frame.bWidth=0.0;
00240 
00241     QValueList<AttrProcessing> attrProcessingList;
00242     attrProcessingList
00243         << AttrProcessing ( "right",        frameAnchor->frame.right  )
00244         << AttrProcessing ( "left",         frameAnchor->frame.left   )
00245         << AttrProcessing ( "top",          frameAnchor->frame.top    )
00246         << AttrProcessing ( "bottom",       frameAnchor->frame.bottom )
00247 
00248         << AttrProcessing ( "min-height",   frameAnchor->frame.minHeight )
00249 
00250         << AttrProcessing ( "runaround",      frameAnchor->frame.runaround         )
00251         << AttrProcessing ( "runaroundSide",  frameAnchor->frame.runaroundSide )
00252         << AttrProcessing ( "runaroundGap",   frameAnchor->frame.runaroundGap   )
00253 
00254         << AttrProcessing ( "autoCreateNewFrame",  frameAnchor->frame.autoCreateNewFrame )
00255         << AttrProcessing ( "newFrameBehavior",    frameAnchor->frame.newFrameBehavior   )
00256         << AttrProcessing ( "newFrameBehaviour", frameAnchor->frame.newFrameBehavior ) // Depreciated name
00257 
00258         << AttrProcessing ( "copy",       frameAnchor->frame.copy      )
00259         << AttrProcessing ( "sheetSide",  frameAnchor->frame.sheetSide )
00260 
00261         << AttrProcessing ( "lWidth",   frameAnchor->frame.lWidth )
00262         << AttrProcessing ( "rWidth",   frameAnchor->frame.rWidth )
00263         << AttrProcessing ( "tWidth",   frameAnchor->frame.tWidth )
00264         << AttrProcessing ( "bWidth",   frameAnchor->frame.bWidth )
00265 
00266         << AttrProcessing ( "lRed",     lRed   )
00267         << AttrProcessing ( "lGreen",   lGreen )
00268         << AttrProcessing ( "lBlue",    lBlue  )
00269 
00270         << AttrProcessing ( "rRed",     rRed   )
00271         << AttrProcessing ( "rGreen",   rGreen )
00272         << AttrProcessing ( "rBlue",    rBlue  )
00273 
00274         << AttrProcessing ( "tRed",     tRed   )
00275         << AttrProcessing ( "tGreen",   tGreen )
00276         << AttrProcessing ( "tBlue",    tBlue  )
00277 
00278         << AttrProcessing ( "bRed",     bRed   )
00279         << AttrProcessing ( "bGreen",   bGreen )
00280         << AttrProcessing ( "bBlue",    bBlue  )
00281 
00282         << AttrProcessing ( "lStyle",    frameAnchor->frame.lStyle )
00283         << AttrProcessing ( "rStyle",    frameAnchor->frame.rStyle )
00284         << AttrProcessing ( "tStyle",    frameAnchor->frame.tStyle )
00285         << AttrProcessing ( "bStyle",    frameAnchor->frame.bStyle )
00286 
00287         << AttrProcessing ( "bkRed",     bkRed   )
00288         << AttrProcessing ( "bkGreen",   bkGreen )
00289         << AttrProcessing ( "bkBlue",    bkBlue  )
00290 
00291         << AttrProcessing ( "bkStyle",    frameAnchor->frame.bkStyle )
00292 
00293         << AttrProcessing ( "bleftpt",     frameAnchor->frame.bleftpt   )
00294         << AttrProcessing ( "brightpt",    frameAnchor->frame.brightpt  )
00295         << AttrProcessing ( "btoppt",      frameAnchor->frame.btoppt    )
00296         << AttrProcessing ( "bbottompt",   frameAnchor->frame.bbottompt )
00297         ;
00298 
00299     if ( leader->m_oldSyntax )
00300     {
00301         attrProcessingList
00302             << AttrProcessing ( "bleftmm" )
00303             << AttrProcessing ( "bleftinch" )
00304             << AttrProcessing ( "brightmm" )
00305             << AttrProcessing ( "brightinch" )
00306             << AttrProcessing ( "btopmm" )
00307             << AttrProcessing ( "btopinch" )
00308             << AttrProcessing ( "bbottommm" )
00309             << AttrProcessing ( "bbottominch" )
00310             ;
00311     }
00312     
00313     ProcessAttributes (myNode, attrProcessingList);
00314 
00315     frameAnchor->frame.lColor.setRgb( lRed, lGreen, lBlue );
00316     frameAnchor->frame.rColor.setRgb( rRed, rGreen, rBlue );
00317     frameAnchor->frame.tColor.setRgb( tRed, tGreen, tBlue );
00318     frameAnchor->frame.bColor.setRgb( bRed, bGreen, bBlue );
00319     frameAnchor->frame.bkColor.setRgb( bkRed, bkGreen, bkBlue );
00320 
00321     AllowNoSubtags (myNode, leader);
00322 }
00323 
00324 static void ProcessPictureAnchor( QDomNode myNode, KWEFKWordLeader *leader, FrameAnchor* frameAnchor, const int frameType )
00325 {
00326     frameAnchor->type = frameType;
00327  
00328     QValueList<TagProcessing> tagProcessingList;
00329     tagProcessingList
00330         << TagProcessing ( "FRAME",   ProcessFrameTag, frameAnchor )
00331         << TagProcessing ( "PICTURE", ProcessImageTag, &frameAnchor->picture.key )
00332         << TagProcessing ( "IMAGE",   ProcessImageTag, &frameAnchor->picture.key )
00333         << TagProcessing ( "CLIPART", ProcessImageTag, &frameAnchor->picture.key )
00334         ;
00335     ProcessSubtags (myNode, tagProcessingList, leader);
00336 
00337     kdDebug (30508) << "FRAMESET PICTURE KEY " << frameAnchor->picture.key.toString() << endl;
00338 
00339     frameAnchor->key = frameAnchor->picture.key;
00340 }
00341 
00342 static void ProcessTableAnchor( QDomNode myNode, KWEFKWordLeader *leader, FrameAnchor* frameAnchor,
00343     const int col, const int row, const int cols, const int rows )
00344 {
00345     frameAnchor->type = 6; // Table
00346 
00347     QValueList<ParaData> cellParaList;
00348     QValueList<TagProcessing> tagProcessingList;
00349     tagProcessingList << TagProcessing ( "FRAME",     ProcessFrameTag,     frameAnchor   )
00350                         << TagProcessing ( "PARAGRAPH", ProcessParagraphTag, &cellParaList );
00351     ProcessSubtags (myNode, tagProcessingList, leader);
00352 
00353     frameAnchor->table.addCell (col, row, cols, rows, cellParaList, frameAnchor->frame);
00354 }
00355 
00356 static void ProcessFramesetTag ( QDomNode        myNode,
00357                                 void            *tagData,
00358                                 KWEFKWordLeader *leader )
00359 {
00360 #if 0
00361     kdDebug (30508) << "ProcessFramesetTag () - Begin" << endl;
00362 #endif
00363 
00364     QValueList<ParaData> *paraList = (QValueList<ParaData> *) tagData;
00365 
00366     int     frameType = -1;
00367     int     frameInfo = -1;
00368     int     col       = -1;
00369     int     row       = -1;
00370     int     cols      = -1;
00371     int     rows      = -1;
00372     QString grpMgr;
00373 
00374     const QString oldName ( leader->m_currentFramesetName );
00375     
00376     QValueList<AttrProcessing> attrProcessingList;
00377     attrProcessingList << AttrProcessing ( "name",        leader->m_currentFramesetName      )
00378                        << AttrProcessing ( "frameType",   frameType )
00379                        << AttrProcessing ( "frameInfo",   frameInfo )
00380                        << AttrProcessing ( "removable" )
00381                        << AttrProcessing ( "visible" )
00382                        << AttrProcessing ( "grpMgr",      grpMgr    )
00383                        << AttrProcessing ( "row",         row       )
00384                        << AttrProcessing ( "col",         col       )
00385                        << AttrProcessing ( "rows",        rows      )
00386                        << AttrProcessing ( "cols",        cols      )
00387                        << AttrProcessing ( "protectSize" )
00388                         ;
00389     ProcessAttributes (myNode, attrProcessingList);
00390 
00391     switch ( frameType )
00392     {
00393     case 1:
00394             if ( grpMgr.isEmpty () )
00395             {
00396                 // As we do not support anything else than normal text, process only normal text.
00397                 // TODO: Treat the other types of frames (frameType)
00398                 if (frameInfo==0)
00399                 {
00400                     // Normal Text
00401                     kdDebug(30508) << "Processing Frameset: " << leader->m_currentFramesetName << endl;
00402                     QValueList<TagProcessing> tagProcessingList;
00403                     tagProcessingList.append(TagProcessing ( "FRAME" ));
00404                     tagProcessingList.append(TagProcessing ( "PARAGRAPH", ProcessParagraphTag,  paraList ));
00405                     ProcessSubtags (myNode, tagProcessingList, leader);
00406                 }
00407                 else if (frameInfo==1)
00408                 {
00409                     // header for first page
00410                     HeaderData header;
00411                     header.page = HeaderData::PAGE_FIRST;
00412                     QValueList<TagProcessing> tagProcessingList;
00413                     tagProcessingList.append(TagProcessing ( "FRAME" ));
00414                     tagProcessingList.append(TagProcessing ( "PARAGRAPH", ProcessParagraphTag,  &header.para ));
00415 
00416                     ProcessSubtags (myNode, tagProcessingList, leader);
00417                     leader->doHeader( header );
00418                 }
00419                 else if (frameInfo==2)
00420                 {
00421                     // header for even page
00422                     HeaderData header;
00423                     header.page = HeaderData::PAGE_EVEN;
00424                     QValueList<TagProcessing> tagProcessingList;
00425                     tagProcessingList.append(TagProcessing ( "FRAME" ));
00426                     tagProcessingList.append(TagProcessing ( "PARAGRAPH", ProcessParagraphTag,  &header.para ));
00427                     ProcessSubtags (myNode, tagProcessingList, leader);
00428                     leader->doHeader( header );
00429                 }
00430                 else if (frameInfo==3)
00431                 {
00432                     // header for odd page (or all page, if hType=0)
00433                     HeaderData header;
00434                     header.page = (leader->headerType() != 0 ) ? HeaderData::PAGE_ODD : HeaderData::PAGE_ALL;
00435                     QValueList<TagProcessing> tagProcessingList;
00436                     tagProcessingList.append(TagProcessing ( "FRAME" ));
00437                     tagProcessingList.append(TagProcessing ( "PARAGRAPH", ProcessParagraphTag,  &header.para ));
00438                     ProcessSubtags (myNode, tagProcessingList, leader);
00439                     leader->doHeader( header );
00440                 }
00441                 else if (frameInfo==4)
00442                 {
00443                     // footer for first page
00444                     FooterData footer;
00445                     footer.page = FooterData::PAGE_FIRST;
00446                     QValueList<TagProcessing> tagProcessingList;
00447                     tagProcessingList.append(TagProcessing ( "FRAME" ));
00448                     tagProcessingList.append(TagProcessing ( "PARAGRAPH", ProcessParagraphTag,  &footer.para ));
00449                     ProcessSubtags (myNode, tagProcessingList, leader);
00450                     leader->doFooter( footer );
00451                 }
00452                 else if (frameInfo==5)
00453                 {
00454                     // footer for even page
00455                     FooterData footer;
00456                     footer.page = FooterData::PAGE_EVEN;
00457                     QValueList<TagProcessing> tagProcessingList;
00458                     tagProcessingList.append(TagProcessing ( "FRAME" ));
00459                     tagProcessingList.append(TagProcessing ( "PARAGRAPH", ProcessParagraphTag,  &footer.para ));
00460                     ProcessSubtags (myNode, tagProcessingList, leader);
00461                     leader->doFooter( footer );
00462                 }
00463                 else if (frameInfo==6)
00464                 {
00465                     // footer for odd page (or all page, if fType=0)
00466                     FooterData footer;
00467                     footer.page = (leader->footerType() != 0) ? FooterData::PAGE_ODD : FooterData::PAGE_ALL;
00468                     QValueList<TagProcessing> tagProcessingList;
00469                     tagProcessingList.append(TagProcessing ( "FRAME" ));
00470                     tagProcessingList.append(TagProcessing ( "PARAGRAPH", ProcessParagraphTag,  &footer.para ));
00471                     ProcessSubtags (myNode, tagProcessingList, leader);
00472                     leader->doFooter( footer );
00473                 }
00474             }
00475             else
00476             {
00477                 if ( col != -1 && row != -1 )
00478                 {
00479                     if ( cols > 0 && rows > 0 )
00480                     {
00481 #if 0
00482                         kdDebug (30508) << "DEBUG - FRAMESET: table " << name << " col, row = "
00483                                         << col << ", " << row << ", Mgr = "<< grpMgr << endl;
00484 #endif
00485                         FrameAnchor *frameAnchor = findAnchor (grpMgr, *paraList);
00486                         if ( frameAnchor )
00487                         {
00488                             ProcessTableAnchor( myNode, leader, frameAnchor, col, row, cols, rows );
00489                         }
00490                         else
00491                         {
00492                             bool found = false;
00493                             KoPictureKey key( grpMgr );
00494                             QValueList<FrameAnchor>::Iterator it;
00495                             for ( it = leader->m_nonInlinedTableAnchors.begin(); it !=  leader->m_nonInlinedTableAnchors.end(); ++it )
00496                             {
00497                                 if ( (*it).key == key )
00498                                 {
00499                                     kdDebug(30508) << "Found pseudo-anchor for table: " << (*it).key.toString() << endl;
00500                                     found = true;
00501                                     break;
00502                                 }
00503                             }
00504                             
00505                             if ( found )
00506                             {
00507                                 ProcessTableAnchor( myNode, leader, &(*it), col, row, cols, rows );
00508                             }
00509                             else
00510                             {
00511                                 kdWarning(30508) << "Table anchor not found: " << grpMgr << endl;
00512                                 FrameAnchor anchor;
00513                                 ProcessTableAnchor( myNode, leader, &anchor, col, row, cols, rows );
00514                                 anchor.key = key; // Needed, so that the pseudo-anchor can be found again
00515                                 leader->m_nonInlinedTableAnchors << anchor;
00516                                 leader->m_unanchoredFramesets.append( grpMgr );
00517                             }
00518                         }
00519                     }
00520                     else
00521                     {
00522                         kdWarning (30508) << "Unexpected value for one of, or all FRAMESET attribute cols, rows: "
00523                                         << cols << ", " << rows << "!" << endl;
00524                         AllowNoSubtags (myNode, leader);
00525                     }
00526                 }
00527                 else
00528                 {
00529                     kdWarning (30508) << "Unset value for one of, or all FRAMESET attributes col, row: "
00530                                     << col << ", " << row << "!" << endl;
00531                     AllowNoSubtags (myNode, leader);
00532                     leader->m_unanchoredFramesets.append( leader->m_currentFramesetName );
00533                 }
00534             }
00535             break;
00536 
00537     case 2: // PICTURE
00538     case 5: // CLIPART: deprecated (up to KOffice 1.2 Beta 2)
00539         {
00540 #if 0
00541             kdDebug (30508) << "DEBUG: FRAMESET name of picture is " << name << endl;
00542 #endif
00543 
00544             FrameAnchor *frameAnchor = findAnchor ( leader->m_currentFramesetName, *paraList );
00545 
00546             if ( frameAnchor )
00547             {
00548                 ProcessPictureAnchor( myNode, leader, frameAnchor, frameType );
00549             }
00550             else
00551             {
00552                 // ### TODO: non-inlined picture?
00553                 // No anchor found, so the picture is not inlined
00554                 kdDebug (30508) << "ProcessFramesetTag: Couldn't find anchor " << leader->m_currentFramesetName << endl;
00555                 FrameAnchor anchor;
00556                 ProcessPictureAnchor( myNode, leader, &anchor, frameType );
00557                 leader->m_nonInlinedPictureAnchors << anchor;
00558                 leader->m_unanchoredFramesets.append( leader->m_currentFramesetName ); // DEBUG
00559             }
00560 
00561             break;
00562         }
00563 
00564     case 4: // KFormula
00565         {
00566             kdWarning(30508) << "KFormula frameset not supported yet!" << endl; // ### TODO
00567             break;
00568         }
00569     default:
00570             kdWarning (30508) << "Unexpected frametype " << frameType << " (in ProcessFramesetTag)" << endl;
00571     }
00572 
00573     leader->m_currentFramesetName = oldName;
00574     
00575 #if 0
00576     kdDebug (30508) << "ProcessFramesetTag () - End" << endl;
00577 #endif
00578 }
00579 
00580 
00581 static void ProcessFramesetsTag ( QDomNode        myNode,
00582                                   void            *tagData,
00583                                   KWEFKWordLeader *leader )
00584 {
00585     AllowNoAttributes (myNode);
00586     QValueList<TagProcessing> tagProcessingList;
00587     tagProcessingList << TagProcessing ( "FRAMESET", ProcessFramesetTag, tagData );
00588     ProcessSubtags (myNode, tagProcessingList, leader);
00589 }
00590 
00591 
00592 static void ProcessStyleTag (QDomNode myNode, void *, KWEFKWordLeader *leader )
00593 {
00594     LayoutData layout;
00595 
00596     ProcessLayoutTag (myNode, &layout, leader);
00597 
00598     leader->doFullDefineStyle (layout);
00599 }
00600 
00601 
00602 static void ProcessStylesPluralTag (QDomNode myNode, void *, KWEFKWordLeader *leader )
00603 {
00604     AllowNoAttributes (myNode);
00605 
00606     leader->doOpenStyles ();
00607 
00608     QValueList<TagProcessing> tagProcessingList;
00609     tagProcessingList << TagProcessing ( "STYLE", ProcessStyleTag, leader );
00610     ProcessSubtags (myNode, tagProcessingList, leader);
00611 
00612     leader->doCloseStyles ();
00613 }
00614 
00615 
00616 static void ProcessPaperBordersTag (QDomNode myNode, void*, KWEFKWordLeader* leader)
00617 {
00618 
00619     double left   = 0.0;
00620     double right  = 0.0;
00621     double top    = 0.0;
00622     double bottom = 0.0;
00623 
00624     QValueList<AttrProcessing> attrProcessingList;
00625     if ( leader->m_oldSyntax )
00626     {
00627         attrProcessingList
00628             << AttrProcessing ( "ptLeft",   left )
00629             << AttrProcessing ( "ptRight",  right )
00630             << AttrProcessing ( "ptTop",    top )
00631             << AttrProcessing ( "ptBottom", bottom )
00632             << AttrProcessing ( "mmLeft" )
00633             << AttrProcessing ( "mmRight" )
00634             << AttrProcessing ( "mmTop" )
00635             << AttrProcessing ( "mmBottom" )
00636             << AttrProcessing ( "inchLeft" )
00637             << AttrProcessing ( "inchRight" )
00638             << AttrProcessing ( "inchTop" )
00639             << AttrProcessing ( "inchBottom" )
00640             ;
00641     }
00642     else
00643     {
00644         attrProcessingList
00645             << AttrProcessing ( "left",   left )
00646             << AttrProcessing ( "right",  right )
00647             << AttrProcessing ( "top",    top )
00648             << AttrProcessing ( "bottom", bottom )
00649             ;
00650     }
00651     ProcessAttributes (myNode, attrProcessingList);
00652 
00653     leader->doFullPaperBorders(top, left, bottom, right);
00654 
00655     AllowNoSubtags (myNode, leader);
00656 }
00657 
00658 static void ProcessPaperTag (QDomNode myNode, void *, KWEFKWordLeader *leader)
00659 {
00660 
00661     int format      = -1;
00662     int orientation = -1;
00663     double width    = -1.0;
00664     double height   = -1.0;
00665     int hType       = -1;
00666     int fType       = -1;
00667     int columns = 1;
00668     double columnspacing = 36.0; // Half-inch
00669     int numPages = -1;
00670 
00671     QValueList<AttrProcessing> attrProcessingList;
00672     attrProcessingList << AttrProcessing ( "format",              format      )
00673                        << AttrProcessing ( "width",               width       )
00674                        << AttrProcessing ( "height",              height      )
00675                        << AttrProcessing ( "orientation",         orientation )
00676                        << AttrProcessing ( "columns",             columns )
00677                        << AttrProcessing ( "columnspacing",       columnspacing )
00678                        << AttrProcessing ( "pages",               numPages )
00679                        << AttrProcessing ( "hType",               hType        )
00680                        << AttrProcessing ( "fType",               fType        )
00681                        << AttrProcessing ( "spHeadBody" )
00682                        << AttrProcessing ( "spFootBody" )
00683                        << AttrProcessing ( "spFootNoteBody" )
00684                        << AttrProcessing ( "slFootNotePosition" )
00685                        << AttrProcessing ( "slFootNoteLength" )
00686                        << AttrProcessing ( "slFootNoteWidth" )
00687                        << AttrProcessing ( "slFootNoteType" );
00688 
00689     if ( leader->m_oldSyntax )
00690     {
00691         // ### TODO: in syntax 1 hType and fType have other values!
00692         attrProcessingList
00693             << AttrProcessing ( "ptWidth", width )
00694             << AttrProcessing ( "ptHeight", height )
00695             << AttrProcessing ( "ptColumnspc", columnspacing )
00696             << AttrProcessing ( "mmWidth" )
00697             << AttrProcessing ( "mmHeight" )
00698             << AttrProcessing ( "mmColumnspc" )
00699             << AttrProcessing ( "inchWidth" )
00700             << AttrProcessing ( "inchHeight" )
00701             << AttrProcessing ( "inchColumnspc" )
00702             ;
00703     }
00704 
00705     ProcessAttributes (myNode, attrProcessingList);
00706 
00707     leader->setHeaderType( hType );
00708     leader->setFooterType( fType );
00709 
00710     leader->doPageInfo ( hType, fType );
00711     leader->doFullPaperFormat (format, width, height, orientation);
00712     leader->doFullPaperFormatOther( columns, columnspacing, numPages );
00713 
00714     QValueList<TagProcessing> tagProcessingList;
00715     tagProcessingList
00716         << TagProcessing ( "PAPERBORDERS", ProcessPaperBordersTag, NULL )
00717         ;
00718 
00719     ProcessSubtags (myNode, tagProcessingList, leader);
00720 }
00721 
00722 static void ProcessVariableSettingsTag (QDomNode myNode, void *, KWEFKWordLeader *leader)
00723 {
00724     VariableSettingsData vs;
00725     QString print, creation, modification; // Dates (in ISO 8601 format)
00726     int creationYear = -1;
00727     int creationMonth = -1;
00728     int creationDay = -1;
00729     int modificationYear = -1;
00730     int modificationMonth = -1;
00731     int modificationDay = -1;
00732 
00733     QValueList<AttrProcessing> attrProcessingList;
00734     attrProcessingList << AttrProcessing ( "startingPageNumber", vs.startingPageNumber )
00735                        << AttrProcessing ( "displaylink", vs.displaylink )
00736                        << AttrProcessing ( "underlinelink", vs.underlinelink )
00737                        << AttrProcessing ( "displaycomment", vs.displaycomment )
00738                        << AttrProcessing ( "displayfieldcode", vs.displayfieldcode )
00739         ;
00740 
00741 
00742     // The following 3 attributes are from syntax 3 but at least the RTF import filter generate them with syntax 2.
00743     attrProcessingList
00744         << AttrProcessing ( "lastPrintingDate", print )
00745         << AttrProcessing ( "creationDate", creation )
00746         << AttrProcessing ( "modificationDate", modification );
00747     ;
00748 
00749     // Some files have the creation and modification date not in one attribute but in an attribute for each the year, the month, the day
00750     // ( e.g. syntax 2 file kofficetests/documents/export/kword/text/all.kwd )
00751     attrProcessingList
00752         << AttrProcessing( "modifyFileYear", modificationYear )
00753         << AttrProcessing( "modifyFileMonth", modificationMonth )
00754         << AttrProcessing( "modifyFileDay", modificationDay )
00755         << AttrProcessing( "createFileYear", creationYear )
00756         << AttrProcessing( "createFileMonth", creationMonth )
00757         << AttrProcessing( "createFileDay", creationDay )
00758         ;
00759 
00760     ProcessAttributes (myNode, attrProcessingList);
00761 
00762     if ( creation.isEmpty() )
00763     {
00764         if ( ( creationYear >= 1970 ) && QDate::isValid( creationYear, creationMonth, creationDay ) )
00765         {
00766             vs.creationTime = QDateTime( QDate( creationYear, creationMonth, creationDay ) );
00767         }
00768     }
00769     else
00770         vs.creationTime=QDateTime::fromString(creation, Qt::ISODate);
00771     //kdDebug(30508) << "Creation time: " << vs.creationTime.toString( Qt::ISODate ) << endl;
00772 
00773     if ( modification.isEmpty() )
00774     {
00775         if ( ( modificationYear >= 1970 ) && QDate::isValid( modificationYear, modificationMonth, modificationDay ) )
00776         {
00777             vs.modificationTime = QDateTime( QDate( modificationYear, modificationMonth, modificationDay ) );
00778         }
00779     }
00780     else
00781         vs.modificationTime=QDateTime::fromString(modification, Qt::ISODate);
00782     //kdDebug(30508) << "Modification time: " << vs.modificationTime.toString( Qt::ISODate ) << endl;
00783 
00784     if (!print.isEmpty())
00785         vs.printTime=QDateTime::fromString(print, Qt::ISODate);
00786     //kdDebug(30508) << "Print time: " << vs.printTime.toString( Qt::ISODate ) << endl;
00787 
00788     leader->doVariableSettings (vs);
00789 }
00790 
00791 static void ProcessSpellCheckIgnoreWordTag (QDomNode myNode, void *, KWEFKWordLeader *leader )
00792 {
00793     QString ignoreword;
00794 
00795     QValueList<AttrProcessing> attrProcessingList;
00796     attrProcessingList
00797         << AttrProcessing ( "word", ignoreword )
00798         ;
00799     ProcessAttributes (myNode, attrProcessingList);
00800 
00801     leader->doFullSpellCheckIgnoreWord (ignoreword);
00802 
00803     AllowNoSubtags (myNode, leader);
00804 }
00805 
00806 
00807 static void ProcessSpellCheckIgnoreListTag (QDomNode myNode, void *, KWEFKWordLeader *leader )
00808 {
00809     AllowNoAttributes (myNode);
00810 
00811     leader->doOpenSpellCheckIgnoreList ();
00812 
00813     QValueList<TagProcessing> tagProcessingList;
00814     tagProcessingList << TagProcessing ( "SPELLCHECKIGNOREWORD", ProcessSpellCheckIgnoreWordTag, leader );
00815     ProcessSubtags (myNode, tagProcessingList, leader);
00816 
00817     leader->doCloseSpellCheckIgnoreList ();
00818 }
00819 
00820 
00821 static void ProcessPixmapsKeyTag ( QDomNode         myNode,
00822                                    void            *tagData,
00823                                    KWEFKWordLeader *leader )
00824 {
00825     QValueList<ParaData> *paraList = (QValueList<ParaData> *) tagData;
00826 
00827     KoPictureKey key;
00828 
00829     // Let KoPictureKey do most of the loading
00830     key.loadAttributes(myNode.toElement());
00831     const QString name(myNode.toElement().attribute("name"));
00832 
00833     kdDebug(30508) << "search anchors: " << key.toString() << endl;
00834     bool found = false;
00835 
00836     // NOTE: we must always search in both inlined and non-inlined pictures. A picture can be used in both ways and a few times in each!
00837     
00838     // Process inlined pictures
00839     QValueList<ParaData>::Iterator paraIt;
00840 
00841     for ( paraIt = paraList->begin(); paraIt != paraList->end(); ++paraIt )
00842     {
00843         ValueListFormatData::Iterator formattingIt;
00844         for ( formattingIt = (*paraIt).formattingList.begin();
00845               formattingIt != (*paraIt).formattingList.end();
00846               formattingIt++ )
00847         {
00848             if ( ( ( (*formattingIt).id == 6 ) || ( (*formattingIt).id == 2 ) )
00849                  && (*formattingIt).frameAnchor.key == key )
00850             {
00851                 kdDebug(30508) << "Found anchor for inlined picture: " << (*formattingIt).frameAnchor.key.toString() << endl;
00852                 (*formattingIt).frameAnchor.picture.koStoreName = name;
00853                 found = true;
00854             }
00855         }
00856     }
00857     // Process non-inline pictures
00858     QValueList<FrameAnchor>::Iterator it;
00859     for ( it = leader->m_nonInlinedPictureAnchors.begin(); it !=  leader->m_nonInlinedPictureAnchors.end(); ++it )
00860     {
00861         if ( (*it).key == key )
00862         {
00863             kdDebug(30508) << "Found pseudo-anchor for non-inlined picture: " << (*it).key.toString() << endl;
00864             (*it).picture.koStoreName = name;
00865             found = true;
00866         }
00867     }
00868     
00869     if ( !found )
00870     {
00871         kdWarning (30508) << "Could not find any anchor for picture " << key.toString() << endl;
00872     }
00873 
00874     AllowNoSubtags (myNode, leader);
00875 }
00876 
00877 
00878 static void ProcessPixmapsTag ( QDomNode         myNode,
00879                                 void            *tagData,
00880                                 KWEFKWordLeader *leader )
00881 {
00882     AllowNoAttributes (myNode);
00883 
00884     QValueList<TagProcessing> tagProcessingList;
00885     tagProcessingList << TagProcessing ( "KEY", ProcessPixmapsKeyTag, tagData );
00886     ProcessSubtags (myNode, tagProcessingList, leader);
00887 }
00888 
00889 
00890 static void FreeCellParaLists ( QValueList<ParaData> &paraList )
00891 {
00892     QValueList<ParaData>::Iterator paraIt;
00893 
00894     for ( paraIt = paraList.begin (); paraIt != paraList.end (); ++paraIt )
00895     {
00896         ValueListFormatData::Iterator formattingIt;
00897 
00898         for ( formattingIt = (*paraIt).formattingList.begin ();
00899               formattingIt != (*paraIt).formattingList.end ();
00900               formattingIt++ )
00901         {
00902             if ( (*formattingIt).id == 6 && (*formattingIt).frameAnchor.type == 6 )
00903             {
00904                 QValueList<TableCell>::Iterator cellIt;
00905 
00906                 for ( cellIt = (*formattingIt).frameAnchor.table.cellList.begin ();
00907                       cellIt != (*formattingIt).frameAnchor.table.cellList.end ();
00908                       cellIt++ )
00909                 {
00910                     FreeCellParaLists ( *(*cellIt).paraList );   // recursion is great
00911                     delete (*cellIt).paraList;
00912                 }
00913             }
00914         }
00915     }
00916 }
00917 
00918 // like ProcessFramesetTag, but only handle footnotes
00919 static void ProcessFootnoteFramesetTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00920 {
00921     QString frameName;
00922     int frameType = -1, frameInfo = -1;
00923     bool visible = false;
00924 
00925     QValueList<AttrProcessing> attrProcessingList;
00926     attrProcessingList
00927         << AttrProcessing ( "name",        frameName      )
00928         << AttrProcessing ( "frameType",   frameType )
00929         << AttrProcessing ( "frameInfo",   frameInfo )
00930         << AttrProcessing ( "removable" )
00931         << AttrProcessing ( "visible",     visible )
00932         << AttrProcessing ( "grpMgr" )
00933         << AttrProcessing ( "row" )
00934         << AttrProcessing ( "col" )
00935         << AttrProcessing ( "rows" )
00936         << AttrProcessing ( "cols" )
00937         << AttrProcessing ( "protectSize" )
00938         ;
00939     ProcessAttributes (myNode, attrProcessingList);
00940 
00941     // for footnote frame, frameType is 1 and frameInfo is 7
00942     if( ( frameType == 1 ) && ( frameInfo == 7 ) )
00943     {
00944         FootnoteData footnote;
00945         footnote.frameName = frameName;
00946         QValueList<TagProcessing> tagProcessingList;
00947         tagProcessingList.append(TagProcessing ( "FRAME" ));
00948         tagProcessingList.append(TagProcessing ( "PARAGRAPH", ProcessParagraphTag,  &footnote.para ));
00949         ProcessSubtags (myNode, tagProcessingList, leader);
00950         leader->footnoteList.append( footnote );
00951     }
00952 }
00953 
00954 // like ProcessFramesetsTag, but only handle footnotes
00955 static void ProcessFootnoteFramesetsTag ( QDomNode myNode, void *tagData, KWEFKWordLeader *leader )
00956 {
00957     AllowNoAttributes (myNode);
00958 
00959     QValueList<TagProcessing> tagProcessingList;
00960     tagProcessingList << TagProcessing ( "FRAMESET", ProcessFootnoteFramesetTag, tagData );
00961     ProcessSubtags (myNode, tagProcessingList, leader);
00962 }
00963 
00964 static void ProcessBookmarkItemTag ( QDomNode myNode, void* tag, KWEFKWordLeader *leader )
00965 {
00966     QValueList<Bookmark> * bookmarkList = static_cast< QValueList<Bookmark> * > ( tag );
00967 
00968     Bookmark bookmark;
00969 
00970     QValueList<AttrProcessing> attrProcessingList;
00971     attrProcessingList
00972         << AttrProcessing ( "name", bookmark.m_name )
00973         << AttrProcessing ( "cursorIndexStart", bookmark.m_cursorIndexStart )
00974         << AttrProcessing ( "cursorIndexEnd", bookmark.m_cursorIndexEnd )
00975         << AttrProcessing ( "frameset", bookmark.m_frameset )
00976         << AttrProcessing ( "startparag", bookmark.m_startparag )
00977         << AttrProcessing ( "endparag", bookmark.m_endparag )
00978         ;
00979 
00980     ProcessAttributes (myNode, attrProcessingList);
00981 
00982     AllowNoSubtags( myNode, leader );
00983     
00984     // ### TODO: some verifications
00985 
00986     kdDebug(30508) << "Bookmark: " << bookmark.m_name << " in frameset " << bookmark.m_frameset << endl;
00987 
00988     bookmarkList->append( bookmark );
00989 }
00990 
00991 static void ProcessBookmarksTag ( QDomNode myNode, void* tag, KWEFKWordLeader *leader )
00992 {
00993     AllowNoAttributes (myNode);
00994 
00995     QValueList<TagProcessing> tagProcessingList;
00996     tagProcessingList << TagProcessing ( "BOOKMARKITEM", ProcessBookmarkItemTag, tag );
00997     ProcessSubtags (myNode, tagProcessingList, leader);
00998 }
00999 
01000 void ProcessDocTag ( QDomNode         myNode,
01001     void* /*tagData*/, KWEFKWordLeader* leader )
01002 {
01003     //kdDebug (30508) << "Entering ProcessDocTag" << endl;
01004 
01005     QString editor, author;
01006     
01007     QValueList<AttrProcessing> attrProcessingList;
01008 
01009     attrProcessingList
01010         << AttrProcessing ( "xmlns" )
01011         << AttrProcessing ( "editor", editor )
01012         << AttrProcessing ( "mime" )
01013         << AttrProcessing ( "syntaxVersion", leader->m_syntaxVersion )
01014         << AttrProcessing ( "author", author )
01015         << AttrProcessing ( "email" )
01016         ;
01017 
01018     ProcessAttributes( myNode, attrProcessingList );
01019 
01020     kdDebug(30508) << "Document written by " << editor << endl;
01021     kdDebug(30508) << "Document of syntax version " << leader->m_syntaxVersion << endl;
01022 
01023     if ( leader->m_syntaxVersion == 1 )
01024     {
01025         leader->m_oldSyntax = true; // Syntax 1 is old syntax
01026     }
01027     else if ( leader->m_syntaxVersion == -1 )
01028     {
01029         // We do not know the version, but it still might be an old syntax.
01030         // However such old documents have still an author attribute, so check its value
01031         if ( author == "Reginald Stadlbauer and Torben Weis" )
01032         {
01033             kdDebug(30508) << "No syntax version but author attribute matches => assuming old syntax" << endl;
01034             leader->m_oldSyntax = true;
01035         }
01036         else
01037         {
01038             kdWarning(30508) << "No syntax version found, author attribute does not match => assuming new syntax" << endl;
01039         }
01040     }
01041 
01042     leader->doOpenHead();
01043 
01044     // At first, process <SPELLCHECKIGNORELIST>, even if mostly it will not be needed
01045     QDomNode nodeIgnoreList=myNode.namedItem("SPELLCHECKIGNORELIST");
01046     if ( nodeIgnoreList.isNull () )
01047         kdDebug (30508) << "No <SPELLCHECKIGNORELIST>" << endl; // Most files will not have it!
01048     else
01049         ProcessSpellCheckIgnoreListTag (nodeIgnoreList, NULL, leader);
01050 
01051     // Process <PAPER> now, even if mostly the output will need to be delayed.
01052     QDomNode nodePaper=myNode.namedItem("PAPER");
01053     if ( nodePaper.isNull () )
01054         kdWarning (30508) << "No <PAPER>" << endl;
01055     else
01056         ProcessPaperTag (nodePaper, NULL, leader);
01057 
01058     // Process <VARIABLESETTINGS>
01059     QDomNode nodeVariableSettings=myNode.namedItem("VARIABLESETTINGS");
01060     if ( nodeVariableSettings.isNull () )
01061     kdWarning (30508) << "No <VARIABLESETTINGS>" << endl;
01062     else
01063     ProcessVariableSettingsTag (nodeVariableSettings, NULL, leader);
01064 
01065     // Then we process the styles
01066     QDomNode nodeStyles=myNode.namedItem("STYLES");
01067     if ( nodeStyles.isNull () )
01068         kdWarning (30508) << "No <STYLES>" << endl;
01069     else
01070         ProcessStylesPluralTag (nodeStyles, NULL, leader);
01071 
01072     // Process framesets, but only to find and extract footnotes (also endnotes)
01073     QValueList<FootnoteData> footnotes;
01074     QDomNode nodeFramesets=myNode.namedItem("FRAMESETS");
01075     if ( !nodeFramesets.isNull() )
01076         ProcessFootnoteFramesetsTag(nodeFramesets, &footnotes, leader );
01077 
01078     // Process all framesets and pictures
01079     QValueList<TagProcessing> tagProcessingList;
01080     QValueList<ParaData> paraList;
01081 
01082     tagProcessingList
01083         << TagProcessing ( "PAPER" ) // Already done
01084         << TagProcessing ( "ATTRIBUTES" )
01085         << TagProcessing ( "FRAMESETS",   ProcessFramesetsTag,    &paraList )
01086         << TagProcessing ( "STYLES" ) // Already done
01087         << TagProcessing ( "PICTURES",    ProcessPixmapsTag,      &paraList )
01088         << TagProcessing ( "PIXMAPS",     ProcessPixmapsTag,      &paraList )
01089         << TagProcessing ( "CLIPARTS",    ProcessPixmapsTag,      &paraList )
01090         << TagProcessing ( "EMBEDDED" )
01091         << TagProcessing ( "BOOKMARKS",   ProcessBookmarksTag,    &leader->m_bookmarkList )
01092         ;
01093 
01094     // TODO: why are the followings used by KWord 1.2 but are not in its DTD?
01095     tagProcessingList << TagProcessing ( "SERIALL" );
01096     tagProcessingList << TagProcessing ( "FOOTNOTEMGR" );
01097 
01098     ProcessSubtags (myNode, tagProcessingList, leader);
01099 
01100     leader->doCloseHead();
01101     leader->doDeclareNonInlinedFramesets( leader->m_nonInlinedPictureAnchors, leader->m_nonInlinedTableAnchors );
01102     leader->doOpenBody();
01103 
01104     leader->doFullDocument (paraList);
01105 
01106     kdDebug(30508) << "Unachored Framesets : START" << endl;
01107     QStringList::ConstIterator it;
01108     for ( it = leader->m_unanchoredFramesets.begin(); it != leader->m_unanchoredFramesets.end(); ++it )
01109     {
01110         kdDebug(30508) << (*it) << endl;
01111     }
01112     kdDebug(30508) << "Unachored Framesets : END" << endl;
01113     
01114     FreeCellParaLists (paraList);
01115 
01116     leader->doCloseBody();
01117 
01118     //kdDebug (30508) << "Exiting ProcessDocTag" << endl;
01119 }
01120 
01121 
01122 void KWEFKWordLeader::setWorker ( KWEFBaseWorker *newWorker )
01123 {
01124     m_worker = newWorker;
01125 
01126     if (newWorker)
01127         newWorker->registerKWordLeader(this);
01128 }
01129 
01130 
01131 KWEFBaseWorker *KWEFKWordLeader::getWorker(void) const
01132 {
01133     return m_worker;
01134 }
01135 
01136 
01137 // Short simple definition for methods with void parameter
01138 #define DO_VOID_DEFINITION(string) \
01139     bool KWEFKWordLeader::string() \
01140     {\
01141         if (m_worker) \
01142             return m_worker->string(); \
01143         return false; \
01144     }
01145 
01146 
01147 bool KWEFKWordLeader::doOpenFile ( const QString &filenameOut, const QString &to )
01148 {
01149     if ( m_worker )
01150         return m_worker->doOpenFile (filenameOut, to);
01151 
01152     // As it would be the first method to be called, warn if worker is NULL
01153     kdError (30508) << "No Worker! (in KWEFKWordLeader::doOpenFile)" << endl;
01154 
01155     return false;
01156 }
01157 
01158 
01159 DO_VOID_DEFINITION (doCloseFile)
01160 DO_VOID_DEFINITION (doAbortFile)
01161 DO_VOID_DEFINITION (doOpenDocument)
01162 DO_VOID_DEFINITION (doCloseDocument)
01163 DO_VOID_DEFINITION (doOpenStyles)
01164 DO_VOID_DEFINITION (doCloseStyles)
01165 DO_VOID_DEFINITION (doOpenHead)
01166 DO_VOID_DEFINITION (doCloseHead)
01167 DO_VOID_DEFINITION (doOpenBody)
01168 DO_VOID_DEFINITION (doCloseBody)
01169 DO_VOID_DEFINITION (doOpenSpellCheckIgnoreList)
01170 DO_VOID_DEFINITION (doCloseSpellCheckIgnoreList)
01171 
01172 bool KWEFKWordLeader::doFullDocumentInfo (const KWEFDocumentInfo &docInfo)
01173 {
01174     if ( m_worker )
01175         return m_worker->doFullDocumentInfo (docInfo);
01176 
01177     return false;
01178 }
01179 
01180 
01181 bool KWEFKWordLeader::doVariableSettings (const VariableSettingsData &varSettings)
01182 {
01183     if ( m_worker )
01184         return m_worker->doVariableSettings (varSettings);
01185 
01186     return false;
01187 }
01188 
01189 
01190 bool KWEFKWordLeader::doFullDocument (const QValueList<ParaData> &paraList)
01191 {
01192     if ( m_worker )
01193         return m_worker->doFullDocument (paraList);
01194 
01195     return false;
01196 }
01197 
01198 bool KWEFKWordLeader::doPageInfo ( const int headerType, const int footerType )
01199 {
01200     if ( m_worker )
01201         return m_worker->doPageInfo ( headerType, footerType );
01202 
01203     return false;
01204 }
01205 
01206 bool KWEFKWordLeader::doFullPaperFormat ( const int format, const double width, const double height, const int orientation )
01207 {
01208     if ( m_worker )
01209         return m_worker->doFullPaperFormat (format, width, height, orientation);
01210 
01211     return false;
01212 }
01213 
01214 bool KWEFKWordLeader::doFullPaperBorders (const double top, const double left, const double bottom, const double right)
01215 {
01216     if ( m_worker )
01217         return m_worker->doFullPaperBorders (top, left, bottom, right);
01218 
01219     return false;
01220 }
01221 
01222 bool KWEFKWordLeader::doFullPaperFormatOther ( const int columns, const double columnspacing, const int numPages )
01223 {
01224     if ( m_worker )
01225         return m_worker->doFullPaperFormatOther ( columns, columnspacing, numPages );
01226     
01227     return false;
01228 }
01229 
01230 bool KWEFKWordLeader::doFullDefineStyle ( LayoutData &layout )
01231 {
01232     if ( m_worker )
01233         return m_worker->doFullDefineStyle (layout);
01234 
01235     return false;
01236 }
01237 
01238 bool KWEFKWordLeader::doFullSpellCheckIgnoreWord (const QString& ignoreword)
01239 {
01240     if ( m_worker )
01241         return m_worker->doFullSpellCheckIgnoreWord (ignoreword);
01242 
01243     return false;
01244 }
01245 
01246 bool KWEFKWordLeader::doHeader ( const HeaderData& header )
01247 {
01248     if ( m_worker )
01249         return m_worker->doHeader (header);
01250 
01251     return false;
01252 }
01253 
01254 bool KWEFKWordLeader::doFooter ( const FooterData& footer )
01255 {
01256     if ( m_worker )
01257         return m_worker->doFooter (footer);
01258 
01259     return false;
01260 }
01261 
01262 bool KWEFKWordLeader::doDeclareNonInlinedFramesets( QValueList<FrameAnchor>& pictureAnchors, QValueList<FrameAnchor>& tableAnchors )
01263 {
01264     if ( m_worker )
01265         return m_worker->doDeclareNonInlinedFramesets( pictureAnchors, tableAnchors );
01266 
01267     return false;
01268 }
01269 
01270 static bool ParseFile ( QIODevice* subFile, QDomDocument& doc)
01271 {
01272     QString errorMsg;
01273     int errorLine;
01274     int errorColumn;
01275 
01276     if ( !doc.setContent (subFile, &errorMsg, &errorLine, &errorColumn) )
01277     {
01278         kdError (30508) << "Parsing Error! Aborting! (in ParseFile)" << endl
01279             << "  Line: " << errorLine << " Column: " << errorColumn << endl
01280             << "  Message: " << errorMsg << endl;
01281         // ### TODO: the error is in which sub-file?
01282         KMessageBox::error( 0L, i18n("An error has occurred while parsing the KWord file.\nAt line: %1, column %2\nError message: %3")
01283             .arg( errorLine ).arg( errorColumn ).arg(i18n( "QXml", errorMsg.utf8() ) ),
01284             i18n("KWord Export Filter Library"), 0 );
01285         return false;
01286     }
01287     return true;
01288 }
01289 
01290 static bool ProcessStoreFile ( QIODevice* subFile,
01291     void (*processor) (QDomNode, void *, KWEFKWordLeader *),
01292     KWEFKWordLeader* leader)
01293 {
01294     if (!subFile)
01295     {
01296         kdWarning(30508) << "Could not get a device for the document!" << endl;
01297     }
01298     else if ( subFile->open ( IO_ReadOnly ) )
01299     {
01300         kdDebug (30508) << "Processing Document..." << endl;
01301         QDomDocument doc;
01302         if (!ParseFile(subFile, doc))
01303         {
01304             subFile->close();
01305             return false;
01306         }
01307         // We must close the subFile before processing,
01308         //  as the processing could open other sub files.
01309         //  However, it would crash if two sub files are opened together
01310         subFile->close();
01311 
01312         QDomNode docNode = doc.documentElement();
01313         processor (docNode, NULL, leader);
01314         return true;
01315     }
01316     else
01317     {
01318         // Note: we do not worry too much if we cannot open the document info!
01319         kdWarning (30508) << "Unable to open document!" << endl;
01320     }
01321     return false;
01322 }
01323 
01324 QIODevice* KWEFKWordLeader::getSubFileDevice(const QString& fileName)
01325 {
01326     KoStoreDevice* subFile;
01327 
01328     subFile=m_chain->storageFile(fileName,KoStore::Read);
01329 
01330     if (!subFile)
01331     {
01332         kdError(30508) << "Could not get a device for sub-file: " << fileName << endl;
01333         return NULL;
01334     }
01335     return subFile;
01336 }
01337 
01338 
01339 bool KWEFKWordLeader::loadSubFile(const QString& fileName, QByteArray& array)
01340 {
01341     KoStoreDevice* subFile;
01342 
01343     subFile=m_chain->storageFile(fileName,KoStore::Read);
01344 
01345     if (!subFile)
01346     {
01347         kdError(30508) << "Could not get a device for sub-file: " << fileName << endl;
01348         return false;
01349     }
01350     else if ( subFile->open ( IO_ReadOnly ) )
01351     {
01352         array = subFile->readAll();
01353         subFile->close ();
01354     }
01355     else
01356     {
01357         kdError(30508) << "Unable to open " << fileName << " sub-file" << endl;
01358         return false;
01359     }
01360 
01361     return true;
01362 }
01363 
01364 KoFilter::ConversionStatus KWEFKWordLeader::convert( KoFilterChain* chain,
01365     const QCString& from, const QCString& to)
01366 {
01367     if ( from != "application/x-kword" )
01368     {
01369         return KoFilter::NotImplemented;
01370     }
01371 
01372     if (!chain)
01373     {
01374         kdError(30508) << "'Chain' is NULL! Internal error of the filter system?" << endl;
01375         return KoFilter::StupidError;
01376     }
01377 
01378     m_chain=chain;
01379 
01380     if ( !doOpenFile (chain->outputFile(),to) )
01381     {
01382         kdError (30508) << "Worker could not open export file! Aborting!" << endl;
01383         return KoFilter::StupidError;
01384     }
01385 
01386     if ( !doOpenDocument () )
01387     {
01388         kdError (30508) << "Worker could not open document! Aborting!" << endl;
01389         doAbortFile ();
01390         return KoFilter::StupidError;
01391     }
01392 
01393     KoStoreDevice* subFile;
01394 
01395     subFile=chain->storageFile("documentinfo.xml",KoStore::Read);
01396     kdDebug (30508) << "Processing documentinfo.xml..." << endl;
01397     // Do not care if we cannot open the document info.
01398     ProcessStoreFile (subFile, ProcessDocumentInfoTag, this);
01399 
01400     subFile=chain->storageFile("root",KoStore::Read);
01401     kdDebug (30508) << "Processing root..." << endl;
01402     if (!ProcessStoreFile (subFile, ProcessDocTag, this))
01403     {
01404         kdWarning(30508) << "Opening root has failed. Trying raw XML file!" << endl;
01405 
01406         const QString filename( chain->inputFile() );
01407         if (filename.isEmpty() )
01408         {
01409             kdError(30508) << "Could not open document as raw XML! Aborting!" << endl;
01410             doAbortFile();
01411             return KoFilter::StupidError;
01412         }
01413         else
01414         {
01415             QFile file( filename );
01416             if ( ! ProcessStoreFile( &file, ProcessDocTag, this ) )
01417             {
01418                 kdError(30508) << "Could not process document! Aborting!" << endl;
01419                 doAbortFile();
01420                 return KoFilter::StupidError;
01421             }
01422         }
01423     }
01424     
01425     doCloseDocument ();
01426 
01427     doCloseFile ();
01428 
01429     return KoFilter::OK;
01430 }
KDE Home | KDE Accessibility Home | Description of Access Keys