kword/latex/export/document.cpp
1/*
2** A program to convert the XML rendered by KWord into LATEX.
3**
4** Copyright (C) 2000, 2001, 2002 Robert JACOLIN
5**
6** This library is free software; you can redistribute it and/or
7** modify it under the terms of the GNU Library General Public
8** License as published by the Free Software Foundation; either
9** version 2 of the License, or (at your option) any later version.
10**
11** This library is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14** Library General Public License for more details.
15**
16** To receive a copy of the GNU Library General Public License, write to the
17** Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19**
20*/
21
22#include <stdlib.h> /* for atoi function */
23
24#include <kdebug.h>
25#include <tdetempfile.h>
26#include <KoStore.h>
27
28#include <tqdir.h>
29
30#include "fileheader.h"
31#include "document.h"
32#include "textFrame.h"
33#include "formula.h"
34#include "pixmapFrame.h"
35
36/*******************************************/
37/* Constructor */
38/*******************************************/
42
43/*******************************************/
44/* Destructor */
45/*******************************************/
46Document::~Document()
47{
48 kdDebug(30522) << "Document destructor" << endl;
49}
50
51/*******************************************/
52/* Analyse */
53/*******************************************/
54void Document::analyse(const TQDomNode balise)
55{
56 //TQDomNode balise = getChild(balise_initial, "FRAMESET");
57 kdDebug(30522) << getChildName(balise, 0) << endl;
58 for(int index= 0; index < getNbChild(balise); index++)
59 {
60 Element *elt = 0;
61 kdDebug(30522) << "--------------------------------------------------" << endl;
62
63 kdDebug(30522) << getChildName(balise, index) << endl;
64 switch(getTypeFrameset(getChild(balise, index)))
65 {
66 case ST_NONE:
67 kdDebug(30522) << "NONE" << endl;
68 break;
69 case ST_TEXT:
70 kdDebug(30522) << "TEXT" << endl;
71 elt = new TextFrame;
72 elt->analyse(getChild(balise, index));
73 break;
74 case ST_PICTURE:
75 kdDebug(30522) << "PICTURE" << endl;
76 elt = new PixmapFrame();
77 elt->analyse(getChild(balise, index));
78 break;
79 case ST_PART:
80 kdDebug(30522) << "PART" << endl;
81 //elt = new Part;
82 //elt->analyse(getChild(balise, index));
83 break;
84 case ST_FORMULA:
85 /* Just save the frameset in a TQString input
86 * call the formula latex export filter
87 * save in output
88 * generate : write the output
89 */
90 kdDebug(30522) << "FORMULA" << endl;
91 elt = new Formula;
92 elt->analyse(getChild(balise, index));
93 break;
94 case ST_HLINE:
95 kdDebug(30522) << "HLINE" << endl;
96 break;
97 default:
98 kdDebug(30522) << "error " << elt->getType() << " " << ST_TEXT << endl;
99 }
100
101 /* 3. Add the Element in one of the lists */
102 if(elt != 0)
103 {
104 kdDebug(30522) << "INFO : " << elt->getSection() << endl;
105 switch(elt->getSection())
106 {
107 case SS_FOOTERS: kdDebug(30522) << " FOOTER" <<endl;
108 _footers.append(elt);
109 break;
110 case SS_HEADERS: kdDebug(30522) << " HEADER" << endl;
111 _headers.append(elt);
112 break;
113 case SS_BODY:
114 if(!elt->isTable())
115 {
116 switch(elt->getType())
117 {
118 case ST_TEXT:
119 _corps.append(elt);
120 kdDebug(30522) << " BODY" << endl;
121 break;
122 case ST_PART:
123 kdDebug(30522) << " PART" <<endl;
124 //_parts.append(elt);
125 break;
126 case ST_FORMULA:
127 kdDebug(30522) << " FORMULA" <<endl;
128 _formulas.append(elt);
129 break;
130 case ST_PICTURE:
131 kdDebug(30522) << " PIXMAP" <<endl;
132 _pixmaps.append(elt);
133 break;
134 default:
135 kdError(30522) << "Element frame type no supported or type unexpected." << endl;
136 }
137 }
138 break;
139 case SS_TABLE:
140 kdDebug(30522) << " TABLE" <<endl;
141 /* Don't add simplely the cell */
142 /* heriter ListTable de ListElement et surcharger
143 * la methode add. Une cellule est un element.
144 */
145 _tables.add(elt);
146 FileHeader::instance()->useTable();
147 break;
148 case SS_FOOTNOTES: /* Just for the new kwd file version */
149 _footnotes.append(elt);
150 break;
151 default: kdDebug(30522) << "UNKNOWN" << endl;
152 break;
153 }
154 }
155 kdDebug(30522) << "END OF ANALYSE OF A FRAMESET" << endl;
156 }
157}
158
159/*******************************************/
160/* AnalysePixmaps */
161/*******************************************/
162void Document::analysePixmaps(const TQDomNode balise)
163{
164 //TQDomNode balise = getChild(balise_initial, "FRAMESET");
165 for(int index= 0; index < getNbChild(balise); index++)
166 {
167 Key *key = 0;
168 kdDebug(30522) << "NEW PIXMAP" << endl;
169
170 key = new Key(Key::PIXMAP);
171 key->analyse(getChild(balise, "KEY"));
172 _keys.append(key);
173 }
174}
175
176/*******************************************/
177/* getTypeFrameset */
178/*******************************************/
179SType Document::getTypeFrameset(const TQDomNode balise)
180{
181 SType type = ST_NONE;
182 type = (SType) getAttr(balise, "frameType").toInt();
183 return type;
184}
185
186/*******************************************/
187/* Generate */
188/*******************************************/
189void Document::generate(TQTextStream &out, bool hasPreambule)
190{
191 kdDebug(30522) << "DOC. GENERATION." << endl;
192
193 if(hasPreambule)
194 generatePreambule(out);
195 kdDebug(30522) << "preambule : " << hasPreambule << endl;
196
197 /* Body */
198 kdDebug(30522) << endl << "body : " << _corps.count() << endl;
199
200 if(hasPreambule)
201 {
202 out << "\\begin{document}" << endl;
203 Config::instance()->indent();
204 }
205 TQString dir = "";
206 if( !Config::instance()->getPicturesDir().isEmpty() &&
207 Config::instance()->getPicturesDir() != NULL &&
208 FileHeader::instance()->hasGraphics())
209 {
210 out << endl << "\\graphicspath{{" << Config::instance()->getPicturesDir() << "}}" << endl;
211 }
212
213 if(_corps.getFirst() != 0)
214 _corps.getFirst()->generate(out);
215
216 /* Just for test */
217 /*if(_tables.getFirst() != 0)
218 _tables.getFirst()->generate(out);
219 if(_formulas.getFirst() != 0)
220 _formulas.getFirst()->generate(out);*/
221 if(hasPreambule)
222 out << "\\end{document}" << endl;
223 Config::instance()->desindent();
224 if(Config::instance()->getIndentation() != 0)
225 kdError(30522) << "Error : indent != 0 at the end ! " << endl;
226}
227
228/*******************************************/
229/* GeneratePreambule */
230/*******************************************/
231void Document::generatePreambule(TQTextStream &out)
232{
233 Element* header;
234 Element* footer;
235
236 /* For each header */
237 if(FileHeader::instance()->hasHeader())
238 {
239 kdDebug(30522) << "header : " << _headers.count() << endl;
240
241 /* default : no rule */
242 out << "\\renewcommand{\\headrulewidth}{0pt}" << endl;
243 for(header = _headers.first(); header != 0; header = _headers.next())
244 {
245 generateTypeHeader(out, header);
246 }
247 }
248
249 /* For each footer */
250 if(FileHeader::instance()->hasFooter())
251 {
252 kdDebug(30522) << "footer : " << _footers.count() << endl;
253
254 /* default : no rule */
255 out << "\\renewcommand{\\footrulewidth}{0pt}" << endl;
256 for(footer = _footers.first(); footer != 0; footer = _footers.next())
257 {
258 generateTypeFooter(out, footer);
259 }
260 }
261 /* Specify what header/footer style to use */
262 if(FileHeader::instance()->hasHeader() || FileHeader::instance()->hasFooter())
263 out << "\\pagestyle{fancy}" << endl;
264 else
265 {
266 out << "\\pagestyle{empty}" << endl;
267 }
268}
269
270/*******************************************/
271/* GenerateTypeHeader */
272/*******************************************/
273void Document::generateTypeHeader(TQTextStream &out, Element *header)
274{
275 kdDebug(30522) << "generate header" << endl;
276 if((FileHeader::instance()->getHeadType() == FileHeader::TH_ALL ||
277 FileHeader::instance()->getHeadType() == FileHeader::TH_FIRST) && header->getInfo() == SI_EVEN)
278 {
279 out << "\\fancyhead[L]{}" << endl;
280 out << "\\fancyhead[C]{";
281 header->generate(out);
282 out << "}" << endl;
283 out << "\\fancyhead[R]{}" << endl;
284 }
285
286 switch(header->getInfo())
287 {
288 case SI_NONE:
289 case SI_FIRST:
290 break;
291 case SI_ODD:
292 out << "\\fancyhead[RO]{}" << endl;
293 out << "\\fancyhead[CO]{";
294 header->generate(out);
295 out << "}" << endl;
296 out << "\\fancyhead[LO]{}" << endl;
297 break;
298 case SI_EVEN:
299 out << "\\fancyhead[RE]{}" << endl;
300 out << "\\fancyhead[CE]{";
301 header->generate(out);
302 out << "}" << endl;
303 out << "\\fancyhead[LE]{}" << endl;
304 break;
305 }
306
307 if(header->getInfo() == SI_FIRST)
308 {
309 out << "\\fancyhead{";
310 header->generate(out);
311 out << "}" << endl;
312 out << "\\thispagestyle{fancy}" << endl;
313 }
314}
315
316/*******************************************/
317/* GenerateTypeFooter */
318/*******************************************/
319void Document::generateTypeFooter(TQTextStream &out, Element *footer)
320{
321 if(FileHeader::instance()->getFootType() == FileHeader::TH_ALL &&
322 footer->getInfo() == SI_EVEN)
323 {
324 out << "\\fancyfoot[L]{}" << endl;
325 out << "\\fancyfoot[C]{";
326 footer->generate(out);
327 out << "}" << endl;
328 out << "\\fancyfoot[R]{}" << endl;
329 }
330 else if(FileHeader::instance()->getFootType() == FileHeader::TH_EVODD)
331 {
332 switch(footer->getInfo())
333 {
334 case SI_NONE:
335 case SI_FIRST:
336 break;
337 case SI_ODD:
338 out << "\\fancyfoot[CO]{";
339 footer->generate(out);
340 out << "}";
341 break;
342 case SI_EVEN:
343 out << "\\fancyfoot[CE]{";
344 footer->generate(out);
345 out << "}";
346 break;
347 }
348 }
349 else if(FileHeader::instance()->getFootType() == FileHeader::TH_FIRST &&
350 footer->getInfo() == SI_FIRST)
351 {
352 out << "\\fanycfoot{";
353 footer->generate(out);
354 out << "}" << endl;
355 out << "\\thispagestyle{fancy}" << endl;
356 }
357}
358
359Element* Document::searchAnchor(TQString anchor)
360{
361 Element *elt = _tables.first();
362 while(elt != 0)
363 {
364 kdDebug(30522) << elt->getGrpMgr() << endl;
365 if(elt->getGrpMgr() == anchor)
366 return elt;
367 elt = _tables.next();
368 }
369 kdDebug(30522) << "No in table, search in formulae list." << endl;
370 elt = _formulas.first();
371 while(elt != 0)
372 {
373 if(elt->getName() == anchor)
374 return elt;
375 elt = _formulas.next();
376 }
377 kdDebug(30522) << "No in table and formulae, search in pictures." << endl;
378 elt = _pixmaps.first();
379 while(elt != 0)
380 {
381 if(elt->getName() == anchor)
382 return elt;
383 elt = _pixmaps.next();
384 }
385 return NULL;
386
387}
388
389Element* Document::searchFootnote(TQString footnote)
390{
391 Element* elt = _footnotes.first();
392 while(elt != 0)
393 {
394 if(elt->getName() == footnote)
395 return elt;
396 elt = _footnotes.next();
397 }
398 return NULL;
399
400}
401
402Key* Document::searchKey(TQString keyName)
403{
404 Key* key = _keys.first();
405 while(key != 0)
406 {
407 kdDebug(30522) << "key " << key->getFilename() << endl;
408 if(key->getFilename() == keyName)
409 return key;
410 key = _keys.next();
411 }
412 return NULL;
413
414}
415
416TQString Document::extractData(TQString key)
417{
418 TQString data = searchKey(key)->getName();
419 kdDebug(30522) << "Opening " << data << endl;
420 if(!getStorage()->isOpen())
421 {
422 if(!getStorage()->open(data))
423 {
424 kdError(30522) << "Unable to open " << data << endl;
425 return TQString("");
426 }
427 }
428
429 /* Temp file with the default name in the default temp dir */
430 KTempFile temp;
431 //temp.setAutoDelete(true);
432 TQFile* tempFile = temp.file();
433
434 const TQ_LONG buflen = 4096;
435 char buffer[ buflen ];
436 TQ_LONG readBytes = getStorage()->read( buffer, buflen );
437
438 while ( readBytes > 0 )
439 {
440 tempFile->writeBlock( buffer, readBytes );
441 readBytes = getStorage()->read( buffer, buflen );
442 }
443 temp.close();
444 if(!getStorage()->close())
445 {
446 kdError(30522) << "Unable to close " << data << endl;
447 return TQString("");
448 }
449 kdDebug(30522) << "temp filename : " << temp.name() << endl;
450 return temp.name();
451}
SType getTypeFrameset(const TQDomNode)
Accessors.
TQString extractData(TQString key)
Save the file in a temp file.
This class is a element.
SSect getSection() const
Accessors.
virtual void analyse(const TQDomNode)
Helpfull functions.
This class hold a formula.
This class hold a real paragraph.
Definition key.h:39
TQString getName() const
Accessors.
Definition key.h:80
void analyse(const TQDomNode)
Helpfull functions.
Definition key.cpp:45
void add(Element *)
Modifiers.
Definition listtable.cpp:60
This class hold a pixmap (frame).
Definition pixmapFrame.h:40
This class hold 2 lists of paragraphs for the text and for the footnotes.
Definition textFrame.h:40