Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / chart2 / source / controller / sidebar / ChartErrorBarPanel.cxx
blob4ef3c19228dd1977af4596becb68e51b97b771fa
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 <com/sun/star/chart/ErrorBarStyle.hpp>
21 #include <com/sun/star/util/XModifyBroadcaster.hpp>
22 #include <com/sun/star/beans/XPropertySet.hpp>
24 #include "ChartErrorBarPanel.hxx"
25 #include <ChartController.hxx>
26 #include <vcl/lstbox.hxx>
27 #include <vcl/field.hxx>
28 #include <vcl/button.hxx>
29 #include <vcl/svapp.hxx>
31 using namespace css;
32 using namespace css::uno;
34 namespace chart { namespace sidebar {
36 namespace {
38 enum class ErrorBarDirection
40 POSITIVE,
41 NEGATIVE
44 css::uno::Reference<css::beans::XPropertySet> getErrorBarPropSet(
45 const css::uno::Reference<css::frame::XModel>& xModel, const OUString& rCID)
47 return ObjectIdentifier::getObjectPropertySet(rCID, xModel);
50 bool showPositiveError(const css::uno::Reference<css::frame::XModel>& xModel,
51 const OUString& rCID)
53 css::uno::Reference<css::beans::XPropertySet> xPropSet =
54 getErrorBarPropSet(xModel, rCID);
56 if (!xPropSet.is())
57 return false;
59 css::uno::Any aAny = xPropSet->getPropertyValue("ShowPositiveError");
61 if (!aAny.hasValue())
62 return false;
64 bool bShow = false;
65 aAny >>= bShow;
66 return bShow;
69 bool showNegativeError(const css::uno::Reference<css::frame::XModel>& xModel,
70 const OUString& rCID)
72 css::uno::Reference<css::beans::XPropertySet> xPropSet =
73 getErrorBarPropSet(xModel, rCID);
75 if (!xPropSet.is())
76 return false;
78 css::uno::Any aAny = xPropSet->getPropertyValue("ShowNegativeError");
80 if (!aAny.hasValue())
81 return false;
83 bool bShow = false;
84 aAny >>= bShow;
85 return bShow;
88 void setShowPositiveError(const css::uno::Reference<css::frame::XModel>& xModel,
89 const OUString& rCID, bool bShow)
91 css::uno::Reference<css::beans::XPropertySet> xPropSet =
92 getErrorBarPropSet(xModel, rCID);
94 if (!xPropSet.is())
95 return;
97 xPropSet->setPropertyValue("ShowPositiveError", css::uno::Any(bShow));
100 void setShowNegativeError(const css::uno::Reference<css::frame::XModel>& xModel,
101 const OUString& rCID, bool bShow)
103 css::uno::Reference<css::beans::XPropertySet> xPropSet =
104 getErrorBarPropSet(xModel, rCID);
106 if (!xPropSet.is())
107 return;
109 xPropSet->setPropertyValue("ShowNegativeError", css::uno::Any(bShow));
112 struct ErrorBarTypeMap
114 sal_Int32 nPos;
115 sal_Int32 nApi;
118 static ErrorBarTypeMap const aErrorBarType[] = {
119 { 0, css::chart::ErrorBarStyle::ABSOLUTE },
120 { 1, css::chart::ErrorBarStyle::RELATIVE },
121 { 2, css::chart::ErrorBarStyle::FROM_DATA },
122 { 3, css::chart::ErrorBarStyle::STANDARD_DEVIATION },
123 { 4, css::chart::ErrorBarStyle::STANDARD_ERROR },
124 { 5, css::chart::ErrorBarStyle::VARIANCE},
125 { 6, css::chart::ErrorBarStyle::ERROR_MARGIN },
128 sal_Int32 getTypePos(const css::uno::Reference<css::frame::XModel>& xModel,
129 const OUString& rCID)
131 css::uno::Reference<css::beans::XPropertySet> xPropSet =
132 getErrorBarPropSet(xModel, rCID);
134 if (!xPropSet.is())
135 return 0;
137 css::uno::Any aAny = xPropSet->getPropertyValue("ErrorBarStyle");
139 if (!aAny.hasValue())
140 return 0;
142 sal_Int32 nApi = 0;
143 aAny >>= nApi;
145 for (ErrorBarTypeMap const & i : aErrorBarType)
147 if (i.nApi == nApi)
148 return i.nPos;
151 return 0;
154 void setTypePos(const css::uno::Reference<css::frame::XModel>& xModel,
155 const OUString& rCID, sal_Int32 nPos)
157 css::uno::Reference<css::beans::XPropertySet> xPropSet =
158 getErrorBarPropSet(xModel, rCID);
160 if (!xPropSet.is())
161 return;
163 sal_Int32 nApi = 0;
164 for (ErrorBarTypeMap const & i : aErrorBarType)
166 if (i.nPos == nPos)
167 nApi = i.nApi;
170 xPropSet->setPropertyValue("ErrorBarStyle", css::uno::Any(nApi));
173 double getValue(const css::uno::Reference<css::frame::XModel>& xModel,
174 const OUString& rCID, ErrorBarDirection eDir)
176 css::uno::Reference<css::beans::XPropertySet> xPropSet =
177 getErrorBarPropSet(xModel, rCID);
179 if (!xPropSet.is())
180 return 0;
182 OUString aName = "PositiveError";
183 if (eDir == ErrorBarDirection::NEGATIVE)
184 aName = "NegativeError";
186 css::uno::Any aAny = xPropSet->getPropertyValue(aName);
188 if (!aAny.hasValue())
189 return 0;
191 double nVal = 0;
192 aAny >>= nVal;
194 return nVal;
197 void setValue(const css::uno::Reference<css::frame::XModel>& xModel,
198 const OUString& rCID, double nVal, ErrorBarDirection eDir)
200 css::uno::Reference<css::beans::XPropertySet> xPropSet =
201 getErrorBarPropSet(xModel, rCID);
203 if (!xPropSet.is())
204 return;
206 OUString aName = "PositiveError";
207 if (eDir == ErrorBarDirection::NEGATIVE)
208 aName = "NegativeError";
210 xPropSet->setPropertyValue(aName, css::uno::Any(nVal));
213 OUString getCID(const css::uno::Reference<css::frame::XModel>& xModel)
215 css::uno::Reference<css::frame::XController> xController(xModel->getCurrentController());
216 css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController, css::uno::UNO_QUERY);
217 if (!xSelectionSupplier.is())
218 return OUString();
220 uno::Any aAny = xSelectionSupplier->getSelection();
221 assert(aAny.hasValue());
222 OUString aCID;
223 aAny >>= aCID;
224 #if defined DBG_UTIL && !defined NDEBUG
225 ObjectType eType = ObjectIdentifier::getObjectType(aCID);
226 assert(eType == OBJECTTYPE_DATA_ERRORS_X ||
227 eType == OBJECTTYPE_DATA_ERRORS_Y ||
228 eType == OBJECTTYPE_DATA_ERRORS_Z);
229 #endif
231 return aCID;
236 ChartErrorBarPanel::ChartErrorBarPanel(
237 vcl::Window* pParent,
238 const css::uno::Reference<css::frame::XFrame>& rxFrame,
239 ChartController* pController)
240 : PanelLayout(pParent, "ChartErrorBarPanel", "modules/schart/ui/sidebarerrorbar.ui", rxFrame),
241 mxModel(pController->getModel()),
242 mxListener(new ChartSidebarModifyListener(this)),
243 mbModelValid(true)
246 get(mpRBPosAndNeg, "radiobutton_positive_negative");
247 get(mpRBPos, "radiobutton_positive");
248 get(mpRBNeg, "radiobutton_negative");
250 get(mpLBType, "comboboxtext_type");
252 get(mpMFPos, "spinbutton_pos");
253 get(mpMFNeg, "spinbutton_neg");
255 Initialize();
258 ChartErrorBarPanel::~ChartErrorBarPanel()
260 disposeOnce();
263 void ChartErrorBarPanel::dispose()
265 css::uno::Reference<css::util::XModifyBroadcaster> xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW);
266 xBroadcaster->removeModifyListener(mxListener);
268 mpRBPosAndNeg.clear();
269 mpRBPos.clear();
270 mpRBNeg.clear();
272 mpLBType.clear();
274 mpMFPos.clear();
275 mpMFNeg.clear();
277 PanelLayout::dispose();
280 void ChartErrorBarPanel::Initialize()
282 css::uno::Reference<css::util::XModifyBroadcaster> xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW);
283 xBroadcaster->addModifyListener(mxListener);
284 mpRBNeg->Check(false);
285 mpRBPos->Check(false);
286 mpRBPosAndNeg->Check(false);
288 updateData();
290 Link<RadioButton&,void> aLink = LINK(this, ChartErrorBarPanel, RadioBtnHdl);
291 mpRBPosAndNeg->SetToggleHdl(aLink);
292 mpRBPos->SetToggleHdl(aLink);
293 mpRBNeg->SetToggleHdl(aLink);
295 mpLBType->SetSelectHdl(LINK(this, ChartErrorBarPanel, ListBoxHdl));
297 Link<Edit&,void> aLink2 = LINK(this, ChartErrorBarPanel, NumericFieldHdl);
298 mpMFPos->SetModifyHdl(aLink2);
299 mpMFNeg->SetModifyHdl(aLink2);
302 void ChartErrorBarPanel::updateData()
304 if (!mbModelValid)
305 return;
307 OUString aCID = getCID(mxModel);
308 bool bPos = showPositiveError(mxModel, aCID);
309 bool bNeg = showNegativeError(mxModel, aCID);
311 SolarMutexGuard aGuard;
313 if (bPos && bNeg)
314 mpRBPosAndNeg->Check();
315 else if (bPos)
316 mpRBPos->Check();
317 else if (bNeg)
318 mpRBNeg->Check();
320 sal_Int32 nTypePos = getTypePos(mxModel, aCID);
321 mpLBType->SelectEntryPos(nTypePos);
323 if (nTypePos <= 1)
325 if (bPos)
326 mpMFPos->Enable();
327 else
328 mpMFPos->Disable();
330 if (bNeg)
331 mpMFNeg->Enable();
332 else
333 mpMFNeg->Disable();
335 double nValPos = getValue(mxModel, aCID, ErrorBarDirection::POSITIVE);
336 double nValNeg = getValue(mxModel, aCID, ErrorBarDirection::NEGATIVE);
338 mpMFPos->SetValue(nValPos);
339 mpMFNeg->SetValue(nValNeg);
341 else
343 mpMFPos->Disable();
344 mpMFNeg->Disable();
348 VclPtr<vcl::Window> ChartErrorBarPanel::Create (
349 vcl::Window* pParent,
350 const css::uno::Reference<css::frame::XFrame>& rxFrame,
351 ChartController* pController)
353 if (pParent == nullptr)
354 throw lang::IllegalArgumentException("no parent Window given to ChartErrorBarPanel::Create", nullptr, 0);
355 if ( ! rxFrame.is())
356 throw lang::IllegalArgumentException("no XFrame given to ChartErrorBarPanel::Create", nullptr, 1);
358 return VclPtr<ChartErrorBarPanel>::Create(
359 pParent, rxFrame, pController);
362 void ChartErrorBarPanel::DataChanged(
363 const DataChangedEvent& )
365 updateData();
368 void ChartErrorBarPanel::HandleContextChange(
369 const vcl::EnumContext& )
371 updateData();
374 void ChartErrorBarPanel::NotifyItemUpdate(
375 sal_uInt16 /*nSID*/,
376 SfxItemState /*eState*/,
377 const SfxPoolItem* /*pState*/ )
381 void ChartErrorBarPanel::modelInvalid()
383 mbModelValid = false;
386 void ChartErrorBarPanel::updateModel(
387 css::uno::Reference<css::frame::XModel> xModel)
389 if (mbModelValid)
391 css::uno::Reference<css::util::XModifyBroadcaster> xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW);
392 xBroadcaster->removeModifyListener(mxListener);
395 mxModel = xModel;
396 mbModelValid = true;
398 css::uno::Reference<css::util::XModifyBroadcaster> xBroadcasterNew(mxModel, css::uno::UNO_QUERY_THROW);
399 xBroadcasterNew->addModifyListener(mxListener);
402 IMPL_LINK_NOARG(ChartErrorBarPanel, RadioBtnHdl, RadioButton&, void)
404 OUString aCID = getCID(mxModel);
405 bool bPos = mpRBPosAndNeg->IsChecked() || mpRBPos->IsChecked();
406 bool bNeg = mpRBPosAndNeg->IsChecked() || mpRBNeg->IsChecked();
408 setShowPositiveError(mxModel, aCID, bPos);
409 setShowNegativeError(mxModel, aCID, bNeg);
412 IMPL_LINK_NOARG(ChartErrorBarPanel, ListBoxHdl, ListBox&, void)
414 OUString aCID = getCID(mxModel);
415 sal_Int32 nPos = mpLBType->GetSelectedEntryPos();
417 setTypePos(mxModel, aCID, nPos);
420 IMPL_LINK(ChartErrorBarPanel, NumericFieldHdl, Edit&, rMetricField, void)
422 OUString aCID = getCID(mxModel);
423 double nVal = static_cast<NumericField&>(rMetricField).GetValue();
424 if (&rMetricField == mpMFPos.get())
425 setValue(mxModel, aCID, nVal, ErrorBarDirection::POSITIVE);
426 else if (&rMetricField == mpMFNeg.get())
427 setValue(mxModel, aCID, nVal, ErrorBarDirection::NEGATIVE);
430 }} // end of namespace ::chart::sidebar
432 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */