android: Update app-specific/MIME type icons
[LibreOffice.git] / writerfilter / source / ooxml / OOXMLPropertySet.cxx
blob36c41187a5606a13a16a202814c4d7123623dc1d
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 <sax/tools/converter.hxx>
26 #include <tools/color.hxx>
27 #include <o3tl/string_view.hxx>
28 #include <utility>
30 namespace writerfilter::ooxml
32 using namespace com::sun::star;
34 OOXMLProperty::OOXMLProperty(Id id, OOXMLValue::Pointer_t pValue,
35 OOXMLProperty::Type_t eType)
36 : mId(id), mpValue(std::move(pValue)), meType(eType)
40 OOXMLProperty::~OOXMLProperty()
44 sal_uInt32 OOXMLProperty::getId() const
46 return mId;
49 Value::Pointer_t OOXMLProperty::getValue()
51 Value::Pointer_t pResult;
53 if (mpValue)
54 pResult = Value::Pointer_t(mpValue->clone());
55 else
56 pResult = Value::Pointer_t(new OOXMLValue());
58 return pResult;
61 writerfilter::Reference<Properties>::Pointer_t OOXMLProperty::getProps()
63 writerfilter::Reference<Properties>::Pointer_t pResult;
65 if (mpValue)
66 pResult = mpValue->getProperties();
68 return pResult;
71 #ifdef DBG_UTIL
72 std::string OOXMLProperty::getName() const
74 std::string sResult(QNameToString(mId));
76 if (sResult.length() == 0)
77 sResult = fastTokenToId(mId);
79 if (sResult.length() == 0)
81 static char sBuffer[256];
83 snprintf(sBuffer, sizeof(sBuffer), "%" SAL_PRIxUINT32, mId);
84 sResult = sBuffer;
87 return sResult;
89 #endif
91 #ifdef DBG_UTIL
92 std::string OOXMLProperty::toString() const
94 std::string sResult = "(";
96 sResult += getName();
97 sResult += ", ";
98 if (mpValue)
99 sResult += mpValue->toString();
100 else
101 sResult +="(null)";
102 sResult +=")";
104 return sResult;
106 #endif
108 void OOXMLProperty::resolve(writerfilter::Properties & rProperties)
110 switch (meType)
112 case SPRM:
113 if (mId != 0x0)
114 rProperties.sprm(*this);
115 break;
116 case ATTRIBUTE:
117 rProperties.attribute(mId, *getValue());
118 break;
123 class OOXMLValue
126 OOXMLValue::OOXMLValue()
130 OOXMLValue::~OOXMLValue()
134 int OOXMLValue::getInt() const
136 return 0;
139 OUString OOXMLValue::getString() const
141 return OUString();
144 uno::Any OOXMLValue::getAny() const
146 return uno::Any();
149 writerfilter::Reference<Properties>::Pointer_t OOXMLValue::getProperties()
151 return writerfilter::Reference<Properties>::Pointer_t();
154 writerfilter::Reference<BinaryObj>::Pointer_t OOXMLValue::getBinary()
156 return writerfilter::Reference<BinaryObj>::Pointer_t();
159 #ifdef DBG_UTIL
160 std::string OOXMLValue::toString() const
162 return "OOXMLValue";
164 #endif
166 OOXMLValue * OOXMLValue::clone() const
168 return new OOXMLValue(*this);
172 class OOXMLBinaryValue
175 OOXMLBinaryValue::OOXMLBinaryValue(OOXMLBinaryObjectReference::Pointer_t pBinaryObj)
176 : mpBinaryObj(std::move(pBinaryObj))
180 OOXMLBinaryValue::~OOXMLBinaryValue()
184 writerfilter::Reference<BinaryObj>::Pointer_t OOXMLBinaryValue::getBinary()
186 return mpBinaryObj;
189 #ifdef DBG_UTIL
190 std::string OOXMLBinaryValue::toString() const
192 return "BinaryObj";
194 #endif
196 OOXMLValue * OOXMLBinaryValue::clone() const
198 return new OOXMLBinaryValue(mpBinaryObj);
202 class OOXMLBooleanValue
205 static bool GetBooleanValue(std::string_view pValue)
207 return pValue == "true"
208 || pValue == "True"
209 || pValue == "1"
210 || pValue == "on"
211 || 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(std::string_view pValue)
224 return Create (GetBooleanValue(pValue));
227 OOXMLBooleanValue::OOXMLBooleanValue(bool bValue)
228 : mbValue(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);
246 #ifdef DBG_UTIL
247 std::string OOXMLBooleanValue::toString() const
249 return mbValue ? "true" : "false";
251 #endif
253 OOXMLValue * OOXMLBooleanValue::clone() const
255 return new OOXMLBooleanValue(*this);
259 class OOXMLStringValue
262 OOXMLStringValue::OOXMLStringValue(OUString sStr)
263 : mStr(std::move(sStr))
267 OOXMLStringValue::~OOXMLStringValue()
271 uno::Any OOXMLStringValue::getAny() const
273 return uno::Any(mStr);
276 OUString OOXMLStringValue::getString() const
278 return mStr;
281 #ifdef DBG_UTIL
282 std::string OOXMLStringValue::toString() const
284 return std::string(OUStringToOString(mStr, RTL_TEXTENCODING_ASCII_US));
286 #endif
288 OOXMLValue * OOXMLStringValue::clone() const
290 return new OOXMLStringValue(*this);
294 class OOXMLInputStreamValue
296 OOXMLInputStreamValue::OOXMLInputStreamValue(uno::Reference<io::XInputStream> xInputStream)
297 : mxInputStream(std::move(xInputStream))
301 OOXMLInputStreamValue::~OOXMLInputStreamValue()
305 uno::Any OOXMLInputStreamValue::getAny() const
307 return uno::Any(mxInputStream);
310 #ifdef DBG_UTIL
311 std::string OOXMLInputStreamValue::toString() const
313 return "InputStream";
315 #endif
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];
344 if (pProp)
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));
382 add(pProperty);
385 void OOXMLPropertySet::add(const OOXMLPropertySet::Pointer_t& pPropertySet)
387 const OOXMLPropertySet * pSet = pPropertySet.get();
389 if (pSet != nullptr)
391 mProperties.insert( mProperties.end(), pSet->mProperties.begin(), pSet->mProperties.end() );
395 OOXMLPropertySet * OOXMLPropertySet::clone() const
397 return new OOXMLPropertySet(*this);
400 #ifdef DBG_UTIL
401 std::string OOXMLPropertySet::toString()
403 std::string sResult = "[";
404 char sBuffer[256];
405 snprintf(sBuffer, sizeof(sBuffer), "%p", this);
406 sResult += sBuffer;
407 sResult += ":";
409 OOXMLProperties_t::iterator aItBegin = begin();
410 OOXMLProperties_t::iterator aItEnd = end();
412 for (OOXMLProperties_t::iterator aIt = aItBegin; aIt != aItEnd; ++aIt)
414 if (aIt != aItBegin)
415 sResult += ", ";
417 if (*aIt)
418 sResult += (*aIt)->toString();
419 else
420 sResult += "0x0";
423 sResult += "]";
425 return sResult;
427 #endif
430 class OOXMLPropertySetValue
433 OOXMLPropertySetValue::OOXMLPropertySetValue(OOXMLPropertySet::Pointer_t pPropertySet)
434 : mpPropertySet(std::move(pPropertySet))
438 OOXMLPropertySetValue::~OOXMLPropertySetValue()
442 writerfilter::Reference<Properties>::Pointer_t OOXMLPropertySetValue::getProperties()
444 return writerfilter::Reference<Properties>::Pointer_t
445 (mpPropertySet->clone());
448 #ifdef DBG_UTIL
449 std::string OOXMLPropertySetValue::toString() const
451 char sBuffer[256];
453 snprintf(sBuffer, sizeof(sBuffer), "t:%p, m:%p", this, mpPropertySet.get());
455 return "OOXMLPropertySetValue(" + std::string(sBuffer) + ")";
457 #endif
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));
481 switch (nValue) {
482 case 0: return Zero;
483 case 1: return One;
484 case 2: return Two;
485 case 3: return Three;
486 case 4: return Four;
487 case 5: return Five;
488 case 6: return Six;
489 case 7: return Seven;
490 case 8: return Eight;
491 case 9: return Nine;
492 default: break;
495 OOXMLValue::Pointer_t value(new OOXMLIntegerValue(nValue));
497 return value;
500 OOXMLIntegerValue::OOXMLIntegerValue(sal_Int32 nValue)
501 : mnValue(nValue)
505 OOXMLIntegerValue::~OOXMLIntegerValue()
509 int OOXMLIntegerValue::getInt() const
511 return mnValue;
514 uno::Any OOXMLIntegerValue::getAny() const
516 return uno::Any(mnValue);
519 OOXMLValue * OOXMLIntegerValue::clone() const
521 return new OOXMLIntegerValue(*this);
524 #ifdef DBG_UTIL
525 std::string OOXMLIntegerValue::toString() const
527 char buffer[256];
528 snprintf(buffer, sizeof(buffer), "%" SAL_PRIdINT32, mnValue);
530 return buffer;
532 #endif
535 class OOXMLHexValue
538 OOXMLHexValue::OOXMLHexValue(sal_uInt32 nValue)
539 : mnValue(nValue)
543 OOXMLHexValue::OOXMLHexValue(std::string_view pValue)
544 : mnValue(o3tl::toUInt32(pValue, 16))
548 OOXMLHexValue::~OOXMLHexValue()
552 int OOXMLHexValue::getInt() const
554 return mnValue;
557 OOXMLValue * OOXMLHexValue::clone() const
559 return new OOXMLHexValue(*this);
562 #ifdef DBG_UTIL
563 std::string OOXMLHexValue::toString() const
565 char buffer[256];
566 snprintf(buffer, sizeof(buffer), "0x%" SAL_PRIxUINT32, mnValue);
568 return buffer;
570 #endif
573 class OOXMLHexColorValue
575 OOXMLHexColorValue::OOXMLHexColorValue(std::string_view pValue)
576 : OOXMLHexValue(sal_uInt32(COL_AUTO))
578 if (pValue == "auto")
579 return;
581 mnValue = o3tl::toUInt32(pValue, 16);
583 // Convert hash-encoded values (like #FF0080)
584 const sal_Int32 nLen = pValue.size();
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
589 if ( nLen == 7 )
591 const OUString sHashColor(pValue.data(), nLen, RTL_TEXTENCODING_ASCII_US);
592 sax::Converter::convertColor( nColor, sHashColor );
594 mnValue = nColor;
598 // OOXMLUniversalMeasureValue
599 // ECMA-376 5th ed. Part 1 , 22.9.2.15
600 OOXMLUniversalMeasureValue::OOXMLUniversalMeasureValue(std::string_view pValue, sal_uInt32 npPt)
602 double val = o3tl::toDouble(pValue); // will ignore the trailing unit
604 int nLen = pValue.size();
605 if (nLen > 2 &&
606 pValue[nLen-2] == 'p' &&
607 pValue[nLen-1] == 't')
609 mnValue = static_cast<int>(val * npPt);
611 else if (nLen > 2 &&
612 pValue[nLen - 2] == 'c' &&
613 pValue[nLen - 1] == 'm')
615 mnValue = static_cast<int>(val * npPt * 72 / 2.54);
617 else if (nLen > 2 &&
618 pValue[nLen - 2] == 'm' &&
619 pValue[nLen - 1] == 'm')
621 mnValue = static_cast<int>(val * npPt * 72 / 25.4);
623 else if (nLen > 2 &&
624 pValue[nLen - 2] == 'i' &&
625 pValue[nLen - 1] == 'n')
627 mnValue = static_cast<int>(val * npPt * 72);
629 else if (nLen > 2 &&
630 pValue[nLen - 2] == 'p' &&
631 ( pValue[nLen - 1] == 'c' || pValue[nLen - 1] == 'i' ))
633 mnValue = static_cast<int>(val * npPt * 12);
635 else
637 mnValue = static_cast<int>(val);
641 OOXMLUniversalMeasureValue::~OOXMLUniversalMeasureValue()
645 int OOXMLUniversalMeasureValue::getInt() const
647 return mnValue;
650 #ifdef DBG_UTIL
651 std::string OOXMLUniversalMeasureValue::toString() const
653 return std::string(OString::number(mnValue));
655 #endif
657 // OOXMLMeasurementOrPercentValue
658 // ECMA-376 5th ed. Part 1 , 17.18.107; 17.18.11
659 OOXMLMeasurementOrPercentValue::OOXMLMeasurementOrPercentValue(std::string_view pValue)
661 double val = o3tl::toDouble(pValue); // will ignore the trailing unit
663 int nLen = pValue.size();
664 if (nLen > 1 &&
665 pValue[nLen - 1] == '%')
667 mnValue = static_cast<int>(val * 50);
669 else
671 mnValue = OOXMLTwipsMeasureValue(pValue).getInt();
675 int OOXMLMeasurementOrPercentValue::getInt() const
677 return mnValue;
680 #ifdef DBG_UTIL
681 std::string OOXMLMeasurementOrPercentValue::toString() const
683 return std::string(OString::number(mnValue));
685 #endif
688 class OOXMLShapeValue
692 OOXMLShapeValue::OOXMLShapeValue(uno::Reference<drawing::XShape> xShape)
693 : mrShape(std::move(xShape))
697 OOXMLShapeValue::~OOXMLShapeValue()
701 uno::Any OOXMLShapeValue::getAny() const
703 return uno::Any(mrShape);
706 #ifdef DBG_UTIL
707 std::string OOXMLShapeValue::toString() const
709 return "Shape";
711 #endif
713 OOXMLValue * OOXMLShapeValue::clone() const
715 return new OOXMLShapeValue(mrShape);
719 class OOXMLStarMathValue
723 OOXMLStarMathValue::OOXMLStarMathValue( uno::Reference< embed::XEmbeddedObject > c )
724 : m_component(std::move(c))
728 OOXMLStarMathValue::~OOXMLStarMathValue()
732 uno::Any OOXMLStarMathValue::getAny() const
734 return uno::Any(m_component);
737 #ifdef DBG_UTIL
738 std::string OOXMLStarMathValue::toString() const
740 return "StarMath";
742 #endif
744 OOXMLValue * OOXMLStarMathValue::clone() const
746 return new OOXMLStarMathValue( m_component );
750 class OOXMLTableImpl
753 OOXMLTable::OOXMLTable()
757 OOXMLTable::~OOXMLTable()
762 void OOXMLTable::resolve(Table & rTable)
764 Table * pTable = &rTable;
766 int nPos = 0;
768 for (const auto& rPropSet : mPropertySets)
770 writerfilter::Reference<Properties>::Pointer_t pProperties
771 (rPropSet->getProperties());
773 if (pProperties)
774 pTable->entry(nPos, pProperties);
776 ++nPos;
780 void OOXMLTable::add(const ValuePointer_t& pPropertySet)
782 if (pPropertySet)
783 mPropertySets.push_back(pPropertySet);
786 OOXMLTable * OOXMLTable::clone() const
788 return new OOXMLTable(*this);
792 class: OOXMLPropertySetEntryToString
795 OOXMLPropertySetEntryToString::OOXMLPropertySetEntryToString(Id nId)
796 : mnId(nId)
800 OOXMLPropertySetEntryToString::~OOXMLPropertySetEntryToString()
804 void OOXMLPropertySetEntryToString::sprm(Sprm & /*rSprm*/)
808 void OOXMLPropertySetEntryToString::attribute(Id nId, Value & rValue)
810 if (nId == mnId)
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)
833 if (nId == mnId)
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)
851 if (nId == mnId)
852 mValue = (rValue.getInt() != 0);
857 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */