21#include "conversion.h"
22#include "texthandler.h"
23#include "graphicshandler.h"
24#include "versionmagic.h"
28#include <KoPageLayout.h>
31#include <wv2/styles.h>
32#include <wv2/ustring.h>
33#include <wv2/word97_generated.h>
34#include <wv2/parser.h>
35#include <wv2/parserfactory.h>
36#include <wv2/paragraphproperties.h>
37#include <wv2/associatedstrings.h>
40#include <KoFilterChain.h>
43Document::Document(
const std::string& fileName, TQDomDocument& mainDocument, TQDomDocument& documentInfo, TQDomElement& framesetsElement, KoFilterChain* chain )
44 : m_mainDocument( mainDocument ), m_documentInfo ( documentInfo ),
45 m_framesetsElement( framesetsElement ),
46 m_replacementHandler( new KWordReplacementHandler ), m_tableHandler( new KWordTableHandler ),
47 m_pictureHandler( new KWordPictureHandler( this ) ), m_textHandler( 0 ),
49 m_parser( wvWare::ParserFactory::createParser( fileName ) ), m_headerFooters( 0 ), m_bodyFound( false ),
50 m_footNoteNumber( 0 ), m_endNoteNumber( 0 )
54 m_textHandler =
new KWordTextHandler( m_parser );
55 connect( m_textHandler, TQ_SIGNAL( subDocFound(
const wvWare::FunctorBase*,
int ) ),
56 this, TQ_SLOT( slotSubDocFound(
const wvWare::FunctorBase*,
int ) ) );
57 connect( m_textHandler, TQ_SIGNAL( tableFound(
const KWord::Table& ) ),
58 this, TQ_SLOT( slotTableFound(
const KWord::Table& ) ) );
59 connect( m_textHandler, TQ_SIGNAL( pictureFound(
const TQString&,
const TQString&,
const wvWare::FunctorBase* ) ),
60 this, TQ_SLOT( slotPictureFound(
const TQString&,
const TQString&,
const wvWare::FunctorBase* ) ) );
61 m_parser->setSubDocumentHandler(
this );
62 m_parser->setTextHandler( m_textHandler );
63 m_parser->setTableHandler( m_tableHandler );
65 m_parser->setPictureHandler( m_pictureHandler );
67 m_parser->setInlineReplacementHandler( m_replacementHandler );
69 processAssociatedStrings();
70 connect( m_tableHandler, TQ_SIGNAL( sigTableCellStart(
int,
int,
int,
int,
const KoRect&,
const TQString&,
const wvWare::Word97::BRC&,
const wvWare::Word97::BRC&,
const wvWare::Word97::BRC&,
const wvWare::Word97::BRC&,
const wvWare::Word97::SHD& ) ),
71 this, TQ_SLOT( slotTableCellStart(
int,
int,
int,
int,
const KoRect&,
const TQString&,
const wvWare::Word97::BRC&,
const wvWare::Word97::BRC&,
const wvWare::Word97::BRC&,
const wvWare::Word97::BRC&,
const wvWare::Word97::SHD& ) ) );
72 connect( m_tableHandler, TQ_SIGNAL( sigTableCellEnd() ),
73 this, TQ_SLOT( slotTableCellEnd() ) );
80 delete m_pictureHandler;
81 delete m_tableHandler;
82 delete m_replacementHandler;
85void Document::finishDocument()
87 const wvWare::Word97::DOP& dop = m_parser->dop();
89 TQDomElement elementDoc = m_mainDocument.documentElement();
92 element = m_mainDocument.createElement(
"ATTRIBUTES");
93 element.setAttribute(
"processing",0);
94 char allHeaders = ( wvWare::HeaderData::HeaderEven |
95 wvWare::HeaderData::HeaderOdd |
96 wvWare::HeaderData::HeaderFirst );
97 element.setAttribute(
"hasHeader", m_headerFooters & allHeaders ? 1 : 0 );
98 char allFooters = ( wvWare::HeaderData::FooterEven |
99 wvWare::HeaderData::FooterOdd |
100 wvWare::HeaderData::FooterFirst );
101 element.setAttribute(
"hasFooter", m_headerFooters & allFooters ? 1 : 0 );
104 element.setAttribute(
"tabStopValue", (
double)dop.dxaTab / 20.0 );
105 elementDoc.appendChild(element);
107 element = m_mainDocument.createElement(
"FOOTNOTESETTING");
108 elementDoc.appendChild(element);
109 element.setAttribute(
"start", dop.nFtn );
110 element.setAttribute(
"type", Conversion::numberFormatCode( dop.nfcFtnRef2 ) );
112 element = m_mainDocument.createElement(
"ENDNOTESETTING");
113 elementDoc.appendChild(element);
114 element.setAttribute(
"start", dop.nEdn );
115 element.setAttribute(
"type", Conversion::numberFormatCode( dop.nfcEdnRef2 ) );
119 TQDomElement paperElement = elementDoc.namedItem(
"PAPER").toElement();
120 Q_ASSERT ( !paperElement.isNull() );
121 if ( !paperElement.isNull() )
123 kdDebug(30513) << k_funcinfo <<
"m_headerFooters=" << m_headerFooters << endl;
124 paperElement.setAttribute(
"hType", Conversion::headerMaskToHType( m_headerFooters ) );
125 paperElement.setAttribute(
"fType", Conversion::headerMaskToFType( m_headerFooters ) );
129 TQDomElement picturesElem = m_mainDocument.createElement(
"PICTURES");
130 elementDoc.appendChild( picturesElem );
131 for( TQStringList::Iterator it = m_pictureList.begin(); it != m_pictureList.end(); ++it ) {
132 TQDomElement keyElem = m_mainDocument.createElement(
"KEY");
133 picturesElem.appendChild( keyElem );
134 keyElem.setAttribute(
"filename", *it );
135 keyElem.setAttribute(
"name", *it );
139void Document::processAssociatedStrings() {
140 wvWare::AssociatedStrings strings( m_parser->associatedStrings() );
142 TQDomElement infodoc = m_documentInfo.createElement(
"document-info" );
143 TQDomElement author = m_documentInfo.createElement(
"author" );
144 TQDomElement fullname = m_documentInfo.createElement(
"full-name" );
145 TQDomElement title = m_documentInfo.createElement(
"title" );
146 TQDomElement about = m_documentInfo.createElement(
"about" );
148 m_documentInfo.appendChild(infodoc);
150 if ( !strings.author().isNull()) {
151 fullname.appendChild(
152 m_documentInfo.createTextNode(
156 author.appendChild(fullname);
157 infodoc.appendChild(author);
160 if ( !strings.title().isNull()) {
162 m_documentInfo.createTextNode(
166 about.appendChild(title);
167 infodoc.appendChild(about);
172void Document::processStyles()
174 TQDomElement stylesElem = m_mainDocument.createElement(
"STYLES" );
175 m_mainDocument.documentElement().appendChild( stylesElem );
177 m_textHandler->setFrameSetElement( stylesElem );
178 const wvWare::StyleSheet& styles = m_parser->styleSheet();
179 unsigned int count = styles.size();
181 for (
unsigned int i = 0; i < count ; ++i )
183 const wvWare::Style* style = styles.styleByIndex( i );
186 if ( style && style->type() == wvWare::Style::sgcPara )
188 TQDomElement styleElem = m_mainDocument.createElement(
"STYLE");
189 stylesElem.appendChild( styleElem );
191 TQConstString name = Conversion::string( style->name() );
192 TQDomElement element = m_mainDocument.createElement(
"NAME");
193 element.setAttribute(
"value", name.string() );
194 styleElem.appendChild( element );
196 kdDebug(30513) << k_funcinfo <<
"Style " << i <<
": " << name.string() << endl;
198 const wvWare::Style* followingStyle = styles.styleByID( style->followingStyle() );
199 if ( followingStyle && followingStyle != style )
201 TQConstString followingName = Conversion::string( followingStyle->name() );
202 element = m_mainDocument.createElement(
"FOLLOWING");
203 element.setAttribute(
"name", followingName.string() );
204 styleElem.appendChild( element );
207 m_textHandler->paragLayoutBegin();
210 m_textHandler->writeFormat( styleElem, &style->chp(), 0L , 0, 0, 1, 0L );
212 m_textHandler->writeLayout( styleElem, style->paragraphProperties(), style );
218bool Document::parse()
221 return m_parser->parse();
225void Document::bodyStart()
227 kdDebug(30513) << k_funcinfo << endl;
229 TQDomElement mainFramesetElement = m_mainDocument.createElement(
"FRAMESET");
230 mainFramesetElement.setAttribute(
"frameType",1);
231 mainFramesetElement.setAttribute(
"frameInfo",0);
233 m_framesetsElement.appendChild(mainFramesetElement);
236 createInitialFrame( mainFramesetElement, 29, 798, 42, 566,
false, Reconnect );
238 m_textHandler->setFrameSetElement( mainFramesetElement );
239 connect( m_textHandler, TQ_SIGNAL( firstSectionFound( wvWare::SharedPtr<const wvWare::Word97::SEP> ) ),
240 this, TQ_SLOT( slotFirstSectionFound( wvWare::SharedPtr<const wvWare::Word97::SEP> ) ) );
244void Document::bodyEnd()
246 kdDebug(30513) << k_funcinfo << endl;
247 disconnect( m_textHandler, TQ_SIGNAL( firstSectionFound( wvWare::SharedPtr<const wvWare::Word97::SEP> ) ),
248 this, TQ_SLOT( slotFirstSectionFound( wvWare::SharedPtr<const wvWare::Word97::SEP> ) ) );
252void Document::slotFirstSectionFound( wvWare::SharedPtr<const wvWare::Word97::SEP> sep )
254 kdDebug(30513) << k_funcinfo << endl;
255 TQDomElement elementDoc = m_mainDocument.documentElement();
257 TQDomElement elementPaper = m_mainDocument.createElement(
"PAPER");
258 bool landscape = (sep->dmOrientPage == 2);
259 double width = (double)sep->xaPage / 20.0;
260 double height = (double)sep->yaPage / 20.0;
261 elementPaper.setAttribute(
"width", width);
262 elementPaper.setAttribute(
"height", height);
265 width = POINT_TO_MM( width );
266 height = POINT_TO_MM( height );
267 KoFormat paperFormat = KoPageFormat::guessFormat( landscape ? height : width, landscape ? width : height );
268 elementPaper.setAttribute(
"format",paperFormat);
270 elementPaper.setAttribute(
"orientation", landscape ? PG_LANDSCAPE : PG_PORTRAIT );
271 elementPaper.setAttribute(
"columns", sep->ccolM1 + 1 );
272 elementPaper.setAttribute(
"columnspacing", (
double)sep->dxaColumns / 20.0);
273 elementPaper.setAttribute(
"spHeadBody", (
double)sep->dyaHdrTop / 20.0);
274 elementPaper.setAttribute(
"spFootBody", (
double)sep->dyaHdrBottom / 20.0);
276 elementDoc.appendChild(elementPaper);
278 TQDomElement element = m_mainDocument.createElement(
"PAPERBORDERS");
279 element.setAttribute(
"left", (
double)sep->dxaLeft / 20.0);
280 element.setAttribute(
"top",(
double)sep->dyaTop / 20.0);
281 element.setAttribute(
"right", (
double)sep->dxaRight / 20.0);
282 element.setAttribute(
"bottom", (
double)sep->dyaBottom / 20.0);
283 elementPaper.appendChild(element);
289void Document::headerStart( wvWare::HeaderData::Type type )
291 kdDebug(30513) <<
"startHeader type=" << type <<
" (" << Conversion::headerTypeToFramesetName( type ) <<
")" << endl;
294 TQDomElement framesetElement = m_mainDocument.createElement(
"FRAMESET");
295 framesetElement.setAttribute(
"frameType", 1 );
296 framesetElement.setAttribute(
"frameInfo", Conversion::headerTypeToFrameInfo( type ) );
297 framesetElement.setAttribute(
"name", Conversion::headerTypeToFramesetName( type ) );
298 m_framesetsElement.appendChild(framesetElement);
300 bool isHeader = Conversion::isHeader( type );
302 createInitialFrame( framesetElement, 29, 798, isHeader?0:567, isHeader?41:567+41,
true, Copy );
304 m_textHandler->setFrameSetElement( framesetElement );
306 m_headerFooters |= type;
314void Document::headerEnd()
316 m_textHandler->setFrameSetElement( TQDomElement() );
319void Document::footnoteStart()
322 SubDocument subdoc( m_subdocQueue.front() );
323 int type = subdoc.data;
326 TQDomElement framesetElement = m_mainDocument.createElement(
"FRAMESET");
327 framesetElement.setAttribute(
"frameType", 1 );
328 framesetElement.setAttribute(
"frameInfo", 7 );
329 if ( type == wvWare::FootnoteData::Endnote )
331 framesetElement.setAttribute(
"name", i18n(
"Endnote %1").arg( ++m_endNoteNumber ) );
334 framesetElement.setAttribute(
"name", i18n(
"Footnote %1").arg( ++m_footNoteNumber ) );
335 m_framesetsElement.appendChild(framesetElement);
337 createInitialFrame( framesetElement, 29, 798, 567, 567+41,
true, NoFollowup );
339 m_textHandler->setFrameSetElement( framesetElement );
342void Document::footnoteEnd()
344 kdDebug(30513) << k_funcinfo << endl;
345 m_textHandler->setFrameSetElement( TQDomElement() );
348void Document::slotTableCellStart(
int row,
int column,
int rowSpan,
int columnSpan,
const KoRect& cellRect,
const TQString& tableName,
const wvWare::Word97::BRC& brcTop,
const wvWare::Word97::BRC& brcBottom,
const wvWare::Word97::BRC& brcLeft,
const wvWare::Word97::BRC& brcRight,
const wvWare::Word97::SHD& shd )
351 TQDomElement framesetElement = m_mainDocument.createElement(
"FRAMESET");
352 framesetElement.setAttribute(
"frameType", 1 );
353 framesetElement.setAttribute(
"frameInfo", 0 );
354 framesetElement.setAttribute(
"grpMgr", tableName );
355 TQString name = i18n(
"Table_Name Cell row,column",
"%1 Cell %2,%3").arg(tableName).arg(row).arg(column);
356 framesetElement.setAttribute(
"name", name );
357 framesetElement.setAttribute(
"row", row );
358 framesetElement.setAttribute(
"col", column );
359 framesetElement.setAttribute(
"rows", rowSpan );
360 framesetElement.setAttribute(
"cols", columnSpan );
361 m_framesetsElement.appendChild(framesetElement);
363 TQDomElement frameElem = createInitialFrame( framesetElement, cellRect.left(), cellRect.right(), cellRect.top(), cellRect.bottom(),
true, NoFollowup );
364 generateFrameBorder( frameElem, brcTop, brcBottom, brcLeft, brcRight, shd );
366 m_textHandler->setFrameSetElement( framesetElement );
369void Document::slotTableCellEnd()
371 m_textHandler->setFrameSetElement( TQDomElement() );
374TQDomElement Document::createInitialFrame( TQDomElement& parentFramesetElem,
double left,
double right,
double top,
double bottom,
bool autoExtend, NewFrameBehavior nfb )
376 TQDomElement frameElementOut = parentFramesetElem.ownerDocument().createElement(
"FRAME");
377 frameElementOut.setAttribute(
"left", left );
378 frameElementOut.setAttribute(
"right", right );
379 frameElementOut.setAttribute(
"top", top );
380 frameElementOut.setAttribute(
"bottom", bottom );
381 frameElementOut.setAttribute(
"runaround", 1 );
383 frameElementOut.setAttribute(
"autoCreateNewFrame", autoExtend ? 0 : 1 );
384 frameElementOut.setAttribute(
"newFrameBehavior", nfb );
385 parentFramesetElem.appendChild( frameElementOut );
386 return frameElementOut;
389void Document::generateFrameBorder( TQDomElement& frameElementOut,
const wvWare::Word97::BRC& brcTop,
const wvWare::Word97::BRC& brcBottom,
const wvWare::Word97::BRC& brcLeft,
const wvWare::Word97::BRC& brcRight,
const wvWare::Word97::SHD& shd )
393 if ( brcTop.cv != 255 && brcTop.dptLineWidth != 255 )
394 Conversion::setBorderAttributes( frameElementOut, brcTop,
"t" );
395 if ( brcBottom.cv != 255 && brcBottom.dptLineWidth != 255 )
396 Conversion::setBorderAttributes( frameElementOut, brcBottom,
"b" );
397 if ( brcLeft.cv != 255 && brcLeft.dptLineWidth != 255 )
398 Conversion::setBorderAttributes( frameElementOut, brcLeft,
"l" );
399 if ( brcRight.cv != 255 && brcRight.dptLineWidth != 255 )
400 Conversion::setBorderAttributes( frameElementOut, brcRight,
"r" );
403 if ( shd.cvFore != 0 || shd.cvBack != 0 )
409 int bkColor = shd.ipat ? shd.cvFore : shd.cvBack;
410 kdDebug(30513) <<
"generateFrameBorder: " <<
" icoFore=" << shd.cvFore <<
" icoBack=" << shd.cvBack <<
" ipat=" << shd.ipat <<
" -> bkColor=" << bkColor << endl;
414 bool grayHack = ( shd.ipat && shd.cvFore == 1 && shd.cvBack == 8 );
418 int grayLevel = Conversion::ditheringToGray( shd.ipat, &ok );
421 TQColor color( 0, 0, grayLevel, TQColor::Hsv );
422 TQString prefix =
"bk";
423 frameElementOut.setAttribute(
"bkRed", color.red() );
424 frameElementOut.setAttribute(
"bkBlue", color.blue() );
425 frameElementOut.setAttribute(
"bkGreen", color.green() );
427 else grayHack =
false;
431 Conversion::setColorAttributes( frameElementOut, bkColor,
"bk",
true );
433 int brushStyle = Conversion::fillPatternStyle( shd.ipat );
434 frameElementOut.setAttribute(
"bkStyle", brushStyle );
439void Document::slotSubDocFound(
const wvWare::FunctorBase* functor,
int data )
441 SubDocument subdoc( functor, data, TQString(), TQString() );
442 m_subdocQueue.push( subdoc );
445void Document::slotTableFound(
const KWord::Table& table )
447 m_tableQueue.push( table );
450void Document::slotPictureFound(
const TQString& frameName,
const TQString& pictureName,
451 const wvWare::FunctorBase* pictureFunctor )
453 SubDocument subdoc( pictureFunctor, 0, frameName, pictureName );
454 m_subdocQueue.push( subdoc );
457void Document::processSubDocQueue()
461 while ( !m_subdocQueue.empty() || !m_tableQueue.empty() )
463 while ( !m_subdocQueue.empty() )
465 SubDocument subdoc( m_subdocQueue.front() );
466 Q_ASSERT( subdoc.functorPtr );
467 (*subdoc.functorPtr)();
468 delete subdoc.functorPtr;
471 while ( !m_tableQueue.empty() )
473 KWord::Table& table = m_tableQueue.front();
474 m_tableHandler->tableStart( &table );
475 TQValueList<KWord::Row> &rows = table.rows;
476 for( TQValueList<KWord::Row>::Iterator it = rows.begin(); it != rows.end(); ++it ) {
477 KWord::TableRowFunctorPtr f = (*it).functorPtr;
482 m_tableHandler->tableEnd();
488KoStoreDevice* Document::createPictureFrameSet(
const KoSize& size )
491 SubDocument subdoc( m_subdocQueue.front() );
493 TQDomElement framesetElement = m_mainDocument.createElement(
"FRAMESET");
494 framesetElement.setAttribute(
"frameType", 2 );
495 framesetElement.setAttribute(
"frameInfo", 0 );
496 framesetElement.setAttribute(
"name", subdoc.name );
497 m_framesetsElement.appendChild(framesetElement);
504 createInitialFrame( framesetElement, 0, size.width(), 0, size.height(),
false, NoFollowup );
506 TQDomElement pictureElem = m_mainDocument.createElement(
"PICTURE");
507 framesetElement.appendChild( pictureElem );
509 TQDomElement keyElem = m_mainDocument.createElement(
"KEY");
510 pictureElem.appendChild( keyElem );
511 keyElem.setAttribute(
"filename", subdoc.extraName );
512 m_pictureList.append( subdoc.extraName );
514 kdDebug(30513) <<
"Preparing to write picture for '" << subdoc.name <<
"' into " << subdoc.extraName << endl;
515 return m_chain->storageFile( subdoc.extraName, KoStore::Write );
519#include "document.moc"
virtual ~Document()
Destructor.