Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : :
21 : : #include "ChartModel.hxx"
22 : : #include "MediaDescriptorHelper.hxx"
23 : : #include "ChartDebugTrace.hxx"
24 : : #include "macros.hxx"
25 : : #include "ChartViewHelper.hxx"
26 : : #include "ChartModelHelper.hxx"
27 : : #include "AxisHelper.hxx"
28 : : #include "ThreeDHelper.hxx"
29 : :
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/lang/XSingleServiceFactory.hpp>
41 : : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
42 : : #include <com/sun/star/uno/XComponentContext.hpp>
43 : : #include <com/sun/star/io/XSeekable.hpp>
44 : :
45 : : #include <ucbhelper/content.hxx>
46 : : #include <unotools/ucbstreamhelper.hxx>
47 : : #include <vcl/cvtgrf.hxx>
48 : : #include <comphelper/storagehelper.hxx>
49 : : #include <vcl/svapp.hxx>
50 : :
51 : : #include <algorithm>
52 : : #include <functional>
53 : :
54 : : using namespace ::com::sun::star;
55 : :
56 : : using ::com::sun::star::uno::Reference;
57 : : using ::com::sun::star::uno::Sequence;
58 : : using ::rtl::OUString;
59 : : using ::osl::MutexGuard;
60 : :
61 : : namespace
62 : : {
63 : 126 : struct lcl_PropNameEquals : public ::std::unary_function< beans::PropertyValue, bool >
64 : : {
65 : 42 : lcl_PropNameEquals( const OUString & rStrToCompareWith ) :
66 : 42 : m_aStr( rStrToCompareWith )
67 : 42 : {}
68 : 171 : bool operator() ( const beans::PropertyValue & rProp )
69 : : {
70 : 171 : return rProp.Name.equals( m_aStr );
71 : : }
72 : : private:
73 : : OUString m_aStr;
74 : : };
75 : :
76 : : template< typename T >
77 : 42 : T lcl_getProperty(
78 : : const Sequence< beans::PropertyValue > & rMediaDescriptor,
79 : : const OUString & rPropName )
80 : : {
81 : 42 : T aResult;
82 [ + - ]: 42 : if( rMediaDescriptor.getLength())
83 : : {
84 : 42 : OUString aPropName( rPropName );
85 : 42 : const beans::PropertyValue * pIt = rMediaDescriptor.getConstArray();
86 : 42 : const beans::PropertyValue * pEndIt = pIt + + rMediaDescriptor.getLength();
87 [ + - ]: 42 : pIt = ::std::find_if( pIt, pEndIt, lcl_PropNameEquals( aPropName ));
88 [ + - ]: 42 : if( pIt != pEndIt )
89 : 42 : (*pIt).Value >>= aResult;
90 : : }
91 : 42 : return aResult;
92 : : }
93 : :
94 : 21 : void lcl_addStorageToMediaDescriptor(
95 : : Sequence< beans::PropertyValue > & rOutMD,
96 : : const Reference< embed::XStorage > & xStorage )
97 : : {
98 : 21 : rOutMD.realloc( rOutMD.getLength() + 1 );
99 [ + - ]: 21 : rOutMD[rOutMD.getLength() - 1] = beans::PropertyValue(
100 [ + - ][ + - ]: 42 : C2U("Storage"), -1, uno::makeAny( xStorage ), beans::PropertyState_DIRECT_VALUE );
101 : 21 : }
102 : :
103 : 0 : Reference< embed::XStorage > lcl_createStorage(
104 : : const OUString & rURL,
105 : : const Reference< uno::XComponentContext > & xContext,
106 : : const Sequence< beans::PropertyValue > & rMediaDescriptor )
107 : : {
108 : : // create new storage
109 : 0 : Reference< embed::XStorage > xStorage;
110 [ # # ]: 0 : if( !xContext.is())
111 : 0 : return xStorage;
112 : :
113 : : try
114 : : {
115 : : Reference< io::XStream > xStream(
116 : : ::ucbhelper::Content( rURL, Reference< ::com::sun::star::ucb::XCommandEnvironment >()).openStream(),
117 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
[ # # ][ # # ]
118 : :
119 : : Reference< lang::XSingleServiceFactory > xStorageFact(
120 [ # # ][ # # ]: 0 : xContext->getServiceManager()->createInstanceWithContext(
[ # # ]
121 : : C2U("com.sun.star.embed.StorageFactory"),
122 : 0 : xContext ),
123 [ # # ][ # # ]: 0 : uno::UNO_QUERY_THROW );
[ # # ]
124 [ # # ]: 0 : Sequence< uno::Any > aStorageArgs( 3 );
125 [ # # ][ # # ]: 0 : aStorageArgs[0] <<= xStream;
126 [ # # ][ # # ]: 0 : aStorageArgs[1] <<= embed::ElementModes::READWRITE;
127 [ # # ][ # # ]: 0 : aStorageArgs[2] <<= rMediaDescriptor;
128 : : xStorage.set(
129 [ # # ][ # # ]: 0 : xStorageFact->createInstanceWithArguments( aStorageArgs ), uno::UNO_QUERY_THROW );
[ # # ]
130 [ # # ][ # # ]: 0 : OSL_ENSURE( xStorage.is(), "No Storage" );
131 : : }
132 [ # # ]: 0 : catch( const ::com::sun::star::ucb::ContentCreationException & rEx )
133 : : {
134 : : ASSERT_EXCEPTION( rEx );
135 : : }
136 : :
137 : 0 : return xStorage;
138 : : }
139 : :
140 : : } // anonymous namespace
141 : :
142 : : namespace chart
143 : : {
144 : :
145 : 21 : Reference< document::XFilter > ChartModel::impl_createFilter(
146 : : const Sequence< beans::PropertyValue > & rMediaDescriptor )
147 : : {
148 : 21 : Reference< document::XFilter > xFilter;
149 : :
150 : : // find FilterName in MediaDescriptor
151 : : OUString aFilterName(
152 [ + - ][ + - ]: 21 : lcl_getProperty< OUString >( rMediaDescriptor, OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ))));
153 : :
154 : : // if FilterName was found, get Filter from factory
155 [ + - ]: 21 : if( !aFilterName.isEmpty() )
156 : : {
157 : : try
158 : : {
159 : : Reference< container::XNameAccess > xFilterFact(
160 [ + - ][ + - ]: 42 : m_xContext->getServiceManager()->createInstanceWithContext(
[ + - ]
161 : 21 : C2U( "com.sun.star.document.FilterFactory" ), m_xContext ),
162 [ + - ][ + - ]: 21 : uno::UNO_QUERY_THROW );
[ + - ]
163 [ + - ][ + - ]: 21 : uno::Any aFilterProps( xFilterFact->getByName( aFilterName ));
164 [ + - ]: 21 : Sequence< beans::PropertyValue > aProps;
165 : :
166 [ + - ][ + - ]: 42 : if( aFilterProps.hasValue() &&
[ + - ]
167 [ + - ]: 21 : (aFilterProps >>= aProps))
168 : : {
169 : : OUString aFilterServiceName(
170 [ + - ][ + - ]: 21 : lcl_getProperty< OUString >( aProps, OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterService" ))));
171 : :
172 [ + - ]: 21 : if( !aFilterServiceName.isEmpty())
173 : : {
174 : : xFilter.set(
175 [ + - ][ + - ]: 42 : m_xContext->getServiceManager()->createInstanceWithContext(
[ + - ]
176 [ + - ][ + - ]: 21 : aFilterServiceName, m_xContext ), uno::UNO_QUERY_THROW );
177 : : OSL_TRACE( "Filter found for service %s", U2C( aFilterServiceName ));
178 : 21 : }
179 [ + - ][ # # ]: 21 : }
180 : : }
181 [ # # ]: 0 : catch( const uno::Exception & ex )
182 : : {
183 : : ASSERT_EXCEPTION( ex );
184 : : }
185 : : OSL_ENSURE( xFilter.is(), "Filter not found via factory" );
186 : : }
187 : :
188 : : // fall-back: create XML-Filter
189 [ - + ]: 21 : if( ! xFilter.is())
190 : : {
191 : : OSL_TRACE( "No FilterName passed in MediaDescriptor" );
192 : : xFilter.set(
193 [ # # ][ # # ]: 0 : m_xContext->getServiceManager()->createInstanceWithContext(
[ # # ]
194 : 0 : C2U("com.sun.star.comp.chart2.XMLFilter"), m_xContext ),
195 [ # # ][ # # ]: 0 : uno::UNO_QUERY_THROW );
[ # # ]
196 : : }
197 : :
198 : 21 : return xFilter;
199 : : }
200 : :
201 : : //-----------------------------------------------------------------
202 : : // frame::XStorable2
203 : : //-----------------------------------------------------------------
204 : :
205 : 0 : void SAL_CALL ChartModel::storeSelf( const Sequence< beans::PropertyValue >& rMediaDescriptor )
206 : : throw (lang::IllegalArgumentException,
207 : : io::IOException,
208 : : uno::RuntimeException)
209 : : {
210 : : // only some parameters are allowed (see also SfxBaseModel)
211 : : // "VersionComment", "Author", "InteractionHandler", "StatusIndicator"
212 : : // However, they are ignored here. They would become interesting when
213 : : // charts support a standalone format again.
214 : 0 : impl_store( rMediaDescriptor, m_xStorage );
215 : 0 : }
216 : :
217 : : //-----------------------------------------------------------------
218 : : // frame::XStorable (base of XStorable2)
219 : : //-----------------------------------------------------------------
220 : 0 : sal_Bool SAL_CALL ChartModel::hasLocation()
221 : : throw(uno::RuntimeException)
222 : : {
223 : : //@todo guard
224 : 0 : return !m_aResource.isEmpty();
225 : : }
226 : :
227 : 0 : ::rtl::OUString SAL_CALL ChartModel::getLocation()
228 : : throw(uno::RuntimeException)
229 : : {
230 : 0 : return impl_g_getLocation();
231 : : }
232 : :
233 : 1578 : sal_Bool SAL_CALL ChartModel::isReadonly()
234 : : throw(uno::RuntimeException)
235 : : {
236 : : //@todo guard
237 : 1578 : return m_bReadOnly;
238 : : }
239 : :
240 : 0 : void SAL_CALL ChartModel::store()
241 : : throw(io::IOException,
242 : : uno::RuntimeException)
243 : : {
244 [ # # ]: 0 : apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
245 [ # # ][ # # ]: 0 : if(!aGuard.startApiCall(sal_True)) //start LongLastingCall
246 : 0 : return; //behave passive if already disposed or closed or throw exception @todo?
247 : :
248 : 0 : ::rtl::OUString aLocation = m_aResource;
249 : :
250 [ # # ]: 0 : if( aLocation.isEmpty() )
251 [ # # ][ # # ]: 0 : throw io::IOException( C2U( "no location specified" ), static_cast< ::cppu::OWeakObject* >(this));
[ # # ]
252 : : //@todo check whether aLocation is something like private:factory...
253 [ # # ]: 0 : if( m_bReadOnly )
254 [ # # ][ # # ]: 0 : throw io::IOException( C2U( "document is read only" ), static_cast< ::cppu::OWeakObject* >(this));
[ # # ]
255 : :
256 [ # # ]: 0 : aGuard.clear();
257 : :
258 : : // store
259 [ # # ][ # # ]: 0 : impl_store( m_aMediaDescriptor, m_xStorage );
[ # # ]
260 : : }
261 : :
262 : 0 : void SAL_CALL ChartModel::storeAsURL(
263 : : const ::rtl::OUString& rURL,
264 : : const uno::Sequence< beans::PropertyValue >& rMediaDescriptor )
265 : : throw(io::IOException, uno::RuntimeException)
266 : : {
267 [ # # ]: 0 : apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
268 [ # # ][ # # ]: 0 : if(!aGuard.startApiCall(sal_True)) //start LongLastingCall
269 : 0 : return; //behave passive if already disposed or closed or throw exception @todo?
270 : :
271 [ # # ]: 0 : apphelper::MediaDescriptorHelper aMediaDescriptorHelper(rMediaDescriptor);
272 : : uno::Sequence< beans::PropertyValue > aReducedMediaDescriptor(
273 [ # # ]: 0 : aMediaDescriptorHelper.getReducedForModel() );
274 : :
275 : 0 : m_bReadOnly = sal_False;
276 [ # # ]: 0 : aGuard.clear();
277 : :
278 : : // create new storage
279 [ # # ]: 0 : Reference< embed::XStorage > xStorage( lcl_createStorage( rURL, m_xContext, aReducedMediaDescriptor ));
280 : :
281 [ # # ]: 0 : if( xStorage.is())
282 : : {
283 [ # # ]: 0 : impl_store( aReducedMediaDescriptor, xStorage );
284 [ # # ]: 0 : attachResource( rURL, aReducedMediaDescriptor );
285 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
286 : : }
287 : :
288 : 0 : void SAL_CALL ChartModel::storeToURL(
289 : : const ::rtl::OUString& rURL,
290 : : const uno::Sequence< beans::PropertyValue >& rMediaDescriptor )
291 : : throw(io::IOException,
292 : : uno::RuntimeException)
293 : : {
294 [ # # ]: 0 : apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
295 [ # # ][ # # ]: 0 : if(!aGuard.startApiCall(sal_True)) //start LongLastingCall
296 : 0 : return; //behave passive if already disposed or closed or throw exception @todo?
297 : : //do not change the internal state of the document here
298 : : //...
299 : :
300 [ # # ]: 0 : aGuard.clear();
301 : :
302 [ # # ]: 0 : apphelper::MediaDescriptorHelper aMediaDescriptorHelper(rMediaDescriptor);
303 : : uno::Sequence< beans::PropertyValue > aReducedMediaDescriptor(
304 [ # # ]: 0 : aMediaDescriptorHelper.getReducedForModel() );
305 : :
306 [ # # ]: 0 : if ( rURL == "private:stream" )
307 : : {
308 : : try
309 : : {
310 [ # # ][ # # ]: 0 : if( m_xContext.is() && aMediaDescriptorHelper.ISSET_OutputStream )
[ # # ]
311 : : {
312 [ # # ][ # # ]: 0 : Reference< lang::XMultiServiceFactory > xFact( m_xContext->getServiceManager(), uno::UNO_QUERY_THROW );
[ # # ]
313 : : Reference< io::XStream > xStream(
314 [ # # ][ # # ]: 0 : xFact->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.TempFile"))), uno::UNO_QUERY_THROW );
[ # # ][ # # ]
315 [ # # ][ # # ]: 0 : Reference< io::XInputStream > xInputStream( xStream->getInputStream());
316 : :
317 : : Reference< embed::XStorage > xStorage(
318 [ # # ]: 0 : ::comphelper::OStorageHelper::GetStorageFromStream( xStream, embed::ElementModes::READWRITE, xFact ));
319 [ # # ]: 0 : if( xStorage.is())
320 : : {
321 [ # # ]: 0 : impl_store( aReducedMediaDescriptor, xStorage );
322 : :
323 [ # # ]: 0 : Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY_THROW );
324 [ # # ][ # # ]: 0 : xSeekable->seek( 0 );
325 [ # # ]: 0 : ::comphelper::OStorageHelper::CopyInputToOutput( xInputStream, aMediaDescriptorHelper.OutputStream );
326 [ # # ]: 0 : }
327 : : }
328 : : }
329 [ # # ]: 0 : catch( const uno::Exception & ex )
330 : : {
331 : : ASSERT_EXCEPTION( ex );
332 : : }
333 : : }
334 : : else
335 : : {
336 : : // create new storage
337 [ # # ]: 0 : Reference< embed::XStorage > xStorage( lcl_createStorage( rURL, m_xContext, aReducedMediaDescriptor ));
338 : :
339 [ # # ]: 0 : if( xStorage.is())
340 [ # # ]: 0 : impl_store( aReducedMediaDescriptor, xStorage );
341 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
342 : : }
343 : :
344 : 15 : void ChartModel::impl_store(
345 : : const Sequence< beans::PropertyValue >& rMediaDescriptor,
346 : : const Reference< embed::XStorage > & xStorage )
347 : : {
348 [ + - ]: 15 : Reference< document::XFilter > xFilter( impl_createFilter( rMediaDescriptor));
349 [ + - ][ + - ]: 15 : if( xFilter.is() && xStorage.is())
[ + - ]
350 : : {
351 [ + - ]: 15 : Sequence< beans::PropertyValue > aMD( rMediaDescriptor );
352 [ + - ]: 15 : lcl_addStorageToMediaDescriptor( aMD, xStorage );
353 : : try
354 : : {
355 [ + - ]: 15 : Reference< document::XExporter > xExporter( xFilter, uno::UNO_QUERY_THROW );
356 [ + - ][ + - ]: 15 : xExporter->setSourceDocument( Reference< lang::XComponent >( this ));
[ + - ]
357 [ + - ][ # # ]: 15 : xFilter->filter( aMD );
[ + - ]
358 : : }
359 [ # # ]: 0 : catch( const uno::Exception & ex )
360 : : {
361 : : ASSERT_EXCEPTION( ex );
362 [ + - ]: 15 : }
363 : : }
364 : : else
365 : : {
366 : : OSL_FAIL( "No filter" );
367 : : }
368 : :
369 [ + - ]: 15 : setModified( sal_False );
370 : :
371 : : //#i66865#
372 : : //for data change notification during chart is not loaded:
373 : : //notify parent data provider after saving thus the parent document can store
374 : : //the ranges for which a load and update of the chart will be necessary
375 [ + - ]: 15 : Reference< beans::XPropertySet > xPropSet( m_xParent, uno::UNO_QUERY );
376 [ + - ][ + + ]: 15 : if ( !hasInternalDataProvider() && xPropSet.is() )
[ + - ][ + + ]
377 : : {
378 [ + - ]: 7 : apphelper::MediaDescriptorHelper aMDHelper(rMediaDescriptor);
379 : : try
380 : : {
381 [ + - ]: 7 : xPropSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "SavedObject" )),
382 [ + - ][ + - ]: 7 : uno::makeAny( aMDHelper.HierarchicalDocumentName ) );
[ + - ][ # # ]
383 : : }
384 [ # # ]: 0 : catch ( const uno::Exception& )
385 : : {
386 [ + - ]: 7 : }
387 : 15 : }
388 : 15 : }
389 : :
390 : : //-----------------------------------------------------------------
391 : : // frame::XLoadable
392 : : //-----------------------------------------------------------------
393 : 50 : void SAL_CALL ChartModel::initNew()
394 : : throw (frame::DoubleInitializationException,
395 : : io::IOException,
396 : : uno::Exception,
397 : : uno::RuntimeException)
398 : : {
399 : 50 : lockControllers();
400 : 50 : createInternalDataProvider( sal_False );
401 : : try
402 : : {
403 : : // create default chart
404 [ + - ]: 50 : Reference< chart2::XChartTypeTemplate > xTemplate( impl_createDefaultChartTypeTemplate() );
405 [ + - ]: 50 : if( xTemplate.is())
406 : : {
407 : : try
408 : : {
409 [ + - ]: 50 : Reference< chart2::data::XDataSource > xDataSource( impl_createDefaultData() );
410 [ + - ]: 50 : Sequence< beans::PropertyValue > aParam;
411 : :
412 [ + - ][ + - ]: 50 : bool bSupportsCategories = xTemplate->supportsCategories();
413 [ + - ]: 50 : if( bSupportsCategories )
414 : : {
415 [ + - ]: 50 : aParam.realloc( 1 );
416 [ + - ]: 50 : aParam[0] = beans::PropertyValue( C2U("HasCategories"), -1, uno::makeAny( true ),
417 [ + - ][ + - ]: 100 : beans::PropertyState_DIRECT_VALUE );
418 : : }
419 : :
420 [ + - ][ + - ]: 50 : Reference< chart2::XDiagram > xDiagram( xTemplate->createDiagramByDataSource( xDataSource, aParam ) );
421 : :
422 [ + - ]: 50 : setFirstDiagram( xDiagram );
423 : :
424 [ + - ][ + - ]: 50 : bool bIsRTL = Application::GetSettings().GetLayoutRTL();
425 : : //reverse x axis for rtl charts
426 [ - + ]: 50 : if( bIsRTL )
427 [ # # ][ # # ]: 0 : AxisHelper::setRTLAxisLayout( AxisHelper::getCoordinateSystemByIndex( xDiagram, 0 ) );
428 : :
429 : : // create and attach legend
430 : : Reference< chart2::XLegend > xLegend(
431 [ + - ][ + - ]: 100 : m_xContext->getServiceManager()->createInstanceWithContext(
[ + - ]
432 [ + - ][ + - ]: 50 : C2U( "com.sun.star.chart2.Legend" ), m_xContext ), uno::UNO_QUERY_THROW );
[ + - ]
433 [ + - ]: 50 : Reference< beans::XPropertySet > xLegendProperties( xLegend, uno::UNO_QUERY );
434 [ + - ]: 50 : if( xLegendProperties.is() )
435 : : {
436 [ + - ][ + - ]: 50 : xLegendProperties->setPropertyValue( C2U( "FillStyle" ), uno::makeAny( drawing::FillStyle_NONE ));
[ + - ][ + - ]
437 [ + - ][ + - ]: 50 : xLegendProperties->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_NONE ));
[ + - ][ + - ]
438 [ + - ][ + - ]: 50 : xLegendProperties->setPropertyValue( C2U( "LineColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) )); // gray30
[ + - ][ + - ]
439 [ + - ][ + - ]: 50 : xLegendProperties->setPropertyValue( C2U( "FillColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xe6e6e6 ) ) ); // gray10
[ + - ][ + - ]
440 : :
441 [ - + ]: 50 : if( bIsRTL )
442 [ # # ][ # # ]: 0 : xLegendProperties->setPropertyValue( C2U( "AnchorPosition" ), uno::makeAny( chart2::LegendPosition_LINE_START ));
[ # # ][ # # ]
443 : : }
444 [ + - ]: 50 : if(xDiagram.is())
445 [ + - ][ + - ]: 50 : xDiagram->setLegend( xLegend );
446 : :
447 : : // set simple 3D look
448 [ + - ]: 50 : Reference< beans::XPropertySet > xDiagramProperties( xDiagram, uno::UNO_QUERY );
449 [ + - ]: 50 : if( xDiagramProperties.is() )
450 : : {
451 [ + - ][ + - ]: 50 : xDiagramProperties->setPropertyValue( C2U("RightAngledAxes"), uno::makeAny( sal_True ));
[ + - ][ + - ]
452 [ + - ][ + - ]: 50 : xDiagramProperties->setPropertyValue( C2U("D3DScenePerspective"), uno::makeAny( drawing::ProjectionMode_PARALLEL ));
[ + - ][ + - ]
453 [ + - ]: 50 : ThreeDHelper::setScheme( xDiagram, ThreeDLookScheme_Realistic );
454 : : }
455 : :
456 : : //set some new 'defaults' for wall and floor
457 [ + - ]: 50 : if( xDiagram.is() )
458 : : {
459 [ + - ][ + - ]: 50 : Reference< beans::XPropertySet > xWall( xDiagram->getWall() );
460 [ + - ]: 50 : if( xWall.is() )
461 : : {
462 [ + - ][ + - ]: 50 : xWall->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_SOLID ) );
[ + - ][ + - ]
463 [ + - ][ + - ]: 50 : xWall->setPropertyValue( C2U( "FillStyle" ), uno::makeAny( drawing::FillStyle_NONE ) );
[ + - ][ + - ]
464 [ + - ][ + - ]: 50 : xWall->setPropertyValue( C2U( "LineColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) ) ); // gray30
[ + - ][ + - ]
465 [ + - ][ + - ]: 50 : xWall->setPropertyValue( C2U( "FillColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xe6e6e6 ) ) ); // gray10
[ + - ][ + - ]
466 : : }
467 [ + - ][ + - ]: 50 : Reference< beans::XPropertySet > xFloor( xDiagram->getFloor() );
468 [ + - ]: 50 : if( xFloor.is() )
469 : : {
470 [ + - ][ + - ]: 50 : xFloor->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_NONE ) );
[ + - ][ + - ]
471 [ + - ][ + - ]: 50 : xFloor->setPropertyValue( C2U( "FillStyle" ), uno::makeAny( drawing::FillStyle_SOLID ) );
[ + - ][ + - ]
472 [ + - ][ + - ]: 50 : xFloor->setPropertyValue( C2U( "LineColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) ) ); // gray30
[ + - ][ + - ]
473 [ + - ][ + - ]: 50 : xFloor->setPropertyValue( C2U( "FillColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xcccccc ) ) ); // gray20
[ + - ][ + - ]
474 : 50 : }
475 : :
476 [ + - ][ # # ]: 50 : }
477 : : }
478 [ # # ]: 0 : catch( const uno::Exception & ex )
479 : : {
480 : : ASSERT_EXCEPTION( ex );
481 : : }
482 : : }
483 [ + - ][ + - ]: 50 : ChartModelHelper::setIncludeHiddenCells( false, this );
[ # # ]
484 : : }
485 : 0 : catch( const uno::Exception & ex )
486 : : {
487 : : ASSERT_EXCEPTION( ex );
488 : : }
489 : 50 : setModified( sal_False );
490 : 50 : unlockControllers();
491 : :
492 : : #if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL
493 : : OSL_TRACE( "ChartModel::initNew: Showing ChartDocument structure" );
494 : : OSL_TRACE( "----------------------------------------------------" );
495 : : ::chart::debug::ChartDebugTraceDocument( Reference< chart2::XChartDocument >( this ));
496 : : #endif
497 : 50 : }
498 : :
499 : 6 : void SAL_CALL ChartModel::load(
500 : : const Sequence< beans::PropertyValue >& rMediaDescriptor )
501 : : throw (frame::DoubleInitializationException,
502 : : io::IOException,
503 : : uno::Exception,
504 : : uno::RuntimeException)
505 : : {
506 : 6 : Reference< embed::XStorage > xStorage;
507 : 6 : OUString aURL;
508 : : try
509 : : {
510 [ + - ]: 6 : apphelper::MediaDescriptorHelper aMDHelper( rMediaDescriptor );
511 [ - + ]: 6 : if( aMDHelper.ISSET_Storage )
512 : : {
513 [ # # ]: 0 : xStorage = aMDHelper.Storage;
514 : : }
515 [ - + ][ # # ]: 6 : else if( aMDHelper.ISSET_Stream ||
516 : : aMDHelper.ISSET_InputStream )
517 : : {
518 [ + - + - : 30 : if( aMDHelper.ISSET_FilterName &&
+ - - + ]
[ - + ]
519 [ + - ][ + - ]: 12 : (aMDHelper.FilterName.equals( C2U("StarChart 5.0")) ||
[ # # ]
520 [ + - ][ + - ]: 12 : aMDHelper.FilterName.equals( C2U("StarChart 4.0")) ||
[ # # ]
521 [ + - ][ + - ]: 12 : aMDHelper.FilterName.equals( C2U("StarChart 3.0")) ))
[ # # ]
522 : : {
523 [ # # ]: 0 : attachResource( aMDHelper.URL, rMediaDescriptor );
524 [ # # ][ # # ]: 0 : impl_load( rMediaDescriptor, 0 ); // cannot create a storage from binary streams, but I do not need the storage here anyhow
525 : 0 : m_bReadOnly = sal_True;
526 : 6 : return;
527 : : }
528 : :
529 : : Reference< lang::XSingleServiceFactory > xStorageFact(
530 [ + - ][ + - ]: 12 : m_xContext->getServiceManager()->createInstanceWithContext(
[ + - ]
531 : : C2U("com.sun.star.embed.StorageFactory"),
532 : 6 : m_xContext ),
533 [ + - ][ + - ]: 6 : uno::UNO_QUERY_THROW );
[ + - ]
534 : :
535 [ + - ]: 6 : if( aMDHelper.ISSET_Stream )
536 : : {
537 : : // convert XStream to XStorage via the storage factory
538 [ + - ]: 6 : Sequence< uno::Any > aStorageArgs( 2 );
539 [ + - ][ + - ]: 6 : aStorageArgs[0] <<= aMDHelper.Stream;
540 : : // todo: check if stream is read-only
541 [ + - ][ + - ]: 6 : aStorageArgs[1] <<= (embed::ElementModes::READ); //WRITE | embed::ElementModes::NOCREATE);
542 : :
543 [ + - ]: 6 : xStorage.set( xStorageFact->createInstanceWithArguments( aStorageArgs ),
544 [ + - ][ + - ]: 6 : uno::UNO_QUERY_THROW );
[ + - ]
545 : : }
546 : : else
547 : : {
548 : : OSL_ASSERT( aMDHelper.ISSET_InputStream );
549 : : // convert XInputStream to XStorage via the storage factory
550 [ # # ]: 0 : Sequence< uno::Any > aStorageArgs( 2 );
551 [ # # ][ # # ]: 0 : aStorageArgs[0] <<= aMDHelper.InputStream;
552 [ # # ][ # # ]: 0 : aStorageArgs[1] <<= (embed::ElementModes::READ);
553 : :
554 [ # # ]: 0 : xStorage.set( xStorageFact->createInstanceWithArguments( aStorageArgs ),
555 [ # # ][ # # ]: 0 : uno::UNO_QUERY_THROW );
[ # # ]
556 : 6 : }
557 : : }
558 : :
559 [ + - ]: 6 : if( aMDHelper.ISSET_URL )
560 [ + - ][ + - ]: 6 : aURL = aMDHelper.URL;
[ # # ]
561 : : }
562 [ # # ]: 0 : catch( const uno::Exception & ex )
563 : : {
564 : : ASSERT_EXCEPTION( ex );
565 : : }
566 : :
567 [ + - ]: 6 : if( xStorage.is())
568 : : {
569 [ + - ]: 6 : attachResource( aURL, rMediaDescriptor );
570 [ + - ]: 6 : impl_load( rMediaDescriptor, xStorage );
571 [ - + ][ + - ]: 6 : }
572 : : }
573 : :
574 : 6 : void ChartModel::impl_load(
575 : : const Sequence< beans::PropertyValue >& rMediaDescriptor,
576 : : const Reference< embed::XStorage >& xStorage )
577 : : {
578 : : {
579 [ + - ]: 6 : MutexGuard aGuard( m_aModelMutex );
580 [ + - ]: 6 : m_nInLoad++;
581 : : }
582 : :
583 [ + - ]: 6 : Reference< document::XFilter > xFilter( impl_createFilter( rMediaDescriptor ));
584 : :
585 [ + - ]: 6 : if( xFilter.is())
586 : : {
587 [ + - ]: 6 : Reference< document::XImporter > xImporter( xFilter, uno::UNO_QUERY_THROW );
588 [ + - ][ + - ]: 6 : xImporter->setTargetDocument( this );
[ + - ]
589 [ + - ]: 6 : Sequence< beans::PropertyValue > aMD( rMediaDescriptor );
590 [ + - ]: 6 : lcl_addStorageToMediaDescriptor( aMD, xStorage );
591 : :
592 [ + - ][ + - ]: 6 : xFilter->filter( aMD );
593 [ + - ]: 6 : xFilter.clear();
594 : : }
595 : : else
596 : : {
597 : : OSL_FAIL( "loadFromStorage cannot create filter" );
598 : : }
599 : :
600 [ + - ]: 6 : if( xStorage.is() )
601 [ + - ]: 6 : impl_loadGraphics( xStorage );
602 : :
603 [ + - ]: 6 : setModified( sal_False );
604 : :
605 : : // switchToStorage without notifying listeners (which shouldn't exist at
606 : : // this time, anyway)
607 [ + - ]: 6 : m_xStorage = xStorage;
608 : :
609 : : {
610 [ + - ]: 6 : MutexGuard aGuard( m_aModelMutex );
611 [ + - ]: 6 : m_nInLoad--;
612 : 6 : }
613 : 6 : }
614 : :
615 : 6 : void ChartModel::impl_loadGraphics(
616 : : const Reference< embed::XStorage >& xStorage )
617 : : {
618 : : try
619 : : {
620 : : const Reference< embed::XStorage >& xGraphicsStorage(
621 [ + - ]: 6 : xStorage->openStorageElement( C2U( "Pictures" ),
622 [ + - ][ + - ]: 6 : embed::ElementModes::READ ) );
623 : :
624 [ + - ]: 6 : if( xGraphicsStorage.is() )
625 : : {
626 : : const uno::Sequence< ::rtl::OUString > aElementNames(
627 [ + - ][ + - ]: 6 : xGraphicsStorage->getElementNames() );
628 : :
629 [ + + ]: 18 : for( int i = 0; i < aElementNames.getLength(); ++i )
630 : : {
631 [ + - ][ + - ]: 12 : if( xGraphicsStorage->isStreamElement( aElementNames[ i ] ) )
[ + - ]
632 : : {
633 : : uno::Reference< io::XStream > xElementStream(
634 [ + - ]: 12 : xGraphicsStorage->openStreamElement(
635 : 12 : aElementNames[ i ],
636 [ + - ]: 12 : embed::ElementModes::READ ) );
637 : :
638 [ + - ]: 12 : if( xElementStream.is() )
639 : : {
640 : : std::auto_ptr< SvStream > apIStm(
641 : : ::utl::UcbStreamHelper::CreateStream(
642 [ + - ]: 12 : xElementStream, true ) );
643 : :
644 [ + - ]: 12 : if( apIStm.get() )
645 : : {
646 [ + - ]: 12 : Graphic aGraphic;
647 : :
648 [ + - ]: 12 : if( !GraphicConverter::Import(
649 : 12 : *apIStm.get(),
650 [ + - ]: 12 : aGraphic ) )
651 : : {
652 [ + - ][ + - ]: 12 : m_aGraphicObjectVector.push_back( aGraphic );
[ + - ]
653 [ + - ]: 12 : }
654 [ + - ]: 12 : }
655 : 12 : }
656 : : }
657 [ + - ]: 6 : }
658 [ # # ]: 6 : }
659 : : }
660 : 0 : catch ( const uno::Exception& )
661 : : {
662 : : }
663 : 6 : }
664 : :
665 : : //-----------------------------------------------------------------
666 : : // util::XModifiable
667 : : //-----------------------------------------------------------------
668 : 1816 : void SAL_CALL ChartModel::impl_notifyModifiedListeners()
669 : : throw( uno::RuntimeException)
670 : : {
671 : : {
672 [ + - ]: 1816 : MutexGuard aGuard( m_aModelMutex );
673 [ + - ]: 1816 : m_bUpdateNotificationsPending = false;
674 : : }
675 : :
676 : : //always notify the view first!
677 [ + - ]: 1816 : ChartViewHelper::setViewToDirtyState( this );
678 : :
679 : : ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
680 : 1816 : .getContainer( ::getCppuType((const uno::Reference< util::XModifyListener >*)0) );
681 [ + + ]: 1816 : if( pIC )
682 : : {
683 [ + - ][ + - ]: 1792 : lang::EventObject aEvent( static_cast< lang::XComponent*>(this) );
684 [ + - ]: 1792 : ::cppu::OInterfaceIteratorHelper aIt( *pIC );
685 [ + + ]: 8872 : while( aIt.hasMoreElements() )
686 : : {
687 [ + - ][ + - ]: 7080 : uno::Reference< util::XModifyListener > xListener( aIt.next(), uno::UNO_QUERY );
688 [ + - ]: 7080 : if( xListener.is() )
689 [ + - ][ + - ]: 7080 : xListener->modified( aEvent );
690 [ + - ][ + - ]: 8872 : }
691 : : }
692 : 1816 : }
693 : :
694 : 3131 : sal_Bool SAL_CALL ChartModel::isModified()
695 : : throw(uno::RuntimeException)
696 : : {
697 : : //@todo guard
698 : 3131 : return m_bModified;
699 : : }
700 : :
701 : 4777 : void SAL_CALL ChartModel::setModified( sal_Bool bModified )
702 : : throw(beans::PropertyVetoException,
703 : : uno::RuntimeException)
704 : : {
705 [ + - ]: 4777 : apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
706 [ + - ][ - + ]: 4777 : if(!aGuard.startApiCall())//@todo ? is this a long lasting call??
707 : : return; //behave passive if already disposed or closed or throw exception @todo?
708 : 4777 : m_bModified = bModified;
709 : :
710 [ + + ]: 4777 : if( m_nControllerLockCount > 0 )
711 : : {
712 : 3058 : m_bUpdateNotificationsPending = true;
713 : : return;//don't call listeners if controllers are locked
714 : : }
715 [ + - ]: 1719 : aGuard.clear();
716 : :
717 [ + + ]: 1719 : if(bModified)
718 [ + - ][ + - ]: 4777 : impl_notifyModifiedListeners();
[ + + ]
719 : : }
720 : :
721 : : //-----------------------------------------------------------------
722 : : // util::XModifyBroadcaster (base of XModifiable)
723 : : //-----------------------------------------------------------------
724 : 224 : void SAL_CALL ChartModel::addModifyListener(
725 : : const uno::Reference< util::XModifyListener >& xListener )
726 : : throw(uno::RuntimeException)
727 : : {
728 [ - + ]: 224 : if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
729 : 224 : return; //behave passive if already disposed or closed
730 : :
731 : : m_aLifeTimeManager.m_aListenerContainer.addInterface(
732 : 224 : ::getCppuType((const uno::Reference< util::XModifyListener >*)0), xListener );
733 : : }
734 : :
735 : 44 : void SAL_CALL ChartModel::removeModifyListener(
736 : : const uno::Reference< util::XModifyListener >& xListener )
737 : : throw(uno::RuntimeException)
738 : : {
739 [ - + ]: 44 : if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) )
740 : 44 : return; //behave passive if already disposed or closed
741 : :
742 : : m_aLifeTimeManager.m_aListenerContainer.removeInterface(
743 : 44 : ::getCppuType((const uno::Reference< util::XModifyListener >*)0), xListener );
744 : : }
745 : :
746 : : //-----------------------------------------------------------------
747 : : // util::XModifyListener
748 : : //-----------------------------------------------------------------
749 : 5918 : void SAL_CALL ChartModel::modified( const lang::EventObject& )
750 : : throw (uno::RuntimeException)
751 : : {
752 [ + + ]: 5918 : if( m_nInLoad == 0 )
753 : 4388 : setModified( sal_True );
754 : 5918 : }
755 : :
756 : : //-----------------------------------------------------------------
757 : : // lang::XEventListener (base of util::XModifyListener)
758 : : //-----------------------------------------------------------------
759 : 76 : void SAL_CALL ChartModel::disposing( const lang::EventObject& )
760 : : throw (uno::RuntimeException)
761 : : {
762 : : // child was disposed -- should not happen from outside
763 : 76 : }
764 : :
765 : :
766 : : //-----------------------------------------------------------------
767 : : // document::XStorageBasedDocument
768 : : //-----------------------------------------------------------------
769 : 0 : void SAL_CALL ChartModel::loadFromStorage(
770 : : const Reference< embed::XStorage >& xStorage,
771 : : const Sequence< beans::PropertyValue >& rMediaDescriptor )
772 : : throw (lang::IllegalArgumentException,
773 : : frame::DoubleInitializationException,
774 : : io::IOException,
775 : : uno::Exception,
776 : : uno::RuntimeException)
777 : : {
778 [ # # ]: 0 : attachResource( OUString(), rMediaDescriptor );
779 : 0 : impl_load( rMediaDescriptor, xStorage );
780 : 0 : }
781 : :
782 : 15 : void SAL_CALL ChartModel::storeToStorage(
783 : : const Reference< embed::XStorage >& xStorage,
784 : : const Sequence< beans::PropertyValue >& rMediaDescriptor )
785 : : throw (lang::IllegalArgumentException,
786 : : io::IOException,
787 : : uno::Exception,
788 : : uno::RuntimeException)
789 : : {
790 : 15 : impl_store( rMediaDescriptor, xStorage );
791 : 15 : }
792 : :
793 : 15 : void SAL_CALL ChartModel::switchToStorage( const Reference< embed::XStorage >& xStorage )
794 : : throw (lang::IllegalArgumentException,
795 : : io::IOException,
796 : : uno::Exception,
797 : : uno::RuntimeException)
798 : : {
799 : 15 : m_xStorage = xStorage;
800 : 15 : impl_notifyStorageChangeListeners();
801 : 15 : }
802 : :
803 : 0 : Reference< embed::XStorage > SAL_CALL ChartModel::getDocumentStorage()
804 : : throw (io::IOException,
805 : : uno::Exception,
806 : : uno::RuntimeException)
807 : : {
808 : 0 : return m_xStorage;
809 : : }
810 : :
811 : 15 : void SAL_CALL ChartModel::impl_notifyStorageChangeListeners()
812 : : throw( uno::RuntimeException)
813 : : {
814 : : ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
815 : 15 : .getContainer( ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0) );
816 [ - + ]: 15 : if( pIC )
817 : : {
818 [ # # ]: 0 : ::cppu::OInterfaceIteratorHelper aIt( *pIC );
819 [ # # ]: 0 : while( aIt.hasMoreElements() )
820 : : {
821 [ # # ][ # # ]: 0 : uno::Reference< document::XStorageChangeListener > xListener( aIt.next(), uno::UNO_QUERY );
822 [ # # ]: 0 : if( xListener.is() )
823 [ # # ][ # # ]: 0 : xListener->notifyStorageChange( static_cast< ::cppu::OWeakObject* >( this ), m_xStorage );
[ # # ]
824 [ # # ]: 0 : }
825 : : }
826 : 15 : }
827 : :
828 : 0 : void SAL_CALL ChartModel::addStorageChangeListener( const Reference< document::XStorageChangeListener >& xListener )
829 : : throw (uno::RuntimeException)
830 : : {
831 [ # # ]: 0 : if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
832 : 0 : return; //behave passive if already disposed or closed
833 : :
834 : : m_aLifeTimeManager.m_aListenerContainer.addInterface(
835 : 0 : ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0), xListener );
836 : : }
837 : :
838 : 0 : void SAL_CALL ChartModel::removeStorageChangeListener( const Reference< document::XStorageChangeListener >& xListener )
839 : : throw (uno::RuntimeException)
840 : : {
841 [ # # ]: 0 : if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) )
842 : 0 : return; //behave passive if already disposed or closed
843 : :
844 : : m_aLifeTimeManager.m_aListenerContainer.removeInterface(
845 : 0 : ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0), xListener );
846 : : }
847 : :
848 : : } // namespace chart
849 : :
850 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|