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 #include <libwpd/libwpd.h>
00033 #include <string.h>
00034
00035 #include "WordPerfectCollector.hxx"
00036 #include "DocumentElement.hxx"
00037 #include "TextRunStyle.hxx"
00038 #include "FontStyle.hxx"
00039 #include "ListStyle.hxx"
00040 #include "PageSpan.hxx"
00041 #include "SectionStyle.hxx"
00042 #include "TableStyle.hxx"
00043 #include "FilterInternal.hxx"
00044 #include "WriterProperties.hxx"
00045
00046 _WriterDocumentState::_WriterDocumentState() :
00047 mbFirstElement(true),
00048 mbInFakeSection(false),
00049 mbListElementOpenedAtCurrentLevel(false),
00050 mbTableCellOpened(false),
00051 mbHeaderRow(false),
00052 mbInNote(false)
00053 {
00054 }
00055
00056 WordPerfectCollector::WordPerfectCollector(WPXInputStream *pInput, DocumentHandler *pHandler) :
00057 mpInput(pInput),
00058 mpHandler(pHandler),
00059 mbUsed(false),
00060 mfSectionSpaceAfter(0.0f),
00061 miNumListStyles(0),
00062 mpCurrentContentElements(&mBodyElements),
00063 mpCurrentPageSpan(NULL),
00064 miNumPageStyles(0),
00065 mpCurrentListStyle(NULL),
00066 miCurrentListLevel(0),
00067 miLastListLevel(0),
00068 miLastListNumber(0),
00069 mbListContinueNumbering(false),
00070 mbListElementParagraphOpened(false),
00071 mbListElementOpened(false)
00072 {
00073 }
00074
00075 WordPerfectCollector::~WordPerfectCollector()
00076 {
00077 }
00078
00079 bool WordPerfectCollector::filter()
00080 {
00081
00082
00083 if (mbUsed)
00084 return false;
00085
00086 mbUsed = true;
00087
00088
00089
00090 if (!_parseSourceDocument(*mpInput))
00091 return false;
00092 if (!_writeTargetDocument(*mpHandler))
00093 return false;
00094
00095
00096 WRITER_DEBUG_MSG(("WriterWordPerfect: Cleaning up our mess..\n"));
00097
00098 WRITER_DEBUG_MSG(("Destroying the body elements\n"));
00099 for (std::vector<DocumentElement *>::iterator iterBody = mBodyElements.begin(); iterBody != mBodyElements.end(); iterBody++) {
00100 delete((*iterBody));
00101 (*iterBody) = NULL;
00102 }
00103
00104 WRITER_DEBUG_MSG(("Destroying the styles elements\n"));
00105 for (std::vector<DocumentElement *>::iterator iterStyles = mStylesElements.begin(); iterStyles != mStylesElements.end(); iterStyles++) {
00106 delete (*iterStyles);
00107 (*iterStyles) = NULL;
00108
00109 }
00110
00111 WRITER_DEBUG_MSG(("Destroying the rest of the styles elements\n"));
00112 for (std::map<WPXString, ParagraphStyle *, ltstr>::iterator iterTextStyle = mTextStyleHash.begin(); iterTextStyle != mTextStyleHash.end(); iterTextStyle++) {
00113 delete(iterTextStyle->second);
00114 }
00115 for (std::map<WPXString, FontStyle *, ltstr>::iterator iterFont = mFontHash.begin(); iterFont != mFontHash.end(); iterFont++) {
00116 delete(iterFont->second);
00117 }
00118
00119 for (std::vector<ListStyle *>::iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); iterListStyles++) {
00120 delete((*iterListStyles));
00121 }
00122 for (std::vector<SectionStyle *>::iterator iterSectionStyles = mSectionStyles.begin(); iterSectionStyles != mSectionStyles.end(); iterSectionStyles++) {
00123 delete((*iterSectionStyles));
00124 }
00125 for (std::vector<TableStyle *>::iterator iterTableStyles = mTableStyles.begin(); iterTableStyles != mTableStyles.end(); iterTableStyles++) {
00126 delete((*iterTableStyles));
00127 }
00128
00129 for (std::vector<PageSpan *>::iterator iterPageSpans = mPageSpans.begin(); iterPageSpans != mPageSpans.end(); iterPageSpans++) {
00130 delete((*iterPageSpans));
00131 }
00132
00133 return true;
00134 }
00135
00136 bool WordPerfectCollector::_parseSourceDocument(WPXInputStream &input)
00137 {
00138 WPDResult result = WPDocument::parse(&input, static_cast<WPXHLListenerImpl *>(this));
00139 if (result != WPD_OK)
00140 return false;
00141
00142 return true;
00143 }
00144
00145 void WordPerfectCollector::_writeDefaultStyles(DocumentHandler &xHandler)
00146 {
00147 TagOpenElement stylesOpenElement("office:styles");
00148 stylesOpenElement.write(xHandler);
00149
00150 TagOpenElement defaultParagraphStyleOpenElement("style:default-style");
00151 defaultParagraphStyleOpenElement.addAttribute("style:family", "paragraph");
00152 defaultParagraphStyleOpenElement.write(xHandler);
00153
00154 TagOpenElement defaultParagraphStylePropertiesOpenElement("style:properties");
00155 defaultParagraphStylePropertiesOpenElement.addAttribute("style:family", "paragraph");
00156 defaultParagraphStylePropertiesOpenElement.addAttribute("style:tab-stop-distance", "0.5inch");
00157 defaultParagraphStylePropertiesOpenElement.write(xHandler);
00158 TagCloseElement defaultParagraphStylePropertiesCloseElement("style:properties");
00159 defaultParagraphStylePropertiesCloseElement.write(xHandler);
00160
00161 TagCloseElement defaultParagraphStyleCloseElement("style:default-style");
00162 defaultParagraphStyleCloseElement.write(xHandler);
00163
00164 TagOpenElement standardStyleOpenElement("style:style");
00165 standardStyleOpenElement.addAttribute("style:name", "Standard");
00166 standardStyleOpenElement.addAttribute("style:family", "paragraph");
00167 standardStyleOpenElement.addAttribute("style:class", "text");
00168 standardStyleOpenElement.write(xHandler);
00169 TagCloseElement standardStyleCloseElement("style:style");
00170 standardStyleCloseElement.write(xHandler);
00171
00172 TagOpenElement textBodyStyleOpenElement("style:style");
00173 textBodyStyleOpenElement.addAttribute("style:name", "Text Body");
00174 textBodyStyleOpenElement.addAttribute("style:family", "paragraph");
00175 textBodyStyleOpenElement.addAttribute("style:parent-style-name", "Standard");
00176 textBodyStyleOpenElement.addAttribute("style:class", "text");
00177 textBodyStyleOpenElement.write(xHandler);
00178 TagCloseElement textBodyStyleCloseElement("style:style");
00179 textBodyStyleCloseElement.write(xHandler);
00180
00181 TagOpenElement tableContentsStyleOpenElement("style:style");
00182 tableContentsStyleOpenElement.addAttribute("style:name", "Table Contents");
00183 tableContentsStyleOpenElement.addAttribute("style:family", "paragraph");
00184 tableContentsStyleOpenElement.addAttribute("style:parent-style-name", "Text Body");
00185 tableContentsStyleOpenElement.addAttribute("style:class", "extra");
00186 tableContentsStyleOpenElement.write(xHandler);
00187 TagCloseElement tableContentsStyleCloseElement("style:style");
00188 tableContentsStyleCloseElement.write(xHandler);
00189
00190 TagOpenElement tableHeadingStyleOpenElement("style:style");
00191 tableHeadingStyleOpenElement.addAttribute("style:name", "Table Heading");
00192 tableHeadingStyleOpenElement.addAttribute("style:family", "paragraph");
00193 tableHeadingStyleOpenElement.addAttribute("style:parent-style-name", "Table Contents");
00194 tableHeadingStyleOpenElement.addAttribute("style:class", "extra");
00195 tableHeadingStyleOpenElement.write(xHandler);
00196 TagCloseElement tableHeadingStyleCloseElement("style:style");
00197 tableHeadingStyleCloseElement.write(xHandler);
00198
00199 TagCloseElement stylesCloseElement("office:styles");
00200 stylesCloseElement.write(xHandler);
00201
00202 }
00203
00204
00205 void WordPerfectCollector::_writeBegin()
00206 {
00207 }
00208
00209 void WordPerfectCollector::_writeMasterPages(DocumentHandler &xHandler)
00210 {
00211 WPXPropertyList xBlankAttrList;
00212
00213 xHandler.startElement("office:master-styles", xBlankAttrList);
00214 int pageNumber = 1;
00215 for (int i=0; i<mPageSpans.size(); i++)
00216 {
00217 bool bLastPage;
00218 (i == (mPageSpans.size() - 1)) ? bLastPage = true : bLastPage = false;
00219 mPageSpans[i]->writeMasterPages(pageNumber, i, bLastPage, xHandler);
00220 pageNumber += mPageSpans[i]->getSpan();
00221 }
00222 xHandler.endElement("office:master-styles");
00223 }
00224
00225 void WordPerfectCollector::_writePageMasters(DocumentHandler &xHandler)
00226 {
00227 int pageNumber = 1;
00228 for (int i=0; i<mPageSpans.size(); i++)
00229 {
00230 mPageSpans[i]->writePageMaster(i, xHandler);
00231 }
00232 }
00233
00234 bool WordPerfectCollector::_writeTargetDocument(DocumentHandler &xHandler)
00235 {
00236 WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Printing out the header stuff..\n"));
00237 WPXPropertyList xBlankAttrList;
00238
00239 WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Start Document\n"));
00240 mpHandler->startDocument();
00241
00242 WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: preamble\n"));
00243 WPXPropertyList docContentPropList;
00244 docContentPropList.insert("xmlns:office", "http://openoffice.org/2000/office");
00245 docContentPropList.insert("xmlns:style", "http://openoffice.org/2000/style");
00246 docContentPropList.insert("xmlns:text", "http://openoffice.org/2000/text");
00247 docContentPropList.insert("xmlns:table", "http://openoffice.org/2000/table");
00248 docContentPropList.insert("xmlns:draw", "http://openoffice.org/2000/draw");
00249 docContentPropList.insert("xmlns:fo", "http://www.w3.org/1999/XSL/Format");
00250 docContentPropList.insert("xmlns:xlink", "http://www.w3.org/1999/xlink");
00251 docContentPropList.insert("xmlns:number", "http://openoffice.org/2000/datastyle");
00252 docContentPropList.insert("xmlns:svg", "http://www.w3.org/2000/svg");
00253 docContentPropList.insert("xmlns:chart", "http://openoffice.org/2000/chart");
00254 docContentPropList.insert("xmlns:dr3d", "http://openoffice.org/2000/dr3d");
00255 docContentPropList.insert("xmlns:math", "http://www.w3.org/1998/Math/MathML");
00256 docContentPropList.insert("xmlns:form", "http://openoffice.org/2000/form");
00257 docContentPropList.insert("xmlns:script", "http://openoffice.org/2000/script");
00258 docContentPropList.insert("office:class", "text");
00259 docContentPropList.insert("office:version", "1.0");
00260 mpHandler->startElement("office:document-content", docContentPropList);
00261
00262
00263 mpHandler->startElement("office:font-decls", xBlankAttrList);
00264 for (std::map<WPXString, FontStyle *, ltstr>::iterator iterFont = mFontHash.begin(); iterFont != mFontHash.end(); iterFont++) {
00265 iterFont->second->write(*mpHandler);
00266 }
00267 TagOpenElement symbolFontOpen("style:font-decl");
00268 symbolFontOpen.addAttribute("style:name", "StarSymbol");
00269 symbolFontOpen.addAttribute("fo:font-family", "StarSymbol");
00270 symbolFontOpen.addAttribute("style:font-charset", "x-symbol");
00271 symbolFontOpen.write(*mpHandler);
00272 mpHandler->endElement("style:font-decl");
00273
00274 mpHandler->endElement("office:font-decls");
00275
00276
00277 WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Writing out the styles..\n"));
00278
00279
00280 _writeDefaultStyles(*mpHandler);
00281
00282 mpHandler->startElement("office:automatic-styles", xBlankAttrList);
00283
00284 for (std::map<WPXString, ParagraphStyle *, ltstr>::iterator iterTextStyle = mTextStyleHash.begin();
00285 iterTextStyle != mTextStyleHash.end(); iterTextStyle++)
00286 {
00287
00288 if (strcmp((iterTextStyle->second)->getName().cstr(), "Standard"))
00289 {
00290
00291 (iterTextStyle->second)->write(xHandler);
00292 }
00293 }
00294
00295
00296 for (std::map<WPXString, SpanStyle *, ltstr>::iterator iterSpanStyle = mSpanStyleHash.begin();
00297 iterSpanStyle != mSpanStyleHash.end(); iterSpanStyle++)
00298 {
00299 (iterSpanStyle->second)->write(xHandler);
00300 }
00301
00302
00303 for (std::vector<SectionStyle *>::iterator iterSectionStyles = mSectionStyles.begin(); iterSectionStyles != mSectionStyles.end(); iterSectionStyles++) {
00304 (*iterSectionStyles)->write(xHandler);
00305 }
00306
00307
00308 for (std::vector<ListStyle *>::iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); iterListStyles++) {
00309 (*iterListStyles)->write(xHandler);
00310 }
00311
00312
00313 for (std::vector<TableStyle *>::iterator iterTableStyles = mTableStyles.begin(); iterTableStyles != mTableStyles.end(); iterTableStyles++) {
00314 (*iterTableStyles)->write(xHandler);
00315 }
00316
00317
00318 _writePageMasters(xHandler);
00319
00320
00321 xHandler.endElement("office:automatic-styles");
00322
00323 _writeMasterPages(xHandler);
00324
00325 WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Writing out the document..\n"));
00326
00327 xHandler.startElement("office:body", xBlankAttrList);
00328
00329 for (std::vector<DocumentElement *>::iterator iterBodyElements = mBodyElements.begin(); iterBodyElements != mBodyElements.end(); iterBodyElements++) {
00330 (*iterBodyElements)->write(xHandler);
00331 }
00332 WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Finished writing all doc els..\n"));
00333
00334 xHandler.endElement("office:body");
00335 xHandler.endElement("office:document-content");
00336
00337 xHandler.endDocument();
00338
00339 return true;
00340 }
00341
00342
00343 WPXString propListToStyleKey(const WPXPropertyList & xPropList)
00344 {
00345 WPXString sKey;
00346 WPXPropertyList::Iter i(xPropList);
00347 for (i.rewind(); i.next(); )
00348 {
00349 WPXString sProp;
00350 sProp.sprintf("[%s:%s]", i.key(), i()->getStr().cstr());
00351 sKey.append(sProp);
00352 }
00353
00354 return sKey;
00355 }
00356
00357 WPXString getParagraphStyleKey(const WPXPropertyList & xPropList, const WPXPropertyListVector & xTabStops)
00358 {
00359 WPXString sKey = propListToStyleKey(xPropList);
00360
00361 WPXString sTabStops;
00362 sTabStops.sprintf("[num-tab-stops:%i]", xTabStops.count());
00363 WPXPropertyListVector::Iter i(xTabStops);
00364 for (i.rewind(); i.next();)
00365 {
00366 sTabStops.append(propListToStyleKey(i()));
00367 }
00368 sKey.append(sTabStops);
00369
00370 return sKey;
00371 }
00372
00373
00374 void WordPerfectCollector::_allocateFontName(const WPXString & sFontName)
00375 {
00376 if (mFontHash.find(sFontName) == mFontHash.end())
00377 {
00378 FontStyle *pFontStyle = new FontStyle(sFontName.cstr(), sFontName.cstr());
00379 mFontHash[sFontName] = pFontStyle;
00380 }
00381 }
00382
00383 void WordPerfectCollector::openPageSpan(const WPXPropertyList &propList)
00384 {
00385 PageSpan *pPageSpan = new PageSpan(propList);
00386 mPageSpans.push_back(pPageSpan);
00387 mpCurrentPageSpan = pPageSpan;
00388 }
00389
00390 void WordPerfectCollector::openHeader(const WPXPropertyList &propList)
00391 {
00392 std::vector<DocumentElement *> * pHeaderFooterContentElements = new std::vector<DocumentElement *>;
00393
00394 if (propList["libwpd:occurence"]->getStr() == "even")
00395 mpCurrentPageSpan->setHeaderLeftContent(pHeaderFooterContentElements);
00396 else
00397 mpCurrentPageSpan->setHeaderContent(pHeaderFooterContentElements);
00398
00399 mpCurrentContentElements = pHeaderFooterContentElements;
00400 }
00401
00402 void WordPerfectCollector::closeHeader()
00403 {
00404 mpCurrentContentElements = &mBodyElements;
00405 }
00406
00407 void WordPerfectCollector::openFooter(const WPXPropertyList &propList)
00408 {
00409 std::vector<DocumentElement *> * pHeaderFooterContentElements = new std::vector<DocumentElement *>;
00410
00411 if (propList["libwpd:occurence"]->getStr() == "even")
00412 mpCurrentPageSpan->setFooterLeftContent(pHeaderFooterContentElements);
00413 else
00414 mpCurrentPageSpan->setFooterContent(pHeaderFooterContentElements);
00415
00416 mpCurrentContentElements = pHeaderFooterContentElements;
00417 }
00418
00419 void WordPerfectCollector::closeFooter()
00420 {
00421 mpCurrentContentElements = &mBodyElements;
00422 }
00423
00424 void WordPerfectCollector::openSection(const WPXPropertyList &propList, const WPXPropertyListVector &columns)
00425 {
00426 int iNumColumns = columns.count();
00427
00428 if (iNumColumns > 1)
00429 {
00430 mfSectionSpaceAfter = propList["fo:margin-bottom"]->getFloat();
00431 WPXString sSectionName;
00432 sSectionName.sprintf("Section%i", mSectionStyles.size());
00433
00434 SectionStyle *pSectionStyle = new SectionStyle(propList, columns, sSectionName.cstr());
00435 mSectionStyles.push_back(pSectionStyle);
00436
00437 TagOpenElement *pSectionOpenElement = new TagOpenElement("text:section");
00438 pSectionOpenElement->addAttribute("text:style-name", pSectionStyle->getName());
00439 pSectionOpenElement->addAttribute("text:name", pSectionStyle->getName());
00440 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pSectionOpenElement));
00441 }
00442 else
00443 mWriterDocumentState.mbInFakeSection = true;
00444 }
00445
00446 void WordPerfectCollector::closeSection()
00447 {
00448 if (!mWriterDocumentState.mbInFakeSection)
00449 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:section")));
00450 else
00451 mWriterDocumentState.mbInFakeSection = false;
00452
00453
00454
00455 #if 0
00456 for (float f=0.0f; f<mfSectionSpaceAfter; f+=1.0f) {
00457 vector<WPXTabStop> dummyTabStops;
00458 openParagraph(WPX_PARAGRAPH_JUSTIFICATION_LEFT, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, dummyTabStops, false, false);
00459 closeParagraph();
00460 }
00461 #endif
00462 mfSectionSpaceAfter = 0.0f;
00463 }
00464
00465 void WordPerfectCollector::openParagraph(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops)
00466 {
00467
00468
00469
00470 WPXPropertyList *pPersistPropList = new WPXPropertyList(propList);
00471 ParagraphStyle *pStyle = NULL;
00472
00473 if (mWriterDocumentState.mbFirstElement && mpCurrentContentElements == &mBodyElements)
00474 {
00475
00476
00477
00478
00479
00480 pPersistPropList->insert("style:parent-style-name", "Standard");
00481 WPXString sName;
00482 sName.sprintf("FS");
00483
00484 WPXString sParagraphHashKey("P|FS");
00485 pPersistPropList->insert("style:master-page-name", "Page Style 1");
00486 pStyle = new ParagraphStyle(pPersistPropList, tabStops, sName);
00487 mTextStyleHash[sParagraphHashKey] = pStyle;
00488 mWriterDocumentState.mbFirstElement = false;
00489 }
00490 else
00491 {
00492 if (mWriterDocumentState.mbTableCellOpened)
00493 {
00494 if (mWriterDocumentState.mbHeaderRow)
00495 pPersistPropList->insert("style:parent-style-name", "Table Heading");
00496 else
00497 pPersistPropList->insert("style:parent-style-name", "Table Contents");
00498 }
00499 else
00500 pPersistPropList->insert("style:parent-style-name", "Standard");
00501
00502 WPXString sKey = getParagraphStyleKey(*pPersistPropList, tabStops);
00503
00504 if (mTextStyleHash.find(sKey) == mTextStyleHash.end()) {
00505 WPXString sName;
00506 sName.sprintf("S%i", mTextStyleHash.size());
00507
00508 pStyle = new ParagraphStyle(pPersistPropList, tabStops, sName);
00509
00510 mTextStyleHash[sKey] = pStyle;
00511 }
00512 else
00513 {
00514 pStyle = mTextStyleHash[sKey];
00515 delete pPersistPropList;
00516 }
00517 }
00518
00519 TagOpenElement *pParagraphOpenElement = new TagOpenElement("text:p");
00520 pParagraphOpenElement->addAttribute("text:style-name", pStyle->getName());
00521 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pParagraphOpenElement));
00522 }
00523
00524 void WordPerfectCollector::closeParagraph()
00525 {
00526 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:p")));
00527 }
00528
00529 void WordPerfectCollector::openSpan(const WPXPropertyList &propList)
00530 {
00531 if (propList["style:font-name"])
00532 _allocateFontName(propList["style:font-name"]->getStr());
00533 WPXString sSpanHashKey = propListToStyleKey(propList);
00534 WRITER_DEBUG_MSG(("WriterWordPerfect: Span Hash Key: %s\n", sSpanHashKey.cstr()));
00535
00536
00537 WPXString sName;
00538 if (mSpanStyleHash.find(sSpanHashKey) == mSpanStyleHash.end())
00539 {
00540
00541 sName.sprintf("Span%i", mSpanStyleHash.size());
00542 SpanStyle *pStyle = new SpanStyle(sName.cstr(), propList);
00543
00544 mSpanStyleHash[sSpanHashKey] = pStyle;
00545 }
00546 else
00547 {
00548 sName.sprintf("%s", mSpanStyleHash.find(sSpanHashKey)->second->getName().cstr());
00549 }
00550
00551
00552 TagOpenElement *pSpanOpenElement = new TagOpenElement("text:span");
00553 pSpanOpenElement->addAttribute("text:style-name", sName.cstr());
00554 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pSpanOpenElement));
00555 }
00556
00557 void WordPerfectCollector::closeSpan()
00558 {
00559 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:span")));
00560 }
00561
00562 void WordPerfectCollector::defineOrderedListLevel(const WPXPropertyList &propList)
00563 {
00564 int id = 0;
00565 if (propList["libwpd:id"])
00566 id = propList["libwpd:id"]->getInt();
00567
00568 OrderedListStyle *pOrderedListStyle = NULL;
00569 if (mpCurrentListStyle && mpCurrentListStyle->getListID() == id)
00570 pOrderedListStyle = static_cast<OrderedListStyle *>(mpCurrentListStyle);
00571
00572
00573
00574
00575
00576 if (pOrderedListStyle == NULL || pOrderedListStyle->getListID() != id ||
00577 (propList["libwpd:level"] && propList["libwpd:level"]->getInt()==1 &&
00578 (propList["text:start-value"] && propList["text:start-value"]->getInt() != (miLastListNumber+1))))
00579 {
00580 WRITER_DEBUG_MSG(("Attempting to create a new ordered list style (listid: %i)\n", id));
00581 WPXString sName;
00582 sName.sprintf("OL%i", miNumListStyles);
00583 miNumListStyles++;
00584 pOrderedListStyle = new OrderedListStyle(sName.cstr(), propList["libwpd:id"]->getInt());
00585 mListStyles.push_back(static_cast<ListStyle *>(pOrderedListStyle));
00586 mpCurrentListStyle = static_cast<ListStyle *>(pOrderedListStyle);
00587 mbListContinueNumbering = false;
00588 miLastListNumber = 0;
00589 }
00590 else
00591 mbListContinueNumbering = true;
00592
00593
00594
00595
00596 for (std::vector<ListStyle *>::iterator iterOrderedListStyles = mListStyles.begin(); iterOrderedListStyles != mListStyles.end(); iterOrderedListStyles++)
00597 {
00598 if ((* iterOrderedListStyles)->getListID() == propList["libwpd:id"]->getInt())
00599 (* iterOrderedListStyles)->updateListLevel((propList["libwpd:level"]->getInt() - 1), propList);
00600 }
00601 }
00602
00603 void WordPerfectCollector::defineUnorderedListLevel(const WPXPropertyList &propList)
00604 {
00605 int id = 0;
00606 if (propList["libwpd:id"])
00607 id = propList["libwpd:id"]->getInt();
00608
00609 UnorderedListStyle *pUnorderedListStyle = NULL;
00610 if (mpCurrentListStyle && mpCurrentListStyle->getListID() == id)
00611 pUnorderedListStyle = static_cast<UnorderedListStyle *>(mpCurrentListStyle);
00612
00613 if (pUnorderedListStyle == NULL) {
00614 WRITER_DEBUG_MSG(("Attempting to create a new unordered list style (listid: %i)\n", id));
00615 WPXString sName;
00616 sName.sprintf("UL%i", miNumListStyles);
00617 pUnorderedListStyle = new UnorderedListStyle(sName.cstr(), id);
00618 mListStyles.push_back(static_cast<ListStyle *>(pUnorderedListStyle));
00619 mpCurrentListStyle = static_cast<ListStyle *>(pUnorderedListStyle);
00620 }
00621
00622
00623 for (std::vector<ListStyle *>::iterator iterUnorderedListStyles = mListStyles.begin(); iterUnorderedListStyles != mListStyles.end(); iterUnorderedListStyles++)
00624 {
00625 if ((* iterUnorderedListStyles)->getListID() == propList["libwpd:id"]->getInt())
00626 (* iterUnorderedListStyles)->updateListLevel((propList["libwpd:level"]->getInt() - 1), propList);
00627 }
00628 }
00629
00630 void WordPerfectCollector::openOrderedListLevel(const WPXPropertyList &propList)
00631 {
00632 miCurrentListLevel++;
00633 TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:ordered-list");
00634 _openListLevel(pListLevelOpenElement);
00635
00636 if (mbListContinueNumbering) {
00637 pListLevelOpenElement->addAttribute("text:continue-numbering", "true");
00638 }
00639
00640 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pListLevelOpenElement));
00641 }
00642
00643 void WordPerfectCollector::openUnorderedListLevel(const WPXPropertyList &propList)
00644 {
00645 miCurrentListLevel++;
00646 TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:unordered-list");
00647 _openListLevel(pListLevelOpenElement);
00648
00649 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pListLevelOpenElement));
00650 }
00651
00652 void WordPerfectCollector::_openListLevel(TagOpenElement *pListLevelOpenElement)
00653 {
00654 if (!mbListElementOpened && miCurrentListLevel > 1)
00655 {
00656 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:list-item")));
00657 }
00658 else if (mbListElementParagraphOpened)
00659 {
00660 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:p")));
00661 mbListElementParagraphOpened = false;
00662 }
00663
00664 if (miCurrentListLevel==1) {
00665 pListLevelOpenElement->addAttribute("text:style-name", mpCurrentListStyle->getName());
00666 }
00667
00668 mbListElementOpened = false;
00669 }
00670
00671 void WordPerfectCollector::closeOrderedListLevel()
00672 {
00673 _closeListLevel("ordered-list");
00674 }
00675
00676 void WordPerfectCollector::closeUnorderedListLevel()
00677 {
00678 _closeListLevel("unordered-list");
00679 }
00680
00681 void WordPerfectCollector::_closeListLevel(const char *szListType)
00682 {
00683 if (mbListElementOpened)
00684 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:list-item")));
00685
00686 miCurrentListLevel--;
00687
00688 WPXString sCloseElement;
00689 sCloseElement.sprintf("text:%s", szListType);
00690 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement(sCloseElement.cstr())));
00691
00692 if (miCurrentListLevel > 0)
00693 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:list-item")));
00694 mbListElementOpened = false;
00695 }
00696
00697 void WordPerfectCollector::openListElement(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops)
00698 {
00699 miLastListLevel = miCurrentListLevel;
00700 if (miCurrentListLevel == 1)
00701 miLastListNumber++;
00702
00703 if (mbListElementOpened)
00704 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:list-item")));
00705
00706 ParagraphStyle *pStyle = NULL;
00707
00708 WPXPropertyList *pPersistPropList = new WPXPropertyList(propList);
00709 pPersistPropList->insert("style:list-style-name", mpCurrentListStyle->getName());
00710 pPersistPropList->insert("style:parent-style-name", "Standard");
00711
00712 WPXString sKey = getParagraphStyleKey(*pPersistPropList, tabStops);
00713
00714 if (mTextStyleHash.find(sKey) == mTextStyleHash.end())
00715 {
00716 WPXString sName;
00717 sName.sprintf("S%i", mTextStyleHash.size());
00718
00719 pStyle = new ParagraphStyle(pPersistPropList, tabStops, sName);
00720
00721 mTextStyleHash[sKey] = pStyle;
00722 }
00723 else
00724 {
00725 pStyle = mTextStyleHash[sKey];
00726 delete pPersistPropList;
00727 }
00728
00729 TagOpenElement *pOpenListElement = new TagOpenElement("text:list-item");
00730 TagOpenElement *pOpenListElementParagraph = new TagOpenElement("text:p");
00731
00732 pOpenListElementParagraph->addAttribute("text:style-name", pStyle->getName());
00733
00734 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pOpenListElement));
00735 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pOpenListElementParagraph));
00736
00737 mbListElementOpened = true;
00738 mbListElementParagraphOpened = true;
00739 mbListContinueNumbering = false;
00740 }
00741
00742 void WordPerfectCollector::closeListElement()
00743 {
00744
00745
00746
00747
00748 if (mbListElementParagraphOpened)
00749 {
00750 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:p")));
00751 mbListElementParagraphOpened = false;
00752 }
00753 }
00754
00755 void WordPerfectCollector::openFootnote(const WPXPropertyList &propList)
00756 {
00757 TagOpenElement *pOpenFootNote = new TagOpenElement("text:footnote");
00758 if (propList["libwpd:number"])
00759 {
00760 WPXString tmpString("ftn");
00761 tmpString.append(propList["libwpd:number"]->getStr());
00762 pOpenFootNote->addAttribute("text:id", tmpString);
00763 }
00764 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pOpenFootNote));
00765
00766 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:footnote-citation")));
00767 if (propList["libwpd:number"])
00768 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new CharDataElement(propList["libwpd:number"]->getStr().cstr())));
00769 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:footnote-citation")));
00770
00771 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:footnote-body")));
00772
00773 mWriterDocumentState.mbInNote = true;
00774 }
00775
00776 void WordPerfectCollector::closeFootnote()
00777 {
00778 mWriterDocumentState.mbInNote = false;
00779
00780 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:footnote-body")));
00781 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:footnote")));
00782 }
00783
00784 void WordPerfectCollector::openEndnote(const WPXPropertyList &propList)
00785 {
00786 TagOpenElement *pOpenEndNote = new TagOpenElement("text:endnote");
00787 if (propList["libwpd:number"])
00788 {
00789 WPXString tmpString("edn");
00790 tmpString.append(propList["libwpd:number"]->getStr());
00791 pOpenEndNote->addAttribute("text:id", tmpString);
00792 }
00793 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pOpenEndNote));
00794
00795 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:endnote-citation")));
00796 if (propList["libwpd:number"])
00797 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new CharDataElement(propList["libwpd:number"]->getStr().cstr())));
00798 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:endnote-citation")));
00799
00800 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:endnote-body")));
00801
00802 mWriterDocumentState.mbInNote = true;
00803 }
00804
00805 void WordPerfectCollector::closeEndnote()
00806 {
00807 mWriterDocumentState.mbInNote = false;
00808
00809 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:endnote-body")));
00810 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:endnote")));
00811 }
00812
00813 void WordPerfectCollector::openTable(const WPXPropertyList &propList, const WPXPropertyListVector &columns)
00814 {
00815 if (!mWriterDocumentState.mbInNote)
00816 {
00817 WPXString sTableName;
00818 sTableName.sprintf("Table%i", mTableStyles.size());
00819
00820
00821
00822
00823 TableStyle *pTableStyle = new TableStyle(propList, columns, sTableName.cstr());
00824
00825 if (mWriterDocumentState.mbFirstElement && mpCurrentContentElements == &mBodyElements)
00826 {
00827 WPXString sMasterPageName("Page Style 1");
00828 pTableStyle->setMasterPageName(sMasterPageName);
00829 mWriterDocumentState.mbFirstElement = false;
00830 }
00831
00832 mTableStyles.push_back(pTableStyle);
00833
00834 mpCurrentTableStyle = pTableStyle;
00835
00836 TagOpenElement *pTableOpenElement = new TagOpenElement("table:table");
00837
00838 pTableOpenElement->addAttribute("table:name", sTableName.cstr());
00839 pTableOpenElement->addAttribute("table:style-name", sTableName.cstr());
00840 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pTableOpenElement));
00841
00842 for (int i=0; i<pTableStyle->getNumColumns(); i++)
00843 {
00844 TagOpenElement *pTableColumnOpenElement = new TagOpenElement("table:table-column");
00845 WPXString sColumnStyleName;
00846 sColumnStyleName.sprintf("%s.Column%i", sTableName.cstr(), (i+1));
00847 pTableColumnOpenElement->addAttribute("table:style-name", sColumnStyleName.cstr());
00848 mpCurrentContentElements->push_back(pTableColumnOpenElement);
00849
00850 TagCloseElement *pTableColumnCloseElement = new TagCloseElement("table:table-column");
00851 mpCurrentContentElements->push_back(pTableColumnCloseElement);
00852 }
00853 }
00854 }
00855
00856 void WordPerfectCollector::openTableRow(const WPXPropertyList &propList)
00857 {
00858 if (!mWriterDocumentState.mbInNote)
00859 {
00860 if (propList["libwpd:is-header-row"] && (propList["libwpd:is-header-row"]->getInt()))
00861 {
00862 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("table:table-header-rows")));
00863 mWriterDocumentState.mbHeaderRow = true;
00864 }
00865
00866 WPXString sTableRowStyleName;
00867 sTableRowStyleName.sprintf("%s.Row%i", mpCurrentTableStyle->getName().cstr(), mpCurrentTableStyle->getNumTableRowStyles());
00868 TableRowStyle *pTableRowStyle = new TableRowStyle(propList, sTableRowStyleName.cstr());
00869 mpCurrentTableStyle->addTableRowStyle(pTableRowStyle);
00870
00871 TagOpenElement *pTableRowOpenElement = new TagOpenElement("table:table-row");
00872 pTableRowOpenElement->addAttribute("table:style-name", sTableRowStyleName);
00873 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pTableRowOpenElement));
00874 }
00875 }
00876
00877 void WordPerfectCollector::closeTableRow()
00878 {
00879 if (!mWriterDocumentState.mbInNote)
00880 {
00881 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table-row")));
00882 if (mWriterDocumentState.mbHeaderRow)
00883 {
00884 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table-header-rows")));
00885 mWriterDocumentState.mbHeaderRow = false;
00886 }
00887 }
00888 }
00889
00890 void WordPerfectCollector::openTableCell(const WPXPropertyList &propList)
00891 {
00892 if (!mWriterDocumentState.mbInNote)
00893 {
00894 WPXString sTableCellStyleName;
00895 sTableCellStyleName.sprintf( "%s.Cell%i", mpCurrentTableStyle->getName().cstr(), mpCurrentTableStyle->getNumTableCellStyles());
00896 TableCellStyle *pTableCellStyle = new TableCellStyle(propList, sTableCellStyleName.cstr());
00897 mpCurrentTableStyle->addTableCellStyle(pTableCellStyle);
00898
00899 TagOpenElement *pTableCellOpenElement = new TagOpenElement("table:table-cell");
00900 pTableCellOpenElement->addAttribute("table:style-name", sTableCellStyleName);
00901 if (propList["table:number-columns-spanned"])
00902 pTableCellOpenElement->addAttribute("table:number-columns-spanned",
00903 propList["table:number-columns-spanned"]->getStr().cstr());
00904 if (propList["table:number-rows-spanned"])
00905 pTableCellOpenElement->addAttribute("table:number-rows-spanned",
00906 propList["table:number-rows-spanned"]->getStr().cstr());
00907 pTableCellOpenElement->addAttribute("table:value-type", "string");
00908 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pTableCellOpenElement));
00909
00910 mWriterDocumentState.mbTableCellOpened = true;
00911 }
00912 }
00913
00914 void WordPerfectCollector::closeTableCell()
00915 {
00916 if (!mWriterDocumentState.mbInNote)
00917 {
00918 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table-cell")));
00919 mWriterDocumentState.mbTableCellOpened = false;
00920 }
00921 }
00922
00923 void WordPerfectCollector::insertCoveredTableCell(const WPXPropertyList &propList)
00924 {
00925 if (!mWriterDocumentState.mbInNote)
00926 {
00927 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("table:covered-table-cell")));
00928 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:covered-table-cell")));
00929 }
00930 }
00931
00932 void WordPerfectCollector::closeTable()
00933 {
00934 if (!mWriterDocumentState.mbInNote)
00935 {
00936 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table")));
00937 }
00938 }
00939
00940
00941 void WordPerfectCollector::insertTab()
00942 {
00943 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:tab-stop")));
00944 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:tab-stop")));
00945 }
00946
00947 void WordPerfectCollector::insertLineBreak()
00948 {
00949 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:line-break")));
00950 mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:line-break")));
00951 }
00952
00953 void WordPerfectCollector::insertText(const WPXString &text)
00954 {
00955 DocumentElement *pText = new TextElement(text);
00956 mpCurrentContentElements->push_back(pText);
00957 }