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 <com/sun/star/chart/ErrorBarStyle.hpp>
21 #include <com/sun/star/beans/XPropertySet.hpp>
23 #include "ChartErrorBarPanel.hxx"
24 #include <ChartController.hxx>
25 #include <ChartModel.hxx>
26 #include <vcl/svapp.hxx>
27 #include <sal/log.hxx>
31 using namespace css::uno
;
33 namespace chart::sidebar
{
37 enum class ErrorBarDirection
43 css::uno::Reference
<css::beans::XPropertySet
> getErrorBarPropSet(
44 const rtl::Reference
<::chart::ChartModel
>& xModel
, std::u16string_view rCID
)
46 return ObjectIdentifier::getObjectPropertySet(rCID
, xModel
);
49 bool showPositiveError(const rtl::Reference
<::chart::ChartModel
>& xModel
,
50 std::u16string_view rCID
)
52 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
=
53 getErrorBarPropSet(xModel
, rCID
);
58 css::uno::Any aAny
= xPropSet
->getPropertyValue("ShowPositiveError");
68 bool showNegativeError(const rtl::Reference
<::chart::ChartModel
>& xModel
,
69 std::u16string_view rCID
)
71 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
=
72 getErrorBarPropSet(xModel
, rCID
);
77 css::uno::Any aAny
= xPropSet
->getPropertyValue("ShowNegativeError");
87 void setShowPositiveError(const rtl::Reference
<::chart::ChartModel
>& xModel
,
88 std::u16string_view rCID
, bool bShow
)
90 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
=
91 getErrorBarPropSet(xModel
, rCID
);
96 xPropSet
->setPropertyValue("ShowPositiveError", css::uno::Any(bShow
));
99 void setShowNegativeError(const rtl::Reference
<::chart::ChartModel
>& xModel
,
100 std::u16string_view rCID
, bool bShow
)
102 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
=
103 getErrorBarPropSet(xModel
, rCID
);
108 xPropSet
->setPropertyValue("ShowNegativeError", css::uno::Any(bShow
));
111 struct ErrorBarTypeMap
117 ErrorBarTypeMap
const aErrorBarType
[] = {
118 { 0, css::chart::ErrorBarStyle::ABSOLUTE
},
119 { 1, css::chart::ErrorBarStyle::RELATIVE
},
120 { 2, css::chart::ErrorBarStyle::FROM_DATA
},
121 { 3, css::chart::ErrorBarStyle::STANDARD_DEVIATION
},
122 { 4, css::chart::ErrorBarStyle::STANDARD_ERROR
},
123 { 5, css::chart::ErrorBarStyle::VARIANCE
},
124 { 6, css::chart::ErrorBarStyle::ERROR_MARGIN
},
127 sal_Int32
getTypePos(const rtl::Reference
<::chart::ChartModel
>& xModel
,
128 std::u16string_view rCID
)
130 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
=
131 getErrorBarPropSet(xModel
, rCID
);
136 css::uno::Any aAny
= xPropSet
->getPropertyValue("ErrorBarStyle");
138 if (!aAny
.hasValue())
144 for (ErrorBarTypeMap
const & i
: aErrorBarType
)
153 void setTypePos(const rtl::Reference
<::chart::ChartModel
>& xModel
,
154 std::u16string_view rCID
, sal_Int32 nPos
)
156 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
=
157 getErrorBarPropSet(xModel
, rCID
);
163 for (ErrorBarTypeMap
const & i
: aErrorBarType
)
169 xPropSet
->setPropertyValue("ErrorBarStyle", css::uno::Any(nApi
));
172 double getValue(const rtl::Reference
<::chart::ChartModel
>& xModel
,
173 std::u16string_view rCID
, ErrorBarDirection eDir
)
175 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
=
176 getErrorBarPropSet(xModel
, rCID
);
181 OUString aName
= "PositiveError";
182 if (eDir
== ErrorBarDirection::NEGATIVE
)
183 aName
= "NegativeError";
185 css::uno::Any aAny
= xPropSet
->getPropertyValue(aName
);
187 if (!aAny
.hasValue())
196 void setValue(const rtl::Reference
<::chart::ChartModel
>& xModel
,
197 std::u16string_view rCID
, double nVal
, ErrorBarDirection eDir
)
199 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
=
200 getErrorBarPropSet(xModel
, rCID
);
205 OUString aName
= "PositiveError";
206 if (eDir
== ErrorBarDirection::NEGATIVE
)
207 aName
= "NegativeError";
209 xPropSet
->setPropertyValue(aName
, css::uno::Any(nVal
));
212 OUString
getCID(const rtl::Reference
<::chart::ChartModel
>& xModel
)
214 css::uno::Reference
<css::frame::XController
> xController(xModel
->getCurrentController());
215 css::uno::Reference
<css::view::XSelectionSupplier
> xSelectionSupplier(xController
, css::uno::UNO_QUERY
);
216 if (!xSelectionSupplier
.is())
219 uno::Any aAny
= xSelectionSupplier
->getSelection();
220 assert(aAny
.hasValue());
223 #if defined DBG_UTIL && !defined NDEBUG
224 ObjectType eType
= ObjectIdentifier::getObjectType(aCID
);
225 if (eType
!= OBJECTTYPE_DATA_ERRORS_X
&&
226 eType
!= OBJECTTYPE_DATA_ERRORS_Y
&&
227 eType
!= OBJECTTYPE_DATA_ERRORS_Z
)
228 SAL_WARN("chart2","Selected item is not an error bar");
237 ChartErrorBarPanel::ChartErrorBarPanel(weld::Widget
* pParent
, ChartController
* pController
)
238 : PanelLayout(pParent
, "ChartErrorBarPanel", "modules/schart/ui/sidebarerrorbar.ui")
239 , mxRBPosAndNeg(m_xBuilder
->weld_radio_button("radiobutton_positive_negative"))
240 , mxRBPos(m_xBuilder
->weld_radio_button("radiobutton_positive"))
241 , mxRBNeg(m_xBuilder
->weld_radio_button("radiobutton_negative"))
242 , mxLBType(m_xBuilder
->weld_combo_box("comboboxtext_type"))
243 , mxMFPos(m_xBuilder
->weld_spin_button("spinbutton_pos"))
244 , mxMFNeg(m_xBuilder
->weld_spin_button("spinbutton_neg"))
245 , mxModel(pController
->getChartModel())
246 , mxListener(new ChartSidebarModifyListener(this))
252 ChartErrorBarPanel::~ChartErrorBarPanel()
254 doUpdateModel(nullptr);
256 mxRBPosAndNeg
.reset();
266 void ChartErrorBarPanel::Initialize()
268 mxModel
->addModifyListener(mxListener
);
269 mxRBNeg
->set_active(false);
270 mxRBPos
->set_active(false);
271 mxRBPosAndNeg
->set_active(false);
275 Link
<weld::Toggleable
&,void> aLink
= LINK(this, ChartErrorBarPanel
, RadioBtnHdl
);
276 mxRBPosAndNeg
->connect_toggled(aLink
);
277 mxRBPos
->connect_toggled(aLink
);
278 mxRBNeg
->connect_toggled(aLink
);
280 mxLBType
->connect_changed(LINK(this, ChartErrorBarPanel
, ListBoxHdl
));
282 Link
<weld::SpinButton
&,void> aLink2
= LINK(this, ChartErrorBarPanel
, NumericFieldHdl
);
283 mxMFPos
->connect_value_changed(aLink2
);
284 mxMFNeg
->connect_value_changed(aLink2
);
287 void ChartErrorBarPanel::updateData()
292 OUString aCID
= getCID(mxModel
);
293 ObjectType eType
= ObjectIdentifier::getObjectType(aCID
);
294 if (eType
!= OBJECTTYPE_DATA_ERRORS_X
&&
295 eType
!= OBJECTTYPE_DATA_ERRORS_Y
&&
296 eType
!= OBJECTTYPE_DATA_ERRORS_Z
)
299 bool bPos
= showPositiveError(mxModel
, aCID
);
300 bool bNeg
= showNegativeError(mxModel
, aCID
);
302 SolarMutexGuard aGuard
;
305 mxRBPosAndNeg
->set_active(true);
307 mxRBPos
->set_active(true);
309 mxRBNeg
->set_active(true);
311 sal_Int32 nTypePos
= getTypePos(mxModel
, aCID
);
312 mxLBType
->set_active(nTypePos
);
317 mxMFPos
->set_sensitive(true);
319 mxMFPos
->set_sensitive(false);
322 mxMFNeg
->set_sensitive(true);
324 mxMFNeg
->set_sensitive(false);
326 double nValPos
= getValue(mxModel
, aCID
, ErrorBarDirection::POSITIVE
);
327 double nValNeg
= getValue(mxModel
, aCID
, ErrorBarDirection::NEGATIVE
);
329 mxMFPos
->set_value(nValPos
);
330 mxMFNeg
->set_value(nValNeg
);
334 mxMFPos
->set_sensitive(false);
335 mxMFNeg
->set_sensitive(false);
339 std::unique_ptr
<PanelLayout
> ChartErrorBarPanel::Create (
340 weld::Widget
* pParent
,
341 ChartController
* pController
)
343 if (pParent
== nullptr)
344 throw lang::IllegalArgumentException("no parent Window given to ChartErrorBarPanel::Create", nullptr, 0);
345 return std::make_unique
<ChartErrorBarPanel
>(pParent
, pController
);
348 void ChartErrorBarPanel::DataChanged(const DataChangedEvent
& rEvent
)
350 PanelLayout::DataChanged(rEvent
);
354 void ChartErrorBarPanel::HandleContextChange(
355 const vcl::EnumContext
& )
360 void ChartErrorBarPanel::NotifyItemUpdate(
362 SfxItemState
/*eState*/,
363 const SfxPoolItem
* /*pState*/ )
367 void ChartErrorBarPanel::modelInvalid()
369 mbModelValid
= false;
372 void ChartErrorBarPanel::doUpdateModel(const rtl::Reference
<::chart::ChartModel
>& xModel
)
376 mxModel
->removeModifyListener(mxListener
);
380 mbModelValid
= mxModel
.is();
385 mxModel
->addModifyListener(mxListener
);
388 void ChartErrorBarPanel::updateModel(css::uno::Reference
<css::frame::XModel
> xModel
)
390 ::chart::ChartModel
* pModel
= dynamic_cast<::chart::ChartModel
*>(xModel
.get());
391 assert(!xModel
|| pModel
);
392 doUpdateModel(pModel
);
395 IMPL_LINK_NOARG(ChartErrorBarPanel
, RadioBtnHdl
, weld::Toggleable
&, void)
397 OUString aCID
= getCID(mxModel
);
398 bool bPos
= mxRBPosAndNeg
->get_active() || mxRBPos
->get_active();
399 bool bNeg
= mxRBPosAndNeg
->get_active() || mxRBNeg
->get_active();
401 setShowPositiveError(mxModel
, aCID
, bPos
);
402 setShowNegativeError(mxModel
, aCID
, bNeg
);
405 IMPL_LINK_NOARG(ChartErrorBarPanel
, ListBoxHdl
, weld::ComboBox
&, void)
407 OUString aCID
= getCID(mxModel
);
408 sal_Int32 nPos
= mxLBType
->get_active();
410 setTypePos(mxModel
, aCID
, nPos
);
413 IMPL_LINK(ChartErrorBarPanel
, NumericFieldHdl
, weld::SpinButton
&, rMetricField
, void)
415 OUString aCID
= getCID(mxModel
);
416 double nVal
= rMetricField
.get_value();
417 if (&rMetricField
== mxMFPos
.get())
418 setValue(mxModel
, aCID
, nVal
, ErrorBarDirection::POSITIVE
);
419 else if (&rMetricField
== mxMFNeg
.get())
420 setValue(mxModel
, aCID
, nVal
, ErrorBarDirection::NEGATIVE
);
423 } // end of namespace ::chart::sidebar
425 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */