summaryrefslogtreecommitdiffstats
path: root/svx/source/sidebar/nbdtmg.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/sidebar/nbdtmg.cxx')
-rw-r--r--svx/source/sidebar/nbdtmg.cxx905
1 files changed, 905 insertions, 0 deletions
diff --git a/svx/source/sidebar/nbdtmg.cxx b/svx/source/sidebar/nbdtmg.cxx
new file mode 100644
index 000000000..241b91673
--- /dev/null
+++ b/svx/source/sidebar/nbdtmg.cxx
@@ -0,0 +1,905 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <svx/nbdtmg.hxx>
+#include <svx/svxids.hrc>
+#include <vcl/svapp.hxx>
+#include <svl/itemset.hxx>
+#include <sfx2/request.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/ctrltool.hxx>
+#include <sfx2/objsh.hxx>
+#include <editeng/flstitem.hxx>
+#include <svl/itempool.hxx>
+#include <vcl/outdev.hxx>
+#include <editeng/brushitem.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <vcl/graph.hxx>
+#include <vcl/settings.hxx>
+
+#include <i18nlangtag/languagetag.hxx>
+#include <o3tl/temporary.hxx>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/pathoptions.hxx>
+#include <editeng/eeitem.hxx>
+
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/style/NumberingType.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/text/DefaultNumberingProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <comphelper/processfactory.hxx>
+#include <memory>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::text;
+using namespace com::sun::star::container;
+using namespace com::sun::star::style;
+
+namespace svx::sidebar {
+
+namespace {
+
+const vcl::Font& lcl_GetDefaultBulletFont()
+{
+ static vcl::Font aDefBulletFont = []()
+ {
+ static vcl::Font tmp("OpenSymbol", "", Size(0, 14));
+ tmp.SetCharSet( RTL_TEXTENCODING_SYMBOL );
+ tmp.SetFamily( FAMILY_DONTKNOW );
+ tmp.SetPitch( PITCH_DONTKNOW );
+ tmp.SetWeight( WEIGHT_DONTKNOW );
+ tmp.SetTransparent( true );
+ return tmp;
+ }();
+ return aDefBulletFont;
+}
+
+const sal_Unicode aDefaultBulletTypes[] =
+{
+ 0x2022,
+ 0x25cf,
+ 0xe00c,
+ 0xe00a,
+ 0x2794,
+ 0x27a2,
+ 0x2717,
+ 0x2714
+};
+
+NumSettings_Impl* lcl_CreateNumberingSettingsPtr(const Sequence<PropertyValue>& rLevelProps)
+{
+ NumSettings_Impl* pNew = new NumSettings_Impl;
+ for(const PropertyValue& rValue : rLevelProps)
+ {
+ if(rValue.Name == "NumberingType")
+ {
+ sal_Int16 nTmp;
+ if (rValue.Value >>= nTmp)
+ pNew->nNumberType = static_cast<SvxNumType>(nTmp);
+ }
+ else if(rValue.Name == "Prefix")
+ rValue.Value >>= pNew->sPrefix;
+ else if(rValue.Name == "Suffix")
+ rValue.Value >>= pNew->sSuffix;
+ else if(rValue.Name == "ParentNumbering")
+ rValue.Value >>= pNew->nParentNumbering;
+ else if(rValue.Name == "BulletChar")
+ rValue.Value >>= pNew->sBulletChar;
+ else if(rValue.Name == "BulletFontName")
+ rValue.Value >>= pNew->sBulletFont;
+ }
+ const sal_Unicode cLocalPrefix = pNew->sPrefix.getLength() ? pNew->sPrefix[0] : 0;
+ const sal_Unicode cLocalSuffix = pNew->sSuffix.getLength() ? pNew->sSuffix[0] : 0;
+ if( cLocalPrefix == ' ') pNew->sPrefix.clear();
+ if( cLocalSuffix == ' ') pNew->sSuffix.clear();
+ return pNew;
+}
+
+}
+
+sal_uInt16 NBOTypeMgrBase:: IsSingleLevel(sal_uInt16 nCurLevel)
+{
+ sal_uInt16 nLv = sal_uInt16(0xFFFF);
+ sal_uInt16 nCount = 0;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < SVX_MAX_NUM; i++ )
+ {
+ if(nCurLevel & nMask)
+ {
+ nCount++;
+ nLv=i;
+ }
+ nMask <<= 1 ;
+ }
+
+ if ( nCount == 1)
+ return nLv;
+ else
+ return sal_uInt16(0xFFFF);
+}
+
+void NBOTypeMgrBase::SetItems(const SfxItemSet* pArg) {
+ pSet = pArg;
+ if ( !pSet )
+ return;
+
+ SfxAllItemSet aSet(*pSet);
+
+ const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
+ if (pBulletCharFmt)
+ aBulletCharFmtName = pBulletCharFmt->GetValue();
+
+ const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
+ if (pNumCharFmt)
+ aNumCharFmtName = pNumCharFmt->GetValue();
+
+ const SfxPoolItem* pItem;
+ SfxItemState eState = pSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
+ if(eState == SfxItemState::SET)
+ {
+ eCoreUnit = pSet->GetPool()->GetMetric(pSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
+ } else {
+ //sd use different sid for numbering rule
+ eState = pSet->GetItemState(EE_PARA_NUMBULLET, false, &pItem);
+ if(eState == SfxItemState::SET)
+ {
+ eCoreUnit = pSet->GetPool()->GetMetric(pSet->GetPool()->GetWhich(EE_PARA_NUMBULLET));
+ }
+ }
+}
+
+void NBOTypeMgrBase::ImplLoad(std::u16string_view filename)
+{
+ bIsLoading = true;
+ MapUnit eOldCoreUnit=eCoreUnit;
+ eCoreUnit = MapUnit::Map100thMM;
+ INetURLObject aFile( SvtPathOptions().GetUserConfigPath() );
+ aFile.Append( filename);
+ std::unique_ptr<SvStream> xIStm(::utl::UcbStreamHelper::CreateStream( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
+ if( xIStm ) {
+ sal_uInt32 nVersion = 0;
+ sal_Int32 nNumIndex = 0;
+ xIStm->ReadUInt32( nVersion );
+ if (nVersion==DEFAULT_NUMBERING_CACHE_FORMAT_VERSION) //first version
+ {
+ xIStm->ReadInt32( nNumIndex );
+ while (nNumIndex>=0 && nNumIndex<DEFAULT_NUM_VALUSET_COUNT) {
+ SvxNumRule aNum(*xIStm);
+ //bullet color in font properties is not stored correctly. Need set transparency bits manually
+ for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++)
+ {
+ SvxNumberFormat aFmt(aNum.GetLevel(i));
+ if (aFmt.GetBulletFont()) {
+ vcl::Font aFont(*aFmt.GetBulletFont());
+ Color c=aFont.GetColor();
+ c.SetAlpha(0);
+ aFont.SetColor(c);
+ aFmt.SetBulletFont(&aFont);
+ aNum.SetLevel(i, aFmt);
+ }
+ }
+ RelplaceNumRule(aNum,nNumIndex,0x1/*nLevel*/);
+ xIStm->ReadInt32( nNumIndex );
+ }
+ }
+ }
+ eCoreUnit = eOldCoreUnit;
+ bIsLoading = false;
+}
+void NBOTypeMgrBase::ImplStore(std::u16string_view filename)
+{
+ if (bIsLoading) return;
+ MapUnit eOldCoreUnit=eCoreUnit;
+ eCoreUnit = MapUnit::Map100thMM;
+ INetURLObject aFile( SvtPathOptions().GetUserConfigPath() );
+ aFile.Append( filename);
+ std::unique_ptr<SvStream> xOStm(::utl::UcbStreamHelper::CreateStream( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE ));
+ if( xOStm ) {
+ sal_uInt32 nVersion;
+ sal_Int32 nNumIndex;
+ nVersion = DEFAULT_NUMBERING_CACHE_FORMAT_VERSION;
+ xOStm->WriteUInt32( nVersion );
+ for(sal_Int32 nItem = 0; nItem < DEFAULT_NUM_VALUSET_COUNT; nItem++ ) {
+ if (IsCustomized(nItem)) {
+ SvxNumRule aDefNumRule( SvxNumRuleFlags::BULLET_REL_SIZE | SvxNumRuleFlags::CONTINUOUS | SvxNumRuleFlags::BULLET_COLOR,
+ 10, false,
+ SvxNumRuleType::NUMBERING, SvxNumberFormat::LABEL_ALIGNMENT);
+ xOStm->WriteInt32( nItem );
+ ApplyNumRule(aDefNumRule,nItem,0x1/*nLevel*/,false,true);
+ aDefNumRule.Store(*xOStm);
+ }
+ }
+ nNumIndex = -1;
+ xOStm->WriteInt32( nNumIndex ); //write end flag
+ }
+ eCoreUnit = eOldCoreUnit;
+}
+
+// Character Bullet Type lib
+BulletsSettings* BulletsTypeMgr::pActualBullets[] ={nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr};
+sal_Unicode BulletsTypeMgr::aDynamicBulletTypes[]={' ',' ',' ',' ',' ',' ',' ',' '};
+sal_Unicode BulletsTypeMgr::aDynamicRTLBulletTypes[]={' ',' ',' ',' ',' ',' ',' ',' '};
+
+BulletsTypeMgr::BulletsTypeMgr()
+{
+ Init();
+}
+
+BulletsTypeMgr& BulletsTypeMgr::GetInstance()
+{
+ static BulletsTypeMgr theBulletsTypeMgr;
+ return theBulletsTypeMgr;
+}
+
+void BulletsTypeMgr::Init()
+{
+ const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
+
+ for (sal_uInt16 i=0;i<DEFAULT_BULLET_TYPES;i++)
+ {
+ pActualBullets[i] = new BulletsSettings;
+ pActualBullets[i]->cBulletChar = aDefaultBulletTypes[i];
+ pActualBullets[i]->aFont = rActBulletFont;
+ OString id = OString::Concat(RID_SVXSTR_BULLET_DESCRIPTION_0.mpId) + OString::number(i);
+ pActualBullets[i]->sDescription = SvxResId( TranslateId(RID_SVXSTR_BULLET_DESCRIPTION_0.mpContext, id.getStr()) );
+ }
+}
+sal_uInt16 BulletsTypeMgr::GetNBOIndexForNumRule(SvxNumRule& aNum,sal_uInt16 mLevel,sal_uInt16 nFromIndex)
+{
+ if ( mLevel == sal_uInt16(0xFFFF) || mLevel == 0)
+ return sal_uInt16(0xFFFF);
+ //if ( !lcl_IsNumFmtSet(pNR, mLevel) ) return (sal_uInt16)0xFFFF;
+
+ sal_uInt16 nActLv = IsSingleLevel(mLevel);
+
+ if ( nActLv == sal_uInt16(0xFFFF) )
+ return sal_uInt16(0xFFFF);
+
+ const SvxNumberFormat& aFmt(aNum.GetLevel(nActLv));
+ sal_UCS4 cChar = aFmt.GetBulletChar();
+ for(sal_uInt16 i = nFromIndex; i < DEFAULT_BULLET_TYPES; i++)
+ {
+ if ( (cChar == pActualBullets[i]->cBulletChar) ||
+ (cChar == 9830 && 57356 == pActualBullets[i]->cBulletChar) ||
+ (cChar == 9632 && 57354 == pActualBullets[i]->cBulletChar) )
+ {
+ return i+1;
+ }
+ }
+
+ return sal_uInt16(0xFFFF);
+}
+
+void BulletsTypeMgr::RelplaceNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel)
+{
+ if ( mLevel == sal_uInt16(0xFFFF) || mLevel == 0)
+ return;
+
+ if ( GetNBOIndexForNumRule(aNum,mLevel) != sal_uInt16(0xFFFF) )
+ return;
+
+ sal_uInt16 nActLv = IsSingleLevel(mLevel);
+
+ if ( nActLv == sal_uInt16(0xFFFF) )
+ return;
+
+ SvxNumberFormat aFmt(aNum.GetLevel(nActLv));
+ sal_UCS4 cChar = aFmt.GetBulletChar();
+ std::optional<vcl::Font> pFont = aFmt.GetBulletFont();
+ if ( nIndex >= DEFAULT_BULLET_TYPES )
+ return;
+
+ pActualBullets[nIndex]->cBulletChar = cChar;
+ if ( pFont )
+ pActualBullets[nIndex]->aFont = *pFont;
+ pActualBullets[nIndex]->bIsCustomized = true;
+}
+
+void BulletsTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel, bool /*isDefault*/, bool isResetSize)
+{
+ if ( nIndex >= DEFAULT_BULLET_TYPES )
+ return;
+ sal_UCS4 cChar = pActualBullets[nIndex]->cBulletChar;
+ const vcl::Font& rActBulletFont = pActualBullets[nIndex]->aFont;
+
+ sal_uInt16 nMask = 1;
+ OUString sBulletCharFormatName = GetBulletCharFmtName();
+ for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++)
+ {
+ if(mLevel & nMask)
+ {
+ SvxNumberFormat aFmt(aNum.GetLevel(i));
+ aFmt.SetNumberingType( SVX_NUM_CHAR_SPECIAL );
+ aFmt.SetBulletFont(&rActBulletFont);
+ aFmt.SetBulletChar(cChar);
+ aFmt.SetCharFormatName(sBulletCharFormatName);
+ aFmt.SetListFormat( "" );
+ if (isResetSize) aFmt.SetBulletRelSize(45);
+ aNum.SetLevel(i, aFmt);
+ }
+ nMask <<= 1;
+ }
+}
+
+OUString BulletsTypeMgr::GetDescription(sal_uInt16 nIndex, bool /*isDefault*/)
+{
+ OUString sRet;
+
+ if ( nIndex >= DEFAULT_BULLET_TYPES )
+ return sRet;
+ else
+ sRet = pActualBullets[nIndex]->sDescription;
+
+ return sRet;
+}
+
+bool BulletsTypeMgr::IsCustomized(sal_uInt16 nIndex)
+{
+ bool bRet = false;
+
+ if ( nIndex >= DEFAULT_BULLET_TYPES )
+ bRet = false;
+ else
+ bRet = pActualBullets[nIndex]->bIsCustomized;
+
+ return bRet;
+}
+
+// Numbering Type lib
+NumberingTypeMgr::NumberingTypeMgr()
+{
+ Init();
+ maDefaultNumberSettingsArr = maNumberSettingsArr;
+ ImplLoad(u"standard.syb");
+}
+
+NumberingTypeMgr::~NumberingTypeMgr()
+{
+}
+
+const TranslateId RID_SVXSTR_SINGLENUM_DESCRIPTIONS[] =
+{
+ RID_SVXSTR_SINGLENUM_DESCRIPTION_0,
+ RID_SVXSTR_SINGLENUM_DESCRIPTION_1,
+ RID_SVXSTR_SINGLENUM_DESCRIPTION_2,
+ RID_SVXSTR_SINGLENUM_DESCRIPTION_3,
+ RID_SVXSTR_SINGLENUM_DESCRIPTION_4,
+ RID_SVXSTR_SINGLENUM_DESCRIPTION_5,
+ RID_SVXSTR_SINGLENUM_DESCRIPTION_6,
+ RID_SVXSTR_SINGLENUM_DESCRIPTION_7
+};
+
+NumberingTypeMgr& NumberingTypeMgr::GetInstance()
+{
+ static NumberingTypeMgr theNumberingTypeMgr;
+ return theNumberingTypeMgr;
+}
+
+void NumberingTypeMgr::Init()
+{
+ Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference<XDefaultNumberingProvider> xDefNum = DefaultNumberingProvider::create( xContext );
+
+ Sequence< Sequence< PropertyValue > > aNumberings;
+ Locale aLocale(Application::GetSettings().GetLanguageTag().getLocale());
+ try
+ {
+ aNumberings = xDefNum->getDefaultContinuousNumberingLevels( aLocale );
+
+ sal_Int32 nLength = aNumberings.getLength();
+
+ const Sequence<PropertyValue>* pValuesArr = aNumberings.getConstArray();
+ for(sal_Int32 i = 0; i < nLength; i++)
+ {
+ NumSettings_Impl* pNew = lcl_CreateNumberingSettingsPtr(pValuesArr[i]);
+ std::shared_ptr<NumberSettings_Impl> pNumEntry = std::make_shared<NumberSettings_Impl>();
+ pNumEntry->pNumSetting = pNew;
+ if ( i < 8 )
+ pNumEntry->sDescription = SvxResId(RID_SVXSTR_SINGLENUM_DESCRIPTIONS[i]);
+ maNumberSettingsArr.push_back(pNumEntry);
+ }
+ }
+ catch(Exception&)
+ {
+ }
+}
+
+sal_uInt16 NumberingTypeMgr::GetNBOIndexForNumRule(SvxNumRule& aNum,sal_uInt16 mLevel,sal_uInt16 nFromIndex)
+{
+ if ( mLevel == sal_uInt16(0xFFFF) || mLevel > aNum.GetLevelCount() || mLevel == 0)
+ return sal_uInt16(0xFFFF);
+
+ sal_uInt16 nActLv = IsSingleLevel(mLevel);
+
+ if ( nActLv == sal_uInt16(0xFFFF) )
+ return sal_uInt16(0xFFFF);
+
+ const SvxNumberFormat& aFmt(aNum.GetLevel(nActLv));
+ //sal_Unicode cPrefix = OUString(aFmt.GetPrefix())[0];
+ //sal_Unicode cSuffix = :OUString(aFmt.GetSuffix())[0];
+ const OUString& sPrefix = aFmt.GetPrefix();
+ const OUString& sLclSuffix = aFmt.GetSuffix();
+ sal_Int16 eNumType = aFmt.GetNumberingType();
+
+ sal_uInt16 nCount = maNumberSettingsArr.size();
+ for(sal_uInt16 i = nFromIndex; i < nCount; ++i)
+ {
+ NumberSettings_Impl* _pSet = maNumberSettingsArr[i].get();
+ sal_Int16 eNType = _pSet->pNumSetting->nNumberType;
+ OUString sLocalPrefix = _pSet->pNumSetting->sPrefix;
+ OUString sLocalSuffix = _pSet->pNumSetting->sSuffix;
+ if (sPrefix == sLocalPrefix &&
+ sLclSuffix == sLocalSuffix &&
+ eNumType == eNType )
+ {
+ return i+1;
+ }
+ }
+
+
+ return sal_uInt16(0xFFFF);
+}
+
+void NumberingTypeMgr::RelplaceNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel)
+{
+ sal_uInt16 nActLv = IsSingleLevel(mLevel);
+
+ if ( nActLv == sal_uInt16(0xFFFF) )
+ return;
+
+ const SvxNumberFormat& aFmt(aNum.GetLevel(nActLv));
+ SvxNumType eNumType = aFmt.GetNumberingType();
+
+ sal_uInt16 nCount = maNumberSettingsArr.size();
+ if ( nIndex >= nCount )
+ return;
+
+ NumberSettings_Impl* _pSet = maNumberSettingsArr[nIndex].get();
+
+ _pSet->pNumSetting->sPrefix = aFmt.GetPrefix();
+ _pSet->pNumSetting->sSuffix = aFmt.GetSuffix();
+ _pSet->pNumSetting->nNumberType = eNumType;
+ _pSet->bIsCustomized = true;
+
+ SvxNumRule aTmpRule1(aNum);
+ SvxNumRule aTmpRule2(aNum);
+ ApplyNumRule(aTmpRule1,nIndex,mLevel,true);
+ ApplyNumRule(aTmpRule2,nIndex,mLevel);
+ if (aTmpRule1==aTmpRule2) _pSet->bIsCustomized=false;
+ if (!_pSet->bIsCustomized) {
+ _pSet->sDescription = GetDescription(nIndex,true);
+ }
+ ImplStore(u"standard.syb");
+}
+
+void NumberingTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel, bool isDefault, bool isResetSize)
+{
+ if(maNumberSettingsArr.size() <= nIndex)
+ return;
+ NumberSettingsArr_Impl* pCurrentNumberSettingsArr = &maNumberSettingsArr;
+ if (isDefault) pCurrentNumberSettingsArr = &maDefaultNumberSettingsArr;
+ NumberSettings_Impl* _pSet = (*pCurrentNumberSettingsArr)[nIndex].get();
+ SvxNumType eNewType = _pSet->pNumSetting->nNumberType;
+
+ sal_uInt16 nMask = 1;
+ OUString sNumCharFmtName = GetNumCharFmtName();
+ for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++)
+ {
+ if(mLevel & nMask)
+ {
+ SvxNumberFormat aFmt(aNum.GetLevel(i));
+ if (eNewType!=aFmt.GetNumberingType()) isResetSize=true;
+ aFmt.SetNumberingType(eNewType);
+ aFmt.SetListFormat(_pSet->pNumSetting->sPrefix, _pSet->pNumSetting->sSuffix, i);
+ aFmt.SetCharFormatName(sNumCharFmtName);
+ if (isResetSize) aFmt.SetBulletRelSize(100);
+ aNum.SetLevel(i, aFmt);
+ }
+ nMask <<= 1 ;
+ }
+}
+
+OUString NumberingTypeMgr::GetDescription(sal_uInt16 nIndex, bool isDefault)
+{
+ OUString sRet;
+ sal_uInt16 nLength = maNumberSettingsArr.size();
+
+ if ( nIndex >= nLength )
+ return sRet;
+ else
+ sRet = maNumberSettingsArr[nIndex]->sDescription;
+ if (isDefault) sRet = maDefaultNumberSettingsArr[nIndex]->sDescription;
+
+ return sRet;
+}
+
+bool NumberingTypeMgr::IsCustomized(sal_uInt16 nIndex)
+{
+ bool bRet = false;
+ sal_uInt16 nLength = maNumberSettingsArr.size();
+
+ if ( nIndex >= nLength )
+ bRet = false;
+ else
+ bRet = maNumberSettingsArr[nIndex]->bIsCustomized;
+
+ return bRet;
+}
+// Multi-level /Outline Type lib
+OutlineTypeMgr::OutlineTypeMgr()
+{
+ Init();
+ for(sal_Int32 nItem = 0; nItem < DEFAULT_NUM_VALUSET_COUNT; nItem++ )
+ {
+ pDefaultOutlineSettingsArrs[nItem] = pOutlineSettingsArrs[nItem];
+ }
+ //Initial the first time to store the default value. Then do it again for customized value
+ Init();
+ ImplLoad(u"standard.syc");
+}
+
+OutlineTypeMgr& OutlineTypeMgr::GetInstance()
+{
+ static OutlineTypeMgr theOutlineTypeMgr;
+ return theOutlineTypeMgr;
+}
+
+void OutlineTypeMgr::Init()
+{
+ Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference<XDefaultNumberingProvider> xDefNum = DefaultNumberingProvider::create( xContext );
+
+ Sequence<Reference<XIndexAccess> > aOutlineAccess;
+ Locale aLocale(Application::GetSettings().GetLanguageTag().getLocale());
+ try
+ {
+ aOutlineAccess = xDefNum->getDefaultOutlineNumberings( aLocale );
+
+ SvxNumRule aDefNumRule( SvxNumRuleFlags::BULLET_REL_SIZE | SvxNumRuleFlags::CONTINUOUS | SvxNumRuleFlags::BULLET_COLOR,
+ 10, false,
+ SvxNumRuleType::NUMBERING, SvxNumberFormat::LABEL_ALIGNMENT);
+
+ auto nSize = std::min<sal_Int32>(aOutlineAccess.getLength(), DEFAULT_NUM_VALUSET_COUNT);
+ for(sal_Int32 nItem = 0; nItem < nSize; nItem++ )
+ {
+ pOutlineSettingsArrs[ nItem ] = new OutlineSettings_Impl;
+ OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[ nItem ];
+ OString id = OString::Concat(RID_SVXSTR_OUTLINENUM_DESCRIPTION_0.mpId) + OString::number(nItem);
+ pItemArr->sDescription = SvxResId( TranslateId(RID_SVXSTR_OUTLINENUM_DESCRIPTION_0.mpContext, id.getStr()) );
+ pItemArr->pNumSettingsArr = new NumSettingsArr_Impl;
+ Reference<XIndexAccess> xLevel = aOutlineAccess.getConstArray()[nItem];
+ for(sal_Int32 nLevel = 0; nLevel < xLevel->getCount() && nLevel < 5; nLevel++)
+ {
+ Any aValueAny = xLevel->getByIndex(nLevel);
+ Sequence<PropertyValue> aLevelProps;
+ aValueAny >>= aLevelProps;
+ NumSettings_Impl* pNew = lcl_CreateNumberingSettingsPtr(aLevelProps);
+ const SvxNumberFormat& aNumFmt( aDefNumRule.GetLevel( nLevel) );
+ pNew->eLabelFollowedBy = aNumFmt.GetLabelFollowedBy();
+ pNew->nTabValue = aNumFmt.GetListtabPos();
+ pNew->eNumAlign = aNumFmt.GetNumAdjust();
+ pNew->nNumAlignAt = aNumFmt.GetFirstLineIndent();
+ pNew->nNumIndentAt = aNumFmt.GetIndentAt();
+ pItemArr->pNumSettingsArr->push_back(std::shared_ptr<NumSettings_Impl>(pNew));
+ }
+ }
+ }
+ catch(Exception&)
+ {
+ }
+}
+
+sal_uInt16 OutlineTypeMgr::GetNBOIndexForNumRule(SvxNumRule& aNum,sal_uInt16 /*mLevel*/,sal_uInt16 nFromIndex)
+{
+ sal_uInt16 const nLength = SAL_N_ELEMENTS(pOutlineSettingsArrs);
+ for(sal_uInt16 iDex = nFromIndex; iDex < nLength; iDex++)
+ {
+ bool bNotMatch = false;
+ OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[iDex];
+ sal_uInt16 nCount = pItemArr->pNumSettingsArr->size();
+ for (sal_uInt16 iLevel=0;iLevel < nCount;iLevel++)
+ {
+ NumSettings_Impl* _pSet = (*pItemArr->pNumSettingsArr)[iLevel].get();
+ sal_Int16 eNType = _pSet->nNumberType;
+
+ const SvxNumberFormat& aFmt(aNum.GetLevel(iLevel));
+ const OUString& sPrefix = aFmt.GetPrefix();
+ const OUString& sLclSuffix = aFmt.GetSuffix();
+ sal_Int16 eNumType = aFmt.GetNumberingType();
+ if( eNumType == SVX_NUM_CHAR_SPECIAL)
+ {
+ sal_UCS4 cChar = aFmt.GetBulletChar();
+
+ sal_UCS4 ccChar
+ = _pSet->sBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
+
+ if ( !((cChar == ccChar) &&
+ _pSet->eLabelFollowedBy == aFmt.GetLabelFollowedBy() &&
+ _pSet->nTabValue == aFmt.GetListtabPos() &&
+ _pSet->eNumAlign == aFmt.GetNumAdjust() &&
+ _pSet->nNumAlignAt == aFmt.GetFirstLineIndent() &&
+ _pSet->nNumIndentAt == aFmt.GetIndentAt()))
+ {
+ bNotMatch = true;
+ break;
+ }
+ }
+ else if ((eNumType&(~LINK_TOKEN)) == SVX_NUM_BITMAP )
+ {
+ const SvxBrushItem* pBrsh1 = aFmt.GetBrush();
+ const SvxBrushItem* pBrsh2 = _pSet->pBrushItem;
+ bool bIsMatch = false;
+ if (pBrsh1==pBrsh2) bIsMatch = true;
+ if (pBrsh1 && pBrsh2) {
+ const Graphic* pGrf1 = pBrsh1->GetGraphic();
+ const Graphic* pGrf2 = pBrsh2->GetGraphic();
+ if (pGrf1==pGrf2) bIsMatch = true;
+ if (pGrf1 && pGrf2) {
+ if ( pGrf1->GetBitmapEx() == pGrf2->GetBitmapEx() &&
+ _pSet->aSize == aFmt.GetGraphicSize())
+ bIsMatch = true;
+ }
+ }
+ if (!bIsMatch) {
+ bNotMatch = true;
+ break;
+ }
+ }
+ else
+ {
+ if (!(sPrefix == _pSet->sPrefix &&
+ sLclSuffix == _pSet->sSuffix &&
+ eNumType == eNType &&
+ _pSet->eLabelFollowedBy == aFmt.GetLabelFollowedBy() &&
+ _pSet->nTabValue == aFmt.GetListtabPos() &&
+ _pSet->eNumAlign == aFmt.GetNumAdjust() &&
+ _pSet->nNumAlignAt == aFmt.GetFirstLineIndent() &&
+ _pSet->nNumIndentAt == aFmt.GetIndentAt()))
+ {
+ bNotMatch = true;
+ break;
+ }
+ }
+ }
+ if ( !bNotMatch )
+ return iDex+1;
+ }
+
+
+ return sal_uInt16(0xFFFF);
+}
+
+void OutlineTypeMgr::RelplaceNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel)
+{
+ sal_uInt16 const nLength = SAL_N_ELEMENTS(pOutlineSettingsArrs);
+ if ( nIndex >= nLength )
+ return;
+
+ OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
+ sal_uInt16 nCount = pItemArr->pNumSettingsArr->size();
+ for (sal_uInt16 iLevel=0;iLevel < nCount;iLevel++)
+ {
+ const SvxNumberFormat& aFmt(aNum.GetLevel(iLevel));
+ SvxNumType eNumType = aFmt.GetNumberingType();
+
+ NumSettings_Impl* _pSet = (*pItemArr->pNumSettingsArr)[iLevel].get();
+
+ _pSet->eLabelFollowedBy = aFmt.GetLabelFollowedBy();
+ _pSet->nTabValue = aFmt.GetListtabPos();
+ _pSet->eNumAlign = aFmt.GetNumAdjust();
+ _pSet->nNumAlignAt = aFmt.GetFirstLineIndent();
+ _pSet->nNumIndentAt = aFmt.GetIndentAt();
+
+ if( eNumType == SVX_NUM_CHAR_SPECIAL)
+ {
+ sal_UCS4 cChar = aFmt.GetBulletChar();
+ OUString sChar(&cChar, 1);
+ _pSet->sBulletChar = sChar;
+ if ( aFmt.GetBulletFont() )
+ _pSet->sBulletFont = aFmt.GetBulletFont()->GetFamilyName();
+ _pSet->nNumberType = eNumType;
+ pItemArr->bIsCustomized = true;
+ }else if ((eNumType&(~LINK_TOKEN)) == SVX_NUM_BITMAP ) {
+ if (_pSet->pBrushItem) {
+ delete _pSet->pBrushItem;
+ _pSet->pBrushItem=nullptr;
+ }
+ if (aFmt.GetBrush())
+ _pSet->pBrushItem = new SvxBrushItem(*aFmt.GetBrush());
+ _pSet->aSize = aFmt.GetGraphicSize();
+ _pSet->nNumberType = eNumType;
+ } else
+ {
+ _pSet->sPrefix = aFmt.GetPrefix();
+ _pSet->sSuffix = aFmt.GetSuffix();
+ _pSet->nNumberType = eNumType;
+ if ( aFmt.GetBulletFont() )
+ _pSet->sBulletFont = aFmt.GetBulletFont()->GetFamilyName();
+ pItemArr->bIsCustomized = true;
+ }
+ }
+ SvxNumRule aTmpRule1(aNum);
+ SvxNumRule aTmpRule2(aNum);
+ ApplyNumRule(aTmpRule1,nIndex,mLevel,true);
+ ApplyNumRule(aTmpRule2,nIndex,mLevel);
+ if (aTmpRule1==aTmpRule2) pItemArr->bIsCustomized=false;
+ if (!pItemArr->bIsCustomized) {
+ pItemArr->sDescription = GetDescription(nIndex,true);
+ }
+ ImplStore(u"standard.syc");
+}
+
+void OutlineTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 /*mLevel*/, bool isDefault, bool isResetSize)
+{
+ DBG_ASSERT(DEFAULT_NUM_VALUSET_COUNT > nIndex, "wrong index");
+ if(DEFAULT_NUM_VALUSET_COUNT <= nIndex)
+ return;
+
+ const FontList* pList = nullptr;
+
+ OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
+ if (isDefault) pItemArr=pDefaultOutlineSettingsArrs[nIndex];
+
+ NumSettingsArr_Impl *pNumSettingsArr=pItemArr->pNumSettingsArr;
+
+ NumSettings_Impl* pLevelSettings = nullptr;
+ for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++)
+ {
+ if(pNumSettingsArr->size() > i)
+ pLevelSettings = (*pNumSettingsArr)[i].get();
+
+ if(!pLevelSettings)
+ break;
+
+ SvxNumberFormat aFmt(aNum.GetLevel(i));
+ const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
+ if (pLevelSettings->nNumberType !=aFmt.GetNumberingType()) isResetSize=true;
+ aFmt.SetNumberingType( pLevelSettings->nNumberType );
+ sal_uInt16 nUpperLevelOrChar = static_cast<sal_uInt16>(pLevelSettings->nParentNumbering);
+ if(aFmt.GetNumberingType() == SVX_NUM_CHAR_SPECIAL)
+ {
+ if( pLevelSettings->sBulletFont.getLength() &&
+ pLevelSettings->sBulletFont != rActBulletFont.GetFamilyName() )
+ {
+ //search for the font
+ if(!pList)
+ {
+ if (SfxObjectShell* pCurDocShell = SfxObjectShell::Current())
+ {
+ const SvxFontListItem* pFontListItem = static_cast<const SvxFontListItem*>(pCurDocShell->GetItem(SID_ATTR_CHAR_FONTLIST));
+ pList = pFontListItem ? pFontListItem->GetFontList() : nullptr;
+ }
+ }
+ if(pList && pList->IsAvailable( pLevelSettings->sBulletFont ) )
+ {
+ FontMetric aFontMetric = pList->Get(pLevelSettings->sBulletFont,WEIGHT_NORMAL, ITALIC_NONE);
+ vcl::Font aFont(aFontMetric);
+ aFmt.SetBulletFont(&aFont);
+ }
+ else
+ {
+ //if it cannot be found then create a new one
+ vcl::Font aCreateFont( pLevelSettings->sBulletFont, OUString(), Size( 0, 14 ) );
+ aCreateFont.SetCharSet( RTL_TEXTENCODING_DONTKNOW );
+ aCreateFont.SetFamily( FAMILY_DONTKNOW );
+ aCreateFont.SetPitch( PITCH_DONTKNOW );
+ aCreateFont.SetWeight( WEIGHT_DONTKNOW );
+ aCreateFont.SetTransparent( true );
+ aFmt.SetBulletFont( &aCreateFont );
+ }
+ }else
+ aFmt.SetBulletFont( &rActBulletFont );
+
+ sal_UCS4 cChar = 0;
+ if( !pLevelSettings->sBulletChar.isEmpty() )
+ {
+ cChar
+ = pLevelSettings->sBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
+ }
+ if( AllSettings::GetLayoutRTL() )
+ {
+ if( 0 == i && cChar == BulletsTypeMgr::aDynamicBulletTypes[5] )
+ cChar = BulletsTypeMgr::aDynamicRTLBulletTypes[5];
+ else if( 1 == i )
+ {
+ const SvxNumberFormat& numberFmt = aNum.GetLevel(0);
+ if( numberFmt.GetBulletChar() == BulletsTypeMgr::aDynamicRTLBulletTypes[5] )
+ cChar = BulletsTypeMgr::aDynamicRTLBulletTypes[4];
+ }
+ }
+
+ aFmt.SetBulletChar(cChar);
+ aFmt.SetCharFormatName( GetBulletCharFmtName() );
+ if (isResetSize) aFmt.SetBulletRelSize(45);
+ }else if ((aFmt.GetNumberingType()&(~LINK_TOKEN)) == SVX_NUM_BITMAP ) {
+ if (pLevelSettings->pBrushItem) {
+ const Graphic* pGrf = pLevelSettings->pBrushItem->GetGraphic();
+ Size aSize = pLevelSettings->aSize;
+ sal_Int16 eOrient = text::VertOrientation::LINE_CENTER;
+ if (!isResetSize && aFmt.GetGraphicSize()!=Size(0,0))
+ aSize = aFmt.GetGraphicSize();
+ else if (aSize.IsEmpty() && pGrf)
+ aSize = SvxNumberFormat::GetGraphicSizeMM100( pGrf );
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(GetMapUnit()));
+ aFmt.SetGraphicBrush( pLevelSettings->pBrushItem, &aSize, &eOrient );
+ }
+ } else
+ {
+ aFmt.SetIncludeUpperLevels(sal::static_int_cast< sal_uInt8 >(0 != nUpperLevelOrChar ? aNum.GetLevelCount() : 1));
+ aFmt.SetCharFormatName(GetNumCharFmtName());
+ if (isResetSize) aFmt.SetBulletRelSize(100);
+ }
+ if(pNumSettingsArr->size() > i) {
+ aFmt.SetLabelFollowedBy(pLevelSettings->eLabelFollowedBy);
+ aFmt.SetListtabPos(pLevelSettings->nTabValue);
+ aFmt.SetNumAdjust(pLevelSettings->eNumAlign);
+ aFmt.SetFirstLineIndent(pLevelSettings->nNumAlignAt);
+ aFmt.SetIndentAt(pLevelSettings->nNumIndentAt);
+ }
+ aFmt.SetListFormat(pLevelSettings->sPrefix, pLevelSettings->sSuffix, i);
+ aNum.SetLevel(i, aFmt);
+ }
+}
+
+OUString OutlineTypeMgr::GetDescription(sal_uInt16 nIndex, bool isDefault)
+{
+ OUString sRet;
+
+ if ( nIndex >= SAL_N_ELEMENTS(pOutlineSettingsArrs) )
+ return sRet;
+ else
+ {
+ OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
+ if (isDefault) pItemArr = pDefaultOutlineSettingsArrs[nIndex];
+ if ( pItemArr )
+ {
+ sRet = pItemArr->sDescription;
+ }
+ }
+ return sRet;
+}
+
+bool OutlineTypeMgr::IsCustomized(sal_uInt16 nIndex)
+{
+ bool bRet = false;
+
+ if ( nIndex >= SAL_N_ELEMENTS(pOutlineSettingsArrs) )
+ return bRet;
+ else
+ {
+ OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
+ if ( pItemArr )
+ {
+ bRet = pItemArr->bIsCustomized;
+ }
+ }
+
+ return bRet;
+}
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */