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 <sal/log.hxx>
41 #include <comphelper/diagnose_ex.hxx>
42 #include <comphelper/sequence.hxx>
43 #include <comphelper/propertyvalue.hxx>
45 #include <tools/fontenum.hxx>
46 #include <tools/color.hxx>
48 #include <sax/tools/converter.hxx>
50 #include <vcl/vclenum.hxx>
52 #include <xmloff/xmlnamespace.hxx>
53 #include <xmloff/xmlimp.hxx>
54 #include <xmloff/XMLBase64ImportContext.hxx>
55 #include <xmloff/xmltoken.hxx>
57 #include <xmloff/xmluconv.hxx>
58 #include "fonthdl.hxx"
59 #include <xmloff/XMLFontStylesContext.hxx>
60 #include <xmloff/families.hxx>
61 #include <xmloff/maptype.hxx>
63 #include <xmloff/xmlnumi.hxx>
66 using namespace ::com::sun::star
;
67 using namespace ::com::sun::star::uno
;
68 using namespace ::com::sun::star::style
;
69 using namespace ::com::sun::star::text
;
70 using namespace ::com::sun::star::beans
;
71 using namespace ::com::sun::star::container
;
72 using namespace ::com::sun::star::lang
;
73 using namespace ::com::sun::star::frame
;
74 using namespace ::xmloff::token
;
75 using namespace ::com::sun::star::io
;
77 class SvxXMLListLevelStyleContext_Impl
;
81 class SvxXMLListLevelStyleAttrContext_Impl
: public SvXMLImportContext
83 SvxXMLListLevelStyleContext_Impl
& rListLevel
;
87 SvxXMLListLevelStyleAttrContext_Impl(
88 SvXMLImport
& rImport
, sal_Int32 nElement
,
89 const Reference
< xml::sax::XFastAttributeList
>& xAttrList
,
90 SvxXMLListLevelStyleContext_Impl
& rLLevel
);
92 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
createFastChildContext(
94 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
) override
;
97 class SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl
: public SvXMLImportContext
101 SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl(
102 SvXMLImport
& rImport
, sal_Int32 nElement
,
103 const Reference
< xml::sax::XFastAttributeList
>& xAttrList
,
104 SvxXMLListLevelStyleContext_Impl
& rLLevel
);
109 class SvxXMLListLevelStyleContext_Impl
: public SvXMLImportContext
111 friend SvxXMLListLevelStyleAttrContext_Impl
;
115 std::optional
<OUString
> sListFormat
; // It is optional to distinguish empty format string
116 // from not existing format string in old docs
117 OUString sTextStyleName
;
119 OUString sNumLetterSync
;
120 OUString sBulletFontName
;
121 OUString sBulletFontStyleName
;
124 Reference
< XOutputStream
> xBase64Stream
;
127 sal_Int32 nSpaceBefore
;
128 sal_Int32 nMinLabelWidth
;
129 sal_Int32 nMinLabelDist
;
130 sal_Int32 nImageWidth
;
131 sal_Int32 nImageHeight
;
132 sal_Int16 nNumStartValue
;
133 sal_Int16 nNumDisplayLevels
;
136 sal_Int16 eBulletFontFamily
;
137 sal_Int16 eBulletFontPitch
;
138 rtl_TextEncoding eBulletFontEncoding
;
139 sal_Int16 eImageVertOrient
;
146 sal_Int16 ePosAndSpaceMode
;
147 sal_Int16 eLabelFollowedBy
;
148 sal_Int32 nListtabStopPosition
;
149 sal_Int32 nFirstLineIndent
;
157 bool m_bIsLegal
= false;
159 void SetRelSize( sal_Int16 nRel
) { nRelSize
= nRel
; }
160 void SetColor( Color nColor
)
161 { m_nColor
= nColor
; bHasColor
= true; }
162 void SetSpaceBefore( sal_Int32 nSet
) { nSpaceBefore
= nSet
; }
163 void SetMinLabelWidth( sal_Int32 nSet
) { nMinLabelWidth
= nSet
; }
164 void SetMinLabelDist( sal_Int32 nSet
) { nMinLabelDist
= nSet
; }
165 void SetAdjust( sal_Int16 eSet
) { eAdjust
= eSet
; }
167 void SetBulletFontName( const OUString
& rSet
) { sBulletFontName
= rSet
; }
168 void SetBulletFontStyleName( const OUString
& rSet
)
169 { sBulletFontStyleName
= rSet
; }
170 void SetBulletFontFamily( sal_Int16 eSet
) { eBulletFontFamily
= eSet
; }
171 void SetBulletFontPitch( sal_Int16 eSet
) { eBulletFontPitch
= eSet
; }
172 void SetBulletFontEncoding( rtl_TextEncoding eSet
)
173 { eBulletFontEncoding
= eSet
; }
175 void SetImageWidth( sal_Int32 nSet
) { nImageWidth
= nSet
; }
176 void SetImageHeight( sal_Int32 nSet
) { nImageHeight
= nSet
; }
177 void SetImageVertOrient( sal_Int16 eSet
)
178 { eImageVertOrient
= eSet
; }
182 SvxXMLListLevelStyleContext_Impl(
183 SvXMLImport
& rImport
, sal_Int32 nElement
,
184 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
);
186 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
createFastChildContext(
188 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
) override
;
190 sal_Int32
GetLevel() const { return nLevel
; }
191 Sequence
<beans::PropertyValue
> GetProperties();
193 void SetPosAndSpaceMode( sal_Int16 eValue
)
195 ePosAndSpaceMode
= eValue
;
197 void SetLabelFollowedBy( sal_Int16 eValue
)
199 eLabelFollowedBy
= eValue
;
201 void SetListtabStopPosition( sal_Int32 nValue
)
203 nListtabStopPosition
= nValue
;
205 void SetFirstLineIndent( sal_Int32 nValue
)
207 nFirstLineIndent
= nValue
;
209 void SetIndentAt( sal_Int32 nValue
)
215 constexpr OUStringLiteral
gsStarBats( u
"StarBats" );
216 constexpr OUStringLiteral
gsStarMath( u
"StarMath" );
218 SvxXMLListLevelStyleContext_Impl::SvxXMLListLevelStyleContext_Impl(
219 SvXMLImport
& rImport
, sal_Int32 nElement
,
220 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
)
222 : SvXMLImportContext( rImport
)
223 , sNumFormat( u
"1"_ustr
)
226 , nMinLabelWidth( 0 )
230 , nNumStartValue( 1 )
231 , nNumDisplayLevels( 1 )
232 , eAdjust( HoriOrientation::LEFT
)
233 , eBulletFontFamily( FAMILY_DONTKNOW
)
234 , eBulletFontPitch( PITCH_DONTKNOW
)
235 , eBulletFontEncoding( RTL_TEXTENCODING_DONTKNOW
)
236 , eImageVertOrient(0)
240 , ePosAndSpaceMode( PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION
)
241 , eLabelFollowedBy( LabelFollow::LISTTAB
)
242 , nListtabStopPosition( 0 )
243 , nFirstLineIndent( 0 )
250 switch (nElement
& TOKEN_MASK
)
252 case XML_LIST_LEVEL_STYLE_NUMBER
:
253 case XML_OUTLINE_LEVEL_STYLE
:
256 case XML_LIST_LEVEL_STYLE_BULLET
:
259 case XML_LIST_LEVEL_STYLE_IMAGE
:
264 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
266 switch( aIter
.getToken() )
268 case XML_ELEMENT(TEXT
, XML_LEVEL
):
269 nLevel
= aIter
.toInt32();
275 case XML_ELEMENT(TEXT
, XML_STYLE_NAME
):
276 sTextStyleName
= aIter
.toString();
278 case XML_ELEMENT(TEXT
, XML_BULLET_CHAR
):
279 if (!aIter
.isEmpty())
281 cBullet
= aIter
.toString().iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
284 case XML_ELEMENT(XLINK
, XML_HREF
):
286 sImageURL
= aIter
.toString();
288 case XML_ELEMENT(XLINK
, XML_TYPE
):
289 case XML_ELEMENT(XLINK
, XML_SHOW
):
290 case XML_ELEMENT(XLINK
, XML_ACTUATE
):
291 // This properties will be ignored
293 case XML_ELEMENT(STYLE
, XML_NUM_FORMAT
):
295 sNumFormat
= aIter
.toString();
297 case XML_ELEMENT(STYLE
, XML_NUM_PREFIX
):
298 sPrefix
= aIter
.toString();
300 case XML_ELEMENT(STYLE
, XML_NUM_SUFFIX
):
301 sSuffix
= aIter
.toString();
303 case XML_ELEMENT(STYLE
, XML_NUM_LIST_FORMAT
):
304 case XML_ELEMENT(LO_EXT
, XML_NUM_LIST_FORMAT
):
305 sListFormat
= std::make_optional(aIter
.toString());
307 case XML_ELEMENT(LO_EXT
, XML_IS_LEGAL
):
308 m_bIsLegal
= aIter
.toBoolean();
310 case XML_ELEMENT(STYLE
, XML_NUM_LETTER_SYNC
):
312 sNumLetterSync
= aIter
.toString();
314 case XML_ELEMENT(TEXT
, XML_START_VALUE
):
317 sal_Int32 nTmp
= aIter
.toInt32();
319 (nTmp
< 0) ? 1 : ( (nTmp
>SHRT_MAX
) ? SHRT_MAX
320 : static_cast<sal_Int16
>(nTmp
) );
323 case XML_ELEMENT(TEXT
, XML_DISPLAY_LEVELS
):
326 sal_Int32 nTmp
= aIter
.toInt32();
328 (nTmp
< 1) ? 1 : ( (nTmp
>SHRT_MAX
) ? SHRT_MAX
329 : static_cast<sal_Int16
>(nTmp
) );
333 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
338 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SvxXMLListLevelStyleContext_Impl::createFastChildContext(
340 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
342 if( nElement
== XML_ELEMENT(STYLE
, XML_LIST_LEVEL_PROPERTIES
) ||
343 nElement
== XML_ELEMENT(STYLE
, XML_TEXT_PROPERTIES
) )
345 return new SvxXMLListLevelStyleAttrContext_Impl( GetImport(),
350 else if( nElement
== XML_ELEMENT(OFFICE
, XML_BINARY_DATA
) )
352 if( bImage
&& sImageURL
.isEmpty() && !xBase64Stream
.is() )
354 xBase64Stream
= GetImport().GetStreamForGraphicObjectURLFromBase64();
355 if( xBase64Stream
.is() )
356 return new XMLBase64ImportContext( GetImport(), xBase64Stream
);
359 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
363 Sequence
<beans::PropertyValue
> SvxXMLListLevelStyleContext_Impl::GetProperties()
365 if (!bBullet
&& !bImage
&& !bNum
)
367 return Sequence
<beans::PropertyValue
>();
370 sal_Int16 eType
= NumberingType::NUMBER_NONE
;
371 std::vector
<beans::PropertyValue
> aProperties
;
375 eType
= NumberingType::CHAR_SPECIAL
;
379 eType
= NumberingType::BITMAP
;
383 eType
= NumberingType::ARABIC
;
384 GetImport().GetMM100UnitConverter().convertNumFormat(
385 eType
, sNumFormat
, sNumLetterSync
, true );
388 if (bBullet
&& !sSuffix
.isEmpty())
390 sal_uInt16
const nVersion(GetImport().getGeneratorVersion());
393 if (GetImport().getBuildIds(nUPD
, nBuildId
)
394 && ( (SvXMLImport::OOo_1x
== nVersion
)
395 || (SvXMLImport::OOo_2x
== nVersion
)
396 || (310 == nUPD
) || (320 == nUPD
) || (330 == nUPD
)
397 || ((300 == nUPD
) && (nBuildId
<= 9573))))
399 // #i93908# OOo < 3.4 wrote a bogus suffix for bullet chars
400 sSuffix
.clear(); // clear it
404 if (!sListFormat
.has_value())
406 // This is older document: it has no list format, but can probably contain prefix and/or suffix
407 // Generate list format string, based on this
408 sListFormat
= std::make_optional(sPrefix
);
410 for (int i
= 1; i
<= nNumDisplayLevels
; i
++)
413 *sListFormat
+= OUString::number(nLevel
- nNumDisplayLevels
+ i
+ 1);
415 if (i
!= nNumDisplayLevels
)
416 *sListFormat
+= "."; // Default separator for older ODT
419 *sListFormat
+= sSuffix
;
422 aProperties
.push_back(comphelper::makePropertyValue(u
"NumberingType"_ustr
, eType
));
424 aProperties
.push_back(comphelper::makePropertyValue(u
"Prefix"_ustr
, sPrefix
));
426 aProperties
.push_back(comphelper::makePropertyValue(u
"Suffix"_ustr
, sSuffix
));
428 aProperties
.push_back(comphelper::makePropertyValue(u
"Adjust"_ustr
, eAdjust
));
430 sal_Int32 nLeftMargin
= nSpaceBefore
+ nMinLabelWidth
;
431 aProperties
.push_back(comphelper::makePropertyValue(u
"LeftMargin"_ustr
, nLeftMargin
));
433 sal_Int32 nFirstLineOffset
= -nMinLabelWidth
;
434 aProperties
.push_back(comphelper::makePropertyValue(u
"FirstLineOffset"_ustr
, nFirstLineOffset
));
436 aProperties
.push_back(comphelper::makePropertyValue(u
"SymbolTextDistance"_ustr
, static_cast<sal_Int16
>(nMinLabelDist
)));
438 aProperties
.push_back(comphelper::makePropertyValue(u
"PositionAndSpaceMode"_ustr
, ePosAndSpaceMode
));
440 aProperties
.push_back(comphelper::makePropertyValue(u
"LabelFollowedBy"_ustr
, eLabelFollowedBy
));
442 aProperties
.push_back(comphelper::makePropertyValue(u
"ListtabStopPosition"_ustr
, nListtabStopPosition
));
444 aProperties
.push_back(comphelper::makePropertyValue(u
"FirstLineIndent"_ustr
, nFirstLineIndent
));
446 aProperties
.push_back(comphelper::makePropertyValue(u
"IndentAt"_ustr
, nIndentAt
));
448 OUString sDisplayTextStyleName
= GetImport().GetStyleDisplayName(XmlStyleFamily::TEXT_TEXT
, sTextStyleName
);
449 aProperties
.push_back(comphelper::makePropertyValue(u
"CharStyleName"_ustr
, sDisplayTextStyleName
));
453 awt::FontDescriptor aFDesc
;
454 aFDesc
.Name
= sBulletFontName
;
455 if( !sBulletFontName
.isEmpty() )
457 aFDesc
.StyleName
= sBulletFontStyleName
;
458 aFDesc
.Family
= eBulletFontFamily
;
459 aFDesc
.Pitch
= eBulletFontPitch
;
460 aFDesc
.CharSet
= eBulletFontEncoding
;
461 aFDesc
.Weight
= WEIGHT_DONTKNOW
;
462 bool bStarSymbol
= false;
463 if( aFDesc
.Name
.equalsIgnoreAsciiCase( gsStarBats
) )
465 cBullet
= GetImport().ConvStarBatsCharToStarSymbol( cBullet
);
468 else if( aFDesc
.Name
.equalsIgnoreAsciiCase( gsStarMath
) )
470 cBullet
= GetImport().ConvStarMathCharToStarSymbol( cBullet
);
474 aFDesc
.Name
= "StarSymbol" ;
477 // Must append 'cBullet' even if it is zero
478 // if 'bBullet' is true and 'cBullet' is zero - BulletChar property must be 0.
479 aProperties
.push_back(comphelper::makePropertyValue(u
"BulletChar"_ustr
, OUString(&cBullet
, 1)));
480 aProperties
.push_back(comphelper::makePropertyValue(u
"BulletFont"_ustr
, aFDesc
));
485 uno::Reference
<graphic::XGraphic
> xGraphic
;
486 if (!sImageURL
.isEmpty())
488 xGraphic
= GetImport().loadGraphicByURL(sImageURL
);
490 else if( xBase64Stream
.is() )
492 xGraphic
= GetImport().loadGraphicFromBase64(xBase64Stream
);
495 uno::Reference
<awt::XBitmap
> xBitmap
;
497 xBitmap
.set(xGraphic
, uno::UNO_QUERY
);
501 aProperties
.push_back(comphelper::makePropertyValue(u
"GraphicBitmap"_ustr
, xBitmap
));
504 awt::Size
aSize(nImageWidth
, nImageHeight
);
505 aProperties
.push_back(comphelper::makePropertyValue(u
"GraphicSize"_ustr
, aSize
));
506 aProperties
.push_back(comphelper::makePropertyValue(u
"VertOrient"_ustr
, eImageVertOrient
));
511 aProperties
.push_back(comphelper::makePropertyValue(u
"StartWith"_ustr
, nNumStartValue
));
512 aProperties
.push_back(comphelper::makePropertyValue(u
"ParentNumbering"_ustr
, nNumDisplayLevels
));
515 if( ( bNum
|| bBullet
) && nRelSize
)
517 aProperties
.push_back(comphelper::makePropertyValue(u
"BulletRelSize"_ustr
, nRelSize
));
520 if( !bImage
&& bHasColor
)
522 aProperties
.push_back(comphelper::makePropertyValue(u
"BulletColor"_ustr
, m_nColor
));
525 aProperties
.push_back(comphelper::makePropertyValue(u
"ListFormat"_ustr
, *sListFormat
));
528 aProperties
.push_back(comphelper::makePropertyValue(u
"IsLegal"_ustr
, true));
530 return comphelper::containerToSequence(aProperties
);
533 SvxXMLListLevelStyleAttrContext_Impl::SvxXMLListLevelStyleAttrContext_Impl(
534 SvXMLImport
& rImport
, sal_Int32
/*nElement*/,
535 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
536 SvxXMLListLevelStyleContext_Impl
& rLLevel
) :
537 SvXMLImportContext( rImport
),
538 rListLevel( rLLevel
)
540 SvXMLUnitConverter
& rUnitConv
= GetImport().GetMM100UnitConverter();
542 OUString sFontName
, sFontFamily
, sFontStyleName
, sFontFamilyGeneric
,
543 sFontPitch
, sFontCharset
;
544 OUString sVerticalPos
, sVerticalRel
;
546 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
549 switch( aIter
.getToken() )
551 case XML_ELEMENT(TEXT
, XML_SPACE_BEFORE
):
552 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView(), SHRT_MIN
, SHRT_MAX
))
553 rListLevel
.SetSpaceBefore( nVal
);
555 case XML_ELEMENT(TEXT
, XML_MIN_LABEL_WIDTH
):
556 if (rUnitConv
.convertMeasureToCore( nVal
, aIter
.toView(), 0, SHRT_MAX
))
557 rListLevel
.SetMinLabelWidth( nVal
);
559 case XML_ELEMENT(TEXT
, XML_MIN_LABEL_DISTANCE
):
560 if (rUnitConv
.convertMeasureToCore( nVal
, aIter
.toView(), 0, USHRT_MAX
))
561 rListLevel
.SetMinLabelDist( nVal
);
563 case XML_ELEMENT(FO
, XML_TEXT_ALIGN
):
564 case XML_ELEMENT(FO_COMPAT
, XML_TEXT_ALIGN
):
565 if( !aIter
.isEmpty() )
567 sal_Int16 eAdjust
= HoriOrientation::LEFT
;
568 if( IsXMLToken( aIter
, XML_CENTER
) )
569 eAdjust
= HoriOrientation::CENTER
;
570 else if( IsXMLToken( aIter
, XML_END
) )
571 eAdjust
= HoriOrientation::RIGHT
;
572 rListLevel
.SetAdjust( eAdjust
);
575 case XML_ELEMENT(STYLE
, XML_FONT_NAME
):
576 sFontName
= aIter
.toString();
578 case XML_ELEMENT(FO
, XML_FONT_FAMILY
):
579 case XML_ELEMENT(FO_COMPAT
, XML_FONT_FAMILY
):
580 sFontFamily
= aIter
.toString();
582 case XML_ELEMENT(STYLE
, XML_FONT_FAMILY_GENERIC
):
583 sFontFamilyGeneric
= aIter
.toString();
585 case XML_ELEMENT(STYLE
, XML_FONT_STYLE_NAME
):
586 sFontStyleName
= aIter
.toString();
588 case XML_ELEMENT(STYLE
, XML_FONT_PITCH
):
589 sFontPitch
= aIter
.toString();
591 case XML_ELEMENT(STYLE
, XML_FONT_CHARSET
):
592 sFontCharset
= aIter
.toString();
594 case XML_ELEMENT(STYLE
, XML_VERTICAL_POS
):
595 sVerticalPos
= aIter
.toString();
597 case XML_ELEMENT(STYLE
, XML_VERTICAL_REL
):
598 sVerticalRel
= aIter
.toString();
600 case XML_ELEMENT(FO
, XML_WIDTH
):
601 case XML_ELEMENT(FO_COMPAT
, XML_WIDTH
):
602 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView()))
603 rListLevel
.SetImageWidth( nVal
);
605 case XML_ELEMENT(FO
, XML_HEIGHT
):
606 case XML_ELEMENT(FO_COMPAT
, XML_HEIGHT
):
607 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView()))
608 rListLevel
.SetImageHeight( nVal
);
610 case XML_ELEMENT(FO
, XML_COLOR
):
611 case XML_ELEMENT(FO_COMPAT
, XML_COLOR
):
614 if (::sax::Converter::convertColor( nColor
, aIter
.toView() ))
615 rListLevel
.SetColor( nColor
);
618 case XML_ELEMENT(STYLE
, XML_USE_WINDOW_FONT_COLOR
):
620 if( IsXMLToken( aIter
, XML_TRUE
) )
621 rListLevel
.SetColor(COL_AUTO
);
624 case XML_ELEMENT(FO
, XML_FONT_SIZE
):
625 case XML_ELEMENT(FO_COMPAT
, XML_FONT_SIZE
):
626 if (::sax::Converter::convertPercent( nVal
, aIter
.toView() ))
627 rListLevel
.SetRelSize( static_cast<sal_Int16
>(nVal
) );
629 case XML_ELEMENT(TEXT
, XML_LIST_LEVEL_POSITION_AND_SPACE_MODE
):
631 sal_Int16 ePosAndSpaceMode
= PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION
;
632 if( IsXMLToken( aIter
, XML_LABEL_ALIGNMENT
) )
633 ePosAndSpaceMode
= PositionAndSpaceMode::LABEL_ALIGNMENT
;
634 rListLevel
.SetPosAndSpaceMode( ePosAndSpaceMode
);
638 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
642 if( !sFontName
.isEmpty() )
644 const XMLFontStylesContext
*pFontDecls
=
645 GetImport().GetFontDecls();
648 ::std::vector
< XMLPropertyState
> aProps
;
649 if( pFontDecls
->FillProperties( sFontName
, aProps
, 0, 1, 2, 3, 4 ) )
653 for( const auto& rProp
: aProps
)
655 switch( rProp
.mnIndex
)
658 rProp
.maValue
>>= sTmp
;
659 rListLevel
.SetBulletFontName( sTmp
);
662 rProp
.maValue
>>= sTmp
;
663 rListLevel
.SetBulletFontStyleName( sTmp
);
666 rProp
.maValue
>>= nTmp
;
667 rListLevel
.SetBulletFontFamily( nTmp
);
670 rProp
.maValue
>>= nTmp
;
671 rListLevel
.SetBulletFontPitch( nTmp
);
674 rProp
.maValue
>>= nTmp
;
675 rListLevel
.SetBulletFontEncoding( nTmp
);
682 if( !sFontFamily
.isEmpty() )
686 XMLFontFamilyNamePropHdl aFamilyNameHdl
;
687 if( aFamilyNameHdl
.importXML( sFontFamily
, aAny
, rUnitConv
) )
691 rListLevel
.SetBulletFontName( sTmp
);
694 XMLFontFamilyPropHdl aFamilyHdl
;
695 if( !sFontFamilyGeneric
.isEmpty() &&
696 aFamilyHdl
.importXML( sFontFamilyGeneric
, aAny
, rUnitConv
) )
700 rListLevel
.SetBulletFontFamily( nTmp
);
703 if( !sFontStyleName
.isEmpty() )
704 rListLevel
.SetBulletFontStyleName( sFontStyleName
);
706 XMLFontPitchPropHdl aPitchHdl
;
707 if( !sFontPitch
.isEmpty() &&
708 aPitchHdl
.importXML( sFontPitch
, aAny
, rUnitConv
) )
712 rListLevel
.SetBulletFontPitch( nTmp
);
715 XMLFontEncodingPropHdl aEncHdl
;
716 if( !sFontCharset
.isEmpty() &&
717 aEncHdl
.importXML( sFontCharset
, aAny
, rUnitConv
) )
721 rListLevel
.SetBulletFontEncoding( nTmp
);
725 sal_Int16 eVertOrient
= VertOrientation::LINE_CENTER
;
726 if( !sVerticalPos
.isEmpty() )
728 if( IsXMLToken( sVerticalPos
, XML_TOP
) )
729 eVertOrient
= VertOrientation::LINE_TOP
;
730 else if( IsXMLToken( sVerticalPos
, XML_BOTTOM
) )
731 eVertOrient
= VertOrientation::LINE_BOTTOM
;
733 if( !sVerticalRel
.isEmpty() )
735 if( IsXMLToken( sVerticalRel
, XML_BASELINE
) )
737 // TOP and BOTTOM are exchanged for a baseline relation
738 switch( eVertOrient
)
740 case VertOrientation::LINE_TOP
:
741 eVertOrient
= VertOrientation::BOTTOM
;
743 case VertOrientation::LINE_CENTER
:
744 eVertOrient
= VertOrientation::CENTER
;
746 case VertOrientation::LINE_BOTTOM
:
747 eVertOrient
= VertOrientation::TOP
;
751 else if( IsXMLToken( sVerticalRel
, XML_CHAR
) )
753 switch( eVertOrient
)
755 case VertOrientation::LINE_TOP
:
756 eVertOrient
= VertOrientation::CHAR_TOP
;
758 case VertOrientation::LINE_CENTER
:
759 eVertOrient
= VertOrientation::CHAR_CENTER
;
761 case VertOrientation::LINE_BOTTOM
:
762 eVertOrient
= VertOrientation::CHAR_BOTTOM
;
767 rListLevel
.SetImageVertOrient( eVertOrient
);
770 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SvxXMLListLevelStyleAttrContext_Impl::createFastChildContext(
772 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
774 if ( nElement
== XML_ELEMENT(STYLE
, XML_LIST_LEVEL_LABEL_ALIGNMENT
) )
776 return new SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl( GetImport(),
781 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
786 SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl::SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl(
787 SvXMLImport
& rImport
, sal_Int32
/*nElement*/,
788 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
789 SvxXMLListLevelStyleContext_Impl
& rLLevel
) :
790 SvXMLImportContext( rImport
)
792 SvXMLUnitConverter
& rUnitConv
= GetImport().GetMM100UnitConverter();
794 sal_Int16 eLabelFollowedBy
= LabelFollow::LISTTAB
;
795 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
798 switch( aIter
.getToken() )
800 case XML_ELEMENT(TEXT
, XML_LABEL_FOLLOWED_BY
):
801 case XML_ELEMENT(LO_EXT
, XML_LABEL_FOLLOWED_BY
):
803 if( eLabelFollowedBy
== LabelFollow::NEWLINE
)
804 //NewLine from LO_EXT has precedence over other values of the Non LO_EXT namespace
806 if( IsXMLToken( aIter
, XML_SPACE
) )
807 eLabelFollowedBy
= LabelFollow::SPACE
;
808 else if( IsXMLToken( aIter
, XML_NOTHING
) )
809 eLabelFollowedBy
= LabelFollow::NOTHING
;
810 else if( IsXMLToken( aIter
, XML_NEWLINE
) )
811 eLabelFollowedBy
= LabelFollow::NEWLINE
;
814 case XML_ELEMENT(TEXT
, XML_LIST_TAB_STOP_POSITION
):
815 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView(), 0, SHRT_MAX
))
816 rLLevel
.SetListtabStopPosition( nVal
);
818 case XML_ELEMENT(FO
, XML_TEXT_INDENT
):
819 case XML_ELEMENT(FO_COMPAT
, XML_TEXT_INDENT
):
820 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView(), SHRT_MIN
, SHRT_MAX
))
821 rLLevel
.SetFirstLineIndent( nVal
);
823 case XML_ELEMENT(FO
, XML_MARGIN_LEFT
):
824 case XML_ELEMENT(FO_COMPAT
, XML_MARGIN_LEFT
):
825 if (rUnitConv
.convertMeasureToCore(nVal
, aIter
.toView(), SHRT_MIN
, SHRT_MAX
))
826 rLLevel
.SetIndentAt( nVal
);
829 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
832 rLLevel
.SetLabelFollowedBy( eLabelFollowedBy
);
835 void SvxXMLListStyleContext::SetAttribute( sal_Int32 nElement
,
836 const OUString
& rValue
)
838 if( nElement
== XML_ELEMENT(TEXT
, XML_CONSECUTIVE_NUMBERING
) )
840 m_bConsecutive
= IsXMLToken( rValue
, XML_TRUE
);
844 SvXMLStyleContext::SetAttribute( nElement
, rValue
);
848 constexpr OUString
sIsPhysical( u
"IsPhysical"_ustr
);
849 constexpr OUString
sNumberingRules( u
"NumberingRules"_ustr
);
850 constexpr OUString
sIsContinuousNumbering( u
"IsContinuousNumbering"_ustr
);
852 SvxXMLListStyleContext::SvxXMLListStyleContext( SvXMLImport
& rImport
,
854 : SvXMLStyleContext( rImport
, bOutl
? XmlStyleFamily::TEXT_OUTLINE
: XmlStyleFamily::TEXT_LIST
)
855 , m_bConsecutive( false )
856 , m_bOutline( bOutl
)
860 SvxXMLListStyleContext::~SvxXMLListStyleContext() {}
862 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SvxXMLListStyleContext::createFastChildContext(
864 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
867 ? nElement
== XML_ELEMENT(TEXT
, XML_OUTLINE_LEVEL_STYLE
)
868 : ( nElement
== XML_ELEMENT(TEXT
, XML_LIST_LEVEL_STYLE_NUMBER
) ||
869 nElement
== XML_ELEMENT(TEXT
, XML_LIST_LEVEL_STYLE_BULLET
) ||
870 nElement
== XML_ELEMENT(TEXT
, XML_LIST_LEVEL_STYLE_IMAGE
) ) )
872 rtl::Reference
<SvxXMLListLevelStyleContext_Impl
> xLevelStyle
{
873 new SvxXMLListLevelStyleContext_Impl( GetImport(), nElement
, xAttrList
)};
874 if( !m_pLevelStyles
)
875 m_pLevelStyles
= std::make_unique
<SvxXMLListStyle_Impl
>();
876 m_pLevelStyles
->push_back( xLevelStyle
);
880 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
884 void SvxXMLListStyleContext::FillUnoNumRule(
885 const Reference
<container::XIndexReplace
> & rNumRule
) const
889 if( m_pLevelStyles
&& rNumRule
.is() )
891 sal_Int32 l_nLevels
= rNumRule
->getCount();
892 for (const auto& pLevelStyle
: *m_pLevelStyles
)
894 sal_Int32 nLevel
= pLevelStyle
->GetLevel();
895 if( nLevel
>= 0 && nLevel
< l_nLevels
)
897 Sequence
<beans::PropertyValue
> aProps
=
898 pLevelStyle
->GetProperties();
899 rNumRule
->replaceByIndex( nLevel
, Any(aProps
) );
904 Reference
< XPropertySet
> xPropSet( rNumRule
, UNO_QUERY
);
905 Reference
< XPropertySetInfo
> xPropSetInfo
;
907 xPropSetInfo
= xPropSet
->getPropertySetInfo();
908 if( xPropSetInfo
.is() &&
909 xPropSetInfo
->hasPropertyByName( sIsContinuousNumbering
) )
911 xPropSet
->setPropertyValue( sIsContinuousNumbering
, Any(m_bConsecutive
) );
914 catch (const Exception
&)
916 TOOLS_WARN_EXCEPTION("xmloff.style", "" );
920 void SvxXMLListStyleContext::CreateAndInsertLate( bool bOverwrite
)
926 const Reference
< XIndexReplace
>& rNumRule
=
927 GetImport().GetTextImport()->GetChapterNumbering();
928 // We don't set xNumberingRules here, to avoid using them
929 // as numbering rules.
931 FillUnoNumRule(rNumRule
);
936 Reference
< XStyle
> xStyle
;
937 const OUString
& rName
= GetDisplayName();
938 if( rName
.isEmpty() )
944 const Reference
< XNameContainer
>& rNumStyles
=
945 GetImport().GetTextImport()->GetNumberingStyles();
946 if( !rNumStyles
.is() )
953 if( rNumStyles
->hasByName( rName
) )
955 Any aAny
= rNumStyles
->getByName( rName
);
960 Reference
< XMultiServiceFactory
> xFactory( GetImport().GetModel(),
962 SAL_WARN_IF( !xFactory
.is(), "xmloff", "no factory" );
966 Reference
< XInterface
> xIfc
= xFactory
->createInstance(u
"com.sun.star.style.NumberingStyle"_ustr
);
969 xStyle
.set(xIfc
, UNO_QUERY
);
973 rNumStyles
->insertByName( rName
, Any(xStyle
) );
977 Reference
< XPropertySet
> xPropSet( xStyle
, UNO_QUERY
);
978 Reference
< XPropertySetInfo
> xPropSetInfo
=
979 xPropSet
->getPropertySetInfo();
980 if( !bNew
&& xPropSetInfo
->hasPropertyByName( sIsPhysical
) )
982 Any aAny
= xPropSet
->getPropertyValue( sIsPhysical
);
983 bNew
= !*o3tl::doAccess
<bool>(aAny
);
986 if ( xPropSetInfo
->hasPropertyByName( u
"Hidden"_ustr
) )
987 xPropSet
->setPropertyValue( u
"Hidden"_ustr
, uno::Any( IsHidden( ) ) );
989 if( rName
!= GetName() )
990 GetImport().AddStyleDisplayName( XmlStyleFamily::TEXT_LIST
,
993 Any aAny
= xPropSet
->getPropertyValue( sNumberingRules
);
994 aAny
>>= m_xNumRules
;
995 if( bOverwrite
|| bNew
)
997 FillUnoNumRule(m_xNumRules
);
998 xPropSet
->setPropertyValue( sNumberingRules
, Any(m_xNumRules
) );
1009 void SvxXMLListStyleContext::CreateAndInsertAuto() const
1011 SAL_WARN_IF( m_bOutline
, "xmloff", "Outlines cannot be inserted here" );
1012 SAL_WARN_IF( m_xNumRules
.is(), "xmloff", "Numbering Rule is existing already" );
1014 const OUString
& rName
= GetName();
1015 if( m_bOutline
|| m_xNumRules
.is() || rName
.isEmpty() )
1017 const_cast<SvxXMLListStyleContext
*>(this)->SetValid( false );
1021 const_cast<SvxXMLListStyleContext
*>(this)->m_xNumRules
= CreateNumRule(
1022 GetImport().GetModel() );
1024 FillUnoNumRule(m_xNumRules
);
1027 Reference
< XIndexReplace
> SvxXMLListStyleContext::CreateNumRule(
1028 const Reference
< XModel
> & rModel
)
1030 Reference
<XIndexReplace
> xNumRule
;
1032 Reference
< XMultiServiceFactory
> xFactory( rModel
, UNO_QUERY
);
1033 SAL_WARN_IF( !xFactory
.is(), "xmloff", "no factory" );
1034 if( !xFactory
.is() )
1037 Reference
< XInterface
> xIfc
= xFactory
->createInstance(u
"com.sun.star.text.NumberingRules"_ustr
);
1041 xNumRule
.set( xIfc
, UNO_QUERY
);
1042 SAL_WARN_IF( !xNumRule
.is(), "xmloff", "go no numbering rule" );
1047 void SvxXMLListStyleContext::SetDefaultStyle(
1048 const Reference
< XIndexReplace
> & rNumRule
,
1052 Sequence
<beans::PropertyValue
> aPropSeq( bOrdered
? 1 : 4 );
1053 beans::PropertyValue
*pProps
= aPropSeq
.getArray();
1055 pProps
->Name
= "NumberingType";
1056 (pProps
++)->Value
<<= static_cast<sal_Int16
>(bOrdered
? NumberingType::ARABIC
1057 : NumberingType::CHAR_SPECIAL
);
1060 // TODO: Bullet-Font
1061 awt::FontDescriptor aFDesc
;
1069 aFDesc
.Family
= FAMILY_DONTKNOW
;
1070 aFDesc
.Pitch
= PITCH_DONTKNOW
;
1071 aFDesc
.CharSet
= RTL_TEXTENCODING_SYMBOL
;
1072 aFDesc
.Weight
= WEIGHT_DONTKNOW
;
1073 pProps
->Name
= "BulletFont";
1074 (pProps
++)->Value
<<= aFDesc
;
1076 pProps
->Name
= "BulletChar";
1077 (pProps
++)->Value
<<= OUString(sal_Unicode(0xF000 + 149));
1078 pProps
->Name
= "CharStyleName";
1079 (pProps
++)->Value
<<= u
"Numbering Symbols"_ustr
;
1082 rNumRule
->replaceByIndex( nLevel
, Any(aPropSeq
) );
1085 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */