00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <qmap.h>
00034 #include <qiodevice.h>
00035 #include <qbuffer.h>
00036 #include <qtextstream.h>
00037 #include <qdom.h>
00038
00039 #include <kdebug.h>
00040 #include <klocale.h>
00041 #include <kzip.h>
00042
00043 #include <KoPageLayout.h>
00044 #include <KoPictureKey.h>
00045 #include <KoPicture.h>
00046
00047 #include <KWEFStructures.h>
00048 #include <KWEFUtil.h>
00049 #include <KWEFBaseWorker.h>
00050 #include <KWEFKWordLeader.h>
00051
00052 #include "ExportFilter.h"
00053
00054 OOWriterWorker::OOWriterWorker(void) : m_streamOut(NULL),
00055 m_paperBorderTop(0.0),m_paperBorderLeft(0.0),
00056 m_paperBorderBottom(0.0),m_paperBorderRight(0.0), m_zip(NULL), m_pictureNumber(0),
00057 m_automaticParagraphStyleNumber(0), m_automaticTextStyleNumber(0),
00058 m_footnoteNumber(0), m_tableNumber(0), m_textBoxNumber( 0 ),
00059 m_columnspacing( 36.0 ), m_columns( 1 )
00060 {
00061 }
00062
00063 QString OOWriterWorker::escapeOOText(const QString& strText) const
00064 {
00065
00066
00067 return KWEFUtil::EscapeSgmlText(NULL,strText,true,true);
00068 }
00069
00070 QString OOWriterWorker::escapeOOSpan(const QString& strText) const
00071
00072 {
00073 QString strReturn;
00074 QChar ch;
00075 int spaceNumber = 0;
00076
00077 for (uint i=0; i<strText.length(); i++)
00078 {
00079 ch=strText[i];
00080
00081 if (ch!=' ')
00082 {
00083
00084 if ( spaceNumber > 0 )
00085 {
00086 strReturn += ' ';
00087 --spaceNumber;
00088 if ( spaceNumber > 0 )
00089 {
00090 strReturn += "<text:s text:c=\"";
00091 strReturn += QString::number( spaceNumber );
00092 strReturn += "\"/>";
00093 }
00094 spaceNumber = 0;
00095 }
00096 }
00097
00098
00099 switch (ch.unicode())
00100 {
00101 case 9:
00102 {
00103 strReturn+="<text:tab-stop/>";
00104 break;
00105 }
00106 case 10:
00107 {
00108 strReturn+="<text:line-break/>";
00109 break;
00110 }
00111 case 32:
00112 {
00113 if ( spaceNumber > 0 )
00114 {
00115 ++spaceNumber;
00116 }
00117 else
00118 {
00119 spaceNumber = 1;
00120 }
00121 break;
00122 }
00123 case 38:
00124 {
00125 strReturn+="&";
00126 break;
00127 }
00128 case 60:
00129 {
00130 strReturn+="<";
00131 break;
00132 }
00133 case 62:
00134 {
00135 strReturn+=">";
00136 break;
00137 }
00138 case 34:
00139 {
00140 strReturn+=""";
00141 break;
00142 }
00143 case 39:
00144 {
00145 strReturn+="'";
00146 break;
00147 }
00148 case 1:
00149 {
00150 strReturn += '#';
00151 break;
00152 }
00153
00154 case 0:
00155 case 2:
00156 case 3:
00157 case 4:
00158 case 5:
00159 case 6:
00160 case 7:
00161 case 8:
00162 case 11:
00163 case 12:
00164 case 14:
00165 case 15:
00166 case 16:
00167 case 17:
00168 case 18:
00169 case 19:
00170 case 20:
00171 case 21:
00172 case 22:
00173 case 23:
00174 case 24:
00175 case 25:
00176 case 26:
00177 case 27:
00178 case 28:
00179 case 29:
00180 case 30:
00181 case 31:
00182 {
00183 kdWarning(30518) << "Not allowed XML character: " << ch.unicode() << endl;
00184 strReturn += '?';
00185 break;
00186 }
00187 case 13:
00188 default:
00189 {
00190 strReturn+=ch;
00191 break;
00192 }
00193 }
00194 }
00195
00196 if ( spaceNumber > 0 )
00197 {
00198
00199 strReturn += ' ';
00200 --spaceNumber;
00201 if ( spaceNumber > 0 )
00202 {
00203 strReturn += "<text:s text:c=\"";
00204 strReturn += QString::number( spaceNumber );
00205 strReturn += "\"/>";
00206 }
00207 spaceNumber = 0;
00208 }
00209
00210 return strReturn;
00211 }
00212
00213 bool OOWriterWorker::doOpenFile(const QString& filenameOut, const QString& )
00214 {
00215 kdDebug(30518) << "Opening file: " << filenameOut
00216 << " (in OOWriterWorker::doOpenFile)" << endl;
00217
00218 m_zip=new KZip(filenameOut);
00219
00220 if (!m_zip->open(IO_WriteOnly))
00221 {
00222 kdError(30518) << "Could not open ZIP file for writing! Aborting!" << endl;
00223 delete m_zip;
00224 m_zip=NULL;
00225 return false;
00226 }
00227
00228 m_zip->setCompression( KZip::NoCompression );
00229 m_zip->setExtraField( KZip::NoExtraField );
00230
00231 const QCString appId( "application/vnd.sun.xml.writer" );
00232
00233 m_zip->writeFile( "mimetype", QString::null, QString::null, appId.length(), appId.data() );
00234
00235 m_zip->setCompression( KZip::DeflateCompression );
00236
00237 m_streamOut=new QTextStream(m_contentBody, IO_WriteOnly);
00238
00239 m_streamOut->setEncoding( QTextStream::UnicodeUTF8 );
00240
00241 return true;
00242 }
00243
00244 bool OOWriterWorker::zipPrepareWriting(const QString& name)
00245 {
00246 if (!m_zip)
00247 return false;
00248 m_size=0;
00249 return m_zip->prepareWriting(name, QString::null, QString::null, 0);
00250 }
00251
00252 bool OOWriterWorker::zipDoneWriting(void)
00253 {
00254 if (!m_zip)
00255 return false;
00256 return m_zip->doneWriting(m_size);
00257 }
00258
00259 bool OOWriterWorker::zipWriteData(const char* str)
00260 {
00261 if (!m_zip)
00262 return false;
00263 const uint size=strlen(str);
00264 m_size+=size;
00265 return m_zip->writeData(str,size);
00266 }
00267
00268 bool OOWriterWorker::zipWriteData(const QByteArray& array)
00269 {
00270 if (!m_zip)
00271 return false;
00272 const uint size=array.size();
00273 m_size+=size;
00274 return m_zip->writeData(array.data(),size);
00275 }
00276
00277 bool OOWriterWorker::zipWriteData(const QCString& cstr)
00278 {
00279 if (!m_zip)
00280 return false;
00281 const uint size=cstr.length();
00282 m_size+=size;
00283 return m_zip->writeData(cstr.data(),size);
00284 }
00285
00286 bool OOWriterWorker::zipWriteData(const QString& str)
00287 {
00288 return zipWriteData(str.utf8());
00289 }
00290
00291 void OOWriterWorker::writeStartOfFile(const QString& type)
00292 {
00293 const bool noType=type.isEmpty();
00294 zipWriteData("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
00295
00296 zipWriteData("<!DOCTYPE office:document");
00297 if (!noType)
00298 {
00299
00300 zipWriteData("-");
00301 zipWriteData(type);
00302 }
00303 zipWriteData(" PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\"");
00304 zipWriteData(" \"office.dtd\"");
00305 zipWriteData(">\n");
00306
00307 zipWriteData("<office:document");
00308 if (!noType)
00309 {
00310 zipWriteData("-");
00311 zipWriteData(type);
00312 }
00313
00314
00315
00316
00317 zipWriteData(" xmlns:office=\"http://openoffice.org/2000/office\"");
00318 zipWriteData(" xmlns:xlink=\"http://www.w3.org/1999/xlink\"");
00319
00320
00321 if ( type == "content" || type == "styles" || type.isEmpty() )
00322 {
00323 zipWriteData(" xmlns:style=\"http://openoffice.org/2000/style\"");
00324 zipWriteData(" xmlns:text=\"http://openoffice.org/2000/text\"");
00325 zipWriteData(" xmlns:table=\"http://openoffice.org/2000/table\"");
00326 zipWriteData(" xmlns:draw=\"http://openoffice.org/2000/drawing\"");
00327 zipWriteData(" xmlns:fo=\"http://www.w3.org/1999/XSL/Format\"");
00328
00329
00330 zipWriteData(" xmlns:svg=\"http://www.w3.org/2000/svg\"");
00331
00332
00333
00334
00335
00336 }
00337
00338
00339 if ( type == "meta" || type.isEmpty() )
00340 {
00341 zipWriteData(" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"");
00342 zipWriteData(" xmlns:meta=\"http://openoffice.org/2000/meta\"");
00343 }
00344
00345 zipWriteData(" office:class=\"text\"");
00346
00347
00348 #ifdef STRICT_OOWRITER_VERSION_1
00349 zipWriteData(" office:version=\"1.0\"");
00350 #else
00351
00352
00353 #endif
00354
00355 zipWriteData(">\n");
00356 }
00357
00358 void OOWriterWorker::writeFontDeclaration(void)
00359 {
00360 zipWriteData( " <office:font-decls>\n");
00361 QMap<QString,QString>::ConstIterator end(m_fontNames.end());
00362 for (QMap<QString,QString>::ConstIterator it=m_fontNames.begin(); it!=end; ++it)
00363 {
00364 const bool space=(it.key().find(' ')>=0);
00365 const QString fontName(escapeOOText(it.key()));
00366 zipWriteData(" <style:font-decl style:name=\"");
00367 zipWriteData(fontName);
00368 zipWriteData("\" fo:font-family=\"");
00369 if (space)
00370 {
00371 zipWriteData("'");
00372 zipWriteData(fontName);
00373 zipWriteData("'");
00374 }
00375 else
00376 {
00377 zipWriteData(fontName);
00378 }
00379 zipWriteData("\" ");
00380 zipWriteData(it.data());
00381 zipWriteData(" />\n");
00382 }
00383 zipWriteData(" </office:font-decls>\n");
00384 }
00385
00386 void OOWriterWorker::writeStylesXml(void)
00387 {
00388 if (!m_zip)
00389 return;
00390
00391 zipPrepareWriting("styles.xml");
00392
00393 writeStartOfFile("styles");
00394
00395 writeFontDeclaration();
00396
00397 zipWriteData(m_styles);
00398
00399 zipWriteData(" <office:automatic-styles>\n");
00400 zipWriteData(" <style:page-master style:name=\"pm1\">\n");
00401
00402 zipWriteData(" <style:properties ");
00403 zipWriteData( " style:page-usage=\"all\"" );
00404
00405 zipWriteData(" fo:page-width=\"");
00406 zipWriteData(QString::number(m_paperWidth));
00407 zipWriteData("pt\" fo:page-height=\"");
00408 zipWriteData(QString::number(m_paperHeight));
00409 zipWriteData("pt\" ");
00410
00411 zipWriteData("style:print-orientation=\"");
00412 if (1==m_paperOrientation)
00413 {
00414 zipWriteData("landscape");
00415 }
00416 else
00417 {
00418 zipWriteData("portrait");
00419 }
00420
00421 zipWriteData("\" fo:margin-top=\"");
00422 zipWriteData(QString::number(m_paperBorderTop));
00423 zipWriteData("pt\" fo:margin-bottom=\"");
00424 zipWriteData(QString::number(m_paperBorderBottom));
00425 zipWriteData("pt\" fo:margin-left=\"");
00426 zipWriteData(QString::number(m_paperBorderLeft));
00427 zipWriteData("pt\" fo:margin-right=\"");
00428 zipWriteData(QString::number(m_paperBorderRight));
00429 zipWriteData("pt\" style:first-page-number=\"");
00430 zipWriteData(QString::number(m_varSet.startingPageNumber));
00431 zipWriteData( "\">\n" );
00432
00433 if ( m_columns > 1 )
00434 {
00435 zipWriteData( " <style:columns" );
00436 zipWriteData( " fo:column-count=\"" );
00437 zipWriteData( QString::number( m_columns ) );
00438 zipWriteData( "\" fo:column-gap=\"" );
00439 zipWriteData( QString::number( m_columnspacing ) );
00440 zipWriteData( "pt\">\n" );
00441
00442 for (int i=0; i < m_columns; ++i)
00443 {
00444 zipWriteData( " <style:column style:rel-width=\"1*\" fo:margin-left=\"0cm\" fo:margin-right=\"0cm\"/>\n" );
00445 }
00446
00447 zipWriteData( " </style:columns>\n" );
00448 }
00449
00450 zipWriteData(" </style:properties>\n");
00451
00452 zipWriteData(" </style:page-master>\n");
00453 zipWriteData(" </office:automatic-styles>\n");
00454
00455 zipWriteData(" <office:master-styles>\n");
00456 zipWriteData(" <style:master-page style:name=\"Standard\" style:page-master-name=\"pm1\" />\n");
00457 zipWriteData(" </office:master-styles>\n");
00458
00459 zipWriteData( "</office:document-styles>\n" );
00460
00461 zipDoneWriting();
00462 }
00463
00464 void OOWriterWorker::writeContentXml(void)
00465 {
00466 if (!m_zip)
00467 return;
00468
00469 zipPrepareWriting("content.xml");
00470
00471 writeStartOfFile("content");
00472
00473 writeFontDeclaration();
00474
00475 zipWriteData(" <office:automatic-styles>\n");
00476 zipWriteData(m_contentAutomaticStyles);
00477 m_contentAutomaticStyles = QString::null;
00478
00479 zipWriteData(" </office:automatic-styles>\n");
00480
00481 zipWriteData(m_contentBody);
00482 m_contentBody.resize( 0 );
00483
00484 zipWriteData( "</office:document-content>\n" );
00485
00486 zipDoneWriting();
00487 }
00488
00489 void OOWriterWorker::writeMetaXml(void)
00490 {
00491 if (!m_zip)
00492 return;
00493
00494 zipPrepareWriting("meta.xml");
00495
00496 writeStartOfFile("meta");
00497
00498 zipWriteData(" <office:meta>\n");
00499
00500
00501 zipWriteData(" <meta:generator>KWord's OOWriter Export Filter");
00502 zipWriteData(QString("$Revision: 515673 $").mid(10).remove('$'));
00503
00504 zipWriteData("</meta:generator>\n");
00505
00506 if (!m_docInfo.title.isEmpty())
00507 {
00508 zipWriteData(" <dc:title>");
00509 zipWriteData(escapeOOText(m_docInfo.title));
00510 zipWriteData("</dc:title>\n");
00511 }
00512 if (!m_docInfo.abstract.isEmpty())
00513 {
00514 zipWriteData(" <dc:description>");
00515 zipWriteData(escapeOOText(m_docInfo.abstract));
00516 zipWriteData("</dc:description>\n");
00517 }
00518
00519 if (m_varSet.creationTime.isValid())
00520 {
00521 zipWriteData(" <meta:creation-date>");
00522 zipWriteData(escapeOOText(m_varSet.creationTime.toString(Qt::ISODate)));
00523 zipWriteData("</meta:creation-date>\n");
00524 }
00525
00526 if (m_varSet.modificationTime.isValid())
00527 {
00528 zipWriteData(" <dc:date>");
00529 zipWriteData(escapeOOText(m_varSet.modificationTime.toString(Qt::ISODate)));
00530 zipWriteData("</dc:date>\n");
00531 }
00532
00533 if (m_varSet.printTime.isValid())
00534 {
00535 zipWriteData(" <meta:print-date>");
00536 zipWriteData(escapeOOText(m_varSet.printTime.toString(Qt::ISODate)));
00537 zipWriteData("</meta:print-date>\n");
00538 }
00539
00540 zipWriteData( " <meta:document-statistic" );
00541
00542
00543 if ( m_numPages > 0 )
00544 {
00545 zipWriteData( " meta:page-count=\"" );
00546 zipWriteData( QString::number ( m_numPages ) );
00547 zipWriteData( "\"" );
00548 }
00549
00550 zipWriteData( " meta:image-count=\"" );
00551 zipWriteData( QString::number ( m_pictureNumber ) );
00552 zipWriteData( "\"" );
00553
00554 zipWriteData( " meta:table-count=\"" );
00555 zipWriteData( QString::number ( m_tableNumber ) );
00556 zipWriteData( "\"" );
00557
00558 zipWriteData( "/>\n" );
00559
00560 zipWriteData(" </office:meta>\n");
00561 zipWriteData("</office:document-meta>\n");
00562
00563 zipDoneWriting();
00564 }
00565
00566 bool OOWriterWorker::doCloseFile(void)
00567 {
00568 kdDebug(30518)<< "OOWriterWorker::doCloseFile" << endl;
00569 if (m_zip)
00570 {
00571 writeContentXml();
00572 writeMetaXml();
00573 writeStylesXml();
00574 m_zip->close();
00575 }
00576
00577 delete m_zip;
00578 m_zip=NULL;
00579 return true;
00580 }
00581
00582 bool OOWriterWorker::doOpenDocument(void)
00583 {
00584 kdDebug(30518)<< "OOWriterWorker::doOpenDocument" << endl;
00585
00586 *m_streamOut << " <office:body>\n";
00587
00588 return true;
00589 }
00590
00591 bool OOWriterWorker::doCloseDocument(void)
00592 {
00593 *m_streamOut << " </office:body>\n";
00594 return true;
00595 }
00596
00597 bool OOWriterWorker::doOpenBody(void)
00598 {
00599 QValueList<FrameAnchor>::Iterator it;
00600
00601
00602 kdDebug(30518) << "=== Processing non-inlined pictures ===" << endl;
00603 for ( it = m_nonInlinedPictureAnchors.begin(); it != m_nonInlinedPictureAnchors.end(); ++it )
00604 {
00605 *m_streamOut << " ";
00606 makePicture( *it, AnchorNonInlined );
00607 *m_streamOut << "\n";
00608 }
00609 kdDebug(30518) << "=== Non-inlined pictures processed ===" << endl;
00610
00611
00612 kdDebug(30518) << "=== Processing non-inlined tables ===" << endl;
00613 for ( it = m_nonInlinedTableAnchors.begin(); it != m_nonInlinedTableAnchors.end(); ++it )
00614 {
00615 *m_streamOut << " ";
00616 makeTable( *it, AnchorNonInlined );
00617 *m_streamOut << "\n";
00618 }
00619 kdDebug(30518) << "=== Non-inlined tables processed ===" << endl;
00620
00621 return true;
00622 }
00623
00624 QString OOWriterWorker::textFormatToStyle(const TextFormatting& formatOrigin,
00625 const TextFormatting& formatData, const bool force, QString& key)
00626 {
00627
00628 QString strElement;
00629
00630
00631 QString fontName = formatData.fontName;
00632 declareFont(fontName);
00633 if ( !fontName.isEmpty()
00634 && (force || (formatOrigin.fontName!=formatData.fontName)))
00635 {
00636 strElement+="style:font-name=\"";
00637 strElement+= escapeOOText(fontName);
00638 strElement+="\" ";
00639 key += fontName;
00640 }
00641
00642 key += ",";
00643
00644 if (force || (formatOrigin.italic!=formatData.italic))
00645 {
00646
00647 strElement+="fo:font-style=\"";
00648 if ( formatData.italic )
00649 {
00650 strElement+="italic";
00651 key+='I';
00652 }
00653 else
00654 {
00655 strElement+="normal";
00656 key+='N';
00657 }
00658 strElement+="\" ";
00659 }
00660
00661 key += ",";
00662
00663 if (force || ((formatOrigin.weight>=75)!=(formatData.weight>=75)))
00664 {
00665 strElement+="fo:font-weight=\"";
00666 if ( formatData.weight >= 75 )
00667 {
00668 strElement+="bold";
00669 key+='B';
00670 }
00671 else
00672 {
00673 strElement+="normal";
00674 key+='N';
00675 }
00676 strElement+="\" ";
00677 }
00678
00679 key += ",";
00680
00681 if (force || (formatOrigin.fontSize!=formatData.fontSize))
00682 {
00683 const int size=formatData.fontSize;
00684 if (size>0)
00685 {
00686 strElement+="fo:font-size=\"";
00687 strElement+=QString::number(size,10);
00688 strElement+="pt\" ";
00689 key+=QString::number(size,10);
00690 }
00691 }
00692
00693 key += ",";
00694
00695 if (force || (formatOrigin.fgColor!=formatData.fgColor))
00696 {
00697 if ( formatData.fgColor.isValid() )
00698 {
00699 strElement+="fo:color=\"";
00700 strElement+=formatData.fgColor.name();
00701 strElement+="\" ";
00702 key+=formatData.fgColor.name();
00703 }
00704 }
00705
00706 key += ",";
00707
00708 if (force || (formatOrigin.bgColor!=formatData.bgColor))
00709 {
00710 if ( formatData.bgColor.isValid() )
00711 {
00712 strElement+="style:text-background-color=\"";
00713 strElement+=formatData.bgColor.name();
00714 strElement+="\" ";
00715 key+=formatData.bgColor.name();
00716 }
00717 }
00718
00719 key += ';';
00720
00721 if ( force || ( formatOrigin.underline != formatData.underline )
00722 || ( formatOrigin.underlineColor != formatData.underlineColor )
00723 || ( formatOrigin.underlineValue != formatData.underlineValue )
00724 || ( formatOrigin.underlineStyle != formatData.underlineStyle ) )
00725 {
00726 strElement+="style:text-underline=\"";
00727 if ( formatData.underline )
00728 {
00729 QString underlineValue ( formatData.underlineValue );
00730 QString underlineStyle ( formatData.underlineStyle );
00731
00732 if ( underlineStyle.isEmpty() )
00733 underlineStyle = "solid";
00734 if ( underlineValue == "1" )
00735 underlineValue = "single";
00736
00737 if ( underlineValue == "single" )
00738 {
00739 if ( underlineStyle == "dash" )
00740 {
00741 strElement += "dash";
00742 key += "DA";
00743 }
00744 else if ( underlineStyle == "dot" )
00745 {
00746 strElement += "dotted";
00747 key += "DO";
00748 }
00749 else if ( underlineStyle == "dashdot" )
00750 {
00751 strElement += "dot-dash";
00752 key += "DDA";
00753 }
00754 else if ( underlineStyle == "dashdotdot" )
00755 {
00756 strElement += "dot-dot-dash";
00757 key += "DDDA";
00758 }
00759 else
00760 {
00761 strElement += "single";
00762 key += "1";
00763 }
00764 }
00765 else if ( underlineValue == "double" )
00766 {
00767 strElement += "double";
00768 key += "2";
00769 }
00770 else if ( underlineValue == "single-bold" )
00771 {
00772 strElement += "bold";
00773 key += "BL";
00774 }
00775 else if ( underlineValue == "wave" )
00776 {
00777 strElement += "wave";
00778 key += "WV";
00779 }
00780 else
00781 {
00782 strElement += "single";
00783 key += "?";
00784 }
00785 }
00786 else
00787 {
00788 strElement+="none";
00789 key += 'N';
00790 }
00791 strElement += "\" ";
00792
00793 if ( formatData.underline && formatData.underlineColor.isValid() )
00794 {
00795 const QString colorName( formatData.underlineColor.name() );
00796 strElement += "style:text-underline-color=\"";
00797 strElement += colorName;
00798 strElement += "\" ";
00799 key += colorName;
00800 }
00801
00802 }
00803
00804 key += ',';
00805
00806 if ( force
00807 || (formatOrigin.strikeout != formatData.strikeout )
00808 || (formatOrigin.strikeoutType != formatData.strikeoutType ) )
00809 {
00810
00811
00812
00813 strElement+="style:text-crossing-out=\"";
00814 if ( ( formatData.strikeoutType == "single" ) || ( formatData.strikeoutType == "1" ) )
00815 {
00816 strElement+="single-line";
00817 key += "1";
00818 }
00819 else if ( formatData.strikeoutType == "double" )
00820 {
00821 strElement+="double-line";
00822 key += "2";
00823 }
00824 else if ( formatData.strikeoutType == "single-bold" )
00825 {
00826 strElement+="thick";
00827 key += "T";
00828 }
00829 else
00830 {
00831 strElement+="none";
00832 key += 'N';
00833 }
00834 strElement+="\" ";
00835 }
00836
00837 key += ',';
00838
00839
00840
00841 if (force || ( formatOrigin.underlineWord != formatData.underlineWord )
00842 || (formatOrigin.strikeoutWord != formatData.strikeoutWord ) )
00843 {
00844
00845
00846 strElement+="fo:score-spaces=\"";
00847 if ( formatData.underlineWord || formatData.strikeoutWord )
00848 {
00849 strElement += "false";
00850 key += 'W';
00851 }
00852 else
00853 {
00854 strElement += "true";
00855 key += 'N';
00856 }
00857 strElement += "\" ";
00858 }
00859
00860 key += ',';
00861
00862 if ( force || ( formatOrigin.language != formatData.language ) )
00863 {
00864 const QString lang ( formatData.language );
00865 if ( ! lang.isEmpty() )
00866 {
00867 const int res = lang.find( '_' );
00868
00869 if ( res >= 0 )
00870 {
00871 kdDebug(30518) << "Language: " << lang << " => " << lang.left( res ) << " - " << lang.mid( res + 1 ) << endl;
00872 strElement += "fo:language=\"";
00873 strElement += lang.left( res );
00874 strElement += "\" ";
00875 strElement += "fo:country=\"";
00876 strElement += lang.mid( res + 1 );
00877 strElement += "\" ";
00878 }
00879 else
00880 {
00881 kdDebug(30518) << "Language without country: " << lang << endl;
00882 strElement += "fo:language=\"";
00883 strElement += lang;
00884 strElement += "\" ";
00885 }
00886
00887 key+=formatData.language;
00888 }
00889 }
00890
00891 key += ",";
00892
00893 if ( force || ( formatOrigin.fontAttribute != formatData.fontAttribute ) )
00894 {
00895
00896
00897 if ( formatData.fontAttribute == "uppercase" )
00898 {
00899 strElement += "fo:text-transform=\"uppercase\" ";
00900 key += 'U';
00901 }
00902 else if ( formatData.fontAttribute == "lowercase" )
00903 {
00904 strElement += "fo:text-transform=\"lowercase\" ";
00905 key += 'L';
00906 }
00907 else if ( formatData.fontAttribute == "smallcaps" )
00908 {
00909 strElement += "fo:font-variant=\"small-caps\" ";
00910 key += 'S';
00911 }
00912 else
00913 {
00914 strElement += "fo:text-transform=\"none\" ";
00915 strElement += "fo:font-variant=\"normal\" ";
00916 key += 'N';
00917 }
00918 }
00919
00920 key += ",";
00921
00922 if ( force || ( formatOrigin.verticalAlignment != formatData.verticalAlignment ) )
00923 {
00924 if ( 1 == formatData.verticalAlignment )
00925 {
00926
00927 strElement += "style:text-position=\"sub\" ";
00928 key += 'B';
00929 }
00930 else if ( 2 == formatData.verticalAlignment )
00931 {
00932
00933 strElement += "style:text-position=\"super\" ";
00934 key += 'P';
00935 }
00936
00937 }
00938
00939 return strElement.stripWhiteSpace();
00940 }
00941
00942 #define ALLOW_TABLE
00943
00944 QString OOWriterWorker::cellToProperties( const TableCell& cell, QString& key) const
00945 {
00946 #ifdef ALLOW_TABLE
00947 const FrameData& frame = cell.frame;
00948 QString properties;
00949
00950 key += "!L";
00951 key += frame.lColor.name();
00952 key += ",";
00953 key += QString::number( frame.lWidth );
00954 properties += " fo:border-left=\"";
00955 if ( frame.lColor.isValid() && frame.lWidth > 0.0 )
00956 {
00957 properties += QString::number( frame.lWidth );
00958 properties += "pt";
00959 properties += " solid ";
00960 properties += frame.lColor.name();
00961 }
00962 else
00963 {
00964 properties += "0pt none #000000";
00965 }
00966 properties += "\"";
00967
00968 key += "!R";
00969 key += frame.rColor.name();
00970 key += ",";
00971 key += QString::number( frame.rWidth );
00972 properties += " fo:border-right=\"";
00973 if ( frame.rColor.isValid() && frame.rWidth > 0.0 )
00974 {
00975 properties += QString::number( frame.rWidth );
00976 properties += "pt";
00977 properties += " solid ";
00978 properties += frame.rColor.name();
00979 }
00980 else
00981 {
00982 properties += "0pt none #000000";
00983 }
00984 properties += "\"";
00985
00986 key += "!T";
00987 key += frame.tColor.name();
00988 key += ",";
00989 key += QString::number( frame.tWidth );
00990 properties += " fo:border-top=\"";
00991 if ( frame.tColor.isValid() && frame.tWidth > 0.0 )
00992 {
00993 properties += QString::number( frame.tWidth );
00994 properties += "pt";
00995 properties += " solid ";
00996 properties += frame.tColor.name();
00997 }
00998 else
00999 {
01000 properties += "0pt none #000000";
01001 }
01002 properties += "\"";
01003
01004 key += "!B";
01005 key += frame.bColor.name();
01006 key += ",";
01007 key += QString::number( frame.bWidth );
01008 properties += " fo:border-bottom=\"";
01009 if ( frame.bColor.isValid() && frame.bWidth > 0.0 )
01010 {
01011 properties += QString::number( frame.bWidth );
01012 properties += "pt";
01013 properties += " solid ";
01014 properties += frame.bColor.name();
01015 }
01016 else
01017 {
01018 properties += "0pt none #000000";
01019 }
01020 properties += "\"";
01021
01022 return properties;
01023 #else
01024 return QString::null;
01025 #endif
01026 }
01027
01028 bool OOWriterWorker::makeTableRows( const QString& tableName, const Table& table, int firstRowNumber )
01029 {
01030 #ifdef ALLOW_TABLE
01031
01032
01033
01034
01035
01036 *m_streamOut << "<table:table-row>\n";
01037 int rowCurrent = firstRowNumber;
01038
01039 ulong cellNumber = 0L;
01040
01041 QMap<QString,QString> mapCellStyleKeys;
01042
01043 for ( QValueList<TableCell>::ConstIterator itCell ( table.cellList.begin() );
01044 itCell != table.cellList.end(); ++itCell)
01045 {
01046 if ( rowCurrent != (*itCell).row )
01047 {
01048 rowCurrent = (*itCell).row;
01049 *m_streamOut << "</table:table-row>\n";
01050 *m_streamOut << "<table:table-row>\n";
01051 }
01052
01053 QString key;
01054 const QString props ( cellToProperties( (*itCell), key ) );
01055
01056 QString automaticCellStyle;
01057 QMap<QString,QString>::ConstIterator it ( mapCellStyleKeys.find( key ) );
01058 if ( it == mapCellStyleKeys.end() )
01059 {
01060 automaticCellStyle = makeAutomaticStyleName( tableName + ".Cell", cellNumber );
01061 mapCellStyleKeys [ key ] = automaticCellStyle;
01062 kdDebug(30518) << "Creating automatic cell style: " << automaticCellStyle << " key: " << key << endl;
01063 m_contentAutomaticStyles += " <style:style";
01064 m_contentAutomaticStyles += " style:name=\"" + escapeOOText( automaticCellStyle ) + "\"";
01065 m_contentAutomaticStyles += " style:family=\"table-cell\"";
01066 m_contentAutomaticStyles += ">\n";
01067 m_contentAutomaticStyles += " <style:properties ";
01068 m_contentAutomaticStyles += props;
01069 m_contentAutomaticStyles += "/>\n";
01070 m_contentAutomaticStyles += " </style:style>\n";
01071 }
01072 else
01073 {
01074 automaticCellStyle = it.data();
01075 kdDebug(30518) << "Using automatic cell style: " << automaticCellStyle << " key: " << key << endl;
01076 }
01077
01078 *m_streamOut << "<table:table-cell table:value-type=\"string\" table:style-name=\""
01079 << escapeOOText( automaticCellStyle)
01080 << "\"";
01081
01082
01083 {
01084 *m_streamOut << " table:number-columns-spanned=\"" << (*itCell).m_cols << "\"";
01085 }
01086
01087 *m_streamOut << ">\n";
01088
01089 if (!doFullAllParagraphs(*(*itCell).paraList))
01090 {
01091 return false;
01092 }
01093
01094 *m_streamOut << "</table:table-cell>\n";
01095
01096 if ( (*itCell).m_cols > 1 )
01097 {
01098
01099 for (int i = 1; i < (*itCell).m_cols; ++i)
01100 {
01101 *m_streamOut << "<table:covered-table-cell/>";
01102 }
01103 }
01104 }
01105
01106 *m_streamOut << "</table:table-row>\n";
01107 return true;
01108 #else
01109 return false;
01110 #endif
01111 }
01112
01113 #ifdef ALLOW_TABLE
01114 static uint getColumnWidths( const Table& table, QMemArray<double>& widthArray, int firstRowNumber )
01115 {
01116 bool uniqueColumns = true;
01117 uint currentColumn = 0;
01118 int tryingRow = firstRowNumber;
01119 QValueList<TableCell>::ConstIterator itCell;
01120
01121 for ( itCell = table.cellList.begin();
01122 itCell != table.cellList.end(); ++itCell )
01123 {
01124 kdDebug(30518) << "Column: " << (*itCell).col << " (Row: " << (*itCell).row << ")" << endl;
01125
01126 if ( (*itCell).row != tryingRow )
01127 {
01128 if ( uniqueColumns )
01129 {
01130
01131 return currentColumn;
01132 }
01133 else
01134 {
01135
01136 tryingRow = (*itCell).row;
01137 uniqueColumns = true;
01138 currentColumn = 0;
01139 }
01140 }
01141
01142 if ( (*itCell).m_cols > 1 )
01143 {
01144
01145 uniqueColumns = false;
01146
01147 continue;
01148 }
01149
01150 const double width = ( (*itCell).frame.right - (*itCell).frame.left );
01151
01152 if ( currentColumn >= widthArray.size() )
01153 widthArray.resize( currentColumn + 4, QGArray::SpeedOptim);
01154
01155 widthArray.at( currentColumn ) = width;
01156 ++currentColumn;
01157 }
01158
01159
01160
01161
01162
01163 return uniqueColumns ? currentColumn : 0;
01164 }
01165 #endif
01166
01167 #ifdef ALLOW_TABLE
01168 static uint getFirstRowColumnWidths( const Table& table, QMemArray<double>& widthArray, int firstRowNumber )
01169
01170
01171 {
01172 uint currentColumn = 0;
01173 QValueList<TableCell>::ConstIterator itCell;
01174
01175 for ( itCell = table.cellList.begin();
01176 itCell != table.cellList.end(); ++itCell )
01177 {
01178 kdDebug(30518) << "Column: " << (*itCell).col << " (Row: " << (*itCell).row << ")" << endl;
01179 if ( (*itCell).row != firstRowNumber )
01180 break;
01181
01182 int cols = (*itCell).m_cols;
01183 if ( cols < 1)
01184 cols = 1;
01185
01186
01187 const double width = ( (*itCell).frame.right - (*itCell).frame.left ) / cols;
01188
01189 if ( currentColumn + cols > widthArray.size() )
01190 widthArray.resize( currentColumn + 4, QGArray::SpeedOptim);
01191
01192 for ( int i = 0; i < cols; ++i )
01193 {
01194 widthArray.at( currentColumn ) = width;
01195 ++currentColumn;
01196 }
01197 }
01198 return currentColumn;
01199 }
01200 #endif
01201
01202 bool OOWriterWorker::makeTable( const FrameAnchor& anchor, const AnchorType anchorType )
01203 {
01204 #ifdef ALLOW_TABLE
01205
01206
01207 const QString automaticTableStyle ( makeAutomaticStyleName( "Table", m_tableNumber ) );
01208 const QString tableName( QString( "Table" ) + QString::number( m_tableNumber ) );
01209 const QString translatedName( i18n( "Object name", "Table %1").arg( m_tableNumber ) );
01210 const QString automaticFrameStyle ( makeAutomaticStyleName( "TableFrame", m_textBoxNumber ) );
01211 const QString translatedFrameName( i18n( "Object name", "Table Frame %1").arg( m_textBoxNumber ) );
01212
01213 kdDebug(30518) << "Processing table " << anchor.key.toString() << " => " << tableName << endl;
01214
01215 const QValueList<TableCell>::ConstIterator firstCell ( anchor.table.cellList.begin() );
01216
01217 if ( firstCell == anchor.table.cellList.end() )
01218 {
01219 kdError(30518) << "Table has not any cell!" << endl;
01220 return false;
01221 }
01222
01223 const int firstRowNumber = (*firstCell).row;
01224 kdDebug(30518) << "First row: " << firstRowNumber << endl;
01225
01226 QMemArray<double> widthArray(4);
01227
01228 uint numberColumns = getColumnWidths( anchor.table, widthArray, firstRowNumber );
01229
01230 if ( numberColumns <= 0 )
01231 {
01232 kdDebug(30518) << "Could not get correct column widths, so approximating" << endl;
01233
01234 numberColumns = getFirstRowColumnWidths( anchor.table, widthArray, firstRowNumber );
01235 if ( numberColumns <= 0 )
01236 {
01237
01238 kdError(30518) << "Cannot get column widths of table " << anchor.key.toString() << endl;
01239 return false;
01240 }
01241 }
01242
01243 kdDebug(30518) << "Number of columns: " << numberColumns << endl;
01244
01245
01246 double tableWidth = 0.0;
01247 uint i;
01248 for ( i=0; i < numberColumns; ++i )
01249 {
01250 tableWidth += widthArray.at( i );
01251 }
01252 kdDebug(30518) << "Table width: " << tableWidth << endl;
01253
01254
01255 *m_streamOut << "<draw:text-box";
01256 *m_streamOut << " style:name=\"" << escapeOOText( automaticFrameStyle ) << "\"";
01257 *m_streamOut << " draw:name=\"" << escapeOOText( translatedFrameName ) << "\"";
01258 if ( anchorType == AnchorNonInlined )
01259 {
01260
01261 *m_streamOut << " text:anchor-type=\"paragraph\"";
01262 }
01263 else
01264 {
01265 *m_streamOut << " text:anchor-type=\"as-char\"";
01266 }
01267 *m_streamOut << " svg:width=\"" << tableWidth << "pt\"";
01268
01269 *m_streamOut << ">\n";
01270
01271 *m_streamOut << "<table:table table:name=\""
01272 << escapeOOText( translatedName )
01273 << "\" table:style-name=\""
01274 << escapeOOText( automaticTableStyle )
01275 << "\" >\n";
01276
01277
01278
01279
01280 kdDebug(30518) << "Creating automatic frame style: " << automaticFrameStyle << endl;
01281 m_contentAutomaticStyles += " <style:style";
01282 m_contentAutomaticStyles += " style:name=\"" + escapeOOText( automaticFrameStyle ) + "\"";
01283 m_contentAutomaticStyles += " style:family=\"graphics\"";
01284 m_contentAutomaticStyles += " style:parent-style-name=\"Frame\"";
01285 m_contentAutomaticStyles += ">\n";
01286 m_contentAutomaticStyles += " <style:properties ";
01287 m_contentAutomaticStyles += " text:anchor-type=\"as-char\"";
01288 m_contentAutomaticStyles += " fo:padding=\"0pt\" fo:border=\"none\"";
01289 m_contentAutomaticStyles += " fo:margin-left=\"0pt\"";
01290 m_contentAutomaticStyles += " fo:margin-top=\"0pt\"";
01291 m_contentAutomaticStyles += " fo:margin-bottom=\"0pt\"";
01292 m_contentAutomaticStyles += " fo:margin-right=\"0pt\"";
01293 m_contentAutomaticStyles += "/>\n";
01294 m_contentAutomaticStyles += " </style:style>\n";
01295
01296 kdDebug(30518) << "Creating automatic table style: " << automaticTableStyle << endl;
01297 m_contentAutomaticStyles += " <style:style";
01298 m_contentAutomaticStyles += " style:name=\"" + escapeOOText( automaticTableStyle ) + "\"";
01299 m_contentAutomaticStyles += " style:family=\"table\"";
01300 m_contentAutomaticStyles += ">\n";
01301 m_contentAutomaticStyles += " <style:properties ";
01302 m_contentAutomaticStyles += " style:width=\"" + QString::number( tableWidth ) + "pt\" ";
01303 m_contentAutomaticStyles += "/>\n";
01304 m_contentAutomaticStyles += " </style:style>\n";
01305
01306 QValueList<TableCell>::ConstIterator itCell;
01307
01308 ulong columnNumber = 0L;
01309
01310 for ( i=0; i < numberColumns; ++i )
01311 {
01312 const QString automaticColumnStyle ( makeAutomaticStyleName( tableName + ".Column", columnNumber ) );
01313 kdDebug(30518) << "Creating automatic column style: " << automaticColumnStyle << endl;
01314
01315 m_contentAutomaticStyles += " <style:style";
01316 m_contentAutomaticStyles += " style:name=\"" + escapeOOText( automaticColumnStyle ) + "\"";
01317 m_contentAutomaticStyles += " style:family=\"table-column\"";
01318 m_contentAutomaticStyles += ">\n";
01319 m_contentAutomaticStyles += " <style:properties ";
01320
01321
01322 m_contentAutomaticStyles += " style:column-width=\"" + QString::number( widthArray.at( i ) ) + "pt\" ";
01323 m_contentAutomaticStyles += "/>\n";
01324 m_contentAutomaticStyles += " </style:style>\n";
01325
01326
01327 *m_streamOut << "<table:table-column table:style-name=\""
01328 << escapeOOText( automaticColumnStyle )
01329 << "\" table:number-columns-repeated=\"1\"/>\n";
01330 }
01331
01332 makeTableRows( tableName, anchor.table, firstRowNumber );
01333
01334 *m_streamOut << "</table:table>\n";
01335
01336 *m_streamOut << "</draw:text-box>";
01337
01338 #endif
01339 return true;
01340 }
01341
01342 bool OOWriterWorker::makePicture( const FrameAnchor& anchor, const AnchorType anchorType )
01343 {
01344 kdDebug(30518) << "New picture: " << anchor.picture.koStoreName
01345 << " , " << anchor.picture.key.toString() << endl;
01346
01347 const QString koStoreName(anchor.picture.koStoreName);
01348
01349 QByteArray image;
01350
01351 QString strExtension(koStoreName.lower());
01352 const int result=koStoreName.findRev(".");
01353 if (result>=0)
01354 {
01355 strExtension=koStoreName.mid(result+1);
01356 }
01357
01358 bool isImageLoaded=false;
01359
01360 if (strExtension=="png")
01361 {
01362 isImageLoaded=loadSubFile(koStoreName,image);
01363 }
01364 else if ((strExtension=="jpg") || (strExtension=="jpeg"))
01365 {
01366 isImageLoaded=loadSubFile(koStoreName,image);
01367 strExtension="jpg";
01368 }
01369 else if ((strExtension=="tif") || (strExtension=="tiff"))
01370 {
01371 isImageLoaded=loadSubFile(koStoreName,image);
01372 strExtension="tif";
01373 }
01374 else if ((strExtension=="gif") || (strExtension=="wmf"))
01375
01376 {
01377 isImageLoaded=loadSubFile(koStoreName,image);
01378 }
01379 else
01380 {
01381
01382 isImageLoaded=loadAndConvertToImage(koStoreName,strExtension,"PNG",image);
01383 strExtension="png";
01384 }
01385
01386 if (!isImageLoaded)
01387 {
01388 kdWarning(30518) << "Unable to load picture: " << koStoreName << endl;
01389 return true;
01390 }
01391
01392 kdDebug(30518) << "Picture loaded: " << koStoreName << endl;
01393
01394 double height = 0.0;
01395 double width = 0.0;
01396
01397 if ( anchorType == AnchorTextImage )
01398 {
01399
01400 QBuffer buffer( image.copy() );
01401 KoPicture pic;
01402 buffer.open( IO_ReadOnly );
01403 if ( pic.load( &buffer, strExtension ) )
01404 {
01405 const QSize size ( pic.getOriginalSize() );
01406 height = size.height();
01407 width = size.width();
01408 }
01409 else
01410 {
01411 kdWarning(30518) << "Could not load KoPicture: " << koStoreName << endl;
01412 }
01413 buffer.close();
01414 }
01415 else
01416 {
01417
01418 height=anchor.frame.bottom - anchor.frame.top;
01419 width =anchor.frame.right - anchor.frame.left;
01420 }
01421
01422 if ( height < 1.0 )
01423 {
01424 kdWarning(30518) << "Silly height for " << koStoreName << " : " << height << endl;
01425 height = 72.0;
01426 }
01427 if ( width < 1.0 )
01428 {
01429 kdWarning(30518) << "Silly width for " << koStoreName << " : " << width << endl;
01430 width = 72.0;
01431 }
01432
01433
01434
01435 QString number;
01436 number.fill('0',32);
01437 number += QString::number(++m_pictureNumber,16);
01438
01439 QString ooName("Pictures/");
01440 ooName += number.right(32);
01441 ooName += '.';
01442 ooName += strExtension;
01443
01444 kdDebug(30518) << "Picture " << koStoreName << " => " << ooName << endl;
01445
01446
01447
01448 *m_streamOut << "<draw:image draw:name=\"" << anchor.picture.key.filename() << "\"";
01449 *m_streamOut << " draw:style-name=\"Graphics\"";
01450 if ( anchorType == AnchorNonInlined )
01451 {
01452
01453 *m_streamOut << " text:anchor-type=\"paragraph\"";
01454 }
01455 else
01456 {
01457 *m_streamOut << " text:anchor-type=\"as-char\"";
01458 }
01459 *m_streamOut << " svg:height=\"" << height << "pt\" svg:width=\"" << width << "pt\"";
01460 *m_streamOut << " draw:z-index=\"0\" xlink:href=\"#" << ooName << "\"";
01461 *m_streamOut << " xlink:type=\"simple\" xlink:show=\"embed\" xlink:actuate=\"onLoad\"";
01462 *m_streamOut << "/>";
01463
01464 if (m_zip)
01465 {
01466 #if 0
01467
01468 m_zip->writeFile(ooName,QString::null, QString::null, image.size(), image.data());
01469 #else
01470 zipPrepareWriting(ooName);
01471 zipWriteData( image );
01472 zipDoneWriting();
01473 #endif
01474 }
01475
01476 return true;
01477 }
01478
01479 void OOWriterWorker::processNormalText ( const QString ¶Text,
01480 const TextFormatting& formatLayout,
01481 const FormatData& formatData)
01482 {
01483
01484 const QString partialText( escapeOOSpan( paraText.mid( formatData.pos, formatData.len ) ) );
01485
01486 if (formatData.text.missing)
01487 {
01488
01489 *m_streamOut << partialText;
01490 }
01491 else
01492 {
01493 *m_streamOut << "<text:span";
01494
01495 QString styleKey;
01496 const QString props ( textFormatToStyle(formatLayout,formatData.text,false,styleKey) );
01497
01498 QMap<QString,QString>::ConstIterator it ( m_mapTextStyleKeys.find(styleKey) );
01499 kdDebug(30518) << "Searching text key: " << styleKey << endl;
01500
01501 QString automaticStyle;
01502 if (it==m_mapTextStyleKeys.end())
01503 {
01504
01505 automaticStyle=makeAutomaticStyleName("T", m_automaticTextStyleNumber);
01506 kdDebug(30518) << "Creating automatic text style: " << automaticStyle << " key: " << styleKey << endl;
01507 m_mapTextStyleKeys[styleKey]=automaticStyle;
01508
01509 m_contentAutomaticStyles += " <style:style";
01510 m_contentAutomaticStyles += " style:name=\"" + escapeOOText(automaticStyle) + "\"";
01511 m_contentAutomaticStyles += " style:family=\"text\"";
01512 m_contentAutomaticStyles += ">\n";
01513 m_contentAutomaticStyles += " <style:properties ";
01514 m_contentAutomaticStyles += props;
01515 m_contentAutomaticStyles += "/>\n";
01516 m_contentAutomaticStyles += " </style:style>\n";
01517 }
01518 else
01519 {
01520
01521 automaticStyle=it.data();
01522 kdDebug(30518) << "Using automatic text style: " << automaticStyle << " key: " << styleKey << endl;
01523 }
01524
01525 *m_streamOut << " text:style-name=\"" << escapeOOText(automaticStyle) << "\" ";
01526
01527 *m_streamOut << ">" << partialText << "</text:span>";
01528 }
01529 }
01530
01531 void OOWriterWorker::processFootnote( const VariableData& variable )
01532 {
01533
01534 const QValueList<ParaData> *paraList = variable.getFootnotePara();
01535 if( paraList )
01536 {
01537 const QString value ( variable.getFootnoteValue() );
01538
01539 const bool flag = variable.getFootnoteType();
01540
01541 if ( flag )
01542 {
01543 *m_streamOut << "<text:footnote text:id=\"ft";
01544 *m_streamOut << (++m_footnoteNumber);
01545 *m_streamOut << "\">";
01546 *m_streamOut << "<text:footnote-citation>" << escapeOOText( value ) << "</text:footnote-citation>";
01547 *m_streamOut << "<text:footnote-body>\n";
01548
01549 doFullAllParagraphs( *paraList );
01550
01551 *m_streamOut << "\n</text:footnote-body>";
01552 *m_streamOut << "</text:footnote>";
01553 }
01554 else
01555 {
01556 *m_streamOut << "<text:endnote text:id=\"ft";
01557 *m_streamOut << (++m_footnoteNumber);
01558 *m_streamOut << "\">";
01559 *m_streamOut << "<text:endnote-citation>" << escapeOOText( value ) << "</text:endnote-citation>";
01560 *m_streamOut << "<text:endnote-body>\n";
01561
01562 doFullAllParagraphs( *paraList );
01563
01564 *m_streamOut << "\n</text:endnote-body>";
01565 *m_streamOut << "</text:endnote>";
01566 }
01567 }
01568 }
01569
01570 void OOWriterWorker::processNote( const VariableData& variable )
01571 {
01572
01573
01574
01575 *m_streamOut << "<office:annotation office:create-date=\"";
01576
01577
01578
01579 if ( m_varSet.creationTime.isValid() )
01580 *m_streamOut << escapeOOText( m_varSet.creationTime.date().toString( Qt::ISODate ) );
01581 else
01582 *m_streamOut << "1970-01-01";
01583
01584 *m_streamOut << "\" office:author=\"";
01585
01586
01587 if ( m_docInfo.fullName.isEmpty() )
01588 *m_streamOut << escapeOOText( i18n( "Pseudo-author for annotations", "KWord 1.3" ) );
01589 else
01590 *m_streamOut << escapeOOText( m_docInfo.fullName );
01591
01592 *m_streamOut << "\">\n";
01593 *m_streamOut << "<text:p>"
01594 << escapeOOSpan( variable.getGenericData( "note" ) )
01595 << "</text:p>\n"
01596 << "</office:annotation>";
01597 }
01598
01599 void OOWriterWorker::processVariable ( const QString&,
01600 const TextFormatting& ,
01601 const FormatData& formatData)
01602 {
01603 if (0==formatData.variable.m_type)
01604 {
01605 *m_streamOut << "<text:date/>";
01606 }
01607 else if (2==formatData.variable.m_type)
01608 {
01609 *m_streamOut << "<text:time/>";
01610 }
01611 else if (4==formatData.variable.m_type)
01612 {
01613
01614 if (formatData.variable.isPageNumber())
01615 {
01616 *m_streamOut << "<text:page-number text:select-page=\"current\"/>";
01617 }
01618 else if (formatData.variable.isPageCount())
01619 {
01620 *m_streamOut << "<text:page-count/>";
01621 }
01622 else
01623 {
01624
01625 *m_streamOut << formatData.variable.m_text;
01626 }
01627 }
01628 else if (9==formatData.variable.m_type)
01629 {
01630
01631 *m_streamOut << "<text:a xlink:href=\""
01632 << escapeOOText(formatData.variable.getHrefName())
01633 << "\" xlink:type=\"simple\">"
01634 << escapeOOText(formatData.variable.getLinkName())
01635 << "</text:a>";
01636 }
01637 else if ( 10 == formatData.variable.m_type )
01638 {
01639 processNote ( formatData.variable );
01640 }
01641 else if (11==formatData.variable.m_type)
01642 {
01643
01644 processFootnote ( formatData.variable );
01645 }
01646 else
01647 {
01648
01649 *m_streamOut << formatData.variable.m_text;
01650 }
01651 }
01652
01653 void OOWriterWorker::processAnchor ( const QString&,
01654 const TextFormatting& ,
01655 const FormatData& formatData)
01656 {
01657
01658 if ( (2==formatData.frameAnchor.type)
01659 || (5==formatData.frameAnchor.type) )
01660 {
01661 makePicture( formatData.frameAnchor, AnchorInlined );
01662 }
01663 else if (6==formatData.frameAnchor.type)
01664 {
01665 makeTable( formatData.frameAnchor, AnchorInlined );
01666 }
01667 else
01668 {
01669 kdWarning(30518) << "Unsupported anchor type: "
01670 << formatData.frameAnchor.type << endl;
01671 }
01672 }
01673
01674 void OOWriterWorker::processTextImage ( const QString&,
01675 const TextFormatting& ,
01676 const FormatData& formatData)
01677 {
01678 kdDebug(30518) << "Text Image: " << formatData.frameAnchor.key.toString() << endl;
01679 makePicture( formatData.frameAnchor, AnchorTextImage );
01680 }
01681
01682 void OOWriterWorker::processParagraphData ( const QString ¶Text,
01683 const TextFormatting& formatLayout,
01684 const ValueListFormatData ¶FormatDataList)
01685 {
01686 if ( paraText.length () > 0 )
01687 {
01688 ValueListFormatData::ConstIterator paraFormatDataIt;
01689
01690 for ( paraFormatDataIt = paraFormatDataList.begin ();
01691 paraFormatDataIt != paraFormatDataList.end ();
01692 paraFormatDataIt++ )
01693 {
01694 if (1==(*paraFormatDataIt).id)
01695 {
01696 processNormalText(paraText, formatLayout, (*paraFormatDataIt));
01697 }
01698 else if (2==(*paraFormatDataIt).id)
01699 {
01700 processTextImage(paraText, formatLayout, (*paraFormatDataIt));
01701 }
01702 else if ( 3 == (*paraFormatDataIt).id )
01703 {
01704
01705 *m_streamOut << "<text:tab-stop/>";
01706 }
01707 else if (4==(*paraFormatDataIt).id)
01708 {
01709 processVariable(paraText, formatLayout, (*paraFormatDataIt));
01710 }
01711 else if (6==(*paraFormatDataIt).id)
01712 {
01713 processAnchor(paraText, formatLayout, (*paraFormatDataIt));
01714 }
01715 else if ( 1001 == (*paraFormatDataIt).id )
01716 {
01717 *m_streamOut << "<text:bookmark-start text:name=\""
01718 << escapeOOText( (*paraFormatDataIt).variable.m_text )
01719 <<"\"/>";
01720 }
01721 else if ( 1002 == (*paraFormatDataIt).id )
01722 {
01723 *m_streamOut << "<text:bookmark-end text:name=\""
01724 << escapeOOText( (*paraFormatDataIt).variable.m_text )
01725 <<"\"/>";
01726 }
01727 }
01728 }
01729 }
01730
01731 QString OOWriterWorker::layoutToParagraphStyle(const LayoutData& layoutOrigin,
01732 const LayoutData& layout, const bool force, QString& styleKey)
01733 {
01734 QString props;
01735
01736 styleKey += layout.styleName;
01737 styleKey += ',';
01738
01739 if (force || (layoutOrigin.alignment!=layout.alignment))
01740 {
01741
01742
01743 if (layout.alignment == "left")
01744 {
01745 props += "fo:text-align=\"start\" ";
01746 styleKey += 'L';
01747 }
01748 else if (layout.alignment == "right")
01749 {
01750 props += "fo:text-align=\"end\" ";
01751 styleKey += 'R';
01752 }
01753 else if (layout.alignment == "center")
01754 {
01755 props += "fo:text-align=\"center\" ";
01756 styleKey += 'C';
01757 }
01758 else if (layout.alignment == "justify")
01759 {
01760 props += "fo:text-align=\"justify\" ";
01761 styleKey += 'J';
01762 }
01763 else if (layout.alignment == "auto")
01764 {
01765 props += "fo:text-align=\"start\" ";
01766 #ifndef STRICT_OOWRITER_VERSION_1
01767 props += "style:text-auto-align=\"true\" ";
01768 #endif
01769 styleKey += 'A';
01770 }
01771 else
01772 {
01773 kdWarning(30518) << "Unknown alignment: " << layout.alignment << endl;
01774 }
01775 }
01776
01777 styleKey += ',';
01778
01779 if ((layout.indentLeft>=0.0)
01780 && (force || (layoutOrigin.indentLeft!=layout.indentLeft)))
01781 {
01782 props += QString("fo:margin-left=\"%1pt\" ").arg(layout.indentLeft);
01783 styleKey += QString::number(layout.indentLeft);
01784 }
01785
01786 styleKey += ',';
01787
01788 if ((layout.indentRight>=0.0)
01789 && (force || (layoutOrigin.indentRight!=layout.indentRight)))
01790 {
01791 props += QString("fo:margin-right=\"%1pt\" ").arg(layout.indentRight);
01792 styleKey += QString::number(layout.indentRight);
01793 }
01794
01795 styleKey += ',';
01796
01797 if (force || (layoutOrigin.indentLeft!=layout.indentLeft))
01798 {
01799 props += "fo:text-indent=\"";
01800 props += QString::number(layout.indentFirst);
01801 props += "\" ";
01802 styleKey += QString::number(layout.indentFirst);
01803 }
01804
01805 styleKey += ',';
01806
01807 if ((layout.marginBottom>=0.0)
01808 && ( force || ( layoutOrigin.marginBottom != layout.marginBottom ) ) )
01809 {
01810 props += QString("fo:margin-bottom=\"%1pt\" ").arg(layout.marginBottom);
01811 styleKey += QString::number(layout.marginBottom);
01812 }
01813
01814 styleKey += ',';
01815
01816 if ((layout.marginTop>=0.0)
01817 && ( force || ( layoutOrigin.marginTop != layout.marginTop ) ) )
01818 {
01819 props += QString("fo:margin-top=\"%1pt\" ").arg(layout.marginTop);
01820 styleKey += QString::number(layout.marginTop);
01821 }
01822
01823 styleKey += ',';
01824
01825 if (force
01826 || ( layoutOrigin.lineSpacingType != layout.lineSpacingType )
01827 || ( layoutOrigin.lineSpacing != layout.lineSpacing ) )
01828 {
01829 switch ( layout.lineSpacingType )
01830 {
01831 case LayoutData::LS_CUSTOM:
01832 {
01833
01834 const QString height ( QString::number(layout.lineSpacing) );
01835 props += "style:line-spacing=\"";
01836 props += height;
01837 props += "pt\" ";
01838 styleKey += height;
01839 styleKey += 'C';
01840 break;
01841 }
01842 case LayoutData::LS_SINGLE:
01843 {
01844 props += "fo:line-height=\"normal\" ";
01845 styleKey += "100%";
01846 break;
01847 }
01848 case LayoutData::LS_ONEANDHALF:
01849 {
01850 props += "fo:line-height=\"150%\" ";
01851 styleKey += "150%";
01852 break;
01853 }
01854 case LayoutData::LS_DOUBLE:
01855 {
01856 props += "fo:line-height=\"200%\" ";
01857 styleKey += "200%";
01858 break;
01859 }
01860 case LayoutData::LS_MULTIPLE:
01861 {
01862
01863 const QString mult ( QString::number( qRound( layout.lineSpacing * 100 ) ) );
01864 props += "fo:line-height=\"";
01865 props += mult;
01866 props += "%\" ";
01867 styleKey += mult;
01868 styleKey += "%";
01869 break;
01870 }
01871 case LayoutData::LS_FIXED:
01872 {
01873
01874 const QString height ( QString::number(layout.lineSpacing) );
01875 props += "fo:line-height=\"";
01876 props += height;
01877 props += "pt\" ";
01878 styleKey += height;
01879 styleKey += 'F';
01880 break;
01881 }
01882 case LayoutData::LS_ATLEAST:
01883 {
01884
01885 const QString height ( QString::number(layout.lineSpacing) );
01886 props += "style:line-height-at-least=\"";
01887 props += height;
01888 props += "pt\" ";
01889 styleKey += height;
01890 styleKey += 'A';
01891 break;
01892 }
01893 default:
01894 {
01895 kdWarning(30518) << "Unsupported lineSpacingType: " << layout.lineSpacingType << " (Ignoring!)" << endl;
01896 break;
01897 }
01898 }
01899 }
01900
01901 styleKey += ',';
01902
01903 if ( layout.pageBreakBefore )
01904 {
01905
01906 props += "fo:page-break-before=\"page\" ";
01907 styleKey += 'B';
01908 }
01909
01910 styleKey += ',';
01911
01912 if ( layout.pageBreakAfter )
01913 {
01914
01915 props += "fo:page-break-after=\"page\" ";
01916 styleKey += 'A';
01917 }
01918
01919 styleKey += '@';
01920
01921 props += textFormatToStyle(layoutOrigin.formatData.text,layout.formatData.text,force,styleKey);
01922
01923 props += ">";
01924
01925 styleKey += '@';
01926
01927
01928 if (!layout.tabulatorList.isEmpty()
01929 && (force || (layoutOrigin.tabulatorList!=layout.tabulatorList) ))
01930 {
01931 props += "\n <style:tab-stops>\n";
01932 TabulatorList::ConstIterator it;
01933 TabulatorList::ConstIterator end(layout.tabulatorList.end());
01934 for (it=layout.tabulatorList.begin();it!=end;++it)
01935 {
01936 props+=" <style:tab-stop style:position=\"";
01937 props += QString::number((*it).m_ptpos);
01938 props += "pt\"";
01939 styleKey += QString::number((*it).m_ptpos);
01940 switch ((*it).m_type)
01941 {
01942 case 0: props += " style:type=\"left\""; styleKey += "L"; break;
01943 case 1: props += " style:type=\"center\""; styleKey += "C"; break;
01944 case 2: props += " style:type=\"right\""; styleKey += "R"; break;
01945 case 3: props += " style:type=\"char\" style:char=\".\""; styleKey += "D"; break;
01946 default: props += " style:type=\"left\""; styleKey += "L"; break;
01947 }
01948 switch ((*it).m_filling)
01949 {
01950 case TabulatorData::TF_NONE: break;
01951 case TabulatorData::TF_DOT: props += " style:leader-char=\".\""; break;
01952 case TabulatorData::TF_LINE: props += " style:leader-char=\"_\""; break;
01953
01954 case TabulatorData::TF_DASH:
01955 case TabulatorData::TF_DASHDOT:
01956 case TabulatorData::TF_DASHDOTDOT: props += " style:leader-char=\"-\""; break;
01957
01958 default: break;
01959 }
01960 props += "/>\n";
01961 styleKey +='/';
01962 }
01963 props += " </style:tab-stops>\n ";
01964 }
01965
01966 return props;
01967 }
01968
01969 bool OOWriterWorker::doFullParagraph(const QString& paraText, const LayoutData& layout,
01970 const ValueListFormatData& paraFormatDataList)
01971 {
01972 const bool header = ( (layout.counter.numbering == CounterData::NUM_CHAPTER)
01973 && (layout.counter.depth<10) );
01974
01975 if (header)
01976 {
01977 *m_streamOut << " <text:h text:level=\"";
01978 *m_streamOut << QString::number(layout.counter.depth+1,10);
01979 *m_streamOut << "\" ";
01980 }
01981 else
01982 *m_streamOut << " <text:p ";
01983
01984 const LayoutData& styleLayout=m_styleMap[layout.styleName];
01985
01986 QString styleKey;
01987 const QString props(layoutToParagraphStyle(styleLayout,layout,false,styleKey));
01988
01989 QString actualStyle(layout.styleName);
01990 if (!props.isEmpty())
01991 {
01992 QMap<QString,QString>::ConstIterator it ( m_mapParaStyleKeys.find(styleKey) );
01993 kdDebug(30518) << "Searching paragraph key: " << styleKey << endl;
01994
01995 QString automaticStyle;
01996
01997 if (it==m_mapParaStyleKeys.end())
01998 {
01999
02000 automaticStyle = makeAutomaticStyleName("P", m_automaticParagraphStyleNumber);
02001 kdDebug(30518) << "Creating automatic paragraph style: " << automaticStyle << " key: " << styleKey << endl;
02002 m_mapParaStyleKeys[styleKey]=automaticStyle;
02003
02004 m_contentAutomaticStyles += " <style:style";
02005 m_contentAutomaticStyles += " style:name=\"" + escapeOOText(automaticStyle) + "\"";
02006 m_contentAutomaticStyles += " style:parent-style-name=\"" + escapeOOText(layout.styleName) + "\"";
02007 m_contentAutomaticStyles += " style:family=\"paragraph\" style:class=\"text\"";
02008 m_contentAutomaticStyles += ">\n";
02009 m_contentAutomaticStyles += " <style:properties ";
02010 m_contentAutomaticStyles += props;
02011 m_contentAutomaticStyles += "</style:properties>\n";
02012 m_contentAutomaticStyles += " </style:style>\n";
02013 }
02014 else
02015 {
02016
02017 automaticStyle=it.data();
02018 kdDebug(30518) << "Using automatic paragraph style: " << automaticStyle << " key: " << styleKey << endl;
02019 }
02020
02021 actualStyle=automaticStyle;
02022 }
02023
02024 if (!actualStyle.isEmpty())
02025 {
02026 *m_streamOut << "text:style-name=\"" << escapeOOText(actualStyle) << "\" ";
02027 }
02028 else
02029 {
02030 kdWarning(30518) << "No style for a paragraph!" << endl;
02031 }
02032
02033 *m_streamOut << ">";
02034
02035 processParagraphData(paraText, layout.formatData.text, paraFormatDataList);
02036
02037 if (header)
02038 *m_streamOut << "</text:h>\n";
02039 else
02040 *m_streamOut << "</text:p>\n";
02041
02042 return true;
02043 }
02044
02045 bool OOWriterWorker::doOpenStyles(void)
02046 {
02047 m_styles += " <office:styles>\n";
02048 m_styles += " <style:style style:name=\"Graphics\" style:family=\"graphics\">\n";
02049 m_styles += " <style:properties text:anchor-type=\"paragraph\" style:wrap=\"none\"/>\n";
02050 m_styles += " </style:style>\n";
02051 m_styles += " <style:style style:name=\"Frame\" style:family=\"graphics\">\n";
02052 m_styles += " <style:properties text:anchor-type=\"paragraph\" style:wrap=\"none\"/>\n";
02053 m_styles += " </style:style>\n";
02054 return true;
02055 }
02056
02057 bool OOWriterWorker::doFullDefineStyle(LayoutData& layout)
02058 {
02059
02060 m_styleMap[layout.styleName]=layout;
02061
02062 m_styles += " <style:style";
02063
02064 m_styles += " style:name=\"" + escapeOOText( layout.styleName ) + "\"";
02065 m_styles += " style:next-style-name=\"" + escapeOOText( layout.styleFollowing ) + "\"";
02066 m_styles += " style:family=\"paragraph\" style:class=\"text\"";
02067 m_styles += ">\n";
02068 m_styles += " <style:properties ";
02069
02070 QString debugKey;
02071 m_styles += layoutToParagraphStyle(layout,layout,true,debugKey);
02072 kdDebug(30518) << "Defining style: " << debugKey << endl;
02073
02074 m_styles += "</style:properties>\n";
02075 m_styles += " </style:style>\n";
02076
02077 return true;
02078 }
02079
02080 bool OOWriterWorker::doCloseStyles(void)
02081 {
02082 m_styles += " </office:styles>\n";
02083 return true;
02084 }
02085
02086 bool OOWriterWorker::doFullPaperFormat(const int format,
02087 const double width, const double height, const int orientation)
02088 {
02089 if ( ( format < 0 )
02090 || ( width < 1.0 )
02091 || ( height < 1.0 ) )
02092 {
02093 kdWarning(30518) << "Page size problem: format: " << format << " width: " << width << " height: " << height << endl;
02094
02095 KoFormat newFormat = KoFormat ( format );
02096 if ( ( format < 0 ) || ( format > PG_LAST_FORMAT ) )
02097 {
02098
02099 newFormat = PG_DIN_A4;
02100 }
02101 m_paperWidth = KoPageFormat::width ( newFormat, KoOrientation( orientation ) ) * 72.0 / 25.4 ;
02102 m_paperHeight = KoPageFormat::height ( newFormat, KoOrientation( orientation ) ) * 72.0 / 25.4 ;
02103 m_paperFormat = newFormat;
02104 }
02105 else
02106 {
02107 m_paperFormat=format;
02108 m_paperWidth=width;
02109 m_paperHeight=height;
02110 }
02111 m_paperOrientation=orientation;
02112 return true;
02113 }
02114
02115 bool OOWriterWorker::doFullPaperBorders (const double top, const double left,
02116 const double bottom, const double right)
02117 {
02118 m_paperBorderTop=top;
02119 m_paperBorderLeft=left;
02120 m_paperBorderBottom=bottom;
02121 m_paperBorderRight=right;
02122 return true;
02123 }
02124
02125 bool OOWriterWorker::doFullPaperFormatOther ( const int columns, const double columnspacing, const int numPages )
02126 {
02127 m_columns = columns;
02128 m_columnspacing = columnspacing;
02129 m_numPages = numPages;
02130 return true;
02131 }
02132
02133 bool OOWriterWorker::doFullDocumentInfo(const KWEFDocumentInfo& docInfo)
02134 {
02135 m_docInfo=docInfo;
02136
02137 return true;
02138 }
02139
02140 bool OOWriterWorker::doVariableSettings(const VariableSettingsData& vs)
02141 {
02142 m_varSet=vs;
02143
02144 return true;
02145 }
02146
02147 bool OOWriterWorker::doDeclareNonInlinedFramesets( QValueList<FrameAnchor>& pictureAnchors, QValueList<FrameAnchor>& tableAnchors )
02148 {
02149 m_nonInlinedPictureAnchors = pictureAnchors;
02150 m_nonInlinedTableAnchors = tableAnchors;
02151 return true;
02152 }
02153
02154 void OOWriterWorker::declareFont(const QString& fontName)
02155 {
02156 if (fontName.isEmpty())
02157 return;
02158
02159 if (m_fontNames.find(fontName)==m_fontNames.end())
02160 {
02161 QString props;
02162
02163
02164 #if 0
02165 QFont font(fontName);
02166 QFontInfo info(font);
02167 props+="style:font-family-generic=\""
02168 switch (info.styleHint())
02169 {
02170 case QFont::SansSerif:
02171 default:
02172 {
02173 props += "swiss";
02174 break;
02175 }
02176 case QFont::Serif:
02177 {
02178 props += "roman";
02179 break;
02180 }
02181 case QFont::Courier:
02182 {
02183 props += "modern";
02184 break;
02185 }
02186 case QFont::OldEnglish:
02187 {
02188 props += "decorative";
02189 break;
02190 }
02191 }
02192 props +="\" ";
02193 #endif
02194
02195 props +="style:font-pitch=\"variable\"";
02196
02197 m_fontNames[fontName]=props;
02198 }
02199 }
02200
02201 QString OOWriterWorker::makeAutomaticStyleName(const QString& prefix, ulong& counter) const
02202 {
02203 const QString str (prefix + QString::number(++counter,10));
02204
02205
02206
02207
02208 if (m_styleMap.find(str)==m_styleMap.end())
02209 return str;
02210
02211 QString str2(str+"_bis");
02212 if (m_styleMap.find(str2)==m_styleMap.end())
02213 return str2;
02214
02215 str2 = str+"_ter";
02216 if (m_styleMap.find(str2)==m_styleMap.end())
02217 return str2;
02218
02219
02220 const QDateTime dt(QDateTime::currentDateTime(Qt::UTC));
02221
02222 str2 = str + "_" + QString::number(dt.toTime_t(),16);
02223 if (m_styleMap.find(str2)==m_styleMap.end())
02224 return str2;
02225
02226 kdWarning(30518) << "Could not make an unique style name: " << str2 << endl;
02227 return str2;
02228 }
02229