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 <editeng/unolingu.hxx>
26 #include <svtools/ctrltool.hxx>
27 #include <sfx2/objsh.hxx>
28 #include <editeng/flstitem.hxx>
29 #include <svl/itempool.hxx>
30 #include <vcl/outdev.hxx>
31 #include <svx/gallery.hxx>
32 #include <editeng/brushitem.hxx>
33 #include <svx/dialmgr.hxx>
34 #include <svx/strings.hrc>
35 #include <vcl/graph.hxx>
36 #include <vcl/settings.hxx>
38 #include <unotools/streamwrap.hxx>
39 #include <unotools/ucbstreamhelper.hxx>
40 #include <unotools/pathoptions.hxx>
41 #include <editeng/eeitem.hxx>
43 #include <com/sun/star/text/HoriOrientation.hpp>
44 #include <com/sun/star/text/VertOrientation.hpp>
45 #include <com/sun/star/text/RelOrientation.hpp>
46 #include <com/sun/star/style/NumberingType.hpp>
47 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
48 #include <com/sun/star/container/XIndexAccess.hpp>
49 #include <com/sun/star/text/DefaultNumberingProvider.hpp>
50 #include <com/sun/star/text/XNumberingFormatter.hpp>
51 #include <com/sun/star/beans/PropertyValue.hpp>
52 #include <comphelper/processfactory.hxx>
53 #include <com/sun/star/text/XNumberingTypeInfo.hpp>
56 using namespace com::sun::star
;
57 using namespace com::sun::star::uno
;
58 using namespace com::sun::star::beans
;
59 using namespace com::sun::star::lang
;
60 using namespace com::sun::star::text
;
61 using namespace com::sun::star::container
;
62 using namespace com::sun::star::style
;
64 namespace svx
{ namespace sidebar
{
68 const vcl::Font
& lcl_GetDefaultBulletFont()
70 static bool bInit
= false;
71 static vcl::Font
aDefBulletFont("OpenSymbol", "", Size(0, 14));
74 aDefBulletFont
.SetCharSet( RTL_TEXTENCODING_SYMBOL
);
75 aDefBulletFont
.SetFamily( FAMILY_DONTKNOW
);
76 aDefBulletFont
.SetPitch( PITCH_DONTKNOW
);
77 aDefBulletFont
.SetWeight( WEIGHT_DONTKNOW
);
78 aDefBulletFont
.SetTransparent( true );
81 return aDefBulletFont
;
84 const sal_Unicode aDefaultBulletTypes
[] =
96 NumSettings_Impl
* lcl_CreateNumberingSettingsPtr(const Sequence
<PropertyValue
>& rLevelProps
)
98 const PropertyValue
* pValues
= rLevelProps
.getConstArray();
99 NumSettings_Impl
* pNew
= new NumSettings_Impl
;
100 for(sal_Int32 j
= 0; j
< rLevelProps
.getLength(); j
++)
102 if(pValues
[j
].Name
== "NumberingType")
105 if (pValues
[j
].Value
>>= nTmp
)
106 pNew
->nNumberType
= (SvxNumType
)nTmp
;
108 else if(pValues
[j
].Name
== "Prefix")
109 pValues
[j
].Value
>>= pNew
->sPrefix
;
110 else if(pValues
[j
].Name
== "Suffix")
111 pValues
[j
].Value
>>= pNew
->sSuffix
;
112 else if(pValues
[j
].Name
== "ParentNumbering")
113 pValues
[j
].Value
>>= pNew
->nParentNumbering
;
114 else if(pValues
[j
].Name
== "BulletChar")
115 pValues
[j
].Value
>>= pNew
->sBulletChar
;
116 else if(pValues
[j
].Name
== "BulletFontName")
117 pValues
[j
].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
) {
153 SfxAllItemSet
aSet(*pSet
);
155 const SfxStringItem
* pBulletCharFmt
= aSet
.GetItem
<SfxStringItem
>(SID_BULLET_CHAR_FMT
, false);
157 aBulletCharFmtName
= pBulletCharFmt
->GetValue();
159 const SfxStringItem
* pNumCharFmt
= aSet
.GetItem
<SfxStringItem
>(SID_NUM_CHAR_FMT
, false);
161 aNumCharFmtName
= pNumCharFmt
->GetValue();
163 const SfxPoolItem
* pItem
;
164 SfxItemState eState
= pSet
->GetItemState(SID_ATTR_NUMBERING_RULE
, false, &pItem
);
165 if(eState
== SfxItemState::SET
)
167 eCoreUnit
= pSet
->GetPool()->GetMetric(pSet
->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE
));
169 //sd use different sid for numbering rule
170 eState
= pSet
->GetItemState(EE_PARA_NUMBULLET
, false, &pItem
);
171 if(eState
== SfxItemState::SET
)
173 eCoreUnit
= pSet
->GetPool()->GetMetric(pSet
->GetPool()->GetWhich(EE_PARA_NUMBULLET
));
179 void NBOTypeMgrBase::ImplLoad(const OUString
& 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 tranparency 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();
203 c
.SetTransparency(0xFF);
205 aFmt
.SetBulletFont(&aFont
);
206 aNum
.SetLevel(i
, aFmt
);
209 RelplaceNumRule(aNum
,nNumIndex
,0x1/*nLevel*/);
210 xIStm
->ReadInt32( nNumIndex
);
214 eCoreUnit
= eOldCoreUnit
;
217 void NBOTypeMgrBase::ImplStore(const OUString
& 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
|
233 SvxNumRuleFlags::CHAR_TEXT_DISTANCE
,
235 SvxNumRuleType::NUMBERING
, SvxNumberFormat::LABEL_ALIGNMENT
);
236 xOStm
->WriteInt32( nItem
);
237 ApplyNumRule(aDefNumRule
,nItem
,0x1/*nLevel*/,false,true);
238 aDefNumRule
.Store(*xOStm
);
242 xOStm
->WriteInt32( nNumIndex
); //write end flag
244 eCoreUnit
= eOldCoreUnit
;
247 // Character Bullet Type lib
248 BulletsSettings
* BulletsTypeMgr::pActualBullets
[] ={nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr};
249 sal_Unicode
BulletsTypeMgr::aDynamicBulletTypes
[]={' ',' ',' ',' ',' ',' ',' ',' '};
250 sal_Unicode
BulletsTypeMgr::aDynamicRTLBulletTypes
[]={' ',' ',' ',' ',' ',' ',' ',' '};
252 BulletsTypeMgr::BulletsTypeMgr()
258 class theBulletsTypeMgr
: public rtl::Static
<BulletsTypeMgr
, theBulletsTypeMgr
> {};
260 BulletsTypeMgr
& BulletsTypeMgr::GetInstance()
262 return theBulletsTypeMgr::get();
265 void BulletsTypeMgr::Init()
267 const vcl::Font
& rActBulletFont
= lcl_GetDefaultBulletFont();
269 for (sal_uInt16 i
=0;i
<DEFAULT_BULLET_TYPES
;i
++)
271 pActualBullets
[i
] = new BulletsSettings
;
272 pActualBullets
[i
]->cBulletChar
= aDefaultBulletTypes
[i
];
273 pActualBullets
[i
]->aFont
= rActBulletFont
;
274 pActualBullets
[i
]->sDescription
= SvxResId( RID_SVXSTR_BULLET_DESCRIPTION_0
+ i
);
277 sal_uInt16
BulletsTypeMgr::GetNBOIndexForNumRule(SvxNumRule
& aNum
,sal_uInt16 mLevel
,sal_uInt16 nFromIndex
)
279 if ( mLevel
== (sal_uInt16
)0xFFFF || mLevel
== 0)
280 return (sal_uInt16
)0xFFFF;
281 //if ( !lcl_IsNumFmtSet(pNR, mLevel) ) return (sal_uInt16)0xFFFF;
283 sal_uInt16 nActLv
= IsSingleLevel(mLevel
);
285 if ( nActLv
== (sal_uInt16
)0xFFFF )
286 return (sal_uInt16
)0xFFFF;
288 SvxNumberFormat
aFmt(aNum
.GetLevel(nActLv
));
289 sal_Unicode cChar
= aFmt
.GetBulletChar();
290 for(sal_uInt16 i
= nFromIndex
; i
< DEFAULT_BULLET_TYPES
; i
++)
292 if ( (cChar
== pActualBullets
[i
]->cBulletChar
) ||
293 (cChar
== 9830 && 57356 == pActualBullets
[i
]->cBulletChar
) ||
294 (cChar
== 9632 && 57354 == pActualBullets
[i
]->cBulletChar
) )
300 return (sal_uInt16
)0xFFFF;
303 void BulletsTypeMgr::RelplaceNumRule(SvxNumRule
& aNum
, sal_uInt16 nIndex
, sal_uInt16 mLevel
)
305 if ( mLevel
== (sal_uInt16
)0xFFFF || mLevel
== 0)
308 if ( GetNBOIndexForNumRule(aNum
,mLevel
) != (sal_uInt16
)0xFFFF )
311 sal_uInt16 nActLv
= IsSingleLevel(mLevel
);
313 if ( nActLv
== (sal_uInt16
)0xFFFF )
316 SvxNumberFormat
aFmt(aNum
.GetLevel(nActLv
));
317 sal_Unicode cChar
= aFmt
.GetBulletChar();
318 const vcl::Font
* pFont
= aFmt
.GetBulletFont();
319 if ( nIndex
>= DEFAULT_BULLET_TYPES
)
322 pActualBullets
[nIndex
]->cBulletChar
= cChar
;
324 pActualBullets
[nIndex
]->aFont
= *pFont
;
325 pActualBullets
[nIndex
]->bIsCustomized
= true;
328 void BulletsTypeMgr::ApplyNumRule(SvxNumRule
& aNum
, sal_uInt16 nIndex
, sal_uInt16 mLevel
, bool /*isDefault*/, bool isResetSize
)
330 if ( nIndex
>= DEFAULT_BULLET_TYPES
)
332 sal_Unicode cChar
= pActualBullets
[nIndex
]->cBulletChar
;
333 const vcl::Font
& rActBulletFont
= pActualBullets
[nIndex
]->aFont
;
335 sal_uInt16 nMask
= 1;
336 OUString sBulletCharFormatName
= GetBulletCharFmtName();
337 for(sal_uInt16 i
= 0; i
< aNum
.GetLevelCount(); i
++)
341 SvxNumberFormat
aFmt(aNum
.GetLevel(i
));
342 aFmt
.SetNumberingType( SVX_NUM_CHAR_SPECIAL
);
343 aFmt
.SetBulletFont(&rActBulletFont
);
344 aFmt
.SetBulletChar(cChar
);
345 aFmt
.SetCharFormatName(sBulletCharFormatName
);
346 aFmt
.SetPrefix( "" );
347 aFmt
.SetSuffix( "" );
348 if (isResetSize
) aFmt
.SetBulletRelSize(45);
349 aNum
.SetLevel(i
, aFmt
);
355 OUString
BulletsTypeMgr::GetDescription(sal_uInt16 nIndex
, bool /*isDefault*/)
359 if ( nIndex
>= DEFAULT_BULLET_TYPES
)
362 sRet
= pActualBullets
[nIndex
]->sDescription
;
367 bool BulletsTypeMgr::IsCustomized(sal_uInt16 nIndex
)
371 if ( nIndex
>= DEFAULT_BULLET_TYPES
)
374 bRet
= pActualBullets
[nIndex
]->bIsCustomized
;
379 // Numbering Type lib
380 NumberingTypeMgr::NumberingTypeMgr()
384 maDefaultNumberSettingsArr
= maNumberSettingsArr
;
385 ImplLoad("standard.syb");
388 NumberingTypeMgr::~NumberingTypeMgr()
392 static const char* RID_SVXSTR_SINGLENUM_DESCRIPTIONS
[] =
394 RID_SVXSTR_SINGLENUM_DESCRIPTION_0
,
395 RID_SVXSTR_SINGLENUM_DESCRIPTION_1
,
396 RID_SVXSTR_SINGLENUM_DESCRIPTION_2
,
397 RID_SVXSTR_SINGLENUM_DESCRIPTION_3
,
398 RID_SVXSTR_SINGLENUM_DESCRIPTION_4
,
399 RID_SVXSTR_SINGLENUM_DESCRIPTION_5
,
400 RID_SVXSTR_SINGLENUM_DESCRIPTION_6
,
401 RID_SVXSTR_SINGLENUM_DESCRIPTION_7
404 class theNumberingTypeMgr
: public rtl::Static
<NumberingTypeMgr
, theNumberingTypeMgr
> {};
406 NumberingTypeMgr
& NumberingTypeMgr::GetInstance()
408 return theNumberingTypeMgr::get();
411 void NumberingTypeMgr::Init()
413 Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
414 Reference
<XDefaultNumberingProvider
> xDefNum
= DefaultNumberingProvider::create( xContext
);
416 Sequence
< Sequence
< PropertyValue
> > aNumberings
;
417 Locale
aLocale(Application::GetSettings().GetLanguageTag().getLocale());
420 aNumberings
= xDefNum
->getDefaultContinuousNumberingLevels( aLocale
);
422 sal_Int32 nLength
= aNumberings
.getLength();
424 const Sequence
<PropertyValue
>* pValuesArr
= aNumberings
.getConstArray();
425 for(sal_Int32 i
= 0; i
< nLength
; i
++)
427 NumSettings_Impl
* pNew
= lcl_CreateNumberingSettingsPtr(pValuesArr
[i
]);
428 NumberSettings_Impl
* pNumEntry
= new NumberSettings_Impl
;
429 pNumEntry
->pNumSetting
= pNew
;
431 pNumEntry
->sDescription
= SvxResId(RID_SVXSTR_SINGLENUM_DESCRIPTIONS
[i
]);
432 maNumberSettingsArr
.push_back(std::shared_ptr
<NumberSettings_Impl
>(pNumEntry
));
440 sal_uInt16
NumberingTypeMgr::GetNBOIndexForNumRule(SvxNumRule
& aNum
,sal_uInt16 mLevel
,sal_uInt16 nFromIndex
)
442 if ( mLevel
== (sal_uInt16
)0xFFFF || mLevel
> aNum
.GetLevelCount() || mLevel
== 0)
443 return (sal_uInt16
)0xFFFF;
445 sal_uInt16 nActLv
= IsSingleLevel(mLevel
);
447 if ( nActLv
== (sal_uInt16
)0xFFFF )
448 return (sal_uInt16
)0xFFFF;
450 SvxNumberFormat
aFmt(aNum
.GetLevel(nActLv
));
451 //sal_Unicode cPrefix = rtl::OUString(aFmt.GetPrefix())[0];
452 //sal_Unicode cSuffix = rtl::OUString(aFmt.GetSuffix())[0];
453 OUString sPrefix
= aFmt
.GetPrefix();
454 OUString sLclSuffix
= aFmt
.GetSuffix();
455 sal_Int16 eNumType
= aFmt
.GetNumberingType();
457 sal_uInt16 nCount
= maNumberSettingsArr
.size();
458 for(sal_uInt16 i
= nFromIndex
; i
< nCount
; ++i
)
460 NumberSettings_Impl
* _pSet
= maNumberSettingsArr
[i
].get();
461 sal_Int16 eNType
= _pSet
->pNumSetting
->nNumberType
;
462 OUString sLocalPrefix
= _pSet
->pNumSetting
->sPrefix
;
463 OUString sLocalSuffix
= _pSet
->pNumSetting
->sSuffix
;
464 if (sPrefix
== sLocalPrefix
&&
465 sLclSuffix
== sLocalSuffix
&&
473 return (sal_uInt16
)0xFFFF;
476 void NumberingTypeMgr::RelplaceNumRule(SvxNumRule
& aNum
, sal_uInt16 nIndex
, sal_uInt16 mLevel
)
478 sal_uInt16 nActLv
= IsSingleLevel(mLevel
);
480 if ( nActLv
== (sal_uInt16
)0xFFFF )
483 SvxNumberFormat
aFmt(aNum
.GetLevel(nActLv
));
484 SvxNumType eNumType
= aFmt
.GetNumberingType();
486 sal_uInt16 nCount
= maNumberSettingsArr
.size();
487 if ( nIndex
>= nCount
)
490 NumberSettings_Impl
* _pSet
= maNumberSettingsArr
[nIndex
].get();
492 _pSet
->pNumSetting
->sPrefix
= aFmt
.GetPrefix();
493 _pSet
->pNumSetting
->sSuffix
= aFmt
.GetSuffix();
494 _pSet
->pNumSetting
->nNumberType
= eNumType
;
495 _pSet
->bIsCustomized
= true;
497 SvxNumRule
aTmpRule1(aNum
);
498 SvxNumRule
aTmpRule2(aNum
);
499 ApplyNumRule(aTmpRule1
,nIndex
,mLevel
,true);
500 ApplyNumRule(aTmpRule2
,nIndex
,mLevel
);
501 if (aTmpRule1
==aTmpRule2
) _pSet
->bIsCustomized
=false;
502 if (!_pSet
->bIsCustomized
) {
503 _pSet
->sDescription
= GetDescription(nIndex
,true);
505 ImplStore("standard.syb");
508 void NumberingTypeMgr::ApplyNumRule(SvxNumRule
& aNum
, sal_uInt16 nIndex
, sal_uInt16 mLevel
, bool isDefault
, bool isResetSize
)
510 if(maNumberSettingsArr
.size() <= nIndex
)
512 NumberSettingsArr_Impl
* pCurrentNumberSettingsArr
= &maNumberSettingsArr
;
513 if (isDefault
) pCurrentNumberSettingsArr
= &maDefaultNumberSettingsArr
;
514 NumberSettings_Impl
* _pSet
= (*pCurrentNumberSettingsArr
)[nIndex
].get();
515 SvxNumType eNewType
= _pSet
->pNumSetting
->nNumberType
;
517 sal_uInt16 nMask
= 1;
518 OUString sNumCharFmtName
= GetNumCharFmtName();
519 for(sal_uInt16 i
= 0; i
< aNum
.GetLevelCount(); i
++)
523 SvxNumberFormat
aFmt(aNum
.GetLevel(i
));
524 if (eNewType
!=aFmt
.GetNumberingType()) isResetSize
=true;
525 aFmt
.SetNumberingType(eNewType
);
526 aFmt
.SetPrefix(_pSet
->pNumSetting
->sPrefix
);
527 aFmt
.SetSuffix(_pSet
->pNumSetting
->sSuffix
);
529 aFmt
.SetCharFormatName(sNumCharFmtName
);
530 if (isResetSize
) aFmt
.SetBulletRelSize(100);
531 aNum
.SetLevel(i
, aFmt
);
537 OUString
NumberingTypeMgr::GetDescription(sal_uInt16 nIndex
, bool isDefault
)
540 sal_uInt16 nLength
= 0;
541 nLength
= maNumberSettingsArr
.size();
543 if ( nIndex
>= nLength
)
546 sRet
= maNumberSettingsArr
[nIndex
]->sDescription
;
547 if (isDefault
) sRet
= maDefaultNumberSettingsArr
[nIndex
]->sDescription
;
552 bool NumberingTypeMgr::IsCustomized(sal_uInt16 nIndex
)
555 sal_uInt16 nLength
= 0;
556 nLength
= maNumberSettingsArr
.size();
558 if ( nIndex
>= nLength
)
561 bRet
= maNumberSettingsArr
[nIndex
]->bIsCustomized
;
565 // Multi-level /Outline Type lib
566 OutlineTypeMgr::OutlineTypeMgr()
570 for(sal_Int32 nItem
= 0; nItem
< DEFAULT_NUM_VALUSET_COUNT
; nItem
++ )
572 pDefaultOutlineSettingsArrs
[nItem
] = pOutlineSettingsArrs
[nItem
];
574 //Initial the first time to store the default value. Then do it again for customized value
576 ImplLoad("standard.syc");
579 class theOutlineTypeMgr
: public rtl::Static
<OutlineTypeMgr
, theOutlineTypeMgr
> {};
581 OutlineTypeMgr
& OutlineTypeMgr::GetInstance()
583 return theOutlineTypeMgr::get();
586 void OutlineTypeMgr::Init()
588 Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
589 Reference
<XDefaultNumberingProvider
> xDefNum
= DefaultNumberingProvider::create( xContext
);
591 Sequence
<Reference
<XIndexAccess
> > aOutlineAccess
;
592 Locale
aLocale(Application::GetSettings().GetLanguageTag().getLocale());
595 aOutlineAccess
= xDefNum
->getDefaultOutlineNumberings( aLocale
);
597 SvxNumRule
aDefNumRule( SvxNumRuleFlags::BULLET_REL_SIZE
| SvxNumRuleFlags::CONTINUOUS
| SvxNumRuleFlags::BULLET_COLOR
|
598 SvxNumRuleFlags::CHAR_TEXT_DISTANCE
,
600 SvxNumRuleType::NUMBERING
, SvxNumberFormat::LABEL_ALIGNMENT
);
602 for(sal_Int32 nItem
= 0;
603 nItem
< aOutlineAccess
.getLength() && nItem
< DEFAULT_NUM_VALUSET_COUNT
;
606 pOutlineSettingsArrs
[ nItem
] = new OutlineSettings_Impl
;
607 OutlineSettings_Impl
* pItemArr
= pOutlineSettingsArrs
[ nItem
];
608 pItemArr
->sDescription
= SvxResId( RID_SVXSTR_OUTLINENUM_DESCRIPTION_0
+ nItem
);
609 pItemArr
->pNumSettingsArr
= new NumSettingsArr_Impl
;
610 Reference
<XIndexAccess
> xLevel
= aOutlineAccess
.getConstArray()[nItem
];
611 for(sal_Int32 nLevel
= 0; nLevel
< xLevel
->getCount() && nLevel
< 5; nLevel
++)
613 Any aValueAny
= xLevel
->getByIndex(nLevel
);
614 Sequence
<PropertyValue
> aLevelProps
;
615 aValueAny
>>= aLevelProps
;
616 NumSettings_Impl
* pNew
= lcl_CreateNumberingSettingsPtr(aLevelProps
);
617 SvxNumberFormat
aNumFmt( aDefNumRule
.GetLevel( nLevel
) );
618 pNew
->eLabelFollowedBy
= aNumFmt
.GetLabelFollowedBy();
619 pNew
->nTabValue
= aNumFmt
.GetListtabPos();
620 pNew
->eNumAlign
= aNumFmt
.GetNumAdjust();
621 pNew
->nNumAlignAt
= aNumFmt
.GetFirstLineIndent();
622 pNew
->nNumIndentAt
= aNumFmt
.GetIndentAt();
623 pItemArr
->pNumSettingsArr
->push_back(std::shared_ptr
<NumSettings_Impl
>(pNew
));
632 sal_uInt16
OutlineTypeMgr::GetNBOIndexForNumRule(SvxNumRule
& aNum
,sal_uInt16
/*mLevel*/,sal_uInt16 nFromIndex
)
634 sal_uInt16
const nLength
= SAL_N_ELEMENTS(pOutlineSettingsArrs
);
635 for(sal_uInt16 iDex
= nFromIndex
; iDex
< nLength
; iDex
++)
637 bool bNotMatch
= false;
638 OutlineSettings_Impl
* pItemArr
= pOutlineSettingsArrs
[iDex
];
639 sal_uInt16 nCount
= pItemArr
->pNumSettingsArr
->size();
640 for (sal_uInt16 iLevel
=0;iLevel
< nCount
;iLevel
++)
642 NumSettings_Impl
* _pSet
= (*pItemArr
->pNumSettingsArr
)[iLevel
].get();
643 sal_Int16 eNType
= _pSet
->nNumberType
;
645 SvxNumberFormat
aFmt(aNum
.GetLevel(iLevel
));
646 OUString sPrefix
= aFmt
.GetPrefix();
647 OUString sLclSuffix
= aFmt
.GetSuffix();
648 sal_Int16 eNumType
= aFmt
.GetNumberingType();
649 if( eNumType
== SVX_NUM_CHAR_SPECIAL
)
651 sal_Unicode cChar
= aFmt
.GetBulletChar();
652 sal_Unicode ccChar
= _pSet
->sBulletChar
[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()))
663 }else if ((eNumType
&(~LINK_TOKEN
)) == SVX_NUM_BITMAP
) {
664 const SvxBrushItem
* pBrsh1
= aFmt
.GetBrush();
665 const SvxBrushItem
* pBrsh2
= _pSet
->pBrushItem
;
666 bool bIsMatch
= false;
667 if (pBrsh1
==pBrsh2
) bIsMatch
= true;
668 if (pBrsh1
&& pBrsh2
) {
669 const Graphic
* pGrf1
= pBrsh1
->GetGraphic();
670 const Graphic
* pGrf2
= pBrsh2
->GetGraphic();
671 if (pGrf1
==pGrf2
) bIsMatch
= true;
672 if (pGrf1
&& pGrf2
) {
673 if ( pGrf1
->GetBitmap() == pGrf2
->GetBitmap() &&
674 _pSet
->aSize
== aFmt
.GetGraphicSize())
684 if (!(sPrefix
== _pSet
->sPrefix
&&
685 sLclSuffix
== _pSet
->sSuffix
&&
686 eNumType
== eNType
&&
687 _pSet
->eLabelFollowedBy
== aFmt
.GetLabelFollowedBy() &&
688 _pSet
->nTabValue
== aFmt
.GetListtabPos() &&
689 _pSet
->eNumAlign
== aFmt
.GetNumAdjust() &&
690 _pSet
->nNumAlignAt
== aFmt
.GetFirstLineIndent() &&
691 _pSet
->nNumIndentAt
== aFmt
.GetIndentAt()))
703 return (sal_uInt16
)0xFFFF;
706 void OutlineTypeMgr::RelplaceNumRule(SvxNumRule
& aNum
, sal_uInt16 nIndex
, sal_uInt16 mLevel
)
708 sal_uInt16
const nLength
= SAL_N_ELEMENTS(pOutlineSettingsArrs
);
709 if ( nIndex
>= nLength
)
712 OutlineSettings_Impl
* pItemArr
= pOutlineSettingsArrs
[nIndex
];
713 sal_uInt16 nCount
= pItemArr
->pNumSettingsArr
->size();
714 for (sal_uInt16 iLevel
=0;iLevel
< nCount
;iLevel
++)
716 SvxNumberFormat
aFmt(aNum
.GetLevel(iLevel
));
717 SvxNumType eNumType
= aFmt
.GetNumberingType();
719 NumSettings_Impl
* _pSet
= (*pItemArr
->pNumSettingsArr
)[iLevel
].get();
721 _pSet
->eLabelFollowedBy
= aFmt
.GetLabelFollowedBy();
722 _pSet
->nTabValue
= aFmt
.GetListtabPos();
723 _pSet
->eNumAlign
= aFmt
.GetNumAdjust();
724 _pSet
->nNumAlignAt
= aFmt
.GetFirstLineIndent();
725 _pSet
->nNumIndentAt
= aFmt
.GetIndentAt();
727 if( eNumType
== SVX_NUM_CHAR_SPECIAL
)
729 sal_Unicode cChar
= aFmt
.GetBulletChar();
730 OUString
sChar(cChar
);
731 _pSet
->sBulletChar
= sChar
;
732 if ( aFmt
.GetBulletFont() )
733 _pSet
->sBulletFont
= aFmt
.GetBulletFont()->GetFamilyName();
734 _pSet
->nNumberType
= eNumType
;
735 pItemArr
->bIsCustomized
= true;
736 }else if ((eNumType
&(~LINK_TOKEN
)) == SVX_NUM_BITMAP
) {
737 if (_pSet
->pBrushItem
) {
738 delete (_pSet
->pBrushItem
);
739 _pSet
->pBrushItem
=nullptr;
742 _pSet
->pBrushItem
= new SvxBrushItem(*aFmt
.GetBrush());
743 _pSet
->aSize
= aFmt
.GetGraphicSize();
744 _pSet
->nNumberType
= eNumType
;
747 _pSet
->sPrefix
= aFmt
.GetPrefix();
748 _pSet
->sSuffix
= aFmt
.GetSuffix();
749 _pSet
->nNumberType
= eNumType
;
750 if ( aFmt
.GetBulletFont() )
751 _pSet
->sBulletFont
= aFmt
.GetBulletFont()->GetFamilyName();
752 pItemArr
->bIsCustomized
= true;
755 SvxNumRule
aTmpRule1(aNum
);
756 SvxNumRule
aTmpRule2(aNum
);
757 ApplyNumRule(aTmpRule1
,nIndex
,mLevel
,true);
758 ApplyNumRule(aTmpRule2
,nIndex
,mLevel
);
759 if (aTmpRule1
==aTmpRule2
) pItemArr
->bIsCustomized
=false;
760 if (!pItemArr
->bIsCustomized
) {
761 pItemArr
->sDescription
= GetDescription(nIndex
,true);
763 ImplStore("standard.syc");
766 void OutlineTypeMgr::ApplyNumRule(SvxNumRule
& aNum
, sal_uInt16 nIndex
, sal_uInt16
/*mLevel*/, bool isDefault
, bool isResetSize
)
768 DBG_ASSERT(DEFAULT_NUM_VALUSET_COUNT
> nIndex
, "wrong index");
769 if(DEFAULT_NUM_VALUSET_COUNT
<= nIndex
)
772 const FontList
* pList
= nullptr;
774 OutlineSettings_Impl
* pItemArr
= pOutlineSettingsArrs
[nIndex
];
775 if (isDefault
) pItemArr
=pDefaultOutlineSettingsArrs
[nIndex
];
777 NumSettingsArr_Impl
*pNumSettingsArr
=pItemArr
->pNumSettingsArr
;
779 NumSettings_Impl
* pLevelSettings
= nullptr;
780 for(sal_uInt16 i
= 0; i
< aNum
.GetLevelCount(); i
++)
782 if(pNumSettingsArr
->size() > i
)
783 pLevelSettings
= (*pNumSettingsArr
)[i
].get();
788 SvxNumberFormat
aFmt(aNum
.GetLevel(i
));
789 const vcl::Font
& rActBulletFont
= lcl_GetDefaultBulletFont();
790 if (pLevelSettings
->nNumberType
!=aFmt
.GetNumberingType()) isResetSize
=true;
791 aFmt
.SetNumberingType( pLevelSettings
->nNumberType
);
792 sal_uInt16 nUpperLevelOrChar
= (sal_uInt16
)pLevelSettings
->nParentNumbering
;
793 if(aFmt
.GetNumberingType() == SVX_NUM_CHAR_SPECIAL
)
795 if( pLevelSettings
->sBulletFont
.getLength() &&
796 pLevelSettings
->sBulletFont
!= rActBulletFont
.GetFamilyName() )
798 //search for the font
801 SfxObjectShell
* pCurDocShell
= SfxObjectShell::Current();
802 const SvxFontListItem
* pFontListItem
= static_cast<const SvxFontListItem
*>( pCurDocShell
->GetItem( SID_ATTR_CHAR_FONTLIST
) );
803 pList
= pFontListItem
? pFontListItem
->GetFontList() : nullptr;
805 if(pList
&& pList
->IsAvailable( pLevelSettings
->sBulletFont
) )
807 FontMetric aFontMetric
= pList
->Get(pLevelSettings
->sBulletFont
,WEIGHT_NORMAL
, ITALIC_NONE
);
808 vcl::Font
aFont(aFontMetric
);
809 aFmt
.SetBulletFont(&aFont
);
813 //if it cannot be found then create a new one
814 vcl::Font
aCreateFont( pLevelSettings
->sBulletFont
, OUString(), Size( 0, 14 ) );
815 aCreateFont
.SetCharSet( RTL_TEXTENCODING_DONTKNOW
);
816 aCreateFont
.SetFamily( FAMILY_DONTKNOW
);
817 aCreateFont
.SetPitch( PITCH_DONTKNOW
);
818 aCreateFont
.SetWeight( WEIGHT_DONTKNOW
);
819 aCreateFont
.SetTransparent( true );
820 aFmt
.SetBulletFont( &aCreateFont
);
823 aFmt
.SetBulletFont( &rActBulletFont
);
825 sal_Unicode cChar
= 0;
826 if( !pLevelSettings
->sBulletChar
.isEmpty() )
827 cChar
= pLevelSettings
->sBulletChar
[0];
828 if( AllSettings::GetLayoutRTL() )
830 if( 0 == i
&& cChar
== BulletsTypeMgr::aDynamicBulletTypes
[5] )
831 cChar
= BulletsTypeMgr::aDynamicRTLBulletTypes
[5];
834 const SvxNumberFormat
& numberFmt
= aNum
.GetLevel(0);
835 if( numberFmt
.GetBulletChar() == BulletsTypeMgr::aDynamicRTLBulletTypes
[5] )
836 cChar
= BulletsTypeMgr::aDynamicRTLBulletTypes
[4];
840 aFmt
.SetBulletChar(cChar
);
841 aFmt
.SetCharFormatName( GetBulletCharFmtName() );
842 if (isResetSize
) aFmt
.SetBulletRelSize(45);
843 }else if ((aFmt
.GetNumberingType()&(~LINK_TOKEN
)) == SVX_NUM_BITMAP
) {
844 if (pLevelSettings
->pBrushItem
) {
845 const Graphic
* pGrf
= pLevelSettings
->pBrushItem
->GetGraphic();
846 Size aSize
= pLevelSettings
->aSize
;
847 sal_Int16 eOrient
= text::VertOrientation::LINE_CENTER
;
848 if (!isResetSize
&& aFmt
.GetGraphicSize()!=Size(0,0)) aSize
=aFmt
.GetGraphicSize();
850 if (aSize
.Width()==0 && aSize
.Height()==0 && pGrf
) {
851 aSize
= SvxNumberFormat::GetGraphicSizeMM100( pGrf
);
854 aSize
= OutputDevice::LogicToLogic(aSize
, MapMode(MapUnit::Map100thMM
), MapMode(GetMapUnit()));
855 aFmt
.SetGraphicBrush( pLevelSettings
->pBrushItem
, &aSize
, &eOrient
);
859 aFmt
.SetIncludeUpperLevels(sal::static_int_cast
< sal_uInt8
>(0 != nUpperLevelOrChar
? aNum
.GetLevelCount() : 0));
860 aFmt
.SetCharFormatName(GetNumCharFmtName());
861 if (isResetSize
) aFmt
.SetBulletRelSize(100);
863 if(pNumSettingsArr
->size() > i
) {
864 aFmt
.SetLabelFollowedBy(pLevelSettings
->eLabelFollowedBy
);
865 aFmt
.SetListtabPos(pLevelSettings
->nTabValue
);
866 aFmt
.SetNumAdjust(pLevelSettings
->eNumAlign
);
867 aFmt
.SetFirstLineIndent(pLevelSettings
->nNumAlignAt
);
868 aFmt
.SetIndentAt(pLevelSettings
->nNumIndentAt
);
870 aFmt
.SetPrefix(pLevelSettings
->sPrefix
);
871 aFmt
.SetSuffix(pLevelSettings
->sSuffix
);
872 aNum
.SetLevel(i
, aFmt
);
876 OUString
OutlineTypeMgr::GetDescription(sal_uInt16 nIndex
, bool isDefault
)
880 if ( nIndex
>= SAL_N_ELEMENTS(pOutlineSettingsArrs
) )
884 OutlineSettings_Impl
* pItemArr
= pOutlineSettingsArrs
[nIndex
];
885 if (isDefault
) pItemArr
= pDefaultOutlineSettingsArrs
[nIndex
];
888 sRet
= pItemArr
->sDescription
;
894 bool OutlineTypeMgr::IsCustomized(sal_uInt16 nIndex
)
898 if ( nIndex
>= SAL_N_ELEMENTS(pOutlineSettingsArrs
) )
902 OutlineSettings_Impl
* pItemArr
= pOutlineSettingsArrs
[nIndex
];
905 bRet
= pItemArr
->bIsCustomized
;
915 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */