1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chart2.hxx"
26 
27 #include "VAxisBase.hxx"
28 #include "ShapeFactory.hxx"
29 #include "CommonConverters.hxx"
30 #include "Tickmarks.hxx"
31 #include "macros.hxx"
32 
33 // header for define DBG_ASSERT
34 #include <tools/debug.hxx>
35 
36 #include <memory>
37 
38 //.............................................................................
39 namespace chart
40 {
41 //.............................................................................
42 using namespace ::com::sun::star;
43 using namespace ::com::sun::star::chart2;
44 using ::com::sun::star::uno::Reference;
45 
VAxisBase(sal_Int32 nDimensionIndex,sal_Int32 nDimensionCount,const AxisProperties & rAxisProperties,const uno::Reference<util::XNumberFormatsSupplier> & xNumberFormatsSupplier)46 VAxisBase::VAxisBase( sal_Int32 nDimensionIndex, sal_Int32 nDimensionCount
47                      , const AxisProperties& rAxisProperties
48                      , const uno::Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier )
49             : VAxisOrGridBase( nDimensionIndex, nDimensionCount )
50             , m_xNumberFormatsSupplier( xNumberFormatsSupplier )
51             , m_aAxisProperties( rAxisProperties )
52             , m_bUseTextLabels( false )
53             , m_bReCreateAllTickInfos( true )
54             , m_bRecordMaximumTextSize(false)
55             , m_nMaximumTextWidthSoFar(0)
56             , m_nMaximumTextHeightSoFar(0)
57 {
58 }
59 
~VAxisBase()60 VAxisBase::~VAxisBase()
61 {
62 }
63 
getDimensionCount()64 sal_Int32 VAxisBase::getDimensionCount()
65 {
66     return m_nDimension;
67 }
68 
initAxisLabelProperties(const::com::sun::star::awt::Size & rFontReferenceSize,const::com::sun::star::awt::Rectangle & rMaximumSpaceForLabels)69 void VAxisBase::initAxisLabelProperties( const ::com::sun::star::awt::Size& rFontReferenceSize
70                   , const ::com::sun::star::awt::Rectangle& rMaximumSpaceForLabels )
71 {
72     m_aAxisLabelProperties.m_aFontReferenceSize = rFontReferenceSize;
73     m_aAxisLabelProperties.m_aMaximumSpaceForLabels = rMaximumSpaceForLabels;
74 
75     if( !m_aAxisProperties.m_bDisplayLabels )
76         return;
77 
78     if( AxisType::SERIES==m_aAxisProperties.m_nAxisType )
79     {
80         if( m_aAxisProperties.m_xAxisTextProvider.is() )
81             m_aTextLabels = m_aAxisProperties.m_xAxisTextProvider->getTextualData();
82 
83         m_bUseTextLabels = true;
84         if( m_aTextLabels.getLength() == 1 )
85         {
86             //don't show a single series name
87             m_aAxisProperties.m_bDisplayLabels = false;
88             return;
89         }
90     }
91     else if( AxisType::CATEGORY==m_aAxisProperties.m_nAxisType )
92     {
93         if( m_aAxisProperties.m_pExplicitCategoriesProvider )
94             m_aTextLabels = m_aAxisProperties.m_pExplicitCategoriesProvider->getSimpleCategories();
95 
96         m_bUseTextLabels = true;
97     }
98 
99     m_aAxisLabelProperties.nNumberFormatKey = m_aAxisProperties.m_nNumberFormatKey;
100     m_aAxisLabelProperties.init(m_aAxisProperties.m_xAxisModel);
101     if( m_aAxisProperties.m_bComplexCategories && AxisType::CATEGORY == m_aAxisProperties.m_nAxisType )
102         m_aAxisLabelProperties.eStaggering = SIDE_BY_SIDE;
103 }
104 
isDateAxis() const105 bool VAxisBase::isDateAxis() const
106 {
107     return AxisType::DATE == m_aScale.AxisType;
108 }
isComplexCategoryAxis() const109 bool VAxisBase::isComplexCategoryAxis() const
110 {
111     return m_aAxisProperties.m_bComplexCategories && m_bUseTextLabels;
112 }
113 
recordMaximumTextSize(const Reference<drawing::XShape> & xShape,double fRotationAngleDegree)114 void VAxisBase::recordMaximumTextSize( const Reference< drawing::XShape >& xShape, double fRotationAngleDegree )
115 {
116     if( m_bRecordMaximumTextSize && xShape.is() )
117     {
118         awt::Size aSize( ShapeFactory::getSizeAfterRotation(
119                             xShape, fRotationAngleDegree ) );
120 
121         m_nMaximumTextWidthSoFar = std::max( m_nMaximumTextWidthSoFar, aSize.Width );
122         m_nMaximumTextHeightSoFar = std::max( m_nMaximumTextHeightSoFar, aSize.Height );
123     }
124 }
125 
estimateMaximumAutoMainIncrementCount()126 sal_Int32 VAxisBase::estimateMaximumAutoMainIncrementCount()
127 {
128     return 10;
129 }
130 
setExrtaLinePositionAtOtherAxis(const double & fCrossingAt)131 void VAxisBase::setExrtaLinePositionAtOtherAxis( const double& fCrossingAt )
132 {
133     if( m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis )
134         delete m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis;
135     m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis = new double(fCrossingAt);
136 }
137 
isAnythingToDraw()138 sal_Bool VAxisBase::isAnythingToDraw()
139 {
140     if( !m_aAxisProperties.m_xAxisModel.is() )
141         return false;
142 
143     DBG_ASSERT(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is(),"Axis is not proper initialized");
144     if(!(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()))
145         return false;
146 
147     uno::Reference< beans::XPropertySet > xProps( m_aAxisProperties.m_xAxisModel, uno::UNO_QUERY );
148     if( xProps.is() )
149     {
150         sal_Bool bShow = sal_False;
151         xProps->getPropertyValue( C2U( "Show" ) ) >>= bShow;
152         if( !bShow )
153             return false;
154     }
155     return true;
156 }
157 
setExplicitScaleAndIncrement(const ExplicitScaleData & rScale,const ExplicitIncrementData & rIncrement)158 void VAxisBase::setExplicitScaleAndIncrement(
159               const ExplicitScaleData& rScale
160             , const ExplicitIncrementData& rIncrement )
161             throw (uno::RuntimeException)
162 {
163     m_bReCreateAllTickInfos = true;
164     m_aScale = rScale;
165     m_aIncrement = rIncrement;
166 }
167 
createAllTickInfos(::std::vector<::std::vector<TickInfo>> & rAllTickInfos)168 void VAxisBase::createAllTickInfos( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos )
169 {
170     std::auto_ptr< TickFactory > apTickFactory( this->createTickFactory() );
171     if( m_aScale.ShiftedCategoryPosition )
172         apTickFactory->getAllTicksShifted( rAllTickInfos );
173     else
174         apTickFactory->getAllTicks( rAllTickInfos );
175 }
176 
prepareShapeCreation()177 bool VAxisBase::prepareShapeCreation()
178 {
179     //returns true if all is ready for further shape creation and any shapes need to be created
180     if( !isAnythingToDraw() )
181         return false;
182 
183     if( m_bReCreateAllTickInfos )
184     {
185         //-----------------------------------------
186         //create all scaled tickmark values
187         removeTextShapesFromTicks();
188 
189         createAllTickInfos(m_aAllTickInfos);
190         m_bReCreateAllTickInfos = false;
191     }
192 
193     if( m_xGroupShape_Shapes.is() )
194         return true;
195 
196     //-----------------------------------------
197     //create named group shape
198     m_xGroupShape_Shapes = this->createGroupShape( m_xLogicTarget, m_nDimension==2 ? m_aCID : C2U(""));
199 
200     if( m_aAxisProperties.m_bDisplayLabels )
201         m_xTextTarget = m_pShapeFactory->createGroup2D( m_xFinalTarget, m_aCID );
202 
203     return true;
204 }
205 
getIndexOfLongestLabel(const uno::Sequence<rtl::OUString> & rLabels)206 sal_Int32 VAxisBase::getIndexOfLongestLabel( const uno::Sequence< rtl::OUString >& rLabels )
207 {
208     sal_Int32 nRet = 0;
209     sal_Int32 nLength = 0;
210     sal_Int32 nN = 0;
211     for( nN=0; nN<rLabels.getLength(); nN++ )
212     {
213         //todo: get real text width (without creating shape) instead of character count
214         if( rLabels[nN].getLength() > nLength )
215         {
216             nLength = rLabels[nN].getLength();
217             nRet = nN;
218         }
219     }
220     return nRet;
221 }
222 
removeTextShapesFromTicks()223 void VAxisBase::removeTextShapesFromTicks()
224 {
225     if( m_xTextTarget.is() )
226     {
227        ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter = m_aAllTickInfos.begin();
228         const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd  = m_aAllTickInfos.end();
229         for( ; aDepthIter != aDepthEnd; aDepthIter++ )
230         {
231             ::std::vector< TickInfo >::iterator       aTickIter = (*aDepthIter).begin();
232             const ::std::vector< TickInfo >::const_iterator aTickEnd  = (*aDepthIter).end();
233             for( ; aTickIter != aTickEnd; aTickIter++ )
234             {
235                 TickInfo& rTickInfo = (*aTickIter);
236                 if(rTickInfo.xTextShape.is())
237                 {
238                     m_xTextTarget->remove(rTickInfo.xTextShape);
239                     rTickInfo.xTextShape = NULL;
240                 }
241             }
242         }
243     }
244 }
245 
updateUnscaledValuesAtTicks(TickIter & rIter)246 void VAxisBase::updateUnscaledValuesAtTicks( TickIter& rIter )
247 {
248     Reference< XScaling > xInverseScaling( NULL );
249     if( m_aScale.Scaling.is() )
250         xInverseScaling = m_aScale.Scaling->getInverseScaling();
251 
252     for( TickInfo* pTickInfo = rIter.firstInfo()
253         ; pTickInfo; pTickInfo = rIter.nextInfo() )
254     {
255         //xxxxx pTickInfo->updateUnscaledValue( xInverseScaling );
256     }
257 }
258 
259 //.............................................................................
260 } //namespace chart
261 //.............................................................................
262