filters

document.cc

00001 /*
00002 ** A program to convert the XML rendered by KWord into LATEX.
00003 **
00004 ** Copyright (C) 2000, 2001, 2002 Robert JACOLIN
00005 **
00006 ** This library is free software; you can redistribute it and/or
00007 ** modify it under the terms of the GNU Library General Public
00008 ** License as published by the Free Software Foundation; either
00009 ** version 2 of the License, or (at your option) any later version.
00010 **
00011 ** This library is distributed in the hope that it will be useful,
00012 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 ** Library General Public License for more details.
00015 **
00016 ** To receive a copy of the GNU Library General Public License, write to the
00017 ** Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 **
00020 */
00021 
00022 #include <stdlib.h>     /* for atoi function    */
00023 
00024 #include <kdebug.h>
00025 #include <ktempfile.h>
00026 #include <KoStore.h>
00027 
00028 #include <qdir.h>
00029 
00030 #include "fileheader.h"
00031 #include "document.h"
00032 #include "textFrame.h"
00033 #include "formula.h"
00034 #include "pixmapFrame.h"
00035 
00036 /*******************************************/
00037 /* Constructor                             */
00038 /*******************************************/
00039 Document::Document()
00040 {
00041 }
00042 
00043 /*******************************************/
00044 /* Destructor                              */
00045 /*******************************************/
00046 Document::~Document()
00047 {
00048     kdDebug(30522) << "Document destructor" << endl;
00049 }
00050 
00051 /*******************************************/
00052 /* Analyse                                 */
00053 /*******************************************/
00054 void Document::analyse(const QDomNode balise)
00055 {
00056     //QDomNode balise = getChild(balise_initial, "FRAMESET");
00057     kdDebug(30522) << getChildName(balise, 0) << endl;
00058     for(int index= 0; index < getNbChild(balise); index++)
00059     {
00060         Element *elt = 0;
00061         kdDebug(30522) << "--------------------------------------------------" << endl;
00062 
00063         kdDebug(30522) << getChildName(balise, index) << endl;
00064         switch(getTypeFrameset(getChild(balise, index)))
00065         {
00066             case ST_NONE:
00067                 kdDebug(30522) << "NONE" << endl;
00068                 break;
00069             case ST_TEXT:
00070                 kdDebug(30522) << "TEXT" << endl;
00071                 elt = new TextFrame;
00072                 elt->analyse(getChild(balise, index));
00073                 break;
00074             case ST_PICTURE:
00075                 kdDebug(30522) << "PICTURE" << endl;
00076                 elt = new PixmapFrame();
00077                 elt->analyse(getChild(balise, index));
00078                 break;
00079             case ST_PART:
00080                 kdDebug(30522) << "PART" << endl;
00081                 //elt = new Part;
00082                 //elt->analyse(getChild(balise, index));
00083                 break;
00084             case ST_FORMULA:
00085                 /* Just save the frameset in a QString input
00086                  * call the formula latex export filter
00087                  * save in output
00088                  * generate : write the output
00089                  */
00090                 kdDebug(30522) << "FORMULA" << endl;
00091                 elt = new Formula;
00092                 elt->analyse(getChild(balise, index));
00093                 break;
00094             case ST_HLINE:
00095                 kdDebug(30522) << "HLINE" << endl;
00096                 break;
00097             default:
00098                 kdDebug(30522) << "error " << elt->getType() << " " << ST_TEXT << endl;
00099         }
00100 
00101         /* 3. Add the Element in one of the lists */
00102         if(elt != 0)
00103         {
00104             kdDebug(30522) << "INFO : " << elt->getSection() << endl;
00105             switch(elt->getSection())
00106             {
00107                 case SS_FOOTERS: kdDebug(30522) << " FOOTER" <<endl;
00108                            _footers.append(elt);
00109                            break;
00110                 case SS_HEADERS: kdDebug(30522) << " HEADER" << endl;
00111                         _headers.append(elt);
00112                     break;
00113                 case SS_BODY:
00114                     if(!elt->isTable())
00115                     {
00116                         switch(elt->getType())
00117                         {
00118                             case ST_TEXT:
00119                                     _corps.append(elt);
00120                                     kdDebug(30522) << " BODY" << endl;
00121                                 break;
00122                             case ST_PART:
00123                                     kdDebug(30522) << " PART" <<endl;
00124                                     //_parts.append(elt);
00125                                 break;
00126                             case ST_FORMULA:
00127                                     kdDebug(30522) << " FORMULA" <<endl;
00128                                     _formulas.append(elt);
00129                                 break;
00130                             case ST_PICTURE:
00131                                     kdDebug(30522) << " PIXMAP" <<endl;
00132                                     _pixmaps.append(elt);
00133                                 break;
00134                             default:
00135                                     kdError(30522) << "Element frame type no supported or type unexpected." << endl;
00136                         }
00137                     }
00138                     break;
00139                 case SS_TABLE:
00140                     kdDebug(30522) << " TABLE" <<endl;
00141                     /* Don't add simplely the cell */
00142                     /* heriter ListTable de ListElement et surcharger
00143                      * la methode add. Une cellule est un element.
00144                      */
00145                     _tables.add(elt);
00146                     FileHeader::instance()->useTable();
00147                     break;
00148                 case SS_FOOTNOTES: /* Just for the new kwd file version */
00149                         _footnotes.append(elt);
00150                 break;
00151                 default: kdDebug(30522) << "UNKNOWN" << endl;
00152                     break;
00153             }
00154         }
00155         kdDebug(30522) << "END OF ANALYSE OF A FRAMESET" << endl;
00156     }
00157 }
00158 
00159 /*******************************************/
00160 /* AnalysePixmaps                          */
00161 /*******************************************/
00162 void Document::analysePixmaps(const QDomNode balise)
00163 {
00164     //QDomNode balise = getChild(balise_initial, "FRAMESET");
00165     for(int index= 0; index < getNbChild(balise); index++)
00166     {
00167         Key *key = 0;
00168         kdDebug(30522) << "NEW PIXMAP" << endl;
00169 
00170         key = new Key(Key::PIXMAP);
00171         key->analyse(getChild(balise, "KEY"));
00172         _keys.append(key);
00173     }
00174 }
00175 
00176 /*******************************************/
00177 /* getTypeFrameset                         */
00178 /*******************************************/
00179 SType Document::getTypeFrameset(const QDomNode balise)
00180 {
00181     SType type = ST_NONE;
00182     type = (SType) getAttr(balise, "frameType").toInt();
00183     return type;
00184 }
00185 
00186 /*******************************************/
00187 /* Generate                                */
00188 /*******************************************/
00189 void Document::generate(QTextStream &out, bool hasPreambule)
00190 {
00191     kdDebug(30522) << "DOC. GENERATION." << endl;
00192 
00193     if(hasPreambule)
00194         generatePreambule(out);
00195     kdDebug(30522) << "preambule : " << hasPreambule << endl;
00196 
00197     /* Body */
00198     kdDebug(30522) << endl << "body : " << _corps.count() << endl;
00199 
00200     if(hasPreambule)
00201     {
00202         out << "\\begin{document}" << endl;
00203         Config::instance()->indent();
00204     }
00205     QString dir = "";
00206     if( !Config::instance()->getPicturesDir().isEmpty() &&
00207             Config::instance()->getPicturesDir() != NULL &&
00208             FileHeader::instance()->hasGraphics())
00209     {
00210         out << endl << "\\graphicspath{{" << Config::instance()->getPicturesDir() << "}}" << endl;
00211     }
00212 
00213     if(_corps.getFirst() != 0)
00214         _corps.getFirst()->generate(out);
00215 
00216     /* Just for test */
00217     /*if(_tables.getFirst() != 0)
00218         _tables.getFirst()->generate(out);
00219     if(_formulas.getFirst() != 0)
00220         _formulas.getFirst()->generate(out);*/
00221     if(hasPreambule)
00222         out << "\\end{document}" << endl;
00223     Config::instance()->desindent();
00224     if(Config::instance()->getIndentation() != 0)
00225             kdError(30522) << "Error : indent != 0 at the end ! " << endl;
00226 }
00227 
00228 /*******************************************/
00229 /* GeneratePreambule                       */
00230 /*******************************************/
00231 void Document::generatePreambule(QTextStream &out)
00232 {
00233     Element* header;
00234     Element* footer;
00235 
00236     /* For each header */
00237     if(FileHeader::instance()->hasHeader())
00238     {
00239         kdDebug(30522) << "header : " << _headers.count() << endl;
00240 
00241         /* default : no rule */
00242         out << "\\renewcommand{\\headrulewidth}{0pt}" << endl;
00243         for(header = _headers.first(); header != 0; header = _headers.next())
00244         {
00245             generateTypeHeader(out, header);
00246         }
00247     }
00248 
00249     /* For each footer */
00250     if(FileHeader::instance()->hasFooter())
00251     {
00252         kdDebug(30522) << "footer : " << _footers.count() << endl;
00253 
00254         /* default : no rule */
00255         out << "\\renewcommand{\\footrulewidth}{0pt}" << endl;
00256         for(footer = _footers.first(); footer != 0; footer = _footers.next())
00257         {
00258             generateTypeFooter(out, footer);
00259         }
00260     }
00261     /* Specify what header/footer style to use */
00262     if(FileHeader::instance()->hasHeader() || FileHeader::instance()->hasFooter())
00263         out << "\\pagestyle{fancy}" << endl;
00264     else
00265     {
00266         out << "\\pagestyle{empty}" << endl;
00267     }
00268 }
00269 
00270 /*******************************************/
00271 /* GenerateTypeHeader                      */
00272 /*******************************************/
00273 void Document::generateTypeHeader(QTextStream &out, Element *header)
00274 {
00275     kdDebug(30522) << "generate header" << endl;
00276     if((FileHeader::instance()->getHeadType() == FileHeader::TH_ALL ||
00277         FileHeader::instance()->getHeadType() == FileHeader::TH_FIRST) && header->getInfo() == SI_EVEN)
00278     {
00279         out << "\\fancyhead[L]{}" << endl;
00280         out << "\\fancyhead[C]{";
00281         header->generate(out);
00282         out << "}" << endl;
00283         out << "\\fancyhead[R]{}" << endl;
00284     }
00285 
00286     switch(header->getInfo())
00287     {
00288         case SI_NONE:
00289         case SI_FIRST:
00290             break;
00291         case SI_ODD:
00292             out << "\\fancyhead[RO]{}" << endl;
00293             out << "\\fancyhead[CO]{";
00294             header->generate(out);
00295             out << "}" << endl;
00296             out << "\\fancyhead[LO]{}" << endl;
00297             break;
00298         case SI_EVEN:
00299             out << "\\fancyhead[RE]{}" << endl;
00300             out << "\\fancyhead[CE]{";
00301             header->generate(out);
00302             out << "}" << endl;
00303             out << "\\fancyhead[LE]{}" << endl;
00304             break;
00305     }
00306 
00307     if(header->getInfo() == SI_FIRST)
00308     {
00309         out << "\\fancyhead{";
00310         header->generate(out);
00311         out << "}" << endl;
00312         out << "\\thispagestyle{fancy}" << endl;
00313     }
00314 }
00315 
00316 /*******************************************/
00317 /* GenerateTypeFooter                      */
00318 /*******************************************/
00319 void Document::generateTypeFooter(QTextStream &out, Element *footer)
00320 {
00321     if(FileHeader::instance()->getFootType() == FileHeader::TH_ALL &&
00322             footer->getInfo() == SI_EVEN)
00323     {
00324         out << "\\fancyfoot[L]{}" << endl;
00325         out << "\\fancyfoot[C]{";
00326         footer->generate(out);
00327         out << "}" << endl;
00328         out << "\\fancyfoot[R]{}" << endl;
00329     }
00330     else if(FileHeader::instance()->getFootType() == FileHeader::TH_EVODD)
00331     {
00332         switch(footer->getInfo())
00333         {
00334             case SI_NONE:
00335             case SI_FIRST:
00336                 break;
00337             case SI_ODD:
00338                 out << "\\fancyfoot[CO]{";
00339                 footer->generate(out);
00340                 out << "}";
00341                 break;
00342             case SI_EVEN:
00343                 out << "\\fancyfoot[CE]{";
00344                 footer->generate(out);
00345                 out << "}";
00346                 break;
00347         }
00348     }
00349     else if(FileHeader::instance()->getFootType() == FileHeader::TH_FIRST &&
00350             footer->getInfo() == SI_FIRST)
00351     {
00352         out << "\\fanycfoot{";
00353         footer->generate(out);
00354         out << "}" << endl;
00355         out << "\\thispagestyle{fancy}" << endl;
00356     }
00357 }
00358 
00359 Element* Document::searchAnchor(QString anchor)
00360 {
00361     Element *elt = _tables.first();
00362     while(elt != 0)
00363     {
00364         kdDebug(30522) << elt->getGrpMgr() << endl;
00365         if(elt->getGrpMgr() == anchor)
00366             return elt;
00367         elt = _tables.next();
00368     }
00369     kdDebug(30522) << "No in table, search in formulae list." << endl;
00370     elt = _formulas.first();
00371     while(elt != 0)
00372     {
00373         if(elt->getName() == anchor)
00374             return elt;
00375         elt = _formulas.next();
00376     }
00377     kdDebug(30522) << "No in table and formulae, search in pictures." << endl;
00378     elt = _pixmaps.first();
00379     while(elt != 0)
00380     {
00381         if(elt->getName() == anchor)
00382             return elt;
00383         elt = _pixmaps.next();
00384     }
00385     return NULL;
00386 
00387 }
00388 
00389 Element* Document::searchFootnote(QString footnote)
00390 {
00391     Element* elt = _footnotes.first();
00392     while(elt != 0)
00393     {
00394         if(elt->getName() == footnote)
00395             return elt;
00396         elt = _footnotes.next();
00397     }
00398     return NULL;
00399 
00400 }
00401 
00402 Key* Document::searchKey(QString keyName)
00403 {
00404     Key* key = _keys.first();
00405     while(key != 0)
00406     {
00407         kdDebug(30522) << "key " << key->getFilename() << endl;
00408         if(key->getFilename() == keyName)
00409             return key;
00410         key = _keys.next();
00411     }
00412     return NULL;
00413 
00414 }
00415 
00416 QString Document::extractData(QString key)
00417 {
00418     QString data = searchKey(key)->getName();
00419     kdDebug(30522) << "Opening " << data << endl;
00420     if(!getStorage()->isOpen())
00421     {
00422         if(!getStorage()->open(data))
00423         {
00424             kdError(30522) << "Unable to open " << data << endl;
00425             return QString("");
00426         }
00427     }
00428 
00429     /* Temp file with the default name in the default temp dir */
00430     KTempFile temp;
00431     //temp.setAutoDelete(true);
00432     QFile* tempFile = temp.file();
00433 
00434     const Q_LONG buflen = 4096;
00435     char buffer[ buflen ];
00436     Q_LONG readBytes = getStorage()->read( buffer, buflen );
00437 
00438     while ( readBytes > 0 )
00439     {
00440         tempFile->writeBlock( buffer, readBytes );
00441         readBytes = getStorage()->read( buffer, buflen );
00442     }
00443     temp.close();
00444     if(!getStorage()->close())
00445     {
00446         kdError(30522) << "Unable to close " << data << endl;
00447         return QString("");
00448     }
00449     kdDebug(30522) << "temp filename : " << temp.name() << endl;
00450     return temp.name();
00451 }
KDE Home | KDE Accessibility Home | Description of Access Keys