nss: upgrade to release 3.73
[LibreOffice.git] / chart2 / source / view / axes / VAxisProperties.cxx
blob27a4950a886b23421903c82e6ec04e316a96146e
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 "VAxisProperties.hxx"
21 #include <ViewDefines.hxx>
22 #include <AxisHelper.hxx>
23 #include <ChartModelHelper.hxx>
24 #include <ExplicitCategoriesProvider.hxx>
26 #include <com/sun/star/beans/XPropertySet.hpp>
27 #include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp>
28 #include <com/sun/star/chart2/AxisType.hpp>
29 #include <com/sun/star/chart2/XAxis.hpp>
31 #include <tools/diagnose_ex.h>
32 #include <rtl/math.hxx>
34 using namespace ::com::sun::star;
35 using namespace ::com::sun::star::chart2;
37 namespace chart {
39 AxisLabelAlignment::AxisLabelAlignment() :
40 mfLabelDirection(1.0),
41 mfInnerTickDirection(1.0),
42 meAlignment(LABEL_ALIGN_RIGHT_TOP) {}
44 static sal_Int32 lcl_calcTickLengthForDepth(sal_Int32 nDepth,sal_Int32 nTickmarkStyle)
46 sal_Int32 const nWidth = AXIS2D_TICKLENGTH; //@maybefuturetodo this length could be offered by the model
47 double fPercent = 1.0;
48 switch(nDepth)
50 case 0:
51 fPercent = 1.0;
52 break;
53 case 1:
54 fPercent = 0.75;//percentage like in the old chart
55 break;
56 case 2:
57 fPercent = 0.5;
58 break;
59 default:
60 fPercent = 0.3;
61 break;
63 if(nTickmarkStyle==3)//inner and outer tickmarks
64 fPercent*=2.0;
65 return static_cast<sal_Int32>(nWidth*fPercent);
68 static double lcl_getTickOffset(sal_Int32 nLength,sal_Int32 nTickmarkStyle)
70 double fPercent = 0.0; //0<=fPercent<=1
71 //0.0: completely inner
72 //1.0: completely outer
73 //0.5: half and half
76 nTickmarkStyle:
77 1: inner tickmarks
78 2: outer tickmarks
79 3: inner and outer tickmarks
81 switch(nTickmarkStyle)
83 case 1:
84 fPercent = 0.0;
85 break;
86 case 2:
87 fPercent = 1.0;
88 break;
89 default:
90 fPercent = 0.5;
91 break;
93 return fPercent*nLength;
96 TickmarkProperties AxisProperties::makeTickmarkProperties(
97 sal_Int32 nDepth ) const
100 nTickmarkStyle:
101 1: inner tickmarks
102 2: outer tickmarks
103 3: inner and outer tickmarks
105 sal_Int32 nTickmarkStyle = 1;
106 if(nDepth==0)
108 nTickmarkStyle = m_nMajorTickmarks;
109 if(!nTickmarkStyle)
111 //create major tickmarks as if they were minor tickmarks
112 nDepth = 1;
113 nTickmarkStyle = m_nMinorTickmarks;
116 else if( nDepth==1)
118 nTickmarkStyle = m_nMinorTickmarks;
121 if (maLabelAlignment.mfInnerTickDirection == 0.0)
123 if( nTickmarkStyle != 0 )
124 nTickmarkStyle = 3; //inner and outer tickmarks
127 TickmarkProperties aTickmarkProperties;
128 aTickmarkProperties.Length = lcl_calcTickLengthForDepth(nDepth,nTickmarkStyle);
129 aTickmarkProperties.RelativePos = static_cast<sal_Int32>(lcl_getTickOffset(aTickmarkProperties.Length,nTickmarkStyle));
130 aTickmarkProperties.aLineProperties = makeLinePropertiesForDepth();
131 return aTickmarkProperties;
134 TickmarkProperties AxisProperties::makeTickmarkPropertiesForComplexCategories(
135 sal_Int32 nTickLength, sal_Int32 nTickStartDistanceToAxis ) const
137 sal_Int32 nTickmarkStyle = (maLabelAlignment.mfLabelDirection == maLabelAlignment.mfInnerTickDirection) ? 2/*outside*/ : 1/*inside*/;
139 TickmarkProperties aTickmarkProperties;
140 aTickmarkProperties.Length = nTickLength;// + nTextLevel*( lcl_calcTickLengthForDepth(0,nTickmarkStyle) );
141 aTickmarkProperties.RelativePos = static_cast<sal_Int32>(lcl_getTickOffset(aTickmarkProperties.Length+nTickStartDistanceToAxis,nTickmarkStyle));
142 aTickmarkProperties.aLineProperties = makeLinePropertiesForDepth();
143 return aTickmarkProperties;
146 TickmarkProperties AxisProperties::getBiggestTickmarkProperties()
148 TickmarkProperties aTickmarkProperties;
149 sal_Int32 nTickmarkStyle = 3;//inner and outer tickmarks
150 aTickmarkProperties.Length = lcl_calcTickLengthForDepth( 0/*nDepth*/,nTickmarkStyle );
151 aTickmarkProperties.RelativePos = static_cast<sal_Int32>( lcl_getTickOffset( aTickmarkProperties.Length, nTickmarkStyle ) );
152 return aTickmarkProperties;
155 AxisProperties::AxisProperties( const uno::Reference< XAxis >& xAxisModel
156 , ExplicitCategoriesProvider* pExplicitCategoriesProvider )
157 : m_xAxisModel(xAxisModel)
158 , m_nDimensionIndex(0)
159 , m_bIsMainAxis(true)
160 , m_bSwapXAndY(false)
161 , m_eCrossoverType( css::chart::ChartAxisPosition_ZERO )
162 , m_eLabelPos( css::chart::ChartAxisLabelPosition_NEAR_AXIS )
163 , m_eTickmarkPos( css::chart::ChartAxisMarkPosition_AT_LABELS_AND_AXIS )
164 , m_bCrossingAxisHasReverseDirection(false)
165 , m_bCrossingAxisIsCategoryAxes(false)
166 , m_bDisplayLabels( true )
167 , m_bTryStaggeringFirst( false )
168 , m_nNumberFormatKey(0)
169 , m_nMajorTickmarks(1)
170 , m_nMinorTickmarks(1)
171 , m_aTickmarkPropertiesList()
172 , m_aLineProperties()
173 //for category axes
174 , m_nAxisType(AxisType::REALNUMBER)
175 , m_bComplexCategories(false)
176 , m_pExplicitCategoriesProvider(pExplicitCategoriesProvider)
177 , m_bLimitSpaceForLabels(false)
181 static LabelAlignment lcl_getLabelAlignmentForZAxis( const AxisProperties& rAxisProperties )
183 LabelAlignment aRet( LABEL_ALIGN_RIGHT );
184 if (rAxisProperties.maLabelAlignment.mfLabelDirection < 0)
185 aRet = LABEL_ALIGN_LEFT;
186 return aRet;
189 static LabelAlignment lcl_getLabelAlignmentForYAxis( const AxisProperties& rAxisProperties )
191 LabelAlignment aRet( LABEL_ALIGN_RIGHT );
192 if (rAxisProperties.maLabelAlignment.mfLabelDirection < 0)
193 aRet = LABEL_ALIGN_LEFT;
194 return aRet;
197 static LabelAlignment lcl_getLabelAlignmentForXAxis( const AxisProperties& rAxisProperties )
199 LabelAlignment aRet( LABEL_ALIGN_BOTTOM );
200 if (rAxisProperties.maLabelAlignment.mfLabelDirection < 0)
201 aRet = LABEL_ALIGN_TOP;
202 return aRet;
205 void AxisProperties::initAxisPositioning( const uno::Reference< beans::XPropertySet >& xAxisProp )
207 if( !xAxisProp.is() )
208 return;
211 if( AxisHelper::isAxisPositioningEnabled() )
213 xAxisProp->getPropertyValue("CrossoverPosition") >>= m_eCrossoverType;
214 if( m_eCrossoverType == css::chart::ChartAxisPosition_VALUE )
216 double fValue = 0.0;
217 xAxisProp->getPropertyValue("CrossoverValue") >>= fValue;
219 if( m_bCrossingAxisIsCategoryAxes )
220 fValue = ::rtl::math::round(fValue);
221 m_pfMainLinePositionAtOtherAxis = fValue;
223 else if( m_eCrossoverType == css::chart::ChartAxisPosition_ZERO )
224 m_pfMainLinePositionAtOtherAxis = 0.0;
226 xAxisProp->getPropertyValue("LabelPosition") >>= m_eLabelPos;
227 xAxisProp->getPropertyValue("MarkPosition") >>= m_eTickmarkPos;
229 else
231 m_eCrossoverType = css::chart::ChartAxisPosition_START;
232 if( m_bIsMainAxis == m_bCrossingAxisHasReverseDirection )
233 m_eCrossoverType = css::chart::ChartAxisPosition_END;
234 m_eLabelPos = css::chart::ChartAxisLabelPosition_NEAR_AXIS;
235 m_eTickmarkPos = css::chart::ChartAxisMarkPosition_AT_LABELS;
238 catch( const uno::Exception& )
240 TOOLS_WARN_EXCEPTION("chart2", "" );
244 void AxisProperties::init( bool bCartesian )
246 uno::Reference< beans::XPropertySet > xProp =
247 uno::Reference<beans::XPropertySet>::query( m_xAxisModel );
248 if( !xProp.is() )
249 return;
251 if( m_nDimensionIndex<2 )
252 initAxisPositioning( xProp );
254 ScaleData aScaleData = m_xAxisModel->getScaleData();
255 if( m_nDimensionIndex==0 )
256 AxisHelper::checkDateAxis( aScaleData, m_pExplicitCategoriesProvider, bCartesian );
257 m_nAxisType = aScaleData.AxisType;
259 if( bCartesian )
261 if( m_nDimensionIndex == 0 && m_nAxisType == AxisType::CATEGORY
262 && m_pExplicitCategoriesProvider && m_pExplicitCategoriesProvider->hasComplexCategories() )
263 m_bComplexCategories = true;
265 if( m_eCrossoverType == css::chart::ChartAxisPosition_END )
266 maLabelAlignment.mfInnerTickDirection = m_bCrossingAxisHasReverseDirection ? 1.0 : -1.0;
267 else
268 maLabelAlignment.mfInnerTickDirection = m_bCrossingAxisHasReverseDirection ? -1.0 : 1.0;
270 if( m_eLabelPos == css::chart::ChartAxisLabelPosition_NEAR_AXIS )
271 maLabelAlignment.mfLabelDirection = maLabelAlignment.mfInnerTickDirection;
272 else if( m_eLabelPos == css::chart::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE )
273 maLabelAlignment.mfLabelDirection = -maLabelAlignment.mfInnerTickDirection;
274 else if( m_eLabelPos == css::chart::ChartAxisLabelPosition_OUTSIDE_START )
275 maLabelAlignment.mfLabelDirection = m_bCrossingAxisHasReverseDirection ? -1 : 1;
276 else if( m_eLabelPos == css::chart::ChartAxisLabelPosition_OUTSIDE_END )
277 maLabelAlignment.mfLabelDirection = m_bCrossingAxisHasReverseDirection ? 1 : -1;
279 if( m_nDimensionIndex==2 )
280 maLabelAlignment.meAlignment = lcl_getLabelAlignmentForZAxis(*this);
281 else
283 bool bIsYAxisPosition = (m_nDimensionIndex==1 && !m_bSwapXAndY)
284 || (m_nDimensionIndex==0 && m_bSwapXAndY);
285 if( bIsYAxisPosition )
287 maLabelAlignment.mfLabelDirection *= -1.0;
288 maLabelAlignment.mfInnerTickDirection *= -1.0;
291 if( bIsYAxisPosition )
292 maLabelAlignment.meAlignment = lcl_getLabelAlignmentForYAxis(*this);
293 else
294 maLabelAlignment.meAlignment = lcl_getLabelAlignmentForXAxis(*this);
300 //init LineProperties
301 m_aLineProperties.initFromPropertySet( xProp );
303 //init display labels
304 xProp->getPropertyValue( "DisplayLabels" ) >>= m_bDisplayLabels;
306 // Init layout strategy hint for axis labels.
307 // Compatibility option: starting from LibreOffice 5.1 the rotated
308 // layout is preferred to staggering for axis labels.
309 xProp->getPropertyValue( "TryStaggeringFirst" ) >>= m_bTryStaggeringFirst;
311 //init TickmarkProperties
312 xProp->getPropertyValue( "MajorTickmarks" ) >>= m_nMajorTickmarks;
313 xProp->getPropertyValue( "MinorTickmarks" ) >>= m_nMinorTickmarks;
315 sal_Int32 nMaxDepth = 0;
316 if(m_nMinorTickmarks!=0)
317 nMaxDepth=2;
318 else if(m_nMajorTickmarks!=0)
319 nMaxDepth=1;
321 m_aTickmarkPropertiesList.clear();
322 for( sal_Int32 nDepth=0; nDepth<nMaxDepth; nDepth++ )
324 TickmarkProperties aTickmarkProperties = makeTickmarkProperties( nDepth );
325 m_aTickmarkPropertiesList.push_back( aTickmarkProperties );
328 catch( const uno::Exception& )
330 TOOLS_WARN_EXCEPTION("chart2", "" );
334 AxisLabelProperties::AxisLabelProperties()
335 : m_aFontReferenceSize( ChartModelHelper::getDefaultPageSize() )
336 , m_aMaximumSpaceForLabels( 0 , 0, m_aFontReferenceSize.Width, m_aFontReferenceSize.Height )
337 , nNumberFormatKey(0)
338 , eStaggering( AxisLabelStaggering::SideBySide )
339 , bLineBreakAllowed( false )
340 , bOverlapAllowed( false )
341 , bStackCharacters( false )
342 , fRotationAngleDegree( 0.0 )
343 , nRhythm( 1 )
348 void AxisLabelProperties::init( const uno::Reference< XAxis >& xAxisModel )
350 uno::Reference< beans::XPropertySet > xProp =
351 uno::Reference<beans::XPropertySet>::query( xAxisModel );
352 if(!xProp.is())
353 return;
357 xProp->getPropertyValue( "TextBreak" ) >>= bLineBreakAllowed;
358 xProp->getPropertyValue( "TextOverlap" ) >>= bOverlapAllowed;
359 xProp->getPropertyValue( "StackCharacters" ) >>= bStackCharacters;
360 xProp->getPropertyValue( "TextRotation" ) >>= fRotationAngleDegree;
362 css::chart::ChartAxisArrangeOrderType eArrangeOrder;
363 xProp->getPropertyValue( "ArrangeOrder" ) >>= eArrangeOrder;
364 switch(eArrangeOrder)
366 case css::chart::ChartAxisArrangeOrderType_SIDE_BY_SIDE:
367 eStaggering = AxisLabelStaggering::SideBySide;
368 break;
369 case css::chart::ChartAxisArrangeOrderType_STAGGER_EVEN:
370 eStaggering = AxisLabelStaggering::StaggerEven;
371 break;
372 case css::chart::ChartAxisArrangeOrderType_STAGGER_ODD:
373 eStaggering = AxisLabelStaggering::StaggerOdd;
374 break;
375 default:
376 eStaggering = AxisLabelStaggering::StaggerAuto;
377 break;
380 catch( const uno::Exception& )
382 TOOLS_WARN_EXCEPTION("chart2", "" );
386 bool AxisLabelProperties::isStaggered() const
388 return ( eStaggering == AxisLabelStaggering::StaggerOdd || eStaggering == AxisLabelStaggering::StaggerEven );
391 void AxisLabelProperties::autoRotate45()
393 fRotationAngleDegree = 45;
394 bLineBreakAllowed = false;
395 eStaggering = AxisLabelStaggering::SideBySide;
398 } //namespace chart
400 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */