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 : #include "ChartView.hxx"
21 : #include "chartview/DrawModelWrapper.hxx"
22 : #include "NumberFormatterWrapper.hxx"
23 : #include "ViewDefines.hxx"
24 : #include "VDiagram.hxx"
25 : #include "VTitle.hxx"
26 : #include "ShapeFactory.hxx"
27 : #include "VCoordinateSystem.hxx"
28 : #include "VSeriesPlotter.hxx"
29 : #include "CommonConverters.hxx"
30 : #include "macros.hxx"
31 : #include "TitleHelper.hxx"
32 : #include "LegendHelper.hxx"
33 : #include "VLegend.hxx"
34 : #include "PropertyMapper.hxx"
35 : #include "ChartModelHelper.hxx"
36 : #include "ChartTypeHelper.hxx"
37 : #include "ScaleAutomatism.hxx"
38 : #include "MinimumAndMaximumSupplier.hxx"
39 : #include "ObjectIdentifier.hxx"
40 : #include "DiagramHelper.hxx"
41 : #include "RelativePositionHelper.hxx"
42 : #include "servicenames.hxx"
43 : #include "AxisHelper.hxx"
44 : #include "AxisIndexDefines.hxx"
45 : #include "ControllerLockGuard.hxx"
46 : #include "BaseGFXHelper.hxx"
47 : #include "DataSeriesHelper.hxx"
48 : #include "DateHelper.hxx"
49 : #include "defines.hxx"
50 :
51 : #include <rtl/uuid.h>
52 : #include <comphelper/scopeguard.hxx>
53 : #include <comphelper/servicehelper.hxx>
54 : #include <boost/bind.hpp>
55 : #include <unotools/streamwrap.hxx>
56 : // header for class LocaleDataWrapper
57 : #include <unotools/localedatawrapper.hxx>
58 : // header for class SdrPage
59 : #include <svx/svdpage.hxx>
60 : // header for class SvxDrawPage
61 : #include <svx/unopage.hxx>
62 : // header for class SvxShape
63 : #include <svx/unoshape.hxx>
64 : // header for class Application
65 : #include <vcl/svapp.hxx>
66 : #include <osl/mutex.hxx>
67 : #include <svx/unofill.hxx>
68 :
69 : #include <drawinglayer/XShapeDumper.hxx>
70 :
71 : #include <time.h>
72 :
73 : #include <com/sun/star/chart/ChartAxisPosition.hpp>
74 : #include <com/sun/star/chart/DataLabelPlacement.hpp>
75 : #include <com/sun/star/chart/MissingValueTreatment.hpp>
76 : #include <com/sun/star/chart2/StackingDirection.hpp>
77 : #include <com/sun/star/chart2/XChartDocument.hpp>
78 : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
79 : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
80 : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
81 : #include <com/sun/star/chart2/XTitled.hpp>
82 : #include <com/sun/star/chart2/RelativePosition.hpp>
83 : #include <com/sun/star/chart2/RelativeSize.hpp>
84 : #include <com/sun/star/drawing/FillStyle.hpp>
85 : #include <com/sun/star/drawing/LineStyle.hpp>
86 : #include <com/sun/star/drawing/XShapeGroup.hpp>
87 : #include <com/sun/star/document/XExporter.hpp>
88 : #include <com/sun/star/document/XFilter.hpp>
89 : #include <com/sun/star/io/XSeekable.hpp>
90 : #include <com/sun/star/util/XModifiable.hpp>
91 : #include <com/sun/star/util/XRefreshable.hpp>
92 : #include <com/sun/star/util/NumberFormat.hpp>
93 : #include <com/sun/star/awt/Size.hpp>
94 : #include <com/sun/star/awt/Point.hpp>
95 : #include <com/sun/star/drawing/XShapeDescriptor.hpp>
96 : #include <com/sun/star/text/XText.hpp>
97 :
98 : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
99 : #include <com/sun/star/text/XTextDocument.hpp>
100 : #include <com/sun/star/text/WritingMode2.hpp>
101 : #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
102 : #include <com/sun/star/view/XSelectionSupplier.hpp>
103 : #include <svl/languageoptions.hxx>
104 : #include <sot/clsids.hxx>
105 :
106 : #include <rtl/strbuf.hxx>
107 : #include <rtl/ustring.hxx>
108 :
109 : #include <boost/shared_ptr.hpp>
110 :
111 : namespace chart {
112 :
113 : using namespace ::com::sun::star;
114 : using namespace ::com::sun::star::chart2;
115 : using ::com::sun::star::uno::Reference;
116 : using ::com::sun::star::uno::Sequence;
117 : using ::com::sun::star::uno::Any;
118 : using rtl::OUString;
119 :
120 : namespace
121 : {
122 : class theExplicitValueProviderUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theExplicitValueProviderUnoTunnelId > {};
123 : }
124 :
125 280 : const uno::Sequence<sal_Int8>& ExplicitValueProvider::getUnoTunnelId()
126 : {
127 280 : return theExplicitValueProviderUnoTunnelId::get().getSeq();
128 : }
129 :
130 0 : ExplicitValueProvider* ExplicitValueProvider::getExplicitValueProvider(
131 : const Reference< uno::XInterface >& xChartView )
132 : {
133 0 : ExplicitValueProvider* pExplicitValueProvider=0;
134 :
135 0 : Reference< lang::XUnoTunnel > xTunnel( xChartView, uno::UNO_QUERY );
136 0 : if( xTunnel.is() )
137 : {
138 0 : pExplicitValueProvider = reinterpret_cast<ExplicitValueProvider*>(xTunnel->getSomething(
139 0 : ExplicitValueProvider::getUnoTunnelId() ));
140 : }
141 0 : return pExplicitValueProvider;
142 : }
143 :
144 41 : ChartView::ChartView(
145 : uno::Reference<uno::XComponentContext> const & xContext)
146 : : m_aMutex()
147 : , m_xCC(xContext)
148 : , m_xChartModel()
149 : , m_xShapeFactory()
150 : , m_xDrawPage()
151 : , m_pDrawModelWrapper()
152 : , m_aListenerContainer( m_aMutex )
153 : , m_bViewDirty(true)
154 : , m_bInViewUpdate(false)
155 : , m_bViewUpdatePending(false)
156 : , m_bRefreshAddIn(true)
157 : , m_aPageResolution(1000,1000)
158 : , m_bPointsWereSkipped(false)
159 : , m_nScaleXNumerator(1)
160 : , m_nScaleXDenominator(1)
161 : , m_nScaleYNumerator(1)
162 : , m_nScaleYDenominator(1)
163 : , m_bSdrViewIsInEditMode(sal_False)
164 41 : , m_aResultingDiagramRectangleExcludingAxes(0,0,0,0)
165 : {
166 41 : }
167 :
168 41 : void ChartView::impl_setChartModel( const uno::Reference< frame::XModel >& xChartModel )
169 : {
170 41 : if( m_xChartModel != xChartModel )
171 : {
172 41 : m_xChartModel = xChartModel;
173 41 : m_bViewDirty = true;
174 : }
175 41 : }
176 :
177 41 : void SAL_CALL ChartView::initialize( const uno::Sequence< uno::Any >& aArguments )
178 : throw ( uno::Exception, uno::RuntimeException)
179 : {
180 : OSL_PRECOND(aArguments.getLength() >= 1,"need 1 argument to initialize the view: xModel");
181 41 : if( !(aArguments.getLength() >= 1) )
182 41 : return;
183 :
184 41 : uno::Reference< frame::XModel > xNewChartModel;
185 41 : if( !(aArguments[0] >>= xNewChartModel) )
186 : {
187 : OSL_FAIL( "need a Reference to frame::XModel as first parameter for view initialization" );
188 : }
189 41 : impl_setChartModel( xNewChartModel );
190 :
191 41 : if( !m_pDrawModelWrapper.get() )
192 : {
193 41 : SolarMutexGuard aSolarGuard;
194 41 : m_pDrawModelWrapper = ::boost::shared_ptr< DrawModelWrapper >( new DrawModelWrapper( m_xCC ) );
195 41 : m_xShapeFactory = m_pDrawModelWrapper->getShapeFactory();
196 41 : m_xDrawPage = m_pDrawModelWrapper->getMainDrawPage();
197 41 : StartListening( m_pDrawModelWrapper->getSdrModel(), false /*bPreventDups*/ );
198 41 : }
199 : }
200 :
201 123 : ChartView::~ChartView()
202 : {
203 41 : if( m_pDrawModelWrapper.get() )
204 : {
205 41 : EndListening( m_pDrawModelWrapper->getSdrModel(), false /*bAllDups*/ );
206 41 : SolarMutexGuard aSolarGuard;
207 41 : m_pDrawModelWrapper.reset();
208 : }
209 41 : m_xDrawPage = NULL;
210 41 : impl_deleteCoordinateSystems();
211 82 : }
212 :
213 82 : void ChartView::impl_deleteCoordinateSystems()
214 : {
215 : //delete all coordinate systems
216 82 : ::std::vector< VCoordinateSystem* > aVectorToDeleteObjects;
217 82 : ::std::swap( aVectorToDeleteObjects, m_aVCooSysList );//#i109770#
218 82 : ::std::vector< VCoordinateSystem* >::const_iterator aIter = aVectorToDeleteObjects.begin();
219 82 : const ::std::vector< VCoordinateSystem* >::const_iterator aEnd = aVectorToDeleteObjects.end();
220 123 : for( ; aIter != aEnd; ++aIter )
221 : {
222 41 : delete *aIter;
223 : }
224 82 : aVectorToDeleteObjects.clear();
225 82 : }
226 :
227 :
228 : //-----------------------------------------------------------------
229 : // datatransfer::XTransferable
230 : namespace
231 : {
232 1 : const rtl::OUString lcl_aGDIMetaFileMIMEType(
233 : RTL_CONSTASCII_USTRINGPARAM("application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\""));
234 1 : const rtl::OUString lcl_aGDIMetaFileMIMETypeHighContrast(
235 : RTL_CONSTASCII_USTRINGPARAM("application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\""));
236 : } // anonymous namespace
237 :
238 0 : void ChartView::getMetaFile( const uno::Reference< io::XOutputStream >& xOutStream
239 : , bool bUseHighContrast )
240 : {
241 0 : if( !m_xDrawPage.is() )
242 : return;
243 :
244 0 : uno::Reference< lang::XMultiServiceFactory > xFactory( m_xCC->getServiceManager(), uno::UNO_QUERY );
245 0 : if( !xFactory.is() )
246 : return;
247 :
248 : // creating the graphic exporter
249 0 : uno::Reference< document::XExporter > xExporter( xFactory->createInstance(
250 0 : C2U("com.sun.star.drawing.GraphicExportFilter")), uno::UNO_QUERY);
251 0 : uno::Reference< document::XFilter > xFilter( xExporter, uno::UNO_QUERY );
252 :
253 0 : if( !xExporter.is() || !xFilter.is() )
254 : return;
255 :
256 0 : uno::Sequence< beans::PropertyValue > aProps(3);
257 0 : aProps[0].Name = C2U("FilterName");
258 0 : aProps[0].Value <<= C2U("SVM");
259 :
260 0 : aProps[1].Name = C2U("OutputStream");
261 0 : aProps[1].Value <<= xOutStream;
262 :
263 0 : uno::Sequence< beans::PropertyValue > aFilterData(4);
264 0 : aFilterData[0].Name = C2U("ExportOnlyBackground");
265 0 : aFilterData[0].Value <<= sal_False;
266 0 : aFilterData[1].Name = C2U("HighContrast");
267 0 : aFilterData[1].Value <<= bUseHighContrast;
268 :
269 0 : aFilterData[2].Name = C2U("Version");
270 0 : const sal_Int32 nVersion = SOFFICE_FILEFORMAT_50;
271 0 : aFilterData[2].Value <<= nVersion;
272 :
273 0 : aFilterData[3].Name = C2U("CurrentPage");
274 0 : aFilterData[3].Value <<= uno::Reference< uno::XInterface >( m_xDrawPage, uno::UNO_QUERY );
275 :
276 : //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
277 : {
278 0 : aFilterData.realloc( aFilterData.getLength()+4 );
279 0 : aFilterData[4].Name = C2U("ScaleXNumerator");
280 0 : aFilterData[4].Value = uno::makeAny( m_nScaleXNumerator );
281 0 : aFilterData[5].Name = C2U("ScaleXDenominator");
282 0 : aFilterData[5].Value = uno::makeAny( m_nScaleXDenominator );
283 0 : aFilterData[6].Name = C2U("ScaleYNumerator");
284 0 : aFilterData[6].Value = uno::makeAny( m_nScaleYNumerator );
285 0 : aFilterData[7].Name = C2U("ScaleYDenominator");
286 0 : aFilterData[7].Value = uno::makeAny( m_nScaleYDenominator );
287 : }
288 :
289 0 : aProps[2].Name = C2U("FilterData");
290 0 : aProps[2].Value <<= aFilterData;
291 :
292 0 : xExporter->setSourceDocument( uno::Reference< lang::XComponent >( m_xDrawPage, uno::UNO_QUERY) );
293 0 : if( xFilter->filter( aProps ) )
294 : {
295 0 : xOutStream->flush();
296 0 : xOutStream->closeOutput();
297 0 : uno::Reference< io::XSeekable > xSeekable( xOutStream, uno::UNO_QUERY );
298 0 : if( xSeekable.is() )
299 0 : xSeekable->seek(0);
300 0 : }
301 : }
302 :
303 0 : uno::Any SAL_CALL ChartView::getTransferData( const datatransfer::DataFlavor& aFlavor )
304 : throw (datatransfer::UnsupportedFlavorException, io::IOException, uno::RuntimeException)
305 : {
306 0 : bool bHighContrastMetaFile( aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast));
307 0 : uno::Any aRet;
308 0 : if( ! (bHighContrastMetaFile || aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMEType)) )
309 : return aRet;
310 :
311 0 : update();
312 :
313 0 : SvMemoryStream aStream( 1024, 1024 );
314 0 : utl::OStreamWrapper* pStreamWrapper = new utl::OStreamWrapper( aStream );
315 :
316 0 : uno::Reference< io::XOutputStream > xOutStream( pStreamWrapper );
317 0 : uno::Reference< io::XInputStream > xInStream( pStreamWrapper );
318 0 : uno::Reference< io::XSeekable > xSeekable( pStreamWrapper );
319 :
320 0 : if( xOutStream.is() )
321 : {
322 0 : this->getMetaFile( xOutStream, bHighContrastMetaFile );
323 :
324 0 : if( xInStream.is() && xSeekable.is() )
325 : {
326 0 : xSeekable->seek(0);
327 0 : sal_Int32 nBytesToRead = xInStream->available();
328 0 : uno::Sequence< sal_Int8 > aSeq( nBytesToRead );
329 0 : xInStream->readBytes( aSeq, nBytesToRead);
330 0 : aRet <<= aSeq;
331 0 : xInStream->closeInput();
332 : }
333 : }
334 :
335 0 : return aRet;
336 : }
337 0 : uno::Sequence< datatransfer::DataFlavor > SAL_CALL ChartView::getTransferDataFlavors()
338 : throw (uno::RuntimeException)
339 : {
340 0 : uno::Sequence< datatransfer::DataFlavor > aRet(2);
341 :
342 0 : aRet[0] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMEType,
343 : C2U( "GDIMetaFile" ),
344 0 : ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) );
345 0 : aRet[1] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMETypeHighContrast,
346 : C2U( "GDIMetaFile" ),
347 0 : ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) );
348 :
349 0 : return aRet;
350 : }
351 0 : ::sal_Bool SAL_CALL ChartView::isDataFlavorSupported( const datatransfer::DataFlavor& aFlavor )
352 : throw (uno::RuntimeException)
353 : {
354 0 : return ( aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMEType) ||
355 0 : aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast) );
356 : }
357 :
358 : //-----------------------------------------------------------------
359 : // ____ XUnoTunnel ___
360 140 : ::sal_Int64 SAL_CALL ChartView::getSomething( const uno::Sequence< ::sal_Int8 >& aIdentifier )
361 : throw( uno::RuntimeException)
362 : {
363 420 : if( aIdentifier.getLength() == 16 && 0 == memcmp( ExplicitValueProvider::getUnoTunnelId().getConstArray(),
364 280 : aIdentifier.getConstArray(), 16 ) )
365 : {
366 140 : ExplicitValueProvider* pProvider = this;
367 140 : return reinterpret_cast<sal_Int64>(pProvider);
368 : }
369 0 : return 0;
370 : }
371 :
372 : //-----------------------------------------------------------------
373 : // lang::XServiceInfo
374 :
375 1 : APPHELPER_XSERVICEINFO_IMPL(ChartView,CHART_VIEW_SERVICE_IMPLEMENTATION_NAME)
376 :
377 1 : uno::Sequence< rtl::OUString > ChartView
378 : ::getSupportedServiceNames_Static()
379 : {
380 1 : uno::Sequence< rtl::OUString > aSNS( 1 );
381 1 : aSNS.getArray()[ 0 ] = CHART_VIEW_SERVICE_NAME;
382 1 : return aSNS;
383 : }
384 :
385 : //-----------------------------------------------------------------
386 : //-----------------------------------------------------------------
387 :
388 164 : ::basegfx::B3DHomMatrix createTransformationSceneToScreen(
389 : const ::basegfx::B2IRectangle& rDiagramRectangleWithoutAxes )
390 : {
391 164 : ::basegfx::B3DHomMatrix aM;
392 164 : aM.scale(double(rDiagramRectangleWithoutAxes.getWidth())/FIXED_SIZE_FOR_3D_CHART_VOLUME
393 328 : , -double(rDiagramRectangleWithoutAxes.getHeight())/FIXED_SIZE_FOR_3D_CHART_VOLUME, 1.0 );
394 164 : aM.translate(double(rDiagramRectangleWithoutAxes.getMinX())
395 328 : , double(rDiagramRectangleWithoutAxes.getMinY()+rDiagramRectangleWithoutAxes.getHeight()-1), 0);
396 164 : return aM;
397 : }
398 :
399 41 : VCoordinateSystem* findInCooSysList( const std::vector< VCoordinateSystem* >& rVCooSysList
400 : , const uno::Reference< XCoordinateSystem >& xCooSys )
401 : {
402 41 : for( size_t nC=0; nC < rVCooSysList.size(); nC++)
403 : {
404 0 : VCoordinateSystem* pVCooSys = rVCooSysList[nC];
405 0 : if(pVCooSys->getModel()==xCooSys)
406 0 : return pVCooSys;
407 : }
408 41 : return NULL;
409 : }
410 :
411 41 : VCoordinateSystem* addCooSysToList( std::vector< VCoordinateSystem* >& rVCooSysList
412 : , const uno::Reference< XCoordinateSystem >& xCooSys
413 : , const uno::Reference< frame::XModel >& xChartModel )
414 : {
415 41 : VCoordinateSystem* pVCooSys = findInCooSysList( rVCooSysList, xCooSys );
416 41 : if( !pVCooSys )
417 : {
418 41 : pVCooSys = VCoordinateSystem::createCoordinateSystem(xCooSys );
419 41 : if(pVCooSys)
420 : {
421 41 : rtl::OUString aCooSysParticle( ObjectIdentifier::createParticleForCoordinateSystem( xCooSys, xChartModel ) );
422 41 : pVCooSys->setParticle(aCooSysParticle);
423 :
424 41 : pVCooSys->setExplicitCategoriesProvider( new ExplicitCategoriesProvider(xCooSys,xChartModel) );
425 :
426 41 : rVCooSysList.push_back( pVCooSys );
427 : }
428 : }
429 41 : return pVCooSys;
430 : }
431 :
432 164 : VCoordinateSystem* lcl_getCooSysForPlotter( const std::vector< VCoordinateSystem* >& rVCooSysList, MinimumAndMaximumSupplier* pMinimumAndMaximumSupplier )
433 : {
434 164 : if(!pMinimumAndMaximumSupplier)
435 0 : return 0;
436 164 : for( size_t nC=0; nC < rVCooSysList.size(); nC++)
437 : {
438 164 : VCoordinateSystem* pVCooSys = rVCooSysList[nC];
439 164 : if(pVCooSys->hasMinimumAndMaximumSupplier( pMinimumAndMaximumSupplier ))
440 164 : return pVCooSys;
441 : }
442 0 : return 0;
443 : }
444 :
445 : typedef std::pair< sal_Int32, sal_Int32 > tFullAxisIndex; //first index is the dimension, second index is the axis index that indicates whether this is a main or secondary axis
446 : typedef std::map< VCoordinateSystem*, tFullAxisIndex > tCoordinateSystemMap;
447 :
448 164 : struct AxisUsage
449 : {
450 : AxisUsage();
451 : ~AxisUsage();
452 :
453 : void addCoordinateSystem( VCoordinateSystem* pCooSys, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex );
454 : ::std::vector< VCoordinateSystem* > getCoordinateSystems( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex );
455 : sal_Int32 getMaxAxisIndexForDimension( sal_Int32 nDimensionIndex );
456 :
457 : ScaleAutomatism aScaleAutomatism;
458 :
459 : private:
460 : tCoordinateSystemMap aCoordinateSystems;
461 : std::map< sal_Int32, sal_Int32 > aMaxIndexPerDimension;
462 : };
463 :
464 82 : AxisUsage::AxisUsage()
465 82 : : aScaleAutomatism(AxisHelper::createDefaultScale(),Date( Date::SYSTEM ))
466 : {
467 82 : }
468 :
469 492 : AxisUsage::~AxisUsage()
470 : {
471 246 : aCoordinateSystems.clear();
472 246 : }
473 :
474 82 : void AxisUsage::addCoordinateSystem( VCoordinateSystem* pCooSys, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
475 : {
476 82 : if(!pCooSys)
477 : return;
478 :
479 82 : tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex );
480 82 : tCoordinateSystemMap::const_iterator aFound( aCoordinateSystems.find(pCooSys) );
481 :
482 : //use one scale only once for each coordinate system
483 : //main axis are preferred over secondary axis
484 : //value scales are preferred
485 82 : if(aFound!=aCoordinateSystems.end())
486 : {
487 0 : sal_Int32 nFoundAxisIndex = aFound->second.second;
488 0 : if( nFoundAxisIndex < nAxisIndex )
489 : return;
490 0 : sal_Int32 nFoundDimension = aFound->second.first;
491 0 : if( nFoundDimension ==1 )
492 : return;
493 0 : if( nFoundDimension < nDimensionIndex )
494 : return;
495 : }
496 82 : aCoordinateSystems[pCooSys] = aFullAxisIndex;
497 :
498 : //set maximum scale index
499 82 : std::map< sal_Int32, sal_Int32 >::const_iterator aIter = aMaxIndexPerDimension.find(nDimensionIndex);
500 82 : if( aIter != aMaxIndexPerDimension.end() )
501 : {
502 0 : sal_Int32 nCurrentMaxIndex = aIter->second;
503 0 : if( nCurrentMaxIndex < nAxisIndex )
504 0 : aMaxIndexPerDimension[nDimensionIndex]=nAxisIndex;
505 : }
506 : else
507 82 : aMaxIndexPerDimension[nDimensionIndex]=nAxisIndex;
508 : }
509 1148 : ::std::vector< VCoordinateSystem* > AxisUsage::getCoordinateSystems( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
510 : {
511 1148 : ::std::vector< VCoordinateSystem* > aRet;
512 :
513 1148 : tCoordinateSystemMap::const_iterator aIter;
514 2296 : for( aIter = aCoordinateSystems.begin(); aIter!=aCoordinateSystems.end();++aIter )
515 : {
516 1148 : if( aIter->second.first != nDimensionIndex )
517 738 : continue;
518 410 : if( aIter->second.second != nAxisIndex )
519 0 : continue;
520 410 : aRet.push_back( aIter->first );
521 : }
522 :
523 1148 : return aRet;
524 : }
525 246 : sal_Int32 AxisUsage::getMaxAxisIndexForDimension( sal_Int32 nDimensionIndex )
526 : {
527 246 : sal_Int32 nRet = -1;
528 246 : std::map< sal_Int32, sal_Int32 >::const_iterator aIter = aMaxIndexPerDimension.find(nDimensionIndex);
529 246 : if( aIter != aMaxIndexPerDimension.end() )
530 82 : nRet = aIter->second;
531 246 : return nRet;
532 : }
533 :
534 : //-----------------------------------------------------
535 :
536 : class SeriesPlotterContainer
537 : {
538 : public:
539 : SeriesPlotterContainer( std::vector< VCoordinateSystem* >& rVCooSysList );
540 : ~SeriesPlotterContainer();
541 :
542 : void initializeCooSysAndSeriesPlotter( const uno::Reference< frame::XModel >& xChartModel );
543 : void initAxisUsageList(const Date& rNullDate);
544 : void doAutoScaling( const uno::Reference< frame::XModel >& xChartModel );
545 : void updateScalesAndIncrementsOnAxes();
546 : void setScalesFromCooSysToPlotter();
547 : void setNumberFormatsFromAxes();
548 : drawing::Direction3D getPreferredAspectRatio();
549 :
550 41 : std::vector< VSeriesPlotter* >& getSeriesPlotterList() { return m_aSeriesPlotterList; }
551 41 : std::vector< VCoordinateSystem* >& getCooSysList() { return m_rVCooSysList; }
552 : std::vector< LegendEntryProvider* > getLegendEntryProviderList();
553 :
554 : void AdaptScaleOfYAxisWithoutAttachedSeries( const uno::Reference< frame::XModel >& xChartModel );
555 :
556 : private:
557 : std::vector< VSeriesPlotter* > m_aSeriesPlotterList;
558 : std::vector< VCoordinateSystem* >& m_rVCooSysList;
559 : ::std::map< uno::Reference< XAxis >, AxisUsage > m_aAxisUsageList;
560 : sal_Int32 m_nMaxAxisIndex;
561 : bool m_bChartTypeUsesShiftedCategoryPositionPerDefault;
562 : sal_Int32 m_nDefaultDateNumberFormat;
563 : };
564 :
565 41 : SeriesPlotterContainer::SeriesPlotterContainer( std::vector< VCoordinateSystem* >& rVCooSysList )
566 : : m_rVCooSysList( rVCooSysList )
567 : , m_nMaxAxisIndex(0)
568 : , m_bChartTypeUsesShiftedCategoryPositionPerDefault(false)
569 41 : , m_nDefaultDateNumberFormat(0)
570 : {
571 41 : }
572 :
573 82 : SeriesPlotterContainer::~SeriesPlotterContainer()
574 : {
575 : // - remove plotter from coordinatesystems
576 82 : for( size_t nC=0; nC < m_rVCooSysList.size(); nC++)
577 41 : m_rVCooSysList[nC]->clearMinimumAndMaximumSupplierList();
578 : // - delete all plotter
579 41 : ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin();
580 41 : const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end();
581 82 : for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
582 41 : delete *aPlotterIter;
583 41 : m_aSeriesPlotterList.clear();
584 41 : }
585 :
586 41 : std::vector< LegendEntryProvider* > SeriesPlotterContainer::getLegendEntryProviderList()
587 : {
588 41 : std::vector< LegendEntryProvider* > aRet( m_aSeriesPlotterList.size() );
589 41 : ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin();
590 41 : const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end();
591 41 : sal_Int32 nN = 0;
592 82 : for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter, nN++ )
593 41 : aRet[nN] = *aPlotterIter;
594 41 : return aRet;
595 : }
596 :
597 41 : void SeriesPlotterContainer::initializeCooSysAndSeriesPlotter(
598 : const uno::Reference< frame::XModel >& xChartModel )
599 : {
600 : //------------ get model series from model
601 41 : sal_Int32 nDiagramIndex = 0;//todo if more than one diagram is supported
602 41 : uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
603 41 : if( !xDiagram.is())
604 : return;
605 :
606 41 : uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xChartModel, uno::UNO_QUERY );
607 41 : uno::Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY );
608 82 : if( xChartDoc.is() && xChartDoc->hasInternalDataProvider()
609 41 : && DiagramHelper::isSupportingDateAxis( xDiagram ) )
610 41 : m_nDefaultDateNumberFormat=DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier );
611 :
612 41 : sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
613 41 : if(!nDimensionCount)
614 : {
615 : //@todo handle mixed dimension
616 0 : nDimensionCount = 2;
617 : }
618 :
619 41 : sal_Bool bSortByXValues = sal_False;
620 41 : sal_Bool bConnectBars = sal_False;
621 41 : sal_Bool bGroupBarsPerAxis = sal_True;
622 41 : sal_Bool bIncludeHiddenCells = sal_True;
623 41 : sal_Int32 nStartingAngle = 90;
624 : try
625 : {
626 41 : uno::Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY_THROW );
627 41 : xDiaProp->getPropertyValue( C2U( "SortByXValues" ) ) >>= bSortByXValues;
628 41 : xDiaProp->getPropertyValue( C2U( "ConnectBars" ) ) >>= bConnectBars;
629 41 : xDiaProp->getPropertyValue( C2U( "GroupBarsPerAxis" ) ) >>= bGroupBarsPerAxis;
630 41 : xDiaProp->getPropertyValue( C2U( "IncludeHiddenCells" ) ) >>= bIncludeHiddenCells;
631 41 : xDiaProp->getPropertyValue( C2U( "StartingAngle" ) ) >>= nStartingAngle;
632 : }
633 0 : catch( const uno::Exception & ex )
634 : {
635 : ASSERT_EXCEPTION( ex );
636 : }
637 :
638 : //---------------------------------------------------------------------
639 : //prepare for autoscaling and shape creation
640 : // - create plotter for charttypes (for each first scale group at each plotter, as they are independent)
641 : // - add series to plotter (thus each charttype can provide minimum and maximum values for autoscaling)
642 : // - add plotter to coordinate systems
643 :
644 : //iterate through all coordinate systems
645 41 : uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
646 : OSL_ASSERT( xCooSysContainer.is());
647 41 : if( !xCooSysContainer.is())
648 : return;
649 41 : uno::Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
650 41 : uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
651 41 : sal_Int32 nGlobalSeriesIndex = 0;//for automatic symbols
652 82 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
653 : {
654 41 : uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
655 41 : VCoordinateSystem* pVCooSys = addCooSysToList(m_rVCooSysList,xCooSys,xChartModel);
656 :
657 : //iterate through all chart types in the current coordinate system
658 41 : uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
659 : OSL_ASSERT( xChartTypeContainer.is());
660 41 : if( !xChartTypeContainer.is() )
661 0 : continue;
662 41 : uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
663 82 : for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
664 : {
665 41 : uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
666 :
667 41 : if(nT==0)
668 41 : m_bChartTypeUsesShiftedCategoryPositionPerDefault = ChartTypeHelper::shiftCategoryPosAtXAxisPerDefault( xChartType );
669 :
670 41 : bool bExcludingPositioning = DiagramPositioningMode_EXCLUDING == DiagramHelper::getDiagramPositioningMode( xDiagram );
671 41 : VSeriesPlotter* pPlotter = VSeriesPlotter::createSeriesPlotter( xChartType, nDimensionCount, bExcludingPositioning );
672 41 : if( !pPlotter )
673 0 : continue;
674 41 : m_aSeriesPlotterList.push_back( pPlotter );
675 41 : pPlotter->setNumberFormatsSupplier( xNumberFormatsSupplier );
676 41 : pPlotter->setColorScheme( xColorScheme );
677 41 : if(pVCooSys)
678 41 : pPlotter->setExplicitCategoriesProvider( pVCooSys->getExplicitCategoriesProvider() );
679 41 : sal_Int32 nMissingValueTreatment = DiagramHelper::getCorrectedMissingValueTreatment( xDiagram, xChartType );
680 :
681 41 : if(pVCooSys)
682 41 : pVCooSys->addMinimumAndMaximumSupplier(pPlotter);
683 :
684 : //------------ add series to plotter and thus prepare him(it) for providing minimum and maximum values
685 41 : uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
686 : OSL_ASSERT( xDataSeriesContainer.is());
687 41 : if( !xDataSeriesContainer.is() )
688 0 : continue;
689 41 : sal_Int32 zSlot=-1;
690 41 : sal_Int32 xSlot=-1;
691 41 : sal_Int32 ySlot=-1;
692 41 : uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
693 164 : for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
694 : {
695 123 : uno::Reference< XDataSeries > xDataSeries( aSeriesList[nS], uno::UNO_QUERY );
696 123 : if(!xDataSeries.is())
697 0 : continue;
698 123 : if( !bIncludeHiddenCells && !DataSeriesHelper::hasUnhiddenData(xDataSeries) )
699 0 : continue;
700 :
701 123 : VDataSeries* pSeries = new VDataSeries( xDataSeries );
702 :
703 123 : pSeries->setGlobalSeriesIndex(nGlobalSeriesIndex);
704 123 : nGlobalSeriesIndex++;
705 :
706 123 : if( bSortByXValues )
707 0 : pSeries->doSortByXValues();
708 :
709 123 : pSeries->setConnectBars( bConnectBars );
710 123 : pSeries->setGroupBarsPerAxis( bGroupBarsPerAxis );
711 123 : pSeries->setStartingAngle( nStartingAngle );
712 :
713 123 : pSeries->setMissingValueTreatment( nMissingValueTreatment );
714 :
715 123 : rtl::OUString aSeriesParticle( ObjectIdentifier::createParticleForSeries( nDiagramIndex, nCS, nT, nS ) );
716 123 : pSeries->setParticle(aSeriesParticle);
717 :
718 123 : OUString aRole( ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( xChartType ) );
719 123 : pSeries->setRoleOfSequenceForDataLabelNumberFormatDetection(aRole);
720 :
721 : //ignore secondary axis for charttypes that do not suppoert them
722 123 : if( pSeries->getAttachedAxisIndex() != MAIN_AXIS_INDEX &&
723 0 : !ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimensionCount, 1 ) )
724 : {
725 0 : pSeries->setAttachedAxisIndex(MAIN_AXIS_INDEX);
726 : }
727 :
728 123 : StackingDirection eDirection = pSeries->getStackingDirection();
729 123 : switch(eDirection)
730 : {
731 : case StackingDirection_NO_STACKING:
732 123 : xSlot++; ySlot=-1;
733 123 : if(zSlot<0)
734 41 : zSlot=0;
735 123 : break;
736 : case StackingDirection_Y_STACKING:
737 0 : ySlot++;
738 0 : if(xSlot<0)
739 0 : xSlot=0;
740 0 : if(zSlot<0)
741 0 : zSlot=0;
742 0 : break;
743 : case StackingDirection_Z_STACKING:
744 0 : zSlot++; xSlot=-1; ySlot=-1;
745 0 : break;
746 : default:
747 : // UNO enums have one additional auto-generated case
748 0 : break;
749 : }
750 123 : pPlotter->addSeries( pSeries, zSlot, xSlot, ySlot );
751 123 : }
752 41 : }
753 41 : }
754 :
755 : //transport seriesnames to the coordinatesystems if needed
756 41 : if( !m_aSeriesPlotterList.empty() )
757 : {
758 41 : uno::Sequence< rtl::OUString > aSeriesNames;
759 41 : bool bSeriesNamesInitialized = false;
760 82 : for( size_t nC=0; nC < m_rVCooSysList.size(); nC++)
761 : {
762 41 : VCoordinateSystem* pVCooSys = m_rVCooSysList[nC];
763 41 : if(!pVCooSys)
764 0 : continue;
765 41 : if( pVCooSys->needSeriesNamesForAxis() )
766 : {
767 0 : if(!bSeriesNamesInitialized)
768 : {
769 0 : VSeriesPlotter* pSeriesPlotter = m_aSeriesPlotterList[0];
770 0 : if( pSeriesPlotter )
771 0 : aSeriesNames = pSeriesPlotter->getSeriesNames();
772 0 : bSeriesNamesInitialized = true;
773 : }
774 0 : pVCooSys->setSeriesNamesForAxis( aSeriesNames );
775 : }
776 41 : }
777 41 : }
778 : }
779 :
780 41 : void SeriesPlotterContainer::initAxisUsageList(const Date& rNullDate)
781 : {
782 41 : m_aAxisUsageList.clear();
783 : size_t nC;
784 82 : for( nC=0; nC < m_rVCooSysList.size(); nC++)
785 : {
786 41 : VCoordinateSystem* pVCooSys = m_rVCooSysList[nC];
787 164 : for(sal_Int32 nDimensionIndex=0; nDimensionIndex<3; nDimensionIndex++)
788 : {
789 123 : uno::Reference< XCoordinateSystem > xCooSys = pVCooSys->getModel();
790 123 : sal_Int32 nDimensionCount = xCooSys->getDimension();
791 123 : if( nDimensionIndex >= nDimensionCount )
792 41 : continue;
793 82 : bool bChartTypeAllowsDateAxis = ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( xCooSys, 0 ), nDimensionCount, nDimensionIndex );
794 82 : const sal_Int32 nMaximumAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
795 164 : for(sal_Int32 nAxisIndex=0; nAxisIndex<=nMaximumAxisIndex; ++nAxisIndex)
796 : {
797 82 : uno::Reference< XAxis > xAxis( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) );
798 : OSL_ASSERT( xAxis.is());
799 82 : if( xAxis.is())
800 : {
801 82 : if(m_aAxisUsageList.find(xAxis)==m_aAxisUsageList.end())
802 : {
803 82 : chart2::ScaleData aSourceScale = xAxis->getScaleData();
804 82 : ExplicitCategoriesProvider* pExplicitCategoriesProvider = pVCooSys->getExplicitCategoriesProvider();
805 82 : if( nDimensionIndex==0 )
806 41 : AxisHelper::checkDateAxis( aSourceScale, pExplicitCategoriesProvider, bChartTypeAllowsDateAxis );
807 82 : if( (aSourceScale.AxisType == AxisType::CATEGORY && m_bChartTypeUsesShiftedCategoryPositionPerDefault)
808 0 : || (aSourceScale.AxisType==AxisType::CATEGORY && pExplicitCategoriesProvider && pExplicitCategoriesProvider->hasComplexCategories() )
809 : || aSourceScale.AxisType == AxisType::DATE
810 : || aSourceScale.AxisType == AxisType::SERIES )
811 41 : aSourceScale.ShiftedCategoryPosition = true;
812 : else
813 41 : aSourceScale.ShiftedCategoryPosition = false;
814 82 : m_aAxisUsageList[xAxis].aScaleAutomatism = ScaleAutomatism(aSourceScale,rNullDate);
815 : }
816 82 : AxisUsage& rAxisUsage = m_aAxisUsageList[xAxis];
817 82 : rAxisUsage.addCoordinateSystem(pVCooSys,nDimensionIndex,nAxisIndex);
818 : }
819 82 : }
820 123 : }
821 : }
822 :
823 41 : ::std::map< uno::Reference< XAxis >, AxisUsage >::iterator aAxisIter = m_aAxisUsageList.begin();
824 41 : const ::std::map< uno::Reference< XAxis >, AxisUsage >::const_iterator aAxisEndIter = m_aAxisUsageList.end();
825 :
826 : //init m_nMaxAxisIndex
827 41 : m_nMaxAxisIndex = 0;
828 164 : for(sal_Int32 nDimensionIndex=0; nDimensionIndex<3; nDimensionIndex++)
829 : {
830 369 : for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter )
831 : {
832 246 : sal_Int32 nLocalMax = aAxisIter->second.getMaxAxisIndexForDimension( nDimensionIndex );
833 246 : if( m_nMaxAxisIndex < nLocalMax )
834 0 : m_nMaxAxisIndex = nLocalMax;
835 : }
836 : }
837 41 : }
838 :
839 82 : void SeriesPlotterContainer::setScalesFromCooSysToPlotter()
840 : {
841 : //set scales to plotter to enable them to provide the preferred scene AspectRatio
842 82 : ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin();
843 82 : const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end();
844 164 : for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
845 : {
846 82 : VSeriesPlotter* pSeriesPlotter = *aPlotterIter;
847 82 : VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( m_rVCooSysList, pSeriesPlotter );
848 82 : if(pVCooSys)
849 : {
850 82 : pSeriesPlotter->setScales( pVCooSys->getExplicitScales(0,0), pVCooSys->getPropertySwapXAndYAxis() );
851 82 : sal_Int32 nMaxAxisIndex = pVCooSys->getMaximumAxisIndexByDimension(1);//only additional value axis are relevant for series plotter
852 82 : for( sal_Int32 nI=1; nI<=nMaxAxisIndex; nI++ )
853 0 : pSeriesPlotter->addSecondaryValueScale( pVCooSys->getExplicitScale(1,nI), nI );
854 : }
855 : }
856 82 : }
857 :
858 41 : void SeriesPlotterContainer::setNumberFormatsFromAxes()
859 : {
860 : //set numberformats to plotter to enable them to display the data labels in the numberformat of the axis
861 :
862 41 : ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin();
863 41 : const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end();
864 82 : for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
865 : {
866 41 : VSeriesPlotter* pSeriesPlotter = *aPlotterIter;
867 41 : VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( m_rVCooSysList, pSeriesPlotter );
868 41 : if(pVCooSys)
869 : {
870 41 : AxesNumberFormats aAxesNumberFormats;
871 41 : uno::Reference< XCoordinateSystem > xCooSys = pVCooSys->getModel();
872 41 : sal_Int32 nDimensionCount = xCooSys->getDimension();
873 123 : for(sal_Int32 nDimensionIndex=0; nDimensionIndex<nDimensionCount; ++nDimensionIndex)
874 : {
875 82 : const sal_Int32 nMaximumAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
876 164 : for(sal_Int32 nAxisIndex=0; nAxisIndex<=nMaximumAxisIndex; ++nAxisIndex)
877 : {
878 : try
879 : {
880 82 : Reference< beans::XPropertySet > xAxisProp( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ), uno::UNO_QUERY );
881 82 : if( xAxisProp.is())
882 : {
883 82 : sal_Int32 nNumberFormatKey(0);
884 82 : if( xAxisProp->getPropertyValue( C2U( "NumberFormat" ) ) >>= nNumberFormatKey )
885 : {
886 0 : aAxesNumberFormats.setFormat( nNumberFormatKey, nDimensionIndex, nAxisIndex );
887 : }
888 82 : else if( nDimensionIndex==0 )
889 : {
890 : //provide a default date format for date axis with own data
891 41 : aAxesNumberFormats.setFormat( m_nDefaultDateNumberFormat, nDimensionIndex, nAxisIndex );
892 : }
893 82 : }
894 : }
895 0 : catch( const lang::IndexOutOfBoundsException& e )
896 : {
897 : ASSERT_EXCEPTION( e );
898 : }
899 : }
900 : }
901 41 : pSeriesPlotter->setAxesNumberFormats( aAxesNumberFormats );
902 : }
903 : }
904 41 : }
905 :
906 41 : void SeriesPlotterContainer::updateScalesAndIncrementsOnAxes()
907 : {
908 82 : for( size_t nC=0; nC < m_rVCooSysList.size(); nC++)
909 41 : m_rVCooSysList[nC]->updateScalesAndIncrementsOnAxes();
910 41 : }
911 :
912 82 : void SeriesPlotterContainer::doAutoScaling( const uno::Reference< frame::XModel >& xChartModel )
913 : {
914 : //precondition: need a initialized m_aSeriesPlotterList
915 : //precondition: need a initialized m_aAxisUsageList
916 :
917 82 : ::std::map< uno::Reference< XAxis >, AxisUsage >::iterator aAxisIter = m_aAxisUsageList.begin();
918 82 : const ::std::map< uno::Reference< XAxis >, AxisUsage >::const_iterator aAxisEndIter = m_aAxisUsageList.end();
919 :
920 : //iterate over the main scales first than secondary axis
921 : size_t nC;
922 82 : sal_Int32 nAxisIndex=0;
923 164 : for( nAxisIndex=0; nAxisIndex<=m_nMaxAxisIndex; nAxisIndex++ )
924 : {
925 :
926 : // - first do autoscale for all x and z scales (because they are treated independent)
927 246 : for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter )
928 : {
929 164 : AxisUsage& rAxisUsage = (*aAxisIter).second;
930 164 : ::std::vector< VCoordinateSystem* > aVCooSysList_X = rAxisUsage.getCoordinateSystems(0,nAxisIndex);
931 164 : ::std::vector< VCoordinateSystem* > aVCooSysList_Z = rAxisUsage.getCoordinateSystems(2,nAxisIndex);
932 :
933 246 : for( nC=0; nC < aVCooSysList_X.size(); nC++)
934 82 : aVCooSysList_X[nC]->prepareScaleAutomatismForDimensionAndIndex(rAxisUsage.aScaleAutomatism,0,nAxisIndex);
935 164 : for( nC=0; nC < aVCooSysList_Z.size(); nC++)
936 0 : aVCooSysList_Z[nC]->prepareScaleAutomatismForDimensionAndIndex(rAxisUsage.aScaleAutomatism,2,nAxisIndex);
937 :
938 164 : ExplicitScaleData aExplicitScale;
939 164 : ExplicitIncrementData aExplicitIncrement;
940 164 : rAxisUsage.aScaleAutomatism.calculateExplicitScaleAndIncrement( aExplicitScale, aExplicitIncrement );
941 :
942 246 : for( nC=0; nC < aVCooSysList_X.size(); nC++)
943 82 : aVCooSysList_X[nC]->setExplicitScaleAndIncrement( 0, nAxisIndex, aExplicitScale, aExplicitIncrement );
944 164 : for( nC=0; nC < aVCooSysList_Z.size(); nC++)
945 0 : aVCooSysList_Z[nC]->setExplicitScaleAndIncrement( 2, nAxisIndex, aExplicitScale, aExplicitIncrement );
946 164 : }
947 :
948 : // - second do autoscale for the dependent y scales (the coordinate systems are prepared with x and z scales already )
949 246 : for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter )
950 : {
951 164 : AxisUsage& rAxisUsage = (*aAxisIter).second;
952 164 : ::std::vector< VCoordinateSystem* > aVCooSysList_X = rAxisUsage.getCoordinateSystems(0,nAxisIndex);
953 164 : ::std::vector< VCoordinateSystem* > aVCooSysList_Y = rAxisUsage.getCoordinateSystems(1,nAxisIndex);
954 164 : ::std::vector< VCoordinateSystem* > aVCooSysList_Z = rAxisUsage.getCoordinateSystems(2,nAxisIndex);
955 :
956 164 : if(!aVCooSysList_Y.size())
957 82 : continue;
958 :
959 164 : for( nC=0; nC < aVCooSysList_Y.size(); nC++)
960 82 : aVCooSysList_Y[nC]->prepareScaleAutomatismForDimensionAndIndex(rAxisUsage.aScaleAutomatism,1,nAxisIndex);
961 :
962 82 : ExplicitScaleData aExplicitScale;
963 82 : ExplicitIncrementData aExplicitIncrement;
964 82 : rAxisUsage.aScaleAutomatism.calculateExplicitScaleAndIncrement( aExplicitScale, aExplicitIncrement );
965 :
966 82 : for( nC=0; nC < aVCooSysList_X.size(); nC++)
967 0 : aVCooSysList_X[nC]->setExplicitScaleAndIncrement( 0, nAxisIndex, aExplicitScale, aExplicitIncrement );
968 164 : for( nC=0; nC < aVCooSysList_Y.size(); nC++)
969 82 : aVCooSysList_Y[nC]->setExplicitScaleAndIncrement( 1, nAxisIndex, aExplicitScale, aExplicitIncrement );
970 82 : for( nC=0; nC < aVCooSysList_Z.size(); nC++)
971 0 : aVCooSysList_Z[nC]->setExplicitScaleAndIncrement( 2, nAxisIndex, aExplicitScale, aExplicitIncrement );
972 82 : }
973 : }
974 82 : AdaptScaleOfYAxisWithoutAttachedSeries( xChartModel );
975 82 : }
976 :
977 82 : void SeriesPlotterContainer::AdaptScaleOfYAxisWithoutAttachedSeries( const uno::Reference< frame::XModel >& xChartModel )
978 : {
979 : //issue #i80518#
980 :
981 82 : ::std::map< uno::Reference< XAxis >, AxisUsage >::iterator aAxisIter = m_aAxisUsageList.begin();
982 82 : const ::std::map< uno::Reference< XAxis >, AxisUsage >::const_iterator aAxisEndIter = m_aAxisUsageList.end();
983 :
984 164 : for( sal_Int32 nAxisIndex=0; nAxisIndex<=m_nMaxAxisIndex; nAxisIndex++ )
985 : {
986 246 : for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter )
987 : {
988 164 : AxisUsage& rAxisUsage = (*aAxisIter).second;
989 164 : ::std::vector< VCoordinateSystem* > aVCooSysList_Y = rAxisUsage.getCoordinateSystems( 1, nAxisIndex );
990 164 : if( !aVCooSysList_Y.size() )
991 82 : continue;
992 :
993 82 : uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
994 82 : if( xDiagram.is() )
995 : {
996 82 : bool bSeriesAttachedToThisAxis = false;
997 82 : sal_Int32 nAttachedAxisIndex = -1;
998 : {
999 82 : ::std::vector< Reference< XDataSeries > > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
1000 82 : ::std::vector< Reference< XDataSeries > >::const_iterator aIter = aSeriesVector.begin();
1001 82 : for( ; aIter != aSeriesVector.end(); ++aIter )
1002 : {
1003 82 : sal_Int32 nCurrentIndex = DataSeriesHelper::getAttachedAxisIndex( *aIter );
1004 82 : if( nAxisIndex == nCurrentIndex )
1005 : {
1006 82 : bSeriesAttachedToThisAxis = true;
1007 82 : break;
1008 : }
1009 0 : else if( nAttachedAxisIndex<0 || nAttachedAxisIndex>nCurrentIndex )
1010 0 : nAttachedAxisIndex=nCurrentIndex;
1011 82 : }
1012 : }
1013 :
1014 82 : if( !bSeriesAttachedToThisAxis && nAttachedAxisIndex >= 0 )
1015 : {
1016 0 : for( size_t nC = 0; nC < aVCooSysList_Y.size(); ++nC )
1017 : {
1018 0 : aVCooSysList_Y[nC]->prepareScaleAutomatismForDimensionAndIndex( rAxisUsage.aScaleAutomatism, 1, nAttachedAxisIndex );
1019 :
1020 0 : ExplicitScaleData aExplicitScaleSource = aVCooSysList_Y[nC]->getExplicitScale( 1,nAttachedAxisIndex );
1021 0 : ExplicitIncrementData aExplicitIncrementSource = aVCooSysList_Y[nC]->getExplicitIncrement( 1,nAttachedAxisIndex );
1022 :
1023 0 : ExplicitScaleData aExplicitScaleDest = aVCooSysList_Y[nC]->getExplicitScale( 1,nAxisIndex );;
1024 0 : ExplicitIncrementData aExplicitIncrementDest = aVCooSysList_Y[nC]->getExplicitIncrement( 1,nAxisIndex );;
1025 :
1026 0 : aExplicitScaleDest.Orientation = aExplicitScaleSource.Orientation;
1027 0 : aExplicitScaleDest.Scaling = aExplicitScaleSource.Scaling;
1028 0 : aExplicitScaleDest.AxisType = aExplicitScaleSource.AxisType;
1029 :
1030 0 : aExplicitIncrementDest.BaseValue = aExplicitIncrementSource.BaseValue;
1031 :
1032 0 : ScaleData aScale( rAxisUsage.aScaleAutomatism.getScale() );
1033 0 : if( !aScale.Minimum.hasValue() )
1034 : {
1035 0 : bool bNewMinOK = true;
1036 0 : double fMax=0.0;
1037 0 : if( aScale.Maximum >>= fMax )
1038 0 : bNewMinOK = (aExplicitScaleSource.Minimum <= fMax);
1039 0 : if( bNewMinOK )
1040 0 : aExplicitScaleDest.Minimum = aExplicitScaleSource.Minimum;
1041 : }
1042 : else
1043 0 : aExplicitIncrementDest.BaseValue = aExplicitScaleDest.Minimum;
1044 :
1045 0 : if( !aScale.Maximum.hasValue() )
1046 : {
1047 0 : bool bNewMaxOK = true;
1048 0 : double fMin=0.0;
1049 0 : if( aScale.Minimum >>= fMin )
1050 0 : bNewMaxOK = (fMin <= aExplicitScaleSource.Maximum);
1051 0 : if( bNewMaxOK )
1052 0 : aExplicitScaleDest.Maximum = aExplicitScaleSource.Maximum;
1053 : }
1054 0 : if( !aScale.Origin.hasValue() )
1055 0 : aExplicitScaleDest.Origin = aExplicitScaleSource.Origin;
1056 :
1057 0 : if( !aScale.IncrementData.Distance.hasValue() )
1058 0 : aExplicitIncrementDest.Distance = aExplicitIncrementSource.Distance;
1059 :
1060 0 : bool bAutoMinorInterval = true;
1061 0 : if( aScale.IncrementData.SubIncrements.getLength() )
1062 0 : bAutoMinorInterval = !( aScale.IncrementData.SubIncrements[0].IntervalCount.hasValue() );
1063 0 : if( bAutoMinorInterval )
1064 : {
1065 0 : if( !aExplicitIncrementDest.SubIncrements.empty() && !aExplicitIncrementSource.SubIncrements.empty() )
1066 0 : aExplicitIncrementDest.SubIncrements[0].IntervalCount =
1067 0 : aExplicitIncrementSource.SubIncrements[0].IntervalCount;
1068 : }
1069 :
1070 0 : aVCooSysList_Y[nC]->setExplicitScaleAndIncrement( 1, nAxisIndex, aExplicitScaleDest, aExplicitIncrementDest );
1071 0 : }
1072 : }
1073 : }
1074 82 : }
1075 : }
1076 :
1077 82 : if( AxisHelper::isAxisPositioningEnabled() )
1078 : {
1079 : //correct origin for y main axis (the origin is where the other main axis crosses)
1080 82 : sal_Int32 nAxisIndex=0;
1081 82 : sal_Int32 nDimensionIndex=1;
1082 246 : for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter )
1083 : {
1084 164 : AxisUsage& rAxisUsage = (*aAxisIter).second;
1085 164 : ::std::vector< VCoordinateSystem* > aVCooSysList = rAxisUsage.getCoordinateSystems(nDimensionIndex,nAxisIndex);
1086 : size_t nC;
1087 246 : for( nC=0; nC < aVCooSysList.size(); nC++)
1088 : {
1089 82 : ExplicitScaleData aExplicitScale( aVCooSysList[nC]->getExplicitScale( nDimensionIndex, nAxisIndex ) );
1090 82 : ExplicitIncrementData aExplicitIncrement( aVCooSysList[nC]->getExplicitIncrement( nDimensionIndex, nAxisIndex ) );
1091 :
1092 82 : Reference< chart2::XCoordinateSystem > xCooSys( aVCooSysList[nC]->getModel() );
1093 82 : Reference< XAxis > xAxis( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) );
1094 82 : Reference< beans::XPropertySet > xCrossingMainAxis( AxisHelper::getCrossingMainAxis( xAxis, xCooSys ), uno::UNO_QUERY );
1095 :
1096 82 : ::com::sun::star::chart::ChartAxisPosition eCrossingMainAxisPos( ::com::sun::star::chart::ChartAxisPosition_ZERO );
1097 82 : if( xCrossingMainAxis.is() )
1098 : {
1099 82 : xCrossingMainAxis->getPropertyValue(C2U( "CrossoverPosition" )) >>= eCrossingMainAxisPos;
1100 82 : if( ::com::sun::star::chart::ChartAxisPosition_VALUE == eCrossingMainAxisPos )
1101 : {
1102 0 : double fValue = 0.0;
1103 0 : xCrossingMainAxis->getPropertyValue(C2U( "CrossoverValue" )) >>= fValue;
1104 0 : aExplicitScale.Origin = fValue;
1105 : }
1106 82 : else if( ::com::sun::star::chart::ChartAxisPosition_ZERO == eCrossingMainAxisPos )
1107 82 : aExplicitScale.Origin = 0.0;
1108 0 : else if( ::com::sun::star::chart::ChartAxisPosition_START == eCrossingMainAxisPos )
1109 0 : aExplicitScale.Origin = aExplicitScale.Minimum;
1110 0 : else if( ::com::sun::star::chart::ChartAxisPosition_END == eCrossingMainAxisPos )
1111 0 : aExplicitScale.Origin = aExplicitScale.Maximum;
1112 : }
1113 :
1114 82 : aVCooSysList[nC]->setExplicitScaleAndIncrement( nDimensionIndex, nAxisIndex, aExplicitScale, aExplicitIncrement );
1115 82 : }
1116 164 : }
1117 : }
1118 82 : }
1119 :
1120 41 : drawing::Direction3D SeriesPlotterContainer::getPreferredAspectRatio()
1121 : {
1122 41 : drawing::Direction3D aPreferredAspectRatio(1.0,1.0,1.0);
1123 :
1124 41 : sal_Int32 nPlotterCount=0;
1125 : //get a list of all preferred aspect ratios and combine them
1126 : //first with special demands wins (less or equal zero <-> arbitrary)
1127 : double fx, fy, fz;
1128 41 : fx = fy = fz = -1.0;
1129 41 : ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin();
1130 41 : const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end();
1131 123 : for( aPlotterIter = m_aSeriesPlotterList.begin(), nPlotterCount=0
1132 41 : ; aPlotterIter != aPlotterEnd; ++aPlotterIter, ++nPlotterCount )
1133 : {
1134 41 : drawing::Direction3D aSingleRatio( (*aPlotterIter)->getPreferredDiagramAspectRatio() );
1135 41 : if( fx<0 && aSingleRatio.DirectionX>0 )
1136 0 : fx = aSingleRatio.DirectionX;
1137 :
1138 41 : if( fy<0 && aSingleRatio.DirectionY>0 )
1139 : {
1140 0 : if( fx>0 && aSingleRatio.DirectionX>0 )
1141 0 : fy = fx*aSingleRatio.DirectionY/aSingleRatio.DirectionX;
1142 0 : else if( fz>0 && aSingleRatio.DirectionZ>0 )
1143 0 : fy = fz*aSingleRatio.DirectionY/aSingleRatio.DirectionZ;
1144 : else
1145 0 : fy = aSingleRatio.DirectionY;
1146 : }
1147 :
1148 41 : if( fz<0 && aSingleRatio.DirectionZ>0 )
1149 : {
1150 0 : if( fx>0 && aSingleRatio.DirectionX>0 )
1151 0 : fz = fx*aSingleRatio.DirectionZ/aSingleRatio.DirectionX;
1152 0 : else if( fy>0 && aSingleRatio.DirectionY>0 )
1153 0 : fz = fy*aSingleRatio.DirectionZ/aSingleRatio.DirectionY;
1154 : else
1155 0 : fz = aSingleRatio.DirectionZ;
1156 : }
1157 :
1158 41 : if( fx>0 && fy>0 && fz>0 )
1159 : break;
1160 : }
1161 41 : aPreferredAspectRatio = drawing::Direction3D(fx, fy, fz);
1162 41 : return aPreferredAspectRatio;
1163 : }
1164 :
1165 : //-----------------------------------------------------
1166 :
1167 : namespace
1168 : {
1169 :
1170 41 : bool lcl_IsPieOrDonut( const uno::Reference< XDiagram >& xDiagram )
1171 : {
1172 : //special treatment for pie charts
1173 : //the size is checked after complete creation to get the datalabels into the given space
1174 :
1175 : //todo: this is just a workaround at the moment for pie and donut labels
1176 41 : return DiagramHelper::isPieOrDonutChart( xDiagram );
1177 : }
1178 :
1179 41 : void lcl_setDefaultWritingMode( ::boost::shared_ptr< DrawModelWrapper > pDrawModelWrapper, const Reference< frame::XModel >& xChartModel )
1180 : {
1181 : //get writing mode from parent document:
1182 41 : if( SvtLanguageOptions().IsCTLFontEnabled() )
1183 : {
1184 : try
1185 : {
1186 41 : uno::Reference< container::XChild > xChild( xChartModel, uno::UNO_QUERY );
1187 41 : sal_Int16 nWritingMode=-1;
1188 41 : if ( xChild.is() )
1189 : {
1190 41 : uno::Reference< beans::XPropertySet > xParentProps( xChild->getParent(), uno::UNO_QUERY );
1191 41 : uno::Reference< style::XStyleFamiliesSupplier > xStyleFamiliesSupplier( xParentProps, uno::UNO_QUERY );
1192 41 : if( xStyleFamiliesSupplier.is() )
1193 : {
1194 41 : uno::Reference< container::XNameAccess > xStylesFamilies( xStyleFamiliesSupplier->getStyleFamilies() );
1195 41 : if( xStylesFamilies.is() )
1196 : {
1197 41 : if( !xStylesFamilies->hasByName( C2U("PageStyles") ) )
1198 : {
1199 : //draw/impress is parent document
1200 0 : uno::Reference< lang::XMultiServiceFactory > xFatcory( xParentProps, uno::UNO_QUERY );
1201 0 : if( xFatcory.is() )
1202 : {
1203 0 : uno::Reference< beans::XPropertySet > xDrawDefaults( xFatcory->createInstance( C2U( "com.sun.star.drawing.Defaults" ) ), uno::UNO_QUERY );
1204 0 : if( xDrawDefaults.is() )
1205 0 : xDrawDefaults->getPropertyValue( C2U("WritingMode") ) >>= nWritingMode;
1206 0 : }
1207 : }
1208 : else
1209 : {
1210 41 : uno::Reference< container::XNameAccess > xPageStyles( xStylesFamilies->getByName( C2U("PageStyles") ), uno::UNO_QUERY );
1211 41 : if( xPageStyles.is() )
1212 : {
1213 41 : rtl::OUString aPageStyle;
1214 :
1215 41 : uno::Reference< text::XTextDocument > xTextDocument( xParentProps, uno::UNO_QUERY );
1216 41 : if( xTextDocument.is() )
1217 : {
1218 : //writer is parent document
1219 : //retrieve the current page style from the text cursor property PageStyleName
1220 :
1221 0 : uno::Reference< text::XTextEmbeddedObjectsSupplier > xTextEmbeddedObjectsSupplier( xTextDocument, uno::UNO_QUERY );
1222 0 : if( xTextEmbeddedObjectsSupplier.is() )
1223 : {
1224 0 : uno::Reference< container::XNameAccess > xEmbeddedObjects( xTextEmbeddedObjectsSupplier->getEmbeddedObjects() );
1225 0 : if( xEmbeddedObjects.is() )
1226 : {
1227 0 : uno::Sequence< rtl::OUString > aNames( xEmbeddedObjects->getElementNames() );
1228 :
1229 0 : sal_Int32 nCount = aNames.getLength();
1230 0 : for( sal_Int32 nN=0; nN<nCount; nN++ )
1231 : {
1232 0 : uno::Reference< beans::XPropertySet > xEmbeddedProps( xEmbeddedObjects->getByName( aNames[nN] ), uno::UNO_QUERY );
1233 0 : if( xEmbeddedProps.is() )
1234 : {
1235 0 : static rtl::OUString aChartCLSID = rtl::OUString( SvGlobalName( SO3_SCH_CLASSID ).GetHexName());
1236 0 : rtl::OUString aCLSID;
1237 0 : xEmbeddedProps->getPropertyValue( C2U("CLSID") ) >>= aCLSID;
1238 0 : if( aCLSID.equals(aChartCLSID) )
1239 : {
1240 0 : uno::Reference< frame::XModel > xModel;
1241 0 : xEmbeddedProps->getPropertyValue( C2U("Model") ) >>= xModel;
1242 0 : if( xModel == xChartModel )
1243 : {
1244 0 : uno::Reference< text::XTextContent > xEmbeddedObject( xEmbeddedProps, uno::UNO_QUERY );
1245 0 : if( xEmbeddedObject.is() )
1246 : {
1247 0 : uno::Reference< text::XTextRange > xAnchor( xEmbeddedObject->getAnchor() );
1248 0 : if( xAnchor.is() )
1249 : {
1250 0 : uno::Reference< beans::XPropertySet > xAnchorProps( xAnchor, uno::UNO_QUERY );
1251 0 : if( xAnchorProps.is() )
1252 : {
1253 0 : xAnchorProps->getPropertyValue( C2U("WritingMode") ) >>= nWritingMode;
1254 : }
1255 0 : uno::Reference< text::XText > xText( xAnchor->getText() );
1256 0 : if( xText.is() )
1257 : {
1258 0 : uno::Reference< beans::XPropertySet > xTextCursorProps( xText->createTextCursor(), uno::UNO_QUERY );
1259 0 : if( xTextCursorProps.is() )
1260 0 : xTextCursorProps->getPropertyValue( C2U("PageStyleName") ) >>= aPageStyle;
1261 0 : }
1262 0 : }
1263 : }
1264 0 : break;
1265 0 : }
1266 0 : }
1267 : }
1268 0 : }
1269 0 : }
1270 : }
1271 0 : if( aPageStyle.isEmpty() )
1272 : {
1273 0 : uno::Reference< text::XText > xText( xTextDocument->getText() );
1274 0 : if( xText.is() )
1275 : {
1276 0 : uno::Reference< beans::XPropertySet > xTextCursorProps( xText->createTextCursor(), uno::UNO_QUERY );
1277 0 : if( xTextCursorProps.is() )
1278 0 : xTextCursorProps->getPropertyValue( C2U("PageStyleName") ) >>= aPageStyle;
1279 0 : }
1280 0 : }
1281 : }
1282 : else
1283 : {
1284 : //Calc is parent document
1285 41 : xParentProps->getPropertyValue( C2U("PageStyle") ) >>= aPageStyle;
1286 41 : if(aPageStyle.isEmpty())
1287 41 : aPageStyle = C2U("Default");
1288 : }
1289 41 : if( nWritingMode == -1 || nWritingMode == text::WritingMode2::PAGE )
1290 : {
1291 41 : uno::Reference< beans::XPropertySet > xPageStyle( xPageStyles->getByName( aPageStyle ), uno::UNO_QUERY );
1292 41 : if( xPageStyle.is() )
1293 41 : xPageStyle->getPropertyValue( C2U("WritingMode") ) >>= nWritingMode;
1294 41 : }
1295 41 : }
1296 : }
1297 41 : }
1298 41 : }
1299 : }
1300 41 : if( nWritingMode != -1 && nWritingMode != text::WritingMode2::PAGE )
1301 : {
1302 41 : if( pDrawModelWrapper.get() )
1303 41 : pDrawModelWrapper->GetItemPool().SetPoolDefaultItem(SfxInt32Item(EE_PARA_WRITINGDIR, nWritingMode) );
1304 41 : }
1305 : }
1306 0 : catch( const uno::Exception& ex )
1307 : {
1308 : ASSERT_EXCEPTION( ex );
1309 : }
1310 : }
1311 41 : }
1312 :
1313 41 : sal_Int16 lcl_getDefaultWritingModeFromPool( ::boost::shared_ptr< DrawModelWrapper > pDrawModelWrapper )
1314 : {
1315 41 : sal_Int16 nWritingMode = text::WritingMode2::LR_TB;
1316 41 : if( pDrawModelWrapper.get() )
1317 : {
1318 41 : const SfxPoolItem* pItem = &(pDrawModelWrapper->GetItemPool().GetDefaultItem( EE_PARA_WRITINGDIR ));
1319 41 : if( pItem )
1320 41 : nWritingMode = static_cast< sal_Int16 >((static_cast< const SfxInt32Item * >( pItem ))->GetValue());
1321 : }
1322 41 : return nWritingMode;
1323 : }
1324 :
1325 : } //end anonymous namespace
1326 :
1327 : //------------ create complete diagram shape (inclusive axis and series)
1328 :
1329 41 : awt::Rectangle ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlotterContainer
1330 : , const uno::Reference< drawing::XShapes>& xDiagramPlusAxes_Shapes
1331 : , const awt::Point& rAvailablePos
1332 : , const awt::Size& rAvailableSize
1333 : , const awt::Size& rPageSize
1334 : , bool bUseFixedInnerSize
1335 : , const uno::Reference< drawing::XShape>& xDiagram_MarkHandles /*needs to be resized to fit the result*/
1336 : )
1337 : {
1338 : //return the used rectangle
1339 41 : awt::Rectangle aUsedOuterRect( rAvailablePos.X, rAvailablePos.Y, 0, 0 );
1340 :
1341 : // sal_Int32 nDiagramIndex = 0;//todo if more than one diagam is supported
1342 41 : uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartModel ) );
1343 41 : if( !xDiagram.is())
1344 : return aUsedOuterRect;
1345 :
1346 41 : sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
1347 41 : if(!nDimensionCount)
1348 : {
1349 : //@todo handle mixed dimension
1350 0 : nDimensionCount = 2;
1351 : }
1352 :
1353 41 : ::basegfx::B2IRectangle aAvailableOuterRect( BaseGFXHelper::makeRectangle(rAvailablePos,rAvailableSize) );
1354 :
1355 41 : const std::vector< VCoordinateSystem* >& rVCooSysList( rSeriesPlotterContainer.getCooSysList() );
1356 41 : const std::vector< VSeriesPlotter* >& rSeriesPlotterList( rSeriesPlotterContainer.getSeriesPlotterList() );
1357 :
1358 : //create VAxis, so they can give necessary information for automatic scaling
1359 41 : uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( m_xChartModel, uno::UNO_QUERY );
1360 41 : size_t nC = 0;
1361 82 : for( nC=0; nC < rVCooSysList.size(); nC++)
1362 : {
1363 41 : VCoordinateSystem* pVCooSys = rVCooSysList[nC];
1364 41 : if(3==nDimensionCount)
1365 : {
1366 0 : uno::Reference<beans::XPropertySet> xSceneProperties( xDiagram, uno::UNO_QUERY );
1367 0 : CuboidPlanePosition eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( xSceneProperties ) );
1368 0 : CuboidPlanePosition eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( xSceneProperties ) );
1369 0 : CuboidPlanePosition eBottomPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( xSceneProperties ) );
1370 0 : pVCooSys->set3DWallPositions( eLeftWallPos, eBackWallPos, eBottomPos );
1371 : }
1372 : pVCooSys->createVAxisList( xNumberFormatsSupplier
1373 : , rPageSize //font reference size
1374 : , BaseGFXHelper::B2IRectangleToAWTRectangle( aAvailableOuterRect ) //maximum space for labels
1375 41 : );
1376 : }
1377 :
1378 :
1379 : // - prepare list of all axis and how they are used
1380 41 : Date aNullDate = NumberFormatterWrapper( uno::Reference< util::XNumberFormatsSupplier >( m_xChartModel, uno::UNO_QUERY ) ).getNullDate();
1381 41 : rSeriesPlotterContainer.initAxisUsageList(aNullDate);
1382 41 : rSeriesPlotterContainer.doAutoScaling( m_xChartModel );
1383 41 : rSeriesPlotterContainer.setScalesFromCooSysToPlotter();
1384 41 : rSeriesPlotterContainer.setNumberFormatsFromAxes();
1385 :
1386 : //---------------------------------------------------------------------
1387 : //create shapes
1388 :
1389 : //------------ create diagram shapes
1390 : //aspect ratio
1391 : drawing::Direction3D aPreferredAspectRatio(
1392 41 : rSeriesPlotterContainer.getPreferredAspectRatio() );
1393 :
1394 41 : uno::Reference< drawing::XShapes > xSeriesTargetInFrontOfAxis(0);
1395 41 : uno::Reference< drawing::XShapes > xSeriesTargetBehindAxis(0);
1396 41 : VDiagram aVDiagram(xDiagram, aPreferredAspectRatio, nDimensionCount);
1397 : {//create diagram
1398 41 : aVDiagram.init(xDiagramPlusAxes_Shapes,xDiagramPlusAxes_Shapes,m_xShapeFactory);
1399 41 : aVDiagram.createShapes(rAvailablePos,rAvailableSize);
1400 41 : xSeriesTargetInFrontOfAxis = aVDiagram.getCoordinateRegion();
1401 41 : if( !bUseFixedInnerSize )
1402 41 : aVDiagram.reduceToMimimumSize();
1403 : }
1404 :
1405 41 : uno::Reference< drawing::XShapes > xTextTargetShapes( ShapeFactory(m_xShapeFactory).createGroup2D(xDiagramPlusAxes_Shapes) );
1406 :
1407 : // - create axis and grids for all coordinate systems
1408 :
1409 : //init all coordinate systems
1410 82 : for( nC=0; nC < rVCooSysList.size(); nC++)
1411 : {
1412 41 : VCoordinateSystem* pVCooSys = rVCooSysList[nC];
1413 41 : pVCooSys->initPlottingTargets(xSeriesTargetInFrontOfAxis,xTextTargetShapes,m_xShapeFactory,xSeriesTargetBehindAxis);
1414 :
1415 : pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
1416 41 : createTransformationSceneToScreen( aVDiagram.getCurrentRectangle() ) ));
1417 :
1418 41 : pVCooSys->initVAxisInList();
1419 : }
1420 :
1421 : //calculate resulting size respecting axis label layout and fontscaling
1422 :
1423 41 : uno::Reference< drawing::XShape > xBoundingShape( xDiagramPlusAxes_Shapes, uno::UNO_QUERY );
1424 41 : ::basegfx::B2IRectangle aConsumedOuterRect;
1425 :
1426 : //use first coosys only so far; todo: calculate for more than one coosys if we have more in future
1427 : //todo: this is just a workaround at the moment for pie and donut labels
1428 41 : bool bIsPieOrDonut = lcl_IsPieOrDonut(xDiagram);
1429 41 : if( !bIsPieOrDonut && (!rVCooSysList.empty()) )
1430 : {
1431 41 : VCoordinateSystem* pVCooSys = rVCooSysList[0];
1432 41 : pVCooSys->createMaximumAxesLabels();
1433 :
1434 41 : aConsumedOuterRect = ::basegfx::B2IRectangle( ShapeFactory::getRectangleOfShape(xBoundingShape) );
1435 41 : ::basegfx::B2IRectangle aNewInnerRect( aVDiagram.getCurrentRectangle() );
1436 41 : if( !bUseFixedInnerSize )
1437 41 : aNewInnerRect = aVDiagram.adjustInnerSize( aConsumedOuterRect );
1438 :
1439 : pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
1440 41 : createTransformationSceneToScreen( aNewInnerRect ) ));
1441 :
1442 : //redo autoscaling to get size and text dependent automatic main increment count
1443 41 : rSeriesPlotterContainer.doAutoScaling( m_xChartModel );
1444 41 : rSeriesPlotterContainer.updateScalesAndIncrementsOnAxes();
1445 41 : rSeriesPlotterContainer.setScalesFromCooSysToPlotter();
1446 :
1447 41 : pVCooSys->createAxesLabels();
1448 :
1449 41 : bool bLessSpaceConsumedThanExpected = false;
1450 : {
1451 41 : aConsumedOuterRect = ShapeFactory::getRectangleOfShape(xBoundingShape);
1452 85 : if( aConsumedOuterRect.getMinX() > aAvailableOuterRect.getMinX()
1453 41 : || aConsumedOuterRect.getMaxX() < aAvailableOuterRect.getMaxX()
1454 2 : || aConsumedOuterRect.getMinY() > aAvailableOuterRect.getMinY()
1455 1 : || aConsumedOuterRect.getMinY() < aAvailableOuterRect.getMaxY() )
1456 41 : bLessSpaceConsumedThanExpected = true;
1457 : }
1458 :
1459 41 : if( bLessSpaceConsumedThanExpected && !bUseFixedInnerSize )
1460 : {
1461 41 : aVDiagram.adjustInnerSize( aConsumedOuterRect );
1462 : pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
1463 41 : createTransformationSceneToScreen( aVDiagram.getCurrentRectangle() ) ));
1464 : }
1465 41 : pVCooSys->updatePositions();//todo: logically this belongs to the condition above, but it seems also to be neccessary to give the axes group shapes the right bounding rects for hit test - probably caused by bug i106183 -> check again if fixed
1466 : }
1467 :
1468 : //create axes and grids for the final size
1469 82 : for( nC=0; nC < rVCooSysList.size(); nC++)
1470 : {
1471 41 : VCoordinateSystem* pVCooSys = rVCooSysList[nC];
1472 :
1473 : pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
1474 41 : createTransformationSceneToScreen( aVDiagram.getCurrentRectangle() ) ));
1475 :
1476 41 : pVCooSys->createAxesShapes();
1477 41 : pVCooSys->createGridShapes();
1478 : }
1479 :
1480 : // - create data series for all charttypes
1481 41 : m_bPointsWereSkipped = false;
1482 41 : ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = rSeriesPlotterList.begin();
1483 41 : const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = rSeriesPlotterList.end();
1484 82 : for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
1485 : {
1486 : //------------ set transformation to plotter / create series
1487 41 : VSeriesPlotter* pSeriesPlotter = *aPlotterIter;
1488 41 : rtl::OUString aCID; //III
1489 41 : uno::Reference< drawing::XShapes > xSeriesTarget(0);
1490 41 : if( pSeriesPlotter->WantToPlotInFrontOfAxisLine() )
1491 41 : xSeriesTarget = xSeriesTargetInFrontOfAxis;
1492 : else
1493 : {
1494 0 : xSeriesTarget = xSeriesTargetBehindAxis;
1495 : OSL_ENSURE( !bIsPieOrDonut, "not implemented yet! - during a complete recreation this shape is destroyed so no series can be created anymore" );
1496 : }
1497 41 : pSeriesPlotter->initPlotter( xSeriesTarget,xTextTargetShapes,m_xShapeFactory,aCID );
1498 41 : pSeriesPlotter->setPageReferenceSize( rPageSize );
1499 41 : VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( rVCooSysList, pSeriesPlotter );
1500 41 : if(2==nDimensionCount)
1501 41 : pSeriesPlotter->setTransformationSceneToScreen( pVCooSys->getTransformationSceneToScreen() );
1502 : //better performance for big data
1503 41 : awt::Size aCoordinateRegionResolution(1000,1000);
1504 : {
1505 : //calculate resolution for coordinate system
1506 41 : Sequence<sal_Int32> aCoordinateSystemResolution = pVCooSys->getCoordinateSystemResolution( rPageSize, m_aPageResolution );
1507 41 : pSeriesPlotter->setCoordinateSystemResolution( aCoordinateSystemResolution );
1508 : }
1509 : //
1510 41 : pSeriesPlotter->createShapes();
1511 41 : m_bPointsWereSkipped = m_bPointsWereSkipped || pSeriesPlotter->PointsWereSkipped();
1512 41 : }
1513 :
1514 : //recreate all with corrected sizes if requested
1515 41 : if( bIsPieOrDonut )
1516 : {
1517 0 : m_bPointsWereSkipped = false;
1518 :
1519 0 : aConsumedOuterRect = ::basegfx::B2IRectangle( ShapeFactory::getRectangleOfShape(xBoundingShape) );
1520 0 : ::basegfx::B2IRectangle aNewInnerRect( aVDiagram.getCurrentRectangle() );
1521 0 : if( !bUseFixedInnerSize )
1522 0 : aNewInnerRect = aVDiagram.adjustInnerSize( aConsumedOuterRect );
1523 :
1524 0 : for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
1525 : {
1526 0 : VSeriesPlotter* pSeriesPlotter = *aPlotterIter;
1527 0 : pSeriesPlotter->releaseShapes();
1528 : }
1529 :
1530 : //clear and recreate
1531 0 : ShapeFactory::removeSubShapes( xSeriesTargetInFrontOfAxis ); //xSeriesTargetBehindAxis is a sub shape of xSeriesTargetInFrontOfAxis and will be removed here
1532 0 : xSeriesTargetBehindAxis.clear();
1533 0 : ShapeFactory::removeSubShapes( xTextTargetShapes );
1534 :
1535 : //set new transformation
1536 0 : for( nC=0; nC < rVCooSysList.size(); nC++)
1537 : {
1538 0 : VCoordinateSystem* pVCooSys = rVCooSysList[nC];
1539 : pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
1540 0 : createTransformationSceneToScreen( aNewInnerRect ) ));
1541 : }
1542 :
1543 : // - create data series for all charttypes
1544 0 : for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
1545 : {
1546 : //------------ set transformation to plotter / create series
1547 0 : VSeriesPlotter* pSeriesPlotter = *aPlotterIter;
1548 0 : VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( rVCooSysList, pSeriesPlotter );
1549 0 : if(2==nDimensionCount)
1550 0 : pSeriesPlotter->setTransformationSceneToScreen( pVCooSys->getTransformationSceneToScreen() );
1551 0 : pSeriesPlotter->createShapes();
1552 0 : m_bPointsWereSkipped = m_bPointsWereSkipped || pSeriesPlotter->PointsWereSkipped();
1553 : }
1554 :
1555 0 : for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
1556 : {
1557 0 : VSeriesPlotter* pSeriesPlotter = *aPlotterIter;
1558 0 : pSeriesPlotter->rearrangeLabelToAvoidOverlapIfRequested( rPageSize );
1559 : }
1560 : }
1561 :
1562 41 : if( bUseFixedInnerSize )
1563 : {
1564 0 : aUsedOuterRect = awt::Rectangle( aConsumedOuterRect.getMinX(), aConsumedOuterRect.getMinY(), aConsumedOuterRect.getWidth(), aConsumedOuterRect.getHeight() );
1565 : }
1566 : else
1567 41 : aUsedOuterRect = awt::Rectangle( rAvailablePos.X, rAvailablePos.Y, rAvailableSize.Width, rAvailableSize.Height );
1568 :
1569 41 : bool bSnapRectToUsedArea = false;
1570 41 : for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
1571 : {
1572 41 : VSeriesPlotter* pSeriesPlotter = *aPlotterIter;
1573 41 : bSnapRectToUsedArea = pSeriesPlotter->shouldSnapRectToUsedArea();
1574 41 : if(bSnapRectToUsedArea)
1575 41 : break;
1576 : }
1577 41 : if(bSnapRectToUsedArea)
1578 : {
1579 41 : if( bUseFixedInnerSize )
1580 0 : m_aResultingDiagramRectangleExcludingAxes = getRectangleOfObject( C2U("PlotAreaExcludingAxes") );
1581 : else
1582 : {
1583 41 : ::basegfx::B2IRectangle aConsumedInnerRect = aVDiagram.getCurrentRectangle();
1584 41 : m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle( aConsumedInnerRect.getMinX(), aConsumedInnerRect.getMinY(), aConsumedInnerRect.getWidth(), aConsumedInnerRect.getHeight() );
1585 : }
1586 : }
1587 : else
1588 : {
1589 0 : if( bUseFixedInnerSize )
1590 0 : m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle( rAvailablePos.X, rAvailablePos.Y, rAvailableSize.Width, rAvailableSize.Height );
1591 : else
1592 : {
1593 0 : ::basegfx::B2IRectangle aConsumedInnerRect = aVDiagram.getCurrentRectangle();
1594 0 : m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle( aConsumedInnerRect.getMinX(), aConsumedInnerRect.getMinY(), aConsumedInnerRect.getWidth(), aConsumedInnerRect.getHeight() );
1595 : }
1596 : }
1597 :
1598 41 : if( xDiagram_MarkHandles.is() )
1599 : {
1600 41 : awt::Point aPos(rAvailablePos);
1601 41 : awt::Size aSize(rAvailableSize);
1602 41 : bool bPosSizeExcludeAxesProperty = true;
1603 41 : uno::Reference< beans::XPropertySet > xDiaProps( xDiagram, uno::UNO_QUERY_THROW );
1604 41 : if( xDiaProps.is() )
1605 41 : xDiaProps->getPropertyValue(C2U("PosSizeExcludeAxes")) >>= bPosSizeExcludeAxesProperty;
1606 41 : if( bUseFixedInnerSize || bPosSizeExcludeAxesProperty )
1607 : {
1608 41 : aPos = awt::Point( m_aResultingDiagramRectangleExcludingAxes.X, m_aResultingDiagramRectangleExcludingAxes.Y );
1609 41 : aSize = awt::Size( m_aResultingDiagramRectangleExcludingAxes.Width, m_aResultingDiagramRectangleExcludingAxes.Height );
1610 : }
1611 41 : xDiagram_MarkHandles->setPosition( aPos );
1612 41 : xDiagram_MarkHandles->setSize( aSize );
1613 : }
1614 :
1615 41 : return aUsedOuterRect;
1616 : }
1617 :
1618 : //-------------------------------------------------------------
1619 : //-------------------------------------------------------------
1620 : //-------------------------------------------------------------
1621 :
1622 0 : sal_Bool ChartView::getExplicitValuesForAxis(
1623 : uno::Reference< XAxis > xAxis
1624 : , ExplicitScaleData& rExplicitScale
1625 : , ExplicitIncrementData& rExplicitIncrement )
1626 : {
1627 0 : impl_updateView();
1628 :
1629 0 : if(!xAxis.is())
1630 0 : return sal_False;
1631 :
1632 0 : uno::Reference< XCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis(xAxis,ChartModelHelper::findDiagram( m_xChartModel ) ) );
1633 0 : const VCoordinateSystem* pVCooSys = findInCooSysList(m_aVCooSysList,xCooSys);
1634 0 : if(!pVCooSys)
1635 0 : return sal_False;
1636 :
1637 0 : sal_Int32 nDimensionIndex=-1;
1638 0 : sal_Int32 nAxisIndex=-1;
1639 0 : if( AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex ) )
1640 : {
1641 0 : rExplicitScale = pVCooSys->getExplicitScale(nDimensionIndex,nAxisIndex);
1642 0 : rExplicitIncrement = pVCooSys->getExplicitIncrement(nDimensionIndex,nAxisIndex);
1643 0 : if( rExplicitScale.ShiftedCategoryPosition )
1644 : {
1645 : //remove 'one' from max
1646 0 : if( rExplicitScale.AxisType == ::com::sun::star::chart2::AxisType::DATE )
1647 : {
1648 0 : Date aMaxDate(rExplicitScale.NullDate); aMaxDate += static_cast<long>(::rtl::math::approxFloor(rExplicitScale.Maximum));
1649 : //for explicit scales with shifted categories we need one interval more
1650 0 : switch( rExplicitScale.TimeResolution )
1651 : {
1652 : case ::com::sun::star::chart::TimeUnit::DAY:
1653 0 : aMaxDate--;break;
1654 : case ::com::sun::star::chart::TimeUnit::MONTH:
1655 0 : aMaxDate = DateHelper::GetDateSomeMonthsAway(aMaxDate,-1);
1656 0 : break;
1657 : case ::com::sun::star::chart::TimeUnit::YEAR:
1658 0 : aMaxDate = DateHelper::GetDateSomeYearsAway(aMaxDate,-1);
1659 0 : break;
1660 : }
1661 0 : rExplicitScale.Maximum = aMaxDate - rExplicitScale.NullDate;
1662 : }
1663 0 : else if( rExplicitScale.AxisType == ::com::sun::star::chart2::AxisType::CATEGORY )
1664 0 : rExplicitScale.Maximum -= 1.0;
1665 0 : else if( rExplicitScale.AxisType == ::com::sun::star::chart2::AxisType::SERIES )
1666 0 : rExplicitScale.Maximum -= 1.0;
1667 : }
1668 0 : return sal_True;
1669 : }
1670 0 : return sal_False;
1671 : }
1672 :
1673 61 : SdrPage* ChartView::getSdrPage()
1674 : {
1675 61 : SdrPage* pPage=0;
1676 61 : Reference< lang::XUnoTunnel> xUnoTunnel(m_xDrawPage,uno::UNO_QUERY);
1677 61 : if(xUnoTunnel.is())
1678 : {
1679 61 : SvxDrawPage* pSvxDrawPage = reinterpret_cast<SvxDrawPage*>(xUnoTunnel->getSomething(
1680 61 : SvxDrawPage::getUnoTunnelId() ));
1681 61 : if(pSvxDrawPage)
1682 : {
1683 61 : pPage = pSvxDrawPage->GetSdrPage();
1684 : }
1685 : }
1686 61 : return pPage;
1687 : }
1688 :
1689 20 : uno::Reference< drawing::XShape > ChartView::getShapeForCID( const rtl::OUString& rObjectCID )
1690 : {
1691 20 : SolarMutexGuard aSolarGuard;
1692 20 : SdrObject* pObj = DrawModelWrapper::getNamedSdrObject( rObjectCID, this->getSdrPage() );
1693 20 : if( pObj )
1694 0 : return uno::Reference< drawing::XShape >( pObj->getUnoShape(), uno::UNO_QUERY);
1695 20 : return 0;
1696 : }
1697 :
1698 0 : awt::Rectangle ChartView::getDiagramRectangleExcludingAxes()
1699 : {
1700 0 : impl_updateView();
1701 0 : return m_aResultingDiagramRectangleExcludingAxes;
1702 : }
1703 :
1704 20 : awt::Rectangle ChartView::getRectangleOfObject( const rtl::OUString& rObjectCID, bool bSnapRect )
1705 : {
1706 20 : impl_updateView();
1707 :
1708 20 : awt::Rectangle aRet;
1709 20 : uno::Reference< drawing::XShape > xShape( getShapeForCID(rObjectCID) );
1710 20 : if(xShape.is())
1711 : {
1712 : //special handling for axis for old api:
1713 : //same special handling for diagram
1714 0 : ObjectType eObjectType( ObjectIdentifier::getObjectType( rObjectCID ) );
1715 0 : if( eObjectType == OBJECTTYPE_AXIS || eObjectType == OBJECTTYPE_DIAGRAM )
1716 : {
1717 0 : SolarMutexGuard aSolarGuard;
1718 0 : SvxShape* pRoot = SvxShape::getImplementation( xShape );
1719 0 : if( pRoot )
1720 : {
1721 0 : SdrObject* pRootSdrObject = pRoot->GetSdrObject();
1722 0 : if( pRootSdrObject )
1723 : {
1724 0 : SdrObjList* pRootList = pRootSdrObject->GetSubList();
1725 0 : if( pRootList )
1726 : {
1727 0 : OUString aShapeName = C2U("MarkHandles");
1728 0 : if( eObjectType == OBJECTTYPE_DIAGRAM )
1729 0 : aShapeName = C2U("PlotAreaIncludingAxes");
1730 0 : SdrObject* pShape = DrawModelWrapper::getNamedSdrObject( aShapeName, pRootList );
1731 0 : if( pShape )
1732 0 : xShape = uno::Reference< drawing::XShape >( pShape->getUnoShape(), uno::UNO_QUERY);
1733 : }
1734 : }
1735 0 : }
1736 : }
1737 :
1738 0 : awt::Size aSize( xShape->getSize() );
1739 0 : awt::Point aPoint( xShape->getPosition() );
1740 0 : aRet = awt::Rectangle( aPoint.X, aPoint.Y, aSize.Width, aSize.Height );
1741 0 : if( bSnapRect )
1742 : {
1743 : //for rotated objects the shape size and position differs from the visible rectangle
1744 0 : SvxShape* pShape = SvxShape::getImplementation( xShape );
1745 0 : if( pShape )
1746 : {
1747 0 : SdrObject* pSdrObject = pShape->GetSdrObject();
1748 0 : if( pSdrObject )
1749 : {
1750 0 : Rectangle aSnapRect( pSdrObject->GetSnapRect() );
1751 0 : aRet = awt::Rectangle(aSnapRect.Left(),aSnapRect.Top(),aSnapRect.GetWidth(),aSnapRect.GetHeight());
1752 : }
1753 : }
1754 : }
1755 : }
1756 20 : return aRet;
1757 : }
1758 :
1759 120 : ::boost::shared_ptr< DrawModelWrapper > ChartView::getDrawModelWrapper()
1760 : {
1761 120 : return m_pDrawModelWrapper;
1762 : }
1763 :
1764 : namespace
1765 : {
1766 0 : sal_Int32 lcl_getDiagramTitleSpace()
1767 : {
1768 0 : return 200; //=0,2 cm spacing
1769 : }
1770 0 : bool lcl_getPropertySwapXAndYAxis( const uno::Reference< XDiagram >& xDiagram )
1771 : {
1772 0 : bool bSwapXAndY = false;
1773 :
1774 0 : uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
1775 0 : if( xCooSysContainer.is() )
1776 : {
1777 0 : uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
1778 0 : if( aCooSysList.getLength() )
1779 : {
1780 0 : uno::Reference<beans::XPropertySet> xProp(aCooSysList[0], uno::UNO_QUERY );
1781 0 : if( xProp.is()) try
1782 : {
1783 0 : xProp->getPropertyValue( C2U( "SwapXAndYAxis" ) ) >>= bSwapXAndY;
1784 : }
1785 0 : catch( const uno::Exception& e )
1786 : {
1787 : ASSERT_EXCEPTION( e );
1788 0 : }
1789 0 : }
1790 : }
1791 0 : return bSwapXAndY;
1792 : }
1793 :
1794 : }
1795 :
1796 82 : sal_Int32 ExplicitValueProvider::getExplicitNumberFormatKeyForAxis(
1797 : const Reference< chart2::XAxis >& xAxis
1798 : , const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem
1799 : , const Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier )
1800 : {
1801 : return AxisHelper::getExplicitNumberFormatKeyForAxis( xAxis, xCorrespondingCoordinateSystem, xNumberFormatsSupplier
1802 82 : , true /*bSearchForParallelAxisIfNothingIsFound*/ );
1803 : }
1804 :
1805 0 : sal_Int32 ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel(
1806 : const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp,
1807 : const uno::Reference< XDataSeries >& xSeries,
1808 : sal_Int32 nPointIndex /*-1 for whole series*/,
1809 : const uno::Reference< XDiagram >& xDiagram
1810 : )
1811 : {
1812 0 : sal_Int32 nFormat=0;
1813 0 : if( !xSeriesOrPointProp.is() )
1814 0 : return nFormat;
1815 :
1816 0 : rtl::OUString aPropName( C2U( "NumberFormat" ) );
1817 0 : if( !(xSeriesOrPointProp->getPropertyValue(aPropName) >>= nFormat) )
1818 : {
1819 0 : uno::Reference< chart2::XChartType > xChartType( DataSeriesHelper::getChartTypeOfSeries( xSeries, xDiagram ) );
1820 :
1821 0 : bool bFormatFound = false;
1822 0 : if( ChartTypeHelper::shouldLabelNumberFormatKeyBeDetectedFromYAxis( xChartType ) )
1823 : {
1824 0 : uno::Reference< beans::XPropertySet > xAttachedAxisProps( DiagramHelper::getAttachedAxis( xSeries, xDiagram ), uno::UNO_QUERY );
1825 0 : if( xAttachedAxisProps.is() && ( xAttachedAxisProps->getPropertyValue( aPropName ) >>= nFormat ) )
1826 0 : bFormatFound = true;
1827 : }
1828 0 : if( !bFormatFound )
1829 : {
1830 0 : Reference< chart2::data::XDataSource > xSeriesSource( xSeries, uno::UNO_QUERY );
1831 0 : OUString aRole( ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( xChartType ) );
1832 :
1833 : Reference< data::XLabeledDataSequence > xLabeledSequence(
1834 0 : DataSeriesHelper::getDataSequenceByRole( xSeriesSource, aRole, false ));
1835 0 : if( xLabeledSequence.is() )
1836 : {
1837 0 : Reference< data::XDataSequence > xValues( xLabeledSequence->getValues() );
1838 0 : if( xValues.is() )
1839 0 : nFormat = xValues->getNumberFormatKeyByIndex( nPointIndex );
1840 0 : }
1841 0 : }
1842 : }
1843 0 : if(nFormat<0)
1844 0 : nFormat=0;
1845 0 : return nFormat;
1846 : }
1847 :
1848 0 : sal_Int32 ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabel(
1849 : const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp,
1850 : const uno::Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier )
1851 : {
1852 0 : sal_Int32 nFormat=0;
1853 0 : if( !xSeriesOrPointProp.is() )
1854 0 : return nFormat;
1855 0 : if( !(xSeriesOrPointProp->getPropertyValue(C2U( "PercentageNumberFormat" )) >>= nFormat) )
1856 : {
1857 0 : nFormat = DiagramHelper::getPercentNumberFormat( xNumberFormatsSupplier );
1858 : }
1859 0 : if(nFormat<0)
1860 0 : nFormat=0;
1861 0 : return nFormat;
1862 : }
1863 :
1864 0 : awt::Rectangle ExplicitValueProvider::addAxisTitleSizes(
1865 : const Reference< frame::XModel >& xChartModel
1866 : , const Reference< uno::XInterface >& xChartView
1867 : , const awt::Rectangle& rExcludingPositionAndSize )
1868 : {
1869 0 : awt::Rectangle aRet(rExcludingPositionAndSize);
1870 :
1871 : //add axis title sizes to the diagram size
1872 0 : uno::Reference< chart2::XTitle > xTitle_Height( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, xChartModel ) );
1873 0 : uno::Reference< chart2::XTitle > xTitle_Width( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION, xChartModel ) );
1874 0 : uno::Reference< chart2::XTitle > xSecondTitle_Height( TitleHelper::getTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, xChartModel ) );
1875 0 : uno::Reference< chart2::XTitle > xSecondTitle_Width( TitleHelper::getTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, xChartModel ) );
1876 0 : if( xTitle_Height.is() || xTitle_Width.is() || xSecondTitle_Height.is() || xSecondTitle_Width.is() )
1877 : {
1878 0 : ExplicitValueProvider* pExplicitValueProvider = ExplicitValueProvider::getExplicitValueProvider(xChartView);
1879 0 : if( pExplicitValueProvider )
1880 : {
1881 : //detect whether x axis points into x direction or not
1882 0 : if( lcl_getPropertySwapXAndYAxis( ChartModelHelper::findDiagram( xChartModel ) ) )
1883 : {
1884 0 : std::swap( xTitle_Height, xTitle_Width );
1885 0 : std::swap( xSecondTitle_Height, xSecondTitle_Width );
1886 : }
1887 :
1888 0 : sal_Int32 nTitleSpaceWidth = 0;
1889 0 : sal_Int32 nTitleSpaceHeight = 0;
1890 0 : sal_Int32 nSecondTitleSpaceWidth = 0;
1891 0 : sal_Int32 nSecondTitleSpaceHeight = 0;
1892 :
1893 0 : if( xTitle_Height.is() )
1894 : {
1895 0 : rtl::OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Height, xChartModel ) );
1896 0 : nTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height;
1897 0 : if( nTitleSpaceHeight )
1898 0 : nTitleSpaceHeight+=lcl_getDiagramTitleSpace();
1899 : }
1900 0 : if( xTitle_Width.is() )
1901 : {
1902 0 : rtl::OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Width, xChartModel ) );
1903 0 : nTitleSpaceWidth = pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width;
1904 0 : if(nTitleSpaceWidth)
1905 0 : nTitleSpaceWidth+=lcl_getDiagramTitleSpace();
1906 : }
1907 0 : if( xSecondTitle_Height.is() )
1908 : {
1909 0 : rtl::OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Height, xChartModel ) );
1910 0 : nSecondTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height;
1911 0 : if( nSecondTitleSpaceHeight )
1912 0 : nSecondTitleSpaceHeight+=lcl_getDiagramTitleSpace();
1913 : }
1914 0 : if( xSecondTitle_Width.is() )
1915 : {
1916 0 : rtl::OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Width, xChartModel ) );
1917 0 : nSecondTitleSpaceWidth += pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width;
1918 0 : if( nSecondTitleSpaceWidth )
1919 0 : nSecondTitleSpaceWidth+=lcl_getDiagramTitleSpace();
1920 : }
1921 :
1922 0 : aRet.X -= nTitleSpaceWidth;
1923 0 : aRet.Y -= nSecondTitleSpaceHeight;
1924 0 : aRet.Width += nTitleSpaceWidth + nSecondTitleSpaceWidth;
1925 0 : aRet.Height += nTitleSpaceHeight + nSecondTitleSpaceHeight;
1926 : }
1927 : }
1928 0 : return aRet;
1929 : }
1930 :
1931 0 : awt::Rectangle ExplicitValueProvider::substractAxisTitleSizes(
1932 : const Reference< frame::XModel >& xChartModel
1933 : , const Reference< uno::XInterface >& xChartView
1934 : , const awt::Rectangle& rPositionAndSizeIncludingTitles )
1935 : {
1936 0 : awt::Rectangle aRet(rPositionAndSizeIncludingTitles);
1937 :
1938 : //add axis title sizes to the diagram size
1939 0 : uno::Reference< chart2::XTitle > xTitle_Height( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, xChartModel ) );
1940 0 : uno::Reference< chart2::XTitle > xTitle_Width( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION, xChartModel ) );
1941 0 : uno::Reference< chart2::XTitle > xSecondTitle_Height( TitleHelper::getTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, xChartModel ) );
1942 0 : uno::Reference< chart2::XTitle > xSecondTitle_Width( TitleHelper::getTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, xChartModel ) );
1943 0 : if( xTitle_Height.is() || xTitle_Width.is() || xSecondTitle_Height.is() || xSecondTitle_Width.is() )
1944 : {
1945 0 : ExplicitValueProvider* pExplicitValueProvider = ExplicitValueProvider::getExplicitValueProvider(xChartView);
1946 0 : if( pExplicitValueProvider )
1947 : {
1948 : //detect whether x axis points into x direction or not
1949 0 : if( lcl_getPropertySwapXAndYAxis( ChartModelHelper::findDiagram( xChartModel ) ) )
1950 : {
1951 0 : std::swap( xTitle_Height, xTitle_Width );
1952 0 : std::swap( xSecondTitle_Height, xSecondTitle_Width );
1953 : }
1954 :
1955 0 : sal_Int32 nTitleSpaceWidth = 0;
1956 0 : sal_Int32 nTitleSpaceHeight = 0;
1957 0 : sal_Int32 nSecondTitleSpaceWidth = 0;
1958 0 : sal_Int32 nSecondTitleSpaceHeight = 0;
1959 :
1960 0 : if( xTitle_Height.is() )
1961 : {
1962 0 : rtl::OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Height, xChartModel ) );
1963 0 : nTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height;
1964 0 : if( nTitleSpaceHeight )
1965 0 : nTitleSpaceHeight+=lcl_getDiagramTitleSpace();
1966 : }
1967 0 : if( xTitle_Width.is() )
1968 : {
1969 0 : rtl::OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Width, xChartModel ) );
1970 0 : nTitleSpaceWidth = pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width;
1971 0 : if(nTitleSpaceWidth)
1972 0 : nTitleSpaceWidth+=lcl_getDiagramTitleSpace();
1973 : }
1974 0 : if( xSecondTitle_Height.is() )
1975 : {
1976 0 : rtl::OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Height, xChartModel ) );
1977 0 : nSecondTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height;
1978 0 : if( nSecondTitleSpaceHeight )
1979 0 : nSecondTitleSpaceHeight+=lcl_getDiagramTitleSpace();
1980 : }
1981 0 : if( xSecondTitle_Width.is() )
1982 : {
1983 0 : rtl::OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Width, xChartModel ) );
1984 0 : nSecondTitleSpaceWidth += pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width;
1985 0 : if( nSecondTitleSpaceWidth )
1986 0 : nSecondTitleSpaceWidth+=lcl_getDiagramTitleSpace();
1987 : }
1988 :
1989 0 : aRet.X += nTitleSpaceWidth;
1990 0 : aRet.Y += nSecondTitleSpaceHeight;
1991 0 : aRet.Width -= (nTitleSpaceWidth + nSecondTitleSpaceWidth);
1992 0 : aRet.Height -= (nTitleSpaceHeight + nSecondTitleSpaceHeight);
1993 : }
1994 : }
1995 0 : return aRet;
1996 : }
1997 :
1998 328 : double lcl_getPageLayoutDistancePercentage()
1999 : {
2000 328 : return 0.02;
2001 : }
2002 :
2003 41 : bool getAvailablePosAndSizeForDiagram(
2004 : awt::Point& rOutPos, awt::Size& rOutAvailableDiagramSize
2005 : , const awt::Rectangle& rSpaceLeft
2006 : , const awt::Size & rPageSize
2007 : , const uno::Reference< XDiagram > & xDiagram
2008 : , bool& bUseFixedInnerSize )
2009 : {
2010 41 : bUseFixedInnerSize = false;
2011 :
2012 : //@todo: we need a size dependent on the axis labels
2013 41 : awt::Rectangle aRemainingSpace(rSpaceLeft);
2014 : {
2015 41 : sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height*lcl_getPageLayoutDistancePercentage());
2016 41 : sal_Int32 nXDistance = static_cast<sal_Int32>(rPageSize.Width*lcl_getPageLayoutDistancePercentage());
2017 41 : aRemainingSpace.X+=nXDistance;
2018 41 : aRemainingSpace.Width-=2*nXDistance;
2019 41 : aRemainingSpace.Y+=nYDistance;
2020 41 : aRemainingSpace.Height-=2*nYDistance;
2021 : }
2022 41 : if(aRemainingSpace.Width <= 0 || aRemainingSpace.Height <= 0 )
2023 0 : return false;
2024 :
2025 41 : uno::Reference< beans::XPropertySet > xProp(xDiagram, uno::UNO_QUERY);
2026 :
2027 41 : bool bPosSizeExcludeAxes = false;
2028 41 : if( xProp.is() )
2029 41 : xProp->getPropertyValue( C2U( "PosSizeExcludeAxes" ) ) >>= bPosSizeExcludeAxes;
2030 :
2031 : //size:
2032 41 : ::com::sun::star::chart2::RelativeSize aRelativeSize;
2033 41 : if( xProp.is() && (xProp->getPropertyValue( C2U( "RelativeSize" ) )>>=aRelativeSize) )
2034 : {
2035 0 : rOutAvailableDiagramSize.Height = static_cast<sal_Int32>(aRelativeSize.Secondary*rPageSize.Height);
2036 0 : rOutAvailableDiagramSize.Width = static_cast<sal_Int32>(aRelativeSize.Primary*rPageSize.Width);
2037 0 : bUseFixedInnerSize = bPosSizeExcludeAxes;
2038 : }
2039 : else
2040 41 : rOutAvailableDiagramSize = awt::Size(aRemainingSpace.Width,aRemainingSpace.Height);
2041 :
2042 : //position:
2043 41 : chart2::RelativePosition aRelativePosition;
2044 41 : if( xProp.is() && (xProp->getPropertyValue( C2U( "RelativePosition" ) )>>=aRelativePosition) )
2045 : {
2046 : //@todo decide whether x is primary or secondary
2047 :
2048 : //the coordinates re relative to the page
2049 0 : double fX = aRelativePosition.Primary*rPageSize.Width;
2050 0 : double fY = aRelativePosition.Secondary*rPageSize.Height;
2051 :
2052 : rOutPos = RelativePositionHelper::getUpperLeftCornerOfAnchoredObject(
2053 : awt::Point(static_cast<sal_Int32>(fX),static_cast<sal_Int32>(fY))
2054 0 : , rOutAvailableDiagramSize, aRelativePosition.Anchor );
2055 0 : bUseFixedInnerSize = bPosSizeExcludeAxes;
2056 : }
2057 : else
2058 41 : rOutPos = awt::Point(aRemainingSpace.X,aRemainingSpace.Y);
2059 :
2060 : //ensure that the diagram does not lap out right side or out of bottom
2061 : {
2062 41 : if( rOutPos.Y + rOutAvailableDiagramSize.Height > rPageSize.Height )
2063 0 : rOutAvailableDiagramSize.Height = rPageSize.Height - rOutPos.Y;
2064 41 : if( rOutPos.X + rOutAvailableDiagramSize.Width > rPageSize.Width )
2065 0 : rOutAvailableDiagramSize.Width = rPageSize.Width - rOutPos.X;
2066 : }
2067 :
2068 41 : return true;
2069 : }
2070 :
2071 : enum TitleAlignment { ALIGN_LEFT, ALIGN_TOP, ALIGN_RIGHT, ALIGN_BOTTOM, ALIGN_Z };
2072 :
2073 205 : void changePositionOfAxisTitle( VTitle* pVTitle, TitleAlignment eAlignment
2074 : , awt::Rectangle& rDiagramPlusAxesRect, const awt::Size & rPageSize )
2075 : {
2076 205 : if(!pVTitle)
2077 205 : return;
2078 :
2079 0 : awt::Point aNewPosition(0,0);
2080 0 : awt::Size aTitleSize = pVTitle->getFinalSize();
2081 0 : sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height*lcl_getPageLayoutDistancePercentage());
2082 0 : sal_Int32 nXDistance = static_cast<sal_Int32>(rPageSize.Width*lcl_getPageLayoutDistancePercentage());
2083 0 : switch( eAlignment )
2084 : {
2085 : case ALIGN_TOP:
2086 : aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width/2
2087 0 : , rDiagramPlusAxesRect.Y - aTitleSize.Height/2 - nYDistance );
2088 0 : break;
2089 : case ALIGN_BOTTOM:
2090 : aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width/2
2091 0 : , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height + aTitleSize.Height/2 + nYDistance );
2092 0 : break;
2093 : case ALIGN_LEFT:
2094 : aNewPosition = awt::Point( rDiagramPlusAxesRect.X - aTitleSize.Width/2 - nXDistance
2095 0 : , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height/2 );
2096 0 : break;
2097 : case ALIGN_RIGHT:
2098 : aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width + aTitleSize.Width/2 + nXDistance
2099 0 : , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height/2 );
2100 0 : break;
2101 : case ALIGN_Z:
2102 : aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width + aTitleSize.Width/2 + nXDistance
2103 0 : , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height - aTitleSize.Height/2 );
2104 0 : break;
2105 : default:
2106 0 : break;
2107 : }
2108 :
2109 0 : sal_Int32 nMaxY = rPageSize.Height - aTitleSize.Height/2;
2110 0 : sal_Int32 nMaxX = rPageSize.Width - aTitleSize.Width/2;
2111 0 : sal_Int32 nMinX = aTitleSize.Width/2;
2112 0 : sal_Int32 nMinY = aTitleSize.Height/2;
2113 0 : if( aNewPosition.Y > nMaxY )
2114 0 : aNewPosition.Y = nMaxY;
2115 0 : if( aNewPosition.X > nMaxX )
2116 0 : aNewPosition.X = nMaxX;
2117 0 : if( aNewPosition.Y < nMinY )
2118 0 : aNewPosition.Y = nMinY;
2119 0 : if( aNewPosition.X < nMinX )
2120 0 : aNewPosition.X = nMinX;
2121 :
2122 0 : pVTitle->changePosition( aNewPosition );
2123 : }
2124 :
2125 246 : boost::shared_ptr<VTitle> lcl_createTitle( TitleHelper::eTitleType eType
2126 : , const uno::Reference< drawing::XShapes>& xPageShapes
2127 : , const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory
2128 : , const uno::Reference< frame::XModel >& xChartModel
2129 : , awt::Rectangle& rRemainingSpace
2130 : , const awt::Size & rPageSize
2131 : , TitleAlignment eAlignment
2132 : , bool& rbAutoPosition )
2133 : {
2134 246 : boost::shared_ptr<VTitle> apVTitle;
2135 :
2136 : // #i109336# Improve auto positioning in chart
2137 246 : double fPercentage = lcl_getPageLayoutDistancePercentage();
2138 246 : sal_Int32 nXDistance = static_cast< sal_Int32 >( rPageSize.Width * fPercentage );
2139 246 : sal_Int32 nYDistance = static_cast< sal_Int32 >( rPageSize.Height * fPercentage );
2140 246 : if ( eType == TitleHelper::MAIN_TITLE )
2141 : {
2142 41 : sal_Int32 nYOffset = 135; // 1/100 mm
2143 41 : nYDistance += nYOffset;
2144 : }
2145 205 : else if ( eType == TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION )
2146 : {
2147 41 : sal_Int32 nYOffset = 420; // 1/100 mm
2148 41 : nYDistance = nYOffset;
2149 : }
2150 164 : else if ( eType == TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION )
2151 : {
2152 41 : sal_Int32 nXOffset = 450; // 1/100 mm
2153 41 : nXDistance = nXOffset;
2154 : }
2155 :
2156 246 : uno::Reference< XTitle > xTitle( TitleHelper::getTitle( eType, xChartModel ) );
2157 246 : rtl::OUString aCompleteString( TitleHelper::getCompleteString( xTitle ) );
2158 246 : if( !aCompleteString.isEmpty() )
2159 : {
2160 : //create title
2161 0 : apVTitle.reset(new VTitle(xTitle));
2162 0 : rtl::OUString aCID( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle, xChartModel ) );
2163 0 : apVTitle->init(xPageShapes,xShapeFactory,aCID);
2164 0 : apVTitle->createShapes( awt::Point(0,0), rPageSize );
2165 0 : awt::Size aTitleUnrotatedSize = apVTitle->getUnrotatedSize();
2166 0 : awt::Size aTitleSize = apVTitle->getFinalSize();
2167 :
2168 : //position
2169 0 : rbAutoPosition=true;
2170 0 : awt::Point aNewPosition(0,0);
2171 0 : chart2::RelativePosition aRelativePosition;
2172 0 : uno::Reference< beans::XPropertySet > xProp(xTitle, uno::UNO_QUERY);
2173 0 : if( xProp.is() && (xProp->getPropertyValue( C2U( "RelativePosition" ) )>>=aRelativePosition) )
2174 : {
2175 0 : rbAutoPosition = false;
2176 :
2177 : //@todo decide whether x is primary or secondary
2178 0 : double fX = aRelativePosition.Primary*rPageSize.Width;
2179 0 : double fY = aRelativePosition.Secondary*rPageSize.Height;
2180 :
2181 0 : double fAnglePi = apVTitle->getRotationAnglePi();
2182 : aNewPosition = RelativePositionHelper::getCenterOfAnchoredObject(
2183 : awt::Point(static_cast<sal_Int32>(fX),static_cast<sal_Int32>(fY))
2184 0 : , aTitleUnrotatedSize, aRelativePosition.Anchor, fAnglePi );
2185 : }
2186 : else //auto position
2187 : {
2188 0 : switch( eAlignment )
2189 : {
2190 : case ALIGN_TOP:
2191 : aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width/2
2192 0 : , rRemainingSpace.Y + aTitleSize.Height/2 + nYDistance );
2193 0 : break;
2194 : case ALIGN_BOTTOM:
2195 : aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width/2
2196 0 : , rRemainingSpace.Y + rRemainingSpace.Height - aTitleSize.Height/2 - nYDistance );
2197 0 : break;
2198 : case ALIGN_LEFT:
2199 : aNewPosition = awt::Point( rRemainingSpace.X + aTitleSize.Width/2 + nXDistance
2200 0 : , rRemainingSpace.Y + rRemainingSpace.Height/2 );
2201 0 : break;
2202 : case ALIGN_RIGHT:
2203 : aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width - aTitleSize.Width/2 - nXDistance
2204 0 : , rRemainingSpace.Y + rRemainingSpace.Height/2 );
2205 0 : break;
2206 : default:
2207 0 : break;
2208 :
2209 : }
2210 : }
2211 0 : apVTitle->changePosition( aNewPosition );
2212 :
2213 : //remaining space
2214 0 : switch( eAlignment )
2215 : {
2216 : case ALIGN_TOP:
2217 0 : rRemainingSpace.Y += ( aTitleSize.Height + nYDistance );
2218 0 : rRemainingSpace.Height -= ( aTitleSize.Height + nYDistance );
2219 0 : break;
2220 : case ALIGN_BOTTOM:
2221 0 : rRemainingSpace.Height -= ( aTitleSize.Height + nYDistance );
2222 0 : break;
2223 : case ALIGN_LEFT:
2224 0 : rRemainingSpace.X += ( aTitleSize.Width + nXDistance );
2225 0 : rRemainingSpace.Width -= ( aTitleSize.Width + nXDistance );
2226 0 : break;
2227 : case ALIGN_RIGHT:
2228 0 : rRemainingSpace.Width -= ( aTitleSize.Width + nXDistance );
2229 0 : break;
2230 : default:
2231 0 : break;
2232 0 : }
2233 : }
2234 : else
2235 : {
2236 : // #i109336# Improve auto positioning in chart
2237 246 : switch ( eAlignment )
2238 : {
2239 : case ALIGN_TOP:
2240 : {
2241 123 : rRemainingSpace.Y += nYDistance;
2242 123 : rRemainingSpace.Height -= nYDistance;
2243 : }
2244 123 : break;
2245 : case ALIGN_BOTTOM:
2246 : {
2247 41 : rRemainingSpace.Height -= nYDistance;
2248 : }
2249 41 : break;
2250 : case ALIGN_LEFT:
2251 : {
2252 41 : rRemainingSpace.X += nXDistance;
2253 41 : rRemainingSpace.Width -= nXDistance;
2254 : }
2255 41 : break;
2256 : case ALIGN_RIGHT:
2257 : {
2258 41 : rRemainingSpace.Width -= nXDistance;
2259 : }
2260 41 : break;
2261 : default:
2262 0 : break;
2263 : }
2264 : }
2265 246 : return apVTitle;
2266 : }
2267 :
2268 41 : bool lcl_createLegend( const uno::Reference< XLegend > & xLegend
2269 : , const uno::Reference< drawing::XShapes>& xPageShapes
2270 : , const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory
2271 : , const uno::Reference< uno::XComponentContext > & xContext
2272 : , awt::Rectangle & rRemainingSpace
2273 : , const awt::Size & rPageSize
2274 : , const uno::Reference< frame::XModel > & xModel
2275 : , const std::vector< LegendEntryProvider* >& rLegendEntryProviderList
2276 : , sal_Int16 nDefaultWritingMode )
2277 : {
2278 41 : if( VLegend::isVisible( xLegend ))
2279 : {
2280 41 : VLegend aVLegend( xLegend, xContext, rLegendEntryProviderList );
2281 41 : aVLegend.init( xPageShapes, xShapeFactory, xModel );
2282 41 : aVLegend.setDefaultWritingMode( nDefaultWritingMode );
2283 : aVLegend.createShapes( awt::Size( rRemainingSpace.Width, rRemainingSpace.Height ),
2284 41 : rPageSize );
2285 41 : aVLegend.changePosition( rRemainingSpace, rPageSize );
2286 41 : return true;
2287 : }
2288 0 : return false;
2289 : }
2290 :
2291 41 : void formatPage(
2292 : const uno::Reference< frame::XModel > & xModel
2293 : , const awt::Size rPageSize
2294 : , const uno::Reference< drawing::XShapes >& xTarget
2295 : , const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory
2296 : )
2297 : {
2298 : try
2299 : {
2300 41 : uno::Reference< XChartDocument > xChartDoc( xModel, uno::UNO_QUERY );
2301 : OSL_ASSERT( xChartDoc.is());
2302 41 : if( ! xChartDoc.is())
2303 : return;
2304 41 : uno::Reference< beans::XPropertySet > xModelPage( xChartDoc->getPageBackground());
2305 41 : if( ! xModelPage.is())
2306 : return;
2307 :
2308 :
2309 41 : if( !xShapeFactory.is() )
2310 : return;
2311 :
2312 41 : uno::Reference< beans::XPropertySet > xPageProp;
2313 : // create a shape for the background
2314 : {
2315 : uno::Reference< drawing::XShape > xShape(
2316 41 : xShapeFactory->createInstance(
2317 41 : C2U( "com.sun.star.drawing.RectangleShape" )), uno::UNO_QUERY );
2318 82 : if( xTarget.is() &&
2319 41 : xShape.is())
2320 : {
2321 41 : xTarget->add( xShape );
2322 41 : xShape->setSize( rPageSize );
2323 41 : xPageProp.set( xShape, uno::UNO_QUERY );
2324 41 : if( xPageProp.is())
2325 : {
2326 41 : xPageProp->setPropertyValue( C2U("LineStyle"), uno::makeAny( drawing::LineStyle_NONE ));
2327 : }
2328 41 : }
2329 : }
2330 :
2331 : //format page
2332 41 : if( xPageProp.is())
2333 : {
2334 41 : tPropertyNameValueMap aNameValueMap;
2335 41 : PropertyMapper::getValueMap( aNameValueMap, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), xModelPage );
2336 :
2337 41 : rtl::OUString aCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, rtl::OUString() ) );
2338 41 : aNameValueMap.insert( tPropertyNameValueMap::value_type( C2U("Name"), uno::makeAny( aCID ) ) ); //CID rtl::OUString
2339 :
2340 41 : tNameSequence aNames;
2341 41 : tAnySequence aValues;
2342 41 : PropertyMapper::getMultiPropertyListsFromValueMap( aNames, aValues, aNameValueMap );
2343 41 : PropertyMapper::setMultiProperties( aNames, aValues, xPageProp );
2344 41 : }
2345 : }
2346 0 : catch( const uno::Exception & ex )
2347 : {
2348 : ASSERT_EXCEPTION( ex );
2349 : }
2350 : }
2351 :
2352 1230 : void lcl_removeEmptyGroupShapes( const Reference< drawing::XShapes>& xParent )
2353 : {
2354 1230 : if(!xParent.is())
2355 : return;
2356 1230 : Reference< drawing::XShapeGroup > xParentGroup( xParent, uno::UNO_QUERY );
2357 1230 : if( !xParentGroup.is() )
2358 : {
2359 0 : Reference< drawing::XDrawPage > xPage( xParent, uno::UNO_QUERY );
2360 0 : if( !xPage.is() )
2361 0 : return;
2362 : }
2363 :
2364 : //iterate from back!
2365 5412 : for( sal_Int32 nN = xParent->getCount(); nN--; )
2366 : {
2367 2952 : uno::Any aAny = xParent->getByIndex( nN );
2368 2952 : Reference< drawing::XShapes> xShapes(0);
2369 2952 : if( aAny >>= xShapes )
2370 1189 : lcl_removeEmptyGroupShapes( xShapes );
2371 2952 : if( xShapes.is() && xShapes->getCount()==0 )
2372 : {
2373 : //remove empty group shape
2374 205 : Reference< drawing::XShapeGroup > xGroup( xShapes, uno::UNO_QUERY );
2375 205 : Reference< drawing::XShape > xShape( xShapes, uno::UNO_QUERY );
2376 205 : if( xGroup.is() )
2377 205 : xParent->remove( xShape );
2378 : }
2379 4182 : }
2380 : }
2381 :
2382 41 : bool ChartView::impl_AddInDrawsAllByItself()
2383 : {
2384 41 : return false;
2385 : }
2386 :
2387 41 : void ChartView::impl_refreshAddIn()
2388 : {
2389 41 : if( !m_bRefreshAddIn )
2390 41 : return;
2391 :
2392 41 : uno::Reference< beans::XPropertySet > xProp( m_xChartModel, uno::UNO_QUERY );
2393 41 : if( xProp.is()) try
2394 : {
2395 41 : uno::Reference< util::XRefreshable > xAddIn;
2396 41 : xProp->getPropertyValue( C2U( "AddIn" ) ) >>= xAddIn;
2397 41 : if( xAddIn.is() )
2398 : {
2399 0 : sal_Bool bRefreshAddInAllowed = sal_True;
2400 0 : xProp->getPropertyValue( C2U( "RefreshAddInAllowed" ) ) >>= bRefreshAddInAllowed;
2401 0 : if( bRefreshAddInAllowed )
2402 0 : xAddIn->refresh();
2403 41 : }
2404 : }
2405 0 : catch( const uno::Exception& e )
2406 : {
2407 : ASSERT_EXCEPTION( e );
2408 41 : }
2409 : }
2410 :
2411 41 : void ChartView::createShapes()
2412 : {
2413 : #if OSL_DEBUG_LEVEL > 0
2414 : clock_t nStart = clock();
2415 : OSL_TRACE( "\nPPPPPPPPP>>>>>>>>>>>> chart view :: createShapes()" );
2416 : #endif
2417 :
2418 : //make sure add-in is refreshed after creating the shapes
2419 41 : const ::comphelper::ScopeGuard aGuard( boost::bind( &ChartView::impl_refreshAddIn, this ) );
2420 41 : if( impl_AddInDrawsAllByItself() )
2421 : return;
2422 :
2423 41 : m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle(0,0,0,0);
2424 41 : impl_deleteCoordinateSystems();
2425 41 : if( m_pDrawModelWrapper )
2426 : {
2427 41 : SolarMutexGuard aSolarGuard;
2428 : // #i12587# support for shapes in chart
2429 41 : m_pDrawModelWrapper->getSdrModel().EnableUndo( sal_False );
2430 41 : m_pDrawModelWrapper->clearMainDrawPage();
2431 : }
2432 :
2433 41 : lcl_setDefaultWritingMode( m_pDrawModelWrapper, m_xChartModel );
2434 :
2435 41 : awt::Size aPageSize = ChartModelHelper::getPageSize( m_xChartModel );
2436 :
2437 : uno::Reference<drawing::XShapes> xPageShapes( ShapeFactory(m_xShapeFactory)
2438 41 : .getOrCreateChartRootShape( m_xDrawPage ) );
2439 :
2440 41 : SdrPage* pPage = ChartView::getSdrPage();
2441 41 : if(pPage) //it is neccessary to use the implementation here as the uno page does not provide a propertyset
2442 41 : pPage->SetSize(Size(aPageSize.Width,aPageSize.Height));
2443 : else
2444 : {
2445 : OSL_FAIL("could not set page size correctly");
2446 : }
2447 :
2448 : {
2449 41 : SolarMutexGuard aSolarGuard;
2450 :
2451 : //------------ apply fill properties to page
2452 : // todo: it would be nicer to just pass the page m_xDrawPage and format it,
2453 : // but the draw page does not support XPropertySet
2454 41 : formatPage( m_xChartModel, aPageSize, xPageShapes, m_xShapeFactory );
2455 :
2456 : //sal_Int32 nYDistance = static_cast<sal_Int32>(aPageSize.Height*lcl_getPageLayoutDistancePercentage());
2457 41 : awt::Rectangle aRemainingSpace( 0, 0, aPageSize.Width, aPageSize.Height );
2458 :
2459 : //create the group shape for diagram and axes first to have title and legends on top of it
2460 41 : uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartModel ) );
2461 41 : rtl::OUString aDiagramCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, rtl::OUString::valueOf( sal_Int32(0) ) ) );//todo: other index if more than one diagram is possible
2462 41 : uno::Reference< drawing::XShapes > xDiagramPlusAxesPlusMarkHandlesGroup_Shapes( ShapeFactory(m_xShapeFactory).createGroup2D(xPageShapes,aDiagramCID) );
2463 :
2464 : uno::Reference< drawing::XShape > xDiagram_MarkHandles( ShapeFactory(m_xShapeFactory).createInvisibleRectangle(
2465 41 : xDiagramPlusAxesPlusMarkHandlesGroup_Shapes, awt::Size(0,0) ) );
2466 41 : ShapeFactory::setShapeName( xDiagram_MarkHandles, C2U("MarkHandles") );
2467 :
2468 : uno::Reference< drawing::XShape > xDiagram_OuterRect( ShapeFactory(m_xShapeFactory).createInvisibleRectangle(
2469 41 : xDiagramPlusAxesPlusMarkHandlesGroup_Shapes, awt::Size(0,0) ) );
2470 41 : ShapeFactory::setShapeName( xDiagram_OuterRect, C2U("PlotAreaIncludingAxes") );
2471 :
2472 41 : uno::Reference< drawing::XShapes > xDiagramPlusAxes_Shapes( ShapeFactory(m_xShapeFactory).createGroup2D(xDiagramPlusAxesPlusMarkHandlesGroup_Shapes ) );
2473 :
2474 41 : bool bAutoPositionDummy = true;
2475 :
2476 : //------------ create main title shape
2477 : lcl_createTitle( TitleHelper::MAIN_TITLE, xPageShapes, m_xShapeFactory, m_xChartModel
2478 41 : , aRemainingSpace, aPageSize, ALIGN_TOP, bAutoPositionDummy );
2479 41 : if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
2480 : return;
2481 :
2482 : //------------ create sub title shape
2483 : lcl_createTitle( TitleHelper::SUB_TITLE, xPageShapes, m_xShapeFactory, m_xChartModel
2484 41 : , aRemainingSpace, aPageSize, ALIGN_TOP, bAutoPositionDummy );
2485 41 : if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
2486 : return;
2487 :
2488 :
2489 : //------------ prepare series to give input to the legend (create categories and symbols etc.)
2490 41 : SeriesPlotterContainer aSeriesPlotterContainer( m_aVCooSysList );
2491 41 : aSeriesPlotterContainer.initializeCooSysAndSeriesPlotter( m_xChartModel );
2492 :
2493 : //------------ create legend
2494 : lcl_createLegend( LegendHelper::getLegend( m_xChartModel ), xPageShapes, m_xShapeFactory, m_xCC
2495 : , aRemainingSpace, aPageSize, m_xChartModel, aSeriesPlotterContainer.getLegendEntryProviderList()
2496 41 : , lcl_getDefaultWritingModeFromPool( m_pDrawModelWrapper ) );
2497 41 : if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
2498 : return;
2499 :
2500 41 : Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
2501 41 : sal_Int32 nDimension = DiagramHelper::getDimension( xDiagram );
2502 :
2503 : //------------ create x axis title
2504 41 : bool bAutoPosition_XTitle = true;
2505 41 : boost::shared_ptr<VTitle> apVTitle_X;
2506 41 : if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 0 ) )
2507 : apVTitle_X = lcl_createTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, xPageShapes, m_xShapeFactory, m_xChartModel
2508 41 : , aRemainingSpace, aPageSize, ALIGN_BOTTOM, bAutoPosition_XTitle );
2509 41 : if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
2510 : return;
2511 :
2512 : //------------ create y axis title
2513 41 : bool bAutoPosition_YTitle = true;
2514 41 : boost::shared_ptr<VTitle> apVTitle_Y;
2515 41 : if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 1 ) )
2516 : apVTitle_Y = lcl_createTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION, xPageShapes, m_xShapeFactory, m_xChartModel
2517 41 : , aRemainingSpace, aPageSize, ALIGN_LEFT, bAutoPosition_YTitle );
2518 41 : if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
2519 : return;
2520 :
2521 : //------------ create z axis title
2522 41 : bool bAutoPosition_ZTitle = true;
2523 41 : boost::shared_ptr<VTitle> apVTitle_Z;
2524 41 : if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 2 ) )
2525 : apVTitle_Z = lcl_createTitle( TitleHelper::Z_AXIS_TITLE, xPageShapes, m_xShapeFactory, m_xChartModel
2526 0 : , aRemainingSpace, aPageSize, ALIGN_RIGHT, bAutoPosition_ZTitle );
2527 41 : if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
2528 : return;
2529 :
2530 41 : bool bDummy = false;
2531 41 : bool bIsVertical = DiagramHelper::getVertical( xDiagram, bDummy, bDummy );
2532 :
2533 : //------------ create secondary x axis title
2534 41 : bool bAutoPosition_SecondXTitle = true;
2535 41 : boost::shared_ptr<VTitle> apVTitle_SecondX;
2536 41 : if( ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimension, 0 ) )
2537 : apVTitle_SecondX = lcl_createTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, xPageShapes, m_xShapeFactory, m_xChartModel
2538 41 : , aRemainingSpace, aPageSize, bIsVertical? ALIGN_RIGHT : ALIGN_TOP, bAutoPosition_SecondXTitle );
2539 41 : if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
2540 : return;
2541 :
2542 : //------------ create secondary y axis title
2543 41 : bool bAutoPosition_SecondYTitle = true;
2544 41 : boost::shared_ptr<VTitle> apVTitle_SecondY;
2545 41 : if( ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimension, 1 ) )
2546 : apVTitle_SecondY = lcl_createTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, xPageShapes, m_xShapeFactory, m_xChartModel
2547 41 : , aRemainingSpace, aPageSize, bIsVertical? ALIGN_TOP : ALIGN_RIGHT, bAutoPosition_SecondYTitle );
2548 41 : if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
2549 : return;
2550 :
2551 : //------------ create complete diagram shape (inclusive axis and series)
2552 41 : awt::Point aAvailablePosDia;
2553 41 : awt::Size aAvailableSizeForDiagram;
2554 41 : bool bUseFixedInnerSize = false;
2555 82 : if( getAvailablePosAndSizeForDiagram( aAvailablePosDia, aAvailableSizeForDiagram, aRemainingSpace, aPageSize
2556 82 : , ChartModelHelper::findDiagram( m_xChartModel ), bUseFixedInnerSize ) )
2557 : {
2558 : awt::Rectangle aUsedOuterRect = impl_createDiagramAndContent( aSeriesPlotterContainer
2559 : , xDiagramPlusAxes_Shapes
2560 41 : , aAvailablePosDia ,aAvailableSizeForDiagram, aPageSize, bUseFixedInnerSize, xDiagram_MarkHandles );
2561 :
2562 41 : if( xDiagram_OuterRect.is() )
2563 : {
2564 41 : xDiagram_OuterRect->setPosition( awt::Point( aUsedOuterRect.X, aUsedOuterRect.Y ) );
2565 41 : xDiagram_OuterRect->setSize( awt::Size( aUsedOuterRect.Width, aUsedOuterRect.Height ) );
2566 : }
2567 :
2568 : //correct axis title position
2569 41 : awt::Rectangle aDiagramPlusAxesRect( aUsedOuterRect );
2570 41 : if(bAutoPosition_XTitle)
2571 41 : changePositionOfAxisTitle( apVTitle_X.get(), ALIGN_BOTTOM, aDiagramPlusAxesRect, aPageSize );
2572 41 : if(bAutoPosition_YTitle)
2573 41 : changePositionOfAxisTitle( apVTitle_Y.get(), ALIGN_LEFT, aDiagramPlusAxesRect, aPageSize );
2574 41 : if(bAutoPosition_ZTitle)
2575 41 : changePositionOfAxisTitle( apVTitle_Z.get(), ALIGN_Z, aDiagramPlusAxesRect, aPageSize );
2576 41 : if(bAutoPosition_SecondXTitle)
2577 41 : changePositionOfAxisTitle( apVTitle_SecondX.get(), bIsVertical? ALIGN_RIGHT : ALIGN_TOP, aDiagramPlusAxesRect, aPageSize );
2578 41 : if(bAutoPosition_SecondYTitle)
2579 41 : changePositionOfAxisTitle( apVTitle_SecondY.get(), bIsVertical? ALIGN_TOP : ALIGN_RIGHT, aDiagramPlusAxesRect, aPageSize );
2580 : }
2581 :
2582 : //cleanup: remove all empty group shapes to avoid grey border lines:
2583 41 : lcl_removeEmptyGroupShapes( xPageShapes );
2584 : }
2585 :
2586 : // #i12587# support for shapes in chart
2587 41 : if ( m_pDrawModelWrapper )
2588 : {
2589 41 : SolarMutexGuard aSolarGuard;
2590 41 : m_pDrawModelWrapper->getSdrModel().EnableUndo( true );
2591 41 : }
2592 :
2593 : #if OSL_DEBUG_LEVEL > 0
2594 : clock_t nEnd = clock();
2595 : double fDuration =(double(nEnd-nStart)*1000.0)/double(CLOCKS_PER_SEC);
2596 :
2597 : OSL_TRACE( "\nPPPPPPPPP<<<<<<<<<<<< chart view :: createShapes():: needed %f msec", fDuration );
2598 : #endif
2599 : }
2600 :
2601 : //-----------------------------------------------------------------
2602 : // util::XEventListener (base of XCloseListener)
2603 : //-----------------------------------------------------------------
2604 0 : void SAL_CALL ChartView::disposing( const lang::EventObject& /* rSource */ )
2605 : throw(uno::RuntimeException)
2606 : {
2607 0 : impl_setChartModel( 0 );
2608 0 : }
2609 :
2610 61 : void ChartView::impl_updateView()
2611 : {
2612 61 : if( !m_xChartModel.is() || !m_pDrawModelWrapper )
2613 0 : return;
2614 :
2615 : // #i12587# support for shapes in chart
2616 61 : if ( m_bSdrViewIsInEditMode )
2617 : {
2618 0 : return;
2619 : }
2620 :
2621 61 : if( m_bViewDirty && !m_bInViewUpdate )
2622 : {
2623 41 : m_bInViewUpdate = true;
2624 : //bool bOldRefreshAddIn = m_bRefreshAddIn;
2625 : //m_bRefreshAddIn = false;
2626 : try
2627 : {
2628 41 : impl_notifyModeChangeListener(C2U("invalid"));
2629 :
2630 : //prepare draw model
2631 : {
2632 41 : SolarMutexGuard aSolarGuard;
2633 41 : m_pDrawModelWrapper->lockControllers();
2634 : }
2635 :
2636 : //create chart view
2637 : {
2638 41 : m_bViewDirty = false;
2639 41 : m_bViewUpdatePending = false;
2640 41 : createShapes();
2641 :
2642 41 : if( m_bViewDirty )
2643 : {
2644 : //avoid recursions due to add-in
2645 0 : m_bRefreshAddIn = false;
2646 0 : m_bViewDirty = false;
2647 0 : m_bViewUpdatePending = false;
2648 : //delete old chart view
2649 0 : createShapes();
2650 0 : m_bRefreshAddIn = true;
2651 : }
2652 : }
2653 :
2654 41 : m_bViewDirty = m_bViewUpdatePending;
2655 41 : m_bViewUpdatePending = false;
2656 41 : m_bInViewUpdate = false;
2657 : }
2658 0 : catch( const uno::Exception& ex)
2659 : {
2660 0 : m_bViewDirty = m_bViewUpdatePending;
2661 0 : m_bViewUpdatePending = false;
2662 0 : m_bInViewUpdate = false;
2663 : ASSERT_EXCEPTION( ex );
2664 : }
2665 :
2666 : {
2667 41 : SolarMutexGuard aSolarGuard;
2668 41 : m_pDrawModelWrapper->unlockControllers();
2669 : }
2670 :
2671 41 : impl_notifyModeChangeListener(C2U("valid"));
2672 :
2673 : //m_bRefreshAddIn = bOldRefreshAddIn;
2674 : }
2675 : }
2676 :
2677 : // ____ XModifyListener ____
2678 122 : void SAL_CALL ChartView::modified( const lang::EventObject& /* aEvent */ )
2679 : throw (uno::RuntimeException)
2680 : {
2681 122 : m_bViewDirty = sal_True;
2682 122 : if( m_bInViewUpdate )
2683 0 : m_bViewUpdatePending = true;
2684 :
2685 122 : impl_notifyModeChangeListener(C2U("dirty"));
2686 122 : }
2687 :
2688 : //SfxListener
2689 3649 : void ChartView::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
2690 : {
2691 : //#i77362 change notification for changes on additional shapes are missing
2692 3649 : if( m_bInViewUpdate )
2693 : return;
2694 :
2695 : // #i12587# support for shapes in chart
2696 0 : if ( m_bSdrViewIsInEditMode && m_xChartModel.is() )
2697 : {
2698 0 : uno::Reference< view::XSelectionSupplier > xSelectionSupplier( m_xChartModel->getCurrentController(), uno::UNO_QUERY );
2699 0 : if ( xSelectionSupplier.is() )
2700 : {
2701 0 : ::rtl::OUString aSelObjCID;
2702 0 : uno::Any aSelObj( xSelectionSupplier->getSelection() );
2703 0 : aSelObj >>= aSelObjCID;
2704 0 : if ( !aSelObjCID.isEmpty() )
2705 : {
2706 : return;
2707 0 : }
2708 0 : }
2709 : }
2710 :
2711 0 : const SdrHint* pSdrHint = dynamic_cast< const SdrHint* >(&rHint);
2712 0 : if( !pSdrHint )
2713 : return;
2714 :
2715 0 : bool bShapeChanged = false;
2716 0 : switch( pSdrHint->GetKind() )
2717 : {
2718 : case HINT_OBJCHG:
2719 0 : bShapeChanged = true;
2720 0 : break;
2721 : case HINT_OBJINSERTED:
2722 0 : bShapeChanged = true;
2723 0 : break;
2724 : case HINT_OBJREMOVED:
2725 0 : bShapeChanged = true;
2726 0 : break;
2727 : case HINT_MODELCLEARED:
2728 0 : bShapeChanged = true;
2729 0 : break;
2730 : case HINT_ENDEDIT:
2731 0 : bShapeChanged = true;
2732 0 : break;
2733 : default:
2734 0 : break;
2735 : }
2736 :
2737 0 : if(bShapeChanged)
2738 : {
2739 : //#i76053# do not send view modified notifications for changes on the hidden page which contains e.g. the symbols for the dialogs
2740 0 : if( ChartView::getSdrPage() != pSdrHint->GetPage() )
2741 0 : bShapeChanged=false;
2742 : }
2743 :
2744 0 : if(!bShapeChanged)
2745 : return;
2746 :
2747 0 : Reference< util::XModifiable > xModifiable( m_xChartModel, uno::UNO_QUERY );
2748 0 : if( xModifiable.is() )
2749 0 : xModifiable->setModified( sal_True );
2750 : }
2751 :
2752 204 : void ChartView::impl_notifyModeChangeListener( const rtl::OUString& rNewMode )
2753 : {
2754 : try
2755 : {
2756 : ::cppu::OInterfaceContainerHelper* pIC = m_aListenerContainer
2757 204 : .getContainer( ::getCppuType((const uno::Reference< util::XModeChangeListener >*)0) );
2758 204 : if( pIC )
2759 : {
2760 0 : util::ModeChangeEvent aEvent( static_cast< uno::XWeak* >( this ), rNewMode );
2761 0 : ::cppu::OInterfaceIteratorHelper aIt( *pIC );
2762 0 : while( aIt.hasMoreElements() )
2763 : {
2764 0 : uno::Reference< util::XModeChangeListener > xListener( aIt.next(), uno::UNO_QUERY );
2765 0 : if( xListener.is() )
2766 0 : xListener->modeChanged( aEvent );
2767 0 : }
2768 : }
2769 : }
2770 0 : catch( const uno::Exception& ex)
2771 : {
2772 : ASSERT_EXCEPTION( ex );
2773 : }
2774 204 : }
2775 :
2776 : // ____ XModeChangeBroadcaster ____
2777 :
2778 0 : void SAL_CALL ChartView::addModeChangeListener( const uno::Reference< util::XModeChangeListener >& xListener )
2779 : throw (uno::RuntimeException)
2780 : {
2781 : m_aListenerContainer.addInterface(
2782 0 : ::getCppuType((const uno::Reference< util::XModeChangeListener >*)0), xListener );
2783 0 : }
2784 0 : void SAL_CALL ChartView::removeModeChangeListener( const uno::Reference< util::XModeChangeListener >& xListener )
2785 : throw (uno::RuntimeException)
2786 : {
2787 : m_aListenerContainer.removeInterface(
2788 0 : ::getCppuType((const uno::Reference< util::XModeChangeListener >*)0), xListener );
2789 0 : }
2790 0 : void SAL_CALL ChartView::addModeChangeApproveListener( const uno::Reference< util::XModeChangeApproveListener >& /* _rxListener */ )
2791 : throw (lang::NoSupportException, uno::RuntimeException)
2792 : {
2793 :
2794 0 : }
2795 0 : void SAL_CALL ChartView::removeModeChangeApproveListener( const uno::Reference< util::XModeChangeApproveListener >& /* _rxListener */ )
2796 : throw (lang::NoSupportException, uno::RuntimeException)
2797 : {
2798 :
2799 0 : }
2800 :
2801 : // ____ XUpdatable ____
2802 41 : void SAL_CALL ChartView::update() throw (uno::RuntimeException)
2803 : {
2804 41 : impl_updateView();
2805 :
2806 : //#i100778# migrate all imported or old documents to a plot area sizing exclusive axes (in case the save settings allow for this):
2807 : //Although in general it is a bad idea to change the model from within the view this is exceptionally the best place to do this special conversion.
2808 : //When a view update is requested (what happens for creating the metafile or displaying
2809 : //the chart in edit mode or printing) it is most likely that all necessary informations are available - like the underlying spreadsheet data for example.
2810 : //Those data is important for the correct axis lable sizes which are needed during conversion.
2811 41 : if( DiagramHelper::switchDiagramPositioningToExcludingPositioning( m_xChartModel, true, false ) )
2812 0 : impl_updateView();
2813 41 : }
2814 :
2815 : // ____ XPropertySet ____
2816 0 : Reference< beans::XPropertySetInfo > SAL_CALL ChartView::getPropertySetInfo()
2817 : throw (uno::RuntimeException)
2818 : {
2819 : OSL_FAIL("not implemented");
2820 0 : return 0;
2821 : }
2822 :
2823 0 : void SAL_CALL ChartView::setPropertyValue( const ::rtl::OUString& rPropertyName
2824 : , const Any& rValue )
2825 : throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException
2826 : , lang::WrappedTargetException, uno::RuntimeException)
2827 : {
2828 0 : if( rPropertyName.equals(C2U("Resolution")) )
2829 : {
2830 0 : awt::Size aNewResolution;
2831 0 : if( ! (rValue >>= aNewResolution) )
2832 0 : throw lang::IllegalArgumentException( C2U("Property 'Resolution' requires value of type awt::Size"), 0, 0 );
2833 :
2834 0 : if( m_aPageResolution.Width!=aNewResolution.Width || m_aPageResolution.Height!=aNewResolution.Height )
2835 : {
2836 : //set modified only when the new resolution is higher and points were skipped before
2837 0 : bool bSetModified = m_bPointsWereSkipped && (m_aPageResolution.Width<aNewResolution.Width || m_aPageResolution.Height<aNewResolution.Height);
2838 :
2839 0 : m_aPageResolution = aNewResolution;
2840 :
2841 0 : if( bSetModified )
2842 0 : this->modified( lang::EventObject( static_cast< uno::XWeak* >( this ) ) );
2843 : }
2844 : }
2845 0 : else if( rPropertyName.equals(C2U("ZoomFactors")) )
2846 : {
2847 : //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
2848 0 : uno::Sequence< beans::PropertyValue > aZoomFactors;
2849 0 : if( ! (rValue >>= aZoomFactors) )
2850 0 : throw lang::IllegalArgumentException( C2U("Property 'ZoomFactors' requires value of type Sequence< PropertyValue >"), 0, 0 );
2851 :
2852 0 : sal_Int32 nFilterArgs = aZoomFactors.getLength();
2853 0 : beans::PropertyValue* pDataValues = aZoomFactors.getArray();
2854 0 : while( nFilterArgs-- )
2855 : {
2856 0 : if ( pDataValues->Name == "ScaleXNumerator" )
2857 0 : pDataValues->Value >>= m_nScaleXNumerator;
2858 0 : else if ( pDataValues->Name == "ScaleXDenominator" )
2859 0 : pDataValues->Value >>= m_nScaleXDenominator;
2860 0 : else if ( pDataValues->Name == "ScaleYNumerator" )
2861 0 : pDataValues->Value >>= m_nScaleYNumerator;
2862 0 : else if ( pDataValues->Name == "ScaleYDenominator" )
2863 0 : pDataValues->Value >>= m_nScaleYDenominator;
2864 :
2865 0 : pDataValues++;
2866 0 : }
2867 : }
2868 0 : else if( rPropertyName.equals(C2U("SdrViewIsInEditMode")) )
2869 : {
2870 : //#i77362 change notification for changes on additional shapes are missing
2871 0 : if( ! (rValue >>= m_bSdrViewIsInEditMode) )
2872 0 : throw lang::IllegalArgumentException( C2U("Property 'SdrViewIsInEditMode' requires value of type sal_Bool"), 0, 0 );
2873 : }
2874 : else
2875 0 : throw beans::UnknownPropertyException( C2U("unknown property was tried to set to chart wizard"), 0 );
2876 0 : }
2877 :
2878 0 : Any SAL_CALL ChartView::getPropertyValue( const ::rtl::OUString& rPropertyName )
2879 : throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
2880 : {
2881 0 : Any aRet;
2882 0 : if( rPropertyName.equals(C2U("Resolution")) )
2883 : {
2884 0 : aRet = uno::makeAny( m_aPageResolution );
2885 : }
2886 : else
2887 0 : throw beans::UnknownPropertyException( C2U("unknown property was tried to get from chart wizard"), 0 );
2888 0 : return aRet;
2889 : }
2890 :
2891 0 : void SAL_CALL ChartView::addPropertyChangeListener(
2892 : const ::rtl::OUString& /* aPropertyName */, const Reference< beans::XPropertyChangeListener >& /* xListener */ )
2893 : throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
2894 : {
2895 : OSL_FAIL("not implemented");
2896 0 : }
2897 0 : void SAL_CALL ChartView::removePropertyChangeListener(
2898 : const ::rtl::OUString& /* aPropertyName */, const Reference< beans::XPropertyChangeListener >& /* aListener */ )
2899 : throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
2900 : {
2901 : OSL_FAIL("not implemented");
2902 0 : }
2903 :
2904 0 : void SAL_CALL ChartView::addVetoableChangeListener( const ::rtl::OUString& /* PropertyName */, const Reference< beans::XVetoableChangeListener >& /* aListener */ )
2905 : throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
2906 : {
2907 : OSL_FAIL("not implemented");
2908 0 : }
2909 :
2910 0 : void SAL_CALL ChartView::removeVetoableChangeListener( const ::rtl::OUString& /* PropertyName */, const Reference< beans::XVetoableChangeListener >& /* aListener */ )
2911 : throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
2912 : {
2913 : OSL_FAIL("not implemented");
2914 0 : }
2915 :
2916 : // ____ XMultiServiceFactory ____
2917 :
2918 205 : Reference< uno::XInterface > ChartView::createInstance( const ::rtl::OUString& aServiceSpecifier )
2919 : throw (uno::Exception, uno::RuntimeException)
2920 : {
2921 205 : SdrModel* pModel = ( m_pDrawModelWrapper ? &m_pDrawModelWrapper->getSdrModel() : NULL );
2922 205 : if ( pModel )
2923 : {
2924 205 : if ( aServiceSpecifier.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.DashTable" ) ) == 0 )
2925 : {
2926 41 : if ( !m_xDashTable.is() )
2927 : {
2928 41 : m_xDashTable = SvxUnoDashTable_createInstance( pModel );
2929 : }
2930 41 : return m_xDashTable;
2931 : }
2932 164 : else if ( aServiceSpecifier.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.GradientTable" ) ) == 0 )
2933 : {
2934 41 : if ( !m_xGradientTable.is() )
2935 : {
2936 41 : m_xGradientTable = SvxUnoGradientTable_createInstance( pModel );
2937 : }
2938 41 : return m_xGradientTable;
2939 : }
2940 123 : else if ( aServiceSpecifier.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.HatchTable" ) ) == 0 )
2941 : {
2942 41 : if ( !m_xHatchTable.is() )
2943 : {
2944 41 : m_xHatchTable = SvxUnoHatchTable_createInstance( pModel );
2945 : }
2946 41 : return m_xHatchTable;
2947 : }
2948 82 : else if ( aServiceSpecifier.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.BitmapTable" ) ) == 0 )
2949 : {
2950 41 : if ( !m_xBitmapTable.is() )
2951 : {
2952 41 : m_xBitmapTable = SvxUnoBitmapTable_createInstance( pModel );
2953 : }
2954 41 : return m_xBitmapTable;
2955 : }
2956 41 : else if ( aServiceSpecifier.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.TransparencyGradientTable" ) ) == 0 )
2957 : {
2958 41 : if ( !m_xTransGradientTable.is() )
2959 : {
2960 41 : m_xTransGradientTable = SvxUnoTransGradientTable_createInstance( pModel );
2961 : }
2962 41 : return m_xTransGradientTable;
2963 : }
2964 0 : else if ( aServiceSpecifier.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.MarkerTable" ) ) == 0 )
2965 : {
2966 0 : if ( !m_xMarkerTable.is() )
2967 : {
2968 0 : m_xMarkerTable = SvxUnoMarkerTable_createInstance( pModel );
2969 : }
2970 0 : return m_xMarkerTable;
2971 : }
2972 : }
2973 :
2974 0 : return 0;
2975 : }
2976 :
2977 0 : Reference< uno::XInterface > ChartView::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const uno::Sequence< uno::Any >& Arguments )
2978 : throw (uno::Exception, uno::RuntimeException)
2979 : {
2980 : OSL_ENSURE( Arguments.getLength(), "ChartView::createInstanceWithArguments: arguments are ignored" );
2981 : (void) Arguments; // avoid warning
2982 0 : return createInstance( ServiceSpecifier );
2983 : }
2984 :
2985 0 : uno::Sequence< ::rtl::OUString > ChartView::getAvailableServiceNames() throw (uno::RuntimeException)
2986 : {
2987 0 : uno::Sequence< ::rtl::OUString > aServiceNames( 6 );
2988 :
2989 0 : aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DashTable" ) );
2990 0 : aServiceNames[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.GradientTable" ) );
2991 0 : aServiceNames[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.HatchTable" ) );
2992 0 : aServiceNames[3] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.BitmapTable" ) );
2993 0 : aServiceNames[4] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.TransparencyGradientTable" ) );
2994 0 : aServiceNames[5] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.MarkerTable" ) );
2995 :
2996 0 : return aServiceNames;
2997 : }
2998 :
2999 : /* ----------------------
3000 : goes to drawinglayer/XShapeDumper.cxx
3001 : ----------------------
3002 : namespace {
3003 :
3004 : #define DEBUG_DUMPER 0
3005 :
3006 : int writeCallback(void* pContext, const char* sBuffer, int nLen)
3007 : {
3008 : rtl::OStringBuffer* pBuffer = static_cast<rtl::OStringBuffer*>(pContext);
3009 : pBuffer->append(sBuffer);
3010 : return nLen;
3011 : }
3012 :
3013 : int closeCallback(void* )
3014 : {
3015 : return 0;
3016 : }
3017 :
3018 : void dumpPositionAsAttribute(const awt::Point& rPoint, xmlTextWriterPtr xmlWriter)
3019 : {
3020 : xmlTextWriterWriteFormatAttribute(xmlWriter, BAD_CAST("positionX"), "%" SAL_PRIdINT32, rPoint.X);
3021 : xmlTextWriterWriteFormatAttribute(xmlWriter, BAD_CAST("positionY"), "%" SAL_PRIdINT32, rPoint.Y);
3022 : }
3023 :
3024 : void dumpSizeAsAttribute(const awt::Size& rSize, xmlTextWriterPtr xmlWriter)
3025 : {
3026 : xmlTextWriterWriteFormatAttribute(xmlWriter, BAD_CAST("sizeX"), "%" SAL_PRIdINT32, rSize.Width);
3027 : xmlTextWriterWriteFormatAttribute(xmlWriter, BAD_CAST("sizeY"), "%" SAL_PRIdINT32, rSize.Height);
3028 : }
3029 :
3030 : void dumpShapeDescriptorAsAttribute( uno::Reference< drawing::XShapeDescriptor > xDescr, xmlTextWriterPtr xmlWriter )
3031 : {
3032 : xmlTextWriterWriteFormatAttribute(xmlWriter, BAD_CAST("type"), "%s", rtl::OUStringToOString(xDescr->getShapeType(), RTL_TEXTENCODING_UTF8).getStr());
3033 : }
3034 :
3035 : void dumpXShapes( uno::Reference< drawing::XShapes > xShapes, xmlTextWriterPtr xmlWriter );
3036 :
3037 : void dumpXShape( uno::Reference< drawing::XShape > xShape, xmlTextWriterPtr xmlWriter )
3038 : {
3039 : xmlTextWriterStartElement( xmlWriter, BAD_CAST( "XShape" ) );
3040 :
3041 : dumpPositionAsAttribute(xShape->getPosition(), xmlWriter);
3042 : dumpSizeAsAttribute(xShape->getSize(), xmlWriter);
3043 : uno::Reference< drawing::XShapeDescriptor > xDescr(xShape, uno::UNO_QUERY_THROW);
3044 : dumpShapeDescriptorAsAttribute(xDescr, xmlWriter);
3045 :
3046 : uno::Reference< lang::XServiceInfo > xServiceInfo( xShape, uno::UNO_QUERY_THROW );
3047 : uno::Sequence< rtl::OUString > aServiceNames = xServiceInfo->getSupportedServiceNames();
3048 :
3049 : uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY_THROW);
3050 : uno::Any aAny = xPropSet->getPropertyValue("Name");
3051 : rtl::OUString aName;
3052 : if (aAny >>= aName)
3053 : {
3054 : if (!aName.isEmpty())
3055 : xmlTextWriterWriteFormatAttribute( xmlWriter, BAD_CAST("name"), "%s", rtl::OUStringToOString(aName, RTL_TEXTENCODING_UTF8).getStr());
3056 : }
3057 : if (xServiceInfo->supportsService("com.sun.star.drawing.Text"))
3058 : {
3059 : uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY_THROW);
3060 : rtl::OUString aText = xText->getString();
3061 : if(!aText.isEmpty())
3062 : xmlTextWriterWriteFormatAttribute( xmlWriter, BAD_CAST("text"), "%s", rtl::OUStringToOString(aText, RTL_TEXTENCODING_UTF8).getStr());
3063 : }
3064 : else if(xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
3065 : {
3066 : uno::Reference< drawing::XShapes > xShapes(xShape, uno::UNO_QUERY_THROW);
3067 : dumpXShapes(xShapes, xmlWriter);
3068 : }
3069 : #if DEBUG_DUMPER
3070 : sal_Int32 nServices = aServiceNames.getLength();
3071 : for (sal_Int32 i = 0; i < nServices; ++i)
3072 : {
3073 : xmlTextWriterStartElement(xmlWriter, BAD_CAST( "ServiceName" ));
3074 : xmlTextWriterWriteFormatAttribute(xmlWriter, BAD_CAST( "name" ), "%s", rtl::OUStringToOString(aServiceNames[i], RTL_TEXTENCODING_UTF8).getStr());
3075 : xmlTextWriterEndElement( xmlWriter );
3076 : }
3077 : #endif
3078 :
3079 : xmlTextWriterEndElement( xmlWriter );
3080 : }
3081 :
3082 : void dumpXShapes( uno::Reference< drawing::XShapes > xShapes, xmlTextWriterPtr xmlWriter )
3083 : {
3084 : xmlTextWriterStartElement( xmlWriter, BAD_CAST( "XShapes" ) );
3085 : uno::Reference< container::XIndexAccess > xIA( xShapes, uno::UNO_QUERY_THROW);
3086 : sal_Int32 nLength = xIA->getCount();
3087 : for (sal_Int32 i = 0; i < nLength; ++i)
3088 : {
3089 : uno::Reference< drawing::XShape > xShape( xIA->getByIndex( i ), uno::UNO_QUERY_THROW );
3090 : dumpXShape( xShape, xmlWriter );
3091 : }
3092 :
3093 : xmlTextWriterEndElement( xmlWriter );
3094 : }
3095 :
3096 : }
3097 : */
3098 :
3099 0 : rtl::OUString ChartView::dump() throw (uno::RuntimeException)
3100 : {
3101 0 : impl_updateView();
3102 : uno::Reference<drawing::XShapes> xPageShapes( ShapeFactory(m_xShapeFactory)
3103 0 : .getOrCreateChartRootShape( m_xDrawPage ) );
3104 :
3105 0 : if (!xPageShapes.is())
3106 0 : return rtl::OUString();
3107 : else
3108 : {
3109 0 : XShapeDumper dumper;
3110 0 : return dumper.dump(xPageShapes);
3111 0 : }
3112 :
3113 : }
3114 :
3115 : //.............................................................................
3116 3 : } //namespace chart
3117 : //.............................................................................
3118 :
3119 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|