merged tag ooo/OOO330_m14
[LibreOffice.git] / chart2 / source / model / main / ChartModel_Persistence.cxx
blob1868c38e094f2ddf3d06661b11016620a8907af0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_chart2.hxx"
31 #include "ChartModel.hxx"
32 #include "MediaDescriptorHelper.hxx"
33 #include "ChartDebugTrace.hxx"
34 #include "macros.hxx"
35 #include "ChartViewHelper.hxx"
36 #include "ChartModelHelper.hxx"
37 #include "AxisHelper.hxx"
38 #include "ThreeDHelper.hxx"
40 #include <com/sun/star/chart2/LegendPosition.hpp>
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/drawing/FillStyle.hpp>
46 #include <com/sun/star/drawing/LineStyle.hpp>
47 #include <com/sun/star/drawing/ProjectionMode.hpp>
48 #include <com/sun/star/embed/ElementModes.hpp>
49 #include <com/sun/star/embed/XStorage.hpp>
50 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
51 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
52 #include <com/sun/star/uno/XComponentContext.hpp>
53 #include <com/sun/star/io/XSeekable.hpp>
55 #include <ucbhelper/content.hxx>
56 #ifndef _UNOTOOLS_UCBSTREAMHELPER_HXX
57 #include <unotools/ucbstreamhelper.hxx>
58 #endif
59 #include <vcl/cvtgrf.hxx>
60 #include <comphelper/storagehelper.hxx>
61 #include <vcl/svapp.hxx>
63 #include <algorithm>
64 #include <functional>
66 using namespace ::com::sun::star;
68 using ::com::sun::star::uno::Reference;
69 using ::com::sun::star::uno::Sequence;
70 using ::rtl::OUString;
71 using ::osl::MutexGuard;
73 namespace
75 struct lcl_PropNameEquals : public ::std::unary_function< beans::PropertyValue, bool >
77 lcl_PropNameEquals( const OUString & rStrToCompareWith ) :
78 m_aStr( rStrToCompareWith )
80 bool operator() ( const beans::PropertyValue & rProp )
82 return rProp.Name.equals( m_aStr );
84 private:
85 OUString m_aStr;
88 template< typename T >
89 T lcl_getProperty(
90 const Sequence< beans::PropertyValue > & rMediaDescriptor,
91 const OUString & rPropName )
93 T aResult;
94 if( rMediaDescriptor.getLength())
96 OUString aPropName( rPropName );
97 const beans::PropertyValue * pIt = rMediaDescriptor.getConstArray();
98 const beans::PropertyValue * pEndIt = pIt + + rMediaDescriptor.getLength();
99 pIt = ::std::find_if( pIt, pEndIt, lcl_PropNameEquals( aPropName ));
100 if( pIt != pEndIt )
101 (*pIt).Value >>= aResult;
103 return aResult;
106 void lcl_addStorageToMediaDescriptor(
107 Sequence< beans::PropertyValue > & rOutMD,
108 const Reference< embed::XStorage > & xStorage )
110 rOutMD.realloc( rOutMD.getLength() + 1 );
111 rOutMD[rOutMD.getLength() - 1] = beans::PropertyValue(
112 C2U("Storage"), -1, uno::makeAny( xStorage ), beans::PropertyState_DIRECT_VALUE );
115 Reference< embed::XStorage > lcl_createStorage(
116 const OUString & rURL,
117 const Reference< uno::XComponentContext > & xContext,
118 const Sequence< beans::PropertyValue > & rMediaDescriptor )
120 // create new storage
121 Reference< embed::XStorage > xStorage;
122 if( !xContext.is())
123 return xStorage;
127 Reference< io::XStream > xStream(
128 ::ucbhelper::Content( rURL, Reference< ::com::sun::star::ucb::XCommandEnvironment >()).openStream(),
129 uno::UNO_QUERY );
131 Reference< lang::XSingleServiceFactory > xStorageFact(
132 xContext->getServiceManager()->createInstanceWithContext(
133 C2U("com.sun.star.embed.StorageFactory"),
134 xContext ),
135 uno::UNO_QUERY_THROW );
136 Sequence< uno::Any > aStorageArgs( 3 );
137 aStorageArgs[0] <<= xStream;
138 aStorageArgs[1] <<= embed::ElementModes::READWRITE;
139 aStorageArgs[2] <<= rMediaDescriptor;
140 xStorage.set(
141 xStorageFact->createInstanceWithArguments( aStorageArgs ), uno::UNO_QUERY_THROW );
142 OSL_ENSURE( xStorage.is(), "No Storage" );
144 catch( ::com::sun::star::ucb::ContentCreationException & rEx )
146 ASSERT_EXCEPTION( rEx );
149 return xStorage;
152 } // anonymous namespace
154 namespace chart
157 Reference< document::XFilter > ChartModel::impl_createFilter(
158 const Sequence< beans::PropertyValue > & rMediaDescriptor )
160 Reference< document::XFilter > xFilter;
162 // find FilterName in MediaDescriptor
163 OUString aFilterName(
164 lcl_getProperty< OUString >( rMediaDescriptor, OUString::createFromAscii("FilterName")));
166 // if FilterName was found, get Filter from factory
167 if( aFilterName.getLength() > 0 )
171 Reference< container::XNameAccess > xFilterFact(
172 m_xContext->getServiceManager()->createInstanceWithContext(
173 C2U( "com.sun.star.document.FilterFactory" ), m_xContext ),
174 uno::UNO_QUERY_THROW );
175 uno::Any aFilterProps( xFilterFact->getByName( aFilterName ));
176 Sequence< beans::PropertyValue > aProps;
178 if( aFilterProps.hasValue() &&
179 (aFilterProps >>= aProps))
181 OUString aFilterServiceName(
182 lcl_getProperty< OUString >( aProps, OUString::createFromAscii("FilterService")));
184 if( aFilterServiceName.getLength())
186 xFilter.set(
187 m_xContext->getServiceManager()->createInstanceWithContext(
188 aFilterServiceName, m_xContext ), uno::UNO_QUERY_THROW );
189 OSL_TRACE( "Filter found for service %s", U2C( aFilterServiceName ));
193 catch( uno::Exception & ex )
195 ASSERT_EXCEPTION( ex );
197 OSL_ENSURE( xFilter.is(), "Filter not found via factory" );
200 // fall-back: create XML-Filter
201 if( ! xFilter.is())
203 OSL_TRACE( "No FilterName passed in MediaDescriptor" );
204 xFilter.set(
205 m_xContext->getServiceManager()->createInstanceWithContext(
206 C2U("com.sun.star.comp.chart2.XMLFilter"), m_xContext ),
207 uno::UNO_QUERY_THROW );
210 return xFilter;
213 //-----------------------------------------------------------------
214 // frame::XStorable2
215 //-----------------------------------------------------------------
217 void SAL_CALL ChartModel::storeSelf( const Sequence< beans::PropertyValue >& rMediaDescriptor )
218 throw (lang::IllegalArgumentException,
219 io::IOException,
220 uno::RuntimeException)
222 // only some parameters are allowed (see also SfxBaseModel)
223 // "VersionComment", "Author", "InteractionHandler", "StatusIndicator"
224 // However, they are ignored here. They would become interesting when
225 // charts support a standalone format again.
226 impl_store( rMediaDescriptor, m_xStorage );
229 //-----------------------------------------------------------------
230 // frame::XStorable (base of XStorable2)
231 //-----------------------------------------------------------------
232 sal_Bool SAL_CALL ChartModel::hasLocation()
233 throw(uno::RuntimeException)
235 //@todo guard
236 return m_aResource.getLength()!=0;
239 ::rtl::OUString SAL_CALL ChartModel::getLocation()
240 throw(uno::RuntimeException)
242 return impl_g_getLocation();
245 sal_Bool SAL_CALL ChartModel::isReadonly()
246 throw(uno::RuntimeException)
248 //@todo guard
249 return m_bReadOnly;
252 void SAL_CALL ChartModel::store()
253 throw(io::IOException,
254 uno::RuntimeException)
256 apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
257 if(!aGuard.startApiCall(sal_True)) //start LongLastingCall
258 return; //behave passive if already disposed or closed or throw exception @todo?
260 ::rtl::OUString aLocation = m_aResource;
262 if( aLocation.getLength() == 0 )
263 throw io::IOException( C2U( "no location specified" ), static_cast< ::cppu::OWeakObject* >(this));
264 //@todo check wether aLocation is something like private:factory...
265 if( m_bReadOnly )
266 throw io::IOException( C2U( "document is read only" ), static_cast< ::cppu::OWeakObject* >(this));
268 aGuard.clear();
270 // store
271 impl_store( m_aMediaDescriptor, m_xStorage );
274 void SAL_CALL ChartModel::storeAsURL(
275 const ::rtl::OUString& rURL,
276 const uno::Sequence< beans::PropertyValue >& rMediaDescriptor )
277 throw(io::IOException, uno::RuntimeException)
279 apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
280 if(!aGuard.startApiCall(sal_True)) //start LongLastingCall
281 return; //behave passive if already disposed or closed or throw exception @todo?
283 apphelper::MediaDescriptorHelper aMediaDescriptorHelper(rMediaDescriptor);
284 uno::Sequence< beans::PropertyValue > aReducedMediaDescriptor(
285 aMediaDescriptorHelper.getReducedForModel() );
287 m_bReadOnly = sal_False;
288 aGuard.clear();
290 // create new storage
291 Reference< embed::XStorage > xStorage( lcl_createStorage( rURL, m_xContext, aReducedMediaDescriptor ));
293 if( xStorage.is())
295 impl_store( aReducedMediaDescriptor, xStorage );
296 attachResource( rURL, aReducedMediaDescriptor );
300 void SAL_CALL ChartModel::storeToURL(
301 const ::rtl::OUString& rURL,
302 const uno::Sequence< beans::PropertyValue >& rMediaDescriptor )
303 throw(io::IOException,
304 uno::RuntimeException)
306 apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
307 if(!aGuard.startApiCall(sal_True)) //start LongLastingCall
308 return; //behave passive if already disposed or closed or throw exception @todo?
309 //do not change the internal state of the document here
310 //...
312 aGuard.clear();
314 apphelper::MediaDescriptorHelper aMediaDescriptorHelper(rMediaDescriptor);
315 uno::Sequence< beans::PropertyValue > aReducedMediaDescriptor(
316 aMediaDescriptorHelper.getReducedForModel() );
318 if( rURL.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("private:stream")))
322 if( m_xContext.is() && aMediaDescriptorHelper.ISSET_OutputStream )
324 Reference< lang::XMultiServiceFactory > xFact( m_xContext->getServiceManager(), uno::UNO_QUERY_THROW );
325 Reference< io::XStream > xStream(
326 xFact->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.TempFile"))), uno::UNO_QUERY_THROW );
327 Reference< io::XInputStream > xInputStream( xStream->getInputStream());
329 Reference< embed::XStorage > xStorage(
330 ::comphelper::OStorageHelper::GetStorageFromStream( xStream, embed::ElementModes::READWRITE, xFact ));
331 if( xStorage.is())
333 impl_store( aReducedMediaDescriptor, xStorage );
335 Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY_THROW );
336 xSeekable->seek( 0 );
337 ::comphelper::OStorageHelper::CopyInputToOutput( xInputStream, aMediaDescriptorHelper.OutputStream );
341 catch( const uno::Exception & ex )
343 ASSERT_EXCEPTION( ex );
346 else
348 // create new storage
349 Reference< embed::XStorage > xStorage( lcl_createStorage( rURL, m_xContext, aReducedMediaDescriptor ));
351 if( xStorage.is())
352 impl_store( aReducedMediaDescriptor, xStorage );
356 void ChartModel::impl_store(
357 const Sequence< beans::PropertyValue >& rMediaDescriptor,
358 const Reference< embed::XStorage > & xStorage )
360 Reference< document::XFilter > xFilter( impl_createFilter( rMediaDescriptor));
361 if( xFilter.is() && xStorage.is())
363 Sequence< beans::PropertyValue > aMD( rMediaDescriptor );
364 lcl_addStorageToMediaDescriptor( aMD, xStorage );
367 Reference< document::XExporter > xExporter( xFilter, uno::UNO_QUERY_THROW );
368 xExporter->setSourceDocument( Reference< lang::XComponent >( this ));
369 xFilter->filter( aMD );
371 catch( uno::Exception & ex )
373 ASSERT_EXCEPTION( ex );
376 else
378 OSL_ENSURE( false, "No filter" );
381 setModified( sal_False );
383 //#i66865#
384 //for data change notification during chart is not loaded:
385 //notify parent data provider after saving thus the parent document can store
386 //the ranges for which a load and update of the chart will be necessary
387 Reference< beans::XPropertySet > xPropSet( m_xParent, uno::UNO_QUERY );
388 if ( !hasInternalDataProvider() && xPropSet.is() )
390 apphelper::MediaDescriptorHelper aMDHelper(rMediaDescriptor);
393 xPropSet->setPropertyValue( OUString::createFromAscii("SavedObject"),
394 uno::makeAny( aMDHelper.HierarchicalDocumentName ) );
396 catch ( uno::Exception& )
402 //-----------------------------------------------------------------
403 // frame::XLoadable
404 //-----------------------------------------------------------------
405 void SAL_CALL ChartModel::initNew()
406 throw (frame::DoubleInitializationException,
407 io::IOException,
408 uno::Exception,
409 uno::RuntimeException)
411 lockControllers();
412 createInternalDataProvider( sal_False );
415 // create default chart
416 Reference< chart2::XChartTypeTemplate > xTemplate( impl_createDefaultChartTypeTemplate() );
417 if( xTemplate.is())
421 Reference< chart2::data::XDataSource > xDataSource( impl_createDefaultData() );
422 Sequence< beans::PropertyValue > aParam;
424 bool bSupportsCategories = xTemplate->supportsCategories();
425 if( bSupportsCategories )
427 aParam.realloc( 1 );
428 aParam[0] = beans::PropertyValue( C2U("HasCategories"), -1, uno::makeAny( true ),
429 beans::PropertyState_DIRECT_VALUE );
432 Reference< chart2::XDiagram > xDiagram( xTemplate->createDiagramByDataSource( xDataSource, aParam ) );
434 setFirstDiagram( xDiagram );
436 bool bIsRTL = Application::GetSettings().GetLayoutRTL();
437 //reverse x axis for rtl charts
438 if( bIsRTL )
439 AxisHelper::setRTLAxisLayout( AxisHelper::getCoordinateSystemByIndex( xDiagram, 0 ) );
441 // create and attach legend
442 Reference< chart2::XLegend > xLegend(
443 m_xContext->getServiceManager()->createInstanceWithContext(
444 C2U( "com.sun.star.chart2.Legend" ), m_xContext ), uno::UNO_QUERY_THROW );
445 Reference< beans::XPropertySet > xLegendProperties( xLegend, uno::UNO_QUERY );
446 if( xLegendProperties.is() )
448 xLegendProperties->setPropertyValue( C2U( "FillStyle" ), uno::makeAny( drawing::FillStyle_NONE ));
449 xLegendProperties->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_NONE ));
450 xLegendProperties->setPropertyValue( C2U( "LineColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) )); // gray30
451 xLegendProperties->setPropertyValue( C2U( "FillColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xe6e6e6 ) ) ); // gray10
453 if( bIsRTL )
454 xLegendProperties->setPropertyValue( C2U( "AnchorPosition" ), uno::makeAny( chart2::LegendPosition_LINE_START ));
456 if(xDiagram.is())
457 xDiagram->setLegend( xLegend );
459 // set simple 3D look
460 Reference< beans::XPropertySet > xDiagramProperties( xDiagram, uno::UNO_QUERY );
461 if( xDiagramProperties.is() )
463 xDiagramProperties->setPropertyValue( C2U("RightAngledAxes"), uno::makeAny( sal_True ));
464 xDiagramProperties->setPropertyValue( C2U("D3DScenePerspective"), uno::makeAny( drawing::ProjectionMode_PARALLEL ));
465 ThreeDHelper::setScheme( xDiagram, ThreeDLookScheme_Realistic );
468 //set some new 'defaults' for wall and floor
469 if( xDiagram.is() )
471 Reference< beans::XPropertySet > xWall( xDiagram->getWall() );
472 if( xWall.is() )
474 xWall->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_SOLID ) );
475 xWall->setPropertyValue( C2U( "FillStyle" ), uno::makeAny( drawing::FillStyle_NONE ) );
476 xWall->setPropertyValue( C2U( "LineColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) ) ); // gray30
477 xWall->setPropertyValue( C2U( "FillColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xe6e6e6 ) ) ); // gray10
479 Reference< beans::XPropertySet > xFloor( xDiagram->getFloor() );
480 if( xFloor.is() )
482 xFloor->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_NONE ) );
483 xFloor->setPropertyValue( C2U( "FillStyle" ), uno::makeAny( drawing::FillStyle_SOLID ) );
484 xFloor->setPropertyValue( C2U( "LineColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) ) ); // gray30
485 xFloor->setPropertyValue( C2U( "FillColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xcccccc ) ) ); // gray20
490 catch( uno::Exception & ex )
492 ASSERT_EXCEPTION( ex );
495 ChartModelHelper::setIncludeHiddenCells( false, this );
497 catch( uno::Exception & ex )
499 ASSERT_EXCEPTION( ex );
501 setModified( sal_False );
502 unlockControllers();
504 #if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL
505 OSL_TRACE( "ChartModel::initNew: Showing ChartDocument structure" );
506 OSL_TRACE( "----------------------------------------------------" );
507 debug::ChartDebugTraceDocument( Reference< chart2::XChartDocument >( this ));
508 #endif
511 void SAL_CALL ChartModel::load(
512 const Sequence< beans::PropertyValue >& rMediaDescriptor )
513 throw (frame::DoubleInitializationException,
514 io::IOException,
515 uno::Exception,
516 uno::RuntimeException)
518 Reference< embed::XStorage > xStorage;
519 OUString aURL;
522 apphelper::MediaDescriptorHelper aMDHelper( rMediaDescriptor );
523 if( aMDHelper.ISSET_Storage )
525 xStorage = aMDHelper.Storage;
527 else if( aMDHelper.ISSET_Stream ||
528 aMDHelper.ISSET_InputStream )
530 if( aMDHelper.ISSET_FilterName &&
531 (aMDHelper.FilterName.equals( C2U("StarChart 5.0")) ||
532 aMDHelper.FilterName.equals( C2U("StarChart 4.0")) ||
533 aMDHelper.FilterName.equals( C2U("StarChart 3.0")) ))
535 attachResource( aMDHelper.URL, rMediaDescriptor );
536 impl_load( rMediaDescriptor, 0 ); // cannot create a storage from binary streams, but I do not need the storage here anyhow
537 m_bReadOnly = sal_True;
538 return;
541 Reference< lang::XSingleServiceFactory > xStorageFact(
542 m_xContext->getServiceManager()->createInstanceWithContext(
543 C2U("com.sun.star.embed.StorageFactory"),
544 m_xContext ),
545 uno::UNO_QUERY_THROW );
547 if( aMDHelper.ISSET_Stream )
549 // convert XStream to XStorage via the storage factory
550 Sequence< uno::Any > aStorageArgs( 2 );
551 aStorageArgs[0] <<= aMDHelper.Stream;
552 // todo: check if stream is read-only
553 aStorageArgs[1] <<= (embed::ElementModes::READ); //WRITE | embed::ElementModes::NOCREATE);
555 xStorage.set( xStorageFact->createInstanceWithArguments( aStorageArgs ),
556 uno::UNO_QUERY_THROW );
558 else
560 OSL_ASSERT( aMDHelper.ISSET_InputStream );
561 // convert XInputStream to XStorage via the storage factory
562 Sequence< uno::Any > aStorageArgs( 2 );
563 aStorageArgs[0] <<= aMDHelper.InputStream;
564 aStorageArgs[1] <<= (embed::ElementModes::READ);
566 xStorage.set( xStorageFact->createInstanceWithArguments( aStorageArgs ),
567 uno::UNO_QUERY_THROW );
571 if( aMDHelper.ISSET_URL )
572 aURL = aMDHelper.URL;
574 catch( uno::Exception & ex )
576 ASSERT_EXCEPTION( ex );
579 if( xStorage.is())
581 attachResource( aURL, rMediaDescriptor );
582 impl_load( rMediaDescriptor, xStorage );
586 void ChartModel::impl_load(
587 const Sequence< beans::PropertyValue >& rMediaDescriptor,
588 const Reference< embed::XStorage >& xStorage )
591 MutexGuard aGuard( m_aModelMutex );
592 m_nInLoad++;
595 Reference< document::XFilter > xFilter( impl_createFilter( rMediaDescriptor ));
597 if( xFilter.is())
599 Reference< document::XImporter > xImporter( xFilter, uno::UNO_QUERY_THROW );
600 xImporter->setTargetDocument( this );
601 Sequence< beans::PropertyValue > aMD( rMediaDescriptor );
602 lcl_addStorageToMediaDescriptor( aMD, xStorage );
604 xFilter->filter( aMD );
605 xFilter.clear();
607 else
609 OSL_ENSURE( false, "loadFromStorage cannot create filter" );
612 if( xStorage.is() )
613 impl_loadGraphics( xStorage );
615 setModified( sal_False );
617 // switchToStorage without notifying listeners (which shouldn't exist at
618 // this time, anyway)
619 m_xStorage = xStorage;
622 MutexGuard aGuard( m_aModelMutex );
623 m_nInLoad--;
627 void ChartModel::impl_loadGraphics(
628 const Reference< embed::XStorage >& xStorage )
632 const Reference< embed::XStorage >& xGraphicsStorage(
633 xStorage->openStorageElement( C2U( "Pictures" ),
634 embed::ElementModes::READ ) );
636 if( xGraphicsStorage.is() )
638 const uno::Sequence< ::rtl::OUString > aElementNames(
639 xGraphicsStorage->getElementNames() );
641 for( int i = 0; i < aElementNames.getLength(); ++i )
643 if( xGraphicsStorage->isStreamElement( aElementNames[ i ] ) )
645 uno::Reference< io::XStream > xElementStream(
646 xGraphicsStorage->openStreamElement(
647 aElementNames[ i ],
648 embed::ElementModes::READ ) );
650 if( xElementStream.is() )
652 std::auto_ptr< SvStream > apIStm(
653 ::utl::UcbStreamHelper::CreateStream(
654 xElementStream, true ) );
656 if( apIStm.get() )
658 Graphic aGraphic;
660 if( !GraphicConverter::Import(
661 *apIStm.get(),
662 aGraphic ) )
664 m_aGraphicObjectVector.push_back( aGraphic );
672 catch ( uno::Exception& )
677 //-----------------------------------------------------------------
678 // util::XModifiable
679 //-----------------------------------------------------------------
680 void SAL_CALL ChartModel::impl_notifyModifiedListeners()
681 throw( uno::RuntimeException)
684 MutexGuard aGuard( m_aModelMutex );
685 m_bUpdateNotificationsPending = false;
688 //always notify the view first!
689 ChartViewHelper::setViewToDirtyState( this );
691 ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
692 .getContainer( ::getCppuType((const uno::Reference< util::XModifyListener >*)0) );
693 if( pIC )
695 lang::EventObject aEvent( static_cast< lang::XComponent*>(this) );
696 ::cppu::OInterfaceIteratorHelper aIt( *pIC );
697 while( aIt.hasMoreElements() )
699 uno::Reference< util::XModifyListener > xListener( aIt.next(), uno::UNO_QUERY );
700 if( xListener.is() )
701 xListener->modified( aEvent );
706 sal_Bool SAL_CALL ChartModel::isModified()
707 throw(uno::RuntimeException)
709 //@todo guard
710 return m_bModified;
713 void SAL_CALL ChartModel::setModified( sal_Bool bModified )
714 throw(beans::PropertyVetoException,
715 uno::RuntimeException)
717 apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
718 if(!aGuard.startApiCall())//@todo ? is this a long lasting call??
719 return; //behave passive if already disposed or closed or throw exception @todo?
720 m_bModified = bModified;
722 if( m_nControllerLockCount > 0 )
724 m_bUpdateNotificationsPending = true;
725 return;//don't call listeners if controllers are locked
727 aGuard.clear();
729 if(bModified)
730 impl_notifyModifiedListeners();
733 //-----------------------------------------------------------------
734 // util::XModifyBroadcaster (base of XModifiable)
735 //-----------------------------------------------------------------
736 void SAL_CALL ChartModel::addModifyListener(
737 const uno::Reference< util::XModifyListener >& xListener )
738 throw(uno::RuntimeException)
740 if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
741 return; //behave passive if already disposed or closed
743 m_aLifeTimeManager.m_aListenerContainer.addInterface(
744 ::getCppuType((const uno::Reference< util::XModifyListener >*)0), xListener );
747 void SAL_CALL ChartModel::removeModifyListener(
748 const uno::Reference< util::XModifyListener >& xListener )
749 throw(uno::RuntimeException)
751 if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) )
752 return; //behave passive if already disposed or closed
754 m_aLifeTimeManager.m_aListenerContainer.removeInterface(
755 ::getCppuType((const uno::Reference< util::XModifyListener >*)0), xListener );
758 //-----------------------------------------------------------------
759 // util::XModifyListener
760 //-----------------------------------------------------------------
761 void SAL_CALL ChartModel::modified( const lang::EventObject& )
762 throw (uno::RuntimeException)
764 if( m_nInLoad == 0 )
765 setModified( sal_True );
768 //-----------------------------------------------------------------
769 // lang::XEventListener (base of util::XModifyListener)
770 //-----------------------------------------------------------------
771 void SAL_CALL ChartModel::disposing( const lang::EventObject& )
772 throw (uno::RuntimeException)
774 // child was disposed -- should not happen from outside
778 //-----------------------------------------------------------------
779 // document::XStorageBasedDocument
780 //-----------------------------------------------------------------
781 void SAL_CALL ChartModel::loadFromStorage(
782 const Reference< embed::XStorage >& xStorage,
783 const Sequence< beans::PropertyValue >& rMediaDescriptor )
784 throw (lang::IllegalArgumentException,
785 frame::DoubleInitializationException,
786 io::IOException,
787 uno::Exception,
788 uno::RuntimeException)
790 attachResource( OUString(), rMediaDescriptor );
791 impl_load( rMediaDescriptor, xStorage );
794 void SAL_CALL ChartModel::storeToStorage(
795 const Reference< embed::XStorage >& xStorage,
796 const Sequence< beans::PropertyValue >& rMediaDescriptor )
797 throw (lang::IllegalArgumentException,
798 io::IOException,
799 uno::Exception,
800 uno::RuntimeException)
802 impl_store( rMediaDescriptor, xStorage );
805 void SAL_CALL ChartModel::switchToStorage( const Reference< embed::XStorage >& xStorage )
806 throw (lang::IllegalArgumentException,
807 io::IOException,
808 uno::Exception,
809 uno::RuntimeException)
811 m_xStorage = xStorage;
812 impl_notifyStorageChangeListeners();
815 Reference< embed::XStorage > SAL_CALL ChartModel::getDocumentStorage()
816 throw (io::IOException,
817 uno::Exception,
818 uno::RuntimeException)
820 return m_xStorage;
823 void SAL_CALL ChartModel::impl_notifyStorageChangeListeners()
824 throw( uno::RuntimeException)
826 ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
827 .getContainer( ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0) );
828 if( pIC )
830 ::cppu::OInterfaceIteratorHelper aIt( *pIC );
831 while( aIt.hasMoreElements() )
833 uno::Reference< document::XStorageChangeListener > xListener( aIt.next(), uno::UNO_QUERY );
834 if( xListener.is() )
835 xListener->notifyStorageChange( static_cast< ::cppu::OWeakObject* >( this ), m_xStorage );
840 void SAL_CALL ChartModel::addStorageChangeListener( const Reference< document::XStorageChangeListener >& xListener )
841 throw (uno::RuntimeException)
843 if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
844 return; //behave passive if already disposed or closed
846 m_aLifeTimeManager.m_aListenerContainer.addInterface(
847 ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0), xListener );
850 void SAL_CALL ChartModel::removeStorageChangeListener( const Reference< document::XStorageChangeListener >& xListener )
851 throw (uno::RuntimeException)
853 if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) )
854 return; //behave passive if already disposed or closed
856 m_aLifeTimeManager.m_aListenerContainer.removeInterface(
857 ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0), xListener );
860 } // namespace chart