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