Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / svx / source / sidebar / paragraph / ParaPropertyPanel.cxx
blob20e05096d6c46735b647e2d8908d68de285616de
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 .
19 #include "ParaPropertyPanel.hxx"
20 #include <sfx2/dispatch.hxx>
21 #include <sfx2/module.hxx>
22 #include <sfx2/viewfrm.hxx>
23 #include <sfx2/weldutils.hxx>
24 #include <editeng/lrspitem.hxx>
25 #include <editeng/ulspitem.hxx>
26 #include <svx/dlgctrl.hxx>
27 #include <svx/svxids.hrc>
28 #include <svl/intitem.hxx>
29 #include <sfx2/objsh.hxx>
30 #include <svtools/unitconv.hxx>
31 #include <sal/log.hxx>
33 #include <com/sun/star/lang/IllegalArgumentException.hpp>
34 #include <utility>
36 using namespace css;
37 using namespace css::uno;
39 namespace svx::sidebar {
40 #define DEFAULT_VALUE 0
42 #define MAX_DURCH 31680 // tdf#68335: 1584 pt for UX interoperability with Word
44 #define MAX_SW 1709400
45 #define MAX_SC_SD 116220200
46 #define NEGA_MAXVALUE -10000000
48 std::unique_ptr<PanelLayout> ParaPropertyPanel::Create (
49 weld::Widget* pParent,
50 const css::uno::Reference<css::frame::XFrame>& rxFrame,
51 SfxBindings* pBindings,
52 const css::uno::Reference<css::ui::XSidebar>& rxSidebar)
54 if (pParent == nullptr)
55 throw lang::IllegalArgumentException("no parent Window given to ParaPropertyPanel::Create", nullptr, 0);
56 if ( ! rxFrame.is())
57 throw lang::IllegalArgumentException("no XFrame given to ParaPropertyPanel::Create", nullptr, 1);
58 if (pBindings == nullptr)
59 throw lang::IllegalArgumentException("no SfxBindings given to ParaPropertyPanel::Create", nullptr, 2);
61 return std::make_unique<ParaPropertyPanel>(pParent, rxFrame, pBindings, rxSidebar);
64 void ParaPropertyPanel::HandleContextChange (
65 const vcl::EnumContext& rContext)
67 if (maContext == rContext)
69 // Nothing to do.
70 return;
73 maContext = rContext;
74 switch (maContext.GetCombinedContext_DI())
76 case CombinedEnumContext(Application::Calc, Context::DrawText):
77 case CombinedEnumContext(Application::WriterVariants, Context::DrawText):
78 mxTBxVertAlign->show();
79 mxTBxBackColor->hide();
80 mxTBxNumBullet->hide();
81 ReSize();
82 break;
84 case CombinedEnumContext(Application::DrawImpress, Context::Draw):
85 case CombinedEnumContext(Application::DrawImpress, Context::TextObject):
86 case CombinedEnumContext(Application::DrawImpress, Context::Graphic):
87 case CombinedEnumContext(Application::DrawImpress, Context::DrawText):
88 case CombinedEnumContext(Application::DrawImpress, Context::Table):
89 mxTBxVertAlign->show();
90 mxTBxBackColor->hide();
91 mxTBxNumBullet->hide();
92 ReSize();
93 break;
95 case CombinedEnumContext(Application::WriterVariants, Context::Default):
96 case CombinedEnumContext(Application::WriterVariants, Context::Text):
97 mxTBxVertAlign->hide();
98 mxTBxBackColor->show();
99 mxTBxNumBullet->show();
100 ReSize();
101 break;
103 case CombinedEnumContext(Application::WriterVariants, Context::Table):
104 mxTBxVertAlign->show();
105 mxTBxBackColor->show();
106 mxTBxNumBullet->show();
107 ReSize();
108 break;
110 case CombinedEnumContext(Application::WriterVariants, Context::Annotation):
111 mxTBxVertAlign->hide();
112 mxTBxBackColor->hide();
113 mxTBxNumBullet->hide();
114 ReSize();
115 break;
117 case CombinedEnumContext(Application::Calc, Context::EditCell):
118 case CombinedEnumContext(Application::Calc, Context::Cell):
119 case CombinedEnumContext(Application::Calc, Context::Pivot):
120 case CombinedEnumContext(Application::Calc, Context::Sparkline):
121 case CombinedEnumContext(Application::DrawImpress, Context::Text):
122 case CombinedEnumContext(Application::DrawImpress, Context::OutlineText):
123 break;
125 default:
126 break;
130 void ParaPropertyPanel::ReSize()
132 if (mxSidebar.is())
133 mxSidebar->requestLayout();
136 void ParaPropertyPanel::InitToolBoxIndent()
138 Link<weld::MetricSpinButton&,void> aLink = LINK( this, ParaPropertyPanel, ModifyIndentHdl_Impl );
139 mxLeftIndent->connect_value_changed( aLink );
140 mxRightIndent->connect_value_changed( aLink );
141 mxFLineIndent->connect_value_changed( aLink );
143 m_eLRSpaceUnit = maLRSpaceControl.GetCoreMetric();
146 void ParaPropertyPanel::InitToolBoxSpacing()
148 Link<weld::MetricSpinButton&,void> aLink = LINK( this, ParaPropertyPanel, ULSpaceHdl_Impl );
149 mxTopDist->connect_value_changed(aLink);
150 mxBottomDist->connect_value_changed( aLink );
152 m_eULSpaceUnit = maULSpaceControl.GetCoreMetric();
155 void ParaPropertyPanel::initial()
157 limitMetricWidths();
159 //toolbox
160 InitToolBoxIndent();
161 InitToolBoxSpacing();
164 // for Paragraph Indent
165 IMPL_LINK_NOARG( ParaPropertyPanel, ModifyIndentHdl_Impl, weld::MetricSpinButton&, void)
167 SvxLRSpaceItem aMargin( SID_ATTR_PARA_LRSPACE );
168 aMargin.SetTextLeft(mxLeftIndent->GetCoreValue(m_eLRSpaceUnit));
169 aMargin.SetRight(mxRightIndent->GetCoreValue(m_eLRSpaceUnit));
170 aMargin.SetTextFirstLineOffset(static_cast<short>(mxFLineIndent->GetCoreValue(m_eLRSpaceUnit)));
172 GetBindings()->GetDispatcher()->ExecuteList(
173 SID_ATTR_PARA_LRSPACE, SfxCallMode::RECORD, { &aMargin });
177 // for Paragraph Spacing
178 IMPL_LINK_NOARG( ParaPropertyPanel, ULSpaceHdl_Impl, weld::MetricSpinButton&, void)
180 SvxULSpaceItem aMargin( SID_ATTR_PARA_ULSPACE );
181 aMargin.SetUpper( static_cast<sal_uInt16>(mxTopDist->GetCoreValue(m_eULSpaceUnit)));
182 aMargin.SetLower( static_cast<sal_uInt16>(mxBottomDist->GetCoreValue(m_eULSpaceUnit)));
184 GetBindings()->GetDispatcher()->ExecuteList(
185 SID_ATTR_PARA_ULSPACE, SfxCallMode::RECORD, { &aMargin });
188 // for Paragraph State change
189 void ParaPropertyPanel::NotifyItemUpdate(
190 sal_uInt16 nSID,
191 SfxItemState eState,
192 const SfxPoolItem* pState)
194 switch (nSID)
196 case SID_ATTR_METRIC:
198 m_eMetricUnit = GetCurrentUnit(eState,pState);
199 if( m_eMetricUnit!=m_last_eMetricUnit )
201 mxLeftIndent->SetFieldUnit(m_eMetricUnit);
202 mxRightIndent->SetFieldUnit(m_eMetricUnit);
203 mxFLineIndent->SetFieldUnit(m_eMetricUnit);
204 mxTopDist->SetFieldUnit(m_eMetricUnit);
205 mxBottomDist->SetFieldUnit(m_eMetricUnit);
207 limitMetricWidths();
209 m_last_eMetricUnit = m_eMetricUnit;
211 break;
213 case SID_ATTR_PARA_LRSPACE:
214 StateChangedIndentImpl( eState, pState );
215 break;
217 case SID_ATTR_PARA_ULSPACE:
218 StateChangedULImpl( eState, pState );
219 break;
223 void ParaPropertyPanel::StateChangedIndentImpl( SfxItemState eState, const SfxPoolItem* pState )
225 switch (maContext.GetCombinedContext_DI())
228 case CombinedEnumContext(Application::WriterVariants, Context::DrawText):
229 case CombinedEnumContext(Application::WriterVariants, Context::Annotation):
230 case CombinedEnumContext(Application::Calc, Context::DrawText):
231 case CombinedEnumContext(Application::DrawImpress, Context::DrawText):
232 case CombinedEnumContext(Application::DrawImpress, Context::Draw):
233 case CombinedEnumContext(Application::DrawImpress, Context::TextObject):
234 case CombinedEnumContext(Application::DrawImpress, Context::Graphic):
235 case CombinedEnumContext(Application::DrawImpress, Context::Table):
237 mxLeftIndent->set_min( DEFAULT_VALUE, FieldUnit::NONE );
238 mxRightIndent->set_min( DEFAULT_VALUE, FieldUnit::NONE );
239 mxFLineIndent->set_min( DEFAULT_VALUE, FieldUnit::NONE );
241 break;
242 case CombinedEnumContext(Application::WriterVariants, Context::Default):
243 case CombinedEnumContext(Application::WriterVariants, Context::Text):
244 case CombinedEnumContext(Application::WriterVariants, Context::Table):
246 mxLeftIndent->set_min( NEGA_MAXVALUE, FieldUnit::MM_100TH );
247 mxRightIndent->set_min( NEGA_MAXVALUE, FieldUnit::MM_100TH );
248 mxFLineIndent->set_min( NEGA_MAXVALUE, FieldUnit::MM_100TH );
250 break;
253 bool bDisabled = eState == SfxItemState::DISABLED;
254 mxLeftIndent->set_sensitive(!bDisabled);
255 mxRightIndent->set_sensitive(!bDisabled);
256 mxFLineIndent->set_sensitive(!bDisabled);
258 if (pState && eState >= SfxItemState::DEFAULT)
260 const SvxLRSpaceItem* pSpace = static_cast<const SvxLRSpaceItem*>(pState);
261 maTxtLeft = pSpace->GetTextLeft();
262 maTxtLeft = OutputDevice::LogicToLogic(maTxtLeft, m_eLRSpaceUnit, MapUnit::MapTwip);
264 tools::Long aTxtRight = pSpace->GetRight();
265 aTxtRight = OutputDevice::LogicToLogic(aTxtRight, m_eLRSpaceUnit, MapUnit::MapTwip);
267 tools::Long aTxtFirstLineOfst = pSpace->GetTextFirstLineOffset();
268 aTxtFirstLineOfst = OutputDevice::LogicToLogic( aTxtFirstLineOfst, m_eLRSpaceUnit, MapUnit::MapTwip );
270 tools::Long nVal = o3tl::convert(maTxtLeft, o3tl::Length::twip, o3tl::Length::mm100);
271 nVal = static_cast<tools::Long>(mxLeftIndent->normalize( nVal ));
273 if ( maContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Text)
274 && maContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Default)
275 && maContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Table))
277 mxFLineIndent->set_min( nVal*-1, FieldUnit::MM_100TH );
280 tools::Long nrVal = o3tl::convert(aTxtRight, o3tl::Length::twip, o3tl::Length::mm100);
281 nrVal = static_cast<tools::Long>(mxRightIndent->normalize( nrVal ));
283 switch (maContext.GetCombinedContext_DI())
285 case CombinedEnumContext(Application::WriterVariants, Context::DrawText):
286 case CombinedEnumContext(Application::WriterVariants, Context::Text):
287 case CombinedEnumContext(Application::WriterVariants, Context::Default):
288 case CombinedEnumContext(Application::WriterVariants, Context::Table):
289 case CombinedEnumContext(Application::WriterVariants, Context::Annotation):
291 mxLeftIndent->set_max( MAX_SW - nrVal, FieldUnit::MM_100TH );
292 mxRightIndent->set_max( MAX_SW - nVal, FieldUnit::MM_100TH );
293 mxFLineIndent->set_max( MAX_SW - nVal - nrVal, FieldUnit::MM_100TH );
295 break;
296 case CombinedEnumContext(Application::DrawImpress, Context::DrawText):
297 case CombinedEnumContext(Application::DrawImpress, Context::Draw):
298 case CombinedEnumContext(Application::DrawImpress, Context::Table):
299 case CombinedEnumContext(Application::DrawImpress, Context::TextObject):
300 case CombinedEnumContext(Application::DrawImpress, Context::Graphic):
302 mxLeftIndent->set_max( MAX_SC_SD - nrVal, FieldUnit::MM_100TH );
303 mxRightIndent->set_max( MAX_SC_SD - nVal, FieldUnit::MM_100TH );
304 mxFLineIndent->set_max( MAX_SC_SD - nVal - nrVal, FieldUnit::MM_100TH );
308 mxLeftIndent->set_value( nVal, FieldUnit::MM_100TH );
309 mxRightIndent->set_value( nrVal, FieldUnit::MM_100TH );
311 tools::Long nfVal = o3tl::convert(aTxtFirstLineOfst, o3tl::Length::twip, o3tl::Length::mm100);
312 nfVal = static_cast<tools::Long>(mxFLineIndent->normalize( nfVal ));
313 mxFLineIndent->set_value( nfVal, FieldUnit::MM_100TH );
315 else if (eState != SfxItemState::DISABLED )
317 mxLeftIndent->set_text("");
318 mxRightIndent->set_text("");
319 mxFLineIndent->set_text("");
322 limitMetricWidths();
325 void ParaPropertyPanel::StateChangedULImpl( SfxItemState eState, const SfxPoolItem* pState )
327 mxTopDist->set_max( mxTopDist->normalize( MAX_DURCH ), MapToFieldUnit(m_eULSpaceUnit) );
328 mxBottomDist->set_max( mxBottomDist->normalize( MAX_DURCH ), MapToFieldUnit(m_eULSpaceUnit) );
330 bool bDisabled = eState == SfxItemState::DISABLED;
331 mxTopDist->set_sensitive(!bDisabled);
332 mxBottomDist->set_sensitive(!bDisabled);
334 if( pState && eState >= SfxItemState::DEFAULT )
336 const SvxULSpaceItem* pOldItem = static_cast<const SvxULSpaceItem*>(pState);
338 maUpper = pOldItem->GetUpper();
339 maUpper = OutputDevice::LogicToLogic(maUpper, m_eULSpaceUnit, MapUnit::MapTwip);
341 maLower = pOldItem->GetLower();
342 maLower = OutputDevice::LogicToLogic(maLower, m_eULSpaceUnit, MapUnit::MapTwip);
344 sal_Int64 nVal = o3tl::convert(maUpper, o3tl::Length::twip, o3tl::Length::mm100);
345 nVal = mxTopDist->normalize( nVal );
346 mxTopDist->set_value( nVal, FieldUnit::MM_100TH );
348 nVal = o3tl::convert(maLower, o3tl::Length::twip, o3tl::Length::mm100);
349 nVal = mxBottomDist->normalize( nVal );
350 mxBottomDist->set_value( nVal, FieldUnit::MM_100TH );
352 else if (eState != SfxItemState::DISABLED )
354 mxTopDist->set_text("");
355 mxBottomDist->set_text("");
357 limitMetricWidths();
360 FieldUnit ParaPropertyPanel::GetCurrentUnit( SfxItemState eState, const SfxPoolItem* pState )
362 FieldUnit eUnit = FieldUnit::NONE;
364 if ( pState && eState >= SfxItemState::DEFAULT )
365 eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pState)->GetValue());
366 else
368 SfxViewFrame* pFrame = SfxViewFrame::Current();
369 SfxObjectShell* pSh = nullptr;
370 if ( pFrame )
371 pSh = pFrame->GetObjectShell();
372 if ( pSh ) //the object shell is not always available during reload
374 SfxModule* pModule = pSh->GetModule();
375 if ( pModule )
377 const SfxPoolItem* pItem = pModule->GetItem( SID_ATTR_METRIC );
378 if ( pItem )
379 eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
381 else
383 SAL_WARN("svx.sidebar", "GetModuleFieldUnit(): no module found");
388 return eUnit;
391 ParaPropertyPanel::ParaPropertyPanel(weld::Widget* pParent,
392 const css::uno::Reference<css::frame::XFrame>& rxFrame,
393 SfxBindings* pBindings,
394 css::uno::Reference<css::ui::XSidebar> xSidebar)
395 : PanelLayout(pParent, "ParaPropertyPanel", "svx/ui/sidebarparagraph.ui"),
396 //Alignment
397 mxTBxHorzAlign(m_xBuilder->weld_toolbar("horizontalalignment")),
398 mxHorzAlignDispatch(new ToolbarUnoDispatcher(*mxTBxHorzAlign, *m_xBuilder, rxFrame)),
399 mxTBxVertAlign(m_xBuilder->weld_toolbar("verticalalignment")),
400 mxVertAlignDispatch(new ToolbarUnoDispatcher(*mxTBxVertAlign, *m_xBuilder, rxFrame)),
401 //NumBullet&Backcolor
402 mxTBxNumBullet(m_xBuilder->weld_toolbar("numberbullet")),
403 mxNumBulletDispatch(new ToolbarUnoDispatcher(*mxTBxNumBullet, *m_xBuilder, rxFrame)),
404 mxTBxBackColor(m_xBuilder->weld_toolbar("backgroundcolor")),
405 mxBackColorDispatch(new ToolbarUnoDispatcher(*mxTBxBackColor, *m_xBuilder, rxFrame)),
406 mxTBxWriteDirection(m_xBuilder->weld_toolbar("writedirection")),
407 mxWriteDirectionDispatch(new ToolbarUnoDispatcher(*mxTBxWriteDirection, *m_xBuilder, rxFrame)),
408 mxTBxParaSpacing(m_xBuilder->weld_toolbar("paraspacing")),
409 mxParaSpacingDispatch(new ToolbarUnoDispatcher(*mxTBxParaSpacing, *m_xBuilder, rxFrame)),
410 mxTBxLineSpacing(m_xBuilder->weld_toolbar("linespacing")),
411 mxLineSpacingDispatch(new ToolbarUnoDispatcher(*mxTBxLineSpacing, *m_xBuilder, rxFrame)),
412 mxTBxIndent(m_xBuilder->weld_toolbar("indent")),
413 mxIndentDispatch(new ToolbarUnoDispatcher(*mxTBxIndent, *m_xBuilder, rxFrame)),
414 //Paragraph spacing
415 mxTopDist(m_xBuilder->weld_metric_spin_button("aboveparaspacing", FieldUnit::CM)),
416 mxBottomDist(m_xBuilder->weld_metric_spin_button("belowparaspacing", FieldUnit::CM)),
417 mxLeftIndent(m_xBuilder->weld_metric_spin_button("beforetextindent", FieldUnit::CM)),
418 mxRightIndent(m_xBuilder->weld_metric_spin_button("aftertextindent", FieldUnit::CM)),
419 mxFLineIndent(m_xBuilder->weld_metric_spin_button("firstlineindent", FieldUnit::CM)),
420 maTxtLeft (0),
421 maUpper (0),
422 maLower (0),
423 m_eMetricUnit(FieldUnit::NONE),
424 m_last_eMetricUnit(FieldUnit::NONE),
425 m_eLRSpaceUnit(),
426 m_eULSpaceUnit(),
427 maLRSpaceControl (SID_ATTR_PARA_LRSPACE,*pBindings,*this),
428 maULSpaceControl (SID_ATTR_PARA_ULSPACE, *pBindings,*this),
429 m_aMetricCtl (SID_ATTR_METRIC, *pBindings,*this),
430 mpBindings(pBindings),
431 mxSidebar(std::move(xSidebar))
433 // tdf#130197 We want to give this toolbar a width as if it had 5 entries
434 // (the parent grid has homogeneous width set so both columns will have the
435 // same width). This ParaPropertyPanel is a default panel in writer, so
436 // subsequent panels, e.g. the TableEditPanel panel can have up to 5
437 // entries in each of its column and remain in alignment with this panel
438 padWidthForSidebar(*mxTBxIndent, rxFrame);
440 initial();
441 m_aMetricCtl.RequestUpdate();
444 void ParaPropertyPanel::limitMetricWidths()
446 limitWidthForSidebar(*mxTopDist);
447 limitWidthForSidebar(*mxBottomDist);
448 limitWidthForSidebar(*mxLeftIndent);
449 limitWidthForSidebar(*mxRightIndent);
450 limitWidthForSidebar(*mxFLineIndent);
453 ParaPropertyPanel::~ParaPropertyPanel()
455 mxHorzAlignDispatch.reset();
456 mxTBxHorzAlign.reset();
458 mxVertAlignDispatch.reset();
459 mxTBxVertAlign.reset();
461 mxNumBulletDispatch.reset();
462 mxTBxNumBullet.reset();
464 mxBackColorDispatch.reset();
465 mxTBxBackColor.reset();
467 mxWriteDirectionDispatch.reset();
468 mxTBxWriteDirection.reset();
470 mxParaSpacingDispatch.reset();
471 mxTBxParaSpacing.reset();
473 mxLineSpacingDispatch.reset();
474 mxTBxLineSpacing.reset();
476 mxIndentDispatch.reset();
477 mxTBxIndent.reset();
479 mxTopDist.reset();
480 mxBottomDist.reset();
481 mxLeftIndent.reset();
482 mxRightIndent.reset();
483 mxFLineIndent.reset();
485 maLRSpaceControl.dispose();
486 maULSpaceControl.dispose();
487 m_aMetricCtl.dispose();
490 } // end of namespace svx::sidebar
492 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */