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 "xmlbahdl.hxx"
22 #include <XMLNumberWithAutoForVoidPropHdl.hxx>
23 #include <sal/log.hxx>
24 #include <o3tl/any.hxx>
25 #include <o3tl/safeint.hxx>
26 #include <o3tl/string_view.hxx>
27 #include <sax/tools/converter.hxx>
28 #include <xmloff/xmluconv.hxx>
29 #include <com/sun/star/uno/Any.hxx>
30 #include <xmloff/xmltoken.hxx>
34 using namespace ::com::sun::star::uno
;
35 using namespace ::xmloff::token
;
37 static void lcl_xmloff_setAny( Any
& rValue
, sal_Int32 nValue
, sal_Int8 nBytes
)
42 if( nValue
< SCHAR_MIN
)
44 else if( nValue
> SCHAR_MAX
)
46 rValue
<<= static_cast<sal_Int8
>(nValue
);
49 if( nValue
< SHRT_MIN
)
51 else if( nValue
> SHRT_MAX
)
53 rValue
<<= static_cast<sal_Int16
>(nValue
);
61 static bool lcl_xmloff_getAny( const Any
& rValue
, sal_Int32
& nValue
,
71 bRet
= rValue
>>= nValue8
;
77 sal_Int16 nValue16
= 0;
78 bRet
= rValue
>>= nValue16
;
83 bRet
= rValue
>>= nValue
;
91 XMLNumberPropHdl::~XMLNumberPropHdl()
96 bool XMLNumberPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
99 bool bRet
= ::sax::Converter::convertNumber( nValue
, rStrImpValue
);
100 lcl_xmloff_setAny( rValue
, nValue
, nBytes
);
105 bool XMLNumberPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
110 if( lcl_xmloff_getAny( rValue
, nValue
, nBytes
) )
112 rStrExpValue
= OUString::number( nValue
);
121 XMLNumberNonePropHdl::XMLNumberNonePropHdl( sal_Int8 nB
) :
122 sZeroStr( GetXMLToken(XML_NO_LIMIT
) ),
127 XMLNumberNonePropHdl::XMLNumberNonePropHdl( enum XMLTokenEnum eZeroString
, sal_Int8 nB
) :
128 sZeroStr( GetXMLToken( eZeroString
) ),
133 XMLNumberNonePropHdl::~XMLNumberNonePropHdl()
138 bool XMLNumberNonePropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
142 sal_Int32 nValue
= 0;
143 if( rStrImpValue
== sZeroStr
)
149 bRet
= ::sax::Converter::convertNumber( nValue
, rStrImpValue
);
151 lcl_xmloff_setAny( rValue
, nValue
, nBytes
);
156 bool XMLNumberNonePropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
161 if( lcl_xmloff_getAny( rValue
, nValue
, nBytes
) )
165 rStrExpValue
= sZeroStr
;
169 rStrExpValue
= OUString::number( nValue
);
179 XMLMeasurePropHdl::~XMLMeasurePropHdl()
184 bool XMLMeasurePropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& rUnitConverter
) const
186 sal_Int32 nValue
= 0;
187 bool bRet
= rUnitConverter
.convertMeasureToCore( nValue
, rStrImpValue
);
188 lcl_xmloff_setAny( rValue
, nValue
, nBytes
);
192 bool XMLMeasurePropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& rUnitConverter
) const
197 if( lcl_xmloff_getAny( rValue
, nValue
, nBytes
) )
200 rUnitConverter
.convertMeasureToXML( aOut
, nValue
);
201 rStrExpValue
= aOut
.makeStringAndClear();
210 XMLBoolFalsePropHdl::~XMLBoolFalsePropHdl()
215 bool XMLBoolFalsePropHdl::importXML( const OUString
&, Any
&, const SvXMLUnitConverter
& ) const
220 bool XMLBoolFalsePropHdl::exportXML( OUString
& rStrExpValue
, const Any
& /*rValue*/, const SvXMLUnitConverter
& rCnv
) const
222 return XMLBoolPropHdl::exportXML( rStrExpValue
, Any( false ), rCnv
);
226 XMLBoolPropHdl::~XMLBoolPropHdl()
231 bool XMLBoolPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
234 bool const bRet
= ::sax::Converter::convertBool( bValue
, rStrImpValue
);
240 bool XMLBoolPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
245 if (rValue
>>= bValue
)
248 ::sax::Converter::convertBool( aOut
, bValue
);
249 rStrExpValue
= aOut
.makeStringAndClear();
258 XMLNBoolPropHdl::~XMLNBoolPropHdl()
263 bool XMLNBoolPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
266 bool const bRet
= ::sax::Converter::convertBool( bValue
, rStrImpValue
);
272 bool XMLNBoolPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
277 if (rValue
>>= bValue
)
280 ::sax::Converter::convertBool( aOut
, !bValue
);
281 rStrExpValue
= aOut
.makeStringAndClear();
290 XMLPercentPropHdl::~XMLPercentPropHdl()
295 bool XMLPercentPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
297 sal_Int32 nValue
= 0;
298 bool const bRet
= ::sax::Converter::convertPercent( nValue
, rStrImpValue
);
299 lcl_xmloff_setAny( rValue
, nValue
, nBytes
);
304 bool XMLPercentPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
309 if( lcl_xmloff_getAny( rValue
, nValue
, nBytes
) )
312 ::sax::Converter::convertPercent( aOut
, nValue
);
313 rStrExpValue
= aOut
.makeStringAndClear();
322 bool XMLDoublePercentPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
328 if( rStrImpValue
.indexOf( '%' ) == -1 )
330 fValue
= rStrImpValue
.toDouble();
334 sal_Int32 nValue
= 0;
335 bRet
= ::sax::Converter::convertPercent( nValue
, rStrImpValue
);
336 fValue
= static_cast<double>(nValue
) / 100.0;
343 bool XMLDoublePercentPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
348 if( rValue
>>= fValue
)
351 if( fValue
> 0 ) fValue
+= 0.5; else fValue
-= 0.5;
353 sal_Int32 nValue
= static_cast<sal_Int32
>(fValue
);
356 ::sax::Converter::convertPercent( aOut
, nValue
);
357 rStrExpValue
= aOut
.makeStringAndClear();
365 bool XML100thPercentPropHdl::importXML(const OUString
& rStrImpValue
, Any
& rValue
,
366 const SvXMLUnitConverter
&) const
370 sal_Int32 nValue
= 0;
371 bRet
= sax::Converter::convertPercent(nValue
, rStrImpValue
);
372 rValue
<<= static_cast<sal_Int16
>(nValue
* 100);
377 bool XML100thPercentPropHdl::exportXML(OUString
& rStrExpValue
, const Any
& rValue
,
378 const SvXMLUnitConverter
&) const
381 sal_Int16 nValue
= 0;
383 if (rValue
>>= nValue
)
385 nValue
= std::round(static_cast<double>(nValue
) / 100);
387 sax::Converter::convertPercent(aOut
, nValue
);
388 rStrExpValue
= aOut
.makeStringAndClear();
396 XMLNegPercentPropHdl::~XMLNegPercentPropHdl()
401 bool XMLNegPercentPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
403 sal_Int32 nValue
= 0;
404 bool bRet
= ::sax::Converter::convertPercent( nValue
, rStrImpValue
);
406 bRet
= !o3tl::checked_sub
<sal_Int32
>(100, nValue
, nValue
);
408 lcl_xmloff_setAny( rValue
, nValue
, nBytes
);
412 bool XMLNegPercentPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
417 if( lcl_xmloff_getAny( rValue
, nValue
, nBytes
) )
420 ::sax::Converter::convertPercent( aOut
, 100-nValue
);
421 rStrExpValue
= aOut
.makeStringAndClear();
429 XMLMeasurePxPropHdl::~XMLMeasurePxPropHdl()
434 bool XMLMeasurePxPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
436 sal_Int32 nValue
= 0;
437 bool bRet
= ::sax::Converter::convertMeasurePx( nValue
, rStrImpValue
);
438 lcl_xmloff_setAny( rValue
, nValue
, nBytes
);
442 bool XMLMeasurePxPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
447 if( lcl_xmloff_getAny( rValue
, nValue
, nBytes
) )
450 ::sax::Converter::convertMeasurePx( aOut
, nValue
);
451 rStrExpValue
= aOut
.makeStringAndClear();
460 XMLColorPropHdl::~XMLColorPropHdl()
465 bool XMLColorPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
469 if( rStrImpValue
.matchIgnoreAsciiCase( "hsl" ) )
471 sal_Int32 nOpen
= rStrImpValue
.indexOf( '(' );
472 sal_Int32 nClose
= rStrImpValue
.lastIndexOf( ')' );
474 if( (nOpen
!= -1) && (nClose
> nOpen
) )
476 const std::u16string_view
aTmp( rStrImpValue
.subView( nOpen
+1, nClose
- nOpen
-1) );
478 sal_Int32 nIndex
= 0;
480 Sequence
< double > aHSL
482 o3tl::toDouble(o3tl::getToken(aTmp
, 0, ',', nIndex
)),
483 o3tl::toDouble(o3tl::getToken(aTmp
, 0, ',', nIndex
)) / 100.0,
484 o3tl::toDouble(o3tl::getToken(aTmp
, 0, ',', nIndex
)) / 100.0
493 bRet
= ::sax::Converter::convertColor( nColor
, rStrImpValue
);
500 bool XMLColorPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
503 sal_Int32 nColor
= 0;
506 if( rValue
>>= nColor
)
508 ::sax::Converter::convertColor( aOut
, nColor
);
509 rStrExpValue
= aOut
.makeStringAndClear();
515 Sequence
< double > aHSL
;
516 if( (rValue
>>= aHSL
) && (aHSL
.getLength() == 3) )
518 rStrExpValue
= "hsl(" + OUString::number(aHSL
[0]) + "," +
519 OUString::number(aHSL
[1] * 100.0) + "%," +
520 OUString::number(aHSL
[2] * 100.0) + "%)";
530 XMLHexPropHdl::~XMLHexPropHdl()
535 bool XMLHexPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
538 bool bRet
= SvXMLUnitConverter::convertHex( nRsid
, rStrImpValue
);
544 bool XMLHexPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
547 sal_uInt32 nRsid
= 0;
549 if( rValue
>>= nRsid
)
552 SvXMLUnitConverter::convertHex( aOut
, nRsid
);
553 rStrExpValue
= aOut
.makeStringAndClear();
566 XMLStringPropHdl::~XMLStringPropHdl()
571 bool XMLStringPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
573 rValue
<<= rStrImpValue
;
577 bool XMLStringPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
581 if( rValue
>>= rStrExpValue
)
588 XMLStyleNamePropHdl::~XMLStyleNamePropHdl()
593 bool XMLStyleNamePropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& rUnitConverter
) const
597 if( rValue
>>= rStrExpValue
)
599 rStrExpValue
= rUnitConverter
.encodeStyleName( rStrExpValue
);
607 XMLDoublePropHdl::~XMLDoublePropHdl()
612 bool XMLDoublePropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
614 double fDblValue(0.0);
615 bool const bRet
= ::sax::Converter::convertDouble(fDblValue
, rStrImpValue
);
616 rValue
<<= fDblValue
;
620 bool XMLDoublePropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
626 if( rValue
>>= fValue
)
629 ::sax::Converter::convertDouble( aOut
, fValue
);
630 rStrExpValue
= aOut
.makeStringAndClear();
638 XMLColorTransparentPropHdl::XMLColorTransparentPropHdl(
639 enum XMLTokenEnum eTransparent
) :
640 sTransparent( GetXMLToken(
641 eTransparent
!= XML_TOKEN_INVALID
? eTransparent
: XML_TRANSPARENT
) )
646 XMLColorTransparentPropHdl::~XMLColorTransparentPropHdl()
651 bool XMLColorTransparentPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
655 if( rStrImpValue
!= sTransparent
)
658 bRet
= ::sax::Converter::convertColor( nColor
, rStrImpValue
);
665 bool XMLColorTransparentPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
668 sal_Int32 nColor
= 0;
670 if( rStrExpValue
== sTransparent
)
672 else if( rValue
>>= nColor
)
675 ::sax::Converter::convertColor( aOut
, nColor
);
676 rStrExpValue
= aOut
.makeStringAndClear();
685 XMLIsTransparentPropHdl::XMLIsTransparentPropHdl(
686 enum XMLTokenEnum eTransparent
, bool bTransPropVal
) :
687 sTransparent( GetXMLToken(
688 eTransparent
!= XML_TOKEN_INVALID
? eTransparent
: XML_TRANSPARENT
) ),
689 bTransPropValue( bTransPropVal
)
693 XMLIsTransparentPropHdl::~XMLIsTransparentPropHdl()
698 bool XMLIsTransparentPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
700 bool bValue
= ( (rStrImpValue
== sTransparent
) == bTransPropValue
);
706 bool XMLIsTransparentPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
710 // MIB: This looks a bit strange, because bTransPropValue == bValue should
711 // do the same, but this only applies if 'true' is represented by the same
712 // 8 bit value in bValue and bTransPropValue. Who will ensure this?
713 bool bValue
= *o3tl::doAccess
<bool>(rValue
);
714 bool bIsTrans
= bTransPropValue
? bValue
: !bValue
;
718 rStrExpValue
= sTransparent
;
726 XMLColorAutoPropHdl::XMLColorAutoPropHdl()
731 XMLColorAutoPropHdl::~XMLColorAutoPropHdl()
736 bool XMLColorAutoPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
740 // This is a multi property: the value might be set to AUTO_COLOR
741 // already by the XMLIsAutoColorPropHdl!
742 sal_Int32 nColor
= 0;
743 if( !(rValue
>>= nColor
) || -1 != nColor
)
745 bRet
= ::sax::Converter::convertColor( nColor
, rStrImpValue
);
753 bool XMLColorAutoPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
757 sal_Int32 nColor
= 0;
758 if( (rValue
>>= nColor
) && -1 != nColor
)
761 ::sax::Converter::convertColor( aOut
, nColor
);
762 rStrExpValue
= aOut
.makeStringAndClear();
771 XMLIsAutoColorPropHdl::XMLIsAutoColorPropHdl()
775 XMLIsAutoColorPropHdl::~XMLIsAutoColorPropHdl()
780 bool XMLIsAutoColorPropHdl::importXML( const OUString
& rStrImpValue
, Any
& rValue
, const SvXMLUnitConverter
& ) const
782 // An auto color overrides any other color set!
784 bool const bRet
= ::sax::Converter::convertBool( bValue
, rStrImpValue
);
786 rValue
<<= sal_Int32(-1);
791 bool XMLIsAutoColorPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
794 sal_Int32 nColor
= 0;
796 if( (rValue
>>= nColor
) && -1 == nColor
)
799 ::sax::Converter::convertBool( aOut
, true );
800 rStrExpValue
= aOut
.makeStringAndClear();
809 XMLCompareOnlyPropHdl::~XMLCompareOnlyPropHdl()
814 bool XMLCompareOnlyPropHdl::importXML( const OUString
&, Any
&, const SvXMLUnitConverter
& ) const
816 SAL_WARN( "xmloff", "importXML called for compare-only-property" );
820 bool XMLCompareOnlyPropHdl::exportXML( OUString
&, const Any
&, const SvXMLUnitConverter
& ) const
822 SAL_WARN( "xmloff", "exportXML called for compare-only-property" );
827 XMLNumberWithoutZeroPropHdl::XMLNumberWithoutZeroPropHdl( sal_Int8 nB
) :
832 XMLNumberWithoutZeroPropHdl::~XMLNumberWithoutZeroPropHdl()
836 bool XMLNumberWithoutZeroPropHdl::importXML(
837 const OUString
& rStrImpValue
,
839 const SvXMLUnitConverter
& ) const
841 sal_Int32 nValue
= 0;
842 bool const bRet
= ::sax::Converter::convertNumber( nValue
, rStrImpValue
);
844 lcl_xmloff_setAny( rValue
, nValue
, nBytes
);
848 bool XMLNumberWithoutZeroPropHdl::exportXML( OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
& ) const
851 sal_Int32 nValue
= 0;
852 bool bRet
= lcl_xmloff_getAny( rValue
, nValue
, nBytes
);
857 rStrExpValue
= OUString::number(nValue
);
864 XMLNumberWithAutoForVoidPropHdl::~XMLNumberWithAutoForVoidPropHdl()
868 bool XMLNumberWithAutoForVoidPropHdl::importXML(
869 const OUString
& rStrImpValue
,
871 const SvXMLUnitConverter
& ) const
873 sal_Int32 nValue
= 0;
874 bool bRet
= ::sax::Converter::convertNumber( nValue
, rStrImpValue
);
876 lcl_xmloff_setAny( rValue
, nValue
, 2 );
877 else if( rStrImpValue
== GetXMLToken( XML_AUTO
) )
879 rValue
.clear(); // void
885 bool XMLNumberWithAutoForVoidPropHdl::exportXML(
886 OUString
& rStrExpValue
, const Any
& rValue
, const SvXMLUnitConverter
&) const
889 sal_Int32 nValue
= 0;
890 bool bRet
= lcl_xmloff_getAny( rValue
, nValue
, 2 );
892 // note: 0 is a valid value here, see CTF_PAGENUMBEROFFSET for when it isn't
895 rStrExpValue
= GetXMLToken( XML_AUTO
);
898 rStrExpValue
= OUString::number(nValue
);
904 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */