1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ChartModel_Persistence.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
34 #include "ChartModel.hxx"
35 #include "ImplChartModel.hxx"
36 #include "MediaDescriptorHelper.hxx"
37 #include "ChartDebugTrace.hxx"
39 #include "ChartViewHelper.hxx"
40 #include "ChartModelHelper.hxx"
41 #include <com/sun/star/container/XNameAccess.hpp>
42 #include <com/sun/star/document/XExporter.hpp>
43 #include <com/sun/star/document/XImporter.hpp>
44 #include <com/sun/star/document/XFilter.hpp>
45 #include <com/sun/star/embed/ElementModes.hpp>
46 #include <com/sun/star/embed/XStorage.hpp>
47 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
48 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
49 #include <com/sun/star/uno/XComponentContext.hpp>
50 #include <com/sun/star/io/XSeekable.hpp>
51 #include <ucbhelper/content.hxx>
52 #ifndef _UNOTOOLS_UCBSTREAMHELPER_HXX
53 #include <unotools/ucbstreamhelper.hxx>
55 #include <vcl/cvtgrf.hxx>
56 #include <comphelper/storagehelper.hxx>
61 using namespace ::com::sun::star
;
63 using ::com::sun::star::uno::Reference
;
64 using ::com::sun::star::uno::Sequence
;
65 using ::rtl::OUString
;
66 using ::osl::MutexGuard
;
70 struct lcl_PropNameEquals
: public ::std::unary_function
< beans::PropertyValue
, bool >
72 lcl_PropNameEquals( const OUString
& rStrToCompareWith
) :
73 m_aStr( rStrToCompareWith
)
75 bool operator() ( const beans::PropertyValue
& rProp
)
77 return rProp
.Name
.equals( m_aStr
);
83 template< typename T
>
85 const Sequence
< beans::PropertyValue
> & rMediaDescriptor
,
86 const OUString
& rPropName
)
89 if( rMediaDescriptor
.getLength())
91 OUString
aPropName( rPropName
);
92 const beans::PropertyValue
* pIt
= rMediaDescriptor
.getConstArray();
93 const beans::PropertyValue
* pEndIt
= pIt
+ + rMediaDescriptor
.getLength();
94 pIt
= ::std::find_if( pIt
, pEndIt
, lcl_PropNameEquals( aPropName
));
96 (*pIt
).Value
>>= aResult
;
101 void lcl_addStorageToMediaDescriptor(
102 Sequence
< beans::PropertyValue
> & rOutMD
,
103 const Reference
< embed::XStorage
> & xStorage
)
105 rOutMD
.realloc( rOutMD
.getLength() + 1 );
106 rOutMD
[rOutMD
.getLength() - 1] = beans::PropertyValue(
107 C2U("Storage"), -1, uno::makeAny( xStorage
), beans::PropertyState_DIRECT_VALUE
);
110 Reference
< embed::XStorage
> lcl_createStorage(
111 const OUString
& rURL
,
112 const Reference
< uno::XComponentContext
> & xContext
,
113 const Sequence
< beans::PropertyValue
> & rMediaDescriptor
)
115 // create new storage
116 Reference
< embed::XStorage
> xStorage
;
122 Reference
< io::XStream
> xStream(
123 ::ucbhelper::Content( rURL
, Reference
< ::com::sun::star::ucb::XCommandEnvironment
>()).openStream(),
126 Reference
< lang::XSingleServiceFactory
> xStorageFact(
127 xContext
->getServiceManager()->createInstanceWithContext(
128 C2U("com.sun.star.embed.StorageFactory"),
130 uno::UNO_QUERY_THROW
);
131 Sequence
< uno::Any
> aStorageArgs( 3 );
132 aStorageArgs
[0] <<= xStream
;
133 aStorageArgs
[1] <<= embed::ElementModes::READWRITE
;
134 aStorageArgs
[2] <<= rMediaDescriptor
;
136 xStorageFact
->createInstanceWithArguments( aStorageArgs
), uno::UNO_QUERY_THROW
);
137 OSL_ENSURE( xStorage
.is(), "No Storage" );
139 catch( ::com::sun::star::ucb::ContentCreationException
& rEx
)
141 ASSERT_EXCEPTION( rEx
);
147 } // anonymous namespace
152 Reference
< document::XFilter
> ChartModel::impl_createFilter(
153 const Sequence
< beans::PropertyValue
> & rMediaDescriptor
)
155 Reference
< document::XFilter
> xFilter
;
157 // find FilterName in MediaDescriptor
158 OUString
aFilterName(
159 lcl_getProperty
< OUString
>( rMediaDescriptor
, OUString::createFromAscii("FilterName")));
161 // if FilterName was found, get Filter from factory
162 if( aFilterName
.getLength() > 0 )
166 Reference
< container::XNameAccess
> xFilterFact(
167 m_xContext
->getServiceManager()->createInstanceWithContext(
168 C2U( "com.sun.star.document.FilterFactory" ), m_xContext
),
169 uno::UNO_QUERY_THROW
);
170 uno::Any
aFilterProps( xFilterFact
->getByName( aFilterName
));
171 Sequence
< beans::PropertyValue
> aProps
;
173 if( aFilterProps
.hasValue() &&
174 (aFilterProps
>>= aProps
))
176 OUString
aFilterServiceName(
177 lcl_getProperty
< OUString
>( aProps
, OUString::createFromAscii("FilterService")));
179 if( aFilterServiceName
.getLength())
182 m_xContext
->getServiceManager()->createInstanceWithContext(
183 aFilterServiceName
, m_xContext
), uno::UNO_QUERY_THROW
);
184 OSL_TRACE( "Filter found for service %s", U2C( aFilterServiceName
));
188 catch( uno::Exception
& ex
)
190 ASSERT_EXCEPTION( ex
);
192 OSL_ENSURE( xFilter
.is(), "Filter not found via factory" );
195 // fall-back: create XML-Filter
198 OSL_TRACE( "No FilterName passed in MediaDescriptor" );
200 m_xContext
->getServiceManager()->createInstanceWithContext(
201 C2U("com.sun.star.comp.chart2.XMLFilter"), m_xContext
),
202 uno::UNO_QUERY_THROW
);
208 //-----------------------------------------------------------------
210 //-----------------------------------------------------------------
212 void SAL_CALL
ChartModel::storeSelf( const Sequence
< beans::PropertyValue
>& rMediaDescriptor
)
213 throw (lang::IllegalArgumentException
,
215 uno::RuntimeException
)
217 // only some parameters are allowed (see also SfxBaseModel)
218 // "VersionComment", "Author", "InteractionHandler", "StatusIndicator"
219 // However, they are ignored here. They would become interesting when
220 // charts support a standalone format again.
221 impl_store( rMediaDescriptor
, m_xStorage
);
224 //-----------------------------------------------------------------
225 // frame::XStorable (base of XStorable2)
226 //-----------------------------------------------------------------
227 sal_Bool SAL_CALL
ChartModel::hasLocation()
228 throw(uno::RuntimeException
)
231 return m_aResource
.getLength()!=0;
234 ::rtl::OUString SAL_CALL
ChartModel::getLocation()
235 throw(uno::RuntimeException
)
237 return impl_g_getLocation();
240 sal_Bool SAL_CALL
ChartModel::isReadonly()
241 throw(uno::RuntimeException
)
247 void SAL_CALL
ChartModel::store()
248 throw(io::IOException
,
249 uno::RuntimeException
)
251 apphelper::LifeTimeGuard
aGuard(m_aLifeTimeManager
);
252 if(!aGuard
.startApiCall(sal_True
)) //start LongLastingCall
253 return; //behave passive if already disposed or closed or throw exception @todo?
255 ::rtl::OUString aLocation
= m_aResource
;
257 if( aLocation
.getLength() == 0 )
258 throw io::IOException( C2U( "no location specified" ), static_cast< ::cppu::OWeakObject
* >(this));
259 //@todo check wether aLocation is something like private:factory...
261 throw io::IOException( C2U( "document is read only" ), static_cast< ::cppu::OWeakObject
* >(this));
266 impl_store( m_aMediaDescriptor
, m_xStorage
);
269 void SAL_CALL
ChartModel::storeAsURL(
270 const ::rtl::OUString
& rURL
,
271 const uno::Sequence
< beans::PropertyValue
>& rMediaDescriptor
)
272 throw(io::IOException
, uno::RuntimeException
)
274 apphelper::LifeTimeGuard
aGuard(m_aLifeTimeManager
);
275 if(!aGuard
.startApiCall(sal_True
)) //start LongLastingCall
276 return; //behave passive if already disposed or closed or throw exception @todo?
278 apphelper::MediaDescriptorHelper
aMediaDescriptorHelper(rMediaDescriptor
);
279 uno::Sequence
< beans::PropertyValue
> aReducedMediaDescriptor(
280 aMediaDescriptorHelper
.getReducedForModel() );
282 m_bReadOnly
= sal_False
;
285 // create new storage
286 Reference
< embed::XStorage
> xStorage( lcl_createStorage( rURL
, m_xContext
, aReducedMediaDescriptor
));
290 impl_store( aReducedMediaDescriptor
, xStorage
);
291 attachResource( rURL
, aReducedMediaDescriptor
);
295 void SAL_CALL
ChartModel::storeToURL(
296 const ::rtl::OUString
& rURL
,
297 const uno::Sequence
< beans::PropertyValue
>& rMediaDescriptor
)
298 throw(io::IOException
,
299 uno::RuntimeException
)
301 apphelper::LifeTimeGuard
aGuard(m_aLifeTimeManager
);
302 if(!aGuard
.startApiCall(sal_True
)) //start LongLastingCall
303 return; //behave passive if already disposed or closed or throw exception @todo?
304 //do not change the internal state of the document here
309 apphelper::MediaDescriptorHelper
aMediaDescriptorHelper(rMediaDescriptor
);
310 uno::Sequence
< beans::PropertyValue
> aReducedMediaDescriptor(
311 aMediaDescriptorHelper
.getReducedForModel() );
313 if( rURL
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("private:stream")))
317 if( m_xContext
.is() && aMediaDescriptorHelper
.ISSET_OutputStream
)
319 Reference
< lang::XMultiServiceFactory
> xFact( m_xContext
->getServiceManager(), uno::UNO_QUERY_THROW
);
320 Reference
< io::XStream
> xStream(
321 xFact
->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.TempFile"))), uno::UNO_QUERY_THROW
);
322 Reference
< io::XInputStream
> xInputStream( xStream
->getInputStream());
324 Reference
< embed::XStorage
> xStorage(
325 ::comphelper::OStorageHelper::GetStorageFromStream( xStream
, embed::ElementModes::READWRITE
, xFact
));
328 impl_store( aReducedMediaDescriptor
, xStorage
);
330 Reference
< io::XSeekable
> xSeekable( xStream
, uno::UNO_QUERY_THROW
);
331 xSeekable
->seek( 0 );
332 ::comphelper::OStorageHelper::CopyInputToOutput( xInputStream
, aMediaDescriptorHelper
.OutputStream
);
336 catch( const uno::Exception
& ex
)
338 ASSERT_EXCEPTION( ex
);
343 // create new storage
344 Reference
< embed::XStorage
> xStorage( lcl_createStorage( rURL
, m_xContext
, aReducedMediaDescriptor
));
347 impl_store( aReducedMediaDescriptor
, xStorage
);
351 void ChartModel::impl_store(
352 const Sequence
< beans::PropertyValue
>& rMediaDescriptor
,
353 const Reference
< embed::XStorage
> & xStorage
)
355 Reference
< document::XFilter
> xFilter( impl_createFilter( rMediaDescriptor
));
356 if( xFilter
.is() && xStorage
.is())
358 Sequence
< beans::PropertyValue
> aMD( rMediaDescriptor
);
359 lcl_addStorageToMediaDescriptor( aMD
, xStorage
);
362 Reference
< document::XExporter
> xExporter( xFilter
, uno::UNO_QUERY_THROW
);
363 xExporter
->setSourceDocument( Reference
< lang::XComponent
>( this ));
364 xFilter
->filter( aMD
);
366 catch( uno::Exception
& ex
)
368 ASSERT_EXCEPTION( ex
);
373 OSL_ENSURE( false, "No filter" );
376 setModified( sal_False
);
379 //for data change notification during chart is not loaded:
380 //notify parent data provider after saving thus the parent document can store
381 //the ranges for which a load and update of the chart will be necessary
382 Reference
< beans::XPropertySet
> xPropSet( m_xParent
, uno::UNO_QUERY
);
383 if ( !hasInternalDataProvider() && xPropSet
.is() )
385 apphelper::MediaDescriptorHelper
aMDHelper(rMediaDescriptor
);
388 xPropSet
->setPropertyValue( OUString::createFromAscii("SavedObject"),
389 uno::makeAny( aMDHelper
.HierarchicalDocumentName
) );
391 catch ( uno::Exception
& )
397 //-----------------------------------------------------------------
399 //-----------------------------------------------------------------
400 void SAL_CALL
ChartModel::initNew()
401 throw (frame::DoubleInitializationException
,
404 uno::RuntimeException
)
407 createInternalDataProvider( sal_False
);
410 m_pImplChartModel
->CreateDefaultChart();
411 ChartModelHelper::setIncludeHiddenCells( false, this );
413 catch( uno::Exception
& ex
)
415 ASSERT_EXCEPTION( ex
);
417 setModified( sal_False
);
420 #if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL
421 OSL_TRACE( "ChartModel::initNew: Showing ChartDocument structure" );
422 OSL_TRACE( "----------------------------------------------------" );
423 debug::ChartDebugTraceDocument( Reference
< chart2::XChartDocument
>( this ));
427 void SAL_CALL
ChartModel::load(
428 const Sequence
< beans::PropertyValue
>& rMediaDescriptor
)
429 throw (frame::DoubleInitializationException
,
432 uno::RuntimeException
)
434 Reference
< embed::XStorage
> xStorage
;
438 apphelper::MediaDescriptorHelper
aMDHelper( rMediaDescriptor
);
439 if( aMDHelper
.ISSET_Storage
)
441 xStorage
= aMDHelper
.Storage
;
443 else if( aMDHelper
.ISSET_Stream
||
444 aMDHelper
.ISSET_InputStream
)
446 if( aMDHelper
.ISSET_FilterName
&&
447 (aMDHelper
.FilterName
.equals( C2U("StarChart 5.0")) ||
448 aMDHelper
.FilterName
.equals( C2U("StarChart 4.0")) ||
449 aMDHelper
.FilterName
.equals( C2U("StarChart 3.0")) ))
451 attachResource( aMDHelper
.URL
, rMediaDescriptor
);
452 impl_load( rMediaDescriptor
, 0 ); // cannot create a storage from binary streams, but I do not need the storage here anyhow
453 m_bReadOnly
= sal_True
;
457 Reference
< lang::XSingleServiceFactory
> xStorageFact(
458 m_xContext
->getServiceManager()->createInstanceWithContext(
459 C2U("com.sun.star.embed.StorageFactory"),
461 uno::UNO_QUERY_THROW
);
463 if( aMDHelper
.ISSET_Stream
)
465 // convert XStream to XStorage via the storage factory
466 Sequence
< uno::Any
> aStorageArgs( 2 );
467 aStorageArgs
[0] <<= aMDHelper
.Stream
;
468 // todo: check if stream is read-only
469 aStorageArgs
[1] <<= (embed::ElementModes::READ
); //WRITE | embed::ElementModes::NOCREATE);
471 xStorage
.set( xStorageFact
->createInstanceWithArguments( aStorageArgs
),
472 uno::UNO_QUERY_THROW
);
476 OSL_ASSERT( aMDHelper
.ISSET_InputStream
);
477 // convert XInputStream to XStorage via the storage factory
478 Sequence
< uno::Any
> aStorageArgs( 2 );
479 aStorageArgs
[0] <<= aMDHelper
.InputStream
;
480 aStorageArgs
[1] <<= (embed::ElementModes::READ
);
482 xStorage
.set( xStorageFact
->createInstanceWithArguments( aStorageArgs
),
483 uno::UNO_QUERY_THROW
);
487 if( aMDHelper
.ISSET_URL
)
488 aURL
= aMDHelper
.URL
;
490 catch( uno::Exception
& ex
)
492 ASSERT_EXCEPTION( ex
);
497 attachResource( aURL
, rMediaDescriptor
);
498 impl_load( rMediaDescriptor
, xStorage
);
502 void ChartModel::impl_load(
503 const Sequence
< beans::PropertyValue
>& rMediaDescriptor
,
504 const Reference
< embed::XStorage
>& xStorage
)
507 MutexGuard
aGuard( m_aModelMutex
);
511 Reference
< document::XFilter
> xFilter( impl_createFilter( rMediaDescriptor
));
515 Reference
< document::XImporter
> xImporter( xFilter
, uno::UNO_QUERY_THROW
);
516 xImporter
->setTargetDocument( this );
517 Sequence
< beans::PropertyValue
> aMD( rMediaDescriptor
);
518 lcl_addStorageToMediaDescriptor( aMD
, xStorage
);
520 xFilter
->filter( aMD
);
525 OSL_ENSURE( false, "loadFromStorage cannot create filter" );
529 impl_loadGraphics( xStorage
);
531 setModified( sal_False
);
533 // switchToStorage without notifying listeners (which shouldn't exist at
534 // this time, anyway)
535 m_xStorage
= xStorage
;
538 MutexGuard
aGuard( m_aModelMutex
);
543 void ChartModel::impl_loadGraphics(
544 const Reference
< embed::XStorage
>& xStorage
)
548 const Reference
< embed::XStorage
>& xGraphicsStorage(
549 xStorage
->openStorageElement( C2U( "Pictures" ),
550 embed::ElementModes::READ
) );
552 if( xGraphicsStorage
.is() )
554 const uno::Sequence
< ::rtl::OUString
> aElementNames(
555 xGraphicsStorage
->getElementNames() );
557 for( int i
= 0; i
< aElementNames
.getLength(); ++i
)
559 if( xGraphicsStorage
->isStreamElement( aElementNames
[ i
] ) )
561 uno::Reference
< io::XStream
> xElementStream(
562 xGraphicsStorage
->openStreamElement(
564 embed::ElementModes::READ
) );
566 if( xElementStream
.is() )
568 std::auto_ptr
< SvStream
> apIStm(
569 ::utl::UcbStreamHelper::CreateStream(
570 xElementStream
, true ) );
576 if( !GraphicConverter::Import(
580 m_aGraphicObjectVector
.push_back( aGraphic
);
588 catch ( uno::Exception
& )
593 //-----------------------------------------------------------------
595 //-----------------------------------------------------------------
596 void SAL_CALL
ChartModel::impl_notifyModifiedListeners()
597 throw( uno::RuntimeException
)
600 MutexGuard
aGuard( m_aModelMutex
);
601 m_bUpdateNotificationsPending
= false;
604 //always notify the view first!
605 ChartViewHelper::setViewToDirtyState( this );
607 ::cppu::OInterfaceContainerHelper
* pIC
= m_aLifeTimeManager
.m_aListenerContainer
608 .getContainer( ::getCppuType((const uno::Reference
< util::XModifyListener
>*)0) );
611 lang::EventObject
aEvent( static_cast< lang::XComponent
*>(this) );
612 ::cppu::OInterfaceIteratorHelper
aIt( *pIC
);
613 while( aIt
.hasMoreElements() )
614 (static_cast< util::XModifyListener
*>(aIt
.next()))->modified( aEvent
);
618 sal_Bool SAL_CALL
ChartModel::isModified()
619 throw(uno::RuntimeException
)
625 void SAL_CALL
ChartModel::setModified( sal_Bool bModified
)
626 throw(beans::PropertyVetoException
,
627 uno::RuntimeException
)
629 apphelper::LifeTimeGuard
aGuard(m_aLifeTimeManager
);
630 if(!aGuard
.startApiCall())//@todo ? is this a long lasting call??
631 return; //behave passive if already disposed or closed or throw exception @todo?
632 m_bModified
= bModified
;
634 if( m_nControllerLockCount
> 0 )
636 m_bUpdateNotificationsPending
= true;
637 return;//don't call listeners if controllers are locked
642 impl_notifyModifiedListeners();
645 //-----------------------------------------------------------------
646 // util::XModifyBroadcaster (base of XModifiable)
647 //-----------------------------------------------------------------
648 void SAL_CALL
ChartModel::addModifyListener(
649 const uno::Reference
< util::XModifyListener
>& xListener
)
650 throw(uno::RuntimeException
)
652 if( m_aLifeTimeManager
.impl_isDisposedOrClosed() )
653 return; //behave passive if already disposed or closed
655 m_aLifeTimeManager
.m_aListenerContainer
.addInterface(
656 ::getCppuType((const uno::Reference
< util::XModifyListener
>*)0), xListener
);
659 void SAL_CALL
ChartModel::removeModifyListener(
660 const uno::Reference
< util::XModifyListener
>& xListener
)
661 throw(uno::RuntimeException
)
663 if( m_aLifeTimeManager
.impl_isDisposedOrClosed() )
664 return; //behave passive if already disposed or closed
666 m_aLifeTimeManager
.m_aListenerContainer
.removeInterface(
667 ::getCppuType((const uno::Reference
< util::XModifyListener
>*)0), xListener
);
670 //-----------------------------------------------------------------
671 // util::XModifyListener
672 //-----------------------------------------------------------------
673 void SAL_CALL
ChartModel::modified( const lang::EventObject
& )
674 throw (uno::RuntimeException
)
677 setModified( sal_True
);
680 //-----------------------------------------------------------------
681 // lang::XEventListener (base of util::XModifyListener)
682 //-----------------------------------------------------------------
683 void SAL_CALL
ChartModel::disposing( const lang::EventObject
& )
684 throw (uno::RuntimeException
)
686 // child was disposed -- should not happen from outside
690 //-----------------------------------------------------------------
691 // document::XStorageBasedDocument
692 //-----------------------------------------------------------------
693 void SAL_CALL
ChartModel::loadFromStorage(
694 const Reference
< embed::XStorage
>& xStorage
,
695 const Sequence
< beans::PropertyValue
>& rMediaDescriptor
)
696 throw (lang::IllegalArgumentException
,
697 frame::DoubleInitializationException
,
700 uno::RuntimeException
)
702 attachResource( OUString(), rMediaDescriptor
);
703 impl_load( rMediaDescriptor
, xStorage
);
706 void SAL_CALL
ChartModel::storeToStorage(
707 const Reference
< embed::XStorage
>& xStorage
,
708 const Sequence
< beans::PropertyValue
>& rMediaDescriptor
)
709 throw (lang::IllegalArgumentException
,
712 uno::RuntimeException
)
714 impl_store( rMediaDescriptor
, xStorage
);
717 void SAL_CALL
ChartModel::switchToStorage( const Reference
< embed::XStorage
>& xStorage
)
718 throw (lang::IllegalArgumentException
,
721 uno::RuntimeException
)
723 m_xStorage
= xStorage
;
724 impl_notifyStorageChangeListeners();
727 Reference
< embed::XStorage
> SAL_CALL
ChartModel::getDocumentStorage()
728 throw (io::IOException
,
730 uno::RuntimeException
)
735 void SAL_CALL
ChartModel::impl_notifyStorageChangeListeners()
736 throw( uno::RuntimeException
)
738 ::cppu::OInterfaceContainerHelper
* pIC
= m_aLifeTimeManager
.m_aListenerContainer
739 .getContainer( ::getCppuType((const uno::Reference
< document::XStorageChangeListener
>*)0) );
742 ::cppu::OInterfaceIteratorHelper
aIt( *pIC
);
743 while( aIt
.hasMoreElements() )
744 (static_cast< document::XStorageChangeListener
* >(aIt
.next()))->notifyStorageChange(
745 static_cast< ::cppu::OWeakObject
* >( this ), m_xStorage
);
749 void SAL_CALL
ChartModel::addStorageChangeListener( const Reference
< document::XStorageChangeListener
>& xListener
)
750 throw (uno::RuntimeException
)
752 if( m_aLifeTimeManager
.impl_isDisposedOrClosed() )
753 return; //behave passive if already disposed or closed
755 m_aLifeTimeManager
.m_aListenerContainer
.addInterface(
756 ::getCppuType((const uno::Reference
< document::XStorageChangeListener
>*)0), xListener
);
759 void SAL_CALL
ChartModel::removeStorageChangeListener( const Reference
< document::XStorageChangeListener
>& xListener
)
760 throw (uno::RuntimeException
)
762 if( m_aLifeTimeManager
.impl_isDisposedOrClosed() )
763 return; //behave passive if already disposed or closed
765 m_aLifeTimeManager
.m_aListenerContainer
.removeInterface(
766 ::getCppuType((const uno::Reference
< document::XStorageChangeListener
>*)0), xListener
);