Get the style color and number just once
[LibreOffice.git] / chart2 / source / tools / ReferenceSizeProvider.cxx
blob57c2015ad23bedbe74b3ca655e2d8ec0d7771e41
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 <ReferenceSizeProvider.hxx>
21 #include <RelativeSizeHelper.hxx>
22 #include <ChartModel.hxx>
23 #include <DataSeries.hxx>
24 #include <DataSeriesProperties.hxx>
25 #include <Diagram.hxx>
26 #include <Axis.hxx>
27 #include <AxisHelper.hxx>
28 #include <Legend.hxx>
29 #include <comphelper/diagnose_ex.hxx>
31 #include <vector>
33 using namespace ::com::sun::star;
34 using namespace ::com::sun::star::chart2;
35 using namespace ::chart::DataSeriesProperties;
37 using ::com::sun::star::uno::Reference;
38 using ::com::sun::star::uno::Sequence;
40 namespace chart
43 ReferenceSizeProvider::ReferenceSizeProvider(
44 awt::Size aPageSize,
45 const rtl::Reference<::chart::ChartModel> & xChartDoc ) :
46 m_aPageSize( aPageSize ),
47 m_xChartDoc( xChartDoc ),
48 m_bUseAutoScale( getAutoResizeState( xChartDoc ) == AUTO_RESIZE_YES )
51 void ReferenceSizeProvider::impl_setValuesAtTitled(
52 const Reference< XTitled > & xTitled )
54 if( xTitled.is())
56 Reference< XTitle > xTitle( xTitled->getTitleObject());
57 if( xTitle.is())
58 setValuesAtTitle( xTitle );
62 void ReferenceSizeProvider::setValuesAtTitle(
63 const Reference< XTitle > & xTitle )
65 try
67 Reference< beans::XPropertySet > xTitleProp( xTitle, uno::UNO_QUERY_THROW );
68 awt::Size aOldRefSize;
69 bool bHasOldRefSize(
70 xTitleProp->getPropertyValue( u"ReferencePageSize"_ustr) >>= aOldRefSize );
72 // set from auto-resize on to off -> adapt font sizes at XFormattedStrings
73 if( bHasOldRefSize && ! useAutoScale())
75 const uno::Sequence< uno::Reference< XFormattedString > > aStrSeq(
76 xTitle->getText());
77 for( uno::Reference< XFormattedString > const & formattedStr : aStrSeq )
79 RelativeSizeHelper::adaptFontSizes(
80 Reference< beans::XPropertySet >( formattedStr, uno::UNO_QUERY ),
81 aOldRefSize, getPageSize());
85 setValuesAtPropertySet( xTitleProp, /* bAdaptFontSizes = */ false );
87 catch (const uno::Exception&)
89 DBG_UNHANDLED_EXCEPTION("chart2");
93 void ReferenceSizeProvider::setValuesAtAllDataSeries()
95 rtl::Reference< Diagram > xDiagram( m_xChartDoc->getFirstChartDiagram());
96 if (!xDiagram)
97 return;
99 // DataSeries/Points
100 std::vector< rtl::Reference< DataSeries > > aSeries =
101 xDiagram->getDataSeries();
103 for (auto const& elem : aSeries)
105 // data points
106 Sequence< sal_Int32 > aPointIndexes;
109 // "AttributedDataPoints"
110 if( elem->getFastPropertyValue( PROP_DATASERIES_ATTRIBUTED_DATA_POINTS) >>= aPointIndexes )
112 for (sal_Int32 idx : aPointIndexes)
113 setValuesAtPropertySet(
114 elem->getDataPointByIndex( idx ) );
117 catch (const uno::Exception&)
119 DBG_UNHANDLED_EXCEPTION("chart2");
122 //it is important to correct the datapoint properties first as they do reference the series properties
123 setValuesAtPropertySet( elem );
127 void ReferenceSizeProvider::setValuesAtPropertySet(
128 const Reference< beans::XPropertySet > & xProp,
129 bool bAdaptFontSizes /* = true */ )
131 if( ! xProp.is())
132 return;
134 static constexpr OUString aRefSizeName = u"ReferencePageSize"_ustr;
138 awt::Size aRefSize( getPageSize() );
139 awt::Size aOldRefSize;
140 bool bHasOldRefSize( xProp->getPropertyValue( aRefSizeName ) >>= aOldRefSize );
142 if( useAutoScale())
144 if( ! bHasOldRefSize )
145 xProp->setPropertyValue( aRefSizeName, uno::Any( aRefSize ));
147 else
149 if( bHasOldRefSize )
151 xProp->setPropertyValue( aRefSizeName, uno::Any());
153 // adapt font sizes
154 if( bAdaptFontSizes )
155 RelativeSizeHelper::adaptFontSizes( xProp, aOldRefSize, aRefSize );
159 catch (const uno::Exception&)
161 DBG_UNHANDLED_EXCEPTION("chart2");
165 void ReferenceSizeProvider::getAutoResizeFromPropSet(
166 const Reference< beans::XPropertySet > & xProp,
167 ReferenceSizeProvider::AutoResizeState & rInOutState )
169 AutoResizeState eSingleState = AUTO_RESIZE_UNKNOWN;
171 if( xProp.is())
175 if( xProp->getPropertyValue( u"ReferencePageSize"_ustr ).hasValue())
176 eSingleState = AUTO_RESIZE_YES;
177 else
178 eSingleState = AUTO_RESIZE_NO;
180 catch (const uno::Exception&)
182 // unknown property -> state stays unknown
186 // current state unknown => nothing changes. Otherwise if current state
187 // differs from state so far, we have an ambiguity
188 if( rInOutState == AUTO_RESIZE_UNKNOWN )
190 rInOutState = eSingleState;
192 else if( eSingleState != AUTO_RESIZE_UNKNOWN &&
193 eSingleState != rInOutState )
195 rInOutState = AUTO_RESIZE_AMBIGUOUS;
199 void ReferenceSizeProvider::impl_getAutoResizeFromTitled(
200 const Reference< XTitled > & xTitled,
201 ReferenceSizeProvider::AutoResizeState & rInOutState )
203 if( xTitled.is())
205 Reference< beans::XPropertySet > xProp( xTitled->getTitleObject(), uno::UNO_QUERY );
206 if( xProp.is())
207 getAutoResizeFromPropSet( xProp, rInOutState );
211 /** Retrieves the state auto-resize from all objects that support this
212 feature. If all objects return the same state, AUTO_RESIZE_YES or
213 AUTO_RESIZE_NO is returned.
215 If no object supporting the feature is found, AUTO_RESIZE_UNKNOWN is
216 returned. If there are multiple objects, some with state YES and some
217 with state NO, AUTO_RESIZE_AMBIGUOUS is returned.
219 ReferenceSizeProvider::AutoResizeState ReferenceSizeProvider::getAutoResizeState(
220 const rtl::Reference<::chart::ChartModel> & xChartDoc )
222 AutoResizeState eResult = AUTO_RESIZE_UNKNOWN;
224 // Main Title
225 if( xChartDoc.is())
226 impl_getAutoResizeFromTitled( xChartDoc, eResult );
227 if( eResult == AUTO_RESIZE_AMBIGUOUS )
228 return eResult;
230 // diagram is needed by the rest of the objects
231 rtl::Reference< Diagram > xDiagram = xChartDoc->getFirstChartDiagram();
232 if( ! xDiagram.is())
233 return eResult;
235 // Sub Title
236 if( xDiagram.is())
237 impl_getAutoResizeFromTitled( xDiagram, eResult );
238 if( eResult == AUTO_RESIZE_AMBIGUOUS )
239 return eResult;
241 // Legend
242 rtl::Reference< Legend > xLegend( xDiagram->getLegend2() );
243 if( xLegend.is())
244 getAutoResizeFromPropSet( xLegend, eResult );
245 if( eResult == AUTO_RESIZE_AMBIGUOUS )
246 return eResult;
248 // Axes (incl. Axis Titles)
249 const std::vector< rtl::Reference< Axis > > aAxes = AxisHelper::getAllAxesOfDiagram( xDiagram );
250 for( rtl::Reference< Axis > const & axis : aAxes )
252 getAutoResizeFromPropSet( axis, eResult );
253 impl_getAutoResizeFromTitled( axis, eResult );
254 if( eResult == AUTO_RESIZE_AMBIGUOUS )
255 return eResult;
258 // DataSeries/Points
259 std::vector< rtl::Reference< DataSeries > > aSeries =
260 xDiagram->getDataSeries();
262 for (auto const& elem : aSeries)
264 getAutoResizeFromPropSet( elem, eResult );
265 if( eResult == AUTO_RESIZE_AMBIGUOUS )
266 return eResult;
268 // data points
269 Sequence< sal_Int32 > aPointIndexes;
272 // "AttributedDataPoints"
273 if( elem->getFastPropertyValue( PROP_DATASERIES_ATTRIBUTED_DATA_POINTS) >>= aPointIndexes )
275 for (sal_Int32 idx : aPointIndexes)
277 getAutoResizeFromPropSet(
278 elem->getDataPointByIndex( idx ), eResult );
279 if( eResult == AUTO_RESIZE_AMBIGUOUS )
280 return eResult;
284 catch (const uno::Exception&)
286 DBG_UNHANDLED_EXCEPTION("chart2");
290 return eResult;
293 void ReferenceSizeProvider::toggleAutoResizeState()
295 setAutoResizeState( m_bUseAutoScale ? AUTO_RESIZE_NO : AUTO_RESIZE_YES );
298 /** sets the auto-resize at all objects that support this feature for text.
299 eNewState must be either AUTO_RESIZE_YES or AUTO_RESIZE_NO
301 void ReferenceSizeProvider::setAutoResizeState( ReferenceSizeProvider::AutoResizeState eNewState )
303 m_bUseAutoScale = (eNewState == AUTO_RESIZE_YES);
305 // Main Title
306 impl_setValuesAtTitled( m_xChartDoc );
308 // diagram is needed by the rest of the objects
309 rtl::Reference< Diagram > xDiagram = m_xChartDoc->getFirstChartDiagram();
310 if( ! xDiagram.is())
311 return;
313 // Sub Title
314 impl_setValuesAtTitled( xDiagram );
316 // Legend
317 rtl::Reference< Legend > xLegend( xDiagram->getLegend2() );
318 if( xLegend.is())
319 setValuesAtPropertySet( xLegend );
321 // Axes (incl. Axis Titles)
322 const std::vector< rtl::Reference< Axis > > aAxes = AxisHelper::getAllAxesOfDiagram( xDiagram );
323 for( rtl::Reference< Axis > const & axis : aAxes )
325 setValuesAtPropertySet( axis );
326 impl_setValuesAtTitled( axis );
329 // DataSeries/Points
330 setValuesAtAllDataSeries();
332 // recalculate new state (in case it stays unknown or is ambiguous
333 m_bUseAutoScale = (getAutoResizeState( m_xChartDoc ) == AUTO_RESIZE_YES);
336 } // namespace chart
338 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */