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 #include "ColumnLineChartTypeTemplate.hxx"
27 #include "macros.hxx"
28 #include "CommonConverters.hxx"
29 #include "DiagramHelper.hxx"
30 #include "DataSeriesHelper.hxx"
31 #include "servicenames_charttypes.hxx"
32 #include "ColumnLineDataInterpreter.hxx"
33 #include "ContainerHelper.hxx"
34 #include "PropertyHelper.hxx"
35 #include <com/sun/star/beans/PropertyAttribute.hpp>
36 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
37 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
38 #include <com/sun/star/drawing/LineStyle.hpp>
39
40 #include <algorithm>
41
42 using namespace ::com::sun::star::chart2;
43 using namespace ::com::sun::star;
44
45 using ::com::sun::star::uno::Reference;
46 using ::com::sun::star::uno::Sequence;
47 using ::rtl::OUString;
48 using ::com::sun::star::beans::Property;
49 using ::com::sun::star::uno::Reference;
50 using ::com::sun::star::uno::Any;
51 using ::osl::MutexGuard;
52
53 namespace
54 {
55
56 static const ::rtl::OUString lcl_aServiceName(
57 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.ColumnLineChartTypeTemplate" ));
58
59 enum
60 {
61 PROP_COL_LINE_NUMBER_OF_LINES
62 };
63
lcl_AddPropertiesToVector(::std::vector<Property> & rOutProperties)64 void lcl_AddPropertiesToVector(
65 ::std::vector< Property > & rOutProperties )
66 {
67 rOutProperties.push_back(
68 Property( C2U( "NumberOfLines" ),
69 PROP_COL_LINE_NUMBER_OF_LINES,
70 ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
71 beans::PropertyAttribute::BOUND
72 | beans::PropertyAttribute::MAYBEDEFAULT ));
73 }
74
75 struct StaticColumnLineChartTypeTemplateDefaults_Initializer
76 {
operator ()__anonea19145b0111::StaticColumnLineChartTypeTemplateDefaults_Initializer77 ::chart::tPropertyValueMap* operator()()
78 {
79 static ::chart::tPropertyValueMap aStaticDefaults;
80 lcl_AddDefaultsToMap( aStaticDefaults );
81 return &aStaticDefaults;
82 }
83 private:
lcl_AddDefaultsToMap__anonea19145b0111::StaticColumnLineChartTypeTemplateDefaults_Initializer84 void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap )
85 {
86 ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_COL_LINE_NUMBER_OF_LINES, 1 );
87 }
88 };
89
90 struct StaticColumnLineChartTypeTemplateDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticColumnLineChartTypeTemplateDefaults_Initializer >
91 {
92 };
93
94 struct StaticColumnLineChartTypeTemplateInfoHelper_Initializer
95 {
operator ()__anonea19145b0111::StaticColumnLineChartTypeTemplateInfoHelper_Initializer96 ::cppu::OPropertyArrayHelper* operator()()
97 {
98 static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() );
99 return &aPropHelper;
100 }
101
102 private:
lcl_GetPropertySequence__anonea19145b0111::StaticColumnLineChartTypeTemplateInfoHelper_Initializer103 uno::Sequence< Property > lcl_GetPropertySequence()
104 {
105 ::std::vector< ::com::sun::star::beans::Property > aProperties;
106 lcl_AddPropertiesToVector( aProperties );
107
108 ::std::sort( aProperties.begin(), aProperties.end(),
109 ::chart::PropertyNameLess() );
110
111 return ::chart::ContainerHelper::ContainerToSequence( aProperties );
112 }
113
114 };
115
116 struct StaticColumnLineChartTypeTemplateInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticColumnLineChartTypeTemplateInfoHelper_Initializer >
117 {
118 };
119
120 struct StaticColumnLineChartTypeTemplateInfo_Initializer
121 {
operator ()__anonea19145b0111::StaticColumnLineChartTypeTemplateInfo_Initializer122 uno::Reference< beans::XPropertySetInfo >* operator()()
123 {
124 static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo(
125 ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticColumnLineChartTypeTemplateInfoHelper::get() ) );
126 return &xPropertySetInfo;
127 }
128 };
129
130 struct StaticColumnLineChartTypeTemplateInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticColumnLineChartTypeTemplateInfo_Initializer >
131 {
132 };
133
134 } // anonymous namespace
135
136 namespace chart
137 {
138
ColumnLineChartTypeTemplate(Reference<uno::XComponentContext> const & xContext,const::rtl::OUString & rServiceName,StackMode eStackMode,sal_Int32 nNumberOfLines)139 ColumnLineChartTypeTemplate::ColumnLineChartTypeTemplate(
140 Reference<
141 uno::XComponentContext > const & xContext,
142 const ::rtl::OUString & rServiceName,
143 StackMode eStackMode,
144 sal_Int32 nNumberOfLines ) :
145 ChartTypeTemplate( xContext, rServiceName ),
146 ::property::OPropertySet( m_aMutex ),
147 m_eStackMode( eStackMode )
148 {
149 setFastPropertyValue_NoBroadcast( PROP_COL_LINE_NUMBER_OF_LINES, uno::makeAny( nNumberOfLines ));
150 }
151
~ColumnLineChartTypeTemplate()152 ColumnLineChartTypeTemplate::~ColumnLineChartTypeTemplate()
153 {}
154
155 // ____ OPropertySet ____
GetDefaultValue(sal_Int32 nHandle) const156 uno::Any ColumnLineChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle ) const
157 throw(beans::UnknownPropertyException)
158 {
159 const tPropertyValueMap& rStaticDefaults = *StaticColumnLineChartTypeTemplateDefaults::get();
160 tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) );
161 if( aFound == rStaticDefaults.end() )
162 return uno::Any();
163 return (*aFound).second;
164 }
165
getInfoHelper()166 ::cppu::IPropertyArrayHelper & SAL_CALL ColumnLineChartTypeTemplate::getInfoHelper()
167 {
168 return *StaticColumnLineChartTypeTemplateInfoHelper::get();
169 }
170
171 // ____ XPropertySet ____
getPropertySetInfo()172 uno::Reference< beans::XPropertySetInfo > SAL_CALL ColumnLineChartTypeTemplate::getPropertySetInfo()
173 throw (uno::RuntimeException)
174 {
175 return *StaticColumnLineChartTypeTemplateInfo::get();
176 }
177
createChartTypes(const Sequence<Sequence<Reference<XDataSeries>>> & aSeriesSeq,const Sequence<Reference<XCoordinateSystem>> & rCoordSys,const Sequence<Reference<XChartType>> & aOldChartTypesSeq)178 void ColumnLineChartTypeTemplate::createChartTypes(
179 const Sequence< Sequence< Reference< XDataSeries > > > & aSeriesSeq,
180 const Sequence< Reference< XCoordinateSystem > > & rCoordSys,
181 const Sequence< Reference< XChartType > >& aOldChartTypesSeq )
182 {
183 if( rCoordSys.getLength() == 0 ||
184 ! rCoordSys[0].is() )
185 return;
186
187 try
188 {
189 Reference< lang::XMultiServiceFactory > xFact(
190 GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW );
191 Sequence< Reference< XDataSeries > > aFlatSeriesSeq( FlattenSequence( aSeriesSeq ));
192 sal_Int32 nNumberOfSeries = aFlatSeriesSeq.getLength();
193 sal_Int32 nNumberOfLines = 0;
194 sal_Int32 nNumberOfColumns = 0;
195
196 getFastPropertyValue( PROP_COL_LINE_NUMBER_OF_LINES ) >>= nNumberOfLines;
197 OSL_ENSURE( nNumberOfLines>=0, "number of lines should be not negative" );
198 if( nNumberOfLines < 0 )
199 nNumberOfLines = 0;
200
201 if( nNumberOfLines >= nNumberOfSeries )
202 {
203 if( nNumberOfSeries > 0 )
204 {
205 nNumberOfLines = nNumberOfSeries - 1;
206 nNumberOfColumns = 1;
207 }
208 else
209 nNumberOfLines = 0;
210 }
211 else
212 nNumberOfColumns = nNumberOfSeries - nNumberOfLines;
213
214 // Columns
215 // -------
216 Reference< XChartType > xCT(
217 xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ), uno::UNO_QUERY_THROW );
218
219 ChartTypeTemplate::copyPropertiesFromOldToNewCoordianteSystem( aOldChartTypesSeq, xCT );
220
221 Reference< XChartTypeContainer > xCTCnt( rCoordSys[ 0 ], uno::UNO_QUERY_THROW );
222 xCTCnt->setChartTypes( Sequence< Reference< chart2::XChartType > >( &xCT, 1 ));
223
224 if( nNumberOfColumns > 0 )
225 {
226 Reference< XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW );
227 Sequence< Reference< XDataSeries > > aColumnSeq( nNumberOfColumns );
228 ::std::copy( aFlatSeriesSeq.getConstArray(),
229 aFlatSeriesSeq.getConstArray() + nNumberOfColumns,
230 aColumnSeq.getArray());
231 xDSCnt->setDataSeries( aColumnSeq );
232 }
233
234 // Lines
235 // -----
236 xCT.set( xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_LINE ), uno::UNO_QUERY_THROW );
237 xCTCnt.set( rCoordSys[ 0 ], uno::UNO_QUERY_THROW );
238 xCTCnt->addChartType( xCT );
239
240 if( nNumberOfLines > 0 )
241 {
242 Reference< XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW );
243 Sequence< Reference< XDataSeries > > aLineSeq( nNumberOfLines );
244 ::std::copy( aFlatSeriesSeq.getConstArray() + nNumberOfColumns,
245 aFlatSeriesSeq.getConstArray() + aFlatSeriesSeq.getLength(),
246 aLineSeq.getArray());
247 xDSCnt->setDataSeries( aLineSeq );
248 }
249 }
250 catch( uno::Exception & ex )
251 {
252 ASSERT_EXCEPTION( ex );
253 }
254 }
255
applyStyle(const Reference<chart2::XDataSeries> & xSeries,::sal_Int32 nChartTypeIndex,::sal_Int32 nSeriesIndex,::sal_Int32 nSeriesCount)256 void SAL_CALL ColumnLineChartTypeTemplate::applyStyle(
257 const Reference< chart2::XDataSeries >& xSeries,
258 ::sal_Int32 nChartTypeIndex,
259 ::sal_Int32 nSeriesIndex,
260 ::sal_Int32 nSeriesCount )
261 throw (uno::RuntimeException)
262 {
263 ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount );
264
265 if( nChartTypeIndex==0 ) // columns
266 {
267 DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "BorderStyle" ), uno::makeAny( drawing::LineStyle_NONE ) );
268 }
269 else if( nChartTypeIndex==1 ) // lines
270 {
271 Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
272 if( xProp.is() )
273 {
274 DataSeriesHelper::switchLinesOnOrOff( xProp, true );
275 DataSeriesHelper::switchSymbolsOnOrOff( xProp, false, nSeriesIndex );
276 DataSeriesHelper::makeLinesThickOrThin( xProp, true );
277 }
278 }
279 }
280
getStackMode(sal_Int32 nChartTypeIndex) const281 StackMode ColumnLineChartTypeTemplate::getStackMode( sal_Int32 nChartTypeIndex ) const
282 {
283 if( nChartTypeIndex == 0 )
284 return m_eStackMode;
285 return StackMode_NONE;
286 }
287
288 // ____ XChartTypeTemplate ____
matchesTemplate(const uno::Reference<XDiagram> & xDiagram,sal_Bool bAdaptProperties)289 sal_Bool SAL_CALL ColumnLineChartTypeTemplate::matchesTemplate(
290 const uno::Reference< XDiagram >& xDiagram,
291 sal_Bool bAdaptProperties )
292 throw (uno::RuntimeException)
293 {
294 sal_Bool bResult = sal_False;
295
296 if( ! xDiagram.is())
297 return bResult;
298
299 try
300 {
301 Reference< chart2::XChartType > xColumnChartType;
302 Reference< XCoordinateSystem > xColumnChartCooSys;
303 Reference< chart2::XChartType > xLineChartType;
304 sal_Int32 nNumberOfChartTypes = 0;
305
306 Reference< XCoordinateSystemContainer > xCooSysCnt(
307 xDiagram, uno::UNO_QUERY_THROW );
308 Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
309 xCooSysCnt->getCoordinateSystems());
310 for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
311 {
312 Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
313 Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
314 for( sal_Int32 j=0; j<aChartTypeSeq.getLength(); ++j )
315 {
316 if( aChartTypeSeq[j].is())
317 {
318 ++nNumberOfChartTypes;
319 if( nNumberOfChartTypes > 2 )
320 break;
321 OUString aCTService = aChartTypeSeq[j]->getChartType();
322 if( aCTService.equals( CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ))
323 {
324 xColumnChartType.set( aChartTypeSeq[j] );
325 xColumnChartCooSys.set( aCooSysSeq[i] );
326 }
327 else if( aCTService.equals( CHART2_SERVICE_NAME_CHARTTYPE_LINE ))
328 xLineChartType.set( aChartTypeSeq[j] );
329 }
330 }
331 if( nNumberOfChartTypes > 2 )
332 break;
333 }
334
335 if( nNumberOfChartTypes == 2 &&
336 xColumnChartType.is() &&
337 xLineChartType.is())
338 {
339 OSL_ASSERT( xColumnChartCooSys.is());
340
341 // check stackmode of bars
342 bResult = (xColumnChartCooSys->getDimension() == getDimension());
343 if( bResult )
344 {
345 bool bFound=false;
346 bool bAmbiguous=false;
347 bResult = ( DiagramHelper::getStackModeFromChartType(
348 xColumnChartType, bFound, bAmbiguous,
349 xColumnChartCooSys )
350 == getStackMode( 0 ) );
351
352 if( bResult && bAdaptProperties )
353 {
354 Reference< XDataSeriesContainer > xSeriesContainer( xLineChartType, uno::UNO_QUERY );
355 if( xSeriesContainer.is() )
356 {
357 sal_Int32 nNumberOfLines = xSeriesContainer->getDataSeries().getLength();
358 setFastPropertyValue_NoBroadcast( PROP_COL_LINE_NUMBER_OF_LINES, uno::makeAny( nNumberOfLines ));
359 }
360 }
361 }
362 }
363 }
364 catch( uno::Exception & ex )
365 {
366 ASSERT_EXCEPTION( ex );
367 }
368
369 return bResult;
370 }
371
getChartTypeForIndex(sal_Int32 nChartTypeIndex)372 Reference< chart2::XChartType > ColumnLineChartTypeTemplate::getChartTypeForIndex( sal_Int32 nChartTypeIndex )
373 {
374 Reference< chart2::XChartType > xCT;
375 Reference< lang::XMultiServiceFactory > xFact(
376 GetComponentContext()->getServiceManager(), uno::UNO_QUERY );
377 if(xFact.is())
378 {
379 if( nChartTypeIndex == 0 )
380 xCT.set( xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ), uno::UNO_QUERY );
381 else
382 xCT.set( xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_LINE ), uno::UNO_QUERY );
383 }
384 return xCT;
385 }
386
getChartTypeForNewSeries(const uno::Sequence<Reference<chart2::XChartType>> & aFormerlyUsedChartTypes)387 Reference< XChartType > SAL_CALL ColumnLineChartTypeTemplate::getChartTypeForNewSeries(
388 const uno::Sequence< Reference< chart2::XChartType > >& aFormerlyUsedChartTypes )
389 throw (uno::RuntimeException)
390 {
391 Reference< chart2::XChartType > xResult;
392
393 try
394 {
395 Reference< lang::XMultiServiceFactory > xFact(
396 GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW );
397 xResult.set( xFact->createInstance(
398 CHART2_SERVICE_NAME_CHARTTYPE_LINE ), uno::UNO_QUERY_THROW );
399 ChartTypeTemplate::copyPropertiesFromOldToNewCoordianteSystem( aFormerlyUsedChartTypes, xResult );
400 }
401 catch( uno::Exception & ex )
402 {
403 ASSERT_EXCEPTION( ex );
404 }
405
406 return xResult;
407 }
408
getDataInterpreter()409 Reference< XDataInterpreter > SAL_CALL ColumnLineChartTypeTemplate::getDataInterpreter()
410 throw (uno::RuntimeException)
411 {
412 if( ! m_xDataInterpreter.is())
413 {
414 sal_Int32 nNumberOfLines = 1;
415 getFastPropertyValue( PROP_COL_LINE_NUMBER_OF_LINES ) >>= nNumberOfLines;
416 m_xDataInterpreter.set( new ColumnLineDataInterpreter( nNumberOfLines, GetComponentContext() ) );
417 }
418 else
419 {
420 //todo...
421 OSL_ENSURE( false, "number of lines may not be valid anymore in the datainterpreter" );
422
423 }
424
425 return m_xDataInterpreter;
426 }
427
428 // ----------------------------------------
429
getSupportedServiceNames_Static()430 uno::Sequence< ::rtl::OUString > ColumnLineChartTypeTemplate::getSupportedServiceNames_Static()
431 {
432 uno::Sequence< ::rtl::OUString > aServices( 2 );
433 aServices[ 0 ] = lcl_aServiceName;
434 aServices[ 1 ] = C2U( "com.sun.star.chart2.ChartTypeTemplate" );
435 return aServices;
436 }
437
438 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
439 APPHELPER_XSERVICEINFO_IMPL( ColumnLineChartTypeTemplate, lcl_aServiceName );
440
441 IMPLEMENT_FORWARD_XINTERFACE2( ColumnLineChartTypeTemplate, ChartTypeTemplate, OPropertySet )
442 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ColumnLineChartTypeTemplate, ChartTypeTemplate, OPropertySet )
443
444 } // namespace chart
445