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 <tools/mapunit.hxx>
21 #include <tools/urlobj.hxx>
22 #include <editeng/numitem.hxx>
23 #include <svl/eitem.hxx>
24 #include <svl/itempool.hxx>
25 #include <svx/colorbox.hxx>
26 #include <svx/strarray.hxx>
27 #include <svx/gallery.hxx>
28 #include <editeng/brushitem.hxx>
29 #include <svl/intitem.hxx>
30 #include <vcl/graph.hxx>
31 #include <svtools/unitconv.hxx>
32 #include <svx/svxids.hrc>
33
34 #include <algorithm>
35 #include <memory>
36 #include <vector>
37 #include <sfx2/opengrf.hxx>
38
39 #include <strings.hrc>
40 #include <svl/stritem.hxx>
41 #include <sal/log.hxx>
42 #include <vcl/virdev.hxx>
43 #include <svx/SvxNumOptionsTabPageHelper.hxx>
44 #include <View.hxx>
45 #include <drawdoc.hxx>
46 #include <cui/cuicharmap.hxx>
47 #include <BulletAndPositionDlg.hxx>
48 #include <sdresid.hxx>
49 #include <DrawViewShell.hxx>
50
51 #define SHOW_NUMBERING 0
52 #define SHOW_BULLET 1
53 #define SHOW_BITMAP 2
54
55 #define MAX_BMP_WIDTH 16
56 #define MAX_BMP_HEIGHT 16
57
58 static bool bLastRelative = false;
59
lcl_GetDefaultBulletFont()60 static const vcl::Font& lcl_GetDefaultBulletFont()
61 {
62 static vcl::Font aDefBulletFont = [&]() {
63 vcl::Font tmp("OpenSymbol", "", Size(0, 14));
64 tmp.SetCharSet(RTL_TEXTENCODING_SYMBOL);
65 tmp.SetFamily(FAMILY_DONTKNOW);
66 tmp.SetPitch(PITCH_DONTKNOW);
67 tmp.SetWeight(WEIGHT_DONTKNOW);
68 tmp.SetTransparent(true);
69 return tmp;
70 }();
71 return aDefBulletFont;
72 }
73
74 class SdDrawDocument;
75
SvxBulletAndPositionDlg(weld::Window * pWindow,const SfxItemSet & rSet,const::sd::View * pView)76 SvxBulletAndPositionDlg::SvxBulletAndPositionDlg(weld::Window* pWindow, const SfxItemSet& rSet,
77 const ::sd::View* pView)
78 : GenericDialogController(pWindow, "cui/ui/bulletandposition.ui", "BulletAndPosition")
79 , rFirstStateSet(rSet)
80 , bLastWidthModified(false)
81 , bModified(false)
82 , bInInitControl(false)
83 , bLabelAlignmentPosAndSpaceModeActive(false)
84 , bApplyToMaster(false)
85 , nBullet(0xff)
86 , nActNumLvl(1)
87 , p_Window(pWindow)
88 , nNumItemId(SID_ATTR_NUMBERING_RULE)
89 , m_xGrid(m_xBuilder->weld_widget("grid2"))
90 , m_xLevelLB(m_xBuilder->weld_tree_view("levellb"))
91 , m_xFmtLB(m_xBuilder->weld_combo_box("numfmtlb"))
92 , m_xPrefixFT(m_xBuilder->weld_label("prefixft"))
93 , m_xPrefixED(m_xBuilder->weld_entry("prefix"))
94 , m_xSuffixFT(m_xBuilder->weld_label("suffixft"))
95 , m_xSuffixED(m_xBuilder->weld_entry("suffix"))
96 , m_xBeforeAfter(m_xBuilder->weld_frame("beforeafter"))
97 , m_xBulColorFT(m_xBuilder->weld_label("colorft"))
98 , m_xBulColLB(new ColorListBox(m_xBuilder->weld_menu_button("color"),
99 [this] { return m_xDialog.get(); }))
100 , m_xBulRelSizeFT(m_xBuilder->weld_label("relsizeft"))
101 , m_xBulRelSizeMF(m_xBuilder->weld_metric_spin_button("relsize", FieldUnit::PERCENT))
102 , m_xStartFT(m_xBuilder->weld_label("startatft"))
103 , m_xStartED(m_xBuilder->weld_spin_button("startat"))
104 , m_xBulletFT(m_xBuilder->weld_label("bulletft"))
105 , m_xBulletPB(m_xBuilder->weld_button("bullet"))
106 , m_xBitmapMB(m_xBuilder->weld_menu_button("bitmap"))
107 , m_xWidthFT(m_xBuilder->weld_label("widthft"))
108 , m_xWidthMF(m_xBuilder->weld_metric_spin_button("widthmf", FieldUnit::CM))
109 , m_xHeightFT(m_xBuilder->weld_label("heightft"))
110 , m_xHeightMF(m_xBuilder->weld_metric_spin_button("heightmf", FieldUnit::CM))
111 , m_xRatioCB(m_xBuilder->weld_check_button("keepratio"))
112 , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWIN))
113 , m_xDistBorderFT(m_xBuilder->weld_label("indent"))
114 , m_xDistBorderMF(m_xBuilder->weld_metric_spin_button("indentmf", FieldUnit::CM))
115 , m_xRelativeCB(m_xBuilder->weld_check_button("relative"))
116 , m_xIndentFT(m_xBuilder->weld_label("numberingwidth"))
117 , m_xIndentMF(m_xBuilder->weld_metric_spin_button("numberingwidthmf", FieldUnit::CM))
118 , m_xLeftTB(m_xBuilder->weld_toggle_button("left"))
119 , m_xCenterTB(m_xBuilder->weld_toggle_button("center"))
120 , m_xRightTB(m_xBuilder->weld_toggle_button("right"))
121 , m_xSlideRB(m_xBuilder->weld_radio_button("sliderb"))
122 , m_xSelectionRB(m_xBuilder->weld_radio_button("selectionrb"))
123 , m_xApplyToMaster(m_xBuilder->weld_toggle_button("applytomaster"))
124 , m_xReset(m_xBuilder->weld_button("reset"))
125 {
126 m_xBulColLB->SetSlotId(SID_ATTR_CHAR_COLOR);
127 m_xBulRelSizeMF->set_min(SVX_NUM_REL_SIZE_MIN, FieldUnit::PERCENT);
128 m_xBulRelSizeMF->set_increments(5, 50, FieldUnit::PERCENT);
129 aActBulletFont = lcl_GetDefaultBulletFont();
130
131 m_xBulletPB->connect_clicked(LINK(this, SvxBulletAndPositionDlg, BulletHdl_Impl));
132 m_xFmtLB->connect_changed(LINK(this, SvxBulletAndPositionDlg, NumberTypeSelectHdl_Impl));
133 m_xBitmapMB->connect_selected(LINK(this, SvxBulletAndPositionDlg, GraphicHdl_Impl));
134 m_xBitmapMB->connect_toggled(LINK(this, SvxBulletAndPositionDlg, PopupActivateHdl_Impl));
135 m_xLevelLB->set_selection_mode(SelectionMode::Multiple);
136 m_xLevelLB->connect_changed(LINK(this, SvxBulletAndPositionDlg, LevelHdl_Impl));
137 m_xWidthMF->connect_value_changed(LINK(this, SvxBulletAndPositionDlg, SizeHdl_Impl));
138 m_xHeightMF->connect_value_changed(LINK(this, SvxBulletAndPositionDlg, SizeHdl_Impl));
139 m_xRatioCB->connect_toggled(LINK(this, SvxBulletAndPositionDlg, RatioHdl_Impl));
140 m_xStartED->connect_changed(LINK(this, SvxBulletAndPositionDlg, EditModifyHdl_Impl));
141 m_xPrefixED->connect_changed(LINK(this, SvxBulletAndPositionDlg, EditModifyHdl_Impl));
142 m_xSuffixED->connect_changed(LINK(this, SvxBulletAndPositionDlg, EditModifyHdl_Impl));
143 m_xBulRelSizeMF->connect_value_changed(LINK(this, SvxBulletAndPositionDlg, BulRelSizeHdl_Impl));
144 m_xBulColLB->SetSelectHdl(LINK(this, SvxBulletAndPositionDlg, BulColorHdl_Impl));
145 m_xLeftTB->connect_toggled(LINK(this, SvxBulletAndPositionDlg, SelectLeftAlignmentHdl_Impl));
146 m_xCenterTB->connect_toggled(
147 LINK(this, SvxBulletAndPositionDlg, SelectCenterAlignmentHdl_Impl));
148 m_xRightTB->connect_toggled(LINK(this, SvxBulletAndPositionDlg, SelectRightAlignmentHdl_Impl));
149 m_xApplyToMaster->connect_toggled(LINK(this, SvxBulletAndPositionDlg, ApplyToMasterHdl_Impl));
150 m_xReset->connect_clicked(LINK(this, SvxBulletAndPositionDlg, ResetHdl_Impl));
151
152 aInvalidateTimer.SetInvokeHandler(
153 LINK(this, SvxBulletAndPositionDlg, PreviewInvalidateHdl_Impl));
154 aInvalidateTimer.SetTimeout(50);
155
156 eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
157
158 // Fill ListBox with predefined / translated numbering types.
159 sal_uInt32 nCount = SvxNumberingTypeTable::Count();
160 for (sal_uInt32 i = 0; i < nCount; ++i)
161 {
162 m_xFmtLB->append(OUString::number(SvxNumberingTypeTable::GetValue(i)),
163 SvxNumberingTypeTable::GetString(i));
164 }
165
166 // Get advanced numbering types from the component.
167 // Watch out for the ugly
168 // 136 == 0x88 == SVX_NUM_BITMAP|0x80 == SVX_NUM_BITMAP|LINK_TOKEN
169 // to not remove that.
170 SvxNumOptionsTabPageHelper::GetI18nNumbering(*m_xFmtLB, (SVX_NUM_BITMAP | LINK_TOKEN));
171
172 m_xFmtLB->set_active(0);
173 m_xRelativeCB->set_active(true);
174
175 Link<weld::MetricSpinButton&, void> aLk3
176 = LINK(this, SvxBulletAndPositionDlg, DistanceHdl_Impl);
177 m_xDistBorderMF->connect_value_changed(aLk3);
178 m_xIndentMF->connect_value_changed(aLk3);
179
180 m_xRelativeCB->connect_toggled(LINK(this, SvxBulletAndPositionDlg, RelativeHdl_Impl));
181 m_xRelativeCB->set_active(bLastRelative);
182
183 Size aSize(m_xGrid->get_preferred_size());
184 m_xGrid->set_size_request(aSize.Width(), -1);
185
186 // PageCreated
187 FieldUnit eMetric = pView->GetDoc().GetUIUnit();
188 SfxAllItemSet aSet(*(rSet.GetPool()));
189 aSet.Put(SfxUInt16Item(SID_METRIC_ITEM, static_cast<sal_uInt16>(eMetric)));
190
191 const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
192 const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false);
193
194 if (pNumCharFmt)
195 SetCharFmt(pNumCharFmt->GetValue());
196
197 if (pMetricItem)
198 SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue()));
199
200 // tdf#130526: Hide "Apply To Master"-button in Draw and rename "Slide" to "Page"
201 DocumentType aDocumentType = pView->GetDoc().GetDocumentType();
202 if (aDocumentType == DocumentType::Draw)
203 {
204 m_xApplyToMaster->hide();
205 m_xSlideRB->set_label(SdResId(STR_PAGE_NAME));
206 }
207 // tdf#137406: Crash when clicking "Apply to Master" in Slide Master mode on Bullets and Numbering dialog
208 EditMode aEditmode = static_cast<::sd::DrawViewShell*>(pView->GetViewShell())->GetEditMode();
209 if (aDocumentType == DocumentType::Impress && aEditmode == EditMode::MasterPage)
210 m_xApplyToMaster->hide();
211
212 // End PageCreated
213
214 Reset(&rSet);
215
216 // ActivatePage part
217
218 const SfxPoolItem* pItem;
219 const SfxItemSet* pExampleSet = &rSet;
220 sal_uInt16 nTmpNumLvl = 1;
221 bool bPreset = false;
222 if (pExampleSet)
223 {
224 if (SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_NUM_PRESET, false, &pItem))
225 bPreset = static_cast<const SfxBoolItem*>(pItem)->GetValue();
226 if (SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_CUR_NUM_LEVEL, false, &pItem))
227 nTmpNumLvl = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
228 }
229 if (SfxItemState::SET == rSet.GetItemState(nNumItemId, false, &pItem))
230 {
231 pSaveNum.reset(new SvxNumRule(static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()));
232 }
233
234 bModified = (!pActNum->Get(0) || bPreset);
235 if (*pActNum != *pSaveNum || nActNumLvl != nTmpNumLvl)
236 {
237 nActNumLvl = nTmpNumLvl;
238 sal_uInt16 nMask = 1;
239 if (nActNumLvl == SAL_MAX_UINT16)
240 m_xLevelLB->select(pActNum->GetLevelCount());
241 if (nActNumLvl != SAL_MAX_UINT16)
242 {
243 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
244 {
245 if (nActNumLvl & nMask)
246 m_xLevelLB->select(i);
247 nMask <<= 1;
248 }
249 }
250 *pActNum = *pSaveNum;
251
252 m_xRelativeCB->set_sensitive(nActNumLvl != 1);
253
254 InitPosAndSpaceMode();
255 InitControls();
256 }
257
258 m_aPreviewWIN.SetLevel(nActNumLvl);
259 m_aPreviewWIN.Invalidate();
260
261 // End of the ActivatePage part
262 }
263
~SvxBulletAndPositionDlg()264 SvxBulletAndPositionDlg::~SvxBulletAndPositionDlg() {}
265
SetMetric(FieldUnit eMetric)266 void SvxBulletAndPositionDlg::SetMetric(FieldUnit eMetric)
267 {
268 if (eMetric == FieldUnit::MM)
269 {
270 m_xWidthMF->set_digits(1);
271 m_xHeightMF->set_digits(1);
272 m_xDistBorderMF->set_digits(1);
273 m_xIndentMF->set_digits(1);
274 }
275 m_xWidthMF->set_unit(eMetric);
276 m_xHeightMF->set_unit(eMetric);
277 m_xDistBorderMF->set_unit(eMetric);
278 m_xIndentMF->set_unit(eMetric);
279 }
280
GetOutputItemSet(SfxItemSet * pSet)281 SfxItemSet* SvxBulletAndPositionDlg::GetOutputItemSet(SfxItemSet* pSet)
282 {
283 pSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl));
284 if (bModified && pActNum)
285 {
286 *pSaveNum = *pActNum;
287 pSet->Put(SvxNumBulletItem(*pSaveNum, nNumItemId));
288 pSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false));
289 }
290 return pSet;
291 };
292
IsApplyToMaster() const293 bool SvxBulletAndPositionDlg::IsApplyToMaster() const { return bApplyToMaster; }
IsSlideScope() const294 bool SvxBulletAndPositionDlg::IsSlideScope() const { return m_xSlideRB->get_active(); }
295
Reset(const SfxItemSet * rSet)296 void SvxBulletAndPositionDlg::Reset(const SfxItemSet* rSet)
297 {
298 const SfxPoolItem* pItem;
299 // in Draw the item exists as WhichId, in Writer only as SlotId
300 SfxItemState eState = rSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
301 if (eState != SfxItemState::SET)
302 {
303 nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
304 eState = rSet->GetItemState(nNumItemId, false, &pItem);
305
306 if (eState != SfxItemState::SET)
307 {
308 pItem = &static_cast<const SvxNumBulletItem&>(rSet->Get(nNumItemId));
309 eState = SfxItemState::SET;
310 }
311 }
312 DBG_ASSERT(eState == SfxItemState::SET, "no item found!");
313 pSaveNum.reset(new SvxNumRule(static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()));
314
315 // insert levels
316 if (!m_xLevelLB->n_children())
317 {
318 for (sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++)
319 m_xLevelLB->append_text(OUString::number(i));
320 if (pSaveNum->GetLevelCount() > 1)
321 {
322 OUString sEntry = "1 - " + OUString::number(pSaveNum->GetLevelCount());
323 m_xLevelLB->append_text(sEntry);
324 m_xLevelLB->select_text(sEntry);
325 }
326 else
327 m_xLevelLB->select(0);
328 }
329 else
330 m_xLevelLB->select(m_xLevelLB->n_children() - 1);
331
332 sal_uInt16 nMask = 1;
333 m_xLevelLB->unselect_all();
334 if (nActNumLvl == SAL_MAX_UINT16)
335 {
336 m_xLevelLB->select(pSaveNum->GetLevelCount());
337 }
338 else
339 {
340 for (sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++)
341 {
342 if (nActNumLvl & nMask)
343 m_xLevelLB->select(i);
344 nMask <<= 1;
345 }
346 }
347
348 if (!pActNum)
349 pActNum.reset(new SvxNumRule(*pSaveNum));
350 else if (*pSaveNum != *pActNum)
351 *pActNum = *pSaveNum;
352 m_aPreviewWIN.SetNumRule(pActNum.get());
353
354 bool bContinuous = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
355
356 // again misusage: in Draw there is numeration only until the bitmap
357 // without SVX_NUM_NUMBER_NONE
358 //remove types that are unsupported by Draw/Impress
359 if (!bContinuous)
360 {
361 sal_Int32 nFmtCount = m_xFmtLB->get_count();
362 for (sal_Int32 i = nFmtCount; i; i--)
363 {
364 sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32();
365 if (/*SVX_NUM_NUMBER_NONE == nEntryData ||*/
366 (SVX_NUM_BITMAP | LINK_TOKEN) == nEntryData)
367 m_xFmtLB->remove(i - 1);
368 }
369 }
370 //one must be enabled
371 if (!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_LINKED_BMP))
372 {
373 auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP | LINK_TOKEN));
374 if (nPos != -1)
375 m_xFmtLB->remove(nPos);
376 }
377 else if (!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP))
378 {
379 auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP));
380 if (nPos != -1)
381 m_xFmtLB->remove(nPos);
382 }
383
384 // MegaHack: because of a not-fixable 'design mistake/error' in Impress
385 // delete all kinds of numeric enumerations
386 if (pActNum->IsFeatureSupported(SvxNumRuleFlags::NO_NUMBERS))
387 {
388 sal_Int32 nFmtCount = m_xFmtLB->get_count();
389 for (sal_Int32 i = nFmtCount; i; i--)
390 {
391 sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32();
392 if (/*nEntryData >= SVX_NUM_CHARS_UPPER_LETTER &&*/ nEntryData <= SVX_NUM_NUMBER_NONE)
393 m_xFmtLB->remove(i - 1);
394 }
395 }
396
397 InitPosAndSpaceMode();
398
399 InitControls();
400 bModified = false;
401 }
402
InitControls()403 void SvxBulletAndPositionDlg::InitControls()
404 {
405 bInInitControl = true;
406
407 const bool bRelative = !bLabelAlignmentPosAndSpaceModeActive && m_xRelativeCB->get_sensitive()
408 && m_xRelativeCB->get_active();
409 const bool bSingleSelection
410 = m_xLevelLB->count_selected_rows() == 1 && SAL_MAX_UINT16 != nActNumLvl;
411
412 m_xDistBorderMF->set_sensitive(!bLabelAlignmentPosAndSpaceModeActive
413 && (bSingleSelection || bRelative));
414 m_xDistBorderFT->set_sensitive(!bLabelAlignmentPosAndSpaceModeActive
415 && (bSingleSelection || bRelative));
416
417 bool bShowBullet = true;
418 bool bShowBitmap = true;
419 bool bSameType = true;
420 bool bSameStart = true;
421 bool bSamePrefix = true;
422 bool bSameSuffix = true;
423 bool bSameSize = true;
424 bool bSameBulColor = true;
425 bool bSameBulRelSize = true;
426 bool bSameDistBorderNum = !bLabelAlignmentPosAndSpaceModeActive;
427 bool bSetDistEmpty = false;
428 bool bSameIndent = !bLabelAlignmentPosAndSpaceModeActive;
429
430 const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM];
431 SvxAdjust eFirstAdjust = SvxAdjust::Left;
432 Size aFirstSize(0, 0);
433 sal_uInt16 nMask = 1;
434 sal_uInt16 nLvl = SAL_MAX_UINT16;
435
436 bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
437 bool bBullRelSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
438 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
439 {
440 aNumFmtArr[i] = &pActNum->GetLevel(i);
441
442 if (nActNumLvl & nMask)
443 {
444 bShowBullet &= aNumFmtArr[i]->GetNumberingType() == SVX_NUM_CHAR_SPECIAL;
445 bShowBitmap &= (aNumFmtArr[i]->GetNumberingType() & (~LINK_TOKEN)) == SVX_NUM_BITMAP;
446 eFirstAdjust = aNumFmtArr[i]->GetNumAdjust();
447 if (SAL_MAX_UINT16 == nLvl)
448 {
449 nLvl = i;
450 if (bShowBitmap)
451 aFirstSize = aNumFmtArr[i]->GetGraphicSize();
452 }
453 if (i > nLvl)
454 {
455 bSameType
456 &= aNumFmtArr[i]->GetNumberingType() == aNumFmtArr[nLvl]->GetNumberingType();
457 bSameStart = aNumFmtArr[i]->GetStart() == aNumFmtArr[nLvl]->GetStart();
458
459 bSamePrefix = aNumFmtArr[i]->GetPrefix() == aNumFmtArr[nLvl]->GetPrefix();
460 bSameSuffix = aNumFmtArr[i]->GetSuffix() == aNumFmtArr[nLvl]->GetSuffix();
461 //bSameAdjust &= eFirstAdjust == aNumFmtArr[i]->GetNumAdjust();
462 if (bShowBitmap && bSameSize)
463 bSameSize &= aNumFmtArr[i]->GetGraphicSize() == aFirstSize;
464 bSameBulColor
465 &= aNumFmtArr[i]->GetBulletColor() == aNumFmtArr[nLvl]->GetBulletColor();
466 bSameBulRelSize
467 &= aNumFmtArr[i]->GetBulletRelSize() == aNumFmtArr[nLvl]->GetBulletRelSize();
468 bSameIndent //?
469 &= aNumFmtArr[i]->GetFirstLineOffset()
470 == aNumFmtArr[nLvl]->GetFirstLineOffset();
471 }
472 }
473
474 nMask <<= 1;
475 }
476 SwitchNumberType(bShowBullet ? 1 : bShowBitmap ? 2 : 0);
477
478 sal_uInt16 nNumberingType;
479 if (nLvl != SAL_MAX_UINT16)
480 nNumberingType = aNumFmtArr[nLvl]->GetNumberingType();
481 else
482 {
483 nNumberingType = SVX_NUM_NUMBER_NONE;
484 bSameDistBorderNum = false;
485 bSameIndent = false;
486 bSameBulRelSize = false;
487 bSameBulColor = false;
488 bSameStart = false;
489 bSamePrefix = false;
490 bSameSuffix = false;
491 }
492
493 CheckForStartValue_Impl(nNumberingType);
494
495 if (bShowBitmap)
496 {
497 if (bSameSize)
498 {
499 SetMetricValue(*m_xHeightMF, aFirstSize.Height(), eCoreUnit);
500 SetMetricValue(*m_xWidthMF, aFirstSize.Width(), eCoreUnit);
501 }
502 else
503 {
504 m_xHeightMF->set_text("");
505 m_xWidthMF->set_text("");
506 }
507 }
508
509 if (bSameType)
510 {
511 sal_uInt16 nLBData = nNumberingType;
512 m_xFmtLB->set_active_id(OUString::number(nLBData));
513 }
514 else
515 m_xFmtLB->set_active(-1);
516
517 if (bBullRelSize)
518 {
519 if (bSameBulRelSize)
520 m_xBulRelSizeMF->set_value(aNumFmtArr[nLvl]->GetBulletRelSize(), FieldUnit::PERCENT);
521 else
522 m_xBulRelSizeMF->set_text("");
523 }
524 if (bBullColor)
525 {
526 if (bSameBulColor)
527 m_xBulColLB->SelectEntry(aNumFmtArr[nLvl]->GetBulletColor());
528 else
529 m_xBulColLB->SetNoSelection();
530 }
531 switch (nBullet)
532 {
533 case SHOW_NUMBERING:
534 if (bSameStart)
535 {
536 m_xStartED->set_value(aNumFmtArr[nLvl]->GetStart());
537 }
538 else
539 m_xStartED->set_text("");
540 break;
541 case SHOW_BULLET:
542 break;
543 case SHOW_BITMAP:
544 break;
545 }
546
547 switch (eFirstAdjust)
548 {
549 case SvxAdjust::Left:
550 m_xLeftTB->set_active(true);
551 m_xCenterTB->set_active(false);
552 m_xRightTB->set_active(false);
553 break;
554 case SvxAdjust::Center:
555 m_xLeftTB->set_active(false);
556 m_xCenterTB->set_active(true);
557 m_xRightTB->set_active(false);
558 break;
559 case SvxAdjust::Right:
560 m_xLeftTB->set_active(false);
561 m_xCenterTB->set_active(false);
562 m_xRightTB->set_active(true);
563 break;
564 default:
565 break;
566 }
567
568 if (bSamePrefix)
569 m_xPrefixED->set_text(aNumFmtArr[nLvl]->GetPrefix());
570 else
571 m_xPrefixED->set_text("");
572 if (bSameSuffix)
573 m_xSuffixED->set_text(aNumFmtArr[nLvl]->GetSuffix());
574 else
575 m_xSuffixED->set_text("");
576
577 if (bSameDistBorderNum)
578 {
579 tools::Long nDistBorderNum;
580 if (bRelative)
581 {
582 nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace())
583 + aNumFmtArr[nLvl]->GetFirstLineOffset();
584 if (nLvl)
585 nDistBorderNum -= static_cast<tools::Long>(aNumFmtArr[nLvl - 1]->GetAbsLSpace())
586 + aNumFmtArr[nLvl - 1]->GetFirstLineOffset();
587 }
588 else
589 {
590 nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace())
591 + aNumFmtArr[nLvl]->GetFirstLineOffset();
592 }
593 SetMetricValue(*m_xDistBorderMF, nDistBorderNum, eCoreUnit);
594 }
595 else
596 bSetDistEmpty = true;
597
598 if (bSetDistEmpty)
599 m_xDistBorderMF->set_text("");
600
601 if (bSameIndent)
602 SetMetricValue(*m_xIndentMF, -aNumFmtArr[nLvl]->GetFirstLineOffset(), eCoreUnit);
603 else
604 m_xIndentMF->set_text("");
605
606 m_xSelectionRB->set_active(true);
607
608 m_aPreviewWIN.SetLevel(nActNumLvl);
609 m_aPreviewWIN.Invalidate();
610 bInInitControl = false;
611 }
612
613 // 0 - Number; 1 - Bullet; 2 - Bitmap
SwitchNumberType(sal_uInt8 nType)614 void SvxBulletAndPositionDlg::SwitchNumberType(sal_uInt8 nType)
615 {
616 if (nBullet == nType)
617 return;
618 nBullet = nType;
619 bool bBullet = (nType == SHOW_BULLET);
620 bool bBitmap = (nType == SHOW_BITMAP);
621 bool bEnableBitmap = (nType == SHOW_BITMAP);
622 bool bNumeric = !(bBitmap || bBullet);
623 m_xPrefixFT->set_visible(bNumeric);
624 m_xPrefixED->set_visible(bNumeric);
625 m_xSuffixFT->set_visible(bNumeric);
626 m_xSuffixED->set_visible(bNumeric);
627 m_xBeforeAfter->set_visible(bNumeric);
628
629 m_xStartFT->set_visible(!(bBullet || bBitmap));
630 m_xStartED->set_visible(!(bBullet || bBitmap));
631
632 m_xBulletFT->set_visible(bBullet);
633 m_xBulletPB->set_visible(bBullet);
634 bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
635 m_xBulColorFT->set_visible(!bBitmap && bBullColor);
636 m_xBulColLB->set_visible(!bBitmap && bBullColor);
637 bool bBullResSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
638 m_xBulRelSizeFT->set_visible(!bBitmap && bBullResSize);
639 m_xBulRelSizeMF->set_visible(!bBitmap && bBullResSize);
640
641 m_xBitmapMB->set_visible(bBitmap);
642
643 m_xWidthFT->set_visible(bBitmap);
644 m_xWidthMF->set_visible(bBitmap);
645 m_xHeightFT->set_visible(bBitmap);
646 m_xHeightMF->set_visible(bBitmap);
647 m_xRatioCB->set_visible(bBitmap);
648
649 m_xWidthFT->set_sensitive(bEnableBitmap);
650 m_xWidthMF->set_sensitive(bEnableBitmap);
651 m_xHeightFT->set_sensitive(bEnableBitmap);
652 m_xHeightMF->set_sensitive(bEnableBitmap);
653 m_xRatioCB->set_sensitive(bEnableBitmap);
654 }
655
CheckForStartValue_Impl(sal_uInt16 nNumberingType)656 void SvxBulletAndPositionDlg::CheckForStartValue_Impl(sal_uInt16 nNumberingType)
657 {
658 bool bIsNull = m_xStartED->get_value() == 0;
659 bool bNoZeroAllowed = nNumberingType < SVX_NUM_ARABIC
660 || SVX_NUM_CHARS_UPPER_LETTER_N == nNumberingType
661 || SVX_NUM_CHARS_LOWER_LETTER_N == nNumberingType;
662 m_xStartED->set_min(bNoZeroAllowed ? 1 : 0);
663 if (bIsNull && bNoZeroAllowed)
664 EditModifyHdl_Impl(*m_xStartED);
665 }
666
IMPL_LINK(SvxBulletAndPositionDlg,LevelHdl_Impl,weld::TreeView &,rBox,void)667 IMPL_LINK(SvxBulletAndPositionDlg, LevelHdl_Impl, weld::TreeView&, rBox, void)
668 {
669 sal_uInt16 nSaveNumLvl = nActNumLvl;
670 nActNumLvl = 0;
671 auto aSelectedRows = rBox.get_selected_rows();
672 if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount())
673 != aSelectedRows.end()
674 && (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
675 {
676 nActNumLvl = 0xFFFF;
677 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
678 rBox.unselect(i);
679 }
680 else if (!aSelectedRows.empty())
681 {
682 sal_uInt16 nMask = 1;
683 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
684 {
685 if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end())
686 nActNumLvl |= nMask;
687 nMask <<= 1;
688 }
689 rBox.unselect(pActNum->GetLevelCount());
690 }
691 else
692 nActNumLvl = nSaveNumLvl;
693
694 InitControls();
695 }
696
IMPL_LINK_NOARG(SvxBulletAndPositionDlg,PreviewInvalidateHdl_Impl,Timer *,void)697 IMPL_LINK_NOARG(SvxBulletAndPositionDlg, PreviewInvalidateHdl_Impl, Timer*, void)
698 {
699 m_aPreviewWIN.Invalidate();
700 }
701
IMPL_LINK(SvxBulletAndPositionDlg,NumberTypeSelectHdl_Impl,weld::ComboBox &,rBox,void)702 IMPL_LINK(SvxBulletAndPositionDlg, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox, void)
703 {
704 bool bBmp = false;
705 sal_uInt16 nMask = 1;
706 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
707 {
708 if (nActNumLvl & nMask)
709 {
710 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
711 // PAGEDESC does not exist
712 SvxNumType nNumType = static_cast<SvxNumType>(rBox.get_active_id().toUInt32());
713 aNumFmt.SetNumberingType(nNumType);
714 sal_uInt16 nNumberingType = aNumFmt.GetNumberingType();
715 if (SVX_NUM_BITMAP == (nNumberingType & (~LINK_TOKEN)))
716 {
717 bBmp |= nullptr != aNumFmt.GetBrush();
718 aNumFmt.SetIncludeUpperLevels(0);
719 aNumFmt.SetListFormat("", "", i);
720 if (!bBmp)
721 aNumFmt.SetGraphic("");
722 pActNum->SetLevel(i, aNumFmt);
723 SwitchNumberType(SHOW_BITMAP);
724 }
725 else if (SVX_NUM_CHAR_SPECIAL == nNumberingType)
726 {
727 aNumFmt.SetIncludeUpperLevels(0);
728 aNumFmt.SetListFormat("", "", i);
729 if (!aNumFmt.GetBulletFont())
730 aNumFmt.SetBulletFont(&aActBulletFont);
731 if (!aNumFmt.GetBulletChar())
732 aNumFmt.SetBulletChar(SVX_DEF_BULLET);
733 pActNum->SetLevel(i, aNumFmt);
734 SwitchNumberType(SHOW_BULLET);
735 // allocation of the drawing pattern is automatic
736 }
737 else
738 {
739 aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
740 SwitchNumberType(SHOW_NUMBERING);
741 pActNum->SetLevel(i, aNumFmt);
742 CheckForStartValue_Impl(nNumberingType);
743
744 // allocation of the drawing pattern is automatic
745 }
746 }
747 nMask <<= 1;
748 }
749
750 SetModified();
751 }
752
IMPL_LINK(SvxBulletAndPositionDlg,BulColorHdl_Impl,ColorListBox &,rColorBox,void)753 IMPL_LINK(SvxBulletAndPositionDlg, BulColorHdl_Impl, ColorListBox&, rColorBox, void)
754 {
755 Color nSetColor = rColorBox.GetSelectEntryColor();
756
757 sal_uInt16 nMask = 1;
758 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
759 {
760 if (nActNumLvl & nMask)
761 {
762 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
763 aNumFmt.SetBulletColor(nSetColor);
764 pActNum->SetLevel(i, aNumFmt);
765 }
766 nMask <<= 1;
767 }
768 SetModified();
769 }
770
IMPL_LINK(SvxBulletAndPositionDlg,BulRelSizeHdl_Impl,weld::MetricSpinButton &,rField,void)771 IMPL_LINK(SvxBulletAndPositionDlg, BulRelSizeHdl_Impl, weld::MetricSpinButton&, rField, void)
772 {
773 sal_uInt16 nRelSize = rField.get_value(FieldUnit::PERCENT);
774
775 sal_uInt16 nMask = 1;
776 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
777 {
778 if (nActNumLvl & nMask)
779 {
780 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
781 aNumFmt.SetBulletRelSize(nRelSize);
782 pActNum->SetLevel(i, aNumFmt);
783 }
784 nMask <<= 1;
785 }
786 SetModified();
787 }
788
IMPL_LINK(SvxBulletAndPositionDlg,GraphicHdl_Impl,const OString &,rIdent,void)789 IMPL_LINK(SvxBulletAndPositionDlg, GraphicHdl_Impl, const OString&, rIdent, void)
790 {
791 OUString aGrfName;
792 Size aSize;
793 bool bSucc(false);
794 SvxOpenGraphicDialog aGrfDlg(SdResId(RID_SVXSTR_EDIT_GRAPHIC), p_Window);
795
796 OString sNumber;
797 if (rIdent.startsWith("gallery", &sNumber))
798 {
799 auto idx = sNumber.toUInt32();
800 if (idx < aGrfNames.size())
801 {
802 aGrfName = aGrfNames[idx];
803 Graphic aGraphic;
804 if (GalleryExplorer::GetGraphicObj(GALLERY_THEME_BULLETS, idx, &aGraphic))
805 {
806 aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
807 bSucc = true;
808 }
809 }
810 }
811 else if (rIdent == "fromfile")
812 {
813 aGrfDlg.EnableLink(false);
814 aGrfDlg.AsLink(false);
815 if (!aGrfDlg.Execute())
816 {
817 // memorize selected filter
818 aGrfName = aGrfDlg.GetPath();
819
820 Graphic aGraphic;
821 if (!aGrfDlg.GetGraphic(aGraphic))
822 {
823 aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
824 bSucc = true;
825 }
826 }
827 }
828 if (!bSucc)
829 return;
830
831 aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit));
832
833 sal_uInt16 nMask = 1;
834 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
835 {
836 if (nActNumLvl & nMask)
837 {
838 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
839 aNumFmt.SetCharFormatName(m_sNumCharFmtName);
840 aNumFmt.SetGraphic(aGrfName);
841
842 // set size for a later comparison
843 const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
844 // initiate asynchronous loading
845 sal_Int16 eOrient = aNumFmt.GetVertOrient();
846 aNumFmt.SetGraphicBrush(pBrushItem, &aSize, &eOrient);
847 aInitSize[i] = aNumFmt.GetGraphicSize();
848
849 pActNum->SetLevel(i, aNumFmt);
850 }
851 nMask <<= 1;
852 }
853 m_xRatioCB->set_sensitive(true);
854 m_xWidthFT->set_sensitive(true);
855 m_xHeightFT->set_sensitive(true);
856 m_xWidthMF->set_sensitive(true);
857 m_xHeightMF->set_sensitive(true);
858 SetMetricValue(*m_xWidthMF, aSize.Width(), eCoreUnit);
859 SetMetricValue(*m_xHeightMF, aSize.Height(), eCoreUnit);
860
861 SetModified();
862 //needed due to asynchronous loading of graphics in the SvxBrushItem
863 aInvalidateTimer.Start();
864 }
865
IMPL_LINK_NOARG(SvxBulletAndPositionDlg,PopupActivateHdl_Impl,weld::Toggleable &,void)866 IMPL_LINK_NOARG(SvxBulletAndPositionDlg, PopupActivateHdl_Impl, weld::Toggleable&, void)
867 {
868 if (m_xGalleryMenu)
869 return;
870
871 m_xGalleryMenu = m_xBuilder->weld_menu("gallerysubmenu");
872 weld::WaitObject aWait(p_Window);
873
874 if (!GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames))
875 return;
876
877 GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS);
878
879 Graphic aGraphic;
880 OUString sGrfName;
881 ScopedVclPtrInstance<VirtualDevice> pVD;
882 size_t i = 0;
883 for (const auto& grfName : aGrfNames)
884 {
885 sGrfName = grfName;
886 OUString sItemId = "gallery" + OUString::number(i);
887 INetURLObject aObj(sGrfName);
888 if (aObj.GetProtocol() == INetProtocol::File)
889 sGrfName = aObj.PathToFileName();
890 if (GalleryExplorer::GetGraphicObj(GALLERY_THEME_BULLETS, i, &aGraphic))
891 {
892 BitmapEx aBitmap(aGraphic.GetBitmapEx());
893 Size aSize(aBitmap.GetSizePixel());
894 if (aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT)
895 {
896 bool bWidth = aSize.Width() > aSize.Height();
897 double nScale = bWidth
898 ? double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width())
899 : double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
900 aBitmap.Scale(nScale, nScale);
901 }
902 pVD->SetOutputSizePixel(aBitmap.GetSizePixel(), false);
903 pVD->DrawBitmapEx(Point(), aBitmap);
904
905 // We want to show only icon names not full path.
906 aObj.removeExtension();
907 OUString sIconName = aObj.GetLastName(INetURLObject::DecodeMechanism::WithCharset);
908
909 m_xGalleryMenu->append(sItemId, sIconName, *pVD);
910 }
911 else
912 {
913 m_xGalleryMenu->append(sItemId, sGrfName);
914 }
915 ++i;
916 }
917 GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS);
918 }
919
IMPL_LINK_NOARG(SvxBulletAndPositionDlg,BulletHdl_Impl,weld::Button &,void)920 IMPL_LINK_NOARG(SvxBulletAndPositionDlg, BulletHdl_Impl, weld::Button&, void)
921 {
922 SvxCharacterMap aMap(p_Window, nullptr, nullptr);
923
924 sal_uInt16 nMask = 1;
925 const vcl::Font* pFmtFont = nullptr;
926 bool bSameBullet = true;
927 sal_UCS4 cBullet = 0;
928 bool bFirst = true;
929 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
930 {
931 if (nActNumLvl & nMask)
932 {
933 const SvxNumberFormat& rCurFmt = pActNum->GetLevel(i);
934 if (bFirst)
935 {
936 cBullet = rCurFmt.GetBulletChar();
937 }
938 else if (rCurFmt.GetBulletChar() != cBullet)
939 {
940 bSameBullet = false;
941 break;
942 }
943 if (!pFmtFont)
944 pFmtFont = rCurFmt.GetBulletFont();
945 bFirst = false;
946 }
947 nMask <<= 1;
948 }
949
950 if (pFmtFont)
951 aMap.SetCharFont(*pFmtFont);
952 else
953 aMap.SetCharFont(aActBulletFont);
954 if (bSameBullet)
955 aMap.SetChar(cBullet);
956 if (aMap.run() != RET_OK)
957 return;
958
959 // change Font Numrules
960 aActBulletFont = aMap.GetCharFont();
961
962 sal_uInt16 _nMask = 1;
963 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
964 {
965 if (nActNumLvl & _nMask)
966 {
967 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
968 aNumFmt.SetBulletFont(&aActBulletFont);
969 aNumFmt.SetBulletChar(aMap.GetChar());
970 pActNum->SetLevel(i, aNumFmt);
971 }
972 _nMask <<= 1;
973 }
974
975 SetModified();
976 }
977
IMPL_LINK(SvxBulletAndPositionDlg,SizeHdl_Impl,weld::MetricSpinButton &,rField,void)978 IMPL_LINK(SvxBulletAndPositionDlg, SizeHdl_Impl, weld::MetricSpinButton&, rField, void)
979 {
980 bool bWidth = &rField == m_xWidthMF.get();
981 bLastWidthModified = bWidth;
982 bool bRatio = m_xRatioCB->get_active();
983 tools::Long nWidthVal = static_cast<tools::Long>(
984 m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::MM_100TH)));
985 tools::Long nHeightVal = static_cast<tools::Long>(
986 m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::MM_100TH)));
987 nWidthVal = OutputDevice::LogicToLogic(nWidthVal, MapUnit::Map100thMM, eCoreUnit);
988 nHeightVal = OutputDevice::LogicToLogic(nHeightVal, MapUnit::Map100thMM, eCoreUnit);
989 double fSizeRatio;
990
991 bool bRepaint = false;
992 sal_uInt16 nMask = 1;
993 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
994 {
995 if (nActNumLvl & nMask)
996 {
997 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
998 if (SVX_NUM_BITMAP == (aNumFmt.GetNumberingType() & (~LINK_TOKEN)))
999 {
1000 Size aSize(aNumFmt.GetGraphicSize());
1001 Size aSaveSize(aSize);
1002
1003 if (aInitSize[i].Height())
1004 fSizeRatio = static_cast<double>(aInitSize[i].Width())
1005 / static_cast<double>(aInitSize[i].Height());
1006 else
1007 fSizeRatio = double(1);
1008
1009 if (bWidth)
1010 {
1011 tools::Long nDelta = nWidthVal - aInitSize[i].Width();
1012 aSize.setWidth(nWidthVal);
1013 if (bRatio)
1014 {
1015 aSize.setHeight(
1016 aInitSize[i].Height()
1017 + static_cast<tools::Long>(static_cast<double>(nDelta) / fSizeRatio));
1018 m_xHeightMF->set_value(m_xHeightMF->normalize(OutputDevice::LogicToLogic(
1019 aSize.Height(), eCoreUnit, MapUnit::Map100thMM)),
1020 FieldUnit::MM_100TH);
1021 }
1022 }
1023 else
1024 {
1025 tools::Long nDelta = nHeightVal - aInitSize[i].Height();
1026 aSize.setHeight(nHeightVal);
1027 if (bRatio)
1028 {
1029 aSize.setWidth(
1030 aInitSize[i].Width()
1031 + static_cast<tools::Long>(static_cast<double>(nDelta) * fSizeRatio));
1032 m_xWidthMF->set_value(m_xWidthMF->normalize(OutputDevice::LogicToLogic(
1033 aSize.Width(), eCoreUnit, MapUnit::Map100thMM)),
1034 FieldUnit::MM_100TH);
1035 }
1036 }
1037 const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
1038 sal_Int16 eOrient = aNumFmt.GetVertOrient();
1039 if (aSize != aSaveSize)
1040 bRepaint = true;
1041 aNumFmt.SetGraphicBrush(pBrushItem, &aSize, &eOrient);
1042 pActNum->SetLevel(i, aNumFmt);
1043 }
1044 }
1045 nMask <<= 1;
1046 }
1047 SetModified(bRepaint);
1048 }
1049
IMPL_LINK(SvxBulletAndPositionDlg,RatioHdl_Impl,weld::Toggleable &,rBox,void)1050 IMPL_LINK(SvxBulletAndPositionDlg, RatioHdl_Impl, weld::Toggleable&, rBox, void)
1051 {
1052 if (rBox.get_active())
1053 {
1054 if (bLastWidthModified)
1055 SizeHdl_Impl(*m_xWidthMF);
1056 else
1057 SizeHdl_Impl(*m_xHeightMF);
1058 }
1059 }
1060
IMPL_LINK(SvxBulletAndPositionDlg,SelectLeftAlignmentHdl_Impl,weld::Toggleable &,rButton,void)1061 IMPL_LINK(SvxBulletAndPositionDlg, SelectLeftAlignmentHdl_Impl, weld::Toggleable&, rButton, void)
1062 {
1063 if (rButton.get_active())
1064 {
1065 SetAlignmentHdl_Impl(SvxAdjust::Left);
1066
1067 m_xCenterTB->set_active(false);
1068 m_xRightTB->set_active(false);
1069
1070 SetModified();
1071 }
1072 }
1073
IMPL_LINK(SvxBulletAndPositionDlg,SelectCenterAlignmentHdl_Impl,weld::Toggleable &,rButton,void)1074 IMPL_LINK(SvxBulletAndPositionDlg, SelectCenterAlignmentHdl_Impl, weld::Toggleable&, rButton, void)
1075 {
1076 if (rButton.get_active())
1077 {
1078 SetAlignmentHdl_Impl(SvxAdjust::Center);
1079
1080 m_xLeftTB->set_active(false);
1081 m_xRightTB->set_active(false);
1082
1083 SetModified();
1084 }
1085 }
1086
IMPL_LINK(SvxBulletAndPositionDlg,SelectRightAlignmentHdl_Impl,weld::Toggleable &,rButton,void)1087 IMPL_LINK(SvxBulletAndPositionDlg, SelectRightAlignmentHdl_Impl, weld::Toggleable&, rButton, void)
1088 {
1089 if (rButton.get_active())
1090 {
1091 SetAlignmentHdl_Impl(SvxAdjust::Right);
1092
1093 m_xLeftTB->set_active(false);
1094 m_xCenterTB->set_active(false);
1095
1096 SetModified();
1097 }
1098 }
1099
SetAlignmentHdl_Impl(SvxAdjust eAdjust)1100 void SvxBulletAndPositionDlg::SetAlignmentHdl_Impl(SvxAdjust eAdjust)
1101 {
1102 sal_uInt16 nMask = 1;
1103 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
1104 {
1105 if (nActNumLvl & nMask)
1106 {
1107 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
1108 aNumFmt.SetNumAdjust(eAdjust);
1109 pActNum->SetLevel(i, aNumFmt);
1110 }
1111 nMask <<= 1;
1112 }
1113 }
1114
IMPL_LINK(SvxBulletAndPositionDlg,ApplyToMasterHdl_Impl,weld::Toggleable &,rButton,void)1115 IMPL_LINK(SvxBulletAndPositionDlg, ApplyToMasterHdl_Impl, weld::Toggleable&, rButton, void)
1116 {
1117 bApplyToMaster = rButton.get_active();
1118 }
1119
IMPL_LINK_NOARG(SvxBulletAndPositionDlg,ResetHdl_Impl,weld::Button &,void)1120 IMPL_LINK_NOARG(SvxBulletAndPositionDlg, ResetHdl_Impl, weld::Button&, void)
1121 {
1122 Reset(&rFirstStateSet);
1123 }
1124
IMPL_LINK(SvxBulletAndPositionDlg,EditModifyHdl_Impl,weld::Entry &,rEdit,void)1125 IMPL_LINK(SvxBulletAndPositionDlg, EditModifyHdl_Impl, weld::Entry&, rEdit, void)
1126 {
1127 EditModifyHdl_Impl(&rEdit);
1128 }
1129
IMPL_LINK(SvxBulletAndPositionDlg,DistanceHdl_Impl,weld::MetricSpinButton &,rFld,void)1130 IMPL_LINK(SvxBulletAndPositionDlg, DistanceHdl_Impl, weld::MetricSpinButton&, rFld, void)
1131 {
1132 if (bInInitControl)
1133 return;
1134 tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
1135 sal_uInt16 nMask = 1;
1136 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
1137 {
1138 if (nActNumLvl & nMask)
1139 {
1140 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
1141 if (&rFld == m_xDistBorderMF.get())
1142 {
1143 if (m_xRelativeCB->get_active())
1144 {
1145 if (0 == i)
1146 {
1147 auto const nTmp = aNumFmt.GetFirstLineOffset();
1148 aNumFmt.SetAbsLSpace(nValue - nTmp);
1149 }
1150 else
1151 {
1152 tools::Long nTmp = pActNum->GetLevel(i - 1).GetAbsLSpace()
1153 + pActNum->GetLevel(i - 1).GetFirstLineOffset()
1154 - pActNum->GetLevel(i).GetFirstLineOffset();
1155
1156 aNumFmt.SetAbsLSpace(nValue + nTmp);
1157 }
1158 }
1159 else
1160 {
1161 aNumFmt.SetAbsLSpace(nValue - aNumFmt.GetFirstLineOffset());
1162 }
1163 }
1164 else if (&rFld == m_xIndentMF.get())
1165 {
1166 // together with the FirstLineOffset the AbsLSpace must be changed, too
1167 tools::Long nDiff = nValue + aNumFmt.GetFirstLineOffset();
1168 auto const nAbsLSpace = aNumFmt.GetAbsLSpace();
1169 aNumFmt.SetAbsLSpace(nAbsLSpace + nDiff);
1170 aNumFmt.SetFirstLineOffset(-nValue);
1171 }
1172
1173 pActNum->SetLevel(i, aNumFmt);
1174 }
1175 nMask <<= 1;
1176 }
1177
1178 SetModified();
1179 if (!m_xDistBorderMF->get_sensitive())
1180 {
1181 m_xDistBorderMF->set_text("");
1182 }
1183
1184 sal_Int32 aLastLevelLSpace
1185 = pActNum->GetLevel(pActNum->GetLevelCount() - 1).GetAbsLSpace() / 40;
1186 m_aPreviewWIN.set_size_request(aLastLevelLSpace, 300);
1187 }
1188
IMPL_LINK(SvxBulletAndPositionDlg,RelativeHdl_Impl,weld::Toggleable &,rBox,void)1189 IMPL_LINK(SvxBulletAndPositionDlg, RelativeHdl_Impl, weld::Toggleable&, rBox, void)
1190 {
1191 bool bOn = rBox.get_active();
1192 bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 && SAL_MAX_UINT16 != nActNumLvl;
1193 bool bSetValue = false;
1194 tools::Long nValue = 0;
1195 if (bOn || bSingleSelection)
1196 {
1197 sal_uInt16 nMask = 1;
1198 bool bFirst = true;
1199 bSetValue = true;
1200 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
1201 {
1202 if (nActNumLvl & nMask)
1203 {
1204 const SvxNumberFormat& rNumFmt = pActNum->GetLevel(i);
1205 if (bFirst)
1206 {
1207 nValue = rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset();
1208 if (bOn && i)
1209 nValue -= (pActNum->GetLevel(i - 1).GetAbsLSpace()
1210 + pActNum->GetLevel(i - 1).GetFirstLineOffset());
1211 }
1212 else
1213 bSetValue = nValue
1214 == (rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset())
1215 - (pActNum->GetLevel(i - 1).GetAbsLSpace()
1216 + pActNum->GetLevel(i - 1).GetFirstLineOffset());
1217 bFirst = false;
1218 }
1219 nMask <<= 1;
1220 }
1221 }
1222 if (bSetValue)
1223 SetMetricValue(*m_xDistBorderMF, nValue, eCoreUnit);
1224 else
1225 m_xDistBorderMF->set_text("");
1226 m_xDistBorderMF->set_sensitive(bOn || bSingleSelection);
1227 m_xDistBorderFT->set_sensitive(bOn || bSingleSelection);
1228 bLastRelative = bOn;
1229 }
1230
EditModifyHdl_Impl(const weld::Entry * pEdit)1231 void SvxBulletAndPositionDlg::EditModifyHdl_Impl(const weld::Entry* pEdit)
1232 {
1233 bool bPrefixOrSuffix = (pEdit == m_xPrefixED.get()) || (pEdit == m_xSuffixED.get());
1234 bool bStart = pEdit == m_xStartED.get();
1235 sal_uInt16 nMask = 1;
1236 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
1237 {
1238 if (nActNumLvl & nMask)
1239 {
1240 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
1241 if (bPrefixOrSuffix)
1242 aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
1243 else if (bStart)
1244 aNumFmt.SetStart(m_xStartED->get_value());
1245 pActNum->SetLevel(i, aNumFmt);
1246 }
1247 nMask <<= 1;
1248 }
1249 SetModified();
1250 }
1251
SetModified(bool bRepaint)1252 void SvxBulletAndPositionDlg::SetModified(bool bRepaint)
1253 {
1254 bModified = true;
1255 if (bRepaint)
1256 {
1257 m_aPreviewWIN.SetLevel(nActNumLvl);
1258 m_aPreviewWIN.Invalidate();
1259 }
1260 }
1261
InitPosAndSpaceMode()1262 void SvxBulletAndPositionDlg::InitPosAndSpaceMode()
1263 {
1264 if (pActNum == nullptr)
1265 {
1266 SAL_WARN("cui.tabpages", "<SvxNumPositionTabPage::InitPosAndSpaceMode()> - misusage of "
1267 "method -> <pAktNum> has to be already set!");
1268 return;
1269 }
1270
1271 SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode = SvxNumberFormat::LABEL_ALIGNMENT;
1272 sal_uInt16 nMask = 1;
1273 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i)
1274 {
1275 if (nActNumLvl & nMask)
1276 {
1277 SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
1278 ePosAndSpaceMode = aNumFmt.GetPositionAndSpaceMode();
1279 if (ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT)
1280 {
1281 break;
1282 }
1283 }
1284 nMask <<= 1;
1285 }
1286
1287 bLabelAlignmentPosAndSpaceModeActive = ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT;
1288 }
1289
1290 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1291