Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / chart2 / source / controller / sidebar / ChartErrorBarPanel.cxx
blob4b3b5998abb5dafa589b0c6758b0067e0fff3923
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 <sfx2/sidebar/ControlFactory.hxx>
22 #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
23 #include <com/sun/star/chart/ErrorBarStyle.hpp>
25 #include "ChartErrorBarPanel.hxx"
26 #include <ChartController.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <vcl/fixed.hxx>
30 #include <vcl/lstbox.hxx>
31 #include <vcl/field.hxx>
32 #include <vcl/toolbox.hxx>
33 #include <svl/intitem.hxx>
34 #include <svl/stritem.hxx>
36 using namespace css;
37 using namespace css::uno;
39 namespace chart { namespace sidebar {
41 namespace {
43 enum class ErrorBarDirection
45 POSITIVE,
46 NEGATIVE
49 css::uno::Reference<css::beans::XPropertySet> getErrorBarPropSet(
50 const css::uno::Reference<css::frame::XModel>& xModel, const OUString& rCID)
52 return ObjectIdentifier::getObjectPropertySet(rCID, xModel);
55 bool showPositiveError(const css::uno::Reference<css::frame::XModel>& xModel,
56 const OUString& rCID)
58 css::uno::Reference<css::beans::XPropertySet> xPropSet =
59 getErrorBarPropSet(xModel, rCID);
61 if (!xPropSet.is())
62 return false;
64 css::uno::Any aAny = xPropSet->getPropertyValue("ShowPositiveError");
66 if (!aAny.hasValue())
67 return false;
69 bool bShow = false;
70 aAny >>= bShow;
71 return bShow;
74 bool showNegativeError(const css::uno::Reference<css::frame::XModel>& xModel,
75 const OUString& rCID)
77 css::uno::Reference<css::beans::XPropertySet> xPropSet =
78 getErrorBarPropSet(xModel, rCID);
80 if (!xPropSet.is())
81 return false;
83 css::uno::Any aAny = xPropSet->getPropertyValue("ShowNegativeError");
85 if (!aAny.hasValue())
86 return false;
88 bool bShow = false;
89 aAny >>= bShow;
90 return bShow;
93 void setShowPositiveError(const css::uno::Reference<css::frame::XModel>& xModel,
94 const OUString& rCID, bool bShow)
96 css::uno::Reference<css::beans::XPropertySet> xPropSet =
97 getErrorBarPropSet(xModel, rCID);
99 if (!xPropSet.is())
100 return;
102 xPropSet->setPropertyValue("ShowPositiveError", css::uno::Any(bShow));
105 void setShowNegativeError(const css::uno::Reference<css::frame::XModel>& xModel,
106 const OUString& rCID, bool bShow)
108 css::uno::Reference<css::beans::XPropertySet> xPropSet =
109 getErrorBarPropSet(xModel, rCID);
111 if (!xPropSet.is())
112 return;
114 xPropSet->setPropertyValue("ShowNegativeError", css::uno::Any(bShow));
117 struct ErrorBarTypeMap
119 sal_Int32 nPos;
120 sal_Int32 nApi;
123 ErrorBarTypeMap aErrorBarType[] = {
124 { 0, css::chart::ErrorBarStyle::ABSOLUTE },
125 { 1, css::chart::ErrorBarStyle::RELATIVE },
126 { 2, css::chart::ErrorBarStyle::FROM_DATA },
127 { 3, css::chart::ErrorBarStyle::STANDARD_DEVIATION },
128 { 4, css::chart::ErrorBarStyle::STANDARD_ERROR },
129 { 5, css::chart::ErrorBarStyle::VARIANCE},
130 { 6, css::chart::ErrorBarStyle::ERROR_MARGIN },
133 sal_Int32 getTypePos(const css::uno::Reference<css::frame::XModel>& xModel,
134 const OUString& rCID)
136 css::uno::Reference<css::beans::XPropertySet> xPropSet =
137 getErrorBarPropSet(xModel, rCID);
139 if (!xPropSet.is())
140 return 0;
142 css::uno::Any aAny = xPropSet->getPropertyValue("ErrorBarStyle");
144 if (!aAny.hasValue())
145 return 0;
147 sal_Int32 nApi = 0;
148 aAny >>= nApi;
150 for (ErrorBarTypeMap & i : aErrorBarType)
152 if (i.nApi == nApi)
153 return i.nPos;
156 return 0;
159 void setTypePos(const css::uno::Reference<css::frame::XModel>& xModel,
160 const OUString& rCID, sal_Int32 nPos)
162 css::uno::Reference<css::beans::XPropertySet> xPropSet =
163 getErrorBarPropSet(xModel, rCID);
165 if (!xPropSet.is())
166 return;
168 sal_Int32 nApi = 0;
169 for (ErrorBarTypeMap & i : aErrorBarType)
171 if (i.nPos == nPos)
172 nApi = i.nApi;
175 xPropSet->setPropertyValue("ErrorBarStyle", css::uno::Any(nApi));
178 double getValue(const css::uno::Reference<css::frame::XModel>& xModel,
179 const OUString& rCID, ErrorBarDirection eDir)
181 css::uno::Reference<css::beans::XPropertySet> xPropSet =
182 getErrorBarPropSet(xModel, rCID);
184 if (!xPropSet.is())
185 return 0;
187 OUString aName = "PositiveError";
188 if (eDir == ErrorBarDirection::NEGATIVE)
189 aName = "NegativeError";
191 css::uno::Any aAny = xPropSet->getPropertyValue(aName);
193 if (!aAny.hasValue())
194 return 0;
196 double nVal = 0;
197 aAny >>= nVal;
199 return nVal;
202 void setValue(const css::uno::Reference<css::frame::XModel>& xModel,
203 const OUString& rCID, double nVal, ErrorBarDirection eDir)
205 css::uno::Reference<css::beans::XPropertySet> xPropSet =
206 getErrorBarPropSet(xModel, rCID);
208 if (!xPropSet.is())
209 return;
211 OUString aName = "PositiveError";
212 if (eDir == ErrorBarDirection::NEGATIVE)
213 aName = "NegativeError";
215 xPropSet->setPropertyValue(aName, css::uno::Any(nVal));
218 OUString getCID(const css::uno::Reference<css::frame::XModel>& xModel)
220 css::uno::Reference<css::frame::XController> xController(xModel->getCurrentController());
221 css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController, css::uno::UNO_QUERY);
222 if (!xSelectionSupplier.is())
223 return OUString();
225 uno::Any aAny = xSelectionSupplier->getSelection();
226 assert(aAny.hasValue());
227 OUString aCID;
228 aAny >>= aCID;
229 #ifdef DBG_UTIL
230 ObjectType eType = ObjectIdentifier::getObjectType(aCID);
231 assert(eType == OBJECTTYPE_DATA_ERRORS_X ||
232 eType == OBJECTTYPE_DATA_ERRORS_Y ||
233 eType == OBJECTTYPE_DATA_ERRORS_Z);
234 #endif
236 return aCID;
241 ChartErrorBarPanel::ChartErrorBarPanel(
242 vcl::Window* pParent,
243 const css::uno::Reference<css::frame::XFrame>& rxFrame,
244 ChartController* pController)
245 : PanelLayout(pParent, "ChartErrorBarPanel", "modules/schart/ui/sidebarerrorbar.ui", rxFrame),
246 mxModel(pController->getModel()),
247 mxListener(new ChartSidebarModifyListener(this)),
248 mbModelValid(true)
251 get(mpRBPosAndNeg, "radiobutton_positive_negative");
252 get(mpRBPos, "radiobutton_positive");
253 get(mpRBNeg, "radiobutton_negative");
255 get(mpLBType, "comboboxtext_type");
257 get(mpMFPos, "spinbutton_pos");
258 get(mpMFNeg, "spinbutton_neg");
260 Initialize();
263 ChartErrorBarPanel::~ChartErrorBarPanel()
265 disposeOnce();
268 void ChartErrorBarPanel::dispose()
270 css::uno::Reference<css::util::XModifyBroadcaster> xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW);
271 xBroadcaster->removeModifyListener(mxListener);
273 mpRBPosAndNeg.clear();
274 mpRBPos.clear();
275 mpRBNeg.clear();
277 mpLBType.clear();
279 mpMFPos.clear();
280 mpMFNeg.clear();
282 PanelLayout::dispose();
285 void ChartErrorBarPanel::Initialize()
287 css::uno::Reference<css::util::XModifyBroadcaster> xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW);
288 xBroadcaster->addModifyListener(mxListener);
289 mpRBNeg->Check(false);
290 mpRBPos->Check(false);
291 mpRBPosAndNeg->Check(false);
293 updateData();
295 Link<RadioButton&,void> aLink = LINK(this, ChartErrorBarPanel, RadioBtnHdl);
296 mpRBPosAndNeg->SetToggleHdl(aLink);
297 mpRBPos->SetToggleHdl(aLink);
298 mpRBNeg->SetToggleHdl(aLink);
300 mpLBType->SetSelectHdl(LINK(this, ChartErrorBarPanel, ListBoxHdl));
302 Link<Edit&,void> aLink2 = LINK(this, ChartErrorBarPanel, NumericFieldHdl);
303 mpMFPos->SetModifyHdl(aLink2);
304 mpMFNeg->SetModifyHdl(aLink2);
307 void ChartErrorBarPanel::updateData()
309 if (!mbModelValid)
310 return;
312 OUString aCID = getCID(mxModel);
313 bool bPos = showPositiveError(mxModel, aCID);
314 bool bNeg = showNegativeError(mxModel, aCID);
316 SolarMutexGuard aGuard;
318 if (bPos && bNeg)
319 mpRBPosAndNeg->Check();
320 else if (bPos)
321 mpRBPos->Check();
322 else if (bNeg)
323 mpRBNeg->Check();
325 sal_Int32 nTypePos = getTypePos(mxModel, aCID);
326 mpLBType->SelectEntryPos(nTypePos);
328 if (nTypePos <= 1)
330 if (bPos)
331 mpMFPos->Enable();
332 else
333 mpMFPos->Disable();
335 if (bNeg)
336 mpMFNeg->Enable();
337 else
338 mpMFNeg->Disable();
340 double nValPos = getValue(mxModel, aCID, ErrorBarDirection::POSITIVE);
341 double nValNeg = getValue(mxModel, aCID, ErrorBarDirection::NEGATIVE);
343 mpMFPos->SetValue(nValPos);
344 mpMFNeg->SetValue(nValNeg);
346 else
348 mpMFPos->Disable();
349 mpMFNeg->Disable();
353 VclPtr<vcl::Window> ChartErrorBarPanel::Create (
354 vcl::Window* pParent,
355 const css::uno::Reference<css::frame::XFrame>& rxFrame,
356 ChartController* pController)
358 if (pParent == nullptr)
359 throw lang::IllegalArgumentException("no parent Window given to ChartErrorBarPanel::Create", nullptr, 0);
360 if ( ! rxFrame.is())
361 throw lang::IllegalArgumentException("no XFrame given to ChartErrorBarPanel::Create", nullptr, 1);
363 return VclPtr<ChartErrorBarPanel>::Create(
364 pParent, rxFrame, pController);
367 void ChartErrorBarPanel::DataChanged(
368 const DataChangedEvent& )
370 updateData();
373 void ChartErrorBarPanel::HandleContextChange(
374 const vcl::EnumContext& )
376 updateData();
379 void ChartErrorBarPanel::NotifyItemUpdate(
380 sal_uInt16 /*nSID*/,
381 SfxItemState /*eState*/,
382 const SfxPoolItem* /*pState*/,
383 const bool )
387 void ChartErrorBarPanel::modelInvalid()
389 mbModelValid = false;
392 void ChartErrorBarPanel::updateModel(
393 css::uno::Reference<css::frame::XModel> xModel)
395 if (mbModelValid)
397 css::uno::Reference<css::util::XModifyBroadcaster> xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW);
398 xBroadcaster->removeModifyListener(mxListener);
401 mxModel = xModel;
402 mbModelValid = true;
404 css::uno::Reference<css::util::XModifyBroadcaster> xBroadcasterNew(mxModel, css::uno::UNO_QUERY_THROW);
405 xBroadcasterNew->addModifyListener(mxListener);
408 IMPL_LINK_NOARG(ChartErrorBarPanel, RadioBtnHdl, RadioButton&, void)
410 OUString aCID = getCID(mxModel);
411 bool bPos = mpRBPosAndNeg->IsChecked() || mpRBPos->IsChecked();
412 bool bNeg = mpRBPosAndNeg->IsChecked() || mpRBNeg->IsChecked();
414 setShowPositiveError(mxModel, aCID, bPos);
415 setShowNegativeError(mxModel, aCID, bNeg);
418 IMPL_LINK_NOARG(ChartErrorBarPanel, ListBoxHdl, ListBox&, void)
420 OUString aCID = getCID(mxModel);
421 sal_Int32 nPos = mpLBType->GetSelectedEntryPos();
423 setTypePos(mxModel, aCID, nPos);
426 IMPL_LINK(ChartErrorBarPanel, NumericFieldHdl, Edit&, rMetricField, void)
428 OUString aCID = getCID(mxModel);
429 double nVal = static_cast<NumericField&>(rMetricField).GetValue();
430 if (&rMetricField == mpMFPos.get())
431 setValue(mxModel, aCID, nVal, ErrorBarDirection::POSITIVE);
432 else if (&rMetricField == mpMFNeg.get())
433 setValue(mxModel, aCID, nVal, ErrorBarDirection::NEGATIVE);
436 }} // end of namespace ::chart::sidebar
438 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */