1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include <svx/nbdtmg.hxx>
20 #include <svx/svxids.hrc>
21 #include <vcl/svapp.hxx>
22 #include <svl/itemset.hxx>
23 #include <sfx2/request.hxx>
24 #include <svl/stritem.hxx>
25 #include <svtools/ctrltool.hxx>
26 #include <sfx2/objsh.hxx>
27 #include <editeng/flstitem.hxx>
28 #include <svl/itempool.hxx>
29 #include <vcl/outdev.hxx>
30 #include <editeng/brushitem.hxx>
31 #include <svx/dialmgr.hxx>
32 #include <svx/strings.hrc>
33 #include <vcl/graph.hxx>
34 #include <vcl/settings.hxx>
36 #include <i18nlangtag/languagetag.hxx>
37 #include <o3tl/temporary.hxx>
38 #include <tools/debug.hxx>
39 #include <tools/urlobj.hxx>
40 #include <unotools/ucbstreamhelper.hxx>
41 #include <unotools/pathoptions.hxx>
42 #include <editeng/eeitem.hxx>
44 #include <com/sun/star/text/VertOrientation.hpp>
45 #include <com/sun/star/style/NumberingType.hpp>
46 #include <com/sun/star/container/XIndexAccess.hpp>
47 #include <com/sun/star/text/DefaultNumberingProvider.hpp>
48 #include <com/sun/star/beans/PropertyValue.hpp>
49 #include <comphelper/processfactory.hxx>
52 using namespace com::sun::star
;
53 using namespace com::sun::star::uno
;
54 using namespace com::sun::star::beans
;
55 using namespace com::sun::star::lang
;
56 using namespace com::sun::star::text
;
57 using namespace com::sun::star::container
;
58 using namespace com::sun::star::style
;
60 namespace svx::sidebar
{
64 const vcl::Font
& lcl_GetDefaultBulletFont()
66 static vcl::Font aDefBulletFont
= []()
68 static vcl::Font
tmp("OpenSymbol", "", Size(0, 14));
69 tmp
.SetCharSet( RTL_TEXTENCODING_SYMBOL
);
70 tmp
.SetFamily( FAMILY_DONTKNOW
);
71 tmp
.SetPitch( PITCH_DONTKNOW
);
72 tmp
.SetWeight( WEIGHT_DONTKNOW
);
73 tmp
.SetTransparent( true );
76 return aDefBulletFont
;
79 const sal_Unicode aDefaultBulletTypes
[] =
91 NumSettings_Impl
* lcl_CreateNumberingSettingsPtr(const Sequence
<PropertyValue
>& rLevelProps
)
93 NumSettings_Impl
* pNew
= new NumSettings_Impl
;
94 for(const PropertyValue
& rValue
: rLevelProps
)
96 if(rValue
.Name
== "NumberingType")
99 if (rValue
.Value
>>= nTmp
)
100 pNew
->nNumberType
= static_cast<SvxNumType
>(nTmp
);
102 else if(rValue
.Name
== "Prefix")
103 rValue
.Value
>>= pNew
->sPrefix
;
104 else if(rValue
.Name
== "Suffix")
105 rValue
.Value
>>= pNew
->sSuffix
;
106 else if (rValue
.Name
== "Adjust")
109 if (rValue
.Value
>>= nTmp
)
110 pNew
->eNumAlign
= static_cast<SvxAdjust
>(nTmp
);
112 else if(rValue
.Name
== "ParentNumbering")
113 rValue
.Value
>>= pNew
->nParentNumbering
;
114 else if(rValue
.Name
== "BulletChar")
115 rValue
.Value
>>= pNew
->sBulletChar
;
116 else if(rValue
.Name
== "BulletFontName")
117 rValue
.Value
>>= pNew
->sBulletFont
;
119 const sal_Unicode cLocalPrefix
= pNew
->sPrefix
.getLength() ? pNew
->sPrefix
[0] : 0;
120 const sal_Unicode cLocalSuffix
= pNew
->sSuffix
.getLength() ? pNew
->sSuffix
[0] : 0;
121 if( cLocalPrefix
== ' ') pNew
->sPrefix
.clear();
122 if( cLocalSuffix
== ' ') pNew
->sSuffix
.clear();
128 sal_uInt16
NBOTypeMgrBase:: IsSingleLevel(sal_uInt16 nCurLevel
)
130 sal_uInt16 nLv
= sal_uInt16(0xFFFF);
131 sal_uInt16 nCount
= 0;
132 sal_uInt16 nMask
= 1;
133 for( sal_uInt16 i
= 0; i
< SVX_MAX_NUM
; i
++ )
135 if(nCurLevel
& nMask
)
146 return sal_uInt16(0xFFFF);
149 void NBOTypeMgrBase::SetItems(const SfxItemSet
* pArg
) {
154 SfxAllItemSet
aSet(*pSet
);
156 const SfxStringItem
* pBulletCharFmt
= aSet
.GetItem
<SfxStringItem
>(SID_BULLET_CHAR_FMT
, false);
158 aBulletCharFmtName
= pBulletCharFmt
->GetValue();
160 const SfxStringItem
* pNumCharFmt
= aSet
.GetItem
<SfxStringItem
>(SID_NUM_CHAR_FMT
, false);
162 aNumCharFmtName
= pNumCharFmt
->GetValue();
164 const SfxPoolItem
* pItem
;
165 SfxItemState eState
= pSet
->GetItemState(SID_ATTR_NUMBERING_RULE
, false, &pItem
);
166 if(eState
== SfxItemState::SET
)
168 eCoreUnit
= pSet
->GetPool()->GetMetric(pSet
->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE
));
170 //sd use different sid for numbering rule
171 eState
= pSet
->GetItemState(EE_PARA_NUMBULLET
, false, &pItem
);
172 if(eState
== SfxItemState::SET
)
174 eCoreUnit
= pSet
->GetPool()->GetMetric(pSet
->GetPool()->GetWhich(EE_PARA_NUMBULLET
));
179 void NBOTypeMgrBase::ImplLoad(std::u16string_view filename
)
182 MapUnit eOldCoreUnit
=eCoreUnit
;
183 eCoreUnit
= MapUnit::Map100thMM
;
184 INetURLObject
aFile( SvtPathOptions().GetUserConfigPath() );
185 aFile
.Append( filename
);
186 std::unique_ptr
<SvStream
> xIStm(::utl::UcbStreamHelper::CreateStream( aFile
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), StreamMode::READ
));
188 sal_uInt32 nVersion
= 0;
189 sal_Int32 nNumIndex
= 0;
190 xIStm
->ReadUInt32( nVersion
);
191 if (nVersion
==DEFAULT_NUMBERING_CACHE_FORMAT_VERSION
) //first version
193 xIStm
->ReadInt32( nNumIndex
);
194 while (nNumIndex
>=0 && nNumIndex
<DEFAULT_NUM_VALUSET_COUNT
) {
195 SvxNumRule
aNum(*xIStm
);
196 //bullet color in font properties is not stored correctly. Need set transparency bits manually
197 for(sal_uInt16 i
= 0; i
< aNum
.GetLevelCount(); i
++)
199 SvxNumberFormat
aFmt(aNum
.GetLevel(i
));
200 if (aFmt
.GetBulletFont()) {
201 vcl::Font
aFont(*aFmt
.GetBulletFont());
202 Color c
=aFont
.GetColor();
205 aFmt
.SetBulletFont(&aFont
);
206 aNum
.SetLevel(i
, aFmt
);
209 ReplaceNumRule(aNum
,nNumIndex
,0x1/*nLevel*/);
210 xIStm
->ReadInt32( nNumIndex
);
214 eCoreUnit
= eOldCoreUnit
;
217 void NBOTypeMgrBase::ImplStore(std::u16string_view filename
)
219 if (bIsLoading
) return;
220 MapUnit eOldCoreUnit
=eCoreUnit
;
221 eCoreUnit
= MapUnit::Map100thMM
;
222 INetURLObject
aFile( SvtPathOptions().GetUserConfigPath() );
223 aFile
.Append( filename
);
224 std::unique_ptr
<SvStream
> xOStm(::utl::UcbStreamHelper::CreateStream( aFile
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), StreamMode::WRITE
));
228 nVersion
= DEFAULT_NUMBERING_CACHE_FORMAT_VERSION
;
229 xOStm
->WriteUInt32( nVersion
);
230 for(sal_Int32 nItem
= 0; nItem
< DEFAULT_NUM_VALUSET_COUNT
; nItem
++ ) {
231 if (IsCustomized(nItem
)) {
232 SvxNumRule
aDefNumRule( SvxNumRuleFlags::BULLET_REL_SIZE
| SvxNumRuleFlags::CONTINUOUS
| SvxNumRuleFlags::BULLET_COLOR
,
234 SvxNumRuleType::NUMBERING
, SvxNumberFormat::LABEL_ALIGNMENT
);
235 xOStm
->WriteInt32( nItem
);
236 ApplyNumRule(aDefNumRule
,nItem
,0x1/*nLevel*/,false,true);
237 aDefNumRule
.Store(*xOStm
);
241 xOStm
->WriteInt32( nNumIndex
); //write end flag
243 eCoreUnit
= eOldCoreUnit
;
246 // Character Bullet Type lib
247 BulletsSettings
* BulletsTypeMgr::pActualBullets
[] ={nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr};
248 sal_Unicode
BulletsTypeMgr::aDynamicBulletTypes
[]={' ',' ',' ',' ',' ',' ',' ',' '};
249 sal_Unicode
BulletsTypeMgr::aDynamicRTLBulletTypes
[]={' ',' ',' ',' ',' ',' ',' ',' '};
251 BulletsTypeMgr::BulletsTypeMgr()
256 BulletsTypeMgr
& BulletsTypeMgr::GetInstance()
258 static BulletsTypeMgr theBulletsTypeMgr
;
259 return theBulletsTypeMgr
;
262 void BulletsTypeMgr::Init()
264 const vcl::Font
& rActBulletFont
= lcl_GetDefaultBulletFont();
266 for (sal_uInt16 i
=0;i
<DEFAULT_BULLET_TYPES
;i
++)
268 pActualBullets
[i
] = new BulletsSettings
;
269 pActualBullets
[i
]->cBulletChar
= aDefaultBulletTypes
[i
];
270 pActualBullets
[i
]->aFont
= rActBulletFont
;
271 OString id
= OString::Concat(RID_SVXSTR_BULLET_DESCRIPTION_0
.getId()) + OString::number(i
);
272 pActualBullets
[i
]->sDescription
= SvxResId( TranslateId(RID_SVXSTR_BULLET_DESCRIPTION_0
.mpContext
, id
.getStr()) );
275 sal_uInt16
BulletsTypeMgr::GetNBOIndexForNumRule(SvxNumRule
& aNum
,sal_uInt16 mLevel
,sal_uInt16 nFromIndex
)
277 if ( mLevel
== sal_uInt16(0xFFFF) || mLevel
== 0)
278 return sal_uInt16(0xFFFF);
279 //if ( !lcl_IsNumFmtSet(pNR, mLevel) ) return (sal_uInt16)0xFFFF;
281 sal_uInt16 nActLv
= IsSingleLevel(mLevel
);
283 if ( nActLv
== sal_uInt16(0xFFFF) )
284 return sal_uInt16(0xFFFF);
286 const SvxNumberFormat
& aFmt(aNum
.GetLevel(nActLv
));
287 sal_UCS4 cChar
= aFmt
.GetBulletChar();
288 for(sal_uInt16 i
= nFromIndex
; i
< DEFAULT_BULLET_TYPES
; i
++)
290 if ( (cChar
== pActualBullets
[i
]->cBulletChar
) ||
291 (cChar
== 9830 && 57356 == pActualBullets
[i
]->cBulletChar
) ||
292 (cChar
== 9632 && 57354 == pActualBullets
[i
]->cBulletChar
) )
298 return sal_uInt16(0xFFFF);
301 void BulletsTypeMgr::ReplaceNumRule(SvxNumRule
& aNum
, sal_uInt16 nIndex
, sal_uInt16 mLevel
)
303 if ( nIndex
>= DEFAULT_BULLET_TYPES
)
306 if ( mLevel
== sal_uInt16(0xFFFF) || mLevel
== 0)
309 if ( GetNBOIndexForNumRule(aNum
,mLevel
) != sal_uInt16(0xFFFF) )
312 sal_uInt16 nActLv
= IsSingleLevel(mLevel
);
314 if ( nActLv
== sal_uInt16(0xFFFF) )
317 SvxNumberFormat
aFmt(aNum
.GetLevel(nActLv
));
318 sal_UCS4 cChar
= aFmt
.GetBulletChar();
319 std::optional
<vcl::Font
> pFont
= aFmt
.GetBulletFont();
321 pActualBullets
[nIndex
]->cBulletChar
= cChar
;
323 pActualBullets
[nIndex
]->aFont
= *pFont
;
324 pActualBullets
[nIndex
]->bIsCustomized
= true;
327 void BulletsTypeMgr::ApplyNumRule(SvxNumRule
& aNum
, sal_uInt16 nIndex
, sal_uInt16 mLevel
, bool /*isDefault*/, bool isResetSize
)
329 if ( nIndex
>= DEFAULT_BULLET_TYPES
)
331 sal_UCS4 cChar
= pActualBullets
[nIndex
]->cBulletChar
;
332 const vcl::Font
& rActBulletFont
= pActualBullets
[nIndex
]->aFont
;
334 sal_uInt16 nMask
= 1;
335 OUString sBulletCharFormatName
= GetBulletCharFmtName();
336 for(sal_uInt16 i
= 0; i
< aNum
.GetLevelCount(); i
++)
340 SvxNumberFormat
aFmt(aNum
.GetLevel(i
));
341 aFmt
.SetNumberingType( SVX_NUM_CHAR_SPECIAL
);
342 aFmt
.SetBulletFont(&rActBulletFont
);
343 aFmt
.SetBulletChar(cChar
);
344 aFmt
.SetCharFormatName(sBulletCharFormatName
);
345 aFmt
.SetListFormat( "" );
346 if (isResetSize
) aFmt
.SetBulletRelSize(45);
347 aNum
.SetLevel(i
, aFmt
);
353 OUString
BulletsTypeMgr::GetDescription(sal_uInt16 nIndex
, bool /*isDefault*/)
357 if ( nIndex
>= DEFAULT_BULLET_TYPES
)
360 sRet
= pActualBullets
[nIndex
]->sDescription
;
365 bool BulletsTypeMgr::IsCustomized(sal_uInt16 nIndex
)
369 if ( nIndex
>= DEFAULT_BULLET_TYPES
)
372 bRet
= pActualBullets
[nIndex
]->bIsCustomized
;
377 // Numbering Type lib
378 NumberingTypeMgr::NumberingTypeMgr()
381 maDefaultNumberSettingsArr
= maNumberSettingsArr
;
382 ImplLoad(u
"standard.syb");
385 NumberingTypeMgr::~NumberingTypeMgr()
389 const TranslateId RID_SVXSTR_SINGLENUM_DESCRIPTIONS
[] =
391 RID_SVXSTR_SINGLENUM_DESCRIPTION_0
,
392 RID_SVXSTR_SINGLENUM_DESCRIPTION_1
,
393 RID_SVXSTR_SINGLENUM_DESCRIPTION_2
,
394 RID_SVXSTR_SINGLENUM_DESCRIPTION_3
,
395 RID_SVXSTR_SINGLENUM_DESCRIPTION_4
,
396 RID_SVXSTR_SINGLENUM_DESCRIPTION_5
,
397 RID_SVXSTR_SINGLENUM_DESCRIPTION_6
,
398 RID_SVXSTR_SINGLENUM_DESCRIPTION_7
401 NumberingTypeMgr
& NumberingTypeMgr::GetInstance()
403 static NumberingTypeMgr theNumberingTypeMgr
;
404 return theNumberingTypeMgr
;
407 void NumberingTypeMgr::Init()
409 Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
410 Reference
<XDefaultNumberingProvider
> xDefNum
= DefaultNumberingProvider::create( xContext
);
412 Sequence
< Sequence
< PropertyValue
> > aNumberings
;
413 Locale
aLocale(Application::GetSettings().GetLanguageTag().getLocale());
416 aNumberings
= xDefNum
->getDefaultContinuousNumberingLevels( aLocale
);
418 sal_Int32 nLength
= aNumberings
.getLength();
420 const Sequence
<PropertyValue
>* pValuesArr
= aNumberings
.getConstArray();
421 for(sal_Int32 i
= 0; i
< nLength
; i
++)
423 NumSettings_Impl
* pNew
= lcl_CreateNumberingSettingsPtr(pValuesArr
[i
]);
424 std::shared_ptr
<NumberSettings_Impl
> pNumEntry
= std::make_shared
<NumberSettings_Impl
>();
425 pNumEntry
->pNumSetting
= pNew
;
427 pNumEntry
->sDescription
= SvxResId(RID_SVXSTR_SINGLENUM_DESCRIPTIONS
[i
]);
428 maNumberSettingsArr
.push_back(pNumEntry
);
436 sal_uInt16
NumberingTypeMgr::GetNBOIndexForNumRule(SvxNumRule
& aNum
,sal_uInt16 mLevel
,sal_uInt16 nFromIndex
)
438 if ( mLevel
== sal_uInt16(0xFFFF) || mLevel
> aNum
.GetLevelCount() || mLevel
== 0)
439 return sal_uInt16(0xFFFF);
441 sal_uInt16 nActLv
= IsSingleLevel(mLevel
);
443 if ( nActLv
== sal_uInt16(0xFFFF) )
444 return sal_uInt16(0xFFFF);
446 const SvxNumberFormat
& aFmt(aNum
.GetLevel(nActLv
));
447 //sal_Unicode cPrefix = OUString(aFmt.GetPrefix())[0];
448 //sal_Unicode cSuffix = :OUString(aFmt.GetSuffix())[0];
449 const OUString
& sPrefix
= aFmt
.GetPrefix();
450 const OUString
& sLclSuffix
= aFmt
.GetSuffix();
451 sal_Int16 eNumType
= aFmt
.GetNumberingType();
453 sal_uInt16 nCount
= maNumberSettingsArr
.size();
454 for(sal_uInt16 i
= nFromIndex
; i
< nCount
; ++i
)
456 NumberSettings_Impl
* _pSet
= maNumberSettingsArr
[i
].get();
457 sal_Int16 eNType
= _pSet
->pNumSetting
->nNumberType
;
458 OUString sLocalPrefix
= _pSet
->pNumSetting
->sPrefix
;
459 OUString sLocalSuffix
= _pSet
->pNumSetting
->sSuffix
;
460 if (sPrefix
== sLocalPrefix
&&
461 sLclSuffix
== sLocalSuffix
&&
469 return sal_uInt16(0xFFFF);
472 void NumberingTypeMgr::ReplaceNumRule(SvxNumRule
& aNum
, sal_uInt16 nIndex
, sal_uInt16 mLevel
)
474 sal_uInt16 nActLv
= IsSingleLevel(mLevel
);
476 if ( nActLv
== sal_uInt16(0xFFFF) )
479 const SvxNumberFormat
& aFmt(aNum
.GetLevel(nActLv
));
480 SvxNumType eNumType
= aFmt
.GetNumberingType();
482 sal_uInt16 nCount
= maNumberSettingsArr
.size();
483 if ( nIndex
>= nCount
)
486 NumberSettings_Impl
* _pSet
= maNumberSettingsArr
[nIndex
].get();
488 _pSet
->pNumSetting
->sPrefix
= aFmt
.GetPrefix();
489 _pSet
->pNumSetting
->sSuffix
= aFmt
.GetSuffix();
490 _pSet
->pNumSetting
->nNumberType
= eNumType
;
491 _pSet
->bIsCustomized
= true;
493 SvxNumRule
aTmpRule1(aNum
);
494 SvxNumRule
aTmpRule2(aNum
);
495 ApplyNumRule(aTmpRule1
,nIndex
,mLevel
,true);
496 ApplyNumRule(aTmpRule2
,nIndex
,mLevel
);
497 if (aTmpRule1
==aTmpRule2
) _pSet
->bIsCustomized
=false;
498 if (!_pSet
->bIsCustomized
) {
499 _pSet
->sDescription
= GetDescription(nIndex
,true);
501 ImplStore(u
"standard.syb");
504 void NumberingTypeMgr::ApplyNumRule(SvxNumRule
& aNum
, sal_uInt16 nIndex
, sal_uInt16 mLevel
, bool isDefault
, bool isResetSize
)
506 if(maNumberSettingsArr
.size() <= nIndex
)
508 NumberSettingsArr_Impl
* pCurrentNumberSettingsArr
= &maNumberSettingsArr
;
509 if (isDefault
) pCurrentNumberSettingsArr
= &maDefaultNumberSettingsArr
;
510 NumberSettings_Impl
* _pSet
= (*pCurrentNumberSettingsArr
)[nIndex
].get();
511 SvxNumType eNewType
= _pSet
->pNumSetting
->nNumberType
;
513 sal_uInt16 nMask
= 1;
514 OUString sNumCharFmtName
= GetNumCharFmtName();
515 for(sal_uInt16 i
= 0; i
< aNum
.GetLevelCount(); i
++)
519 SvxNumberFormat
aFmt(aNum
.GetLevel(i
));
520 if (eNewType
!=aFmt
.GetNumberingType()) isResetSize
=true;
521 aFmt
.SetNumberingType(eNewType
);
522 aFmt
.SetListFormat(_pSet
->pNumSetting
->sPrefix
, _pSet
->pNumSetting
->sSuffix
, i
);
523 aFmt
.SetCharFormatName(sNumCharFmtName
);
524 if (isResetSize
) aFmt
.SetBulletRelSize(100);
525 aNum
.SetLevel(i
, aFmt
);
531 OUString
NumberingTypeMgr::GetDescription(sal_uInt16 nIndex
, bool isDefault
)
534 sal_uInt16 nLength
= maNumberSettingsArr
.size();
536 if ( nIndex
>= nLength
)
539 sRet
= maNumberSettingsArr
[nIndex
]->sDescription
;
540 if (isDefault
) sRet
= maDefaultNumberSettingsArr
[nIndex
]->sDescription
;
545 bool NumberingTypeMgr::IsCustomized(sal_uInt16 nIndex
)
548 sal_uInt16 nLength
= maNumberSettingsArr
.size();
550 if ( nIndex
>= nLength
)
553 bRet
= maNumberSettingsArr
[nIndex
]->bIsCustomized
;
557 // Multi-level /Outline Type lib
558 OutlineTypeMgr::OutlineTypeMgr()
561 for(sal_Int32 nItem
= 0; nItem
< DEFAULT_NUM_VALUSET_COUNT
; nItem
++ )
563 pDefaultOutlineSettingsArrs
[nItem
] = pOutlineSettingsArrs
[nItem
];
565 //Initial the first time to store the default value. Then do it again for customized value
567 ImplLoad(u
"standard.syc");
570 OutlineTypeMgr
& OutlineTypeMgr::GetInstance()
572 static OutlineTypeMgr theOutlineTypeMgr
;
573 return theOutlineTypeMgr
;
576 void OutlineTypeMgr::Init()
578 Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
579 Reference
<XDefaultNumberingProvider
> xDefNum
= DefaultNumberingProvider::create( xContext
);
581 Sequence
<Reference
<XIndexAccess
> > aOutlineAccess
;
582 Locale
aLocale(Application::GetSettings().GetLanguageTag().getLocale());
585 aOutlineAccess
= xDefNum
->getDefaultOutlineNumberings( aLocale
);
587 SvxNumRule
aDefNumRule( SvxNumRuleFlags::BULLET_REL_SIZE
| SvxNumRuleFlags::CONTINUOUS
| SvxNumRuleFlags::BULLET_COLOR
,
589 SvxNumRuleType::NUMBERING
, SvxNumberFormat::LABEL_ALIGNMENT
);
591 auto nSize
= std::min
<sal_Int32
>(aOutlineAccess
.getLength(), DEFAULT_NUM_VALUSET_COUNT
);
592 for(sal_Int32 nItem
= 0; nItem
< nSize
; nItem
++ )
594 pOutlineSettingsArrs
[ nItem
] = new OutlineSettings_Impl
;
595 OutlineSettings_Impl
* pItemArr
= pOutlineSettingsArrs
[ nItem
];
596 OString id
= OString::Concat(RID_SVXSTR_OUTLINENUM_DESCRIPTION_0
.getId()) + OString::number(nItem
);
597 pItemArr
->sDescription
= SvxResId( TranslateId(RID_SVXSTR_OUTLINENUM_DESCRIPTION_0
.mpContext
, id
.getStr()) );
598 pItemArr
->pNumSettingsArr
= new NumSettingsArr_Impl
;
599 Reference
<XIndexAccess
> xLevel
= aOutlineAccess
.getConstArray()[nItem
];
600 for(sal_Int32 nLevel
= 0; nLevel
< SVX_MAX_NUM
; nLevel
++)
602 // use the last locale-defined level for all remaining levels.
603 sal_Int32 nLocaleLevel
= std::min(nLevel
, xLevel
->getCount() - 1);
604 Sequence
<PropertyValue
> aLevelProps
;
605 if (nLocaleLevel
>= 0)
606 xLevel
->getByIndex(nLocaleLevel
) >>= aLevelProps
;
608 NumSettings_Impl
* pNew
= lcl_CreateNumberingSettingsPtr(aLevelProps
);
609 const SvxNumberFormat
& aNumFmt( aDefNumRule
.GetLevel( nLevel
) );
610 assert(aNumFmt
.GetNumAdjust() == SvxAdjust::Left
&& "new entry was previously defined by default, now defaults to Left");
611 pNew
->eLabelFollowedBy
= aNumFmt
.GetLabelFollowedBy();
612 pNew
->nTabValue
= aNumFmt
.GetListtabPos();
613 if (pNew
->eNumAlign
== SvxAdjust::Right
)
614 pNew
->nNumAlignAt
= -174; // number borrowed from RES_POOLNUMRULE_NUM4
616 pNew
->nNumAlignAt
= aNumFmt
.GetFirstLineIndent();
617 pNew
->nNumIndentAt
= aNumFmt
.GetIndentAt();
618 pItemArr
->pNumSettingsArr
->push_back(std::shared_ptr
<NumSettings_Impl
>(pNew
));
627 sal_uInt16
OutlineTypeMgr::GetNBOIndexForNumRule(SvxNumRule
& aNum
,sal_uInt16
/*mLevel*/,sal_uInt16 nFromIndex
)
629 sal_uInt16
const nLength
= SAL_N_ELEMENTS(pOutlineSettingsArrs
);
630 for(sal_uInt16 iDex
= nFromIndex
; iDex
< nLength
; iDex
++)
632 bool bNotMatch
= false;
633 OutlineSettings_Impl
* pItemArr
= pOutlineSettingsArrs
[iDex
];
634 sal_uInt16 nCount
= pItemArr
? pItemArr
->pNumSettingsArr
->size() : 0;
635 for (sal_uInt16 iLevel
=0;iLevel
< nCount
;iLevel
++)
637 NumSettings_Impl
* _pSet
= (*pItemArr
->pNumSettingsArr
)[iLevel
].get();
638 sal_Int16 eNType
= _pSet
->nNumberType
;
640 const SvxNumberFormat
& aFmt(aNum
.GetLevel(iLevel
));
641 const OUString
& sPrefix
= aFmt
.GetPrefix();
642 const OUString
& sLclSuffix
= aFmt
.GetSuffix();
643 sal_Int16 eNumType
= aFmt
.GetNumberingType();
644 if( eNumType
== SVX_NUM_CHAR_SPECIAL
)
646 sal_UCS4 cChar
= aFmt
.GetBulletChar();
649 = _pSet
->sBulletChar
.isEmpty()
651 : _pSet
->sBulletChar
.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
653 if ( !((cChar
== ccChar
) &&
654 _pSet
->eLabelFollowedBy
== aFmt
.GetLabelFollowedBy() &&
655 _pSet
->nTabValue
== aFmt
.GetListtabPos() &&
656 _pSet
->eNumAlign
== aFmt
.GetNumAdjust() &&
657 _pSet
->nNumAlignAt
== aFmt
.GetFirstLineIndent() &&
658 _pSet
->nNumIndentAt
== aFmt
.GetIndentAt()))
664 else if ((eNumType
&(~LINK_TOKEN
)) == SVX_NUM_BITMAP
)
666 const SvxBrushItem
* pBrsh1
= aFmt
.GetBrush();
667 const SvxBrushItem
* pBrsh2
= _pSet
->pBrushItem
;
668 bool bIsMatch
= false;
669 if (SfxPoolItem::areSame(pBrsh1
,pBrsh2
)) bIsMatch
= true;
670 if (pBrsh1
&& pBrsh2
) {
671 const Graphic
* pGrf1
= pBrsh1
->GetGraphic();
672 const Graphic
* pGrf2
= pBrsh2
->GetGraphic();
673 if (pGrf1
==pGrf2
) bIsMatch
= true;
674 if (pGrf1
&& pGrf2
) {
675 if ( pGrf1
->GetBitmapEx() == pGrf2
->GetBitmapEx() &&
676 _pSet
->aSize
== aFmt
.GetGraphicSize())
687 if (!(sPrefix
== _pSet
->sPrefix
&&
688 sLclSuffix
== _pSet
->sSuffix
&&
689 eNumType
== eNType
&&
690 _pSet
->eLabelFollowedBy
== aFmt
.GetLabelFollowedBy() &&
691 _pSet
->nTabValue
== aFmt
.GetListtabPos() &&
692 _pSet
->eNumAlign
== aFmt
.GetNumAdjust() &&
693 _pSet
->nNumAlignAt
== aFmt
.GetFirstLineIndent() &&
694 _pSet
->nNumIndentAt
== aFmt
.GetIndentAt()))
706 return sal_uInt16(0xFFFF);
709 void OutlineTypeMgr::ReplaceNumRule(SvxNumRule
& aNum
, sal_uInt16 nIndex
, sal_uInt16 mLevel
)
711 sal_uInt16
const nLength
= SAL_N_ELEMENTS(pOutlineSettingsArrs
);
712 if ( nIndex
>= nLength
)
715 OutlineSettings_Impl
* pItemArr
= pOutlineSettingsArrs
[nIndex
];
716 sal_uInt16 nCount
= pItemArr
->pNumSettingsArr
->size();
717 for (sal_uInt16 iLevel
=0;iLevel
< nCount
;iLevel
++)
719 const SvxNumberFormat
& aFmt(aNum
.GetLevel(iLevel
));
720 SvxNumType eNumType
= aFmt
.GetNumberingType();
722 NumSettings_Impl
* _pSet
= (*pItemArr
->pNumSettingsArr
)[iLevel
].get();
724 _pSet
->eLabelFollowedBy
= aFmt
.GetLabelFollowedBy();
725 _pSet
->nTabValue
= aFmt
.GetListtabPos();
726 _pSet
->eNumAlign
= aFmt
.GetNumAdjust();
727 _pSet
->nNumAlignAt
= aFmt
.GetFirstLineIndent();
728 _pSet
->nNumIndentAt
= aFmt
.GetIndentAt();
730 if( eNumType
== SVX_NUM_CHAR_SPECIAL
)
732 sal_UCS4 cChar
= aFmt
.GetBulletChar();
733 OUString
sChar(&cChar
, 1);
734 _pSet
->sBulletChar
= sChar
;
735 if ( aFmt
.GetBulletFont() )
736 _pSet
->sBulletFont
= aFmt
.GetBulletFont()->GetFamilyName();
737 _pSet
->nNumberType
= eNumType
;
738 pItemArr
->bIsCustomized
= true;
739 }else if ((eNumType
&(~LINK_TOKEN
)) == SVX_NUM_BITMAP
) {
740 if (_pSet
->pBrushItem
) {
741 delete _pSet
->pBrushItem
;
742 _pSet
->pBrushItem
=nullptr;
745 _pSet
->pBrushItem
= new SvxBrushItem(*aFmt
.GetBrush());
746 _pSet
->aSize
= aFmt
.GetGraphicSize();
747 _pSet
->nNumberType
= eNumType
;
750 _pSet
->sPrefix
= aFmt
.GetPrefix();
751 _pSet
->sSuffix
= aFmt
.GetSuffix();
752 _pSet
->nNumberType
= eNumType
;
753 if ( aFmt
.GetBulletFont() )
754 _pSet
->sBulletFont
= aFmt
.GetBulletFont()->GetFamilyName();
755 pItemArr
->bIsCustomized
= true;
758 SvxNumRule
aTmpRule1(aNum
);
759 SvxNumRule
aTmpRule2(aNum
);
760 ApplyNumRule(aTmpRule1
,nIndex
,mLevel
,true);
761 ApplyNumRule(aTmpRule2
,nIndex
,mLevel
);
762 if (aTmpRule1
==aTmpRule2
) pItemArr
->bIsCustomized
=false;
763 if (!pItemArr
->bIsCustomized
) {
764 pItemArr
->sDescription
= GetDescription(nIndex
,true);
766 ImplStore(u
"standard.syc");
769 void OutlineTypeMgr::ApplyNumRule(SvxNumRule
& aNum
, sal_uInt16 nIndex
, sal_uInt16
/*mLevel*/, bool isDefault
, bool isResetSize
)
771 DBG_ASSERT(DEFAULT_NUM_VALUSET_COUNT
> nIndex
, "wrong index");
772 if(DEFAULT_NUM_VALUSET_COUNT
<= nIndex
)
775 const FontList
* pList
= nullptr;
777 OutlineSettings_Impl
* pItemArr
= pOutlineSettingsArrs
[nIndex
];
778 if (isDefault
) pItemArr
=pDefaultOutlineSettingsArrs
[nIndex
];
780 NumSettingsArr_Impl
*pNumSettingsArr
=pItemArr
->pNumSettingsArr
;
782 NumSettings_Impl
* pLevelSettings
= nullptr;
783 for(sal_uInt16 i
= 0; i
< aNum
.GetLevelCount(); i
++)
785 if(pNumSettingsArr
->size() > i
)
786 pLevelSettings
= (*pNumSettingsArr
)[i
].get();
791 SvxNumberFormat
aFmt(aNum
.GetLevel(i
));
792 const vcl::Font
& rActBulletFont
= lcl_GetDefaultBulletFont();
793 if (pLevelSettings
->nNumberType
!=aFmt
.GetNumberingType()) isResetSize
=true;
794 aFmt
.SetNumberingType( pLevelSettings
->nNumberType
);
795 sal_uInt16 nUpperLevelOrChar
= static_cast<sal_uInt16
>(pLevelSettings
->nParentNumbering
);
796 if(aFmt
.GetNumberingType() == SVX_NUM_CHAR_SPECIAL
)
798 if( pLevelSettings
->sBulletFont
.getLength() &&
799 pLevelSettings
->sBulletFont
!= rActBulletFont
.GetFamilyName() )
801 //search for the font
804 if (SfxObjectShell
* pCurDocShell
= SfxObjectShell::Current())
806 const SvxFontListItem
* pFontListItem
= static_cast<const SvxFontListItem
*>(pCurDocShell
->GetItem(SID_ATTR_CHAR_FONTLIST
));
807 pList
= pFontListItem
? pFontListItem
->GetFontList() : nullptr;
810 if(pList
&& pList
->IsAvailable( pLevelSettings
->sBulletFont
) )
812 FontMetric aFontMetric
= pList
->Get(pLevelSettings
->sBulletFont
,WEIGHT_NORMAL
, ITALIC_NONE
);
813 vcl::Font
aFont(aFontMetric
);
814 aFmt
.SetBulletFont(&aFont
);
818 //if it cannot be found then create a new one
819 vcl::Font
aCreateFont( pLevelSettings
->sBulletFont
, OUString(), Size( 0, 14 ) );
820 aCreateFont
.SetCharSet( RTL_TEXTENCODING_DONTKNOW
);
821 aCreateFont
.SetFamily( FAMILY_DONTKNOW
);
822 aCreateFont
.SetPitch( PITCH_DONTKNOW
);
823 aCreateFont
.SetWeight( WEIGHT_DONTKNOW
);
824 aCreateFont
.SetTransparent( true );
825 aFmt
.SetBulletFont( &aCreateFont
);
828 aFmt
.SetBulletFont( &rActBulletFont
);
831 if( !pLevelSettings
->sBulletChar
.isEmpty() )
834 = pLevelSettings
->sBulletChar
.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
836 if( AllSettings::GetLayoutRTL() )
838 if( 0 == i
&& cChar
== BulletsTypeMgr::aDynamicBulletTypes
[5] )
839 cChar
= BulletsTypeMgr::aDynamicRTLBulletTypes
[5];
842 const SvxNumberFormat
& numberFmt
= aNum
.GetLevel(0);
843 if( numberFmt
.GetBulletChar() == BulletsTypeMgr::aDynamicRTLBulletTypes
[5] )
844 cChar
= BulletsTypeMgr::aDynamicRTLBulletTypes
[4];
848 aFmt
.SetBulletChar(cChar
);
849 aFmt
.SetCharFormatName( GetBulletCharFmtName() );
850 if (isResetSize
) aFmt
.SetBulletRelSize(45);
851 }else if ((aFmt
.GetNumberingType()&(~LINK_TOKEN
)) == SVX_NUM_BITMAP
) {
852 if (pLevelSettings
->pBrushItem
) {
853 const Graphic
* pGrf
= pLevelSettings
->pBrushItem
->GetGraphic();
854 Size aSize
= pLevelSettings
->aSize
;
855 sal_Int16 eOrient
= text::VertOrientation::LINE_CENTER
;
856 if (!isResetSize
&& aFmt
.GetGraphicSize()!=Size(0,0))
857 aSize
= aFmt
.GetGraphicSize();
858 else if (aSize
.IsEmpty() && pGrf
)
859 aSize
= SvxNumberFormat::GetGraphicSizeMM100( pGrf
);
860 aSize
= OutputDevice::LogicToLogic(aSize
, MapMode(MapUnit::Map100thMM
), MapMode(GetMapUnit()));
861 aFmt
.SetGraphicBrush( pLevelSettings
->pBrushItem
, &aSize
, &eOrient
);
865 aFmt
.SetIncludeUpperLevels(sal::static_int_cast
< sal_uInt8
>(0 != nUpperLevelOrChar
? aNum
.GetLevelCount() : 1));
866 aFmt
.SetCharFormatName(GetNumCharFmtName());
867 if (isResetSize
) aFmt
.SetBulletRelSize(100);
869 if(pNumSettingsArr
->size() > i
) {
870 aFmt
.SetLabelFollowedBy(pLevelSettings
->eLabelFollowedBy
);
871 aFmt
.SetListtabPos(pLevelSettings
->nTabValue
);
872 aFmt
.SetNumAdjust(pLevelSettings
->eNumAlign
);
873 aFmt
.SetFirstLineIndent(pLevelSettings
->nNumAlignAt
);
874 aFmt
.SetIndentAt(pLevelSettings
->nNumIndentAt
);
876 aFmt
.SetListFormat(pLevelSettings
->sPrefix
, pLevelSettings
->sSuffix
, i
);
877 aNum
.SetLevel(i
, aFmt
);
881 OUString
OutlineTypeMgr::GetDescription(sal_uInt16 nIndex
, bool isDefault
)
885 if ( nIndex
>= SAL_N_ELEMENTS(pOutlineSettingsArrs
) )
889 OutlineSettings_Impl
* pItemArr
= pOutlineSettingsArrs
[nIndex
];
890 if (isDefault
) pItemArr
= pDefaultOutlineSettingsArrs
[nIndex
];
893 sRet
= pItemArr
->sDescription
;
899 bool OutlineTypeMgr::IsCustomized(sal_uInt16 nIndex
)
903 if ( nIndex
>= SAL_N_ELEMENTS(pOutlineSettingsArrs
) )
907 OutlineSettings_Impl
* pItemArr
= pOutlineSettingsArrs
[nIndex
];
910 bRet
= pItemArr
->bIsCustomized
;
920 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */