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 "res_Trendline.hxx"
21 #include <bitmaps.hlst>
22 #include <chartview/ChartSfxItemIds.hxx>
24 #include <com/sun/star/chart2/MovingAverageType.hpp>
26 #include <svl/intitem.hxx>
27 #include <svl/numformat.hxx>
28 #include <svl/stritem.hxx>
29 #include <vcl/formatter.hxx>
30 #include <vcl/weld.hxx>
32 using namespace css::chart2
;
37 static void lcl_setValue(weld::FormattedSpinButton
& rFmtField
, double fValue
)
39 Formatter
& rFieldFormatter
= rFmtField
.GetFormatter();
40 rFieldFormatter
.SetValue(fValue
);
41 rFieldFormatter
.SetDefaultValue( fValue
);
44 TrendlineResources::TrendlineResources(weld::Builder
& rBuilder
, const SfxItemSet
& rInAttrs
)
45 : m_eTrendLineType(SvxChartRegress::Linear
)
46 , m_bTrendLineUnique(true)
47 , m_pNumFormatter(nullptr)
49 , m_xRB_Linear(rBuilder
.weld_radio_button(u
"linear"_ustr
))
50 , m_xRB_Logarithmic(rBuilder
.weld_radio_button(u
"logarithmic"_ustr
))
51 , m_xRB_Exponential(rBuilder
.weld_radio_button(u
"exponential"_ustr
))
52 , m_xRB_Power(rBuilder
.weld_radio_button(u
"power"_ustr
))
53 , m_xRB_Polynomial(rBuilder
.weld_radio_button(u
"polynomial"_ustr
))
54 , m_xRB_MovingAverage(rBuilder
.weld_radio_button(u
"movingAverage"_ustr
))
55 , m_xFI_Linear(rBuilder
.weld_image(u
"imageLinear"_ustr
))
56 , m_xFI_Logarithmic(rBuilder
.weld_image(u
"imageLogarithmic"_ustr
))
57 , m_xFI_Exponential(rBuilder
.weld_image(u
"imageExponential"_ustr
))
58 , m_xFI_Power(rBuilder
.weld_image(u
"imagePower"_ustr
))
59 , m_xFI_Polynomial(rBuilder
.weld_image(u
"imagePolynomial"_ustr
))
60 , m_xFI_MovingAverage(rBuilder
.weld_image(u
"imageMovingAverage"_ustr
))
61 , m_xNF_Degree(rBuilder
.weld_spin_button(u
"degree"_ustr
))
62 , m_xNF_Period(rBuilder
.weld_spin_button(u
"period"_ustr
))
63 , m_xEE_Name(rBuilder
.weld_entry(u
"entry_name"_ustr
))
64 , m_xFmtFld_ExtrapolateForward(rBuilder
.weld_formatted_spin_button(u
"extrapolateForward"_ustr
))
65 , m_xFmtFld_ExtrapolateBackward(rBuilder
.weld_formatted_spin_button(u
"extrapolateBackward"_ustr
))
66 , m_xCB_SetIntercept(rBuilder
.weld_check_button(u
"setIntercept"_ustr
))
67 , m_xFmtFld_InterceptValue(rBuilder
.weld_formatted_spin_button(u
"interceptValue"_ustr
))
68 , m_xCB_ShowEquation(rBuilder
.weld_check_button(u
"showEquation"_ustr
))
69 , m_xEE_XName(rBuilder
.weld_entry(u
"entry_Xname"_ustr
))
70 , m_xEE_YName(rBuilder
.weld_entry(u
"entry_Yname"_ustr
))
71 , m_xCB_ShowCorrelationCoeff(rBuilder
.weld_check_button(u
"showCorrelationCoefficient"_ustr
))
72 , m_xCB_RegressionMovingType(rBuilder
.weld_combo_box(u
"combo_moving_type"_ustr
))
76 Formatter
& rForwardFormatter
= m_xFmtFld_ExtrapolateForward
->GetFormatter();
77 rForwardFormatter
.ClearMinValue();
78 rForwardFormatter
.ClearMaxValue();
79 Formatter
& rBackwardFormatter
= m_xFmtFld_ExtrapolateBackward
->GetFormatter();
80 rBackwardFormatter
.ClearMinValue();
81 rBackwardFormatter
.ClearMaxValue();
82 Formatter
& rInterceptFormatter
= m_xFmtFld_InterceptValue
->GetFormatter();
83 rInterceptFormatter
.ClearMinValue();
84 rInterceptFormatter
.ClearMaxValue();
86 Link
<weld::Toggleable
&,void> aLink
= LINK(this, TrendlineResources
, SelectTrendLine
);
87 m_xRB_Linear
->connect_toggled( aLink
);
88 m_xRB_Logarithmic
->connect_toggled( aLink
);
89 m_xRB_Exponential
->connect_toggled( aLink
);
90 m_xRB_Power
->connect_toggled( aLink
);
91 m_xRB_Polynomial
->connect_toggled( aLink
);
92 m_xRB_MovingAverage
->connect_toggled( aLink
);
94 Link
<weld::SpinButton
&,void> aLink2
= LINK(this, TrendlineResources
, ChangeSpinValue
);
95 m_xNF_Degree
->connect_value_changed(aLink2
);
96 m_xNF_Period
->connect_value_changed(aLink2
);
97 m_xFmtFld_InterceptValue
->connect_value_changed(LINK(this, TrendlineResources
, ChangeFormattedValue
));
99 m_xCB_ShowEquation
->connect_toggled(LINK(this, TrendlineResources
, ShowEquation
));
102 UpdateControlStates();
105 TrendlineResources::~TrendlineResources()
108 IMPL_LINK_NOARG(TrendlineResources
, SelectTrendLine
, weld::Toggleable
&, void)
110 if (m_xRB_Linear
->get_active())
111 m_eTrendLineType
= SvxChartRegress::Linear
;
112 else if (m_xRB_Logarithmic
->get_active())
113 m_eTrendLineType
= SvxChartRegress::Log
;
114 else if (m_xRB_Exponential
->get_active())
115 m_eTrendLineType
= SvxChartRegress::Exp
;
116 else if (m_xRB_Power
->get_active())
117 m_eTrendLineType
= SvxChartRegress::Power
;
118 else if (m_xRB_Polynomial
->get_active())
119 m_eTrendLineType
= SvxChartRegress::Polynomial
;
120 else if (m_xRB_MovingAverage
->get_active())
121 m_eTrendLineType
= SvxChartRegress::MovingAverage
;
122 m_bTrendLineUnique
= true;
124 UpdateControlStates();
127 void TrendlineResources::Reset( const SfxItemSet
& rInAttrs
)
129 if( const SfxStringItem
* pCurveNameItem
= rInAttrs
.GetItemIfSet( SCHATTR_REGRESSION_CURVE_NAME
) )
131 OUString aName
= pCurveNameItem
->GetValue();
132 m_xEE_Name
->set_text(aName
);
136 m_xEE_Name
->set_text(u
""_ustr
);
138 if( const SfxStringItem
* pRegressionXNameItem
= rInAttrs
.GetItemIfSet( SCHATTR_REGRESSION_XNAME
) )
140 OUString aName
= pRegressionXNameItem
->GetValue();
141 m_xEE_XName
->set_text(aName
);
145 m_xEE_XName
->set_text(u
"x"_ustr
);
147 if( const SfxStringItem
* pRegressionYNameItem
= rInAttrs
.GetItemIfSet( SCHATTR_REGRESSION_YNAME
) )
149 OUString aName
= pRegressionYNameItem
->GetValue();
150 m_xEE_YName
->set_text(aName
);
154 m_xEE_YName
->set_text(u
"f(x)"_ustr
);
157 const SfxPoolItem
* pPoolItem
= nullptr;
158 SfxItemState aState
= rInAttrs
.GetItemState( SCHATTR_REGRESSION_TYPE
, true, &pPoolItem
);
159 m_bTrendLineUnique
= ( aState
!= SfxItemState::INVALID
);
160 if( aState
== SfxItemState::SET
)
162 const SvxChartRegressItem
* pItem
= dynamic_cast< const SvxChartRegressItem
* >( pPoolItem
);
165 m_eTrendLineType
= pItem
->GetValue();
169 if( const SfxInt32Item
* pDegreeItem
= rInAttrs
.GetItemIfSet( SCHATTR_REGRESSION_DEGREE
) )
171 sal_Int32 nDegree
= pDegreeItem
->GetValue();
172 m_xNF_Degree
->set_value( nDegree
);
176 m_xNF_Degree
->set_value( 2 );
179 m_xNF_Degree
->save_value();
181 if( const SfxInt32Item
* pPeriodItem
= rInAttrs
.GetItemIfSet( SCHATTR_REGRESSION_PERIOD
) )
183 sal_Int32 nPeriod
= pPeriodItem
->GetValue();
184 m_xNF_Period
->set_value( nPeriod
);
188 m_xNF_Period
->set_value( 2 );
191 m_xNF_Period
->save_value();
194 if( const SvxDoubleItem
* pForwardItem
= rInAttrs
.GetItemIfSet( SCHATTR_REGRESSION_EXTRAPOLATE_FORWARD
) )
196 nValue
= pForwardItem
->GetValue() ;
198 lcl_setValue(*m_xFmtFld_ExtrapolateForward
, nValue
);
201 if( const SvxDoubleItem
* pBackwardItem
= rInAttrs
.GetItemIfSet( SCHATTR_REGRESSION_EXTRAPOLATE_BACKWARD
) )
203 nValue
= pBackwardItem
->GetValue() ;
205 lcl_setValue(*m_xFmtFld_ExtrapolateBackward
, nValue
);
208 if( const SvxDoubleItem
* pValueItem
= rInAttrs
.GetItemIfSet( SCHATTR_REGRESSION_INTERCEPT_VALUE
) )
210 nValue
= pValueItem
->GetValue() ;
212 lcl_setValue(*m_xFmtFld_InterceptValue
, nValue
);
214 aState
= rInAttrs
.GetItemState( SCHATTR_REGRESSION_SET_INTERCEPT
, true, &pPoolItem
);
215 if( aState
== SfxItemState::INVALID
)
217 m_xCB_SetIntercept
->set_state(TRISTATE_INDET
);
221 if( aState
== SfxItemState::SET
)
222 m_xCB_SetIntercept
->set_active( static_cast< const SfxBoolItem
* >( pPoolItem
)->GetValue());
225 aState
= rInAttrs
.GetItemState( SCHATTR_REGRESSION_SHOW_EQUATION
, true, &pPoolItem
);
226 if( aState
== SfxItemState::INVALID
)
228 m_xCB_ShowEquation
->set_state(TRISTATE_INDET
);
232 if( aState
== SfxItemState::SET
)
233 m_xCB_ShowEquation
->set_active( static_cast< const SfxBoolItem
* >( pPoolItem
)->GetValue());
236 aState
= rInAttrs
.GetItemState( SCHATTR_REGRESSION_SHOW_COEFF
, true, &pPoolItem
);
237 if( aState
== SfxItemState::INVALID
)
239 m_xCB_ShowCorrelationCoeff
->set_state(TRISTATE_INDET
);
243 if( aState
== SfxItemState::SET
)
244 m_xCB_ShowCorrelationCoeff
->set_active( static_cast< const SfxBoolItem
* >( pPoolItem
)->GetValue());
247 if( const SfxInt32Item
* pMovingTypeItem
= rInAttrs
.GetItemIfSet( SCHATTR_REGRESSION_MOVING_TYPE
) )
249 sal_Int32 nMovingType
= pMovingTypeItem
->GetValue();
250 if (nMovingType
== MovingAverageType::Prior
)
251 m_xCB_RegressionMovingType
->set_active(0);
252 else if (nMovingType
== MovingAverageType::Central
)
253 m_xCB_RegressionMovingType
->set_active(1);
254 else if (nMovingType
== MovingAverageType::AveragedAbscissa
)
255 m_xCB_RegressionMovingType
->set_active(2);
259 m_xCB_RegressionMovingType
->set_active(0);
262 if( !m_bTrendLineUnique
)
265 switch( m_eTrendLineType
)
267 case SvxChartRegress::Linear
:
268 m_xRB_Linear
->set_active(true);
270 case SvxChartRegress::Log
:
271 m_xRB_Logarithmic
->set_active(true);
273 case SvxChartRegress::Exp
:
274 m_xRB_Exponential
->set_active(true);
276 case SvxChartRegress::Power
:
277 m_xRB_Power
->set_active(true);
279 case SvxChartRegress::Polynomial
:
280 m_xRB_Polynomial
->set_active(true);
282 case SvxChartRegress::MovingAverage
:
283 m_xRB_MovingAverage
->set_active(true);
290 void TrendlineResources::FillItemSet(SfxItemSet
* rOutAttrs
) const
292 if( m_bTrendLineUnique
)
293 rOutAttrs
->Put( SvxChartRegressItem( m_eTrendLineType
, SCHATTR_REGRESSION_TYPE
));
295 if (m_eTrendLineType
== SvxChartRegress::MovingAverage
)
297 sal_Int32 nType
= MovingAverageType::Prior
;
298 if (m_xCB_RegressionMovingType
->get_active() == 1)
299 nType
= MovingAverageType::Central
;
300 else if (m_xCB_RegressionMovingType
->get_active() == 2)
301 nType
= MovingAverageType::AveragedAbscissa
;
303 rOutAttrs
->Put(SfxInt32Item(SCHATTR_REGRESSION_MOVING_TYPE
, nType
));
306 if( m_xCB_ShowEquation
->get_state() != TRISTATE_INDET
)
307 rOutAttrs
->Put( SfxBoolItem( SCHATTR_REGRESSION_SHOW_EQUATION
, m_xCB_ShowEquation
->get_active() ));
309 if( m_xCB_ShowCorrelationCoeff
->get_state() != TRISTATE_INDET
)
310 rOutAttrs
->Put( SfxBoolItem( SCHATTR_REGRESSION_SHOW_COEFF
, m_xCB_ShowCorrelationCoeff
->get_active() ));
312 OUString aName
= m_xEE_Name
->get_text();
313 rOutAttrs
->Put(SfxStringItem(SCHATTR_REGRESSION_CURVE_NAME
, aName
));
314 aName
= m_xEE_XName
->get_text();
315 if ( aName
.isEmpty() )
317 rOutAttrs
->Put(SfxStringItem(SCHATTR_REGRESSION_XNAME
, aName
));
318 aName
= m_xEE_YName
->get_text();
319 if ( aName
.isEmpty() )
321 rOutAttrs
->Put(SfxStringItem(SCHATTR_REGRESSION_YNAME
, aName
));
323 sal_Int32 aDegree
= m_xNF_Degree
->get_value();
324 rOutAttrs
->Put(SfxInt32Item( SCHATTR_REGRESSION_DEGREE
, aDegree
) );
326 sal_Int32 aPeriod
= m_xNF_Period
->get_value();
327 rOutAttrs
->Put(SfxInt32Item( SCHATTR_REGRESSION_PERIOD
, aPeriod
) );
329 sal_uInt32 nIndex
= 0;
331 (void)m_pNumFormatter
->IsNumberFormat(m_xFmtFld_ExtrapolateForward
->get_text(),nIndex
,aValue
);
332 rOutAttrs
->Put(SvxDoubleItem( aValue
, SCHATTR_REGRESSION_EXTRAPOLATE_FORWARD
) );
335 (void)m_pNumFormatter
->IsNumberFormat(m_xFmtFld_ExtrapolateBackward
->get_text(),nIndex
,aValue
);
336 rOutAttrs
->Put(SvxDoubleItem( aValue
, SCHATTR_REGRESSION_EXTRAPOLATE_BACKWARD
) );
338 if( m_xCB_SetIntercept
->get_state() != TRISTATE_INDET
)
339 rOutAttrs
->Put( SfxBoolItem( SCHATTR_REGRESSION_SET_INTERCEPT
, m_xCB_SetIntercept
->get_active() ));
342 (void)m_pNumFormatter
->IsNumberFormat(m_xFmtFld_InterceptValue
->get_text(),nIndex
,aValue
);
343 rOutAttrs
->Put(SvxDoubleItem( aValue
, SCHATTR_REGRESSION_INTERCEPT_VALUE
) );
346 void TrendlineResources::FillValueSets()
348 m_xFI_Linear
->set_from_icon_name(BMP_REGRESSION_LINEAR
);
349 m_xFI_Logarithmic
->set_from_icon_name(BMP_REGRESSION_LOG
);
350 m_xFI_Exponential
->set_from_icon_name(BMP_REGRESSION_EXP
);
351 m_xFI_Power
->set_from_icon_name(BMP_REGRESSION_POWER
);
352 m_xFI_Polynomial
->set_from_icon_name(BMP_REGRESSION_POLYNOMIAL
);
353 m_xFI_MovingAverage
->set_from_icon_name(BMP_REGRESSION_MOVING_AVERAGE
);
356 void TrendlineResources::UpdateControlStates()
358 if( m_nNbPoints
> 0 )
360 sal_Int32 nMaxValue
= m_nNbPoints
- 1 + (m_xCB_SetIntercept
->get_active() ? 1 : 0);
361 m_xNF_Degree
->set_max(nMaxValue
);
362 m_xNF_Period
->set_max(m_nNbPoints
- 1);
364 bool bMovingAverage
= ( m_eTrendLineType
== SvxChartRegress::MovingAverage
);
365 bool bPolynomial
= ( m_eTrendLineType
== SvxChartRegress::Polynomial
);
366 bool bInterceptAvailable
= ( m_eTrendLineType
== SvxChartRegress::Linear
)
367 || ( m_eTrendLineType
== SvxChartRegress::Polynomial
)
368 || ( m_eTrendLineType
== SvxChartRegress::Exp
);
369 m_xFmtFld_ExtrapolateForward
->set_sensitive( !bMovingAverage
);
370 m_xFmtFld_ExtrapolateBackward
->set_sensitive( !bMovingAverage
);
371 m_xCB_SetIntercept
->set_sensitive( bInterceptAvailable
);
372 m_xFmtFld_InterceptValue
->set_sensitive( bInterceptAvailable
);
375 m_xCB_ShowCorrelationCoeff
->set_state(TRISTATE_FALSE
);
377 m_xCB_ShowCorrelationCoeff
->set_sensitive( !bMovingAverage
);
378 m_xCB_RegressionMovingType
->set_sensitive(bMovingAverage
);
379 m_xNF_Period
->set_sensitive(bMovingAverage
);
380 m_xNF_Degree
->set_sensitive(bPolynomial
);
381 m_xEE_XName
->set_sensitive( !bMovingAverage
&& m_xCB_ShowEquation
->get_active() );
382 m_xEE_YName
->set_sensitive( !bMovingAverage
&& m_xCB_ShowEquation
->get_active() );
385 IMPL_LINK(TrendlineResources
, ChangeSpinValue
, weld::SpinButton
&, rNumericField
, void)
387 if (&rNumericField
== m_xNF_Degree
.get())
389 if (!m_xRB_Polynomial
->get_active() && m_xNF_Degree
->get_value_changed_from_saved())
391 m_xRB_Polynomial
->set_active(true);
392 SelectTrendLine(*m_xRB_Polynomial
);
395 else if (&rNumericField
== m_xNF_Period
.get())
397 if (!m_xRB_MovingAverage
->get_active() && m_xNF_Period
->get_value_changed_from_saved())
399 m_xRB_MovingAverage
->set_active(true);
400 SelectTrendLine(*m_xRB_MovingAverage
);
403 UpdateControlStates();
406 IMPL_LINK_NOARG(TrendlineResources
, ChangeFormattedValue
, weld::FormattedSpinButton
&, void)
408 if (!m_xCB_SetIntercept
->get_active())
409 m_xCB_SetIntercept
->set_active(true);
410 UpdateControlStates();
413 void TrendlineResources::SetNumFormatter( SvNumberFormatter
* pFormatter
)
415 m_pNumFormatter
= pFormatter
;
416 m_xFmtFld_ExtrapolateForward
->GetFormatter().SetFormatter(m_pNumFormatter
);
417 m_xFmtFld_ExtrapolateBackward
->GetFormatter().SetFormatter(m_pNumFormatter
);
418 m_xFmtFld_InterceptValue
->GetFormatter().SetFormatter(m_pNumFormatter
);
421 void TrendlineResources::SetNbPoints( sal_Int32 nNbPoints
)
423 m_nNbPoints
= nNbPoints
;
424 UpdateControlStates();
427 IMPL_LINK_NOARG(TrendlineResources
, ShowEquation
, weld::Toggleable
&, void)
429 UpdateControlStates();
434 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */