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 "OOXMLPropertySet.hxx"
23 #include <ooxml/QNameToString.hxx>
24 #include <com/sun/star/drawing/XShape.hpp>
25 #include <oox/token/tokens.hxx>
26 #include <sax/tools/converter.hxx>
27 #include <tools/color.hxx>
29 namespace writerfilter
{
32 using namespace ::std
;
33 using namespace com::sun::star
;
35 OOXMLProperty::OOXMLProperty(Id id
, const OOXMLValue::Pointer_t
& pValue
,
36 OOXMLProperty::Type_t eType
)
37 : mId(id
), mpValue(pValue
), meType(eType
)
41 OOXMLProperty::~OOXMLProperty()
45 sal_uInt32
OOXMLProperty::getId() const
50 Value::Pointer_t
OOXMLProperty::getValue()
52 Value::Pointer_t pResult
;
54 if (mpValue
.get() != nullptr)
55 pResult
= Value::Pointer_t(mpValue
->clone());
57 pResult
= Value::Pointer_t(new OOXMLValue());
62 writerfilter::Reference
<Properties
>::Pointer_t
OOXMLProperty::getProps()
64 writerfilter::Reference
<Properties
>::Pointer_t pResult
;
66 if (mpValue
.get() != nullptr)
67 pResult
= mpValue
->getProperties();
73 string
OOXMLProperty::getName() const
75 string
sResult((*QNameToString::Instance())(mId
));
77 if (sResult
.length() == 0)
78 sResult
= fastTokenToId(mId
);
80 if (sResult
.length() == 0)
82 static char sBuffer
[256];
84 snprintf(sBuffer
, sizeof(sBuffer
), "%" SAL_PRIxUINT32
, mId
);
93 string
OOXMLProperty::toString() const
99 if (mpValue
.get() != nullptr)
100 sResult
+= mpValue
->toString();
109 void OOXMLProperty::resolve(writerfilter::Properties
& rProperties
)
115 rProperties
.sprm(*this);
118 rProperties
.attribute(mId
, *getValue());
127 OOXMLValue::OOXMLValue()
131 OOXMLValue::~OOXMLValue()
135 int OOXMLValue::getInt() const
140 OUString
OOXMLValue::getString() const
145 uno::Any
OOXMLValue::getAny() const
150 writerfilter::Reference
<Properties
>::Pointer_t
OOXMLValue::getProperties()
152 return writerfilter::Reference
<Properties
>::Pointer_t();
155 writerfilter::Reference
<BinaryObj
>::Pointer_t
OOXMLValue::getBinary()
157 return writerfilter::Reference
<BinaryObj
>::Pointer_t();
161 string
OOXMLValue::toString() const
167 OOXMLValue
* OOXMLValue::clone() const
169 return new OOXMLValue(*this);
173 class OOXMLBinaryValue
176 OOXMLBinaryValue::OOXMLBinaryValue(OOXMLBinaryObjectReference::Pointer_t
const &
178 : mpBinaryObj(pBinaryObj
)
182 OOXMLBinaryValue::~OOXMLBinaryValue()
186 writerfilter::Reference
<BinaryObj
>::Pointer_t
OOXMLBinaryValue::getBinary()
192 string
OOXMLBinaryValue::toString() const
198 OOXMLValue
* OOXMLBinaryValue::clone() const
200 return new OOXMLBinaryValue(mpBinaryObj
);
204 class OOXMLBooleanValue
207 static bool GetBooleanValue(const char *pValue
)
209 return !strcmp(pValue
, "true")
210 || !strcmp(pValue
, "True")
211 || !strcmp(pValue
, "1")
212 || !strcmp(pValue
, "on")
213 || !strcmp(pValue
, "On");
216 OOXMLValue::Pointer_t
const & OOXMLBooleanValue::Create(bool bValue
)
218 static OOXMLValue::Pointer_t
False(new OOXMLBooleanValue (false));
219 static OOXMLValue::Pointer_t
True(new OOXMLBooleanValue (true));
221 return bValue
? True
: False
;
224 OOXMLValue::Pointer_t
const & OOXMLBooleanValue::Create(const char *pValue
)
226 return Create (GetBooleanValue(pValue
));
229 OOXMLBooleanValue::OOXMLBooleanValue(bool bValue
)
234 OOXMLBooleanValue::~OOXMLBooleanValue()
238 int OOXMLBooleanValue::getInt() const
240 return mbValue
? 1 : 0;
243 uno::Any
OOXMLBooleanValue::getAny() const
245 return uno::Any(mbValue
);
249 string
OOXMLBooleanValue::toString() const
251 return mbValue
? "true" : "false";
255 OOXMLValue
* OOXMLBooleanValue::clone() const
257 return new OOXMLBooleanValue(*this);
261 class OOXMLStringValue
264 OOXMLStringValue::OOXMLStringValue(const OUString
& rStr
)
269 OOXMLStringValue::~OOXMLStringValue()
273 uno::Any
OOXMLStringValue::getAny() const
275 return uno::Any(mStr
);
278 OUString
OOXMLStringValue::getString() const
284 string
OOXMLStringValue::toString() const
286 return OUStringToOString(mStr
, RTL_TEXTENCODING_ASCII_US
).getStr();
290 OOXMLValue
* OOXMLStringValue::clone() const
292 return new OOXMLStringValue(*this);
296 class OOXMLInputStreamValue
298 OOXMLInputStreamValue::OOXMLInputStreamValue(uno::Reference
<io::XInputStream
> const & xInputStream
)
299 : mxInputStream(xInputStream
)
303 OOXMLInputStreamValue::~OOXMLInputStreamValue()
307 uno::Any
OOXMLInputStreamValue::getAny() const
309 return uno::Any(mxInputStream
);
313 string
OOXMLInputStreamValue::toString() const
315 return "InputStream";
319 OOXMLValue
* OOXMLInputStreamValue::clone() const
321 return new OOXMLInputStreamValue(mxInputStream
);
325 class OOXMLPropertySet
328 OOXMLPropertySet::OOXMLPropertySet()
332 OOXMLPropertySet::~OOXMLPropertySet()
336 void OOXMLPropertySet::resolve(Properties
& rHandler
)
338 // The pProp->resolve(rHandler) call below can cause elements to
339 // be appended to mProperties. I don't think it can cause elements
340 // to be deleted. But let's check with < here just to be safe that
341 // the indexing below works.
342 for (size_t nIt
= 0; nIt
< mProperties
.size(); ++nIt
)
344 OOXMLProperty::Pointer_t pProp
= mProperties
[nIt
];
346 if (pProp
.get() != nullptr)
347 pProp
->resolve(rHandler
);
351 OOXMLPropertySet::OOXMLProperties_t::iterator
OOXMLPropertySet::begin()
353 return mProperties
.begin();
356 OOXMLPropertySet::OOXMLProperties_t::iterator
OOXMLPropertySet::end()
358 return mProperties
.end();
361 OOXMLPropertySet::OOXMLProperties_t::const_iterator
362 OOXMLPropertySet::begin() const
364 return mProperties
.begin();
367 OOXMLPropertySet::OOXMLProperties_t::const_iterator
368 OOXMLPropertySet::end() const
370 return mProperties
.end();
373 void OOXMLPropertySet::add(const OOXMLProperty::Pointer_t
& pProperty
)
375 if (pProperty
.get() != nullptr && pProperty
->getId() != 0x0)
377 mProperties
.push_back(pProperty
);
381 void OOXMLPropertySet::add(Id id
, const OOXMLValue::Pointer_t
& pValue
, OOXMLProperty::Type_t eType
)
383 OOXMLProperty::Pointer_t
pProperty(new OOXMLProperty(id
, pValue
, eType
));
387 void OOXMLPropertySet::add(const OOXMLPropertySet::Pointer_t
& pPropertySet
)
389 const OOXMLPropertySet
* pSet
= pPropertySet
.get();
393 int x
= mProperties
.size();
394 mProperties
.resize(mProperties
.size() + pSet
->mProperties
.size());
395 std::copy(pSet
->mProperties
.begin(), pSet
->mProperties
.end(), mProperties
.begin() + x
);
399 OOXMLPropertySet
* OOXMLPropertySet::clone() const
401 return new OOXMLPropertySet(*this);
405 string
OOXMLPropertySet::toString()
407 string sResult
= "[";
409 snprintf(sBuffer
, sizeof(sBuffer
), "%p", this);
413 OOXMLProperties_t::iterator aItBegin
= begin();
414 OOXMLProperties_t::iterator aItEnd
= end();
416 for (OOXMLProperties_t::iterator aIt
= aItBegin
; aIt
!= aItEnd
; ++aIt
)
421 if ((*aIt
).get() != nullptr)
422 sResult
+= (*aIt
)->toString();
434 class OOXMLPropertySetValue
437 OOXMLPropertySetValue::OOXMLPropertySetValue(const OOXMLPropertySet::Pointer_t
& pPropertySet
)
438 : mpPropertySet(pPropertySet
)
442 OOXMLPropertySetValue::~OOXMLPropertySetValue()
446 writerfilter::Reference
<Properties
>::Pointer_t
OOXMLPropertySetValue::getProperties()
448 return writerfilter::Reference
<Properties
>::Pointer_t
449 (mpPropertySet
->clone());
453 string
OOXMLPropertySetValue::toString() const
457 snprintf(sBuffer
, sizeof(sBuffer
), "t:%p, m:%p", this, mpPropertySet
.get());
459 return "OOXMLPropertySetValue(" + string(sBuffer
) + ")";
463 OOXMLValue
* OOXMLPropertySetValue::clone() const
465 return new OOXMLPropertySetValue(*this);
469 class OOXMLIntegerValue
472 OOXMLValue::Pointer_t
OOXMLIntegerValue::Create(sal_Int32 nValue
)
474 static OOXMLValue::Pointer_t
Zero(new OOXMLIntegerValue (0));
475 static OOXMLValue::Pointer_t
One(new OOXMLIntegerValue (1));
476 static OOXMLValue::Pointer_t
Two(new OOXMLIntegerValue (2));
477 static OOXMLValue::Pointer_t
Three(new OOXMLIntegerValue (3));
478 static OOXMLValue::Pointer_t
Four(new OOXMLIntegerValue (4));
479 static OOXMLValue::Pointer_t
Five(new OOXMLIntegerValue (5));
480 static OOXMLValue::Pointer_t
Six(new OOXMLIntegerValue (6));
481 static OOXMLValue::Pointer_t
Seven(new OOXMLIntegerValue (7));
482 static OOXMLValue::Pointer_t
Eight(new OOXMLIntegerValue (8));
483 static OOXMLValue::Pointer_t
Nine(new OOXMLIntegerValue (9));
489 case 3: return Three
;
493 case 7: return Seven
;
494 case 8: return Eight
;
499 OOXMLValue::Pointer_t
value(new OOXMLIntegerValue(nValue
));
504 OOXMLIntegerValue::OOXMLIntegerValue(sal_Int32 nValue
)
509 OOXMLIntegerValue::~OOXMLIntegerValue()
513 int OOXMLIntegerValue::getInt() const
518 uno::Any
OOXMLIntegerValue::getAny() const
520 return uno::Any(mnValue
);
523 OOXMLValue
* OOXMLIntegerValue::clone() const
525 return new OOXMLIntegerValue(*this);
529 string
OOXMLIntegerValue::toString() const
532 snprintf(buffer
, sizeof(buffer
), "%" SAL_PRIdINT32
, mnValue
);
542 OOXMLHexValue::OOXMLHexValue(sal_uInt32 nValue
)
547 OOXMLHexValue::OOXMLHexValue(const char * pValue
)
548 : mnValue(rtl_str_toUInt32(pValue
, 16))
552 OOXMLHexValue::~OOXMLHexValue()
556 int OOXMLHexValue::getInt() const
561 OOXMLValue
* OOXMLHexValue::clone() const
563 return new OOXMLHexValue(*this);
567 string
OOXMLHexValue::toString() const
570 snprintf(buffer
, sizeof(buffer
), "0x%" SAL_PRIxUINT32
, mnValue
);
577 class OOXMLHexColorValue
579 OOXMLHexColorValue::OOXMLHexColorValue(const char * pValue
)
580 : OOXMLHexValue(sal_uInt32(COL_AUTO
))
582 if (strcmp(pValue
, "auto"))
584 mnValue
= rtl_str_toUInt32(pValue
, 16);
586 // Convert hash-encoded values (like #FF0080)
587 const sal_Int32 nLen
= strlen(pValue
);
588 if ( !mnValue
&& nLen
> 1 && pValue
[0] == '#' )
590 sal_Int32
nColor(COL_AUTO
);
591 // Word appears to require strict 6 digit length, else it ignores it
594 const OUString
sHashColor(pValue
, nLen
, RTL_TEXTENCODING_ASCII_US
);
595 sax::Converter::convertColor( nColor
, sHashColor
);
602 // OOXMLUniversalMeasureValue
603 // ECMA-376 5th ed. Part 1 , 22.9.2.15
604 OOXMLUniversalMeasureValue::OOXMLUniversalMeasureValue(const char * pValue
, sal_uInt32 npPt
)
606 double val
= rtl_str_toDouble(pValue
); // will ignore the trailing unit
608 int nLen
= strlen(pValue
);
610 pValue
[nLen
-2] == 'p' &&
611 pValue
[nLen
-1] == 't')
613 mnValue
= static_cast<int>(val
* npPt
);
616 pValue
[nLen
- 2] == 'c' &&
617 pValue
[nLen
- 1] == 'm')
619 mnValue
= static_cast<int>(val
* npPt
* 72 / 2.54);
622 pValue
[nLen
- 2] == 'm' &&
623 pValue
[nLen
- 1] == 'm')
625 mnValue
= static_cast<int>(val
* npPt
* 72 / 25.4);
628 pValue
[nLen
- 2] == 'i' &&
629 pValue
[nLen
- 1] == 'n')
631 mnValue
= static_cast<int>(val
* npPt
* 72);
634 pValue
[nLen
- 2] == 'p' &&
635 ( pValue
[nLen
- 1] == 'c' || pValue
[nLen
- 1] == 'i' ))
637 mnValue
= static_cast<int>(val
* npPt
* 12);
641 mnValue
= static_cast<int>(val
);
645 OOXMLUniversalMeasureValue::~OOXMLUniversalMeasureValue()
649 int OOXMLUniversalMeasureValue::getInt() const
655 string
OOXMLUniversalMeasureValue::toString() const
657 return OString::number(mnValue
).getStr();
661 // OOXMLMeasurementOrPercentValue
662 // ECMA-376 5th ed. Part 1 , 17.18.107; 17.18.11
663 OOXMLMeasurementOrPercentValue::OOXMLMeasurementOrPercentValue(const char * pValue
)
665 double val
= rtl_str_toDouble(pValue
); // will ignore the trailing unit
667 int nLen
= strlen(pValue
);
669 pValue
[nLen
- 1] == '%')
671 mnValue
= static_cast<int>(val
* 50);
675 mnValue
= OOXMLTwipsMeasureValue(pValue
).getInt();
679 int OOXMLMeasurementOrPercentValue::getInt() const
685 string
OOXMLMeasurementOrPercentValue::toString() const
687 return OString::number(mnValue
).getStr();
692 class OOXMLShapeValue
696 OOXMLShapeValue::OOXMLShapeValue(uno::Reference
<drawing::XShape
> const & rShape
)
701 OOXMLShapeValue::~OOXMLShapeValue()
705 uno::Any
OOXMLShapeValue::getAny() const
707 return uno::Any(mrShape
);
711 string
OOXMLShapeValue::toString() const
717 OOXMLValue
* OOXMLShapeValue::clone() const
719 return new OOXMLShapeValue(mrShape
);
723 class OOXMLStarMathValue
727 OOXMLStarMathValue::OOXMLStarMathValue( uno::Reference
< embed::XEmbeddedObject
> const & c
)
732 OOXMLStarMathValue::~OOXMLStarMathValue()
736 uno::Any
OOXMLStarMathValue::getAny() const
738 return uno::Any(component
);
742 string
OOXMLStarMathValue::toString() const
748 OOXMLValue
* OOXMLStarMathValue::clone() const
750 return new OOXMLStarMathValue( component
);
757 OOXMLTable::OOXMLTable()
761 OOXMLTable::~OOXMLTable()
766 void OOXMLTable::resolve(Table
& rTable
)
768 Table
* pTable
= &rTable
;
772 for (const auto& rPropSet
: mPropertySets
)
774 writerfilter::Reference
<Properties
>::Pointer_t pProperties
775 (rPropSet
->getProperties());
777 if (pProperties
.get() != nullptr)
778 pTable
->entry(nPos
, pProperties
);
784 void OOXMLTable::add(const ValuePointer_t
& pPropertySet
)
786 if (pPropertySet
.get() != nullptr)
787 mPropertySets
.push_back(pPropertySet
);
790 OOXMLTable
* OOXMLTable::clone() const
792 return new OOXMLTable(*this);
796 class: OOXMLPropertySetEntryToString
799 OOXMLPropertySetEntryToString::OOXMLPropertySetEntryToString(Id nId
)
804 OOXMLPropertySetEntryToString::~OOXMLPropertySetEntryToString()
808 void OOXMLPropertySetEntryToString::sprm(Sprm
& /*rSprm*/)
812 void OOXMLPropertySetEntryToString::attribute(Id nId
, Value
& rValue
)
815 mStr
= rValue
.getString();
819 class: OOXMLPropertySetEntryToInteger
822 OOXMLPropertySetEntryToInteger::OOXMLPropertySetEntryToInteger(Id nId
)
823 : mnId(nId
), mnValue(0)
827 OOXMLPropertySetEntryToInteger::~OOXMLPropertySetEntryToInteger()
831 void OOXMLPropertySetEntryToInteger::sprm(Sprm
& /*rSprm*/)
835 void OOXMLPropertySetEntryToInteger::attribute(Id nId
, Value
& rValue
)
838 mnValue
= rValue
.getInt();
842 class: OOXMLPropertySetEntryToBool
845 OOXMLPropertySetEntryToBool::OOXMLPropertySetEntryToBool(Id nId
)
846 : mnId(nId
), mValue(false)
849 OOXMLPropertySetEntryToBool::~OOXMLPropertySetEntryToBool() {}
851 void OOXMLPropertySetEntryToBool::sprm(Sprm
& /*rSprm*/) {}
853 void OOXMLPropertySetEntryToBool::attribute(Id nId
, Value
& rValue
)
856 mValue
= (rValue
.getInt() != 0);
861 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */