1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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);
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
)
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();
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();
95 case CombinedEnumContext(Application::WriterVariants
, Context::Default
):
96 case CombinedEnumContext(Application::WriterVariants
, Context::Text
):
97 mxTBxVertAlign
->hide();
98 mxTBxBackColor
->show();
99 mxTBxNumBullet
->show();
103 case CombinedEnumContext(Application::WriterVariants
, Context::Table
):
104 mxTBxVertAlign
->show();
105 mxTBxBackColor
->show();
106 mxTBxNumBullet
->show();
110 case CombinedEnumContext(Application::WriterVariants
, Context::Annotation
):
111 mxTBxVertAlign
->hide();
112 mxTBxBackColor
->hide();
113 mxTBxNumBullet
->hide();
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
):
130 void ParaPropertyPanel::ReSize()
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()
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(
192 const SfxPoolItem
* pState
)
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
);
209 m_last_eMetricUnit
= m_eMetricUnit
;
213 case SID_ATTR_PARA_LRSPACE
:
214 StateChangedIndentImpl( eState
, pState
);
217 case SID_ATTR_PARA_ULSPACE
:
218 StateChangedULImpl( eState
, pState
);
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
);
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
);
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
);
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("");
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("");
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());
368 SfxViewFrame
* pFrame
= SfxViewFrame::Current();
369 SfxObjectShell
* pSh
= nullptr;
371 pSh
= pFrame
->GetObjectShell();
372 if ( pSh
) //the object shell is not always available during reload
374 SfxModule
* pModule
= pSh
->GetModule();
377 const SfxPoolItem
* pItem
= pModule
->GetItem( SID_ATTR_METRIC
);
379 eUnit
= static_cast<FieldUnit
>(static_cast<const SfxUInt16Item
*>(pItem
)->GetValue());
383 SAL_WARN("svx.sidebar", "GetModuleFieldUnit(): no module found");
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"),
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
)),
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
)),
423 m_eMetricUnit(FieldUnit::NONE
),
424 m_last_eMetricUnit(FieldUnit::NONE
),
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
);
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();
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: */