36#include <com/sun/star/chart2/LegendPosition.hpp>
37#include <com/sun/star/container/XNameAccess.hpp>
38#include <com/sun/star/document/XExporter.hpp>
39#include <com/sun/star/document/XImporter.hpp>
40#include <com/sun/star/document/XFilter.hpp>
41#include <com/sun/star/drawing/FillStyle.hpp>
42#include <com/sun/star/drawing/LineStyle.hpp>
43#include <com/sun/star/drawing/ProjectionMode.hpp>
44#include <com/sun/star/embed/ElementModes.hpp>
45#include <com/sun/star/embed/XStorage.hpp>
46#include <com/sun/star/embed/StorageFactory.hpp>
47#include <com/sun/star/io/IOException.hpp>
48#include <com/sun/star/lang/XSingleServiceFactory.hpp>
49#include <com/sun/star/uno/XComponentContext.hpp>
50#include <com/sun/star/io/TempFile.hpp>
51#include <com/sun/star/io/XSeekable.hpp>
52#include <com/sun/star/ucb/CommandFailedException.hpp>
53#include <com/sun/star/ucb/ContentCreationException.hpp>
55#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
74using ::com::sun::star::uno::Reference;
75using ::com::sun::star::uno::Sequence;
76using ::osl::MutexGuard;
80struct lcl_PropNameEquals
82 explicit lcl_PropNameEquals( OUString aStrToCompareWith ) :
83 m_aStr(
std::move( aStrToCompareWith ))
85 bool operator() (
const beans::PropertyValue & rProp )
87 return rProp.Name == m_aStr;
95 const Sequence< beans::PropertyValue > & rMediaDescriptor,
96 const OUString & rPropName )
99 if( rMediaDescriptor.hasElements())
101 const beans::PropertyValue * pIt = rMediaDescriptor.getConstArray();
102 const beans::PropertyValue * pEndIt = pIt + + rMediaDescriptor.getLength();
103 pIt = std::find_if( pIt, pEndIt, lcl_PropNameEquals( rPropName ));
105 (*pIt).Value >>= aResult;
110void lcl_addStorageToMediaDescriptor(
111 Sequence< beans::PropertyValue > & rOutMD,
112 const Reference< embed::XStorage > & xStorage )
114 rOutMD.realloc( rOutMD.getLength() + 1 );
115 rOutMD.getArray()[rOutMD.getLength() - 1] = beans::PropertyValue(
116 "Storage", -1,
uno::Any( xStorage ), beans::PropertyState_DIRECT_VALUE );
119Reference< embed::XStorage > lcl_createStorage(
120 const OUString & rURL,
121 const Reference< uno::XComponentContext > & xContext,
122 const Sequence< beans::PropertyValue > & rMediaDescriptor )
125 Reference< embed::XStorage > xStorage;
131 Reference< io::XStream >
xStream(
135 Reference< lang::XSingleServiceFactory > xStorageFact( embed::StorageFactory::create( xContext ) );
136 Sequence< uno::Any > aStorageArgs{
uno::Any(xStream),
137 uno::Any(embed::ElementModes::READWRITE),
140 xStorageFact->createInstanceWithArguments( aStorageArgs ), uno::UNO_QUERY_THROW );
142 catch(
const css::ucb::ContentCreationException&)
146 catch(
const css::ucb::CommandFailedException&)
159Reference< document::XFilter > ChartModel::impl_createFilter(
160 const Sequence< beans::PropertyValue > & rMediaDescriptor )
162 Reference< document::XFilter > xFilter;
165 OUString aFilterName(
166 lcl_getProperty< OUString >( rMediaDescriptor,
"FilterName" ) );
169 if( !aFilterName.isEmpty() )
173 Reference< container::XNameAccess > xFilterFact(
174 m_xContext->getServiceManager()->createInstanceWithContext(
175 "com.sun.star.document.FilterFactory",
m_xContext ),
176 uno::UNO_QUERY_THROW );
177 uno::Any aFilterProps( xFilterFact->getByName( aFilterName ));
178 Sequence< beans::PropertyValue > aProps;
180 if( aFilterProps.hasValue() &&
181 (aFilterProps >>= aProps))
183 OUString aFilterServiceName(
184 lcl_getProperty< OUString >( aProps,
"FilterService" ) );
186 if( !aFilterServiceName.isEmpty())
189 m_xContext->getServiceManager()->createInstanceWithContext(
190 aFilterServiceName,
m_xContext ), uno::UNO_QUERY_THROW );
191 SAL_INFO(
"chart2",
"Filter found for service " << aFilterServiceName );
195 catch(
const uno::Exception & )
199 OSL_ENSURE( xFilter.is(),
"Filter not found via factory" );
205 SAL_WARN(
"chart2",
"No FilterName passed in MediaDescriptor" );
214void SAL_CALL ChartModel::storeSelf(
const Sequence< beans::PropertyValue >& rMediaDescriptor )
220 impl_store( rMediaDescriptor, m_xStorage );
224sal_Bool SAL_CALL ChartModel::hasLocation()
227 return !m_aResource.isEmpty();
230OUString SAL_CALL ChartModel::getLocation()
232 return impl_g_getLocation();
235sal_Bool SAL_CALL ChartModel::isReadonly()
241void SAL_CALL ChartModel::store()
244 if(!aGuard.startApiCall(
true))
247 OUString aLocation = m_aResource;
249 if( aLocation.isEmpty() )
250 throw io::IOException(
"no location specified",
static_cast< ::
cppu::OWeakObject*
>(
this));
253 throw io::IOException(
"document is read only",
static_cast< ::
cppu::OWeakObject*
>(
this));
258 impl_store( m_aMediaDescriptor, m_xStorage );
261void SAL_CALL ChartModel::storeAsURL(
262 const OUString& rURL,
263 const uno::Sequence< beans::PropertyValue >& rMediaDescriptor )
266 if(!aGuard.startApiCall(
true))
270 uno::Sequence< beans::PropertyValue > aReducedMediaDescriptor(
271 aMediaDescriptorHelper.getReducedForModel() );
277 Reference< embed::XStorage > xStorage( lcl_createStorage( rURL,
m_xContext, aReducedMediaDescriptor ));
281 impl_store( aReducedMediaDescriptor, xStorage );
282 attachResource( rURL, aReducedMediaDescriptor );
286void SAL_CALL ChartModel::storeToURL(
287 const OUString& rURL,
288 const uno::Sequence< beans::PropertyValue >& rMediaDescriptor )
291 if(!aGuard.startApiCall(
true))
298 uno::Sequence< beans::PropertyValue > aReducedMediaDescriptor(
299 aMediaDescriptorHelper.getReducedForModel() );
301 if ( rURL ==
"private:stream" )
305 if(
m_xContext.is() && aMediaDescriptorHelper.ISSET_OutputStream )
308 Reference< io::XInputStream > xInputStream(
xStream->getInputStream());
310 Reference< embed::XStorage > xStorage(
314 impl_store( aReducedMediaDescriptor, xStorage );
321 catch(
const uno::Exception & )
329 Reference< embed::XStorage > xStorage( lcl_createStorage( rURL,
m_xContext, aReducedMediaDescriptor ));
332 impl_store( aReducedMediaDescriptor, xStorage );
336void ChartModel::impl_store(
337 const Sequence< beans::PropertyValue >& rMediaDescriptor,
338 const Reference< embed::XStorage > & xStorage )
340 Reference< document::XFilter > xFilter( impl_createFilter( rMediaDescriptor));
341 if( xFilter.is() && xStorage.is())
343 Sequence< beans::PropertyValue > aMD( rMediaDescriptor );
344 lcl_addStorageToMediaDescriptor( aMD, xStorage );
347 Reference< document::XExporter > xExporter( xFilter, uno::UNO_QUERY_THROW );
348 xExporter->setSourceDocument( Reference< lang::XComponent >(
this ));
349 xFilter->filter( aMD );
351 catch(
const uno::Exception & )
358 OSL_FAIL(
"No filter" );
361 setModified(
false );
367 Reference< beans::XPropertySet > xPropSet( m_xParent, uno::UNO_QUERY );
368 if ( hasInternalDataProvider() || !xPropSet.is() )
374 xPropSet->setPropertyValue(
376 uno::Any( aMDHelper.HierarchicalDocumentName ) );
378 catch (
const uno::Exception& )
383void ChartModel::insertDefaultChart()
386 createInternalDataProvider(
false );
395 Reference< chart2::data::XDataSource > xDataSource( impl_createDefaultData() );
396 Sequence< beans::PropertyValue > aParam;
398 bool bSupportsCategories = xTemplate->supportsCategories();
399 if( bSupportsCategories )
401 aParam = { beans::PropertyValue(
"HasCategories", -1,
uno::Any(
true ),
402 beans::PropertyState_DIRECT_VALUE ) };
407 setFirstDiagram( xDiagram );
416 xLegend->setPropertyValue(
"FillStyle",
uno::Any( drawing::FillStyle_NONE ));
417 xLegend->setPropertyValue(
"LineStyle",
uno::Any( drawing::LineStyle_NONE ));
418 xLegend->setPropertyValue(
"LineColor",
uno::Any(
static_cast< sal_Int32
>( 0xb3b3b3 ) ));
419 xLegend->setPropertyValue(
"FillColor",
uno::Any(
static_cast< sal_Int32
>( 0xe6e6e6 ) ) );
422 xLegend->setPropertyValue(
"AnchorPosition",
uno::Any( chart2::LegendPosition_LINE_START ));
424 xDiagram->setLegend( xLegend );
429 xDiagram->setPropertyValue(
"RightAngledAxes",
uno::Any(
true ));
430 xDiagram->setPropertyValue(
"D3DScenePerspective",
uno::Any( drawing::ProjectionMode_PARALLEL ));
437 Reference< beans::XPropertySet > xWall( xDiagram->getWall() );
440 xWall->setPropertyValue(
"LineStyle",
uno::Any( drawing::LineStyle_SOLID ) );
441 xWall->setPropertyValue(
"FillStyle",
uno::Any( drawing::FillStyle_NONE ) );
442 xWall->setPropertyValue(
"LineColor",
uno::Any(
static_cast< sal_Int32
>( 0xb3b3b3 ) ) );
443 xWall->setPropertyValue(
"FillColor",
uno::Any(
static_cast< sal_Int32
>( 0xe6e6e6 ) ) );
445 Reference< beans::XPropertySet > xFloor( xDiagram->getFloor() );
448 xFloor->setPropertyValue(
"LineStyle",
uno::Any( drawing::LineStyle_NONE ) );
449 xFloor->setPropertyValue(
"FillStyle",
uno::Any( drawing::FillStyle_SOLID ) );
450 xFloor->setPropertyValue(
"LineColor",
uno::Any(
static_cast< sal_Int32
>( 0xb3b3b3 ) ) );
451 xFloor->setPropertyValue(
"FillColor",
uno::Any(
static_cast< sal_Int32
>( 0xcccccc ) ) );
456 catch(
const uno::Exception & )
463 catch(
const uno::Exception & )
467 setModified(
false );
472void SAL_CALL ChartModel::initNew()
476void SAL_CALL ChartModel::load(
477 const Sequence< beans::PropertyValue >& rMediaDescriptor )
479 Reference< embed::XStorage > xStorage;
484 if( aMDHelper.ISSET_Storage )
486 xStorage = aMDHelper.Storage;
488 else if( aMDHelper.ISSET_Stream ||
489 aMDHelper.ISSET_InputStream )
491 if( aMDHelper.ISSET_FilterName &&
492 (aMDHelper.FilterName ==
"StarChart 5.0" ||
493 aMDHelper.FilterName ==
"StarChart 4.0" ||
494 aMDHelper.FilterName ==
"StarChart 3.0" ))
496 attachResource( aMDHelper.URL, rMediaDescriptor );
497 impl_load( rMediaDescriptor,
nullptr );
502 Reference< lang::XSingleServiceFactory > xStorageFact( embed::StorageFactory::create(
m_xContext) );
504 if( aMDHelper.ISSET_Stream )
507 Sequence< uno::Any > aStorageArgs{
uno::Any(aMDHelper.Stream),
509 uno::Any(embed::ElementModes::READ) };
511 xStorage.set( xStorageFact->createInstanceWithArguments( aStorageArgs ),
512 uno::UNO_QUERY_THROW );
516 OSL_ASSERT( aMDHelper.ISSET_InputStream );
518 Sequence< uno::Any > aStorageArgs{
uno::Any(aMDHelper.InputStream),
519 uno::Any(embed::ElementModes::READ) };
521 xStorage.set( xStorageFact->createInstanceWithArguments( aStorageArgs ),
522 uno::UNO_QUERY_THROW );
526 if( aMDHelper.ISSET_URL )
527 aURL = aMDHelper.URL;
529 catch(
const uno::Exception & )
536 attachResource( aURL, rMediaDescriptor );
537 impl_load( rMediaDescriptor, xStorage );
541void ChartModel::impl_load(
542 const Sequence< beans::PropertyValue >& rMediaDescriptor,
543 const Reference< embed::XStorage >& xStorage )
546 MutexGuard aGuard( m_aModelMutex );
550 Reference< document::XFilter > xFilter( impl_createFilter( rMediaDescriptor ));
554 Reference< document::XImporter > xImporter( xFilter, uno::UNO_QUERY_THROW );
555 xImporter->setTargetDocument(
this );
556 Sequence< beans::PropertyValue > aMD( rMediaDescriptor );
557 lcl_addStorageToMediaDescriptor( aMD, xStorage );
559 xFilter->filter( aMD );
564 OSL_FAIL(
"loadFromStorage cannot create filter" );
568 impl_loadGraphics( xStorage );
570 setModified(
false );
574 m_xStorage = xStorage;
577 MutexGuard aGuard( m_aModelMutex );
582void ChartModel::impl_loadGraphics(
583 const Reference< embed::XStorage >& xStorage )
587 const Reference< embed::XStorage >& xGraphicsStorage(
588 xStorage->openStorageElement(
"Pictures",
589 embed::ElementModes::READ ) );
591 if( xGraphicsStorage.is() )
593 const uno::Sequence< OUString > aElementNames(
594 xGraphicsStorage->getElementNames() );
596 for( OUString
const & streamName : aElementNames )
598 if( xGraphicsStorage->isStreamElement( streamName ) )
600 uno::Reference< io::XStream > xElementStream(
601 xGraphicsStorage->openStreamElement(
603 embed::ElementModes::READ ) );
605 if( xElementStream.is() )
607 std::unique_ptr< SvStream > apIStm(
609 xElementStream,
true ) );
617 m_aGraphicObjectVector.emplace_back(aGraphic );
625 catch (
const uno::Exception& )
631void ChartModel::impl_notifyModifiedListeners()
634 MutexGuard aGuard( m_aModelMutex );
635 m_bUpdateNotificationsPending =
false;
641 std::unique_lock aGuard(m_aLifeTimeManager.m_aAccessMutex);
642 if( m_aLifeTimeManager.m_aModifyListeners.getLength(aGuard) )
644 lang::EventObject
aEvent(
static_cast< lang::XComponent*
>(
this) );
645 m_aLifeTimeManager.m_aModifyListeners.notifyEach(aGuard, &util::XModifyListener::modified, aEvent);
649sal_Bool SAL_CALL ChartModel::isModified()
655void SAL_CALL ChartModel::setModified(
sal_Bool bModified )
668 if(!aGuard.startApiCall())
670 m_bModified = bModified;
672 if( m_nControllerLockCount > 0 )
674 m_bUpdateNotificationsPending =
true;
680 impl_notifyModifiedListeners();
684void SAL_CALL ChartModel::addModifyListener(
685 const uno::Reference< util::XModifyListener >& xListener )
687 if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
690 std::unique_lock aGuard(m_aLifeTimeManager.m_aAccessMutex);
691 m_aLifeTimeManager.m_aModifyListeners.addInterface( aGuard, xListener );
694void SAL_CALL ChartModel::removeModifyListener(
695 const uno::Reference< util::XModifyListener >& xListener )
697 if( m_aLifeTimeManager.impl_isDisposedOrClosed(
false) )
700 std::unique_lock aGuard(m_aLifeTimeManager.m_aAccessMutex);
701 m_aLifeTimeManager.m_aModifyListeners.removeInterface( aGuard, xListener );
705void SAL_CALL ChartModel::modified(
const lang::EventObject& rEvenObject)
707 uno::Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(rEvenObject.Source, uno::UNO_QUERY);
708 if (xPivotTableDataProvider.is())
711 uno::Reference<chart2::data::XDataProvider> xDataProvider(xPivotTableDataProvider, uno::UNO_QUERY);
714 uno::Sequence<beans::PropertyValue>
aArguments =
717 Reference<chart2::data::XDataSource> xDataSource(xDataProvider->createDataSource(aArguments));
721 Diagram::tTemplateWithServiceName aTemplateAndService = xDiagram->getTemplate(xChartTypeManager);
722 aTemplateAndService.xChartTypeTemplate->changeDiagramData(xDiagram, xDataSource, aArguments);
724 catch (
const uno::Exception &)
736void SAL_CALL ChartModel::disposing(
const lang::EventObject& )
742void SAL_CALL ChartModel::loadFromStorage(
743 const Reference< embed::XStorage >& xStorage,
744 const Sequence< beans::PropertyValue >& rMediaDescriptor )
746 attachResource( OUString(), rMediaDescriptor );
747 impl_load( rMediaDescriptor, xStorage );
750void SAL_CALL ChartModel::storeToStorage(
751 const Reference< embed::XStorage >& xStorage,
752 const Sequence< beans::PropertyValue >& rMediaDescriptor )
754 impl_store( rMediaDescriptor, xStorage );
757void SAL_CALL ChartModel::switchToStorage(
const Reference< embed::XStorage >& xStorage )
759 m_xStorage = xStorage;
760 impl_notifyStorageChangeListeners();
763Reference< embed::XStorage > SAL_CALL ChartModel::getDocumentStorage()
768void ChartModel::impl_notifyStorageChangeListeners()
770 std::unique_lock aGuard(m_aLifeTimeManager.m_aAccessMutex);
771 if( m_aLifeTimeManager.m_aStorageChangeListeners.getLength(aGuard) )
773 m_aLifeTimeManager.m_aStorageChangeListeners.forEach(aGuard,
774 [
this](
const uno::Reference<document::XStorageChangeListener>& l)
776 l->notifyStorageChange(
static_cast< ::
cppu::OWeakObject*
>(
this ), m_xStorage );
781void SAL_CALL ChartModel::addStorageChangeListener(
const Reference< document::XStorageChangeListener >& xListener )
783 if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
786 std::unique_lock aGuard(m_aLifeTimeManager.m_aAccessMutex);
787 m_aLifeTimeManager.m_aStorageChangeListeners.addInterface( aGuard, xListener );
790void SAL_CALL ChartModel::removeStorageChangeListener(
const Reference< document::XStorageChangeListener >& xListener )
792 if( m_aLifeTimeManager.impl_isDisposedOrClosed(
false) )
795 std::unique_lock aGuard(m_aLifeTimeManager.m_aAccessMutex);
796 m_aLifeTimeManager.m_aStorageChangeListeners.removeInterface(aGuard, xListener );
Reference< uno::XComponentContext > m_xContext
static bool GetMathLayoutRTL()
static ErrCode Import(SvStream &rIStm, Graphic &rGraphic, ConvertDataFormat nFormat=ConvertDataFormat::Unknown)
static SfxObjectShell * GetShellFromComponent(const css::uno::Reference< css::uno::XInterface > &xComp)
bool IsEnableSetModified() const
static rtl::Reference< ::chart::BaseCoordinateSystem > getCoordinateSystemByIndex(const rtl::Reference< ::chart::Diagram > &xDiagram, sal_Int32 nIndex)
static void setRTLAxisLayout(const rtl::Reference< ::chart::BaseCoordinateSystem > &xCooSys)
static bool setIncludeHiddenCells(bool bIncludeHiddenCells, ChartModel &rModel)
static void setViewToDirtyState(const rtl::Reference<::chart::ChartModel > &xChartModel)
static css::uno::Sequence< css::beans::PropertyValue > createArguments(bool bUseColumns, bool bFirstCellAsLabel, bool bHasCategories)
static css::uno::Reference< css::embed::XStorage > GetStorageFromStream(const css::uno::Reference< css::io::XStream > &xStream, sal_Int32 nStorageMode=css::embed::ElementModes::READWRITE, const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
static void CopyInputToOutput(const css::uno::Reference< css::io::XInputStream > &xInput, const css::uno::Reference< css::io::XOutputStream > &xOutput)
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
#define DBG_UNHANDLED_EXCEPTION(...)
Sequence< PropertyValue > aArguments
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
@ ThreeDLookScheme_Realistic
Reference< XComponentContext > getProcessComponentContext()