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_xmloff.hxx"
30 
31 #include "SchXMLSeriesHelper.hxx"
32 #include <com/sun/star/chart2/XChartDocument.hpp>
33 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
34 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
35 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
36 #include <com/sun/star/lang/XInitialization.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 
39 // header for define RTL_CONSTASCII_USTRINGPARAM
40 #include <rtl/ustring.h>
41 // header for define DBG_ERROR1
42 #include <tools/debug.hxx>
43 
44 #include <typeinfo>
45 
46 using namespace ::com::sun::star;
47 using ::rtl::OUString;
48 using ::rtl::OUStringToOString;
49 
50 using ::com::sun::star::uno::Reference;
51 using ::com::sun::star::uno::Sequence;
52 using ::rtl::OUString;
53 
54 // ----------------------------------------
55 
56 ::std::vector< Reference< chart2::XDataSeries > >
57     SchXMLSeriesHelper::getDataSeriesFromDiagram(
58         const Reference< chart2::XDiagram > & xDiagram )
59 {
60     ::std::vector< Reference< chart2::XDataSeries > > aResult;
61 
62     try
63     {
64         Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
65             xDiagram, uno::UNO_QUERY_THROW );
66         Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
67             xCooSysCnt->getCoordinateSystems());
68         for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
69         {
70             Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
71             Sequence< Reference< chart2::XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
72             for( sal_Int32 j=0; j<aChartTypeSeq.getLength(); ++j )
73             {
74                 Reference< chart2::XDataSeriesContainer > xDSCnt( aChartTypeSeq[j], uno::UNO_QUERY_THROW );
75                 Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
76                 ::std::copy( aSeriesSeq.getConstArray(), aSeriesSeq.getConstArray() + aSeriesSeq.getLength(),
77                              ::std::back_inserter( aResult ));
78             }
79         }
80     }
81     catch( uno::Exception & ex )
82     {
83         (void)ex; // avoid warning for pro build
84 
85         OSL_ENSURE( false, OUStringToOString( OUString(
86                         OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
87                         OUString::createFromAscii( typeid( ex ).name()) +
88                         OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
89                         ex.Message), RTL_TEXTENCODING_ASCII_US ).getStr());
90 
91     }
92 
93     return aResult;
94 }
95 
96 ::std::map< Reference< chart2::XDataSeries >, sal_Int32 > SchXMLSeriesHelper::getDataSeriesIndexMapFromDiagram(
97         const Reference< chart2::XDiagram > & xDiagram )
98 {
99     ::std::map< Reference< chart2::XDataSeries >, sal_Int32 > aRet;
100 
101     sal_Int32 nIndex=0;
102 
103     ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram ));
104     for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aSeriesIt( aSeriesVector.begin() )
105         ; aSeriesIt != aSeriesVector.end()
106         ; aSeriesIt++, nIndex++ )
107     {
108         Reference< chart2::XDataSeries > xSeries( *aSeriesIt );
109         if( xSeries.is() )
110         {
111             if( aRet.end() == aRet.find(xSeries) )
112                 aRet[xSeries]=nIndex;
113         }
114     }
115     return aRet;
116 }
117 
118 uno::Reference< chart2::XChartType > lcl_getChartTypeOfSeries(
119 								const uno::Reference< chart2::XDiagram >&   xDiagram
120 						      , const Reference< chart2::XDataSeries >& xSeries )
121 {
122     if(!xDiagram.is())
123         return 0;
124 
125 	//iterate through the model to find the given xSeries
126 	//the found parent indicates the charttype
127 
128     //iterate through all coordinate systems
129     uno::Reference< chart2::XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
130     if( !xCooSysContainer.is())
131         return 0;
132 
133     uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
134     for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
135     {
136         uno::Reference< chart2::XCoordinateSystem > xCooSys( aCooSysList[nCS] );
137 
138         //iterate through all chart types in the current coordinate system
139         uno::Reference< chart2::XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
140         OSL_ASSERT( xChartTypeContainer.is());
141         if( !xChartTypeContainer.is() )
142             continue;
143         uno::Sequence< uno::Reference< chart2::XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
144         for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
145         {
146             uno::Reference< chart2::XChartType > xChartType( aChartTypeList[nT] );
147 
148             //iterate through all series in this chart type
149             uno::Reference< chart2::XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
150             OSL_ASSERT( xDataSeriesContainer.is());
151             if( !xDataSeriesContainer.is() )
152                 continue;
153 
154             uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
155             for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
156             {
157                 Reference< chart2::XDataSeries > xCurrentSeries( aSeriesList[nS] );
158 
159                 if( xSeries == xCurrentSeries )
160                     return xChartType;
161             }
162         }
163     }
164 	return 0;
165 }
166 
167 bool SchXMLSeriesHelper::isCandleStickSeries(
168                   const Reference< chart2::XDataSeries >& xSeries
169                 , const Reference< frame::XModel >& xChartModel )
170 {
171     bool bRet = false;
172 
173     uno::Reference< chart2::XChartDocument > xNewDoc( xChartModel, uno::UNO_QUERY );
174     if( xNewDoc.is() )
175     {
176         uno::Reference< chart2::XDiagram > xNewDiagram( xNewDoc->getFirstDiagram() );
177         if( xNewDiagram.is() )
178         {
179             uno::Reference< chart2::XChartType > xChartType( lcl_getChartTypeOfSeries(
180 								        xNewDiagram, xSeries ) );
181             if( xChartType.is() )
182             {
183                 rtl::OUString aServiceName( xChartType->getChartType() );
184                 if( aServiceName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.CandleStickChartType" ) ) ) )
185                     bRet = true;
186             }
187         }
188     }
189     return bRet;
190 }
191 
192 // static
193 Reference< chart2::XDataSeries > SchXMLSeriesHelper::getFirstCandleStickSeries(
194     const Reference< chart2::XDiagram > & xDiagram  )
195 {
196     Reference< chart2::XDataSeries > xResult;
197 
198     try
199     {
200         Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
201         Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
202         for( sal_Int32 nCooSysIdx=0; !xResult.is() && nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
203         {
204             Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
205             Sequence< Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
206             for( sal_Int32 nCTIdx=0; !xResult.is() && nCTIdx<aCTSeq.getLength(); ++nCTIdx )
207             {
208                 if( aCTSeq[nCTIdx]->getChartType().equals(
209                         ::rtl::OUString::createFromAscii("com.sun.star.chart2.CandleStickChartType")))
210                 {
211                     Reference< chart2::XDataSeriesContainer > xSeriesCnt( aCTSeq[nCTIdx], uno::UNO_QUERY_THROW );
212                     Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xSeriesCnt->getDataSeries() );
213                     if( aSeriesSeq.getLength())
214                         xResult.set( aSeriesSeq[0] );
215                     break;
216                 }
217             }
218         }
219     }
220     catch( const uno::Exception & )
221     {
222         OSL_ENSURE( false, "Exception caught" );
223     }
224     return xResult;
225 }
226 
227 //static
228 uno::Reference< beans::XPropertySet > SchXMLSeriesHelper::createOldAPISeriesPropertySet(
229             const uno::Reference< chart2::XDataSeries >& xSeries
230             , const uno::Reference< frame::XModel >& xChartModel )
231 {
232     uno::Reference< beans::XPropertySet > xRet;
233 
234     if( xSeries.is() )
235     {
236         try
237         {
238             uno::Reference< lang::XMultiServiceFactory > xFactory( xChartModel, uno::UNO_QUERY );
239             if( xFactory.is() )
240             {
241                 xRet = uno::Reference< beans::XPropertySet >( xFactory->createInstance(
242                     OUString::createFromAscii( "com.sun.star.comp.chart2.DataSeriesWrapper" ) ), uno::UNO_QUERY );
243                 Reference< lang::XInitialization > xInit( xRet, uno::UNO_QUERY );
244                 if(xInit.is())
245                 {
246                     Sequence< uno::Any > aArguments(1);
247                     aArguments[0]=uno::makeAny(xSeries);
248                     xInit->initialize(aArguments);
249                 }
250             }
251         }
252         catch( uno::Exception & rEx )
253 	    {
254             (void)rEx; // avoid warning for pro build
255             DBG_ERROR1( "Exception caught SchXMLSeriesHelper::createOldAPISeriesPropertySet: %s",
256                         OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
257         }
258     }
259 
260     return xRet;
261 }
262 
263 //static
264 uno::Reference< beans::XPropertySet > SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
265             const uno::Reference< chart2::XDataSeries >& xSeries
266             , sal_Int32 nPointIndex
267             , const uno::Reference< frame::XModel >& xChartModel )
268 {
269     uno::Reference< beans::XPropertySet > xRet;
270 
271     if( xSeries.is() )
272     {
273         try
274         {
275             uno::Reference< lang::XMultiServiceFactory > xFactory( xChartModel, uno::UNO_QUERY );
276             if( xFactory.is() )
277             {
278                 xRet = uno::Reference< beans::XPropertySet >( xFactory->createInstance(
279                     OUString::createFromAscii( "com.sun.star.comp.chart2.DataSeriesWrapper" ) ), uno::UNO_QUERY );
280                 Reference< lang::XInitialization > xInit( xRet, uno::UNO_QUERY );
281                 if(xInit.is())
282                 {
283                     Sequence< uno::Any > aArguments(2);
284                     aArguments[0]=uno::makeAny(xSeries);
285                     aArguments[1]=uno::makeAny(nPointIndex);
286                     xInit->initialize(aArguments);
287                 }
288             }
289         }
290         catch( uno::Exception & rEx )
291 	    {
292             (void)rEx; // avoid warning for pro build
293 
294             DBG_ERROR1( "Exception caught SchXMLSeriesHelper::createOldAPIDataPointPropertySet: %s",
295                         OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
296         }
297     }
298 
299     return xRet;
300 }
301 
302