tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / xmloff / source / style / xmlnumi.cxx
blob8019855f6b164cd68346edce1c6b49d00f1dc309
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <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>
64 #include <optional>
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;
79 namespace {
81 class SvxXMLListLevelStyleAttrContext_Impl : public SvXMLImportContext
83 SvxXMLListLevelStyleContext_Impl& rListLevel;
85 public:
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(
93 sal_Int32 nElement,
94 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
97 class SvxXMLListLevelStyleLabelAlignmentAttrContext_Impl : public SvXMLImportContext
99 public:
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;
113 OUString sPrefix;
114 OUString sSuffix;
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;
118 OUString sNumFormat;
119 OUString sNumLetterSync;
120 OUString sBulletFontName;
121 OUString sBulletFontStyleName;
122 OUString sImageURL;
124 Reference < XOutputStream > xBase64Stream;
126 sal_Int32 nLevel;
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;
135 sal_Int16 eAdjust;
136 sal_Int16 eBulletFontFamily;
137 sal_Int16 eBulletFontPitch;
138 rtl_TextEncoding eBulletFontEncoding;
139 sal_Int16 eImageVertOrient;
141 sal_UCS4 cBullet;
143 sal_Int16 nRelSize;
144 Color m_nColor;
146 sal_Int16 ePosAndSpaceMode;
147 sal_Int16 eLabelFollowedBy;
148 sal_Int32 nListtabStopPosition;
149 sal_Int32 nFirstLineIndent;
150 sal_Int32 nIndentAt;
152 bool bBullet : 1;
153 bool bImage : 1;
154 bool bNum : 1;
155 bool bHasColor : 1;
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; }
180 public:
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(
187 sal_Int32 nElement,
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 )
211 nIndentAt = 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 )
224 , nLevel( -1 )
225 , nSpaceBefore( 0 )
226 , nMinLabelWidth( 0 )
227 , nMinLabelDist( 0 )
228 , nImageWidth( 0 )
229 , nImageHeight( 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)
237 , cBullet( 0 )
238 , nRelSize(0)
239 , m_nColor(0)
240 , ePosAndSpaceMode( PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION )
241 , eLabelFollowedBy( LabelFollow::LISTTAB )
242 , nListtabStopPosition( 0 )
243 , nFirstLineIndent( 0 )
244 , nIndentAt( 0 )
245 , bBullet( false )
246 , bImage( false )
247 , bNum( false )
248 , bHasColor( false )
250 switch (nElement & TOKEN_MASK)
252 case XML_LIST_LEVEL_STYLE_NUMBER:
253 case XML_OUTLINE_LEVEL_STYLE:
254 bNum = true;
255 break;
256 case XML_LIST_LEVEL_STYLE_BULLET:
257 bBullet = true;
258 break;
259 case XML_LIST_LEVEL_STYLE_IMAGE:
260 bImage = true;
261 break;
264 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
266 switch( aIter.getToken() )
268 case XML_ELEMENT(TEXT, XML_LEVEL):
269 nLevel = aIter.toInt32();
270 if( nLevel >= 1 )
271 nLevel--;
272 else
273 nLevel = 0;
274 break;
275 case XML_ELEMENT(TEXT, XML_STYLE_NAME):
276 sTextStyleName = aIter.toString();
277 break;
278 case XML_ELEMENT(TEXT, XML_BULLET_CHAR):
279 if (!aIter.isEmpty())
281 cBullet = aIter.toString().iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
283 break;
284 case XML_ELEMENT(XLINK, XML_HREF):
285 if( bImage )
286 sImageURL = aIter.toString();
287 break;
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
292 break;
293 case XML_ELEMENT(STYLE, XML_NUM_FORMAT):
294 if( bNum )
295 sNumFormat = aIter.toString();
296 break;
297 case XML_ELEMENT(STYLE, XML_NUM_PREFIX):
298 sPrefix = aIter.toString();
299 break;
300 case XML_ELEMENT(STYLE, XML_NUM_SUFFIX):
301 sSuffix = aIter.toString();
302 break;
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());
306 break;
307 case XML_ELEMENT(LO_EXT, XML_IS_LEGAL):
308 m_bIsLegal = aIter.toBoolean();
309 break;
310 case XML_ELEMENT(STYLE, XML_NUM_LETTER_SYNC):
311 if( bNum )
312 sNumLetterSync = aIter.toString();
313 break;
314 case XML_ELEMENT(TEXT, XML_START_VALUE):
315 if( bNum )
317 sal_Int32 nTmp = aIter.toInt32();
318 nNumStartValue =
319 (nTmp < 0) ? 1 : ( (nTmp>SHRT_MAX) ? SHRT_MAX
320 : static_cast<sal_Int16>(nTmp) );
322 break;
323 case XML_ELEMENT(TEXT, XML_DISPLAY_LEVELS):
324 if( bNum )
326 sal_Int32 nTmp = aIter.toInt32();
327 nNumDisplayLevels =
328 (nTmp < 1) ? 1 : ( (nTmp>SHRT_MAX) ? SHRT_MAX
329 : static_cast<sal_Int16>(nTmp) );
331 break;
332 default:
333 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
338 css::uno::Reference< css::xml::sax::XFastContextHandler > SvxXMLListLevelStyleContext_Impl::createFastChildContext(
339 sal_Int32 nElement,
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(),
346 nElement,
347 xAttrList,
348 *this );
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);
360 return nullptr;
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;
373 if( bBullet )
375 eType = NumberingType::CHAR_SPECIAL;
377 if( bImage )
379 eType = NumberingType::BITMAP;
381 if( bNum )
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());
391 sal_Int32 nUPD;
392 sal_Int32 nBuildId;
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++)
412 *sListFormat += "%";
413 *sListFormat += OUString::number(nLevel - nNumDisplayLevels + i + 1);
414 *sListFormat += "%";
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));
451 if( bBullet )
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 );
466 bStarSymbol = true;
468 else if( aFDesc.Name.equalsIgnoreAsciiCase( gsStarMath ) )
470 cBullet = GetImport().ConvStarMathCharToStarSymbol( cBullet );
471 bStarSymbol = true;
473 if( bStarSymbol )
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));
483 if( bImage )
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;
496 if (xGraphic.is())
497 xBitmap.set(xGraphic, uno::UNO_QUERY);
499 if (xBitmap.is())
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));
509 if( bNum )
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));
527 if (m_bIsLegal)
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) )
548 sal_Int32 nVal;
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 );
554 break;
555 case XML_ELEMENT(TEXT, XML_MIN_LABEL_WIDTH):
556 if (rUnitConv.convertMeasureToCore( nVal, aIter.toView(), 0, SHRT_MAX ))
557 rListLevel.SetMinLabelWidth( nVal );
558 break;
559 case XML_ELEMENT(TEXT, XML_MIN_LABEL_DISTANCE):
560 if (rUnitConv.convertMeasureToCore( nVal, aIter.toView(), 0, USHRT_MAX ))
561 rListLevel.SetMinLabelDist( nVal );
562 break;
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 );
574 break;
575 case XML_ELEMENT(STYLE, XML_FONT_NAME):
576 sFontName = aIter.toString();
577 break;
578 case XML_ELEMENT(FO, XML_FONT_FAMILY):
579 case XML_ELEMENT(FO_COMPAT, XML_FONT_FAMILY):
580 sFontFamily = aIter.toString();
581 break;
582 case XML_ELEMENT(STYLE, XML_FONT_FAMILY_GENERIC):
583 sFontFamilyGeneric = aIter.toString();
584 break;
585 case XML_ELEMENT(STYLE, XML_FONT_STYLE_NAME):
586 sFontStyleName = aIter.toString();
587 break;
588 case XML_ELEMENT(STYLE, XML_FONT_PITCH):
589 sFontPitch = aIter.toString();
590 break;
591 case XML_ELEMENT(STYLE, XML_FONT_CHARSET):
592 sFontCharset = aIter.toString();
593 break;
594 case XML_ELEMENT(STYLE, XML_VERTICAL_POS):
595 sVerticalPos = aIter.toString();
596 break;
597 case XML_ELEMENT(STYLE, XML_VERTICAL_REL):
598 sVerticalRel = aIter.toString();
599 break;
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 );
604 break;
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 );
609 break;
610 case XML_ELEMENT(FO, XML_COLOR):
611 case XML_ELEMENT(FO_COMPAT, XML_COLOR):
613 Color nColor;
614 if (::sax::Converter::convertColor( nColor, aIter.toView() ))
615 rListLevel.SetColor( nColor );
617 break;
618 case XML_ELEMENT(STYLE, XML_USE_WINDOW_FONT_COLOR):
620 if( IsXMLToken( aIter, XML_TRUE ) )
621 rListLevel.SetColor(COL_AUTO);
623 break;
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) );
628 break;
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 );
636 break;
637 default:
638 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
642 if( !sFontName.isEmpty() )
644 const XMLFontStylesContext *pFontDecls =
645 GetImport().GetFontDecls();
646 if( pFontDecls )
648 ::std::vector < XMLPropertyState > aProps;
649 if( pFontDecls->FillProperties( sFontName, aProps, 0, 1, 2, 3, 4 ) )
651 OUString sTmp;
652 sal_Int16 nTmp = 0;
653 for( const auto& rProp : aProps )
655 switch( rProp.mnIndex )
657 case 0:
658 rProp.maValue >>= sTmp;
659 rListLevel.SetBulletFontName( sTmp);
660 break;
661 case 1:
662 rProp.maValue >>= sTmp;
663 rListLevel.SetBulletFontStyleName( sTmp );
664 break;
665 case 2:
666 rProp.maValue >>= nTmp;
667 rListLevel.SetBulletFontFamily( nTmp );
668 break;
669 case 3:
670 rProp.maValue >>= nTmp;
671 rListLevel.SetBulletFontPitch( nTmp );
672 break;
673 case 4:
674 rProp.maValue >>= nTmp;
675 rListLevel.SetBulletFontEncoding( nTmp );
676 break;
682 if( !sFontFamily.isEmpty() )
684 Any aAny;
686 XMLFontFamilyNamePropHdl aFamilyNameHdl;
687 if( aFamilyNameHdl.importXML( sFontFamily, aAny, rUnitConv ) )
689 OUString sTmp;
690 aAny >>= sTmp;
691 rListLevel.SetBulletFontName( sTmp);
694 XMLFontFamilyPropHdl aFamilyHdl;
695 if( !sFontFamilyGeneric.isEmpty() &&
696 aFamilyHdl.importXML( sFontFamilyGeneric, aAny, rUnitConv ) )
698 sal_Int16 nTmp = 0;
699 aAny >>= nTmp;
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 ) )
710 sal_Int16 nTmp = 0;
711 aAny >>= nTmp;
712 rListLevel.SetBulletFontPitch( nTmp );
715 XMLFontEncodingPropHdl aEncHdl;
716 if( !sFontCharset.isEmpty() &&
717 aEncHdl.importXML( sFontCharset, aAny, rUnitConv ) )
719 sal_Int16 nTmp = 0;
720 aAny >>= nTmp;
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;
742 break;
743 case VertOrientation::LINE_CENTER:
744 eVertOrient = VertOrientation::CENTER;
745 break;
746 case VertOrientation::LINE_BOTTOM:
747 eVertOrient = VertOrientation::TOP;
748 break;
751 else if( IsXMLToken( sVerticalRel, XML_CHAR ) )
753 switch( eVertOrient )
755 case VertOrientation::LINE_TOP:
756 eVertOrient = VertOrientation::CHAR_TOP;
757 break;
758 case VertOrientation::LINE_CENTER:
759 eVertOrient = VertOrientation::CHAR_CENTER;
760 break;
761 case VertOrientation::LINE_BOTTOM:
762 eVertOrient = VertOrientation::CHAR_BOTTOM;
763 break;
767 rListLevel.SetImageVertOrient( eVertOrient );
770 css::uno::Reference< css::xml::sax::XFastContextHandler > SvxXMLListLevelStyleAttrContext_Impl::createFastChildContext(
771 sal_Int32 nElement,
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(),
777 nElement,
778 xAttrList,
779 rListLevel );
781 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
782 return nullptr;
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) )
797 sal_Int32 nVal;
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
805 break;
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;
813 break;
814 case XML_ELEMENT(TEXT, XML_LIST_TAB_STOP_POSITION):
815 if (rUnitConv.convertMeasureToCore(nVal, aIter.toView(), 0, SHRT_MAX))
816 rLLevel.SetListtabStopPosition( nVal );
817 break;
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 );
822 break;
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 );
827 break;
828 default:
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 );
842 else
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,
853 bool bOutl )
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(
863 sal_Int32 nElement,
864 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
866 if( m_bOutline
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 );
878 return xLevelStyle;
880 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
881 return nullptr;
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;
906 if (xPropSet.is())
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 )
922 if( m_bOutline )
924 if( 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.
930 if( rNumRule.is() )
931 FillUnoNumRule(rNumRule);
934 else
936 Reference < XStyle > xStyle;
937 const OUString& rName = GetDisplayName();
938 if( rName.isEmpty() )
940 SetValid( false );
941 return;
944 const Reference < XNameContainer >& rNumStyles =
945 GetImport().GetTextImport()->GetNumberingStyles();
946 if( !rNumStyles.is() )
948 SetValid( false );
949 return;
952 bool bNew = false;
953 if( rNumStyles->hasByName( rName ) )
955 Any aAny = rNumStyles->getByName( rName );
956 aAny >>= xStyle;
958 else
960 Reference< XMultiServiceFactory > xFactory( GetImport().GetModel(),
961 UNO_QUERY );
962 SAL_WARN_IF( !xFactory.is(), "xmloff", "no factory" );
963 if( !xFactory.is() )
964 return;
966 Reference < XInterface > xIfc = xFactory->createInstance(u"com.sun.star.style.NumberingStyle"_ustr);
967 if( !xIfc.is() )
968 return;
969 xStyle.set(xIfc, UNO_QUERY);
970 if( !xStyle.is() )
971 return;
973 rNumStyles->insertByName( rName, Any(xStyle) );
974 bNew = true;
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,
991 GetName(), rName );
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) );
1000 else
1002 SetValid( false );
1005 SetNew( bNew );
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 );
1018 return;
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() )
1035 return xNumRule;
1037 Reference < XInterface > xIfc = xFactory->createInstance(u"com.sun.star.text.NumberingRules"_ustr);
1038 if( !xIfc.is() )
1039 return xNumRule;
1041 xNumRule.set( xIfc, UNO_QUERY );
1042 SAL_WARN_IF( !xNumRule.is(), "xmloff", "go no numbering rule" );
1044 return xNumRule;
1047 void SvxXMLListStyleContext::SetDefaultStyle(
1048 const Reference < XIndexReplace > & rNumRule,
1049 sal_Int16 nLevel,
1050 bool bOrdered )
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 );
1058 if( !bOrdered )
1060 // TODO: Bullet-Font
1061 awt::FontDescriptor aFDesc;
1062 aFDesc.Name =
1063 #ifdef _WIN32
1064 "StarBats"
1065 #else
1066 "starbats"
1067 #endif
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: */