Bump version to 4.1-6
[LibreOffice.git] / writerfilter / source / doctok / WW8DocumentImpl.cxx
blobcfdae5ff777cbfb66ad80f984a8c5d0099b97375
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <resourcemodel/exceptions.hxx>
21 #include <resourcemodel/QNameToString.hxx>
22 #include <WW8DocumentImpl.hxx>
23 #include <WW8FKPImpl.hxx>
24 #include <WW8PieceTableImpl.hxx>
25 #include <WW8BinTableImpl.hxx>
26 #include <WW8StreamImpl.hxx>
27 #include <WW8Sttbf.hxx>
28 #include <Dff.hxx>
29 #include <iterator>
30 #include <XNoteHelperImpl.hxx>
31 #include <rtl/ustring.hxx>
32 #include <rtl/ustrbuf.hxx>
33 #include <doctokLoggers.hxx>
35 namespace writerfilter {
36 namespace doctok
39 using namespace ::std;
41 template <class T>
42 struct PLCFHelper
44 static void processPLCFCpAndFcs(WW8DocumentImpl & rDoc,
45 WW8PieceTable::Pointer_t pPieceTable,
46 typename PLCF<T>::Pointer_t pPLCF,
47 PropertyType eType,
48 sal_uInt32 nOffset)
50 sal_uInt32 nCount = pPLCF->getEntryCount();
51 for (sal_uInt32 n = 0; n < nCount; ++n)
53 Cp aCp(pPLCF->getFc(n) + nOffset);
54 CpAndFc aCpAndFc = pPieceTable->createCpAndFc(aCp, eType);
56 rDoc.insertCpAndFc(aCpAndFc);
61 // WW8DocumentIteratorImpl
62 bool operator == (const WW8DocumentIterator & rA,
63 const WW8DocumentIterator & rB)
65 return rA.equal(rB);
68 WW8DocumentIterator::~WW8DocumentIterator()
72 WW8DocumentIteratorImpl::~WW8DocumentIteratorImpl()
76 WW8DocumentIterator & WW8DocumentIteratorImpl::operator++()
78 mCpAndFc = mpDocument->getNextCp(mCpAndFc);
80 return *this;
83 WW8DocumentIterator & WW8DocumentIteratorImpl::operator--()
85 mCpAndFc = mpDocument->getPrevCp(mCpAndFc);
87 return *this;
90 bool WW8DocumentIteratorImpl::equal(const WW8DocumentIterator & rIt_) const
92 const WW8DocumentIteratorImpl & rIt =
93 dynamic_cast<const WW8DocumentIteratorImpl &>(rIt_);
95 return mCpAndFc == rIt.mCpAndFc && mpDocument == rIt.mpDocument;
98 writerfilter::Reference<Properties>::Pointer_t
99 WW8DocumentIteratorImpl::getProperties() const
101 return mpDocument->getProperties(mCpAndFc);
104 writerfilter::Reference<Stream>::Pointer_t
105 WW8DocumentIteratorImpl::getSubDocument() const
107 return mpDocument->getSubDocument(mCpAndFc);
110 WW8Stream::Sequence WW8DocumentIteratorImpl::getText()
112 return mpDocument->getText(mCpAndFc);
115 writerfilter::Reference<Properties>::Pointer_t
116 WW8DocumentIteratorImpl::getShape() const
118 return mpDocument->getShape(mCpAndFc);
121 PropertyType WW8DocumentIteratorImpl::getPropertyType() const
123 return mCpAndFc.getType();
126 bool WW8DocumentIteratorImpl::isComplex() const
128 return mCpAndFc.isComplex();
131 void WW8DocumentIteratorImpl::dump(ostream & o) const
133 o << mCpAndFc;
136 string WW8DocumentIteratorImpl::toString() const
138 return mCpAndFc.toString();
141 // WW8DocumentImpl
143 WW8Document::~WW8Document()
147 #if OSL_DEBUG_LEVEL > 1
148 class WW8IdToString : public IdToString
150 public:
151 WW8IdToString() : IdToString() {}
152 virtual ~WW8IdToString() {}
154 virtual string toString(const Id & rId) const
156 string s((*SprmIdToString::Instance())(rId));
158 if (s.empty())
159 s = (*QNameToString::Instance())(rId);
161 return s;
164 #endif
166 WW8DocumentImpl::~WW8DocumentImpl()
170 WW8DocumentImpl::WW8DocumentImpl(WW8Stream::Pointer_t rpStream)
171 : bSubDocument(false), mfcPicLoc(0), mbPicIsData(false), mpStream(rpStream),
172 mbInSection(false), mbInParagraphGroup(false), mbInCharacterGroup(false)
174 mpDocStream = getSubStream("WordDocument");
176 mpSummaryInformationStream = getSubStream("\5SummaryInformation");
180 mpDataStream = getSubStream("Data");
182 catch (const ExceptionNotFound &)
188 mpCompObjStream = getSubStream("\1CompObj");
190 catch (const ExceptionNotFound &)
194 mpCHPFKPCache =
195 WW8FKPCache::Pointer_t(new WW8CHPFKPCacheImpl(mpDocStream, 5));
196 mpPAPFKPCache =
197 WW8FKPCache::Pointer_t(new WW8PAPFKPCacheImpl(mpDocStream, 5));
199 mpFib = WW8Fib::Pointer_t(new WW8Fib(*mpDocStream));
201 switch (mpFib->get_fWhichTblStm())
203 case 0:
204 mpTableStream = getSubStream("0Table");
206 break;
208 case 1:
209 mpTableStream = getSubStream("1Table");
211 break;
213 default:
214 break;
217 if (mpFib->get_nFib() >= 0xD9)
219 mpFibRgFcLcb2000.reset(new WW8FibRgFcLcb2000(*mpFib));
222 if (mpTableStream.get() == NULL)
223 throw ExceptionNotFound("Table stream not found.");
225 mpPieceTable =
226 WW8PieceTable::Pointer_t
227 (new WW8PieceTableImpl(*mpTableStream, mpFib->get_fcClx(),
228 mpFib->get_lcbClx()));
231 Cp aCp(mpPieceTable->getLastCp());
232 Fc aFc(mpPieceTable->getLastFc());
233 CpAndFc aCpAndFc(aCp, aFc, PROP_DOC);
234 mCpAndFcs.insert(aCpAndFc);
238 Cp aCp(mpFib->get_ccpText());
240 mDocumentEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
241 PROP_DOC);
242 mCpAndFcs.insert(mDocumentEndCpAndFc);
244 aCp += mpFib->get_ccpFtn();
245 mFootnoteEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
246 PROP_DOC);
247 mCpAndFcs.insert(mFootnoteEndCpAndFc);
249 aCp += mpFib->get_ccpHdd();
250 mHeaderEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
251 PROP_DOC);
252 mCpAndFcs.insert(mHeaderEndCpAndFc);
254 aCp += mpFib->get_ccpAtn();
255 mAnnotationEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
256 PROP_DOC);
257 mCpAndFcs.insert(mAnnotationEndCpAndFc);
259 aCp += mpFib->get_ccpEdn();
260 mEndnoteEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
261 PROP_DOC);
262 mCpAndFcs.insert(mEndnoteEndCpAndFc);
264 aCp += mpFib->get_ccpTxbx();
265 mTextboxEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
266 PROP_DOC);
267 mCpAndFcs.insert(mTextboxEndCpAndFc);
269 aCp += mpFib->get_ccpHdrTxbx();
270 mTextboxHeaderEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
271 PROP_DOC);
272 mCpAndFcs.insert(mTextboxHeaderEndCpAndFc);
275 mpBinTablePAPX =
276 WW8BinTable::Pointer_t(new WW8BinTableImpl
277 (*mpTableStream,
278 mpFib->get_fcPlcfbtePapx(),
279 mpFib->get_lcbPlcfbtePapx()));
281 //clog << "BinTable(PAP):" << mpBinTablePAPX->toString();
283 parseBinTableCpAndFcs(*mpBinTablePAPX, PROP_PAP);
285 mpBinTableCHPX =
286 WW8BinTable::Pointer_t(new WW8BinTableImpl
287 (*mpTableStream,
288 mpFib->get_fcPlcfbteChpx(),
289 mpFib->get_lcbPlcfbteChpx()));
291 parseBinTableCpAndFcs(*mpBinTableCHPX, PROP_CHP);
293 mpSEDs = PLCF<WW8SED>::Pointer_t(new PLCF<WW8SED>
294 (*mpTableStream,
295 mpFib->get_fcPlcfsed(),
296 mpFib->get_lcbPlcfsed()));
299 PLCFHelper<WW8SED>::processPLCFCpAndFcs
300 (*this, mpPieceTable, mpSEDs, PROP_SEC, 0);
303 sal_uInt32 nHeaders = getHeaderCount();
305 if (nHeaders > 0)
307 mpHeaderOffsets = WW8StructBase::Pointer_t
308 (new WW8StructBase(*mpTableStream,
309 mpFib->get_fcPlcfhdd(),
310 mpFib->get_lcbPlcfhdd()));
313 for (sal_uInt32 n = 0; n <= nHeaders; ++n)
315 CpAndFc aCpAndFc(getHeaderCpAndFc(n));
317 mCpAndFcs.insert(aCpAndFc);
322 if (mpFib->get_lcbPlcffndTxt() > 0)
324 WW8StructBase::Pointer_t pCps
325 (new WW8StructBase(*mpTableStream,
326 mpFib->get_fcPlcffndTxt(),
327 mpFib->get_lcbPlcffndTxt()));
329 PLCF<WW8FRD>::Pointer_t pRefs
330 (new PLCF<WW8FRD>(*mpTableStream,
331 mpFib->get_fcPlcffndRef(),
332 mpFib->get_lcbPlcffndRef()));
334 mpFootnoteHelper = XNoteHelper<WW8FRD>::Pointer_t
335 (new XNoteHelper<WW8FRD>(pCps, pRefs, mpPieceTable, this,
336 PROP_FOOTNOTE, getDocumentEndCp()));
338 mpFootnoteHelper->init();
341 if (mpFib->get_lcbPlcfendTxt() > 0)
343 WW8StructBase::Pointer_t pCps
344 (new WW8StructBase(*mpTableStream,
345 mpFib->get_fcPlcfendTxt(),
346 mpFib->get_lcbPlcfendTxt()));
348 PLCF<WW8FRD>::Pointer_t pRefs
349 (new PLCF<WW8FRD>(*mpTableStream,
350 mpFib->get_fcPlcfendRef(),
351 mpFib->get_lcbPlcfendRef()));
353 mpEndnoteHelper = XNoteHelper<WW8FRD>::Pointer_t
354 (new XNoteHelper<WW8FRD>(pCps, pRefs, mpPieceTable, this,
355 PROP_ENDNOTE, getAnnotationEndCp()));
357 mpEndnoteHelper->init();
360 if (mpFib->get_lcbPlcfandTxt() > 0)
362 WW8StructBase::Pointer_t pCps
363 (new WW8StructBase(*mpTableStream,
364 mpFib->get_fcPlcfandTxt(),
365 mpFib->get_lcbPlcfandTxt()));
367 PLCF<WW8ATRD>::Pointer_t pRefs
368 (new PLCF<WW8ATRD>(*mpTableStream,
369 mpFib->get_fcPlcfandRef(),
370 mpFib->get_lcbPlcfandRef()));
372 mpAnnotationHelper = XNoteHelper<WW8ATRD>::Pointer_t
373 (new XNoteHelper<WW8ATRD>(pCps, pRefs, mpPieceTable, this,
374 PROP_ANNOTATION, getHeaderEndCp()));
376 mpAnnotationHelper->init();
379 if (mpFib->get_lcbSttbfbkmk() > 0)
381 PLCF<WW8BKF>::Pointer_t pStartCps
382 (new PLCF<WW8BKF>(*mpTableStream, mpFib->get_fcPlcfbkf(),
383 mpFib->get_lcbPlcfbkf()));
385 WW8StructBase::Pointer_t pEndCps
386 (new WW8StructBase(*mpTableStream, mpFib->get_fcPlcfbkl(),
387 mpFib->get_lcbPlcfbkl()));
389 WW8Sttbf::Pointer_t pNames
390 (new WW8Sttbf(*mpTableStream, mpFib->get_fcSttbfbkmk(),
391 mpFib->get_lcbSttbfbkmk()));
393 mpBookmarkHelper = BookmarkHelper::Pointer_t
394 (new BookmarkHelper(pStartCps, pEndCps, pNames, mpPieceTable, this));
396 mpBookmarkHelper->init();
400 PLCF<WW8FLD>::Pointer_t pPlcffldMom;
402 if (mpFib->get_lcbPlcffldMom() > 0)
404 pPlcffldMom = PLCF<WW8FLD>::Pointer_t
405 (new PLCF<WW8FLD>(*mpTableStream,
406 mpFib->get_fcPlcffldMom(),
407 mpFib->get_lcbPlcffldMom()));
409 mpFieldHelper = FieldHelper::Pointer_t
410 (new FieldHelper(pPlcffldMom,
411 this));
413 mpFieldHelper->init();
417 PLCF<WW8FSPA>::Pointer_t pPlcspaMom;
418 if (mpFib->get_lcbPlcspaMom() > 0)
420 pPlcspaMom = PLCF<WW8FSPA>::Pointer_t
421 (new PLCF<WW8FSPA>
422 (*mpTableStream, mpFib->get_fcPlcspaMom(),
423 mpFib->get_lcbPlcspaMom()));
426 PLCF<WW8FSPA>::Pointer_t pPlcspaHdr;
427 if (mpFib->get_lcbPlcspaHdr() > 0)
429 pPlcspaHdr = PLCF<WW8FSPA>::Pointer_t
430 (new PLCF<WW8FSPA>
431 (*mpTableStream, mpFib->get_fcPlcspaHdr(),
432 mpFib->get_lcbPlcspaHdr()));
435 mpShapeHelper = ShapeHelper::Pointer_t
436 (new ShapeHelper(pPlcspaMom, pPlcspaHdr, this));
438 mpShapeHelper->init();
440 PLCF<WW8BKD>::Pointer_t pPlcbkdMother;
441 if (mpFib->get_fcBkdMother() > 0 && mpFib->get_lcbBkdMother() > 0)
443 pPlcbkdMother = PLCF<WW8BKD>::Pointer_t
444 (new PLCF<WW8BKD>
445 (*mpTableStream, mpFib->get_fcBkdMother(),
446 mpFib->get_lcbBkdMother()));
449 mpBreakHelper = BreakHelper::Pointer_t
450 (new BreakHelper(pPlcbkdMother, this));
452 mpBreakHelper->init();
454 if (mpFib->get_fcDggInfo() != 0 && mpFib->get_lcbDggInfo() > 0)
456 mpDffBlock = DffBlock::Pointer_t
457 (new DffBlock(*mpTableStream, mpFib->get_fcDggInfo(),
458 mpFib->get_lcbDggInfo(), 1));
460 mpDffBlock->setDocument(this);
463 if (mpFib->get_lcbPlcftxbxTxt() > 0)
465 mpTextBoxStories = PLCF<WW8FTXBXS>::Pointer_t
466 (new PLCF<WW8FTXBXS>(*mpTableStream,
467 mpFib->get_fcPlcftxbxTxt(),
468 mpFib->get_lcbPlcftxbxTxt()));
470 PLCFHelper<WW8FTXBXS>::processPLCFCpAndFcs
471 (*this, mpPieceTable, mpTextBoxStories, PROP_DOC,
472 mEndnoteEndCpAndFc.getCp().get());
475 if (mCpAndFcs.size() > 0)
477 mCpAndFcStart = *mCpAndFcs.begin();
478 mCpAndFcEnd = getDocumentEndCp();
482 bool WW8DocumentImpl::isSpecial(sal_uInt32 nChar)
484 bool bResult = false;
486 if (nChar <= 8)
487 bResult = true;
488 else if (nChar >= 10)
490 if (nChar == 12)
491 bResult= true;
492 else if (nChar <= 16)
493 bResult = true;
494 else if (nChar >= 22)
496 if (nChar <= 30)
497 bResult = true;
498 else if (nChar >= 33)
500 if (nChar <= 39)
501 bResult = true;
502 else if (nChar == 41)
503 bResult = true;
508 return bResult;
511 WW8DocumentImpl::WW8DocumentImpl(const WW8DocumentImpl & rSrc,
512 const CpAndFc & rStart, const CpAndFc & rEnd)
513 : bSubDocument(true), mfcPicLoc(0), mbPicIsData(false)
515 Assign(rSrc);
517 mCpAndFcStart = rStart;
518 mCpAndFcEnd = rEnd;
521 WW8DocumentImpl & WW8DocumentImpl::Assign(const WW8DocumentImpl & rSrc)
523 mCpAndFcs = rSrc.mCpAndFcs;
525 mpCHPFKPCache = rSrc.mpCHPFKPCache;
526 mpPAPFKPCache = rSrc.mpPAPFKPCache;
528 mpStream = rSrc.mpStream;
529 mpTableStream = rSrc.mpTableStream;
530 mpDataStream = rSrc.mpDataStream;
531 mpDocStream = rSrc.mpDocStream;
532 mpCompObjStream = rSrc.mpCompObjStream;
534 mpPieceTable = rSrc.mpPieceTable;
536 mpBinTableCHPX = rSrc.mpBinTableCHPX;
537 mpBinTablePAPX = rSrc.mpBinTablePAPX;
539 mpSEDs = rSrc.mpSEDs;
541 mpFib = rSrc.mpFib;
543 mpHeaderOffsets = rSrc.mpHeaderOffsets;
544 mpFootnoteHelper = rSrc.mpFootnoteHelper;
545 mpEndnoteHelper = rSrc.mpEndnoteHelper;
546 mpAnnotationHelper = rSrc.mpAnnotationHelper;
547 mpShapeHelper = rSrc.mpShapeHelper;
548 mpBreakHelper = rSrc.mpBreakHelper;
550 mpBookmarkHelper = rSrc.mpBookmarkHelper;
552 mpDffBlock = rSrc.mpDffBlock;
553 mpTextBoxStories = rSrc.mpTextBoxStories;
555 mDocumentEndCpAndFc = rSrc.mDocumentEndCpAndFc;
556 mFootnoteEndCpAndFc = rSrc.mFootnoteEndCpAndFc;
558 return *this;
561 string WW8DocumentImpl::getType() const
563 return "WW8DocumentImpl";
566 void WW8DocumentImpl::parseBinTableCpAndFcs(WW8BinTable & rTable,
567 PropertyType eType_)
569 for (sal_uInt32 i = 0; i < rTable.getEntryCount(); i++)
571 Fc aFcFromTable(rTable.getFc(i));
573 if (aFcFromTable < mpPieceTable->getFirstFc())
574 aFcFromTable = mpPieceTable->getFirstFc();
576 bool bComplex = mpPieceTable->isComplex(aFcFromTable);
577 aFcFromTable.setComplex(bComplex);
581 Cp aCpFromTable(mpPieceTable->fc2cp(aFcFromTable));
582 CpAndFc aCpAndFcFromTable(aCpFromTable, aFcFromTable, eType_);
584 mCpAndFcs.insert(aCpAndFcFromTable);
586 WW8FKP::Pointer_t pFKP;
588 switch (eType_)
590 case PROP_CHP:
591 pFKP = getFKPCHPX(rTable.getPageNumber(i),
592 aCpAndFcFromTable.isComplex());
594 break;
596 case PROP_PAP:
597 pFKP = getFKPPAPX(rTable.getPageNumber(i),
598 aCpAndFcFromTable.isComplex());
600 break;
601 default:
602 break;
605 for (sal_uInt32 n = 0; n < pFKP->getEntryCount(); n++)
607 Fc aFc = pFKP->getFc(n);
609 if (aFc < mpPieceTable->getFirstFc())
610 aFc = mpPieceTable->getFirstFc();
612 bool bComplexFKP = mpPieceTable->isComplex(aFc);
613 aFc.setComplex(bComplexFKP);
617 Cp aCp = mpPieceTable->fc2cp(aFc);
619 CpAndFc aCpAndFc(aCp, aFc, eType_);
621 mCpAndFcs.insert(aCpAndFc);
623 catch (const ExceptionNotFound &e)
625 clog << e.getText() << endl;
629 catch (const ExceptionNotFound &e)
631 clog << e.getText() << endl;
636 WW8Stream::Pointer_t WW8DocumentImpl::getSubStream
637 (const OUString & sId) const
639 return mpStream->getSubStream(sId);
642 WW8Document::Pointer_t WW8DocumentImpl::getSubDocument(SubDocumentId /*nId*/)
644 return WW8Document::Pointer_t(new WW8DocumentImpl(*this));
647 WW8DocumentIterator::Pointer_t
648 WW8DocumentImpl::getIterator(const CpAndFc & rCpAndFc)
650 return WW8DocumentIterator::Pointer_t
651 (new WW8DocumentIteratorImpl(this, rCpAndFc));
654 WW8DocumentIterator::Pointer_t WW8DocumentImpl::begin()
656 return getIterator(getFirstCp());
659 WW8DocumentIterator::Pointer_t WW8DocumentImpl::end()
661 return getIterator(getLastCp());
664 WW8Stream::Pointer_t WW8DocumentImpl::getDocStream() const
666 return mpDocStream;
669 WW8Stream::Pointer_t WW8DocumentImpl::getDataStream() const
671 return mpDataStream;
674 sal_uInt32 WW8DocumentImpl::getByteLength(const CpAndFc & rCpAndFc) const
676 CpAndFc aEnd = getNextCp(rCpAndFc);
678 sal_uInt32 nResult = 3;
680 if (rCpAndFc < aEnd)
681 nResult = (aEnd - rCpAndFc) *
682 (mpPieceTable->isComplex(rCpAndFc.getCp()) ? 1 : 2);
684 return nResult;
687 WW8Stream::Sequence
688 WW8DocumentImpl::getText(const CpAndFc & rStart)
690 return mpDocStream->get(rStart.getFc().get(), getByteLength(rStart));
693 const CpAndFc & WW8DocumentImpl::getFirstCp() const
695 return mCpAndFcStart;
698 const CpAndFc & WW8DocumentImpl::getLastCp() const
700 return mCpAndFcEnd;
703 CpAndFc WW8DocumentImpl::getDocumentEndCp() const
705 return mDocumentEndCpAndFc;
708 CpAndFc WW8DocumentImpl::getFootnodeEndCp() const
710 return mFootnoteEndCpAndFc;
713 CpAndFc WW8DocumentImpl::getHeaderEndCp() const
715 return mHeaderEndCpAndFc;
718 CpAndFc WW8DocumentImpl::getAnnotationEndCp() const
720 return mAnnotationEndCpAndFc;
723 CpAndFc WW8DocumentImpl::getEndnoteEndCp() const
725 return mEndnoteEndCpAndFc;
728 CpAndFc WW8DocumentImpl::getNextCp(const CpAndFc & rCpAndFc) const
730 CpAndFc aResult = mCpAndFcEnd;
731 CpAndFcs::const_iterator aIt = mCpAndFcs.find(rCpAndFc);
733 if (aIt != mCpAndFcs.end())
735 ++aIt;
737 if (aIt != mCpAndFcs.end())
738 aResult = *aIt;
740 else
741 throw ExceptionNotFound("getNextCp: " + rCpAndFc.toString());
743 return aResult;
746 CpAndFc WW8DocumentImpl::getPrevCp(const CpAndFc & rCpAndFc) const
748 CpAndFc aResult = mCpAndFcStart;
750 CpAndFcs::const_iterator aIt = mCpAndFcs.find(CpAndFc(rCpAndFc));
752 if (aIt != mCpAndFcs.end() && aIt != mCpAndFcs.begin())
754 --aIt;
756 aResult = *aIt;
758 else
759 throw ExceptionNotFound("getPrevCp: " + rCpAndFc.toString());
761 return aResult;
764 WW8FKP::Pointer_t WW8DocumentImpl::getFKP(const CpAndFc & rCpAndFc)
766 WW8FKP::Pointer_t pResult;
768 sal_uInt32 nPageNumber = 0;
770 switch (rCpAndFc.getType())
772 case PROP_PAP:
774 nPageNumber =
775 mpBinTablePAPX->getPageNumber(rCpAndFc.getFc());
777 pResult = getFKPPAPX(nPageNumber, rCpAndFc.isComplex());
779 break;
780 case PROP_CHP:
782 nPageNumber =
783 mpBinTableCHPX->getPageNumber(rCpAndFc.getFc());
785 pResult = getFKPCHPX(nPageNumber, rCpAndFc.isComplex());
787 break;
788 default:
789 break;
792 if (pResult.get() != NULL)
793 pResult->setDocument(this);
795 return pResult;
798 WW8FKP::Pointer_t WW8DocumentImpl::getFKPCHPX(sal_uInt32 nIndex,
799 bool bComplex)
801 return mpCHPFKPCache->get(nIndex, bComplex);
804 WW8FKP::Pointer_t WW8DocumentImpl::getFKPPAPX(sal_uInt32 nIndex,
805 bool bComplex)
807 return mpPAPFKPCache->get(nIndex, bComplex);
810 writerfilter::Reference<Properties>::Pointer_t WW8DocumentImpl::getProperties
811 (const CpAndFc & rCpAndFc)
813 writerfilter::Reference<Properties>::Pointer_t pResult;
815 switch (rCpAndFc.getType())
817 case PROP_CHP:
818 case PROP_PAP:
822 WW8FKP::Pointer_t pFKP = getFKP(rCpAndFc);
824 pResult = pFKP->getProperties(rCpAndFc.getFc());
826 catch (const ExceptionOutOfBounds &)
831 break;
833 case PROP_SEC:
835 pResult = writerfilter::Reference<Properties>::Pointer_t
836 (getSED(rCpAndFc));
839 break;
841 case PROP_FOOTNOTE:
843 pResult = writerfilter::Reference<Properties>::Pointer_t
844 (mpFootnoteHelper->getRef(rCpAndFc));
846 break;
848 case PROP_ENDNOTE:
850 pResult = writerfilter::Reference<Properties>::Pointer_t
851 (mpEndnoteHelper->getRef(rCpAndFc));
853 break;
855 case PROP_ANNOTATION:
857 pResult = writerfilter::Reference<Properties>::Pointer_t
858 (mpAnnotationHelper->getRef(rCpAndFc));
860 break;
862 case PROP_BOOKMARKSTART:
863 case PROP_BOOKMARKEND:
865 pResult = getBookmark(rCpAndFc);
868 break;
869 case PROP_FLD:
871 pResult = getField(rCpAndFc);
873 mpFLD = mpFieldHelper->getWW8FLD(rCpAndFc);
876 break;
877 case PROP_SHP:
879 pResult = getShape(rCpAndFc);
881 break;
882 case PROP_BRK:
884 pResult = getBreak(rCpAndFc);
886 break;
887 default:
888 break;
891 return pResult;
894 writerfilter::Reference<Stream>::Pointer_t
895 WW8DocumentImpl::getSubDocument(const CpAndFc & rCpAndFc)
897 writerfilter::Reference<Stream>::Pointer_t pResult;
899 switch (rCpAndFc.getType())
901 case PROP_FOOTNOTE:
902 pResult = getFootnote(rCpAndFc);
903 break;
905 case PROP_ENDNOTE:
906 pResult = getEndnote(rCpAndFc);
907 break;
909 case PROP_ANNOTATION:
910 pResult = getAnnotation(rCpAndFc);
911 break;
913 default:
914 break;
917 return pResult;
920 WW8SED * WW8DocumentImpl::getSED(const CpAndFc & rCpAndFc) const
922 WW8SED * pResult = mpSEDs->getEntryByFc(rCpAndFc.getCp().get());
924 pResult->setDoc(const_cast<const WW8DocumentImpl *>(this));
926 return pResult;
929 writerfilter::Reference<Table>::Pointer_t WW8DocumentImpl::getListTplcs() const
931 writerfilter::Reference<Table>::Pointer_t pResult;
933 if (mpFibRgFcLcb2000.get() != NULL &&
934 mpFibRgFcLcb2000->get_fcSttbRgtplc() != 0 &&
935 mpFibRgFcLcb2000->get_lcbSttbRgtplc() != 0)
937 WW8SttbRgtplc * pSttbRgtplc =
938 new WW8SttbRgtplc(*mpTableStream,
939 mpFibRgFcLcb2000->get_fcSttbRgtplc(),
940 mpFibRgFcLcb2000->get_lcbSttbRgtplc());
942 pResult = writerfilter::Reference<Table>::Pointer_t(pSttbRgtplc);
945 return pResult;
948 writerfilter::Reference<Table>::Pointer_t WW8DocumentImpl::getListTable() const
950 writerfilter::Reference<Table>::Pointer_t pResult;
952 if (mpFib->get_fcPlcfLst() != 0 && mpFib->get_lcbPlcfLst() > 0)
956 WW8ListTable * pList = new WW8ListTable(*mpTableStream,
957 mpFib->get_fcPlcfLst(),
958 mpFib->get_fcPlfLfo() -
959 mpFib->get_fcPlcfLst());
961 pList->setPayloadOffset(mpFib->get_lcbPlcfLst());
962 pList->initPayload();
964 pResult = writerfilter::Reference<Table>::Pointer_t(pList);
966 catch (const ExceptionOutOfBounds &) {
970 return pResult;
973 writerfilter::Reference<Table>::Pointer_t WW8DocumentImpl::getLFOTable() const
975 writerfilter::Reference<Table>::Pointer_t pResult;
977 if (mpFib->get_fcPlfLfo() != 0 && mpFib->get_lcbPlfLfo() > 0)
981 WW8LFOTable * pLFOs = new WW8LFOTable(*mpTableStream,
982 mpFib->get_fcPlfLfo(),
983 mpFib->get_lcbPlfLfo());
985 pLFOs->setPayloadOffset(mpFib->get_lcbPlcfLst());
986 pLFOs->initPayload();
988 pResult = writerfilter::Reference<Table>::Pointer_t(pLFOs);
990 catch (const Exception &e)
992 clog << e.getText() << endl;
996 return pResult;
999 writerfilter::Reference<Table>::Pointer_t WW8DocumentImpl::getFontTable() const
1001 writerfilter::Reference<Table>::Pointer_t pResult;
1003 if (mpFib->get_fcSttbfffn() != 0 && mpFib->get_lcbSttbfffn() > 0)
1005 WW8FontTable * pFonts = new WW8FontTable(*mpTableStream,
1006 mpFib->get_fcSttbfffn(),
1007 mpFib->get_lcbSttbfffn());
1009 pFonts->initPayload();
1011 pResult = writerfilter::Reference<Table>::Pointer_t(pFonts);
1014 return pResult;
1017 writerfilter::Reference<Table>::Pointer_t WW8DocumentImpl::getStyleSheet() const
1019 writerfilter::Reference<Table>::Pointer_t pResult;
1021 if (mpFib->get_lcbStshf() > 0)
1023 WW8StyleSheet * pStyles = new WW8StyleSheet(*mpTableStream,
1024 mpFib->get_fcStshf(),
1025 mpFib->get_lcbStshf());
1027 pStyles->initPayload();
1029 pResult = writerfilter::Reference<Table>::Pointer_t(pStyles);
1032 return pResult;
1035 writerfilter::Reference<Table>::Pointer_t WW8DocumentImpl::getAssocTable() const
1037 writerfilter::Reference<Table>::Pointer_t pResult;
1039 if (mpFib->get_lcbSttbfAssoc() > 0)
1041 WW8Sttbf::Pointer_t pSttbfAssoc
1042 (new WW8Sttbf(*mpTableStream,
1043 mpFib->get_fcSttbfAssoc(),
1044 mpFib->get_lcbSttbfAssoc()));
1046 pResult = writerfilter::Reference<Table>::Pointer_t
1047 (new WW8SttbTableResource(pSttbfAssoc));
1050 return pResult;
1053 sal_uInt32 WW8DocumentImpl::getHeaderCount() const
1055 sal_uInt32 nResult = 0;
1056 sal_uInt32 nLcbPlcfhdd = mpFib->get_lcbPlcfhdd();
1058 if (nLcbPlcfhdd > 4)
1059 nResult = (nLcbPlcfhdd / 4) - 1;
1061 return nResult;
1064 CpAndFc WW8DocumentImpl::getHeaderCpAndFc(sal_uInt32 nPos)
1066 sal_uInt32 nCount = getHeaderCount();
1068 // There are getHeaderCount() + 1 entries in mpHeaderOffsets => greater
1069 if (nPos > nCount)
1070 throw ExceptionNotFound("getHeaderCpAndFc");
1072 if (nPos == nCount)
1073 return mHeaderEndCpAndFc;
1074 else
1076 Cp aCp(getFootnodeEndCp().getCp() + mpHeaderOffsets->getU32(nPos * 4));
1077 Fc aFc(mpPieceTable->cp2fc(aCp));
1078 CpAndFc aCpAndFc(aCp, aFc, PROP_DOC);
1080 return aCpAndFc;
1085 writerfilter::Reference<Stream>::Pointer_t WW8DocumentImpl::getHeader(sal_uInt32 nPos)
1087 // There are getHeaderCount() headers => greater or equal
1088 if (nPos >= getHeaderCount())
1089 throw ExceptionNotFound("getHeader");
1091 writerfilter::Reference<Stream>::Pointer_t pResult;
1093 CpAndFc aCpAndFcStart(getHeaderCpAndFc(nPos));
1094 CpAndFc aCpAndFcEnd(getHeaderCpAndFc(nPos + 1));
1096 if (aCpAndFcStart < aCpAndFcEnd)
1097 pResult = writerfilter::Reference<Stream>::Pointer_t
1098 (new WW8DocumentImpl(*this, aCpAndFcStart, aCpAndFcEnd));
1100 return pResult;
1103 writerfilter::Reference<Stream>::Pointer_t
1104 WW8DocumentImpl::getFootnote(const CpAndFc & rCpAndFc)
1106 writerfilter::Reference<Stream>::Pointer_t pResult;
1108 if (! bSubDocument)
1109 pResult = mpFootnoteHelper->get(rCpAndFc);
1111 return pResult;
1114 writerfilter::Reference<Stream>::Pointer_t
1115 WW8DocumentImpl::getEndnote(const CpAndFc & rCpAndFc)
1117 writerfilter::Reference<Stream>::Pointer_t pResult;
1119 if (! bSubDocument)
1120 pResult = mpEndnoteHelper->get(rCpAndFc);
1122 return pResult;
1126 writerfilter::Reference<Stream>::Pointer_t
1127 WW8DocumentImpl::getAnnotation(const CpAndFc & rCpAndFc)
1129 writerfilter::Reference<Stream>::Pointer_t pResult;
1131 if (! bSubDocument)
1132 pResult = mpAnnotationHelper->get(rCpAndFc);
1134 return pResult;
1137 writerfilter::Reference<Properties>::Pointer_t
1138 WW8DocumentImpl::getBookmark(const CpAndFc & rCpAndFc) const
1140 return mpBookmarkHelper->getBookmark(rCpAndFc);
1143 writerfilter::Reference<Properties>::Pointer_t
1144 WW8DocumentImpl::getShape(const CpAndFc & rCpAndFc) const
1146 return mpShapeHelper->getShape(rCpAndFc);
1149 writerfilter::Reference<Properties>::Pointer_t
1150 WW8DocumentImpl::getShape(sal_uInt32 nSpid)
1152 writerfilter::Reference<Properties>::Pointer_t pResult;
1153 DffRecord::Pointer_t pShape = mpDffBlock->getShape(nSpid);
1155 if (pShape.get() != NULL)
1157 DffSpContainer * pTmp = new DffSpContainer(*pShape);
1158 pTmp->setDocument(this);
1160 pResult = writerfilter::Reference<Properties>::Pointer_t(pTmp);
1163 return pResult;
1166 writerfilter::Reference<Properties>::Pointer_t
1167 WW8DocumentImpl::getBreak(const CpAndFc & rCpAndFc) const
1169 return mpBreakHelper->getBreak(rCpAndFc);
1172 writerfilter::Reference<Properties>::Pointer_t
1173 WW8DocumentImpl::getBlip(sal_uInt32 nBid)
1175 writerfilter::Reference<Properties>::Pointer_t pResult;
1177 if (mpDffBlock != NULL)
1179 DffRecord::Pointer_t pDffRecord(mpDffBlock->getBlip(nBid));
1181 if (pDffRecord.get() != NULL)
1183 DffBSE * pBlip = new DffBSE(*pDffRecord);
1185 if (pBlip != NULL)
1186 pResult = writerfilter::Reference<Properties>::Pointer_t(pBlip);
1190 return pResult;
1193 writerfilter::Reference<Properties>::Pointer_t
1194 WW8DocumentImpl::getField(const CpAndFc & rCpAndFc) const
1196 return mpFieldHelper->getField(rCpAndFc);
1199 writerfilter::Reference<Properties>::Pointer_t
1200 WW8DocumentImpl::getDocumentProperties() const
1202 writerfilter::Reference<Properties>::Pointer_t pResult;
1204 if (mpFib->get_lcbDop() > 0)
1206 pResult.reset(new WW8DopBase(*mpTableStream, mpFib->get_fcDop(), mpFib->get_lcbDop()));
1209 return pResult;
1212 WW8FLD::Pointer_t WW8DocumentImpl::getCurrentFLD() const
1214 return mpFLD;
1217 void WW8DocumentImpl::setPicLocation(sal_uInt32 fcPicLoc)
1219 mfcPicLoc = fcPicLoc;
1222 bool WW8DocumentImpl::isPicData()
1224 return mbPicIsData;
1227 void WW8DocumentImpl::setPicIsData(bool bPicIsData)
1229 mbPicIsData = bPicIsData;
1232 writerfilter::Reference<Stream>::Pointer_t
1233 WW8DocumentImpl::getTextboxText(sal_uInt32 nShpId) const
1235 writerfilter::Reference<Stream>::Pointer_t pResult;
1237 if (mpTextBoxStories.get() != NULL)
1239 sal_uInt32 nCount = mpTextBoxStories->getEntryCount();
1241 sal_uInt32 n = 0;
1242 while (n < nCount)
1244 WW8FTXBXS * pTextboxStory = mpTextBoxStories->getEntryPointer(n);
1246 if (pTextboxStory->get_lid() == nShpId)
1247 break;
1249 ++n;
1252 if (n < nCount)
1254 Cp aCpStart(mpTextBoxStories->getFc(n));
1255 aCpStart += getEndnoteEndCp().getCp().get();
1256 CpAndFc aCpAndFcStart =
1257 mpPieceTable->createCpAndFc(aCpStart, PROP_DOC);
1258 Cp aCpEnd(mpTextBoxStories->getFc(n + 1));
1259 aCpEnd += getEndnoteEndCp().getCp().get();
1260 CpAndFc aCpAndFcEnd = mpPieceTable->createCpAndFc(aCpEnd, PROP_DOC);
1262 pResult = writerfilter::Reference<Stream>::Pointer_t
1263 (new WW8DocumentImpl(*this, aCpAndFcStart, aCpAndFcEnd));
1267 return pResult;
1270 Id lcl_headerQName(sal_uInt32 nIndex)
1272 Id qName = NS_rtf::LN_header;
1274 if (nIndex > 5)
1276 switch ((nIndex - 6) % 6)
1278 case 0:
1279 qName = NS_rtf::LN_headerl;
1281 break;
1282 case 1:
1283 qName = NS_rtf::LN_headerr;
1285 break;
1286 case 2:
1287 qName = NS_rtf::LN_footerl;
1289 break;
1290 case 3:
1291 qName = NS_rtf::LN_footerr;
1293 break;
1294 case 4:
1295 qName = NS_rtf::LN_headerf;
1297 break;
1298 case 5:
1299 qName = NS_rtf::LN_footerf;
1301 break;
1305 return qName;
1308 Fc WW8DocumentImpl::cp2fc(const Cp & cp) const
1310 return mpPieceTable->cp2fc(cp);
1313 CpAndFc WW8DocumentImpl::getCpAndFc(const Cp & cp, PropertyType type) const
1315 Fc aFc = cp2fc(cp);
1317 return CpAndFc(cp, aFc, type);
1320 void WW8DocumentImpl::resolvePicture(Stream & rStream)
1322 WW8Stream::Pointer_t pStream = getDataStream();
1324 if (pStream.get() != NULL)
1326 WW8StructBase aStruct(*pStream, mfcPicLoc, 4);
1327 sal_uInt32 nCount = aStruct.getU32(0);
1330 WW8PICF * pPicf = new WW8PICF(*pStream, mfcPicLoc, nCount);
1331 pPicf->setDocument(this);
1333 writerfilter::Reference<Properties>::Pointer_t pProps(pPicf);
1335 rStream.props(pProps);
1340 void WW8DocumentImpl::resolveSpecialChar(sal_uInt32 nChar, Stream & rStream)
1342 switch (nChar)
1344 case 0x1:
1345 resolvePicture(rStream);
1346 break;
1347 default:
1348 break;
1352 void WW8DocumentImpl::text(Stream & rStream, const sal_uInt8 * data, size_t len)
1354 #ifdef DEBUG_ELEMENT
1355 OUString sText( (const sal_Char*) data, len, RTL_TEXTENCODING_MS_1252 );
1356 debug_logger->startElement("text");
1357 debug_logger->chars(OUStringToOString(sText, RTL_TEXTENCODING_ASCII_US).getStr());
1358 debug_logger->endElement();
1359 #endif
1360 rStream.text(data, len);
1363 void WW8DocumentImpl::utext(Stream & rStream, const sal_uInt8 * data, size_t len)
1365 #ifdef DEBUG_ELEMENT
1366 debug_logger->startElement("utext");
1368 OUString sText;
1369 OUStringBuffer aBuffer = ::rtl:: OUStringBuffer(len);
1370 aBuffer.append( (const sal_Unicode *) data, len);
1371 sText = aBuffer.makeStringAndClear();
1373 debug_logger->chars(OUStringToOString(sText, RTL_TEXTENCODING_ASCII_US).getStr());
1374 debug_logger->endElement();
1375 #endif
1376 rStream.utext(data, len);
1380 void WW8DocumentImpl::resolveText(WW8DocumentIterator::Pointer_t pIt,
1381 Stream & rStream)
1383 WW8Stream::Sequence aSeq = pIt->getText();
1385 sal_uInt32 nCount = aSeq.getCount();
1386 bool bComplex = pIt->isComplex();
1389 Assumption: Special characters are always at the beginning or end of a
1390 run.
1392 if (nCount > 0)
1394 if (nCount == 1)
1395 bComplex = true;
1397 if (bComplex)
1399 sal_uInt32 nStartIndex = 0;
1400 sal_uInt32 nEndIndex = nCount - 1;
1402 sal_uInt32 nCharFirst = aSeq[0];
1403 sal_uInt32 nCharLast = aSeq[nEndIndex];
1405 if (isSpecial(nCharFirst))
1407 nStartIndex += 1;
1408 resolveSpecialChar(nCharFirst, rStream);
1409 text(rStream, &aSeq[0], 1);
1412 if (!isSpecial(nCharLast))
1413 nEndIndex += 1;
1415 if (nStartIndex < nEndIndex)
1417 sal_uInt32 nChars = nEndIndex - nStartIndex;
1418 text(rStream, &aSeq[nStartIndex], nChars);
1420 if (isSpecial(nCharLast))
1422 resolveSpecialChar(nCharLast, rStream);
1423 text(rStream, &aSeq[nEndIndex], 1);
1427 else
1429 sal_uInt32 nStartIndex = 0;
1430 sal_uInt32 nEndIndex = nCount - 2;
1432 sal_uInt32 nCharFirst = aSeq[0] + (aSeq[1] << 8);
1433 sal_uInt32 nCharLast = aSeq[nEndIndex] + (aSeq[nEndIndex + 1]);
1435 if (isSpecial(nCharFirst))
1437 nStartIndex += 2;
1438 resolveSpecialChar(nCharFirst, rStream);
1439 utext(rStream, &aSeq[0], 1);
1442 if (!isSpecial(nCharLast))
1443 nEndIndex += 2;
1445 if (nStartIndex < nEndIndex)
1447 sal_uInt32 nChars = (nEndIndex - nStartIndex) / 2;
1448 utext(rStream, &aSeq[nStartIndex], nChars);
1450 if (isSpecial(nCharLast))
1452 resolveSpecialChar(nCharLast, rStream);
1453 utext(rStream, &aSeq[nEndIndex], 1);
1460 void WW8DocumentImpl::startCharacterGroup(Stream & rStream)
1462 if (mbInCharacterGroup)
1463 endCharacterGroup(rStream);
1465 #ifdef DEBUG_ELEMENT
1466 debug_logger->startElement("charactergroup");
1467 #endif
1469 rStream.startCharacterGroup();
1470 mbInCharacterGroup = true;
1473 void WW8DocumentImpl::endCharacterGroup(Stream & rStream)
1475 #ifdef DEBUG_ELEMENT
1476 debug_logger->endElement();
1477 #endif
1479 rStream.endCharacterGroup();
1480 mbInCharacterGroup = false;
1483 void WW8DocumentImpl::startParagraphGroup(Stream & rStream)
1485 if (mbInParagraphGroup)
1486 endParagraphGroup(rStream);
1488 #ifdef DEBUG_ELEMENT
1489 debug_logger->startElement("paragraphgroup");
1490 #endif
1492 rStream.startParagraphGroup();
1493 mbInParagraphGroup = true;
1496 void WW8DocumentImpl::endParagraphGroup(Stream & rStream)
1498 if (mbInCharacterGroup)
1499 endCharacterGroup(rStream);
1501 #ifdef DEBUG_ELEMENT
1502 debug_logger->endElement();
1503 #endif
1504 rStream.endParagraphGroup();
1505 mbInParagraphGroup = false;
1508 void WW8DocumentImpl::startSectionGroup(Stream & rStream)
1510 if (mbInSection)
1511 endSectionGroup(rStream);
1513 #ifdef DEBUG_ELEMENT
1514 debug_logger->startElement("sectiongroup");
1515 #endif
1517 rStream.startSectionGroup();
1518 mbInSection = true;
1521 void WW8DocumentImpl::endSectionGroup(Stream & rStream)
1523 if (mbInParagraphGroup)
1524 endParagraphGroup(rStream);
1526 #ifdef DEBUG_ELEMENT
1527 debug_logger->endElement();
1528 #endif
1529 rStream.endSectionGroup();
1530 mbInSection = false;
1533 void WW8DocumentImpl::resolve(Stream & rStream)
1535 if (! bSubDocument)
1537 output.addItem("<substream-names>");
1538 output.addItem(mpStream->getSubStreamNames());
1539 output.addItem("</substream-names>");
1541 if (mpDocStream.get() != NULL)
1543 mpDocStream->dump(output);
1546 if (mpSummaryInformationStream.get() != NULL)
1548 mpSummaryInformationStream->dump(output);
1551 writerfilter::Reference<Properties>::Pointer_t pFib
1552 (new WW8Fib(*mpFib));
1553 rStream.props(pFib);
1555 if (mpFibRgFcLcb2000.get() != NULL)
1557 writerfilter::Reference<Properties>::Pointer_t pFibRgFcLcb2000
1558 (new WW8FibRgFcLcb2000(*mpFibRgFcLcb2000));
1559 rStream.props(pFibRgFcLcb2000);
1562 if (mpFib->get_lcbPlcftxbxBkd() > 0)
1564 PLCF<WW8BKD> aPLCF(*mpTableStream,
1565 mpFib->get_fcPlcftxbxBkd(),
1566 mpFib->get_lcbPlcftxbxBkd());
1569 if (mpDffBlock.get() != NULL)
1571 DffBlock * pTmp = new DffBlock(*mpDffBlock);
1572 writerfilter::Reference<Properties>::Pointer_t pDffBlock =
1573 writerfilter::Reference<Properties>::Pointer_t(pTmp);
1575 rStream.props(pDffBlock);
1579 rStream.info("headers");
1580 sal_uInt32 nHeaderCount = getHeaderCount();
1581 for (sal_uInt32 n = 0; n < nHeaderCount; ++n)
1583 rStream.info(getHeaderCpAndFc(n).toString());
1585 rStream.info("/headers");
1588 writerfilter::Reference<Table>::Pointer_t pSttbRgtplc = getListTplcs();
1590 if (pSttbRgtplc.get() != NULL)
1591 rStream.table(NS_rtf::LN_SttbRgtplc, pSttbRgtplc);
1593 writerfilter::Reference<Table>::Pointer_t pFontTable = getFontTable();
1595 if (pFontTable.get() != NULL)
1596 rStream.table(NS_rtf::LN_FONTTABLE, pFontTable);
1600 writerfilter::Reference<Table>::Pointer_t pStyleSheet = getStyleSheet();
1602 if (pStyleSheet.get() != NULL)
1603 rStream.table(NS_rtf::LN_STYLESHEET, pStyleSheet);
1605 catch (const Exception &e)
1607 clog << e.getText() << endl;
1610 writerfilter::Reference<Table>::Pointer_t pAssocTable = getAssocTable();
1612 if (pAssocTable.get() != NULL)
1613 rStream.table(NS_rtf::LN_SttbAssoc, pAssocTable);
1615 writerfilter::Reference<Table>::Pointer_t pListTable = getListTable();
1617 if (pListTable.get() != NULL)
1618 rStream.table(NS_rtf::LN_LISTTABLE, pListTable);
1620 writerfilter::Reference<Table>::Pointer_t pLFOTable = getLFOTable();
1622 if (pLFOTable.get() != NULL)
1623 rStream.table(NS_rtf::LN_LFOTABLE, pLFOTable);
1626 WW8DocumentIterator::Pointer_t pIt = begin();
1627 WW8DocumentIterator::Pointer_t pItEnd = end();
1629 mbInParagraphGroup = false;
1630 mbInCharacterGroup = false;
1631 mbInSection = false;
1633 sal_uInt32 nSectionIndex = 0;
1635 rStream.info(pIt->toString());
1636 rStream.info(pItEnd->toString());
1638 while (! pIt->equal(*pItEnd))
1640 writerfilter::Reference<Properties>::Pointer_t
1641 pProperties(pIt->getProperties());
1643 switch (pIt->getPropertyType())
1645 case PROP_FOOTNOTE:
1647 rStream.info(pIt->toString());
1648 writerfilter::Reference<Stream>::Pointer_t
1649 pFootnote(pIt->getSubDocument());
1651 if (pFootnote.get() != NULL)
1653 #ifdef DEBUG_ELEMENT
1654 debug_logger->startElement("substream");
1655 #endif
1656 rStream.substream(NS_rtf::LN_footnote, pFootnote);
1657 #ifdef DEBUG_ELEMENT
1658 debug_logger->endElement();
1659 #endif
1662 break;
1663 case PROP_ENDNOTE:
1665 rStream.info(pIt->toString());
1666 writerfilter::Reference<Stream>::Pointer_t
1667 pEndnote(pIt->getSubDocument());
1669 if (pEndnote.get() != NULL)
1671 #ifdef DEBUG_ELEMENT
1672 debug_logger->startElement("substream");
1673 #endif
1674 rStream.substream(NS_rtf::LN_endnote, pEndnote);
1675 #ifdef DEBUG_ELEMENT
1676 debug_logger->endElement();
1677 #endif
1680 break;
1681 case PROP_ANNOTATION:
1683 rStream.info(pIt->toString());
1684 writerfilter::Reference<Stream>::Pointer_t
1685 pAnnotation(pIt->getSubDocument());
1687 if (pAnnotation.get() != NULL)
1689 #ifdef DEBUG_ELEMENT
1690 debug_logger->startElement("substream");
1691 #endif
1692 rStream.substream(NS_rtf::LN_annotation, pAnnotation);
1693 #ifdef DEBUG_ELEMENT
1694 debug_logger->endElement();
1695 #endif
1698 break;
1699 case PROP_CHP:
1701 startCharacterGroup(rStream);
1704 break;
1705 case PROP_PAP:
1707 startParagraphGroup(rStream);
1708 rStream.info(pIt->toString());
1711 break;
1712 case PROP_SEC:
1714 startSectionGroup(rStream);
1715 rStream.info(pIt->toString());
1717 if (nSectionIndex == 0)
1718 rStream.props(getDocumentProperties());
1720 sal_uInt32 nHeaderStartIndex = 6 + nSectionIndex * 6;
1721 sal_uInt32 nHeaderEndIndex = nHeaderStartIndex + 6;
1723 if (nHeaderStartIndex >= getHeaderCount())
1724 nHeaderStartIndex = getHeaderCount();
1726 if (nHeaderEndIndex >= getHeaderCount())
1727 nHeaderEndIndex = getHeaderCount();
1729 for (sal_uInt32 n = nHeaderStartIndex; n < nHeaderEndIndex; ++n)
1731 writerfilter::Reference<Stream>::Pointer_t
1732 pHeader(getHeader(n));
1734 Id qName = lcl_headerQName(n);
1736 if (pHeader.get() != NULL)
1737 rStream.substream(qName, pHeader);
1740 ++nSectionIndex;
1743 break;
1744 default:
1745 rStream.info(pIt->toString());
1748 if (pProperties.get() != NULL)
1750 #ifdef DEBUG_PROPERTIES
1751 debug_logger->propertySet(pProperties,
1752 IdToString::Pointer_t(new WW8IdToString()));
1753 #endif
1755 rStream.props(pProperties);
1758 if (pIt->getPropertyType() == PROP_PAP)
1760 startCharacterGroup(rStream);
1763 resolveText(pIt, rStream);
1765 ++(*pIt);
1768 if (mbInCharacterGroup)
1769 endCharacterGroup(rStream);
1771 if (mbInParagraphGroup)
1772 endParagraphGroup(rStream);
1774 if (mbInSection)
1775 endSectionGroup(rStream);
1779 WW8Stream::Pointer_t
1780 WW8DocumentFactory::createStream(uno::Reference<uno::XComponentContext> rContext,
1781 uno::Reference<io::XInputStream> rStream)
1783 return WW8Stream::Pointer_t(new WW8StreamImpl(rContext, rStream));
1786 WW8Document *
1787 WW8DocumentFactory::createDocument(WW8Stream::Pointer_t rpStream)
1789 return new WW8DocumentImpl(rpStream);
1792 writerfilter::Reference<Properties>::Pointer_t
1793 WW8SED::get_sepx()
1795 writerfilter::Reference<Properties>::Pointer_t pResult;
1797 if (get_fcSepx() != 0xffffffff)
1799 WW8StructBase aTmp(*mpDoc->getDocStream(), get_fcSepx(), 2);
1800 pResult = writerfilter::Reference<Properties>::Pointer_t
1801 (new WW8PropertySetImpl
1802 (*mpDoc->getDocStream(), get_fcSepx() + 2,
1803 (sal_uInt32) aTmp.getU16(0), false));
1806 return pResult;
1809 void WW8DocumentImpl::insertCpAndFc(const CpAndFc & rCpAndFc)
1811 mCpAndFcs.insert(rCpAndFc);
1814 string propertyTypeToString(PropertyType nType)
1816 string result;
1818 switch (nType)
1820 case PROP_SHP:
1821 result = "SHP";
1823 break;
1824 case PROP_FLD:
1825 result = "FLD";
1827 break;
1828 case PROP_BOOKMARKSTART:
1829 result = "BOOKMARKSTART";
1831 break;
1832 case PROP_BOOKMARKEND:
1833 result = "BOOKMARKEND";
1835 break;
1836 case PROP_ENDNOTE:
1837 result = "ENDNOTE";
1839 break;
1840 case PROP_FOOTNOTE:
1841 result = "FOOTNOTE";
1843 break;
1844 case PROP_ANNOTATION:
1845 result = "ANNOTATION";
1847 break;
1848 case PROP_DOC:
1849 result = "DOC";
1851 break;
1853 case PROP_SEC:
1854 result = "SEC";
1856 break;
1858 case PROP_PAP:
1859 result = "PAP";
1861 break;
1863 case PROP_CHP:
1864 result = "CHP";
1866 break;
1867 default:
1868 break;
1871 return result;
1874 string CpAndFc::toString() const
1876 string result;
1878 result += "(";
1879 result += getCp().toString();
1880 result += ", ";
1881 result += getFc().toString();
1882 result += ", ";
1884 result += propertyTypeToString(getType());
1886 result += ")";
1888 return result;
1892 // Bookmark
1894 Bookmark::Bookmark(writerfilter::Reference<Properties>::Pointer_t pBKF,
1895 OUString & rName)
1896 : mpBKF(pBKF), mName(rName)
1900 void Bookmark::resolve(Properties & rHandler)
1902 mpBKF->resolve(rHandler);
1904 WW8Value::Pointer_t pValue = createValue(mName);
1905 rHandler.attribute(NS_rtf::LN_BOOKMARKNAME, *pValue);
1908 string Bookmark::getType() const
1910 return "Bookmark";
1913 // BookmarkHelper
1915 CpAndFc BookmarkHelper::getStartCpAndFc(sal_uInt32 nPos)
1917 Cp aCp(mpStartCps->getFc(nPos));
1918 Fc aFc(mpPieceTable->cp2fc(aCp));
1919 CpAndFc aCpAndFc(aCp, aFc, PROP_BOOKMARKSTART);
1921 return aCpAndFc;
1924 CpAndFc BookmarkHelper::getEndCpAndFc(sal_uInt32 nPos)
1926 Cp aCp(mpEndCps->getU32(nPos * 4));
1927 Fc aFc(mpPieceTable->cp2fc(aCp));
1928 CpAndFc aCpAndFc(aCp, aFc, PROP_BOOKMARKEND);
1930 return aCpAndFc;
1933 OUString BookmarkHelper::getName(sal_uInt32 nPos)
1935 return mpNames->getEntry(nPos);
1938 sal_uInt32 BookmarkHelper::getIndex(const CpAndFc & rCpAndFc)
1940 sal_uInt32 nResult = mpStartCps->getEntryCount();
1942 sal_uInt32 nCp = rCpAndFc.getCp().get();
1944 sal_uInt32 n;
1945 switch (rCpAndFc.getType())
1947 case PROP_BOOKMARKSTART:
1949 sal_uInt32 nStartsCount = mpStartCps->getEntryCount();
1951 for (n = 0; n < nStartsCount; ++n)
1953 if (nCp == mpStartCps->getFc(n))
1955 nResult = n;
1957 break;
1961 if (n == nStartsCount)
1962 throw ExceptionNotFound("BookmarkHelper::getIndex");
1965 break;
1967 case PROP_BOOKMARKEND:
1969 sal_uInt32 nEndsCount = mpEndCps->getCount() / 4;
1970 sal_uInt32 nIndex = nEndsCount;
1972 for (n = 0; n < nEndsCount; ++n)
1974 if (nCp == mpEndCps->getU16(n * 4))
1976 nIndex = n;
1978 break;
1982 if (n == nEndsCount)
1983 throw ExceptionNotFound("BookmarkHelper::getIndex");
1987 sal_uInt32 nStartsCount = mpStartCps->getEntryCount();
1988 for (n = 0; n < nStartsCount; ++n)
1990 WW8BKF::Pointer_t pBKF(mpStartCps->getEntry(n));
1992 if (pBKF->get_ibkl() ==
1993 sal::static_int_cast<sal_Int32>(nIndex))
1995 nResult = n;
1997 break;
2001 if (n == nStartsCount)
2002 throw ExceptionNotFound("BookmarkHelper::getIndex");
2007 break;
2008 default:
2009 break;
2012 return nResult;
2015 void BookmarkHelper::init()
2018 sal_uInt32 nStartsCount = mpStartCps->getEntryCount();
2020 for (sal_uInt32 n = 0; n < nStartsCount; ++n)
2021 mpDoc->insertCpAndFc(getStartCpAndFc(n));
2025 sal_uInt32 nEndsCount = mpEndCps->getCount() / 4;
2027 for (sal_uInt32 n = 0; n < nEndsCount; ++n)
2028 mpDoc->insertCpAndFc(getEndCpAndFc(n));
2032 writerfilter::Reference<Properties>::Pointer_t
2033 BookmarkHelper::getBKF(const CpAndFc & rCpAndFc)
2035 sal_uInt32 nIndex = getIndex(rCpAndFc);
2037 return writerfilter::Reference<Properties>::Pointer_t
2038 (mpStartCps->getEntryPointer(nIndex));
2041 writerfilter::Reference<Properties>::Pointer_t
2042 BookmarkHelper::getBookmark(const CpAndFc & rCpAndFc)
2044 writerfilter::Reference<Properties>::Pointer_t pResult;
2048 OUString aName = getName(rCpAndFc);
2050 pResult = writerfilter::Reference<Properties>::Pointer_t
2051 (new Bookmark(getBKF(rCpAndFc), aName));
2053 catch (const ExceptionNotFound &e)
2055 clog << e.getText() << endl;
2058 return pResult;
2061 OUString BookmarkHelper::getName(const CpAndFc & rCpAndFc)
2063 OUString sResult;
2065 sal_uInt32 nIndex = getIndex(rCpAndFc);
2067 sResult = getName(nIndex);
2069 return sResult;
2072 template <class T, class Helper>
2073 struct ProcessPLCF2Map
2075 void process(typename PLCF<T>::Pointer_t pPlcf,
2076 typename Helper::Map_t & rMap,
2077 PropertyType type,
2078 WW8DocumentImpl * pDoc)
2080 if (pPlcf.get() != NULL)
2082 sal_uInt32 nCount = pPlcf->getEntryCount();
2084 for (sal_uInt32 n = 0; n < nCount; n++)
2086 Cp aCp(pPlcf->getFc(n));
2087 CpAndFc aCpAndFc(pDoc->getCpAndFc(aCp, type));
2088 typename T::Pointer_t pT = pPlcf->getEntry(n);
2090 rMap[aCpAndFc] = pT;
2096 FieldHelper::FieldHelper(PLCF<WW8FLD>::Pointer_t pPlcffldMom,
2097 WW8DocumentImpl * pDoc)
2098 : mpDoc(pDoc)
2100 ProcessPLCF2Map<WW8FLD, FieldHelper> process;
2101 process.process(pPlcffldMom, mMap, PROP_FLD, pDoc);
2104 void FieldHelper::init()
2106 Map_t::iterator aIt;
2108 for (aIt = mMap.begin(); aIt != mMap.end(); ++aIt)
2110 mpDoc->insertCpAndFc(aIt->first);
2114 WW8FLD::Pointer_t FieldHelper::getWW8FLD(const CpAndFc & rCpAndFc)
2116 WW8FLD::Pointer_t pFld = mMap[rCpAndFc];
2118 return pFld;
2121 writerfilter::Reference<Properties>::Pointer_t
2122 FieldHelper::getField(const CpAndFc & rCpAndFc)
2124 WW8FLD::Pointer_t pFLD = getWW8FLD(rCpAndFc);
2126 return writerfilter::Reference<Properties>::Pointer_t
2127 (new WW8FLD(*pFLD));
2130 ShapeHelper::ShapeHelper(PLCF<WW8FSPA>::Pointer_t pPlcspaMom,
2131 PLCF<WW8FSPA>::Pointer_t pPlcspaHdr,
2132 WW8DocumentImpl * pDoc)
2133 : mpDoc(pDoc)
2135 ProcessPLCF2Map<WW8FSPA, ShapeHelper> process;
2136 process.process(pPlcspaMom, mMap, PROP_SHP, pDoc);
2137 process.process(pPlcspaHdr, mMap, PROP_SHP, pDoc);
2140 void ShapeHelper::init()
2142 Map_t::iterator aIt;
2144 for (aIt = mMap.begin(); aIt != mMap.end(); ++aIt)
2146 mpDoc->insertCpAndFc(aIt->first);
2147 aIt->second->setDocument(mpDoc);
2151 writerfilter::Reference<Properties>::Pointer_t
2152 ShapeHelper::getShape(const CpAndFc & rCpAndFc)
2154 WW8FSPA::Pointer_t pFSPA = mMap[rCpAndFc];
2156 return writerfilter::Reference<Properties>::Pointer_t
2157 (new WW8FSPA(*pFSPA));
2160 BreakHelper::BreakHelper(PLCF<WW8BKD>::Pointer_t pPlcfbkdMom,
2161 WW8DocumentImpl * pDoc)
2162 : mpDoc(pDoc)
2164 ProcessPLCF2Map<WW8BKD, BreakHelper> process;
2165 process.process(pPlcfbkdMom, mMap, PROP_BRK, pDoc);
2168 void BreakHelper::init()
2170 Map_t::iterator aIt;
2172 for (aIt = mMap.begin(); aIt != mMap.end(); ++aIt)
2174 mpDoc->insertCpAndFc(aIt->first);
2178 writerfilter::Reference<Properties>::Pointer_t
2179 BreakHelper::getBreak(const CpAndFc & rCpAndFc)
2181 WW8BKD::Pointer_t pBKD = mMap[rCpAndFc];
2183 return writerfilter::Reference<Properties>::Pointer_t
2184 (new WW8BKD(*pBKD));
2190 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */