cid#1606642 Data race condition
[LibreOffice.git] / cui / source / tabpages / align.cxx
blob33ea17f11f4a224adc992af80039f65f3c3d3050
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <align.hxx>
22 #include <editeng/svxenum.hxx>
23 #include <svx/svxids.hrc>
24 #include <svx/strings.hrc>
25 #include <svx/dialmgr.hxx>
26 #include <bitmaps.hlst>
27 #include <svx/rotmodit.hxx>
28 #include <svx/sdangitm.hxx>
30 #include <editeng/frmdiritem.hxx>
31 #include <editeng/justifyitem.hxx>
32 #include <svl/cjkoptions.hxx>
33 #include <svl/intitem.hxx>
34 #include <vcl/image.hxx>
36 #define IID_BOTTOMLOCK 1
37 #define IID_TOPLOCK 2
38 #define IID_CELLLOCK 3
40 namespace svx {
42 const WhichRangesContainer AlignmentTabPage::s_pRanges(
43 svl::Items<
44 SID_ATTR_ALIGN_STACKED, SID_ATTR_ALIGN_LINEBREAK, // 10229 - 10230
45 SID_ATTR_ALIGN_INDENT, SID_ATTR_ALIGN_INDENT, // 10460 - 10460
46 SID_ATTR_ALIGN_DEGREES, SID_ATTR_ALIGN_DEGREES, // 10577 - 10577
47 SID_ATTR_ALIGN_LOCKPOS, SID_ATTR_ALIGN_LOCKPOS, // 10578 - 10578
48 SID_ATTR_ALIGN_HYPHENATION, SID_ATTR_ALIGN_HYPHENATION, // 10931 - 10931
49 SID_ATTR_FRAMEDIRECTION, SID_ATTR_FRAMEDIRECTION, // 10944 - 10944
50 SID_ATTR_ALIGN_ASIANVERTICAL, SID_ATTR_ALIGN_ASIANVERTICAL, // 10949 - 10949
51 SID_ATTR_ALIGN_SHRINKTOFIT, SID_ATTR_ALIGN_SHRINKTOFIT, // 11015 - 11015
52 SID_ATTR_ALIGN_HOR_JUSTIFY, SID_ATTR_ALIGN_VER_JUSTIFY>); // 11571 - 11572
55 namespace {
57 template<typename JustContainerType, typename JustEnumType>
58 void lcl_MaybeResetAlignToDistro(
59 weld::ComboBox& rLB, sal_uInt16 nListId, const SfxItemSet& rCoreAttrs, TypedWhichId<SfxEnumItemInterface> nWhichAlign, TypedWhichId<SfxEnumItemInterface> nWhichJM, JustEnumType eBlock)
61 const SfxEnumItemInterface* p = rCoreAttrs.GetItemIfSet(nWhichAlign);
62 if (!p)
63 // alignment not set.
64 return;
66 JustContainerType eVal = static_cast<JustContainerType>(p->GetEnumValue());
67 if (eVal != eBlock)
68 // alignment is not 'justify'. No need to go further.
69 return;
71 p = rCoreAttrs.GetItemIfSet(nWhichJM);
72 if (!p)
73 // justification method is not set.
74 return;
76 SvxCellJustifyMethod eMethod = static_cast<SvxCellJustifyMethod>(p->GetEnumValue());
77 if (eMethod == SvxCellJustifyMethod::Distribute)
79 // Select the 'distribute' entry in the specified list box.
80 rLB.set_active_id(OUString::number(nListId));
84 void lcl_SetJustifyMethodToItemSet(SfxItemSet& rSet, const SfxItemSet& rOldSet, sal_uInt16 nWhichJM, const weld::ComboBox& rLB, sal_uInt16 nListId)
86 // tdf#138698 unsupported, e.g. dbaccess
87 if (rLB.find_id(OUString::number(nListId)) == -1)
88 return;
90 // feature supported , e.g. calc
91 SvxCellJustifyMethod eJM = SvxCellJustifyMethod::Auto;
92 if (rLB.get_active_id().toInt32() == nListId)
93 eJM = SvxCellJustifyMethod::Distribute;
95 // tdf#129300 If it would create no change, don't force it
96 const SvxJustifyMethodItem& rOldItem = static_cast<const SvxJustifyMethodItem&>(rOldSet.Get(nWhichJM));
97 if (rOldItem.GetValue() == eJM)
99 rSet.InvalidateItem(nWhichJM);
100 return;
103 SvxJustifyMethodItem aItem(eJM, nWhichJM);
104 rSet.Put(aItem);
107 }//namespace
109 AlignmentTabPage::AlignmentTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
110 : SfxTabPage(pPage, pController, u"cui/ui/cellalignment.ui"_ustr, u"CellAlignPage"_ustr, &rCoreAttrs)
111 , m_aVsRefEdge(nullptr)
112 // text alignment
113 , m_xLbHorAlign(m_xBuilder->weld_combo_box(u"comboboxHorzAlign"_ustr))
114 , m_xFtIndent(m_xBuilder->weld_label(u"labelIndent"_ustr))
115 , m_xEdIndent(m_xBuilder->weld_metric_spin_button(u"spinIndentFrom"_ustr, FieldUnit::POINT))
116 , m_xFtVerAlign(m_xBuilder->weld_label(u"labelVertAlign"_ustr))
117 , m_xLbVerAlign(m_xBuilder->weld_combo_box(u"comboboxVertAlign"_ustr))
118 //text rotation
119 , m_xFtRotate(m_xBuilder->weld_label(u"labelDegrees"_ustr))
120 , m_xNfRotate(m_xBuilder->weld_metric_spin_button(u"spinDegrees"_ustr, FieldUnit::DEGREE))
121 , m_xFtRefEdge(m_xBuilder->weld_label(u"labelRefEdge"_ustr))
122 //Asian mode
123 , m_xCbStacked(m_xBuilder->weld_check_button(u"checkVertStack"_ustr))
124 , m_xCbAsianMode(m_xBuilder->weld_check_button(u"checkAsianMode"_ustr))
125 // Properties
126 , m_xBtnWrap(m_xBuilder->weld_check_button(u"checkWrapTextAuto"_ustr))
127 , m_xBtnHyphen(m_xBuilder->weld_check_button(u"checkHyphActive"_ustr))
128 , m_xBtnShrink(m_xBuilder->weld_check_button(u"checkShrinkFitCellSize"_ustr))
129 , m_xLbFrameDir(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box(u"comboTextDirBox"_ustr)))
130 //ValueSet hover strings
131 , m_xFtBotLock(m_xBuilder->weld_label(u"labelSTR_BOTTOMLOCK"_ustr))
132 , m_xFtTopLock(m_xBuilder->weld_label(u"labelSTR_TOPLOCK"_ustr))
133 , m_xFtCelLock(m_xBuilder->weld_label(u"labelSTR_CELLLOCK"_ustr))
134 , m_xFtABCD(m_xBuilder->weld_label(u"labelABCD"_ustr))
135 , m_xAlignmentFrame(m_xBuilder->weld_widget(u"alignment"_ustr))
136 , m_xOrientFrame(m_xBuilder->weld_widget(u"orientation"_ustr))
137 , m_xPropertiesFrame(m_xBuilder->weld_widget(u"properties"_ustr))
138 , m_xVsRefEdge(new weld::CustomWeld(*m_xBuilder, u"references"_ustr, m_aVsRefEdge))
139 , m_xCtrlDial(new DialControl)
140 , m_xCtrlDialWin(new weld::CustomWeld(*m_xBuilder, u"dialcontrol"_ustr, *m_xCtrlDial))
142 m_xCtrlDial->SetLinkedField(m_xNfRotate.get());
143 m_xCtrlDial->SetText(m_xFtABCD->get_label());
145 InitVsRefEgde();
147 m_xLbHorAlign->connect_changed(LINK(this, AlignmentTabPage, UpdateEnableHdl));
149 m_xCbStacked->connect_toggled(LINK(this, AlignmentTabPage, StackedClickHdl));
150 m_xCbAsianMode->connect_toggled(LINK(this, AlignmentTabPage, AsianModeClickHdl));
151 m_xBtnWrap->connect_toggled(LINK(this, AlignmentTabPage, WrapClickHdl));
152 m_xBtnHyphen->connect_toggled(LINK(this, AlignmentTabPage, HyphenClickHdl));
153 m_xBtnShrink->connect_toggled(LINK(this, AlignmentTabPage, ShrinkClickHdl));
155 // Asian vertical mode
156 m_xCbAsianMode->set_visible(SvtCJKOptions::IsVerticalTextEnabled());
158 m_xLbFrameDir->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_FRAMEDIR_LTR));
159 m_xLbFrameDir->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_FRAMEDIR_RTL));
160 m_xLbFrameDir->append(SvxFrameDirection::Environment, SvxResId(RID_SVXSTR_FRAMEDIR_SUPER));
162 // This page needs ExchangeSupport.
163 SetExchangeSupport();
166 AlignmentTabPage::~AlignmentTabPage()
168 m_xCtrlDialWin.reset();
169 m_xCtrlDial.reset();
170 m_xVsRefEdge.reset();
171 m_xLbFrameDir.reset();
174 std::unique_ptr<SfxTabPage> AlignmentTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
176 return std::make_unique<AlignmentTabPage>(pPage, pController, *rAttrSet);
179 bool AlignmentTabPage::FillItemSet( SfxItemSet* rSet )
181 const SfxItemSet& rOldSet = GetItemSet();
183 bool bChanged = SfxTabPage::FillItemSet(rSet);
185 sal_uInt16 nWhich = GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY);
186 if (m_xLbHorAlign->get_value_changed_from_saved())
188 SvxCellHorJustify eJustify(SvxCellHorJustify::Standard);
189 switch (m_xLbHorAlign->get_active_id().toInt32())
191 case ALIGNDLG_HORALIGN_STD:
192 eJustify = SvxCellHorJustify::Standard;
193 break;
194 case ALIGNDLG_HORALIGN_LEFT:
195 eJustify = SvxCellHorJustify::Left;
196 break;
197 case ALIGNDLG_HORALIGN_CENTER:
198 eJustify = SvxCellHorJustify::Center;
199 break;
200 case ALIGNDLG_HORALIGN_RIGHT:
201 eJustify = SvxCellHorJustify::Right;
202 break;
203 case ALIGNDLG_HORALIGN_BLOCK:
204 case ALIGNDLG_HORALIGN_DISTRIBUTED:
205 eJustify = SvxCellHorJustify::Block;
206 break;
207 case ALIGNDLG_HORALIGN_FILL:
208 eJustify = SvxCellHorJustify::Repeat;
209 break;
211 rSet->Put(SvxHorJustifyItem(eJustify, nWhich));
212 bChanged = true;
214 else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
215 rSet->InvalidateItem(nWhich);
217 nWhich = GetWhich(SID_ATTR_ALIGN_INDENT);
218 if (m_xEdIndent->get_value_changed_from_saved())
220 const SfxUInt16Item* pIndentItem = static_cast<const SfxUInt16Item*>(GetOldItem(
221 *rSet, SID_ATTR_ALIGN_INDENT));
222 assert(pIndentItem);
223 std::unique_ptr<SfxUInt16Item> pNewIndentItem(pIndentItem->Clone());
224 pNewIndentItem->SetValue(m_xEdIndent->get_value(FieldUnit::TWIP));
225 rSet->Put(std::move(pNewIndentItem));
226 bChanged = true;
228 else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
229 rSet->InvalidateItem(nWhich);
231 nWhich = GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY);
232 if (m_xLbVerAlign->get_value_changed_from_saved())
234 SvxCellVerJustify eJustify(SvxCellVerJustify::Standard);
235 switch (m_xLbVerAlign->get_active_id().toInt32())
237 case ALIGNDLG_VERALIGN_STD:
238 eJustify = SvxCellVerJustify::Standard;
239 break;
240 case ALIGNDLG_VERALIGN_TOP:
241 eJustify = SvxCellVerJustify::Top;
242 break;
243 case ALIGNDLG_VERALIGN_MID:
244 eJustify = SvxCellVerJustify::Center;
245 break;
246 case ALIGNDLG_VERALIGN_BOTTOM:
247 eJustify = SvxCellVerJustify::Bottom;
248 break;
249 case ALIGNDLG_VERALIGN_BLOCK:
250 case ALIGNDLG_VERALIGN_DISTRIBUTED:
251 eJustify = SvxCellVerJustify::Block;
252 break;
254 rSet->Put(SvxVerJustifyItem(eJustify, nWhich));
255 bChanged = true;
257 else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
258 rSet->InvalidateItem(nWhich);
260 nWhich = GetWhich(SID_ATTR_ALIGN_DEGREES);
261 if (m_xNfRotate->get_value_changed_from_saved())
263 const SdrAngleItem* pAngleItem = static_cast<const SdrAngleItem*>(GetOldItem(
264 *rSet, SID_ATTR_ALIGN_DEGREES));
265 assert(pAngleItem);
266 std::unique_ptr<SdrAngleItem> pNewAngleItem(pAngleItem->Clone());
267 pNewAngleItem->SetValue(m_xCtrlDial->GetRotation());
268 rSet->Put(std::move(pNewAngleItem));
269 bChanged = true;
271 else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
272 rSet->InvalidateItem(nWhich);
274 TypedWhichId<SvxRotateModeItem> nWhichLockPos(GetWhich(SID_ATTR_ALIGN_LOCKPOS));
275 if (m_aVsRefEdge.IsValueChangedFromSaved())
277 switch (m_aVsRefEdge.GetSelectedItemId())
279 case IID_CELLLOCK:
280 rSet->Put(SvxRotateModeItem(SvxRotateMode::SVX_ROTATE_MODE_STANDARD, nWhichLockPos));
281 break;
282 case IID_TOPLOCK:
283 rSet->Put(SvxRotateModeItem(SvxRotateMode::SVX_ROTATE_MODE_TOP, nWhichLockPos));
284 break;
285 case IID_BOTTOMLOCK:
286 rSet->Put(SvxRotateModeItem(SvxRotateMode::SVX_ROTATE_MODE_BOTTOM, nWhichLockPos));
287 break;
288 default:
289 m_aVsRefEdge.SetNoSelection();
290 break;
292 bChanged = true;
294 else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhichLockPos, false))
295 rSet->InvalidateItem(nWhichLockPos);
297 nWhich = GetWhich(SID_ATTR_ALIGN_STACKED);
298 if (m_xCbStacked->get_state_changed_from_saved())
300 const SfxBoolItem* pStackItem = static_cast<const SfxBoolItem*>(GetOldItem(
301 *rSet, SID_ATTR_ALIGN_STACKED));
302 assert(pStackItem);
303 std::unique_ptr<SfxBoolItem> pNewStackItem(pStackItem->Clone());
304 pNewStackItem->SetValue(m_xCbStacked->get_active());
305 rSet->Put(std::move(pNewStackItem));
306 bChanged = true;
308 else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
309 rSet->InvalidateItem(nWhich);
311 nWhich = GetWhich(SID_ATTR_ALIGN_ASIANVERTICAL);
312 if (m_xCbAsianMode->get_state_changed_from_saved())
314 rSet->Put(SfxBoolItem(nWhich, m_xCbAsianMode->get_active()));
315 bChanged = true;
317 else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
318 rSet->InvalidateItem(nWhich);
320 nWhich = GetWhich(SID_ATTR_ALIGN_LINEBREAK);
321 if (m_xBtnWrap->get_state_changed_from_saved())
323 const SfxBoolItem* pWrapItem = static_cast<const SfxBoolItem*>(GetOldItem(
324 *rSet, SID_ATTR_ALIGN_LINEBREAK));
325 assert(pWrapItem);
326 std::unique_ptr<SfxBoolItem> pNewWrapItem(pWrapItem->Clone());
327 pNewWrapItem->SetValue(m_xBtnWrap->get_active());
328 rSet->Put(std::move(pNewWrapItem));
329 bChanged = true;
331 else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
332 rSet->InvalidateItem(nWhich);
334 nWhich = GetWhich(SID_ATTR_ALIGN_HYPHENATION);
335 if (m_xBtnHyphen->get_state_changed_from_saved())
337 const SfxBoolItem* pHyphItem = static_cast<const SfxBoolItem*>(GetOldItem(
338 *rSet, SID_ATTR_ALIGN_HYPHENATION));
339 assert(pHyphItem);
340 std::unique_ptr<SfxBoolItem> pNewHyphItem(pHyphItem->Clone());
341 pNewHyphItem->SetValue(m_xBtnHyphen->get_active());
342 rSet->Put(std::move(pNewHyphItem));
343 bChanged = true;
345 else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
346 rSet->InvalidateItem(nWhich);
348 nWhich = GetWhich(SID_ATTR_ALIGN_SHRINKTOFIT);
349 if (m_xBtnShrink->get_state_changed_from_saved())
351 const SfxBoolItem* pShrinkItem = static_cast<const SfxBoolItem*>(GetOldItem(
352 *rSet, SID_ATTR_ALIGN_SHRINKTOFIT));
353 assert(pShrinkItem);
354 std::unique_ptr<SfxBoolItem> pNewShrinkItem(pShrinkItem->Clone());
355 pNewShrinkItem->SetValue(m_xBtnShrink->get_active());
356 rSet->Put(std::move(pNewShrinkItem));
357 bChanged = true;
359 else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
360 rSet->InvalidateItem(nWhich);
362 if (m_xLbFrameDir->get_visible())
364 nWhich = GetWhich(SID_ATTR_FRAMEDIRECTION);
365 if (m_xLbFrameDir->get_value_changed_from_saved())
367 SvxFrameDirection eDir = m_xLbFrameDir->get_active_id();
368 rSet->Put(SvxFrameDirectionItem(eDir, nWhich));
369 bChanged = true;
371 else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
372 rSet->InvalidateItem(nWhich);
375 // Special treatment for distributed alignment; we need to set the justify
376 // method to 'distribute' to distinguish from the normal justification.
377 TypedWhichId<SfxEnumItemInterface> nWhichHorJM(GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD));
378 lcl_SetJustifyMethodToItemSet(*rSet, rOldSet, nWhichHorJM, *m_xLbHorAlign, ALIGNDLG_HORALIGN_DISTRIBUTED);
379 if (!bChanged)
380 bChanged = HasAlignmentChanged(*rSet, nWhichHorJM);
382 TypedWhichId<SfxEnumItemInterface> nWhichVerJM(GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY_METHOD));
383 lcl_SetJustifyMethodToItemSet(*rSet, rOldSet, nWhichVerJM, *m_xLbVerAlign, ALIGNDLG_VERALIGN_DISTRIBUTED);
384 if (!bChanged)
385 bChanged = HasAlignmentChanged(*rSet, nWhichVerJM);
387 return bChanged;
390 namespace
392 void ResetBool(sal_uInt16 nWhich, const SfxItemSet* pSet, weld::CheckButton& rBtn, weld::TriStateEnabled& rTriState)
394 SfxItemState eState = pSet->GetItemState(nWhich);
395 switch (eState)
397 case SfxItemState::UNKNOWN:
398 rBtn.hide();
399 rTriState.bTriStateEnabled = false;
400 break;
401 case SfxItemState::DISABLED:
402 rBtn.set_sensitive(false);
403 rTriState.bTriStateEnabled = false;
404 break;
405 case SfxItemState::INVALID:
406 rBtn.set_state(TRISTATE_INDET);
407 rTriState.bTriStateEnabled = true;
408 break;
409 case SfxItemState::DEFAULT:
410 case SfxItemState::SET:
412 const SfxBoolItem& rItem = static_cast<const SfxBoolItem&>(pSet->Get(nWhich));
413 rBtn.set_state(static_cast<TriState>(rItem.GetValue()));
414 rTriState.bTriStateEnabled = false;
415 break;
418 rBtn.save_state();
422 void AlignmentTabPage::Reset(const SfxItemSet* pCoreAttrs)
424 SfxTabPage::Reset(pCoreAttrs);
426 ResetBool(GetWhich(SID_ATTR_ALIGN_STACKED), pCoreAttrs, *m_xCbStacked, m_aStackedState);
427 ResetBool(GetWhich(SID_ATTR_ALIGN_ASIANVERTICAL), pCoreAttrs, *m_xCbAsianMode, m_aAsianModeState);
428 ResetBool(GetWhich(SID_ATTR_ALIGN_LINEBREAK), pCoreAttrs, *m_xBtnWrap, m_aWrapState);
429 ResetBool(GetWhich(SID_ATTR_ALIGN_HYPHENATION), pCoreAttrs, *m_xBtnHyphen, m_aHyphenState);
430 ResetBool(GetWhich(SID_ATTR_ALIGN_SHRINKTOFIT), pCoreAttrs, *m_xBtnShrink, m_aShrinkState);
432 sal_uInt16 nWhich = GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY);
433 SfxItemState eState = pCoreAttrs->GetItemState(nWhich);
434 switch (eState)
436 case SfxItemState::UNKNOWN:
437 m_xLbHorAlign->hide();
438 break;
439 case SfxItemState::DISABLED:
440 m_xLbHorAlign->set_sensitive(false);
441 break;
442 case SfxItemState::INVALID:
443 m_xLbHorAlign->set_active(-1);
444 break;
445 case SfxItemState::DEFAULT:
446 case SfxItemState::SET:
448 const SvxHorJustifyItem& rJustifyItem = static_cast<const SvxHorJustifyItem&>(pCoreAttrs->Get(nWhich));
449 switch (rJustifyItem.GetValue())
451 case SvxCellHorJustify::Standard:
452 m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_STD));
453 break;
454 case SvxCellHorJustify::Left:
455 m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_LEFT));
456 break;
457 case SvxCellHorJustify::Center:
458 m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_CENTER));
459 break;
460 case SvxCellHorJustify::Right:
461 m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_RIGHT));
462 break;
463 case SvxCellHorJustify::Block:
464 m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_BLOCK));
465 break;
466 case SvxCellHorJustify::Repeat:
467 m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_FILL));
468 break;
470 break;
474 nWhich = GetWhich(SID_ATTR_ALIGN_INDENT);
475 eState = pCoreAttrs->GetItemState(nWhich);
476 switch (eState)
478 case SfxItemState::UNKNOWN:
479 m_xEdIndent->hide();
480 m_xFtIndent->hide();
481 break;
482 case SfxItemState::DISABLED:
483 m_xEdIndent->set_sensitive(false);
484 break;
485 case SfxItemState::INVALID:
486 m_xEdIndent->set_text(u""_ustr);
487 break;
488 case SfxItemState::DEFAULT:
489 case SfxItemState::SET:
491 const SfxUInt16Item& rIndentItem = static_cast<const SfxUInt16Item&>(pCoreAttrs->Get(nWhich));
492 m_xEdIndent->set_value(rIndentItem.GetValue(), FieldUnit::TWIP);
493 break;
497 nWhich = GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY);
498 eState = pCoreAttrs->GetItemState(nWhich);
499 switch (eState)
501 case SfxItemState::UNKNOWN:
502 m_xLbVerAlign->hide();
503 m_xFtVerAlign->hide();
504 break;
505 case SfxItemState::DISABLED:
506 m_xLbVerAlign->set_sensitive(false);
507 break;
508 case SfxItemState::INVALID:
509 m_xLbVerAlign->set_active(-1);
510 break;
511 case SfxItemState::DEFAULT:
512 case SfxItemState::SET:
514 const SvxVerJustifyItem& rJustifyItem = static_cast<const SvxVerJustifyItem&>(pCoreAttrs->Get(nWhich));
515 switch (rJustifyItem.GetValue())
517 case SvxCellVerJustify::Standard:
518 m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_STD));
519 break;
520 case SvxCellVerJustify::Top:
521 m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_TOP));
522 break;
523 case SvxCellVerJustify::Center:
524 m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_MID));
525 break;
526 case SvxCellVerJustify::Bottom:
527 m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_BOTTOM));
528 break;
529 case SvxCellVerJustify::Block:
530 m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_BLOCK));
531 break;
533 break;
537 nWhich = GetWhich(SID_ATTR_ALIGN_DEGREES);
538 eState = pCoreAttrs->GetItemState(nWhich);
539 switch (eState)
541 case SfxItemState::UNKNOWN:
542 m_xNfRotate->hide();
543 m_xCtrlDialWin->hide();
544 break;
545 case SfxItemState::DISABLED:
546 m_xNfRotate->set_sensitive(false);
547 m_xCtrlDialWin->set_sensitive(false);
548 break;
549 case SfxItemState::INVALID:
550 m_xCtrlDial->SetNoRotation();
551 break;
552 case SfxItemState::DEFAULT:
553 case SfxItemState::SET:
555 const SdrAngleItem& rAlignItem = static_cast<const SdrAngleItem&>(pCoreAttrs->Get(nWhich));
556 m_xCtrlDial->SetRotation(rAlignItem.GetValue());
557 break;
561 nWhich = GetWhich(SID_ATTR_ALIGN_LOCKPOS);
562 eState = pCoreAttrs->GetItemState(nWhich);
563 switch (eState)
565 case SfxItemState::UNKNOWN:
566 m_xVsRefEdge->hide();
567 break;
568 case SfxItemState::DISABLED:
569 m_xVsRefEdge->set_sensitive(false);
570 break;
571 case SfxItemState::INVALID:
572 m_aVsRefEdge.SetNoSelection();
573 break;
574 case SfxItemState::DEFAULT:
575 case SfxItemState::SET:
577 const SvxRotateModeItem& rRotateModeItem = static_cast<const SvxRotateModeItem&>(pCoreAttrs->Get(nWhich));
578 switch (rRotateModeItem.GetValue())
580 case SvxRotateMode::SVX_ROTATE_MODE_STANDARD:
581 m_aVsRefEdge.SelectItem(IID_CELLLOCK);
582 break;
583 case SvxRotateMode::SVX_ROTATE_MODE_TOP:
584 m_aVsRefEdge.SelectItem(IID_TOPLOCK);
585 break;
586 case SvxRotateMode::SVX_ROTATE_MODE_BOTTOM:
587 m_aVsRefEdge.SelectItem(IID_BOTTOMLOCK);
588 break;
589 default:
590 m_aVsRefEdge.SetNoSelection();
591 break;
593 break;
596 m_aVsRefEdge.SaveValue();
598 //text direction
599 nWhich = GetWhich(SID_ATTR_FRAMEDIRECTION);
600 eState = pCoreAttrs->GetItemState(nWhich);
601 switch (eState)
603 case SfxItemState::UNKNOWN:
604 m_xLbFrameDir->hide();
605 break;
606 case SfxItemState::DISABLED:
607 m_xLbFrameDir->set_sensitive(false);
608 break;
609 case SfxItemState::INVALID:
610 m_xLbFrameDir->set_active(-1);
611 break;
612 case SfxItemState::DEFAULT:
613 case SfxItemState::SET:
615 const SvxFrameDirectionItem& rFrameDirItem = static_cast<const SvxFrameDirectionItem&>(pCoreAttrs->Get(nWhich));
616 m_xLbFrameDir->set_active_id(rFrameDirItem.GetValue());
617 break;
621 // Special treatment for distributed alignment; we need to set the justify
622 // method to 'distribute' to distinguish from the normal justification.
623 TypedWhichId<SfxEnumItemInterface> nHorJustifyMethodWhich(GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD));
624 SfxItemState eHorJustifyMethodState = pCoreAttrs->GetItemState(nHorJustifyMethodWhich);
625 if (eHorJustifyMethodState == SfxItemState::UNKNOWN)
627 // feature unknown, e.g. dbaccess, remove the option
628 int nDistribId = m_xLbHorAlign->find_id(OUString::number(ALIGNDLG_HORALIGN_DISTRIBUTED));
629 if (nDistribId != -1)
630 m_xLbHorAlign->remove(nDistribId);
632 else
634 // feature known, e.g. calc
635 lcl_MaybeResetAlignToDistro<SvxCellHorJustify, SvxCellHorJustify>(
636 *m_xLbHorAlign, ALIGNDLG_HORALIGN_DISTRIBUTED, *pCoreAttrs,
637 TypedWhichId<SfxEnumItemInterface>(GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY)), nHorJustifyMethodWhich,
638 SvxCellHorJustify::Block);
641 TypedWhichId<SfxEnumItemInterface> nVerJustifyMethodWhich( GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY_METHOD) );
642 SfxItemState eVerJustifyMethodState = pCoreAttrs->GetItemState(nVerJustifyMethodWhich);
643 if (eVerJustifyMethodState == SfxItemState::UNKNOWN)
645 // feature unknown, e.g. dbaccess, remove the option
646 int nDistribId = m_xLbVerAlign->find_id(OUString::number(ALIGNDLG_VERALIGN_DISTRIBUTED));
647 if (nDistribId != -1)
648 m_xLbVerAlign->remove(nDistribId);
650 else
652 // feature known, e.g. calc
653 lcl_MaybeResetAlignToDistro<SvxCellVerJustify, SvxCellVerJustify>(
654 *m_xLbVerAlign, ALIGNDLG_VERALIGN_DISTRIBUTED, *pCoreAttrs,
655 TypedWhichId<SfxEnumItemInterface>(GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY)), nVerJustifyMethodWhich,
656 SvxCellVerJustify::Block);
659 m_xLbHorAlign->save_value();
660 m_xLbFrameDir->save_value();
661 m_xLbVerAlign->save_value();
662 m_xNfRotate->save_value();
663 m_xEdIndent->save_value();
665 UpdateEnableControls();
668 DeactivateRC AlignmentTabPage::DeactivatePage( SfxItemSet* _pSet )
670 if( _pSet )
671 FillItemSet( _pSet );
672 return DeactivateRC::LeavePage;
675 void AlignmentTabPage::InitVsRefEgde()
677 // remember selection - is deleted in call to ValueSet::Clear()
678 sal_uInt16 nSel = m_aVsRefEdge.GetSelectedItemId();
680 Image aBottomLock(StockImage::Yes, RID_SVXBMP_BOTTOMLOCK);
681 Image aTopLock(StockImage::Yes, RID_SVXBMP_TOPLOCK);
682 Image aCellLock(StockImage::Yes, RID_SVXBMP_CELLLOCK);
684 m_aVsRefEdge.Clear();
685 m_aVsRefEdge.SetStyle(m_aVsRefEdge.GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER);
687 m_aVsRefEdge.SetColCount(3);
688 m_aVsRefEdge.InsertItem(IID_BOTTOMLOCK, aBottomLock, m_xFtBotLock->get_label());
689 m_aVsRefEdge.InsertItem(IID_TOPLOCK, aTopLock, m_xFtTopLock->get_label());
690 m_aVsRefEdge.InsertItem(IID_CELLLOCK, aCellLock, m_xFtCelLock->get_label());
691 m_aVsRefEdge.SetOptimalSize();
693 m_aVsRefEdge.SelectItem( nSel );
696 void AlignmentTabPage::UpdateEnableControls()
698 const sal_Int32 nHorAlign = m_xLbHorAlign->get_active_id().toInt32();
699 bool bHorLeft = (nHorAlign == ALIGNDLG_HORALIGN_LEFT);
700 bool bHorBlock = (nHorAlign == ALIGNDLG_HORALIGN_BLOCK);
701 bool bHorFill = (nHorAlign == ALIGNDLG_HORALIGN_FILL);
702 bool bHorDist = (nHorAlign == ALIGNDLG_HORALIGN_DISTRIBUTED);
704 // indent edit field only for left alignment
705 m_xFtIndent->set_sensitive( bHorLeft );
706 m_xEdIndent->set_sensitive( bHorLeft );
708 // stacked disabled for fill alignment
709 m_xCbStacked->set_sensitive(!bHorFill);
711 // hyphenation only for automatic line breaks or for block alignment
712 m_xBtnHyphen->set_sensitive( m_xBtnWrap->get_active() || bHorBlock );
714 // shrink only without automatic line break, and not for block, fill or distribute.
715 m_xBtnShrink->set_sensitive( (m_xBtnWrap->get_state() == TRISTATE_FALSE) && !bHorBlock && !bHorFill && !bHorDist );
717 // visibility of frames
718 m_xAlignmentFrame->set_visible(m_xLbHorAlign->get_visible() || m_xEdIndent->get_visible() ||
719 m_xLbVerAlign->get_visible());
720 m_xOrientFrame->set_visible(m_xCtrlDialWin->get_visible() || m_xVsRefEdge->get_visible() ||
721 m_xCbStacked->get_visible() || m_xCbAsianMode->get_visible());
722 m_xPropertiesFrame->set_visible(m_xBtnWrap->get_visible() || m_xBtnHyphen->get_visible() ||
723 m_xBtnShrink->get_visible() || m_xLbFrameDir->get_visible());
725 bool bStackedText = m_xCbStacked->get_active();
726 // windows to be disabled, if stacked text is turned ON
727 m_xFtRotate->set_sensitive(!bStackedText);
728 m_xFtRefEdge->set_sensitive(!bStackedText);
729 m_xVsRefEdge->set_sensitive(!bStackedText);
730 // windows to be disabled, if stacked text is turned OFF
731 m_xCbAsianMode->set_sensitive(bStackedText);
732 // rotation/stacked disabled for fill alignment/stacked
733 m_xCtrlDialWin->set_sensitive(!bHorFill && !bStackedText);
734 m_xNfRotate->set_sensitive(!bHorFill && !bStackedText);
737 bool AlignmentTabPage::HasAlignmentChanged( const SfxItemSet& rNew, TypedWhichId<SfxEnumItemInterface> nWhich ) const
739 const SfxItemSet& rOld = GetItemSet();
740 SvxCellJustifyMethod eMethodOld = SvxCellJustifyMethod::Auto;
741 SvxCellJustifyMethod eMethodNew = SvxCellJustifyMethod::Auto;
742 if (const SfxEnumItemInterface* p = rOld.GetItemIfSet(nWhich))
744 eMethodOld = static_cast<SvxCellJustifyMethod>(p->GetEnumValue());
747 if (const SfxEnumItemInterface* p = rNew.GetItemIfSet(nWhich))
749 eMethodNew = static_cast<SvxCellJustifyMethod>(p->GetEnumValue());
752 return eMethodOld != eMethodNew;
755 IMPL_LINK(AlignmentTabPage, StackedClickHdl, weld::Toggleable&, rToggle, void)
757 m_aStackedState.ButtonToggled(rToggle);
758 UpdateEnableControls();
761 IMPL_LINK(AlignmentTabPage, AsianModeClickHdl, weld::Toggleable&, rToggle, void)
763 m_aAsianModeState.ButtonToggled(rToggle);
766 IMPL_LINK(AlignmentTabPage, WrapClickHdl, weld::Toggleable&, rToggle, void)
768 m_aWrapState.ButtonToggled(rToggle);
769 UpdateEnableControls();
772 IMPL_LINK(AlignmentTabPage, HyphenClickHdl, weld::Toggleable&, rToggle, void)
774 m_aHyphenState.ButtonToggled(rToggle);
777 IMPL_LINK(AlignmentTabPage, ShrinkClickHdl, weld::Toggleable&, rToggle, void)
779 m_aShrinkState.ButtonToggled(rToggle);
782 IMPL_LINK_NOARG(AlignmentTabPage, UpdateEnableHdl, weld::ComboBox&, void)
784 UpdateEnableControls();
789 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */