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