xref: /trunk/main/chart2/source/model/main/Diagram.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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_chartmodel.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 ()__anon92c82b930111::StaticDiagramDefaults_Initializer185     ::chart::tPropertyValueMap* operator()()
186     {
187         static ::chart::tPropertyValueMap aStaticDefaults;
188         lcl_AddDefaultsToMap( aStaticDefaults );
189         return &aStaticDefaults;
190     }
191 private:
lcl_AddDefaultsToMap__anon92c82b930111::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 ()__anon92c82b930111::StaticDiagramInfoHelper_Initializer212     ::cppu::OPropertyArrayHelper* operator()()
213     {
214         static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() );
215         return &aPropHelper;
216     }
217 
218 private:
lcl_GetPropertySequence__anon92c82b930111::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 ()__anon92c82b930111::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 implementation.
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 {
346     uno::Reference< beans::XPropertySet > xRet;
347     bool bAddListener = false;
348     {
349         MutexGuard aGuard( GetMutex() );
350         if( !m_xWall.is() )
351         {
352             m_xWall.set( new Wall() );
353             bAddListener = true;
354         }
355         xRet =  m_xWall;
356     }
357     if(bAddListener)
358         ModifyListenerHelper::addListener( xRet, m_xModifyEventForwarder );
359     return xRet;
360 }
361 
getFloor()362 uno::Reference< beans::XPropertySet > SAL_CALL Diagram::getFloor()
363 {
364     uno::Reference< beans::XPropertySet > xRet;
365     bool bAddListener = false;
366     {
367         MutexGuard aGuard( GetMutex() );
368         if( !m_xFloor.is() )
369         {
370             m_xFloor.set( new Wall() );
371             bAddListener = true;
372         }
373         xRet = m_xFloor;
374     }
375     if(bAddListener)
376         ModifyListenerHelper::addListener( xRet, m_xModifyEventForwarder );
377     return xRet;
378 }
379 
getLegend()380 uno::Reference< chart2::XLegend > SAL_CALL Diagram::getLegend()
381 {
382     MutexGuard aGuard( GetMutex() );
383     return m_xLegend;
384 }
385 
setLegend(const uno::Reference<chart2::XLegend> & xNewLegend)386 void SAL_CALL Diagram::setLegend( const uno::Reference< chart2::XLegend >& xNewLegend )
387 {
388     Reference< chart2::XLegend > xOldLegend;
389     {
390         MutexGuard aGuard( GetMutex() );
391         if( m_xLegend == xNewLegend )
392             return;
393         xOldLegend = m_xLegend;
394         m_xLegend = xNewLegend;
395     }
396     if( xOldLegend.is())
397         ModifyListenerHelper::removeListener( xOldLegend, m_xModifyEventForwarder );
398     if( xNewLegend.is())
399         ModifyListenerHelper::addListener( xNewLegend, m_xModifyEventForwarder );
400     fireModifyEvent();
401 }
402 
getDefaultColorScheme()403 Reference< chart2::XColorScheme > SAL_CALL Diagram::getDefaultColorScheme()
404 {
405     Reference< chart2::XColorScheme > xRet;
406     {
407         MutexGuard aGuard( GetMutex() );
408         xRet = m_xColorScheme;
409     }
410 
411     if( !xRet.is())
412     {
413         xRet.set( createConfigColorScheme( m_xContext ));
414         MutexGuard aGuard( GetMutex() );
415         m_xColorScheme = xRet;
416     }
417     return xRet;
418 }
419 
setDefaultColorScheme(const Reference<chart2::XColorScheme> & xColorScheme)420 void SAL_CALL Diagram::setDefaultColorScheme( const Reference< chart2::XColorScheme >& xColorScheme )
421 {
422     {
423         MutexGuard aGuard( GetMutex() );
424         m_xColorScheme.set( xColorScheme );
425     }
426     fireModifyEvent();
427 }
428 
setDiagramData(const Reference<chart2::data::XDataSource> & xDataSource,const Sequence<beans::PropertyValue> & aArguments)429 void SAL_CALL Diagram::setDiagramData(
430     const Reference< chart2::data::XDataSource >& xDataSource,
431     const Sequence< beans::PropertyValue >& aArguments )
432 {
433     uno::Reference< lang::XMultiServiceFactory > xChartTypeManager( m_xContext->getServiceManager()->createInstanceWithContext(
434             C2U( "com.sun.star.chart2.ChartTypeManager" ), m_xContext ), uno::UNO_QUERY );
435     DiagramHelper::tTemplateWithServiceName aTemplateAndService = DiagramHelper::getTemplateForDiagram( this, xChartTypeManager );
436     uno::Reference< chart2::XChartTypeTemplate > xTemplate( aTemplateAndService.first );
437     if( !xTemplate.is() )
438         xTemplate.set( xChartTypeManager->createInstance( C2U("com.sun.star.chart2.template.Column") ), uno::UNO_QUERY );
439     if(!xTemplate.is())
440         return;
441     xTemplate->changeDiagramData( this, xDataSource, aArguments );
442 }
443 
444 // ____ XTitled ____
getTitleObject()445 uno::Reference< chart2::XTitle > SAL_CALL Diagram::getTitleObject()
446 {
447     MutexGuard aGuard( GetMutex() );
448     return m_xTitle;
449 }
450 
setTitleObject(const uno::Reference<chart2::XTitle> & xNewTitle)451 void SAL_CALL Diagram::setTitleObject( const uno::Reference< chart2::XTitle >& xNewTitle )
452 {
453     Reference< chart2::XTitle > xOldTitle;
454     {
455         MutexGuard aGuard( GetMutex() );
456         if( m_xTitle == xNewTitle )
457             return;
458         xOldTitle = m_xTitle;
459         m_xTitle = xNewTitle;
460     }
461     if( xOldTitle.is())
462         ModifyListenerHelper::removeListener( xOldTitle, m_xModifyEventForwarder );
463     if( xNewTitle.is())
464         ModifyListenerHelper::addListener( xNewTitle, m_xModifyEventForwarder );
465     fireModifyEvent();
466 }
467 
468 // ____ X3DDefaultSetter ____
set3DSettingsToDefault()469 void SAL_CALL Diagram::set3DSettingsToDefault()
470 {
471     ThreeDHelper::set3DSettingsToDefault( this );
472 }
473 
setDefaultRotation()474 void SAL_CALL Diagram::setDefaultRotation()
475 {
476     ThreeDHelper::setDefaultRotation( this );
477 }
478 
setDefaultIllumination()479 void SAL_CALL Diagram::setDefaultIllumination()
480 {
481     ThreeDHelper::setDefaultIllumination( this );
482 }
483 
484 // ____ XCoordinateSystemContainer ____
addCoordinateSystem(const uno::Reference<chart2::XCoordinateSystem> & aCoordSys)485 void SAL_CALL Diagram::addCoordinateSystem(
486     const uno::Reference< chart2::XCoordinateSystem >& aCoordSys )
487 {
488     {
489         MutexGuard aGuard( GetMutex() );
490         if( ::std::find( m_aCoordSystems.begin(), m_aCoordSystems.end(), aCoordSys )
491             != m_aCoordSystems.end())
492             throw lang::IllegalArgumentException();
493 
494         if( m_aCoordSystems.size()>=1 )
495         {
496             OSL_ENSURE( false, "more than one coordinatesystem is not supported yet by the fileformat" );
497             return;
498         }
499         m_aCoordSystems.push_back( aCoordSys );
500     }
501     ModifyListenerHelper::addListener( aCoordSys, m_xModifyEventForwarder );
502     fireModifyEvent();
503 }
504 
removeCoordinateSystem(const uno::Reference<chart2::XCoordinateSystem> & aCoordSys)505 void SAL_CALL Diagram::removeCoordinateSystem(
506     const uno::Reference< chart2::XCoordinateSystem >& aCoordSys )
507 {
508     {
509         MutexGuard aGuard( GetMutex() );
510         ::std::vector< uno::Reference< chart2::XCoordinateSystem > >::iterator
511               aIt( ::std::find( m_aCoordSystems.begin(), m_aCoordSystems.end(), aCoordSys ));
512         if( aIt == m_aCoordSystems.end())
513             throw container::NoSuchElementException(
514                 C2U( "The given coordinate-system is no element of the container" ),
515                 static_cast< uno::XWeak * >( this ));
516         m_aCoordSystems.erase( aIt );
517     }
518     ModifyListenerHelper::removeListener( aCoordSys, m_xModifyEventForwarder );
519     fireModifyEvent();
520 }
521 
getCoordinateSystems()522 uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > SAL_CALL Diagram::getCoordinateSystems()
523 {
524     MutexGuard aGuard( GetMutex() );
525     return ContainerHelper::ContainerToSequence( m_aCoordSystems );
526 }
527 
setCoordinateSystems(const Sequence<Reference<chart2::XCoordinateSystem>> & aCoordinateSystems)528 void SAL_CALL Diagram::setCoordinateSystems(
529     const Sequence< Reference< chart2::XCoordinateSystem > >& aCoordinateSystems )
530 {
531     tCoordinateSystemContainerType aNew;
532     tCoordinateSystemContainerType aOld;
533     if( aCoordinateSystems.getLength()>0 )
534     {
535         OSL_ENSURE( aCoordinateSystems.getLength()<=1, "more than one coordinatesystem is not supported yet by the fileformat" );
536         aNew.push_back( aCoordinateSystems[0] );
537     }
538     {
539         MutexGuard aGuard( GetMutex() );
540         std::swap( aOld, m_aCoordSystems );
541         m_aCoordSystems = aNew;
542     }
543     ModifyListenerHelper::removeListenerFromAllElements( aOld, m_xModifyEventForwarder );
544     ModifyListenerHelper::addListenerToAllElements( aNew, m_xModifyEventForwarder );
545     fireModifyEvent();
546 }
547 
548 // ____ XCloneable ____
createClone()549 Reference< util::XCloneable > SAL_CALL Diagram::createClone()
550 {
551     MutexGuard aGuard( GetMutex() );
552     return Reference< util::XCloneable >( new Diagram( *this ));
553 }
554 
555 // ____ XModifyBroadcaster ____
addModifyListener(const Reference<util::XModifyListener> & aListener)556 void SAL_CALL Diagram::addModifyListener( const Reference< util::XModifyListener >& aListener )
557 {
558     try
559     {
560         Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
561         xBroadcaster->addModifyListener( aListener );
562     }
563     catch( const uno::Exception & ex )
564     {
565         ASSERT_EXCEPTION( ex );
566     }
567 }
568 
removeModifyListener(const Reference<util::XModifyListener> & aListener)569 void SAL_CALL Diagram::removeModifyListener( const Reference< util::XModifyListener >& aListener )
570 {
571     try
572     {
573         Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
574         xBroadcaster->removeModifyListener( aListener );
575     }
576     catch( const uno::Exception & ex )
577     {
578         ASSERT_EXCEPTION( ex );
579     }
580 }
581 
582 // ____ XModifyListener ____
modified(const lang::EventObject & aEvent)583 void SAL_CALL Diagram::modified( const lang::EventObject& aEvent )
584 {
585     m_xModifyEventForwarder->modified( aEvent );
586 }
587 
588 // ____ XEventListener (base of XModifyListener) ____
disposing(const lang::EventObject &)589 void SAL_CALL Diagram::disposing( const lang::EventObject& /* Source */ )
590 {
591     // nothing
592 }
593 
594 // ____ OPropertySet ____
firePropertyChangeEvent()595 void Diagram::firePropertyChangeEvent()
596 {
597     fireModifyEvent();
598 }
599 
fireModifyEvent()600 void Diagram::fireModifyEvent()
601 {
602     m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
603 }
604 
605 // ============================================================
606 
getSupportedServiceNames_Static()607 Sequence< OUString > Diagram::getSupportedServiceNames_Static()
608 {
609     Sequence< OUString > aServices( 3 );
610 
611     aServices[ 0 ] = C2U( "com.sun.star.chart2.Diagram" );
612     aServices[ 1 ] = C2U( "com.sun.star.layout.LayoutElement" );
613     aServices[ 2 ] = C2U( "com.sun.star.beans.PropertySet" );
614     return aServices;
615 }
616 
617 // ____ OPropertySet ____
GetDefaultValue(sal_Int32 nHandle) const618 uno::Any Diagram::GetDefaultValue( sal_Int32 nHandle ) const
619 {
620     const tPropertyValueMap& rStaticDefaults = *StaticDiagramDefaults::get();
621     tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) );
622     if( aFound == rStaticDefaults.end() )
623         return uno::Any();
624     return (*aFound).second;
625 }
626 
627 // ____ OPropertySet ____
getInfoHelper()628 ::cppu::IPropertyArrayHelper & SAL_CALL Diagram::getInfoHelper()
629 {
630     return *StaticDiagramInfoHelper::get();
631 }
632 
633 // ____ XPropertySet ____
getPropertySetInfo()634 uno::Reference< beans::XPropertySetInfo > SAL_CALL Diagram::getPropertySetInfo()
635 {
636     return *StaticDiagramInfo::get();
637 }
638 
639 // ____ XFastPropertySet ____
setFastPropertyValue(sal_Int32 nHandle,const Any & rValue)640 void SAL_CALL Diagram::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue )
641 {
642     //special treatment for some 3D properties
643     if( PROP_DIAGRAM_PERSPECTIVE == nHandle )
644     {
645         sal_Int32 fPerspective = 20;
646         if( rValue >>=fPerspective )
647             ThreeDHelper::setCameraDistance( this, ThreeDHelper::PerspectiveToCameraDistance( fPerspective ) );
648     }
649     else if( PROP_DIAGRAM_ROTATION_HORIZONTAL == nHandle
650         || PROP_DIAGRAM_ROTATION_VERTICAL == nHandle )
651     {
652         sal_Int32 nNewAngleDegree = 0;
653         if( rValue >>=nNewAngleDegree )
654         {
655             sal_Int32 nHorizontal, nVertical;
656             ThreeDHelper::getRotationFromDiagram( const_cast< Diagram* >( this ), nHorizontal, nVertical );
657             if( PROP_DIAGRAM_ROTATION_HORIZONTAL == nHandle )
658                 nHorizontal = nNewAngleDegree;
659             else
660                 nVertical = nNewAngleDegree;
661             ThreeDHelper::setRotationToDiagram( this, nHorizontal, nVertical );
662         }
663     }
664     else
665         ::property::OPropertySet::setFastPropertyValue( nHandle, rValue );
666 }
667 
getFastPropertyValue(Any & rValue,sal_Int32 nHandle) const668 void SAL_CALL Diagram::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
669 {
670     //special treatment for some 3D properties
671     if( nHandle == PROP_DIAGRAM_PERSPECTIVE )
672     {
673         sal_Int32 nPerspective = ::basegfx::fround( ThreeDHelper::CameraDistanceToPerspective(
674             ThreeDHelper::getCameraDistance( const_cast< Diagram* >( this ) ) ) );
675         rValue = uno::makeAny(nPerspective);
676     }
677     else if( PROP_DIAGRAM_ROTATION_HORIZONTAL == nHandle
678         || PROP_DIAGRAM_ROTATION_VERTICAL == nHandle )
679     {
680         sal_Int32 nHorizontal, nVertical;
681         ThreeDHelper::getRotationFromDiagram( const_cast< Diagram* >( this ), nHorizontal, nVertical );
682         sal_Int32 nAngleDegree = 0;
683         if( PROP_DIAGRAM_ROTATION_HORIZONTAL == nHandle )
684             nAngleDegree = nHorizontal;
685         else
686             nAngleDegree = nVertical;
687         rValue = uno::makeAny(nAngleDegree);
688     }
689     else
690         ::property::OPropertySet::getFastPropertyValue( rValue,nHandle );
691 }
692 
693 // ================================================================================
694 
695 using impl::Diagram_Base;
696 
697 IMPLEMENT_FORWARD_XINTERFACE2( Diagram, Diagram_Base, ::property::OPropertySet )
698 IMPLEMENT_FORWARD_XTYPEPROVIDER2( Diagram, Diagram_Base, ::property::OPropertySet )
699 
700 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
701 APPHELPER_XSERVICEINFO_IMPL( Diagram,
702                              C2U( "com.sun.star.comp.chart2.Diagram" ));
703 
704 } //  namespace chart
705