Adjust includes
[LibreOffice.git] / svx / source / sidebar / nbdtmg.cxx
blob540e65387d7ddc9c08b3f10641640b63cfba6abc
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 <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>
54 #include <memory>
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 {
66 namespace {
68 const vcl::Font& lcl_GetDefaultBulletFont()
70 static bool bInit = false;
71 static vcl::Font aDefBulletFont("OpenSymbol", "", Size(0, 14));
72 if(!bInit)
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 );
79 bInit = true;
81 return aDefBulletFont;
84 const sal_Unicode aDefaultBulletTypes[] =
86 0x2022,
87 0x25cf,
88 0xe00c,
89 0xe00a,
90 0x2794,
91 0x27a2,
92 0x2717,
93 0x2714
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")
104 sal_Int16 nTmp;
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();
123 return pNew;
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)
137 nCount++;
138 nLv=i;
140 nMask <<= 1 ;
143 if ( nCount == 1)
144 return nLv;
145 else
146 return (sal_uInt16)0xFFFF;
149 void NBOTypeMgrBase::SetItems(const SfxItemSet* pArg) {
150 pSet = pArg;
151 if ( pSet )
153 SfxAllItemSet aSet(*pSet);
155 const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
156 if (pBulletCharFmt)
157 aBulletCharFmtName = pBulletCharFmt->GetValue();
159 const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
160 if (pNumCharFmt)
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));
168 } else {
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)
181 bIsLoading = true;
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 ));
187 if( xIStm ) {
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);
204 aFont.SetColor(c);
205 aFmt.SetBulletFont(&aFont);
206 aNum.SetLevel(i, aFmt);
209 RelplaceNumRule(aNum,nNumIndex,0x1/*nLevel*/);
210 xIStm->ReadInt32( nNumIndex );
214 eCoreUnit = eOldCoreUnit;
215 bIsLoading = false;
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 ));
225 if( xOStm ) {
226 sal_uInt32 nVersion;
227 sal_Int32 nNumIndex;
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,
234 10, false,
235 SvxNumRuleType::NUMBERING, SvxNumberFormat::LABEL_ALIGNMENT);
236 xOStm->WriteInt32( nItem );
237 ApplyNumRule(aDefNumRule,nItem,0x1/*nLevel*/,false,true);
238 aDefNumRule.Store(*xOStm);
241 nNumIndex = -1;
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()
253 : NBOTypeMgrBase()
255 Init();
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) )
296 return i+1;
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)
306 return;
308 if ( GetNBOIndexForNumRule(aNum,mLevel) != (sal_uInt16)0xFFFF )
309 return;
311 sal_uInt16 nActLv = IsSingleLevel(mLevel);
313 if ( nActLv == (sal_uInt16)0xFFFF )
314 return;
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 )
320 return;
322 pActualBullets[nIndex]->cBulletChar = cChar;
323 if ( pFont )
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 )
331 return;
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++)
339 if(mLevel & nMask)
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);
351 nMask <<= 1;
355 OUString BulletsTypeMgr::GetDescription(sal_uInt16 nIndex, bool /*isDefault*/)
357 OUString sRet;
359 if ( nIndex >= DEFAULT_BULLET_TYPES )
360 return sRet;
361 else
362 sRet = pActualBullets[nIndex]->sDescription;
364 return sRet;
367 bool BulletsTypeMgr::IsCustomized(sal_uInt16 nIndex)
369 bool bRet = false;
371 if ( nIndex >= DEFAULT_BULLET_TYPES )
372 bRet = false;
373 else
374 bRet = pActualBullets[nIndex]->bIsCustomized;
376 return bRet;
379 // Numbering Type lib
380 NumberingTypeMgr::NumberingTypeMgr()
381 : NBOTypeMgrBase()
383 Init();
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;
430 if ( i < 8 )
431 pNumEntry->sDescription = SvxResId(RID_SVXSTR_SINGLENUM_DESCRIPTIONS[i]);
432 maNumberSettingsArr.push_back(std::shared_ptr<NumberSettings_Impl>(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 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 &&
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 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("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.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);
533 nMask <<= 1 ;
537 OUString NumberingTypeMgr::GetDescription(sal_uInt16 nIndex, bool isDefault)
539 OUString sRet;
540 sal_uInt16 nLength = 0;
541 nLength = maNumberSettingsArr.size();
543 if ( nIndex >= nLength )
544 return sRet;
545 else
546 sRet = maNumberSettingsArr[nIndex]->sDescription;
547 if (isDefault) sRet = maDefaultNumberSettingsArr[nIndex]->sDescription;
549 return sRet;
552 bool NumberingTypeMgr::IsCustomized(sal_uInt16 nIndex)
554 bool bRet = false;
555 sal_uInt16 nLength = 0;
556 nLength = maNumberSettingsArr.size();
558 if ( nIndex >= nLength )
559 bRet = false;
560 else
561 bRet = maNumberSettingsArr[nIndex]->bIsCustomized;
563 return bRet;
565 // Multi-level /Outline Type lib
566 OutlineTypeMgr::OutlineTypeMgr()
567 : NBOTypeMgrBase()
569 Init();
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
575 Init();
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,
599 10, false,
600 SvxNumRuleType::NUMBERING, SvxNumberFormat::LABEL_ALIGNMENT);
602 for(sal_Int32 nItem = 0;
603 nItem < aOutlineAccess.getLength() && nItem < DEFAULT_NUM_VALUSET_COUNT;
604 nItem++ )
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));
627 catch(Exception&)
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()))
660 bNotMatch = true;
661 break;
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())
675 bIsMatch = true;
678 if (!bIsMatch) {
679 bNotMatch = true;
680 break;
682 } else
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()))
693 bNotMatch = true;
694 break;
698 if ( !bNotMatch )
699 return iDex+1;
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 )
710 return;
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;
741 if (aFmt.GetBrush())
742 _pSet->pBrushItem = new SvxBrushItem(*aFmt.GetBrush());
743 _pSet->aSize = aFmt.GetGraphicSize();
744 _pSet->nNumberType = eNumType;
745 } else
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)
770 return;
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();
785 if(!pLevelSettings)
786 break;
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
799 if(!pList)
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);
811 else
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 );
822 }else
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];
832 else if( 1 == i )
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();
849 else {
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 );
857 } else
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)
878 OUString sRet;
880 if ( nIndex >= SAL_N_ELEMENTS(pOutlineSettingsArrs) )
881 return sRet;
882 else
884 OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
885 if (isDefault) pItemArr = pDefaultOutlineSettingsArrs[nIndex];
886 if ( pItemArr )
888 sRet = pItemArr->sDescription;
891 return sRet;
894 bool OutlineTypeMgr::IsCustomized(sal_uInt16 nIndex)
896 bool bRet = false;
898 if ( nIndex >= SAL_N_ELEMENTS(pOutlineSettingsArrs) )
899 return bRet;
900 else
902 OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
903 if ( pItemArr )
905 bRet = pItemArr->bIsCustomized;
909 return bRet;
915 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */