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 <sax/tools/converter.hxx>
26 #include <tools/color.hxx>
28 namespace writerfilter::ooxml
30 using namespace ::std
;
31 using namespace com::sun::star
;
33 OOXMLProperty::OOXMLProperty(Id id
, const OOXMLValue::Pointer_t
& pValue
,
34 OOXMLProperty::Type_t eType
)
35 : mId(id
), mpValue(pValue
), meType(eType
)
39 OOXMLProperty::~OOXMLProperty()
43 sal_uInt32
OOXMLProperty::getId() const
48 Value::Pointer_t
OOXMLProperty::getValue()
50 Value::Pointer_t pResult
;
53 pResult
= Value::Pointer_t(mpValue
->clone());
55 pResult
= Value::Pointer_t(new OOXMLValue());
60 writerfilter::Reference
<Properties
>::Pointer_t
OOXMLProperty::getProps()
62 writerfilter::Reference
<Properties
>::Pointer_t pResult
;
65 pResult
= mpValue
->getProperties();
71 string
OOXMLProperty::getName() const
73 string
sResult(QNameToString(mId
));
75 if (sResult
.length() == 0)
76 sResult
= fastTokenToId(mId
);
78 if (sResult
.length() == 0)
80 static char sBuffer
[256];
82 snprintf(sBuffer
, sizeof(sBuffer
), "%" SAL_PRIxUINT32
, mId
);
91 string
OOXMLProperty::toString() const
98 sResult
+= mpValue
->toString();
107 void OOXMLProperty::resolve(writerfilter::Properties
& rProperties
)
113 rProperties
.sprm(*this);
116 rProperties
.attribute(mId
, *getValue());
125 OOXMLValue::OOXMLValue()
129 OOXMLValue::~OOXMLValue()
133 int OOXMLValue::getInt() const
138 OUString
OOXMLValue::getString() const
143 uno::Any
OOXMLValue::getAny() const
148 writerfilter::Reference
<Properties
>::Pointer_t
OOXMLValue::getProperties()
150 return writerfilter::Reference
<Properties
>::Pointer_t();
153 writerfilter::Reference
<BinaryObj
>::Pointer_t
OOXMLValue::getBinary()
155 return writerfilter::Reference
<BinaryObj
>::Pointer_t();
159 string
OOXMLValue::toString() const
165 OOXMLValue
* OOXMLValue::clone() const
167 return new OOXMLValue(*this);
171 class OOXMLBinaryValue
174 OOXMLBinaryValue::OOXMLBinaryValue(OOXMLBinaryObjectReference::Pointer_t
const &
176 : mpBinaryObj(pBinaryObj
)
180 OOXMLBinaryValue::~OOXMLBinaryValue()
184 writerfilter::Reference
<BinaryObj
>::Pointer_t
OOXMLBinaryValue::getBinary()
190 string
OOXMLBinaryValue::toString() const
196 OOXMLValue
* OOXMLBinaryValue::clone() const
198 return new OOXMLBinaryValue(mpBinaryObj
);
202 class OOXMLBooleanValue
205 static bool GetBooleanValue(const char *pValue
)
207 return !strcmp(pValue
, "true")
208 || !strcmp(pValue
, "True")
209 || !strcmp(pValue
, "1")
210 || !strcmp(pValue
, "on")
211 || !strcmp(pValue
, "On");
214 OOXMLValue::Pointer_t
const & OOXMLBooleanValue::Create(bool bValue
)
216 static OOXMLValue::Pointer_t
False(new OOXMLBooleanValue (false));
217 static OOXMLValue::Pointer_t
True(new OOXMLBooleanValue (true));
219 return bValue
? True
: False
;
222 OOXMLValue::Pointer_t
const & OOXMLBooleanValue::Create(const char *pValue
)
224 return Create (GetBooleanValue(pValue
));
227 OOXMLBooleanValue::OOXMLBooleanValue(bool bValue
)
232 OOXMLBooleanValue::~OOXMLBooleanValue()
236 int OOXMLBooleanValue::getInt() const
238 return mbValue
? 1 : 0;
241 uno::Any
OOXMLBooleanValue::getAny() const
243 return uno::Any(mbValue
);
247 string
OOXMLBooleanValue::toString() const
249 return mbValue
? "true" : "false";
253 OOXMLValue
* OOXMLBooleanValue::clone() const
255 return new OOXMLBooleanValue(*this);
259 class OOXMLStringValue
262 OOXMLStringValue::OOXMLStringValue(const OUString
& rStr
)
267 OOXMLStringValue::~OOXMLStringValue()
271 uno::Any
OOXMLStringValue::getAny() const
273 return uno::Any(mStr
);
276 OUString
OOXMLStringValue::getString() const
282 string
OOXMLStringValue::toString() const
284 return OUStringToOString(mStr
, RTL_TEXTENCODING_ASCII_US
).getStr();
288 OOXMLValue
* OOXMLStringValue::clone() const
290 return new OOXMLStringValue(*this);
294 class OOXMLInputStreamValue
296 OOXMLInputStreamValue::OOXMLInputStreamValue(uno::Reference
<io::XInputStream
> const & xInputStream
)
297 : mxInputStream(xInputStream
)
301 OOXMLInputStreamValue::~OOXMLInputStreamValue()
305 uno::Any
OOXMLInputStreamValue::getAny() const
307 return uno::Any(mxInputStream
);
311 string
OOXMLInputStreamValue::toString() const
313 return "InputStream";
317 OOXMLValue
* OOXMLInputStreamValue::clone() const
319 return new OOXMLInputStreamValue(mxInputStream
);
323 class OOXMLPropertySet
326 OOXMLPropertySet::OOXMLPropertySet()
330 OOXMLPropertySet::~OOXMLPropertySet()
334 void OOXMLPropertySet::resolve(Properties
& rHandler
)
336 // The pProp->resolve(rHandler) call below can cause elements to
337 // be appended to mProperties. I don't think it can cause elements
338 // to be deleted. But let's check with < here just to be safe that
339 // the indexing below works.
340 for (size_t nIt
= 0; nIt
< mProperties
.size(); ++nIt
)
342 OOXMLProperty::Pointer_t pProp
= mProperties
[nIt
];
345 pProp
->resolve(rHandler
);
349 OOXMLPropertySet::OOXMLProperties_t::iterator
OOXMLPropertySet::begin()
351 return mProperties
.begin();
354 OOXMLPropertySet::OOXMLProperties_t::iterator
OOXMLPropertySet::end()
356 return mProperties
.end();
359 OOXMLPropertySet::OOXMLProperties_t::const_iterator
360 OOXMLPropertySet::begin() const
362 return mProperties
.begin();
365 OOXMLPropertySet::OOXMLProperties_t::const_iterator
366 OOXMLPropertySet::end() const
368 return mProperties
.end();
371 void OOXMLPropertySet::add(const OOXMLProperty::Pointer_t
& pProperty
)
373 if (pProperty
&& pProperty
->getId() != 0x0)
375 mProperties
.push_back(pProperty
);
379 void OOXMLPropertySet::add(Id id
, const OOXMLValue::Pointer_t
& pValue
, OOXMLProperty::Type_t eType
)
381 OOXMLProperty::Pointer_t
pProperty(new OOXMLProperty(id
, pValue
, eType
));
385 void OOXMLPropertySet::add(const OOXMLPropertySet::Pointer_t
& pPropertySet
)
387 const OOXMLPropertySet
* pSet
= pPropertySet
.get();
391 mProperties
.insert( mProperties
.end(), pSet
->mProperties
.begin(), pSet
->mProperties
.end() );
395 OOXMLPropertySet
* OOXMLPropertySet::clone() const
397 return new OOXMLPropertySet(*this);
401 string
OOXMLPropertySet::toString()
403 string sResult
= "[";
405 snprintf(sBuffer
, sizeof(sBuffer
), "%p", this);
409 OOXMLProperties_t::iterator aItBegin
= begin();
410 OOXMLProperties_t::iterator aItEnd
= end();
412 for (OOXMLProperties_t::iterator aIt
= aItBegin
; aIt
!= aItEnd
; ++aIt
)
418 sResult
+= (*aIt
)->toString();
430 class OOXMLPropertySetValue
433 OOXMLPropertySetValue::OOXMLPropertySetValue(const OOXMLPropertySet::Pointer_t
& pPropertySet
)
434 : mpPropertySet(pPropertySet
)
438 OOXMLPropertySetValue::~OOXMLPropertySetValue()
442 writerfilter::Reference
<Properties
>::Pointer_t
OOXMLPropertySetValue::getProperties()
444 return writerfilter::Reference
<Properties
>::Pointer_t
445 (mpPropertySet
->clone());
449 string
OOXMLPropertySetValue::toString() const
453 snprintf(sBuffer
, sizeof(sBuffer
), "t:%p, m:%p", this, mpPropertySet
.get());
455 return "OOXMLPropertySetValue(" + string(sBuffer
) + ")";
459 OOXMLValue
* OOXMLPropertySetValue::clone() const
461 return new OOXMLPropertySetValue(*this);
465 class OOXMLIntegerValue
468 OOXMLValue::Pointer_t
OOXMLIntegerValue::Create(sal_Int32 nValue
)
470 static OOXMLValue::Pointer_t
Zero(new OOXMLIntegerValue (0));
471 static OOXMLValue::Pointer_t
One(new OOXMLIntegerValue (1));
472 static OOXMLValue::Pointer_t
Two(new OOXMLIntegerValue (2));
473 static OOXMLValue::Pointer_t
Three(new OOXMLIntegerValue (3));
474 static OOXMLValue::Pointer_t
Four(new OOXMLIntegerValue (4));
475 static OOXMLValue::Pointer_t
Five(new OOXMLIntegerValue (5));
476 static OOXMLValue::Pointer_t
Six(new OOXMLIntegerValue (6));
477 static OOXMLValue::Pointer_t
Seven(new OOXMLIntegerValue (7));
478 static OOXMLValue::Pointer_t
Eight(new OOXMLIntegerValue (8));
479 static OOXMLValue::Pointer_t
Nine(new OOXMLIntegerValue (9));
485 case 3: return Three
;
489 case 7: return Seven
;
490 case 8: return Eight
;
495 OOXMLValue::Pointer_t
value(new OOXMLIntegerValue(nValue
));
500 OOXMLIntegerValue::OOXMLIntegerValue(sal_Int32 nValue
)
505 OOXMLIntegerValue::~OOXMLIntegerValue()
509 int OOXMLIntegerValue::getInt() const
514 uno::Any
OOXMLIntegerValue::getAny() const
516 return uno::Any(mnValue
);
519 OOXMLValue
* OOXMLIntegerValue::clone() const
521 return new OOXMLIntegerValue(*this);
525 string
OOXMLIntegerValue::toString() const
528 snprintf(buffer
, sizeof(buffer
), "%" SAL_PRIdINT32
, mnValue
);
538 OOXMLHexValue::OOXMLHexValue(sal_uInt32 nValue
)
543 OOXMLHexValue::OOXMLHexValue(const char * pValue
)
544 : mnValue(rtl_str_toUInt32(pValue
, 16))
548 OOXMLHexValue::~OOXMLHexValue()
552 int OOXMLHexValue::getInt() const
557 OOXMLValue
* OOXMLHexValue::clone() const
559 return new OOXMLHexValue(*this);
563 string
OOXMLHexValue::toString() const
566 snprintf(buffer
, sizeof(buffer
), "0x%" SAL_PRIxUINT32
, mnValue
);
573 class OOXMLHexColorValue
575 OOXMLHexColorValue::OOXMLHexColorValue(const char * pValue
)
576 : OOXMLHexValue(sal_uInt32(COL_AUTO
))
578 if (!strcmp(pValue
, "auto"))
581 mnValue
= rtl_str_toUInt32(pValue
, 16);
583 // Convert hash-encoded values (like #FF0080)
584 const sal_Int32 nLen
= strlen(pValue
);
585 if ( !mnValue
&& nLen
> 1 && pValue
[0] == '#' )
587 sal_Int32
nColor(COL_AUTO
);
588 // Word appears to require strict 6 digit length, else it ignores it
591 const OUString
sHashColor(pValue
, nLen
, RTL_TEXTENCODING_ASCII_US
);
592 sax::Converter::convertColor( nColor
, sHashColor
);
598 // OOXMLUniversalMeasureValue
599 // ECMA-376 5th ed. Part 1 , 22.9.2.15
600 OOXMLUniversalMeasureValue::OOXMLUniversalMeasureValue(const char * pValue
, sal_uInt32 npPt
)
602 double val
= rtl_str_toDouble(pValue
); // will ignore the trailing unit
604 int nLen
= strlen(pValue
);
606 pValue
[nLen
-2] == 'p' &&
607 pValue
[nLen
-1] == 't')
609 mnValue
= static_cast<int>(val
* npPt
);
612 pValue
[nLen
- 2] == 'c' &&
613 pValue
[nLen
- 1] == 'm')
615 mnValue
= static_cast<int>(val
* npPt
* 72 / 2.54);
618 pValue
[nLen
- 2] == 'm' &&
619 pValue
[nLen
- 1] == 'm')
621 mnValue
= static_cast<int>(val
* npPt
* 72 / 25.4);
624 pValue
[nLen
- 2] == 'i' &&
625 pValue
[nLen
- 1] == 'n')
627 mnValue
= static_cast<int>(val
* npPt
* 72);
630 pValue
[nLen
- 2] == 'p' &&
631 ( pValue
[nLen
- 1] == 'c' || pValue
[nLen
- 1] == 'i' ))
633 mnValue
= static_cast<int>(val
* npPt
* 12);
637 mnValue
= static_cast<int>(val
);
641 OOXMLUniversalMeasureValue::~OOXMLUniversalMeasureValue()
645 int OOXMLUniversalMeasureValue::getInt() const
651 string
OOXMLUniversalMeasureValue::toString() const
653 return OString::number(mnValue
).getStr();
657 // OOXMLMeasurementOrPercentValue
658 // ECMA-376 5th ed. Part 1 , 17.18.107; 17.18.11
659 OOXMLMeasurementOrPercentValue::OOXMLMeasurementOrPercentValue(const char * pValue
)
661 double val
= rtl_str_toDouble(pValue
); // will ignore the trailing unit
663 int nLen
= strlen(pValue
);
665 pValue
[nLen
- 1] == '%')
667 mnValue
= static_cast<int>(val
* 50);
671 mnValue
= OOXMLTwipsMeasureValue(pValue
).getInt();
675 int OOXMLMeasurementOrPercentValue::getInt() const
681 string
OOXMLMeasurementOrPercentValue::toString() const
683 return OString::number(mnValue
).getStr();
688 class OOXMLShapeValue
692 OOXMLShapeValue::OOXMLShapeValue(uno::Reference
<drawing::XShape
> const & rShape
)
697 OOXMLShapeValue::~OOXMLShapeValue()
701 uno::Any
OOXMLShapeValue::getAny() const
703 return uno::Any(mrShape
);
707 string
OOXMLShapeValue::toString() const
713 OOXMLValue
* OOXMLShapeValue::clone() const
715 return new OOXMLShapeValue(mrShape
);
719 class OOXMLStarMathValue
723 OOXMLStarMathValue::OOXMLStarMathValue( uno::Reference
< embed::XEmbeddedObject
> const & c
)
728 OOXMLStarMathValue::~OOXMLStarMathValue()
732 uno::Any
OOXMLStarMathValue::getAny() const
734 return uno::Any(component
);
738 string
OOXMLStarMathValue::toString() const
744 OOXMLValue
* OOXMLStarMathValue::clone() const
746 return new OOXMLStarMathValue( component
);
753 OOXMLTable::OOXMLTable()
757 OOXMLTable::~OOXMLTable()
762 void OOXMLTable::resolve(Table
& rTable
)
764 Table
* pTable
= &rTable
;
768 for (const auto& rPropSet
: mPropertySets
)
770 writerfilter::Reference
<Properties
>::Pointer_t pProperties
771 (rPropSet
->getProperties());
774 pTable
->entry(nPos
, pProperties
);
780 void OOXMLTable::add(const ValuePointer_t
& pPropertySet
)
783 mPropertySets
.push_back(pPropertySet
);
786 OOXMLTable
* OOXMLTable::clone() const
788 return new OOXMLTable(*this);
792 class: OOXMLPropertySetEntryToString
795 OOXMLPropertySetEntryToString::OOXMLPropertySetEntryToString(Id nId
)
800 OOXMLPropertySetEntryToString::~OOXMLPropertySetEntryToString()
804 void OOXMLPropertySetEntryToString::sprm(Sprm
& /*rSprm*/)
808 void OOXMLPropertySetEntryToString::attribute(Id nId
, Value
& rValue
)
811 mStr
= rValue
.getString();
815 class: OOXMLPropertySetEntryToInteger
818 OOXMLPropertySetEntryToInteger::OOXMLPropertySetEntryToInteger(Id nId
)
819 : mnId(nId
), mnValue(0)
823 OOXMLPropertySetEntryToInteger::~OOXMLPropertySetEntryToInteger()
827 void OOXMLPropertySetEntryToInteger::sprm(Sprm
& /*rSprm*/)
831 void OOXMLPropertySetEntryToInteger::attribute(Id nId
, Value
& rValue
)
834 mnValue
= rValue
.getInt();
838 class: OOXMLPropertySetEntryToBool
841 OOXMLPropertySetEntryToBool::OOXMLPropertySetEntryToBool(Id nId
)
842 : mnId(nId
), mValue(false)
845 OOXMLPropertySetEntryToBool::~OOXMLPropertySetEntryToBool() {}
847 void OOXMLPropertySetEntryToBool::sprm(Sprm
& /*rSprm*/) {}
849 void OOXMLPropertySetEntryToBool::attribute(Id nId
, Value
& rValue
)
852 mValue
= (rValue
.getInt() != 0);
857 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */