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 void SetRelSize( sal_Int16 nRel
) { nRelSize
= nRel
; }
161 void SetColor( Color nColor
)
162 { m_nColor
= nColor
; bHasColor
= true; }
163 void SetSpaceBefore( sal_Int32 nSet
) { nSpaceBefore
= nSet
; }
164 void SetMinLabelWidth( sal_Int32 nSet
) { nMinLabelWidth
= nSet
; }
165 void SetMinLabelDist( sal_Int32 nSet
) { nMinLabelDist
= nSet
; }
166 void SetAdjust( sal_Int16 eSet
) { eAdjust
= eSet
; }
168 void SetBulletFontName( const OUString
& rSet
) { sBulletFontName
= rSet
; }
169 void SetBulletFontStyleName( const OUString
& rSet
)
170 { sBulletFontStyleName
= rSet
; }
171 void SetBulletFontFamily( sal_Int16 eSet
) { eBulletFontFamily
= eSet
; }
172 void SetBulletFontPitch( sal_Int16 eSet
) { eBulletFontPitch
= eSet
; }
173 void SetBulletFontEncoding( rtl_TextEncoding eSet
)
174 { eBulletFontEncoding
= eSet
; }
176 void SetImageWidth( sal_Int32 nSet
) { nImageWidth
= nSet
; }
177 void SetImageHeight( sal_Int32 nSet
) { nImageHeight
= nSet
; }
178 void SetImageVertOrient( sal_Int16 eSet
)
179 { eImageVertOrient
= eSet
; }
183 SvxXMLListLevelStyleContext_Impl(
184 SvXMLImport
& rImport
, sal_Int32 nElement
,
185 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
);
187 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
createFastChildContext(
189 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
) override
;
191 sal_Int32
GetLevel() const { return nLevel
; }
192 Sequence
<beans::PropertyValue
> GetProperties();
194 void SetPosAndSpaceMode( sal_Int16 eValue
)
196 ePosAndSpaceMode
= eValue
;
198 void SetLabelFollowedBy( sal_Int16 eValue
)
200 eLabelFollowedBy
= eValue
;
202 void SetListtabStopPosition( sal_Int32 nValue
)
204 nListtabStopPosition
= nValue
;
206 void SetFirstLineIndent( sal_Int32 nValue
)
208 nFirstLineIndent
= nValue
;
210 void SetIndentAt( sal_Int32 nValue
)
216 constexpr OUStringLiteral
gsStarBats( u
"StarBats" );
217 constexpr OUStringLiteral
gsStarMath( u
"StarMath" );
219 SvxXMLListLevelStyleContext_Impl::SvxXMLListLevelStyleContext_Impl(
220 SvXMLImport
& rImport
, sal_Int32 nElement
,
221 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
)
223 : SvXMLImportContext( rImport
)
227 , nMinLabelWidth( 0 )
231 , nNumStartValue( 1 )
232 , nNumDisplayLevels( 1 )
233 , eAdjust( HoriOrientation::LEFT
)
234 , eBulletFontFamily( FAMILY_DONTKNOW
)
235 , eBulletFontPitch( PITCH_DONTKNOW
)
236 , eBulletFontEncoding( RTL_TEXTENCODING_DONTKNOW
)
237 , eImageVertOrient(0)
241 , ePosAndSpaceMode( PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION
)
242 , eLabelFollowedBy( LabelFollow::LISTTAB
)
243 , nListtabStopPosition( 0 )
244 , nFirstLineIndent( 0 )
251 switch (nElement
& TOKEN_MASK
)
253 case XML_LIST_LEVEL_STYLE_NUMBER
:
254 case XML_OUTLINE_LEVEL_STYLE
:
257 case XML_LIST_LEVEL_STYLE_BULLET
:
260 case XML_LIST_LEVEL_STYLE_IMAGE
:
265 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
267 switch( aIter
.getToken() )
269 case XML_ELEMENT(TEXT
, XML_LEVEL
):
270 nLevel
= aIter
.toInt32();
276 case XML_ELEMENT(TEXT
, XML_STYLE_NAME
):
277 sTextStyleName
= aIter
.toString();
279 case XML_ELEMENT(TEXT
, XML_BULLET_CHAR
):
280 if (!aIter
.isEmpty())
282 cBullet
= aIter
.toString().iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
285 case XML_ELEMENT(XLINK
, XML_HREF
):
287 sImageURL
= aIter
.toString();
289 case XML_ELEMENT(XLINK
, XML_TYPE
):
290 case XML_ELEMENT(XLINK
, XML_SHOW
):
291 case XML_ELEMENT(XLINK
, XML_ACTUATE
):
292 // This properties will be ignored
294 case XML_ELEMENT(STYLE
, XML_NUM_FORMAT
):
296 sNumFormat
= aIter
.toString();
298 case XML_ELEMENT(STYLE
, XML_NUM_PREFIX
):
299 sPrefix
= aIter
.toString();
301 case XML_ELEMENT(STYLE
, XML_NUM_SUFFIX
):
302 sSuffix
= aIter
.toString();
304 case XML_ELEMENT(STYLE
, XML_NUM_LIST_FORMAT
):
305 case XML_ELEMENT(LO_EXT
, XML_NUM_LIST_FORMAT
):
306 sListFormat
= std::make_optional(aIter
.toString());
308 case XML_ELEMENT(STYLE
, XML_NUM_LETTER_SYNC
):
310 sNumLetterSync
= aIter
.toString();
312 case XML_ELEMENT(TEXT
, XML_START_VALUE
):
315 sal_Int32 nTmp
= aIter
.toInt32();
317 (nTmp
< 0) ? 1 : ( (nTmp
>SHRT_MAX
) ? SHRT_MAX
318 : static_cast<sal_Int16
>(nTmp
) );
321 case XML_ELEMENT(TEXT
, XML_DISPLAY_LEVELS
):
324 sal_Int32 nTmp
= aIter
.toInt32();
326 (nTmp
< 1) ? 1 : ( (nTmp
>SHRT_MAX
) ? SHRT_MAX
327 : static_cast<sal_Int16
>(nTmp
) );
331 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
336 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SvxXMLListLevelStyleContext_Impl::createFastChildContext(
338 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
340 if( nElement
== XML_ELEMENT(STYLE
, XML_LIST_LEVEL_PROPERTIES
) ||
341 nElement
== XML_ELEMENT(STYLE
, XML_TEXT_PROPERTIES
) )
343 return new SvxXMLListLevelStyleAttrContext_Impl( GetImport(),
348 else if( nElement
== XML_ELEMENT(OFFICE
, XML_BINARY_DATA
) )
350 if( bImage
&& sImageURL
.isEmpty() && !xBase64Stream
.is() )
352 xBase64Stream
= GetImport().GetStreamForGraphicObjectURLFromBase64();
353 if( xBase64Stream
.is() )
354 return new XMLBase64ImportContext( GetImport(), xBase64Stream
);
357 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
361 Sequence
<beans::PropertyValue
> SvxXMLListLevelStyleContext_Impl::GetProperties()
363 if (!bBullet
&& !bImage
&& !bNum
)
365 return Sequence
<beans::PropertyValue
>();
368 sal_Int16 eType
= NumberingType::NUMBER_NONE
;
369 std::vector
<beans::PropertyValue
> aProperties
;
373 eType
= NumberingType::CHAR_SPECIAL
;
377 eType
= NumberingType::BITMAP
;
381 eType
= NumberingType::ARABIC
;
382 GetImport().GetMM100UnitConverter().convertNumFormat(
383 eType
, sNumFormat
, sNumLetterSync
, true );
386 if (bBullet
&& !sSuffix
.isEmpty())
388 sal_uInt16
const nVersion(GetImport().getGeneratorVersion());
391 if (GetImport().getBuildIds(nUPD
, nBuildId
)
392 && ( (SvXMLImport::OOo_1x
== nVersion
)
393 || (SvXMLImport::OOo_2x
== nVersion
)
394 || (310 == nUPD
) || (320 == nUPD
) || (330 == nUPD
)
395 || ((300 == nUPD
) && (nBuildId
<= 9573))))
397 // #i93908# OOo < 3.4 wrote a bogus suffix for bullet chars
398 sSuffix
.clear(); // clear it
402 if (!sListFormat
.has_value())
404 // This is older document: it has no list format, but can probably contain prefix and/or suffix
405 // Generate list format string, based on this
406 sListFormat
= std::make_optional(sPrefix
);
408 for (int i
= 1; i
<= nNumDisplayLevels
; i
++)
411 *sListFormat
+= OUString::number(nLevel
- nNumDisplayLevels
+ i
+ 1);
413 if (i
!= nNumDisplayLevels
)
414 *sListFormat
+= "."; // Default separator for older ODT
417 *sListFormat
+= sSuffix
;
420 aProperties
.push_back(comphelper::makePropertyValue("NumberingType", eType
));
422 aProperties
.push_back(comphelper::makePropertyValue("Prefix", sPrefix
));
424 aProperties
.push_back(comphelper::makePropertyValue("Suffix", sSuffix
));
426 aProperties
.push_back(comphelper::makePropertyValue("Adjust", eAdjust
));
428 sal_Int32 nLeftMargin
= nSpaceBefore
+ nMinLabelWidth
;
429 aProperties
.push_back(comphelper::makePropertyValue("LeftMargin", nLeftMargin
));
431 sal_Int32 nFirstLineOffset
= -nMinLabelWidth
;
432 aProperties
.push_back(comphelper::makePropertyValue("FirstLineOffset", nFirstLineOffset
));
434 aProperties
.push_back(comphelper::makePropertyValue("SymbolTextDistance", static_cast<sal_Int16
>(nMinLabelDist
)));
436 aProperties
.push_back(comphelper::makePropertyValue("PositionAndSpaceMode", ePosAndSpaceMode
));
438 aProperties
.push_back(comphelper::makePropertyValue("LabelFollowedBy", eLabelFollowedBy
));
440 aProperties
.push_back(comphelper::makePropertyValue("ListtabStopPosition", nListtabStopPosition
));
442 aProperties
.push_back(comphelper::makePropertyValue("FirstLineIndent", nFirstLineIndent
));
444 aProperties
.push_back(comphelper::makePropertyValue("IndentAt", nIndentAt
));
446 OUString sDisplayTextStyleName
= GetImport().GetStyleDisplayName(XmlStyleFamily::TEXT_TEXT
, sTextStyleName
);
447 aProperties
.push_back(comphelper::makePropertyValue("CharStyleName", sDisplayTextStyleName
));
451 awt::FontDescriptor aFDesc
;
452 aFDesc
.Name
= sBulletFontName
;
453 if( !sBulletFontName
.isEmpty() )
455 aFDesc
.StyleName
= sBulletFontStyleName
;
456 aFDesc
.Family
= eBulletFontFamily
;
457 aFDesc
.Pitch
= eBulletFontPitch
;
458 aFDesc
.CharSet
= eBulletFontEncoding
;
459 aFDesc
.Weight
= WEIGHT_DONTKNOW
;
460 bool bStarSymbol
= false;
461 if( aFDesc
.Name
.equalsIgnoreAsciiCase( gsStarBats
) )
463 cBullet
= GetImport().ConvStarBatsCharToStarSymbol( cBullet
);
466 else if( aFDesc
.Name
.equalsIgnoreAsciiCase( gsStarMath
) )
468 cBullet
= GetImport().ConvStarMathCharToStarSymbol( cBullet
);
472 aFDesc
.Name
= "StarSymbol" ;
475 // Must append 'cBullet' even if it is zero
476 // if 'bBullet' is true and 'cBullet' is zero - BulletChar property must be 0.
477 aProperties
.push_back(comphelper::makePropertyValue("BulletChar", OUString(&cBullet
, 1)));
478 aProperties
.push_back(comphelper::makePropertyValue("BulletFont", aFDesc
));
483 uno::Reference
<graphic::XGraphic
> xGraphic
;
484 if (!sImageURL
.isEmpty())
486 xGraphic
= GetImport().loadGraphicByURL(sImageURL
);
488 else if( xBase64Stream
.is() )
490 xGraphic
= GetImport().loadGraphicFromBase64(xBase64Stream
);
493 uno::Reference
<awt::XBitmap
> xBitmap
;
495 xBitmap
.set(xGraphic
, uno::UNO_QUERY
);
499 aProperties
.push_back(comphelper::makePropertyValue("GraphicBitmap", xBitmap
));
502 awt::Size
aSize(nImageWidth
, nImageHeight
);
503 aProperties
.push_back(comphelper::makePropertyValue("GraphicSize", aSize
));
504 aProperties
.push_back(comphelper::makePropertyValue("VertOrient", eImageVertOrient
));
509 aProperties
.push_back(comphelper::makePropertyValue("StartWith", nNumStartValue
));
510 aProperties
.push_back(comphelper::makePropertyValue("ParentNumbering", nNumDisplayLevels
));
513 if( ( bNum
|| bBullet
) && nRelSize
)
515 aProperties
.push_back(comphelper::makePropertyValue("BulletRelSize", nRelSize
));
518 if( !bImage
&& bHasColor
)
520 aProperties
.push_back(comphelper::makePropertyValue("BulletColor", m_nColor
));
523 aProperties
.push_back(comphelper::makePropertyValue("ListFormat", *sListFormat
));
525 return comphelper::containerToSequence(aProperties
);
528 SvxXMLListLevelStyleAttrContext_Impl::SvxXMLListLevelStyleAttrContext_Impl(
529 SvXMLImport
& rImport
, sal_Int32
/*nElement*/,
530 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
531 SvxXMLListLevelStyleContext_Impl
& rLLevel
) :
532 SvXMLImportContext( rImport
),
533 rListLevel( rLLevel
)
535 SvXMLUnitConverter
& rUnitConv
= GetImport().GetMM100UnitConverter();
537 OUString sFontName
, sFontFamily
, sFontStyleName
, sFontFamilyGeneric
,
538 sFontPitch
, sFontCharset
;
539 OUString sVerticalPos
, sVerticalRel
;
541 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
544 switch( aIter
.getToken() )
546 case XML_ELEMENT(TEXT
, XML_SPACE_BEFORE
):
547 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView(), SHRT_MIN
, SHRT_MAX
))
548 rListLevel
.SetSpaceBefore( nVal
);
550 case XML_ELEMENT(TEXT
, XML_MIN_LABEL_WIDTH
):
551 if (rUnitConv
.convertMeasureToCore( nVal
, aIter
.toView(), 0, SHRT_MAX
))
552 rListLevel
.SetMinLabelWidth( nVal
);
554 case XML_ELEMENT(TEXT
, XML_MIN_LABEL_DISTANCE
):
555 if (rUnitConv
.convertMeasureToCore( nVal
, aIter
.toView(), 0, USHRT_MAX
))
556 rListLevel
.SetMinLabelDist( nVal
);
558 case XML_ELEMENT(FO
, XML_TEXT_ALIGN
):
559 case XML_ELEMENT(FO_COMPAT
, XML_TEXT_ALIGN
):
560 if( !aIter
.isEmpty() )
562 sal_Int16 eAdjust
= HoriOrientation::LEFT
;
563 if( IsXMLToken( aIter
, XML_CENTER
) )
564 eAdjust
= HoriOrientation::CENTER
;
565 else if( IsXMLToken( aIter
, XML_END
) )
566 eAdjust
= HoriOrientation::RIGHT
;
567 rListLevel
.SetAdjust( eAdjust
);
570 case XML_ELEMENT(STYLE
, XML_FONT_NAME
):
571 sFontName
= aIter
.toString();
573 case XML_ELEMENT(FO
, XML_FONT_FAMILY
):
574 case XML_ELEMENT(FO_COMPAT
, XML_FONT_FAMILY
):
575 sFontFamily
= aIter
.toString();
577 case XML_ELEMENT(STYLE
, XML_FONT_FAMILY_GENERIC
):
578 sFontFamilyGeneric
= aIter
.toString();
580 case XML_ELEMENT(STYLE
, XML_FONT_STYLE_NAME
):
581 sFontStyleName
= aIter
.toString();
583 case XML_ELEMENT(STYLE
, XML_FONT_PITCH
):
584 sFontPitch
= aIter
.toString();
586 case XML_ELEMENT(STYLE
, XML_FONT_CHARSET
):
587 sFontCharset
= aIter
.toString();
589 case XML_ELEMENT(STYLE
, XML_VERTICAL_POS
):
590 sVerticalPos
= aIter
.toString();
592 case XML_ELEMENT(STYLE
, XML_VERTICAL_REL
):
593 sVerticalRel
= aIter
.toString();
595 case XML_ELEMENT(FO
, XML_WIDTH
):
596 case XML_ELEMENT(FO_COMPAT
, XML_WIDTH
):
597 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView()))
598 rListLevel
.SetImageWidth( nVal
);
600 case XML_ELEMENT(FO
, XML_HEIGHT
):
601 case XML_ELEMENT(FO_COMPAT
, XML_HEIGHT
):
602 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView()))
603 rListLevel
.SetImageHeight( nVal
);
605 case XML_ELEMENT(FO
, XML_COLOR
):
606 case XML_ELEMENT(FO_COMPAT
, XML_COLOR
):
609 if (::sax::Converter::convertColor( nColor
, aIter
.toView() ))
610 rListLevel
.SetColor( nColor
);
613 case XML_ELEMENT(STYLE
, XML_USE_WINDOW_FONT_COLOR
):
615 if( IsXMLToken( aIter
, XML_TRUE
) )
616 rListLevel
.SetColor(COL_AUTO
);
619 case XML_ELEMENT(FO
, XML_FONT_SIZE
):
620 case XML_ELEMENT(FO_COMPAT
, XML_FONT_SIZE
):
621 if (::sax::Converter::convertPercent( nVal
, aIter
.toView() ))
622 rListLevel
.SetRelSize( static_cast<sal_Int16
>(nVal
) );
624 case XML_ELEMENT(TEXT
, XML_LIST_LEVEL_POSITION_AND_SPACE_MODE
):
626 sal_Int16 ePosAndSpaceMode
= PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION
;
627 if( IsXMLToken( aIter
, XML_LABEL_ALIGNMENT
) )
628 ePosAndSpaceMode
= PositionAndSpaceMode::LABEL_ALIGNMENT
;
629 rListLevel
.SetPosAndSpaceMode( ePosAndSpaceMode
);
633 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
637 if( !sFontName
.isEmpty() )
639 const XMLFontStylesContext
*pFontDecls
=
640 GetImport().GetFontDecls();
643 ::std::vector
< XMLPropertyState
> aProps
;
644 if( pFontDecls
->FillProperties( sFontName
, aProps
, 0, 1, 2, 3, 4 ) )
648 for( const auto& rProp
: aProps
)
650 switch( rProp
.mnIndex
)
653 rProp
.maValue
>>= sTmp
;
654 rListLevel
.SetBulletFontName( sTmp
);
657 rProp
.maValue
>>= sTmp
;
658 rListLevel
.SetBulletFontStyleName( sTmp
);
661 rProp
.maValue
>>= nTmp
;
662 rListLevel
.SetBulletFontFamily( nTmp
);
665 rProp
.maValue
>>= nTmp
;
666 rListLevel
.SetBulletFontPitch( nTmp
);
669 rProp
.maValue
>>= nTmp
;
670 rListLevel
.SetBulletFontEncoding( nTmp
);
677 if( !sFontFamily
.isEmpty() )
681 XMLFontFamilyNamePropHdl aFamilyNameHdl
;
682 if( aFamilyNameHdl
.importXML( sFontFamily
, aAny
, rUnitConv
) )
686 rListLevel
.SetBulletFontName( sTmp
);
689 XMLFontFamilyPropHdl aFamilyHdl
;
690 if( !sFontFamilyGeneric
.isEmpty() &&
691 aFamilyHdl
.importXML( sFontFamilyGeneric
, aAny
, rUnitConv
) )
695 rListLevel
.SetBulletFontFamily( nTmp
);
698 if( !sFontStyleName
.isEmpty() )
699 rListLevel
.SetBulletFontStyleName( sFontStyleName
);
701 XMLFontPitchPropHdl aPitchHdl
;
702 if( !sFontPitch
.isEmpty() &&
703 aPitchHdl
.importXML( sFontPitch
, aAny
, rUnitConv
) )
707 rListLevel
.SetBulletFontPitch( nTmp
);
710 XMLFontEncodingPropHdl aEncHdl
;
711 if( !sFontCharset
.isEmpty() &&
712 aEncHdl
.importXML( sFontCharset
, aAny
, rUnitConv
) )
716 rListLevel
.SetBulletFontEncoding( nTmp
);
720 sal_Int16 eVertOrient
= VertOrientation::LINE_CENTER
;
721 if( !sVerticalPos
.isEmpty() )
723 if( IsXMLToken( sVerticalPos
, XML_TOP
) )
724 eVertOrient
= VertOrientation::LINE_TOP
;
725 else if( IsXMLToken( sVerticalPos
, XML_BOTTOM
) )
726 eVertOrient
= VertOrientation::LINE_BOTTOM
;
728 if( !sVerticalRel
.isEmpty() )
730 if( IsXMLToken( sVerticalRel
, XML_BASELINE
) )
732 // TOP and BOTTOM are exchanged for a baseline relation
733 switch( eVertOrient
)
735 case VertOrientation::LINE_TOP
:
736 eVertOrient
= VertOrientation::BOTTOM
;
738 case VertOrientation::LINE_CENTER
:
739 eVertOrient
= VertOrientation::CENTER
;
741 case VertOrientation::LINE_BOTTOM
:
742 eVertOrient
= VertOrientation::TOP
;
746 else if( IsXMLToken( sVerticalRel
, XML_CHAR
) )
748 switch( eVertOrient
)
750 case VertOrientation::LINE_TOP
:
751 eVertOrient
= VertOrientation::CHAR_TOP
;
753 case VertOrientation::LINE_CENTER
:
754 eVertOrient
= VertOrientation::CHAR_CENTER
;
756 case VertOrientation::LINE_BOTTOM
:
757 eVertOrient
= VertOrientation::CHAR_BOTTOM
;
762 rListLevel
.SetImageVertOrient( eVertOrient
);
765 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SvxXMLListLevelStyleAttrContext_Impl::createFastChildContext(
767 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
769 if ( nElement
== XML_ELEMENT(STYLE
, XML_LIST_LEVEL_LABEL_ALIGNMENT
) )
771 return new SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl( GetImport(),
776 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
781 SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl::SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl(
782 SvXMLImport
& rImport
, sal_Int32
/*nElement*/,
783 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
784 SvxXMLListLevelStyleContext_Impl
& rLLevel
) :
785 SvXMLImportContext( rImport
)
787 SvXMLUnitConverter
& rUnitConv
= GetImport().GetMM100UnitConverter();
789 sal_Int16 eLabelFollowedBy
= LabelFollow::LISTTAB
;
790 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
793 switch( aIter
.getToken() )
795 case XML_ELEMENT(TEXT
, XML_LABEL_FOLLOWED_BY
):
796 case XML_ELEMENT(LO_EXT
, XML_LABEL_FOLLOWED_BY
):
798 if( eLabelFollowedBy
== LabelFollow::NEWLINE
)
799 //NewLine from LO_EXT has precedence over other values of the Non LO_EXT namespace
801 if( IsXMLToken( aIter
, XML_SPACE
) )
802 eLabelFollowedBy
= LabelFollow::SPACE
;
803 else if( IsXMLToken( aIter
, XML_NOTHING
) )
804 eLabelFollowedBy
= LabelFollow::NOTHING
;
805 else if( IsXMLToken( aIter
, XML_NEWLINE
) )
806 eLabelFollowedBy
= LabelFollow::NEWLINE
;
809 case XML_ELEMENT(TEXT
, XML_LIST_TAB_STOP_POSITION
):
810 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView(), 0, SHRT_MAX
))
811 rLLevel
.SetListtabStopPosition( nVal
);
813 case XML_ELEMENT(FO
, XML_TEXT_INDENT
):
814 case XML_ELEMENT(FO_COMPAT
, XML_TEXT_INDENT
):
815 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView(), SHRT_MIN
, SHRT_MAX
))
816 rLLevel
.SetFirstLineIndent( nVal
);
818 case XML_ELEMENT(FO
, XML_MARGIN_LEFT
):
819 case XML_ELEMENT(FO_COMPAT
, XML_MARGIN_LEFT
):
820 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView(), SHRT_MIN
, SHRT_MAX
))
821 rLLevel
.SetIndentAt( nVal
);
824 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
827 rLLevel
.SetLabelFollowedBy( eLabelFollowedBy
);
830 void SvxXMLListStyleContext::SetAttribute( sal_Int32 nElement
,
831 const OUString
& rValue
)
833 if( nElement
== XML_ELEMENT(TEXT
, XML_CONSECUTIVE_NUMBERING
) )
835 bConsecutive
= IsXMLToken( rValue
, XML_TRUE
);
839 SvXMLStyleContext::SetAttribute( nElement
, rValue
);
843 constexpr OUStringLiteral
sIsPhysical( u
"IsPhysical" );
844 constexpr OUStringLiteral
sNumberingRules( u
"NumberingRules" );
845 constexpr OUStringLiteral
sIsContinuousNumbering( u
"IsContinuousNumbering" );
847 SvxXMLListStyleContext::SvxXMLListStyleContext( SvXMLImport
& rImport
,
849 : SvXMLStyleContext( rImport
, bOutl
? XmlStyleFamily::TEXT_OUTLINE
: XmlStyleFamily::TEXT_LIST
)
850 , bConsecutive( false )
855 SvxXMLListStyleContext::~SvxXMLListStyleContext() {}
857 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SvxXMLListStyleContext::createFastChildContext(
859 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
862 ? nElement
== XML_ELEMENT(TEXT
, XML_OUTLINE_LEVEL_STYLE
)
863 : ( nElement
== XML_ELEMENT(TEXT
, XML_LIST_LEVEL_STYLE_NUMBER
) ||
864 nElement
== XML_ELEMENT(TEXT
, XML_LIST_LEVEL_STYLE_BULLET
) ||
865 nElement
== XML_ELEMENT(TEXT
, XML_LIST_LEVEL_STYLE_IMAGE
) ) )
867 rtl::Reference
<SvxXMLListLevelStyleContext_Impl
> xLevelStyle
{
868 new SvxXMLListLevelStyleContext_Impl( GetImport(), nElement
, xAttrList
)};
870 pLevelStyles
= std::make_unique
<SvxXMLListStyle_Impl
>();
871 pLevelStyles
->push_back( xLevelStyle
);
875 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
879 void SvxXMLListStyleContext::FillUnoNumRule(
880 const Reference
<container::XIndexReplace
> & rNumRule
) const
884 if( pLevelStyles
&& rNumRule
.is() )
886 sal_Int32 l_nLevels
= rNumRule
->getCount();
887 for (const auto& pLevelStyle
: *pLevelStyles
)
889 sal_Int32 nLevel
= pLevelStyle
->GetLevel();
890 if( nLevel
>= 0 && nLevel
< l_nLevels
)
892 Sequence
<beans::PropertyValue
> aProps
=
893 pLevelStyle
->GetProperties();
894 rNumRule
->replaceByIndex( nLevel
, Any(aProps
) );
899 Reference
< XPropertySet
> xPropSet( rNumRule
, UNO_QUERY
);
900 Reference
< XPropertySetInfo
> xPropSetInfo
;
902 xPropSetInfo
= xPropSet
->getPropertySetInfo();
903 if( xPropSetInfo
.is() &&
904 xPropSetInfo
->hasPropertyByName( sIsContinuousNumbering
) )
906 xPropSet
->setPropertyValue( sIsContinuousNumbering
, Any(bConsecutive
) );
909 catch (const Exception
&)
911 TOOLS_WARN_EXCEPTION("xmloff.style", "" );
915 void SvxXMLListStyleContext::CreateAndInsertLate( bool bOverwrite
)
921 const Reference
< XIndexReplace
>& rNumRule
=
922 GetImport().GetTextImport()->GetChapterNumbering();
923 // We don't set xNumberingRules here, to avoid using them
924 // as numbering rules.
926 FillUnoNumRule(rNumRule
);
931 Reference
< XStyle
> xStyle
;
932 const OUString
& rName
= GetDisplayName();
933 if( rName
.isEmpty() )
939 const Reference
< XNameContainer
>& rNumStyles
=
940 GetImport().GetTextImport()->GetNumberingStyles();
941 if( !rNumStyles
.is() )
948 if( rNumStyles
->hasByName( rName
) )
950 Any aAny
= rNumStyles
->getByName( rName
);
955 Reference
< XMultiServiceFactory
> xFactory( GetImport().GetModel(),
957 SAL_WARN_IF( !xFactory
.is(), "xmloff", "no factory" );
961 Reference
< XInterface
> xIfc
= xFactory
->createInstance("com.sun.star.style.NumberingStyle");
964 Reference
< XStyle
> xTmp( xIfc
, UNO_QUERY
);
969 rNumStyles
->insertByName( rName
, Any(xStyle
) );
973 Reference
< XPropertySet
> xPropSet( xStyle
, UNO_QUERY
);
974 Reference
< XPropertySetInfo
> xPropSetInfo
=
975 xPropSet
->getPropertySetInfo();
976 if( !bNew
&& xPropSetInfo
->hasPropertyByName( sIsPhysical
) )
978 Any aAny
= xPropSet
->getPropertyValue( sIsPhysical
);
979 bNew
= !*o3tl::doAccess
<bool>(aAny
);
982 if ( xPropSetInfo
->hasPropertyByName( "Hidden" ) )
983 xPropSet
->setPropertyValue( "Hidden", uno::Any( IsHidden( ) ) );
985 if( rName
!= GetName() )
986 GetImport().AddStyleDisplayName( XmlStyleFamily::TEXT_LIST
,
989 Any aAny
= xPropSet
->getPropertyValue( sNumberingRules
);
991 if( bOverwrite
|| bNew
)
993 FillUnoNumRule(xNumRules
);
994 xPropSet
->setPropertyValue( sNumberingRules
, Any(xNumRules
) );
1005 void SvxXMLListStyleContext::CreateAndInsertAuto() const
1007 SAL_WARN_IF( bOutline
, "xmloff", "Outlines cannot be inserted here" );
1008 SAL_WARN_IF( xNumRules
.is(), "xmloff", "Numbering Rule is existing already" );
1010 const OUString
& rName
= GetName();
1011 if( bOutline
|| xNumRules
.is() || rName
.isEmpty() )
1013 const_cast<SvxXMLListStyleContext
*>(this)->SetValid( false );
1017 const_cast<SvxXMLListStyleContext
*>(this)->xNumRules
= CreateNumRule(
1018 GetImport().GetModel() );
1020 FillUnoNumRule(xNumRules
);
1023 Reference
< XIndexReplace
> SvxXMLListStyleContext::CreateNumRule(
1024 const Reference
< XModel
> & rModel
)
1026 Reference
<XIndexReplace
> xNumRule
;
1028 Reference
< XMultiServiceFactory
> xFactory( rModel
, UNO_QUERY
);
1029 SAL_WARN_IF( !xFactory
.is(), "xmloff", "no factory" );
1030 if( !xFactory
.is() )
1033 Reference
< XInterface
> xIfc
= xFactory
->createInstance("com.sun.star.text.NumberingRules");
1037 xNumRule
.set( xIfc
, UNO_QUERY
);
1038 SAL_WARN_IF( !xNumRule
.is(), "xmloff", "go no numbering rule" );
1043 void SvxXMLListStyleContext::SetDefaultStyle(
1044 const Reference
< XIndexReplace
> & rNumRule
,
1048 Sequence
<beans::PropertyValue
> aPropSeq( bOrdered
? 1 : 4 );
1049 beans::PropertyValue
*pProps
= aPropSeq
.getArray();
1051 pProps
->Name
= "NumberingType";
1052 (pProps
++)->Value
<<= static_cast<sal_Int16
>(bOrdered
? NumberingType::ARABIC
1053 : NumberingType::CHAR_SPECIAL
);
1056 // TODO: Bullet-Font
1057 awt::FontDescriptor aFDesc
;
1065 aFDesc
.Family
= FAMILY_DONTKNOW
;
1066 aFDesc
.Pitch
= PITCH_DONTKNOW
;
1067 aFDesc
.CharSet
= RTL_TEXTENCODING_SYMBOL
;
1068 aFDesc
.Weight
= WEIGHT_DONTKNOW
;
1069 pProps
->Name
= "BulletFont";
1070 (pProps
++)->Value
<<= aFDesc
;
1072 pProps
->Name
= "BulletChar";
1073 (pProps
++)->Value
<<= OUString(sal_Unicode(0xF000 + 149));
1074 pProps
->Name
= "CharStyleName";
1075 (pProps
++)->Value
<<= OUString( "Numbering Symbols" );
1078 rNumRule
->replaceByIndex( nLevel
, Any(aPropSeq
) );
1081 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */