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 .
20 #include "AlignmentPropertyPanel.hxx"
21 #include <editeng/justifyitem.hxx>
24 #include <scitems.hxx>
25 #include <sfx2/bindings.hxx>
26 #include <sfx2/dispatch.hxx>
27 #include <svl/intitem.hxx>
28 #include <svx/rotmodit.hxx>
29 #include <svx/sdangitm.hxx>
30 #include <svtools/unitconv.hxx>
31 #include <unotools/localedatawrapper.hxx>
32 #include <com/sun/star/lang/IllegalArgumentException.hpp>
33 #include <boost/property_tree/json_parser.hpp>
34 #include <sfx2/lokhelper.hxx>
35 #include <comphelper/lok.hxx>
38 using namespace css::uno
;
42 namespace sc::sidebar
{
44 AlignmentPropertyPanel::AlignmentPropertyPanel(
46 const css::uno::Reference
<css::frame::XFrame
>& rxFrame
,
47 SfxBindings
* pBindings
)
48 : PanelLayout(pParent
, "AlignmentPropertyPanel", "modules/scalc/ui/sidebaralignment.ui", rxFrame
, true)
49 , mxFTLeftIndent(m_xBuilder
->weld_label("leftindentlabel"))
50 , mxMFLeftIndent(m_xBuilder
->weld_metric_spin_button("leftindent", FieldUnit::POINT
))
51 , mxCBXWrapText(m_xBuilder
->weld_check_button("wraptext"))
52 , mxCBXMergeCell(m_xBuilder
->weld_check_button("mergecells"))
53 , mxFtRotate(m_xBuilder
->weld_label("orientationlabel"))
54 , mxMtrAngle(m_xBuilder
->weld_metric_spin_button("orientationdegrees", FieldUnit::DEGREE
))
55 , mxRefEdgeBottom(m_xBuilder
->weld_radio_button("bottom"))
56 , mxRefEdgeTop(m_xBuilder
->weld_radio_button("top"))
57 , mxRefEdgeStd(m_xBuilder
->weld_radio_button("standard"))
58 , mxCBStacked(m_xBuilder
->weld_check_button("stacked"))
59 , mxTextOrientBox(m_xBuilder
->weld_widget("textorientbox"))
60 , mxHorizontalAlign(m_xBuilder
->weld_toolbar("horizontalalignment"))
61 , mxHorizontalAlignDispatch(new ToolbarUnoDispatcher(*mxHorizontalAlign
, rxFrame
))
62 , mxVertAlign(m_xBuilder
->weld_toolbar("verticalalignment"))
63 , mxVertAlignDispatch(new ToolbarUnoDispatcher(*mxVertAlign
, rxFrame
))
64 , mxWriteDirection(m_xBuilder
->weld_toolbar("writedirection"))
65 , mxWriteDirectionDispatch(new ToolbarUnoDispatcher(*mxWriteDirection
, rxFrame
))
66 , mxIndentButtons(m_xBuilder
->weld_toolbar("indentbuttons"))
67 , mxIndentButtonsDispatch(new ToolbarUnoDispatcher(*mxIndentButtons
, rxFrame
))
68 , maAlignHorControl(SID_H_ALIGNCELL
, *pBindings
, *this)
69 , maLeftIndentControl(SID_ATTR_ALIGN_INDENT
, *pBindings
, *this)
70 , maMergeCellControl(FID_MERGE_TOGGLE
, *pBindings
, *this)
71 , maWrapTextControl(SID_ATTR_ALIGN_LINEBREAK
, *pBindings
, *this)
72 , maAngleControl(SID_ATTR_ALIGN_DEGREES
, *pBindings
, *this)
73 , maVrtStackControl(SID_ATTR_ALIGN_STACKED
, *pBindings
, *this)
74 , maRefEdgeControl(SID_ATTR_ALIGN_LOCKPOS
, *pBindings
, *this)
75 , mbMultiDisable(false)
76 , mbSettingToggles(false)
78 , mpBindings(pBindings
)
83 AlignmentPropertyPanel::~AlignmentPropertyPanel()
88 void AlignmentPropertyPanel::dispose()
90 mxIndentButtonsDispatch
.reset();
91 mxIndentButtons
.reset();
92 mxWriteDirectionDispatch
.reset();
93 mxWriteDirection
.reset();
94 mxVertAlignDispatch
.reset();
96 mxHorizontalAlignDispatch
.reset();
97 mxHorizontalAlign
.reset();
99 mxFTLeftIndent
.reset();
100 mxMFLeftIndent
.reset();
101 mxCBXWrapText
.reset();
102 mxCBXMergeCell
.reset();
106 mxRefEdgeBottom
.reset();
107 mxRefEdgeTop
.reset();
108 mxRefEdgeStd
.reset();
109 mxTextOrientBox
.reset();
111 maAlignHorControl
.dispose();
112 maLeftIndentControl
.dispose();
113 maMergeCellControl
.dispose();
114 maWrapTextControl
.dispose();
115 maAngleControl
.dispose();
116 maVrtStackControl
.dispose();
117 maRefEdgeControl
.dispose();
119 PanelLayout::dispose();
122 void AlignmentPropertyPanel::Initialize()
124 mxFTLeftIndent
->set_sensitive(false);
125 mxMFLeftIndent
->set_sensitive(false);
126 Link
<weld::MetricSpinButton
&,void> aLink
= LINK(this, AlignmentPropertyPanel
, MFLeftIndentMdyHdl
);
127 mxMFLeftIndent
->connect_value_changed( aLink
);
129 mxCBXMergeCell
->connect_toggled( LINK(this, AlignmentPropertyPanel
, CBOXMergnCellClkHdl
) );
131 mxCBXWrapText
->connect_toggled( LINK(this, AlignmentPropertyPanel
, CBOXWrapTextClkHdl
) );
134 mxMtrAngle
->connect_value_changed(LINK( this, AlignmentPropertyPanel
, AngleModifiedHdl
));
135 mxCBStacked
->connect_toggled(LINK(this, AlignmentPropertyPanel
, ClickStackHdl
));
137 Link
<weld::ToggleButton
&,void> aLink2
= LINK(this, AlignmentPropertyPanel
, ReferenceEdgeHdl
);
138 mxRefEdgeBottom
->connect_toggled(aLink2
);
139 mxRefEdgeTop
->connect_toggled(aLink2
);
140 mxRefEdgeStd
->connect_toggled(aLink2
);
145 void eraseNode(boost::property_tree::ptree
& pTree
, const std::string
& aValue
)
147 boost::optional
<boost::property_tree::ptree
&> pId
;
148 boost::optional
<boost::property_tree::ptree
&> pSubTree
= pTree
.get_child_optional("children");
152 boost::property_tree::ptree::iterator itFound
= pSubTree
.get().end();
153 for (boost::property_tree::ptree::iterator it
= pSubTree
.get().begin(); it
!= pSubTree
.get().end(); ++it
)
155 pId
= it
->second
.get_child_optional("id");
156 if (pId
&& pId
.get().get_value
<std::string
>("") == aValue
)
162 eraseNode(it
->second
, aValue
);
165 if (itFound
!= pSubTree
.get().end())
167 pSubTree
.get().erase(itFound
);
174 boost::property_tree::ptree
AlignmentPropertyPanel::DumpAsPropertyTree()
176 boost::property_tree::ptree aTree
= PanelLayout::DumpAsPropertyTree();
178 if (comphelper::LibreOfficeKit::isMobile(SfxLokHelper::getView()))
180 eraseNode(aTree
, "textorientbox");
186 IMPL_LINK(AlignmentPropertyPanel
, ReferenceEdgeHdl
, weld::ToggleButton
&, rToggle
, void)
188 if (mbSettingToggles
)
191 if (&rToggle
== mxRefEdgeBottom
.get() && mxRefEdgeBottom
->get_active())
192 eMode
= SVX_ROTATE_MODE_BOTTOM
;
193 else if (&rToggle
== mxRefEdgeTop
.get() && mxRefEdgeTop
->get_active())
194 eMode
= SVX_ROTATE_MODE_TOP
;
195 else if (&rToggle
== mxRefEdgeStd
.get() && mxRefEdgeStd
->get_active())
196 eMode
= SVX_ROTATE_MODE_STANDARD
;
199 SvxRotateModeItem
aItem(eMode
, ATTR_ROTATE_MODE
);
200 GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_ALIGN_LOCKPOS
,
201 SfxCallMode::RECORD
, { &aItem
});
204 IMPL_LINK_NOARG( AlignmentPropertyPanel
, AngleModifiedHdl
, weld::MetricSpinButton
&, void )
206 sal_uInt32 nAngle
= mxMtrAngle
->get_value(FieldUnit::DEGREE
) * 100;
207 ScRotateValueItem
aAngleItem(nAngle
);
209 GetBindings()->GetDispatcher()->ExecuteList(
210 SID_ATTR_ALIGN_DEGREES
, SfxCallMode::RECORD
, { &aAngleItem
});
213 IMPL_LINK_NOARG( AlignmentPropertyPanel
, ClickStackHdl
, weld::ToggleButton
&, void )
215 bool bVertical
= mxCBStacked
->get_active();
216 ScVerticalStackCell
aStackItem(bVertical
);
217 GetBindings()->GetDispatcher()->ExecuteList(
218 SID_ATTR_ALIGN_STACKED
, SfxCallMode::RECORD
, { &aStackItem
});
221 IMPL_LINK_NOARG(AlignmentPropertyPanel
, MFLeftIndentMdyHdl
, weld::MetricSpinButton
&, void)
223 sal_uInt16 nVal
= mxMFLeftIndent
->get_value(FieldUnit::NONE
);
224 ScIndentItem
aItem(static_cast<sal_uInt16
>(CalcToUnit(nVal
, MapUnit::MapTwip
)));
226 GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_ALIGN_INDENT
,
227 SfxCallMode::RECORD
, { &aItem
});
230 IMPL_LINK_NOARG(AlignmentPropertyPanel
, CBOXMergnCellClkHdl
, weld::ToggleButton
&, void)
232 bool bState
= mxCBXMergeCell
->get_active();
235 GetBindings()->GetDispatcher()->Execute(FID_MERGE_ON
, SfxCallMode::RECORD
);
237 GetBindings()->GetDispatcher()->Execute(FID_MERGE_OFF
, SfxCallMode::RECORD
);
238 GetBindings()->Invalidate(FID_MERGE_TOGGLE
,true);
241 IMPL_LINK_NOARG(AlignmentPropertyPanel
, CBOXWrapTextClkHdl
, weld::ToggleButton
&, void)
243 bool bState
= mxCBXWrapText
->get_active();
244 ScLineBreakCell
aItem(bState
);
245 GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_ALIGN_LINEBREAK
,
246 SfxCallMode::RECORD
, { &aItem
});
249 VclPtr
<vcl::Window
> AlignmentPropertyPanel::Create (
250 vcl::Window
* pParent
,
251 const css::uno::Reference
<css::frame::XFrame
>& rxFrame
,
252 SfxBindings
* pBindings
)
254 if (pParent
== nullptr)
255 throw lang::IllegalArgumentException("no parent Window given to AlignmentPropertyPanel::Create", nullptr, 0);
257 throw lang::IllegalArgumentException("no XFrame given to AlignmentPropertyPanel::Create", nullptr, 1);
258 if (pBindings
== nullptr)
259 throw lang::IllegalArgumentException("no SfxBindings given to AlignmentPropertyPanel::Create", nullptr, 2);
261 return VclPtr
<AlignmentPropertyPanel
>::Create(
262 pParent
, rxFrame
, pBindings
);
265 void AlignmentPropertyPanel::DataChanged(
266 const DataChangedEvent
&)
269 void AlignmentPropertyPanel::HandleContextChange(
270 const vcl::EnumContext
& rContext
)
272 if (maContext
== rContext
)
278 maContext
= rContext
;
281 void AlignmentPropertyPanel::NotifyItemUpdate(
284 const SfxPoolItem
* pState
)
288 case SID_H_ALIGNCELL
:
290 SvxCellHorJustify meHorAlignState
= SvxCellHorJustify::Standard
;
291 if(eState
>= SfxItemState::DEFAULT
&& dynamic_cast<const SvxHorJustifyItem
*>( pState
) )
293 const SvxHorJustifyItem
* pItem
= static_cast<const SvxHorJustifyItem
*>(pState
);
294 meHorAlignState
= pItem
->GetValue();
297 if( meHorAlignState
== SvxCellHorJustify::Repeat
)
299 mxFtRotate
->set_sensitive(false);
300 mxMtrAngle
->set_sensitive(false);
304 mxFtRotate
->set_sensitive(!mbMultiDisable
);
305 mxMtrAngle
->set_sensitive(!mbMultiDisable
);
308 mxFTLeftIndent
->set_sensitive( meHorAlignState
== SvxCellHorJustify::Left
);
309 mxMFLeftIndent
->set_sensitive( meHorAlignState
== SvxCellHorJustify::Left
);
312 case SID_ATTR_ALIGN_INDENT
:
313 if(eState
>= SfxItemState::DEFAULT
&& dynamic_cast<const SfxUInt16Item
*>( pState
) )
315 const SfxUInt16Item
* pItem
= static_cast<const SfxUInt16Item
*>(pState
);
316 sal_uInt16 nVal
= pItem
->GetValue();
317 mxMFLeftIndent
->set_value( CalcToPoint(nVal
, MapUnit::MapTwip
, 1), FieldUnit::NONE
);
321 mxMFLeftIndent
->set_value(0, FieldUnit::NONE
);
322 mxMFLeftIndent
->set_text(OUString());
325 case FID_MERGE_TOGGLE
:
326 if(eState
>= SfxItemState::DEFAULT
&& dynamic_cast<const SfxBoolItem
*>( pState
) )
328 mxCBXMergeCell
->set_sensitive(true);
329 const SfxBoolItem
* pItem
= static_cast<const SfxBoolItem
*>(pState
);
330 mxCBXMergeCell
->set_active(pItem
->GetValue());
334 mxCBXMergeCell
->set_active(false);
335 mxCBXMergeCell
->set_sensitive(false);
339 case SID_ATTR_ALIGN_LINEBREAK
:
340 if(eState
== SfxItemState::DISABLED
)
342 mxCBXWrapText
->set_active(false);
343 mxCBXWrapText
->set_sensitive(false);
347 mxCBXWrapText
->set_sensitive(true);
348 if(eState
>= SfxItemState::DEFAULT
&& dynamic_cast<const ScLineBreakCell
*>( pState
) )
350 const ScLineBreakCell
* pItem
= static_cast<const ScLineBreakCell
*>(pState
);
351 mxCBXWrapText
->set_active(pItem
->GetValue());
353 else if(eState
== SfxItemState::DONTCARE
)
355 mxCBXWrapText
->set_state(TRISTATE_INDET
);
359 case SID_ATTR_ALIGN_STACKED
:
360 if (eState
>= SfxItemState::DEFAULT
)
362 const SfxBoolItem
* pStackItem
= static_cast<const ScVerticalStackCell
*>(pState
);
363 mbMultiDisable
= pStackItem
->GetValue();
364 mxCBStacked
->set_active(mbMultiDisable
);
365 mxTextOrientBox
->set_sensitive(!mbMultiDisable
);
369 mbMultiDisable
= true;
370 mxTextOrientBox
->set_sensitive(false);
371 mxCBStacked
->set_state(TRISTATE_INDET
);
374 case SID_ATTR_ALIGN_LOCKPOS
:
375 if( eState
>= SfxItemState::DEFAULT
)
377 mbSettingToggles
= true;
378 const SvxRotateModeItem
* pItem
= static_cast<const SvxRotateModeItem
*>(pState
);
379 SvxRotateMode eMode
= pItem
->GetValue();
380 if(eMode
== SVX_ROTATE_MODE_BOTTOM
)
382 mxRefEdgeBottom
->set_state(TRISTATE_TRUE
);
384 else if(eMode
== SVX_ROTATE_MODE_TOP
)
386 mxRefEdgeTop
->set_state(TRISTATE_TRUE
);
388 else if(eMode
== SVX_ROTATE_MODE_STANDARD
)
390 mxRefEdgeStd
->set_state(TRISTATE_TRUE
);
392 mbSettingToggles
= false;
395 case SID_ATTR_ALIGN_DEGREES
:
396 if (eState
>= SfxItemState::DEFAULT
)
398 long nTmp
= static_cast<const ScRotateValueItem
*>(pState
)->GetValue();
399 mxMtrAngle
->set_value(nTmp
/ 100, FieldUnit::DEGREE
);
403 mxMtrAngle
->set_text( OUString() );
411 } // end of namespace ::sc::sidebar
413 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */