summaryrefslogtreecommitdiffstats
path: root/cui/source/tabpages/numpages.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'cui/source/tabpages/numpages.cxx')
-rw-r--r--cui/source/tabpages/numpages.cxx3400
1 files changed, 3400 insertions, 0 deletions
diff --git a/cui/source/tabpages/numpages.cxx b/cui/source/tabpages/numpages.cxx
new file mode 100644
index 0000000000..d1cb793412
--- /dev/null
+++ b/cui/source/tabpages/numpages.cxx
@@ -0,0 +1,3400 @@
+/* -*- 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 <com/sun/star/text/VertOrientation.hpp>
+
+#include <numpages.hxx>
+#include <dialmgr.hxx>
+#include <tools/mapunit.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <editeng/numitem.hxx>
+#include <svl/eitem.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/strarray.hxx>
+#include <svx/gallery.hxx>
+#include <editeng/brushitem.hxx>
+#include <svl/intitem.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/settings.hxx>
+#include <cui/cuicharmap.hxx>
+#include <editeng/flstitem.hxx>
+#include <svx/numvset.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svtools/unitconv.hxx>
+#include <svtools/colorcfg.hxx>
+#include <com/sun/star/style/NumberingType.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/text/XDefaultNumberingProvider.hpp>
+#include <com/sun/star/text/XNumberingFormatter.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/lok.hxx>
+#include <svx/svxids.hrc>
+#include <o3tl/string_view.hxx>
+
+#include <algorithm>
+#include <memory>
+#include <vector>
+#include <sfx2/opengrf.hxx>
+
+#include <strings.hrc>
+#include <svl/stritem.hxx>
+#include <svl/slstitm.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+#include <sal/log.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <svx/SvxNumOptionsTabPageHelper.hxx>
+#include <tools/urlobj.hxx>
+#include <o3tl/temporary.hxx>
+#include <osl/diagnose.h>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::beans;
+using namespace css::lang;
+using namespace css::text;
+using namespace css::container;
+using namespace css::style;
+
+#define SHOW_NUMBERING 0
+#define SHOW_BULLET 1
+#define SHOW_BITMAP 2
+
+#define MAX_BMP_WIDTH 16
+#define MAX_BMP_HEIGHT 16
+#define SEARCHPATH_DELIMITER u';'
+#define SEARCHFILENAME_DELIMITER u'/'
+
+static bool bLastRelative = false;
+
+static SvxNumSettings_Impl* lcl_CreateNumSettingsPtr(const Sequence<PropertyValue>& rLevelProps)
+{
+ const PropertyValue* pValues = rLevelProps.getConstArray();
+ SvxNumSettings_Impl* pNew = new SvxNumSettings_Impl;
+ for(sal_Int32 j = 0; j < rLevelProps.getLength(); j++)
+ {
+ if ( pValues[j].Name == "NumberingType" )
+ {
+ sal_Int16 nTmp;
+ if (pValues[j].Value >>= nTmp)
+ pNew->nNumberType = static_cast<SvxNumType>(nTmp);
+ }
+ else if ( pValues[j].Name == "Prefix" )
+ pValues[j].Value >>= pNew->sPrefix;
+ else if ( pValues[j].Name == "Suffix" )
+ pValues[j].Value >>= pNew->sSuffix;
+ else if ( pValues[j].Name == "ParentNumbering" )
+ pValues[j].Value >>= pNew->nParentNumbering;
+ else if ( pValues[j].Name == "BulletChar" )
+ pValues[j].Value >>= pNew->sBulletChar;
+ else if ( pValues[j].Name == "BulletFontName" )
+ pValues[j].Value >>= pNew->sBulletFont;
+ }
+ return pNew;
+}
+
+// the selection of bullets from the OpenSymbol
+const sal_Unicode aBulletTypes[] =
+{
+ 0x2022,
+ 0x25cf,
+ 0xe00c,
+ 0xe00a,
+ 0x2794,
+ 0x27a2,
+ 0x2717,
+ 0x2714
+};
+
+// Is one of the masked formats set?
+static bool lcl_IsNumFmtSet(SvxNumRule const * pNum, sal_uInt16 nLevelMask)
+{
+ bool bRet = false;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < SVX_MAX_NUM && !bRet; i++ )
+ {
+ if(nLevelMask & nMask)
+ bRet |= nullptr != pNum->Get( i );
+ nMask <<= 1 ;
+ }
+ return bRet;
+}
+
+static const vcl::Font& lcl_GetDefaultBulletFont()
+{
+ static vcl::Font aDefBulletFont = []()
+ {
+ 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;
+}
+
+SvxSingleNumPickTabPage::SvxSingleNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/picknumberingpage.ui", "PickNumberingPage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , bModified(false)
+ , bPreset(false)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+ m_xExamplesVS->init(NumberingPageType::SINGLENUM);
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxSingleNumPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxSingleNumPickTabPage, DoubleClickHdl_Impl));
+
+ Reference<XDefaultNumberingProvider> xDefNum = SvxNumOptionsTabPageHelper::GetNumberingProvider();
+ if(!xDefNum.is())
+ return;
+
+ Sequence< Sequence< PropertyValue > > aNumberings;
+ const Locale& rLocale = Application::GetSettings().GetLanguageTag().getLocale();
+ try
+ {
+ aNumberings =
+ xDefNum->getDefaultContinuousNumberingLevels( rLocale );
+
+
+ sal_Int32 nLength = std::min<sal_Int32>(aNumberings.getLength(), NUM_VALUSET_COUNT);
+
+ const Sequence<PropertyValue>* pValuesArr = aNumberings.getConstArray();
+ for(sal_Int32 i = 0; i < nLength; i++)
+ {
+ SvxNumSettings_Impl* pNew = lcl_CreateNumSettingsPtr(pValuesArr[i]);
+ aNumSettingsArr.push_back(std::unique_ptr<SvxNumSettings_Impl>(pNew));
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+ Reference<XNumberingFormatter> xFormat(xDefNum, UNO_QUERY);
+ m_xExamplesVS->SetNumberingSettings(aNumberings, xFormat, rLocale);
+}
+
+SvxSingleNumPickTabPage::~SvxSingleNumPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxSingleNumPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxSingleNumPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxSingleNumPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( (bPreset || bModified) && pSaveNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+
+ return bModified;
+}
+
+void SvxSingleNumPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bIsPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nActNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pNumItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pNumItem->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+
+ bModified = false;
+}
+
+DeactivateRC SvxSingleNumPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SvxSingleNumPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxPoolItem* pItem;
+
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ SfxItemState eState = rSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
+ if(eState != SfxItemState::SET)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ eState = rSet->GetItemState(nNumItemId, false, &pItem);
+
+ if( eState != SfxItemState::SET )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ eState = SfxItemState::SET;
+ }
+ }
+ DBG_ASSERT(eState == SfxItemState::SET, "no item found!");
+ pSaveNum.reset( new SvxNumRule(static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+}
+
+IMPL_LINK_NOARG(SvxSingleNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+ sal_uInt16 nIdx = m_xExamplesVS->GetSelectedItemId() - 1;
+ DBG_ASSERT(aNumSettingsArr.size() > nIdx, "wrong index");
+ if(aNumSettingsArr.size() <= nIdx)
+ return;
+ SvxNumSettings_Impl* _pSet = aNumSettingsArr[nIdx].get();
+ SvxNumType eNewType = _pSet->nNumberType;
+ const sal_Unicode cLocalPrefix = !_pSet->sPrefix.isEmpty() ? _pSet->sPrefix[0] : 0;
+ const sal_Unicode cLocalSuffix = !_pSet->sSuffix.isEmpty() ? _pSet->sSuffix[0] : 0;
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType(eNewType);
+ aFmt.SetListFormat(cLocalPrefix == ' ' ? "" : _pSet->sPrefix,
+ cLocalSuffix == ' ' ? "" : _pSet->sSuffix, i);
+ aFmt.SetCharFormatName("");
+ aFmt.SetBulletRelSize(100);
+ pActNum->SetLevel(i, aFmt);
+ }
+ nMask <<= 1;
+ }
+}
+
+IMPL_LINK_NOARG(SvxSingleNumPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+SvxBulletPickTabPage::SvxBulletPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/pickbulletpage.ui", "PickBulletPage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , bModified(false)
+ , bPreset(false)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+ m_xExamplesVS->init(NumberingPageType::BULLET);
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxBulletPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxBulletPickTabPage, DoubleClickHdl_Impl));
+}
+
+SvxBulletPickTabPage::~SvxBulletPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxBulletPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxBulletPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxBulletPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( (bPreset || bModified) && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+ return bModified;
+}
+
+void SvxBulletPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bIsPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nActNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+ bModified = false;
+}
+
+DeactivateRC SvxBulletPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SvxBulletPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pItem )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ }
+
+ }
+ pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+}
+
+IMPL_LINK_NOARG(SvxBulletPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+ sal_Unicode cChar = aBulletTypes[m_xExamplesVS->GetSelectedItemId() - 1];
+ const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType( SVX_NUM_CHAR_SPECIAL );
+ // #i93908# clear suffix for bullet lists
+ aFmt.SetListFormat("", "", i);
+ aFmt.SetBulletFont(&rActBulletFont);
+ aFmt.SetBulletChar(cChar );
+ aFmt.SetCharFormatName(sBulletCharFormatName);
+ aFmt.SetBulletRelSize(45);
+ pActNum->SetLevel(i, aFmt);
+ }
+ nMask <<= 1;
+ }
+}
+
+IMPL_LINK_NOARG(SvxBulletPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+void SvxBulletPickTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
+
+ if (pBulletCharFmt)
+ sBulletCharFormatName = pBulletCharFmt->GetValue();
+}
+
+SvxNumPickTabPage::SvxNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/pickoutlinepage.ui", "PickOutlinePage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , bModified(false)
+ , bPreset(false)
+ , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+
+ m_xExamplesVS->init(NumberingPageType::OUTLINE);
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxNumPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxNumPickTabPage, DoubleClickHdl_Impl));
+
+ Reference<XDefaultNumberingProvider> xDefNum = SvxNumOptionsTabPageHelper::GetNumberingProvider();
+ if(!xDefNum.is())
+ return;
+
+ Sequence<Reference<XIndexAccess> > aOutlineAccess;
+ const Locale& rLocale = Application::GetSettings().GetLanguageTag().getLocale();
+ try
+ {
+ aOutlineAccess = xDefNum->getDefaultOutlineNumberings( rLocale );
+
+ for(sal_Int32 nItem = 0;
+ nItem < aOutlineAccess.getLength() && nItem < NUM_VALUSET_COUNT;
+ nItem++ )
+ {
+ SvxNumSettingsArr_Impl& rItemArr = aNumSettingsArrays[ nItem ];
+
+ Reference<XIndexAccess> xLevel = aOutlineAccess.getConstArray()[nItem];
+ for(sal_Int32 nLevel = 0; nLevel < SVX_MAX_NUM; nLevel++)
+ {
+ // use the last locale-defined level for all remaining levels.
+ sal_Int32 nLocaleLevel = std::min(nLevel, xLevel->getCount() - 1);
+ Sequence<PropertyValue> aLevelProps;
+ if (nLocaleLevel >= 0)
+ xLevel->getByIndex(nLocaleLevel) >>= aLevelProps;
+
+ SvxNumSettings_Impl* pNew = lcl_CreateNumSettingsPtr(aLevelProps);
+ rItemArr.push_back( std::unique_ptr<SvxNumSettings_Impl>(pNew) );
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+ Reference<XNumberingFormatter> xFormat(xDefNum, UNO_QUERY);
+ m_xExamplesVS->SetOutlineNumberingSettings(aOutlineAccess, xFormat, rLocale);
+}
+
+SvxNumPickTabPage::~SvxNumPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxNumPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxNumPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxNumPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( (bPreset || bModified) && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+ return bModified;
+}
+
+void SvxNumPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bIsPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nActNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+ bModified = false;
+}
+
+DeactivateRC SvxNumPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SvxNumPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pItem )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ }
+ }
+ pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+
+}
+
+// all levels are changed here
+IMPL_LINK_NOARG(SvxNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+
+ const FontList* pList = nullptr;
+
+ SvxNumSettingsArr_Impl& rItemArr = aNumSettingsArrays[m_xExamplesVS->GetSelectedItemId() - 1];
+
+ const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
+ SvxNumSettings_Impl* pLevelSettings = nullptr;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(rItemArr.size() > i)
+ pLevelSettings = rItemArr[i].get();
+ if(!pLevelSettings)
+ break;
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType( pLevelSettings->nNumberType );
+ sal_uInt16 nUpperLevelOrChar = static_cast<sal_uInt16>(pLevelSettings->nParentNumbering);
+ if(aFmt.GetNumberingType() == SVX_NUM_CHAR_SPECIAL)
+ {
+ // #i93908# clear suffix for bullet lists
+ aFmt.SetListFormat("", "", i);
+ if( !pLevelSettings->sBulletFont.isEmpty() &&
+ 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 );
+
+ aFmt.SetBulletChar( !pLevelSettings->sBulletChar.isEmpty()
+ ? pLevelSettings->sBulletChar.iterateCodePoints(
+ &o3tl::temporary(sal_Int32(0)))
+ : 0 );
+ aFmt.SetCharFormatName( sBulletCharFormatName );
+ aFmt.SetBulletRelSize(45);
+ }
+ else
+ {
+ aFmt.SetIncludeUpperLevels(sal::static_int_cast< sal_uInt8 >(0 != nUpperLevelOrChar ? pActNum->GetLevelCount() : 1));
+ aFmt.SetCharFormatName(sNumCharFmtName);
+ aFmt.SetBulletRelSize(100);
+
+ // Completely ignore the Left/Right value provided by the locale outline definition,
+ // because this function doesn't actually modify the indents at all,
+ // and right-adjusted numbering definitely needs a different FirstLineIndent.
+
+ // #i93908#
+ aFmt.SetListFormat(pLevelSettings->sPrefix, pLevelSettings->sSuffix, i);
+ }
+ pActNum->SetLevel(i, aFmt);
+ }
+}
+
+IMPL_LINK_NOARG(SvxNumPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+void SvxNumPickTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
+ const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
+
+
+ if (pNumCharFmt &&pBulletCharFmt)
+ SetCharFormatNames( pNumCharFmt->GetValue(),pBulletCharFmt->GetValue());
+}
+
+SvxBitmapPickTabPage::SvxBitmapPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/pickgraphicpage.ui", "PickGraphicPage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , bModified(false)
+ , bPreset(false)
+ , m_xErrorText(m_xBuilder->weld_label("errorft"))
+ , m_xBtBrowseFile(m_xBuilder->weld_button("browseBtn"))
+ , m_xExamplesVS(new SvxBmpNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+
+ m_xExamplesVS->init();
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxBitmapPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxBitmapPickTabPage, DoubleClickHdl_Impl));
+ m_xBtBrowseFile->connect_clicked(LINK(this, SvxBitmapPickTabPage, ClickAddBrowseHdl_Impl));
+
+ eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
+
+ // determine graphic name
+ GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames);
+
+ size_t i = 0;
+ for (auto & grfName : aGrfNames)
+ {
+ m_xExamplesVS->InsertItem( i + 1, i);
+
+ INetURLObject aObj(grfName);
+ if (aObj.GetProtocol() == INetProtocol::File)
+ {
+ // tdf#114070 - only show the last name of the filename without its extension
+ aObj.removeExtension();
+ grfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
+ }
+
+ m_xExamplesVS->SetItemText( i + 1, grfName );
+ ++i;
+ }
+
+ if(aGrfNames.empty())
+ {
+ m_xErrorText->show();
+ }
+ else
+ {
+ m_xExamplesVS->Show();
+ m_xExamplesVS->SetFormat();
+ m_xExamplesVS->Invalidate();
+ }
+}
+
+SvxBitmapPickTabPage::~SvxBitmapPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxBitmapPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxBitmapPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxBitmapPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bIsPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nActNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(!aGrfNames.empty() &&
+ (pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset)))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+ bModified = false;
+}
+
+DeactivateRC SvxBitmapPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxBitmapPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if ( aGrfNames.empty() )
+ {
+ return false;
+ }
+ if( (bPreset || bModified) && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ) );
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+
+ return bModified;
+}
+
+void SvxBitmapPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pItem )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ }
+
+ }
+ DBG_ASSERT(pItem, "no item found!");
+ pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+}
+
+IMPL_LINK_NOARG(SvxBitmapPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+ sal_uInt16 nIdx = m_xExamplesVS->GetSelectedItemId() - 1;
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType(SVX_NUM_BITMAP);
+ aFmt.SetListFormat("", "", i);
+ aFmt.SetCharFormatName( "" );
+
+ Graphic aGraphic;
+ if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, nIdx, &aGraphic))
+ {
+ Size aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
+ sal_Int16 eOrient = text::VertOrientation::LINE_CENTER;
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit));
+ SvxBrushItem aBrush(aGraphic, GPOS_AREA, SID_ATTR_BRUSH );
+ aFmt.SetGraphicBrush( &aBrush, &aSize, &eOrient );
+ }
+ else if(aGrfNames.size() > nIdx)
+ aFmt.SetGraphic( aGrfNames[nIdx] );
+ pActNum->SetLevel(i, aFmt);
+ }
+ nMask <<= 1;
+ }
+}
+
+IMPL_LINK_NOARG(SvxBitmapPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+IMPL_LINK_NOARG(SvxBitmapPickTabPage, ClickAddBrowseHdl_Impl, weld::Button&, void)
+{
+ sfx2::FileDialogHelper aFileDialog(0, FileDialogFlags::NONE, GetFrameWeld());
+ aFileDialog.SetContext(sfx2::FileDialogHelper::BulletsAddImage);
+ aFileDialog.SetTitle(CuiResId(RID_CUISTR_ADD_IMAGE));
+ if ( aFileDialog.Execute() != ERRCODE_NONE )
+ return;
+
+ OUString aPath = SvtPathOptions().GetGalleryPath();
+ std::u16string_view aPathToken = o3tl::getToken(aPath, 1 , SEARCHPATH_DELIMITER );
+
+ OUString aUserImageURL = aFileDialog.GetPath();
+
+ OUString aFileName;
+ const sal_Int32 nPos {aUserImageURL.lastIndexOf(SEARCHFILENAME_DELIMITER)+1};
+ if (nPos<=0)
+ aFileName = aUserImageURL;
+ else if (nPos<aUserImageURL.getLength())
+ aFileName = aUserImageURL.copy(nPos);
+
+ OUString aUserGalleryURL = OUString::Concat(aPathToken) + "/" + aFileName;
+ INetURLObject aURL( aUserImageURL );
+ DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ GraphicDescriptor aDescriptor(aURL);
+ if (!aDescriptor.Detect())
+ return;
+
+ uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess(
+ ucb::SimpleFileAccess::create( ::comphelper::getComponentContext(xFactory) ) );
+ if ( !xSimpleFileAccess->exists( aUserImageURL ))
+ return;
+
+ xSimpleFileAccess->copy( aUserImageURL, aUserGalleryURL );
+ INetURLObject gURL( aUserGalleryURL );
+ std::unique_ptr<SvStream> pIn(::utl::UcbStreamHelper::CreateStream(
+ gURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
+ if ( !pIn )
+ return;
+
+ Graphic aGraphic;
+ GraphicConverter::Import( *pIn, aGraphic );
+
+ BitmapEx aBitmap = aGraphic.GetBitmapEx();
+ tools::Long nPixelX = aBitmap.GetSizePixel().Width();
+ tools::Long nPixelY = aBitmap.GetSizePixel().Height();
+ double ratio = nPixelY/static_cast<double>(nPixelX);
+ if(nPixelX > 30)
+ {
+ nPixelX = 30;
+ nPixelY = static_cast<tools::Long>(nPixelX*ratio);
+ }
+ if(nPixelY > 30)
+ {
+ nPixelY = 30;
+ nPixelX = static_cast<tools::Long>(nPixelY/ratio);
+ }
+
+ aBitmap.Scale( Size( nPixelX, nPixelY ), BmpScaleFlag::Fast );
+ Graphic aScaledGraphic( aBitmap );
+ GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+
+ Sequence< PropertyValue > aFilterData{
+ comphelper::makePropertyValue("Compression", sal_Int32(-1)),
+ comphelper::makePropertyValue("Quality", sal_Int32(1))
+ };
+
+ sal_uInt16 nFilterFormat = rFilter.GetExportFormatNumberForShortName( gURL.GetFileExtension() );
+ rFilter.ExportGraphic( aScaledGraphic, gURL , nFilterFormat, &aFilterData );
+ GalleryExplorer::InsertURL( GALLERY_THEME_BULLETS, aUserGalleryURL );
+
+ aGrfNames.push_back(aUserGalleryURL);
+ size_t i = 0;
+ for (auto & grfName : aGrfNames)
+ {
+ m_xExamplesVS->InsertItem( i + 1, i);
+ INetURLObject aObj(grfName);
+ if (aObj.GetProtocol() == INetProtocol::File)
+ {
+ // tdf#114070 - only show the last name of the filename without its extension
+ aObj.removeExtension();
+ grfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
+ }
+ m_xExamplesVS->SetItemText( i + 1, grfName );
+ ++i;
+ }
+
+ if(aGrfNames.empty())
+ {
+ m_xErrorText->show();
+ }
+ else
+ {
+ m_xExamplesVS->Show();
+ m_xExamplesVS->SetFormat();
+ }
+}
+
+// tabpage numbering options
+SvxNumOptionsTabPage::SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/numberingoptionspage.ui", "NumberingOptionsPage", &rSet)
+ , aInvalidateTimer("cui SvxNumOptionsTabPage aInvalidateTimer")
+ , m_pLevelHdlEvent(nullptr)
+ , bLastWidthModified(false)
+ , bModified(false)
+ , bPreset(false)
+ , bAutomaticCharStyles(true)
+ , bHTMLMode(false)
+ , nBullet(0xff)
+ , nActNumLvl(1)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , m_xGrid(m_xBuilder->weld_widget("grid2"))
+ , m_xLevelLB(m_xBuilder->weld_tree_view("levellb"))
+ , m_xFmtLB(m_xBuilder->weld_combo_box("numfmtlb"))
+ , m_xSeparatorFT(m_xBuilder->weld_label("separator"))
+ , m_xPrefixFT(m_xBuilder->weld_label("prefixft"))
+ , m_xPrefixED(m_xBuilder->weld_entry("prefix"))
+ , m_xSuffixFT(m_xBuilder->weld_label("suffixft"))
+ , m_xSuffixED(m_xBuilder->weld_entry("suffix"))
+ , m_xCharFmtFT(m_xBuilder->weld_label("charstyleft"))
+ , m_xCharFmtLB(m_xBuilder->weld_combo_box("charstyle"))
+ , m_xBulColorFT(m_xBuilder->weld_label("colorft"))
+ , m_xBulColLB(new ColorListBox(m_xBuilder->weld_menu_button("color"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xBulRelSizeFT(m_xBuilder->weld_label("relsizeft"))
+ , m_xBulRelSizeMF(m_xBuilder->weld_metric_spin_button("relsize", FieldUnit::PERCENT))
+ , m_xAllLevelFT(m_xBuilder->weld_label("sublevelsft"))
+ , m_xAllLevelNF(m_xBuilder->weld_spin_button("sublevels"))
+ , m_xIsLegalCB(m_xBuilder->weld_check_button("islegal"))
+ , m_xStartFT(m_xBuilder->weld_label("startatft"))
+ , m_xStartED(m_xBuilder->weld_spin_button("startat"))
+ , m_xBulletFT(m_xBuilder->weld_label("bulletft"))
+ , m_xBulletPB(m_xBuilder->weld_button("bullet"))
+ , m_xBitmapFT(m_xBuilder->weld_label("bitmapft"))
+ , m_xBitmapMB(m_xBuilder->weld_menu_button("bitmap"))
+ , m_xWidthFT(m_xBuilder->weld_label("widthft"))
+ , m_xWidthMF(m_xBuilder->weld_metric_spin_button("widthmf", FieldUnit::CM))
+ , m_xHeightFT(m_xBuilder->weld_label("heightft"))
+ , m_xHeightMF(m_xBuilder->weld_metric_spin_button("heightmf", FieldUnit::CM))
+ , m_xRatioCB(m_xBuilder->weld_check_button("keepratio"))
+ , m_xOrientFT(m_xBuilder->weld_label("orientft"))
+ , m_xOrientLB(m_xBuilder->weld_combo_box("orientlb"))
+ , m_xAllLevelsFrame(m_xBuilder->weld_widget("levelsframe"))
+ , m_xSameLevelCB(m_xBuilder->weld_check_button("allsame"))
+ , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWIN))
+{
+ m_xBulColLB->SetSlotId(SID_ATTR_CHAR_COLOR);
+ m_xBulRelSizeMF->set_min(SVX_NUM_REL_SIZE_MIN, FieldUnit::PERCENT);
+ m_xBulRelSizeMF->set_increments(5, 50, FieldUnit::PERCENT);
+ SetExchangeSupport();
+ aActBulletFont = lcl_GetDefaultBulletFont();
+
+ m_xBulletPB->connect_clicked(LINK(this, SvxNumOptionsTabPage, BulletHdl_Impl));
+ m_xFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl));
+ m_xBitmapMB->connect_selected(LINK(this, SvxNumOptionsTabPage, GraphicHdl_Impl));
+ m_xBitmapMB->connect_toggled(LINK(this, SvxNumOptionsTabPage, PopupActivateHdl_Impl));
+ m_xLevelLB->set_selection_mode(SelectionMode::Multiple);
+ m_xLevelLB->connect_changed(LINK(this, SvxNumOptionsTabPage, LevelHdl_Impl));
+ m_xCharFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, CharFmtHdl_Impl));
+ m_xWidthMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl));
+ m_xHeightMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl));
+ m_xRatioCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, RatioHdl_Impl));
+ m_xStartED->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SpinModifyHdl_Impl));
+ m_xPrefixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl));
+ m_xSuffixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl));
+ m_xAllLevelNF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, AllLevelHdl_Impl));
+ m_xIsLegalCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, IsLegalHdl_Impl));
+ m_xOrientLB->connect_changed(LINK(this, SvxNumOptionsTabPage, OrientHdl_Impl));
+ m_xSameLevelCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, SameLevelHdl_Impl));
+ m_xBulRelSizeMF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, BulRelSizeHdl_Impl));
+ m_xBulColLB->SetSelectHdl(LINK(this, SvxNumOptionsTabPage, BulColorHdl_Impl));
+ aInvalidateTimer.SetInvokeHandler(LINK(this, SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl));
+ aInvalidateTimer.SetTimeout(50);
+
+ eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
+
+ // Fill ListBox with predefined / translated numbering types.
+ sal_uInt32 nCount = SvxNumberingTypeTable::Count();
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ int nValue = SvxNumberingTypeTable::GetValue(i);
+ if (comphelper::LibreOfficeKit::isActive() && (nValue & SVX_NUM_BITMAP)) continue;
+ m_xFmtLB->append(OUString::number(nValue), SvxNumberingTypeTable::GetString(i));
+ }
+
+ // Get advanced numbering types from the component.
+ // Watch out for the ugly
+ // 136 == 0x88 == SVX_NUM_BITMAP|0x80 == SVX_NUM_BITMAP|LINK_TOKEN
+ // to not remove that.
+ SvxNumOptionsTabPageHelper::GetI18nNumbering( *m_xFmtLB, (SVX_NUM_BITMAP | LINK_TOKEN));
+
+ m_xFmtLB->set_active(0);
+
+ m_xCharFmtLB->set_size_request(m_xCharFmtLB->get_approximate_digit_width() * 10, -1);
+ Size aSize(m_xGrid->get_preferred_size());
+ m_xGrid->set_size_request(aSize.Width(), -1);
+}
+
+SvxNumOptionsTabPage::~SvxNumOptionsTabPage()
+{
+ m_xPreviewWIN.reset();
+ m_xBulColLB.reset();
+ pActNum.reset();
+ pSaveNum.reset();
+ if (m_pLevelHdlEvent)
+ {
+ Application::RemoveUserEvent(m_pLevelHdlEvent);
+ m_pLevelHdlEvent = nullptr;
+ }
+}
+
+void SvxNumOptionsTabPage::SetMetric(FieldUnit eMetric)
+{
+ if(eMetric == FieldUnit::MM)
+ {
+ m_xWidthMF->set_digits(1);
+ m_xHeightMF->set_digits(1);
+ }
+ m_xWidthMF->set_unit(eMetric);
+ m_xHeightMF->set_unit(eMetric);
+}
+
+std::unique_ptr<SfxTabPage> SvxNumOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxNumOptionsTabPage>(pPage, pController, *rAttrSet);
+};
+
+void SvxNumOptionsTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ sal_uInt16 nTmpNumLvl = 1;
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nTmpNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+
+ bModified = (!pActNum->Get( 0 ) || bPreset);
+ if(*pActNum == *pSaveNum && nActNumLvl == nTmpNumLvl)
+ return;
+
+ nActNumLvl = nTmpNumLvl;
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ m_xLevelLB->select(pActNum->GetLevelCount());
+ if(nActNumLvl != SAL_MAX_UINT16)
+ {
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1 ;
+ }
+ }
+ *pActNum = *pSaveNum;
+
+ InitControls();
+}
+
+DeactivateRC SvxNumOptionsTabPage::DeactivatePage(SfxItemSet * _pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxNumOptionsTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl));
+ if(bModified && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false));
+ }
+ return bModified;
+};
+
+void SvxNumOptionsTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pBulletItem =
+ rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pBulletItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pBulletItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pBulletItem )
+ {
+ pBulletItem = & rSet->Get( nNumItemId );
+ }
+ }
+ DBG_ASSERT(pBulletItem, "no item found!");
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+
+ // insert levels
+ if (!m_xLevelLB->n_children())
+ {
+ for(sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++)
+ m_xLevelLB->append_text(OUString::number(i));
+ if(pSaveNum->GetLevelCount() > 1)
+ {
+ OUString sEntry = "1 - " + OUString::number( pSaveNum->GetLevelCount() );
+ m_xLevelLB->append_text(sEntry);
+ m_xLevelLB->select_text(sEntry);
+ }
+ else
+ m_xLevelLB->select(0);
+ }
+ else
+ m_xLevelLB->select(m_xLevelLB->n_children() - 1);
+
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ {
+ m_xLevelLB->select( pSaveNum->GetLevelCount() );
+ }
+ else
+ {
+ for(sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ m_xLevelLB->select( i );
+ nMask <<= 1 ;
+ }
+ }
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+ m_aPreviewWIN.SetNumRule(pActNum.get());
+ m_xSameLevelCB->set_active(pActNum->IsContinuousNumbering());
+
+ const SfxUInt16Item* pHtmlModeItem =
+ rSet->GetItemIfSet( SID_HTML_MODE, false );
+ if (!pHtmlModeItem)
+ {
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ pHtmlModeItem = pShell->GetItem( SID_HTML_MODE );
+ }
+ if ( pHtmlModeItem )
+ {
+ sal_uInt16 nHtmlMode = pHtmlModeItem->GetValue();
+ bHTMLMode = 0 != (nHtmlMode&HTMLMODE_ON);
+ }
+
+ bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
+ m_xCharFmtFT->set_visible(bCharFmt);
+ m_xCharFmtLB->set_visible(bCharFmt);
+
+ bool bContinuous = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
+
+ bool bAllLevel = bContinuous && !bHTMLMode;
+ m_xAllLevelFT->set_visible(bAllLevel);
+ m_xAllLevelNF->set_visible(bAllLevel);
+ m_xIsLegalCB->set_visible(bAllLevel);
+
+ m_xAllLevelsFrame->set_visible(bContinuous);
+
+ // again misusage: in Draw there is numeration only until the bitmap
+ // without SVX_NUM_NUMBER_NONE
+ //remove types that are unsupported by Draw/Impress
+ if(!bContinuous)
+ {
+ sal_Int32 nFmtCount = m_xFmtLB->get_count();
+ for(sal_Int32 i = nFmtCount; i; i--)
+ {
+ sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32();
+ if(/*SVX_NUM_NUMBER_NONE == nEntryData ||*/
+ (SVX_NUM_BITMAP|LINK_TOKEN) == nEntryData)
+ m_xFmtLB->remove(i - 1);
+ }
+ }
+ //one must be enabled
+ if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_LINKED_BMP))
+ {
+ auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP|LINK_TOKEN));
+ if (nPos != -1)
+ m_xFmtLB->remove(nPos);
+ }
+ else if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP))
+ {
+ auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP));
+ if (nPos != -1)
+ m_xFmtLB->remove(nPos);
+ }
+
+ // MegaHack: because of a not-fixable 'design mistake/error' in Impress
+ // delete all kinds of numeric enumerations
+ if(pActNum->IsFeatureSupported(SvxNumRuleFlags::NO_NUMBERS))
+ {
+ sal_Int32 nFmtCount = m_xFmtLB->get_count();
+ for(sal_Int32 i = nFmtCount; i; i--)
+ {
+ sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32();
+ if( /*nEntryData >= SVX_NUM_CHARS_UPPER_LETTER &&*/ nEntryData <= SVX_NUM_NUMBER_NONE)
+ m_xFmtLB->remove(i - 1);
+ }
+ }
+
+ InitControls();
+ bModified = false;
+}
+
+void SvxNumOptionsTabPage::InitControls()
+{
+ bool bShowBullet = true;
+ bool bShowBitmap = true;
+ bool bSameType = true;
+ bool bSameStart = true;
+ bool bSamePrefix = true;
+ bool bSameSuffix = true;
+ bool bAllLevel = true;
+ bool bSameCharFmt = true;
+ bool bSameVOrient = true;
+ bool bSameSize = true;
+ bool bSameBulColor = true;
+ bool bSameBulRelSize= true;
+
+ TriState isLegal = TRISTATE_INDET;
+
+ const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM];
+ OUString sFirstCharFmt;
+ sal_Int16 eFirstOrient = text::VertOrientation::NONE;
+ Size aFirstSize(0,0);
+ sal_uInt16 nMask = 1;
+ sal_uInt16 nLvl = SAL_MAX_UINT16;
+ sal_uInt16 nHighestLevel = 0;
+
+ bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
+ bool bBullRelSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ aNumFmtArr[i] = &pActNum->GetLevel(i);
+ bShowBullet &= aNumFmtArr[i]->GetNumberingType() == SVX_NUM_CHAR_SPECIAL;
+ bShowBitmap &= (aNumFmtArr[i]->GetNumberingType()&(~LINK_TOKEN)) == SVX_NUM_BITMAP;
+ if(SAL_MAX_UINT16 == nLvl)
+ {
+ nLvl = i;
+ sFirstCharFmt = aNumFmtArr[i]->GetCharFormatName();
+ eFirstOrient = aNumFmtArr[i]->GetVertOrient();
+ if(bShowBitmap)
+ aFirstSize = aNumFmtArr[i]->GetGraphicSize();
+ isLegal = aNumFmtArr[i]->GetIsLegal() ? TRISTATE_TRUE : TRISTATE_FALSE;
+ }
+ if( i > nLvl)
+ {
+ bSameType &= aNumFmtArr[i]->GetNumberingType() == aNumFmtArr[nLvl]->GetNumberingType();
+ bSameStart = aNumFmtArr[i]->GetStart() == aNumFmtArr[nLvl]->GetStart();
+
+ bSamePrefix = aNumFmtArr[i]->GetPrefix() == aNumFmtArr[nLvl]->GetPrefix();
+ bSameSuffix = aNumFmtArr[i]->GetSuffix() == aNumFmtArr[nLvl]->GetSuffix();
+ bAllLevel &= aNumFmtArr[i]->GetIncludeUpperLevels() == aNumFmtArr[nLvl]->GetIncludeUpperLevels();
+ if (aNumFmtArr[i]->GetIsLegal() != aNumFmtArr[nLvl]->GetIsLegal())
+ isLegal = TRISTATE_INDET;
+ bSameCharFmt &= sFirstCharFmt == aNumFmtArr[i]->GetCharFormatName();
+ bSameVOrient &= eFirstOrient == aNumFmtArr[i]->GetVertOrient();
+ if(bShowBitmap && bSameSize)
+ bSameSize &= aNumFmtArr[i]->GetGraphicSize() == aFirstSize;
+ bSameBulColor &= aNumFmtArr[i]->GetBulletColor() == aNumFmtArr[nLvl]->GetBulletColor();
+ bSameBulRelSize &= aNumFmtArr[i]->GetBulletRelSize() == aNumFmtArr[nLvl]->GetBulletRelSize();
+ }
+ nHighestLevel = i;
+ }
+ else
+ aNumFmtArr[i] = nullptr;
+
+ nMask <<= 1 ;
+ }
+ SwitchNumberType(bShowBullet ? 1 : bShowBitmap ? 2 : 0);
+
+ sal_uInt16 nNumberingType;
+ if (nLvl != SAL_MAX_UINT16)
+ nNumberingType = aNumFmtArr[nLvl]->GetNumberingType();
+ else
+ {
+ nNumberingType = SVX_NUM_NUMBER_NONE;
+ bAllLevel = false;
+ bSameBulRelSize = false;
+ bSameBulColor = false;
+ bSameStart = false;
+ bSamePrefix = false;
+ bSameSuffix = false;
+ }
+
+ CheckForStartValue_Impl(nNumberingType);
+
+ if(bShowBitmap)
+ {
+ if(!bSameVOrient || eFirstOrient == text::VertOrientation::NONE)
+ m_xOrientLB->set_active(-1);
+ else
+ m_xOrientLB->set_active(
+ sal::static_int_cast< sal_Int32 >(eFirstOrient - 1));
+ // no text::VertOrientation::NONE
+
+ if(bSameSize)
+ {
+ SetMetricValue(*m_xHeightMF, aFirstSize.Height(), eCoreUnit);
+ SetMetricValue(*m_xWidthMF, aFirstSize.Width(), eCoreUnit);
+ }
+ else
+ {
+ m_xHeightMF->set_text("");
+ m_xWidthMF->set_text("");
+ }
+ }
+
+ if(bSameType)
+ {
+ sal_uInt16 nLBData = nNumberingType;
+ m_xFmtLB->set_active_id(OUString::number(nLBData));
+ }
+ else
+ m_xFmtLB->set_active(-1);
+
+ m_xAllLevelNF->set_sensitive(nHighestLevel > 0 && !m_xSameLevelCB->get_active());
+ m_xAllLevelNF->set_max(nHighestLevel + 1);
+ if(bAllLevel)
+ {
+ m_xAllLevelNF->set_value(aNumFmtArr[nLvl]->GetIncludeUpperLevels());
+ }
+ else
+ {
+ m_xAllLevelNF->set_text("");
+ }
+
+ m_xIsLegalCB->set_state(isLegal);
+ m_xIsLegalCB->set_sensitive(!m_xSameLevelCB->get_active());
+
+ if(bBullRelSize)
+ {
+ if(bSameBulRelSize)
+ m_xBulRelSizeMF->set_value(aNumFmtArr[nLvl]->GetBulletRelSize(), FieldUnit::PERCENT);
+ else
+ m_xBulRelSizeMF->set_text("");
+ }
+ if(bBullColor)
+ {
+ if(bSameBulColor)
+ m_xBulColLB->SelectEntry(aNumFmtArr[nLvl]->GetBulletColor());
+ else
+ m_xBulColLB->SetNoSelection();
+ }
+ m_xStartED->set_value(1); // If this isn't set then changing the bullet type to a numbered type doesn't reset the start level
+ switch(nBullet)
+ {
+ case SHOW_NUMBERING:
+ if(bSameStart)
+ {
+ m_xStartED->set_value(aNumFmtArr[nLvl]->GetStart());
+ }
+ else
+ m_xStartED->set_text("");
+ break;
+ case SHOW_BULLET:
+ break;
+ case SHOW_BITMAP:
+ break;
+ }
+
+ if(bSamePrefix)
+ m_xPrefixED->set_text(aNumFmtArr[nLvl]->GetPrefix());
+ else
+ m_xPrefixED->set_text("");
+ if(bSameSuffix)
+ m_xSuffixED->set_text(aNumFmtArr[nLvl]->GetSuffix());
+ else
+ m_xSuffixED->set_text("");
+
+ if(bSameCharFmt)
+ {
+ if (!sFirstCharFmt.isEmpty())
+ m_xCharFmtLB->set_active_text(sFirstCharFmt);
+ else if (m_xCharFmtLB->get_count())
+ m_xCharFmtLB->set_active(0);
+ }
+ else
+ m_xCharFmtLB->set_active(-1);
+
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+
+// 0 - Number; 1 - Bullet; 2 - Bitmap
+void SvxNumOptionsTabPage::SwitchNumberType( sal_uInt8 nType )
+{
+ if(nBullet == nType)
+ return;
+ nBullet = nType;
+ bool bBullet = (nType == SHOW_BULLET);
+ bool bBitmap = (nType == SHOW_BITMAP);
+ bool bEnableBitmap = (nType == SHOW_BITMAP);
+ bool bNumeric = !(bBitmap||bBullet);
+ m_xSeparatorFT->set_visible(bNumeric);
+ m_xPrefixFT->set_visible(bNumeric);
+ m_xPrefixED->set_visible(bNumeric);
+ m_xSuffixFT->set_visible(bNumeric);
+ m_xSuffixED->set_visible(bNumeric);
+
+ bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
+ m_xCharFmtFT->set_visible(!bBitmap && bCharFmt);
+ m_xCharFmtLB->set_visible(!bBitmap && bCharFmt);
+
+ // this is rather misusage, as there is no own flag
+ // for complete numeration
+ bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
+ bool bAllLevel = bNumeric && bAllLevelFeature && !bHTMLMode;
+ m_xAllLevelFT->set_visible(bAllLevel);
+ m_xAllLevelNF->set_visible(bAllLevel);
+ m_xIsLegalCB->set_visible(bAllLevel);
+
+ m_xStartFT->set_visible(!(bBullet||bBitmap));
+ m_xStartED->set_visible(!(bBullet||bBitmap));
+
+ m_xBulletFT->set_visible(bBullet);
+ m_xBulletPB->set_visible(bBullet);
+ bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
+ m_xBulColorFT->set_visible(!bBitmap && bBullColor);
+ m_xBulColLB->set_visible(!bBitmap && bBullColor);
+ bool bBullResSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
+ m_xBulRelSizeFT->set_visible(!bBitmap && bBullResSize);
+ m_xBulRelSizeMF->set_visible(!bBitmap && bBullResSize);
+
+ m_xBitmapFT->set_visible(bBitmap);
+ m_xBitmapMB->set_visible(bBitmap);
+
+ m_xWidthFT->set_visible(bBitmap);
+ m_xWidthMF->set_visible(bBitmap);
+ m_xHeightFT->set_visible(bBitmap);
+ m_xHeightMF->set_visible(bBitmap);
+ m_xRatioCB->set_visible(bBitmap);
+
+ m_xOrientFT->set_visible(bBitmap && bAllLevelFeature);
+ m_xOrientLB->set_visible(bBitmap && bAllLevelFeature);
+
+ m_xWidthFT->set_sensitive(bEnableBitmap);
+ m_xWidthMF->set_sensitive(bEnableBitmap);
+ m_xHeightFT->set_sensitive(bEnableBitmap);
+ m_xHeightMF->set_sensitive(bEnableBitmap);
+ m_xRatioCB->set_sensitive(bEnableBitmap);
+ m_xOrientFT->set_sensitive(bEnableBitmap);
+ m_xOrientLB->set_sensitive(bEnableBitmap);
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, LevelHdl_Impl, weld::TreeView&, void)
+{
+ if (m_pLevelHdlEvent)
+ return;
+ // tdf#127112 (borrowing tdf#127120 solution) multiselection may be implemented by deselect follow by select so
+ // fire off the handler to happen on next event loop and only process the
+ // final state
+ m_pLevelHdlEvent = Application::PostUserEvent(LINK(this, SvxNumOptionsTabPage, LevelHdl));
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, LevelHdl, void*, void)
+{
+ m_pLevelHdlEvent = nullptr;
+
+ sal_uInt16 nSaveNumLvl = nActNumLvl;
+ nActNumLvl = 0;
+ std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows();
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() &&
+ (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
+ {
+ nActNumLvl = 0xFFFF;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ m_xLevelLB->unselect(i);
+ }
+ else if (!aSelectedRows.empty())
+ {
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end())
+ nActNumLvl |= nMask;
+ nMask <<= 1;
+ }
+ m_xLevelLB->unselect(pActNum->GetLevelCount());
+ }
+ else
+ {
+ nActNumLvl = nSaveNumLvl;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if(nActNumLvl & nMask)
+ {
+ m_xLevelLB->select(i);
+ break;
+ }
+ nMask <<=1;
+ }
+ }
+ InitControls();
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl, Timer *, void)
+{
+ m_aPreviewWIN.Invalidate();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, AllLevelHdl_Impl, weld::SpinButton&, rBox, void)
+{
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 e = 0; e < pActNum->GetLevelCount(); e++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(e));
+ aNumFmt.SetIncludeUpperLevels(static_cast<sal_uInt8>(std::min(rBox.get_value(), sal_Int64(e + 1))) );
+ // Set the same prefix/suffix to generate list format with changed IncludedUpperLevels
+ aNumFmt.SetListFormat(aNumFmt.GetPrefix(), aNumFmt.GetSuffix(), e);
+ pActNum->SetLevel(e, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, IsLegalHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bSet = rBox.get_active();
+ for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if (nActNumLvl & (sal_uInt16(1) << i))
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetIsLegal(bSet);
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ OUString sSelectStyle;
+ bool bShowOrient = false;
+ bool bBmp = false;
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ // PAGEDESC does not exist
+ SvxNumType nNumType = static_cast<SvxNumType>(rBox.get_active_id().toUInt32());
+ aNumFmt.SetNumberingType(nNumType);
+ sal_uInt16 nNumberingType = aNumFmt.GetNumberingType();
+ if(SVX_NUM_BITMAP == (nNumberingType&(~LINK_TOKEN)))
+ {
+ bBmp |= nullptr != aNumFmt.GetBrush();
+ aNumFmt.SetIncludeUpperLevels( 1 );
+ aNumFmt.SetListFormat("", "", i);
+ if(!bBmp)
+ aNumFmt.SetGraphic("");
+ pActNum->SetLevel(i, aNumFmt);
+ SwitchNumberType(SHOW_BITMAP);
+ bShowOrient = true;
+ }
+ else if( SVX_NUM_CHAR_SPECIAL == nNumberingType )
+ {
+ aNumFmt.SetIncludeUpperLevels( 1 );
+ aNumFmt.SetListFormat("", "", i);
+ if( !aNumFmt.GetBulletFont() )
+ aNumFmt.SetBulletFont(&aActBulletFont);
+ if( !aNumFmt.GetBulletChar() )
+ aNumFmt.SetBulletChar( SVX_DEF_BULLET );
+ pActNum->SetLevel(i, aNumFmt);
+ SwitchNumberType(SHOW_BULLET);
+ // allocation of the drawing pattern is automatic
+ if(bAutomaticCharStyles)
+ {
+ sSelectStyle = m_sBulletCharFormatName;
+ }
+ }
+ else
+ {
+ aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
+
+ SwitchNumberType(SHOW_NUMBERING);
+ pActNum->SetLevel(i, aNumFmt);
+ CheckForStartValue_Impl(nNumberingType);
+
+ // allocation of the drawing pattern is automatic
+ if(bAutomaticCharStyles)
+ {
+ sSelectStyle = m_sNumCharFmtName;
+ }
+ }
+ }
+ nMask <<= 1;
+ }
+ bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
+ if(bShowOrient && bAllLevelFeature)
+ {
+ m_xOrientFT->show();
+ m_xOrientLB->show();
+ }
+ else
+ {
+ m_xOrientFT->hide();
+ m_xOrientLB->hide();
+ }
+ SetModified();
+ if(!sSelectStyle.isEmpty())
+ {
+ m_xCharFmtLB->set_active_text(sSelectStyle);
+ CharFmtHdl_Impl(*m_xCharFmtLB);
+ bAutomaticCharStyles = true;
+ }
+}
+
+void SvxNumOptionsTabPage::CheckForStartValue_Impl(sal_uInt16 nNumberingType)
+{
+ bool bIsNull = m_xStartED->get_value() == 0;
+ bool bNoZeroAllowed = nNumberingType < SVX_NUM_ARABIC ||
+ SVX_NUM_CHARS_UPPER_LETTER_N == nNumberingType ||
+ SVX_NUM_CHARS_LOWER_LETTER_N == nNumberingType;
+ m_xStartED->set_min(bNoZeroAllowed ? 1 : 0);
+ if (bIsNull && bNoZeroAllowed)
+ EditModifyHdl_Impl(*m_xStartED);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, OrientHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ sal_Int32 nPos = rBox.get_active();
+ nPos ++; // no VERT_NONE
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
+ {
+ const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
+ const Size& rSize = aNumFmt.GetGraphicSize();
+ sal_Int16 eOrient = static_cast<sal_Int16>(nPos);
+ aNumFmt.SetGraphicBrush( pBrushItem, &rSize, &eOrient );
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ }
+ nMask <<= 1;
+ }
+ SetModified(false);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, SameLevelHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bSet = rBox.get_active();
+ pActNum->SetContinuousNumbering(bSet);
+ bool bRepaint = false;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if(aNumFmt.GetNumberingType() != SVX_NUM_NUMBER_NONE)
+ {
+ bRepaint = true;
+ break;
+ }
+ }
+ SetModified(bRepaint);
+ InitControls();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, BulColorHdl_Impl, ColorListBox&, rColorBox, void)
+{
+ Color nSetColor = rColorBox.GetSelectEntryColor();
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetBulletColor(nSetColor);
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, BulRelSizeHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ sal_uInt16 nRelSize = rField.get_value(FieldUnit::PERCENT);
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetBulletRelSize(nRelSize);
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, GraphicHdl_Impl, const OUString&, rIdent, void)
+{
+ OUString aGrfName;
+ Size aSize;
+ bool bSucc(false);
+ SvxOpenGraphicDialog aGrfDlg(CuiResId(RID_CUISTR_EDIT_GRAPHIC), GetFrameWeld());
+
+ OUString sNumber;
+ if (rIdent.startsWith("gallery", &sNumber))
+ {
+ auto idx = sNumber.toUInt32();
+ if (idx < aGrfNames.size())
+ {
+ aGrfName = aGrfNames[idx];
+ Graphic aGraphic;
+ if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, idx, &aGraphic))
+ {
+ aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
+ bSucc = true;
+ }
+ }
+ }
+ else if (rIdent == "fromfile")
+ {
+ aGrfDlg.EnableLink( false );
+ aGrfDlg.AsLink( false );
+ if ( !aGrfDlg.Execute() )
+ {
+ // memorize selected filter
+ aGrfName = aGrfDlg.GetPath();
+
+ Graphic aGraphic;
+ if( !aGrfDlg.GetGraphic(aGraphic) )
+ {
+ aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
+ bSucc = true;
+ }
+ }
+ }
+ if(!bSucc)
+ return;
+
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit));
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetCharFormatName(m_sNumCharFmtName);
+ aNumFmt.SetGraphic(aGrfName);
+
+ // set size for a later comparison
+ const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
+ // initiate asynchronous loading
+ sal_Int16 eOrient = aNumFmt.GetVertOrient();
+ aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient );
+ aInitSize[i] = aNumFmt.GetGraphicSize();
+
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ m_xRatioCB->set_sensitive(true);
+ m_xWidthFT->set_sensitive(true);
+ m_xHeightFT->set_sensitive(true);
+ m_xWidthMF->set_sensitive(true);
+ m_xHeightMF->set_sensitive(true);
+ SetMetricValue(*m_xWidthMF, aSize.Width(), eCoreUnit);
+ SetMetricValue(*m_xHeightMF, aSize.Height(), eCoreUnit);
+ m_xOrientFT->set_sensitive(true);
+ m_xOrientLB->set_sensitive(true);
+ SetModified();
+ //needed due to asynchronous loading of graphics in the SvxBrushItem
+ aInvalidateTimer.Start();
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, PopupActivateHdl_Impl, weld::Toggleable&, void)
+{
+ if (m_xGalleryMenu)
+ return;
+
+ m_xGalleryMenu = m_xBuilder->weld_menu("gallerysubmenu");
+ weld::WaitObject aWait(GetFrameWeld());
+
+ if (!GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames))
+ return;
+
+ GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS);
+
+ Graphic aGraphic;
+ OUString sGrfName;
+ ScopedVclPtrInstance< VirtualDevice > pVD;
+ size_t i = 0;
+ for (const auto & grfName : aGrfNames)
+ {
+ sGrfName = grfName;
+ OUString sItemId = "gallery" + OUString::number(i);
+ INetURLObject aObj(sGrfName);
+ if (aObj.GetProtocol() == INetProtocol::File)
+ {
+ // tdf#141334 - only show the last name of the filename without its extension
+ aObj.removeExtension();
+ sGrfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
+ }
+ if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, i, &aGraphic))
+ {
+ BitmapEx aBitmap(aGraphic.GetBitmapEx());
+ Size aSize(aBitmap.GetSizePixel());
+ if(aSize.Width() > MAX_BMP_WIDTH ||
+ aSize.Height() > MAX_BMP_HEIGHT)
+ {
+ bool bWidth = aSize.Width() > aSize.Height();
+ double nScale = bWidth ?
+ double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
+ double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
+ aBitmap.Scale(nScale, nScale);
+ }
+ pVD->SetOutputSizePixel(aBitmap.GetSizePixel(), false);
+ pVD->DrawBitmapEx(Point(), aBitmap);
+ m_xGalleryMenu->append(sItemId, sGrfName, *pVD);
+ }
+ else
+ {
+ m_xGalleryMenu->append(sItemId, sGrfName);
+ }
+ ++i;
+ }
+ GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS);
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, BulletHdl_Impl, weld::Button&, void)
+{
+ SvxCharacterMap aMap(GetFrameWeld(), nullptr, nullptr);
+
+ sal_uInt16 nMask = 1;
+ std::optional<vcl::Font> pFmtFont;
+ bool bSameBullet = true;
+ sal_UCS4 cBullet = 0;
+ bool bFirst = true;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ const SvxNumberFormat& rCurFmt = pActNum->GetLevel(i);
+ if(bFirst)
+ {
+ cBullet = rCurFmt.GetBulletChar();
+ }
+ else if(rCurFmt.GetBulletChar() != cBullet )
+ {
+ bSameBullet = false;
+ break;
+ }
+ if(!pFmtFont)
+ pFmtFont = rCurFmt.GetBulletFont();
+ bFirst = false;
+ }
+ nMask <<= 1;
+
+ }
+
+ if (pFmtFont)
+ aMap.SetCharFont(*pFmtFont);
+ else
+ aMap.SetCharFont(aActBulletFont);
+ if (bSameBullet)
+ aMap.SetChar(cBullet);
+ if (aMap.run() != RET_OK)
+ return;
+
+ // change Font Numrules
+ aActBulletFont = aMap.GetCharFont();
+
+ sal_uInt16 _nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & _nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetBulletFont(&aActBulletFont);
+ aNumFmt.SetBulletChar(aMap.GetChar());
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ _nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK( SvxNumOptionsTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ bool bWidth = &rField == m_xWidthMF.get();
+ bLastWidthModified = bWidth;
+ bool bRatio = m_xRatioCB->get_active();
+ tools::Long nWidthVal = static_cast<tools::Long>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::MM_100TH)));
+ tools::Long nHeightVal = static_cast<tools::Long>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::MM_100TH)));
+ nWidthVal = OutputDevice::LogicToLogic( nWidthVal ,
+ MapUnit::Map100thMM, eCoreUnit );
+ nHeightVal = OutputDevice::LogicToLogic( nHeightVal,
+ MapUnit::Map100thMM, eCoreUnit);
+ double fSizeRatio;
+
+ bool bRepaint = false;
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
+ {
+ Size aSize(aNumFmt.GetGraphicSize() );
+ Size aSaveSize(aSize);
+
+ if (aInitSize[i].Height())
+ fSizeRatio = static_cast<double>(aInitSize[i].Width()) / static_cast<double>(aInitSize[i].Height());
+ else
+ fSizeRatio = double(1);
+
+ if(bWidth)
+ {
+ tools::Long nDelta = nWidthVal - aInitSize[i].Width();
+ aSize.setWidth( nWidthVal );
+ if (bRatio)
+ {
+ aSize.setHeight( aInitSize[i].Height() + static_cast<tools::Long>(static_cast<double>(nDelta) / fSizeRatio) );
+ m_xHeightMF->set_value(m_xHeightMF->normalize(
+ OutputDevice::LogicToLogic( aSize.Height(), eCoreUnit, MapUnit::Map100thMM )),
+ FieldUnit::MM_100TH);
+ }
+ }
+ else
+ {
+ tools::Long nDelta = nHeightVal - aInitSize[i].Height();
+ aSize.setHeight( nHeightVal );
+ if (bRatio)
+ {
+ aSize.setWidth( aInitSize[i].Width() + static_cast<tools::Long>(static_cast<double>(nDelta) * fSizeRatio) );
+ m_xWidthMF->set_value(m_xWidthMF->normalize(
+ OutputDevice::LogicToLogic( aSize.Width(), eCoreUnit, MapUnit::Map100thMM )),
+ FieldUnit::MM_100TH);
+ }
+ }
+ const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
+ sal_Int16 eOrient = aNumFmt.GetVertOrient();
+ if(aSize != aSaveSize)
+ bRepaint = true;
+ aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient );
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ }
+ nMask <<= 1;
+ }
+ SetModified(bRepaint);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, RatioHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ if (rBox.get_active())
+ {
+ if (bLastWidthModified)
+ SizeHdl_Impl(*m_xWidthMF);
+ else
+ SizeHdl_Impl(*m_xHeightMF);
+ }
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, CharFmtHdl_Impl, weld::ComboBox&, void)
+{
+ bAutomaticCharStyles = false;
+ sal_Int32 nEntryPos = m_xCharFmtLB->get_active();
+ OUString sEntry = m_xCharFmtLB->get_active_text();
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if( 0 == nEntryPos )
+ aNumFmt.SetCharFormatName("");
+ else
+ {
+ if(SVX_NUM_BITMAP != (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
+ aNumFmt.SetCharFormatName(sEntry);
+ }
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified(false);
+};
+
+IMPL_LINK(SvxNumOptionsTabPage, EditModifyHdl_Impl, weld::Entry&, rEdit, void)
+{
+ EditModifyHdl_Impl(&rEdit);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, SpinModifyHdl_Impl, weld::SpinButton&, rSpinButton, void)
+{
+ EditModifyHdl_Impl(&rSpinButton);
+}
+
+void SvxNumOptionsTabPage::EditModifyHdl_Impl(const weld::Entry* pEdit)
+{
+ bool bPrefixSuffix = (pEdit == m_xPrefixED.get())|| (pEdit == m_xSuffixED.get());
+ bool bStart = pEdit == m_xStartED.get();
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if (bPrefixSuffix)
+ aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
+ else if(bStart)
+ aNumFmt.SetStart(m_xStartED->get_value());
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+static tools::Long lcl_DrawGraphic(VirtualDevice& rVDev, const SvxNumberFormat &rFmt, tools::Long nXStart,
+ tools::Long nYMiddle, tools::Long nDivision)
+{
+ const SvxBrushItem* pBrushItem = rFmt.GetBrush();
+ tools::Long nRet = 0;
+ if(pBrushItem)
+ {
+ const Graphic* pGrf = pBrushItem->GetGraphic();
+ if(pGrf)
+ {
+ Size aGSize( rFmt.GetGraphicSize() );
+ aGSize.setWidth( aGSize.Width() / nDivision );
+ nRet = aGSize.Width();
+ aGSize.setHeight( aGSize.Height() / nDivision );
+ pGrf->Draw(rVDev, Point(nXStart,nYMiddle - ( aGSize.Height() / 2) ),
+ rVDev.PixelToLogic( aGSize ) );
+ }
+ }
+ return nRet;
+
+}
+
+static tools::Long lcl_DrawBullet(VirtualDevice* pVDev,
+ const SvxNumberFormat& rFmt, tools::Long nXStart,
+ tools::Long nYStart, const Size& rSize)
+{
+ vcl::Font aTmpFont(pVDev->GetFont());
+
+ // via Uno it's possible that no font has been set!
+ vcl::Font aFont(rFmt.GetBulletFont() ? *rFmt.GetBulletFont() : aTmpFont);
+ Size aTmpSize(rSize);
+ aTmpSize.setWidth( aTmpSize.Width() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setWidth( aTmpSize.Width() / 100 ) ;
+ aTmpSize.setHeight( aTmpSize.Height() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setHeight( aTmpSize.Height() / 100 ) ;
+ // in case of a height of zero it is drawn in original height
+ if(!aTmpSize.Height())
+ aTmpSize.setHeight( 1 );
+ aFont.SetFontSize(aTmpSize);
+ aFont.SetTransparent(true);
+ Color aBulletColor = rFmt.GetBulletColor();
+ if (aBulletColor == COL_AUTO)
+ aBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+ else if (pVDev->GetBackgroundColor().IsDark() == aBulletColor.IsDark())
+ aBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+ aFont.SetColor(aBulletColor);
+ pVDev->SetFont( aFont );
+ sal_UCS4 cChar = rFmt.GetBulletChar();
+ OUString aText(&cChar, 1);
+ tools::Long nY = nYStart;
+ nY -= ((aTmpSize.Height() - rSize.Height())/ 2);
+ pVDev->DrawText( Point(nXStart, nY), aText );
+ tools::Long nRet = pVDev->GetTextWidth(aText);
+
+ pVDev->SetFont(aTmpFont);
+ return nRet;
+}
+
+SvxNumberingPreview::SvxNumberingPreview()
+ : pActNum(nullptr)
+ , bPosition(false)
+ , nActLevel(SAL_MAX_UINT16)
+{
+}
+
+// paint preview of numeration
+void SvxNumberingPreview::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& /*rRect*/)
+{
+ Size aSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
+
+ // Use default document and font colors to create preview
+ const Color aBackColor = svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
+ const Color aTextColor = svtools::ColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
+
+ ScopedVclPtrInstance<VirtualDevice> pVDev(rRenderContext);
+ pVDev->EnableRTL(rRenderContext.IsRTLEnabled());
+ pVDev->SetMapMode(rRenderContext.GetMapMode());
+ pVDev->SetOutputSize(aSize);
+
+ Color aLineColor(COL_LIGHTGRAY);
+ if (aLineColor == aBackColor)
+ aLineColor.Invert();
+ pVDev->SetLineColor(aLineColor);
+ pVDev->SetFillColor(aBackColor);
+ pVDev->SetBackground(Wallpaper(aBackColor));
+ pVDev->DrawWallpaper(pVDev->GetOutputRectPixel(), pVDev->GetBackground());
+
+ if (pActNum)
+ {
+ tools::Long nWidthRelation = 30; // chapter dialog
+
+ // height per level
+ tools::Long nXStep = aSize.Width() / (pActNum->GetLevelCount() > 1 ? 3 * pActNum->GetLevelCount() : 3);
+ if (pActNum->GetLevelCount() < 10)
+ nXStep /= 2;
+ tools::Long nYStart = 4;
+ // the whole height mustn't be used for a single level
+ tools::Long nYStep = (aSize.Height() - 6)/ (pActNum->GetLevelCount() > 1 ? pActNum->GetLevelCount() : 5);
+
+ aStdFont = OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS, MsLangId::getConfiguredSystemLanguage(), GetDefaultFontFlags::OnlyOne);
+ aStdFont.SetColor(aTextColor);
+ aStdFont.SetFillColor(aBackColor);
+
+ tools::Long nFontHeight = nYStep * 6 / 10;
+ if (bPosition)
+ nFontHeight = nYStep * 15 / 10;
+ aStdFont.SetFontSize(Size( 0, nFontHeight ));
+
+ SvxNodeNum aNum;
+ sal_uInt16 nPreNum = pActNum->GetLevel(0).GetStart();
+
+ if (bPosition)
+ {
+ // When bPosition == true, draw the preview used in the Writer's "Position" tab
+ // This is not used in Impress/Draw
+
+ tools::Long nLineHeight = nFontHeight * 8 / 7;
+ sal_uInt8 nStart = 0;
+ while (!(nActLevel & (1<<nStart)))
+ {
+ nStart++;
+ }
+ if (nStart)
+ nStart--;
+ sal_uInt8 nEnd = std::min(sal_uInt8(nStart + 3), sal_uInt8(pActNum->GetLevelCount()));
+ for (sal_uInt8 nLevel = nStart; nLevel < nEnd; ++nLevel)
+ {
+ const SvxNumberFormat &rFmt = pActNum->GetLevel(nLevel);
+ aNum.GetLevelVal()[nLevel] = rFmt.GetStart();
+
+ tools::Long nXStart( 0 );
+ short nTextOffset( 0 );
+ tools::Long nNumberXPos( 0 );
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
+ nTextOffset = rFmt.GetCharTextDistance() / nWidthRelation;
+ nNumberXPos = nXStart;
+ tools::Long nFirstLineOffset = (-rFmt.GetFirstLineOffset()) / nWidthRelation;
+
+ if (nFirstLineOffset <= nNumberXPos)
+ nNumberXPos = nNumberXPos - nFirstLineOffset;
+ else
+ nNumberXPos = 0;
+ // in draw this is valid
+ if (nTextOffset < 0)
+ nNumberXPos = nNumberXPos + nTextOffset;
+ }
+ else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ const tools::Long nTmpNumberXPos((rFmt.GetIndentAt() + rFmt.GetFirstLineIndent() ) / nWidthRelation);
+ if (nTmpNumberXPos < 0)
+ {
+ nNumberXPos = 0;
+ }
+ else
+ {
+ nNumberXPos = nTmpNumberXPos;
+ }
+ }
+
+ tools::Long nBulletWidth = 0;
+ if (SVX_NUM_BITMAP == (rFmt.GetNumberingType() &(~LINK_TOKEN)))
+ {
+ tools::Long nYMiddle = nYStart + ( nFontHeight / 2 );
+ nBulletWidth = rFmt.IsShowSymbol() ? lcl_DrawGraphic(*pVDev, rFmt, nNumberXPos, nYMiddle, nWidthRelation) : 0;
+ }
+ else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType())
+ {
+ nBulletWidth = rFmt.IsShowSymbol() ? lcl_DrawBullet(pVDev.get(), rFmt, nNumberXPos, nYStart, aStdFont.GetFontSize()) : 0;
+ }
+ else
+ {
+ pVDev->SetFont(aStdFont);
+ aNum.SetLevel(nLevel);
+ if (pActNum->IsContinuousNumbering())
+ aNum.GetLevelVal()[nLevel] = nPreNum;
+ OUString aText(pActNum->MakeNumString( aNum ));
+ vcl::Font aSaveFont = pVDev->GetFont();
+ vcl::Font aColorFont(aSaveFont);
+ Color aTmpBulletColor = rFmt.GetBulletColor();
+ if (aTmpBulletColor == COL_AUTO)
+ aTmpBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+ else if (pVDev->GetBackgroundColor().IsDark() == aTmpBulletColor.IsDark())
+ aTmpBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+ aColorFont.SetColor(aTmpBulletColor);
+ pVDev->SetFont(aColorFont);
+ pVDev->DrawText(Point(nNumberXPos, nYStart), aText);
+ pVDev->SetFont(aSaveFont);
+ nBulletWidth = pVDev->GetTextWidth(aText);
+ nPreNum++;
+ }
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT &&
+ rFmt.GetLabelFollowedBy() == SvxNumberFormat::SPACE )
+ {
+ pVDev->SetFont(aStdFont);
+ OUString aText(' ');
+ pVDev->DrawText( Point(nNumberXPos, nYStart), aText );
+ nBulletWidth = nBulletWidth + pVDev->GetTextWidth(aText);
+ }
+
+ tools::Long nTextXPos( 0 );
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nTextXPos = nXStart;
+ if (nTextOffset < 0)
+ nTextXPos = nTextXPos + nTextOffset;
+ if (nNumberXPos + nBulletWidth + nTextOffset > nTextXPos)
+ nTextXPos = nNumberXPos + nBulletWidth + nTextOffset;
+ }
+ else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ switch (rFmt.GetLabelFollowedBy())
+ {
+ case SvxNumberFormat::LISTTAB:
+ {
+ nTextXPos = rFmt.GetListtabPos() / nWidthRelation;
+ if (nTextXPos < nNumberXPos + nBulletWidth)
+ {
+ nTextXPos = nNumberXPos + nBulletWidth;
+ }
+ }
+ break;
+ case SvxNumberFormat::SPACE:
+ case SvxNumberFormat::NOTHING:
+ case SvxNumberFormat::NEWLINE:
+ {
+ nTextXPos = nNumberXPos + nBulletWidth;
+ }
+ break;
+ }
+
+ nXStart = rFmt.GetIndentAt() / nWidthRelation;
+ }
+
+ ::tools::Rectangle aRect1(Point(nTextXPos, nYStart + nFontHeight / 2), Size(aSize.Width() / 2, 2));
+ pVDev->SetFillColor(aBackColor);
+ pVDev->DrawRect(aRect1);
+
+ ::tools::Rectangle aRect2(Point(nXStart, nYStart + nLineHeight + nFontHeight / 2 ), Size(aSize.Width() / 2, 2));
+ pVDev->DrawRect(aRect2);
+ nYStart += 2 * nLineHeight;
+ }
+ }
+ else
+ {
+ // When bPosition == false, draw the preview used in Writer's "Customize" tab
+ // and in Impress' "Bullets and Numbering" dialog
+
+ //#i5153# painting gray or black rectangles as 'normal' numbering text
+ tools::Long nWidth = pVDev->GetTextWidth("Preview");
+ tools::Long nTextHeight = pVDev->GetTextHeight();
+ tools::Long nRectHeight = nTextHeight * 2 / 3;
+ tools::Long nTopOffset = nTextHeight - nRectHeight;
+ Color aSelRectColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+
+ for (sal_uInt16 nLevel = 0; nLevel < pActNum->GetLevelCount(); ++nLevel, nYStart = nYStart + nYStep)
+ {
+ const SvxNumberFormat &rFmt = pActNum->GetLevel(nLevel);
+ aNum.GetLevelVal()[ nLevel ] = rFmt.GetStart();
+ tools::Long nXStart( 0 );
+ pVDev->SetFillColor( aBackColor );
+
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
+ }
+ else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ const tools::Long nTmpXStart((rFmt.GetIndentAt() + rFmt.GetFirstLineIndent() ) / nWidthRelation);
+ if (nTmpXStart < 0)
+ {
+ nXStart = 0;
+ }
+ else
+ {
+ nXStart = nTmpXStart;
+ }
+ }
+ nXStart /= 2;
+ nXStart += 2;
+ tools::Long nTextOffset = 2 * nXStep;
+ if (SVX_NUM_BITMAP == (rFmt.GetNumberingType()&(~LINK_TOKEN)))
+ {
+ if (rFmt.IsShowSymbol())
+ {
+ tools::Long nYMiddle = nYStart + ( nFontHeight / 2 );
+ nTextOffset = lcl_DrawGraphic(*pVDev, rFmt, nXStart, nYMiddle, nWidthRelation);
+ nTextOffset = nTextOffset + nXStep;
+ }
+ }
+ else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType())
+ {
+ if (rFmt.IsShowSymbol())
+ {
+ nTextOffset = lcl_DrawBullet(pVDev.get(), rFmt, nXStart, nYStart, aStdFont.GetFontSize());
+ nTextOffset = nTextOffset + nXStep;
+ }
+ }
+ else
+ {
+ vcl::Font aFont(aStdFont);
+ Size aTmpSize(aStdFont.GetFontSize());
+ if(pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE))
+ {
+ aTmpSize.setWidth( aTmpSize.Width() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setWidth( aTmpSize.Width() / 100 ) ;
+ aTmpSize.setHeight( aTmpSize.Height() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setHeight( aTmpSize.Height() / 100 ) ;
+ }
+ if(!aTmpSize.Height())
+ aTmpSize.setHeight( 1 );
+ aFont.SetFontSize(aTmpSize);
+ Color aTmpBulletColor = rFmt.GetBulletColor();
+ if (aTmpBulletColor == COL_AUTO)
+ aTmpBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+ else if (pVDev->GetBackgroundColor().IsDark() == aTmpBulletColor.IsDark())
+ aTmpBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+ aFont.SetColor(aTmpBulletColor);
+ pVDev->SetFont(aFont);
+ aNum.SetLevel( nLevel );
+ if (pActNum->IsContinuousNumbering())
+ aNum.GetLevelVal()[nLevel] = nPreNum;
+ OUString aText(pActNum->MakeNumString(aNum));
+ tools::Long nY = nYStart;
+ nY -= (pVDev->GetTextHeight() - nTextHeight - pVDev->GetFontMetric().GetDescent());
+ pVDev->DrawText(Point(nXStart, nY), aText);
+ nTextOffset = pVDev->GetTextWidth(aText);
+ nTextOffset = nTextOffset + nXStep;
+ nPreNum++;
+ pVDev->SetFont(aStdFont);
+ }
+ //#i5153# the selected rectangle(s) should be black
+ if (0 != (nActLevel & (1<<nLevel)))
+ {
+ pVDev->SetFillColor( aSelRectColor );
+ pVDev->SetLineColor( aSelRectColor );
+ }
+ else
+ {
+ //#i5153# unselected levels are gray
+ pVDev->SetFillColor( aLineColor );
+ pVDev->SetLineColor( aLineColor );
+ }
+ ::tools::Rectangle aRect1(Point(nXStart + nTextOffset, nYStart + nTopOffset), Size(nWidth, nRectHeight));
+ pVDev->DrawRect(aRect1);
+ }
+ }
+ }
+ rRenderContext.DrawOutDev(Point(), aSize, Point(), aSize, *pVDev);
+}
+
+
+//See uiconfig/swriter/ui/outlinepositionpage.ui for effectively a duplicate
+//dialog to this one, except with a different preview window impl.
+//TODO, determine if SwNumPositionTabPage and SvxNumPositionTabPage can be
+//merged
+SvxNumPositionTabPage::SvxNumPositionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/numberingpositionpage.ui", "NumberingPositionPage", &rSet)
+ , m_pLevelHdlEvent(nullptr)
+ , nActNumLvl(1)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , bModified(false)
+ , bPreset(false)
+ , bInInintControl(false)
+ , bLabelAlignmentPosAndSpaceModeActive(false)
+ , m_xLevelLB(m_xBuilder->weld_tree_view("levellb"))
+ , m_xDistBorderFT(m_xBuilder->weld_label("indent"))
+ , m_xDistBorderMF(m_xBuilder->weld_metric_spin_button("indentmf", FieldUnit::CM))
+ , m_xRelativeCB(m_xBuilder->weld_check_button("relative"))
+ , m_xIndentFT(m_xBuilder->weld_label("numberingwidth"))
+ , m_xIndentMF(m_xBuilder->weld_metric_spin_button("numberingwidthmf", FieldUnit::CM))
+ , m_xDistNumFT(m_xBuilder->weld_label("numdist"))
+ , m_xDistNumMF(m_xBuilder->weld_metric_spin_button("numdistmf", FieldUnit::CM))
+ , m_xAlignFT(m_xBuilder->weld_label("numalign"))
+ , m_xAlignLB(m_xBuilder->weld_combo_box("numalignlb"))
+ , m_xLabelFollowedByFT(m_xBuilder->weld_label("numfollowedby"))
+ , m_xLabelFollowedByLB(m_xBuilder->weld_combo_box("numfollowedbylb"))
+ , m_xListtabFT(m_xBuilder->weld_label("at"))
+ , m_xListtabMF(m_xBuilder->weld_metric_spin_button("atmf", FieldUnit::CM))
+ , m_xAlign2FT(m_xBuilder->weld_label("num2align"))
+ , m_xAlign2LB(m_xBuilder->weld_combo_box("num2alignlb"))
+ , m_xAlignedAtFT(m_xBuilder->weld_label("alignedat"))
+ , m_xAlignedAtMF(m_xBuilder->weld_metric_spin_button("alignedatmf", FieldUnit::CM))
+ , m_xIndentAtFT(m_xBuilder->weld_label("indentat"))
+ , m_xIndentAtMF(m_xBuilder->weld_metric_spin_button("indentatmf", FieldUnit::CM))
+ , m_xStandardPB(m_xBuilder->weld_button("standard"))
+ , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWIN))
+{
+ SetExchangeSupport();
+
+ // set metric
+ FieldUnit eFUnit = GetModuleFieldUnit(rSet);
+
+ SetFieldUnit( *m_xDistBorderMF, eFUnit );
+ SetFieldUnit( *m_xIndentMF, eFUnit );
+ SetFieldUnit( *m_xDistNumMF, eFUnit );
+
+ m_xAlignedAtMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
+ m_xListtabMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
+ m_xIndentAtMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
+
+ m_xRelativeCB->set_active(true);
+ m_xAlignLB->connect_changed(LINK(this, SvxNumPositionTabPage, EditModifyHdl_Impl));
+ m_xAlign2LB->connect_changed(LINK(this, SvxNumPositionTabPage, EditModifyHdl_Impl));
+ for ( sal_Int32 i = 0; i < m_xAlignLB->get_count(); ++i )
+ {
+ m_xAlign2LB->append_text(m_xAlignLB->get_text(i));
+ }
+
+ Link<weld::MetricSpinButton&,void> aLk3 = LINK(this, SvxNumPositionTabPage, DistanceHdl_Impl);
+ m_xDistBorderMF->connect_value_changed(aLk3);
+ m_xDistNumMF->connect_value_changed(aLk3);
+ m_xIndentMF->connect_value_changed(aLk3);
+
+ m_xLabelFollowedByLB->connect_changed(LINK(this, SvxNumPositionTabPage, LabelFollowedByHdl_Impl));
+
+ m_xListtabMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, ListtabPosHdl_Impl));
+ m_xAlignedAtMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, AlignAtHdl_Impl));
+ m_xIndentAtMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, IndentAtHdl_Impl));
+
+ m_xLevelLB->set_selection_mode(SelectionMode::Multiple);
+ m_xLevelLB->connect_changed(LINK(this, SvxNumPositionTabPage, LevelHdl_Impl));
+ m_xRelativeCB->connect_toggled(LINK(this, SvxNumPositionTabPage, RelativeHdl_Impl));
+ m_xStandardPB->connect_clicked(LINK(this, SvxNumPositionTabPage, StandardHdl_Impl));
+
+ m_xRelativeCB->set_active(bLastRelative);
+ m_aPreviewWIN.SetPositionMode();
+ eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
+}
+
+SvxNumPositionTabPage::~SvxNumPositionTabPage()
+{
+ if (m_pLevelHdlEvent)
+ {
+ Application::RemoveUserEvent(m_pLevelHdlEvent);
+ m_pLevelHdlEvent = nullptr;
+ }
+ m_xPreviewWIN.reset();
+}
+
+/*-------------------------------------------------------*/
+
+void SvxNumPositionTabPage::InitControls()
+{
+ bInInintControl = true;
+ const bool bRelative = !bLabelAlignmentPosAndSpaceModeActive &&
+ m_xRelativeCB->get_sensitive() && m_xRelativeCB->get_active();
+ const bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 &&
+ SAL_MAX_UINT16 != nActNumLvl;
+
+ m_xDistBorderMF->set_sensitive( !bLabelAlignmentPosAndSpaceModeActive &&
+ ( bSingleSelection || bRelative ) );
+ m_xDistBorderFT->set_sensitive( !bLabelAlignmentPosAndSpaceModeActive &&
+ ( bSingleSelection || bRelative ) );
+
+ bool bSetDistEmpty = false;
+ bool bSameDistBorderNum = !bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameDist = !bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameIndent = !bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameAdjust = true;
+
+ bool bSameLabelFollowedBy = bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameListtab = bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameAlignAt = bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameIndentAt = bLabelAlignmentPosAndSpaceModeActive;
+
+ const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM];
+ sal_uInt16 nMask = 1;
+ sal_uInt16 nLvl = SAL_MAX_UINT16;
+ tools::Long nFirstBorderTextRelative = -1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ aNumFmtArr[i] = &pActNum->GetLevel(i);
+ if(nActNumLvl & nMask)
+ {
+ if(SAL_MAX_UINT16 == nLvl)
+ nLvl = i;
+
+ if( i > nLvl)
+ {
+ bSameAdjust &= aNumFmtArr[i]->GetNumAdjust() == aNumFmtArr[nLvl]->GetNumAdjust();
+ if ( !bLabelAlignmentPosAndSpaceModeActive )
+ {
+ if(bRelative)
+ {
+ if(nFirstBorderTextRelative == -1)
+ nFirstBorderTextRelative =
+ (aNumFmtArr[i]->GetAbsLSpace() + aNumFmtArr[i]->GetFirstLineOffset() -
+ aNumFmtArr[i - 1]->GetAbsLSpace() + aNumFmtArr[i - 1]->GetFirstLineOffset());
+ else
+ bSameDistBorderNum &= nFirstBorderTextRelative ==
+ (aNumFmtArr[i]->GetAbsLSpace() + aNumFmtArr[i]->GetFirstLineOffset() -
+ aNumFmtArr[i - 1]->GetAbsLSpace() + aNumFmtArr[i - 1]->GetFirstLineOffset());
+ }
+ else
+ bSameDistBorderNum &=
+ aNumFmtArr[i]->GetAbsLSpace() - aNumFmtArr[i]->GetFirstLineOffset() ==
+ aNumFmtArr[i - 1]->GetAbsLSpace() - aNumFmtArr[i - 1]->GetFirstLineOffset();
+
+ bSameDist &= aNumFmtArr[i]->GetCharTextDistance() == aNumFmtArr[nLvl]->GetCharTextDistance();
+ bSameIndent &= aNumFmtArr[i]->GetFirstLineOffset() == aNumFmtArr[nLvl]->GetFirstLineOffset();
+ }
+ else
+ {
+ bSameLabelFollowedBy &=
+ aNumFmtArr[i]->GetLabelFollowedBy() == aNumFmtArr[nLvl]->GetLabelFollowedBy();
+ bSameListtab &=
+ aNumFmtArr[i]->GetListtabPos() == aNumFmtArr[nLvl]->GetListtabPos();
+ bSameAlignAt &=
+ ( ( aNumFmtArr[i]->GetIndentAt() + aNumFmtArr[i]->GetFirstLineIndent() )
+ == ( aNumFmtArr[nLvl]->GetIndentAt() + aNumFmtArr[nLvl]->GetFirstLineIndent() ) );
+ bSameIndentAt &=
+ aNumFmtArr[i]->GetIndentAt() == aNumFmtArr[nLvl]->GetIndentAt();
+ }
+ }
+ }
+ nMask <<= 1;
+
+ }
+ if (SVX_MAX_NUM <= nLvl)
+ {
+ OSL_ENSURE(false, "cannot happen.");
+ return;
+ }
+
+ if(bSameDistBorderNum)
+ {
+ tools::Long nDistBorderNum;
+ if(bRelative)
+ {
+ nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace())+ aNumFmtArr[nLvl]->GetFirstLineOffset();
+ if(nLvl)
+ nDistBorderNum -= static_cast<tools::Long>(aNumFmtArr[nLvl - 1]->GetAbsLSpace())+ aNumFmtArr[nLvl - 1]->GetFirstLineOffset();
+ }
+ else
+ {
+ nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace())+ aNumFmtArr[nLvl]->GetFirstLineOffset();
+ }
+ SetMetricValue(*m_xDistBorderMF, nDistBorderNum, eCoreUnit);
+ }
+ else
+ bSetDistEmpty = true;
+
+ if(bSameDist)
+ SetMetricValue(*m_xDistNumMF, aNumFmtArr[nLvl]->GetCharTextDistance(), eCoreUnit);
+ else
+ m_xDistNumMF->set_text("");
+ if(bSameIndent)
+ SetMetricValue(*m_xIndentMF, - aNumFmtArr[nLvl]->GetFirstLineOffset(), eCoreUnit);
+ else
+ m_xIndentMF->set_text("");
+
+ if(bSameAdjust)
+ {
+ sal_Int32 nPos = 1; // centered
+ if(aNumFmtArr[nLvl]->GetNumAdjust() == SvxAdjust::Left)
+ nPos = 0;
+ else if(aNumFmtArr[nLvl]->GetNumAdjust() == SvxAdjust::Right)
+ nPos = 2;
+ m_xAlignLB->set_active(nPos);
+ m_xAlign2LB->set_active(nPos);
+ }
+ else
+ {
+ m_xAlignLB->set_active(-1);
+ m_xAlign2LB->set_active(-1);
+ }
+
+ if ( bSameLabelFollowedBy )
+ {
+ sal_Int32 nPos = 0; // LISTTAB
+ if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::SPACE )
+ {
+ nPos = 1;
+ }
+ else if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NOTHING )
+ {
+ nPos = 2;
+ }
+ else if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NEWLINE )
+ {
+ nPos = 3;
+ }
+ m_xLabelFollowedByLB->set_active(nPos);
+ }
+ else
+ {
+ m_xLabelFollowedByLB->set_active(-1);
+ }
+
+ if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
+ {
+ m_xListtabFT->set_sensitive(true);
+ m_xListtabMF->set_sensitive(true);
+ if ( bSameListtab )
+ {
+ SetMetricValue(*m_xListtabMF, aNumFmtArr[nLvl]->GetListtabPos(), eCoreUnit);
+ }
+ else
+ {
+ m_xListtabMF->set_text("");
+ }
+ }
+ else
+ {
+ m_xListtabFT->set_sensitive(false);
+ m_xListtabMF->set_sensitive(false);
+ m_xListtabMF->set_text("");
+ }
+
+ if ( bSameAlignAt )
+ {
+ SetMetricValue(*m_xAlignedAtMF,
+ aNumFmtArr[nLvl]->GetIndentAt() + aNumFmtArr[nLvl]->GetFirstLineIndent(),
+ eCoreUnit);
+ }
+ else
+ {
+ m_xAlignedAtMF->set_text("");
+ }
+
+ if ( bSameIndentAt )
+ {
+ SetMetricValue(*m_xIndentAtMF, aNumFmtArr[nLvl]->GetIndentAt(), eCoreUnit);
+ }
+ else
+ {
+ m_xIndentAtMF->set_text("");
+ }
+
+ if ( bSetDistEmpty )
+ m_xDistBorderMF->set_text("");
+
+ bInInintControl = false;
+}
+
+void SvxNumPositionTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ sal_uInt16 nTmpNumLvl = 1;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nTmpNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+ bModified = (!pActNum->Get( 0 ) || bPreset);
+ if(*pSaveNum != *pActNum ||
+ nActNumLvl != nTmpNumLvl )
+ {
+ *pActNum = *pSaveNum;
+ nActNumLvl = nTmpNumLvl;
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ m_xLevelLB->select(pActNum->GetLevelCount());
+ if (nActNumLvl != SAL_MAX_UINT16)
+ for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if (nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1 ;
+ }
+ m_xRelativeCB->set_sensitive(nActNumLvl != 1);
+
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+
+ InitControls();
+ }
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+
+DeactivateRC SvxNumPositionTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ {
+ if (m_xDistBorderMF->get_sensitive())
+ DistanceHdl_Impl(*m_xDistBorderMF);
+ DistanceHdl_Impl(*m_xIndentMF);
+ FillItemSet(_pSet);
+ }
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxNumPositionTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl));
+
+ if(bModified && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false));
+ }
+ return bModified;
+}
+
+void SvxNumPositionTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pItem =
+ rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pItem )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ }
+ }
+ DBG_ASSERT(pItem, "no item found!");
+ pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
+
+ // insert levels
+ if (!m_xLevelLB->count_selected_rows())
+ {
+ for(sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++)
+ m_xLevelLB->append_text(OUString::number(i));
+ if(pSaveNum->GetLevelCount() > 1)
+ {
+ OUString sEntry = "1 - " + OUString::number( pSaveNum->GetLevelCount() );
+ m_xLevelLB->append_text(sEntry);
+ m_xLevelLB->select_text(sEntry);
+ }
+ else
+ m_xLevelLB->select(0);
+ }
+ else
+ m_xLevelLB->select(m_xLevelLB->count_selected_rows() - 1);
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ {
+ m_xLevelLB->select(pSaveNum->GetLevelCount());
+ }
+ else
+ {
+ for(sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1;
+ }
+ }
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+ m_aPreviewWIN.SetNumRule(pActNum.get());
+
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+
+ InitControls();
+ bModified = false;
+}
+
+void SvxNumPositionTabPage::InitPosAndSpaceMode()
+{
+ if ( pActNum == nullptr )
+ {
+ SAL_WARN( "cui.tabpages",
+ "<SvxNumPositionTabPage::InitPosAndSpaceMode()> - misusage of method -> <pAktNum> has to be already set!" );
+ return;
+ }
+
+ SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode =
+ SvxNumberFormat::LABEL_ALIGNMENT;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ ePosAndSpaceMode = aNumFmt.GetPositionAndSpaceMode();
+ if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ break;
+ }
+ }
+ nMask <<= 1;
+ }
+
+ bLabelAlignmentPosAndSpaceModeActive =
+ ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT;
+}
+
+void SvxNumPositionTabPage::ShowControlsDependingOnPosAndSpaceMode()
+{
+ m_xDistBorderFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xDistBorderMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xRelativeCB->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xDistNumFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive &&
+ pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS) );
+ m_xDistNumMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive &&
+ pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS));
+ m_xAlignFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignLB->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+
+ m_xLabelFollowedByFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xLabelFollowedByLB->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xListtabFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xListtabMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlign2FT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlign2LB->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignedAtFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignedAtMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentAtFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentAtMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+}
+
+std::unique_ptr<SfxTabPage> SvxNumPositionTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxNumPositionTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxNumPositionTabPage::SetMetric(FieldUnit eMetric)
+{
+ if (eMetric == FieldUnit::MM)
+ {
+ m_xDistBorderMF->set_digits(1);
+ m_xDistNumMF->set_digits(1);
+ m_xIndentMF->set_digits(1);
+ m_xListtabMF->set_digits(1);
+ m_xAlignedAtMF->set_digits(1);
+ m_xIndentAtMF->set_digits(1);
+ }
+ m_xDistBorderMF->set_unit(eMetric);
+ m_xDistNumMF->set_unit(eMetric);
+ m_xIndentMF->set_unit(eMetric);
+ m_xListtabMF->set_unit(eMetric);
+ m_xAlignedAtMF->set_unit(eMetric);
+ m_xIndentAtMF->set_unit(eMetric);
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, EditModifyHdl_Impl, weld::ComboBox&, void)
+{
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+
+ const sal_Int32 nPos = m_xAlignLB->get_visible()
+ ? m_xAlignLB->get_active()
+ : m_xAlign2LB->get_active();
+ SvxAdjust eAdjust = SvxAdjust::Center;
+ if(nPos == 0)
+ eAdjust = SvxAdjust::Left;
+ else if(nPos == 2)
+ eAdjust = SvxAdjust::Right;
+ aNumFmt.SetNumAdjust( eAdjust );
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl_Impl, weld::TreeView&, void)
+{
+ if (m_pLevelHdlEvent)
+ return;
+ // tdf#127120 multiselection may be implemented by deselect follow by select so
+ // fire off the handler to happen on next event loop and only process the
+ // final state
+ m_pLevelHdlEvent = Application::PostUserEvent(LINK(this, SvxNumPositionTabPage, LevelHdl));
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl, void*, void)
+{
+ m_pLevelHdlEvent = nullptr;
+
+ sal_uInt16 nSaveNumLvl = nActNumLvl;
+ nActNumLvl = 0;
+ std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows();
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() &&
+ (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
+ {
+ nActNumLvl = 0xFFFF;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ m_xLevelLB->unselect(i);
+ }
+ else if (!aSelectedRows.empty())
+ {
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end())
+ nActNumLvl |= nMask;
+ nMask <<= 1;
+ }
+ m_xLevelLB->unselect(pActNum->GetLevelCount());
+ }
+ else
+ {
+ nActNumLvl = nSaveNumLvl;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if(nActNumLvl & nMask)
+ {
+ m_xLevelLB->select(i);
+ break;
+ }
+ nMask <<=1;
+ }
+ }
+ m_xRelativeCB->set_sensitive(nActNumLvl != 1);
+ SetModified();
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+ InitControls();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, DistanceHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ if(bInInintControl)
+ return;
+ tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel( i ) );
+ if (&rFld == m_xDistBorderMF.get())
+ {
+
+ if (m_xRelativeCB->get_active())
+ {
+ if(0 == i)
+ {
+ auto const nTmp = aNumFmt.GetFirstLineOffset();
+ aNumFmt.SetAbsLSpace( nValue - nTmp);
+ }
+ else
+ {
+ tools::Long nTmp = pActNum->GetLevel( i - 1 ).GetAbsLSpace() +
+ pActNum->GetLevel( i - 1 ).GetFirstLineOffset() -
+ pActNum->GetLevel( i ).GetFirstLineOffset();
+
+ aNumFmt.SetAbsLSpace( nValue + nTmp);
+ }
+ }
+ else
+ {
+ aNumFmt.SetAbsLSpace( nValue - aNumFmt.GetFirstLineOffset());
+ }
+ }
+ else if (&rFld == m_xDistNumMF.get())
+ {
+ aNumFmt.SetCharTextDistance( static_cast<short>(nValue) );
+ }
+ else if (&rFld == m_xIndentMF.get())
+ {
+ // together with the FirstLineOffset the AbsLSpace must be changed, too
+ tools::Long nDiff = nValue + aNumFmt.GetFirstLineOffset();
+ auto const nAbsLSpace = aNumFmt.GetAbsLSpace();
+ aNumFmt.SetAbsLSpace(nAbsLSpace + nDiff);
+ aNumFmt.SetFirstLineOffset( -nValue );
+ }
+
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+ if (!m_xDistBorderMF->get_sensitive())
+ {
+ m_xDistBorderMF->set_text("");
+ }
+}
+
+IMPL_LINK(SvxNumPositionTabPage, RelativeHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bOn = rBox.get_active();
+ bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 && SAL_MAX_UINT16 != nActNumLvl;
+ bool bSetValue = false;
+ tools::Long nValue = 0;
+ if(bOn || bSingleSelection)
+ {
+ sal_uInt16 nMask = 1;
+ bool bFirst = true;
+ bSetValue = true;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ const SvxNumberFormat &rNumFmt = pActNum->GetLevel(i);
+ if(bFirst)
+ {
+ nValue = rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset();
+ if(bOn && i)
+ nValue -= (pActNum->GetLevel(i - 1).GetAbsLSpace() + pActNum->GetLevel(i - 1).GetFirstLineOffset());
+ }
+ else
+ bSetValue = nValue ==
+ (rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset()) -
+ (pActNum->GetLevel(i - 1).GetAbsLSpace() + pActNum->GetLevel(i - 1).GetFirstLineOffset());
+ bFirst = false;
+ }
+ nMask <<= 1;
+ }
+
+ }
+ if(bSetValue)
+ SetMetricValue(*m_xDistBorderMF, nValue, eCoreUnit);
+ else
+ m_xDistBorderMF->set_text("");
+ m_xDistBorderMF->set_sensitive(bOn || bSingleSelection);
+ m_xDistBorderFT->set_sensitive(bOn || bSingleSelection);
+ bLastRelative = bOn;
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, LabelFollowedByHdl_Impl, weld::ComboBox&, void)
+{
+ // determine value to be set at the chosen list levels
+ SvxNumberFormat::LabelFollowedBy eLabelFollowedBy = SvxNumberFormat::LISTTAB;
+ {
+ const auto nPos = m_xLabelFollowedByLB->get_active();
+ if ( nPos == 1 )
+ {
+ eLabelFollowedBy = SvxNumberFormat::SPACE;
+ }
+ else if ( nPos == 2 )
+ {
+ eLabelFollowedBy = SvxNumberFormat::NOTHING;
+ }
+ else if ( nPos == 3 )
+ {
+ eLabelFollowedBy = SvxNumberFormat::NEWLINE;
+ }
+ }
+
+ // set value at the chosen list levels
+ bool bSameListtabPos = true;
+ sal_uInt16 nFirstLvl = SAL_MAX_UINT16;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ aNumFmt.SetLabelFollowedBy( eLabelFollowedBy );
+ pActNum->SetLevel( i, aNumFmt );
+
+ if ( nFirstLvl == SAL_MAX_UINT16 )
+ {
+ nFirstLvl = i;
+ }
+ else
+ {
+ bSameListtabPos &= aNumFmt.GetListtabPos() ==
+ pActNum->GetLevel( nFirstLvl ).GetListtabPos();
+ }
+ }
+ nMask <<= 1;
+ }
+
+ // enable/disable metric field for list tab stop position depending on
+ // selected item following the list label.
+ m_xListtabFT->set_sensitive( eLabelFollowedBy == SvxNumberFormat::LISTTAB );
+ m_xListtabMF->set_sensitive( eLabelFollowedBy == SvxNumberFormat::LISTTAB );
+ if ( bSameListtabPos && eLabelFollowedBy == SvxNumberFormat::LISTTAB )
+ {
+ SetMetricValue(*m_xListtabMF, pActNum->GetLevel( nFirstLvl ).GetListtabPos(), eCoreUnit);
+ }
+ else
+ {
+ m_xListtabMF->set_text(OUString());
+ }
+
+ SetModified();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, ListtabPosHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ // determine value to be set at the chosen list levels
+ const tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ aNumFmt.SetListtabPos( nValue );
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, AlignAtHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ // determine value to be set at the chosen list levels
+ const tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ const tools::Long nFirstLineIndent = nValue - aNumFmt.GetIndentAt();
+ aNumFmt.SetFirstLineIndent( nFirstLineIndent );
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, IndentAtHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ // determine value to be set at the chosen list levels
+ const tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ const tools::Long nAlignedAt = aNumFmt.GetIndentAt() +
+ aNumFmt.GetFirstLineIndent();
+ aNumFmt.SetIndentAt( nValue );
+ const tools::Long nNewFirstLineIndent = nAlignedAt - nValue;
+ aNumFmt.SetFirstLineIndent( nNewFirstLineIndent );
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, StandardHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nMask = 1;
+ SvxNumRule aTmpNumRule( pActNum->GetFeatureFlags(),
+ pActNum->GetLevelCount(),
+ pActNum->IsContinuousNumbering(),
+ SvxNumRuleType::NUMBERING,
+ pActNum->GetLevel( 0 ).GetPositionAndSpaceMode() );
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel( i ) );
+ const SvxNumberFormat& aTempFmt(aTmpNumRule.GetLevel( i ));
+ aNumFmt.SetPositionAndSpaceMode( aTempFmt.GetPositionAndSpaceMode() );
+ if ( aTempFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
+ {
+ aNumFmt.SetAbsLSpace( aTempFmt.GetAbsLSpace() );
+ aNumFmt.SetCharTextDistance( aTempFmt.GetCharTextDistance() );
+ aNumFmt.SetFirstLineOffset( aTempFmt.GetFirstLineOffset() );
+ }
+ else if ( aTempFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ aNumFmt.SetNumAdjust( aTempFmt.GetNumAdjust() );
+ aNumFmt.SetLabelFollowedBy( aTempFmt.GetLabelFollowedBy() );
+ aNumFmt.SetListtabPos( aTempFmt.GetListtabPos() );
+ aNumFmt.SetFirstLineIndent( aTempFmt.GetFirstLineIndent() );
+ aNumFmt.SetIndentAt( aTempFmt.GetIndentAt() );
+ }
+
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ InitControls();
+ SetModified();
+}
+
+void SvxNumPositionTabPage::SetModified()
+{
+ bModified = true;
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+
+void SvxNumOptionsTabPage::SetModified(bool bRepaint)
+{
+ bModified = true;
+ if (bRepaint)
+ {
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+ }
+}
+
+void SvxNumOptionsTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxStringListItem* pListItem = aSet.GetItem<SfxStringListItem>(SID_CHAR_FMT_LIST_BOX, false);
+ const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
+ const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
+ const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false);
+
+ if (pNumCharFmt &&pBulletCharFmt)
+ SetCharFmts( pNumCharFmt->GetValue(),pBulletCharFmt->GetValue());
+
+ if (pListItem)
+ {
+ const std::vector<OUString> &aList = pListItem->GetList();
+ sal_uInt32 nCount = aList.size();
+ for(sal_uInt32 i = 0; i < nCount; i++)
+ m_xCharFmtLB->append_text(aList[i]);
+ }
+ if (pMetricItem)
+ SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue()));
+}
+
+void SvxNumPositionTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false);
+
+ if (pMetricItem)
+ SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue()));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */