1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <com/sun/star/text/VertOrientation.hpp>
21
22 #include <numpages.hxx>
23 #include <dialmgr.hxx>
24 #include <tools/mapunit.hxx>
25 #include <i18nlangtag/languagetag.hxx>
26 #include <i18nlangtag/mslangid.hxx>
27 #include <editeng/numitem.hxx>
28 #include <svl/eitem.hxx>
29 #include <vcl/svapp.hxx>
30 #include <svx/colorbox.hxx>
31 #include <svx/dlgutil.hxx>
32 #include <svx/strarray.hxx>
33 #include <svx/gallery.hxx>
34 #include <editeng/brushitem.hxx>
35 #include <svl/intitem.hxx>
36 #include <sfx2/objsh.hxx>
37 #include <vcl/graph.hxx>
38 #include <vcl/settings.hxx>
39 #include <svx/cuicharmap.hxx>
40 #include <editeng/flstitem.hxx>
41 #include <svx/numvset.hxx>
42 #include <sfx2/htmlmode.hxx>
43 #include <unotools/pathoptions.hxx>
44 #include <svtools/ctrltool.hxx>
45 #include <svtools/unitconv.hxx>
46 #include <svtools/colorcfg.hxx>
47 #include <com/sun/star/style/NumberingType.hpp>
48 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
49 #include <com/sun/star/container/XIndexAccess.hpp>
50 #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
51 #include <com/sun/star/text/XNumberingFormatter.hpp>
52 #include <com/sun/star/beans/PropertyValue.hpp>
53 #include <comphelper/processfactory.hxx>
54 #include <comphelper/propertyvalue.hxx>
55 #include <comphelper/lok.hxx>
56 #include <svx/svxids.hrc>
57 #include <o3tl/string_view.hxx>
58 #include <officecfg/Office/Common.hxx>
59
60 #include <algorithm>
61 #include <memory>
62 #include <vector>
63 #include <sfx2/opengrf.hxx>
64
65 #include <strings.hrc>
66 #include <svl/stritem.hxx>
67 #include <svl/slstitm.hxx>
68 #include <sfx2/filedlghelper.hxx>
69 #include <unotools/ucbstreamhelper.hxx>
70 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
71 #include <sal/log.hxx>
72 #include <vcl/cvtgrf.hxx>
73 #include <vcl/graphicfilter.hxx>
74 #include <svx/SvxNumOptionsTabPageHelper.hxx>
75 #include <tools/urlobj.hxx>
76 #include <o3tl/temporary.hxx>
77 #include <osl/diagnose.h>
78
79 #include <bitmaps.hlst>
80
81 using namespace css;
82 using namespace css::uno;
83 using namespace css::beans;
84 using namespace css::lang;
85 using namespace css::text;
86 using namespace css::container;
87
88 #define SHOW_NUMBERING 0
89 #define SHOW_BULLET 1
90 #define SHOW_BITMAP 2
91
92 #define MAX_BMP_WIDTH 16
93 #define MAX_BMP_HEIGHT 16
94 #define SEARCHPATH_DELIMITER u';'
95 #define SEARCHFILENAME_DELIMITER u'/'
96
97 static bool bLastRelative = false;
98
lcl_CreateNumSettingsPtr(const Sequence<PropertyValue> & rLevelProps)99 static SvxNumSettings_Impl* lcl_CreateNumSettingsPtr(const Sequence<PropertyValue>& rLevelProps)
100 {
101 SvxNumSettings_Impl* pNew = new SvxNumSettings_Impl;
102 for (auto& prop : rLevelProps)
103 {
104 if (prop.Name == "NumberingType")
105 {
106 sal_Int16 nTmp;
107 if (prop.Value >>= nTmp)
108 pNew->nNumberType = static_cast<SvxNumType>(nTmp);
109 }
110 else if (prop.Name == "Prefix")
111 prop.Value >>= pNew->sPrefix;
112 else if (prop.Name == "Suffix")
113 prop.Value >>= pNew->sSuffix;
114 else if (prop.Name == "ParentNumbering")
115 prop.Value >>= pNew->nParentNumbering;
116 else if (prop.Name == "BulletChar")
117 prop.Value >>= pNew->sBulletChar;
118 else if (prop.Name == "BulletFontName")
119 prop.Value >>= pNew->sBulletFont;
120 }
121 return pNew;
122 }
123
124 // Is one of the masked formats set?
lcl_IsNumFmtSet(SvxNumRule const * pNum,sal_uInt16 nLevelMask)125 static bool lcl_IsNumFmtSet(SvxNumRule const * pNum, sal_uInt16 nLevelMask)
126 {
127 bool bRet = false;
128 sal_uInt16 nMask = 1;
129 for( sal_uInt16 i = 0; i < SVX_MAX_NUM && !bRet; i++ )
130 {
131 if(nLevelMask & nMask)
132 bRet |= nullptr != pNum->Get( i );
133 nMask <<= 1 ;
134 }
135 return bRet;
136 }
137
lcl_GetDefaultBulletFont()138 static vcl::Font& lcl_GetDefaultBulletFont()
139 {
140 static vcl::Font aDefBulletFont = []()
141 {
142 vcl::Font tmp(u"OpenSymbol"_ustr, u""_ustr, Size(0, 14));
143 tmp.SetCharSet( RTL_TEXTENCODING_SYMBOL );
144 tmp.SetFamily( FAMILY_DONTKNOW );
145 tmp.SetPitch( PITCH_DONTKNOW );
146 tmp.SetWeight( WEIGHT_DONTKNOW );
147 tmp.SetTransparent( true );
148 return tmp;
149 }();
150 return aDefBulletFont;
151 }
152
SvxSingleNumPickTabPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)153 SvxSingleNumPickTabPage::SvxSingleNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
154 : SfxTabPage(pPage, pController, u"cui/ui/picknumberingpage.ui"_ustr, u"PickNumberingPage"_ustr, &rSet)
155 , nActNumLvl(SAL_MAX_UINT16)
156 , bModified(false)
157 , bPreset(false)
158 , nNumItemId(SID_ATTR_NUMBERING_RULE)
159 , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window(u"valuesetwin"_ustr, true)))
160 , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, u"valueset"_ustr, *m_xExamplesVS))
161 {
162 SetExchangeSupport();
163 m_xExamplesVS->init(NumberingPageType::SINGLENUM);
164 m_xExamplesVS->SetSelectHdl(LINK(this, SvxSingleNumPickTabPage, NumSelectHdl_Impl));
165 m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxSingleNumPickTabPage, DoubleClickHdl_Impl));
166
167 Reference<XDefaultNumberingProvider> xDefNum = SvxNumOptionsTabPageHelper::GetNumberingProvider();
168 if(!xDefNum.is())
169 return;
170
171 Sequence< Sequence< PropertyValue > > aNumberings;
172 const Locale& rLocale = Application::GetSettings().GetLanguageTag().getLocale();
173 try
174 {
175 aNumberings =
176 xDefNum->getDefaultContinuousNumberingLevels( rLocale );
177
178 sal_Int32 nLength = std::min<sal_Int32>(aNumberings.getLength(), NUM_VALUSET_COUNT);
179 for(sal_Int32 i = 0; i < nLength; i++)
180 {
181 SvxNumSettings_Impl* pNew = lcl_CreateNumSettingsPtr(aNumberings[i]);
182 aNumSettingsArr.push_back(std::unique_ptr<SvxNumSettings_Impl>(pNew));
183 }
184 }
185 catch(const Exception&)
186 {
187 }
188 Reference<XNumberingFormatter> xFormat(xDefNum, UNO_QUERY);
189 m_xExamplesVS->SetNumberingSettings(aNumberings, xFormat, rLocale);
190 }
191
~SvxSingleNumPickTabPage()192 SvxSingleNumPickTabPage::~SvxSingleNumPickTabPage()
193 {
194 m_xExamplesVSWin.reset();
195 m_xExamplesVS.reset();
196 }
197
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rAttrSet)198 std::unique_ptr<SfxTabPage> SvxSingleNumPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
199 const SfxItemSet* rAttrSet)
200 {
201 return std::make_unique<SvxSingleNumPickTabPage>(pPage, pController, *rAttrSet);
202 }
203
FillItemSet(SfxItemSet * rSet)204 bool SvxSingleNumPickTabPage::FillItemSet( SfxItemSet* rSet )
205 {
206 if( (bPreset || bModified) && pSaveNum)
207 {
208 *pSaveNum = *pActNum;
209 rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
210 rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
211 }
212
213 return bModified;
214 }
215
ActivatePage(const SfxItemSet & rSet)216 void SvxSingleNumPickTabPage::ActivatePage(const SfxItemSet& rSet)
217 {
218 bPreset = false;
219 bool bIsPreset = false;
220 const SfxItemSet* pExampleSet = GetDialogExampleSet();
221 if(pExampleSet)
222 {
223 if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
224 bIsPreset = pPresetItem->GetValue();
225 if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
226 nActNumLvl = pLevelItem->GetValue();
227 }
228 if(const SvxNumBulletItem* pNumItem = rSet.GetItemIfSet(nNumItemId, false))
229 {
230 pSaveNum.reset( new SvxNumRule(pNumItem->GetNumRule()) );
231 }
232 if(pActNum && *pSaveNum != *pActNum)
233 {
234 *pActNum = *pSaveNum;
235 m_xExamplesVS->SetNoSelection();
236 }
237
238 if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
239 {
240 m_xExamplesVS->SelectItem(1);
241 NumSelectHdl_Impl(m_xExamplesVS.get());
242 bPreset = true;
243 }
244 bPreset |= bIsPreset;
245
246 bModified = false;
247 }
248
DeactivatePage(SfxItemSet * _pSet)249 DeactivateRC SvxSingleNumPickTabPage::DeactivatePage(SfxItemSet *_pSet)
250 {
251 if(_pSet)
252 FillItemSet(_pSet);
253 return DeactivateRC::LeavePage;
254 }
255
Reset(const SfxItemSet * rSet)256 void SvxSingleNumPickTabPage::Reset( const SfxItemSet* rSet )
257 {
258 const SfxPoolItem* pItem;
259
260 // in Draw the item exists as WhichId, in Writer only as SlotId
261 SfxItemState eState = rSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
262 if(eState != SfxItemState::SET)
263 {
264 nNumItemId = rSet->GetPool()->GetWhichIDFromSlotID(SID_ATTR_NUMBERING_RULE);
265 eState = rSet->GetItemState(nNumItemId, false, &pItem);
266
267 if( eState != SfxItemState::SET )
268 {
269 pItem = & rSet->Get( nNumItemId );
270 eState = SfxItemState::SET;
271 }
272 }
273 DBG_ASSERT(eState == SfxItemState::SET, "no item found!");
274 pSaveNum.reset( new SvxNumRule(static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
275
276 if(!pActNum)
277 pActNum.reset( new SvxNumRule(*pSaveNum) );
278 else if(*pSaveNum != *pActNum)
279 *pActNum = *pSaveNum;
280 }
281
IMPL_LINK_NOARG(SvxSingleNumPickTabPage,NumSelectHdl_Impl,ValueSet *,void)282 IMPL_LINK_NOARG(SvxSingleNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
283 {
284 if(!pActNum)
285 return;
286
287 bPreset = false;
288 bModified = true;
289 sal_uInt16 nIdx = m_xExamplesVS->GetSelectedItemId() - 1;
290 DBG_ASSERT(aNumSettingsArr.size() > nIdx, "wrong index");
291 if(aNumSettingsArr.size() <= nIdx)
292 return;
293 SvxNumSettings_Impl* _pSet = aNumSettingsArr[nIdx].get();
294 SvxNumType eNewType = _pSet->nNumberType;
295 const sal_Unicode cLocalPrefix = !_pSet->sPrefix.isEmpty() ? _pSet->sPrefix[0] : 0;
296 const sal_Unicode cLocalSuffix = !_pSet->sSuffix.isEmpty() ? _pSet->sSuffix[0] : 0;
297
298 sal_uInt16 nMask = 1;
299 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
300 {
301 if(nActNumLvl & nMask)
302 {
303 SvxNumberFormat aFmt(pActNum->GetLevel(i));
304 aFmt.SetNumberingType(eNewType);
305 aFmt.SetListFormat(cLocalPrefix == ' ' ? u""_ustr : _pSet->sPrefix,
306 cLocalSuffix == ' ' ? u""_ustr : _pSet->sSuffix, i);
307 aFmt.SetCharFormatName(u""_ustr);
308 aFmt.SetBulletRelSize(100);
309 pActNum->SetLevel(i, aFmt);
310 }
311 nMask <<= 1;
312 }
313 }
314
IMPL_LINK_NOARG(SvxSingleNumPickTabPage,DoubleClickHdl_Impl,ValueSet *,void)315 IMPL_LINK_NOARG(SvxSingleNumPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
316 {
317 NumSelectHdl_Impl(m_xExamplesVS.get());
318 weld::Button& rOk = GetDialogController()->GetOKButton();
319 rOk.clicked();
320 }
321
SvxBulletPickTabPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)322 SvxBulletPickTabPage::SvxBulletPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
323 : SfxTabPage(pPage, pController, u"cui/ui/pickbulletpage.ui"_ustr, u"PickBulletPage"_ustr, &rSet)
324 , nActNumLvl(SAL_MAX_UINT16)
325 , bModified(false)
326 , bPreset(false)
327 , nNumItemId(SID_ATTR_NUMBERING_RULE)
328 , m_xBtChangeBullet(m_xBuilder->weld_button(u"changeBulletBtn"_ustr))
329 , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window(u"valuesetwin"_ustr, true)))
330 , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, u"valueset"_ustr, *m_xExamplesVS))
331 {
332 SetExchangeSupport();
333 m_xBtChangeBullet->set_sensitive(false);
334 m_xExamplesVS->init(NumberingPageType::BULLET);
335 m_xExamplesVS->SetSelectHdl(LINK(this, SvxBulletPickTabPage, NumSelectHdl_Impl));
336 m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxBulletPickTabPage, DoubleClickHdl_Impl));
337 m_xBtChangeBullet->connect_clicked(LINK(this, SvxBulletPickTabPage, ClickAddChangeHdl_Impl));
338 }
339
~SvxBulletPickTabPage()340 SvxBulletPickTabPage::~SvxBulletPickTabPage()
341 {
342 m_xExamplesVSWin.reset();
343 m_xExamplesVS.reset();
344 }
345
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rAttrSet)346 std::unique_ptr<SfxTabPage> SvxBulletPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
347 const SfxItemSet* rAttrSet)
348 {
349 return std::make_unique<SvxBulletPickTabPage>(pPage, pController, *rAttrSet);
350 }
351
FillItemSet(SfxItemSet * rSet)352 bool SvxBulletPickTabPage::FillItemSet( SfxItemSet* rSet )
353 {
354 if( (bPreset || bModified) && pActNum)
355 {
356 *pSaveNum = *pActNum;
357 rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
358 rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
359 }
360 return bModified;
361 }
362
ActivatePage(const SfxItemSet & rSet)363 void SvxBulletPickTabPage::ActivatePage(const SfxItemSet& rSet)
364 {
365 bPreset = false;
366 bool bIsPreset = false;
367 const SfxItemSet* pExampleSet = GetDialogExampleSet();
368 if(pExampleSet)
369 {
370 if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
371 bIsPreset = pPresetItem->GetValue();
372 if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
373 nActNumLvl = pLevelItem->GetValue();
374 }
375 if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
376 {
377 pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
378 }
379 if(pActNum && *pSaveNum != *pActNum)
380 {
381 *pActNum = *pSaveNum;
382 m_xExamplesVS->SetNoSelection();
383 }
384
385 if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
386 {
387 m_xExamplesVS->SelectItem(1);
388 NumSelectHdl_Impl(m_xExamplesVS.get());
389 bPreset = true;
390 }
391 bPreset |= bIsPreset;
392 bModified = false;
393 }
394
DeactivatePage(SfxItemSet * _pSet)395 DeactivateRC SvxBulletPickTabPage::DeactivatePage(SfxItemSet *_pSet)
396 {
397 if(_pSet)
398 FillItemSet(_pSet);
399 return DeactivateRC::LeavePage;
400 }
401
Reset(const SfxItemSet * rSet)402 void SvxBulletPickTabPage::Reset( const SfxItemSet* rSet )
403 {
404 // in Draw the item exists as WhichId, in Writer only as SlotId
405 const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
406 if(!pItem)
407 {
408 nNumItemId = rSet->GetPool()->GetWhichIDFromSlotID(SID_ATTR_NUMBERING_RULE);
409 pItem = rSet->GetItemIfSet(nNumItemId, false);
410
411 if( !pItem )
412 {
413 pItem = & rSet->Get( nNumItemId );
414 }
415
416 }
417 pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
418
419 if(!pActNum)
420 pActNum.reset( new SvxNumRule(*pSaveNum) );
421 else if(*pSaveNum != *pActNum)
422 *pActNum = *pSaveNum;
423 }
424
IMPL_LINK_NOARG(SvxBulletPickTabPage,NumSelectHdl_Impl,ValueSet *,void)425 IMPL_LINK_NOARG(SvxBulletPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
426 {
427 if(!pActNum)
428 return;
429
430 m_xBtChangeBullet->set_sensitive(true);
431
432 bPreset = false;
433 bModified = true;
434 sal_uInt16 nIndex = m_xExamplesVS->GetSelectedItemId() - 1;
435 sal_Unicode cChar = officecfg::Office::Common::BulletsNumbering::DefaultBullets::get()[nIndex].toChar();
436 vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
437 rActBulletFont.SetFamilyName(
438 officecfg::Office::Common::BulletsNumbering::DefaultBulletsFonts::get()[nIndex]);
439
440 sal_uInt16 nMask = 1;
441 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
442 {
443 if(nActNumLvl & nMask)
444 {
445 SvxNumberFormat aFmt(pActNum->GetLevel(i));
446 aFmt.SetNumberingType( SVX_NUM_CHAR_SPECIAL );
447 // #i93908# clear suffix for bullet lists
448 aFmt.SetListFormat(u""_ustr, u""_ustr, i);
449 aFmt.SetBulletFont(&rActBulletFont);
450 aFmt.SetBulletChar(cChar );
451 aFmt.SetCharFormatName(sBulletCharFormatName);
452 aFmt.SetBulletRelSize(45);
453 pActNum->SetLevel(i, aFmt);
454 }
455 nMask <<= 1;
456 }
457 }
458
IMPL_LINK_NOARG(SvxBulletPickTabPage,DoubleClickHdl_Impl,ValueSet *,void)459 IMPL_LINK_NOARG(SvxBulletPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
460 {
461 NumSelectHdl_Impl(m_xExamplesVS.get());
462 weld::Button& rOk = GetDialogController()->GetOKButton();
463 rOk.clicked();
464 }
465
IMPL_LINK_NOARG(SvxBulletPickTabPage,ClickAddChangeHdl_Impl,weld::Button &,void)466 IMPL_LINK_NOARG(SvxBulletPickTabPage, ClickAddChangeHdl_Impl, weld::Button&, void)
467 {
468 SvxCharacterMap aMap(GetFrameWeld(), nullptr, nullptr);
469
470 sal_uInt16 nMask = 1;
471 std::optional<vcl::Font> pFmtFont;
472 bool bSameBullet = true;
473 sal_UCS4 cBullet = 0;
474 bool bFirst = true;
475 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
476 {
477 if (nActNumLvl & nMask)
478 {
479 const SvxNumberFormat& rCurFmt = pActNum->GetLevel(i);
480 if (bFirst)
481 {
482 cBullet = rCurFmt.GetBulletChar();
483 }
484 else if (rCurFmt.GetBulletChar() != cBullet)
485 {
486 bSameBullet = false;
487 break;
488 }
489 if (!pFmtFont)
490 pFmtFont = rCurFmt.GetBulletFont();
491 bFirst = false;
492 }
493 nMask <<= 1;
494 }
495
496 if (pFmtFont)
497 aMap.SetCharFont(*pFmtFont);
498 if (bSameBullet)
499 aMap.SetChar(cBullet);
500 if (aMap.run() != RET_OK)
501 return;
502
503 sal_Unicode cChar = aMap.GetChar();
504 vcl::Font aActBulletFont = aMap.GetCharFont();
505
506 sal_uInt16 _nMask = 1;
507 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
508 {
509 if (nActNumLvl & _nMask)
510 {
511 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
512 aNumFmt.SetBulletFont(&aActBulletFont);
513 aNumFmt.SetBulletChar(cChar);
514 pActNum->SetLevel(i, aNumFmt);
515 }
516 _nMask <<= 1;
517 }
518
519 css::uno::Sequence<OUString> aBulletSymbols(officecfg::Office::Common::BulletsNumbering::DefaultBullets::get());
520 css::uno::Sequence<OUString> aBulletSymbolsFonts(officecfg::Office::Common::BulletsNumbering::DefaultBulletsFonts::get());
521 css::uno::Sequence<OUString> aBulletSymbolsList(aBulletSymbols.size());
522 css::uno::Sequence<OUString> aBulletSymbolsFontsList(aBulletSymbolsFonts.size());
523 auto aBulletSymbolsListRange = asNonConstRange(aBulletSymbolsList);
524 auto aBulletSymbolsFontsListRange = asNonConstRange(aBulletSymbolsFontsList);
525
526 sal_uInt16 nIndex = m_xExamplesVS->GetSelectedItemId() - 1;
527 for (size_t i = 0; i < aBulletSymbols.size(); ++i)
528 {
529 if (i == nIndex)
530 {
531 aBulletSymbolsListRange[i] = OUStringChar(cChar);
532 aBulletSymbolsFontsListRange[i] = aActBulletFont.GetFamilyName();
533 }
534 else
535 {
536 aBulletSymbolsListRange[i] = aBulletSymbols[i];
537 aBulletSymbolsFontsListRange[i] = aBulletSymbolsFonts[i];
538 }
539 }
540
541 std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
542 officecfg::Office::Common::BulletsNumbering::DefaultBullets::set(aBulletSymbolsList, batch);
543 officecfg::Office::Common::BulletsNumbering::DefaultBulletsFonts::set(aBulletSymbolsFontsList, batch);
544 batch->commit();
545
546 m_xExamplesVS->SetFormat();
547 m_xExamplesVS->Invalidate();
548 }
549
PageCreated(const SfxAllItemSet & aSet)550 void SvxBulletPickTabPage::PageCreated(const SfxAllItemSet& aSet)
551 {
552 const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
553
554 if (pBulletCharFmt)
555 sBulletCharFormatName = pBulletCharFmt->GetValue();
556 }
557
SvxNumPickTabPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)558 SvxNumPickTabPage::SvxNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
559 : SfxTabPage(pPage, pController, u"cui/ui/pickoutlinepage.ui"_ustr, u"PickOutlinePage"_ustr, &rSet)
560 , nActNumLvl(SAL_MAX_UINT16)
561 , nNumItemId(SID_ATTR_NUMBERING_RULE)
562 , bModified(false)
563 , bPreset(false)
564 , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window(u"valuesetwin"_ustr, true)))
565 , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, u"valueset"_ustr, *m_xExamplesVS))
566 {
567 SetExchangeSupport();
568
569 m_xExamplesVS->init(NumberingPageType::OUTLINE);
570 m_xExamplesVS->SetSelectHdl(LINK(this, SvxNumPickTabPage, NumSelectHdl_Impl));
571 m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxNumPickTabPage, DoubleClickHdl_Impl));
572
573 Reference<XDefaultNumberingProvider> xDefNum = SvxNumOptionsTabPageHelper::GetNumberingProvider();
574 if(!xDefNum.is())
575 return;
576
577 Sequence<Reference<XIndexAccess> > aOutlineAccess;
578 const Locale& rLocale = Application::GetSettings().GetLanguageTag().getLocale();
579 try
580 {
581 aOutlineAccess = xDefNum->getDefaultOutlineNumberings( rLocale );
582
583 for(sal_Int32 nItem = 0;
584 nItem < aOutlineAccess.getLength() && nItem < NUM_VALUSET_COUNT;
585 nItem++ )
586 {
587 SvxNumSettingsArr_Impl& rItemArr = aNumSettingsArrays[ nItem ];
588
589 Reference<XIndexAccess> xLevel = aOutlineAccess[nItem];
590 for(sal_Int32 nLevel = 0; nLevel < SVX_MAX_NUM; nLevel++)
591 {
592 // use the last locale-defined level for all remaining levels.
593 sal_Int32 nLocaleLevel = std::min(nLevel, xLevel->getCount() - 1);
594 Sequence<PropertyValue> aLevelProps;
595 if (nLocaleLevel >= 0)
596 xLevel->getByIndex(nLocaleLevel) >>= aLevelProps;
597
598 SvxNumSettings_Impl* pNew = lcl_CreateNumSettingsPtr(aLevelProps);
599 rItemArr.push_back( std::unique_ptr<SvxNumSettings_Impl>(pNew) );
600 }
601 }
602 }
603 catch(const Exception&)
604 {
605 }
606 Reference<XNumberingFormatter> xFormat(xDefNum, UNO_QUERY);
607 m_xExamplesVS->SetOutlineNumberingSettings(aOutlineAccess, xFormat, rLocale);
608 }
609
~SvxNumPickTabPage()610 SvxNumPickTabPage::~SvxNumPickTabPage()
611 {
612 m_xExamplesVSWin.reset();
613 m_xExamplesVS.reset();
614 }
615
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rAttrSet)616 std::unique_ptr<SfxTabPage> SvxNumPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
617 const SfxItemSet* rAttrSet)
618 {
619 return std::make_unique<SvxNumPickTabPage>(pPage, pController, *rAttrSet);
620 }
621
FillItemSet(SfxItemSet * rSet)622 bool SvxNumPickTabPage::FillItemSet( SfxItemSet* rSet )
623 {
624 if( (bPreset || bModified) && pActNum)
625 {
626 *pSaveNum = *pActNum;
627 rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
628 rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
629 }
630 return bModified;
631 }
632
ActivatePage(const SfxItemSet & rSet)633 void SvxNumPickTabPage::ActivatePage(const SfxItemSet& rSet)
634 {
635 bPreset = false;
636 bool bIsPreset = false;
637 const SfxItemSet* pExampleSet = GetDialogExampleSet();
638 if(pExampleSet)
639 {
640 if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
641 bIsPreset = pPresetItem->GetValue();
642 if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
643 nActNumLvl = pLevelItem->GetValue();
644 }
645 if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
646 {
647 pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
648 }
649 if(pActNum && *pSaveNum != *pActNum)
650 {
651 *pActNum = *pSaveNum;
652 m_xExamplesVS->SetNoSelection();
653 }
654
655 if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
656 {
657 m_xExamplesVS->SelectItem(1);
658 NumSelectHdl_Impl(m_xExamplesVS.get());
659 bPreset = true;
660 }
661 bPreset |= bIsPreset;
662 bModified = false;
663 }
664
DeactivatePage(SfxItemSet * _pSet)665 DeactivateRC SvxNumPickTabPage::DeactivatePage(SfxItemSet *_pSet)
666 {
667 if(_pSet)
668 FillItemSet(_pSet);
669 return DeactivateRC::LeavePage;
670 }
671
Reset(const SfxItemSet * rSet)672 void SvxNumPickTabPage::Reset( const SfxItemSet* rSet )
673 {
674 // in Draw the item exists as WhichId, in Writer only as SlotId
675 const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
676 if(!pItem)
677 {
678 nNumItemId = rSet->GetPool()->GetWhichIDFromSlotID(SID_ATTR_NUMBERING_RULE);
679 pItem = rSet->GetItemIfSet(nNumItemId, false);
680
681 if( !pItem )
682 {
683 pItem = & rSet->Get( nNumItemId );
684 }
685 }
686 pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
687
688 if(!pActNum)
689 pActNum.reset( new SvxNumRule(*pSaveNum) );
690 else if(*pSaveNum != *pActNum)
691 *pActNum = *pSaveNum;
692
693 }
694
695 // all levels are changed here
IMPL_LINK_NOARG(SvxNumPickTabPage,NumSelectHdl_Impl,ValueSet *,void)696 IMPL_LINK_NOARG(SvxNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
697 {
698 if(!pActNum)
699 return;
700
701 bPreset = false;
702 bModified = true;
703
704 const FontList* pList = nullptr;
705
706 SvxNumSettingsArr_Impl& rItemArr = aNumSettingsArrays[m_xExamplesVS->GetSelectedItemId() - 1];
707
708 const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
709 SvxNumSettings_Impl* pLevelSettings = nullptr;
710 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
711 {
712 if(rItemArr.size() > i)
713 pLevelSettings = rItemArr[i].get();
714 if(!pLevelSettings)
715 break;
716 SvxNumberFormat aFmt(pActNum->GetLevel(i));
717 aFmt.SetNumberingType( pLevelSettings->nNumberType );
718 sal_uInt16 nUpperLevelOrChar = static_cast<sal_uInt16>(pLevelSettings->nParentNumbering);
719 if(aFmt.GetNumberingType() == SVX_NUM_CHAR_SPECIAL)
720 {
721 // #i93908# clear suffix for bullet lists
722 aFmt.SetListFormat(u""_ustr, u""_ustr, i);
723 if( !pLevelSettings->sBulletFont.isEmpty() &&
724 pLevelSettings->sBulletFont != rActBulletFont.GetFamilyName())
725 {
726 //search for the font
727 if(!pList)
728 {
729 if (SfxObjectShell* pCurDocShell = SfxObjectShell::Current())
730 {
731 const SvxFontListItem* pFontListItem =
732 static_cast<const SvxFontListItem*>( pCurDocShell
733 ->GetItem( SID_ATTR_CHAR_FONTLIST ));
734 pList = pFontListItem ? pFontListItem->GetFontList() : nullptr;
735 }
736 }
737 if(pList && pList->IsAvailable( pLevelSettings->sBulletFont ) )
738 {
739 vcl::Font aFont(pList->Get(
740 pLevelSettings->sBulletFont,WEIGHT_NORMAL, ITALIC_NONE));
741 aFmt.SetBulletFont(&aFont);
742 }
743 else
744 {
745 //if it cannot be found then create a new one
746 vcl::Font aCreateFont( pLevelSettings->sBulletFont,
747 OUString(), Size( 0, 14 ) );
748 aCreateFont.SetCharSet( RTL_TEXTENCODING_DONTKNOW );
749 aCreateFont.SetFamily( FAMILY_DONTKNOW );
750 aCreateFont.SetPitch( PITCH_DONTKNOW );
751 aCreateFont.SetWeight( WEIGHT_DONTKNOW );
752 aCreateFont.SetTransparent( true );
753 aFmt.SetBulletFont( &aCreateFont );
754 }
755 }
756 else
757 aFmt.SetBulletFont( &rActBulletFont );
758
759 aFmt.SetBulletChar( !pLevelSettings->sBulletChar.isEmpty()
760 ? pLevelSettings->sBulletChar.iterateCodePoints(
761 &o3tl::temporary(sal_Int32(0)))
762 : 0 );
763 aFmt.SetCharFormatName( sBulletCharFormatName );
764 aFmt.SetBulletRelSize(45);
765 }
766 else
767 {
768 aFmt.SetIncludeUpperLevels(sal::static_int_cast< sal_uInt8 >(0 != nUpperLevelOrChar ? pActNum->GetLevelCount() : 1));
769 aFmt.SetCharFormatName(sNumCharFmtName);
770 aFmt.SetBulletRelSize(100);
771
772 // Completely ignore the Left/Right value provided by the locale outline definition,
773 // because this function doesn't actually modify the indents at all,
774 // and right-adjusted numbering definitely needs a different FirstLineIndent.
775
776 // #i93908#
777 aFmt.SetListFormat(pLevelSettings->sPrefix, pLevelSettings->sSuffix, i);
778 }
779 pActNum->SetLevel(i, aFmt);
780 }
781 }
782
IMPL_LINK_NOARG(SvxNumPickTabPage,DoubleClickHdl_Impl,ValueSet *,void)783 IMPL_LINK_NOARG(SvxNumPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
784 {
785 NumSelectHdl_Impl(m_xExamplesVS.get());
786 weld::Button& rOk = GetDialogController()->GetOKButton();
787 rOk.clicked();
788 }
789
PageCreated(const SfxAllItemSet & aSet)790 void SvxNumPickTabPage::PageCreated(const SfxAllItemSet& aSet)
791 {
792 const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
793 const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
794
795
796 if (pNumCharFmt &&pBulletCharFmt)
797 SetCharFormatNames( pNumCharFmt->GetValue(),pBulletCharFmt->GetValue());
798 }
799
SvxBitmapPickTabPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)800 SvxBitmapPickTabPage::SvxBitmapPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
801 : SfxTabPage(pPage, pController, u"cui/ui/pickgraphicpage.ui"_ustr, u"PickGraphicPage"_ustr, &rSet)
802 , nActNumLvl(SAL_MAX_UINT16)
803 , nNumItemId(SID_ATTR_NUMBERING_RULE)
804 , bModified(false)
805 , bPreset(false)
806 , m_xErrorText(m_xBuilder->weld_label(u"errorft"_ustr))
807 , m_xBtBrowseFile(m_xBuilder->weld_button(u"browseBtn"_ustr))
808 , m_xExamplesVS(new SvxBmpNumValueSet(m_xBuilder->weld_scrolled_window(u"valuesetwin"_ustr, true)))
809 , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, u"valueset"_ustr, *m_xExamplesVS))
810 {
811 SetExchangeSupport();
812
813 m_xExamplesVS->init();
814 m_xExamplesVS->SetSelectHdl(LINK(this, SvxBitmapPickTabPage, NumSelectHdl_Impl));
815 m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxBitmapPickTabPage, DoubleClickHdl_Impl));
816 m_xBtBrowseFile->connect_clicked(LINK(this, SvxBitmapPickTabPage, ClickAddBrowseHdl_Impl));
817
818 if(comphelper::LibreOfficeKit::isActive())
819 m_xBtBrowseFile->hide();
820
821 eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhichIDFromSlotID(SID_ATTR_NUMBERING_RULE));
822
823 // determine graphic name
824 GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames);
825
826 size_t i = 0;
827 for (auto & grfName : aGrfNames)
828 {
829 m_xExamplesVS->InsertItem( i + 1, i);
830
831 INetURLObject aObj(grfName);
832 if (aObj.GetProtocol() == INetProtocol::File)
833 {
834 // tdf#114070 - only show the last name of the filename without its extension
835 aObj.removeExtension();
836 grfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
837 }
838
839 m_xExamplesVS->SetItemText( i + 1, grfName );
840 ++i;
841 }
842
843 if(aGrfNames.empty())
844 {
845 m_xErrorText->show();
846 }
847 else
848 {
849 m_xExamplesVS->Show();
850 m_xExamplesVS->SetFormat();
851 m_xExamplesVS->Invalidate();
852 }
853 }
854
~SvxBitmapPickTabPage()855 SvxBitmapPickTabPage::~SvxBitmapPickTabPage()
856 {
857 m_xExamplesVSWin.reset();
858 m_xExamplesVS.reset();
859 }
860
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rAttrSet)861 std::unique_ptr<SfxTabPage> SvxBitmapPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
862 const SfxItemSet* rAttrSet)
863 {
864 return std::make_unique<SvxBitmapPickTabPage>(pPage, pController, *rAttrSet);
865 }
866
ActivatePage(const SfxItemSet & rSet)867 void SvxBitmapPickTabPage::ActivatePage(const SfxItemSet& rSet)
868 {
869 bPreset = false;
870 bool bIsPreset = false;
871 const SfxItemSet* pExampleSet = GetDialogExampleSet();
872 if(pExampleSet)
873 {
874 if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
875 bIsPreset = pPresetItem->GetValue();
876 if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
877 nActNumLvl = pLevelItem->GetValue();
878 }
879 if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
880 {
881 pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
882 }
883 if(pActNum && *pSaveNum != *pActNum)
884 {
885 *pActNum = *pSaveNum;
886 m_xExamplesVS->SetNoSelection();
887 }
888
889 if(!aGrfNames.empty() &&
890 (pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset)))
891 {
892 m_xExamplesVS->SelectItem(1);
893 NumSelectHdl_Impl(m_xExamplesVS.get());
894 bPreset = true;
895 }
896 bPreset |= bIsPreset;
897 bModified = false;
898 }
899
DeactivatePage(SfxItemSet * _pSet)900 DeactivateRC SvxBitmapPickTabPage::DeactivatePage(SfxItemSet *_pSet)
901 {
902 if(_pSet)
903 FillItemSet(_pSet);
904 return DeactivateRC::LeavePage;
905 }
906
FillItemSet(SfxItemSet * rSet)907 bool SvxBitmapPickTabPage::FillItemSet( SfxItemSet* rSet )
908 {
909 if ( aGrfNames.empty() )
910 {
911 return false;
912 }
913 if( (bPreset || bModified) && pActNum)
914 {
915 *pSaveNum = *pActNum;
916 rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ) );
917 rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
918 }
919
920 return bModified;
921 }
922
Reset(const SfxItemSet * rSet)923 void SvxBitmapPickTabPage::Reset( const SfxItemSet* rSet )
924 {
925 // in Draw the item exists as WhichId, in Writer only as SlotId
926 const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
927 if(!pItem)
928 {
929 nNumItemId = rSet->GetPool()->GetWhichIDFromSlotID(SID_ATTR_NUMBERING_RULE);
930 pItem = rSet->GetItemIfSet(nNumItemId, false);
931
932 if( !pItem )
933 {
934 pItem = & rSet->Get( nNumItemId );
935 }
936
937 }
938 DBG_ASSERT(pItem, "no item found!");
939 pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
940
941 if(!pActNum)
942 pActNum.reset( new SvxNumRule(*pSaveNum) );
943 else if(*pSaveNum != *pActNum)
944 *pActNum = *pSaveNum;
945 }
946
IMPL_LINK_NOARG(SvxBitmapPickTabPage,NumSelectHdl_Impl,ValueSet *,void)947 IMPL_LINK_NOARG(SvxBitmapPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
948 {
949 if(!pActNum)
950 return;
951
952 bPreset = false;
953 bModified = true;
954 sal_uInt16 nIdx = m_xExamplesVS->GetSelectedItemId() - 1;
955
956 sal_uInt16 nMask = 1;
957 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
958 {
959 if(nActNumLvl & nMask)
960 {
961 SvxNumberFormat aFmt(pActNum->GetLevel(i));
962 aFmt.SetNumberingType(SVX_NUM_BITMAP);
963 aFmt.SetListFormat(u""_ustr, u""_ustr, i);
964 aFmt.SetCharFormatName( u""_ustr );
965
966 Graphic aGraphic;
967 if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, nIdx, &aGraphic))
968 {
969 Size aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
970 sal_Int16 eOrient = text::VertOrientation::LINE_CENTER;
971 aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit));
972 SvxBrushItem aBrush(aGraphic, GPOS_AREA, SID_ATTR_BRUSH );
973 aFmt.SetGraphicBrush( &aBrush, &aSize, &eOrient );
974 }
975 else if(aGrfNames.size() > nIdx)
976 aFmt.SetGraphic( aGrfNames[nIdx] );
977 pActNum->SetLevel(i, aFmt);
978 }
979 nMask <<= 1;
980 }
981 }
982
IMPL_LINK_NOARG(SvxBitmapPickTabPage,DoubleClickHdl_Impl,ValueSet *,void)983 IMPL_LINK_NOARG(SvxBitmapPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
984 {
985 NumSelectHdl_Impl(m_xExamplesVS.get());
986 weld::Button& rOk = GetDialogController()->GetOKButton();
987 rOk.clicked();
988 }
989
IMPL_LINK_NOARG(SvxBitmapPickTabPage,ClickAddBrowseHdl_Impl,weld::Button &,void)990 IMPL_LINK_NOARG(SvxBitmapPickTabPage, ClickAddBrowseHdl_Impl, weld::Button&, void)
991 {
992 sfx2::FileDialogHelper aFileDialog(0, FileDialogFlags::NONE, GetFrameWeld());
993 aFileDialog.SetContext(sfx2::FileDialogHelper::BulletsAddImage);
994 aFileDialog.SetTitle(CuiResId(RID_CUISTR_ADD_IMAGE));
995 if ( aFileDialog.Execute() != ERRCODE_NONE )
996 return;
997
998 OUString aPath = SvtPathOptions().GetGalleryPath();
999 std::u16string_view aPathToken = o3tl::getToken(aPath, 1 , SEARCHPATH_DELIMITER );
1000
1001 OUString aUserImageURL = aFileDialog.GetPath();
1002
1003 OUString aFileName;
1004 const sal_Int32 nPos {aUserImageURL.lastIndexOf(SEARCHFILENAME_DELIMITER)+1};
1005 if (nPos<=0)
1006 aFileName = aUserImageURL;
1007 else if (nPos<aUserImageURL.getLength())
1008 aFileName = aUserImageURL.copy(nPos);
1009
1010 OUString aUserGalleryURL = OUString::Concat(aPathToken) + "/" + aFileName;
1011 INetURLObject aURL( aUserImageURL );
1012 DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
1013
1014 GraphicDescriptor aDescriptor(aURL);
1015 if (!aDescriptor.Detect())
1016 return;
1017
1018 uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
1019 uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess(
1020 ucb::SimpleFileAccess::create( ::comphelper::getComponentContext(xFactory) ) );
1021 if ( !xSimpleFileAccess->exists( aUserImageURL ))
1022 return;
1023
1024 xSimpleFileAccess->copy( aUserImageURL, aUserGalleryURL );
1025 INetURLObject gURL( aUserGalleryURL );
1026 std::unique_ptr<SvStream> pIn(::utl::UcbStreamHelper::CreateStream(
1027 gURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
1028 if ( !pIn )
1029 return;
1030
1031 Graphic aGraphic;
1032 GraphicConverter::Import( *pIn, aGraphic );
1033
1034 BitmapEx aBitmap = aGraphic.GetBitmapEx();
1035 tools::Long nPixelX = aBitmap.GetSizePixel().Width();
1036 tools::Long nPixelY = aBitmap.GetSizePixel().Height();
1037 double ratio = nPixelY/static_cast<double>(nPixelX);
1038 if(nPixelX > 30)
1039 {
1040 nPixelX = 30;
1041 nPixelY = static_cast<tools::Long>(nPixelX*ratio);
1042 }
1043 if(nPixelY > 30)
1044 {
1045 nPixelY = 30;
1046 nPixelX = static_cast<tools::Long>(nPixelY/ratio);
1047 }
1048
1049 aBitmap.Scale( Size( nPixelX, nPixelY ), BmpScaleFlag::Fast );
1050 Graphic aScaledGraphic( aBitmap );
1051 GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
1052
1053 Sequence< PropertyValue > aFilterData{
1054 comphelper::makePropertyValue(u"Compression"_ustr, sal_Int32(-1)),
1055 comphelper::makePropertyValue(u"Quality"_ustr, sal_Int32(1))
1056 };
1057
1058 sal_uInt16 nFilterFormat = rFilter.GetExportFormatNumberForShortName( gURL.GetFileExtension() );
1059 rFilter.ExportGraphic( aScaledGraphic, gURL , nFilterFormat, &aFilterData );
1060 GalleryExplorer::InsertURL( GALLERY_THEME_BULLETS, aUserGalleryURL );
1061
1062 aGrfNames.push_back(aUserGalleryURL);
1063 size_t i = 0;
1064 for (auto & grfName : aGrfNames)
1065 {
1066 m_xExamplesVS->InsertItem( i + 1, i);
1067 INetURLObject aObj(grfName);
1068 if (aObj.GetProtocol() == INetProtocol::File)
1069 {
1070 // tdf#114070 - only show the last name of the filename without its extension
1071 aObj.removeExtension();
1072 grfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
1073 }
1074 m_xExamplesVS->SetItemText( i + 1, grfName );
1075 ++i;
1076 }
1077
1078 if(aGrfNames.empty())
1079 {
1080 m_xErrorText->show();
1081 }
1082 else
1083 {
1084 m_xExamplesVS->Show();
1085 m_xExamplesVS->SetFormat();
1086 }
1087 }
1088
1089 // tabpage numbering options
SvxNumOptionsTabPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)1090 SvxNumOptionsTabPage::SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
1091 const SfxItemSet& rSet)
1092 : SfxTabPage(pPage, pController, u"cui/ui/numberingoptionspage.ui"_ustr, u"NumberingOptionsPage"_ustr, &rSet)
1093 , aInvalidateTimer("cui SvxNumOptionsTabPage aInvalidateTimer")
1094 , m_pLevelHdlEvent(nullptr)
1095 , bLastWidthModified(false)
1096 , bModified(false)
1097 , bPreset(false)
1098 , bAutomaticCharStyles(true)
1099 , bHTMLMode(false)
1100 , nBullet(0xff)
1101 , nActNumLvl(1)
1102 , nNumItemId(SID_ATTR_NUMBERING_RULE)
1103 , m_aRatioTop(ConnectorType::Top)
1104 , m_aRatioBottom(ConnectorType::Bottom)
1105 , m_xGrid(m_xBuilder->weld_widget(u"grid2"_ustr))
1106 , m_xLevelLB(m_xBuilder->weld_tree_view(u"levellb"_ustr))
1107 , m_xFmtLB(m_xBuilder->weld_combo_box(u"numfmtlb"_ustr))
1108 , m_xSeparatorFT(m_xBuilder->weld_label(u"separator"_ustr))
1109 , m_xPrefixFT(m_xBuilder->weld_label(u"prefixft"_ustr))
1110 , m_xPrefixED(m_xBuilder->weld_entry(u"prefix"_ustr))
1111 , m_xSuffixFT(m_xBuilder->weld_label(u"suffixft"_ustr))
1112 , m_xSuffixED(m_xBuilder->weld_entry(u"suffix"_ustr))
1113 , m_xCharFmtFT(m_xBuilder->weld_label(u"charstyleft"_ustr))
1114 , m_xCharFmtLB(m_xBuilder->weld_combo_box(u"charstyle"_ustr))
1115 , m_xBulColorFT(m_xBuilder->weld_label(u"colorft"_ustr))
1116 , m_xBulColLB(new ColorListBox(m_xBuilder->weld_menu_button(u"color"_ustr),
1117 [this]{ return GetDialogController()->getDialog(); }))
1118 , m_xBulRelSizeFT(m_xBuilder->weld_label(u"relsizeft"_ustr))
1119 , m_xBulRelSizeMF(m_xBuilder->weld_metric_spin_button(u"relsize"_ustr, FieldUnit::PERCENT))
1120 , m_xAllLevelFT(m_xBuilder->weld_label(u"sublevelsft"_ustr))
1121 , m_xAllLevelNF(m_xBuilder->weld_spin_button(u"sublevels"_ustr))
1122 , m_xIsLegalCB(m_xBuilder->weld_check_button(u"islegal"_ustr))
1123 , m_xStartFT(m_xBuilder->weld_label(u"startatft"_ustr))
1124 , m_xStartED(m_xBuilder->weld_spin_button(u"startat"_ustr))
1125 , m_xBulletFT(m_xBuilder->weld_label(u"bulletft"_ustr))
1126 , m_xBulletPB(m_xBuilder->weld_button(u"bullet"_ustr))
1127 , m_xBitmapFT(m_xBuilder->weld_label(u"bitmapft"_ustr))
1128 , m_xBitmapMB(m_xBuilder->weld_menu_button(u"bitmap"_ustr))
1129 , m_xWidthFT(m_xBuilder->weld_label(u"widthft"_ustr))
1130 , m_xWidthMF(m_xBuilder->weld_metric_spin_button(u"widthmf"_ustr, FieldUnit::CM))
1131 , m_xHeightFT(m_xBuilder->weld_label(u"heightft"_ustr))
1132 , m_xHeightMF(m_xBuilder->weld_metric_spin_button(u"heightmf"_ustr, FieldUnit::CM))
1133 , m_xRatioCB(m_xBuilder->weld_check_button(u"keepratio"_ustr))
1134 , m_xCbxScaleImg(m_xBuilder->weld_image(u"imRatio"_ustr))
1135 , m_xImgRatioTop(new weld::CustomWeld(*m_xBuilder, u"daRatioTop"_ustr, m_aRatioTop))
1136 , m_xImgRatioBottom(new weld::CustomWeld(*m_xBuilder, u"daRatioBottom"_ustr, m_aRatioBottom))
1137 , m_xOrientFT(m_xBuilder->weld_label(u"orientft"_ustr))
1138 , m_xOrientLB(m_xBuilder->weld_combo_box(u"orientlb"_ustr))
1139 , m_xAllLevelsFrame(m_xBuilder->weld_widget(u"levelsframe"_ustr))
1140 , m_xSameLevelCB(m_xBuilder->weld_check_button(u"allsame"_ustr))
1141 , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, u"preview"_ustr, m_aPreviewWIN))
1142 {
1143 m_xBulColLB->SetSlotId(SID_ATTR_CHAR_COLOR);
1144 m_xBulRelSizeMF->set_min(SVX_NUM_REL_SIZE_MIN, FieldUnit::PERCENT);
1145 m_xBulRelSizeMF->set_increments(5, 50, FieldUnit::PERCENT);
1146 SetExchangeSupport();
1147 aActBulletFont = lcl_GetDefaultBulletFont();
1148 // vertical alignment = fill makes the drawingarea expand the associated spinedits so we have to size it here
1149 const sal_Int16 aHeight
1150 = static_cast<sal_Int16>(std::max(int(m_xRatioCB->get_preferred_size().getHeight() / 2
1151 - m_xWidthMF->get_preferred_size().getHeight() / 2),
1152 12));
1153 const sal_Int16 aWidth
1154 = static_cast<sal_Int16>(m_xRatioCB->get_preferred_size().getWidth() / 2);
1155 m_xImgRatioTop->set_size_request(aWidth, aHeight);
1156 m_xImgRatioBottom->set_size_request(aWidth, aHeight);
1157 //init needed for gtk3
1158 m_xCbxScaleImg->set_from_icon_name(m_xRatioCB->get_active() ? RID_SVXBMP_LOCKED
1159 : RID_SVXBMP_UNLOCKED);
1160
1161 m_xBulletPB->connect_clicked(LINK(this, SvxNumOptionsTabPage, BulletHdl_Impl));
1162 m_xFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl));
1163 m_xBitmapMB->connect_selected(LINK(this, SvxNumOptionsTabPage, GraphicHdl_Impl));
1164 m_xBitmapMB->connect_toggled(LINK(this, SvxNumOptionsTabPage, PopupActivateHdl_Impl));
1165 m_xLevelLB->set_selection_mode(SelectionMode::Multiple);
1166 m_xLevelLB->connect_changed(LINK(this, SvxNumOptionsTabPage, LevelHdl_Impl));
1167 m_xCharFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, CharFmtHdl_Impl));
1168 m_xWidthMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl));
1169 m_xHeightMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl));
1170 m_xRatioCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, RatioHdl_Impl));
1171 m_xStartED->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SpinModifyHdl_Impl));
1172 m_xPrefixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl));
1173 m_xSuffixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl));
1174 m_xAllLevelNF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, AllLevelHdl_Impl));
1175 m_xIsLegalCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, IsLegalHdl_Impl));
1176 m_xOrientLB->connect_changed(LINK(this, SvxNumOptionsTabPage, OrientHdl_Impl));
1177 m_xSameLevelCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, SameLevelHdl_Impl));
1178 m_xBulRelSizeMF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, BulRelSizeHdl_Impl));
1179 m_xBulColLB->SetSelectHdl(LINK(this, SvxNumOptionsTabPage, BulColorHdl_Impl));
1180 aInvalidateTimer.SetInvokeHandler(LINK(this, SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl));
1181 aInvalidateTimer.SetTimeout(50);
1182
1183 eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhichIDFromSlotID(SID_ATTR_NUMBERING_RULE));
1184
1185 // Fill ListBox with predefined / translated numbering types.
1186 sal_uInt32 nCount = SvxNumberingTypeTable::Count();
1187 for (sal_uInt32 i = 0; i < nCount; ++i)
1188 {
1189 int nValue = SvxNumberingTypeTable::GetValue(i);
1190 if (comphelper::LibreOfficeKit::isActive() && (nValue & SVX_NUM_BITMAP)) continue;
1191 m_xFmtLB->append(OUString::number(nValue), SvxNumberingTypeTable::GetString(i));
1192 }
1193
1194 // Get advanced numbering types from the component.
1195 // Watch out for the ugly
1196 // 136 == 0x88 == SVX_NUM_BITMAP|0x80 == SVX_NUM_BITMAP|LINK_TOKEN
1197 // to not remove that.
1198 SvxNumOptionsTabPageHelper::GetI18nNumbering( *m_xFmtLB, (SVX_NUM_BITMAP | LINK_TOKEN));
1199
1200 m_xFmtLB->set_active(0);
1201
1202 m_xCharFmtLB->set_size_request(m_xCharFmtLB->get_approximate_digit_width() * 10, -1);
1203 Size aSize(m_xGrid->get_preferred_size());
1204 m_xGrid->set_size_request(aSize.Width(), -1);
1205 }
1206
~SvxNumOptionsTabPage()1207 SvxNumOptionsTabPage::~SvxNumOptionsTabPage()
1208 {
1209 m_xPreviewWIN.reset();
1210 m_xBulColLB.reset();
1211 pActNum.reset();
1212 pSaveNum.reset();
1213 if (m_pLevelHdlEvent)
1214 {
1215 Application::RemoveUserEvent(m_pLevelHdlEvent);
1216 m_pLevelHdlEvent = nullptr;
1217 }
1218 }
1219
SetMetric(FieldUnit eMetric)1220 void SvxNumOptionsTabPage::SetMetric(FieldUnit eMetric)
1221 {
1222 if(eMetric == FieldUnit::MM)
1223 {
1224 m_xWidthMF->set_digits(1);
1225 m_xHeightMF->set_digits(1);
1226 }
1227 m_xWidthMF->set_unit(eMetric);
1228 m_xHeightMF->set_unit(eMetric);
1229 }
1230
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rAttrSet)1231 std::unique_ptr<SfxTabPage> SvxNumOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
1232 const SfxItemSet* rAttrSet)
1233 {
1234 return std::make_unique<SvxNumOptionsTabPage>(pPage, pController, *rAttrSet);
1235 };
1236
ActivatePage(const SfxItemSet & rSet)1237 void SvxNumOptionsTabPage::ActivatePage(const SfxItemSet& rSet)
1238 {
1239 const SfxItemSet* pExampleSet = GetDialogExampleSet();
1240 sal_uInt16 nTmpNumLvl = 1;
1241 if(pExampleSet)
1242 {
1243 if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
1244 bPreset = pPresetItem->GetValue();
1245 if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
1246 nTmpNumLvl = pLevelItem->GetValue();
1247 }
1248 if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
1249 {
1250 pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
1251 }
1252
1253 bModified = (!pActNum->Get( 0 ) || bPreset);
1254 if(*pActNum == *pSaveNum && nActNumLvl == nTmpNumLvl)
1255 return;
1256
1257 nActNumLvl = nTmpNumLvl;
1258 sal_uInt16 nMask = 1;
1259 m_xLevelLB->unselect_all();
1260 if (nActNumLvl == SAL_MAX_UINT16)
1261 m_xLevelLB->select(pActNum->GetLevelCount());
1262 if(nActNumLvl != SAL_MAX_UINT16)
1263 {
1264 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
1265 {
1266 if(nActNumLvl & nMask)
1267 m_xLevelLB->select(i);
1268 nMask <<= 1 ;
1269 }
1270 }
1271 *pActNum = *pSaveNum;
1272
1273 InitControls();
1274 }
1275
DeactivatePage(SfxItemSet * _pSet)1276 DeactivateRC SvxNumOptionsTabPage::DeactivatePage(SfxItemSet * _pSet)
1277 {
1278 if(_pSet)
1279 FillItemSet(_pSet);
1280 return DeactivateRC::LeavePage;
1281 }
1282
FillItemSet(SfxItemSet * rSet)1283 bool SvxNumOptionsTabPage::FillItemSet( SfxItemSet* rSet )
1284 {
1285 rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl));
1286 if(bModified && pActNum)
1287 {
1288 *pSaveNum = *pActNum;
1289 rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
1290 rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false));
1291 }
1292 return bModified;
1293 };
1294
Reset(const SfxItemSet * rSet)1295 void SvxNumOptionsTabPage::Reset( const SfxItemSet* rSet )
1296 {
1297 // in Draw the item exists as WhichId, in Writer only as SlotId
1298 const SvxNumBulletItem* pBulletItem =
1299 rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
1300 if(!pBulletItem)
1301 {
1302 nNumItemId = rSet->GetPool()->GetWhichIDFromSlotID(SID_ATTR_NUMBERING_RULE);
1303 pBulletItem = rSet->GetItemIfSet(nNumItemId, false);
1304
1305 if( !pBulletItem )
1306 {
1307 pBulletItem = & rSet->Get( nNumItemId );
1308 }
1309 }
1310 DBG_ASSERT(pBulletItem, "no item found!");
1311 pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
1312
1313 // insert levels
1314 if (!m_xLevelLB->n_children())
1315 {
1316 for(sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++)
1317 m_xLevelLB->append_text(OUString::number(i));
1318 if(pSaveNum->GetLevelCount() > 1)
1319 {
1320 OUString sEntry = "1 - " + OUString::number( pSaveNum->GetLevelCount() );
1321 m_xLevelLB->append_text(sEntry);
1322 m_xLevelLB->select_text(sEntry);
1323 }
1324 else
1325 m_xLevelLB->select(0);
1326 }
1327 else
1328 m_xLevelLB->select(m_xLevelLB->n_children() - 1);
1329
1330 sal_uInt16 nMask = 1;
1331 m_xLevelLB->unselect_all();
1332 if (nActNumLvl == SAL_MAX_UINT16)
1333 {
1334 m_xLevelLB->select( pSaveNum->GetLevelCount() );
1335 }
1336 else
1337 {
1338 for(sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++)
1339 {
1340 if(nActNumLvl & nMask)
1341 m_xLevelLB->select( i );
1342 nMask <<= 1 ;
1343 }
1344 }
1345
1346 if(!pActNum)
1347 pActNum.reset( new SvxNumRule(*pSaveNum) );
1348 else if(*pSaveNum != *pActNum)
1349 *pActNum = *pSaveNum;
1350 m_aPreviewWIN.SetNumRule(pActNum.get());
1351 m_xSameLevelCB->set_active(pActNum->IsContinuousNumbering());
1352
1353 const SfxUInt16Item* pHtmlModeItem =
1354 rSet->GetItemIfSet( SID_HTML_MODE, false );
1355 if (!pHtmlModeItem)
1356 {
1357 if (SfxObjectShell* pShell = SfxObjectShell::Current())
1358 pHtmlModeItem = pShell->GetItem( SID_HTML_MODE );
1359 }
1360 if ( pHtmlModeItem )
1361 {
1362 sal_uInt16 nHtmlMode = pHtmlModeItem->GetValue();
1363 bHTMLMode = 0 != (nHtmlMode&HTMLMODE_ON);
1364 }
1365
1366 bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
1367 m_xCharFmtFT->set_visible(bCharFmt);
1368 m_xCharFmtLB->set_visible(bCharFmt);
1369
1370 bool bContinuous = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
1371
1372 bool bAllLevel = bContinuous && !bHTMLMode;
1373 m_xAllLevelFT->set_visible(bAllLevel);
1374 m_xAllLevelNF->set_visible(bAllLevel);
1375 m_xIsLegalCB->set_visible(bAllLevel);
1376
1377 m_xAllLevelsFrame->set_visible(bContinuous);
1378
1379 // again misusage: in Draw there is numeration only until the bitmap
1380 // without SVX_NUM_NUMBER_NONE
1381 //remove types that are unsupported by Draw/Impress
1382 if(!bContinuous)
1383 {
1384 sal_Int32 nFmtCount = m_xFmtLB->get_count();
1385 for(sal_Int32 i = nFmtCount; i; i--)
1386 {
1387 sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32();
1388 if(/*SVX_NUM_NUMBER_NONE == nEntryData ||*/
1389 (SVX_NUM_BITMAP|LINK_TOKEN) == nEntryData)
1390 m_xFmtLB->remove(i - 1);
1391 }
1392 }
1393 //one must be enabled
1394 if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_LINKED_BMP))
1395 {
1396 auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP|LINK_TOKEN));
1397 if (nPos != -1)
1398 m_xFmtLB->remove(nPos);
1399 }
1400 else if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP))
1401 {
1402 auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP));
1403 if (nPos != -1)
1404 m_xFmtLB->remove(nPos);
1405 }
1406
1407 // MegaHack: because of a not-fixable 'design mistake/error' in Impress
1408 // delete all kinds of numeric enumerations
1409 if(pActNum->IsFeatureSupported(SvxNumRuleFlags::NO_NUMBERS))
1410 {
1411 sal_Int32 nFmtCount = m_xFmtLB->get_count();
1412 for(sal_Int32 i = nFmtCount; i; i--)
1413 {
1414 sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32();
1415 if( /*nEntryData >= SVX_NUM_CHARS_UPPER_LETTER &&*/ nEntryData <= SVX_NUM_NUMBER_NONE)
1416 m_xFmtLB->remove(i - 1);
1417 }
1418 }
1419
1420 InitControls();
1421 bModified = false;
1422 }
1423
InitControls()1424 void SvxNumOptionsTabPage::InitControls()
1425 {
1426 bool bShowBullet = true;
1427 bool bShowBitmap = true;
1428 bool bSameType = true;
1429 bool bSameStart = true;
1430 bool bSamePrefix = true;
1431 bool bSameSuffix = true;
1432 bool bAllLevel = true;
1433 bool bSameCharFmt = true;
1434 bool bSameVOrient = true;
1435 bool bSameSize = true;
1436 bool bSameBulColor = true;
1437 bool bSameBulRelSize= true;
1438
1439 TriState isLegal = TRISTATE_INDET;
1440
1441 const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM];
1442 OUString sFirstCharFmt;
1443 sal_Int16 eFirstOrient = text::VertOrientation::NONE;
1444 Size aFirstSize(0,0);
1445 sal_uInt16 nMask = 1;
1446 sal_uInt16 nLvl = SAL_MAX_UINT16;
1447 sal_uInt16 nHighestLevel = 0;
1448
1449 bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
1450 bool bBullRelSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
1451 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
1452 {
1453 if(nActNumLvl & nMask)
1454 {
1455 aNumFmtArr[i] = &pActNum->GetLevel(i);
1456 bShowBullet &= aNumFmtArr[i]->GetNumberingType() == SVX_NUM_CHAR_SPECIAL;
1457 bShowBitmap &= (aNumFmtArr[i]->GetNumberingType()&(~LINK_TOKEN)) == SVX_NUM_BITMAP;
1458 if(SAL_MAX_UINT16 == nLvl)
1459 {
1460 nLvl = i;
1461 sFirstCharFmt = aNumFmtArr[i]->GetCharFormatName();
1462 eFirstOrient = aNumFmtArr[i]->GetVertOrient();
1463 if(bShowBitmap)
1464 aFirstSize = aNumFmtArr[i]->GetGraphicSize();
1465 isLegal = aNumFmtArr[i]->GetIsLegal() ? TRISTATE_TRUE : TRISTATE_FALSE;
1466 }
1467 if( i > nLvl)
1468 {
1469 bSameType &= aNumFmtArr[i]->GetNumberingType() == aNumFmtArr[nLvl]->GetNumberingType();
1470 bSameStart = aNumFmtArr[i]->GetStart() == aNumFmtArr[nLvl]->GetStart();
1471
1472 bSamePrefix = aNumFmtArr[i]->GetPrefix() == aNumFmtArr[nLvl]->GetPrefix();
1473 bSameSuffix = aNumFmtArr[i]->GetSuffix() == aNumFmtArr[nLvl]->GetSuffix();
1474 bAllLevel &= aNumFmtArr[i]->GetIncludeUpperLevels() == aNumFmtArr[nLvl]->GetIncludeUpperLevels();
1475 if (aNumFmtArr[i]->GetIsLegal() != aNumFmtArr[nLvl]->GetIsLegal())
1476 isLegal = TRISTATE_INDET;
1477 bSameCharFmt &= sFirstCharFmt == aNumFmtArr[i]->GetCharFormatName();
1478 bSameVOrient &= eFirstOrient == aNumFmtArr[i]->GetVertOrient();
1479 if(bShowBitmap && bSameSize)
1480 bSameSize &= aNumFmtArr[i]->GetGraphicSize() == aFirstSize;
1481 bSameBulColor &= aNumFmtArr[i]->GetBulletColor() == aNumFmtArr[nLvl]->GetBulletColor();
1482 bSameBulRelSize &= aNumFmtArr[i]->GetBulletRelSize() == aNumFmtArr[nLvl]->GetBulletRelSize();
1483 }
1484 nHighestLevel = i;
1485 }
1486 else
1487 aNumFmtArr[i] = nullptr;
1488
1489 nMask <<= 1 ;
1490 }
1491 SwitchNumberType(bShowBullet ? 1 : bShowBitmap ? 2 : 0);
1492
1493 sal_uInt16 nNumberingType;
1494 if (nLvl != SAL_MAX_UINT16)
1495 nNumberingType = aNumFmtArr[nLvl]->GetNumberingType();
1496 else
1497 {
1498 nNumberingType = SVX_NUM_NUMBER_NONE;
1499 bAllLevel = false;
1500 bSameBulRelSize = false;
1501 bSameBulColor = false;
1502 bSameStart = false;
1503 bSamePrefix = false;
1504 bSameSuffix = false;
1505 }
1506
1507 CheckForStartValue_Impl(nNumberingType);
1508
1509 if(bShowBitmap)
1510 {
1511 if(!bSameVOrient || eFirstOrient == text::VertOrientation::NONE)
1512 m_xOrientLB->set_active(-1);
1513 else
1514 m_xOrientLB->set_active(
1515 sal::static_int_cast< sal_Int32 >(eFirstOrient - 1));
1516 // no text::VertOrientation::NONE
1517
1518 if(bSameSize)
1519 {
1520 SetMetricValue(*m_xHeightMF, aFirstSize.Height(), eCoreUnit);
1521 SetMetricValue(*m_xWidthMF, aFirstSize.Width(), eCoreUnit);
1522 }
1523 else
1524 {
1525 m_xHeightMF->set_text(u""_ustr);
1526 m_xWidthMF->set_text(u""_ustr);
1527 }
1528 }
1529
1530 if(bSameType)
1531 {
1532 sal_uInt16 nLBData = nNumberingType;
1533 m_xFmtLB->set_active_id(OUString::number(nLBData));
1534 }
1535 else
1536 m_xFmtLB->set_active(-1);
1537
1538 m_xAllLevelNF->set_sensitive(nHighestLevel > 0 && !m_xSameLevelCB->get_active());
1539 m_xAllLevelNF->set_max(nHighestLevel + 1);
1540 if(bAllLevel)
1541 {
1542 m_xAllLevelNF->set_value(aNumFmtArr[nLvl]->GetIncludeUpperLevels());
1543 }
1544 else
1545 {
1546 m_xAllLevelNF->set_text(u""_ustr);
1547 }
1548
1549 m_xIsLegalCB->set_state(isLegal);
1550 m_xIsLegalCB->set_sensitive(!m_xSameLevelCB->get_active());
1551
1552 if(bBullRelSize)
1553 {
1554 if(bSameBulRelSize)
1555 m_xBulRelSizeMF->set_value(aNumFmtArr[nLvl]->GetBulletRelSize(), FieldUnit::PERCENT);
1556 else
1557 m_xBulRelSizeMF->set_text(u""_ustr);
1558 }
1559 if(bBullColor)
1560 {
1561 if(bSameBulColor)
1562 m_xBulColLB->SelectEntry(aNumFmtArr[nLvl]->GetBulletColor());
1563 else
1564 m_xBulColLB->SetNoSelection();
1565 }
1566 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
1567 switch(nBullet)
1568 {
1569 case SHOW_NUMBERING:
1570 if(bSameStart)
1571 {
1572 m_xStartED->set_value(aNumFmtArr[nLvl]->GetStart());
1573 }
1574 else
1575 m_xStartED->set_text(u""_ustr);
1576 break;
1577 case SHOW_BULLET:
1578 break;
1579 case SHOW_BITMAP:
1580 break;
1581 }
1582
1583 if(bSamePrefix)
1584 m_xPrefixED->set_text(aNumFmtArr[nLvl]->GetPrefix());
1585 else
1586 m_xPrefixED->set_text(u""_ustr);
1587 if(bSameSuffix)
1588 m_xSuffixED->set_text(aNumFmtArr[nLvl]->GetSuffix());
1589 else
1590 m_xSuffixED->set_text(u""_ustr);
1591
1592 if(bSameCharFmt)
1593 {
1594 if (!sFirstCharFmt.isEmpty())
1595 m_xCharFmtLB->set_active_text(sFirstCharFmt);
1596 else if (m_xCharFmtLB->get_count())
1597 m_xCharFmtLB->set_active(0);
1598 }
1599 else
1600 m_xCharFmtLB->set_active(-1);
1601
1602 m_aPreviewWIN.SetLevel(nActNumLvl);
1603 m_aPreviewWIN.Invalidate();
1604 }
1605
1606 // 0 - Number; 1 - Bullet; 2 - Bitmap
SwitchNumberType(sal_uInt8 nType)1607 void SvxNumOptionsTabPage::SwitchNumberType( sal_uInt8 nType )
1608 {
1609 if(nBullet == nType)
1610 return;
1611 nBullet = nType;
1612 bool bBullet = (nType == SHOW_BULLET);
1613 bool bBitmap = (nType == SHOW_BITMAP);
1614 bool bEnableBitmap = (nType == SHOW_BITMAP);
1615 bool bNumeric = !(bBitmap||bBullet);
1616 m_xSeparatorFT->set_visible(bNumeric);
1617 m_xPrefixFT->set_visible(bNumeric);
1618 m_xPrefixED->set_visible(bNumeric);
1619 m_xSuffixFT->set_visible(bNumeric);
1620 m_xSuffixED->set_visible(bNumeric);
1621
1622 bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
1623 m_xCharFmtFT->set_visible(!bBitmap && bCharFmt);
1624 m_xCharFmtLB->set_visible(!bBitmap && bCharFmt);
1625
1626 // this is rather misusage, as there is no own flag
1627 // for complete numeration
1628 bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
1629 bool bAllLevel = bNumeric && bAllLevelFeature && !bHTMLMode;
1630 m_xAllLevelFT->set_visible(bAllLevel);
1631 m_xAllLevelNF->set_visible(bAllLevel);
1632 m_xIsLegalCB->set_visible(bAllLevel);
1633
1634 m_xStartFT->set_visible(!(bBullet||bBitmap));
1635 m_xStartED->set_visible(!(bBullet||bBitmap));
1636
1637 m_xBulletFT->set_visible(bBullet);
1638 m_xBulletPB->set_visible(bBullet);
1639 bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
1640 m_xBulColorFT->set_visible(!bBitmap && bBullColor);
1641 m_xBulColLB->set_visible(!bBitmap && bBullColor);
1642 bool bBullResSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
1643 m_xBulRelSizeFT->set_visible(!bBitmap && bBullResSize);
1644 m_xBulRelSizeMF->set_visible(!bBitmap && bBullResSize);
1645
1646 m_xBitmapFT->set_visible(bBitmap);
1647 m_xBitmapMB->set_visible(bBitmap);
1648
1649 m_xWidthFT->set_visible(bBitmap);
1650 m_xWidthMF->set_visible(bBitmap);
1651 m_xHeightFT->set_visible(bBitmap);
1652 m_xHeightMF->set_visible(bBitmap);
1653 m_xRatioCB->set_visible(bBitmap);
1654 m_xCbxScaleImg->set_visible(bBitmap);
1655 m_xImgRatioTop->set_visible(bBitmap);
1656 m_xImgRatioBottom->set_visible(bBitmap);
1657
1658 m_xOrientFT->set_visible(bBitmap && bAllLevelFeature);
1659 m_xOrientLB->set_visible(bBitmap && bAllLevelFeature);
1660
1661 m_xWidthFT->set_sensitive(bEnableBitmap);
1662 m_xWidthMF->set_sensitive(bEnableBitmap);
1663 m_xHeightFT->set_sensitive(bEnableBitmap);
1664 m_xHeightMF->set_sensitive(bEnableBitmap);
1665 m_xRatioCB->set_sensitive(bEnableBitmap);
1666 m_xOrientFT->set_sensitive(bEnableBitmap);
1667 m_xOrientLB->set_sensitive(bEnableBitmap);
1668 }
1669
IMPL_LINK_NOARG(SvxNumOptionsTabPage,LevelHdl_Impl,weld::TreeView &,void)1670 IMPL_LINK_NOARG(SvxNumOptionsTabPage, LevelHdl_Impl, weld::TreeView&, void)
1671 {
1672 if (m_pLevelHdlEvent)
1673 return;
1674 // tdf#127112 (borrowing tdf#127120 solution) multiselection may be implemented by deselect follow by select so
1675 // fire off the handler to happen on next event loop and only process the
1676 // final state
1677 m_pLevelHdlEvent = Application::PostUserEvent(LINK(this, SvxNumOptionsTabPage, LevelHdl));
1678 }
1679
IMPL_LINK_NOARG(SvxNumOptionsTabPage,LevelHdl,void *,void)1680 IMPL_LINK_NOARG(SvxNumOptionsTabPage, LevelHdl, void*, void)
1681 {
1682 m_pLevelHdlEvent = nullptr;
1683
1684 sal_uInt16 nSaveNumLvl = nActNumLvl;
1685 nActNumLvl = 0;
1686 std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows();
1687 if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() &&
1688 (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
1689 {
1690 nActNumLvl = 0xFFFF;
1691 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
1692 m_xLevelLB->unselect(i);
1693 }
1694 else if (!aSelectedRows.empty())
1695 {
1696 sal_uInt16 nMask = 1;
1697 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
1698 {
1699 if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end())
1700 nActNumLvl |= nMask;
1701 nMask <<= 1;
1702 }
1703 m_xLevelLB->unselect(pActNum->GetLevelCount());
1704 }
1705 else
1706 {
1707 nActNumLvl = nSaveNumLvl;
1708 sal_uInt16 nMask = 1;
1709 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
1710 {
1711 if(nActNumLvl & nMask)
1712 {
1713 m_xLevelLB->select(i);
1714 break;
1715 }
1716 nMask <<=1;
1717 }
1718 }
1719 InitControls();
1720 }
1721
IMPL_LINK_NOARG(SvxNumOptionsTabPage,PreviewInvalidateHdl_Impl,Timer *,void)1722 IMPL_LINK_NOARG(SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl, Timer *, void)
1723 {
1724 m_aPreviewWIN.Invalidate();
1725 }
1726
IMPL_LINK(SvxNumOptionsTabPage,AllLevelHdl_Impl,weld::SpinButton &,rBox,void)1727 IMPL_LINK(SvxNumOptionsTabPage, AllLevelHdl_Impl, weld::SpinButton&, rBox, void)
1728 {
1729 sal_uInt16 nMask = 1;
1730 for(sal_uInt16 e = 0; e < pActNum->GetLevelCount(); e++)
1731 {
1732 if(nActNumLvl & nMask)
1733 {
1734 SvxNumberFormat aNumFmt(pActNum->GetLevel(e));
1735 aNumFmt.SetIncludeUpperLevels(static_cast<sal_uInt8>(std::min(rBox.get_value(), sal_Int64(e + 1))) );
1736 // Set the same prefix/suffix to generate list format with changed IncludedUpperLevels
1737 aNumFmt.SetListFormat(aNumFmt.GetPrefix(), aNumFmt.GetSuffix(), e);
1738 pActNum->SetLevel(e, aNumFmt);
1739 }
1740 nMask <<= 1;
1741 }
1742 SetModified();
1743 }
1744
IMPL_LINK(SvxNumOptionsTabPage,IsLegalHdl_Impl,weld::Toggleable &,rBox,void)1745 IMPL_LINK(SvxNumOptionsTabPage, IsLegalHdl_Impl, weld::Toggleable&, rBox, void)
1746 {
1747 bool bSet = rBox.get_active();
1748 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
1749 {
1750 if (nActNumLvl & (sal_uInt16(1) << i))
1751 {
1752 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
1753 aNumFmt.SetIsLegal(bSet);
1754 pActNum->SetLevel(i, aNumFmt);
1755 }
1756 }
1757 SetModified();
1758 }
1759
IMPL_LINK(SvxNumOptionsTabPage,NumberTypeSelectHdl_Impl,weld::ComboBox &,rBox,void)1760 IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox, void)
1761 {
1762 OUString sSelectStyle;
1763 bool bShowOrient = false;
1764 bool bBmp = false;
1765 sal_uInt16 nMask = 1;
1766 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
1767 {
1768 if(nActNumLvl & nMask)
1769 {
1770 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
1771 // PAGEDESC does not exist
1772 SvxNumType nNumType = static_cast<SvxNumType>(rBox.get_active_id().toUInt32());
1773 aNumFmt.SetNumberingType(nNumType);
1774 sal_uInt16 nNumberingType = aNumFmt.GetNumberingType();
1775 if(SVX_NUM_BITMAP == (nNumberingType&(~LINK_TOKEN)))
1776 {
1777 bBmp |= nullptr != aNumFmt.GetBrush();
1778 aNumFmt.SetIncludeUpperLevels( 1 );
1779 aNumFmt.SetListFormat(u""_ustr, u""_ustr, i);
1780 if(!bBmp)
1781 aNumFmt.SetGraphic(u""_ustr);
1782 pActNum->SetLevel(i, aNumFmt);
1783 SwitchNumberType(SHOW_BITMAP);
1784 bShowOrient = true;
1785 }
1786 else if( SVX_NUM_CHAR_SPECIAL == nNumberingType )
1787 {
1788 aNumFmt.SetIncludeUpperLevels( 1 );
1789 aNumFmt.SetListFormat(u""_ustr, u""_ustr, i);
1790 if( !aNumFmt.GetBulletFont() )
1791 aNumFmt.SetBulletFont(&aActBulletFont);
1792 if( !aNumFmt.GetBulletChar() )
1793 aNumFmt.SetBulletChar( SVX_DEF_BULLET );
1794 pActNum->SetLevel(i, aNumFmt);
1795 SwitchNumberType(SHOW_BULLET);
1796 // allocation of the drawing pattern is automatic
1797 if(bAutomaticCharStyles)
1798 {
1799 sSelectStyle = m_sBulletCharFormatName;
1800 }
1801 }
1802 else
1803 {
1804 aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
1805
1806 SwitchNumberType(SHOW_NUMBERING);
1807 pActNum->SetLevel(i, aNumFmt);
1808 CheckForStartValue_Impl(nNumberingType);
1809
1810 // allocation of the drawing pattern is automatic
1811 if(bAutomaticCharStyles)
1812 {
1813 sSelectStyle = m_sNumCharFmtName;
1814 }
1815 }
1816 }
1817 nMask <<= 1;
1818 }
1819 bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
1820 if(bShowOrient && bAllLevelFeature)
1821 {
1822 m_xOrientFT->show();
1823 m_xOrientLB->show();
1824 }
1825 else
1826 {
1827 m_xOrientFT->hide();
1828 m_xOrientLB->hide();
1829 }
1830 SetModified();
1831 if(!sSelectStyle.isEmpty())
1832 {
1833 m_xCharFmtLB->set_active_text(sSelectStyle);
1834 CharFmtHdl_Impl(*m_xCharFmtLB);
1835 bAutomaticCharStyles = true;
1836 }
1837 }
1838
CheckForStartValue_Impl(sal_uInt16 nNumberingType)1839 void SvxNumOptionsTabPage::CheckForStartValue_Impl(sal_uInt16 nNumberingType)
1840 {
1841 bool bIsNull = m_xStartED->get_value() == 0;
1842 bool bNoZeroAllowed = nNumberingType < SVX_NUM_ARABIC ||
1843 SVX_NUM_CHARS_UPPER_LETTER_N == nNumberingType ||
1844 SVX_NUM_CHARS_LOWER_LETTER_N == nNumberingType;
1845 m_xStartED->set_min(bNoZeroAllowed ? 1 : 0);
1846 if (bIsNull && bNoZeroAllowed)
1847 EditModifyHdl_Impl(*m_xStartED);
1848 }
1849
IMPL_LINK(SvxNumOptionsTabPage,OrientHdl_Impl,weld::ComboBox &,rBox,void)1850 IMPL_LINK(SvxNumOptionsTabPage, OrientHdl_Impl, weld::ComboBox&, rBox, void)
1851 {
1852 sal_Int32 nPos = rBox.get_active();
1853 nPos ++; // no VERT_NONE
1854
1855 sal_uInt16 nMask = 1;
1856 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
1857 {
1858 if(nActNumLvl & nMask)
1859 {
1860 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
1861 if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
1862 {
1863 const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
1864 const Size& rSize = aNumFmt.GetGraphicSize();
1865 sal_Int16 eOrient = static_cast<sal_Int16>(nPos);
1866 aNumFmt.SetGraphicBrush( pBrushItem, &rSize, &eOrient );
1867 pActNum->SetLevel(i, aNumFmt);
1868 }
1869 }
1870 nMask <<= 1;
1871 }
1872 SetModified(false);
1873 }
1874
IMPL_LINK(SvxNumOptionsTabPage,SameLevelHdl_Impl,weld::Toggleable &,rBox,void)1875 IMPL_LINK(SvxNumOptionsTabPage, SameLevelHdl_Impl, weld::Toggleable&, rBox, void)
1876 {
1877 bool bSet = rBox.get_active();
1878 pActNum->SetContinuousNumbering(bSet);
1879 bool bRepaint = false;
1880 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
1881 {
1882 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
1883 if(aNumFmt.GetNumberingType() != SVX_NUM_NUMBER_NONE)
1884 {
1885 bRepaint = true;
1886 break;
1887 }
1888 }
1889 SetModified(bRepaint);
1890 InitControls();
1891 }
1892
IMPL_LINK(SvxNumOptionsTabPage,BulColorHdl_Impl,ColorListBox &,rColorBox,void)1893 IMPL_LINK(SvxNumOptionsTabPage, BulColorHdl_Impl, ColorListBox&, rColorBox, void)
1894 {
1895 Color nSetColor = rColorBox.GetSelectEntryColor();
1896
1897 sal_uInt16 nMask = 1;
1898 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
1899 {
1900 if(nActNumLvl & nMask)
1901 {
1902 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
1903 aNumFmt.SetBulletColor(nSetColor);
1904 pActNum->SetLevel(i, aNumFmt);
1905 }
1906 nMask <<= 1;
1907 }
1908 SetModified();
1909 }
1910
IMPL_LINK(SvxNumOptionsTabPage,BulRelSizeHdl_Impl,weld::MetricSpinButton &,rField,void)1911 IMPL_LINK(SvxNumOptionsTabPage, BulRelSizeHdl_Impl, weld::MetricSpinButton&, rField, void)
1912 {
1913 sal_uInt16 nRelSize = rField.get_value(FieldUnit::PERCENT);
1914
1915 sal_uInt16 nMask = 1;
1916 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
1917 {
1918 if(nActNumLvl & nMask)
1919 {
1920 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
1921 aNumFmt.SetBulletRelSize(nRelSize);
1922 pActNum->SetLevel(i, aNumFmt);
1923 }
1924 nMask <<= 1;
1925 }
1926 SetModified();
1927 }
1928
IMPL_LINK(SvxNumOptionsTabPage,GraphicHdl_Impl,const OUString &,rIdent,void)1929 IMPL_LINK(SvxNumOptionsTabPage, GraphicHdl_Impl, const OUString&, rIdent, void)
1930 {
1931 OUString aGrfName;
1932 Size aSize;
1933 bool bSucc(false);
1934 SvxOpenGraphicDialog aGrfDlg(CuiResId(RID_CUISTR_EDIT_GRAPHIC), GetFrameWeld());
1935
1936 OUString sNumber;
1937 if (rIdent.startsWith("gallery", &sNumber))
1938 {
1939 auto idx = sNumber.toUInt32();
1940 if (idx < aGrfNames.size())
1941 {
1942 aGrfName = aGrfNames[idx];
1943 Graphic aGraphic;
1944 if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, idx, &aGraphic))
1945 {
1946 aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
1947 bSucc = true;
1948 }
1949 }
1950 }
1951 else if (rIdent == "fromfile")
1952 {
1953 aGrfDlg.EnableLink( false );
1954 aGrfDlg.AsLink( false );
1955 if ( !aGrfDlg.Execute() )
1956 {
1957 // memorize selected filter
1958 aGrfName = aGrfDlg.GetPath();
1959
1960 Graphic aGraphic;
1961 if( !aGrfDlg.GetGraphic(aGraphic) )
1962 {
1963 aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
1964 bSucc = true;
1965 }
1966 }
1967 }
1968 if(!bSucc)
1969 return;
1970
1971 aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit));
1972
1973 sal_uInt16 nMask = 1;
1974 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
1975 {
1976 if(nActNumLvl & nMask)
1977 {
1978 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
1979 aNumFmt.SetCharFormatName(m_sNumCharFmtName);
1980 aNumFmt.SetGraphic(aGrfName);
1981
1982 // set size for a later comparison
1983 const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
1984 // initiate asynchronous loading
1985 sal_Int16 eOrient = aNumFmt.GetVertOrient();
1986 aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient );
1987 aInitSize[i] = aNumFmt.GetGraphicSize();
1988
1989 pActNum->SetLevel(i, aNumFmt);
1990 }
1991 nMask <<= 1;
1992 }
1993 m_xRatioCB->set_sensitive(true);
1994 m_xWidthFT->set_sensitive(true);
1995 m_xHeightFT->set_sensitive(true);
1996 m_xWidthMF->set_sensitive(true);
1997 m_xHeightMF->set_sensitive(true);
1998 SetMetricValue(*m_xWidthMF, aSize.Width(), eCoreUnit);
1999 SetMetricValue(*m_xHeightMF, aSize.Height(), eCoreUnit);
2000 m_xOrientFT->set_sensitive(true);
2001 m_xOrientLB->set_sensitive(true);
2002 SetModified();
2003 //needed due to asynchronous loading of graphics in the SvxBrushItem
2004 aInvalidateTimer.Start();
2005 }
2006
IMPL_LINK_NOARG(SvxNumOptionsTabPage,PopupActivateHdl_Impl,weld::Toggleable &,void)2007 IMPL_LINK_NOARG(SvxNumOptionsTabPage, PopupActivateHdl_Impl, weld::Toggleable&, void)
2008 {
2009 if (m_xGalleryMenu)
2010 return;
2011
2012 m_xGalleryMenu = m_xBuilder->weld_menu(u"gallerysubmenu"_ustr);
2013 weld::WaitObject aWait(GetFrameWeld());
2014
2015 if (!GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames))
2016 return;
2017
2018 GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS);
2019
2020 Graphic aGraphic;
2021 OUString sGrfName;
2022 ScopedVclPtrInstance< VirtualDevice > pVD;
2023 size_t i = 0;
2024 for (const auto & grfName : aGrfNames)
2025 {
2026 sGrfName = grfName;
2027 OUString sItemId = "gallery" + OUString::number(i);
2028 INetURLObject aObj(sGrfName);
2029 if (aObj.GetProtocol() == INetProtocol::File)
2030 {
2031 // tdf#141334 - only show the last name of the filename without its extension
2032 aObj.removeExtension();
2033 sGrfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
2034 }
2035 if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, i, &aGraphic))
2036 {
2037 BitmapEx aBitmap(aGraphic.GetBitmapEx());
2038 Size aSize(aBitmap.GetSizePixel());
2039 if(aSize.Width() > MAX_BMP_WIDTH ||
2040 aSize.Height() > MAX_BMP_HEIGHT)
2041 {
2042 bool bWidth = aSize.Width() > aSize.Height();
2043 double nScale = bWidth ?
2044 double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
2045 double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
2046 aBitmap.Scale(nScale, nScale);
2047 }
2048 pVD->SetOutputSizePixel(aBitmap.GetSizePixel(), false);
2049 pVD->DrawBitmapEx(Point(), aBitmap);
2050 m_xGalleryMenu->append(sItemId, sGrfName, *pVD);
2051 }
2052 else
2053 {
2054 m_xGalleryMenu->append(sItemId, sGrfName);
2055 }
2056 ++i;
2057 }
2058 GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS);
2059 }
2060
IMPL_LINK_NOARG(SvxNumOptionsTabPage,BulletHdl_Impl,weld::Button &,void)2061 IMPL_LINK_NOARG(SvxNumOptionsTabPage, BulletHdl_Impl, weld::Button&, void)
2062 {
2063 SvxCharacterMap aMap(GetFrameWeld(), nullptr, nullptr);
2064
2065 sal_uInt16 nMask = 1;
2066 std::optional<vcl::Font> pFmtFont;
2067 bool bSameBullet = true;
2068 sal_UCS4 cBullet = 0;
2069 bool bFirst = true;
2070 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
2071 {
2072 if(nActNumLvl & nMask)
2073 {
2074 const SvxNumberFormat& rCurFmt = pActNum->GetLevel(i);
2075 if(bFirst)
2076 {
2077 cBullet = rCurFmt.GetBulletChar();
2078 }
2079 else if(rCurFmt.GetBulletChar() != cBullet )
2080 {
2081 bSameBullet = false;
2082 break;
2083 }
2084 if(!pFmtFont)
2085 pFmtFont = rCurFmt.GetBulletFont();
2086 bFirst = false;
2087 }
2088 nMask <<= 1;
2089
2090 }
2091
2092 if (pFmtFont)
2093 aMap.SetCharFont(*pFmtFont);
2094 else
2095 aMap.SetCharFont(aActBulletFont);
2096 if (bSameBullet)
2097 aMap.SetChar(cBullet);
2098 if (aMap.run() != RET_OK)
2099 return;
2100
2101 // change Font Numrules
2102 aActBulletFont = aMap.GetCharFont();
2103
2104 sal_uInt16 _nMask = 1;
2105 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
2106 {
2107 if(nActNumLvl & _nMask)
2108 {
2109 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
2110 aNumFmt.SetBulletFont(&aActBulletFont);
2111 aNumFmt.SetBulletChar(aMap.GetChar());
2112 pActNum->SetLevel(i, aNumFmt);
2113 }
2114 _nMask <<= 1;
2115 }
2116
2117 SetModified();
2118 }
2119
IMPL_LINK(SvxNumOptionsTabPage,SizeHdl_Impl,weld::MetricSpinButton &,rField,void)2120 IMPL_LINK( SvxNumOptionsTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField, void)
2121 {
2122 bool bWidth = &rField == m_xWidthMF.get();
2123 bLastWidthModified = bWidth;
2124 bool bRatio = m_xRatioCB->get_active();
2125 tools::Long nWidthVal = static_cast<tools::Long>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::MM_100TH)));
2126 tools::Long nHeightVal = static_cast<tools::Long>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::MM_100TH)));
2127 nWidthVal = OutputDevice::LogicToLogic( nWidthVal ,
2128 MapUnit::Map100thMM, eCoreUnit );
2129 nHeightVal = OutputDevice::LogicToLogic( nHeightVal,
2130 MapUnit::Map100thMM, eCoreUnit);
2131 double fSizeRatio;
2132
2133 bool bRepaint = false;
2134 sal_uInt16 nMask = 1;
2135 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
2136 {
2137 if(nActNumLvl & nMask)
2138 {
2139 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
2140 if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
2141 {
2142 Size aSize(aNumFmt.GetGraphicSize() );
2143 Size aSaveSize(aSize);
2144
2145 if (aInitSize[i].Height())
2146 fSizeRatio = static_cast<double>(aInitSize[i].Width()) / static_cast<double>(aInitSize[i].Height());
2147 else
2148 fSizeRatio = double(1);
2149
2150 if(bWidth)
2151 {
2152 tools::Long nDelta = nWidthVal - aInitSize[i].Width();
2153 aSize.setWidth( nWidthVal );
2154 if (bRatio)
2155 {
2156 aSize.setHeight( aInitSize[i].Height() + static_cast<tools::Long>(static_cast<double>(nDelta) / fSizeRatio) );
2157 m_xHeightMF->set_value(m_xHeightMF->normalize(
2158 OutputDevice::LogicToLogic( aSize.Height(), eCoreUnit, MapUnit::Map100thMM )),
2159 FieldUnit::MM_100TH);
2160 }
2161 }
2162 else
2163 {
2164 tools::Long nDelta = nHeightVal - aInitSize[i].Height();
2165 aSize.setHeight( nHeightVal );
2166 if (bRatio)
2167 {
2168 aSize.setWidth( aInitSize[i].Width() + static_cast<tools::Long>(static_cast<double>(nDelta) * fSizeRatio) );
2169 m_xWidthMF->set_value(m_xWidthMF->normalize(
2170 OutputDevice::LogicToLogic( aSize.Width(), eCoreUnit, MapUnit::Map100thMM )),
2171 FieldUnit::MM_100TH);
2172 }
2173 }
2174 const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
2175 sal_Int16 eOrient = aNumFmt.GetVertOrient();
2176 if(aSize != aSaveSize)
2177 bRepaint = true;
2178 aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient );
2179 pActNum->SetLevel(i, aNumFmt);
2180 }
2181 }
2182 nMask <<= 1;
2183 }
2184 SetModified(bRepaint);
2185 }
2186
IMPL_LINK(SvxNumOptionsTabPage,RatioHdl_Impl,weld::Toggleable &,rBox,void)2187 IMPL_LINK(SvxNumOptionsTabPage, RatioHdl_Impl, weld::Toggleable&, rBox, void)
2188 {
2189 m_xCbxScaleImg->set_from_icon_name(m_xRatioCB->get_active() ? RID_SVXBMP_LOCKED : RID_SVXBMP_UNLOCKED);
2190 if (rBox.get_active())
2191 {
2192 if (bLastWidthModified)
2193 SizeHdl_Impl(*m_xWidthMF);
2194 else
2195 SizeHdl_Impl(*m_xHeightMF);
2196 }
2197 }
2198
IMPL_LINK_NOARG(SvxNumOptionsTabPage,CharFmtHdl_Impl,weld::ComboBox &,void)2199 IMPL_LINK_NOARG(SvxNumOptionsTabPage, CharFmtHdl_Impl, weld::ComboBox&, void)
2200 {
2201 bAutomaticCharStyles = false;
2202 sal_Int32 nEntryPos = m_xCharFmtLB->get_active();
2203 OUString sEntry = m_xCharFmtLB->get_active_text();
2204 sal_uInt16 nMask = 1;
2205 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
2206 {
2207 if(nActNumLvl & nMask)
2208 {
2209 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
2210 if( 0 == nEntryPos )
2211 aNumFmt.SetCharFormatName(u""_ustr);
2212 else
2213 {
2214 if(SVX_NUM_BITMAP != (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
2215 aNumFmt.SetCharFormatName(sEntry);
2216 }
2217 pActNum->SetLevel(i, aNumFmt);
2218 }
2219 nMask <<= 1;
2220 }
2221 SetModified(false);
2222 };
2223
IMPL_LINK(SvxNumOptionsTabPage,EditModifyHdl_Impl,weld::Entry &,rEdit,void)2224 IMPL_LINK(SvxNumOptionsTabPage, EditModifyHdl_Impl, weld::Entry&, rEdit, void)
2225 {
2226 EditModifyHdl_Impl(&rEdit);
2227 }
2228
IMPL_LINK(SvxNumOptionsTabPage,SpinModifyHdl_Impl,weld::SpinButton &,rSpinButton,void)2229 IMPL_LINK(SvxNumOptionsTabPage, SpinModifyHdl_Impl, weld::SpinButton&, rSpinButton, void)
2230 {
2231 EditModifyHdl_Impl(&rSpinButton);
2232 }
2233
EditModifyHdl_Impl(const weld::Entry * pEdit)2234 void SvxNumOptionsTabPage::EditModifyHdl_Impl(const weld::Entry* pEdit)
2235 {
2236 bool bPrefixSuffix = (pEdit == m_xPrefixED.get())|| (pEdit == m_xSuffixED.get());
2237 bool bStart = pEdit == m_xStartED.get();
2238 sal_uInt16 nMask = 1;
2239 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
2240 {
2241 if(nActNumLvl & nMask)
2242 {
2243 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
2244 if (bPrefixSuffix)
2245 aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
2246 else if(bStart)
2247 aNumFmt.SetStart(m_xStartED->get_value());
2248 pActNum->SetLevel(i, aNumFmt);
2249 }
2250 nMask <<= 1;
2251 }
2252 SetModified();
2253 }
2254
2255 //See uiconfig/swriter/ui/outlinepositionpage.ui for effectively a duplicate
2256 //dialog to this one, except with a different preview window impl.
2257 //TODO, determine if SwNumPositionTabPage and SvxNumPositionTabPage can be
2258 //merged
SvxNumPositionTabPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)2259 SvxNumPositionTabPage::SvxNumPositionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
2260 : SfxTabPage(pPage, pController, u"cui/ui/numberingpositionpage.ui"_ustr, u"NumberingPositionPage"_ustr, &rSet)
2261 , m_pLevelHdlEvent(nullptr)
2262 , nActNumLvl(1)
2263 , nNumItemId(SID_ATTR_NUMBERING_RULE)
2264 , bModified(false)
2265 , bPreset(false)
2266 , bInInintControl(false)
2267 , bLabelAlignmentPosAndSpaceModeActive(false)
2268 , m_xLevelLB(m_xBuilder->weld_tree_view(u"levellb"_ustr))
2269 , m_xDistBorderFT(m_xBuilder->weld_label(u"indent"_ustr))
2270 , m_xDistBorderMF(m_xBuilder->weld_metric_spin_button(u"indentmf"_ustr, FieldUnit::CM))
2271 , m_xRelativeCB(m_xBuilder->weld_check_button(u"relative"_ustr))
2272 , m_xIndentFT(m_xBuilder->weld_label(u"numberingwidth"_ustr))
2273 , m_xIndentMF(m_xBuilder->weld_metric_spin_button(u"numberingwidthmf"_ustr, FieldUnit::CM))
2274 , m_xDistNumFT(m_xBuilder->weld_label(u"numdist"_ustr))
2275 , m_xDistNumMF(m_xBuilder->weld_metric_spin_button(u"numdistmf"_ustr, FieldUnit::CM))
2276 , m_xAlignFT(m_xBuilder->weld_label(u"numalign"_ustr))
2277 , m_xAlignLB(m_xBuilder->weld_combo_box(u"numalignlb"_ustr))
2278 , m_xLabelFollowedByFT(m_xBuilder->weld_label(u"numfollowedby"_ustr))
2279 , m_xLabelFollowedByLB(m_xBuilder->weld_combo_box(u"numfollowedbylb"_ustr))
2280 , m_xListtabFT(m_xBuilder->weld_label(u"at"_ustr))
2281 , m_xListtabMF(m_xBuilder->weld_metric_spin_button(u"atmf"_ustr, FieldUnit::CM))
2282 , m_xAlign2FT(m_xBuilder->weld_label(u"num2align"_ustr))
2283 , m_xAlign2LB(m_xBuilder->weld_combo_box(u"num2alignlb"_ustr))
2284 , m_xAlignedAtFT(m_xBuilder->weld_label(u"alignedat"_ustr))
2285 , m_xAlignedAtMF(m_xBuilder->weld_metric_spin_button(u"alignedatmf"_ustr, FieldUnit::CM))
2286 , m_xIndentAtFT(m_xBuilder->weld_label(u"indentat"_ustr))
2287 , m_xIndentAtMF(m_xBuilder->weld_metric_spin_button(u"indentatmf"_ustr, FieldUnit::CM))
2288 , m_xStandardPB(m_xBuilder->weld_button(u"standard"_ustr))
2289 , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, u"preview"_ustr, m_aPreviewWIN))
2290 {
2291 SetExchangeSupport();
2292
2293 // set metric
2294 FieldUnit eFUnit = GetModuleFieldUnit(rSet);
2295
2296 SetFieldUnit( *m_xDistBorderMF, eFUnit );
2297 SetFieldUnit( *m_xIndentMF, eFUnit );
2298 SetFieldUnit( *m_xDistNumMF, eFUnit );
2299
2300 m_xAlignedAtMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
2301 m_xListtabMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
2302 m_xIndentAtMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
2303
2304 m_xRelativeCB->set_active(true);
2305 m_xAlignLB->connect_changed(LINK(this, SvxNumPositionTabPage, EditModifyHdl_Impl));
2306 m_xAlign2LB->connect_changed(LINK(this, SvxNumPositionTabPage, EditModifyHdl_Impl));
2307 for ( sal_Int32 i = 0; i < m_xAlignLB->get_count(); ++i )
2308 {
2309 m_xAlign2LB->append_text(m_xAlignLB->get_text(i));
2310 }
2311
2312 Link<weld::MetricSpinButton&,void> aLk3 = LINK(this, SvxNumPositionTabPage, DistanceHdl_Impl);
2313 m_xDistBorderMF->connect_value_changed(aLk3);
2314 m_xDistNumMF->connect_value_changed(aLk3);
2315 m_xIndentMF->connect_value_changed(aLk3);
2316
2317 m_xLabelFollowedByLB->connect_changed(LINK(this, SvxNumPositionTabPage, LabelFollowedByHdl_Impl));
2318
2319 m_xListtabMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, ListtabPosHdl_Impl));
2320 m_xAlignedAtMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, AlignAtHdl_Impl));
2321 m_xIndentAtMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, IndentAtHdl_Impl));
2322
2323 m_xLevelLB->set_selection_mode(SelectionMode::Multiple);
2324 m_xLevelLB->connect_changed(LINK(this, SvxNumPositionTabPage, LevelHdl_Impl));
2325 m_xRelativeCB->connect_toggled(LINK(this, SvxNumPositionTabPage, RelativeHdl_Impl));
2326 m_xStandardPB->connect_clicked(LINK(this, SvxNumPositionTabPage, StandardHdl_Impl));
2327
2328 m_xRelativeCB->set_active(bLastRelative);
2329 m_aPreviewWIN.SetPositionMode();
2330 eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhichIDFromSlotID(SID_ATTR_NUMBERING_RULE));
2331 }
2332
~SvxNumPositionTabPage()2333 SvxNumPositionTabPage::~SvxNumPositionTabPage()
2334 {
2335 if (m_pLevelHdlEvent)
2336 {
2337 Application::RemoveUserEvent(m_pLevelHdlEvent);
2338 m_pLevelHdlEvent = nullptr;
2339 }
2340 m_xPreviewWIN.reset();
2341 }
2342
2343 /*-------------------------------------------------------*/
2344
InitControls()2345 void SvxNumPositionTabPage::InitControls()
2346 {
2347 bInInintControl = true;
2348 const bool bRelative = !bLabelAlignmentPosAndSpaceModeActive &&
2349 m_xRelativeCB->get_sensitive() && m_xRelativeCB->get_active();
2350 const bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 &&
2351 SAL_MAX_UINT16 != nActNumLvl;
2352
2353 m_xDistBorderMF->set_sensitive( !bLabelAlignmentPosAndSpaceModeActive &&
2354 ( bSingleSelection || bRelative ) );
2355 m_xDistBorderFT->set_sensitive( !bLabelAlignmentPosAndSpaceModeActive &&
2356 ( bSingleSelection || bRelative ) );
2357
2358 bool bSetDistEmpty = false;
2359 bool bSameDistBorderNum = !bLabelAlignmentPosAndSpaceModeActive;
2360 bool bSameDist = !bLabelAlignmentPosAndSpaceModeActive;
2361 bool bSameIndent = !bLabelAlignmentPosAndSpaceModeActive;
2362 bool bSameAdjust = true;
2363
2364 bool bSameLabelFollowedBy = bLabelAlignmentPosAndSpaceModeActive;
2365 bool bSameListtab = bLabelAlignmentPosAndSpaceModeActive;
2366 bool bSameAlignAt = bLabelAlignmentPosAndSpaceModeActive;
2367 bool bSameIndentAt = bLabelAlignmentPosAndSpaceModeActive;
2368
2369 const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM];
2370 sal_uInt16 nMask = 1;
2371 sal_uInt16 nLvl = SAL_MAX_UINT16;
2372 tools::Long nFirstBorderTextRelative = -1;
2373 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
2374 {
2375 aNumFmtArr[i] = &pActNum->GetLevel(i);
2376 if(nActNumLvl & nMask)
2377 {
2378 if(SAL_MAX_UINT16 == nLvl)
2379 nLvl = i;
2380
2381 if( i > nLvl)
2382 {
2383 bSameAdjust &= aNumFmtArr[i]->GetNumAdjust() == aNumFmtArr[nLvl]->GetNumAdjust();
2384 if ( !bLabelAlignmentPosAndSpaceModeActive )
2385 {
2386 if(bRelative)
2387 {
2388 if(nFirstBorderTextRelative == -1)
2389 nFirstBorderTextRelative =
2390 (aNumFmtArr[i]->GetAbsLSpace() + aNumFmtArr[i]->GetFirstLineOffset() -
2391 aNumFmtArr[i - 1]->GetAbsLSpace() + aNumFmtArr[i - 1]->GetFirstLineOffset());
2392 else
2393 bSameDistBorderNum &= nFirstBorderTextRelative ==
2394 (aNumFmtArr[i]->GetAbsLSpace() + aNumFmtArr[i]->GetFirstLineOffset() -
2395 aNumFmtArr[i - 1]->GetAbsLSpace() + aNumFmtArr[i - 1]->GetFirstLineOffset());
2396 }
2397 else
2398 bSameDistBorderNum &=
2399 aNumFmtArr[i]->GetAbsLSpace() - aNumFmtArr[i]->GetFirstLineOffset() ==
2400 aNumFmtArr[i - 1]->GetAbsLSpace() - aNumFmtArr[i - 1]->GetFirstLineOffset();
2401
2402 bSameDist &= aNumFmtArr[i]->GetCharTextDistance() == aNumFmtArr[nLvl]->GetCharTextDistance();
2403 bSameIndent &= aNumFmtArr[i]->GetFirstLineOffset() == aNumFmtArr[nLvl]->GetFirstLineOffset();
2404 }
2405 else
2406 {
2407 bSameLabelFollowedBy &=
2408 aNumFmtArr[i]->GetLabelFollowedBy() == aNumFmtArr[nLvl]->GetLabelFollowedBy();
2409 bSameListtab &=
2410 aNumFmtArr[i]->GetListtabPos() == aNumFmtArr[nLvl]->GetListtabPos();
2411 bSameAlignAt &=
2412 ( ( aNumFmtArr[i]->GetIndentAt() + aNumFmtArr[i]->GetFirstLineIndent() )
2413 == ( aNumFmtArr[nLvl]->GetIndentAt() + aNumFmtArr[nLvl]->GetFirstLineIndent() ) );
2414 bSameIndentAt &=
2415 aNumFmtArr[i]->GetIndentAt() == aNumFmtArr[nLvl]->GetIndentAt();
2416 }
2417 }
2418 }
2419 nMask <<= 1;
2420
2421 }
2422 if (SVX_MAX_NUM <= nLvl)
2423 {
2424 OSL_ENSURE(false, "cannot happen.");
2425 return;
2426 }
2427
2428 if(bSameDistBorderNum)
2429 {
2430 tools::Long nDistBorderNum;
2431 if(bRelative)
2432 {
2433 nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace())+ aNumFmtArr[nLvl]->GetFirstLineOffset();
2434 if(nLvl)
2435 nDistBorderNum -= static_cast<tools::Long>(aNumFmtArr[nLvl - 1]->GetAbsLSpace())+ aNumFmtArr[nLvl - 1]->GetFirstLineOffset();
2436 }
2437 else
2438 {
2439 nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace())+ aNumFmtArr[nLvl]->GetFirstLineOffset();
2440 }
2441 SetMetricValue(*m_xDistBorderMF, nDistBorderNum, eCoreUnit);
2442 }
2443 else
2444 bSetDistEmpty = true;
2445
2446 if(bSameDist)
2447 SetMetricValue(*m_xDistNumMF, aNumFmtArr[nLvl]->GetCharTextDistance(), eCoreUnit);
2448 else
2449 m_xDistNumMF->set_text(u""_ustr);
2450 if(bSameIndent)
2451 SetMetricValue(*m_xIndentMF, - aNumFmtArr[nLvl]->GetFirstLineOffset(), eCoreUnit);
2452 else
2453 m_xIndentMF->set_text(u""_ustr);
2454
2455 if(bSameAdjust)
2456 {
2457 sal_Int32 nPos = 1; // centered
2458 if(aNumFmtArr[nLvl]->GetNumAdjust() == SvxAdjust::Left)
2459 nPos = 0;
2460 else if(aNumFmtArr[nLvl]->GetNumAdjust() == SvxAdjust::Right)
2461 nPos = 2;
2462 m_xAlignLB->set_active(nPos);
2463 m_xAlign2LB->set_active(nPos);
2464 }
2465 else
2466 {
2467 m_xAlignLB->set_active(-1);
2468 m_xAlign2LB->set_active(-1);
2469 }
2470
2471 if ( bSameLabelFollowedBy )
2472 {
2473 sal_Int32 nPos = 0; // LISTTAB
2474 if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::SPACE )
2475 {
2476 nPos = 1;
2477 }
2478 else if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NOTHING )
2479 {
2480 nPos = 2;
2481 }
2482 else if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NEWLINE )
2483 {
2484 nPos = 3;
2485 }
2486 m_xLabelFollowedByLB->set_active(nPos);
2487 }
2488 else
2489 {
2490 m_xLabelFollowedByLB->set_active(-1);
2491 }
2492
2493 if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
2494 {
2495 m_xListtabFT->set_sensitive(true);
2496 m_xListtabMF->set_sensitive(true);
2497 if ( bSameListtab )
2498 {
2499 SetMetricValue(*m_xListtabMF, aNumFmtArr[nLvl]->GetListtabPos(), eCoreUnit);
2500 }
2501 else
2502 {
2503 m_xListtabMF->set_text(u""_ustr);
2504 }
2505 }
2506 else
2507 {
2508 m_xListtabFT->set_sensitive(false);
2509 m_xListtabMF->set_sensitive(false);
2510 m_xListtabMF->set_text(u""_ustr);
2511 }
2512
2513 if ( bSameAlignAt )
2514 {
2515 SetMetricValue(*m_xAlignedAtMF,
2516 aNumFmtArr[nLvl]->GetIndentAt() + aNumFmtArr[nLvl]->GetFirstLineIndent(),
2517 eCoreUnit);
2518 }
2519 else
2520 {
2521 m_xAlignedAtMF->set_text(u""_ustr);
2522 }
2523
2524 if ( bSameIndentAt )
2525 {
2526 SetMetricValue(*m_xIndentAtMF, aNumFmtArr[nLvl]->GetIndentAt(), eCoreUnit);
2527 }
2528 else
2529 {
2530 m_xIndentAtMF->set_text(u""_ustr);
2531 }
2532
2533 if ( bSetDistEmpty )
2534 m_xDistBorderMF->set_text(u""_ustr);
2535
2536 bInInintControl = false;
2537 }
2538
ActivatePage(const SfxItemSet & rSet)2539 void SvxNumPositionTabPage::ActivatePage(const SfxItemSet& rSet)
2540 {
2541 sal_uInt16 nTmpNumLvl = 1;
2542 const SfxItemSet* pExampleSet = GetDialogExampleSet();
2543 if(pExampleSet)
2544 {
2545 if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
2546 bPreset = pPresetItem->GetValue();
2547 if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
2548 nTmpNumLvl = pLevelItem->GetValue();
2549 }
2550 if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
2551 {
2552 pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
2553 }
2554 bModified = (!pActNum->Get( 0 ) || bPreset);
2555 if(*pSaveNum != *pActNum ||
2556 nActNumLvl != nTmpNumLvl )
2557 {
2558 *pActNum = *pSaveNum;
2559 nActNumLvl = nTmpNumLvl;
2560 sal_uInt16 nMask = 1;
2561 m_xLevelLB->unselect_all();
2562 if (nActNumLvl == SAL_MAX_UINT16)
2563 m_xLevelLB->select(pActNum->GetLevelCount());
2564 if (nActNumLvl != SAL_MAX_UINT16)
2565 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
2566 {
2567 if (nActNumLvl & nMask)
2568 m_xLevelLB->select(i);
2569 nMask <<= 1 ;
2570 }
2571 m_xRelativeCB->set_sensitive(nActNumLvl != 1);
2572
2573 InitPosAndSpaceMode();
2574 ShowControlsDependingOnPosAndSpaceMode();
2575
2576 InitControls();
2577 }
2578 m_aPreviewWIN.SetLevel(nActNumLvl);
2579 m_aPreviewWIN.Invalidate();
2580 }
2581
DeactivatePage(SfxItemSet * _pSet)2582 DeactivateRC SvxNumPositionTabPage::DeactivatePage(SfxItemSet *_pSet)
2583 {
2584 if(_pSet)
2585 {
2586 if (m_xDistBorderMF->get_sensitive())
2587 DistanceHdl_Impl(*m_xDistBorderMF);
2588 DistanceHdl_Impl(*m_xIndentMF);
2589 FillItemSet(_pSet);
2590 }
2591 return DeactivateRC::LeavePage;
2592 }
2593
FillItemSet(SfxItemSet * rSet)2594 bool SvxNumPositionTabPage::FillItemSet( SfxItemSet* rSet )
2595 {
2596 rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl));
2597
2598 if(bModified && pActNum)
2599 {
2600 *pSaveNum = *pActNum;
2601 rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
2602 rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false));
2603 }
2604 return bModified;
2605 }
2606
Reset(const SfxItemSet * rSet)2607 void SvxNumPositionTabPage::Reset( const SfxItemSet* rSet )
2608 {
2609 // in Draw the item exists as WhichId, in Writer only as SlotId
2610 const SvxNumBulletItem* pItem =
2611 rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
2612 if(!pItem)
2613 {
2614 nNumItemId = rSet->GetPool()->GetWhichIDFromSlotID(SID_ATTR_NUMBERING_RULE);
2615 pItem = rSet->GetItemIfSet(nNumItemId, false);
2616
2617 if( !pItem )
2618 {
2619 pItem = & rSet->Get( nNumItemId );
2620 }
2621 }
2622 DBG_ASSERT(pItem, "no item found!");
2623 pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
2624
2625 // insert levels
2626 if (!m_xLevelLB->count_selected_rows())
2627 {
2628 for(sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++)
2629 m_xLevelLB->append_text(OUString::number(i));
2630 if(pSaveNum->GetLevelCount() > 1)
2631 {
2632 OUString sEntry = "1 - " + OUString::number( pSaveNum->GetLevelCount() );
2633 m_xLevelLB->append_text(sEntry);
2634 m_xLevelLB->select_text(sEntry);
2635 }
2636 else
2637 m_xLevelLB->select(0);
2638 }
2639 else
2640 m_xLevelLB->select(m_xLevelLB->count_selected_rows() - 1);
2641 sal_uInt16 nMask = 1;
2642 m_xLevelLB->unselect_all();
2643 if (nActNumLvl == SAL_MAX_UINT16)
2644 {
2645 m_xLevelLB->select(pSaveNum->GetLevelCount());
2646 }
2647 else
2648 {
2649 for(sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++)
2650 {
2651 if(nActNumLvl & nMask)
2652 m_xLevelLB->select(i);
2653 nMask <<= 1;
2654 }
2655 }
2656
2657 if(!pActNum)
2658 pActNum.reset( new SvxNumRule(*pSaveNum) );
2659 else if(*pSaveNum != *pActNum)
2660 *pActNum = *pSaveNum;
2661 m_aPreviewWIN.SetNumRule(pActNum.get());
2662
2663 InitPosAndSpaceMode();
2664 ShowControlsDependingOnPosAndSpaceMode();
2665
2666 InitControls();
2667 bModified = false;
2668 }
2669
InitPosAndSpaceMode()2670 void SvxNumPositionTabPage::InitPosAndSpaceMode()
2671 {
2672 if ( pActNum == nullptr )
2673 {
2674 SAL_WARN( "cui.tabpages",
2675 "<SvxNumPositionTabPage::InitPosAndSpaceMode()> - misusage of method -> <pAktNum> has to be already set!" );
2676 return;
2677 }
2678
2679 SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode =
2680 SvxNumberFormat::LABEL_ALIGNMENT;
2681 sal_uInt16 nMask = 1;
2682 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
2683 {
2684 if(nActNumLvl & nMask)
2685 {
2686 SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
2687 ePosAndSpaceMode = aNumFmt.GetPositionAndSpaceMode();
2688 if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
2689 {
2690 break;
2691 }
2692 }
2693 nMask <<= 1;
2694 }
2695
2696 bLabelAlignmentPosAndSpaceModeActive =
2697 ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT;
2698 }
2699
ShowControlsDependingOnPosAndSpaceMode()2700 void SvxNumPositionTabPage::ShowControlsDependingOnPosAndSpaceMode()
2701 {
2702 m_xDistBorderFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
2703 m_xDistBorderMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
2704 m_xRelativeCB->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
2705 m_xIndentFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
2706 m_xIndentMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
2707 m_xDistNumFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive &&
2708 pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS) );
2709 m_xDistNumMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive &&
2710 pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS));
2711 m_xAlignFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
2712 m_xAlignLB->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
2713
2714 m_xLabelFollowedByFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
2715 m_xLabelFollowedByLB->set_visible( bLabelAlignmentPosAndSpaceModeActive );
2716 m_xListtabFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
2717 m_xListtabMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
2718 m_xAlign2FT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
2719 m_xAlign2LB->set_visible( bLabelAlignmentPosAndSpaceModeActive );
2720 m_xAlignedAtFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
2721 m_xAlignedAtMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
2722 m_xIndentAtFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
2723 m_xIndentAtMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
2724 }
2725
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rAttrSet)2726 std::unique_ptr<SfxTabPage> SvxNumPositionTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
2727 const SfxItemSet* rAttrSet)
2728 {
2729 return std::make_unique<SvxNumPositionTabPage>(pPage, pController, *rAttrSet);
2730 }
2731
SetMetric(FieldUnit eMetric)2732 void SvxNumPositionTabPage::SetMetric(FieldUnit eMetric)
2733 {
2734 if (eMetric == FieldUnit::MM)
2735 {
2736 m_xDistBorderMF->set_digits(1);
2737 m_xDistNumMF->set_digits(1);
2738 m_xIndentMF->set_digits(1);
2739 m_xListtabMF->set_digits(1);
2740 m_xAlignedAtMF->set_digits(1);
2741 m_xIndentAtMF->set_digits(1);
2742 }
2743 m_xDistBorderMF->set_unit(eMetric);
2744 m_xDistNumMF->set_unit(eMetric);
2745 m_xIndentMF->set_unit(eMetric);
2746 m_xListtabMF->set_unit(eMetric);
2747 m_xAlignedAtMF->set_unit(eMetric);
2748 m_xIndentAtMF->set_unit(eMetric);
2749 }
2750
IMPL_LINK_NOARG(SvxNumPositionTabPage,EditModifyHdl_Impl,weld::ComboBox &,void)2751 IMPL_LINK_NOARG(SvxNumPositionTabPage, EditModifyHdl_Impl, weld::ComboBox&, void)
2752 {
2753 sal_uInt16 nMask = 1;
2754 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
2755 {
2756 if(nActNumLvl & nMask)
2757 {
2758 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
2759
2760 const sal_Int32 nPos = m_xAlignLB->get_visible()
2761 ? m_xAlignLB->get_active()
2762 : m_xAlign2LB->get_active();
2763 SvxAdjust eAdjust = SvxAdjust::Center;
2764 if(nPos == 0)
2765 eAdjust = SvxAdjust::Left;
2766 else if(nPos == 2)
2767 eAdjust = SvxAdjust::Right;
2768 aNumFmt.SetNumAdjust( eAdjust );
2769 pActNum->SetLevel(i, aNumFmt);
2770 }
2771 nMask <<= 1;
2772 }
2773 SetModified();
2774 }
2775
IMPL_LINK_NOARG(SvxNumPositionTabPage,LevelHdl_Impl,weld::TreeView &,void)2776 IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl_Impl, weld::TreeView&, void)
2777 {
2778 if (m_pLevelHdlEvent)
2779 return;
2780 // tdf#127120 multiselection may be implemented by deselect follow by select so
2781 // fire off the handler to happen on next event loop and only process the
2782 // final state
2783 m_pLevelHdlEvent = Application::PostUserEvent(LINK(this, SvxNumPositionTabPage, LevelHdl));
2784 }
2785
IMPL_LINK_NOARG(SvxNumPositionTabPage,LevelHdl,void *,void)2786 IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl, void*, void)
2787 {
2788 m_pLevelHdlEvent = nullptr;
2789
2790 sal_uInt16 nSaveNumLvl = nActNumLvl;
2791 nActNumLvl = 0;
2792 std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows();
2793 if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() &&
2794 (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
2795 {
2796 nActNumLvl = 0xFFFF;
2797 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
2798 m_xLevelLB->unselect(i);
2799 }
2800 else if (!aSelectedRows.empty())
2801 {
2802 sal_uInt16 nMask = 1;
2803 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
2804 {
2805 if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end())
2806 nActNumLvl |= nMask;
2807 nMask <<= 1;
2808 }
2809 m_xLevelLB->unselect(pActNum->GetLevelCount());
2810 }
2811 else
2812 {
2813 nActNumLvl = nSaveNumLvl;
2814 sal_uInt16 nMask = 1;
2815 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
2816 {
2817 if(nActNumLvl & nMask)
2818 {
2819 m_xLevelLB->select(i);
2820 break;
2821 }
2822 nMask <<=1;
2823 }
2824 }
2825 m_xRelativeCB->set_sensitive(nActNumLvl != 1);
2826 SetModified();
2827 InitPosAndSpaceMode();
2828 ShowControlsDependingOnPosAndSpaceMode();
2829 InitControls();
2830 }
2831
IMPL_LINK(SvxNumPositionTabPage,DistanceHdl_Impl,weld::MetricSpinButton &,rFld,void)2832 IMPL_LINK(SvxNumPositionTabPage, DistanceHdl_Impl, weld::MetricSpinButton&, rFld, void)
2833 {
2834 if(bInInintControl)
2835 return;
2836 tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
2837 sal_uInt16 nMask = 1;
2838 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
2839 {
2840 if(nActNumLvl & nMask)
2841 {
2842 SvxNumberFormat aNumFmt( pActNum->GetLevel( i ) );
2843 if (&rFld == m_xDistBorderMF.get())
2844 {
2845
2846 if (m_xRelativeCB->get_active())
2847 {
2848 if(0 == i)
2849 {
2850 auto const nTmp = aNumFmt.GetFirstLineOffset();
2851 aNumFmt.SetAbsLSpace( nValue - nTmp);
2852 }
2853 else
2854 {
2855 tools::Long nTmp = pActNum->GetLevel( i - 1 ).GetAbsLSpace() +
2856 pActNum->GetLevel( i - 1 ).GetFirstLineOffset() -
2857 pActNum->GetLevel( i ).GetFirstLineOffset();
2858
2859 aNumFmt.SetAbsLSpace( nValue + nTmp);
2860 }
2861 }
2862 else
2863 {
2864 aNumFmt.SetAbsLSpace( nValue - aNumFmt.GetFirstLineOffset());
2865 }
2866 }
2867 else if (&rFld == m_xDistNumMF.get())
2868 {
2869 aNumFmt.SetCharTextDistance( static_cast<short>(nValue) );
2870 }
2871 else if (&rFld == m_xIndentMF.get())
2872 {
2873 // together with the FirstLineOffset the AbsLSpace must be changed, too
2874 tools::Long nDiff = nValue + aNumFmt.GetFirstLineOffset();
2875 auto const nAbsLSpace = aNumFmt.GetAbsLSpace();
2876 aNumFmt.SetAbsLSpace(nAbsLSpace + nDiff);
2877 aNumFmt.SetFirstLineOffset( -nValue );
2878 }
2879
2880 pActNum->SetLevel( i, aNumFmt );
2881 }
2882 nMask <<= 1;
2883 }
2884
2885 SetModified();
2886 if (!m_xDistBorderMF->get_sensitive())
2887 {
2888 m_xDistBorderMF->set_text(u""_ustr);
2889 }
2890 }
2891
IMPL_LINK(SvxNumPositionTabPage,RelativeHdl_Impl,weld::Toggleable &,rBox,void)2892 IMPL_LINK(SvxNumPositionTabPage, RelativeHdl_Impl, weld::Toggleable&, rBox, void)
2893 {
2894 bool bOn = rBox.get_active();
2895 bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 && SAL_MAX_UINT16 != nActNumLvl;
2896 bool bSetValue = false;
2897 tools::Long nValue = 0;
2898 if(bOn || bSingleSelection)
2899 {
2900 sal_uInt16 nMask = 1;
2901 bool bFirst = true;
2902 bSetValue = true;
2903 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
2904 {
2905 if(nActNumLvl & nMask)
2906 {
2907 const SvxNumberFormat &rNumFmt = pActNum->GetLevel(i);
2908 if(bFirst)
2909 {
2910 nValue = rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset();
2911 if(bOn && i)
2912 nValue -= (pActNum->GetLevel(i - 1).GetAbsLSpace() + pActNum->GetLevel(i - 1).GetFirstLineOffset());
2913 }
2914 else
2915 bSetValue = nValue ==
2916 (rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset()) -
2917 (pActNum->GetLevel(i - 1).GetAbsLSpace() + pActNum->GetLevel(i - 1).GetFirstLineOffset());
2918 bFirst = false;
2919 }
2920 nMask <<= 1;
2921 }
2922
2923 }
2924 if(bSetValue)
2925 SetMetricValue(*m_xDistBorderMF, nValue, eCoreUnit);
2926 else
2927 m_xDistBorderMF->set_text(u""_ustr);
2928 m_xDistBorderMF->set_sensitive(bOn || bSingleSelection);
2929 m_xDistBorderFT->set_sensitive(bOn || bSingleSelection);
2930 bLastRelative = bOn;
2931 }
2932
IMPL_LINK_NOARG(SvxNumPositionTabPage,LabelFollowedByHdl_Impl,weld::ComboBox &,void)2933 IMPL_LINK_NOARG(SvxNumPositionTabPage, LabelFollowedByHdl_Impl, weld::ComboBox&, void)
2934 {
2935 // determine value to be set at the chosen list levels
2936 SvxNumberFormat::LabelFollowedBy eLabelFollowedBy = SvxNumberFormat::LISTTAB;
2937 {
2938 const auto nPos = m_xLabelFollowedByLB->get_active();
2939 if ( nPos == 1 )
2940 {
2941 eLabelFollowedBy = SvxNumberFormat::SPACE;
2942 }
2943 else if ( nPos == 2 )
2944 {
2945 eLabelFollowedBy = SvxNumberFormat::NOTHING;
2946 }
2947 else if ( nPos == 3 )
2948 {
2949 eLabelFollowedBy = SvxNumberFormat::NEWLINE;
2950 }
2951 }
2952
2953 // set value at the chosen list levels
2954 bool bSameListtabPos = true;
2955 sal_uInt16 nFirstLvl = SAL_MAX_UINT16;
2956 sal_uInt16 nMask = 1;
2957 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
2958 {
2959 if ( nActNumLvl & nMask )
2960 {
2961 SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
2962 aNumFmt.SetLabelFollowedBy( eLabelFollowedBy );
2963 pActNum->SetLevel( i, aNumFmt );
2964
2965 if ( nFirstLvl == SAL_MAX_UINT16 )
2966 {
2967 nFirstLvl = i;
2968 }
2969 else
2970 {
2971 bSameListtabPos &= aNumFmt.GetListtabPos() ==
2972 pActNum->GetLevel( nFirstLvl ).GetListtabPos();
2973 }
2974 }
2975 nMask <<= 1;
2976 }
2977
2978 // enable/disable metric field for list tab stop position depending on
2979 // selected item following the list label.
2980 m_xListtabFT->set_sensitive( eLabelFollowedBy == SvxNumberFormat::LISTTAB );
2981 m_xListtabMF->set_sensitive( eLabelFollowedBy == SvxNumberFormat::LISTTAB );
2982 if ( bSameListtabPos && eLabelFollowedBy == SvxNumberFormat::LISTTAB )
2983 {
2984 SetMetricValue(*m_xListtabMF, pActNum->GetLevel( nFirstLvl ).GetListtabPos(), eCoreUnit);
2985 }
2986 else
2987 {
2988 m_xListtabMF->set_text(OUString());
2989 }
2990
2991 SetModified();
2992 }
2993
IMPL_LINK(SvxNumPositionTabPage,ListtabPosHdl_Impl,weld::MetricSpinButton &,rFld,void)2994 IMPL_LINK(SvxNumPositionTabPage, ListtabPosHdl_Impl, weld::MetricSpinButton&, rFld, void)
2995 {
2996 // determine value to be set at the chosen list levels
2997 const tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
2998
2999 // set value at the chosen list levels
3000 sal_uInt16 nMask = 1;
3001 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
3002 {
3003 if ( nActNumLvl & nMask )
3004 {
3005 SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
3006 aNumFmt.SetListtabPos( nValue );
3007 pActNum->SetLevel( i, aNumFmt );
3008 }
3009 nMask <<= 1;
3010 }
3011
3012 SetModified();
3013 }
3014
IMPL_LINK(SvxNumPositionTabPage,AlignAtHdl_Impl,weld::MetricSpinButton &,rFld,void)3015 IMPL_LINK(SvxNumPositionTabPage, AlignAtHdl_Impl, weld::MetricSpinButton&, rFld, void)
3016 {
3017 // determine value to be set at the chosen list levels
3018 const tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
3019
3020 // set value at the chosen list levels
3021 sal_uInt16 nMask = 1;
3022 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
3023 {
3024 if ( nActNumLvl & nMask )
3025 {
3026 SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
3027 const tools::Long nFirstLineIndent = nValue - aNumFmt.GetIndentAt();
3028 aNumFmt.SetFirstLineIndent( nFirstLineIndent );
3029 pActNum->SetLevel( i, aNumFmt );
3030 }
3031 nMask <<= 1;
3032 }
3033
3034 SetModified();
3035 }
3036
IMPL_LINK(SvxNumPositionTabPage,IndentAtHdl_Impl,weld::MetricSpinButton &,rFld,void)3037 IMPL_LINK(SvxNumPositionTabPage, IndentAtHdl_Impl, weld::MetricSpinButton&, rFld, void)
3038 {
3039 // determine value to be set at the chosen list levels
3040 const tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
3041
3042 // set value at the chosen list levels
3043 sal_uInt16 nMask = 1;
3044 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
3045 {
3046 if ( nActNumLvl & nMask )
3047 {
3048 SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
3049 const tools::Long nAlignedAt = aNumFmt.GetIndentAt() +
3050 aNumFmt.GetFirstLineIndent();
3051 aNumFmt.SetIndentAt( nValue );
3052 const tools::Long nNewFirstLineIndent = nAlignedAt - nValue;
3053 aNumFmt.SetFirstLineIndent( nNewFirstLineIndent );
3054 pActNum->SetLevel( i, aNumFmt );
3055 }
3056 nMask <<= 1;
3057 }
3058
3059 SetModified();
3060 }
3061
IMPL_LINK_NOARG(SvxNumPositionTabPage,StandardHdl_Impl,weld::Button &,void)3062 IMPL_LINK_NOARG(SvxNumPositionTabPage, StandardHdl_Impl, weld::Button&, void)
3063 {
3064 sal_uInt16 nMask = 1;
3065 SvxNumRule aTmpNumRule( pActNum->GetFeatureFlags(),
3066 pActNum->GetLevelCount(),
3067 pActNum->IsContinuousNumbering(),
3068 SvxNumRuleType::NUMBERING,
3069 pActNum->GetLevel( 0 ).GetPositionAndSpaceMode() );
3070 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
3071 {
3072 if(nActNumLvl & nMask)
3073 {
3074 SvxNumberFormat aNumFmt( pActNum->GetLevel( i ) );
3075 const SvxNumberFormat& aTempFmt(aTmpNumRule.GetLevel( i ));
3076 aNumFmt.SetPositionAndSpaceMode( aTempFmt.GetPositionAndSpaceMode() );
3077 if ( aTempFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
3078 {
3079 aNumFmt.SetAbsLSpace( aTempFmt.GetAbsLSpace() );
3080 aNumFmt.SetCharTextDistance( aTempFmt.GetCharTextDistance() );
3081 aNumFmt.SetFirstLineOffset( aTempFmt.GetFirstLineOffset() );
3082 }
3083 else if ( aTempFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
3084 {
3085 aNumFmt.SetNumAdjust( aTempFmt.GetNumAdjust() );
3086 aNumFmt.SetLabelFollowedBy( aTempFmt.GetLabelFollowedBy() );
3087 aNumFmt.SetListtabPos( aTempFmt.GetListtabPos() );
3088 aNumFmt.SetFirstLineIndent( aTempFmt.GetFirstLineIndent() );
3089 aNumFmt.SetIndentAt( aTempFmt.GetIndentAt() );
3090 }
3091
3092 pActNum->SetLevel( i, aNumFmt );
3093 }
3094 nMask <<= 1;
3095 }
3096
3097 InitControls();
3098 SetModified();
3099 }
3100
SetModified()3101 void SvxNumPositionTabPage::SetModified()
3102 {
3103 bModified = true;
3104 m_aPreviewWIN.SetLevel(nActNumLvl);
3105 m_aPreviewWIN.Invalidate();
3106 }
3107
SetModified(bool bRepaint)3108 void SvxNumOptionsTabPage::SetModified(bool bRepaint)
3109 {
3110 bModified = true;
3111 if (bRepaint)
3112 {
3113 m_aPreviewWIN.SetLevel(nActNumLvl);
3114 m_aPreviewWIN.Invalidate();
3115 }
3116 }
3117
PageCreated(const SfxAllItemSet & aSet)3118 void SvxNumOptionsTabPage::PageCreated(const SfxAllItemSet& aSet)
3119 {
3120 const SfxStringListItem* pListItem = aSet.GetItem<SfxStringListItem>(SID_CHAR_FMT_LIST_BOX, false);
3121 const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
3122 const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
3123 const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false);
3124
3125 if (pNumCharFmt &&pBulletCharFmt)
3126 SetCharFmts( pNumCharFmt->GetValue(),pBulletCharFmt->GetValue());
3127
3128 if (pListItem)
3129 {
3130 const std::vector<OUString> &aList = pListItem->GetList();
3131 for (const auto& rItem : aList)
3132 m_xCharFmtLB->append_text(rItem);
3133 }
3134 if (pMetricItem)
3135 SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue()));
3136 }
3137
PageCreated(const SfxAllItemSet & aSet)3138 void SvxNumPositionTabPage::PageCreated(const SfxAllItemSet& aSet)
3139 {
3140 const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false);
3141
3142 if (pMetricItem)
3143 SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue()));
3144 }
3145
3146 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
3147