1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 "OOXMLPropertySetImpl.hxx"
23 #include <resourcemodel/QNameToString.hxx>
24 #include <resourcemodel/Protocol.hxx>
25 #include <com/sun/star/drawing/XShape.hpp>
26 #include <ooxml/OOXMLFastTokens.hxx>
27 #include "ooxmlLoggers.hxx"
28 #include <ooxml/resourceids.hxx>
30 namespace writerfilter
{
33 using namespace ::std
;
35 OOXMLProperty::~OOXMLProperty()
39 OOXMLPropertySet::~OOXMLPropertySet()
43 OOXMLTable::~OOXMLTable()
47 OOXMLPropertyImpl::OOXMLPropertyImpl(Id id
, OOXMLValue::Pointer_t pValue
,
48 OOXMLPropertyImpl::Type_t eType
)
49 : mId(id
), mpValue(pValue
), meType(eType
)
53 OOXMLPropertyImpl::OOXMLPropertyImpl(const OOXMLPropertyImpl
& rSprm
)
54 : OOXMLProperty(), mId(rSprm
.mId
), mpValue(rSprm
.mpValue
), meType(rSprm
.meType
)
58 OOXMLPropertyImpl::~OOXMLPropertyImpl()
62 sal_uInt32
OOXMLPropertyImpl::getId() const
67 Value::Pointer_t
OOXMLPropertyImpl::getValue()
69 Value::Pointer_t pResult
;
71 if (mpValue
.get() != NULL
)
72 pResult
= Value::Pointer_t(mpValue
->clone());
74 pResult
= Value::Pointer_t(new OOXMLValue());
79 writerfilter::Reference
<BinaryObj
>::Pointer_t
OOXMLPropertyImpl::getBinary()
81 writerfilter::Reference
<BinaryObj
>::Pointer_t pResult
;
83 if (mpValue
.get() != NULL
)
84 pResult
= mpValue
->getBinary();
89 writerfilter::Reference
<Stream
>::Pointer_t
OOXMLPropertyImpl::getStream()
91 writerfilter::Reference
<Stream
>::Pointer_t pResult
;
93 if (mpValue
.get() != NULL
)
94 pResult
= mpValue
->getStream();
99 writerfilter::Reference
<Properties
>::Pointer_t
OOXMLPropertyImpl::getProps()
101 writerfilter::Reference
<Properties
>::Pointer_t pResult
;
103 if (mpValue
.get() != NULL
)
104 pResult
= mpValue
->getProperties();
109 string
OOXMLPropertyImpl::getName() const
111 string sResult
= (*QNameToString::Instance())(mId
);
113 if (sResult
.length() == 0)
114 sResult
= (*SprmIdToString::Instance())(mId
);
116 if (sResult
.length() == 0)
117 sResult
= fastTokenToId(mId
);
119 if (sResult
.length() == 0)
121 static char sBuffer
[256];
123 snprintf(sBuffer
, sizeof(sBuffer
), "%" SAL_PRIxUINT32
, mId
);
130 string
OOXMLPropertyImpl::toString() const
132 string sResult
= "(";
134 sResult
+= getName();
136 if (mpValue
.get() != NULL
)
137 sResult
+= mpValue
->toString();
145 Sprm::Kind
OOXMLPropertyImpl::getKind()
147 return SprmKind(getId());
150 Sprm
* OOXMLPropertyImpl::clone()
152 return new OOXMLPropertyImpl(*this);
155 void OOXMLPropertyImpl::resolve(writerfilter::Properties
& rProperties
)
157 writerfilter::Properties
* pProperties
= NULL
;
158 #ifdef DEBUG_PROTOCOL
159 writerfilter::PropertiesProtocol::Pointer_t pProtocol
160 (new writerfilter::PropertiesProtocol(&rProperties
, debug_logger
));
161 pProperties
= pProtocol
.get();
163 pProperties
= &rProperties
;
170 pProperties
->sprm(*this);
173 pProperties
->attribute(mId
, *getValue());
182 OOXMLValue::OOXMLValue()
186 OOXMLValue::~OOXMLValue()
190 bool OOXMLValue::getBool() const
195 int OOXMLValue::getInt() const
200 OUString
OOXMLValue::getString() const
205 uno::Any
OOXMLValue::getAny() const
210 writerfilter::Reference
<Properties
>::Pointer_t
OOXMLValue::getProperties()
212 return writerfilter::Reference
<Properties
>::Pointer_t();
215 writerfilter::Reference
<Stream
>::Pointer_t
OOXMLValue::getStream()
217 return writerfilter::Reference
<Stream
>::Pointer_t();
220 writerfilter::Reference
<BinaryObj
>::Pointer_t
OOXMLValue::getBinary()
222 return writerfilter::Reference
<BinaryObj
>::Pointer_t();
225 string
OOXMLValue::toString() const
230 OOXMLValue
* OOXMLValue::clone() const
232 return new OOXMLValue(*this);
236 class OOXMLBinaryValue
239 OOXMLBinaryValue::OOXMLBinaryValue(OOXMLBinaryObjectReference::Pointer_t
241 : mpBinaryObj(pBinaryObj
)
245 OOXMLBinaryValue::~OOXMLBinaryValue()
249 writerfilter::Reference
<BinaryObj
>::Pointer_t
OOXMLBinaryValue::getBinary()
254 string
OOXMLBinaryValue::toString() const
259 OOXMLValue
* OOXMLBinaryValue::clone() const
261 return new OOXMLBinaryValue(mpBinaryObj
);
265 class OOXMLBooleanValue
268 OOXMLBooleanValue::OOXMLBooleanValue(bool bValue
)
273 OOXMLBooleanValue::OOXMLBooleanValue(const OUString
& rValue
)
276 mbValue
= (rValue
== "true"
283 OOXMLBooleanValue::~OOXMLBooleanValue()
287 bool OOXMLBooleanValue::getBool() const
292 int OOXMLBooleanValue::getInt() const
294 return mbValue
? 1 : 0;
297 uno::Any
OOXMLBooleanValue::getAny() const
299 uno::Any
aResult(mbValue
);
304 string
OOXMLBooleanValue::toString() const
306 return mbValue
? "true" : "false";
309 OOXMLValue
* OOXMLBooleanValue::clone() const
311 return new OOXMLBooleanValue(*this);
315 class OOXMLStringValue
318 OOXMLStringValue::OOXMLStringValue(const OUString
& rStr
)
323 OOXMLStringValue::~OOXMLStringValue()
327 uno::Any
OOXMLStringValue::getAny() const
334 OUString
OOXMLStringValue::getString() const
339 string
OOXMLStringValue::toString() const
341 return OUStringToOString(mStr
, RTL_TEXTENCODING_ASCII_US
).getStr();
344 OOXMLValue
* OOXMLStringValue::clone() const
346 return new OOXMLStringValue(*this);
350 class OOXMLInputStreamValue
352 OOXMLInputStreamValue::OOXMLInputStreamValue(uno::Reference
<io::XInputStream
> xInputStream
)
353 : mxInputStream(xInputStream
)
357 OOXMLInputStreamValue::~OOXMLInputStreamValue()
361 uno::Any
OOXMLInputStreamValue::getAny() const
363 uno::Any
aAny(mxInputStream
);
368 string
OOXMLInputStreamValue::toString() const
370 return "InputStream";
373 OOXMLValue
* OOXMLInputStreamValue::clone() const
375 return new OOXMLInputStreamValue(mxInputStream
);
379 struct OOXMLPropertySetImplCompare
382 bool OOXMLPropertySetImplCompare::operator()(const OOXMLProperty::Pointer_t x
,
383 const OOXMLProperty::Pointer_t y
) const
385 bool bResult
= false;
387 if (x
.get() == NULL
&& y
.get() != NULL
)
389 else if (x
.get() != NULL
&& y
.get() != NULL
)
390 bResult
= x
->getId() < y
->getId();
396 class OOXMLPropertySetImpl
399 OOXMLPropertySetImpl::OOXMLPropertySetImpl()
400 : msType("OOXMLPropertySetImpl")
404 OOXMLPropertySetImpl::~OOXMLPropertySetImpl()
408 void OOXMLPropertySetImpl::resolve(Properties
& rHandler
)
412 // The pProp->resolve(rHandler) call below can cause elements to
413 // be appended to mProperties. I don't think it can cause elements
414 // to be deleted. But let's check with < here just to be safe that
415 // the indexing below works.
416 while (nIt
< mProperties
.size())
418 OOXMLProperty::Pointer_t pProp
= mProperties
[nIt
];
420 if (pProp
.get() != NULL
)
421 pProp
->resolve(rHandler
);
425 debug_logger
->startElement("error");
426 debug_logger
->chars(std::string("zero-property"));
427 debug_logger
->endElement();
435 OOXMLPropertySetImpl::OOXMLProperties_t::iterator
OOXMLPropertySetImpl::begin()
437 return mProperties
.begin();
440 OOXMLPropertySetImpl::OOXMLProperties_t::iterator
OOXMLPropertySetImpl::end()
442 return mProperties
.end();
445 OOXMLPropertySetImpl::OOXMLProperties_t::const_iterator
446 OOXMLPropertySetImpl::begin() const
448 return mProperties
.begin();
451 OOXMLPropertySetImpl::OOXMLProperties_t::const_iterator
452 OOXMLPropertySetImpl::end() const
454 return mProperties
.end();
457 string
OOXMLPropertySetImpl::getType() const
462 void OOXMLPropertySetImpl::add(OOXMLProperty::Pointer_t pProperty
)
464 #ifdef DEBUG_PROPERTY_SET
465 debug_logger
->startElement("propertyset.add");
466 debug_logger
->chars(pProperty
->toString());
469 if (pProperty
.get() != NULL
&& pProperty
->getId() != 0x0)
472 HACK: Ugly hack. This retarded overdesigned writerfilter thing
473 processes attributes in random order (as given by boost::unordered_map
474 when iterating it), but StyleSheetTable::lcl_attribute() needs
475 to know whether NS_ooxml::LN_CT_Style_type is STYLE_TYPE_TABLE first.
476 And all this overdesigned machinery doesn't even give a reasonable
477 way to find out if an attribute is there before encountering it
478 in random order in lcl_attribute(), so just make sure here that
479 the attribute comes first.
481 if( pProperty
->getId() == NS_ooxml::LN_CT_Style_type
)
482 mProperties
.insert( mProperties
.begin(), pProperty
);
484 mProperties
.push_back(pProperty
);
486 #ifdef DEBUG_PROPERTY_SET
489 debug_logger
->element("warning.property_not_added");
492 debug_logger
->endElement("propertyset.add");
496 void OOXMLPropertySetImpl::add(OOXMLPropertySet::Pointer_t pPropertySet
)
498 if (pPropertySet
.get() != NULL
)
500 OOXMLPropertySetImpl
* pSet
=
501 dynamic_cast<OOXMLPropertySetImpl
*>(pPropertySet
.get());
505 mProperties
.resize(mProperties
.size() + pSet
->mProperties
.size());
506 for (OOXMLProperties_t::iterator aIt
= pSet
->mProperties
.begin();
507 aIt
!= pSet
->mProperties
.end(); ++aIt
)
513 OOXMLPropertySet
* OOXMLPropertySetImpl::clone() const
515 return new OOXMLPropertySetImpl(*this);
518 void OOXMLPropertySetImpl::setType(const string
& rsType
)
523 string
OOXMLPropertySetImpl::toString()
525 string sResult
= "[";
527 snprintf(sBuffer
, sizeof(sBuffer
), "%p", this);
531 OOXMLProperties_t::iterator aItBegin
= begin();
532 OOXMLProperties_t::iterator aItEnd
= end();
534 for (OOXMLProperties_t::iterator aIt
= aItBegin
; aIt
!= aItEnd
; ++aIt
)
539 if ((*aIt
).get() != NULL
)
540 sResult
+= (*aIt
)->toString();
551 class OOXMLPropertySetValue
554 OOXMLPropertySetValue::OOXMLPropertySetValue
555 (OOXMLPropertySet::Pointer_t pPropertySet
)
556 : mpPropertySet(pPropertySet
)
560 OOXMLPropertySetValue::~OOXMLPropertySetValue()
564 writerfilter::Reference
<Properties
>::Pointer_t
OOXMLPropertySetValue::getProperties()
566 return writerfilter::Reference
<Properties
>::Pointer_t
567 (mpPropertySet
->clone());
570 string
OOXMLPropertySetValue::toString() const
574 snprintf(sBuffer
, sizeof(sBuffer
), "t:%p, m:%p", this, mpPropertySet
.get());
576 return "OOXMLPropertySetValue(" + string(sBuffer
) + ")";
579 OOXMLValue
* OOXMLPropertySetValue::clone() const
581 return new OOXMLPropertySetValue(*this);
585 class OOXMLIntegerValue
588 OOXMLIntegerValue::OOXMLIntegerValue(sal_Int32 nValue
)
593 OOXMLIntegerValue::OOXMLIntegerValue(const OUString
& rValue
)
596 mnValue
= rValue
.toInt32();
599 OOXMLIntegerValue::~OOXMLIntegerValue()
603 int OOXMLIntegerValue::getInt() const
608 uno::Any
OOXMLIntegerValue::getAny() const
610 uno::Any
aResult(mnValue
);
615 OOXMLValue
* OOXMLIntegerValue::clone() const
617 return new OOXMLIntegerValue(*this);
620 string
OOXMLIntegerValue::toString() const
623 snprintf(buffer
, sizeof(buffer
), "%" SAL_PRIdINT32
, mnValue
);
632 OOXMLHexValue::OOXMLHexValue(sal_uInt32 nValue
)
637 OOXMLHexValue::OOXMLHexValue(const OUString
& rValue
)
639 mnValue
= static_cast<sal_uInt32
>(rValue
.toInt32(16));
642 OOXMLHexValue::~OOXMLHexValue()
646 int OOXMLHexValue::getInt() const
651 OOXMLValue
* OOXMLHexValue::clone() const
653 return new OOXMLHexValue(*this);
656 string
OOXMLHexValue::toString() const
659 snprintf(buffer
, sizeof(buffer
), "0x%" SAL_PRIxUINT32
, mnValue
);
665 class OOXMLShapeValue
669 OOXMLShapeValue::OOXMLShapeValue(uno::Reference
<XShape
> rShape
)
674 OOXMLShapeValue::~OOXMLShapeValue()
678 uno::Any
OOXMLShapeValue::getAny() const
680 return uno::Any(mrShape
);
683 string
OOXMLShapeValue::toString() const
688 OOXMLValue
* OOXMLShapeValue::clone() const
690 return new OOXMLShapeValue(mrShape
);
694 class OOXMLStarMathValue
698 OOXMLStarMathValue::OOXMLStarMathValue( uno::Reference
< embed::XEmbeddedObject
> c
)
703 OOXMLStarMathValue::~OOXMLStarMathValue()
707 uno::Any
OOXMLStarMathValue::getAny() const
709 return uno::Any(component
);
712 string
OOXMLStarMathValue::toString() const
717 OOXMLValue
* OOXMLStarMathValue::clone() const
719 return new OOXMLStarMathValue( component
);
726 OOXMLTableImpl::OOXMLTableImpl()
730 OOXMLTableImpl::~OOXMLTableImpl()
734 void OOXMLTableImpl::resolve(Table
& rTable
)
736 #ifdef DEBUG_PROTOCOL
737 Table::Pointer_t
pTable(new TableProtocol(&rTable
, debug_logger
));
739 Table
* pTable
= &rTable
;
744 PropertySets_t::iterator it
= mPropertySets
.begin();
745 PropertySets_t::iterator itEnd
= mPropertySets
.end();
749 writerfilter::Reference
<Properties
>::Pointer_t pProperties
750 ((*it
)->getProperties());
752 if (pProperties
.get() != NULL
)
753 pTable
->entry(nPos
, pProperties
);
760 void OOXMLTableImpl::add(ValuePointer_t pPropertySet
)
762 if (pPropertySet
.get() != NULL
)
763 mPropertySets
.push_back(pPropertySet
);
766 string
OOXMLTableImpl::getType() const
768 return "OOXMLTableImpl";
771 OOXMLTable
* OOXMLTableImpl::clone() const
773 return new OOXMLTableImpl(*this);
777 class: OOXMLPropertySetEntryToString
780 OOXMLPropertySetEntryToString::OOXMLPropertySetEntryToString(Id nId
)
785 OOXMLPropertySetEntryToString::~OOXMLPropertySetEntryToString()
789 void OOXMLPropertySetEntryToString::sprm(Sprm
& /*rSprm*/)
793 void OOXMLPropertySetEntryToString::attribute(Id nId
, Value
& rValue
)
796 mStr
= rValue
.getString();
799 const OUString
& OOXMLPropertySetEntryToString::getString() const
804 OOXMLPropertySetEntryToInteger::OOXMLPropertySetEntryToInteger(Id nId
)
805 : mnId(nId
), mnValue(0)
809 OOXMLPropertySetEntryToInteger::~OOXMLPropertySetEntryToInteger()
813 void OOXMLPropertySetEntryToInteger::sprm(Sprm
& /*rSprm*/)
817 void OOXMLPropertySetEntryToInteger::attribute(Id nId
, Value
& rValue
)
820 mnValue
= rValue
.getInt();
823 int OOXMLPropertySetEntryToInteger::getValue() const
830 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */