merge the formfield patch from ooo-build
[ooovba.git] / writerfilter / source / doctok / Dff.cxx
blob965c815c1bb0dda526efc8843d825eb2b6d8893b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: Dff.cxx,v $
10 * $Revision: 1.13 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <stdio.h>
32 #include "Dff.hxx"
33 #include <doctok/resourceids.hxx>
34 #include <resourcemodel/WW8ResourceModel.hxx>
35 #include "resources.hxx"
37 namespace writerfilter {
38 namespace doctok {
40 typedef boost::shared_ptr<WW8Value> WW8ValueSharedPointer_t;
42 DffRecord::DffRecord(WW8Stream & rStream, sal_uInt32 nOffset,
43 sal_uInt32 nCount)
44 : WW8StructBase(rStream, nOffset, nCount), bInitialized(false)
48 DffRecord::DffRecord(WW8StructBase * pParent, sal_uInt32 nOffset,
49 sal_uInt32 nCount)
50 : WW8StructBase(pParent, nOffset, nCount), bInitialized(false)
54 Records_t::iterator DffRecord::begin()
56 if (! bInitialized)
57 initChildren();
59 return mRecords.begin();
62 Records_t::iterator DffRecord::end()
64 if (! bInitialized)
65 initChildren();
67 return mRecords.end();
70 bool DffRecord::isContainer() const
72 return getVersion() == 0xf;
75 sal_uInt32 DffRecord::calcSize() const
77 sal_uInt32 nResult = 0;
79 switch (getRecordType())
81 case 0xf000:
82 case 0xf001:
83 case 0xf002:
84 case 0xf003:
85 case 0xf004:
86 nResult = getU32(0x4) + 8;
88 break;
89 case 0xf700:
90 nResult = 8;
92 break;
93 default:
94 nResult = getU32(0x4);
96 if (! isContainer())
97 nResult += 8;
98 break;
101 return nResult;
104 sal_uInt32 DffRecord::getVersion() const
106 return getU8(0x0) & 0xf;
109 sal_uInt32 DffRecord::getInstance() const
111 return (getU16(0x0) & 0xfff0) >> 4;
114 sal_uInt32 DffRecord::getRecordType() const
116 return getU16(0x2);
119 void DffRecord::initChildren()
121 if (isContainer())
123 sal_uInt32 nOffset = 8;
124 sal_uInt32 nCount = calcSize();
126 while (nCount - nOffset >= 8)
128 sal_uInt32 nSize = 0;
129 boost::shared_ptr<DffRecord> pRec
130 (createDffRecord(this, nOffset, &nSize));
132 if (nSize == 0)
133 break;
135 mRecords.push_back(pRec);
137 nOffset += nSize;
141 bInitialized = true;
144 Records_t DffRecord::findRecords(sal_uInt32 nType, bool bRecursive, bool bAny)
146 Records_t aResult;
148 findRecords(nType, aResult, bRecursive, bAny);
150 return aResult;
153 void DffRecord::findRecords
154 (sal_uInt32 nType, Records_t & rRecords, bool bRecursive, bool bAny)
156 Records_t::iterator aIt = begin();
158 while (aIt != end())
160 Pointer_t pPointer = *aIt;
161 if (bAny || pPointer->getRecordType() == nType)
162 rRecords.push_back(pPointer);
164 if (bRecursive)
165 pPointer->findRecords(nType, rRecords, bRecursive,
166 bAny);
168 ++aIt;
172 void DffRecord::resolveChildren(Properties & rHandler)
174 Records_t::iterator aIt;
175 for (aIt = begin(); aIt != end(); ++aIt)
177 rHandler.sprm(**aIt);
181 void DffRecord::resolveLocal(Properties &)
185 void DffRecord::resolve(Properties & rHandler)
187 WW8Value::Pointer_t pVal = createValue(getRecordType());
188 rHandler.attribute(NS_rtf::LN_dfftype, *pVal);
190 pVal = createValue(getInstance());
191 rHandler.attribute(NS_rtf::LN_dffinstance, *pVal);
193 pVal = createValue(getVersion());
194 rHandler.attribute(NS_rtf::LN_dffversion, *pVal);
196 pVal = createValue(getU32(0x0));
197 rHandler.attribute(NS_rtf::LN_dffheader, *pVal);
199 if (isContainer())
201 resolveChildren(rHandler);
204 resolveLocal(rHandler);
206 #if 1
207 WW8BinaryObjReference::Pointer_t pBinObjRef
208 (new WW8BinaryObjReference(this, 0, getCount()));
209 WW8Sprm aSprm(pBinObjRef);
211 rHandler.sprm(aSprm);
212 #endif
215 sal_uInt32 DffRecord::getShapeType()
217 sal_uInt32 nResult = 0;
219 Records_t aRecords = findRecords(0xf00a);
221 if (aRecords.size() > 0)
223 DffFSP * pDffFSP = dynamic_cast<DffFSP*>((*aRecords.begin()).get());
224 nResult = pDffFSP->get_shptype();
227 return nResult;
230 sal_uInt32 DffRecord::getShapeId()
232 sal_uInt32 nResult = 0;
234 Records_t aRecords = findRecords(0xf00a);
236 if (aRecords.size() > 0)
238 DffFSP * pDffFSP = dynamic_cast<DffFSP*>((*aRecords.begin()).get());
239 nResult = pDffFSP->get_shpid();
242 return nResult;
245 class DffOPTHandler : public Properties
247 map<int, WW8ValueSharedPointer_t> mMap;
248 int nId;
250 public:
251 DffOPTHandler() : nId(0) {}
252 virtual ~DffOPTHandler() {}
254 virtual void attribute(Id name, Value & val)
256 switch (name)
258 case NS_rtf::LN_shppid:
259 nId = val.getInt();
260 break;
261 case NS_rtf::LN_shpvalue:
263 WW8Value & rTmpVal = dynamic_cast<WW8Value &>(val);
264 WW8ValueSharedPointer_t
265 pVal(dynamic_cast<WW8Value *>(rTmpVal.clone()));
266 mMap[nId] = pVal;
271 virtual void sprm(Sprm & /*sprm_*/)
275 WW8ValueSharedPointer_t & getValue(int nId_)
277 return mMap[nId_];
282 sal_uInt32 DffRecord::getShapeBid()
284 sal_uInt32 nResult = 0;
286 if (getShapeType() == 75)
288 Records_t aRecords = findRecords(0xf00b);
290 if (aRecords.size() > 0)
292 DffOPTHandler aHandler;
293 DffOPT * pOpts = dynamic_cast<DffOPT*>((*aRecords.begin()).get());
295 sal_uInt32 nCount = pOpts->get_property_count();
297 for (sal_uInt32 n = 0; n < nCount; ++n)
299 pOpts->get_property(n)->resolve(aHandler);
302 WW8ValueSharedPointer_t pVal = aHandler.getValue(260);
304 if (pVal.get() != NULL)
305 nResult = pVal->getInt();
309 return nResult;
312 string DffRecord::getType() const
314 return "DffRecord";
317 Value::Pointer_t DffRecord::getValue()
319 return Value::Pointer_t();
322 writerfilter::Reference<BinaryObj>::Pointer_t DffRecord::getBinary()
324 return writerfilter::Reference<BinaryObj>::Pointer_t();
327 writerfilter::Reference<Stream>::Pointer_t DffRecord::getStream()
329 return writerfilter::Reference<Stream>::Pointer_t();
332 writerfilter::Reference<Properties>::Pointer_t DffRecord::getProps()
334 return writerfilter::Reference<Properties>::Pointer_t(this->clone());
337 string DffRecord::toString() const
339 char sBuffer[1024];
341 snprintf(sBuffer, sizeof(sBuffer),
342 "<dffrecord type=\"%" SAL_PRIuUINT32 "\" instance=\"%" SAL_PRIuUINT32 "\" version=\"%" SAL_PRIuUINT32 "\">\n",
343 getRecordType(), getInstance(), getVersion());
344 string aResult = sBuffer;
347 if (!isContainer())
348 aResult += mSequence.toString();
349 else
351 WW8StructBase::Sequence aSeq(mSequence, 0, 8);
352 aResult += aSeq.toString();
355 aResult += "</dffrecord>";
357 return aResult;
360 string DffRecord::getName() const
362 return "";
365 Sprm::Kind DffRecord::getKind()
367 return Sprm::UNKNOWN;
370 DffBlock::DffBlock(WW8Stream & rStream, sal_uInt32 nOffset,
371 sal_uInt32 nCount, sal_uInt32 nPadding)
372 : WW8StructBase(rStream, nOffset, nCount), bInitialized(false),
373 mnPadding(nPadding)
377 DffBlock::DffBlock(WW8StructBase * pParent, sal_uInt32 nOffset,
378 sal_uInt32 nCount, sal_uInt32 nPadding)
379 : WW8StructBase(pParent, nOffset, nCount), bInitialized(false),
380 mnPadding(nPadding)
384 DffBlock::DffBlock(const DffBlock & rSrc)
385 : WW8StructBase(rSrc), writerfilter::Reference<Properties>(rSrc),
386 bInitialized(false), mnPadding(rSrc.mnPadding)
390 void DffBlock::initChildren()
392 sal_uInt32 nOffset = 0;
393 sal_uInt32 nCount = getCount();
395 while (nOffset < nCount)
397 sal_uInt32 nSize = 0;
398 DffRecord::Pointer_t pDffRecord
399 (createDffRecord(this, nOffset, &nSize));
401 if (nSize == 0)
402 break;
404 mRecords.push_back(pDffRecord);
406 nOffset += nSize + mnPadding;
409 bInitialized = true;
412 Records_t DffBlock::findRecords(sal_uInt32 nType, bool bRecursive, bool bAny)
414 Records_t aResult;
416 findRecords(nType, aResult, bRecursive, bAny);
418 return aResult;
421 void DffBlock::findRecords
422 (sal_uInt32 nType, Records_t & rRecords, bool bRecursive, bool bAny)
424 Records_t::iterator aIt = begin();
426 while (aIt != end())
428 DffRecord::Pointer_t pPointer(*aIt);
430 if (bAny || pPointer->getRecordType() == nType)
431 rRecords.push_back(pPointer);
433 if (bRecursive)
434 pPointer->findRecords(nType, rRecords, bRecursive,
435 bAny);
437 ++aIt;
441 void DffBlock::resolve(Properties & rHandler)
443 Records_t::iterator aIt;
445 for (aIt = begin(); aIt != end(); ++aIt)
447 DffRecord * pDff = aIt->get();
448 rHandler.sprm(*pDff);
452 DffRecord::Pointer_t DffBlock::getShape(sal_uInt32 nSpid)
454 DffRecord::Pointer_t pResult;
456 Records_t aRecords = findRecords(0xf004);
457 Records_t::iterator aIt;
458 for (aIt = aRecords.begin(); aIt != aRecords.end(); ++aIt)
460 DffRecord::Pointer_t pPointer = *aIt;
462 Records_t aFSPs = pPointer->findRecords(0xf00a);
463 Records_t::iterator aItFSP = aFSPs.begin();
465 if (aItFSP != aFSPs.end())
467 DffFSP * pFSP = dynamic_cast<DffFSP *>((*aItFSP).get());
469 if (pFSP->get_shpid() == nSpid)
471 pResult = pPointer;
473 break;
478 return pResult;
481 DffRecord::Pointer_t DffBlock::getBlip(sal_uInt32 nBlip)
483 DffRecord::Pointer_t pResult;
485 if (nBlip > 0)
487 nBlip--;
489 Records_t aRecords = findRecords(0xf007);
491 if (nBlip < aRecords.size())
493 pResult = aRecords[nBlip];
497 return pResult;
500 Records_t::iterator DffBlock::begin()
502 if (! bInitialized)
503 initChildren();
505 return mRecords.begin();
508 Records_t::iterator DffBlock::end()
510 if (! bInitialized)
511 initChildren();
513 return mRecords.end();
516 string DffBlock::getType() const
518 return "DffBlock";