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