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 <com/sun/star/beans/PropertyValue.hpp>
21 #include <com/sun/star/beans/XPropertySet.hpp>
22 #include <com/sun/star/awt/Size.hpp>
23 #include <com/sun/star/frame/XModel.hpp>
24 #include <com/sun/star/graphic/XGraphic.hpp>
25 #include <com/sun/star/awt/FontDescriptor.hpp>
26 #include <com/sun/star/text/HoriOrientation.hpp>
27 #include <com/sun/star/text/VertOrientation.hpp>
28 #include <com/sun/star/text/PositionAndSpaceMode.hpp>
29 #include <com/sun/star/text/LabelFollow.hpp>
30 #include <com/sun/star/container/XNameContainer.hpp>
31 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32 #include <com/sun/star/style/XStyle.hpp>
33 #include <com/sun/star/io/XOutputStream.hpp>
34 #include <com/sun/star/awt/XBitmap.hpp>
35 #include <com/sun/star/style/NumberingType.hpp>
36 #include <com/sun/star/container/XIndexReplace.hpp>
38 #include <o3tl/any.hxx>
39 #include <o3tl/temporary.hxx>
40 #include <rtl/ustrbuf.hxx>
41 #include <sal/log.hxx>
42 #include <comphelper/diagnose_ex.hxx>
43 #include <comphelper/sequence.hxx>
44 #include <comphelper/propertyvalue.hxx>
46 #include <tools/fontenum.hxx>
47 #include <tools/color.hxx>
49 #include <sax/tools/converter.hxx>
51 #include <vcl/vclenum.hxx>
53 #include <xmloff/xmltkmap.hxx>
54 #include <xmloff/namespacemap.hxx>
55 #include <xmloff/xmlnamespace.hxx>
56 #include <xmloff/xmlimp.hxx>
57 #include <xmloff/XMLBase64ImportContext.hxx>
58 #include <xmloff/xmltoken.hxx>
60 #include <xmloff/xmluconv.hxx>
61 #include "fonthdl.hxx"
62 #include <xmloff/XMLFontStylesContext.hxx>
63 #include <xmloff/families.hxx>
64 #include <xmloff/maptype.hxx>
66 #include <xmloff/xmlnumi.hxx>
69 using namespace ::com::sun::star
;
70 using namespace ::com::sun::star::uno
;
71 using namespace ::com::sun::star::style
;
72 using namespace ::com::sun::star::text
;
73 using namespace ::com::sun::star::beans
;
74 using namespace ::com::sun::star::container
;
75 using namespace ::com::sun::star::lang
;
76 using namespace ::com::sun::star::frame
;
77 using namespace ::xmloff::token
;
78 using namespace ::com::sun::star::io
;
80 class SvxXMLListLevelStyleContext_Impl
;
84 class SvxXMLListLevelStyleAttrContext_Impl
: public SvXMLImportContext
86 SvxXMLListLevelStyleContext_Impl
& rListLevel
;
90 SvxXMLListLevelStyleAttrContext_Impl(
91 SvXMLImport
& rImport
, sal_Int32 nElement
,
92 const Reference
< xml::sax::XFastAttributeList
>& xAttrList
,
93 SvxXMLListLevelStyleContext_Impl
& rLLevel
);
95 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
createFastChildContext(
97 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
) override
;
100 class SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl
: public SvXMLImportContext
104 SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl(
105 SvXMLImport
& rImport
, sal_Int32 nElement
,
106 const Reference
< xml::sax::XFastAttributeList
>& xAttrList
,
107 SvxXMLListLevelStyleContext_Impl
& rLLevel
);
112 class SvxXMLListLevelStyleContext_Impl
: public SvXMLImportContext
114 friend SvxXMLListLevelStyleAttrContext_Impl
;
118 std::optional
<OUString
> sListFormat
; // It is optional to distinguish empty format string
119 // from not existing format string in old docs
120 OUString sTextStyleName
;
122 OUString sNumLetterSync
;
123 OUString sBulletFontName
;
124 OUString sBulletFontStyleName
;
127 Reference
< XOutputStream
> xBase64Stream
;
130 sal_Int32 nSpaceBefore
;
131 sal_Int32 nMinLabelWidth
;
132 sal_Int32 nMinLabelDist
;
133 sal_Int32 nImageWidth
;
134 sal_Int32 nImageHeight
;
135 sal_Int16 nNumStartValue
;
136 sal_Int16 nNumDisplayLevels
;
139 sal_Int16 eBulletFontFamily
;
140 sal_Int16 eBulletFontPitch
;
141 rtl_TextEncoding eBulletFontEncoding
;
142 sal_Int16 eImageVertOrient
;
149 sal_Int16 ePosAndSpaceMode
;
150 sal_Int16 eLabelFollowedBy
;
151 sal_Int32 nListtabStopPosition
;
152 sal_Int32 nFirstLineIndent
;
160 bool m_bIsLegal
= false;
162 void SetRelSize( sal_Int16 nRel
) { nRelSize
= nRel
; }
163 void SetColor( Color nColor
)
164 { m_nColor
= nColor
; bHasColor
= true; }
165 void SetSpaceBefore( sal_Int32 nSet
) { nSpaceBefore
= nSet
; }
166 void SetMinLabelWidth( sal_Int32 nSet
) { nMinLabelWidth
= nSet
; }
167 void SetMinLabelDist( sal_Int32 nSet
) { nMinLabelDist
= nSet
; }
168 void SetAdjust( sal_Int16 eSet
) { eAdjust
= eSet
; }
170 void SetBulletFontName( const OUString
& rSet
) { sBulletFontName
= rSet
; }
171 void SetBulletFontStyleName( const OUString
& rSet
)
172 { sBulletFontStyleName
= rSet
; }
173 void SetBulletFontFamily( sal_Int16 eSet
) { eBulletFontFamily
= eSet
; }
174 void SetBulletFontPitch( sal_Int16 eSet
) { eBulletFontPitch
= eSet
; }
175 void SetBulletFontEncoding( rtl_TextEncoding eSet
)
176 { eBulletFontEncoding
= eSet
; }
178 void SetImageWidth( sal_Int32 nSet
) { nImageWidth
= nSet
; }
179 void SetImageHeight( sal_Int32 nSet
) { nImageHeight
= nSet
; }
180 void SetImageVertOrient( sal_Int16 eSet
)
181 { eImageVertOrient
= eSet
; }
185 SvxXMLListLevelStyleContext_Impl(
186 SvXMLImport
& rImport
, sal_Int32 nElement
,
187 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
);
189 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
createFastChildContext(
191 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
) override
;
193 sal_Int32
GetLevel() const { return nLevel
; }
194 Sequence
<beans::PropertyValue
> GetProperties();
196 void SetPosAndSpaceMode( sal_Int16 eValue
)
198 ePosAndSpaceMode
= eValue
;
200 void SetLabelFollowedBy( sal_Int16 eValue
)
202 eLabelFollowedBy
= eValue
;
204 void SetListtabStopPosition( sal_Int32 nValue
)
206 nListtabStopPosition
= nValue
;
208 void SetFirstLineIndent( sal_Int32 nValue
)
210 nFirstLineIndent
= nValue
;
212 void SetIndentAt( sal_Int32 nValue
)
218 constexpr OUStringLiteral
gsStarBats( u
"StarBats" );
219 constexpr OUStringLiteral
gsStarMath( u
"StarMath" );
221 SvxXMLListLevelStyleContext_Impl::SvxXMLListLevelStyleContext_Impl(
222 SvXMLImport
& rImport
, sal_Int32 nElement
,
223 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
)
225 : SvXMLImportContext( rImport
)
229 , nMinLabelWidth( 0 )
233 , nNumStartValue( 1 )
234 , nNumDisplayLevels( 1 )
235 , eAdjust( HoriOrientation::LEFT
)
236 , eBulletFontFamily( FAMILY_DONTKNOW
)
237 , eBulletFontPitch( PITCH_DONTKNOW
)
238 , eBulletFontEncoding( RTL_TEXTENCODING_DONTKNOW
)
239 , eImageVertOrient(0)
243 , ePosAndSpaceMode( PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION
)
244 , eLabelFollowedBy( LabelFollow::LISTTAB
)
245 , nListtabStopPosition( 0 )
246 , nFirstLineIndent( 0 )
253 switch (nElement
& TOKEN_MASK
)
255 case XML_LIST_LEVEL_STYLE_NUMBER
:
256 case XML_OUTLINE_LEVEL_STYLE
:
259 case XML_LIST_LEVEL_STYLE_BULLET
:
262 case XML_LIST_LEVEL_STYLE_IMAGE
:
267 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
269 switch( aIter
.getToken() )
271 case XML_ELEMENT(TEXT
, XML_LEVEL
):
272 nLevel
= aIter
.toInt32();
278 case XML_ELEMENT(TEXT
, XML_STYLE_NAME
):
279 sTextStyleName
= aIter
.toString();
281 case XML_ELEMENT(TEXT
, XML_BULLET_CHAR
):
282 if (!aIter
.isEmpty())
284 cBullet
= aIter
.toString().iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
287 case XML_ELEMENT(XLINK
, XML_HREF
):
289 sImageURL
= aIter
.toString();
291 case XML_ELEMENT(XLINK
, XML_TYPE
):
292 case XML_ELEMENT(XLINK
, XML_SHOW
):
293 case XML_ELEMENT(XLINK
, XML_ACTUATE
):
294 // This properties will be ignored
296 case XML_ELEMENT(STYLE
, XML_NUM_FORMAT
):
298 sNumFormat
= aIter
.toString();
300 case XML_ELEMENT(STYLE
, XML_NUM_PREFIX
):
301 sPrefix
= aIter
.toString();
303 case XML_ELEMENT(STYLE
, XML_NUM_SUFFIX
):
304 sSuffix
= aIter
.toString();
306 case XML_ELEMENT(STYLE
, XML_NUM_LIST_FORMAT
):
307 case XML_ELEMENT(LO_EXT
, XML_NUM_LIST_FORMAT
):
308 sListFormat
= std::make_optional(aIter
.toString());
310 case XML_ELEMENT(LO_EXT
, XML_IS_LEGAL
):
311 m_bIsLegal
= aIter
.toBoolean();
313 case XML_ELEMENT(STYLE
, XML_NUM_LETTER_SYNC
):
315 sNumLetterSync
= aIter
.toString();
317 case XML_ELEMENT(TEXT
, XML_START_VALUE
):
320 sal_Int32 nTmp
= aIter
.toInt32();
322 (nTmp
< 0) ? 1 : ( (nTmp
>SHRT_MAX
) ? SHRT_MAX
323 : static_cast<sal_Int16
>(nTmp
) );
326 case XML_ELEMENT(TEXT
, XML_DISPLAY_LEVELS
):
329 sal_Int32 nTmp
= aIter
.toInt32();
331 (nTmp
< 1) ? 1 : ( (nTmp
>SHRT_MAX
) ? SHRT_MAX
332 : static_cast<sal_Int16
>(nTmp
) );
336 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
341 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SvxXMLListLevelStyleContext_Impl::createFastChildContext(
343 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
345 if( nElement
== XML_ELEMENT(STYLE
, XML_LIST_LEVEL_PROPERTIES
) ||
346 nElement
== XML_ELEMENT(STYLE
, XML_TEXT_PROPERTIES
) )
348 return new SvxXMLListLevelStyleAttrContext_Impl( GetImport(),
353 else if( nElement
== XML_ELEMENT(OFFICE
, XML_BINARY_DATA
) )
355 if( bImage
&& sImageURL
.isEmpty() && !xBase64Stream
.is() )
357 xBase64Stream
= GetImport().GetStreamForGraphicObjectURLFromBase64();
358 if( xBase64Stream
.is() )
359 return new XMLBase64ImportContext( GetImport(), xBase64Stream
);
362 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
366 Sequence
<beans::PropertyValue
> SvxXMLListLevelStyleContext_Impl::GetProperties()
368 if (!bBullet
&& !bImage
&& !bNum
)
370 return Sequence
<beans::PropertyValue
>();
373 sal_Int16 eType
= NumberingType::NUMBER_NONE
;
374 std::vector
<beans::PropertyValue
> aProperties
;
378 eType
= NumberingType::CHAR_SPECIAL
;
382 eType
= NumberingType::BITMAP
;
386 eType
= NumberingType::ARABIC
;
387 GetImport().GetMM100UnitConverter().convertNumFormat(
388 eType
, sNumFormat
, sNumLetterSync
, true );
391 if (bBullet
&& !sSuffix
.isEmpty())
393 sal_uInt16
const nVersion(GetImport().getGeneratorVersion());
396 if (GetImport().getBuildIds(nUPD
, nBuildId
)
397 && ( (SvXMLImport::OOo_1x
== nVersion
)
398 || (SvXMLImport::OOo_2x
== nVersion
)
399 || (310 == nUPD
) || (320 == nUPD
) || (330 == nUPD
)
400 || ((300 == nUPD
) && (nBuildId
<= 9573))))
402 // #i93908# OOo < 3.4 wrote a bogus suffix for bullet chars
403 sSuffix
.clear(); // clear it
407 if (!sListFormat
.has_value())
409 // This is older document: it has no list format, but can probably contain prefix and/or suffix
410 // Generate list format string, based on this
411 sListFormat
= std::make_optional(sPrefix
);
413 for (int i
= 1; i
<= nNumDisplayLevels
; i
++)
416 *sListFormat
+= OUString::number(nLevel
- nNumDisplayLevels
+ i
+ 1);
418 if (i
!= nNumDisplayLevels
)
419 *sListFormat
+= "."; // Default separator for older ODT
422 *sListFormat
+= sSuffix
;
425 aProperties
.push_back(comphelper::makePropertyValue("NumberingType", eType
));
427 aProperties
.push_back(comphelper::makePropertyValue("Prefix", sPrefix
));
429 aProperties
.push_back(comphelper::makePropertyValue("Suffix", sSuffix
));
431 aProperties
.push_back(comphelper::makePropertyValue("Adjust", eAdjust
));
433 sal_Int32 nLeftMargin
= nSpaceBefore
+ nMinLabelWidth
;
434 aProperties
.push_back(comphelper::makePropertyValue("LeftMargin", nLeftMargin
));
436 sal_Int32 nFirstLineOffset
= -nMinLabelWidth
;
437 aProperties
.push_back(comphelper::makePropertyValue("FirstLineOffset", nFirstLineOffset
));
439 aProperties
.push_back(comphelper::makePropertyValue("SymbolTextDistance", static_cast<sal_Int16
>(nMinLabelDist
)));
441 aProperties
.push_back(comphelper::makePropertyValue("PositionAndSpaceMode", ePosAndSpaceMode
));
443 aProperties
.push_back(comphelper::makePropertyValue("LabelFollowedBy", eLabelFollowedBy
));
445 aProperties
.push_back(comphelper::makePropertyValue("ListtabStopPosition", nListtabStopPosition
));
447 aProperties
.push_back(comphelper::makePropertyValue("FirstLineIndent", nFirstLineIndent
));
449 aProperties
.push_back(comphelper::makePropertyValue("IndentAt", nIndentAt
));
451 OUString sDisplayTextStyleName
= GetImport().GetStyleDisplayName(XmlStyleFamily::TEXT_TEXT
, sTextStyleName
);
452 aProperties
.push_back(comphelper::makePropertyValue("CharStyleName", sDisplayTextStyleName
));
456 awt::FontDescriptor aFDesc
;
457 aFDesc
.Name
= sBulletFontName
;
458 if( !sBulletFontName
.isEmpty() )
460 aFDesc
.StyleName
= sBulletFontStyleName
;
461 aFDesc
.Family
= eBulletFontFamily
;
462 aFDesc
.Pitch
= eBulletFontPitch
;
463 aFDesc
.CharSet
= eBulletFontEncoding
;
464 aFDesc
.Weight
= WEIGHT_DONTKNOW
;
465 bool bStarSymbol
= false;
466 if( aFDesc
.Name
.equalsIgnoreAsciiCase( gsStarBats
) )
468 cBullet
= GetImport().ConvStarBatsCharToStarSymbol( cBullet
);
471 else if( aFDesc
.Name
.equalsIgnoreAsciiCase( gsStarMath
) )
473 cBullet
= GetImport().ConvStarMathCharToStarSymbol( cBullet
);
477 aFDesc
.Name
= "StarSymbol" ;
480 // Must append 'cBullet' even if it is zero
481 // if 'bBullet' is true and 'cBullet' is zero - BulletChar property must be 0.
482 aProperties
.push_back(comphelper::makePropertyValue("BulletChar", OUString(&cBullet
, 1)));
483 aProperties
.push_back(comphelper::makePropertyValue("BulletFont", aFDesc
));
488 uno::Reference
<graphic::XGraphic
> xGraphic
;
489 if (!sImageURL
.isEmpty())
491 xGraphic
= GetImport().loadGraphicByURL(sImageURL
);
493 else if( xBase64Stream
.is() )
495 xGraphic
= GetImport().loadGraphicFromBase64(xBase64Stream
);
498 uno::Reference
<awt::XBitmap
> xBitmap
;
500 xBitmap
.set(xGraphic
, uno::UNO_QUERY
);
504 aProperties
.push_back(comphelper::makePropertyValue("GraphicBitmap", xBitmap
));
507 awt::Size
aSize(nImageWidth
, nImageHeight
);
508 aProperties
.push_back(comphelper::makePropertyValue("GraphicSize", aSize
));
509 aProperties
.push_back(comphelper::makePropertyValue("VertOrient", eImageVertOrient
));
514 aProperties
.push_back(comphelper::makePropertyValue("StartWith", nNumStartValue
));
515 aProperties
.push_back(comphelper::makePropertyValue("ParentNumbering", nNumDisplayLevels
));
518 if( ( bNum
|| bBullet
) && nRelSize
)
520 aProperties
.push_back(comphelper::makePropertyValue("BulletRelSize", nRelSize
));
523 if( !bImage
&& bHasColor
)
525 aProperties
.push_back(comphelper::makePropertyValue("BulletColor", m_nColor
));
528 aProperties
.push_back(comphelper::makePropertyValue("ListFormat", *sListFormat
));
531 aProperties
.push_back(comphelper::makePropertyValue("IsLegal", true));
533 return comphelper::containerToSequence(aProperties
);
536 SvxXMLListLevelStyleAttrContext_Impl::SvxXMLListLevelStyleAttrContext_Impl(
537 SvXMLImport
& rImport
, sal_Int32
/*nElement*/,
538 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
539 SvxXMLListLevelStyleContext_Impl
& rLLevel
) :
540 SvXMLImportContext( rImport
),
541 rListLevel( rLLevel
)
543 SvXMLUnitConverter
& rUnitConv
= GetImport().GetMM100UnitConverter();
545 OUString sFontName
, sFontFamily
, sFontStyleName
, sFontFamilyGeneric
,
546 sFontPitch
, sFontCharset
;
547 OUString sVerticalPos
, sVerticalRel
;
549 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
552 switch( aIter
.getToken() )
554 case XML_ELEMENT(TEXT
, XML_SPACE_BEFORE
):
555 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView(), SHRT_MIN
, SHRT_MAX
))
556 rListLevel
.SetSpaceBefore( nVal
);
558 case XML_ELEMENT(TEXT
, XML_MIN_LABEL_WIDTH
):
559 if (rUnitConv
.convertMeasureToCore( nVal
, aIter
.toView(), 0, SHRT_MAX
))
560 rListLevel
.SetMinLabelWidth( nVal
);
562 case XML_ELEMENT(TEXT
, XML_MIN_LABEL_DISTANCE
):
563 if (rUnitConv
.convertMeasureToCore( nVal
, aIter
.toView(), 0, USHRT_MAX
))
564 rListLevel
.SetMinLabelDist( nVal
);
566 case XML_ELEMENT(FO
, XML_TEXT_ALIGN
):
567 case XML_ELEMENT(FO_COMPAT
, XML_TEXT_ALIGN
):
568 if( !aIter
.isEmpty() )
570 sal_Int16 eAdjust
= HoriOrientation::LEFT
;
571 if( IsXMLToken( aIter
, XML_CENTER
) )
572 eAdjust
= HoriOrientation::CENTER
;
573 else if( IsXMLToken( aIter
, XML_END
) )
574 eAdjust
= HoriOrientation::RIGHT
;
575 rListLevel
.SetAdjust( eAdjust
);
578 case XML_ELEMENT(STYLE
, XML_FONT_NAME
):
579 sFontName
= aIter
.toString();
581 case XML_ELEMENT(FO
, XML_FONT_FAMILY
):
582 case XML_ELEMENT(FO_COMPAT
, XML_FONT_FAMILY
):
583 sFontFamily
= aIter
.toString();
585 case XML_ELEMENT(STYLE
, XML_FONT_FAMILY_GENERIC
):
586 sFontFamilyGeneric
= aIter
.toString();
588 case XML_ELEMENT(STYLE
, XML_FONT_STYLE_NAME
):
589 sFontStyleName
= aIter
.toString();
591 case XML_ELEMENT(STYLE
, XML_FONT_PITCH
):
592 sFontPitch
= aIter
.toString();
594 case XML_ELEMENT(STYLE
, XML_FONT_CHARSET
):
595 sFontCharset
= aIter
.toString();
597 case XML_ELEMENT(STYLE
, XML_VERTICAL_POS
):
598 sVerticalPos
= aIter
.toString();
600 case XML_ELEMENT(STYLE
, XML_VERTICAL_REL
):
601 sVerticalRel
= aIter
.toString();
603 case XML_ELEMENT(FO
, XML_WIDTH
):
604 case XML_ELEMENT(FO_COMPAT
, XML_WIDTH
):
605 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView()))
606 rListLevel
.SetImageWidth( nVal
);
608 case XML_ELEMENT(FO
, XML_HEIGHT
):
609 case XML_ELEMENT(FO_COMPAT
, XML_HEIGHT
):
610 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView()))
611 rListLevel
.SetImageHeight( nVal
);
613 case XML_ELEMENT(FO
, XML_COLOR
):
614 case XML_ELEMENT(FO_COMPAT
, XML_COLOR
):
617 if (::sax::Converter::convertColor( nColor
, aIter
.toView() ))
618 rListLevel
.SetColor( nColor
);
621 case XML_ELEMENT(STYLE
, XML_USE_WINDOW_FONT_COLOR
):
623 if( IsXMLToken( aIter
, XML_TRUE
) )
624 rListLevel
.SetColor(COL_AUTO
);
627 case XML_ELEMENT(FO
, XML_FONT_SIZE
):
628 case XML_ELEMENT(FO_COMPAT
, XML_FONT_SIZE
):
629 if (::sax::Converter::convertPercent( nVal
, aIter
.toView() ))
630 rListLevel
.SetRelSize( static_cast<sal_Int16
>(nVal
) );
632 case XML_ELEMENT(TEXT
, XML_LIST_LEVEL_POSITION_AND_SPACE_MODE
):
634 sal_Int16 ePosAndSpaceMode
= PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION
;
635 if( IsXMLToken( aIter
, XML_LABEL_ALIGNMENT
) )
636 ePosAndSpaceMode
= PositionAndSpaceMode::LABEL_ALIGNMENT
;
637 rListLevel
.SetPosAndSpaceMode( ePosAndSpaceMode
);
641 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
645 if( !sFontName
.isEmpty() )
647 const XMLFontStylesContext
*pFontDecls
=
648 GetImport().GetFontDecls();
651 ::std::vector
< XMLPropertyState
> aProps
;
652 if( pFontDecls
->FillProperties( sFontName
, aProps
, 0, 1, 2, 3, 4 ) )
656 for( const auto& rProp
: aProps
)
658 switch( rProp
.mnIndex
)
661 rProp
.maValue
>>= sTmp
;
662 rListLevel
.SetBulletFontName( sTmp
);
665 rProp
.maValue
>>= sTmp
;
666 rListLevel
.SetBulletFontStyleName( sTmp
);
669 rProp
.maValue
>>= nTmp
;
670 rListLevel
.SetBulletFontFamily( nTmp
);
673 rProp
.maValue
>>= nTmp
;
674 rListLevel
.SetBulletFontPitch( nTmp
);
677 rProp
.maValue
>>= nTmp
;
678 rListLevel
.SetBulletFontEncoding( nTmp
);
685 if( !sFontFamily
.isEmpty() )
689 XMLFontFamilyNamePropHdl aFamilyNameHdl
;
690 if( aFamilyNameHdl
.importXML( sFontFamily
, aAny
, rUnitConv
) )
694 rListLevel
.SetBulletFontName( sTmp
);
697 XMLFontFamilyPropHdl aFamilyHdl
;
698 if( !sFontFamilyGeneric
.isEmpty() &&
699 aFamilyHdl
.importXML( sFontFamilyGeneric
, aAny
, rUnitConv
) )
703 rListLevel
.SetBulletFontFamily( nTmp
);
706 if( !sFontStyleName
.isEmpty() )
707 rListLevel
.SetBulletFontStyleName( sFontStyleName
);
709 XMLFontPitchPropHdl aPitchHdl
;
710 if( !sFontPitch
.isEmpty() &&
711 aPitchHdl
.importXML( sFontPitch
, aAny
, rUnitConv
) )
715 rListLevel
.SetBulletFontPitch( nTmp
);
718 XMLFontEncodingPropHdl aEncHdl
;
719 if( !sFontCharset
.isEmpty() &&
720 aEncHdl
.importXML( sFontCharset
, aAny
, rUnitConv
) )
724 rListLevel
.SetBulletFontEncoding( nTmp
);
728 sal_Int16 eVertOrient
= VertOrientation::LINE_CENTER
;
729 if( !sVerticalPos
.isEmpty() )
731 if( IsXMLToken( sVerticalPos
, XML_TOP
) )
732 eVertOrient
= VertOrientation::LINE_TOP
;
733 else if( IsXMLToken( sVerticalPos
, XML_BOTTOM
) )
734 eVertOrient
= VertOrientation::LINE_BOTTOM
;
736 if( !sVerticalRel
.isEmpty() )
738 if( IsXMLToken( sVerticalRel
, XML_BASELINE
) )
740 // TOP and BOTTOM are exchanged for a baseline relation
741 switch( eVertOrient
)
743 case VertOrientation::LINE_TOP
:
744 eVertOrient
= VertOrientation::BOTTOM
;
746 case VertOrientation::LINE_CENTER
:
747 eVertOrient
= VertOrientation::CENTER
;
749 case VertOrientation::LINE_BOTTOM
:
750 eVertOrient
= VertOrientation::TOP
;
754 else if( IsXMLToken( sVerticalRel
, XML_CHAR
) )
756 switch( eVertOrient
)
758 case VertOrientation::LINE_TOP
:
759 eVertOrient
= VertOrientation::CHAR_TOP
;
761 case VertOrientation::LINE_CENTER
:
762 eVertOrient
= VertOrientation::CHAR_CENTER
;
764 case VertOrientation::LINE_BOTTOM
:
765 eVertOrient
= VertOrientation::CHAR_BOTTOM
;
770 rListLevel
.SetImageVertOrient( eVertOrient
);
773 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SvxXMLListLevelStyleAttrContext_Impl::createFastChildContext(
775 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
777 if ( nElement
== XML_ELEMENT(STYLE
, XML_LIST_LEVEL_LABEL_ALIGNMENT
) )
779 return new SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl( GetImport(),
784 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
789 SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl::SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl(
790 SvXMLImport
& rImport
, sal_Int32
/*nElement*/,
791 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
792 SvxXMLListLevelStyleContext_Impl
& rLLevel
) :
793 SvXMLImportContext( rImport
)
795 SvXMLUnitConverter
& rUnitConv
= GetImport().GetMM100UnitConverter();
797 sal_Int16 eLabelFollowedBy
= LabelFollow::LISTTAB
;
798 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
801 switch( aIter
.getToken() )
803 case XML_ELEMENT(TEXT
, XML_LABEL_FOLLOWED_BY
):
804 case XML_ELEMENT(LO_EXT
, XML_LABEL_FOLLOWED_BY
):
806 if( eLabelFollowedBy
== LabelFollow::NEWLINE
)
807 //NewLine from LO_EXT has precedence over other values of the Non LO_EXT namespace
809 if( IsXMLToken( aIter
, XML_SPACE
) )
810 eLabelFollowedBy
= LabelFollow::SPACE
;
811 else if( IsXMLToken( aIter
, XML_NOTHING
) )
812 eLabelFollowedBy
= LabelFollow::NOTHING
;
813 else if( IsXMLToken( aIter
, XML_NEWLINE
) )
814 eLabelFollowedBy
= LabelFollow::NEWLINE
;
817 case XML_ELEMENT(TEXT
, XML_LIST_TAB_STOP_POSITION
):
818 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView(), 0, SHRT_MAX
))
819 rLLevel
.SetListtabStopPosition( nVal
);
821 case XML_ELEMENT(FO
, XML_TEXT_INDENT
):
822 case XML_ELEMENT(FO_COMPAT
, XML_TEXT_INDENT
):
823 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView(), SHRT_MIN
, SHRT_MAX
))
824 rLLevel
.SetFirstLineIndent( nVal
);
826 case XML_ELEMENT(FO
, XML_MARGIN_LEFT
):
827 case XML_ELEMENT(FO_COMPAT
, XML_MARGIN_LEFT
):
828 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView(), SHRT_MIN
, SHRT_MAX
))
829 rLLevel
.SetIndentAt( nVal
);
832 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
835 rLLevel
.SetLabelFollowedBy( eLabelFollowedBy
);
838 void SvxXMLListStyleContext::SetAttribute( sal_Int32 nElement
,
839 const OUString
& rValue
)
841 if( nElement
== XML_ELEMENT(TEXT
, XML_CONSECUTIVE_NUMBERING
) )
843 m_bConsecutive
= IsXMLToken( rValue
, XML_TRUE
);
847 SvXMLStyleContext::SetAttribute( nElement
, rValue
);
851 constexpr OUString
sIsPhysical( u
"IsPhysical"_ustr
);
852 constexpr OUString
sNumberingRules( u
"NumberingRules"_ustr
);
853 constexpr OUString
sIsContinuousNumbering( u
"IsContinuousNumbering"_ustr
);
855 SvxXMLListStyleContext::SvxXMLListStyleContext( SvXMLImport
& rImport
,
857 : SvXMLStyleContext( rImport
, bOutl
? XmlStyleFamily::TEXT_OUTLINE
: XmlStyleFamily::TEXT_LIST
)
858 , m_bConsecutive( false )
859 , m_bOutline( bOutl
)
863 SvxXMLListStyleContext::~SvxXMLListStyleContext() {}
865 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SvxXMLListStyleContext::createFastChildContext(
867 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
870 ? nElement
== XML_ELEMENT(TEXT
, XML_OUTLINE_LEVEL_STYLE
)
871 : ( nElement
== XML_ELEMENT(TEXT
, XML_LIST_LEVEL_STYLE_NUMBER
) ||
872 nElement
== XML_ELEMENT(TEXT
, XML_LIST_LEVEL_STYLE_BULLET
) ||
873 nElement
== XML_ELEMENT(TEXT
, XML_LIST_LEVEL_STYLE_IMAGE
) ) )
875 rtl::Reference
<SvxXMLListLevelStyleContext_Impl
> xLevelStyle
{
876 new SvxXMLListLevelStyleContext_Impl( GetImport(), nElement
, xAttrList
)};
877 if( !m_pLevelStyles
)
878 m_pLevelStyles
= std::make_unique
<SvxXMLListStyle_Impl
>();
879 m_pLevelStyles
->push_back( xLevelStyle
);
883 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
887 void SvxXMLListStyleContext::FillUnoNumRule(
888 const Reference
<container::XIndexReplace
> & rNumRule
) const
892 if( m_pLevelStyles
&& rNumRule
.is() )
894 sal_Int32 l_nLevels
= rNumRule
->getCount();
895 for (const auto& pLevelStyle
: *m_pLevelStyles
)
897 sal_Int32 nLevel
= pLevelStyle
->GetLevel();
898 if( nLevel
>= 0 && nLevel
< l_nLevels
)
900 Sequence
<beans::PropertyValue
> aProps
=
901 pLevelStyle
->GetProperties();
902 rNumRule
->replaceByIndex( nLevel
, Any(aProps
) );
907 Reference
< XPropertySet
> xPropSet( rNumRule
, UNO_QUERY
);
908 Reference
< XPropertySetInfo
> xPropSetInfo
;
910 xPropSetInfo
= xPropSet
->getPropertySetInfo();
911 if( xPropSetInfo
.is() &&
912 xPropSetInfo
->hasPropertyByName( sIsContinuousNumbering
) )
914 xPropSet
->setPropertyValue( sIsContinuousNumbering
, Any(m_bConsecutive
) );
917 catch (const Exception
&)
919 TOOLS_WARN_EXCEPTION("xmloff.style", "" );
923 void SvxXMLListStyleContext::CreateAndInsertLate( bool bOverwrite
)
929 const Reference
< XIndexReplace
>& rNumRule
=
930 GetImport().GetTextImport()->GetChapterNumbering();
931 // We don't set xNumberingRules here, to avoid using them
932 // as numbering rules.
934 FillUnoNumRule(rNumRule
);
939 Reference
< XStyle
> xStyle
;
940 const OUString
& rName
= GetDisplayName();
941 if( rName
.isEmpty() )
947 const Reference
< XNameContainer
>& rNumStyles
=
948 GetImport().GetTextImport()->GetNumberingStyles();
949 if( !rNumStyles
.is() )
956 if( rNumStyles
->hasByName( rName
) )
958 Any aAny
= rNumStyles
->getByName( rName
);
963 Reference
< XMultiServiceFactory
> xFactory( GetImport().GetModel(),
965 SAL_WARN_IF( !xFactory
.is(), "xmloff", "no factory" );
969 Reference
< XInterface
> xIfc
= xFactory
->createInstance("com.sun.star.style.NumberingStyle");
972 Reference
< XStyle
> xTmp( xIfc
, UNO_QUERY
);
977 rNumStyles
->insertByName( rName
, Any(xStyle
) );
981 Reference
< XPropertySet
> xPropSet( xStyle
, UNO_QUERY
);
982 Reference
< XPropertySetInfo
> xPropSetInfo
=
983 xPropSet
->getPropertySetInfo();
984 if( !bNew
&& xPropSetInfo
->hasPropertyByName( sIsPhysical
) )
986 Any aAny
= xPropSet
->getPropertyValue( sIsPhysical
);
987 bNew
= !*o3tl::doAccess
<bool>(aAny
);
990 if ( xPropSetInfo
->hasPropertyByName( "Hidden" ) )
991 xPropSet
->setPropertyValue( "Hidden", uno::Any( IsHidden( ) ) );
993 if( rName
!= GetName() )
994 GetImport().AddStyleDisplayName( XmlStyleFamily::TEXT_LIST
,
997 Any aAny
= xPropSet
->getPropertyValue( sNumberingRules
);
998 aAny
>>= m_xNumRules
;
999 if( bOverwrite
|| bNew
)
1001 FillUnoNumRule(m_xNumRules
);
1002 xPropSet
->setPropertyValue( sNumberingRules
, Any(m_xNumRules
) );
1013 void SvxXMLListStyleContext::CreateAndInsertAuto() const
1015 SAL_WARN_IF( m_bOutline
, "xmloff", "Outlines cannot be inserted here" );
1016 SAL_WARN_IF( m_xNumRules
.is(), "xmloff", "Numbering Rule is existing already" );
1018 const OUString
& rName
= GetName();
1019 if( m_bOutline
|| m_xNumRules
.is() || rName
.isEmpty() )
1021 const_cast<SvxXMLListStyleContext
*>(this)->SetValid( false );
1025 const_cast<SvxXMLListStyleContext
*>(this)->m_xNumRules
= CreateNumRule(
1026 GetImport().GetModel() );
1028 FillUnoNumRule(m_xNumRules
);
1031 Reference
< XIndexReplace
> SvxXMLListStyleContext::CreateNumRule(
1032 const Reference
< XModel
> & rModel
)
1034 Reference
<XIndexReplace
> xNumRule
;
1036 Reference
< XMultiServiceFactory
> xFactory( rModel
, UNO_QUERY
);
1037 SAL_WARN_IF( !xFactory
.is(), "xmloff", "no factory" );
1038 if( !xFactory
.is() )
1041 Reference
< XInterface
> xIfc
= xFactory
->createInstance("com.sun.star.text.NumberingRules");
1045 xNumRule
.set( xIfc
, UNO_QUERY
);
1046 SAL_WARN_IF( !xNumRule
.is(), "xmloff", "go no numbering rule" );
1051 void SvxXMLListStyleContext::SetDefaultStyle(
1052 const Reference
< XIndexReplace
> & rNumRule
,
1056 Sequence
<beans::PropertyValue
> aPropSeq( bOrdered
? 1 : 4 );
1057 beans::PropertyValue
*pProps
= aPropSeq
.getArray();
1059 pProps
->Name
= "NumberingType";
1060 (pProps
++)->Value
<<= static_cast<sal_Int16
>(bOrdered
? NumberingType::ARABIC
1061 : NumberingType::CHAR_SPECIAL
);
1064 // TODO: Bullet-Font
1065 awt::FontDescriptor aFDesc
;
1073 aFDesc
.Family
= FAMILY_DONTKNOW
;
1074 aFDesc
.Pitch
= PITCH_DONTKNOW
;
1075 aFDesc
.CharSet
= RTL_TEXTENCODING_SYMBOL
;
1076 aFDesc
.Weight
= WEIGHT_DONTKNOW
;
1077 pProps
->Name
= "BulletFont";
1078 (pProps
++)->Value
<<= aFDesc
;
1080 pProps
->Name
= "BulletChar";
1081 (pProps
++)->Value
<<= OUString(sal_Unicode(0xF000 + 149));
1082 pProps
->Name
= "CharStyleName";
1083 (pProps
++)->Value
<<= OUString( "Numbering Symbols" );
1086 rNumRule
->replaceByIndex( nLevel
, Any(aPropSeq
) );
1089 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */