vcl: allow for overriding the default PDF rendering resolution
[LibreOffice.git] / chart2 / source / controller / sidebar / ChartErrorBarPanel.cxx
blob655fe34a811d7f3df0a8899884bd94973a8798d5
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>
30 #include <sal/log.hxx>
33 using namespace css;
34 using namespace css::uno;
36 namespace chart { namespace sidebar {
38 namespace {
40 enum class ErrorBarDirection
42 POSITIVE,
43 NEGATIVE
46 css::uno::Reference<css::beans::XPropertySet> getErrorBarPropSet(
47 const css::uno::Reference<css::frame::XModel>& xModel, const OUString& rCID)
49 return ObjectIdentifier::getObjectPropertySet(rCID, xModel);
52 bool showPositiveError(const css::uno::Reference<css::frame::XModel>& xModel,
53 const OUString& rCID)
55 css::uno::Reference<css::beans::XPropertySet> xPropSet =
56 getErrorBarPropSet(xModel, rCID);
58 if (!xPropSet.is())
59 return false;
61 css::uno::Any aAny = xPropSet->getPropertyValue("ShowPositiveError");
63 if (!aAny.hasValue())
64 return false;
66 bool bShow = false;
67 aAny >>= bShow;
68 return bShow;
71 bool showNegativeError(const css::uno::Reference<css::frame::XModel>& xModel,
72 const OUString& rCID)
74 css::uno::Reference<css::beans::XPropertySet> xPropSet =
75 getErrorBarPropSet(xModel, rCID);
77 if (!xPropSet.is())
78 return false;
80 css::uno::Any aAny = xPropSet->getPropertyValue("ShowNegativeError");
82 if (!aAny.hasValue())
83 return false;
85 bool bShow = false;
86 aAny >>= bShow;
87 return bShow;
90 void setShowPositiveError(const css::uno::Reference<css::frame::XModel>& xModel,
91 const OUString& rCID, bool bShow)
93 css::uno::Reference<css::beans::XPropertySet> xPropSet =
94 getErrorBarPropSet(xModel, rCID);
96 if (!xPropSet.is())
97 return;
99 xPropSet->setPropertyValue("ShowPositiveError", css::uno::Any(bShow));
102 void setShowNegativeError(const css::uno::Reference<css::frame::XModel>& xModel,
103 const OUString& rCID, bool bShow)
105 css::uno::Reference<css::beans::XPropertySet> xPropSet =
106 getErrorBarPropSet(xModel, rCID);
108 if (!xPropSet.is())
109 return;
111 xPropSet->setPropertyValue("ShowNegativeError", css::uno::Any(bShow));
114 struct ErrorBarTypeMap
116 sal_Int32 nPos;
117 sal_Int32 nApi;
120 static ErrorBarTypeMap const aErrorBarType[] = {
121 { 0, css::chart::ErrorBarStyle::ABSOLUTE },
122 { 1, css::chart::ErrorBarStyle::RELATIVE },
123 { 2, css::chart::ErrorBarStyle::FROM_DATA },
124 { 3, css::chart::ErrorBarStyle::STANDARD_DEVIATION },
125 { 4, css::chart::ErrorBarStyle::STANDARD_ERROR },
126 { 5, css::chart::ErrorBarStyle::VARIANCE},
127 { 6, css::chart::ErrorBarStyle::ERROR_MARGIN },
130 sal_Int32 getTypePos(const css::uno::Reference<css::frame::XModel>& xModel,
131 const OUString& rCID)
133 css::uno::Reference<css::beans::XPropertySet> xPropSet =
134 getErrorBarPropSet(xModel, rCID);
136 if (!xPropSet.is())
137 return 0;
139 css::uno::Any aAny = xPropSet->getPropertyValue("ErrorBarStyle");
141 if (!aAny.hasValue())
142 return 0;
144 sal_Int32 nApi = 0;
145 aAny >>= nApi;
147 for (ErrorBarTypeMap const & i : aErrorBarType)
149 if (i.nApi == nApi)
150 return i.nPos;
153 return 0;
156 void setTypePos(const css::uno::Reference<css::frame::XModel>& xModel,
157 const OUString& rCID, sal_Int32 nPos)
159 css::uno::Reference<css::beans::XPropertySet> xPropSet =
160 getErrorBarPropSet(xModel, rCID);
162 if (!xPropSet.is())
163 return;
165 sal_Int32 nApi = 0;
166 for (ErrorBarTypeMap const & i : aErrorBarType)
168 if (i.nPos == nPos)
169 nApi = i.nApi;
172 xPropSet->setPropertyValue("ErrorBarStyle", css::uno::Any(nApi));
175 double getValue(const css::uno::Reference<css::frame::XModel>& xModel,
176 const OUString& rCID, ErrorBarDirection eDir)
178 css::uno::Reference<css::beans::XPropertySet> xPropSet =
179 getErrorBarPropSet(xModel, rCID);
181 if (!xPropSet.is())
182 return 0;
184 OUString aName = "PositiveError";
185 if (eDir == ErrorBarDirection::NEGATIVE)
186 aName = "NegativeError";
188 css::uno::Any aAny = xPropSet->getPropertyValue(aName);
190 if (!aAny.hasValue())
191 return 0;
193 double nVal = 0;
194 aAny >>= nVal;
196 return nVal;
199 void setValue(const css::uno::Reference<css::frame::XModel>& xModel,
200 const OUString& rCID, double nVal, ErrorBarDirection eDir)
202 css::uno::Reference<css::beans::XPropertySet> xPropSet =
203 getErrorBarPropSet(xModel, rCID);
205 if (!xPropSet.is())
206 return;
208 OUString aName = "PositiveError";
209 if (eDir == ErrorBarDirection::NEGATIVE)
210 aName = "NegativeError";
212 xPropSet->setPropertyValue(aName, css::uno::Any(nVal));
215 OUString getCID(const css::uno::Reference<css::frame::XModel>& xModel)
217 css::uno::Reference<css::frame::XController> xController(xModel->getCurrentController());
218 css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController, css::uno::UNO_QUERY);
219 if (!xSelectionSupplier.is())
220 return OUString();
222 uno::Any aAny = xSelectionSupplier->getSelection();
223 assert(aAny.hasValue());
224 OUString aCID;
225 aAny >>= aCID;
226 #if defined DBG_UTIL && !defined NDEBUG
227 ObjectType eType = ObjectIdentifier::getObjectType(aCID);
228 if (eType != OBJECTTYPE_DATA_ERRORS_X &&
229 eType != OBJECTTYPE_DATA_ERRORS_Y &&
230 eType != OBJECTTYPE_DATA_ERRORS_Z)
231 SAL_WARN("chart2","Selected item is not an error bar");
233 #endif
235 return aCID;
240 ChartErrorBarPanel::ChartErrorBarPanel(
241 vcl::Window* pParent,
242 const css::uno::Reference<css::frame::XFrame>& rxFrame,
243 ChartController* pController)
244 : PanelLayout(pParent, "ChartErrorBarPanel", "modules/schart/ui/sidebarerrorbar.ui", rxFrame),
245 mxModel(pController->getModel()),
246 mxListener(new ChartSidebarModifyListener(this)),
247 mbModelValid(true)
250 get(mpRBPosAndNeg, "radiobutton_positive_negative");
251 get(mpRBPos, "radiobutton_positive");
252 get(mpRBNeg, "radiobutton_negative");
254 get(mpLBType, "comboboxtext_type");
256 get(mpMFPos, "spinbutton_pos");
257 get(mpMFNeg, "spinbutton_neg");
259 Initialize();
262 ChartErrorBarPanel::~ChartErrorBarPanel()
264 disposeOnce();
267 void ChartErrorBarPanel::dispose()
269 css::uno::Reference<css::util::XModifyBroadcaster> xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW);
270 xBroadcaster->removeModifyListener(mxListener);
272 mpRBPosAndNeg.clear();
273 mpRBPos.clear();
274 mpRBNeg.clear();
276 mpLBType.clear();
278 mpMFPos.clear();
279 mpMFNeg.clear();
281 PanelLayout::dispose();
284 void ChartErrorBarPanel::Initialize()
286 css::uno::Reference<css::util::XModifyBroadcaster> xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW);
287 xBroadcaster->addModifyListener(mxListener);
288 mpRBNeg->Check(false);
289 mpRBPos->Check(false);
290 mpRBPosAndNeg->Check(false);
292 updateData();
294 Link<RadioButton&,void> aLink = LINK(this, ChartErrorBarPanel, RadioBtnHdl);
295 mpRBPosAndNeg->SetToggleHdl(aLink);
296 mpRBPos->SetToggleHdl(aLink);
297 mpRBNeg->SetToggleHdl(aLink);
299 mpLBType->SetSelectHdl(LINK(this, ChartErrorBarPanel, ListBoxHdl));
301 Link<Edit&,void> aLink2 = LINK(this, ChartErrorBarPanel, NumericFieldHdl);
302 mpMFPos->SetModifyHdl(aLink2);
303 mpMFNeg->SetModifyHdl(aLink2);
306 void ChartErrorBarPanel::updateData()
308 if (!mbModelValid)
309 return;
311 OUString aCID = getCID(mxModel);
312 ObjectType eType = ObjectIdentifier::getObjectType(aCID);
313 if (eType != OBJECTTYPE_DATA_ERRORS_X &&
314 eType != OBJECTTYPE_DATA_ERRORS_Y &&
315 eType != OBJECTTYPE_DATA_ERRORS_Z)
316 return;
318 bool bPos = showPositiveError(mxModel, aCID);
319 bool bNeg = showNegativeError(mxModel, aCID);
321 SolarMutexGuard aGuard;
323 if (bPos && bNeg)
324 mpRBPosAndNeg->Check();
325 else if (bPos)
326 mpRBPos->Check();
327 else if (bNeg)
328 mpRBNeg->Check();
330 sal_Int32 nTypePos = getTypePos(mxModel, aCID);
331 mpLBType->SelectEntryPos(nTypePos);
333 if (nTypePos <= 1)
335 if (bPos)
336 mpMFPos->Enable();
337 else
338 mpMFPos->Disable();
340 if (bNeg)
341 mpMFNeg->Enable();
342 else
343 mpMFNeg->Disable();
345 double nValPos = getValue(mxModel, aCID, ErrorBarDirection::POSITIVE);
346 double nValNeg = getValue(mxModel, aCID, ErrorBarDirection::NEGATIVE);
348 mpMFPos->SetValue(nValPos);
349 mpMFNeg->SetValue(nValNeg);
351 else
353 mpMFPos->Disable();
354 mpMFNeg->Disable();
358 VclPtr<vcl::Window> ChartErrorBarPanel::Create (
359 vcl::Window* pParent,
360 const css::uno::Reference<css::frame::XFrame>& rxFrame,
361 ChartController* pController)
363 if (pParent == nullptr)
364 throw lang::IllegalArgumentException("no parent Window given to ChartErrorBarPanel::Create", nullptr, 0);
365 if ( ! rxFrame.is())
366 throw lang::IllegalArgumentException("no XFrame given to ChartErrorBarPanel::Create", nullptr, 1);
368 return VclPtr<ChartErrorBarPanel>::Create(
369 pParent, rxFrame, pController);
372 void ChartErrorBarPanel::DataChanged(
373 const DataChangedEvent& )
375 updateData();
378 void ChartErrorBarPanel::HandleContextChange(
379 const vcl::EnumContext& )
381 updateData();
384 void ChartErrorBarPanel::NotifyItemUpdate(
385 sal_uInt16 /*nSID*/,
386 SfxItemState /*eState*/,
387 const SfxPoolItem* /*pState*/ )
391 void ChartErrorBarPanel::modelInvalid()
393 mbModelValid = false;
396 void ChartErrorBarPanel::updateModel(
397 css::uno::Reference<css::frame::XModel> xModel)
399 if (mbModelValid)
401 css::uno::Reference<css::util::XModifyBroadcaster> xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW);
402 xBroadcaster->removeModifyListener(mxListener);
405 mxModel = xModel;
406 mbModelValid = true;
408 css::uno::Reference<css::util::XModifyBroadcaster> xBroadcasterNew(mxModel, css::uno::UNO_QUERY_THROW);
409 xBroadcasterNew->addModifyListener(mxListener);
412 IMPL_LINK_NOARG(ChartErrorBarPanel, RadioBtnHdl, RadioButton&, void)
414 OUString aCID = getCID(mxModel);
415 bool bPos = mpRBPosAndNeg->IsChecked() || mpRBPos->IsChecked();
416 bool bNeg = mpRBPosAndNeg->IsChecked() || mpRBNeg->IsChecked();
418 setShowPositiveError(mxModel, aCID, bPos);
419 setShowNegativeError(mxModel, aCID, bNeg);
422 IMPL_LINK_NOARG(ChartErrorBarPanel, ListBoxHdl, ListBox&, void)
424 OUString aCID = getCID(mxModel);
425 sal_Int32 nPos = mpLBType->GetSelectedEntryPos();
427 setTypePos(mxModel, aCID, nPos);
430 IMPL_LINK(ChartErrorBarPanel, NumericFieldHdl, Edit&, rMetricField, void)
432 OUString aCID = getCID(mxModel);
433 double nVal = static_cast<NumericField&>(rMetricField).GetValue();
434 if (&rMetricField == mpMFPos.get())
435 setValue(mxModel, aCID, nVal, ErrorBarDirection::POSITIVE);
436 else if (&rMetricField == mpMFNeg.get())
437 setValue(mxModel, aCID, nVal, ErrorBarDirection::NEGATIVE);
440 }} // end of namespace ::chart::sidebar
442 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */