00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "texthandler.h"
00021 #include "conversion.h"
00022
00023 #include <wv2/styles.h>
00024 #include <wv2/lists.h>
00025 #include <wv2/paragraphproperties.h>
00026 #include <wv2/functor.h>
00027 #include <wv2/functordata.h>
00028 #include <wv2/ustring.h>
00029 #include <wv2/parser.h>
00030 #include <wv2/fields.h>
00031
00032 #include <qfont.h>
00033 #include <qfontinfo.h>
00034 #include <kdebug.h>
00035 #include <klocale.h>
00036
00037
00038 wvWare::U8 KWordReplacementHandler::hardLineBreak()
00039 {
00040 return '\n';
00041 }
00042
00043 wvWare::U8 KWordReplacementHandler::nonBreakingHyphen()
00044 {
00045 return '-';
00046 }
00047
00048 wvWare::U8 KWordReplacementHandler::nonRequiredHyphen()
00049 {
00050 return 0xad;
00051 }
00052
00053
00054 KWordTextHandler::KWordTextHandler( wvWare::SharedPtr<wvWare::Parser> parser )
00055 : m_parser( parser ), m_sectionNumber( 0 ), m_footNoteNumber( 0 ), m_endNoteNumber( 0 ),
00056 m_previousOutlineLSID( 0 ), m_previousEnumLSID( 0 ),
00057 m_currentStyle( 0L ), m_index( 0 ),
00058 m_currentTable( 0L ),
00059 m_bInParagraph( false ),
00060 m_insideField( false ), m_fieldAfterSeparator( false ), m_fieldType( 0 )
00061 {
00062 }
00063
00064 void KWordTextHandler::sectionStart( wvWare::SharedPtr<const wvWare::Word97::SEP> sep )
00065 {
00066 m_sectionNumber++;
00067
00068 if ( m_sectionNumber == 1 )
00069 {
00070
00071
00072
00073 emit firstSectionFound( sep );
00074 }
00075 else
00076 {
00077
00078 if ( sep->bkc >= 1 )
00079 {
00080 pageBreak();
00081 }
00082 }
00083 }
00084
00085 void KWordTextHandler::sectionEnd()
00086 {
00087
00088 }
00089
00090 void KWordTextHandler::pageBreak()
00091 {
00092
00093 QDomElement pageBreak = m_oldLayout.namedItem( "PAGEBREAKING" ).toElement();
00094 if ( pageBreak.isNull() )
00095 {
00096 pageBreak = mainDocument().createElement( "PAGEBREAKING" );
00097 m_oldLayout.appendChild( pageBreak );
00098 }
00099 pageBreak.setAttribute( "hardFrameBreakAfter", "true" );
00100 }
00101
00102 void KWordTextHandler::headersFound( const wvWare::HeaderFunctor& parseHeaders )
00103 {
00104
00105 if ( m_sectionNumber == 1 )
00106 {
00107 emit subDocFound( new wvWare::HeaderFunctor( parseHeaders ), 0 );
00108 }
00109 }
00110
00111 void KWordTextHandler::footnoteFound( wvWare::FootnoteData::Type type,
00112 wvWare::UChar character, wvWare::SharedPtr<const wvWare::Word97::CHP> chp,
00113 const wvWare::FootnoteFunctor& parseFootnote )
00114 {
00115 bool autoNumbered = (character.unicode() == 2);
00116 QDomElement varElem = insertVariable( 11 , chp, "STRI" );
00117 QDomElement footnoteElem = varElem.ownerDocument().createElement( "FOOTNOTE" );
00118 if ( autoNumbered )
00119 footnoteElem.setAttribute( "value", 1 );
00120 else
00121 footnoteElem.setAttribute( "value", QString(QChar(character.unicode())) );
00122 footnoteElem.setAttribute( "notetype", type == wvWare::FootnoteData::Endnote ? "endnote" : "footnote" );
00123 footnoteElem.setAttribute( "numberingtype", autoNumbered ? "auto" : "manual" );
00124 if ( type == wvWare::FootnoteData::Endnote )
00125
00126 footnoteElem.setAttribute( "frameset", i18n("Endnote %1").arg( ++m_endNoteNumber ) );
00127 else
00128
00129 footnoteElem.setAttribute( "frameset", i18n("Footnote %1").arg( ++m_footNoteNumber ) );
00130 varElem.appendChild( footnoteElem );
00131
00132
00133 emit subDocFound( new wvWare::FootnoteFunctor( parseFootnote ), type );
00134 }
00135
00136 QDomElement KWordTextHandler::insertVariable( int type, wvWare::SharedPtr<const wvWare::Word97::CHP> chp, const QString& format )
00137 {
00138 m_paragraph += '#';
00139
00140 QDomElement formatElem;
00141 writeFormat( m_formats, chp, m_currentStyle ? &m_currentStyle->chp() : 0, m_index, 1, 4 , &formatElem );
00142
00143 m_index += 1;
00144
00145 QDomElement varElem = m_formats.ownerDocument().createElement( "VARIABLE" );
00146 QDomElement typeElem = m_formats.ownerDocument().createElement( "TYPE" );
00147 typeElem.setAttribute( "type", type );
00148 typeElem.setAttribute( "key", format );
00149 varElem.appendChild( typeElem );
00150 formatElem.appendChild( varElem );
00151 return varElem;
00152 }
00153
00154 void KWordTextHandler::tableRowFound( const wvWare::TableRowFunctor& functor, wvWare::SharedPtr<const wvWare::Word97::TAP> tap )
00155 {
00156 if ( !m_currentTable )
00157 {
00158
00159 Q_ASSERT( !m_bInParagraph );
00160 paragraphStart( 0L );
00161 static int s_tableNumber = 0;
00162 m_currentTable = new KWord::Table();
00163 m_currentTable->name = i18n("Table %1").arg( ++s_tableNumber );
00164 insertAnchor( m_currentTable->name );
00165 }
00166
00167
00168 for (int i = 0; i <= tap->itcMac; i++)
00169 m_currentTable->cacheCellEdge( tap->rgdxaCenter[ i ] );
00170
00171 KWord::Row row( new wvWare::TableRowFunctor( functor ), tap );
00172 m_currentTable->rows.append( row );
00173 }
00174
00175 #ifdef IMAGE_IMPORT
00176 void KWordTextHandler::pictureFound( const wvWare::PictureFunctor& pictureFunctor,
00177 wvWare::SharedPtr<const wvWare::Word97::PICF> picf,
00178 wvWare::SharedPtr<const wvWare::Word97::CHP> )
00179 {
00180 static unsigned int s_pictureNumber = 0;
00181 QString pictureName = "pictures/picture";
00182 pictureName += QString::number( s_pictureNumber );
00183
00184 QString frameName = i18n("Picture %1").arg( ++s_pictureNumber );
00185 insertAnchor( frameName );
00186
00187 switch ( picf->mfp.mm ) {
00188 case 98:
00189 pictureName += ".tif";
00190 break;
00191 case 99:
00192 pictureName += ".bmp";
00193 break;
00194 default:
00195 pictureName += ".wmf";
00196 break;
00197 }
00198
00199 emit pictureFound( frameName, pictureName, new wvWare::PictureFunctor( pictureFunctor ) );
00200 }
00201 #endif // IMAGE_IMPORT
00202
00203 QDomElement KWordTextHandler::insertAnchor( const QString& fsname )
00204 {
00205 m_paragraph += '#';
00206
00207
00208 QDomElement format( mainDocument().createElement( "FORMAT" ) );
00209 format.setAttribute( "id", 6 );
00210 format.setAttribute( "pos", m_index );
00211 format.setAttribute( "len", 1 );
00212 m_formats.appendChild( format );
00213 QDomElement formatElem = format;
00214
00215 m_index += 1;
00216
00217 QDomElement anchorElem = m_formats.ownerDocument().createElement( "ANCHOR" );
00218 anchorElem.setAttribute( "type", "frameset" );
00219 anchorElem.setAttribute( "instance", fsname );
00220 formatElem.appendChild( anchorElem );
00221 return anchorElem;
00222 }
00223
00224 void KWordTextHandler::paragLayoutBegin()
00225 {
00226 }
00227
00228 void KWordTextHandler::paragraphStart( wvWare::SharedPtr<const wvWare::ParagraphProperties> paragraphProperties )
00229 {
00230 if ( m_bInParagraph )
00231 paragraphEnd();
00232 m_bInParagraph = true;
00233
00234 m_formats = mainDocument().createElement( "FORMATS" );
00235 m_paragraphProperties = paragraphProperties;
00236 const wvWare::StyleSheet& styles = m_parser->styleSheet();
00237 m_currentStyle = 0;
00238 if ( paragraphProperties )
00239 {
00240 m_currentStyle = styles.styleByIndex( paragraphProperties->pap().istd );
00241 Q_ASSERT( m_currentStyle );
00242 }
00243 paragLayoutBegin();
00244 }
00245
00246 void KWordTextHandler::paragraphEnd()
00247 {
00248 Q_ASSERT( m_bInParagraph );
00249 if ( m_currentTable )
00250 {
00251 emit tableFound( *m_currentTable );
00252 delete m_currentTable;
00253 m_currentTable = 0L;
00254 }
00255 if ( m_currentStyle ) {
00256 QConstString styleName = Conversion::string( m_currentStyle->name() );
00257 writeOutParagraph( styleName.string(), m_paragraph );
00258 } else
00259 writeOutParagraph( "Standard", m_paragraph );
00260 m_bInParagraph = false;
00261 }
00262
00263 void KWordTextHandler::fieldStart( const wvWare::FLD* fld, wvWare::SharedPtr<const wvWare::Word97::CHP> )
00264 {
00265 m_fieldType = Conversion::fldToFieldType( fld );
00266 m_insideField = true;
00267 m_fieldAfterSeparator = false;
00268 m_fieldValue = "";
00269 }
00270
00271 void KWordTextHandler::fieldSeparator( const wvWare::FLD* , wvWare::SharedPtr<const wvWare::Word97::CHP> )
00272 {
00273 m_fieldAfterSeparator = true;
00274 }
00275
00276 void KWordTextHandler::fieldEnd( const wvWare::FLD* , wvWare::SharedPtr<const wvWare::Word97::CHP> chp )
00277 {
00278
00279 if( m_fieldType >= 0 )
00280 {
00281 QDomElement varElem = insertVariable( 8, chp, "STRING" );
00282 QDomElement fieldElem = varElem.ownerDocument().createElement( "FIELD" );
00283 fieldElem.setAttribute( "subtype", m_fieldType );
00284 fieldElem.setAttribute( "value", m_fieldValue );
00285 varElem.appendChild( fieldElem );
00286 }
00287
00288
00289 m_fieldValue = "";
00290 m_fieldType = -1;
00291 m_insideField = false;
00292 m_fieldAfterSeparator = false;
00293 }
00294
00295 void KWordTextHandler::runOfText( const wvWare::UString& text, wvWare::SharedPtr<const wvWare::Word97::CHP> chp )
00296 {
00297 QConstString newText( Conversion::string( text ) );
00298
00299
00300
00301 if( m_insideField && !m_fieldAfterSeparator ) return;
00302
00303
00304 if( m_insideField && m_fieldAfterSeparator && ( m_fieldType >= 0 ) )
00305 {
00306 m_fieldValue.append( newText.string() );
00307 return;
00308 }
00309
00310 m_paragraph += newText.string();
00311
00312 writeFormat( m_formats, chp, m_currentStyle ? &m_currentStyle->chp() : 0, m_index, text.length(), 1, 0L );
00313
00314 m_index += text.length();
00315
00316 }
00317
00318 void KWordTextHandler::writeFormat( QDomElement& parentElement, const wvWare::Word97::CHP* chp, const wvWare::Word97::CHP* refChp, int pos, int len, int formatId, QDomElement* pChildElement )
00319 {
00320 QDomElement format( mainDocument().createElement( "FORMAT" ) );
00321 format.setAttribute( "id", formatId );
00322 format.setAttribute( "pos", pos );
00323 format.setAttribute( "len", len );
00324
00325 if ( !refChp || refChp->ico != chp->ico )
00326 {
00327 QColor color = Conversion::color( chp->ico, -1 );
00328 QDomElement colorElem( mainDocument().createElement( "COLOR" ) );
00329 colorElem.setAttribute( "red", color.red() );
00330 colorElem.setAttribute( "blue", color.blue() );
00331 colorElem.setAttribute( "green", color.green() );
00332 format.appendChild( colorElem );
00333 }
00334
00335
00336
00337 if ( !refChp || refChp->ftcAscii != chp->ftcAscii )
00338 {
00339 QString fontName = getFont( chp->ftcAscii );
00340
00341 if ( !fontName.isEmpty() )
00342 {
00343 QDomElement fontElem( mainDocument().createElement( "FONT" ) );
00344 fontElem.setAttribute( "name", fontName );
00345 format.appendChild( fontElem );
00346 }
00347 }
00348
00349 if ( !refChp || refChp->hps != chp->hps )
00350 {
00351
00352 QDomElement fontSize( mainDocument().createElement( "SIZE" ) );
00353 fontSize.setAttribute( "value", (int)(chp->hps / 2) );
00354 format.appendChild( fontSize );
00355 }
00356
00357 if ( !refChp || refChp->fBold != chp->fBold ) {
00358 QDomElement weight( mainDocument().createElement( "WEIGHT" ) );
00359 weight.setAttribute( "value", chp->fBold ? 75 : 50 );
00360 format.appendChild( weight );
00361 }
00362 if ( !refChp || refChp->fItalic != chp->fItalic ) {
00363 QDomElement italic( mainDocument().createElement( "ITALIC" ) );
00364 italic.setAttribute( "value", chp->fItalic ? 1 : 0 );
00365 format.appendChild( italic );
00366 }
00367 if ( !refChp || refChp->kul != chp->kul ) {
00368 QDomElement underline( mainDocument().createElement( "UNDERLINE" ) );
00369 QString val = (chp->kul == 0) ? "0" : "1";
00370 switch ( chp->kul ) {
00371 case 3:
00372 underline.setAttribute( "styleline", "solid" );
00373 val = "double";
00374 break;
00375 case 6:
00376 underline.setAttribute( "styleline", "solid" );
00377 val = "single-bold";
00378 break;
00379 case 7:
00380 underline.setAttribute( "styleline", "dash" );
00381 break;
00382 case 4:
00383 case 8:
00384 underline.setAttribute( "styleline", "dot" );
00385 break;
00386 case 9:
00387 underline.setAttribute( "styleline", "dashdot" );
00388 break;
00389 case 10:
00390 underline.setAttribute( "styleline", "dashdotdot" );
00391 break;
00392 case 11:
00393 underline.setAttribute( "styleline", "wave" );
00394 break;
00395 case 5:
00396 val = "0";
00397 break;
00398 case 1:
00399 case 2:
00400 default:
00401 underline.setAttribute( "styleline", "solid" );
00402 };
00403 underline.setAttribute( "value", val );
00404 format.appendChild( underline );
00405 }
00406 if ( !refChp || refChp->fStrike != chp->fStrike || refChp->fDStrike != chp->fDStrike ) {
00407 QDomElement strikeout( mainDocument().createElement( "STRIKEOUT" ) );
00408 if ( chp->fDStrike )
00409 {
00410 strikeout.setAttribute( "value", "double" );
00411 strikeout.setAttribute( "styleline", "solid" );
00412 }
00413 else if ( chp->fStrike )
00414 {
00415 strikeout.setAttribute( "value", "single" );
00416 strikeout.setAttribute( "styleline", "solid" );
00417 }
00418 else
00419 strikeout.setAttribute( "value", "0" );
00420 format.appendChild( strikeout );
00421 }
00422
00423
00424 if ( !refChp || refChp->fCaps != chp->fCaps || refChp->fSmallCaps != chp->fSmallCaps )
00425 {
00426 QDomElement fontAttrib( mainDocument().createElement( "FONTATTRIBUTE" ) );
00427 fontAttrib.setAttribute( "value", chp->fSmallCaps ? "smallcaps" : chp->fCaps ? "uppercase" : "none" );
00428 format.appendChild( fontAttrib );
00429 }
00430 if ( !refChp || refChp->iss != chp->iss ) {
00431 QDomElement vertAlign( mainDocument().createElement( "VERTALIGN" ) );
00432
00433 int kwordVAlign = (chp->iss==1 ? 2 : chp->iss==2 ? 1 : 0);
00434 vertAlign.setAttribute( "value", kwordVAlign );
00435 format.appendChild( vertAlign );
00436 }
00437
00438
00439 if ( !refChp || refChp->fHighlight != chp->fHighlight || refChp->icoHighlight != chp->icoHighlight ) {
00440 QDomElement bgcolElem( mainDocument().createElement( "TEXTBACKGROUNDCOLOR" ) );
00441 if ( chp->fHighlight )
00442 {
00443 QColor color = Conversion::color( chp->icoHighlight, -1 );
00444 bgcolElem.setAttribute( "red", color.red() );
00445 bgcolElem.setAttribute( "blue", color.blue() );
00446 bgcolElem.setAttribute( "green", color.green() );
00447 } else {
00448 bgcolElem.setAttribute( "red", -1 );
00449 bgcolElem.setAttribute( "blue", -1 );
00450 bgcolElem.setAttribute( "green", -1 );
00451 }
00452 format.appendChild( bgcolElem );
00453 }
00454
00455
00456 if ( !refChp || refChp->fShadow != chp->fShadow || refChp->fImprint != chp->fImprint ) {
00457 QDomElement shadowElem( mainDocument().createElement( "SHADOW" ) );
00458 QString css = "none";
00459
00460
00461 if (chp->fShadow || chp->fImprint)
00462 {
00463 int fontSize = (int)(chp->hps / 2);
00464 int dist = fontSize > 20 ? 2 : 1;
00465 if (chp->fImprint)
00466 dist = -dist;
00467 css = QString::fromLatin1("#bebebe %1pt %1pt").arg(dist).arg(dist);
00468 }
00469 shadowElem.setAttribute( "text-shadow", css );
00470 format.appendChild( shadowElem );
00471 }
00472
00473 if ( pChildElement || !format.firstChild().isNull() )
00474 parentElement.appendChild( format );
00475 if ( pChildElement )
00476 *pChildElement = format;
00477 }
00478
00479
00480
00481
00482
00483 QString KWordTextHandler::getFont(unsigned fc) const
00484 {
00485 Q_ASSERT( m_parser );
00486 if ( !m_parser )
00487 return QString::null;
00488 const wvWare::Word97::FFN& ffn ( m_parser->font( fc ) );
00489
00490 QConstString fontName( Conversion::string( ffn.xszFfn ) );
00491 QString font = fontName.string();
00492
00493 #ifdef FONT_DEBUG
00494 kdDebug(30513) << " MS-FONT: " << font << endl;
00495 #endif
00496
00497 static const unsigned ENTRIES = 6;
00498 static const char* const fuzzyLookup[ENTRIES][2] =
00499 {
00500
00501
00502 { "times", "times" },
00503 { "courier", "courier" },
00504 { "andale", "monotype" },
00505 { "monotype.com", "monotype" },
00506 { "georgia", "times" },
00507 { "helvetica", "helvetica" }
00508 };
00509
00510
00511
00512
00513 unsigned i;
00514
00515 for (i = 0; i < ENTRIES; i++)
00516 {
00517
00518 if (font.find(fuzzyLookup[i][0], 0, FALSE) != -1)
00519 {
00520 font = fuzzyLookup[i][1];
00521 break;
00522 }
00523 }
00524
00525 #ifdef FONT_DEBUG
00526 kdDebug(30513) << " FUZZY-FONT: " << font << endl;
00527 #endif
00528
00529
00530 QFont xFont( font );
00531 QFontInfo info( xFont );
00532
00533 #ifdef FONT_DEBUG
00534 kdDebug(30513) << " QT-FONT: " << info.family() << endl;
00535 #endif
00536
00537 return info.family();
00538 }
00539
00540 void KWordTextHandler::writeOutParagraph( const QString& styleName, const QString& text )
00541 {
00542 if ( m_framesetElement.isNull() )
00543 {
00544 if ( !text.isEmpty() )
00545 kdWarning(30513) << "KWordTextHandler: no frameset element to write to! text=" << text << endl;
00546 return;
00547 }
00548 QDomElement paragraphElementOut=mainDocument().createElement("PARAGRAPH");
00549 m_framesetElement.appendChild(paragraphElementOut);
00550 QDomElement textElement=mainDocument().createElement("TEXT");
00551 textElement.setAttribute( "xml:space", "preserve" );
00552 paragraphElementOut.appendChild(textElement);
00553 paragraphElementOut.appendChild( m_formats );
00554 QDomElement layoutElement=mainDocument().createElement("LAYOUT");
00555 paragraphElementOut.appendChild(layoutElement);
00556
00557 QDomElement nameElement = mainDocument().createElement("NAME");
00558 nameElement.setAttribute("value", styleName);
00559 layoutElement.appendChild(nameElement);
00560
00561 if ( m_paragraphProperties )
00562 {
00563
00564 writeLayout( layoutElement, *m_paragraphProperties, m_currentStyle );
00565 }
00566
00567 textElement.appendChild(mainDocument().createTextNode(text));
00568
00569 m_paragraph = QString( "" );
00570 m_index = 0;
00571 m_oldLayout = layoutElement;
00572 }
00573
00574 void KWordTextHandler::writeLayout( QDomElement& parentElement, const wvWare::ParagraphProperties& paragraphProperties, const wvWare::Style* style )
00575 {
00576 const wvWare::Word97::PAP& pap = paragraphProperties.pap();
00577
00578 QDomElement flowElement = mainDocument().createElement("FLOW");
00579 QString alignment = Conversion::alignment( pap.jc );
00580 flowElement.setAttribute( "align", alignment );
00581 parentElement.appendChild( flowElement );
00582
00583
00584
00585 if ( pap.dxaLeft1 || pap.dxaLeft || pap.dxaRight )
00586 {
00587 QDomElement indentsElement = mainDocument().createElement("INDENTS");
00588
00589 indentsElement.setAttribute( "first", (double)pap.dxaLeft1 / 20.0 );
00590 indentsElement.setAttribute( "left", (double)pap.dxaLeft / 20.0 );
00591 indentsElement.setAttribute( "right", (double)pap.dxaRight / 20.0 );
00592 parentElement.appendChild( indentsElement );
00593 }
00594 if ( pap.dyaBefore || pap.dyaAfter )
00595 {
00596 QDomElement offsetsElement = mainDocument().createElement("OFFSETS");
00597 offsetsElement.setAttribute( "before", (double)pap.dyaBefore / 20.0 );
00598 offsetsElement.setAttribute( "after", (double)pap.dyaAfter / 20.0 );
00599 parentElement.appendChild( offsetsElement );
00600 }
00601
00602
00603 QString lineSpacing = Conversion::lineSpacing( pap.lspd );
00604 if ( lineSpacing != "0" )
00605 {
00606 QDomElement lineSpacingElem = mainDocument().createElement( "LINESPACING" );
00607 lineSpacingElem.setAttribute("value", lineSpacing );
00608 parentElement.appendChild( lineSpacingElem );
00609 }
00610
00611 if ( pap.fKeep || pap.fKeepFollow || pap.fPageBreakBefore )
00612 {
00613 QDomElement pageBreak = mainDocument().createElement( "PAGEBREAKING" );
00614 if ( pap.fKeep )
00615 pageBreak.setAttribute("linesTogether", "true");
00616 if ( pap.fPageBreakBefore )
00617 pageBreak.setAttribute("hardFrameBreak", "true" );
00618 if ( pap.fKeepFollow )
00619 pageBreak.setAttribute("keepWithNext", "true" );
00620 parentElement.appendChild( pageBreak );
00621 }
00622
00623
00624 if ( pap.brcTop.brcType )
00625 {
00626 QDomElement borderElement = mainDocument().createElement( "TOPBORDER" );
00627 Conversion::setBorderAttributes( borderElement, pap.brcTop );
00628 parentElement.appendChild( borderElement );
00629 }
00630 if ( pap.brcBottom.brcType )
00631 {
00632 QDomElement borderElement = mainDocument().createElement( "BOTTOMBORDER" );
00633 Conversion::setBorderAttributes( borderElement, pap.brcBottom );
00634 parentElement.appendChild( borderElement );
00635 }
00636 if ( pap.brcLeft.brcType )
00637 {
00638 QDomElement borderElement = mainDocument().createElement( "LEFTBORDER" );
00639 Conversion::setBorderAttributes( borderElement, pap.brcLeft );
00640 parentElement.appendChild( borderElement );
00641 }
00642 if ( pap.brcRight.brcType )
00643 {
00644 QDomElement borderElement = mainDocument().createElement( "RIGHTBORDER" );
00645 Conversion::setBorderAttributes( borderElement, pap.brcRight );
00646 parentElement.appendChild( borderElement );
00647 }
00648
00649
00650 if ( pap.itbdMac )
00651 {
00652 for ( int i = 0 ; i < pap.itbdMac ; ++i )
00653 {
00654 const wvWare::Word97::TabDescriptor &td = pap.rgdxaTab[i];
00655 QDomElement tabElement = mainDocument().createElement( "TABULATOR" );
00656 tabElement.setAttribute( "ptpos", (double)td.dxaTab / 20.0 );
00657
00658
00659
00660 tabElement.setAttribute( "type", td.tbd.jc % 4 );
00661 int filling = 0;
00662 double width = 0.5;
00663 switch ( td.tbd.tlc ) {
00664 case 1:
00665 case 2:
00666 filling = 1;
00667 break;
00668 case 3:
00669 filling = 2;
00670 break;
00671 case 4:
00672 filling = 2;
00673 width = 2;
00674 }
00675 tabElement.setAttribute( "filling", filling );
00676 tabElement.setAttribute( "width", width );
00677 parentElement.appendChild( tabElement );
00678 }
00679 }
00680
00681 if ( pap.ilfo > 0 )
00682 {
00683 writeCounter( parentElement, paragraphProperties, style );
00684 }
00685 }
00686
00687 void KWordTextHandler::writeCounter( QDomElement& parentElement, const wvWare::ParagraphProperties& paragraphProperties, const wvWare::Style* style )
00688 {
00689 const wvWare::ListInfo* listInfo = paragraphProperties.listInfo();
00690 if ( !listInfo )
00691 return;
00692
00693 #ifndef NDEBUG
00694 listInfo->dump();
00695 #endif
00696
00697 QDomElement counterElement = mainDocument().createElement( "COUNTER" );
00698
00699
00700 int numberingType = listInfo->isWord6() && listInfo->prev() ? 1 : 0;
00701 wvWare::UString text = listInfo->text().text;
00702 int nfc = listInfo->numberFormat();
00703 if ( nfc == 23 )
00704 {
00705 if ( text.length() == 1 )
00706 {
00707 unsigned int code = text[0].unicode();
00708 if ( (code & 0xFF00) == 0xF000 )
00709 code &= 0x00FF;
00710
00711
00712 if ( code == 0xB7 )
00713 {
00714 counterElement.setAttribute( "type", 10 );
00715 } else if ( code == 0xD8 )
00716 {
00717 counterElement.setAttribute( "type", 11 );
00718 } else {
00719
00720 kdDebug(30513) << "custom bullet, code=" << QString::number(code,16) << endl;
00721 counterElement.setAttribute( "type", 6 );
00722 counterElement.setAttribute( "bullet", code );
00723 QString paragFont = getFont( style->chp().ftcAscii );
00724 counterElement.setAttribute( "bulletfont", paragFont );
00725 }
00726 } else
00727 kdWarning(30513) << "Bullet with more than one character, not supported" << endl;
00728 }
00729 else
00730 {
00731 const wvWare::Word97::PAP& pap = paragraphProperties.pap();
00732 counterElement.setAttribute( "start", listInfo->startAt() );
00733
00734 int depth = pap.ilvl;
00735
00736
00737 bool isHeading = style->sti() >= 1 && style->sti() <= 9;
00738 if ( depth == 0 && isHeading )
00739 {
00740 depth = style->sti() - 1;
00741 }
00742 kdDebug(30513) << " ilfo=" << pap.ilfo << " ilvl=" << pap.ilvl << " sti=" << style->sti() << " depth=" << depth << " numberingType=" << numberingType << endl;
00743 counterElement.setAttribute( "depth", depth );
00744
00745
00746
00747 QString prefix, suffix;
00748 bool depthFound = false;
00749 int displayLevels = 1;
00750
00751
00752
00753 for ( int i = 0 ; i < text.length() ; ++i )
00754 {
00755 short ch = text[i].unicode();
00756
00757 if ( ch < 10 ) {
00758 if ( ch == pap.ilvl ) {
00759 if ( depthFound )
00760 kdWarning(30513) << "ilvl " << pap.ilvl << " found twice in listInfo text..." << endl;
00761 else
00762 depthFound = true;
00763 suffix = QString::null;
00764 } else {
00765 Q_ASSERT( ch < pap.ilvl );
00766 if ( ch < pap.ilvl )
00767 ++displayLevels;
00768 prefix = QString::null;
00769 }
00770 } else {
00771 if ( depthFound )
00772 suffix += QChar(ch);
00773 else
00774 prefix += QChar(ch);
00775 }
00776 }
00777 if ( displayLevels > 1 )
00778 {
00779
00780
00781
00782
00783 if ( depth > 0 && !prefix.isEmpty() && m_listSuffixes[ depth - 1 ] == prefix ) {
00784 prefix = QString::null;
00785 kdDebug(30513) << "depth=" << depth << " parent suffix is " << prefix << " -> clearing" << endl;
00786 }
00787 }
00788 if ( isHeading )
00789 numberingType = 1;
00790 if ( depthFound )
00791 {
00792
00793 if ( nfc == 5 && suffix.isEmpty() )
00794 suffix = ".";
00795 kdDebug(30513) << " prefix=" << prefix << " suffix=" << suffix << endl;
00796 counterElement.setAttribute( "type", Conversion::numberFormatCode( nfc ) );
00797 counterElement.setAttribute( "lefttext", prefix );
00798 counterElement.setAttribute( "righttext", suffix );
00799 counterElement.setAttribute( "display-levels", displayLevels );
00800 kdDebug(30513) << "storing suffix " << suffix << " for depth " << depth << endl;
00801 m_listSuffixes[ depth ] = suffix;
00802 }
00803 else
00804 {
00805 kdWarning(30513) << "Not supported: counter text without the depth in it:" << Conversion::string(text).string() << endl;
00806 }
00807
00808 if ( listInfo->startAtOverridden() ||
00809 ( numberingType == 1 && m_previousOutlineLSID != 0 && m_previousOutlineLSID != listInfo->lsid() ) ||
00810 ( numberingType == 0 &&m_previousEnumLSID != 0 && m_previousEnumLSID != listInfo->lsid() ) )
00811 counterElement.setAttribute( "restart", "true" );
00812
00813
00814
00815
00816
00817 }
00818 if ( numberingType == 1 )
00819 m_previousOutlineLSID = listInfo->lsid();
00820 else
00821 m_previousEnumLSID = listInfo->lsid();
00822 counterElement.setAttribute( "numberingtype", numberingType );
00823 parentElement.appendChild( counterElement );
00824 }
00825
00826 void KWordTextHandler::setFrameSetElement( const QDomElement& frameset )
00827 {
00828 m_framesetElement = frameset;
00829 for ( uint i = 0 ; i < 9 ; ++i )
00830 m_listSuffixes[i] = QString::null;
00831 }
00832
00833 QDomDocument KWordTextHandler::mainDocument() const
00834 {
00835 return m_framesetElement.ownerDocument();
00836 }
00837
00838 #include "texthandler.moc"