Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / writerfilter / source / ooxml / OOXMLPropertySet.cxx
blob2165524954a233270e95bf5f1a8cfdaac28c4c70
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
21 #include <stdio.h>
22 #include <iostream>
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 {
30 namespace ooxml
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
47 return mId;
50 Value::Pointer_t OOXMLProperty::getValue()
52 Value::Pointer_t pResult;
54 if (mpValue.get() != nullptr)
55 pResult = Value::Pointer_t(mpValue->clone());
56 else
57 pResult = Value::Pointer_t(new OOXMLValue());
59 return pResult;
62 writerfilter::Reference<Properties>::Pointer_t OOXMLProperty::getProps()
64 writerfilter::Reference<Properties>::Pointer_t pResult;
66 if (mpValue.get() != nullptr)
67 pResult = mpValue->getProperties();
69 return pResult;
72 #ifdef DBG_UTIL
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);
85 sResult = sBuffer;
88 return sResult;
90 #endif
92 #ifdef DBG_UTIL
93 string OOXMLProperty::toString() const
95 string sResult = "(";
97 sResult += getName();
98 sResult += ", ";
99 if (mpValue.get() != nullptr)
100 sResult += mpValue->toString();
101 else
102 sResult +="(null)";
103 sResult +=")";
105 return sResult;
107 #endif
109 void OOXMLProperty::resolve(writerfilter::Properties & rProperties)
111 switch (meType)
113 case SPRM:
114 if (mId != 0x0)
115 rProperties.sprm(*this);
116 break;
117 case ATTRIBUTE:
118 rProperties.attribute(mId, *getValue());
119 break;
124 class OOXMLValue
127 OOXMLValue::OOXMLValue()
131 OOXMLValue::~OOXMLValue()
135 int OOXMLValue::getInt() const
137 return 0;
140 OUString OOXMLValue::getString() const
142 return OUString();
145 uno::Any OOXMLValue::getAny() const
147 return uno::Any();
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();
160 #ifdef DBG_UTIL
161 string OOXMLValue::toString() const
163 return "OOXMLValue";
165 #endif
167 OOXMLValue * OOXMLValue::clone() const
169 return new OOXMLValue(*this);
173 class OOXMLBinaryValue
176 OOXMLBinaryValue::OOXMLBinaryValue(OOXMLBinaryObjectReference::Pointer_t const &
177 pBinaryObj)
178 : mpBinaryObj(pBinaryObj)
182 OOXMLBinaryValue::~OOXMLBinaryValue()
186 writerfilter::Reference<BinaryObj>::Pointer_t OOXMLBinaryValue::getBinary()
188 return mpBinaryObj;
191 #ifdef DBG_UTIL
192 string OOXMLBinaryValue::toString() const
194 return "BinaryObj";
196 #endif
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)
230 : mbValue(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);
248 #ifdef DBG_UTIL
249 string OOXMLBooleanValue::toString() const
251 return mbValue ? "true" : "false";
253 #endif
255 OOXMLValue * OOXMLBooleanValue::clone() const
257 return new OOXMLBooleanValue(*this);
261 class OOXMLStringValue
264 OOXMLStringValue::OOXMLStringValue(const OUString & rStr)
265 : mStr(rStr)
269 OOXMLStringValue::~OOXMLStringValue()
273 uno::Any OOXMLStringValue::getAny() const
275 return uno::Any(mStr);
278 OUString OOXMLStringValue::getString() const
280 return mStr;
283 #ifdef DBG_UTIL
284 string OOXMLStringValue::toString() const
286 return OUStringToOString(mStr, RTL_TEXTENCODING_ASCII_US).getStr();
288 #endif
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);
312 #ifdef DBG_UTIL
313 string OOXMLInputStreamValue::toString() const
315 return "InputStream";
317 #endif
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));
384 add(pProperty);
387 void OOXMLPropertySet::add(const OOXMLPropertySet::Pointer_t& pPropertySet)
389 const OOXMLPropertySet * pSet = pPropertySet.get();
391 if (pSet != nullptr)
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);
404 #ifdef DBG_UTIL
405 string OOXMLPropertySet::toString()
407 string sResult = "[";
408 char sBuffer[256];
409 snprintf(sBuffer, sizeof(sBuffer), "%p", this);
410 sResult += sBuffer;
411 sResult += ":";
413 OOXMLProperties_t::iterator aItBegin = begin();
414 OOXMLProperties_t::iterator aItEnd = end();
416 for (OOXMLProperties_t::iterator aIt = aItBegin; aIt != aItEnd; ++aIt)
418 if (aIt != aItBegin)
419 sResult += ", ";
421 if ((*aIt).get() != nullptr)
422 sResult += (*aIt)->toString();
423 else
424 sResult += "0x0";
427 sResult += "]";
429 return sResult;
431 #endif
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());
452 #ifdef DBG_UTIL
453 string OOXMLPropertySetValue::toString() const
455 char sBuffer[256];
457 snprintf(sBuffer, sizeof(sBuffer), "t:%p, m:%p", this, mpPropertySet.get());
459 return "OOXMLPropertySetValue(" + string(sBuffer) + ")";
461 #endif
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));
485 switch (nValue) {
486 case 0: return Zero;
487 case 1: return One;
488 case 2: return Two;
489 case 3: return Three;
490 case 4: return Four;
491 case 5: return Five;
492 case 6: return Six;
493 case 7: return Seven;
494 case 8: return Eight;
495 case 9: return Nine;
496 default: break;
499 OOXMLValue::Pointer_t value(new OOXMLIntegerValue(nValue));
501 return value;
504 OOXMLIntegerValue::OOXMLIntegerValue(sal_Int32 nValue)
505 : mnValue(nValue)
509 OOXMLIntegerValue::~OOXMLIntegerValue()
513 int OOXMLIntegerValue::getInt() const
515 return mnValue;
518 uno::Any OOXMLIntegerValue::getAny() const
520 return uno::Any(mnValue);
523 OOXMLValue * OOXMLIntegerValue::clone() const
525 return new OOXMLIntegerValue(*this);
528 #ifdef DBG_UTIL
529 string OOXMLIntegerValue::toString() const
531 char buffer[256];
532 snprintf(buffer, sizeof(buffer), "%" SAL_PRIdINT32, mnValue);
534 return buffer;
536 #endif
539 class OOXMLHexValue
542 OOXMLHexValue::OOXMLHexValue(sal_uInt32 nValue)
543 : mnValue(nValue)
547 OOXMLHexValue::OOXMLHexValue(const char * pValue)
548 : mnValue(rtl_str_toUInt32(pValue, 16))
552 OOXMLHexValue::~OOXMLHexValue()
556 int OOXMLHexValue::getInt() const
558 return mnValue;
561 OOXMLValue * OOXMLHexValue::clone() const
563 return new OOXMLHexValue(*this);
566 #ifdef DBG_UTIL
567 string OOXMLHexValue::toString() const
569 char buffer[256];
570 snprintf(buffer, sizeof(buffer), "0x%" SAL_PRIxUINT32, mnValue);
572 return buffer;
574 #endif
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
592 if ( nLen == 7 )
594 const OUString sHashColor(pValue, nLen, RTL_TEXTENCODING_ASCII_US);
595 sax::Converter::convertColor( nColor, sHashColor );
597 mnValue = nColor;
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);
609 if (nLen > 2 &&
610 pValue[nLen-2] == 'p' &&
611 pValue[nLen-1] == 't')
613 mnValue = static_cast<int>(val * npPt);
615 else if (nLen > 2 &&
616 pValue[nLen - 2] == 'c' &&
617 pValue[nLen - 1] == 'm')
619 mnValue = static_cast<int>(val * npPt * 72 / 2.54);
621 else if (nLen > 2 &&
622 pValue[nLen - 2] == 'm' &&
623 pValue[nLen - 1] == 'm')
625 mnValue = static_cast<int>(val * npPt * 72 / 25.4);
627 else if (nLen > 2 &&
628 pValue[nLen - 2] == 'i' &&
629 pValue[nLen - 1] == 'n')
631 mnValue = static_cast<int>(val * npPt * 72);
633 else if (nLen > 2 &&
634 pValue[nLen - 2] == 'p' &&
635 ( pValue[nLen - 1] == 'c' || pValue[nLen - 1] == 'i' ))
637 mnValue = static_cast<int>(val * npPt * 12);
639 else
641 mnValue = static_cast<int>(val);
645 OOXMLUniversalMeasureValue::~OOXMLUniversalMeasureValue()
649 int OOXMLUniversalMeasureValue::getInt() const
651 return mnValue;
654 #ifdef DBG_UTIL
655 string OOXMLUniversalMeasureValue::toString() const
657 return OString::number(mnValue).getStr();
659 #endif
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);
668 if (nLen > 1 &&
669 pValue[nLen - 1] == '%')
671 mnValue = static_cast<int>(val * 50);
673 else
675 mnValue = OOXMLTwipsMeasureValue(pValue).getInt();
679 int OOXMLMeasurementOrPercentValue::getInt() const
681 return mnValue;
684 #ifdef DBG_UTIL
685 string OOXMLMeasurementOrPercentValue::toString() const
687 return OString::number(mnValue).getStr();
689 #endif
692 class OOXMLShapeValue
696 OOXMLShapeValue::OOXMLShapeValue(uno::Reference<drawing::XShape> const & rShape)
697 : mrShape(rShape)
701 OOXMLShapeValue::~OOXMLShapeValue()
705 uno::Any OOXMLShapeValue::getAny() const
707 return uno::Any(mrShape);
710 #ifdef DBG_UTIL
711 string OOXMLShapeValue::toString() const
713 return "Shape";
715 #endif
717 OOXMLValue * OOXMLShapeValue::clone() const
719 return new OOXMLShapeValue(mrShape);
723 class OOXMLStarMathValue
727 OOXMLStarMathValue::OOXMLStarMathValue( uno::Reference< embed::XEmbeddedObject > const & c )
728 : component(c)
732 OOXMLStarMathValue::~OOXMLStarMathValue()
736 uno::Any OOXMLStarMathValue::getAny() const
738 return uno::Any(component);
741 #ifdef DBG_UTIL
742 string OOXMLStarMathValue::toString() const
744 return "StarMath";
746 #endif
748 OOXMLValue * OOXMLStarMathValue::clone() const
750 return new OOXMLStarMathValue( component );
754 class OOXMLTableImpl
757 OOXMLTable::OOXMLTable()
761 OOXMLTable::~OOXMLTable()
766 void OOXMLTable::resolve(Table & rTable)
768 Table * pTable = &rTable;
770 int nPos = 0;
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);
780 ++nPos;
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)
800 : mnId(nId)
804 OOXMLPropertySetEntryToString::~OOXMLPropertySetEntryToString()
808 void OOXMLPropertySetEntryToString::sprm(Sprm & /*rSprm*/)
812 void OOXMLPropertySetEntryToString::attribute(Id nId, Value & rValue)
814 if (nId == mnId)
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)
837 if (nId == mnId)
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)
855 if (nId == mnId)
856 mValue = (rValue.getInt() != 0);
861 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */