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 "Diagram.hxx"
27 #include "macros.hxx"
28 #include "PropertyHelper.hxx"
29 #include "Wall.hxx"
30 #include "UserDefinedProperties.hxx"
31 #include "ConfigColorScheme.hxx"
32 #include "DiagramHelper.hxx"
33 #include "ContainerHelper.hxx"
34 #include "ThreeDHelper.hxx"
35 #include "CloneHelper.hxx"
36 #include "AxisHelper.hxx"
37 #include "SceneProperties.hxx"
38 #include "DisposeHelper.hxx"
39 #include "BaseGFXHelper.hxx"
40 #include <basegfx/numeric/ftools.hxx>
41 #include <rtl/instance.hxx>
42 #include <com/sun/star/beans/PropertyAttribute.hpp>
43 #include <com/sun/star/chart2/RelativePosition.hpp>
44 #include <com/sun/star/chart2/RelativeSize.hpp>
45 #include <com/sun/star/drawing/CameraGeometry.hpp>
46 
47 #include <com/sun/star/drawing/HomogenMatrix.hpp>
48 
49 #include <algorithm>
50 #include <iterator>
51 #include <functional>
52 
53 using namespace ::com::sun::star;
54 using namespace ::com::sun::star::beans::PropertyAttribute;
55 
56 using ::rtl::OUString;
57 using ::com::sun::star::beans::Property;
58 using ::com::sun::star::uno::Sequence;
59 using ::com::sun::star::uno::Reference;
60 using ::com::sun::star::uno::Any;
61 using ::osl::MutexGuard;
62 
63 // ======================================================================
64 
65 namespace
66 {
67 
68 enum
69 {
70     PROP_DIAGRAM_REL_POS,
71     PROP_DIAGRAM_REL_SIZE,
72     PROP_DIAGRAM_POSSIZE_EXCLUDE_LABELS,
73     PROP_DIAGRAM_SORT_BY_X_VALUES,
74     PROP_DIAGRAM_CONNECT_BARS,
75     PROP_DIAGRAM_GROUP_BARS_PER_AXIS,
76     PROP_DIAGRAM_INCLUDE_HIDDEN_CELLS,
77     PROP_DIAGRAM_STARTING_ANGLE,
78     PROP_DIAGRAM_RIGHT_ANGLED_AXES,
79     PROP_DIAGRAM_PERSPECTIVE,
80     PROP_DIAGRAM_ROTATION_HORIZONTAL,
81     PROP_DIAGRAM_ROTATION_VERTICAL,
82     PROP_DIAGRAM_MISSING_VALUE_TREATMENT,
83     PROP_DIAGRAM_3DRELATIVEHEIGHT
84 };
85 
lcl_AddPropertiesToVector(::std::vector<Property> & rOutProperties)86 void lcl_AddPropertiesToVector(
87     ::std::vector< Property > & rOutProperties )
88 {
89     rOutProperties.push_back(
90         Property( C2U( "RelativePosition" ),
91                   PROP_DIAGRAM_REL_POS,
92                   ::getCppuType( reinterpret_cast< const chart2::RelativePosition * >(0)),
93                   beans::PropertyAttribute::BOUND
94                   | beans::PropertyAttribute::MAYBEVOID ));
95 
96     rOutProperties.push_back(
97         Property( C2U( "RelativeSize" ),
98                   PROP_DIAGRAM_REL_SIZE,
99                   ::getCppuType( reinterpret_cast< const chart2::RelativeSize * >(0)),
100                   beans::PropertyAttribute::BOUND
101                   | beans::PropertyAttribute::MAYBEVOID ));
102 
103     rOutProperties.push_back(
104         Property( C2U( "PosSizeExcludeAxes" ),
105                   PROP_DIAGRAM_POSSIZE_EXCLUDE_LABELS,
106                   ::getBooleanCppuType(),
107                   beans::PropertyAttribute::BOUND
108                   | beans::PropertyAttribute::MAYBEDEFAULT ));
109 
110     rOutProperties.push_back(
111         Property( C2U( "SortByXValues" ),
112                   PROP_DIAGRAM_SORT_BY_X_VALUES,
113                   ::getBooleanCppuType(),
114                   beans::PropertyAttribute::BOUND
115                   | beans::PropertyAttribute::MAYBEDEFAULT ));
116 
117     rOutProperties.push_back(
118         Property( C2U("ConnectBars"),
119                   PROP_DIAGRAM_CONNECT_BARS,
120                   ::getBooleanCppuType(),
121                   beans::PropertyAttribute::BOUND
122                   | beans::PropertyAttribute::MAYBEDEFAULT ));
123 
124     rOutProperties.push_back(
125         Property( C2U("GroupBarsPerAxis"),
126                   PROP_DIAGRAM_GROUP_BARS_PER_AXIS,
127                   ::getBooleanCppuType(),
128                   beans::PropertyAttribute::BOUND
129                   | beans::PropertyAttribute::MAYBEDEFAULT ));
130 
131     rOutProperties.push_back(
132         Property( C2U("IncludeHiddenCells"),
133                   PROP_DIAGRAM_INCLUDE_HIDDEN_CELLS,
134                   ::getBooleanCppuType(),
135                   beans::PropertyAttribute::BOUND
136                   | beans::PropertyAttribute::MAYBEDEFAULT ));
137 
138     rOutProperties.push_back(
139         Property( C2U( "StartingAngle" ),
140                   PROP_DIAGRAM_STARTING_ANGLE,
141                   ::getCppuType( reinterpret_cast< const sal_Int32 * >(0) ),
142                   beans::PropertyAttribute::BOUND
143                   | beans::PropertyAttribute::MAYBEDEFAULT ));
144 
145     rOutProperties.push_back(
146         Property( C2U("RightAngledAxes"),
147                   PROP_DIAGRAM_RIGHT_ANGLED_AXES,
148                   ::getBooleanCppuType(),
149                   beans::PropertyAttribute::BOUND
150                   | beans::PropertyAttribute::MAYBEDEFAULT ));
151 
152     rOutProperties.push_back(
153         Property( C2U("Perspective"),
154                   PROP_DIAGRAM_PERSPECTIVE,
155                   ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
156                   beans::PropertyAttribute::MAYBEVOID ));
157 
158     rOutProperties.push_back(
159         Property( C2U("RotationHorizontal"),
160                   PROP_DIAGRAM_ROTATION_HORIZONTAL,
161                   ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
162                   beans::PropertyAttribute::MAYBEVOID ));
163 
164     rOutProperties.push_back(
165         Property( C2U("RotationVertical"),
166                   PROP_DIAGRAM_ROTATION_VERTICAL,
167                   ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
168                   beans::PropertyAttribute::MAYBEVOID ));
169 
170     rOutProperties.push_back(
171         Property( C2U( "MissingValueTreatment" ),
172                   PROP_DIAGRAM_MISSING_VALUE_TREATMENT,
173                   ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
174                   beans::PropertyAttribute::BOUND
175                   | beans::PropertyAttribute::MAYBEVOID ));
176    rOutProperties.push_back(
177    Property( C2U("3DRelativeHeight"),
178                   PROP_DIAGRAM_3DRELATIVEHEIGHT,
179                   ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
180                   beans::PropertyAttribute::MAYBEVOID ));
181 }
182 
183 struct StaticDiagramDefaults_Initializer
184 {
operator ()__anon1178285c0111::StaticDiagramDefaults_Initializer185     ::chart::tPropertyValueMap* operator()()
186     {
187         static ::chart::tPropertyValueMap aStaticDefaults;
188         lcl_AddDefaultsToMap( aStaticDefaults );
189         return &aStaticDefaults;
190     }
191 private:
lcl_AddDefaultsToMap__anon1178285c0111::StaticDiagramDefaults_Initializer192     void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap )
193     {
194         ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_POSSIZE_EXCLUDE_LABELS, true );
195         ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_SORT_BY_X_VALUES, false );
196         ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_CONNECT_BARS, false );
197         ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_GROUP_BARS_PER_AXIS, true );
198         ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_INCLUDE_HIDDEN_CELLS, true );
199         ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_RIGHT_ANGLED_AXES, false );
200         ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_DIAGRAM_STARTING_ANGLE, 90 );
201         ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_DIAGRAM_3DRELATIVEHEIGHT, 100 );
202 		 ::chart::SceneProperties::AddDefaultsToMap( rOutMap );
203     }
204 };
205 
206 struct StaticDiagramDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticDiagramDefaults_Initializer >
207 {
208 };
209 
210 struct StaticDiagramInfoHelper_Initializer
211 {
operator ()__anon1178285c0111::StaticDiagramInfoHelper_Initializer212     ::cppu::OPropertyArrayHelper* operator()()
213     {
214         static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() );
215         return &aPropHelper;
216     }
217 
218 private:
lcl_GetPropertySequence__anon1178285c0111::StaticDiagramInfoHelper_Initializer219     Sequence< Property > lcl_GetPropertySequence()
220     {
221         ::std::vector< ::com::sun::star::beans::Property > aProperties;
222         lcl_AddPropertiesToVector( aProperties );
223         ::chart::SceneProperties::AddPropertiesToVector( aProperties );
224         ::chart::UserDefinedProperties::AddPropertiesToVector( aProperties );
225 
226         ::std::sort( aProperties.begin(), aProperties.end(),
227                      ::chart::PropertyNameLess() );
228 
229         return ::chart::ContainerHelper::ContainerToSequence( aProperties );
230     }
231 };
232 
233 struct StaticDiagramInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticDiagramInfoHelper_Initializer >
234 {
235 };
236 
237 struct StaticDiagramInfo_Initializer
238 {
operator ()__anon1178285c0111::StaticDiagramInfo_Initializer239     uno::Reference< beans::XPropertySetInfo >* operator()()
240     {
241         static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo(
242             ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticDiagramInfoHelper::get() ) );
243         return &xPropertySetInfo;
244     }
245 };
246 
247 struct StaticDiagramInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticDiagramInfo_Initializer >
248 {
249 };
250 
251 /// clones a UNO-sequence of UNO-References
252 typedef Reference< chart2::XCoordinateSystem > lcl_tCooSysRef;
253 typedef ::std::map< lcl_tCooSysRef, lcl_tCooSysRef >  lcl_tCooSysMapping;
254 typedef ::std::vector< lcl_tCooSysRef >               lcl_tCooSysVector;
255 
lcl_CloneCoordinateSystems(const lcl_tCooSysVector & rSource,lcl_tCooSysVector & rDestination)256 lcl_tCooSysMapping lcl_CloneCoordinateSystems(
257         const lcl_tCooSysVector & rSource,
258         lcl_tCooSysVector & rDestination )
259 {
260     lcl_tCooSysMapping aResult;
261 
262     for( lcl_tCooSysVector::const_iterator aIt( rSource.begin());
263          aIt != rSource.end(); ++aIt )
264     {
265         lcl_tCooSysRef xClone;
266         ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable >
267               xCloneable( *aIt, ::com::sun::star::uno::UNO_QUERY );
268         if( xCloneable.is())
269             xClone.set( xCloneable->createClone(), ::com::sun::star::uno::UNO_QUERY );
270 
271         if( xClone.is())
272         {
273             rDestination.push_back( xClone );
274             aResult.insert( lcl_tCooSysMapping::value_type( *aIt, xClone ));
275         }
276         else
277             rDestination.push_back( *aIt );
278     }
279 
280     return aResult;
281 }
282 
283 } // anonymous namespace
284 
285 // ======================================================================
286 
287 namespace chart
288 {
289 
Diagram(uno::Reference<uno::XComponentContext> const & xContext)290 Diagram::Diagram( uno::Reference< uno::XComponentContext > const & xContext ) :
291         ::property::OPropertySet( m_aMutex ),
292         m_xContext( xContext ),
293         m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
294 {
295     // Set camera position to a default position (that should be set hard, so
296     // that it will be exported.  The property default is a camera looking
297     // straight ono the scene).  These defaults have been acquired from the old
298     // chart implemetation.
299     setFastPropertyValue_NoBroadcast(
300         SceneProperties::PROP_SCENE_CAMERA_GEOMETRY, uno::makeAny(
301             ThreeDHelper::getDefaultCameraGeometry()));
302 }
303 
Diagram(const Diagram & rOther)304 Diagram::Diagram( const Diagram & rOther ) :
305         MutexContainer(),
306         impl::Diagram_Base(),
307         ::property::OPropertySet( rOther, m_aMutex ),
308     m_xContext( rOther.m_xContext ),
309     m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
310 {
311     lcl_tCooSysMapping aCooSysMapping =
312         lcl_CloneCoordinateSystems( rOther.m_aCoordSystems, m_aCoordSystems );
313     ModifyListenerHelper::addListenerToAllElements( m_aCoordSystems, m_xModifyEventForwarder );
314 
315     m_xWall.set( CloneHelper::CreateRefClone< Reference< beans::XPropertySet > >()( rOther.m_xWall ));
316     m_xFloor.set( CloneHelper::CreateRefClone< Reference< beans::XPropertySet > >()( rOther.m_xFloor ));
317     m_xTitle.set( CloneHelper::CreateRefClone< Reference< chart2::XTitle > >()( rOther.m_xTitle ));
318     m_xLegend.set( CloneHelper::CreateRefClone< Reference< chart2::XLegend > >()( rOther.m_xLegend ));
319 
320     ModifyListenerHelper::addListener( m_xWall, m_xModifyEventForwarder );
321     ModifyListenerHelper::addListener( m_xFloor, m_xModifyEventForwarder );
322     ModifyListenerHelper::addListener( m_xTitle, m_xModifyEventForwarder );
323     ModifyListenerHelper::addListener( m_xLegend, m_xModifyEventForwarder );
324 }
325 
~Diagram()326 Diagram::~Diagram()
327 {
328     try
329     {
330         ModifyListenerHelper::removeListenerFromAllElements( m_aCoordSystems, m_xModifyEventForwarder );
331 
332         ModifyListenerHelper::removeListener( m_xWall, m_xModifyEventForwarder );
333         ModifyListenerHelper::removeListener( m_xFloor, m_xModifyEventForwarder );
334         ModifyListenerHelper::removeListener( m_xTitle, m_xModifyEventForwarder );
335         ModifyListenerHelper::removeListener( m_xLegend, m_xModifyEventForwarder );
336     }
337     catch( const uno::Exception & ex )
338     {
339         ASSERT_EXCEPTION( ex );
340     }
341 }
342 
343 // ____ XDiagram ____
getWall()344 uno::Reference< beans::XPropertySet > SAL_CALL Diagram::getWall()
345     throw (uno::RuntimeException)
346 {
347     uno::Reference< beans::XPropertySet > xRet;
348     bool bAddListener = false;
349     {
350         MutexGuard aGuard( GetMutex() );
351         if( !m_xWall.is() )
352         {
353             m_xWall.set( new Wall() );
354             bAddListener = true;
355         }
356         xRet =  m_xWall;
357     }
358     if(bAddListener)
359         ModifyListenerHelper::addListener( xRet, m_xModifyEventForwarder );
360     return xRet;
361 }
362 
getFloor()363 uno::Reference< beans::XPropertySet > SAL_CALL Diagram::getFloor()
364     throw (uno::RuntimeException)
365 {
366     uno::Reference< beans::XPropertySet > xRet;
367     bool bAddListener = false;
368     {
369         MutexGuard aGuard( GetMutex() );
370         if( !m_xFloor.is() )
371         {
372             m_xFloor.set( new Wall() );
373             bAddListener = true;
374         }
375         xRet = m_xFloor;
376     }
377     if(bAddListener)
378         ModifyListenerHelper::addListener( xRet, m_xModifyEventForwarder );
379     return xRet;
380 }
381 
getLegend()382 uno::Reference< chart2::XLegend > SAL_CALL Diagram::getLegend()
383     throw (uno::RuntimeException)
384 {
385     MutexGuard aGuard( GetMutex() );
386     return m_xLegend;
387 }
388 
setLegend(const uno::Reference<chart2::XLegend> & xNewLegend)389 void SAL_CALL Diagram::setLegend( const uno::Reference< chart2::XLegend >& xNewLegend )
390     throw (uno::RuntimeException)
391 {
392     Reference< chart2::XLegend > xOldLegend;
393     {
394         MutexGuard aGuard( GetMutex() );
395         if( m_xLegend == xNewLegend )
396             return;
397         xOldLegend = m_xLegend;
398         m_xLegend = xNewLegend;
399     }
400     if( xOldLegend.is())
401         ModifyListenerHelper::removeListener( xOldLegend, m_xModifyEventForwarder );
402     if( xNewLegend.is())
403         ModifyListenerHelper::addListener( xNewLegend, m_xModifyEventForwarder );
404     fireModifyEvent();
405 }
406 
getDefaultColorScheme()407 Reference< chart2::XColorScheme > SAL_CALL Diagram::getDefaultColorScheme()
408     throw (uno::RuntimeException)
409 {
410     Reference< chart2::XColorScheme > xRet;
411     {
412         MutexGuard aGuard( GetMutex() );
413         xRet = m_xColorScheme;
414     }
415 
416     if( !xRet.is())
417     {
418         xRet.set( createConfigColorScheme( m_xContext ));
419         MutexGuard aGuard( GetMutex() );
420         m_xColorScheme = xRet;
421     }
422     return xRet;
423 }
424 
setDefaultColorScheme(const Reference<chart2::XColorScheme> & xColorScheme)425 void SAL_CALL Diagram::setDefaultColorScheme( const Reference< chart2::XColorScheme >& xColorScheme )
426     throw (uno::RuntimeException)
427 {
428     {
429         MutexGuard aGuard( GetMutex() );
430         m_xColorScheme.set( xColorScheme );
431     }
432     fireModifyEvent();
433 }
434 
setDiagramData(const Reference<chart2::data::XDataSource> & xDataSource,const Sequence<beans::PropertyValue> & aArguments)435 void SAL_CALL Diagram::setDiagramData(
436     const Reference< chart2::data::XDataSource >& xDataSource,
437     const Sequence< beans::PropertyValue >& aArguments )
438         throw (uno::RuntimeException)
439 {
440     uno::Reference< lang::XMultiServiceFactory > xChartTypeManager( m_xContext->getServiceManager()->createInstanceWithContext(
441             C2U( "com.sun.star.chart2.ChartTypeManager" ), m_xContext ), uno::UNO_QUERY );
442     DiagramHelper::tTemplateWithServiceName aTemplateAndService = DiagramHelper::getTemplateForDiagram( this, xChartTypeManager );
443     uno::Reference< chart2::XChartTypeTemplate > xTemplate( aTemplateAndService.first );
444     if( !xTemplate.is() )
445         xTemplate.set( xChartTypeManager->createInstance( C2U("com.sun.star.chart2.template.Column") ), uno::UNO_QUERY );
446     if(!xTemplate.is())
447         return;
448     xTemplate->changeDiagramData( this, xDataSource, aArguments );
449 }
450 
451 // ____ XTitled ____
getTitleObject()452 uno::Reference< chart2::XTitle > SAL_CALL Diagram::getTitleObject()
453     throw (uno::RuntimeException)
454 {
455     MutexGuard aGuard( GetMutex() );
456     return m_xTitle;
457 }
458 
setTitleObject(const uno::Reference<chart2::XTitle> & xNewTitle)459 void SAL_CALL Diagram::setTitleObject( const uno::Reference< chart2::XTitle >& xNewTitle )
460     throw (uno::RuntimeException)
461 {
462     Reference< chart2::XTitle > xOldTitle;
463     {
464         MutexGuard aGuard( GetMutex() );
465         if( m_xTitle == xNewTitle )
466             return;
467         xOldTitle = m_xTitle;
468         m_xTitle = xNewTitle;
469     }
470     if( xOldTitle.is())
471         ModifyListenerHelper::removeListener( xOldTitle, m_xModifyEventForwarder );
472     if( xNewTitle.is())
473         ModifyListenerHelper::addListener( xNewTitle, m_xModifyEventForwarder );
474     fireModifyEvent();
475 }
476 
477 // ____ X3DDefaultSetter ____
set3DSettingsToDefault()478 void SAL_CALL Diagram::set3DSettingsToDefault()
479     throw (uno::RuntimeException)
480 {
481     ThreeDHelper::set3DSettingsToDefault( this );
482 }
483 
setDefaultRotation()484 void SAL_CALL Diagram::setDefaultRotation()
485     throw (uno::RuntimeException)
486 {
487     ThreeDHelper::setDefaultRotation( this );
488 }
489 
setDefaultIllumination()490 void SAL_CALL Diagram::setDefaultIllumination()
491     throw (uno::RuntimeException)
492 {
493     ThreeDHelper::setDefaultIllumination( this );
494 }
495 
496 // ____ XCoordinateSystemContainer ____
addCoordinateSystem(const uno::Reference<chart2::XCoordinateSystem> & aCoordSys)497 void SAL_CALL Diagram::addCoordinateSystem(
498     const uno::Reference< chart2::XCoordinateSystem >& aCoordSys )
499     throw (lang::IllegalArgumentException,
500            uno::RuntimeException)
501 {
502     {
503         MutexGuard aGuard( GetMutex() );
504         if( ::std::find( m_aCoordSystems.begin(), m_aCoordSystems.end(), aCoordSys )
505             != m_aCoordSystems.end())
506             throw lang::IllegalArgumentException();
507 
508         if( m_aCoordSystems.size()>=1 )
509         {
510             OSL_ENSURE( false, "more than one coordinatesystem is not supported yet by the fileformat" );
511             return;
512         }
513         m_aCoordSystems.push_back( aCoordSys );
514     }
515     ModifyListenerHelper::addListener( aCoordSys, m_xModifyEventForwarder );
516     fireModifyEvent();
517 }
518 
removeCoordinateSystem(const uno::Reference<chart2::XCoordinateSystem> & aCoordSys)519 void SAL_CALL Diagram::removeCoordinateSystem(
520     const uno::Reference< chart2::XCoordinateSystem >& aCoordSys )
521     throw (container::NoSuchElementException,
522            uno::RuntimeException)
523 {
524     {
525         MutexGuard aGuard( GetMutex() );
526         ::std::vector< uno::Reference< chart2::XCoordinateSystem > >::iterator
527               aIt( ::std::find( m_aCoordSystems.begin(), m_aCoordSystems.end(), aCoordSys ));
528         if( aIt == m_aCoordSystems.end())
529             throw container::NoSuchElementException(
530                 C2U( "The given coordinate-system is no element of the container" ),
531                 static_cast< uno::XWeak * >( this ));
532         m_aCoordSystems.erase( aIt );
533     }
534     ModifyListenerHelper::removeListener( aCoordSys, m_xModifyEventForwarder );
535     fireModifyEvent();
536 }
537 
getCoordinateSystems()538 uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > SAL_CALL Diagram::getCoordinateSystems()
539     throw (uno::RuntimeException)
540 {
541     MutexGuard aGuard( GetMutex() );
542     return ContainerHelper::ContainerToSequence( m_aCoordSystems );
543 }
544 
setCoordinateSystems(const Sequence<Reference<chart2::XCoordinateSystem>> & aCoordinateSystems)545 void SAL_CALL Diagram::setCoordinateSystems(
546     const Sequence< Reference< chart2::XCoordinateSystem > >& aCoordinateSystems )
547     throw (lang::IllegalArgumentException,
548            uno::RuntimeException)
549 {
550     tCoordinateSystemContainerType aNew;
551     tCoordinateSystemContainerType aOld;
552     if( aCoordinateSystems.getLength()>0 )
553     {
554         OSL_ENSURE( aCoordinateSystems.getLength()<=1, "more than one coordinatesystem is not supported yet by the fileformat" );
555         aNew.push_back( aCoordinateSystems[0] );
556     }
557     {
558         MutexGuard aGuard( GetMutex() );
559         std::swap( aOld, m_aCoordSystems );
560         m_aCoordSystems = aNew;
561     }
562     ModifyListenerHelper::removeListenerFromAllElements( aOld, m_xModifyEventForwarder );
563     ModifyListenerHelper::addListenerToAllElements( aNew, m_xModifyEventForwarder );
564     fireModifyEvent();
565 }
566 
567 // ____ XCloneable ____
createClone()568 Reference< util::XCloneable > SAL_CALL Diagram::createClone()
569     throw (uno::RuntimeException)
570 {
571     MutexGuard aGuard( GetMutex() );
572     return Reference< util::XCloneable >( new Diagram( *this ));
573 }
574 
575 // ____ XModifyBroadcaster ____
addModifyListener(const Reference<util::XModifyListener> & aListener)576 void SAL_CALL Diagram::addModifyListener( const Reference< util::XModifyListener >& aListener )
577     throw (uno::RuntimeException)
578 {
579     try
580     {
581         Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
582         xBroadcaster->addModifyListener( aListener );
583     }
584     catch( const uno::Exception & ex )
585     {
586         ASSERT_EXCEPTION( ex );
587     }
588 }
589 
removeModifyListener(const Reference<util::XModifyListener> & aListener)590 void SAL_CALL Diagram::removeModifyListener( const Reference< util::XModifyListener >& aListener )
591     throw (uno::RuntimeException)
592 {
593     try
594     {
595         Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
596         xBroadcaster->removeModifyListener( aListener );
597     }
598     catch( const uno::Exception & ex )
599     {
600         ASSERT_EXCEPTION( ex );
601     }
602 }
603 
604 // ____ XModifyListener ____
modified(const lang::EventObject & aEvent)605 void SAL_CALL Diagram::modified( const lang::EventObject& aEvent )
606     throw (uno::RuntimeException)
607 {
608     m_xModifyEventForwarder->modified( aEvent );
609 }
610 
611 // ____ XEventListener (base of XModifyListener) ____
disposing(const lang::EventObject &)612 void SAL_CALL Diagram::disposing( const lang::EventObject& /* Source */ )
613     throw (uno::RuntimeException)
614 {
615     // nothing
616 }
617 
618 // ____ OPropertySet ____
firePropertyChangeEvent()619 void Diagram::firePropertyChangeEvent()
620 {
621     fireModifyEvent();
622 }
623 
fireModifyEvent()624 void Diagram::fireModifyEvent()
625 {
626     m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
627 }
628 
629 // ============================================================
630 
getSupportedServiceNames_Static()631 Sequence< OUString > Diagram::getSupportedServiceNames_Static()
632 {
633     Sequence< OUString > aServices( 3 );
634 
635     aServices[ 0 ] = C2U( "com.sun.star.chart2.Diagram" );
636     aServices[ 1 ] = C2U( "com.sun.star.layout.LayoutElement" );
637     aServices[ 2 ] = C2U( "com.sun.star.beans.PropertySet" );
638     return aServices;
639 }
640 
641 // ____ OPropertySet ____
GetDefaultValue(sal_Int32 nHandle) const642 uno::Any Diagram::GetDefaultValue( sal_Int32 nHandle ) const
643     throw(beans::UnknownPropertyException)
644 {
645     const tPropertyValueMap& rStaticDefaults = *StaticDiagramDefaults::get();
646     tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) );
647     if( aFound == rStaticDefaults.end() )
648         return uno::Any();
649     return (*aFound).second;
650 }
651 
652 // ____ OPropertySet ____
getInfoHelper()653 ::cppu::IPropertyArrayHelper & SAL_CALL Diagram::getInfoHelper()
654 {
655     return *StaticDiagramInfoHelper::get();
656 }
657 
658 // ____ XPropertySet ____
getPropertySetInfo()659 uno::Reference< beans::XPropertySetInfo > SAL_CALL Diagram::getPropertySetInfo()
660     throw (uno::RuntimeException)
661 {
662     return *StaticDiagramInfo::get();
663 }
664 
665 // ____ XFastPropertySet ____
setFastPropertyValue(sal_Int32 nHandle,const Any & rValue)666 void SAL_CALL Diagram::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue )
667     throw(beans::UnknownPropertyException,
668           beans::PropertyVetoException,
669           lang::IllegalArgumentException,
670           lang::WrappedTargetException, uno::RuntimeException)
671 {
672     //special treatment for some 3D properties
673     if( PROP_DIAGRAM_PERSPECTIVE == nHandle )
674     {
675         sal_Int32 fPerspective = 20;
676         if( rValue >>=fPerspective )
677             ThreeDHelper::setCameraDistance( this, ThreeDHelper::PerspectiveToCameraDistance( fPerspective ) );
678     }
679     else if( PROP_DIAGRAM_ROTATION_HORIZONTAL == nHandle
680         || PROP_DIAGRAM_ROTATION_VERTICAL == nHandle )
681     {
682         sal_Int32 nNewAngleDegree = 0;
683         if( rValue >>=nNewAngleDegree )
684         {
685             sal_Int32 nHorizontal, nVertical;
686             ThreeDHelper::getRotationFromDiagram( const_cast< Diagram* >( this ), nHorizontal, nVertical );
687             if( PROP_DIAGRAM_ROTATION_HORIZONTAL == nHandle )
688                 nHorizontal = nNewAngleDegree;
689             else
690                 nVertical = nNewAngleDegree;
691             ThreeDHelper::setRotationToDiagram( this, nHorizontal, nVertical );
692         }
693     }
694     else
695         ::property::OPropertySet::setFastPropertyValue( nHandle, rValue );
696 }
697 
getFastPropertyValue(Any & rValue,sal_Int32 nHandle) const698 void SAL_CALL Diagram::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
699 {
700     //special treatment for some 3D properties
701     if( nHandle == PROP_DIAGRAM_PERSPECTIVE )
702     {
703         sal_Int32 nPerspective = ::basegfx::fround( ThreeDHelper::CameraDistanceToPerspective(
704             ThreeDHelper::getCameraDistance( const_cast< Diagram* >( this ) ) ) );
705         rValue = uno::makeAny(nPerspective);
706     }
707     else if( PROP_DIAGRAM_ROTATION_HORIZONTAL == nHandle
708         || PROP_DIAGRAM_ROTATION_VERTICAL == nHandle )
709     {
710         sal_Int32 nHorizontal, nVertical;
711         ThreeDHelper::getRotationFromDiagram( const_cast< Diagram* >( this ), nHorizontal, nVertical );
712         sal_Int32 nAngleDegree = 0;
713         if( PROP_DIAGRAM_ROTATION_HORIZONTAL == nHandle )
714             nAngleDegree = nHorizontal;
715         else
716             nAngleDegree = nVertical;
717         rValue = uno::makeAny(nAngleDegree);
718     }
719     else
720         ::property::OPropertySet::getFastPropertyValue( rValue,nHandle );
721 }
722 
723 // ================================================================================
724 
725 using impl::Diagram_Base;
726 
727 IMPLEMENT_FORWARD_XINTERFACE2( Diagram, Diagram_Base, ::property::OPropertySet )
728 IMPLEMENT_FORWARD_XTYPEPROVIDER2( Diagram, Diagram_Base, ::property::OPropertySet )
729 
730 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
731 APPHELPER_XSERVICEINFO_IMPL( Diagram,
732                              C2U( "com.sun.star.comp.chart2.Diagram" ));
733 
734 } //  namespace chart
735