1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: Dff.cxx,v $
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 ************************************************************************/
33 #include <doctok/resourceids.hxx>
34 #include <resourcemodel/WW8ResourceModel.hxx>
35 #include "resources.hxx"
37 namespace writerfilter
{
40 typedef boost::shared_ptr
<WW8Value
> WW8ValueSharedPointer_t
;
42 DffRecord::DffRecord(WW8Stream
& rStream
, sal_uInt32 nOffset
,
44 : WW8StructBase(rStream
, nOffset
, nCount
), bInitialized(false)
48 DffRecord::DffRecord(WW8StructBase
* pParent
, sal_uInt32 nOffset
,
50 : WW8StructBase(pParent
, nOffset
, nCount
), bInitialized(false)
54 Records_t::iterator
DffRecord::begin()
59 return mRecords
.begin();
62 Records_t::iterator
DffRecord::end()
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())
86 nResult
= getU32(0x4) + 8;
94 nResult
= getU32(0x4);
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
119 void DffRecord::initChildren()
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
));
135 mRecords
.push_back(pRec
);
144 Records_t
DffRecord::findRecords(sal_uInt32 nType
, bool bRecursive
, bool bAny
)
148 findRecords(nType
, aResult
, bRecursive
, bAny
);
153 void DffRecord::findRecords
154 (sal_uInt32 nType
, Records_t
& rRecords
, bool bRecursive
, bool bAny
)
156 Records_t::iterator aIt
= begin();
160 Pointer_t pPointer
= *aIt
;
161 if (bAny
|| pPointer
->getRecordType() == nType
)
162 rRecords
.push_back(pPointer
);
165 pPointer
->findRecords(nType
, rRecords
, bRecursive
,
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
);
201 resolveChildren(rHandler
);
204 resolveLocal(rHandler
);
207 WW8BinaryObjReference::Pointer_t pBinObjRef
208 (new WW8BinaryObjReference(this, 0, getCount()));
209 WW8Sprm
aSprm(pBinObjRef
);
211 rHandler
.sprm(aSprm
);
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();
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();
245 class DffOPTHandler
: public Properties
247 map
<int, WW8ValueSharedPointer_t
> mMap
;
251 DffOPTHandler() : nId(0) {}
252 virtual ~DffOPTHandler() {}
254 virtual void attribute(Id name
, Value
& val
)
258 case NS_rtf::LN_shppid
:
261 case NS_rtf::LN_shpvalue
:
263 WW8Value
& rTmpVal
= dynamic_cast<WW8Value
&>(val
);
264 WW8ValueSharedPointer_t
265 pVal(dynamic_cast<WW8Value
*>(rTmpVal
.clone()));
271 virtual void sprm(Sprm
& /*sprm_*/)
275 WW8ValueSharedPointer_t
& getValue(int 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();
312 string
DffRecord::getType() const
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
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
;
348 aResult
+= mSequence
.toString();
351 WW8StructBase::Sequence
aSeq(mSequence
, 0, 8);
352 aResult
+= aSeq
.toString();
355 aResult
+= "</dffrecord>";
360 string
DffRecord::getName() const
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),
377 DffBlock::DffBlock(WW8StructBase
* pParent
, sal_uInt32 nOffset
,
378 sal_uInt32 nCount
, sal_uInt32 nPadding
)
379 : WW8StructBase(pParent
, nOffset
, nCount
), bInitialized(false),
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
));
404 mRecords
.push_back(pDffRecord
);
406 nOffset
+= nSize
+ mnPadding
;
412 Records_t
DffBlock::findRecords(sal_uInt32 nType
, bool bRecursive
, bool bAny
)
416 findRecords(nType
, aResult
, bRecursive
, bAny
);
421 void DffBlock::findRecords
422 (sal_uInt32 nType
, Records_t
& rRecords
, bool bRecursive
, bool bAny
)
424 Records_t::iterator aIt
= begin();
428 DffRecord::Pointer_t
pPointer(*aIt
);
430 if (bAny
|| pPointer
->getRecordType() == nType
)
431 rRecords
.push_back(pPointer
);
434 pPointer
->findRecords(nType
, rRecords
, bRecursive
,
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
)
481 DffRecord::Pointer_t
DffBlock::getBlip(sal_uInt32 nBlip
)
483 DffRecord::Pointer_t pResult
;
489 Records_t aRecords
= findRecords(0xf007);
491 if (nBlip
< aRecords
.size())
493 pResult
= aRecords
[nBlip
];
500 Records_t::iterator
DffBlock::begin()
505 return mRecords
.begin();
508 Records_t::iterator
DffBlock::end()
513 return mRecords
.end();
516 string
DffBlock::getType() const