1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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>
64 using namespace ::com::sun::star
;
66 using ::com::sun::star::uno::Reference
;
67 using ::com::sun::star::uno::Sequence
;
68 using ::osl::MutexGuard
;
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
;
85 template< typename T
>
87 const Sequence
< beans::PropertyValue
> & rMediaDescriptor
,
88 const OUString
& rPropName
)
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
));
97 (*pIt
).Value
>>= 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
;
123 Reference
< io::XStream
> xStream(
124 ::ucbhelper::Content( rURL
, Reference
< css::ucb::XCommandEnvironment
>(), comphelper::getProcessComponentContext()).openStream(),
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
;
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");
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
, "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())
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
198 SAL_WARN("chart2", "No FilterName passed in MediaDescriptor" );
200 m_xContext
->getServiceManager()->createInstanceWithContext(
201 "com.sun.star.comp.chart2.XMLFilter", m_xContext
),
202 uno::UNO_QUERY_THROW
);
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()
223 return !m_aResource
.isEmpty();
226 OUString SAL_CALL
ChartModel::getLocation()
228 return impl_g_getLocation();
231 sal_Bool SAL_CALL
ChartModel::isReadonly()
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...
249 throw io::IOException( "document is read only", static_cast< ::cppu::OWeakObject
* >(this));
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() );
272 // create new storage
273 Reference
< embed::XStorage
> xStorage( lcl_createStorage( rURL
, m_xContext
, aReducedMediaDescriptor
));
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
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
));
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");
326 // create new storage
327 Reference
< embed::XStorage
> xStorage( lcl_createStorage( rURL
, m_xContext
, aReducedMediaDescriptor
));
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");
356 OSL_FAIL( "No filter" );
359 setModified( false );
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() )
369 apphelper::MediaDescriptorHelper
aMDHelper(rMediaDescriptor
);
372 xPropSet
->setPropertyValue(
374 uno::Any( aMDHelper
.HierarchicalDocumentName
) );
376 catch ( const uno::Exception
& )
381 void ChartModel::insertDefaultChart()
384 createInternalDataProvider( false );
387 // create default chart
388 Reference
< chart2::XChartTypeTemplate
> xTemplate( impl_createDefaultChartTypeTemplate() );
393 Reference
< chart2::data::XDataSource
> xDataSource( impl_createDefaultData() );
394 Sequence
< beans::PropertyValue
> aParam
;
396 bool bSupportsCategories
= xTemplate
->supportsCategories();
397 if( bSupportsCategories
)
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
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
426 xLegendProperties
->setPropertyValue( "AnchorPosition", uno::Any( chart2::LegendPosition_LINE_START
));
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
443 Reference
< beans::XPropertySet
> xWall( xDiagram
->getWall() );
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() );
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 );
478 void SAL_CALL
ChartModel::initNew()
482 void SAL_CALL
ChartModel::load(
483 const Sequence
< beans::PropertyValue
>& rMediaDescriptor
)
485 Reference
< embed::XStorage
> xStorage
;
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
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
);
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");
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
);
558 Reference
< document::XFilter
> xFilter( impl_createFilter( rMediaDescriptor
));
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
);
572 OSL_FAIL( "loadFromStorage cannot create filter" );
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
);
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(
611 embed::ElementModes::READ
) );
613 if( xElementStream
.is() )
615 std::unique_ptr
< SvStream
> apIStm(
616 ::utl::UcbStreamHelper::CreateStream(
617 xElementStream
, true ) );
621 SolarMutexGuard aGuard
;
623 if (!GraphicConverter::Import(*apIStm
, aGraphic
))
625 m_aGraphicObjectVector
.emplace_back(aGraphic
);
633 catch ( const uno::Exception
& )
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());
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
);
659 xListener
->modified( aEvent
);
664 sal_Bool SAL_CALL
ChartModel::isModified()
670 void SAL_CALL
ChartModel::setModified( sal_Bool bModified
)
672 // tdf#141914: allow to set *unmodified* when parent does not allow to set modified
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())
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
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())
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");
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()
784 void ChartModel::impl_notifyStorageChangeListeners()
786 ::cppu::OInterfaceContainerHelper
* pIC
= m_aLifeTimeManager
.m_aListenerContainer
787 .getContainer( cppu::UnoType
<document::XStorageChangeListener
>::get());
790 ::cppu::OInterfaceIteratorHelper
aIt( *pIC
);
791 while( aIt
.hasMoreElements() )
793 uno::Reference
< document::XStorageChangeListener
> xListener( aIt
.next(), uno::UNO_QUERY
);
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
);
820 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */