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