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