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