xref: /core/sw/source/core/unocore/unosett.cxx (revision 6756a753)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <editeng/editids.hrc>
21 #include <swtypes.hxx>
22 #include <unomid.h>
23 #include <hintids.hxx>
24 #include <strings.hrc>
25 #include <poolfmt.hxx>
26 #include <fmtcol.hxx>
27 #include <unomap.hxx>
28 #include <unosett.hxx>
29 #include <unoprnms.hxx>
30 #include <ftninfo.hxx>
31 #include <doc.hxx>
32 #include <pagedesc.hxx>
33 #include <IDocumentStylePoolAccess.hxx>
34 #include <charfmt.hxx>
35 #include <lineinfo.hxx>
36 #include <docsh.hxx>
37 #include <docary.hxx>
38 #include <docstyle.hxx>
39 #include <editeng/brushitem.hxx>
40 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
41 #include <com/sun/star/text/FootnoteNumbering.hpp>
42 #include <com/sun/star/text/HoriOrientation.hpp>
43 #include <com/sun/star/style/LineNumberPosition.hpp>
44 #include <com/sun/star/awt/FontDescriptor.hpp>
45 #include <com/sun/star/awt/XBitmap.hpp>
46 #include <com/sun/star/graphic/XGraphic.hpp>
47 #include <com/sun/star/beans/PropertyAttribute.hpp>
48 #include <o3tl/any.hxx>
49 #include <o3tl/enumarray.hxx>
50 #include <tools/UnitConversion.hxx>
51 #include <vcl/font.hxx>
52 #include <editeng/flstitem.hxx>
53 #include <vcl/metric.hxx>
54 #include <vcl/graph.hxx>
55 #include <vcl/GraphicLoader.hxx>
56 #include <sfx2/docfile.hxx>
57 #include <svtools/ctrltool.hxx>
58 #include <vcl/svapp.hxx>
59 #include <editeng/unofdesc.hxx>
60 #include <fmtornt.hxx>
61 #include <SwStyleNameMapper.hxx>
62 #include <com/sun/star/text/PositionAndSpaceMode.hpp>
63 #include <com/sun/star/text/LabelFollow.hpp>
64 #include <numrule.hxx>
65 #include <comphelper/servicehelper.hxx>
66 #include <comphelper/sequence.hxx>
67 #include <cppuhelper/supportsservice.hxx>
68 #include <comphelper/propertyvalue.hxx>
69 #include <svl/itemprop.hxx>
70 #include <svl/listener.hxx>
71 #include <paratr.hxx>
72 #include <sal/log.hxx>
73 
74 using namespace ::com::sun::star;
75 using namespace ::com::sun::star::uno;
76 using namespace ::com::sun::star::lang;
77 using namespace ::com::sun::star::beans;
78 using namespace ::com::sun::star::text;
79 using namespace ::com::sun::star::style;
80 
81 
82 namespace
83 {
GetPageDescNotifier(SwDoc * pDoc)84     SvtBroadcaster& GetPageDescNotifier(SwDoc* pDoc)
85     {
86         return pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier();
87     }
88 }
89 
90 #define WID_PREFIX                      0
91 #define WID_SUFFIX                      1
92 #define WID_NUMBERING_TYPE              2
93 #define WID_START_AT                    3
94 #define WID_FOOTNOTE_COUNTING           4
95 #define WID_PARAGRAPH_STYLE             5
96 #define WID_PAGE_STYLE                  6
97 #define WID_CHARACTER_STYLE             7
98 #define WID_POSITION_END_OF_DOC         8
99 #define WID_END_NOTICE                  9
100 #define WID_BEGIN_NOTICE                10
101 #define WID_ANCHOR_CHARACTER_STYLE      11
102 #define WID_NUM_ON                      12
103 #define WID_SEPARATOR_INTERVAL          13
104 #define WID_NUMBER_POSITION             14
105 #define WID_DISTANCE                    15
106 #define WID_INTERVAL                    16
107 #define WID_SEPARATOR_TEXT              17
108 #define WID_COUNT_EMPTY_LINES           18
109 #define WID_COUNT_LINES_IN_FRAMES       19
110 #define WID_RESTART_AT_EACH_PAGE        20
111 
112 
GetFootnoteSet()113 static const SfxItemPropertySet* GetFootnoteSet()
114 {
115     static const SfxItemPropertyMapEntry aFootnoteMap_Impl[] =
116     {
117         { UNO_NAME_ANCHOR_CHAR_STYLE_NAME,WID_ANCHOR_CHARACTER_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
118         { UNO_NAME_BEGIN_NOTICE,          WID_BEGIN_NOTICE,       ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
119         { UNO_NAME_CHAR_STYLE_NAME,       WID_CHARACTER_STYLE,    ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
120         { UNO_NAME_END_NOTICE,            WID_END_NOTICE ,        ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
121         { UNO_NAME_FOOTNOTE_COUNTING,     WID_FOOTNOTE_COUNTING,  ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE,     0},
122         { UNO_NAME_NUMBERING_TYPE,        WID_NUMBERING_TYPE,     ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE,         0},
123         { UNO_NAME_PAGE_STYLE_NAME,       WID_PAGE_STYLE,         ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
124         { UNO_NAME_PARA_STYLE_NAME,       WID_PARAGRAPH_STYLE,    ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
125         { UNO_NAME_POSITION_END_OF_DOC,   WID_POSITION_END_OF_DOC,cppu::UnoType<bool>::get(), PROPERTY_NONE,         0},
126         { UNO_NAME_PREFIX,                WID_PREFIX,             ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
127         { UNO_NAME_START_AT,              WID_START_AT ,          ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE,         0},
128         { UNO_NAME_SUFFIX,                WID_SUFFIX,             ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
129     };
130     static const SfxItemPropertySet aFootnoteSet_Impl(aFootnoteMap_Impl);
131     return &aFootnoteSet_Impl;
132 }
133 
GetEndnoteSet()134 static const SfxItemPropertySet* GetEndnoteSet()
135 {
136     static const SfxItemPropertyMapEntry aEndnoteMap_Impl[] =
137     {
138         { UNO_NAME_ANCHOR_CHAR_STYLE_NAME,WID_ANCHOR_CHARACTER_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
139         { UNO_NAME_CHAR_STYLE_NAME,       WID_CHARACTER_STYLE,    ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
140         { UNO_NAME_NUMBERING_TYPE,        WID_NUMBERING_TYPE,     ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE,         0},
141         { UNO_NAME_PAGE_STYLE_NAME,       WID_PAGE_STYLE,         ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
142         { UNO_NAME_PARA_STYLE_NAME,       WID_PARAGRAPH_STYLE,    ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
143         { UNO_NAME_PREFIX,                WID_PREFIX,     ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
144         { UNO_NAME_START_AT,              WID_START_AT ,          ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE,         0},
145         { UNO_NAME_SUFFIX,                WID_SUFFIX,     ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
146     };
147     static const SfxItemPropertySet aEndnoteSet_Impl(aEndnoteMap_Impl);
148     return &aEndnoteSet_Impl;
149 }
150 
GetNumberingRulesSet()151 static const SfxItemPropertySet* GetNumberingRulesSet()
152 {
153     static const SfxItemPropertyMapEntry aNumberingRulesMap_Impl[] =
154     {
155         { UNO_NAME_IS_ABSOLUTE_MARGINS,       WID_IS_ABS_MARGINS, cppu::UnoType<bool>::get(),            PROPERTY_NONE,     0},
156         { UNO_NAME_IS_AUTOMATIC,              WID_IS_AUTOMATIC,   cppu::UnoType<bool>::get(),            PROPERTY_NONE,     0},
157         { UNO_NAME_IS_CONTINUOUS_NUMBERING,   WID_CONTINUOUS,     cppu::UnoType<bool>::get(),            PROPERTY_NONE,     0},
158         { UNO_NAME_NAME,                      WID_RULE_NAME   ,   ::cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY,     0},
159         { UNO_NAME_NUMBERING_IS_OUTLINE,      WID_IS_OUTLINE, cppu::UnoType<bool>::get(),            PROPERTY_NONE,     0},
160         { UNO_NAME_DEFAULT_LIST_ID,           WID_DEFAULT_LIST_ID, ::cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
161     };
162     static const SfxItemPropertySet  aNumberingRulesSet_Impl( aNumberingRulesMap_Impl );
163     return &aNumberingRulesSet_Impl;
164 }
165 
GetLineNumberingSet()166 static const SfxItemPropertySet* GetLineNumberingSet()
167 {
168     static const SfxItemPropertyMapEntry aLineNumberingMap_Impl[] =
169     {
170         { UNO_NAME_CHAR_STYLE_NAME,         WID_CHARACTER_STYLE,    ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
171         { UNO_NAME_COUNT_EMPTY_LINES,       WID_COUNT_EMPTY_LINES , cppu::UnoType<bool>::get(),PROPERTY_NONE,     0},
172         { UNO_NAME_COUNT_LINES_IN_FRAMES,   WID_COUNT_LINES_IN_FRAMES, cppu::UnoType<bool>::get(),PROPERTY_NONE,     0},
173         { UNO_NAME_DISTANCE,                WID_DISTANCE       ,    ::cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE,     0},
174         { UNO_NAME_IS_ON,                   WID_NUM_ON,             cppu::UnoType<bool>::get()  ,          PROPERTY_NONE,     0},
175         { UNO_NAME_INTERVAL,                WID_INTERVAL  ,       ::cppu::UnoType<sal_Int16>::get(),PROPERTY_NONE,     0},
176         { UNO_NAME_SEPARATOR_TEXT,          WID_SEPARATOR_TEXT,   ::cppu::UnoType<OUString>::get(), PROPERTY_NONE,     0},
177         { UNO_NAME_NUMBER_POSITION,         WID_NUMBER_POSITION,    ::cppu::UnoType<sal_Int16>::get(),PROPERTY_NONE,     0},
178         { UNO_NAME_NUMBERING_TYPE,          WID_NUMBERING_TYPE ,    ::cppu::UnoType<sal_Int16>::get(),PROPERTY_NONE,     0},
179         { UNO_NAME_RESTART_AT_EACH_PAGE,    WID_RESTART_AT_EACH_PAGE, cppu::UnoType<bool>::get()  ,          PROPERTY_NONE,     0},
180         { UNO_NAME_SEPARATOR_INTERVAL,      WID_SEPARATOR_INTERVAL, ::cppu::UnoType<sal_Int16>::get(),PROPERTY_NONE,     0},
181     };
182     static const SfxItemPropertySet aLineNumberingSet_Impl(aLineNumberingMap_Impl);
183     return &aLineNumberingSet_Impl;
184 }
185 
lcl_getCharFormat(SwDoc * pDoc,const uno::Any & aValue)186 static SwCharFormat* lcl_getCharFormat(SwDoc* pDoc, const uno::Any& aValue)
187 {
188     SwCharFormat* pRet = nullptr;
189     OUString uTmp;
190     aValue >>= uTmp;
191     OUString sCharFormat;
192     SwStyleNameMapper::FillUIName(uTmp, sCharFormat, SwGetPoolIdFromName::ChrFmt);
193     if (sCharFormat != SwResId(STR_POOLCHR_STANDARD))
194     {
195         pRet = pDoc->FindCharFormatByName( sCharFormat );
196     }
197     if(!pRet)
198     {
199         const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(sCharFormat, SwGetPoolIdFromName::ChrFmt);
200         if(USHRT_MAX != nId)
201             pRet = pDoc->getIDocumentStylePoolAccess().GetCharFormatFromPool( nId );
202     }
203     return pRet;
204 }
205 
lcl_GetParaStyle(SwDoc * pDoc,const uno::Any & aValue)206 static SwTextFormatColl* lcl_GetParaStyle(SwDoc* pDoc, const uno::Any& aValue)
207 {
208     OUString uTmp;
209     aValue >>= uTmp;
210     OUString sParaStyle;
211     SwStyleNameMapper::FillUIName(uTmp, sParaStyle, SwGetPoolIdFromName::TxtColl );
212     SwTextFormatColl* pRet = pDoc->FindTextFormatCollByName( sParaStyle );
213     if( !pRet  )
214     {
215         const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName( sParaStyle, SwGetPoolIdFromName::TxtColl );
216         if( USHRT_MAX != nId  )
217             pRet = pDoc->getIDocumentStylePoolAccess().GetTextCollFromPool( nId );
218     }
219     return pRet;
220 }
221 
lcl_GetPageDesc(SwDoc * pDoc,const uno::Any & aValue)222 static SwPageDesc* lcl_GetPageDesc(SwDoc* pDoc, const uno::Any& aValue)
223 {
224     OUString uTmp;
225     aValue >>= uTmp;
226     OUString sPageDesc;
227     SwStyleNameMapper::FillUIName(uTmp, sPageDesc, SwGetPoolIdFromName::PageDesc );
228     SwPageDesc* pRet = pDoc->FindPageDesc( sPageDesc );
229     if(!pRet)
230     {
231         const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(sPageDesc, SwGetPoolIdFromName::PageDesc);
232         if(USHRT_MAX != nId)
233             pRet = pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool( nId );
234     }
235     return pRet;
236 }
237 
238 // Numbering
239 const o3tl::enumarray<SvxAdjust, sal_Int16> aSvxToUnoAdjust
240 {
241     text::HoriOrientation::LEFT,   //3
242     text::HoriOrientation::RIGHT,  //1
243     sal_Int16(-1),
244     text::HoriOrientation::CENTER, //2
245     sal_Int16(-1),
246     sal_Int16(-1)
247 };
248 
getImplementationName()249 OUString SwXFootnoteProperties::getImplementationName()
250 {
251     return u"SwXFootnoteProperties"_ustr;
252 }
253 
supportsService(const OUString & rServiceName)254 sal_Bool SwXFootnoteProperties::supportsService(const OUString& rServiceName)
255 {
256     return cppu::supportsService(this, rServiceName);
257 }
258 
getSupportedServiceNames()259 Sequence< OUString > SwXFootnoteProperties::getSupportedServiceNames()
260 {
261     Sequence<OUString> aRet { u"com.sun.star.text.FootnoteSettings"_ustr };
262     return aRet;
263 }
264 
SwXFootnoteProperties(SwDoc * pDc)265 SwXFootnoteProperties::SwXFootnoteProperties(SwDoc* pDc) :
266     m_pDoc(pDc),
267     m_pPropertySet(GetFootnoteSet())
268 {
269 }
270 
~SwXFootnoteProperties()271 SwXFootnoteProperties::~SwXFootnoteProperties()
272 {
273 
274 }
275 
getPropertySetInfo()276 uno::Reference< beans::XPropertySetInfo >  SwXFootnoteProperties::getPropertySetInfo()
277 {
278     static uno::Reference< beans::XPropertySetInfo >  aRef = m_pPropertySet->getPropertySetInfo();
279     return aRef;
280 }
281 
setPropertyValue(const OUString & rPropertyName,const uno::Any & aValue)282 void SwXFootnoteProperties::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
283 {
284     SolarMutexGuard aGuard;
285     if(!m_pDoc)
286         throw uno::RuntimeException();
287 
288     const SfxItemPropertyMapEntry*  pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
289     if(!pEntry)
290         throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
291 
292     if ( pEntry->nFlags & PropertyAttribute::READONLY)
293         throw PropertyVetoException("Property is read-only: " + rPropertyName, getXWeak() );
294     SwFootnoteInfo aFootnoteInfo(m_pDoc->GetFootnoteInfo());
295     switch(pEntry->nWID)
296     {
297         case WID_PREFIX:
298         {
299             OUString uTmp;
300             aValue >>= uTmp;
301             aFootnoteInfo.SetPrefix(uTmp);
302         }
303         break;
304         case WID_SUFFIX:
305         {
306             OUString uTmp;
307             aValue >>= uTmp;
308             aFootnoteInfo.SetSuffix(uTmp);
309         }
310         break;
311         case WID_NUMBERING_TYPE:
312         {
313             sal_Int16 nTmp = 0;
314             aValue >>= nTmp;
315             if(!(nTmp >= 0 &&
316                 (nTmp <= SVX_NUM_ARABIC ||
317                     nTmp > SVX_NUM_BITMAP)))
318                 throw lang::IllegalArgumentException();
319 
320             aFootnoteInfo.m_aFormat.SetNumberingType(static_cast<SvxNumType>(nTmp));
321 
322         }
323         break;
324         case WID_START_AT:
325         {
326             sal_Int16 nTmp = 0;
327             aValue >>= nTmp;
328             aFootnoteInfo.m_nFootnoteOffset = nTmp;
329         }
330         break;
331         case WID_FOOTNOTE_COUNTING:
332         {
333             sal_Int16 nTmp = 0;
334             aValue >>= nTmp;
335             switch(nTmp)
336             {
337                 case  FootnoteNumbering::PER_PAGE:
338                     aFootnoteInfo.m_eNum = FTNNUM_PAGE;
339                 break;
340                 case  FootnoteNumbering::PER_CHAPTER:
341                     aFootnoteInfo.m_eNum = FTNNUM_CHAPTER;
342                 break;
343                 case  FootnoteNumbering::PER_DOCUMENT:
344                     aFootnoteInfo.m_eNum = FTNNUM_DOC;
345                 break;
346             }
347         }
348         break;
349         case WID_PARAGRAPH_STYLE:
350         {
351             SwTextFormatColl* pColl = lcl_GetParaStyle(m_pDoc, aValue);
352             if(pColl)
353                 aFootnoteInfo.SetFootnoteTextColl(*pColl);
354         }
355         break;
356         case WID_PAGE_STYLE:
357         {
358             SwPageDesc* pDesc = lcl_GetPageDesc(m_pDoc, aValue);
359             if(pDesc)
360                 aFootnoteInfo.ChgPageDesc( pDesc );
361         }
362         break;
363         case WID_ANCHOR_CHARACTER_STYLE:
364         case WID_CHARACTER_STYLE:
365         {
366             SwCharFormat* pFormat = lcl_getCharFormat(m_pDoc, aValue);
367             if(pFormat)
368             {
369                 if(pEntry->nWID == WID_ANCHOR_CHARACTER_STYLE)
370                     aFootnoteInfo.SetAnchorCharFormat(pFormat);
371                 else
372                     aFootnoteInfo.SetCharFormat(pFormat);
373             }
374         }
375         break;
376         case WID_POSITION_END_OF_DOC:
377         {
378             bool bVal = *o3tl::doAccess<bool>(aValue);
379             aFootnoteInfo.m_ePos = bVal ? FTNPOS_CHAPTER : FTNPOS_PAGE;
380         }
381         break;
382         case WID_END_NOTICE:
383         {
384             OUString uTmp;
385             aValue >>= uTmp;
386             aFootnoteInfo.m_aQuoVadis = uTmp;
387         }
388         break;
389         case WID_BEGIN_NOTICE:
390         {
391             OUString uTmp;
392             aValue >>= uTmp;
393             aFootnoteInfo.m_aErgoSum = uTmp;
394         }
395         break;
396     }
397     m_pDoc->SetFootnoteInfo(aFootnoteInfo);
398 
399 
400 }
401 
getPropertyValue(const OUString & rPropertyName)402 uno::Any SwXFootnoteProperties::getPropertyValue(const OUString& rPropertyName)
403 {
404     SolarMutexGuard aGuard;
405     uno::Any aRet;
406     if(!m_pDoc)
407         throw uno::RuntimeException();
408 
409     const SfxItemPropertyMapEntry*  pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
410     if(!pEntry)
411         throw UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
412 
413     const SwFootnoteInfo& rFootnoteInfo = m_pDoc->GetFootnoteInfo();
414     switch(pEntry->nWID)
415     {
416         case WID_PREFIX:
417         {
418             aRet <<= rFootnoteInfo.GetPrefix();
419         }
420         break;
421         case WID_SUFFIX:
422         {
423             aRet <<= rFootnoteInfo.GetSuffix();
424         }
425         break;
426         case  WID_NUMBERING_TYPE :
427         {
428             aRet <<= static_cast<sal_Int16>(rFootnoteInfo.m_aFormat.GetNumberingType());
429         }
430         break;
431         case  WID_START_AT:
432             aRet <<= static_cast<sal_Int16>(rFootnoteInfo.m_nFootnoteOffset);
433         break;
434         case  WID_FOOTNOTE_COUNTING  :
435         {
436             sal_Int16 nRet = 0;
437             switch(rFootnoteInfo.m_eNum)
438             {
439                 case  FTNNUM_PAGE:
440                     nRet = FootnoteNumbering::PER_PAGE;
441                 break;
442                 case  FTNNUM_CHAPTER:
443                     nRet = FootnoteNumbering::PER_CHAPTER;
444                 break;
445                 case  FTNNUM_DOC:
446                     nRet = FootnoteNumbering::PER_DOCUMENT;
447                 break;
448             }
449             aRet <<= nRet;
450         }
451         break;
452         case  WID_PARAGRAPH_STYLE    :
453         {
454             SwTextFormatColl* pColl = rFootnoteInfo.GetFootnoteTextColl();
455             OUString aString;
456             if(pColl)
457                 aString = pColl->GetName();
458             SwStyleNameMapper::FillProgName(aString, aString, SwGetPoolIdFromName::TxtColl);
459             aRet <<= aString;
460         }
461         break;
462         case  WID_PAGE_STYLE :
463         {
464             OUString aString;
465             if( rFootnoteInfo.KnowsPageDesc() )
466             {
467                 SwStyleNameMapper::FillProgName(
468                         rFootnoteInfo.GetPageDesc( *m_pDoc )->GetName(),
469                         aString,
470                         SwGetPoolIdFromName::PageDesc);
471             }
472             aRet <<= aString;
473         }
474         break;
475         case WID_ANCHOR_CHARACTER_STYLE:
476         case WID_CHARACTER_STYLE:
477         {
478             OUString aString;
479             const SwCharFormat* pCharFormat = rFootnoteInfo.GetCurrentCharFormat(pEntry->nWID == WID_ANCHOR_CHARACTER_STYLE);
480             if( pCharFormat )
481             {
482                 SwStyleNameMapper::FillProgName(
483                         pCharFormat->GetName(),
484                         aString,
485                         SwGetPoolIdFromName::ChrFmt);
486             }
487             aRet <<= aString;
488         }
489         break;
490         case  WID_POSITION_END_OF_DOC:
491             aRet <<= FTNPOS_CHAPTER == rFootnoteInfo.m_ePos;
492         break;
493         case  WID_END_NOTICE         :
494             aRet <<= rFootnoteInfo.m_aQuoVadis;
495         break;
496         case  WID_BEGIN_NOTICE       :
497             aRet <<= rFootnoteInfo.m_aErgoSum;
498         break;
499     }
500 
501 
502     return aRet;
503 }
504 
addPropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)505 void SwXFootnoteProperties::addPropertyChangeListener(
506     const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
507 {
508     OSL_FAIL("not implemented");
509 }
510 
removePropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)511 void SwXFootnoteProperties::removePropertyChangeListener(
512     const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
513 {
514     OSL_FAIL("not implemented");
515 }
516 
addVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)517 void SwXFootnoteProperties::addVetoableChangeListener(
518     const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
519 {
520     OSL_FAIL("not implemented");
521 }
522 
removeVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)523 void SwXFootnoteProperties::removeVetoableChangeListener(
524     const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
525 {
526     OSL_FAIL("not implemented");
527 }
528 
getImplementationName()529 OUString SwXEndnoteProperties::getImplementationName()
530 {
531     return u"SwXEndnoteProperties"_ustr;
532 }
533 
supportsService(const OUString & rServiceName)534 sal_Bool SwXEndnoteProperties::supportsService(const OUString& rServiceName)
535 {
536     return cppu::supportsService(this, rServiceName);
537 }
538 
getSupportedServiceNames()539 Sequence< OUString > SwXEndnoteProperties::getSupportedServiceNames()
540 {
541     Sequence<OUString> aRet { u"com.sun.star.text.FootnoteSettings"_ustr };
542     return aRet;
543 }
544 
SwXEndnoteProperties(SwDoc * pDc)545 SwXEndnoteProperties::SwXEndnoteProperties(SwDoc* pDc) :
546     m_pDoc(pDc),
547     m_pPropertySet(GetEndnoteSet())
548 {
549 }
550 
~SwXEndnoteProperties()551 SwXEndnoteProperties::~SwXEndnoteProperties()
552 {
553 }
554 
getPropertySetInfo()555 uno::Reference< beans::XPropertySetInfo >  SwXEndnoteProperties::getPropertySetInfo()
556 {
557     static uno::Reference< beans::XPropertySetInfo >  aRef = m_pPropertySet->getPropertySetInfo();
558     return aRef;
559 }
560 
setPropertyValue(const OUString & rPropertyName,const uno::Any & aValue)561 void SwXEndnoteProperties::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
562 {
563     SolarMutexGuard aGuard;
564     if(!m_pDoc)
565         return;
566 
567     const SfxItemPropertyMapEntry*  pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
568     if(!pEntry)
569         throw UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
570 
571     if ( pEntry->nFlags & PropertyAttribute::READONLY)
572         throw PropertyVetoException("Property is read-only: " + rPropertyName, getXWeak() );
573     SwEndNoteInfo aEndInfo(m_pDoc->GetEndNoteInfo());
574     switch(pEntry->nWID)
575     {
576         case WID_PREFIX:
577         {
578             OUString uTmp;
579             aValue >>= uTmp;
580             aEndInfo.SetPrefix(uTmp);
581         }
582         break;
583         case WID_SUFFIX:
584         {
585             OUString uTmp;
586             aValue >>= uTmp;
587             aEndInfo.SetSuffix(uTmp);
588         }
589         break;
590         case  WID_NUMBERING_TYPE :
591         {
592             sal_Int16 nTmp = 0;
593             aValue >>= nTmp;
594             aEndInfo.m_aFormat.SetNumberingType(static_cast<SvxNumType>(nTmp));
595         }
596         break;
597         case  WID_START_AT:
598         {
599             sal_Int16 nTmp = 0;
600             aValue >>= nTmp;
601             aEndInfo.m_nFootnoteOffset = nTmp;
602         }
603         break;
604         case  WID_PARAGRAPH_STYLE    :
605         {
606             SwTextFormatColl* pColl = lcl_GetParaStyle(m_pDoc, aValue);
607             if(pColl)
608                 aEndInfo.SetFootnoteTextColl(*pColl);
609         }
610         break;
611         case  WID_PAGE_STYLE :
612         {
613             SwPageDesc* pDesc = lcl_GetPageDesc(m_pDoc, aValue);
614             if(pDesc)
615                 aEndInfo.ChgPageDesc( pDesc );
616         }
617         break;
618         case WID_ANCHOR_CHARACTER_STYLE:
619         case  WID_CHARACTER_STYLE    :
620         {
621             SwCharFormat* pFormat = lcl_getCharFormat(m_pDoc, aValue);
622             if(pFormat)
623             {
624                 if(pEntry->nWID == WID_ANCHOR_CHARACTER_STYLE)
625                     aEndInfo.SetAnchorCharFormat(pFormat);
626                 else
627                     aEndInfo.SetCharFormat(pFormat);
628             }
629         }
630         break;
631     }
632     m_pDoc->SetEndNoteInfo(aEndInfo);
633 }
634 
getPropertyValue(const OUString & rPropertyName)635 uno::Any SwXEndnoteProperties::getPropertyValue(const OUString& rPropertyName)
636 {
637     SolarMutexGuard aGuard;
638     uno::Any aRet;
639     if(m_pDoc)
640     {
641         const SfxItemPropertyMapEntry*  pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
642         if(!pEntry)
643             throw UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
644 
645         const SwEndNoteInfo& rEndInfo = m_pDoc->GetEndNoteInfo();
646         switch(pEntry->nWID)
647         {
648             case WID_PREFIX:
649                 aRet <<= rEndInfo.GetPrefix();
650             break;
651             case WID_SUFFIX:
652                 aRet <<= rEndInfo.GetSuffix();
653             break;
654             case  WID_NUMBERING_TYPE :
655                 aRet <<= static_cast<sal_Int16>(rEndInfo.m_aFormat.GetNumberingType());
656             break;
657             case  WID_START_AT:
658                 aRet <<= static_cast<sal_Int16>(rEndInfo.m_nFootnoteOffset);
659             break;
660             case  WID_PARAGRAPH_STYLE    :
661             {
662                 SwTextFormatColl* pColl = rEndInfo.GetFootnoteTextColl();
663                 OUString aString;
664                 if(pColl)
665                     aString = pColl->GetName();
666                 SwStyleNameMapper::FillProgName(
667                         aString,
668                         aString,
669                         SwGetPoolIdFromName::TxtColl);
670                 aRet <<= aString;
671 
672             }
673             break;
674             case  WID_PAGE_STYLE :
675             {
676                 OUString aString;
677                 if( rEndInfo.KnowsPageDesc() )
678                 {
679                     SwStyleNameMapper::FillProgName(
680                         rEndInfo.GetPageDesc( *m_pDoc )->GetName(),
681                         aString,
682                         SwGetPoolIdFromName::PageDesc);
683                 }
684                 aRet <<= aString;
685             }
686             break;
687             case WID_ANCHOR_CHARACTER_STYLE:
688             case WID_CHARACTER_STYLE:
689             {
690                 OUString aString;
691                 const SwCharFormat* pCharFormat = rEndInfo.GetCurrentCharFormat( pEntry->nWID == WID_ANCHOR_CHARACTER_STYLE );
692                 if( pCharFormat )
693                 {
694                     SwStyleNameMapper::FillProgName(
695                             pCharFormat->GetName(),
696                             aString,
697                             SwGetPoolIdFromName::ChrFmt);
698                 }
699                 aRet <<= aString;
700             }
701             break;
702         }
703 
704     }
705     return aRet;
706 }
707 
addPropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)708 void SwXEndnoteProperties::addPropertyChangeListener(
709     const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
710 {
711     OSL_FAIL("not implemented");
712 }
713 
removePropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)714 void SwXEndnoteProperties::removePropertyChangeListener(const OUString& /*PropertyName*/,
715         const uno:: Reference< beans::XPropertyChangeListener > & /*xListener*/)
716 {
717     OSL_FAIL("not implemented");
718 }
719 
addVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)720 void SwXEndnoteProperties::addVetoableChangeListener(const OUString& /*PropertyName*/,
721     const uno:: Reference< beans::XVetoableChangeListener > & /*xListener*/)
722 {
723     OSL_FAIL("not implemented");
724 }
725 
removeVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)726 void SwXEndnoteProperties::removeVetoableChangeListener(const OUString& /*PropertyName*/, const uno:: Reference< beans::XVetoableChangeListener > & /*xListener*/)
727 {
728     OSL_FAIL("not implemented");
729 }
730 
getImplementationName()731 OUString SwXLineNumberingProperties::getImplementationName()
732 {
733     return u"SwXLineNumberingProperties"_ustr;
734 }
735 
supportsService(const OUString & rServiceName)736 sal_Bool SwXLineNumberingProperties::supportsService(const OUString& rServiceName)
737 {
738     return cppu::supportsService(this, rServiceName);
739 }
740 
getSupportedServiceNames()741 Sequence< OUString > SwXLineNumberingProperties::getSupportedServiceNames()
742 {
743     Sequence<OUString> aRet { u"com.sun.star.text.LineNumberingProperties"_ustr };
744     return aRet;
745 }
746 
SwXLineNumberingProperties(SwDoc * pDc)747 SwXLineNumberingProperties::SwXLineNumberingProperties(SwDoc* pDc) :
748     m_pDoc(pDc),
749     m_pPropertySet(GetLineNumberingSet())
750 {
751 }
752 
~SwXLineNumberingProperties()753 SwXLineNumberingProperties::~SwXLineNumberingProperties()
754 {
755 }
756 
getPropertySetInfo()757 uno::Reference< beans::XPropertySetInfo >  SwXLineNumberingProperties::getPropertySetInfo()
758 {
759     static uno::Reference< beans::XPropertySetInfo >  aRef = m_pPropertySet->getPropertySetInfo();
760     return aRef;
761 }
762 
setPropertyValue(const OUString & rPropertyName,const Any & aValue)763 void SwXLineNumberingProperties::setPropertyValue(
764     const OUString& rPropertyName, const Any& aValue)
765 {
766     SolarMutexGuard aGuard;
767     if(!m_pDoc)
768         throw uno::RuntimeException();
769 
770     const SfxItemPropertyMapEntry*  pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
771     if(!pEntry)
772         throw UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
773 
774     if ( pEntry->nFlags & PropertyAttribute::READONLY)
775         throw PropertyVetoException("Property is read-only: " + rPropertyName, getXWeak() );
776     SwLineNumberInfo  aFontMetric(m_pDoc->GetLineNumberInfo());
777     switch(pEntry->nWID)
778     {
779         case WID_NUM_ON:
780         {
781             bool bVal = *o3tl::doAccess<bool>(aValue);
782             aFontMetric.SetPaintLineNumbers(bVal);
783         }
784         break;
785         case WID_CHARACTER_STYLE :
786         {
787             SwCharFormat* pFormat = lcl_getCharFormat(m_pDoc, aValue);
788             if(pFormat)
789                 aFontMetric.SetCharFormat(pFormat);
790         }
791         break;
792         case WID_NUMBERING_TYPE  :
793         {
794             SvxNumberType aNumType(aFontMetric.GetNumType());
795             sal_Int16 nTmp = 0;
796             aValue >>= nTmp;
797             aNumType.SetNumberingType(static_cast<SvxNumType>(nTmp));
798             aFontMetric.SetNumType(aNumType);
799         }
800         break;
801         case WID_NUMBER_POSITION :
802         {
803             sal_Int16 nTmp = 0;
804             aValue >>= nTmp;
805             switch(nTmp)
806             {
807                 case  style::LineNumberPosition::LEFT:
808                      aFontMetric.SetPos(LINENUMBER_POS_LEFT);
809                 break;
810                 case style::LineNumberPosition::RIGHT :
811                      aFontMetric.SetPos(LINENUMBER_POS_RIGHT);
812                 break;
813                 case  style::LineNumberPosition::INSIDE:
814                     aFontMetric.SetPos(LINENUMBER_POS_INSIDE);
815                 break;
816                 case  style::LineNumberPosition::OUTSIDE:
817                     aFontMetric.SetPos(LINENUMBER_POS_OUTSIDE);
818                 break;
819             }
820         }
821         break;
822         case WID_DISTANCE        :
823         {
824             sal_Int32 nVal = 0;
825             aValue >>= nVal;
826             sal_Int32 nTmp = o3tl::toTwips(nVal, o3tl::Length::mm100);
827             if (nTmp > SAL_MAX_UINT16)
828                 nTmp = SAL_MAX_UINT16;
829             aFontMetric.SetPosFromLeft(nTmp);
830         }
831         break;
832         case WID_INTERVAL   :
833         {
834             sal_Int16 nTmp = 0;
835             aValue >>= nTmp;
836             if( nTmp > 0)
837                 aFontMetric.SetCountBy(nTmp);
838         }
839         break;
840         case WID_SEPARATOR_TEXT  :
841         {
842             OUString uTmp;
843             aValue >>= uTmp;
844             aFontMetric.SetDivider(uTmp);
845         }
846         break;
847         case WID_SEPARATOR_INTERVAL:
848         {
849             sal_Int16 nTmp = 0;
850             aValue >>= nTmp;
851             if( nTmp >= 0)
852                 aFontMetric.SetDividerCountBy(nTmp);
853         }
854         break;
855         case WID_COUNT_EMPTY_LINES :
856         {
857             bool bVal = *o3tl::doAccess<bool>(aValue);
858             aFontMetric.SetCountBlankLines(bVal);
859         }
860         break;
861         case WID_COUNT_LINES_IN_FRAMES :
862         {
863             bool bVal = *o3tl::doAccess<bool>(aValue);
864             aFontMetric.SetCountInFlys(bVal);
865         }
866         break;
867         case WID_RESTART_AT_EACH_PAGE :
868         {
869             bool bVal = *o3tl::doAccess<bool>(aValue);
870             aFontMetric.SetRestartEachPage(bVal);
871         }
872         break;
873     }
874     m_pDoc->SetLineNumberInfo(aFontMetric);
875 }
876 
getPropertyValue(const OUString & rPropertyName)877 Any SwXLineNumberingProperties::getPropertyValue(const OUString& rPropertyName)
878 {
879     SolarMutexGuard aGuard;
880     Any aRet;
881     if(!m_pDoc)
882         throw uno::RuntimeException();
883 
884     const SfxItemPropertyMapEntry*  pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
885     if(!pEntry)
886         throw UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
887 
888     const SwLineNumberInfo& rInfo = m_pDoc->GetLineNumberInfo();
889     switch(pEntry->nWID)
890     {
891         case WID_NUM_ON:
892             aRet <<= rInfo.IsPaintLineNumbers();
893         break;
894         case WID_CHARACTER_STYLE :
895         {
896             OUString aString;
897             // return empty string if no char format is set
898             // otherwise it would be created here
899             if(rInfo.HasCharFormat())
900             {
901                 SwStyleNameMapper::FillProgName(
902                             rInfo.GetCharFormat(m_pDoc->getIDocumentStylePoolAccess())->GetName(),
903                             aString,
904                             SwGetPoolIdFromName::ChrFmt);
905             }
906             aRet <<= aString;
907         }
908         break;
909         case WID_NUMBERING_TYPE  :
910             aRet <<= static_cast<sal_Int16>(rInfo.GetNumType().GetNumberingType());
911         break;
912         case WID_NUMBER_POSITION :
913         {
914             sal_Int16 nRet = 0;
915             switch(rInfo.GetPos())
916             {
917                 case  LINENUMBER_POS_LEFT:
918                     nRet = style::LineNumberPosition::LEFT;
919                 break;
920                 case LINENUMBER_POS_RIGHT :
921                     nRet = style::LineNumberPosition::RIGHT      ;
922                 break;
923                 case  LINENUMBER_POS_INSIDE:
924                     nRet = style::LineNumberPosition::INSIDE     ;
925                 break;
926                 case LINENUMBER_POS_OUTSIDE :
927                     nRet = style::LineNumberPosition::OUTSIDE    ;
928                 break;
929             }
930             aRet <<= nRet;
931         }
932         break;
933         case WID_DISTANCE        :
934         {
935             sal_uInt16 nPos = rInfo.GetPosFromLeft();
936             if(USHRT_MAX == nPos)
937                 nPos = 0;
938             aRet <<= static_cast < sal_Int32 >(convertTwipToMm100(nPos));
939         }
940         break;
941         case WID_INTERVAL   :
942             aRet <<= static_cast<sal_Int16>(rInfo.GetCountBy());
943         break;
944         case WID_SEPARATOR_TEXT  :
945             aRet <<= rInfo.GetDivider();
946         break;
947         case WID_SEPARATOR_INTERVAL:
948             aRet <<= static_cast<sal_Int16>(rInfo.GetDividerCountBy());
949         break;
950         case WID_COUNT_EMPTY_LINES :
951             aRet <<= rInfo.IsCountBlankLines();
952         break;
953         case WID_COUNT_LINES_IN_FRAMES :
954             aRet <<= rInfo.IsCountInFlys();
955         break;
956         case WID_RESTART_AT_EACH_PAGE :
957             aRet <<= rInfo.IsRestartEachPage();
958         break;
959     }
960     return aRet;
961 }
962 
addPropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)963 void SwXLineNumberingProperties::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno:: Reference< beans::XPropertyChangeListener > & /*xListener*/)
964 {
965 OSL_FAIL("not implemented");
966 }
967 
removePropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)968 void SwXLineNumberingProperties::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno:: Reference< beans::XPropertyChangeListener > & /*xListener*/)
969 {
970 OSL_FAIL("not implemented");
971 }
972 
addVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)973 void SwXLineNumberingProperties::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno:: Reference< beans::XVetoableChangeListener > & /*xListener*/)
974 {
975 OSL_FAIL("not implemented");
976 }
977 
removeVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)978 void SwXLineNumberingProperties::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno:: Reference< beans::XVetoableChangeListener > & /*xListener*/)
979 {
980 OSL_FAIL("not implemented");
981 }
982 
983 constexpr OUString aInvalidStyle = u"__XXX___invalid"_ustr;
984 
985 class SwXNumberingRules::Impl
986     : public SvtListener
987 {
988     SwXNumberingRules& m_rParent;
989     virtual void Notify(const SfxHint&) override;
990     public:
Impl(SwXNumberingRules & rParent)991         explicit Impl(SwXNumberingRules& rParent) : m_rParent(rParent) {}
992 };
993 
isInvalidStyle(std::u16string_view rName)994 bool SwXNumberingRules::isInvalidStyle(std::u16string_view rName)
995 {
996     return rName == aInvalidStyle;
997 }
998 
getImplementationName()999 OUString SwXNumberingRules::getImplementationName()
1000 {
1001     return u"SwXNumberingRules"_ustr;
1002 }
1003 
supportsService(const OUString & rServiceName)1004 sal_Bool SwXNumberingRules::supportsService(const OUString& rServiceName)
1005 {
1006     return cppu::supportsService(this, rServiceName);
1007 }
1008 
getSupportedServiceNames()1009 Sequence< OUString > SwXNumberingRules::getSupportedServiceNames()
1010 {
1011     Sequence<OUString> aRet { u"com.sun.star.text.NumberingRules"_ustr };
1012     return aRet;
1013 }
1014 
SwXNumberingRules(const SwNumRule & rRule,SwDoc * doc)1015 SwXNumberingRules::SwXNumberingRules(const SwNumRule& rRule, SwDoc* doc) :
1016     m_pImpl(new SwXNumberingRules::Impl(*this)),
1017     m_pDoc(doc),
1018     m_pDocShell(nullptr),
1019     m_pNumRule(new SwNumRule(rRule)),
1020     m_pPropertySet(GetNumberingRulesSet()),
1021     m_bOwnNumRuleCreated(true)
1022 {
1023     // first organize the document - it is dependent on the set character formats
1024     // if no format is set, it should work as well
1025     for( sal_uInt16 i = 0; i < MAXLEVEL; ++i)
1026     {
1027         SwNumFormat rFormat(m_pNumRule->Get(i));
1028         SwCharFormat* pCharFormat = rFormat.GetCharFormat();
1029         if(pCharFormat)
1030         {
1031             m_pDoc = pCharFormat->GetDoc();
1032             break;
1033         }
1034     }
1035     if(m_pDoc)
1036         m_pImpl->StartListening(GetPageDescNotifier(m_pDoc));
1037     for(sal_uInt16 i = 0; i < MAXLEVEL; ++i)
1038     {
1039         m_sNewCharStyleNames[i] = aInvalidStyle;
1040         m_sNewBulletFontNames[i] = aInvalidStyle;
1041     }
1042 }
1043 
SwXNumberingRules(SwDocShell & rDocSh)1044 SwXNumberingRules::SwXNumberingRules(SwDocShell& rDocSh) :
1045     m_pImpl(new SwXNumberingRules::Impl(*this)),
1046     m_pDoc(nullptr),
1047     m_pDocShell(&rDocSh),
1048     m_pNumRule(nullptr),
1049     m_pPropertySet(GetNumberingRulesSet()),
1050     m_bOwnNumRuleCreated(false)
1051 {
1052     if (!m_pDocShell->GetDoc())
1053         throw uno::RuntimeException(u"Uninitialized shell passed to SwXNumberingRules constructor"_ustr);
1054     m_pImpl->StartListening(GetPageDescNotifier(m_pDocShell->GetDoc()));
1055 }
1056 
SwXNumberingRules(SwDoc & rDoc)1057 SwXNumberingRules::SwXNumberingRules(SwDoc& rDoc) :
1058     m_pImpl(new SwXNumberingRules::Impl(*this)),
1059     m_pDoc(&rDoc),
1060     m_pDocShell(nullptr),
1061     m_pNumRule(nullptr),
1062     m_pPropertySet(GetNumberingRulesSet()),
1063     m_bOwnNumRuleCreated(false)
1064 {
1065     m_pImpl->StartListening(GetPageDescNotifier(&rDoc));
1066     m_sCreatedNumRuleName = rDoc.GetUniqueNumRuleName();
1067     rDoc.MakeNumRule( m_sCreatedNumRuleName, nullptr, false,
1068                       // #i89178#
1069                       numfunc::GetDefaultPositionAndSpaceMode() );
1070 }
1071 
~SwXNumberingRules()1072 SwXNumberingRules::~SwXNumberingRules()
1073 {
1074     SolarMutexGuard aGuard;
1075     if(m_pDoc && !m_sCreatedNumRuleName.isEmpty())
1076         m_pDoc->DelNumRule( m_sCreatedNumRuleName );
1077     if( m_bOwnNumRuleCreated )
1078         delete m_pNumRule;
1079 }
1080 
replaceByIndex(sal_Int32 nIndex,const uno::Any & rElement)1081 void SwXNumberingRules::replaceByIndex(sal_Int32 nIndex, const uno::Any& rElement)
1082 {
1083     SolarMutexGuard aGuard;
1084     if(nIndex < 0 || MAXLEVEL <= nIndex)
1085         throw lang::IndexOutOfBoundsException();
1086 
1087     auto rProperties = o3tl::tryAccess<uno::Sequence<beans::PropertyValue>>(
1088         rElement);
1089     if(!rProperties)
1090         throw lang::IllegalArgumentException();
1091     SwNumRule* pRule = nullptr;
1092     if(m_pNumRule)
1093         SwXNumberingRules::SetNumberingRuleByIndex( *m_pNumRule,
1094                             *rProperties, nIndex);
1095     else if(m_pDocShell)
1096     {
1097         // #i87650# - correction of cws warnings:
1098         SwNumRule aNumRule( *(m_pDocShell->GetDoc()->GetOutlineNumRule()) );
1099         SwXNumberingRules::SetNumberingRuleByIndex( aNumRule,
1100                             *rProperties, nIndex);
1101         // set character format if needed
1102         // this code appears to be dead - except when a style is assigned for BITMAP numbering?
1103         const SwCharFormats* pFormats = m_pDocShell->GetDoc()->GetCharFormats();
1104         const size_t nChCount = pFormats->size();
1105         for(sal_uInt16 i = 0; i < MAXLEVEL;i++)
1106         {
1107             SwNumFormat aFormat(aNumRule.Get( i ));
1108             if (!m_sNewCharStyleNames[i].isEmpty() &&
1109                 (!aFormat.GetCharFormat() || aFormat.GetCharFormat()->GetName()!= m_sNewCharStyleNames[i]))
1110             {
1111                 SwCharFormat* pCharFormat = nullptr;
1112                 for(size_t j = 0; j< nChCount; ++j)
1113                 {
1114                     SwCharFormat* pTmp = (*pFormats)[j];
1115                     if(pTmp->GetName() == m_sNewCharStyleNames[i])
1116                     {
1117                         pCharFormat = pTmp;
1118                         break;
1119                     }
1120                 }
1121                 if(!pCharFormat)
1122                 {
1123                     SfxStyleSheetBase* pBase;
1124                     pBase = m_pDocShell->GetStyleSheetPool()->Find(m_sNewCharStyleNames[i],
1125                                                                     SfxStyleFamily::Char);
1126                     if(!pBase)
1127                         pBase = &m_pDocShell->GetStyleSheetPool()->Make(m_sNewCharStyleNames[i], SfxStyleFamily::Char);
1128                     pCharFormat = static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat();
1129 
1130                 }
1131                 aFormat.SetCharFormat( pCharFormat );
1132                 aNumRule.Set( i, aFormat );
1133             }
1134         }
1135         m_pDocShell->GetDoc()->SetOutlineNumRule( aNumRule );
1136     }
1137     else if(m_pDoc && !m_sCreatedNumRuleName.isEmpty() &&
1138         nullptr != (pRule = m_pDoc->FindNumRulePtr( m_sCreatedNumRuleName )))
1139     {
1140         SwXNumberingRules::SetNumberingRuleByIndex( *pRule,
1141                             *rProperties, nIndex);
1142 
1143         pRule->Validate(*m_pDoc);
1144     }
1145     else
1146         throw uno::RuntimeException();
1147 }
1148 
getCount()1149 sal_Int32 SwXNumberingRules::getCount()
1150 {
1151     return MAXLEVEL;
1152 }
1153 
getByIndex(sal_Int32 nIndex)1154 uno::Any SwXNumberingRules::getByIndex(sal_Int32 nIndex)
1155 {
1156     SolarMutexGuard aGuard;
1157     if(nIndex < 0 || MAXLEVEL <= nIndex)
1158         throw lang::IndexOutOfBoundsException();
1159 
1160     uno::Any aVal;
1161     const SwNumRule* pRule = m_pNumRule;
1162     if(!pRule && m_pDoc && !m_sCreatedNumRuleName.isEmpty())
1163         pRule = m_pDoc->FindNumRulePtr( m_sCreatedNumRuleName );
1164     if(pRule)
1165     {
1166         uno::Sequence<beans::PropertyValue> aRet = GetNumberingRuleByIndex(
1167                                         *pRule, nIndex);
1168         aVal <<= aRet;
1169 
1170     }
1171     else if(m_pDocShell)
1172     {
1173         uno::Sequence<beans::PropertyValue> aRet = GetNumberingRuleByIndex(
1174                 *m_pDocShell->GetDoc()->GetOutlineNumRule(), nIndex);
1175         aVal <<= aRet;
1176     }
1177     else
1178         throw uno::RuntimeException();
1179     return aVal;
1180 }
1181 
getElementType()1182 uno::Type SwXNumberingRules::getElementType()
1183 {
1184     return cppu::UnoType<uno::Sequence<beans::PropertyValue>>::get();
1185 }
1186 
hasElements()1187 sal_Bool SwXNumberingRules::hasElements()
1188 {
1189     return true;
1190 }
1191 
1192 const TranslateId STR_POOLCOLL_HEADLINE_ARY[]
1193 {
1194     STR_POOLCOLL_HEADLINE1,
1195     STR_POOLCOLL_HEADLINE2,
1196     STR_POOLCOLL_HEADLINE3,
1197     STR_POOLCOLL_HEADLINE4,
1198     STR_POOLCOLL_HEADLINE5,
1199     STR_POOLCOLL_HEADLINE6,
1200     STR_POOLCOLL_HEADLINE7,
1201     STR_POOLCOLL_HEADLINE8,
1202     STR_POOLCOLL_HEADLINE9,
1203     STR_POOLCOLL_HEADLINE10
1204 };
1205 
GetNumberingRuleByIndex(const SwNumRule & rNumRule,sal_Int32 nIndex) const1206 uno::Sequence<beans::PropertyValue> SwXNumberingRules::GetNumberingRuleByIndex(
1207                 const SwNumRule& rNumRule, sal_Int32 nIndex) const
1208 {
1209     SolarMutexGuard aGuard;
1210     OSL_ENSURE( 0 <= nIndex && nIndex < MAXLEVEL, "index out of range" );
1211 
1212     const SwNumFormat& rFormat = rNumRule.Get( o3tl::narrowing<sal_uInt16>(nIndex) );
1213 
1214     SwCharFormat* pCharFormat = rFormat.GetCharFormat();
1215     OUString CharStyleName;
1216     if (pCharFormat)
1217         CharStyleName = pCharFormat->GetName();
1218 
1219     // Whether or not a style is present: the array entry overwrites this string
1220     if (!m_sNewCharStyleNames[nIndex].isEmpty() &&
1221         !SwXNumberingRules::isInvalidStyle(m_sNewCharStyleNames[nIndex]))
1222     {
1223         CharStyleName = m_sNewCharStyleNames[nIndex];
1224     }
1225 
1226     OUString aUString;
1227     if (m_pDocShell) // -> Chapter Numbering
1228     {
1229         // template name
1230         OUString sValue(SwResId(STR_POOLCOLL_HEADLINE_ARY[nIndex]));
1231         const SwTextFormatColls* pColls = m_pDocShell->GetDoc()->GetTextFormatColls();
1232         const size_t nCount = pColls->size();
1233         for(size_t i = 0; i < nCount; ++i)
1234         {
1235             SwTextFormatColl &rTextColl = *pColls->operator[](i);
1236             if(rTextColl.IsDefault())
1237                 continue;
1238 
1239             const sal_Int16 nOutLevel = rTextColl.IsAssignedToListLevelOfOutlineStyle()
1240                                         ? static_cast<sal_Int16>(rTextColl.GetAssignedOutlineStyleLevel())
1241                                         : MAXLEVEL;
1242             if ( nOutLevel == nIndex )
1243             {
1244                 sValue = rTextColl.GetName();
1245                 break; // the style for the level in question has been found
1246             }
1247             else if( sValue==rTextColl.GetName() )
1248             {
1249                 // if the default for the level is existing, but its
1250                 // level is different, then it cannot be the default.
1251                 sValue.clear();
1252             }
1253         }
1254         SwStyleNameMapper::FillProgName(sValue, aUString, SwGetPoolIdFromName::TxtColl);
1255     }
1256 
1257     OUString referer;
1258     if (m_pDoc != nullptr) {
1259         auto const sh = m_pDoc->GetPersist();
1260         if (sh != nullptr && sh->HasName()) {
1261             referer = sh->GetMedium()->GetName();
1262         }
1263     }
1264     return GetPropertiesForNumFormat(
1265         rFormat, CharStyleName, m_pDocShell ? & aUString : nullptr, referer);
1266 
1267 }
1268 
GetPropertiesForNumFormat(const SwNumFormat & rFormat,OUString const & rCharFormatName,OUString const * const pHeadingStyleName,OUString const & referer)1269 uno::Sequence<beans::PropertyValue> SwXNumberingRules::GetPropertiesForNumFormat(
1270         const SwNumFormat& rFormat, OUString const& rCharFormatName,
1271         OUString const*const pHeadingStyleName, OUString const & referer)
1272 {
1273     bool bChapterNum = pHeadingStyleName != nullptr;
1274 
1275     std::vector<PropertyValue> aPropertyValues;
1276     aPropertyValues.reserve(32);
1277     //fill all properties into the array
1278 
1279     //adjust
1280     SvxAdjust eAdj = rFormat.GetNumAdjust();
1281     sal_Int16 nINT16 = aSvxToUnoAdjust[eAdj];
1282     aPropertyValues.push_back(comphelper::makePropertyValue(u"Adjust"_ustr, nINT16));
1283 
1284     //parentnumbering
1285     nINT16 = rFormat.GetIncludeUpperLevels();
1286     aPropertyValues.push_back(comphelper::makePropertyValue(u"ParentNumbering"_ustr, nINT16));
1287 
1288     //prefix
1289     OUString aUString = rFormat.GetPrefix();
1290     aPropertyValues.push_back(comphelper::makePropertyValue(u"Prefix"_ustr, aUString));
1291 
1292     //suffix
1293     aUString = rFormat.GetSuffix();
1294     aPropertyValues.push_back(comphelper::makePropertyValue(u"Suffix"_ustr, aUString));
1295 
1296     //listformat
1297     if (rFormat.HasListFormat())
1298     {
1299         aPropertyValues.push_back(comphelper::makePropertyValue(u"ListFormat"_ustr, rFormat.GetListFormat()));
1300     }
1301 
1302     if (rFormat.GetIsLegal())
1303         aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_LEVEL_IS_LEGAL, true));
1304 
1305     //char style name
1306     aUString.clear();
1307     SwStyleNameMapper::FillProgName( rCharFormatName, aUString, SwGetPoolIdFromName::ChrFmt);
1308     aPropertyValues.push_back(comphelper::makePropertyValue(u"CharStyleName"_ustr, aUString));
1309 
1310     //startvalue
1311     nINT16 = rFormat.GetStart();
1312     aPropertyValues.push_back(comphelper::makePropertyValue(u"StartWith"_ustr, nINT16));
1313 
1314     if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1315     {
1316         //leftmargin
1317         sal_Int32 nINT32 = convertTwipToMm100(rFormat.GetAbsLSpace());
1318         aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_LEFT_MARGIN, nINT32));
1319 
1320         //chartextoffset
1321         nINT32 = convertTwipToMm100(rFormat.GetCharTextDistance());
1322         aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_SYMBOL_TEXT_DISTANCE, nINT32));
1323 
1324         //firstlineoffset
1325         nINT32 = convertTwipToMm100(rFormat.GetFirstLineOffset());
1326         aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_FIRST_LINE_OFFSET, nINT32));
1327     }
1328 
1329     // PositionAndSpaceMode
1330     nINT16 = PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION;
1331     if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
1332     {
1333         nINT16 = PositionAndSpaceMode::LABEL_ALIGNMENT;
1334     }
1335     aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_POSITION_AND_SPACE_MODE, nINT16));
1336 
1337     if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
1338     {
1339         // LabelFollowedBy
1340         nINT16 = LabelFollow::LISTTAB;
1341         if ( rFormat.GetLabelFollowedBy() == SvxNumberFormat::SPACE )
1342         {
1343             nINT16 = LabelFollow::SPACE;
1344         }
1345         else if ( rFormat.GetLabelFollowedBy() == SvxNumberFormat::NOTHING )
1346         {
1347             nINT16 = LabelFollow::NOTHING;
1348         }
1349         else if ( rFormat.GetLabelFollowedBy() == SvxNumberFormat::NEWLINE )
1350         {
1351             nINT16 = LabelFollow::NEWLINE;
1352         }
1353         aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_LABEL_FOLLOWED_BY, nINT16));
1354 
1355         // ListtabStopPosition
1356         sal_Int32 nINT32 = convertTwipToMm100(rFormat.GetListtabPos());
1357         aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_LISTTAB_STOP_POSITION, nINT32));
1358 
1359         // FirstLineIndent
1360         nINT32 = convertTwipToMm100(rFormat.GetFirstLineIndent());
1361         aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_FIRST_LINE_INDENT, nINT32));
1362 
1363         // IndentAt
1364         nINT32 = convertTwipToMm100(rFormat.GetIndentAt());
1365         aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_INDENT_AT, nINT32));
1366     }
1367 
1368     //numberingtype
1369     nINT16 = rFormat.GetNumberingType();
1370     aPropertyValues.push_back(comphelper::makePropertyValue(u"NumberingType"_ustr, nINT16));
1371 
1372     if(!bChapterNum)
1373     {
1374         if(SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType())
1375         {
1376             sal_UCS4 cBullet = rFormat.GetBulletChar();
1377 
1378             //BulletId
1379             nINT16 = cBullet;
1380             aPropertyValues.push_back(comphelper::makePropertyValue(u"BulletId"_ustr, nINT16));
1381 
1382             std::optional<vcl::Font> pFont = rFormat.GetBulletFont();
1383 
1384             //BulletChar
1385             aUString = OUString(&cBullet, 1);
1386             aPropertyValues.push_back(comphelper::makePropertyValue(u"BulletChar"_ustr, aUString));
1387 
1388             //BulletFontName
1389             aUString = pFont ? pFont->GetStyleName() : OUString();
1390             aPropertyValues.push_back(comphelper::makePropertyValue(u"BulletFontName"_ustr, aUString));
1391 
1392             //BulletFont
1393             if(pFont)
1394             {
1395                 awt::FontDescriptor aDesc;
1396                 SvxUnoFontDescriptor::ConvertFromFont( *pFont, aDesc );
1397                 aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_BULLET_FONT, aDesc));
1398             }
1399         }
1400         if (SVX_NUM_BITMAP == rFormat.GetNumberingType())
1401         {
1402             const SvxBrushItem* pBrush = rFormat.GetBrush();
1403             const Graphic* pGraphic = pBrush ? pBrush->GetGraphic(referer) : nullptr;
1404             if (pGraphic)
1405             {
1406                 //GraphicBitmap
1407                 uno::Reference<awt::XBitmap> xBitmap(pGraphic->GetXGraphic(), uno::UNO_QUERY);
1408                 aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_GRAPHIC_BITMAP, xBitmap));
1409             }
1410 
1411             Size aSize = rFormat.GetGraphicSize();
1412             // #i101131#
1413             // adjust conversion due to type mismatch between <Size> and <awt::Size>
1414             awt::Size aAwtSize(convertTwipToMm100(aSize.Width()), convertTwipToMm100(aSize.Height()));
1415             aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_GRAPHIC_SIZE, aAwtSize));
1416 
1417             const SwFormatVertOrient* pOrient = rFormat.GetGraphicOrientation();
1418             if(pOrient)
1419             {
1420                 uno::Any any;
1421                 pOrient->QueryValue(any);
1422                 aPropertyValues.emplace_back(
1423                     UNO_NAME_VERT_ORIENT, -1, any, PropertyState_DIRECT_VALUE);
1424             }
1425         }
1426     }
1427     else
1428     {
1429         aUString = *pHeadingStyleName;
1430         aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_HEADING_STYLE_NAME, aUString));
1431     }
1432 
1433     return ::comphelper::containerToSequence(aPropertyValues);
1434 }
1435 
SetNumberingRuleByIndex(SwNumRule & rNumRule,const uno::Sequence<beans::PropertyValue> & rProperties,sal_Int32 nIndex)1436 void SwXNumberingRules::SetNumberingRuleByIndex(
1437             SwNumRule& rNumRule,
1438             const uno::Sequence<beans::PropertyValue>& rProperties, sal_Int32 nIndex)
1439 {
1440     SolarMutexGuard aGuard;
1441     OSL_ENSURE( 0 <= nIndex && nIndex < MAXLEVEL, "index out of range" );
1442 
1443     SwNumFormat aFormat(rNumRule.Get( o3tl::narrowing<sal_uInt16>(nIndex) ));
1444 
1445     OUString sHeadingStyleName;
1446     OUString sParagraphStyleName;
1447 
1448     SetPropertiesToNumFormat(aFormat, m_sNewCharStyleNames[nIndex],
1449         &m_sNewBulletFontNames[nIndex],
1450         &sHeadingStyleName, &sParagraphStyleName,
1451         m_pDoc, m_pDocShell, rProperties);
1452 
1453 
1454     if (m_pDoc && !sParagraphStyleName.isEmpty())
1455     {
1456         const SwTextFormatColls* pColls = m_pDoc->GetTextFormatColls();
1457         const size_t nCount = pColls->size();
1458         for (size_t k = 0; k < nCount; ++k)
1459         {
1460             SwTextFormatColl &rTextColl = *((*pColls)[k]);
1461             if (rTextColl.GetName() == sParagraphStyleName)
1462                 rTextColl.SetFormatAttr( SwNumRuleItem( rNumRule.GetName()));
1463         }
1464     }
1465 
1466     if (!sHeadingStyleName.isEmpty())
1467     {
1468         assert(m_pDocShell);
1469         const SwTextFormatColls* pColls = m_pDocShell->GetDoc()->GetTextFormatColls();
1470         const size_t nCount = pColls->size();
1471         for (size_t k = 0; k < nCount; ++k)
1472         {
1473             SwTextFormatColl &rTextColl = *((*pColls)[k]);
1474             if (rTextColl.IsDefault())
1475                 continue;
1476             if (rTextColl.IsAssignedToListLevelOfOutlineStyle() &&
1477                 rTextColl.GetAssignedOutlineStyleLevel() == nIndex &&
1478                 rTextColl.GetName() != sHeadingStyleName)
1479             {
1480                 rTextColl.DeleteAssignmentToListLevelOfOutlineStyle();
1481             }
1482             else if (rTextColl.GetName() == sHeadingStyleName)
1483             {
1484                 rTextColl.AssignToListLevelOfOutlineStyle( nIndex );
1485             }
1486         }
1487     }
1488 
1489     rNumRule.Set(o3tl::narrowing<sal_uInt16>(nIndex), aFormat);
1490 }
1491 
SetPropertiesToNumFormat(SwNumFormat & aFormat,OUString & rCharStyleName,OUString * const pBulletFontName,OUString * const pHeadingStyleName,OUString * const pParagraphStyleName,SwDoc * const pDoc,SwDocShell * const pDocShell,const uno::Sequence<beans::PropertyValue> & rProperties)1492 void SwXNumberingRules::SetPropertiesToNumFormat(
1493         SwNumFormat & aFormat,
1494         OUString & rCharStyleName, OUString *const pBulletFontName,
1495         OUString *const pHeadingStyleName,
1496         OUString *const pParagraphStyleName,
1497         SwDoc *const pDoc,
1498         SwDocShell *const pDocShell,
1499         const uno::Sequence<beans::PropertyValue>& rProperties)
1500 {
1501     assert(pDoc == nullptr || pDocShell == nullptr); // can't be both ordinary and chapter numbering
1502 
1503     bool bWrongArg = false;
1504     std::unique_ptr<SvxBrushItem> pSetBrush;
1505     std::unique_ptr<Size> pSetSize;
1506     std::unique_ptr<SwFormatVertOrient> pSetVOrient;
1507     bool bCharStyleNameSet = false;
1508 
1509     for (const beans::PropertyValue& rProp : rProperties)
1510     {
1511         if (rProp.Name == UNO_NAME_ADJUST)
1512         {
1513             sal_Int16 nValue = text::HoriOrientation::NONE;
1514             rProp.Value >>= nValue;
1515             switch (nValue) {
1516             case text::HoriOrientation::RIGHT:
1517                 aFormat.SetNumAdjust(SvxAdjust::Right);
1518                 break;
1519             case text::HoriOrientation::CENTER:
1520                 aFormat.SetNumAdjust(SvxAdjust::Center);
1521                 break;
1522             case text::HoriOrientation::LEFT:
1523                 aFormat.SetNumAdjust(SvxAdjust::Left);
1524                 break;
1525             default:
1526                 bWrongArg = true;
1527                 break;
1528             }
1529         }
1530         else if (rProp.Name == UNO_NAME_PARENT_NUMBERING)
1531         {
1532             sal_Int16 nSet = 0;
1533             rProp.Value >>= nSet;
1534             if(nSet >= 0 && MAXLEVEL >= nSet)
1535                 aFormat.SetIncludeUpperLevels( static_cast< sal_uInt8 >(nSet) );
1536         }
1537         else if (rProp.Name == UNO_NAME_PREFIX)
1538         {
1539             OUString uTmp;
1540             rProp.Value >>= uTmp;
1541             aFormat.SetPrefix(uTmp);
1542         }
1543         else if (rProp.Name == UNO_NAME_SUFFIX)
1544         {
1545             OUString uTmp;
1546             rProp.Value >>= uTmp;
1547             aFormat.SetSuffix(uTmp);
1548         }
1549         else if (rProp.Name == UNO_NAME_CHAR_STYLE_NAME)
1550         {
1551             bCharStyleNameSet = true;
1552             OUString uTmp;
1553             rProp.Value >>= uTmp;
1554             OUString sCharFormatName;
1555             SwStyleNameMapper::FillUIName( uTmp, sCharFormatName, SwGetPoolIdFromName::ChrFmt );
1556             SwDoc *const pLocalDoc = pDocShell ? pDocShell->GetDoc() : pDoc;
1557             if (sCharFormatName.isEmpty())
1558             {
1559                 rCharStyleName.clear();
1560                 aFormat.SetCharFormat(nullptr);
1561                 aFormat.SetCharFormatName(u""_ustr);
1562             }
1563             else if (pLocalDoc)
1564             {
1565                 SwCharFormat* pCharFormat = nullptr;
1566                 if (!sCharFormatName.isEmpty())
1567                 {
1568                     pCharFormat = pLocalDoc->FindCharFormatByName(sCharFormatName);
1569                     if(!pCharFormat)
1570                     {
1571 
1572                         SfxStyleSheetBase* pBase;
1573                         SfxStyleSheetBasePool* pPool = pLocalDoc->GetDocShell()->GetStyleSheetPool();
1574                         pBase = pPool->Find(sCharFormatName, SfxStyleFamily::Char);
1575                         if(!pBase)
1576                             pBase = &pPool->Make(sCharFormatName, SfxStyleFamily::Char);
1577                         pCharFormat = static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat();
1578                     }
1579                 }
1580                 aFormat.SetCharFormat( pCharFormat );
1581                 // #i51842#
1582                 // If the character format has been found its name should not be in the
1583                 // char style names array
1584                 rCharStyleName.clear();
1585             }
1586             else
1587                 rCharStyleName = sCharFormatName;
1588         }
1589         else if (rProp.Name == UNO_NAME_START_WITH)
1590         {
1591             sal_Int16 nVal = 0;
1592             rProp.Value >>= nVal;
1593             aFormat.SetStart(nVal);
1594         }
1595         else if (rProp.Name == UNO_NAME_LEFT_MARGIN)
1596         {
1597             sal_Int32 nValue = 0;
1598             rProp.Value >>= nValue;
1599             // #i23727# nValue can be negative
1600             aFormat.SetAbsLSpace(o3tl::toTwips(nValue, o3tl::Length::mm100));
1601         }
1602         else if (rProp.Name == UNO_NAME_SYMBOL_TEXT_DISTANCE)
1603         {
1604             sal_Int32 nValue = 0;
1605             rProp.Value >>= nValue;
1606             if (nValue >= 0)
1607                 aFormat.SetCharTextDistance(o3tl::toTwips(nValue, o3tl::Length::mm100));
1608             else
1609                 bWrongArg = true;
1610         }
1611         else if (rProp.Name == UNO_NAME_FIRST_LINE_OFFSET)
1612         {
1613             sal_Int32 nValue = 0;
1614             rProp.Value >>= nValue;
1615             // #i23727# nValue can be positive
1616             nValue = o3tl::toTwips(nValue, o3tl::Length::mm100);
1617             aFormat.SetFirstLineOffset(nValue);
1618         }
1619         else if (rProp.Name == UNO_NAME_POSITION_AND_SPACE_MODE)
1620         {
1621             sal_Int16 nValue = 0;
1622             rProp.Value >>= nValue;
1623             if ( nValue == 0 )
1624             {
1625                 aFormat.SetPositionAndSpaceMode( SvxNumberFormat::LABEL_WIDTH_AND_POSITION );
1626             }
1627             else if ( nValue == 1 )
1628             {
1629                 aFormat.SetPositionAndSpaceMode( SvxNumberFormat::LABEL_ALIGNMENT );
1630             }
1631             else
1632             {
1633                 bWrongArg = true;
1634             }
1635         }
1636         else if (rProp.Name == UNO_NAME_LABEL_FOLLOWED_BY)
1637         {
1638             sal_Int16 nValue = 0;
1639             rProp.Value >>= nValue;
1640             if ( nValue == LabelFollow::LISTTAB )
1641             {
1642                 aFormat.SetLabelFollowedBy( SvxNumberFormat::LISTTAB );
1643             }
1644             else if ( nValue == LabelFollow::SPACE )
1645             {
1646                 aFormat.SetLabelFollowedBy( SvxNumberFormat::SPACE );
1647             }
1648             else if ( nValue == LabelFollow::NOTHING )
1649             {
1650                 aFormat.SetLabelFollowedBy( SvxNumberFormat::NOTHING );
1651             }
1652             else if ( nValue == LabelFollow::NEWLINE )
1653             {
1654                 aFormat.SetLabelFollowedBy( SvxNumberFormat::NEWLINE );
1655             }
1656             else
1657             {
1658                 bWrongArg = true;
1659             }
1660         }
1661         else if (rProp.Name == UNO_NAME_LISTTAB_STOP_POSITION)
1662         {
1663             sal_Int32 nValue = 0;
1664             rProp.Value >>= nValue;
1665             nValue = o3tl::toTwips(nValue, o3tl::Length::mm100);
1666             if ( nValue >= 0 )
1667             {
1668                 aFormat.SetListtabPos( nValue );
1669             }
1670             else
1671             {
1672                 bWrongArg = true;
1673             }
1674         }
1675         else if (rProp.Name == UNO_NAME_FIRST_LINE_INDENT)
1676         {
1677             sal_Int32 nValue = 0;
1678             rProp.Value >>= nValue;
1679             nValue = o3tl::toTwips(nValue, o3tl::Length::mm100);
1680             aFormat.SetFirstLineIndent( nValue );
1681         }
1682         else if (rProp.Name == UNO_NAME_INDENT_AT)
1683         {
1684             sal_Int32 nValue = 0;
1685             rProp.Value >>= nValue;
1686             nValue = o3tl::toTwips(nValue, o3tl::Length::mm100);
1687             aFormat.SetIndentAt( nValue );
1688         }
1689         else if (rProp.Name == UNO_NAME_NUMBERING_TYPE)
1690         {
1691             sal_Int16 nSet = 0;
1692             rProp.Value >>= nSet;
1693             if(nSet >= 0)
1694                 aFormat.SetNumberingType(static_cast<SvxNumType>(nSet));
1695             else
1696                 bWrongArg = true;
1697         }
1698         else if (rProp.Name == UNO_NAME_PARAGRAPH_STYLE_NAME)
1699         {
1700             if (pParagraphStyleName)
1701             {
1702                 OUString uTmp;
1703                 rProp.Value >>= uTmp;
1704                 OUString sStyleName;
1705                 SwStyleNameMapper::FillUIName(uTmp, sStyleName, SwGetPoolIdFromName::TxtColl );
1706                 *pParagraphStyleName = sStyleName;
1707             }
1708         }
1709         else if (rProp.Name == UNO_NAME_BULLET_ID)
1710         {
1711             sal_Int16 nSet = 0;
1712             if( rProp.Value >>= nSet )
1713                 aFormat.SetBulletChar(nSet);
1714             else
1715                 bWrongArg = true;
1716         }
1717         else if (rProp.Name == UNO_NAME_BULLET_FONT)
1718         {
1719             awt::FontDescriptor desc;
1720             if (rProp.Value >>= desc)
1721             {
1722                 // #i93725#
1723                 // do not accept "empty" font
1724                 if (!desc.Name.isEmpty())
1725                 {
1726                     vcl::Font aFont;
1727                     SvxUnoFontDescriptor::ConvertToFont(desc, aFont);
1728                     aFormat.SetBulletFont(&aFont);
1729                 }
1730             }
1731             else
1732                 bWrongArg = true;
1733         }
1734         else if (rProp.Name == UNO_NAME_BULLET_FONT_NAME)
1735         {
1736             OUString sBulletFontName;
1737             rProp.Value >>= sBulletFontName;
1738             SwDocShell *const pLclDocShell = pDocShell ? pDocShell : pDoc ? pDoc->GetDocShell() : nullptr;
1739             if (!sBulletFontName.isEmpty() && pLclDocShell)
1740             {
1741                 const SvxFontListItem* pFontListItem =
1742                         static_cast<const SvxFontListItem* >(pLclDocShell
1743                                             ->GetItem( SID_ATTR_CHAR_FONTLIST ));
1744                 const FontList*  pList = pFontListItem->GetFontList();
1745                 vcl::Font aFont(pList->Get(sBulletFontName, WEIGHT_NORMAL, ITALIC_NONE));
1746                 aFormat.SetBulletFont(&aFont);
1747             }
1748             else if (pBulletFontName)
1749                 *pBulletFontName = sBulletFontName;
1750         }
1751         else if (rProp.Name == UNO_NAME_BULLET_CHAR)
1752         {
1753             OUString aChar;
1754             rProp.Value >>= aChar;
1755             if (aChar.isEmpty())
1756             {
1757                 // If w:lvlText's value is null - set bullet char to zero
1758                 aFormat.SetBulletChar(u'\0');
1759             }
1760             else
1761             {
1762                 sal_Int32 nIndexUtf16 = 0;
1763                 sal_UCS4 cBullet = aChar.iterateCodePoints(&nIndexUtf16);
1764                 if (aChar.getLength() == nIndexUtf16)
1765                     aFormat.SetBulletChar(cBullet);
1766                 else
1767                     bWrongArg = true;
1768             }
1769         }
1770         else if (rProp.Name == UNO_NAME_GRAPHIC)
1771         {
1772             uno::Reference<graphic::XGraphic> xGraphic;
1773             if (rProp.Value >>= xGraphic)
1774             {
1775                 if (!pSetBrush)
1776                 {
1777                     const SvxBrushItem* pOrigBrush = aFormat.GetBrush();
1778                     if(pOrigBrush)
1779                         pSetBrush.reset(new SvxBrushItem(*pOrigBrush));
1780                     else
1781                         pSetBrush.reset(new SvxBrushItem(OUString(), OUString(), GPOS_AREA, RES_BACKGROUND));
1782                 }
1783                 Graphic aGraphic(xGraphic);
1784                 pSetBrush->SetGraphic(aGraphic);
1785             }
1786             else
1787                 bWrongArg = true;
1788         }
1789         else if (rProp.Name == UNO_NAME_GRAPHIC_BITMAP)
1790         {
1791             uno::Reference<awt::XBitmap> xBitmap;
1792             if (rProp.Value >>= xBitmap)
1793             {
1794                 if(!pSetBrush)
1795                 {
1796                     const SvxBrushItem* pOrigBrush = aFormat.GetBrush();
1797                     if(pOrigBrush)
1798                         pSetBrush.reset(new SvxBrushItem(*pOrigBrush));
1799                     else
1800                         pSetBrush.reset(new SvxBrushItem(OUString(), OUString(), GPOS_AREA, RES_BACKGROUND));
1801                 }
1802 
1803                 uno::Reference<graphic::XGraphic> xGraphic(xBitmap, uno::UNO_QUERY);
1804                 Graphic aGraphic(xGraphic);
1805                 pSetBrush->SetGraphic(aGraphic);
1806             }
1807             else
1808                 bWrongArg = true;
1809         }
1810         else if (rProp.Name == UNO_NAME_GRAPHIC_SIZE)
1811         {
1812             if(!pSetSize)
1813                 pSetSize.reset(new Size);
1814             awt::Size size;
1815             if (rProp.Value >>= size)
1816             {
1817                 pSetSize->setWidth(o3tl::toTwips(size.Width, o3tl::Length::mm100));
1818                 pSetSize->setHeight(o3tl::toTwips(size.Height, o3tl::Length::mm100));
1819             }
1820             else
1821                 bWrongArg = true;
1822         }
1823         else if (rProp.Name == UNO_NAME_VERT_ORIENT)
1824         {
1825             if(!pSetVOrient)
1826             {
1827                 if(aFormat.GetGraphicOrientation())
1828                     pSetVOrient.reset(aFormat.GetGraphicOrientation()->Clone());
1829                 else
1830                     pSetVOrient.reset(new SwFormatVertOrient);
1831             }
1832             pSetVOrient->PutValue(rProp.Value, MID_VERTORIENT_ORIENT);
1833         }
1834         else if (rProp.Name == UNO_NAME_HEADING_STYLE_NAME
1835                 && pDocShell) // only on chapter numbering
1836         {
1837             if (pHeadingStyleName)
1838             {
1839                 OUString uTmp;
1840                 rProp.Value >>= uTmp;
1841                 OUString sStyleName;
1842                 SwStyleNameMapper::FillUIName(uTmp, sStyleName, SwGetPoolIdFromName::TxtColl );
1843                 *pHeadingStyleName = sStyleName;
1844             }
1845         }
1846         else if (rProp.Name == UNO_NAME_BULLET_REL_SIZE)
1847         {
1848             // BulletRelSize - unsupported - only available in Impress
1849         }
1850         else if (rProp.Name == UNO_NAME_BULLET_COLOR)
1851         {
1852             // BulletColor - ignored too
1853         }
1854         else if (rProp.Name == UNO_NAME_GRAPHIC_URL)
1855         {
1856             OUString aURL;
1857             if (rProp.Value >>= aURL)
1858             {
1859                 if(!pSetBrush)
1860                 {
1861                     const SvxBrushItem* pOrigBrush = aFormat.GetBrush();
1862                     if(pOrigBrush)
1863                         pSetBrush.reset(new SvxBrushItem(*pOrigBrush));
1864                     else
1865                         pSetBrush.reset(new SvxBrushItem(OUString(), OUString(), GPOS_AREA, RES_BACKGROUND));
1866                 }
1867 
1868                 Graphic aGraphic = vcl::graphic::loadFromURL(aURL);
1869                 if (!aGraphic.IsNone())
1870                     pSetBrush->SetGraphic(aGraphic);
1871             }
1872             else
1873                 bWrongArg = true;
1874         }
1875         else if (rProp.Name == UNO_NAME_LIST_FORMAT)
1876         {
1877             OUString uTmp;
1878             rProp.Value >>= uTmp;
1879             aFormat.SetListFormat(uTmp);
1880         }
1881         else if (rProp.Name == UNO_NAME_LEVEL_IS_LEGAL)
1882         {
1883             if (bool bVal; rProp.Value >>= bVal)
1884                 aFormat.SetIsLegal(bVal);
1885         }
1886         else
1887         {
1888             // Invalid property name
1889             throw beans::UnknownPropertyException("Unknown property " + rProp.Name);
1890         }
1891     }
1892     if(!bWrongArg && (pSetBrush || pSetSize || pSetVOrient))
1893     {
1894         if(!pSetBrush && aFormat.GetBrush())
1895             pSetBrush.reset(new SvxBrushItem(*aFormat.GetBrush()));
1896 
1897         if(pSetBrush)
1898         {
1899             if(!pSetVOrient && aFormat.GetGraphicOrientation())
1900                 pSetVOrient.reset( new SwFormatVertOrient(*aFormat.GetGraphicOrientation()) );
1901 
1902             if(!pSetSize)
1903             {
1904                 pSetSize.reset(new Size(aFormat.GetGraphicSize()));
1905                 if(!pSetSize->Width() || !pSetSize->Height())
1906                 {
1907                     const Graphic* pGraphic = pSetBrush->GetGraphic();
1908                     if(pGraphic)
1909                         *pSetSize = ::GetGraphicSizeTwip(*pGraphic, nullptr);
1910                 }
1911             }
1912             sal_Int16 eOrient = pSetVOrient ?
1913                 pSetVOrient->GetVertOrient() : text::VertOrientation::NONE;
1914             aFormat.SetGraphicBrush( pSetBrush.get(), pSetSize.get(), text::VertOrientation::NONE == eOrient ? nullptr : &eOrient );
1915         }
1916     }
1917     if ((!bCharStyleNameSet || rCharStyleName.isEmpty())
1918         && aFormat.GetNumberingType() == NumberingType::BITMAP
1919         && !aFormat.GetCharFormat()
1920         && !SwXNumberingRules::isInvalidStyle(rCharStyleName))
1921     {
1922         OUString tmp;
1923         SwStyleNameMapper::FillProgName(RES_POOLCHR_BULLET_LEVEL, tmp);
1924         rCharStyleName = tmp;
1925     }
1926 
1927     if(bWrongArg)
1928         throw lang::IllegalArgumentException();
1929 }
1930 
getPropertySetInfo()1931 uno::Reference< XPropertySetInfo > SwXNumberingRules::getPropertySetInfo()
1932 {
1933     static uno::Reference< beans::XPropertySetInfo >  aRef = m_pPropertySet->getPropertySetInfo();
1934     return aRef;
1935 }
1936 
setPropertyValue(const OUString & rPropertyName,const Any & rValue)1937 void SwXNumberingRules::setPropertyValue( const OUString& rPropertyName, const Any& rValue )
1938 {
1939     SolarMutexGuard aGuard;
1940     std::unique_ptr<SwNumRule> pDocRule;
1941     SwNumRule* pCreatedRule = nullptr;
1942     if(!m_pNumRule)
1943     {
1944         if(m_pDocShell)
1945         {
1946             pDocRule.reset(new SwNumRule(*m_pDocShell->GetDoc()->GetOutlineNumRule()));
1947         }
1948         else if(m_pDoc && !m_sCreatedNumRuleName.isEmpty())
1949         {
1950             pCreatedRule = m_pDoc->FindNumRulePtr(m_sCreatedNumRuleName);
1951         }
1952 
1953     }
1954     if(!m_pNumRule && !pDocRule && !pCreatedRule)
1955         throw RuntimeException();
1956 
1957     if(rPropertyName == UNO_NAME_IS_AUTOMATIC)
1958     {
1959         bool bVal = *o3tl::doAccess<bool>(rValue);
1960         if(!pCreatedRule)
1961             pDocRule ? pDocRule->SetAutoRule(bVal) : m_pNumRule->SetAutoRule(bVal);
1962     }
1963     else if(rPropertyName == UNO_NAME_IS_CONTINUOUS_NUMBERING)
1964     {
1965         bool bVal = *o3tl::doAccess<bool>(rValue);
1966         pDocRule ? pDocRule->SetContinusNum(bVal) :
1967             pCreatedRule ? pCreatedRule->SetContinusNum(bVal) : m_pNumRule->SetContinusNum(bVal);
1968     }
1969     else if(rPropertyName == UNO_NAME_NAME)
1970     {
1971         throw IllegalArgumentException();
1972     }
1973     else if(rPropertyName == UNO_NAME_IS_ABSOLUTE_MARGINS)
1974     {
1975         bool bVal = *o3tl::doAccess<bool>(rValue);
1976         pDocRule ? pDocRule->SetAbsSpaces(bVal) :
1977             pCreatedRule ? pCreatedRule->SetAbsSpaces(bVal) : m_pNumRule->SetAbsSpaces(bVal);
1978     }
1979     else if(rPropertyName == UNO_NAME_NUMBERING_IS_OUTLINE)
1980     {
1981         bool bVal = *o3tl::doAccess<bool>(rValue);
1982         SwNumRuleType eNumRuleType = bVal ? OUTLINE_RULE : NUM_RULE;
1983         pDocRule ? pDocRule->SetRuleType(eNumRuleType) :
1984             pCreatedRule ? pCreatedRule->SetRuleType(eNumRuleType) : m_pNumRule->SetRuleType(eNumRuleType);
1985     }
1986     else if(rPropertyName == UNO_NAME_DEFAULT_LIST_ID)
1987     {
1988         throw IllegalArgumentException();
1989     }
1990     else
1991         throw UnknownPropertyException(rPropertyName);
1992 
1993     if(pDocRule)
1994     {
1995         assert(m_pDocShell);
1996         m_pDocShell->GetDoc()->SetOutlineNumRule(*pDocRule);
1997         pDocRule.reset();
1998     }
1999     else if(pCreatedRule)
2000     {
2001         pCreatedRule->Validate(*m_pDoc);
2002     }
2003 }
2004 
getPropertyValue(const OUString & rPropertyName)2005 Any SwXNumberingRules::getPropertyValue( const OUString& rPropertyName )
2006 {
2007     Any aRet;
2008     const SwNumRule* pRule = m_pNumRule;
2009     if(!pRule && m_pDocShell)
2010         pRule = m_pDocShell->GetDoc()->GetOutlineNumRule();
2011     else if(m_pDoc && !m_sCreatedNumRuleName.isEmpty())
2012         pRule = m_pDoc->FindNumRulePtr( m_sCreatedNumRuleName );
2013     if(!pRule)
2014         throw RuntimeException();
2015 
2016     if(rPropertyName == UNO_NAME_IS_AUTOMATIC)
2017     {
2018         aRet <<= pRule->IsAutoRule();
2019     }
2020     else if(rPropertyName == UNO_NAME_IS_CONTINUOUS_NUMBERING)
2021     {
2022         aRet <<= pRule->IsContinusNum();
2023     }
2024     else if(rPropertyName == UNO_NAME_NAME)
2025         aRet <<= pRule->GetName();
2026     else if(rPropertyName == UNO_NAME_IS_ABSOLUTE_MARGINS)
2027     {
2028         aRet <<= pRule->IsAbsSpaces();
2029     }
2030     else if(rPropertyName == UNO_NAME_NUMBERING_IS_OUTLINE)
2031     {
2032         aRet <<= pRule->IsOutlineRule();
2033     }
2034     else if(rPropertyName == UNO_NAME_DEFAULT_LIST_ID)
2035     {
2036         OSL_ENSURE( !pRule->GetDefaultListId().isEmpty(),
2037                 "<SwXNumberingRules::getPropertyValue(..)> - no default list id found. Serious defect." );
2038         aRet <<= pRule->GetDefaultListId();
2039     }
2040     else
2041         throw UnknownPropertyException(rPropertyName);
2042     return aRet;
2043 }
2044 
addPropertyChangeListener(const OUString &,const uno::Reference<XPropertyChangeListener> &)2045 void SwXNumberingRules::addPropertyChangeListener(
2046     const OUString& /*rPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
2047 {
2048 }
2049 
removePropertyChangeListener(const OUString &,const uno::Reference<XPropertyChangeListener> &)2050 void SwXNumberingRules::removePropertyChangeListener(
2051     const OUString& /*rPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
2052 {
2053 }
2054 
addVetoableChangeListener(const OUString &,const uno::Reference<XVetoableChangeListener> &)2055 void SwXNumberingRules::addVetoableChangeListener(
2056     const OUString& /*rPropertyName*/, const uno::Reference< XVetoableChangeListener >& /*xListener*/ )
2057 {
2058 }
2059 
removeVetoableChangeListener(const OUString &,const uno::Reference<XVetoableChangeListener> &)2060 void SwXNumberingRules::removeVetoableChangeListener(
2061     const OUString& /*rPropertyName*/, const uno::Reference< XVetoableChangeListener >& /*xListener*/ )
2062 {
2063 }
2064 
getName()2065 OUString SwXNumberingRules::getName()
2066 {
2067     if(m_pNumRule)
2068     {
2069         OUString aString;
2070         SwStyleNameMapper::FillProgName(m_pNumRule->GetName(), aString, SwGetPoolIdFromName::NumRule );
2071         return aString;
2072     }
2073     // consider chapter numbering <SwXNumberingRules>
2074     if ( m_pDocShell )
2075     {
2076         OUString aString;
2077         SwStyleNameMapper::FillProgName( m_pDocShell->GetDoc()->GetOutlineNumRule()->GetName(),
2078                                          aString, SwGetPoolIdFromName::NumRule );
2079         return aString;
2080     }
2081     return m_sCreatedNumRuleName;
2082 }
2083 
setName(const OUString &)2084 void SwXNumberingRules::setName(const OUString& /*rName*/)
2085 {
2086     throw RuntimeException(u"readonly"_ustr);
2087 }
2088 
Notify(const SfxHint & rHint)2089 void SwXNumberingRules::Impl::Notify(const SfxHint& rHint)
2090 {
2091     if(rHint.GetId() == SfxHintId::Dying)
2092     {
2093         if(m_rParent.m_bOwnNumRuleCreated)
2094             delete m_rParent.m_pNumRule;
2095         m_rParent.m_pNumRule = nullptr;
2096         m_rParent.m_pDoc = nullptr;
2097     }
2098 }
2099 
getImplementationName()2100 OUString SwXChapterNumbering::getImplementationName()
2101 {
2102     return u"SwXChapterNumbering"_ustr;
2103 }
2104 
supportsService(const OUString & rServiceName)2105 sal_Bool SwXChapterNumbering::supportsService(const OUString& rServiceName)
2106 {
2107     return cppu::supportsService(this, rServiceName);
2108 }
2109 
getSupportedServiceNames()2110 Sequence< OUString > SwXChapterNumbering::getSupportedServiceNames()
2111 {
2112     return { u"com.sun.star.text.ChapterNumbering"_ustr, u"com.sun.star.text.NumberingRules"_ustr };
2113 }
2114 
SwXChapterNumbering(SwDocShell & rDocSh)2115 SwXChapterNumbering::SwXChapterNumbering(SwDocShell& rDocSh) :
2116     SwXNumberingRules(rDocSh)
2117 {
2118 }
2119 
~SwXChapterNumbering()2120 SwXChapterNumbering::~SwXChapterNumbering()
2121 {
2122 }
2123 
2124 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2125