nss: upgrade to release 3.73
[LibreOffice.git] / chart2 / source / model / main / ChartModel_Persistence.cxx
blobb26cf6815d724b1cf9da37b74794bdeffb44fc0f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <memory>
21 #include <ChartModel.hxx>
22 #include <MediaDescriptorHelper.hxx>
23 #include <ChartViewHelper.hxx>
24 #include <ChartModelHelper.hxx>
25 #include <DataSourceHelper.hxx>
26 #include <AxisHelper.hxx>
27 #include <ThreeDHelper.hxx>
28 #include <DiagramHelper.hxx>
30 #include <com/sun/star/chart2/LegendPosition.hpp>
31 #include <com/sun/star/container/XNameAccess.hpp>
32 #include <com/sun/star/document/XExporter.hpp>
33 #include <com/sun/star/document/XImporter.hpp>
34 #include <com/sun/star/document/XFilter.hpp>
35 #include <com/sun/star/drawing/FillStyle.hpp>
36 #include <com/sun/star/drawing/LineStyle.hpp>
37 #include <com/sun/star/drawing/ProjectionMode.hpp>
38 #include <com/sun/star/embed/ElementModes.hpp>
39 #include <com/sun/star/embed/XStorage.hpp>
40 #include <com/sun/star/embed/StorageFactory.hpp>
41 #include <com/sun/star/io/IOException.hpp>
42 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
43 #include <com/sun/star/uno/XComponentContext.hpp>
44 #include <com/sun/star/io/TempFile.hpp>
45 #include <com/sun/star/io/XSeekable.hpp>
46 #include <com/sun/star/ucb/CommandFailedException.hpp>
47 #include <com/sun/star/ucb/ContentCreationException.hpp>
49 #include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
51 #include <ucbhelper/content.hxx>
52 #include <unotools/ucbstreamhelper.hxx>
53 #include <vcl/cvtgrf.hxx>
54 #include <comphelper/processfactory.hxx>
55 #include <comphelper/storagehelper.hxx>
56 #include <vcl/settings.hxx>
57 #include <vcl/svapp.hxx>
58 #include <tools/diagnose_ex.h>
59 #include <sal/log.hxx>
60 #include <sfx2/objsh.hxx>
62 #include <algorithm>
64 using namespace ::com::sun::star;
66 using ::com::sun::star::uno::Reference;
67 using ::com::sun::star::uno::Sequence;
68 using ::osl::MutexGuard;
70 namespace
72 struct lcl_PropNameEquals
74 explicit lcl_PropNameEquals( const OUString & rStrToCompareWith ) :
75 m_aStr( rStrToCompareWith )
77 bool operator() ( const beans::PropertyValue & rProp )
79 return rProp.Name == m_aStr;
81 private:
82 OUString m_aStr;
85 template< typename T >
86 T lcl_getProperty(
87 const Sequence< beans::PropertyValue > & rMediaDescriptor,
88 const OUString & rPropName )
90 T aResult;
91 if( rMediaDescriptor.hasElements())
93 const beans::PropertyValue * pIt = rMediaDescriptor.getConstArray();
94 const beans::PropertyValue * pEndIt = pIt + + rMediaDescriptor.getLength();
95 pIt = std::find_if( pIt, pEndIt, lcl_PropNameEquals( rPropName ));
96 if( pIt != pEndIt )
97 (*pIt).Value >>= aResult;
99 return aResult;
102 void lcl_addStorageToMediaDescriptor(
103 Sequence< beans::PropertyValue > & rOutMD,
104 const Reference< embed::XStorage > & xStorage )
106 rOutMD.realloc( rOutMD.getLength() + 1 );
107 rOutMD[rOutMD.getLength() - 1] = beans::PropertyValue(
108 "Storage", -1, uno::Any( xStorage ), beans::PropertyState_DIRECT_VALUE );
111 Reference< embed::XStorage > lcl_createStorage(
112 const OUString & rURL,
113 const Reference< uno::XComponentContext > & xContext,
114 const Sequence< beans::PropertyValue > & rMediaDescriptor )
116 // create new storage
117 Reference< embed::XStorage > xStorage;
118 if( !xContext.is())
119 return xStorage;
123 Reference< io::XStream > xStream(
124 ::ucbhelper::Content( rURL, Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext()).openStream(),
125 uno::UNO_QUERY );
127 Reference< lang::XSingleServiceFactory > xStorageFact( embed::StorageFactory::create( xContext ) );
128 Sequence< uno::Any > aStorageArgs( 3 );
129 aStorageArgs[0] <<= xStream;
130 aStorageArgs[1] <<= embed::ElementModes::READWRITE;
131 aStorageArgs[2] <<= rMediaDescriptor;
132 xStorage.set(
133 xStorageFact->createInstanceWithArguments( aStorageArgs ), uno::UNO_QUERY_THROW );
135 catch(const css::ucb::ContentCreationException&)
137 DBG_UNHANDLED_EXCEPTION("chart2");
139 catch(const css::ucb::CommandFailedException&)
141 DBG_UNHANDLED_EXCEPTION("chart2");
144 return xStorage;
147 } // anonymous namespace
149 namespace chart
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, "FilterName" ) );
161 // if FilterName was found, get Filter from factory
162 if( !aFilterName.isEmpty() )
166 Reference< container::XNameAccess > xFilterFact(
167 m_xContext->getServiceManager()->createInstanceWithContext(
168 "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, "FilterService" ) );
179 if( !aFilterServiceName.isEmpty())
181 xFilter.set(
182 m_xContext->getServiceManager()->createInstanceWithContext(
183 aFilterServiceName, m_xContext ), uno::UNO_QUERY_THROW );
184 SAL_INFO("chart2", "Filter found for service " << aFilterServiceName );
188 catch( const uno::Exception & )
190 DBG_UNHANDLED_EXCEPTION("chart2");
192 OSL_ENSURE( xFilter.is(), "Filter not found via factory" );
195 // fall-back: create XML-Filter
196 if( ! xFilter.is())
198 SAL_WARN("chart2", "No FilterName passed in MediaDescriptor" );
199 xFilter.set(
200 m_xContext->getServiceManager()->createInstanceWithContext(
201 "com.sun.star.comp.chart2.XMLFilter", m_xContext ),
202 uno::UNO_QUERY_THROW );
205 return xFilter;
208 // frame::XStorable2
210 void SAL_CALL ChartModel::storeSelf( const Sequence< beans::PropertyValue >& rMediaDescriptor )
212 // only some parameters are allowed (see also SfxBaseModel)
213 // "VersionComment", "Author", "InteractionHandler", "StatusIndicator"
214 // However, they are ignored here. They would become interesting when
215 // charts support a standalone format again.
216 impl_store( rMediaDescriptor, m_xStorage );
219 // frame::XStorable (base of XStorable2)
220 sal_Bool SAL_CALL ChartModel::hasLocation()
222 //@todo guard
223 return !m_aResource.isEmpty();
226 OUString SAL_CALL ChartModel::getLocation()
228 return impl_g_getLocation();
231 sal_Bool SAL_CALL ChartModel::isReadonly()
233 //@todo guard
234 return m_bReadOnly;
237 void SAL_CALL ChartModel::store()
239 apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
240 if(!aGuard.startApiCall(true)) //start LongLastingCall
241 return; //behave passive if already disposed or closed or throw exception @todo?
243 OUString aLocation = m_aResource;
245 if( aLocation.isEmpty() )
246 throw io::IOException( "no location specified", static_cast< ::cppu::OWeakObject* >(this));
247 //@todo check whether aLocation is something like private:factory...
248 if( m_bReadOnly )
249 throw io::IOException( "document is read only", static_cast< ::cppu::OWeakObject* >(this));
251 aGuard.clear();
253 // store
254 impl_store( m_aMediaDescriptor, m_xStorage );
257 void SAL_CALL ChartModel::storeAsURL(
258 const OUString& rURL,
259 const uno::Sequence< beans::PropertyValue >& rMediaDescriptor )
261 apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
262 if(!aGuard.startApiCall(true)) //start LongLastingCall
263 return; //behave passive if already disposed or closed or throw exception @todo?
265 apphelper::MediaDescriptorHelper aMediaDescriptorHelper(rMediaDescriptor);
266 uno::Sequence< beans::PropertyValue > aReducedMediaDescriptor(
267 aMediaDescriptorHelper.getReducedForModel() );
269 m_bReadOnly = false;
270 aGuard.clear();
272 // create new storage
273 Reference< embed::XStorage > xStorage( lcl_createStorage( rURL, m_xContext, aReducedMediaDescriptor ));
275 if( xStorage.is())
277 impl_store( aReducedMediaDescriptor, xStorage );
278 attachResource( rURL, aReducedMediaDescriptor );
282 void SAL_CALL ChartModel::storeToURL(
283 const OUString& rURL,
284 const uno::Sequence< beans::PropertyValue >& rMediaDescriptor )
286 apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
287 if(!aGuard.startApiCall(true)) //start LongLastingCall
288 return; //behave passive if already disposed or closed or throw exception @todo?
289 //do not change the internal state of the document here
291 aGuard.clear();
293 apphelper::MediaDescriptorHelper aMediaDescriptorHelper(rMediaDescriptor);
294 uno::Sequence< beans::PropertyValue > aReducedMediaDescriptor(
295 aMediaDescriptorHelper.getReducedForModel() );
297 if ( rURL == "private:stream" )
301 if( m_xContext.is() && aMediaDescriptorHelper.ISSET_OutputStream )
303 Reference< io::XStream > xStream(
304 io::TempFile::create(m_xContext), uno::UNO_QUERY_THROW );
305 Reference< io::XInputStream > xInputStream( xStream->getInputStream());
307 Reference< embed::XStorage > xStorage(
308 ::comphelper::OStorageHelper::GetStorageFromStream( xStream, embed::ElementModes::READWRITE, m_xContext ));
309 if( xStorage.is())
311 impl_store( aReducedMediaDescriptor, xStorage );
313 Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY_THROW );
314 xSeekable->seek( 0 );
315 ::comphelper::OStorageHelper::CopyInputToOutput( xInputStream, aMediaDescriptorHelper.OutputStream );
319 catch( const uno::Exception & )
321 DBG_UNHANDLED_EXCEPTION("chart2");
324 else
326 // create new storage
327 Reference< embed::XStorage > xStorage( lcl_createStorage( rURL, m_xContext, aReducedMediaDescriptor ));
329 if( xStorage.is())
330 impl_store( aReducedMediaDescriptor, xStorage );
334 void ChartModel::impl_store(
335 const Sequence< beans::PropertyValue >& rMediaDescriptor,
336 const Reference< embed::XStorage > & xStorage )
338 Reference< document::XFilter > xFilter( impl_createFilter( rMediaDescriptor));
339 if( xFilter.is() && xStorage.is())
341 Sequence< beans::PropertyValue > aMD( rMediaDescriptor );
342 lcl_addStorageToMediaDescriptor( aMD, xStorage );
345 Reference< document::XExporter > xExporter( xFilter, uno::UNO_QUERY_THROW );
346 xExporter->setSourceDocument( Reference< lang::XComponent >( this ));
347 xFilter->filter( aMD );
349 catch( const uno::Exception & )
351 DBG_UNHANDLED_EXCEPTION("chart2");
354 else
356 OSL_FAIL( "No filter" );
359 setModified( false );
361 //#i66865#
362 //for data change notification during chart is not loaded:
363 //notify parent data provider after saving thus the parent document can store
364 //the ranges for which a load and update of the chart will be necessary
365 Reference< beans::XPropertySet > xPropSet( m_xParent, uno::UNO_QUERY );
366 if ( hasInternalDataProvider() || !xPropSet.is() )
367 return;
369 apphelper::MediaDescriptorHelper aMDHelper(rMediaDescriptor);
372 xPropSet->setPropertyValue(
373 "SavedObject",
374 uno::Any( aMDHelper.HierarchicalDocumentName ) );
376 catch ( const uno::Exception& )
381 void ChartModel::insertDefaultChart()
383 lockControllers();
384 createInternalDataProvider( false );
387 // create default chart
388 Reference< chart2::XChartTypeTemplate > xTemplate( impl_createDefaultChartTypeTemplate() );
389 if( xTemplate.is())
393 Reference< chart2::data::XDataSource > xDataSource( impl_createDefaultData() );
394 Sequence< beans::PropertyValue > aParam;
396 bool bSupportsCategories = xTemplate->supportsCategories();
397 if( bSupportsCategories )
399 aParam.realloc( 1 );
400 aParam[0] = beans::PropertyValue( "HasCategories", -1, uno::Any( true ),
401 beans::PropertyState_DIRECT_VALUE );
404 Reference< chart2::XDiagram > xDiagram( xTemplate->createDiagramByDataSource( xDataSource, aParam ) );
406 setFirstDiagram( xDiagram );
408 bool bIsRTL = AllSettings::GetMathLayoutRTL();
409 //reverse x axis for rtl charts
410 if( bIsRTL )
411 AxisHelper::setRTLAxisLayout( AxisHelper::getCoordinateSystemByIndex( xDiagram, 0 ) );
413 // create and attach legend
414 Reference< chart2::XLegend > xLegend(
415 m_xContext->getServiceManager()->createInstanceWithContext(
416 "com.sun.star.chart2.Legend", m_xContext ), uno::UNO_QUERY_THROW );
417 Reference< beans::XPropertySet > xLegendProperties( xLegend, uno::UNO_QUERY );
418 if( xLegendProperties.is() )
420 xLegendProperties->setPropertyValue( "FillStyle", uno::Any( drawing::FillStyle_NONE ));
421 xLegendProperties->setPropertyValue( "LineStyle", uno::Any( drawing::LineStyle_NONE ));
422 xLegendProperties->setPropertyValue( "LineColor", uno::Any( static_cast< sal_Int32 >( 0xb3b3b3 ) )); // gray30
423 xLegendProperties->setPropertyValue( "FillColor", uno::Any( static_cast< sal_Int32 >( 0xe6e6e6 ) ) ); // gray10
425 if( bIsRTL )
426 xLegendProperties->setPropertyValue( "AnchorPosition", uno::Any( chart2::LegendPosition_LINE_START ));
428 if(xDiagram.is())
429 xDiagram->setLegend( xLegend );
431 // set simple 3D look
432 Reference< beans::XPropertySet > xDiagramProperties( xDiagram, uno::UNO_QUERY );
433 if( xDiagramProperties.is() )
435 xDiagramProperties->setPropertyValue( "RightAngledAxes", uno::Any( true ));
436 xDiagramProperties->setPropertyValue( "D3DScenePerspective", uno::Any( drawing::ProjectionMode_PARALLEL ));
437 ThreeDHelper::setScheme( xDiagram, ThreeDLookScheme_Realistic );
440 //set some new 'defaults' for wall and floor
441 if( xDiagram.is() )
443 Reference< beans::XPropertySet > xWall( xDiagram->getWall() );
444 if( xWall.is() )
446 xWall->setPropertyValue( "LineStyle", uno::Any( drawing::LineStyle_SOLID ) );
447 xWall->setPropertyValue( "FillStyle", uno::Any( drawing::FillStyle_NONE ) );
448 xWall->setPropertyValue( "LineColor", uno::Any( static_cast< sal_Int32 >( 0xb3b3b3 ) ) ); // gray30
449 xWall->setPropertyValue( "FillColor", uno::Any( static_cast< sal_Int32 >( 0xe6e6e6 ) ) ); // gray10
451 Reference< beans::XPropertySet > xFloor( xDiagram->getFloor() );
452 if( xFloor.is() )
454 xFloor->setPropertyValue( "LineStyle", uno::Any( drawing::LineStyle_NONE ) );
455 xFloor->setPropertyValue( "FillStyle", uno::Any( drawing::FillStyle_SOLID ) );
456 xFloor->setPropertyValue( "LineColor", uno::Any( static_cast< sal_Int32 >( 0xb3b3b3 ) ) ); // gray30
457 xFloor->setPropertyValue( "FillColor", uno::Any( static_cast< sal_Int32 >( 0xcccccc ) ) ); // gray20
462 catch( const uno::Exception & )
464 DBG_UNHANDLED_EXCEPTION("chart2");
467 ChartModelHelper::setIncludeHiddenCells( false, *this );
469 catch( const uno::Exception & )
471 DBG_UNHANDLED_EXCEPTION("chart2");
473 setModified( false );
474 unlockControllers();
477 // frame::XLoadable
478 void SAL_CALL ChartModel::initNew()
482 void SAL_CALL ChartModel::load(
483 const Sequence< beans::PropertyValue >& rMediaDescriptor )
485 Reference< embed::XStorage > xStorage;
486 OUString aURL;
489 apphelper::MediaDescriptorHelper aMDHelper( rMediaDescriptor );
490 if( aMDHelper.ISSET_Storage )
492 xStorage = aMDHelper.Storage;
494 else if( aMDHelper.ISSET_Stream ||
495 aMDHelper.ISSET_InputStream )
497 if( aMDHelper.ISSET_FilterName &&
498 (aMDHelper.FilterName == "StarChart 5.0" ||
499 aMDHelper.FilterName == "StarChart 4.0" ||
500 aMDHelper.FilterName == "StarChart 3.0" ))
502 attachResource( aMDHelper.URL, rMediaDescriptor );
503 impl_load( rMediaDescriptor, nullptr ); // cannot create a storage from binary streams, but I do not need the storage here anyhow
504 m_bReadOnly = true;
505 return;
508 Reference< lang::XSingleServiceFactory > xStorageFact( embed::StorageFactory::create(m_xContext) );
510 if( aMDHelper.ISSET_Stream )
512 // convert XStream to XStorage via the storage factory
513 Sequence< uno::Any > aStorageArgs( 2 );
514 aStorageArgs[0] <<= aMDHelper.Stream;
515 // todo: check if stream is read-only
516 aStorageArgs[1] <<= embed::ElementModes::READ; //WRITE | embed::ElementModes::NOCREATE);
518 xStorage.set( xStorageFact->createInstanceWithArguments( aStorageArgs ),
519 uno::UNO_QUERY_THROW );
521 else
523 OSL_ASSERT( aMDHelper.ISSET_InputStream );
524 // convert XInputStream to XStorage via the storage factory
525 Sequence< uno::Any > aStorageArgs( 2 );
526 aStorageArgs[0] <<= aMDHelper.InputStream;
527 aStorageArgs[1] <<= embed::ElementModes::READ;
529 xStorage.set( xStorageFact->createInstanceWithArguments( aStorageArgs ),
530 uno::UNO_QUERY_THROW );
534 if( aMDHelper.ISSET_URL )
535 aURL = aMDHelper.URL;
537 catch( const uno::Exception & )
539 DBG_UNHANDLED_EXCEPTION("chart2");
542 if( xStorage.is())
544 attachResource( aURL, rMediaDescriptor );
545 impl_load( rMediaDescriptor, xStorage );
549 void ChartModel::impl_load(
550 const Sequence< beans::PropertyValue >& rMediaDescriptor,
551 const Reference< embed::XStorage >& xStorage )
554 MutexGuard aGuard( m_aModelMutex );
555 m_nInLoad++;
558 Reference< document::XFilter > xFilter( impl_createFilter( rMediaDescriptor ));
560 if( xFilter.is())
562 Reference< document::XImporter > xImporter( xFilter, uno::UNO_QUERY_THROW );
563 xImporter->setTargetDocument( this );
564 Sequence< beans::PropertyValue > aMD( rMediaDescriptor );
565 lcl_addStorageToMediaDescriptor( aMD, xStorage );
567 xFilter->filter( aMD );
568 xFilter.clear();
570 else
572 OSL_FAIL( "loadFromStorage cannot create filter" );
575 if( xStorage.is() )
576 impl_loadGraphics( xStorage );
578 setModified( false );
580 // switchToStorage without notifying listeners (which shouldn't exist at
581 // this time, anyway)
582 m_xStorage = xStorage;
585 MutexGuard aGuard( m_aModelMutex );
586 m_nInLoad--;
590 void ChartModel::impl_loadGraphics(
591 const Reference< embed::XStorage >& xStorage )
595 const Reference< embed::XStorage >& xGraphicsStorage(
596 xStorage->openStorageElement( "Pictures",
597 embed::ElementModes::READ ) );
599 if( xGraphicsStorage.is() )
601 const uno::Sequence< OUString > aElementNames(
602 xGraphicsStorage->getElementNames() );
604 for( OUString const & streamName : aElementNames )
606 if( xGraphicsStorage->isStreamElement( streamName ) )
608 uno::Reference< io::XStream > xElementStream(
609 xGraphicsStorage->openStreamElement(
610 streamName,
611 embed::ElementModes::READ ) );
613 if( xElementStream.is() )
615 std::unique_ptr< SvStream > apIStm(
616 ::utl::UcbStreamHelper::CreateStream(
617 xElementStream, true ) );
619 if (apIStm)
621 SolarMutexGuard aGuard;
622 Graphic aGraphic;
623 if (!GraphicConverter::Import(*apIStm, aGraphic))
625 m_aGraphicObjectVector.emplace_back(aGraphic );
633 catch ( const uno::Exception& )
638 // util::XModifiable
639 void ChartModel::impl_notifyModifiedListeners()
642 MutexGuard aGuard( m_aModelMutex );
643 m_bUpdateNotificationsPending = false;
646 //always notify the view first!
647 ChartViewHelper::setViewToDirtyState( this );
649 ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
650 .getContainer( cppu::UnoType<util::XModifyListener>::get());
651 if( pIC )
653 lang::EventObject aEvent( static_cast< lang::XComponent*>(this) );
654 ::cppu::OInterfaceIteratorHelper aIt( *pIC );
655 while( aIt.hasMoreElements() )
657 uno::Reference< util::XModifyListener > xListener( aIt.next(), uno::UNO_QUERY );
658 if( xListener.is() )
659 xListener->modified( aEvent );
664 sal_Bool SAL_CALL ChartModel::isModified()
666 //@todo guard
667 return m_bModified;
670 void SAL_CALL ChartModel::setModified( sal_Bool bModified )
672 // tdf#141914: allow to set *unmodified* when parent does not allow to set modified
673 if (bModified)
675 // tdf#77007: honor parent's IsEnableSetModified
676 // Check it before LifeTimeGuard, to avoid deadlocking solar mutex and this guard
677 if (auto pParentShell = SfxObjectShell::GetShellFromComponent(getParent());
678 pParentShell && !pParentShell->IsEnableSetModified())
679 return;
682 apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
683 if(!aGuard.startApiCall())//@todo ? is this a long lasting call??
684 return; //behave passive if already disposed or closed or throw exception @todo?
685 m_bModified = bModified;
687 if( m_nControllerLockCount > 0 )
689 m_bUpdateNotificationsPending = true;
690 return;//don't call listeners if controllers are locked
692 aGuard.clear();
694 if(bModified)
695 impl_notifyModifiedListeners();
698 // util::XModifyBroadcaster (base of XModifiable)
699 void SAL_CALL ChartModel::addModifyListener(
700 const uno::Reference< util::XModifyListener >& xListener )
702 if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
703 return; //behave passive if already disposed or closed
705 m_aLifeTimeManager.m_aListenerContainer.addInterface(
706 cppu::UnoType<util::XModifyListener>::get(), xListener );
709 void SAL_CALL ChartModel::removeModifyListener(
710 const uno::Reference< util::XModifyListener >& xListener )
712 if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) )
713 return; //behave passive if already disposed or closed
715 m_aLifeTimeManager.m_aListenerContainer.removeInterface(
716 cppu::UnoType<util::XModifyListener>::get(), xListener );
719 // util::XModifyListener
720 void SAL_CALL ChartModel::modified( const lang::EventObject& rEvenObject)
722 uno::Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(rEvenObject.Source, uno::UNO_QUERY);
723 if (xPivotTableDataProvider.is())
725 lockControllers();
726 uno::Reference<chart2::data::XDataProvider> xDataProvider(xPivotTableDataProvider, uno::UNO_QUERY);
729 uno::Sequence<beans::PropertyValue> aArguments =
730 DataSourceHelper::createArguments("PivotChart", uno::Sequence<sal_Int32>(), true, true, true);
732 Reference<chart2::data::XDataSource> xDataSource(xDataProvider->createDataSource(aArguments));
733 Reference<lang::XMultiServiceFactory> xFactory(getChartTypeManager(), uno::UNO_QUERY);
734 Reference<chart2::XDiagram> xDiagram(getFirstDiagram());
736 DiagramHelper::tTemplateWithServiceName aTemplateAndService = DiagramHelper::getTemplateForDiagram(xDiagram, xFactory);
737 css::uno::Reference<css::chart2::XChartTypeTemplate> xChartTypeTemplate(aTemplateAndService.first);
738 xChartTypeTemplate->changeDiagramData(xDiagram, xDataSource, aArguments);
740 catch (const uno::Exception &)
742 DBG_UNHANDLED_EXCEPTION("chart2");
744 unlockControllers();
747 if (m_nInLoad == 0)
748 setModified(true);
751 // lang::XEventListener (base of util::XModifyListener)
752 void SAL_CALL ChartModel::disposing( const lang::EventObject& )
754 // child was disposed -- should not happen from outside
757 // document::XStorageBasedDocument
758 void SAL_CALL ChartModel::loadFromStorage(
759 const Reference< embed::XStorage >& xStorage,
760 const Sequence< beans::PropertyValue >& rMediaDescriptor )
762 attachResource( OUString(), rMediaDescriptor );
763 impl_load( rMediaDescriptor, xStorage );
766 void SAL_CALL ChartModel::storeToStorage(
767 const Reference< embed::XStorage >& xStorage,
768 const Sequence< beans::PropertyValue >& rMediaDescriptor )
770 impl_store( rMediaDescriptor, xStorage );
773 void SAL_CALL ChartModel::switchToStorage( const Reference< embed::XStorage >& xStorage )
775 m_xStorage = xStorage;
776 impl_notifyStorageChangeListeners();
779 Reference< embed::XStorage > SAL_CALL ChartModel::getDocumentStorage()
781 return m_xStorage;
784 void ChartModel::impl_notifyStorageChangeListeners()
786 ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
787 .getContainer( cppu::UnoType<document::XStorageChangeListener>::get());
788 if( pIC )
790 ::cppu::OInterfaceIteratorHelper aIt( *pIC );
791 while( aIt.hasMoreElements() )
793 uno::Reference< document::XStorageChangeListener > xListener( aIt.next(), uno::UNO_QUERY );
794 if( xListener.is() )
795 xListener->notifyStorageChange( static_cast< ::cppu::OWeakObject* >( this ), m_xStorage );
800 void SAL_CALL ChartModel::addStorageChangeListener( const Reference< document::XStorageChangeListener >& xListener )
802 if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
803 return; //behave passive if already disposed or closed
805 m_aLifeTimeManager.m_aListenerContainer.addInterface(
806 cppu::UnoType<document::XStorageChangeListener>::get(), xListener );
809 void SAL_CALL ChartModel::removeStorageChangeListener( const Reference< document::XStorageChangeListener >& xListener )
811 if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) )
812 return; //behave passive if already disposed or closed
814 m_aLifeTimeManager.m_aListenerContainer.removeInterface(
815 cppu::UnoType<document::XStorageChangeListener>::get(), xListener );
818 } // namespace chart
820 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */