bump product version to 7.2.5.1
[LibreOffice.git] / svx / source / sidebar / nbdtmg.cxx
blobfe3c664c7ebf9377505bdf70bde4d0d6db37aa95
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
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>
50 #include <memory>
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 {
62 namespace {
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 );
74 return tmp;
75 }();
76 return aDefBulletFont;
79 const sal_Unicode aDefaultBulletTypes[] =
81 0x2022,
82 0x25cf,
83 0xe00c,
84 0xe00a,
85 0x2794,
86 0x27a2,
87 0x2717,
88 0x2714
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")
98 sal_Int16 nTmp;
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 == "ParentNumbering")
107 rValue.Value >>= pNew->nParentNumbering;
108 else if(rValue.Name == "BulletChar")
109 rValue.Value >>= pNew->sBulletChar;
110 else if(rValue.Name == "BulletFontName")
111 rValue.Value >>= pNew->sBulletFont;
113 const sal_Unicode cLocalPrefix = pNew->sPrefix.getLength() ? pNew->sPrefix[0] : 0;
114 const sal_Unicode cLocalSuffix = pNew->sSuffix.getLength() ? pNew->sSuffix[0] : 0;
115 if( cLocalPrefix == ' ') pNew->sPrefix.clear();
116 if( cLocalSuffix == ' ') pNew->sSuffix.clear();
117 return pNew;
122 sal_uInt16 NBOTypeMgrBase:: IsSingleLevel(sal_uInt16 nCurLevel)
124 sal_uInt16 nLv = sal_uInt16(0xFFFF);
125 sal_uInt16 nCount = 0;
126 sal_uInt16 nMask = 1;
127 for( sal_uInt16 i = 0; i < SVX_MAX_NUM; i++ )
129 if(nCurLevel & nMask)
131 nCount++;
132 nLv=i;
134 nMask <<= 1 ;
137 if ( nCount == 1)
138 return nLv;
139 else
140 return sal_uInt16(0xFFFF);
143 void NBOTypeMgrBase::SetItems(const SfxItemSet* pArg) {
144 pSet = pArg;
145 if ( !pSet )
146 return;
148 SfxAllItemSet aSet(*pSet);
150 const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
151 if (pBulletCharFmt)
152 aBulletCharFmtName = pBulletCharFmt->GetValue();
154 const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
155 if (pNumCharFmt)
156 aNumCharFmtName = pNumCharFmt->GetValue();
158 const SfxPoolItem* pItem;
159 SfxItemState eState = pSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
160 if(eState == SfxItemState::SET)
162 eCoreUnit = pSet->GetPool()->GetMetric(pSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
163 } else {
164 //sd use different sid for numbering rule
165 eState = pSet->GetItemState(EE_PARA_NUMBULLET, false, &pItem);
166 if(eState == SfxItemState::SET)
168 eCoreUnit = pSet->GetPool()->GetMetric(pSet->GetPool()->GetWhich(EE_PARA_NUMBULLET));
173 void NBOTypeMgrBase::ImplLoad(std::u16string_view filename)
175 bIsLoading = true;
176 MapUnit eOldCoreUnit=eCoreUnit;
177 eCoreUnit = MapUnit::Map100thMM;
178 INetURLObject aFile( SvtPathOptions().GetUserConfigPath() );
179 aFile.Append( filename);
180 std::unique_ptr<SvStream> xIStm(::utl::UcbStreamHelper::CreateStream( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
181 if( xIStm ) {
182 sal_uInt32 nVersion = 0;
183 sal_Int32 nNumIndex = 0;
184 xIStm->ReadUInt32( nVersion );
185 if (nVersion==DEFAULT_NUMBERING_CACHE_FORMAT_VERSION) //first version
187 xIStm->ReadInt32( nNumIndex );
188 while (nNumIndex>=0 && nNumIndex<DEFAULT_NUM_VALUSET_COUNT) {
189 SvxNumRule aNum(*xIStm);
190 //bullet color in font properties is not stored correctly. Need set transparency bits manually
191 for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++)
193 SvxNumberFormat aFmt(aNum.GetLevel(i));
194 if (aFmt.GetBulletFont()) {
195 vcl::Font aFont(*aFmt.GetBulletFont());
196 Color c=aFont.GetColor();
197 c.SetAlpha(0);
198 aFont.SetColor(c);
199 aFmt.SetBulletFont(&aFont);
200 aNum.SetLevel(i, aFmt);
203 RelplaceNumRule(aNum,nNumIndex,0x1/*nLevel*/);
204 xIStm->ReadInt32( nNumIndex );
208 eCoreUnit = eOldCoreUnit;
209 bIsLoading = false;
211 void NBOTypeMgrBase::ImplStore(std::u16string_view filename)
213 if (bIsLoading) return;
214 MapUnit eOldCoreUnit=eCoreUnit;
215 eCoreUnit = MapUnit::Map100thMM;
216 INetURLObject aFile( SvtPathOptions().GetUserConfigPath() );
217 aFile.Append( filename);
218 std::unique_ptr<SvStream> xOStm(::utl::UcbStreamHelper::CreateStream( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE ));
219 if( xOStm ) {
220 sal_uInt32 nVersion;
221 sal_Int32 nNumIndex;
222 nVersion = DEFAULT_NUMBERING_CACHE_FORMAT_VERSION;
223 xOStm->WriteUInt32( nVersion );
224 for(sal_Int32 nItem = 0; nItem < DEFAULT_NUM_VALUSET_COUNT; nItem++ ) {
225 if (IsCustomized(nItem)) {
226 SvxNumRule aDefNumRule( SvxNumRuleFlags::BULLET_REL_SIZE | SvxNumRuleFlags::CONTINUOUS | SvxNumRuleFlags::BULLET_COLOR,
227 10, false,
228 SvxNumRuleType::NUMBERING, SvxNumberFormat::LABEL_ALIGNMENT);
229 xOStm->WriteInt32( nItem );
230 ApplyNumRule(aDefNumRule,nItem,0x1/*nLevel*/,false,true);
231 aDefNumRule.Store(*xOStm);
234 nNumIndex = -1;
235 xOStm->WriteInt32( nNumIndex ); //write end flag
237 eCoreUnit = eOldCoreUnit;
240 // Character Bullet Type lib
241 BulletsSettings* BulletsTypeMgr::pActualBullets[] ={nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr};
242 sal_Unicode BulletsTypeMgr::aDynamicBulletTypes[]={' ',' ',' ',' ',' ',' ',' ',' '};
243 sal_Unicode BulletsTypeMgr::aDynamicRTLBulletTypes[]={' ',' ',' ',' ',' ',' ',' ',' '};
245 BulletsTypeMgr::BulletsTypeMgr()
246 : NBOTypeMgrBase()
248 Init();
251 namespace {
253 class theBulletsTypeMgr : public rtl::Static<BulletsTypeMgr, theBulletsTypeMgr> {};
257 BulletsTypeMgr& BulletsTypeMgr::GetInstance()
259 return theBulletsTypeMgr::get();
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 pActualBullets[i]->sDescription = SvxResId( RID_SVXSTR_BULLET_DESCRIPTION_0 + i );
274 sal_uInt16 BulletsTypeMgr::GetNBOIndexForNumRule(SvxNumRule& aNum,sal_uInt16 mLevel,sal_uInt16 nFromIndex)
276 if ( mLevel == sal_uInt16(0xFFFF) || mLevel == 0)
277 return sal_uInt16(0xFFFF);
278 //if ( !lcl_IsNumFmtSet(pNR, mLevel) ) return (sal_uInt16)0xFFFF;
280 sal_uInt16 nActLv = IsSingleLevel(mLevel);
282 if ( nActLv == sal_uInt16(0xFFFF) )
283 return sal_uInt16(0xFFFF);
285 const SvxNumberFormat& aFmt(aNum.GetLevel(nActLv));
286 sal_UCS4 cChar = aFmt.GetBulletChar();
287 for(sal_uInt16 i = nFromIndex; i < DEFAULT_BULLET_TYPES; i++)
289 if ( (cChar == pActualBullets[i]->cBulletChar) ||
290 (cChar == 9830 && 57356 == pActualBullets[i]->cBulletChar) ||
291 (cChar == 9632 && 57354 == pActualBullets[i]->cBulletChar) )
293 return i+1;
297 return sal_uInt16(0xFFFF);
300 void BulletsTypeMgr::RelplaceNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel)
302 if ( mLevel == sal_uInt16(0xFFFF) || mLevel == 0)
303 return;
305 if ( GetNBOIndexForNumRule(aNum,mLevel) != sal_uInt16(0xFFFF) )
306 return;
308 sal_uInt16 nActLv = IsSingleLevel(mLevel);
310 if ( nActLv == sal_uInt16(0xFFFF) )
311 return;
313 SvxNumberFormat aFmt(aNum.GetLevel(nActLv));
314 sal_UCS4 cChar = aFmt.GetBulletChar();
315 const vcl::Font* pFont = aFmt.GetBulletFont();
316 if ( nIndex >= DEFAULT_BULLET_TYPES )
317 return;
319 pActualBullets[nIndex]->cBulletChar = cChar;
320 if ( pFont )
321 pActualBullets[nIndex]->aFont = *pFont;
322 pActualBullets[nIndex]->bIsCustomized = true;
325 void BulletsTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel, bool /*isDefault*/, bool isResetSize)
327 if ( nIndex >= DEFAULT_BULLET_TYPES )
328 return;
329 sal_UCS4 cChar = pActualBullets[nIndex]->cBulletChar;
330 const vcl::Font& rActBulletFont = pActualBullets[nIndex]->aFont;
332 sal_uInt16 nMask = 1;
333 OUString sBulletCharFormatName = GetBulletCharFmtName();
334 for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++)
336 if(mLevel & nMask)
338 SvxNumberFormat aFmt(aNum.GetLevel(i));
339 aFmt.SetNumberingType( SVX_NUM_CHAR_SPECIAL );
340 aFmt.SetBulletFont(&rActBulletFont);
341 aFmt.SetBulletChar(cChar);
342 aFmt.SetCharFormatName(sBulletCharFormatName);
343 aFmt.SetListFormat( "" );
344 if (isResetSize) aFmt.SetBulletRelSize(45);
345 aNum.SetLevel(i, aFmt);
347 nMask <<= 1;
351 OUString BulletsTypeMgr::GetDescription(sal_uInt16 nIndex, bool /*isDefault*/)
353 OUString sRet;
355 if ( nIndex >= DEFAULT_BULLET_TYPES )
356 return sRet;
357 else
358 sRet = pActualBullets[nIndex]->sDescription;
360 return sRet;
363 bool BulletsTypeMgr::IsCustomized(sal_uInt16 nIndex)
365 bool bRet = false;
367 if ( nIndex >= DEFAULT_BULLET_TYPES )
368 bRet = false;
369 else
370 bRet = pActualBullets[nIndex]->bIsCustomized;
372 return bRet;
375 // Numbering Type lib
376 NumberingTypeMgr::NumberingTypeMgr()
377 : NBOTypeMgrBase()
379 Init();
380 maDefaultNumberSettingsArr = maNumberSettingsArr;
381 ImplLoad(u"standard.syb");
384 NumberingTypeMgr::~NumberingTypeMgr()
388 static const char* RID_SVXSTR_SINGLENUM_DESCRIPTIONS[] =
390 RID_SVXSTR_SINGLENUM_DESCRIPTION_0,
391 RID_SVXSTR_SINGLENUM_DESCRIPTION_1,
392 RID_SVXSTR_SINGLENUM_DESCRIPTION_2,
393 RID_SVXSTR_SINGLENUM_DESCRIPTION_3,
394 RID_SVXSTR_SINGLENUM_DESCRIPTION_4,
395 RID_SVXSTR_SINGLENUM_DESCRIPTION_5,
396 RID_SVXSTR_SINGLENUM_DESCRIPTION_6,
397 RID_SVXSTR_SINGLENUM_DESCRIPTION_7
400 namespace {
402 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 std::shared_ptr<NumberSettings_Impl> pNumEntry = std::make_shared<NumberSettings_Impl>();
429 pNumEntry->pNumSetting = pNew;
430 if ( i < 8 )
431 pNumEntry->sDescription = SvxResId(RID_SVXSTR_SINGLENUM_DESCRIPTIONS[i]);
432 maNumberSettingsArr.push_back(pNumEntry);
435 catch(Exception&)
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 const SvxNumberFormat& aFmt(aNum.GetLevel(nActLv));
451 //sal_Unicode cPrefix = OUString(aFmt.GetPrefix())[0];
452 //sal_Unicode cSuffix = :OUString(aFmt.GetSuffix())[0];
453 const OUString& sPrefix = aFmt.GetPrefix();
454 const 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 &&
466 eNumType == eNType )
468 return i+1;
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) )
481 return;
483 const SvxNumberFormat& aFmt(aNum.GetLevel(nActLv));
484 SvxNumType eNumType = aFmt.GetNumberingType();
486 sal_uInt16 nCount = maNumberSettingsArr.size();
487 if ( nIndex >= nCount )
488 return;
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(u"standard.syb");
508 void NumberingTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel, bool isDefault, bool isResetSize)
510 if(maNumberSettingsArr.size() <= nIndex)
511 return;
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++)
521 if(mLevel & nMask)
523 SvxNumberFormat aFmt(aNum.GetLevel(i));
524 if (eNewType!=aFmt.GetNumberingType()) isResetSize=true;
525 aFmt.SetNumberingType(eNewType);
526 aFmt.SetListFormat(_pSet->pNumSetting->sPrefix, _pSet->pNumSetting->sSuffix, i);
527 aFmt.SetCharFormatName(sNumCharFmtName);
528 if (isResetSize) aFmt.SetBulletRelSize(100);
529 aNum.SetLevel(i, aFmt);
531 nMask <<= 1 ;
535 OUString NumberingTypeMgr::GetDescription(sal_uInt16 nIndex, bool isDefault)
537 OUString sRet;
538 sal_uInt16 nLength = maNumberSettingsArr.size();
540 if ( nIndex >= nLength )
541 return sRet;
542 else
543 sRet = maNumberSettingsArr[nIndex]->sDescription;
544 if (isDefault) sRet = maDefaultNumberSettingsArr[nIndex]->sDescription;
546 return sRet;
549 bool NumberingTypeMgr::IsCustomized(sal_uInt16 nIndex)
551 bool bRet = false;
552 sal_uInt16 nLength = maNumberSettingsArr.size();
554 if ( nIndex >= nLength )
555 bRet = false;
556 else
557 bRet = maNumberSettingsArr[nIndex]->bIsCustomized;
559 return bRet;
561 // Multi-level /Outline Type lib
562 OutlineTypeMgr::OutlineTypeMgr()
563 : NBOTypeMgrBase()
565 Init();
566 for(sal_Int32 nItem = 0; nItem < DEFAULT_NUM_VALUSET_COUNT; nItem++ )
568 pDefaultOutlineSettingsArrs[nItem] = pOutlineSettingsArrs[nItem];
570 //Initial the first time to store the default value. Then do it again for customized value
571 Init();
572 ImplLoad(u"standard.syc");
575 namespace {
577 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 10, false,
599 SvxNumRuleType::NUMBERING, SvxNumberFormat::LABEL_ALIGNMENT);
601 auto nSize = std::min<sal_Int32>(aOutlineAccess.getLength(), DEFAULT_NUM_VALUSET_COUNT);
602 for(sal_Int32 nItem = 0; nItem < nSize; nItem++ )
604 pOutlineSettingsArrs[ nItem ] = new OutlineSettings_Impl;
605 OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[ nItem ];
606 pItemArr->sDescription = SvxResId( RID_SVXSTR_OUTLINENUM_DESCRIPTION_0 + nItem );
607 pItemArr->pNumSettingsArr = new NumSettingsArr_Impl;
608 Reference<XIndexAccess> xLevel = aOutlineAccess.getConstArray()[nItem];
609 for(sal_Int32 nLevel = 0; nLevel < xLevel->getCount() && nLevel < 5; nLevel++)
611 Any aValueAny = xLevel->getByIndex(nLevel);
612 Sequence<PropertyValue> aLevelProps;
613 aValueAny >>= aLevelProps;
614 NumSettings_Impl* pNew = lcl_CreateNumberingSettingsPtr(aLevelProps);
615 const SvxNumberFormat& aNumFmt( aDefNumRule.GetLevel( nLevel) );
616 pNew->eLabelFollowedBy = aNumFmt.GetLabelFollowedBy();
617 pNew->nTabValue = aNumFmt.GetListtabPos();
618 pNew->eNumAlign = aNumFmt.GetNumAdjust();
619 pNew->nNumAlignAt = aNumFmt.GetFirstLineIndent();
620 pNew->nNumIndentAt = aNumFmt.GetIndentAt();
621 pItemArr->pNumSettingsArr->push_back(std::shared_ptr<NumSettings_Impl>(pNew));
625 catch(Exception&)
630 sal_uInt16 OutlineTypeMgr::GetNBOIndexForNumRule(SvxNumRule& aNum,sal_uInt16 /*mLevel*/,sal_uInt16 nFromIndex)
632 sal_uInt16 const nLength = SAL_N_ELEMENTS(pOutlineSettingsArrs);
633 for(sal_uInt16 iDex = nFromIndex; iDex < nLength; iDex++)
635 bool bNotMatch = false;
636 OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[iDex];
637 sal_uInt16 nCount = pItemArr->pNumSettingsArr->size();
638 for (sal_uInt16 iLevel=0;iLevel < nCount;iLevel++)
640 NumSettings_Impl* _pSet = (*pItemArr->pNumSettingsArr)[iLevel].get();
641 sal_Int16 eNType = _pSet->nNumberType;
643 const SvxNumberFormat& aFmt(aNum.GetLevel(iLevel));
644 const OUString& sPrefix = aFmt.GetPrefix();
645 const OUString& sLclSuffix = aFmt.GetSuffix();
646 sal_Int16 eNumType = aFmt.GetNumberingType();
647 if( eNumType == SVX_NUM_CHAR_SPECIAL)
649 sal_UCS4 cChar = aFmt.GetBulletChar();
651 sal_UCS4 ccChar
652 = _pSet->sBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
654 if ( !((cChar == ccChar) &&
655 _pSet->eLabelFollowedBy == aFmt.GetLabelFollowedBy() &&
656 _pSet->nTabValue == aFmt.GetListtabPos() &&
657 _pSet->eNumAlign == aFmt.GetNumAdjust() &&
658 _pSet->nNumAlignAt == aFmt.GetFirstLineIndent() &&
659 _pSet->nNumIndentAt == aFmt.GetIndentAt()))
661 bNotMatch = true;
662 break;
664 }else if ((eNumType&(~LINK_TOKEN)) == SVX_NUM_BITMAP ) {
665 const SvxBrushItem* pBrsh1 = aFmt.GetBrush();
666 const SvxBrushItem* pBrsh2 = _pSet->pBrushItem;
667 bool bIsMatch = false;
668 if (pBrsh1==pBrsh2) bIsMatch = true;
669 if (pBrsh1 && pBrsh2) {
670 const Graphic* pGrf1 = pBrsh1->GetGraphic();
671 const Graphic* pGrf2 = pBrsh2->GetGraphic();
672 if (pGrf1==pGrf2) bIsMatch = true;
673 if (pGrf1 && pGrf2) {
674 if ( pGrf1->GetBitmapEx() == pGrf2->GetBitmapEx() &&
675 _pSet->aSize == aFmt.GetGraphicSize())
676 bIsMatch = true;
679 if (!bIsMatch) {
680 bNotMatch = true;
681 break;
683 } else
685 if (!(sPrefix == _pSet->sPrefix &&
686 sLclSuffix == _pSet->sSuffix &&
687 eNumType == eNType &&
688 _pSet->eLabelFollowedBy == aFmt.GetLabelFollowedBy() &&
689 _pSet->nTabValue == aFmt.GetListtabPos() &&
690 _pSet->eNumAlign == aFmt.GetNumAdjust() &&
691 _pSet->nNumAlignAt == aFmt.GetFirstLineIndent() &&
692 _pSet->nNumIndentAt == aFmt.GetIndentAt()))
694 bNotMatch = true;
695 break;
699 if ( !bNotMatch )
700 return iDex+1;
704 return sal_uInt16(0xFFFF);
707 void OutlineTypeMgr::RelplaceNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel)
709 sal_uInt16 const nLength = SAL_N_ELEMENTS(pOutlineSettingsArrs);
710 if ( nIndex >= nLength )
711 return;
713 OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
714 sal_uInt16 nCount = pItemArr->pNumSettingsArr->size();
715 for (sal_uInt16 iLevel=0;iLevel < nCount;iLevel++)
717 const SvxNumberFormat& aFmt(aNum.GetLevel(iLevel));
718 SvxNumType eNumType = aFmt.GetNumberingType();
720 NumSettings_Impl* _pSet = (*pItemArr->pNumSettingsArr)[iLevel].get();
722 _pSet->eLabelFollowedBy = aFmt.GetLabelFollowedBy();
723 _pSet->nTabValue = aFmt.GetListtabPos();
724 _pSet->eNumAlign = aFmt.GetNumAdjust();
725 _pSet->nNumAlignAt = aFmt.GetFirstLineIndent();
726 _pSet->nNumIndentAt = aFmt.GetIndentAt();
728 if( eNumType == SVX_NUM_CHAR_SPECIAL)
730 sal_UCS4 cChar = aFmt.GetBulletChar();
731 OUString sChar(&cChar, 1);
732 _pSet->sBulletChar = sChar;
733 if ( aFmt.GetBulletFont() )
734 _pSet->sBulletFont = aFmt.GetBulletFont()->GetFamilyName();
735 _pSet->nNumberType = eNumType;
736 pItemArr->bIsCustomized = true;
737 }else if ((eNumType&(~LINK_TOKEN)) == SVX_NUM_BITMAP ) {
738 if (_pSet->pBrushItem) {
739 delete _pSet->pBrushItem;
740 _pSet->pBrushItem=nullptr;
742 if (aFmt.GetBrush())
743 _pSet->pBrushItem = new SvxBrushItem(*aFmt.GetBrush());
744 _pSet->aSize = aFmt.GetGraphicSize();
745 _pSet->nNumberType = eNumType;
746 } else
748 _pSet->sPrefix = aFmt.GetPrefix();
749 _pSet->sSuffix = aFmt.GetSuffix();
750 _pSet->nNumberType = eNumType;
751 if ( aFmt.GetBulletFont() )
752 _pSet->sBulletFont = aFmt.GetBulletFont()->GetFamilyName();
753 pItemArr->bIsCustomized = true;
756 SvxNumRule aTmpRule1(aNum);
757 SvxNumRule aTmpRule2(aNum);
758 ApplyNumRule(aTmpRule1,nIndex,mLevel,true);
759 ApplyNumRule(aTmpRule2,nIndex,mLevel);
760 if (aTmpRule1==aTmpRule2) pItemArr->bIsCustomized=false;
761 if (!pItemArr->bIsCustomized) {
762 pItemArr->sDescription = GetDescription(nIndex,true);
764 ImplStore(u"standard.syc");
767 void OutlineTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 /*mLevel*/, bool isDefault, bool isResetSize)
769 DBG_ASSERT(DEFAULT_NUM_VALUSET_COUNT > nIndex, "wrong index");
770 if(DEFAULT_NUM_VALUSET_COUNT <= nIndex)
771 return;
773 const FontList* pList = nullptr;
775 OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
776 if (isDefault) pItemArr=pDefaultOutlineSettingsArrs[nIndex];
778 NumSettingsArr_Impl *pNumSettingsArr=pItemArr->pNumSettingsArr;
780 NumSettings_Impl* pLevelSettings = nullptr;
781 for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++)
783 if(pNumSettingsArr->size() > i)
784 pLevelSettings = (*pNumSettingsArr)[i].get();
786 if(!pLevelSettings)
787 break;
789 SvxNumberFormat aFmt(aNum.GetLevel(i));
790 const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
791 if (pLevelSettings->nNumberType !=aFmt.GetNumberingType()) isResetSize=true;
792 aFmt.SetNumberingType( pLevelSettings->nNumberType );
793 sal_uInt16 nUpperLevelOrChar = static_cast<sal_uInt16>(pLevelSettings->nParentNumbering);
794 if(aFmt.GetNumberingType() == SVX_NUM_CHAR_SPECIAL)
796 if( pLevelSettings->sBulletFont.getLength() &&
797 pLevelSettings->sBulletFont != rActBulletFont.GetFamilyName() )
799 //search for the font
800 if(!pList)
802 SfxObjectShell* pCurDocShell = SfxObjectShell::Current();
803 const SvxFontListItem* pFontListItem = static_cast<const SvxFontListItem*>( pCurDocShell->GetItem( SID_ATTR_CHAR_FONTLIST ) );
804 pList = pFontListItem ? pFontListItem->GetFontList() : nullptr;
806 if(pList && pList->IsAvailable( pLevelSettings->sBulletFont ) )
808 FontMetric aFontMetric = pList->Get(pLevelSettings->sBulletFont,WEIGHT_NORMAL, ITALIC_NONE);
809 vcl::Font aFont(aFontMetric);
810 aFmt.SetBulletFont(&aFont);
812 else
814 //if it cannot be found then create a new one
815 vcl::Font aCreateFont( pLevelSettings->sBulletFont, OUString(), Size( 0, 14 ) );
816 aCreateFont.SetCharSet( RTL_TEXTENCODING_DONTKNOW );
817 aCreateFont.SetFamily( FAMILY_DONTKNOW );
818 aCreateFont.SetPitch( PITCH_DONTKNOW );
819 aCreateFont.SetWeight( WEIGHT_DONTKNOW );
820 aCreateFont.SetTransparent( true );
821 aFmt.SetBulletFont( &aCreateFont );
823 }else
824 aFmt.SetBulletFont( &rActBulletFont );
826 sal_UCS4 cChar = 0;
827 if( !pLevelSettings->sBulletChar.isEmpty() )
829 cChar
830 = pLevelSettings->sBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
832 if( AllSettings::GetLayoutRTL() )
834 if( 0 == i && cChar == BulletsTypeMgr::aDynamicBulletTypes[5] )
835 cChar = BulletsTypeMgr::aDynamicRTLBulletTypes[5];
836 else if( 1 == i )
838 const SvxNumberFormat& numberFmt = aNum.GetLevel(0);
839 if( numberFmt.GetBulletChar() == BulletsTypeMgr::aDynamicRTLBulletTypes[5] )
840 cChar = BulletsTypeMgr::aDynamicRTLBulletTypes[4];
844 aFmt.SetBulletChar(cChar);
845 aFmt.SetCharFormatName( GetBulletCharFmtName() );
846 if (isResetSize) aFmt.SetBulletRelSize(45);
847 }else if ((aFmt.GetNumberingType()&(~LINK_TOKEN)) == SVX_NUM_BITMAP ) {
848 if (pLevelSettings->pBrushItem) {
849 const Graphic* pGrf = pLevelSettings->pBrushItem->GetGraphic();
850 Size aSize = pLevelSettings->aSize;
851 sal_Int16 eOrient = text::VertOrientation::LINE_CENTER;
852 if (!isResetSize && aFmt.GetGraphicSize()!=Size(0,0))\
853 aSize = aFmt.GetGraphicSize();
854 else if (aSize.IsEmpty() && pGrf)
855 aSize = SvxNumberFormat::GetGraphicSizeMM100( pGrf );
856 aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(GetMapUnit()));
857 aFmt.SetGraphicBrush( pLevelSettings->pBrushItem, &aSize, &eOrient );
859 } else
861 aFmt.SetIncludeUpperLevels(sal::static_int_cast< sal_uInt8 >(0 != nUpperLevelOrChar ? aNum.GetLevelCount() : 1));
862 aFmt.SetCharFormatName(GetNumCharFmtName());
863 if (isResetSize) aFmt.SetBulletRelSize(100);
865 if(pNumSettingsArr->size() > i) {
866 aFmt.SetLabelFollowedBy(pLevelSettings->eLabelFollowedBy);
867 aFmt.SetListtabPos(pLevelSettings->nTabValue);
868 aFmt.SetNumAdjust(pLevelSettings->eNumAlign);
869 aFmt.SetFirstLineIndent(pLevelSettings->nNumAlignAt);
870 aFmt.SetIndentAt(pLevelSettings->nNumIndentAt);
872 aFmt.SetListFormat(pLevelSettings->sPrefix, pLevelSettings->sSuffix, i);
873 aNum.SetLevel(i, aFmt);
877 OUString OutlineTypeMgr::GetDescription(sal_uInt16 nIndex, bool isDefault)
879 OUString sRet;
881 if ( nIndex >= SAL_N_ELEMENTS(pOutlineSettingsArrs) )
882 return sRet;
883 else
885 OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
886 if (isDefault) pItemArr = pDefaultOutlineSettingsArrs[nIndex];
887 if ( pItemArr )
889 sRet = pItemArr->sDescription;
892 return sRet;
895 bool OutlineTypeMgr::IsCustomized(sal_uInt16 nIndex)
897 bool bRet = false;
899 if ( nIndex >= SAL_N_ELEMENTS(pOutlineSettingsArrs) )
900 return bRet;
901 else
903 OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
904 if ( pItemArr )
906 bRet = pItemArr->bIsCustomized;
910 return bRet;
916 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */