Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "xichart.hxx"
31 : :
32 : : #include <algorithm>
33 : : #include <memory>
34 : :
35 : : #include <com/sun/star/frame/XModel.hpp>
36 : : #include <com/sun/star/drawing/Direction3D.hpp>
37 : : #include <com/sun/star/drawing/ProjectionMode.hpp>
38 : : #include <com/sun/star/drawing/ShadeMode.hpp>
39 : : #include <com/sun/star/drawing/XShape.hpp>
40 : : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
41 : : #include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp>
42 : : #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
43 : : #include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
44 : : #include <com/sun/star/chart/ChartAxisPosition.hpp>
45 : : #include <com/sun/star/chart/ChartLegendExpansion.hpp>
46 : : #include <com/sun/star/chart/TimeInterval.hpp>
47 : : #include <com/sun/star/chart/TimeUnit.hpp>
48 : : #include <com/sun/star/chart/XChartDocument.hpp>
49 : : #include <com/sun/star/chart/XDiagramPositioning.hpp>
50 : : #include <com/sun/star/chart2/XChartDocument.hpp>
51 : : #include <com/sun/star/chart2/XDiagram.hpp>
52 : : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
53 : : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
54 : : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
55 : : #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
56 : : #include <com/sun/star/chart2/XTitled.hpp>
57 : : #include <com/sun/star/chart2/data/XDataProvider.hpp>
58 : : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
59 : : #include <com/sun/star/chart2/data/XDataSink.hpp>
60 : : #include <com/sun/star/chart2/AxisType.hpp>
61 : : #include <com/sun/star/chart2/CurveStyle.hpp>
62 : : #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
63 : : #include <com/sun/star/chart2/DataPointLabel.hpp>
64 : : #include <com/sun/star/chart2/LegendPosition.hpp>
65 : : #include <com/sun/star/chart2/StackingDirection.hpp>
66 : : #include <com/sun/star/chart2/TickmarkStyle.hpp>
67 : : #include <com/sun/star/chart2/RelativePosition.hpp>
68 : : #include <com/sun/star/chart2/RelativeSize.hpp>
69 : : #include <com/sun/star/chart/DataLabelPlacement.hpp>
70 : : #include <com/sun/star/chart/ErrorBarStyle.hpp>
71 : : #include <com/sun/star/chart/MissingValueTreatment.hpp>
72 : :
73 : : #include <sfx2/objsh.hxx>
74 : : #include <svx/svdpage.hxx>
75 : : #include <svx/unoapi.hxx>
76 : :
77 : : #include "document.hxx"
78 : : #include "drwlayer.hxx"
79 : : #include "rangeutl.hxx"
80 : : #include "tokenarray.hxx"
81 : : #include "token.hxx"
82 : : #include "compiler.hxx"
83 : : #include "reftokenhelper.hxx"
84 : : #include "chartlis.hxx"
85 : : #include "fprogressbar.hxx"
86 : : #include "xltracer.hxx"
87 : : #include "xistream.hxx"
88 : : #include "xiformula.hxx"
89 : : #include "xistyle.hxx"
90 : : #include "xipage.hxx"
91 : : #include "xiview.hxx"
92 : :
93 : : using ::rtl::OUString;
94 : : using ::rtl::OUStringBuffer;
95 : : using ::com::sun::star::uno::Any;
96 : : using ::com::sun::star::uno::Reference;
97 : : using ::com::sun::star::uno::Sequence;
98 : : using ::com::sun::star::uno::UNO_QUERY;
99 : : using ::com::sun::star::uno::UNO_QUERY_THROW;
100 : : using ::com::sun::star::uno::UNO_SET_THROW;
101 : : using ::com::sun::star::uno::Exception;
102 : : using ::com::sun::star::beans::XPropertySet;
103 : : using ::com::sun::star::lang::XMultiServiceFactory;
104 : : using ::com::sun::star::frame::XModel;
105 : : using ::com::sun::star::util::XNumberFormatsSupplier;
106 : : using ::com::sun::star::drawing::XDrawPage;
107 : : using ::com::sun::star::drawing::XDrawPageSupplier;
108 : : using ::com::sun::star::drawing::XShape;
109 : :
110 : : using ::com::sun::star::chart2::IncrementData;
111 : : using ::com::sun::star::chart2::RelativePosition;
112 : : using ::com::sun::star::chart2::RelativeSize;
113 : : using ::com::sun::star::chart2::ScaleData;
114 : : using ::com::sun::star::chart2::SubIncrement;
115 : : using ::com::sun::star::chart2::XAxis;
116 : : using ::com::sun::star::chart2::XChartDocument;
117 : : using ::com::sun::star::chart2::XChartType;
118 : : using ::com::sun::star::chart2::XChartTypeContainer;
119 : : using ::com::sun::star::chart2::XCoordinateSystem;
120 : : using ::com::sun::star::chart2::XCoordinateSystemContainer;
121 : : using ::com::sun::star::chart2::XDataSeries;
122 : : using ::com::sun::star::chart2::XDataSeriesContainer;
123 : : using ::com::sun::star::chart2::XDiagram;
124 : : using ::com::sun::star::chart2::XFormattedString;
125 : : using ::com::sun::star::chart2::XLegend;
126 : : using ::com::sun::star::chart2::XRegressionCurve;
127 : : using ::com::sun::star::chart2::XRegressionCurveContainer;
128 : : using ::com::sun::star::chart2::XScaling;
129 : : using ::com::sun::star::chart2::XTitle;
130 : : using ::com::sun::star::chart2::XTitled;
131 : :
132 : : using ::com::sun::star::chart2::data::XDataProvider;
133 : : using ::com::sun::star::chart2::data::XDataReceiver;
134 : : using ::com::sun::star::chart2::data::XDataSequence;
135 : : using ::com::sun::star::chart2::data::XDataSink;
136 : : using ::com::sun::star::chart2::data::XLabeledDataSequence;
137 : :
138 : : using ::formula::FormulaToken;
139 : : using ::formula::StackVar;
140 : : using ::boost::shared_ptr;
141 : : using ::std::pair;
142 : : using ::std::auto_ptr;
143 : :
144 : : namespace cssc = ::com::sun::star::chart;
145 : : namespace cssc2 = ::com::sun::star::chart2;
146 : :
147 : : // Helpers ====================================================================
148 : :
149 : : namespace {
150 : :
151 : 42 : XclImpStream& operator>>( XclImpStream& rStrm, XclChRectangle& rRect )
152 : : {
153 : 42 : return rStrm >> rRect.mnX >> rRect.mnY >> rRect.mnWidth >> rRect.mnHeight;
154 : : }
155 : :
156 : 18 : inline void lclSetValueOrClearAny( Any& rAny, double fValue, bool bClear )
157 : : {
158 [ + - ]: 18 : if( bClear )
159 : 18 : rAny.clear();
160 : : else
161 : 0 : rAny <<= fValue;
162 : 18 : }
163 : :
164 : 12 : void lclSetExpValueOrClearAny( Any& rAny, double fValue, bool bLogScale, bool bClear )
165 : : {
166 [ - + ][ # # ]: 12 : if( !bClear && bLogScale )
167 : 0 : fValue = pow( 10.0, fValue );
168 : 12 : lclSetValueOrClearAny( rAny, fValue, bClear );
169 : 12 : }
170 : :
171 : 0 : double lclGetSerialDay( const XclImpRoot& rRoot, sal_uInt16 nValue, sal_uInt16 nTimeUnit )
172 : : {
173 [ # # # # ]: 0 : switch( nTimeUnit )
174 : : {
175 : : case EXC_CHDATERANGE_DAYS:
176 : 0 : return nValue;
177 : : case EXC_CHDATERANGE_MONTHS:
178 [ # # ]: 0 : return rRoot.GetDoubleFromDateTime( Date( 1, static_cast< sal_uInt16 >( 1 + nValue % 12 ), static_cast< sal_uInt16 >( rRoot.GetBaseYear() + nValue / 12 ) ) );
179 : : case EXC_CHDATERANGE_YEARS:
180 [ # # ]: 0 : return rRoot.GetDoubleFromDateTime( Date( 1, 1, static_cast< sal_uInt16 >( rRoot.GetBaseYear() + nValue ) ) );
181 : : default:
182 : : OSL_ENSURE( false, "lclGetSerialDay - unexpected time unit" );
183 : : }
184 : 0 : return nValue;
185 : : }
186 : :
187 : 0 : void lclConvertTimeValue( const XclImpRoot& rRoot, Any& rAny, sal_uInt16 nValue, bool bAuto, sal_uInt16 nTimeUnit )
188 : : {
189 [ # # ]: 0 : if( bAuto )
190 : 0 : rAny.clear();
191 : : else
192 [ # # ]: 0 : rAny <<= lclGetSerialDay( rRoot, nValue, nTimeUnit );
193 : 0 : }
194 : :
195 : 0 : sal_Int32 lclGetApiTimeUnit( sal_uInt16 nTimeUnit )
196 : : {
197 [ # # # # ]: 0 : switch( nTimeUnit )
198 : : {
199 : 0 : case EXC_CHDATERANGE_DAYS: return cssc::TimeUnit::DAY;
200 : 0 : case EXC_CHDATERANGE_MONTHS: return cssc::TimeUnit::MONTH;
201 : 0 : case EXC_CHDATERANGE_YEARS: return cssc::TimeUnit::YEAR;
202 : : default: OSL_ENSURE( false, "lclGetApiTimeUnit - unexpected time unit" );
203 : : }
204 : 0 : return cssc::TimeUnit::DAY;
205 : : }
206 : :
207 : 0 : void lclConvertTimeInterval( Any& rInterval, sal_uInt16 nValue, bool bAuto, sal_uInt16 nTimeUnit )
208 : : {
209 [ # # ][ # # ]: 0 : if( bAuto || (nValue == 0) )
210 : 0 : rInterval.clear();
211 : : else
212 [ # # ]: 0 : rInterval <<= cssc::TimeInterval( nValue, lclGetApiTimeUnit( nTimeUnit ) );
213 : 0 : }
214 : :
215 : : } // namespace
216 : :
217 : : // Common =====================================================================
218 : :
219 : : /** Stores global data needed in various classes of the Chart import filter. */
220 [ - + ]: 12 : struct XclImpChRootData : public XclChRootData
221 : : {
222 : : XclImpChChart& mrChartData; /// The chart data object.
223 : :
224 : 6 : inline explicit XclImpChRootData( XclImpChChart& rChartData ) : mrChartData( rChartData ) {}
225 : : };
226 : :
227 : : // ----------------------------------------------------------------------------
228 : :
229 : 6 : XclImpChRoot::XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart& rChartData ) :
230 : : XclImpRoot( rRoot ),
231 [ + - ][ + - ]: 6 : mxChData( new XclImpChRootData( rChartData ) )
[ + - ]
232 : : {
233 : 6 : }
234 : :
235 [ + - ]: 204 : XclImpChRoot::~XclImpChRoot()
236 : : {
237 [ - + ]: 204 : }
238 : :
239 : 54 : XclImpChChart& XclImpChRoot::GetChartData() const
240 : : {
241 : 54 : return mxChData->mrChartData;
242 : : }
243 : :
244 : 12 : const XclChTypeInfo& XclImpChRoot::GetChartTypeInfo( XclChTypeId eType ) const
245 : : {
246 : 12 : return mxChData->mxTypeInfoProv->GetTypeInfo( eType );
247 : : }
248 : :
249 : 0 : const XclChTypeInfo& XclImpChRoot::GetChartTypeInfo( sal_uInt16 nRecId ) const
250 : : {
251 : 0 : return mxChData->mxTypeInfoProv->GetTypeInfoFromRecId( nRecId );
252 : : }
253 : :
254 : 117 : const XclChFormatInfo& XclImpChRoot::GetFormatInfo( XclChObjectType eObjType ) const
255 : : {
256 : 117 : return mxChData->mxFmtInfoProv->GetFormatInfo( eObjType );
257 : : }
258 : :
259 : 24 : Color XclImpChRoot::GetFontAutoColor() const
260 : : {
261 : 24 : return GetPalette().GetColor( EXC_COLOR_CHWINDOWTEXT );
262 : : }
263 : :
264 : 6 : Color XclImpChRoot::GetSeriesLineAutoColor( sal_uInt16 nFormatIdx ) const
265 : : {
266 : 6 : return GetPalette().GetColor( XclChartHelper::GetSeriesLineAutoColorIdx( nFormatIdx ) );
267 : : }
268 : :
269 : 3 : Color XclImpChRoot::GetSeriesFillAutoColor( sal_uInt16 nFormatIdx ) const
270 : : {
271 [ + - ]: 3 : const XclImpPalette& rPal = GetPalette();
272 [ + - ][ + - ]: 3 : Color aColor = rPal.GetColor( XclChartHelper::GetSeriesFillAutoColorIdx( nFormatIdx ) );
273 [ + - ]: 3 : sal_uInt8 nTrans = XclChartHelper::GetSeriesFillAutoTransp( nFormatIdx );
274 [ + - ][ + - ]: 3 : return ScfTools::GetMixedColor( aColor, rPal.GetColor( EXC_COLOR_CHWINDOWBACK ), nTrans );
275 : : }
276 : :
277 : 6 : void XclImpChRoot::InitConversion( const Reference<XChartDocument>& xChartDoc, const Rectangle& rChartRect ) const
278 : : {
279 : : // create formatting object tables
280 [ + - ]: 6 : mxChData->InitConversion( GetRoot(), xChartDoc, rChartRect );
281 : :
282 : : // lock the model to suppress any internal updates
283 [ + - ]: 6 : Reference< XModel > xModel( xChartDoc, UNO_QUERY );
284 [ + - ]: 6 : if( xModel.is() )
285 [ + - ][ + - ]: 6 : xModel->lockControllers();
286 : :
287 [ + - ]: 6 : SfxObjectShell* pDocShell = GetDocShell();
288 [ + - ]: 6 : Reference< XDataReceiver > xDataRec( xChartDoc, UNO_QUERY );
289 [ + - ][ + - ]: 6 : if( pDocShell && xDataRec.is() )
[ + - ]
290 : : {
291 : : // create and register a data provider
292 : : Reference< XDataProvider > xDataProv(
293 [ + - ][ + - ]: 6 : ScfApiHelper::CreateInstance( pDocShell, SERVICE_CHART2_DATAPROVIDER ), UNO_QUERY );
[ + - ]
294 [ + - ]: 6 : if( xDataProv.is() )
295 [ + - ][ + - ]: 6 : xDataRec->attachDataProvider( xDataProv );
296 : : // attach the number formatter
297 [ + - ][ + - ]: 6 : Reference< XNumberFormatsSupplier > xNumFmtSupp( pDocShell->GetModel(), UNO_QUERY );
298 [ + - ]: 6 : if( xNumFmtSupp.is() )
299 [ + - ][ + - ]: 6 : xDataRec->attachNumberFormatsSupplier( xNumFmtSupp );
300 : 6 : }
301 : 6 : }
302 : :
303 : 6 : void XclImpChRoot::FinishConversion( XclImpDffConverter& rDffConv ) const
304 : : {
305 [ + - ]: 6 : rDffConv.Progress( EXC_CHART_PROGRESS_SIZE );
306 : : // unlock the model
307 [ + - ]: 6 : Reference< XModel > xModel( mxChData->mxChartDoc, UNO_QUERY );
308 [ + - ]: 6 : if( xModel.is() )
309 [ + - ][ + - ]: 6 : xModel->unlockControllers();
310 [ + - ]: 6 : rDffConv.Progress( EXC_CHART_PROGRESS_SIZE );
311 : :
312 [ + - ]: 6 : mxChData->FinishConversion();
313 : 6 : }
314 : :
315 : 18 : Reference< XDataProvider > XclImpChRoot::GetDataProvider() const
316 : : {
317 : 18 : return mxChData->mxChartDoc->getDataProvider();
318 : : }
319 : :
320 : 3 : Reference< XShape > XclImpChRoot::GetTitleShape( const XclChTextKey& rTitleKey ) const
321 : : {
322 : 3 : return mxChData->GetTitleShape( rTitleKey );
323 : : }
324 : :
325 : 12 : sal_Int32 XclImpChRoot::CalcHmmFromChartX( sal_Int32 nPosX ) const
326 : : {
327 : 12 : return static_cast< sal_Int32 >( mxChData->mfUnitSizeX * nPosX + mxChData->mnBorderGapX + 0.5 );
328 : : }
329 : :
330 : 12 : sal_Int32 XclImpChRoot::CalcHmmFromChartY( sal_Int32 nPosY ) const
331 : : {
332 : 12 : return static_cast< sal_Int32 >( mxChData->mfUnitSizeY * nPosY + mxChData->mnBorderGapY + 0.5 );
333 : : }
334 : :
335 : 3 : ::com::sun::star::awt::Rectangle XclImpChRoot::CalcHmmFromChartRect( const XclChRectangle& rRect ) const
336 : : {
337 : : return ::com::sun::star::awt::Rectangle(
338 [ + - ]: 3 : CalcHmmFromChartX( rRect.mnX ),
339 [ + - ]: 3 : CalcHmmFromChartY( rRect.mnY ),
340 [ + - ]: 3 : CalcHmmFromChartX( rRect.mnWidth ),
341 : 6 : CalcHmmFromChartY( rRect.mnHeight ) );
342 : : }
343 : :
344 : 3 : double XclImpChRoot::CalcRelativeFromHmmX( sal_Int32 nPosX ) const
345 : : {
346 : 3 : return static_cast< double >( nPosX ) / mxChData->maChartRect.GetWidth();
347 : : }
348 : :
349 : 3 : double XclImpChRoot::CalcRelativeFromHmmY( sal_Int32 nPosY ) const
350 : : {
351 : 3 : return static_cast< double >( nPosY ) / mxChData->maChartRect.GetHeight();
352 : : }
353 : :
354 : 3 : double XclImpChRoot::CalcRelativeFromChartX( sal_Int32 nPosX ) const
355 : : {
356 : 3 : return CalcRelativeFromHmmX( CalcHmmFromChartX( nPosX ) );
357 : : }
358 : :
359 : 3 : double XclImpChRoot::CalcRelativeFromChartY( sal_Int32 nPosY ) const
360 : : {
361 : 3 : return CalcRelativeFromHmmY( CalcHmmFromChartY( nPosY ) );
362 : : }
363 : :
364 : 42 : void XclImpChRoot::ConvertLineFormat( ScfPropertySet& rPropSet,
365 : : const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode ) const
366 : : {
367 : 42 : GetChartPropSetHelper().WriteLineProperties(
368 : 84 : rPropSet, *mxChData->mxLineDashTable, rLineFmt, ePropMode );
369 : 42 : }
370 : :
371 : 21 : void XclImpChRoot::ConvertAreaFormat( ScfPropertySet& rPropSet,
372 : : const XclChAreaFormat& rAreaFmt, XclChPropertyMode ePropMode ) const
373 : : {
374 : 21 : GetChartPropSetHelper().WriteAreaProperties( rPropSet, rAreaFmt, ePropMode );
375 : 21 : }
376 : :
377 : 0 : void XclImpChRoot::ConvertEscherFormat( ScfPropertySet& rPropSet,
378 : : const XclChEscherFormat& rEscherFmt, const XclChPicFormat* pPicFmt,
379 : : sal_uInt32 nDffFillType, XclChPropertyMode ePropMode ) const
380 : : {
381 : 0 : GetChartPropSetHelper().WriteEscherProperties( rPropSet,
382 : 0 : *mxChData->mxGradientTable, *mxChData->mxHatchTable, *mxChData->mxBitmapTable,
383 : 0 : rEscherFmt, pPicFmt, nDffFillType, ePropMode );
384 : 0 : }
385 : :
386 : 24 : void XclImpChRoot::ConvertFont( ScfPropertySet& rPropSet,
387 : : sal_uInt16 nFontIdx, const Color* pFontColor ) const
388 : : {
389 : 24 : GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CHART, nFontIdx, pFontColor );
390 : 24 : }
391 : :
392 : 0 : void XclImpChRoot::ConvertPieRotation( ScfPropertySet& rPropSet, sal_uInt16 nAngle )
393 : : {
394 : 0 : sal_Int32 nApiRot = (450 - (nAngle % 360)) % 360;
395 [ # # ][ # # ]: 0 : rPropSet.SetProperty( EXC_CHPROP_STARTINGANGLE, nApiRot );
396 : 0 : }
397 : :
398 : : // ----------------------------------------------------------------------------
399 : :
400 : 114 : XclImpChGroupBase::~XclImpChGroupBase()
401 : : {
402 [ - + ]: 114 : }
403 : :
404 : 84 : void XclImpChGroupBase::ReadRecordGroup( XclImpStream& rStrm )
405 : : {
406 : : // read contents of the header record
407 : 84 : ReadHeaderRecord( rStrm );
408 : :
409 : : // only read sub records, if the next record is a CHBEGIN
410 [ + - ]: 84 : if( rStrm.GetNextRecId() == EXC_ID_CHBEGIN )
411 : : {
412 : : // read the CHBEGIN record, may be used for special initial processing
413 : 84 : rStrm.StartNextRecord();
414 : 84 : ReadSubRecord( rStrm );
415 : :
416 : : // read the nested records
417 : 84 : bool bLoop = true;
418 [ + + ][ + - ]: 468 : while( bLoop && rStrm.StartNextRecord() )
[ + + ]
419 : : {
420 : 384 : sal_uInt16 nRecId = rStrm.GetRecId();
421 : 384 : bLoop = nRecId != EXC_ID_CHEND;
422 : : // skip unsupported nested blocks
423 [ - + ]: 384 : if( nRecId == EXC_ID_CHBEGIN )
424 : 0 : SkipBlock( rStrm );
425 : : else
426 : 384 : ReadSubRecord( rStrm );
427 : : }
428 : : }
429 : : /* Returns with current CHEND record or unchanged stream, if no record
430 : : group present. In every case another call to StartNextRecord() will go
431 : : to next record of interest. */
432 : 84 : }
433 : :
434 : 0 : void XclImpChGroupBase::SkipBlock( XclImpStream& rStrm )
435 : : {
436 : : OSL_ENSURE( rStrm.GetRecId() == EXC_ID_CHBEGIN, "XclImpChGroupBase::SkipBlock - no CHBEGIN record" );
437 : : // do nothing if current record is not CHBEGIN
438 : 0 : bool bLoop = rStrm.GetRecId() == EXC_ID_CHBEGIN;
439 [ # # ][ # # ]: 0 : while( bLoop && rStrm.StartNextRecord() )
[ # # ]
440 : : {
441 : 0 : sal_uInt16 nRecId = rStrm.GetRecId();
442 : 0 : bLoop = nRecId != EXC_ID_CHEND;
443 : : // skip nested record groups
444 [ # # ]: 0 : if( nRecId == EXC_ID_CHBEGIN )
445 : 0 : SkipBlock( rStrm );
446 : : }
447 : 0 : }
448 : :
449 : : // Frame formatting ===========================================================
450 : :
451 : 36 : void XclImpChFramePos::ReadChFramePos( XclImpStream& rStrm )
452 : : {
453 : 36 : rStrm >> maData.mnTLMode >> maData.mnBRMode;
454 : : /* According to the spec, the upper 16 bits of all members in the
455 : : rectangle are unused and may contain garbage. */
456 : 36 : maData.maRect.mnX = rStrm.ReadInt16(); rStrm.Ignore( 2 );
457 : 36 : maData.maRect.mnY = rStrm.ReadInt16(); rStrm.Ignore( 2 );
458 : 36 : maData.maRect.mnWidth = rStrm.ReadInt16(); rStrm.Ignore( 2 );
459 : 36 : maData.maRect.mnHeight = rStrm.ReadInt16(); rStrm.Ignore( 2 );
460 : 36 : }
461 : :
462 : : // ----------------------------------------------------------------------------
463 : :
464 : 18 : void XclImpChLineFormat::ReadChLineFormat( XclImpStream& rStrm )
465 : : {
466 : 18 : rStrm >> maData.maColor >> maData.mnPattern >> maData.mnWeight >> maData.mnFlags;
467 : :
468 : 18 : const XclImpRoot& rRoot = rStrm.GetRoot();
469 [ + - ]: 18 : if( rRoot.GetBiff() == EXC_BIFF8 )
470 : : // BIFF8: index into palette used instead of RGB data
471 : 18 : maData.maColor = rRoot.GetPalette().GetColor( rStrm.ReaduInt16() );
472 : 18 : }
473 : :
474 : 42 : void XclImpChLineFormat::Convert( const XclImpChRoot& rRoot,
475 : : ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
476 : : {
477 : 42 : const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
478 [ + + ]: 42 : if( IsAuto() )
479 : : {
480 [ + - ]: 36 : XclChLineFormat aLineFmt;
481 : : aLineFmt.maColor = (eObjType == EXC_CHOBJTYPE_LINEARSERIES) ?
482 : 3 : rRoot.GetSeriesLineAutoColor( nFormatIdx ) :
483 [ + + ][ + - ]: 36 : rRoot.GetPalette().GetColor( rFmtInfo.mnAutoLineColorIdx );
[ + - ][ + - ]
484 : 36 : aLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
485 : 36 : aLineFmt.mnWeight = rFmtInfo.mnAutoLineWeight;
486 [ + - ]: 36 : rRoot.ConvertLineFormat( rPropSet, aLineFmt, rFmtInfo.mePropMode );
487 : : }
488 : : else
489 : : {
490 : 6 : rRoot.ConvertLineFormat( rPropSet, maData, rFmtInfo.mePropMode );
491 : : }
492 : 42 : }
493 : :
494 : : // ----------------------------------------------------------------------------
495 : :
496 : 12 : void XclImpChAreaFormat::ReadChAreaFormat( XclImpStream& rStrm )
497 : : {
498 : 12 : rStrm >> maData.maPattColor >> maData.maBackColor >> maData.mnPattern >> maData.mnFlags;
499 : :
500 : 12 : const XclImpRoot& rRoot = rStrm.GetRoot();
501 [ + - ]: 12 : if( rRoot.GetBiff() == EXC_BIFF8 )
502 : : {
503 : : // BIFF8: index into palette used instead of RGB data
504 : 12 : const XclImpPalette& rPal = rRoot.GetPalette();
505 : 12 : maData.maPattColor = rPal.GetColor( rStrm.ReaduInt16() );
506 : 12 : maData.maBackColor = rPal.GetColor( rStrm.ReaduInt16());
507 : : }
508 : 12 : }
509 : :
510 : 21 : void XclImpChAreaFormat::Convert( const XclImpChRoot& rRoot,
511 : : ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
512 : : {
513 : 21 : const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
514 [ + + ]: 21 : if( IsAuto() )
515 : : {
516 [ + - ]: 15 : XclChAreaFormat aAreaFmt;
517 : : aAreaFmt.maPattColor = (eObjType == EXC_CHOBJTYPE_FILLEDSERIES) ?
518 : 3 : rRoot.GetSeriesFillAutoColor( nFormatIdx ) :
519 [ + + ][ + - ]: 15 : rRoot.GetPalette().GetColor( rFmtInfo.mnAutoPattColorIdx );
[ + - ][ + - ]
520 : 15 : aAreaFmt.mnPattern = EXC_PATT_SOLID;
521 [ + - ]: 15 : rRoot.ConvertAreaFormat( rPropSet, aAreaFmt, rFmtInfo.mePropMode );
522 : : }
523 : : else
524 : : {
525 : 6 : rRoot.ConvertAreaFormat( rPropSet, maData, rFmtInfo.mePropMode );
526 : : }
527 : 21 : }
528 : :
529 : : // ----------------------------------------------------------------------------
530 : :
531 : 0 : XclImpChEscherFormat::XclImpChEscherFormat( const XclImpRoot& rRoot ) :
532 [ # # ][ # # ]: 0 : mnDffFillType( mso_fillSolid )
533 : : {
534 : : maData.mxItemSet.reset(
535 [ # # ][ # # ]: 0 : new SfxItemSet( rRoot.GetDoc().GetDrawLayer()->GetItemPool() ) );
[ # # ][ # # ]
536 : 0 : }
537 : :
538 : 0 : void XclImpChEscherFormat::ReadHeaderRecord( XclImpStream& rStrm )
539 : : {
540 : : // read from stream - CHESCHERFORMAT uses own ID for record continuation
541 [ # # ]: 0 : XclImpDffPropSet aPropSet( rStrm.GetRoot() );
542 [ # # ]: 0 : rStrm.ResetRecord( true, rStrm.GetRecId() );
543 [ # # ]: 0 : rStrm >> aPropSet;
544 : : // get the data
545 [ # # ]: 0 : aPropSet.FillToItemSet( *maData.mxItemSet );
546 : : // get fill type from DFF property set
547 [ # # ][ # # ]: 0 : mnDffFillType = aPropSet.GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
548 : 0 : }
549 : :
550 : 0 : void XclImpChEscherFormat::ReadSubRecord( XclImpStream& rStrm )
551 : : {
552 [ # # ]: 0 : switch( rStrm.GetRecId() )
553 : : {
554 : : case EXC_ID_CHPICFORMAT:
555 : 0 : rStrm >> maPicFmt.mnBmpMode;
556 : 0 : rStrm.Ignore( 2 );
557 : 0 : rStrm >> maPicFmt.mnFlags >> maPicFmt.mfScale;
558 : 0 : break;
559 : : }
560 : 0 : }
561 : :
562 : 0 : void XclImpChEscherFormat::Convert( const XclImpChRoot& rRoot,
563 : : ScfPropertySet& rPropSet, XclChObjectType eObjType, bool bUsePicFmt ) const
564 : : {
565 : 0 : const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
566 [ # # ]: 0 : rRoot.ConvertEscherFormat( rPropSet, maData, bUsePicFmt ? &maPicFmt : 0, mnDffFillType, rFmtInfo.mePropMode );
567 : 0 : }
568 : :
569 : : // ----------------------------------------------------------------------------
570 : :
571 [ + - ][ + - ]: 30 : XclImpChFrameBase::XclImpChFrameBase( const XclChFormatInfo& rFmtInfo )
[ + - ]
572 : : {
573 [ + - ]: 30 : if( rFmtInfo.mbCreateDefFrame ) switch( rFmtInfo.meDefFrameType )
[ + + - ]
574 : : {
575 : : case EXC_CHFRAMETYPE_AUTO:
576 [ + - ][ + - ]: 18 : mxLineFmt.reset( new XclImpChLineFormat );
[ + - ]
577 [ + - ]: 18 : if( rFmtInfo.mbIsFrame )
578 [ + - ][ + - ]: 18 : mxAreaFmt.reset( new XclImpChAreaFormat );
[ + - ]
579 : 18 : break;
580 : : case EXC_CHFRAMETYPE_INVISIBLE:
581 : : {
582 [ + - ]: 12 : XclChLineFormat aLineFmt;
583 : 12 : ::set_flag( aLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, false );
584 : 12 : aLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
585 [ + - ][ + - ]: 12 : mxLineFmt.reset( new XclImpChLineFormat( aLineFmt ) );
586 [ + - ]: 12 : if( rFmtInfo.mbIsFrame )
587 : : {
588 [ + - ]: 12 : XclChAreaFormat aAreaFmt;
589 : 12 : ::set_flag( aAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, false );
590 : 12 : aAreaFmt.mnPattern = EXC_PATT_NONE;
591 [ + - ][ + - ]: 12 : mxAreaFmt.reset( new XclImpChAreaFormat( aAreaFmt ) );
592 : : }
593 : : }
594 : 30 : break;
595 : : default:
596 : : OSL_FAIL( "XclImpChFrameBase::XclImpChFrameBase - unknown frame type" );
597 : : }
598 : 30 : }
599 : :
600 : 60 : void XclImpChFrameBase::ReadSubRecord( XclImpStream& rStrm )
601 : : {
602 [ + + - + ]: 60 : switch( rStrm.GetRecId() )
603 : : {
604 : : case EXC_ID_CHLINEFORMAT:
605 [ + - ]: 12 : mxLineFmt.reset( new XclImpChLineFormat );
606 : 12 : mxLineFmt->ReadChLineFormat( rStrm );
607 : 12 : break;
608 : : case EXC_ID_CHAREAFORMAT:
609 [ + - ]: 12 : mxAreaFmt.reset( new XclImpChAreaFormat );
610 : 12 : mxAreaFmt->ReadChAreaFormat( rStrm );
611 : 12 : break;
612 : : case EXC_ID_CHESCHERFORMAT:
613 [ # # ]: 0 : mxEscherFmt.reset( new XclImpChEscherFormat( rStrm.GetRoot() ) );
614 : 0 : mxEscherFmt->ReadRecordGroup( rStrm );
615 : 0 : break;
616 : : }
617 : 60 : }
618 : :
619 : 24 : void XclImpChFrameBase::ConvertLineBase( const XclImpChRoot& rRoot,
620 : : ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
621 : : {
622 [ + - ]: 24 : if( mxLineFmt )
623 : 24 : mxLineFmt->Convert( rRoot, rPropSet, eObjType, nFormatIdx );
624 : 24 : }
625 : :
626 : 24 : void XclImpChFrameBase::ConvertAreaBase( const XclImpChRoot& rRoot,
627 : : ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx, bool bUsePicFmt ) const
628 : : {
629 [ + + ]: 24 : if( rRoot.GetFormatInfo( eObjType ).mbIsFrame )
630 : : {
631 : : // CHESCHERFORMAT overrides CHAREAFORMAT (even if it is auto)
632 [ - + ]: 21 : if( mxEscherFmt )
633 : 0 : mxEscherFmt->Convert( rRoot, rPropSet, eObjType, bUsePicFmt );
634 [ + - ]: 21 : else if( mxAreaFmt )
635 : 21 : mxAreaFmt->Convert( rRoot, rPropSet, eObjType, nFormatIdx );
636 : : }
637 : 24 : }
638 : :
639 : 24 : void XclImpChFrameBase::ConvertFrameBase( const XclImpChRoot& rRoot,
640 : : ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx, bool bUsePicFmt ) const
641 : : {
642 : 24 : ConvertLineBase( rRoot, rPropSet, eObjType, nFormatIdx );
643 : 24 : ConvertAreaBase( rRoot, rPropSet, eObjType, nFormatIdx, bUsePicFmt );
644 : 24 : }
645 : :
646 : : // ----------------------------------------------------------------------------
647 : :
648 : 30 : XclImpChFrame::XclImpChFrame( const XclImpChRoot& rRoot, XclChObjectType eObjType ) :
649 : 30 : XclImpChFrameBase( rRoot.GetFormatInfo( eObjType ) ),
650 : : XclImpChRoot( rRoot ),
651 [ + - ][ + - ]: 30 : meObjType( eObjType )
652 : : {
653 : 30 : }
654 : :
655 : 12 : void XclImpChFrame::ReadHeaderRecord( XclImpStream& rStrm )
656 : : {
657 : 12 : rStrm >> maData.mnFormat >> maData.mnFlags;
658 : 12 : }
659 : :
660 : 0 : void XclImpChFrame::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData )
661 : : {
662 : 0 : const XclImpPalette& rPal = GetPalette();
663 : :
664 [ # # ][ # # ]: 0 : if( rLineData.IsVisible() && (!mxLineFmt || !mxLineFmt->HasLine()) )
[ # # ][ # # ]
665 : : {
666 : : // line formatting
667 [ # # ]: 0 : XclChLineFormat aLineFmt;
668 [ # # ]: 0 : aLineFmt.maColor = rPal.GetColor( rLineData.mnColorIdx );
669 [ # # # # : 0 : switch( rLineData.mnStyle )
# # # # #
# ]
670 : : {
671 : 0 : case EXC_OBJ_LINE_SOLID: aLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID; break;
672 : 0 : case EXC_OBJ_LINE_DASH: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DASH; break;
673 : 0 : case EXC_OBJ_LINE_DOT: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DOT; break;
674 : 0 : case EXC_OBJ_LINE_DASHDOT: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DASHDOT; break;
675 : 0 : case EXC_OBJ_LINE_DASHDOTDOT: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DASHDOTDOT; break;
676 : 0 : case EXC_OBJ_LINE_MEDTRANS: aLineFmt.mnPattern = EXC_CHLINEFORMAT_MEDTRANS; break;
677 : 0 : case EXC_OBJ_LINE_DARKTRANS: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DARKTRANS; break;
678 : 0 : case EXC_OBJ_LINE_LIGHTTRANS: aLineFmt.mnPattern = EXC_CHLINEFORMAT_LIGHTTRANS; break;
679 : 0 : case EXC_OBJ_LINE_NONE: aLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE; break;
680 : 0 : default: aLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
681 : : }
682 [ # # # # : 0 : switch( rLineData.mnWidth )
# ]
683 : : {
684 : 0 : case EXC_OBJ_LINE_HAIR: aLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR; break;
685 : 0 : case EXC_OBJ_LINE_THIN: aLineFmt.mnWeight = EXC_CHLINEFORMAT_SINGLE; break;
686 : 0 : case EXC_OBJ_LINE_MEDIUM: aLineFmt.mnWeight = EXC_CHLINEFORMAT_DOUBLE; break;
687 : 0 : case EXC_OBJ_LINE_THICK: aLineFmt.mnWeight = EXC_CHLINEFORMAT_TRIPLE; break;
688 : 0 : default: aLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR;
689 : : }
690 [ # # ]: 0 : ::set_flag( aLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, rLineData.IsAuto() );
691 [ # # ][ # # ]: 0 : mxLineFmt.reset( new XclImpChLineFormat( aLineFmt ) );
692 : : }
693 : :
694 [ # # ][ # # ]: 0 : if( rFillData.IsFilled() && (!mxAreaFmt || !mxAreaFmt->HasArea()) && !mxEscherFmt )
[ # # ][ # # ]
[ # # ]
695 : : {
696 : : // area formatting
697 [ # # ]: 0 : XclChAreaFormat aAreaFmt;
698 [ # # ]: 0 : aAreaFmt.maPattColor = rPal.GetColor( rFillData.mnPattColorIdx );
699 [ # # ]: 0 : aAreaFmt.maBackColor = rPal.GetColor( rFillData.mnBackColorIdx );
700 : 0 : aAreaFmt.mnPattern = rFillData.mnPattern;
701 [ # # ]: 0 : ::set_flag( aAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, rFillData.IsAuto() );
702 [ # # ][ # # ]: 0 : mxAreaFmt.reset( new XclImpChAreaFormat( aAreaFmt ) );
703 : : }
704 : 0 : }
705 : :
706 : 18 : void XclImpChFrame::Convert( ScfPropertySet& rPropSet, bool bUsePicFmt ) const
707 : : {
708 : 18 : ConvertFrameBase( GetChRoot(), rPropSet, meObjType, EXC_CHDATAFORMAT_UNKNOWN, bUsePicFmt );
709 : 18 : }
710 : :
711 : : // Source links ===============================================================
712 : :
713 : : namespace {
714 : :
715 : : /** Creates a labeled data sequence object, adds link for series title if present. */
716 : 12 : Reference< XLabeledDataSequence > lclCreateLabeledDataSequence(
717 : : const XclImpChSourceLinkRef& xValueLink, const OUString& rValueRole,
718 : : const XclImpChSourceLink* pTitleLink = 0 )
719 : : {
720 : : // create data sequence for values and title
721 : 12 : Reference< XDataSequence > xValueSeq;
722 [ + - ]: 12 : if( xValueLink )
723 [ + - ][ + - ]: 12 : xValueSeq = xValueLink->CreateDataSequence( rValueRole );
724 : 12 : Reference< XDataSequence > xTitleSeq;
725 [ + + ]: 12 : if( pTitleLink )
726 [ + - ][ + - ]: 6 : xTitleSeq = pTitleLink->CreateDataSequence( EXC_CHPROP_ROLE_LABEL );
[ + - ]
727 : :
728 : : // create the labeled data sequence, if values or title are present
729 : 12 : Reference< XLabeledDataSequence > xLabeledSeq;
730 [ # # ][ + - ]: 12 : if( xValueSeq.is() || xTitleSeq.is() )
[ - + ]
731 [ + - ][ + - ]: 12 : xLabeledSeq.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_LABELEDDATASEQ ), UNO_QUERY );
[ + - ]
732 [ + - ]: 12 : if( xLabeledSeq.is() )
733 : : {
734 [ + - ]: 12 : if( xValueSeq.is() )
735 [ + - ][ + - ]: 12 : xLabeledSeq->setValues( xValueSeq );
736 [ + + ]: 12 : if( xTitleSeq.is() )
737 [ + - ][ + - ]: 6 : xLabeledSeq->setLabel( xTitleSeq );
738 : : }
739 : 12 : return xLabeledSeq;
740 : : }
741 : :
742 : : } // namespace
743 : :
744 : : // ----------------------------------------------------------------------------
745 : :
746 : 48 : XclImpChSourceLink::XclImpChSourceLink( const XclImpChRoot& rRoot ) :
747 [ + - ][ + - ]: 48 : XclImpChRoot( rRoot )
[ + - ]
748 : : {
749 : 48 : }
750 : :
751 [ + - ][ + - ]: 48 : XclImpChSourceLink::~XclImpChSourceLink()
752 : : {
753 [ - + ]: 96 : }
754 : :
755 : 48 : void XclImpChSourceLink::ReadChSourceLink( XclImpStream& rStrm )
756 : : {
757 : 48 : rStrm >> maData.mnDestType
758 : 48 : >> maData.mnLinkType
759 : 48 : >> maData.mnFlags
760 : 48 : >> maData.mnNumFmtIdx;
761 : :
762 : 48 : mxTokenArray.reset();
763 [ + + ]: 48 : if( GetLinkType() == EXC_CHSRCLINK_WORKSHEET )
764 : : {
765 : : // read token array
766 [ + - ]: 18 : XclTokenArray aXclTokArr;
767 [ + - ]: 18 : rStrm >> aXclTokArr;
768 : :
769 : : // convert BIFF formula tokens to Calc token array
770 [ + - ][ + - ]: 18 : if( const ScTokenArray* pTokens = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CHART, aXclTokArr ) )
[ + - ]
771 [ + - ][ + - ]: 18 : mxTokenArray.reset( pTokens->Clone() );
772 : : }
773 : :
774 : : // try to read a following CHSTRING record
775 [ + + ][ + - ]: 48 : if( (rStrm.GetNextRecId() == EXC_ID_CHSTRING) && rStrm.StartNextRecord() )
[ + + ]
776 : : {
777 [ + - ]: 12 : mxString.reset( new XclImpString );
778 : 12 : rStrm.Ignore( 2 );
779 : 12 : mxString->Read( rStrm, EXC_STR_8BITLENGTH | EXC_STR_SEPARATEFORMATS );
780 : : }
781 : 48 : }
782 : :
783 : 0 : void XclImpChSourceLink::SetString( const String& rString )
784 : : {
785 [ # # ]: 0 : if( !mxString )
786 [ # # ]: 0 : mxString.reset( new XclImpString );
787 : 0 : mxString->SetText( rString );
788 : 0 : }
789 : :
790 : 0 : void XclImpChSourceLink::SetTextFormats( const XclFormatRunVec& rFormats )
791 : : {
792 [ # # ]: 0 : if( mxString )
793 : 0 : mxString->SetFormats( rFormats );
794 : 0 : }
795 : :
796 : 0 : sal_uInt16 XclImpChSourceLink::GetCellCount() const
797 : : {
798 : 0 : sal_uInt32 nCellCount = 0;
799 [ # # ]: 0 : if( mxTokenArray )
800 : : {
801 : 0 : mxTokenArray->Reset();
802 [ # # ]: 0 : for( const FormulaToken* pToken = mxTokenArray->First(); pToken; pToken = mxTokenArray->Next() )
803 : : {
804 [ # # # ]: 0 : switch( pToken->GetType() )
805 : : {
806 : : case ::formula::svSingleRef:
807 : : case ::formula::svExternalSingleRef:
808 : : // single cell
809 : 0 : ++nCellCount;
810 : 0 : break;
811 : : case ::formula::svDoubleRef:
812 : : case ::formula::svExternalDoubleRef:
813 : : {
814 : : // cell range
815 : 0 : const ScComplexRefData& rComplexRef = static_cast< const ScToken* >( pToken )->GetDoubleRef();
816 : 0 : const ScSingleRefData& rRef1 = rComplexRef.Ref1;
817 : 0 : const ScSingleRefData& rRef2 = rComplexRef.Ref2;
818 : 0 : sal_uInt32 nTabs = static_cast< sal_uInt32 >( rRef2.nTab - rRef1.nTab + 1 );
819 : 0 : sal_uInt32 nCols = static_cast< sal_uInt32 >( rRef2.nCol - rRef1.nCol + 1 );
820 : 0 : sal_uInt32 nRows = static_cast< sal_uInt32 >( rRef2.nRow - rRef1.nRow + 1 );
821 : 0 : nCellCount += nCols * nRows * nTabs;
822 : : }
823 : 0 : break;
824 : : default: ;
825 : : }
826 : : }
827 : : }
828 : 0 : return limit_cast< sal_uInt16 >( nCellCount );
829 : : }
830 : :
831 : 0 : void XclImpChSourceLink::ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const
832 : : {
833 : 0 : bool bLinkToSource = ::get_flag( maData.mnFlags, EXC_CHSRCLINK_NUMFMT );
834 [ # # ][ # # ]: 0 : sal_uInt32 nScNumFmt = bLinkToSource ? GetNumFmtBuffer().GetScFormat( maData.mnNumFmtIdx ) : NUMBERFORMAT_ENTRY_NOT_FOUND;
[ # # ]
835 [ # # ][ # # ]: 0 : OUString aPropName = bPercent ? EXC_CHPROP_PERCENTAGENUMFMT : EXC_CHPROP_NUMBERFORMAT;
[ # # ]
836 [ # # ]: 0 : if( nScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND )
837 [ # # ]: 0 : rPropSet.SetProperty( aPropName, static_cast< sal_Int32 >( nScNumFmt ) );
838 : : else
839 : : // restore 'link to source' at data point (series may contain manual number format)
840 [ # # ]: 0 : rPropSet.SetAnyProperty( aPropName, Any() );
841 : 0 : }
842 : :
843 : 18 : Reference< XDataSequence > XclImpChSourceLink::CreateDataSequence( const OUString& rRole ) const
844 : : {
845 : 18 : Reference< XDataSequence > xDataSeq;
846 [ + - ]: 18 : Reference< XDataProvider > xDataProv = GetDataProvider();
847 [ + - ][ + - ]: 18 : if( xDataProv.is() && mxTokenArray )
[ + - ]
848 : : {
849 [ + - ]: 18 : ScCompiler aComp( GetDocPtr(), ScAddress(), *mxTokenArray );
850 [ + - ][ + - ]: 18 : aComp.SetGrammar(GetDoc().GetGrammar());
851 : 18 : OUStringBuffer aRangeRep;
852 [ + - ]: 18 : aComp.CreateStringFromTokenArray( aRangeRep );
853 : : try
854 : : {
855 [ + - ][ + - ]: 18 : xDataSeq = xDataProv->createDataSequenceByRangeRepresentation( aRangeRep.makeStringAndClear() );
[ + - ][ + - ]
856 : : // set sequence role
857 [ + - ]: 18 : ScfPropertySet aSeqProp( xDataSeq );
858 [ + - ][ + - ]: 18 : aSeqProp.SetProperty( EXC_CHPROP_ROLE, rRole );
[ # # ][ + - ]
859 : : }
860 [ # # ]: 0 : catch( Exception& )
861 : : {
862 : : // OSL_FAIL( "XclImpChSourceLink::CreateDataSequence - cannot create data sequence" );
863 [ + - ]: 18 : }
864 : : }
865 [ # # ][ # # ]: 0 : else if( rRole == EXC_CHPROP_ROLE_LABEL && mxString && mxString->GetText().Len() )
[ # # ][ # # ]
[ # # ]
[ # # # # ]
866 : : {
867 : : try
868 : : {
869 : 0 : OUString aString = OUString::createFromAscii("\"");
870 [ # # ][ # # ]: 0 : xDataSeq = xDataProv->createDataSequenceByRangeRepresentation( aString + mxString->GetText() + aString );
[ # # ][ # # ]
871 : : // set sequence role
872 [ # # ]: 0 : ScfPropertySet aSeqProp( xDataSeq );
873 [ # # ][ # # ]: 0 : aSeqProp.SetProperty( EXC_CHPROP_ROLE, rRole );
[ # # ][ # # ]
874 : : }
875 [ # # ]: 0 : catch( Exception& ) { }
876 : : }
877 : 18 : return xDataSeq;
878 : : }
879 : :
880 : 6 : Sequence< Reference< XFormattedString > > XclImpChSourceLink::CreateStringSequence(
881 : : const XclImpChRoot& rRoot, sal_uInt16 nLeadFontIdx, const Color& rLeadFontColor ) const
882 : : {
883 [ + - ]: 6 : ::std::vector< Reference< XFormattedString > > aStringVec;
884 [ + - ]: 6 : if( mxString )
885 : : {
886 [ + - ][ + - ]: 12 : for( XclImpStringIterator aIt( *mxString ); aIt.Is(); ++aIt )
[ + + ]
887 : : {
888 : : Reference< XFormattedString > xFmtStr(
889 [ + - ][ + - ]: 6 : ScfApiHelper::CreateInstance( SERVICE_CHART2_FORMATTEDSTRING ), UNO_QUERY );
[ + - ]
890 [ + - ]: 6 : if( xFmtStr.is() )
891 : : {
892 : : // set text data
893 [ + - ][ + - ]: 6 : xFmtStr->setString( aIt.GetPortionText() );
[ + - ][ + - ]
[ + - ]
894 : :
895 : : // set font formatting and font color
896 [ + - ]: 6 : ScfPropertySet aStringProp( xFmtStr );
897 [ + - ]: 6 : sal_uInt16 nFontIdx = aIt.GetPortionFont();
898 [ + - ][ + - ]: 6 : if( (nFontIdx == EXC_FONT_NOTFOUND) && (aIt.GetPortionIndex() == 0) )
[ + - ]
899 : : // leading unformatted portion - use passed font settings
900 [ + - ]: 6 : rRoot.ConvertFont( aStringProp, nLeadFontIdx, &rLeadFontColor );
901 : : else
902 [ # # ]: 0 : rRoot.ConvertFont( aStringProp, nFontIdx );
903 : :
904 : : // add string to vector of strings
905 [ + - ][ + - ]: 6 : aStringVec.push_back( xFmtStr );
906 : : }
907 : 6 : }
908 : : }
909 [ + - ]: 6 : return ScfApiHelper::VectorToSequence( aStringVec );
910 : : }
911 : :
912 : 24 : void XclImpChSourceLink::FillSourceLink( ::std::vector< ScTokenRef >& rTokens ) const
913 : : {
914 [ + + ]: 24 : if( !mxTokenArray )
915 : : // no links to fill.
916 : 24 : return;
917 : :
918 : 18 : mxTokenArray->Reset();
919 [ + + ]: 36 : for (FormulaToken* p = mxTokenArray->First(); p; p = mxTokenArray->Next())
920 : : {
921 [ + - ]: 18 : ScTokenRef pToken(static_cast<ScToken*>(p->Clone()));
922 [ + - ][ + - ]: 18 : if (ScRefTokenHelper::isRef(pToken))
923 : : // This is a reference token. Store it.
924 [ + - ]: 18 : ScRefTokenHelper::join(rTokens, pToken);
925 [ + - ]: 18 : }
926 : : }
927 : :
928 : : // Text =======================================================================
929 : :
930 : 36 : XclImpChFontBase::~XclImpChFontBase()
931 : : {
932 [ - + ]: 36 : }
933 : :
934 : 18 : void XclImpChFontBase::ConvertFontBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const
935 : : {
936 [ + - ]: 18 : Color aFontColor = GetFontColor();
937 [ + - ][ + - ]: 18 : rRoot.ConvertFont( rPropSet, GetFontIndex(), &aFontColor );
938 : 18 : }
939 : :
940 : 18 : void XclImpChFontBase::ConvertRotationBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet, bool bSupportsStacked ) const
941 : : {
942 : 18 : rRoot.GetChartPropSetHelper().WriteRotationProperties( rPropSet, GetRotation(), bSupportsStacked );
943 : 18 : }
944 : :
945 : : // ----------------------------------------------------------------------------
946 : :
947 : 24 : XclImpChFont::XclImpChFont() :
948 : 24 : mnFontIdx( EXC_FONT_NOTFOUND )
949 : : {
950 : 24 : }
951 : :
952 : 24 : void XclImpChFont::ReadChFont( XclImpStream& rStrm )
953 : : {
954 : 24 : rStrm >> mnFontIdx;
955 : 24 : }
956 : :
957 : : // ----------------------------------------------------------------------------
958 : :
959 : 24 : XclImpChText::XclImpChText( const XclImpChRoot& rRoot ) :
960 [ + - ][ + - ]: 24 : XclImpChRoot( rRoot )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
961 : : {
962 : 24 : }
963 : :
964 : 24 : void XclImpChText::ReadHeaderRecord( XclImpStream& rStrm )
965 : : {
966 : 24 : rStrm >> maData.mnHAlign
967 : 24 : >> maData.mnVAlign
968 : 24 : >> maData.mnBackMode
969 : 24 : >> maData.maTextColor
970 : 24 : >> maData.maRect
971 : 24 : >> maData.mnFlags;
972 : :
973 [ + - ]: 24 : if( GetBiff() == EXC_BIFF8 )
974 : : {
975 : : // BIFF8: index into palette used instead of RGB data
976 : 24 : maData.maTextColor = GetPalette().GetColor( rStrm.ReaduInt16() );
977 : : // placement and rotation
978 : 24 : rStrm >> maData.mnFlags2 >> maData.mnRotation;
979 : : }
980 : : else
981 : : {
982 : : // BIFF2-BIFF7: get rotation from text orientation
983 : 0 : sal_uInt8 nOrient = ::extract_value< sal_uInt8 >( maData.mnFlags, 8, 3 );
984 : 0 : maData.mnRotation = XclTools::GetXclRotFromOrient( nOrient );
985 : : }
986 : 24 : }
987 : :
988 : 120 : void XclImpChText::ReadSubRecord( XclImpStream& rStrm )
989 : : {
990 [ + + - + : 120 : switch( rStrm.GetRecId() )
- + - +
+ ]
991 : : {
992 : : case EXC_ID_CHFRAMEPOS:
993 [ + - ]: 24 : mxFramePos.reset( new XclImpChFramePos );
994 : 24 : mxFramePos->ReadChFramePos( rStrm );
995 : 24 : break;
996 : : case EXC_ID_CHFONT:
997 : 18 : mxFont.reset( new XclImpChFont );
998 : 18 : mxFont->ReadChFont( rStrm );
999 : 18 : break;
1000 : : case EXC_ID_CHFORMATRUNS:
1001 [ # # ]: 0 : if( GetBiff() == EXC_BIFF8 )
1002 : 0 : XclImpString::ReadFormats( rStrm, maFormats );
1003 : 0 : break;
1004 : : case EXC_ID_CHSOURCELINK:
1005 [ + - ]: 24 : mxSrcLink.reset( new XclImpChSourceLink( GetChRoot() ) );
1006 : 24 : mxSrcLink->ReadChSourceLink( rStrm );
1007 : 24 : break;
1008 : : case EXC_ID_CHFRAME:
1009 [ # # ]: 0 : mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_TEXT ) );
1010 : 0 : mxFrame->ReadRecordGroup( rStrm );
1011 : 0 : break;
1012 : : case EXC_ID_CHOBJECTLINK:
1013 : 6 : rStrm >> maObjLink.mnTarget >> maObjLink.maPointPos.mnSeriesIdx >> maObjLink.maPointPos.mnPointIdx;
1014 : 6 : break;
1015 : : case EXC_ID_CHFRLABELPROPS:
1016 : 0 : ReadChFrLabelProps( rStrm );
1017 : 0 : break;
1018 : : case EXC_ID_CHEND:
1019 [ + - ][ - + ]: 24 : if( mxSrcLink && !maFormats.empty() )
[ - + ]
1020 : 0 : mxSrcLink->SetTextFormats( maFormats );
1021 : 24 : break;
1022 : : }
1023 : 120 : }
1024 : :
1025 : 18 : sal_uInt16 XclImpChText::GetFontIndex() const
1026 : : {
1027 [ + - ]: 18 : return mxFont ? mxFont->GetFontIndex() : EXC_FONT_NOTFOUND;
1028 : : }
1029 : :
1030 : 18 : Color XclImpChText::GetFontColor() const
1031 : : {
1032 [ + - ]: 18 : return ::get_flag( maData.mnFlags, EXC_CHTEXT_AUTOCOLOR ) ? GetFontAutoColor() : maData.maTextColor;
1033 : : }
1034 : :
1035 : 9 : sal_uInt16 XclImpChText::GetRotation() const
1036 : : {
1037 : 9 : return maData.mnRotation;
1038 : : }
1039 : :
1040 : 0 : void XclImpChText::SetString( const String& rString )
1041 : : {
1042 [ # # ]: 0 : if( !mxSrcLink )
1043 [ # # ]: 0 : mxSrcLink.reset( new XclImpChSourceLink( GetChRoot() ) );
1044 : 0 : mxSrcLink->SetString( rString );
1045 : 0 : }
1046 : :
1047 : 12 : void XclImpChText::UpdateText( const XclImpChText* pParentText )
1048 : : {
1049 [ + - ]: 12 : if( pParentText )
1050 : : {
1051 : : // update missing members
1052 [ + - ]: 12 : if( !mxFrame )
1053 : 12 : mxFrame = pParentText->mxFrame;
1054 [ + + ]: 12 : if( !mxFont )
1055 : : {
1056 : 6 : mxFont = pParentText->mxFont;
1057 : : // text color is taken from CHTEXT record, not from font in CHFONT
1058 : 6 : ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOCOLOR, ::get_flag( pParentText->maData.mnFlags, EXC_CHTEXT_AUTOCOLOR ) );
1059 : 6 : maData.maTextColor = pParentText->maData.maTextColor;
1060 : : }
1061 : : }
1062 : 12 : }
1063 : :
1064 : 0 : void XclImpChText::UpdateDataLabel( bool bCateg, bool bValue, bool bPercent )
1065 : : {
1066 : 0 : ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG, bCateg );
1067 : 0 : ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWVALUE, bValue );
1068 : 0 : ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWPERCENT, bPercent );
1069 [ # # ][ # # ]: 0 : ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEGPERC, bCateg && bPercent );
1070 [ # # ][ # # ]: 0 : ::set_flag( maData.mnFlags, EXC_CHTEXT_DELETED, !bCateg && !bValue && !bPercent );
[ # # ]
1071 : 0 : }
1072 : :
1073 : 12 : void XclImpChText::ConvertFont( ScfPropertySet& rPropSet ) const
1074 : : {
1075 : 12 : ConvertFontBase( GetChRoot(), rPropSet );
1076 : 12 : }
1077 : :
1078 : 6 : void XclImpChText::ConvertRotation( ScfPropertySet& rPropSet, bool bSupportsStacked ) const
1079 : : {
1080 : 6 : ConvertRotationBase( GetChRoot(), rPropSet, bSupportsStacked );
1081 : 6 : }
1082 : :
1083 : 6 : void XclImpChText::ConvertFrame( ScfPropertySet& rPropSet ) const
1084 : : {
1085 [ - + ]: 6 : if( mxFrame )
1086 : 0 : mxFrame->Convert( rPropSet );
1087 : 6 : }
1088 : :
1089 : 0 : void XclImpChText::ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const
1090 : : {
1091 [ # # ]: 0 : if( mxSrcLink )
1092 : 0 : mxSrcLink->ConvertNumFmt( rPropSet, bPercent );
1093 : 0 : }
1094 : :
1095 : 0 : void XclImpChText::ConvertDataLabel( ScfPropertySet& rPropSet, const XclChTypeInfo& rTypeInfo ) const
1096 : : {
1097 : : // existing CHFRLABELPROPS record wins over flags from CHTEXT
1098 [ # # ]: 0 : sal_uInt16 nShowFlags = mxLabelProps ? mxLabelProps->mnFlags : maData.mnFlags;
1099 [ # # ]: 0 : sal_uInt16 SHOWANYCATEG = mxLabelProps ? EXC_CHFRLABELPROPS_SHOWCATEG : (EXC_CHTEXT_SHOWCATEGPERC | EXC_CHTEXT_SHOWCATEG);
1100 [ # # ]: 0 : sal_uInt16 SHOWANYVALUE = mxLabelProps ? EXC_CHFRLABELPROPS_SHOWVALUE : EXC_CHTEXT_SHOWVALUE;
1101 [ # # ]: 0 : sal_uInt16 SHOWANYPERCENT = mxLabelProps ? EXC_CHFRLABELPROPS_SHOWPERCENT : (EXC_CHTEXT_SHOWPERCENT | EXC_CHTEXT_SHOWCATEGPERC);
1102 [ # # ]: 0 : sal_uInt16 SHOWANYBUBBLE = mxLabelProps ? EXC_CHFRLABELPROPS_SHOWBUBBLE : EXC_CHTEXT_SHOWBUBBLE;
1103 : :
1104 : : // get raw flags for label values
1105 [ # # ]: 0 : bool bShowNone = IsDeleted();
1106 [ # # ][ # # ]: 0 : bool bShowCateg = !bShowNone && ::get_flag( nShowFlags, SHOWANYCATEG );
1107 [ # # ][ # # ]: 0 : bool bShowPercent = !bShowNone && ::get_flag( nShowFlags, SHOWANYPERCENT );
1108 [ # # ][ # # ]: 0 : bool bShowValue = !bShowNone && ::get_flag( nShowFlags, SHOWANYVALUE );
1109 [ # # ][ # # ]: 0 : bool bShowBubble = !bShowNone && ::get_flag( nShowFlags, SHOWANYBUBBLE );
1110 : :
1111 : : // adjust to Chart2 behaviour
1112 [ # # ]: 0 : if( rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES )
1113 : 0 : bShowValue = bShowBubble; // Chart2 bubble charts show bubble size if 'ShowValue' is set
1114 : :
1115 : : // other flags
1116 [ # # ][ # # ]: 0 : bool bShowAny = bShowValue || bShowPercent || bShowCateg;
[ # # ]
1117 [ # # ][ # # ]: 0 : bool bShowSymbol = bShowAny && ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWSYMBOL );
1118 : :
1119 : : // create API struct for label values, set API label separator
1120 : 0 : cssc2::DataPointLabel aPointLabel( bShowValue, bShowPercent, bShowCateg, bShowSymbol );
1121 [ # # ][ # # ]: 0 : rPropSet.SetProperty( EXC_CHPROP_LABEL, aPointLabel );
1122 [ # # ][ # # ]: 0 : String aSep = mxLabelProps ? mxLabelProps->maSeparator : rtl::OUString('\n');
1123 [ # # ]: 0 : if( aSep.Len() == 0 )
1124 [ # # ][ # # ]: 0 : aSep = CREATE_STRING( "; " );
[ # # ]
1125 [ # # ][ # # ]: 0 : rPropSet.SetStringProperty( EXC_CHPROP_LABELSEPARATOR, aSep );
1126 : :
1127 : : // text properties of attached label
1128 [ # # ]: 0 : if( bShowAny )
1129 : : {
1130 [ # # ]: 0 : ConvertFont( rPropSet );
1131 [ # # ]: 0 : ConvertRotation( rPropSet, false );
1132 : : // label placement
1133 : : using namespace cssc::DataLabelPlacement;
1134 : 0 : sal_Int32 nPlacement = rTypeInfo.mnDefaultLabelPos;
1135 [ # # # # : 0 : switch( ::extract_value< sal_uInt16 >( maData.mnFlags2, 0, 4 ) )
# # # # #
# # ]
1136 : : {
1137 : 0 : case EXC_CHTEXT_POS_DEFAULT: nPlacement = rTypeInfo.mnDefaultLabelPos; break;
1138 : 0 : case EXC_CHTEXT_POS_OUTSIDE: nPlacement = OUTSIDE; break;
1139 : 0 : case EXC_CHTEXT_POS_INSIDE: nPlacement = INSIDE; break;
1140 : 0 : case EXC_CHTEXT_POS_CENTER: nPlacement = CENTER; break;
1141 : 0 : case EXC_CHTEXT_POS_AXIS: nPlacement = NEAR_ORIGIN; break;
1142 : 0 : case EXC_CHTEXT_POS_ABOVE: nPlacement = TOP; break;
1143 : 0 : case EXC_CHTEXT_POS_BELOW: nPlacement = BOTTOM; break;
1144 : 0 : case EXC_CHTEXT_POS_LEFT: nPlacement = LEFT; break;
1145 : 0 : case EXC_CHTEXT_POS_RIGHT: nPlacement = RIGHT; break;
1146 : 0 : case EXC_CHTEXT_POS_AUTO: nPlacement = AVOID_OVERLAP; break;
1147 : : }
1148 [ # # ][ # # ]: 0 : rPropSet.SetProperty( EXC_CHPROP_LABELPLACEMENT, nPlacement );
1149 : : // label number format (percentage format wins over value format)
1150 [ # # ][ # # ]: 0 : if( bShowPercent || bShowValue )
1151 [ # # ]: 0 : ConvertNumFmt( rPropSet, bShowPercent );
1152 [ # # ]: 0 : }
1153 : 0 : }
1154 : :
1155 : 6 : Reference< XTitle > XclImpChText::CreateTitle() const
1156 : : {
1157 : 6 : Reference< XTitle > xTitle;
1158 [ + - ][ + - ]: 6 : if( mxSrcLink && mxSrcLink->HasString() )
[ + - ][ + - ]
1159 : : {
1160 : : // create the formatted strings
1161 : : Sequence< Reference< XFormattedString > > aStringSeq(
1162 [ + - ][ + - ]: 6 : mxSrcLink->CreateStringSequence( GetChRoot(), GetFontIndex(), GetFontColor() ) );
[ + - ]
1163 [ + - ]: 6 : if( aStringSeq.hasElements() )
1164 : : {
1165 : : // create the title object
1166 [ + - ][ + - ]: 6 : xTitle.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_TITLE ), UNO_QUERY );
[ + - ]
1167 [ + - ]: 6 : if( xTitle.is() )
1168 : : {
1169 : : // set the formatted strings
1170 [ + - ][ + - ]: 6 : xTitle->setText( aStringSeq );
1171 : : // more title formatting properties
1172 [ + - ]: 6 : ScfPropertySet aTitleProp( xTitle );
1173 [ + - ]: 6 : ConvertFrame( aTitleProp );
1174 [ + - ][ + - ]: 6 : ConvertRotation( aTitleProp, true );
1175 : : }
1176 [ + - ]: 6 : }
1177 : : }
1178 : 6 : return xTitle;
1179 : : }
1180 : :
1181 : 6 : void XclImpChText::ConvertTitlePosition( const XclChTextKey& rTitleKey ) const
1182 : : {
1183 [ - + ]: 12 : if( !mxFramePos ) return;
1184 : :
1185 : 6 : const XclChFramePos& rPosData = mxFramePos->GetFramePosData();
1186 : : OSL_ENSURE( (rPosData.mnTLMode == EXC_CHFRAMEPOS_PARENT) && (rPosData.mnBRMode == EXC_CHFRAMEPOS_PARENT),
1187 : : "XclImpChText::ConvertTitlePosition - unexpected frame position mode" );
1188 : :
1189 : : /* Check if title is moved manually. To get the actual position of the
1190 : : title, we do some kind of hack and use the values from the CHTEXT
1191 : : record, effectively ignoring the contents of the CHFRAMEPOS record
1192 : : which contains the position relative to the default title position
1193 : : (according to the spec, the CHFRAMEPOS supersedes the CHTEXT record).
1194 : : Especially when it comes to axis titles, things would become very
1195 : : complicated here, because the relative title position is stored in a
1196 : : measurement unit that is dependent on the size of the inner plot area,
1197 : : the interpretation of the X and Y coordinate is dependent on the
1198 : : direction of the axis, and in 3D charts, and the title default
1199 : : positions are dependent on the 3D view settings (rotation, elevation,
1200 : : and perspective). Thus, it is easier to assume that the creator has
1201 : : written out the correct absolute position and size of the title in the
1202 : : CHTEXT record. This is assured by checking that the shape size stored
1203 : : in the CHTEXT record is non-zero. */
1204 [ + + ][ - + ]: 6 : if( (rPosData.mnTLMode == EXC_CHFRAMEPOS_PARENT) &&
[ + - ][ + - ]
[ + - ]
1205 : : ((rPosData.maRect.mnX != 0) || (rPosData.maRect.mnY != 0)) &&
1206 : : (maData.maRect.mnWidth > 0) && (maData.maRect.mnHeight > 0) ) try
1207 : : {
1208 [ + - ][ + - ]: 3 : Reference< XShape > xTitleShape( GetTitleShape( rTitleKey ), UNO_SET_THROW );
1209 : : // the call to XShape.getSize() may recalc the chart view
1210 [ + - ][ + - ]: 3 : ::com::sun::star::awt::Size aTitleSize = xTitleShape->getSize();
1211 : : // rotated titles need special handling...
1212 [ + - ][ + - ]: 3 : sal_Int32 nScRot = XclTools::GetScRotation( GetRotation(), 0 );
1213 : 3 : double fRad = nScRot * F_PI18000;
1214 : 3 : double fSin = fabs( sin( fRad ) );
1215 : 3 : double fCos = fabs( cos( fRad ) );
1216 : : ::com::sun::star::awt::Size aBoundSize(
1217 : : static_cast< sal_Int32 >( fCos * aTitleSize.Width + fSin * aTitleSize.Height + 0.5 ),
1218 : 3 : static_cast< sal_Int32 >( fSin * aTitleSize.Width + fCos * aTitleSize.Height + 0.5 ) );
1219 : : // calculate the title position from the values in the CHTEXT record
1220 : : ::com::sun::star::awt::Point aTitlePos(
1221 [ + - ]: 3 : CalcHmmFromChartX( maData.maRect.mnX ),
1222 [ + - ]: 6 : CalcHmmFromChartY( maData.maRect.mnY ) );
1223 : : // add part of height to X direction, if title is rotated down (clockwise)
1224 [ - + ]: 3 : if( nScRot > 18000 )
1225 : 0 : aTitlePos.X += static_cast< sal_Int32 >( fSin * aTitleSize.Height + 0.5 );
1226 : : // add part of width to Y direction, if title is rotated up (counterclockwise)
1227 [ - + ]: 3 : else if( nScRot > 0 )
1228 : 0 : aTitlePos.Y += static_cast< sal_Int32 >( fSin * aTitleSize.Width + 0.5 );
1229 : : // set the resulting position at the title shape
1230 [ + - ][ + - ]: 3 : xTitleShape->setPosition( aTitlePos );
[ # # ]
1231 : : }
1232 : 0 : catch( Exception& )
1233 : : {
1234 : : }
1235 : : }
1236 : :
1237 : 0 : void XclImpChText::ReadChFrLabelProps( XclImpStream& rStrm )
1238 : : {
1239 [ # # ]: 0 : if( GetBiff() == EXC_BIFF8 )
1240 : : {
1241 [ # # ][ # # ]: 0 : mxLabelProps.reset( new XclChFrLabelProps );
[ # # ]
1242 : : sal_uInt16 nSepLen;
1243 [ # # ]: 0 : rStrm.Ignore( 12 );
1244 [ # # ][ # # ]: 0 : rStrm >> mxLabelProps->mnFlags >> nSepLen;
1245 [ # # ]: 0 : if( nSepLen > 0 )
1246 [ # # ][ # # ]: 0 : mxLabelProps->maSeparator = rStrm.ReadUniString( nSepLen );
[ # # ]
1247 : : }
1248 : 0 : }
1249 : :
1250 : : namespace {
1251 : :
1252 : 6 : void lclUpdateText( XclImpChTextRef& rxText, const XclImpChText* xDefText )
1253 : : {
1254 [ + - ]: 6 : if( rxText )
1255 : 6 : rxText->UpdateText( xDefText );
1256 : : else
1257 : : {
1258 [ # # ][ # # ]: 0 : XclImpChTextRef xNew(new XclImpChText(*xDefText));
[ # # ]
1259 [ # # ][ # # ]: 0 : rxText = xNew;
1260 : : }
1261 : 6 : }
1262 : :
1263 : 24 : void lclFinalizeTitle( XclImpChTextRef& rxTitle, const XclImpChText* pDefText, const String& rAutoTitle )
1264 : : {
1265 : : /* Do not update a title, if it is not visible (if rxTitle is null).
1266 : : Existing reference indicates enabled title. */
1267 [ + + ]: 24 : if( rxTitle )
1268 : : {
1269 [ - + ]: 6 : if( !rxTitle->HasString() )
1270 : 0 : rxTitle->SetString( rAutoTitle );
1271 [ + - ]: 6 : if( rxTitle->HasString() )
1272 : 6 : rxTitle->UpdateText(pDefText);
1273 : : else
1274 : 0 : rxTitle.reset();
1275 : : }
1276 : 24 : }
1277 : :
1278 : : } // namespace
1279 : :
1280 : : // Data series ================================================================
1281 : :
1282 : 0 : void XclImpChMarkerFormat::ReadChMarkerFormat( XclImpStream& rStrm )
1283 : : {
1284 : 0 : rStrm >> maData.maLineColor >> maData.maFillColor >> maData.mnMarkerType >> maData.mnFlags;
1285 : :
1286 : 0 : const XclImpRoot& rRoot = rStrm.GetRoot();
1287 [ # # ]: 0 : if( rRoot.GetBiff() == EXC_BIFF8 )
1288 : : {
1289 : : // BIFF8: index into palette used instead of RGB data
1290 : 0 : const XclImpPalette& rPal = rRoot.GetPalette();
1291 : 0 : maData.maLineColor = rPal.GetColor( rStrm.ReaduInt16() );
1292 : 0 : maData.maFillColor = rPal.GetColor( rStrm.ReaduInt16() );
1293 : : // marker size
1294 : 0 : rStrm >> maData.mnMarkerSize;
1295 : : }
1296 : 0 : }
1297 : :
1298 : 3 : void XclImpChMarkerFormat::Convert( const XclImpChRoot& rRoot,
1299 : : ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx, sal_Int16 nLineWeight ) const
1300 : : {
1301 [ + - ]: 3 : if( IsAuto() )
1302 : : {
1303 [ + - ]: 3 : XclChMarkerFormat aMarkerFmt;
1304 : : // line and fill color of the symbol are equal to series line color
1305 : : //! TODO: Excel sets no fill color for specific symbols (e.g. cross)
1306 [ + - ]: 3 : aMarkerFmt.maLineColor = aMarkerFmt.maFillColor = rRoot.GetSeriesLineAutoColor( nFormatIdx );
1307 [ - + - - : 3 : switch( nLineWeight )
- ]
1308 : : {
1309 : 0 : case EXC_CHLINEFORMAT_HAIR: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_HAIRSIZE; break;
1310 : 3 : case EXC_CHLINEFORMAT_SINGLE: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_SINGLESIZE; break;
1311 : 0 : case EXC_CHLINEFORMAT_DOUBLE: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_DOUBLESIZE; break;
1312 : 0 : case EXC_CHLINEFORMAT_TRIPLE: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_TRIPLESIZE; break;
1313 : 0 : default: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_SINGLESIZE;
1314 : : }
1315 [ + - ]: 3 : aMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
1316 [ + - ][ + - ]: 3 : rRoot.GetChartPropSetHelper().WriteMarkerProperties( rPropSet, aMarkerFmt );
1317 : : }
1318 : : else
1319 : : {
1320 : 0 : rRoot.GetChartPropSetHelper().WriteMarkerProperties( rPropSet, maData );
1321 : : }
1322 : 3 : }
1323 : :
1324 : 0 : void XclImpChMarkerFormat::ConvertColor( const XclImpChRoot& rRoot,
1325 : : ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const
1326 : : {
1327 [ # # ][ # # ]: 0 : Color aLineColor = IsAuto() ? rRoot.GetSeriesLineAutoColor( nFormatIdx ) : maData.maFillColor;
[ # # ]
1328 [ # # ][ # # ]: 0 : rPropSet.SetColorProperty( EXC_CHPROP_COLOR, aLineColor );
1329 : 0 : }
1330 : :
1331 : : // ----------------------------------------------------------------------------
1332 : :
1333 : 0 : XclImpChPieFormat::XclImpChPieFormat() :
1334 : 0 : mnPieDist( 0 )
1335 : : {
1336 : 0 : }
1337 : :
1338 : 0 : void XclImpChPieFormat::ReadChPieFormat( XclImpStream& rStrm )
1339 : : {
1340 : 0 : rStrm >> mnPieDist;
1341 : 0 : }
1342 : :
1343 : 0 : void XclImpChPieFormat::Convert( ScfPropertySet& rPropSet ) const
1344 : : {
1345 [ # # ]: 0 : double fApiDist = ::std::min< double >( mnPieDist / 100.0, 1.0 );
1346 [ # # ][ # # ]: 0 : rPropSet.SetProperty( EXC_CHPROP_OFFSET, fApiDist );
1347 : 0 : }
1348 : :
1349 : : // ----------------------------------------------------------------------------
1350 : :
1351 : 0 : XclImpChSeriesFormat::XclImpChSeriesFormat() :
1352 : 0 : mnFlags( 0 )
1353 : : {
1354 : 0 : }
1355 : :
1356 : 0 : void XclImpChSeriesFormat::ReadChSeriesFormat( XclImpStream& rStrm )
1357 : : {
1358 : 0 : rStrm >> mnFlags;
1359 : 0 : }
1360 : :
1361 : : // ----------------------------------------------------------------------------
1362 : :
1363 : 6 : void XclImpCh3dDataFormat::ReadCh3dDataFormat( XclImpStream& rStrm )
1364 : : {
1365 : 6 : rStrm >> maData.mnBase >> maData.mnTop;
1366 : 6 : }
1367 : :
1368 : 0 : void XclImpCh3dDataFormat::Convert( ScfPropertySet& rPropSet ) const
1369 : : {
1370 : : using namespace ::com::sun::star::chart2::DataPointGeometry3D;
1371 : : sal_Int32 nApiType = (maData.mnBase == EXC_CH3DDATAFORMAT_RECT) ?
1372 : : ((maData.mnTop == EXC_CH3DDATAFORMAT_STRAIGHT) ? CUBOID : PYRAMID) :
1373 [ # # ][ # # ]: 0 : ((maData.mnTop == EXC_CH3DDATAFORMAT_STRAIGHT) ? CYLINDER : CONE);
[ # # ]
1374 [ # # ][ # # ]: 0 : rPropSet.SetProperty( EXC_CHPROP_GEOMETRY3D, nApiType );
1375 : 0 : }
1376 : :
1377 : : // ----------------------------------------------------------------------------
1378 : :
1379 : 0 : XclImpChAttachedLabel::XclImpChAttachedLabel( const XclImpChRoot& rRoot ) :
1380 : : XclImpChRoot( rRoot ),
1381 : 0 : mnFlags( 0 )
1382 : : {
1383 : 0 : }
1384 : :
1385 : 0 : void XclImpChAttachedLabel::ReadChAttachedLabel( XclImpStream& rStrm )
1386 : : {
1387 : 0 : rStrm >> mnFlags;
1388 : 0 : }
1389 : :
1390 : 0 : XclImpChTextRef XclImpChAttachedLabel::CreateDataLabel( const XclImpChText* pParent ) const
1391 : : {
1392 : 0 : const sal_uInt16 EXC_CHATTLABEL_SHOWANYVALUE = EXC_CHATTLABEL_SHOWVALUE;
1393 : 0 : const sal_uInt16 EXC_CHATTLABEL_SHOWANYPERCENT = EXC_CHATTLABEL_SHOWPERCENT | EXC_CHATTLABEL_SHOWCATEGPERC;
1394 : 0 : const sal_uInt16 EXC_CHATTLABEL_SHOWANYCATEG = EXC_CHATTLABEL_SHOWCATEG | EXC_CHATTLABEL_SHOWCATEGPERC;
1395 : :
1396 [ # # ][ # # ]: 0 : XclImpChTextRef xLabel( pParent ? new XclImpChText( *pParent ) : new XclImpChText( GetChRoot() ) );
[ # # ][ # # ]
[ # # ][ # # ]
1397 : : xLabel->UpdateDataLabel(
1398 : 0 : ::get_flag( mnFlags, EXC_CHATTLABEL_SHOWANYCATEG ),
1399 : 0 : ::get_flag( mnFlags, EXC_CHATTLABEL_SHOWANYVALUE ),
1400 [ # # ]: 0 : ::get_flag( mnFlags, EXC_CHATTLABEL_SHOWANYPERCENT ) );
1401 : 0 : return xLabel;
1402 : : }
1403 : :
1404 : : // ----------------------------------------------------------------------------
1405 : :
1406 : 6 : XclImpChDataFormat::XclImpChDataFormat( const XclImpChRoot& rRoot ) :
1407 [ + - ][ + - ]: 6 : XclImpChRoot( rRoot )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
1408 : : {
1409 : 6 : }
1410 : :
1411 : 6 : void XclImpChDataFormat::ReadHeaderRecord( XclImpStream& rStrm )
1412 : : {
1413 : 6 : rStrm >> maData.maPointPos.mnPointIdx
1414 : 6 : >> maData.maPointPos.mnSeriesIdx
1415 : 6 : >> maData.mnFormatIdx
1416 : 6 : >> maData.mnFlags;
1417 : 6 : }
1418 : :
1419 : 18 : void XclImpChDataFormat::ReadSubRecord( XclImpStream& rStrm )
1420 : : {
1421 [ - - - + : 18 : switch( rStrm.GetRecId() )
- + ]
1422 : : {
1423 : : case EXC_ID_CHMARKERFORMAT:
1424 [ # # ]: 0 : mxMarkerFmt.reset( new XclImpChMarkerFormat );
1425 : 0 : mxMarkerFmt->ReadChMarkerFormat( rStrm );
1426 : 0 : break;
1427 : : case EXC_ID_CHPIEFORMAT:
1428 : 0 : mxPieFmt.reset( new XclImpChPieFormat );
1429 : 0 : mxPieFmt->ReadChPieFormat( rStrm );
1430 : 0 : break;
1431 : : case EXC_ID_CHSERIESFORMAT:
1432 : 0 : mxSeriesFmt.reset( new XclImpChSeriesFormat );
1433 : 0 : mxSeriesFmt->ReadChSeriesFormat( rStrm );
1434 : 0 : break;
1435 : : case EXC_ID_CH3DDATAFORMAT:
1436 [ + - ]: 6 : mx3dDataFmt.reset( new XclImpCh3dDataFormat );
1437 : 6 : mx3dDataFmt->ReadCh3dDataFormat( rStrm );
1438 : 6 : break;
1439 : : case EXC_ID_CHATTACHEDLABEL:
1440 [ # # ]: 0 : mxAttLabel.reset( new XclImpChAttachedLabel( GetChRoot() ) );
1441 : 0 : mxAttLabel->ReadChAttachedLabel( rStrm );
1442 : 0 : break;
1443 : : default:
1444 : 12 : XclImpChFrameBase::ReadSubRecord( rStrm );
1445 : : }
1446 : 18 : }
1447 : :
1448 : 0 : void XclImpChDataFormat::SetPointPos( const XclChDataPointPos& rPointPos, sal_uInt16 nFormatIdx )
1449 : : {
1450 : 0 : maData.maPointPos = rPointPos;
1451 : 0 : maData.mnFormatIdx = nFormatIdx;
1452 : 0 : }
1453 : :
1454 : 0 : void XclImpChDataFormat::UpdateGroupFormat( const XclChExtTypeInfo& rTypeInfo )
1455 : : {
1456 : : // remove formats not used for the current chart type
1457 : 0 : RemoveUnusedFormats( rTypeInfo );
1458 : 0 : }
1459 : :
1460 : 6 : void XclImpChDataFormat::UpdateSeriesFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pGroupFmt )
1461 : : {
1462 : : // update missing formats from passed chart type group format
1463 [ - + ]: 6 : if( pGroupFmt )
1464 : : {
1465 [ # # ]: 0 : if( !mxLineFmt )
1466 : 0 : mxLineFmt = pGroupFmt->mxLineFmt;
1467 [ # # ][ # # ]: 0 : if( !mxAreaFmt && !mxEscherFmt )
[ # # ]
1468 : : {
1469 : 0 : mxAreaFmt = pGroupFmt->mxAreaFmt;
1470 : 0 : mxEscherFmt = pGroupFmt->mxEscherFmt;
1471 : : }
1472 [ # # ]: 0 : if( !mxMarkerFmt )
1473 : 0 : mxMarkerFmt = pGroupFmt->mxMarkerFmt;
1474 [ # # ]: 0 : if( !mxPieFmt )
1475 : 0 : mxPieFmt = pGroupFmt->mxPieFmt;
1476 [ # # ]: 0 : if( !mxSeriesFmt )
1477 : 0 : mxSeriesFmt = pGroupFmt->mxSeriesFmt;
1478 [ # # ]: 0 : if( !mx3dDataFmt )
1479 : 0 : mx3dDataFmt = pGroupFmt->mx3dDataFmt;
1480 [ # # ]: 0 : if( !mxAttLabel )
1481 : 0 : mxAttLabel = pGroupFmt->mxAttLabel;
1482 : : }
1483 : :
1484 : : /* Create missing but required formats. Existing line, area, and marker
1485 : : format objects are needed to create automatic series formatting. */
1486 [ + - ]: 6 : if( !mxLineFmt )
1487 [ + - ]: 6 : mxLineFmt.reset( new XclImpChLineFormat );
1488 [ + - ][ + - ]: 6 : if( !mxAreaFmt && !mxEscherFmt )
[ + - ]
1489 [ + - ]: 6 : mxAreaFmt.reset( new XclImpChAreaFormat );
1490 [ + - ]: 6 : if( !mxMarkerFmt )
1491 [ + - ]: 6 : mxMarkerFmt.reset( new XclImpChMarkerFormat );
1492 : :
1493 : : // remove formats not used for the current chart type
1494 : 6 : RemoveUnusedFormats( rTypeInfo );
1495 : : // update data label
1496 : 6 : UpdateDataLabel( pGroupFmt );
1497 : 6 : }
1498 : :
1499 : 0 : void XclImpChDataFormat::UpdatePointFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pSeriesFmt )
1500 : : {
1501 : : // remove formats if they are automatic in this and in the passed series format
1502 [ # # ]: 0 : if( pSeriesFmt )
1503 : : {
1504 [ # # ][ # # ]: 0 : if( IsAutoLine() && pSeriesFmt->IsAutoLine() )
[ # # ]
1505 : 0 : mxLineFmt.reset();
1506 [ # # ][ # # ]: 0 : if( IsAutoArea() && pSeriesFmt->IsAutoArea() )
[ # # ]
1507 : 0 : mxAreaFmt.reset();
1508 [ # # ][ # # ]: 0 : if( IsAutoMarker() && pSeriesFmt->IsAutoMarker() )
[ # # ]
1509 : 0 : mxMarkerFmt.reset();
1510 : 0 : mxSeriesFmt.reset();
1511 : : }
1512 : :
1513 : : // Excel ignores 3D bar format for single data points
1514 : 0 : mx3dDataFmt.reset();
1515 : : // remove point line formats for linear chart types, TODO: implement in OOChart
1516 [ # # ]: 0 : if( !rTypeInfo.IsSeriesFrameFormat() )
1517 : 0 : mxLineFmt.reset();
1518 : :
1519 : : // remove formats not used for the current chart type
1520 : 0 : RemoveUnusedFormats( rTypeInfo );
1521 : : // update data label
1522 : 0 : UpdateDataLabel( pSeriesFmt );
1523 : 0 : }
1524 : :
1525 : 0 : void XclImpChDataFormat::UpdateTrendLineFormat()
1526 : : {
1527 [ # # ]: 0 : if( !mxLineFmt )
1528 [ # # ]: 0 : mxLineFmt.reset( new XclImpChLineFormat );
1529 : 0 : mxAreaFmt.reset();
1530 : 0 : mxEscherFmt.reset();
1531 : 0 : mxMarkerFmt.reset();
1532 : 0 : mxPieFmt.reset();
1533 : 0 : mxSeriesFmt.reset();
1534 : 0 : mx3dDataFmt.reset();
1535 : 0 : mxAttLabel.reset();
1536 : : // update data label
1537 : 0 : UpdateDataLabel( 0 );
1538 : 0 : }
1539 : :
1540 : 6 : void XclImpChDataFormat::Convert( ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo ) const
1541 : : {
1542 : : /* Line and area format.
1543 : : #i71810# If the data points are filled with bitmaps, textures, or
1544 : : patterns, then only bar charts will use the CHPICFORMAT record to
1545 : : determine stacking/streching mode. All other chart types ignore this
1546 : : record and always use the property 'fill-type' from the DFF property
1547 : : set (streched for bitmaps, and stacked for textures and patterns). */
1548 : 6 : bool bUsePicFmt = rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_BAR;
1549 : 6 : ConvertFrameBase( GetChRoot(), rPropSet, rTypeInfo.GetSeriesObjectType(), maData.mnFormatIdx, bUsePicFmt );
1550 : :
1551 : : #if EXC_CHART2_3DBAR_HAIRLINES_ONLY
1552 : : // #i83151# only hair lines in 3D charts with filled data points
1553 [ # # ][ # # ]: 6 : if( rTypeInfo.mb3dChart && rTypeInfo.IsSeriesFrameFormat() && mxLineFmt && mxLineFmt->HasLine() )
[ # # ][ - + ]
[ - + ]
1554 [ # # ][ # # ]: 0 : rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "BorderWidth" ), 0 );
1555 : : #endif
1556 : :
1557 : : // other formatting
1558 [ + + ]: 6 : if( mxMarkerFmt )
1559 : 3 : mxMarkerFmt->Convert( GetChRoot(), rPropSet, maData.mnFormatIdx, GetLineWeight() );
1560 [ - + ]: 6 : if( mxPieFmt )
1561 : 0 : mxPieFmt->Convert( rPropSet );
1562 [ - + ]: 6 : if( mx3dDataFmt )
1563 : 0 : mx3dDataFmt->Convert( rPropSet );
1564 [ - + ]: 6 : if( mxLabel )
1565 : 0 : mxLabel->ConvertDataLabel( rPropSet, rTypeInfo );
1566 : :
1567 : : // 3D settings
1568 [ + - ][ + - ]: 6 : rPropSet.SetProperty< sal_Int16 >( EXC_CHPROP_PERCENTDIAGONAL, 0 );
1569 : :
1570 : : /* Special case: set marker color as line color, if series line is not
1571 : : visible. This makes the color visible in the marker area.
1572 : : TODO: remove this if OOChart supports own colors in markers. */
1573 [ - + ][ # # ]: 6 : if( !rTypeInfo.IsSeriesFrameFormat() && !HasLine() && mxMarkerFmt )
[ - + ][ + + ]
1574 : 0 : mxMarkerFmt->ConvertColor( GetChRoot(), rPropSet, maData.mnFormatIdx );
1575 : 6 : }
1576 : :
1577 : 0 : void XclImpChDataFormat::ConvertLine( ScfPropertySet& rPropSet, XclChObjectType eObjType ) const
1578 : : {
1579 : 0 : ConvertLineBase( GetChRoot(), rPropSet, eObjType );
1580 : 0 : }
1581 : :
1582 : 0 : void XclImpChDataFormat::ConvertArea( ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx, bool bUsePicFmt ) const
1583 : : {
1584 : 0 : ConvertAreaBase( GetChRoot(), rPropSet, EXC_CHOBJTYPE_FILLEDSERIES, nFormatIdx, bUsePicFmt );
1585 : 0 : }
1586 : :
1587 : 6 : void XclImpChDataFormat::RemoveUnusedFormats( const XclChExtTypeInfo& rTypeInfo )
1588 : : {
1589 : : // data point marker only in linear 2D charts
1590 [ + + ]: 6 : if( rTypeInfo.IsSeriesFrameFormat() )
1591 : 3 : mxMarkerFmt.reset();
1592 : : // pie format only in pie/donut charts
1593 [ + - ]: 6 : if( rTypeInfo.meTypeCateg != EXC_CHTYPECATEG_PIE )
1594 : 6 : mxPieFmt.reset();
1595 : : // 3D format only in 3D bar charts
1596 [ - + ][ # # ]: 6 : if( !rTypeInfo.mb3dChart || (rTypeInfo.meTypeCateg != EXC_CHTYPECATEG_BAR) )
1597 : 6 : mx3dDataFmt.reset();
1598 : 6 : }
1599 : :
1600 : 6 : void XclImpChDataFormat::UpdateDataLabel( const XclImpChDataFormat* pParentFmt )
1601 : : {
1602 : : /* CHTEXT groups linked to data labels override existing CHATTACHEDLABEL
1603 : : records. Only if there is a CHATTACHEDLABEL record without a CHTEXT
1604 : : group, the contents of the CHATTACHEDLABEL record are used. In this
1605 : : case a new CHTEXT group is created and filled with the settings from
1606 : : the CHATTACHEDLABEL record. */
1607 : 6 : const XclImpChText* pDefText = NULL;
1608 [ - + ]: 6 : if (pParentFmt)
1609 : 0 : pDefText = pParentFmt->GetDataLabel();
1610 [ + - ]: 6 : if (!pDefText)
1611 : 6 : pDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_DATALABEL );
1612 [ - + ]: 6 : if (mxLabel)
1613 : 0 : mxLabel->UpdateText(pDefText);
1614 [ - + ]: 6 : else if (mxAttLabel)
1615 [ # # ]: 0 : mxLabel = mxAttLabel->CreateDataLabel( pDefText );
1616 : 6 : }
1617 : :
1618 : : // ----------------------------------------------------------------------------
1619 : :
1620 : 0 : XclImpChSerTrendLine::XclImpChSerTrendLine( const XclImpChRoot& rRoot ) :
1621 [ # # ][ # # ]: 0 : XclImpChRoot( rRoot )
1622 : : {
1623 : 0 : }
1624 : :
1625 : 0 : void XclImpChSerTrendLine::ReadChSerTrendLine( XclImpStream& rStrm )
1626 : : {
1627 : 0 : rStrm >> maData.mnLineType
1628 : 0 : >> maData.mnOrder
1629 : 0 : >> maData.mfIntercept
1630 : 0 : >> maData.mnShowEquation
1631 : 0 : >> maData.mnShowRSquared
1632 : 0 : >> maData.mfForecastFor
1633 : 0 : >> maData.mfForecastBack;
1634 : 0 : }
1635 : :
1636 : 0 : Reference< XRegressionCurve > XclImpChSerTrendLine::CreateRegressionCurve() const
1637 : : {
1638 : : // trend line type
1639 : 0 : OUString aService;
1640 [ # # # # : 0 : switch( maData.mnLineType )
# ]
1641 : : {
1642 : : case EXC_CHSERTREND_POLYNOMIAL:
1643 : : // TODO: only linear trend lines are supported by OOChart (#i20819#)
1644 [ # # ]: 0 : if( maData.mnOrder == 1 )
1645 [ # # ]: 0 : aService = SERVICE_CHART2_LINEARREGCURVE;
1646 : 0 : break;
1647 : : case EXC_CHSERTREND_EXPONENTIAL:
1648 [ # # ]: 0 : aService = SERVICE_CHART2_EXPREGCURVE;
1649 : 0 : break;
1650 : : case EXC_CHSERTREND_LOGARITHMIC:
1651 [ # # ]: 0 : aService = SERVICE_CHART2_LOGREGCURVE;
1652 : 0 : break;
1653 : : case EXC_CHSERTREND_POWER:
1654 [ # # ]: 0 : aService = SERVICE_CHART2_POTREGCURVE;
1655 : 0 : break;
1656 : : }
1657 : 0 : Reference< XRegressionCurve > xRegCurve;
1658 [ # # ]: 0 : if( !aService.isEmpty() )
1659 [ # # ][ # # ]: 0 : xRegCurve.set( ScfApiHelper::CreateInstance( aService ), UNO_QUERY );
1660 : :
1661 : : // trend line formatting
1662 [ # # ][ # # ]: 0 : if( xRegCurve.is() && mxDataFmt )
[ # # ]
1663 : : {
1664 [ # # ]: 0 : ScfPropertySet aPropSet( xRegCurve );
1665 [ # # ]: 0 : mxDataFmt->ConvertLine( aPropSet, EXC_CHOBJTYPE_TRENDLINE );
1666 : :
1667 : : // #i83100# show equation and correlation coefficient
1668 [ # # ][ # # ]: 0 : ScfPropertySet aLabelProp( xRegCurve->getEquationProperties() );
[ # # ]
1669 [ # # ][ # # ]: 0 : aLabelProp.SetBoolProperty( EXC_CHPROP_SHOWEQUATION, maData.mnShowEquation != 0 );
1670 [ # # ][ # # ]: 0 : aLabelProp.SetBoolProperty( EXC_CHPROP_SHOWCORRELATION, maData.mnShowRSquared != 0 );
1671 : :
1672 : : // #i83100# formatting of the equation text box
1673 [ # # ][ # # ]: 0 : if (const XclImpChText* pLabel = mxDataFmt->GetDataLabel())
1674 : : {
1675 [ # # ]: 0 : pLabel->ConvertFont( aLabelProp );
1676 [ # # ]: 0 : pLabel->ConvertFrame( aLabelProp );
1677 [ # # ]: 0 : pLabel->ConvertNumFmt( aLabelProp, false );
1678 [ # # ][ # # ]: 0 : }
1679 : : }
1680 : :
1681 : : // missing features
1682 : : // #i20819# polynomial trend lines
1683 : : // #i66819# moving average trend lines
1684 : : // #i5085# manual trend line size
1685 : : // #i34093# manual crossing point
1686 : :
1687 : 0 : return xRegCurve;
1688 : : }
1689 : :
1690 : : // ----------------------------------------------------------------------------
1691 : :
1692 : 0 : XclImpChSerErrorBar::XclImpChSerErrorBar( const XclImpChRoot& rRoot ) :
1693 [ # # ][ # # ]: 0 : XclImpChRoot( rRoot )
[ # # ]
1694 : : {
1695 : 0 : }
1696 : :
1697 : 0 : void XclImpChSerErrorBar::ReadChSerErrorBar( XclImpStream& rStrm )
1698 : : {
1699 : 0 : rStrm >> maData.mnBarType >> maData.mnSourceType >> maData.mnLineEnd;
1700 : 0 : rStrm.Ignore( 1 );
1701 : 0 : rStrm >> maData.mfValue >> maData.mnValueCount;
1702 : 0 : }
1703 : :
1704 : 0 : void XclImpChSerErrorBar::SetSeriesData( XclImpChSourceLinkRef xValueLink, XclImpChDataFormatRef xDataFmt )
1705 : : {
1706 : 0 : mxValueLink = xValueLink;
1707 : 0 : mxDataFmt = xDataFmt;
1708 : 0 : }
1709 : :
1710 : 0 : Reference< XLabeledDataSequence > XclImpChSerErrorBar::CreateValueSequence() const
1711 : : {
1712 [ # # ]: 0 : return lclCreateLabeledDataSequence( mxValueLink, XclChartHelper::GetErrorBarValuesRole( maData.mnBarType ) );
1713 : : }
1714 : :
1715 : 0 : Reference< XPropertySet > XclImpChSerErrorBar::CreateErrorBar( const XclImpChSerErrorBar* pPosBar, const XclImpChSerErrorBar* pNegBar )
1716 : : {
1717 : 0 : Reference< XPropertySet > xErrorBar;
1718 : :
1719 [ # # ][ # # ]: 0 : if( const XclImpChSerErrorBar* pPrimaryBar = pPosBar ? pPosBar : pNegBar )
1720 : : {
1721 [ # # ][ # # ]: 0 : xErrorBar.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_ERRORBAR ), UNO_QUERY );
[ # # ]
1722 [ # # ]: 0 : ScfPropertySet aBarProp( xErrorBar );
1723 : :
1724 : : // plus/minus bars visible?
1725 [ # # ][ # # ]: 0 : aBarProp.SetBoolProperty( EXC_CHPROP_SHOWPOSITIVEERROR, pPosBar != 0 );
1726 [ # # ][ # # ]: 0 : aBarProp.SetBoolProperty( EXC_CHPROP_SHOWNEGATIVEERROR, pNegBar != 0 );
1727 : :
1728 : : // type of displayed error
1729 [ # # # # : 0 : switch( pPrimaryBar->maData.mnSourceType )
# # ]
1730 : : {
1731 : : case EXC_CHSERERR_PERCENT:
1732 [ # # ][ # # ]: 0 : aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::RELATIVE );
1733 [ # # ][ # # ]: 0 : aBarProp.SetProperty( EXC_CHPROP_POSITIVEERROR, pPrimaryBar->maData.mfValue );
1734 [ # # ][ # # ]: 0 : aBarProp.SetProperty( EXC_CHPROP_NEGATIVEERROR, pPrimaryBar->maData.mfValue );
1735 : 0 : break;
1736 : : case EXC_CHSERERR_FIXED:
1737 [ # # ][ # # ]: 0 : aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::ABSOLUTE );
1738 [ # # ][ # # ]: 0 : aBarProp.SetProperty( EXC_CHPROP_POSITIVEERROR, pPrimaryBar->maData.mfValue );
1739 [ # # ][ # # ]: 0 : aBarProp.SetProperty( EXC_CHPROP_NEGATIVEERROR, pPrimaryBar->maData.mfValue );
1740 : 0 : break;
1741 : : case EXC_CHSERERR_STDDEV:
1742 [ # # ][ # # ]: 0 : aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::STANDARD_DEVIATION );
1743 [ # # ][ # # ]: 0 : aBarProp.SetProperty( EXC_CHPROP_WEIGHT, pPrimaryBar->maData.mfValue );
1744 : 0 : break;
1745 : : case EXC_CHSERERR_STDERR:
1746 [ # # ][ # # ]: 0 : aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::STANDARD_ERROR );
1747 : 0 : break;
1748 : : case EXC_CHSERERR_CUSTOM:
1749 : : {
1750 [ # # ][ # # ]: 0 : aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::FROM_DATA );
1751 : : // attach data sequences to erorr bar
1752 [ # # ]: 0 : Reference< XDataSink > xDataSink( xErrorBar, UNO_QUERY );
1753 [ # # ]: 0 : if( xDataSink.is() )
1754 : : {
1755 : : // create vector of all value sequences
1756 [ # # ]: 0 : ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
1757 : : // add positive values
1758 [ # # ]: 0 : if( pPosBar )
1759 : : {
1760 [ # # ]: 0 : Reference< XLabeledDataSequence > xValueSeq = pPosBar->CreateValueSequence();
1761 [ # # ]: 0 : if( xValueSeq.is() )
1762 [ # # ]: 0 : aLabeledSeqVec.push_back( xValueSeq );
1763 : : }
1764 : : // add negative values
1765 [ # # ]: 0 : if( pNegBar )
1766 : : {
1767 [ # # ]: 0 : Reference< XLabeledDataSequence > xValueSeq = pNegBar->CreateValueSequence();
1768 [ # # ]: 0 : if( xValueSeq.is() )
1769 [ # # ]: 0 : aLabeledSeqVec.push_back( xValueSeq );
1770 : : }
1771 : : // attach labeled data sequences to series
1772 [ # # ]: 0 : if( aLabeledSeqVec.empty() )
1773 : 0 : xErrorBar.clear();
1774 : : else
1775 [ # # ][ # # ]: 0 : xDataSink->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec ) );
[ # # ][ # # ]
1776 : 0 : }
1777 : : }
1778 : 0 : break;
1779 : : default:
1780 : 0 : xErrorBar.clear();
1781 : : }
1782 : :
1783 : : // error bar formatting
1784 [ # # ][ # # ]: 0 : if( pPrimaryBar->mxDataFmt && xErrorBar.is() )
[ # # ]
1785 [ # # ][ # # ]: 0 : pPrimaryBar->mxDataFmt->ConvertLine( aBarProp, EXC_CHOBJTYPE_ERRORBAR );
1786 : : }
1787 : :
1788 : 0 : return xErrorBar;
1789 : : }
1790 : :
1791 : : // ----------------------------------------------------------------------------
1792 : :
1793 : 6 : XclImpChSeries::XclImpChSeries( const XclImpChRoot& rRoot, sal_uInt16 nSeriesIdx ) :
1794 : : XclImpChRoot( rRoot ),
1795 : : mnGroupIdx( EXC_CHSERGROUP_NONE ),
1796 : : mnSeriesIdx( nSeriesIdx ),
1797 [ + - ][ + - ]: 6 : mnParentIdx( EXC_CHSERIES_INVALID )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
1798 : : {
1799 : 6 : }
1800 : :
1801 : 6 : void XclImpChSeries::ReadHeaderRecord( XclImpStream& rStrm )
1802 : : {
1803 : 6 : rStrm >> maData.mnCategType >> maData.mnValueType >> maData.mnCategCount >> maData.mnValueCount;
1804 [ + - ]: 6 : if( GetBiff() == EXC_BIFF8 )
1805 : 6 : rStrm >> maData.mnBubbleType >> maData.mnBubbleCount;
1806 : 6 : }
1807 : :
1808 : 48 : void XclImpChSeries::ReadSubRecord( XclImpStream& rStrm )
1809 : : {
1810 [ + + + - : 48 : switch( rStrm.GetRecId() )
- - + ]
1811 : : {
1812 : : case EXC_ID_CHSOURCELINK:
1813 : 24 : ReadChSourceLink( rStrm );
1814 : 24 : break;
1815 : : case EXC_ID_CHDATAFORMAT:
1816 : 6 : ReadChDataFormat( rStrm );
1817 : 6 : break;
1818 : : case EXC_ID_CHSERGROUP:
1819 : 6 : rStrm >> mnGroupIdx;
1820 : 6 : break;
1821 : : case EXC_ID_CHSERPARENT:
1822 : 0 : ReadChSerParent( rStrm );
1823 : 0 : break;
1824 : : case EXC_ID_CHSERTRENDLINE:
1825 : 0 : ReadChSerTrendLine( rStrm );
1826 : 0 : break;
1827 : : case EXC_ID_CHSERERRORBAR:
1828 : 0 : ReadChSerErrorBar( rStrm );
1829 : 0 : break;
1830 : : }
1831 : 48 : }
1832 : :
1833 : 6 : void XclImpChSeries::SetDataFormat( const XclImpChDataFormatRef& xDataFmt )
1834 : : {
1835 [ + - ]: 6 : if (!xDataFmt)
1836 : : return;
1837 : :
1838 : 6 : sal_uInt16 nPointIdx = xDataFmt->GetPointPos().mnPointIdx;
1839 [ + - ]: 6 : if (nPointIdx == EXC_CHDATAFORMAT_ALLPOINTS)
1840 : : {
1841 [ + - ]: 6 : if (mxSeriesFmt)
1842 : : // Don't overwrite the existing format.
1843 : : return;
1844 : :
1845 [ + - ]: 6 : mxSeriesFmt = xDataFmt;
1846 [ + - ]: 6 : if (HasParentSeries())
1847 : : return;
1848 : :
1849 [ + - ][ + - ]: 6 : XclImpChTypeGroupRef pTypeGroup = GetChartData().GetTypeGroup(mnGroupIdx);
1850 [ + - ]: 6 : if (pTypeGroup)
1851 [ + - ]: 6 : pTypeGroup->SetUsedFormatIndex(xDataFmt->GetFormatIdx());
1852 : :
1853 [ + - ]: 6 : return;
1854 : : }
1855 : :
1856 [ # # ]: 0 : if (nPointIdx >= EXC_CHDATAFORMAT_MAXPOINTCOUNT)
1857 : : // Above the max point count. Bail out.
1858 : : return;
1859 : :
1860 [ # # ]: 0 : XclImpChDataFormatMap::iterator itr = maPointFmts.lower_bound(nPointIdx);
1861 [ # # ][ # # ]: 0 : if (itr == maPointFmts.end() || maPointFmts.key_comp()(nPointIdx, itr->first))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # ]
1862 : : {
1863 : : // No object exists at this point index position. Insert it.
1864 [ # # ][ # # ]: 6 : itr = maPointFmts.insert(itr, XclImpChDataFormatMap::value_type(nPointIdx, xDataFmt));
[ # # ]
1865 : : }
1866 : : }
1867 : :
1868 : 0 : void XclImpChSeries::SetDataLabel( const XclImpChTextRef& xLabel )
1869 : : {
1870 [ # # ]: 0 : if (!xLabel)
1871 : : return;
1872 : :
1873 : 0 : sal_uInt16 nPointIdx = xLabel->GetPointPos().mnPointIdx;
1874 [ # # ][ # # ]: 0 : if ((nPointIdx != EXC_CHDATAFORMAT_ALLPOINTS) && (nPointIdx >= EXC_CHDATAFORMAT_MAXPOINTCOUNT))
1875 : : // Above the maximum allowed data points. Bail out.
1876 : : return;
1877 : :
1878 [ # # ]: 0 : XclImpChTextMap::iterator itr = maLabels.lower_bound(nPointIdx);
1879 [ # # ][ # # ]: 0 : if (itr == maLabels.end() || maLabels.key_comp()(nPointIdx, itr->first))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # ]
1880 : : {
1881 : : // No object exists at this point index position. Insert it.
1882 [ # # ][ # # ]: 0 : itr = maLabels.insert(itr, XclImpChTextMap::value_type(nPointIdx, xLabel));
[ # # ]
1883 : : }
1884 : : }
1885 : :
1886 : 0 : void XclImpChSeries::AddChildSeries( const XclImpChSeries& rSeries )
1887 : : {
1888 : : OSL_ENSURE( !HasParentSeries(), "XclImpChSeries::AddChildSeries - not allowed for child series" );
1889 : :
1890 : : /* In Excel, trend lines and error bars are stored as own series. In Calc,
1891 : : these are properties of the parent series. This function adds the
1892 : : settings of the passed series to this series. */
1893 : 0 : maTrendLines.insert( maTrendLines.end(), rSeries.maTrendLines.begin(), rSeries.maTrendLines.end() );
1894 : 0 : maErrorBars.insert( rSeries.maErrorBars.begin(), rSeries.maErrorBars.end() );
1895 : 0 : }
1896 : :
1897 : 6 : void XclImpChSeries::FinalizeDataFormats()
1898 : : {
1899 [ - + ]: 6 : if( HasParentSeries() )
1900 : : {
1901 : : // *** series is a child series, e.g. trend line or error bar ***
1902 : :
1903 : : // create missing series format
1904 [ # # ]: 0 : if( !mxSeriesFmt )
1905 [ # # ]: 0 : mxSeriesFmt = CreateDataFormat( EXC_CHDATAFORMAT_ALLPOINTS, 0 );
1906 : :
1907 [ # # ]: 0 : if( mxSeriesFmt )
1908 : : {
1909 : : // #i83100# set text label format, e.g. for trend line equations
1910 [ # # ]: 0 : XclImpChTextRef xLabel;
1911 [ # # ]: 0 : XclImpChTextMap::iterator itr = maLabels.find(EXC_CHDATAFORMAT_ALLPOINTS);
1912 [ # # ]: 0 : if (itr != maLabels.end())
1913 [ # # ]: 0 : xLabel = itr->second;
1914 [ # # ][ # # ]: 0 : mxSeriesFmt->SetDataLabel(xLabel);
[ # # ]
1915 : : // create missing automatic formats
1916 [ # # ][ # # ]: 0 : mxSeriesFmt->UpdateTrendLineFormat();
1917 : : }
1918 : :
1919 : : // copy series formatting to child objects
1920 [ # # ]: 0 : for( XclImpChSerTrendLineList::iterator aLIt = maTrendLines.begin(), aLEnd = maTrendLines.end(); aLIt != aLEnd; ++aLIt )
1921 [ # # ][ # # ]: 0 : (*aLIt)->SetDataFormat( mxSeriesFmt );
[ # # ]
1922 [ # # ][ # # ]: 0 : for( XclImpChSerErrorBarMap::iterator aMIt = maErrorBars.begin(), aMEnd = maErrorBars.end(); aMIt != aMEnd; ++aMIt )
[ # # ][ # # ]
[ # # ]
1923 [ # # ][ # # ]: 0 : aMIt->second->SetSeriesData( mxValueLink, mxSeriesFmt );
[ # # ][ # # ]
[ # # ][ # # ]
1924 : : }
1925 [ + - ]: 6 : else if( XclImpChTypeGroup* pTypeGroup = GetChartData().GetTypeGroup( mnGroupIdx ).get() )
1926 : : {
1927 : : // *** series is a regular data series ***
1928 : :
1929 : : // create missing series format
1930 [ - + ]: 6 : if( !mxSeriesFmt )
1931 : : {
1932 : : // #i51639# use a new unused format index to create series default format
1933 : 0 : sal_uInt16 nFormatIdx = pTypeGroup->PopUnusedFormatIndex();
1934 [ # # ]: 0 : mxSeriesFmt = CreateDataFormat( EXC_CHDATAFORMAT_ALLPOINTS, nFormatIdx );
1935 : : }
1936 : :
1937 : : // set text labels to data formats
1938 [ - + ]: 6 : for( XclImpChTextMap::iterator aTIt = maLabels.begin(), aTEnd = maLabels.end(); aTIt != aTEnd; ++aTIt )
1939 : : {
1940 : 0 : sal_uInt16 nPointIdx = aTIt->first;
1941 [ # # ]: 0 : if (nPointIdx == EXC_CHDATAFORMAT_ALLPOINTS)
1942 : : {
1943 [ # # ]: 0 : if (!mxSeriesFmt)
1944 [ # # ][ # # ]: 0 : mxSeriesFmt = CreateDataFormat(nPointIdx, EXC_CHDATAFORMAT_DEFAULT);
[ # # ]
1945 [ # # ][ # # ]: 0 : mxSeriesFmt->SetDataLabel(aTIt->second);
[ # # ]
1946 : : }
1947 [ # # ]: 0 : else if (nPointIdx < EXC_CHDATAFORMAT_MAXPOINTCOUNT)
1948 : : {
1949 [ # # ]: 0 : XclImpChDataFormatRef p;
1950 [ # # ]: 0 : XclImpChDataFormatMap::iterator itr = maPointFmts.lower_bound(nPointIdx);
1951 [ # # ][ # # ]: 0 : if (itr == maPointFmts.end() || maPointFmts.key_comp()(nPointIdx, itr->first))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # ]
1952 : : {
1953 : : // No object exists at this point index position. Insert
1954 : : // a new one.
1955 [ # # ][ # # ]: 0 : p = CreateDataFormat(nPointIdx, EXC_CHDATAFORMAT_DEFAULT);
[ # # ]
1956 : : itr = maPointFmts.insert(
1957 [ # # ][ # # ]: 0 : itr, XclImpChDataFormatMap::value_type(nPointIdx, p));
[ # # ]
1958 : : }
1959 : : else
1960 [ # # ]: 0 : p = itr->second;
1961 [ # # ][ # # ]: 0 : p->SetDataLabel(aTIt->second);
[ # # ][ # # ]
1962 : : }
1963 : : }
1964 : :
1965 : : // update series format (copy missing formatting from group default format)
1966 [ + - ]: 6 : if( mxSeriesFmt )
1967 [ + - ]: 6 : mxSeriesFmt->UpdateSeriesFormat( pTypeGroup->GetTypeInfo(), pTypeGroup->GetGroupFormat().get() );
1968 : :
1969 : : // update data point formats (removes unchanged automatic formatting)
1970 [ - + ]: 6 : for( XclImpChDataFormatMap::iterator aFIt = maPointFmts.begin(), aFEnd = maPointFmts.end(); aFIt != aFEnd; ++aFIt )
1971 [ # # ]: 0 : aFIt->second->UpdatePointFormat( pTypeGroup->GetTypeInfo(), mxSeriesFmt.get() );
1972 : : }
1973 : 6 : }
1974 : :
1975 : : namespace {
1976 : :
1977 : : /** Returns the property set of the specified data point. */
1978 : 0 : ScfPropertySet lclGetPointPropSet( Reference< XDataSeries > xDataSeries, sal_uInt16 nPointIdx )
1979 : : {
1980 : 0 : ScfPropertySet aPropSet;
1981 : : try
1982 : : {
1983 [ # # ][ # # ]: 0 : aPropSet.Set( xDataSeries->getDataPointByIndex( static_cast< sal_Int32 >( nPointIdx ) ) );
[ # # ][ # # ]
1984 : : }
1985 [ # # ]: 0 : catch( Exception& )
1986 : : {
1987 : : OSL_FAIL( "lclGetPointPropSet - no data point property set" );
1988 : : }
1989 : 0 : return aPropSet;
1990 : : }
1991 : :
1992 : : } // namespace
1993 : :
1994 : 6 : Reference< XLabeledDataSequence > XclImpChSeries::CreateValueSequence( const OUString& rValueRole ) const
1995 : : {
1996 : 6 : return lclCreateLabeledDataSequence( mxValueLink, rValueRole, mxTitleLink.get() );
1997 : : }
1998 : :
1999 : 6 : Reference< XLabeledDataSequence > XclImpChSeries::CreateCategSequence( const OUString& rCategRole ) const
2000 : : {
2001 : 6 : return lclCreateLabeledDataSequence( mxCategLink, rCategRole );
2002 : : }
2003 : :
2004 : 6 : Reference< XDataSeries > XclImpChSeries::CreateDataSeries() const
2005 : : {
2006 : 6 : Reference< XDataSeries > xDataSeries;
2007 [ + - ][ + - ]: 6 : if( const XclImpChTypeGroup* pTypeGroup = GetChartData().GetTypeGroup( mnGroupIdx ).get() )
[ + - ][ + - ]
2008 : : {
2009 : 6 : const XclChExtTypeInfo& rTypeInfo = pTypeGroup->GetTypeInfo();
2010 : :
2011 : : // create the data series object
2012 [ + - ][ + - ]: 6 : xDataSeries.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_DATASERIES ), UNO_QUERY );
[ + - ]
2013 : :
2014 : : // attach data and title sequences to series
2015 [ + - ]: 6 : Reference< XDataSink > xDataSink( xDataSeries, UNO_QUERY );
2016 [ + - ]: 6 : if( xDataSink.is() )
2017 : : {
2018 : : // create vector of all value sequences
2019 [ + - ]: 6 : ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
2020 : : // add Y values
2021 : : Reference< XLabeledDataSequence > xYValueSeq =
2022 [ + - ][ + - ]: 6 : CreateValueSequence( EXC_CHPROP_ROLE_YVALUES );
2023 [ + - ]: 6 : if( xYValueSeq.is() )
2024 [ + - ]: 6 : aLabeledSeqVec.push_back( xYValueSeq );
2025 : : // add X values
2026 [ - + ]: 6 : if( !rTypeInfo.mbCategoryAxis )
2027 : : {
2028 : : Reference< XLabeledDataSequence > xXValueSeq =
2029 [ # # ][ # # ]: 0 : CreateCategSequence( EXC_CHPROP_ROLE_XVALUES );
2030 [ # # ]: 0 : if( xXValueSeq.is() )
2031 [ # # ]: 0 : aLabeledSeqVec.push_back( xXValueSeq );
2032 : : // add size values of bubble charts
2033 [ # # ]: 0 : if( rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES )
2034 : : {
2035 : : Reference< XLabeledDataSequence > xSizeValueSeq =
2036 [ # # ][ # # ]: 0 : lclCreateLabeledDataSequence( mxBubbleLink, EXC_CHPROP_ROLE_SIZEVALUES, mxTitleLink.get() );
2037 [ # # ]: 0 : if( xSizeValueSeq.is() )
2038 [ # # ]: 0 : aLabeledSeqVec.push_back( xSizeValueSeq );
2039 : 0 : }
2040 : : }
2041 : : // attach labeled data sequences to series
2042 [ + - ]: 6 : if( !aLabeledSeqVec.empty() )
2043 [ + - ][ + - ]: 6 : xDataSink->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec ) );
[ + - ][ + - ]
2044 : : }
2045 : :
2046 : : // series formatting
2047 [ + - ]: 6 : ScfPropertySet aSeriesProp( xDataSeries );
2048 [ + - ]: 6 : if( mxSeriesFmt )
2049 [ + - ]: 6 : mxSeriesFmt->Convert( aSeriesProp, rTypeInfo );
2050 : :
2051 : : // trend lines
2052 [ + - ]: 6 : ConvertTrendLines( xDataSeries );
2053 : :
2054 : : // error bars
2055 [ + - ]: 6 : Reference< XPropertySet > xErrorBarX = CreateErrorBar( EXC_CHSERERR_XPLUS, EXC_CHSERERR_XMINUS );
2056 [ - + ]: 6 : if( xErrorBarX.is() )
2057 [ # # ][ # # ]: 0 : aSeriesProp.SetProperty( EXC_CHPROP_ERRORBARX, xErrorBarX );
2058 [ + - ]: 6 : Reference< XPropertySet > xErrorBarY = CreateErrorBar( EXC_CHSERERR_YPLUS, EXC_CHSERERR_YMINUS );
2059 [ - + ]: 6 : if( xErrorBarY.is() )
2060 [ # # ][ # # ]: 0 : aSeriesProp.SetProperty( EXC_CHPROP_ERRORBARY, xErrorBarY );
2061 : :
2062 : : // own area formatting for every data point (TODO: varying line color not supported)
2063 [ + - ][ - + ]: 6 : bool bVarPointFmt = pTypeGroup->HasVarPointFormat() && rTypeInfo.IsSeriesFrameFormat();
[ # # ]
2064 : : #if EXC_CHART2_VARYCOLORSBY_PROP
2065 : : aSeriesProp.SetBoolProperty( EXC_CHPROP_VARYCOLORSBY, bVarPointFmt );
2066 : : #else
2067 [ + - ][ + - ]: 6 : aSeriesProp.SetBoolProperty( EXC_CHPROP_VARYCOLORSBY, rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE );
2068 : : #endif
2069 : : // #i91271# always set area formatting for every point in pie/doughnut charts
2070 [ - + ][ # # ]: 6 : if( mxSeriesFmt && ((bVarPointFmt && mxSeriesFmt->IsAutoArea()) || (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE)) )
[ # # ][ - + ]
[ - + ][ + - ]
2071 : : {
2072 [ # # ][ # # ]: 0 : for( sal_uInt16 nPointIdx = 0, nPointCount = mxValueLink->GetCellCount(); nPointIdx < nPointCount; ++nPointIdx )
2073 : : {
2074 [ # # ]: 0 : ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, nPointIdx );
2075 [ # # ][ # # ]: 0 : mxSeriesFmt->ConvertArea( aPointProp, bVarPointFmt ? nPointIdx : mnSeriesIdx, false );
2076 [ # # ]: 0 : }
2077 : : }
2078 : :
2079 : : // data point formatting
2080 [ - + ]: 6 : for( XclImpChDataFormatMap::const_iterator aIt = maPointFmts.begin(), aEnd = maPointFmts.end(); aIt != aEnd; ++aIt )
2081 : : {
2082 [ # # ]: 0 : ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, aIt->first );
2083 [ # # ]: 0 : aIt->second->Convert( aPointProp, rTypeInfo );
2084 [ # # ][ + - ]: 6 : }
2085 : : }
2086 : 6 : return xDataSeries;
2087 : : }
2088 : :
2089 : 6 : void XclImpChSeries::FillAllSourceLinks( ::std::vector< ScTokenRef >& rTokens ) const
2090 : : {
2091 [ + - ]: 6 : if( mxValueLink )
2092 : 6 : mxValueLink->FillSourceLink( rTokens );
2093 [ + - ]: 6 : if( mxCategLink )
2094 : 6 : mxCategLink->FillSourceLink( rTokens );
2095 [ + - ]: 6 : if( mxTitleLink )
2096 : 6 : mxTitleLink->FillSourceLink( rTokens );
2097 [ + - ]: 6 : if( mxBubbleLink )
2098 : 6 : mxBubbleLink->FillSourceLink( rTokens );
2099 : 6 : }
2100 : :
2101 : 24 : void XclImpChSeries::ReadChSourceLink( XclImpStream& rStrm )
2102 : : {
2103 [ + - ][ + - ]: 24 : XclImpChSourceLinkRef xSrcLink( new XclImpChSourceLink( GetChRoot() ) );
[ + - ]
2104 [ + - ]: 24 : xSrcLink->ReadChSourceLink( rStrm );
2105 [ + + + + : 24 : switch( xSrcLink->GetDestType() )
- ]
2106 : : {
2107 [ + - ]: 6 : case EXC_CHSRCLINK_TITLE: mxTitleLink = xSrcLink; break;
2108 [ + - ]: 6 : case EXC_CHSRCLINK_VALUES: mxValueLink = xSrcLink; break;
2109 [ + - ]: 6 : case EXC_CHSRCLINK_CATEGORY: mxCategLink = xSrcLink; break;
2110 [ + - ]: 6 : case EXC_CHSRCLINK_BUBBLES: mxBubbleLink = xSrcLink; break;
2111 [ + - ]: 24 : }
2112 : 24 : }
2113 : :
2114 : 6 : void XclImpChSeries::ReadChDataFormat( XclImpStream& rStrm )
2115 : : {
2116 : : // #i51639# chart stores all data formats and assigns them later to the series
2117 : 6 : GetChartData().ReadChDataFormat( rStrm );
2118 : 6 : }
2119 : :
2120 : 0 : void XclImpChSeries::ReadChSerParent( XclImpStream& rStrm )
2121 : : {
2122 : 0 : rStrm >> mnParentIdx;
2123 : : // index to parent series is 1-based, convert it to 0-based
2124 [ # # ]: 0 : if( mnParentIdx > 0 )
2125 : 0 : --mnParentIdx;
2126 : : else
2127 : 0 : mnParentIdx = EXC_CHSERIES_INVALID;
2128 : 0 : }
2129 : :
2130 : 0 : void XclImpChSeries::ReadChSerTrendLine( XclImpStream& rStrm )
2131 : : {
2132 [ # # ][ # # ]: 0 : XclImpChSerTrendLineRef xTrendLine( new XclImpChSerTrendLine( GetChRoot() ) );
[ # # ]
2133 [ # # ]: 0 : xTrendLine->ReadChSerTrendLine( rStrm );
2134 [ # # ][ # # ]: 0 : maTrendLines.push_back( xTrendLine );
2135 : 0 : }
2136 : :
2137 : 0 : void XclImpChSeries::ReadChSerErrorBar( XclImpStream& rStrm )
2138 : : {
2139 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
2140 [ # # ][ # # ]: 0 : auto_ptr<XclImpChSerErrorBar> pErrorBar(new XclImpChSerErrorBar(GetChRoot()));
2141 : : SAL_WNODEPRECATED_DECLARATIONS_POP
2142 [ # # ]: 0 : pErrorBar->ReadChSerErrorBar(rStrm);
2143 : 0 : sal_uInt8 nBarType = pErrorBar->GetBarType();
2144 [ # # ][ # # ]: 0 : maErrorBars.insert(nBarType, pErrorBar);
[ # # ]
2145 : 0 : }
2146 : :
2147 : 0 : XclImpChDataFormatRef XclImpChSeries::CreateDataFormat( sal_uInt16 nPointIdx, sal_uInt16 nFormatIdx )
2148 : : {
2149 [ # # ][ # # ]: 0 : XclImpChDataFormatRef xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
[ # # ]
2150 [ # # ]: 0 : xDataFmt->SetPointPos( XclChDataPointPos( mnSeriesIdx, nPointIdx ), nFormatIdx );
2151 : 0 : return xDataFmt;
2152 : : }
2153 : :
2154 : 6 : void XclImpChSeries::ConvertTrendLines( Reference< XDataSeries > xDataSeries ) const
2155 : : {
2156 [ + - ]: 6 : Reference< XRegressionCurveContainer > xRegCurveCont( xDataSeries, UNO_QUERY );
2157 [ + - ]: 6 : if( xRegCurveCont.is() )
2158 : : {
2159 [ - + ]: 6 : for( XclImpChSerTrendLineList::const_iterator aIt = maTrendLines.begin(), aEnd = maTrendLines.end(); aIt != aEnd; ++aIt )
2160 : : {
2161 : : try
2162 : : {
2163 [ # # ]: 0 : Reference< XRegressionCurve > xRegCurve = (*aIt)->CreateRegressionCurve();
2164 [ # # ]: 0 : if( xRegCurve.is() )
2165 [ # # ][ # # ]: 0 : xRegCurveCont->addRegressionCurve( xRegCurve );
[ # # ]
2166 : : }
2167 [ # # ]: 0 : catch( Exception& )
2168 : : {
2169 : : OSL_FAIL( "XclImpChSeries::ConvertTrendLines - cannot add regression curve" );
2170 : : }
2171 : : }
2172 : 6 : }
2173 : 6 : }
2174 : :
2175 : 12 : Reference< XPropertySet > XclImpChSeries::CreateErrorBar( sal_uInt8 nPosBarId, sal_uInt8 nNegBarId ) const
2176 : : {
2177 [ + - ]: 12 : XclImpChSerErrorBarMap::const_iterator itrPosBar = maErrorBars.find(nPosBarId);
2178 [ + - ]: 12 : XclImpChSerErrorBarMap::const_iterator itrNegBar = maErrorBars.find(nNegBarId);
2179 [ + - ]: 12 : XclImpChSerErrorBarMap::const_iterator itrEnd = maErrorBars.end();
2180 [ + - ][ - + ]: 12 : if (itrPosBar == itrEnd || itrNegBar == itrEnd)
[ # # ][ # # ]
[ + - ]
2181 : 12 : return Reference<XPropertySet>();
2182 : :
2183 [ # # ][ # # ]: 12 : return XclImpChSerErrorBar::CreateErrorBar(itrPosBar->second, itrNegBar->second);
[ # # ]
2184 : : }
2185 : :
2186 : : // Chart type groups ==========================================================
2187 : :
2188 : 6 : XclImpChType::XclImpChType( const XclImpChRoot& rRoot ) :
2189 : : XclImpChRoot( rRoot ),
2190 : : mnRecId( EXC_ID_CHUNKNOWN ),
2191 [ + - ][ + - ]: 6 : maTypeInfo( rRoot.GetChartTypeInfo( EXC_CHTYPEID_UNKNOWN ) )
2192 : : {
2193 : 6 : }
2194 : :
2195 : 24 : void XclImpChType::ReadChType( XclImpStream& rStrm )
2196 : : {
2197 : 24 : sal_uInt16 nRecId = rStrm.GetRecId();
2198 : 24 : bool bKnownType = true;
2199 : :
2200 [ + + - - : 24 : switch( nRecId )
- - + ]
2201 : : {
2202 : : case EXC_ID_CHBAR:
2203 : 3 : rStrm >> maData.mnOverlap >> maData.mnGap >> maData.mnFlags;
2204 : 3 : break;
2205 : :
2206 : : case EXC_ID_CHLINE:
2207 : : case EXC_ID_CHAREA:
2208 : : case EXC_ID_CHRADARLINE:
2209 : : case EXC_ID_CHRADARAREA:
2210 : 3 : rStrm >> maData.mnFlags;
2211 : 3 : break;
2212 : :
2213 : : case EXC_ID_CHPIE:
2214 : 0 : rStrm >> maData.mnRotation >> maData.mnPieHole;
2215 [ # # ]: 0 : if( GetBiff() == EXC_BIFF8 )
2216 : 0 : rStrm >> maData.mnFlags;
2217 : : else
2218 : 0 : maData.mnFlags = 0;
2219 : 0 : break;
2220 : :
2221 : : case EXC_ID_CHPIEEXT:
2222 : 0 : maData.mnRotation = 0;
2223 : 0 : maData.mnPieHole = 0;
2224 : 0 : maData.mnFlags = 0;
2225 : 0 : break;
2226 : :
2227 : : case EXC_ID_CHSCATTER:
2228 [ # # ]: 0 : if( GetBiff() == EXC_BIFF8 )
2229 : 0 : rStrm >> maData.mnBubbleSize >> maData.mnBubbleType >> maData.mnFlags;
2230 : : else
2231 : 0 : maData.mnFlags = 0;
2232 : 0 : break;
2233 : :
2234 : : case EXC_ID_CHSURFACE:
2235 : 0 : rStrm >> maData.mnFlags;
2236 : 0 : break;
2237 : :
2238 : : default:
2239 : 18 : bKnownType = false;
2240 : : }
2241 : :
2242 [ + + ]: 24 : if( bKnownType )
2243 : 6 : mnRecId = nRecId;
2244 : 24 : }
2245 : :
2246 : 6 : void XclImpChType::Finalize( bool bStockChart )
2247 : : {
2248 [ + + - - : 6 : switch( mnRecId )
- ]
2249 : : {
2250 : : case EXC_ID_CHLINE:
2251 : : maTypeInfo = GetChartTypeInfo( bStockChart ?
2252 [ - + ]: 3 : EXC_CHTYPEID_STOCK : EXC_CHTYPEID_LINE );
2253 : 3 : break;
2254 : : case EXC_ID_CHBAR:
2255 : : maTypeInfo = GetChartTypeInfo( ::get_flagvalue(
2256 : : maData.mnFlags, EXC_CHBAR_HORIZONTAL,
2257 : 3 : EXC_CHTYPEID_HORBAR, EXC_CHTYPEID_BAR ) );
2258 : 3 : break;
2259 : : case EXC_ID_CHPIE:
2260 : : maTypeInfo = GetChartTypeInfo( (maData.mnPieHole > 0) ?
2261 [ # # ]: 0 : EXC_CHTYPEID_DONUT : EXC_CHTYPEID_PIE );
2262 : 0 : break;
2263 : : case EXC_ID_CHSCATTER:
2264 : : maTypeInfo = GetChartTypeInfo( ::get_flagvalue(
2265 : : maData.mnFlags, EXC_CHSCATTER_BUBBLES,
2266 : 0 : EXC_CHTYPEID_BUBBLES, EXC_CHTYPEID_SCATTER ) );
2267 : 0 : break;
2268 : : default:
2269 : 0 : maTypeInfo = GetChartTypeInfo( mnRecId );
2270 : : }
2271 : :
2272 [ - + ]: 6 : switch( maTypeInfo.meTypeId )
2273 : : {
2274 : : case EXC_CHTYPEID_PIEEXT:
2275 : : case EXC_CHTYPEID_BUBBLES:
2276 : : case EXC_CHTYPEID_SURFACE:
2277 : : case EXC_CHTYPEID_UNKNOWN:
2278 : 0 : GetTracer().TraceChartUnKnownType();
2279 : 0 : break;
2280 : : default:;
2281 : : }
2282 : 6 : }
2283 : :
2284 : 12 : bool XclImpChType::IsStacked() const
2285 : : {
2286 : 12 : bool bStacked = false;
2287 [ + - ]: 12 : if( maTypeInfo.mbSupportsStacking ) switch( maTypeInfo.meTypeCateg )
[ + + - ]
2288 : : {
2289 : : case EXC_CHTYPECATEG_LINE:
2290 : : bStacked =
2291 : 6 : ::get_flag( maData.mnFlags, EXC_CHLINE_STACKED ) &&
2292 [ + - ][ + - ]: 6 : !::get_flag( maData.mnFlags, EXC_CHLINE_PERCENT );
2293 : 6 : break;
2294 : : case EXC_CHTYPECATEG_BAR:
2295 : : bStacked =
2296 : 6 : ::get_flag( maData.mnFlags, EXC_CHBAR_STACKED ) &&
2297 [ # # ][ - + ]: 6 : !::get_flag( maData.mnFlags, EXC_CHBAR_PERCENT );
2298 : 12 : break;
2299 : : default:;
2300 : : }
2301 : 12 : return bStacked;
2302 : : }
2303 : :
2304 : 12 : bool XclImpChType::IsPercent() const
2305 : : {
2306 : 12 : bool bPercent = false;
2307 [ + - ]: 12 : if( maTypeInfo.mbSupportsStacking ) switch( maTypeInfo.meTypeCateg )
[ + + - ]
2308 : : {
2309 : : case EXC_CHTYPECATEG_LINE:
2310 : : bPercent =
2311 : 3 : ::get_flag( maData.mnFlags, EXC_CHLINE_STACKED ) &&
2312 [ - + ][ + - ]: 3 : ::get_flag( maData.mnFlags, EXC_CHLINE_PERCENT );
2313 : 3 : break;
2314 : : case EXC_CHTYPECATEG_BAR:
2315 : : bPercent =
2316 : 9 : ::get_flag( maData.mnFlags, EXC_CHBAR_STACKED ) &&
2317 [ # # ][ - + ]: 9 : ::get_flag( maData.mnFlags, EXC_CHBAR_PERCENT );
2318 : 12 : break;
2319 : : default:;
2320 : : }
2321 : 12 : return bPercent;
2322 : : }
2323 : :
2324 : 6 : bool XclImpChType::HasCategoryLabels() const
2325 : : {
2326 : : // radar charts disable category labels in chart type, not in CHTICK of X axis
2327 [ - + ][ # # ]: 6 : return (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_RADAR) || ::get_flag( maData.mnFlags, EXC_CHRADAR_AXISLABELS );
2328 : : }
2329 : :
2330 : 6 : Reference< XCoordinateSystem > XclImpChType::CreateCoordSystem( bool b3dChart ) const
2331 : : {
2332 : : // service name
2333 : 6 : OUString aCoordSysService;
2334 [ - + ]: 6 : if( maTypeInfo.mbPolarCoordSystem )
2335 : : {
2336 [ # # ]: 0 : if( b3dChart )
2337 [ # # ]: 0 : aCoordSysService = SERVICE_CHART2_POLARCOORDSYS3D;
2338 : : else
2339 [ # # ]: 0 : aCoordSysService = SERVICE_CHART2_POLARCOORDSYS2D;
2340 : : }
2341 : : else
2342 : : {
2343 [ - + ]: 6 : if( b3dChart )
2344 [ # # ]: 0 : aCoordSysService = SERVICE_CHART2_CARTESIANCOORDSYS3D;
2345 : : else
2346 [ + - ]: 6 : aCoordSysService = SERVICE_CHART2_CARTESIANCOORDSYS2D;
2347 : : }
2348 : :
2349 : : // create the coordinate system object
2350 [ + - ][ + - ]: 6 : Reference< XCoordinateSystem > xCoordSystem( ScfApiHelper::CreateInstance( aCoordSysService ), UNO_QUERY );
2351 : :
2352 : : // swap X and Y axis
2353 [ - + ]: 6 : if( maTypeInfo.mbSwappedAxesSet )
2354 : : {
2355 [ # # ]: 0 : ScfPropertySet aCoordSysProp( xCoordSystem );
2356 [ # # ][ # # ]: 0 : aCoordSysProp.SetBoolProperty( EXC_CHPROP_SWAPXANDYAXIS, true );
[ # # ]
2357 : : }
2358 : :
2359 : 6 : return xCoordSystem;
2360 : : }
2361 : :
2362 : 6 : Reference< XChartType > XclImpChType::CreateChartType( Reference< XDiagram > xDiagram, bool b3dChart ) const
2363 : : {
2364 : 6 : OUString aService = OUString::createFromAscii( maTypeInfo.mpcServiceName );
2365 [ + - ][ + - ]: 6 : Reference< XChartType > xChartType( ScfApiHelper::CreateInstance( aService ), UNO_QUERY );
2366 : :
2367 : : // additional properties
2368 [ + - + ]: 6 : switch( maTypeInfo.meTypeCateg )
2369 : : {
2370 : : case EXC_CHTYPECATEG_BAR:
2371 : : {
2372 [ + - ]: 3 : ScfPropertySet aTypeProp( xChartType );
2373 [ + - ]: 3 : Sequence< sal_Int32 > aInt32Seq( 2 );
2374 [ + - ][ + - ]: 3 : aInt32Seq[ 0 ] = aInt32Seq[ 1 ] = -maData.mnOverlap;
2375 [ + - ][ + - ]: 3 : aTypeProp.SetProperty( EXC_CHPROP_OVERLAPSEQ, aInt32Seq );
2376 [ + - ][ + - ]: 3 : aInt32Seq[ 0 ] = aInt32Seq[ 1 ] = maData.mnGap;
2377 [ + - ][ + - ]: 3 : aTypeProp.SetProperty( EXC_CHPROP_GAPWIDTHSEQ, aInt32Seq );
[ + - ][ + - ]
2378 : : }
2379 : 3 : break;
2380 : : case EXC_CHTYPECATEG_PIE:
2381 : : {
2382 [ # # ]: 0 : ScfPropertySet aTypeProp( xChartType );
2383 [ # # ][ # # ]: 0 : aTypeProp.SetBoolProperty( EXC_CHPROP_USERINGS, maTypeInfo.meTypeId == EXC_CHTYPEID_DONUT );
2384 : : /* #i85166# starting angle of first pie slice. 3D pie charts use Y
2385 : : rotation setting in view3D element. Of-pie charts do not
2386 : : support pie rotation. */
2387 [ # # ][ # # ]: 0 : if( !b3dChart && (maTypeInfo.meTypeId != EXC_CHTYPEID_PIEEXT) )
2388 : : {
2389 [ # # ]: 0 : ScfPropertySet aDiaProp( xDiagram );
2390 [ # # ][ # # ]: 0 : XclImpChRoot::ConvertPieRotation( aDiaProp, maData.mnRotation );
2391 [ # # ]: 0 : }
2392 : : }
2393 : 0 : break;
2394 : : default:;
2395 : : }
2396 : :
2397 : 6 : return xChartType;
2398 : : }
2399 : :
2400 : : // ----------------------------------------------------------------------------
2401 : :
2402 : 0 : void XclImpChChart3d::ReadChChart3d( XclImpStream& rStrm )
2403 : : {
2404 : 0 : rStrm >> maData.mnRotation
2405 : 0 : >> maData.mnElevation
2406 : 0 : >> maData.mnEyeDist
2407 : 0 : >> maData.mnRelHeight
2408 : 0 : >> maData.mnRelDepth
2409 : 0 : >> maData.mnDepthGap
2410 : 0 : >> maData.mnFlags;
2411 : 0 : }
2412 : :
2413 : 0 : void XclImpChChart3d::Convert( ScfPropertySet& rPropSet, bool b3dWallChart ) const
2414 : : {
2415 : : namespace cssd = ::com::sun::star::drawing;
2416 : :
2417 : : // #i104057# do not assert this, written by broken external generators
2418 : : // OSL_ENSURE( ::get_flag( maData.mnFlags, EXC_CHCHART3D_HASWALLS ) == b3dWallChart, "XclImpChChart3d::Convert - wrong wall flag" );
2419 : :
2420 : 0 : sal_Int32 nRotationY = 0;
2421 : 0 : sal_Int32 nRotationX = 0;
2422 : 0 : sal_Int32 nPerspective = 15;
2423 : 0 : bool bRightAngled = false;
2424 : 0 : cssd::ProjectionMode eProjMode = cssd::ProjectionMode_PERSPECTIVE;
2425 : 0 : Color aAmbientColor, aLightColor;
2426 : :
2427 [ # # ]: 0 : if( b3dWallChart )
2428 : : {
2429 : : // Y rotation (Excel [0..359], Chart2 [-179,180])
2430 : 0 : nRotationY = maData.mnRotation % 360;
2431 [ # # ]: 0 : if( nRotationY > 180 ) nRotationY -= 360;
2432 : : // X rotation a.k.a. elevation (Excel [-90..90], Chart2 [-179,180])
2433 [ # # ]: 0 : nRotationX = limit_cast< sal_Int32, sal_Int32 >( maData.mnElevation, -90, 90 );
2434 : : // perspective (Excel and Chart2 [0,100])
2435 [ # # ]: 0 : nPerspective = limit_cast< sal_Int32, sal_Int32 >( maData.mnEyeDist, 0, 100 );
2436 : : // right-angled axes
2437 : 0 : bRightAngled = !::get_flag( maData.mnFlags, EXC_CHCHART3D_REAL3D );
2438 : : // projection mode (parallel axes, if right-angled, #i90360# or if perspective is at 0%)
2439 [ # # ][ # # ]: 0 : bool bParallel = bRightAngled || (nPerspective == 0);
2440 [ # # ]: 0 : eProjMode = bParallel ? cssd::ProjectionMode_PARALLEL : cssd::ProjectionMode_PERSPECTIVE;
2441 : : // ambient color (Gray 20%)
2442 : 0 : aAmbientColor.SetColor( RGB_COLORDATA( 204, 204, 204 ) );
2443 : : // light color (Gray 60%)
2444 : 0 : aLightColor.SetColor( RGB_COLORDATA( 102, 102, 102 ) );
2445 : : }
2446 : : else
2447 : : {
2448 : : // Y rotation not used in pie charts, but 'first pie slice angle'
2449 : 0 : nRotationY = 0;
2450 [ # # ]: 0 : XclImpChRoot::ConvertPieRotation( rPropSet, maData.mnRotation );
2451 : : // X rotation a.k.a. elevation (map Excel [10..80] to Chart2 [-80,-10])
2452 [ # # ]: 0 : nRotationX = limit_cast< sal_Int32, sal_Int32 >( maData.mnElevation, 10, 80 ) - 90;
2453 : : // perspective (Excel and Chart2 [0,100])
2454 [ # # ]: 0 : nPerspective = limit_cast< sal_Int32, sal_Int32 >( maData.mnEyeDist, 0, 100 );
2455 : : // no right-angled axes in pie charts, but parallel projection
2456 : 0 : bRightAngled = false;
2457 : 0 : eProjMode = cssd::ProjectionMode_PARALLEL;
2458 : : // ambient color (Gray 30%)
2459 : 0 : aAmbientColor.SetColor( RGB_COLORDATA( 179, 179, 179 ) );
2460 : : // light color (Gray 70%)
2461 : 0 : aLightColor.SetColor( RGB_COLORDATA( 76, 76, 76 ) );
2462 : : }
2463 : :
2464 : : // properties
2465 [ # # ][ # # ]: 0 : rPropSet.SetProperty( EXC_CHPROP_ROTATIONVERTICAL, nRotationY );
2466 [ # # ][ # # ]: 0 : rPropSet.SetProperty( EXC_CHPROP_ROTATIONHORIZONTAL, nRotationX );
2467 [ # # ][ # # ]: 0 : rPropSet.SetProperty( EXC_CHPROP_PERSPECTIVE, nPerspective );
2468 [ # # ][ # # ]: 0 : rPropSet.SetBoolProperty( EXC_CHPROP_RIGHTANGLEDAXES, bRightAngled );
2469 [ # # ][ # # ]: 0 : rPropSet.SetProperty( EXC_CHPROP_D3DSCENEPERSPECTIVE, eProjMode );
2470 : :
2471 : : // light settings
2472 [ # # ][ # # ]: 0 : rPropSet.SetProperty( EXC_CHPROP_D3DSCENESHADEMODE, cssd::ShadeMode_FLAT );
2473 [ # # ][ # # ]: 0 : rPropSet.SetColorProperty( EXC_CHPROP_D3DSCENEAMBIENTCOLOR, aAmbientColor );
2474 [ # # ][ # # ]: 0 : rPropSet.SetBoolProperty( EXC_CHPROP_D3DSCENELIGHTON1, false );
2475 [ # # ][ # # ]: 0 : rPropSet.SetBoolProperty( EXC_CHPROP_D3DSCENELIGHTON2, true );
2476 [ # # ][ # # ]: 0 : rPropSet.SetColorProperty( EXC_CHPROP_D3DSCENELIGHTCOLOR2, aLightColor );
2477 [ # # ][ # # ]: 0 : rPropSet.SetProperty( EXC_CHPROP_D3DSCENELIGHTDIR2, cssd::Direction3D( 0.2, 0.4, 1.0 ) );
2478 : 0 : }
2479 : :
2480 : : // ----------------------------------------------------------------------------
2481 : :
2482 : 6 : XclImpChLegend::XclImpChLegend( const XclImpChRoot& rRoot ) :
2483 [ + - ][ + - ]: 6 : XclImpChRoot( rRoot )
[ + - ][ + - ]
[ + - ]
2484 : : {
2485 : 6 : }
2486 : :
2487 : 6 : void XclImpChLegend::ReadHeaderRecord( XclImpStream& rStrm )
2488 : : {
2489 : 6 : rStrm >> maData.maRect >> maData.mnDockMode >> maData.mnSpacing >> maData.mnFlags;
2490 : :
2491 : : // trace unsupported features
2492 [ - + ]: 6 : if( GetTracer().IsEnabled() )
2493 : : {
2494 [ # # ]: 0 : if( maData.mnDockMode == EXC_CHLEGEND_NOTDOCKED )
2495 : 0 : GetTracer().TraceChartLegendPosition();
2496 [ # # ]: 0 : if( ::get_flag( maData.mnFlags, EXC_CHLEGEND_DATATABLE ) )
2497 : 0 : GetTracer().TraceChartDataTable();
2498 : : }
2499 : 6 : }
2500 : :
2501 : 24 : void XclImpChLegend::ReadSubRecord( XclImpStream& rStrm )
2502 : : {
2503 [ + + - + ]: 24 : switch( rStrm.GetRecId() )
2504 : : {
2505 : : case EXC_ID_CHFRAMEPOS:
2506 [ + - ]: 6 : mxFramePos.reset( new XclImpChFramePos );
2507 : 6 : mxFramePos->ReadChFramePos( rStrm );
2508 : 6 : break;
2509 : : case EXC_ID_CHTEXT:
2510 [ + - ]: 6 : mxText.reset( new XclImpChText( GetChRoot() ) );
2511 : 6 : mxText->ReadRecordGroup( rStrm );
2512 : 6 : break;
2513 : : case EXC_ID_CHFRAME:
2514 [ # # ]: 0 : mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_LEGEND ) );
2515 : 0 : mxFrame->ReadRecordGroup( rStrm );
2516 : 0 : break;
2517 : : }
2518 : 24 : }
2519 : :
2520 : 6 : void XclImpChLegend::Finalize()
2521 : : {
2522 : : // legend default formatting differs in OOChart and Excel, missing frame means automatic
2523 [ + - ]: 6 : if( !mxFrame )
2524 [ + - ]: 6 : mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_LEGEND ) );
2525 : : // Update text formatting. If mxText is empty, the passed default text is used.
2526 : 6 : lclUpdateText( mxText, GetChartData().GetDefaultText( EXC_CHTEXTTYPE_LEGEND ) );
2527 : 6 : }
2528 : :
2529 : 6 : Reference< XLegend > XclImpChLegend::CreateLegend() const
2530 : : {
2531 [ + - ][ + - ]: 6 : Reference< XLegend > xLegend( ScfApiHelper::CreateInstance( SERVICE_CHART2_LEGEND ), UNO_QUERY );
2532 [ + - ]: 6 : if( xLegend.is() )
2533 : : {
2534 [ + - ]: 6 : ScfPropertySet aLegendProp( xLegend );
2535 [ + - ][ + - ]: 6 : aLegendProp.SetBoolProperty( EXC_CHPROP_SHOW, true );
2536 : :
2537 : : // frame properties
2538 [ + - ]: 6 : if( mxFrame )
2539 [ + - ]: 6 : mxFrame->Convert( aLegendProp );
2540 : : // text properties
2541 [ + - ]: 6 : if( mxText )
2542 [ + - ]: 6 : mxText->ConvertFont( aLegendProp );
2543 : :
2544 : : /* Legend position and size. Default positions are used only if the
2545 : : plot area is positioned automatically (Excel sets the plot area to
2546 : : manual mode, if the legend is moved or resized). With manual plot
2547 : : areas, Excel ignores the value in maData.mnDockMode completely. */
2548 : 6 : cssc2::LegendPosition eApiPos = cssc2::LegendPosition_CUSTOM;
2549 : 6 : cssc::ChartLegendExpansion eApiExpand = cssc::ChartLegendExpansion_CUSTOM;
2550 [ + - ][ + - ]: 6 : if( !GetChartData().IsManualPlotArea() ) switch( maData.mnDockMode )
[ + + ][ - +
- - - ]
2551 : : {
2552 : : case EXC_CHLEGEND_LEFT:
2553 : 0 : eApiPos = cssc2::LegendPosition_LINE_START;
2554 : 0 : eApiExpand = cssc::ChartLegendExpansion_HIGH;
2555 : 0 : break;
2556 : : case EXC_CHLEGEND_RIGHT:
2557 : : // top-right not supported
2558 : : case EXC_CHLEGEND_CORNER:
2559 : 3 : eApiPos = cssc2::LegendPosition_LINE_END;
2560 : 3 : eApiExpand = cssc::ChartLegendExpansion_HIGH;
2561 : 3 : break;
2562 : : case EXC_CHLEGEND_TOP:
2563 : 0 : eApiPos = cssc2::LegendPosition_PAGE_START;
2564 : 0 : eApiExpand = cssc::ChartLegendExpansion_WIDE;
2565 : 0 : break;
2566 : : case EXC_CHLEGEND_BOTTOM:
2567 : 0 : eApiPos = cssc2::LegendPosition_PAGE_END;
2568 : 0 : eApiExpand = cssc::ChartLegendExpansion_WIDE;
2569 : 3 : break;
2570 : : }
2571 : :
2572 : : // no automatic position/size: try to find the correct position and size
2573 [ + + ]: 6 : if( eApiPos == cssc2::LegendPosition_CUSTOM )
2574 : : {
2575 [ + - ]: 3 : const XclChFramePos* pFramePos = mxFramePos ? &mxFramePos->GetFramePosData() : 0;
2576 : :
2577 : : /* Legend position. Only the settings from the CHFRAMEPOS record
2578 : : are used by Excel, the position in the CHLEGEND record will be
2579 : : ignored. */
2580 [ + - ]: 3 : if( pFramePos )
2581 : : {
2582 : : RelativePosition aRelPos(
2583 [ + - ]: 3 : CalcRelativeFromChartX( pFramePos->maRect.mnX ),
2584 [ + - ]: 3 : CalcRelativeFromChartY( pFramePos->maRect.mnY ),
2585 : 3 : ::com::sun::star::drawing::Alignment_TOP_LEFT );
2586 [ + - ][ + - ]: 3 : aLegendProp.SetProperty( EXC_CHPROP_RELATIVEPOSITION, aRelPos );
2587 : : }
2588 : : else
2589 : : {
2590 : : // no manual position/size found, just go for the default
2591 : 0 : eApiPos = cssc2::LegendPosition_LINE_END;
2592 : : }
2593 : :
2594 : : /* Legend size. The member mnBRMode specifies whether size is
2595 : : automatic or changes manually. Manual size is given in points,
2596 : : not in chart units. */
2597 [ + - ][ - + ]: 3 : if( pFramePos && (pFramePos->mnBRMode == EXC_CHFRAMEPOS_ABSSIZE_POINTS) &&
[ # # ][ # # ]
2598 : : (pFramePos->maRect.mnWidth > 0) && (pFramePos->maRect.mnHeight > 0) )
2599 : : {
2600 : 0 : eApiExpand = cssc::ChartLegendExpansion_CUSTOM;
2601 : 0 : sal_Int32 nWidthHmm = static_cast< sal_Int32 >( pFramePos->maRect.mnWidth / EXC_POINTS_PER_HMM );
2602 : 0 : sal_Int32 nHeightHmm = static_cast< sal_Int32 >( pFramePos->maRect.mnHeight / EXC_POINTS_PER_HMM );
2603 [ # # ][ # # ]: 0 : RelativeSize aRelSize( CalcRelativeFromHmmX( nWidthHmm ), CalcRelativeFromHmmY( nHeightHmm ) );
2604 [ # # ][ # # ]: 0 : aLegendProp.SetProperty( EXC_CHPROP_RELATIVESIZE, aRelSize );
2605 : : }
2606 : : else
2607 : : {
2608 : : // automatic size: determine entry direction from flags
2609 : : eApiExpand = ::get_flagvalue( maData.mnFlags, EXC_CHLEGEND_STACKED,
2610 : 3 : cssc::ChartLegendExpansion_HIGH, cssc::ChartLegendExpansion_WIDE );
2611 : : }
2612 : : }
2613 [ + - ][ + - ]: 6 : aLegendProp.SetProperty( EXC_CHPROP_ANCHORPOSITION, eApiPos );
2614 [ + - ][ + - ]: 6 : aLegendProp.SetProperty( EXC_CHPROP_EXPANSION, eApiExpand );
[ + - ]
2615 : : }
2616 : 6 : return xLegend;
2617 : : }
2618 : :
2619 : : // ----------------------------------------------------------------------------
2620 : :
2621 : 0 : XclImpChDropBar::XclImpChDropBar( sal_uInt16 nDropBar ) :
2622 : : mnDropBar( nDropBar ),
2623 : 0 : mnBarDist( 0 )
2624 : : {
2625 : 0 : }
2626 : :
2627 : 0 : void XclImpChDropBar::ReadHeaderRecord( XclImpStream& rStrm )
2628 : : {
2629 : 0 : rStrm >> mnBarDist;
2630 : 0 : }
2631 : :
2632 : 0 : void XclImpChDropBar::Convert( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const
2633 : : {
2634 : 0 : XclChObjectType eObjType = EXC_CHOBJTYPE_BACKGROUND;
2635 [ # # # ]: 0 : switch( mnDropBar )
2636 : : {
2637 : 0 : case EXC_CHDROPBAR_UP: eObjType = EXC_CHOBJTYPE_WHITEDROPBAR; break;
2638 : 0 : case EXC_CHDROPBAR_DOWN: eObjType = EXC_CHOBJTYPE_BLACKDROPBAR; break;
2639 : : }
2640 : 0 : ConvertFrameBase( rRoot, rPropSet, eObjType );
2641 : 0 : }
2642 : :
2643 : : // ----------------------------------------------------------------------------
2644 : :
2645 : 6 : XclImpChTypeGroup::XclImpChTypeGroup( const XclImpChRoot& rRoot ) :
2646 : : XclImpChRoot( rRoot ),
2647 : : maType( rRoot ),
2648 [ + - ][ + - ]: 6 : maTypeInfo( maType.GetTypeInfo() )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
2649 : : {
2650 : : // Initialize unused format indexes set. At this time, all formats are unused.
2651 [ + + ]: 1542 : for( sal_uInt16 nFormatIdx = 0; nFormatIdx <= EXC_CHSERIES_MAXSERIES; ++nFormatIdx )
2652 [ + - ]: 1536 : maUnusedFormats.insert( maUnusedFormats.end(), nFormatIdx );
2653 : 6 : }
2654 : :
2655 : 6 : void XclImpChTypeGroup::ReadHeaderRecord( XclImpStream& rStrm )
2656 : : {
2657 : 6 : rStrm.Ignore( 16 );
2658 : 6 : rStrm >> maData.mnFlags >> maData.mnGroupIdx;
2659 : 6 : }
2660 : :
2661 : 30 : void XclImpChTypeGroup::ReadSubRecord( XclImpStream& rStrm )
2662 : : {
2663 [ - + - - : 30 : switch( rStrm.GetRecId() )
- - + ]
2664 : : {
2665 : : case EXC_ID_CHCHART3D:
2666 [ # # ]: 0 : mxChart3d.reset( new XclImpChChart3d );
2667 : 0 : mxChart3d->ReadChChart3d( rStrm );
2668 : 0 : break;
2669 : : case EXC_ID_CHLEGEND:
2670 [ + - ]: 6 : mxLegend.reset( new XclImpChLegend( GetChRoot() ) );
2671 : 6 : mxLegend->ReadRecordGroup( rStrm );
2672 : 6 : break;
2673 : : case EXC_ID_CHDEFAULTTEXT:
2674 : 0 : GetChartData().ReadChDefaultText( rStrm );
2675 : 0 : break;
2676 : : case EXC_ID_CHDROPBAR:
2677 : 0 : ReadChDropBar( rStrm );
2678 : 0 : break;
2679 : : case EXC_ID_CHCHARTLINE:
2680 : 0 : ReadChChartLine( rStrm );
2681 : 0 : break;
2682 : : case EXC_ID_CHDATAFORMAT:
2683 : 0 : ReadChDataFormat( rStrm );
2684 : 0 : break;
2685 : : default:
2686 : 24 : maType.ReadChType( rStrm );
2687 : : }
2688 : 30 : }
2689 : :
2690 : 6 : void XclImpChTypeGroup::Finalize()
2691 : : {
2692 : : // check and set valid chart type
2693 : : bool bStockChart =
2694 : 6 : (maType.GetRecId() == EXC_ID_CHLINE) && // must be a line chart
2695 : 3 : !mxChart3d && // must be a 2d chart
2696 : 3 : HasHiLoLine() && // must contain hi-lo lines
2697 [ # # ][ # # ]: 12 : (maSeries.size() == static_cast<XclImpChSeriesVec::size_type>(HasDropBars() ? 4 : 3)); // correct series count
[ + + + -
- + ]
2698 : 6 : maType.Finalize( bStockChart );
2699 : :
2700 : : // extended type info
2701 : 6 : maTypeInfo.Set( maType.GetTypeInfo(), mxChart3d, false );
2702 : :
2703 : : // reverse series order for some unstacked 2D chart types
2704 [ # # ][ # # ]: 6 : if( maTypeInfo.mbReverseSeries && !Is3dChart() && !maType.IsStacked() && !maType.IsPercent() )
[ # # ][ - + ]
[ - + ]
2705 : 0 : ::std::reverse( maSeries.begin(), maSeries.end() );
2706 : :
2707 : : // update chart type group format, may depend on chart type finalized above
2708 [ - + ]: 6 : if( mxGroupFmt )
2709 : 0 : mxGroupFmt->UpdateGroupFormat( maTypeInfo );
2710 : 6 : }
2711 : :
2712 : 6 : void XclImpChTypeGroup::AddSeries( XclImpChSeriesRef xSeries )
2713 : : {
2714 [ + - ]: 6 : if( xSeries )
2715 : 6 : maSeries.push_back( xSeries );
2716 : : // store first inserted series separately, series order may be reversed later
2717 [ + - ]: 6 : if( !mxFirstSeries )
2718 : 6 : mxFirstSeries = xSeries;
2719 : 6 : }
2720 : :
2721 : 6 : void XclImpChTypeGroup::SetUsedFormatIndex( sal_uInt16 nFormatIdx )
2722 : : {
2723 : 6 : maUnusedFormats.erase( nFormatIdx );
2724 : 6 : }
2725 : :
2726 : 0 : sal_uInt16 XclImpChTypeGroup::PopUnusedFormatIndex()
2727 : : {
2728 : : OSL_ENSURE( !maUnusedFormats.empty(), "XclImpChTypeGroup::PopUnusedFormatIndex - no more format indexes available" );
2729 [ # # ][ # # ]: 0 : sal_uInt16 nFormatIdx = maUnusedFormats.empty() ? 0 : *maUnusedFormats.begin();
[ # # ][ # # ]
2730 : 0 : SetUsedFormatIndex( nFormatIdx );
2731 : 0 : return nFormatIdx;
2732 : : }
2733 : :
2734 : 6 : bool XclImpChTypeGroup::HasVarPointFormat() const
2735 : : {
2736 : 6 : return ::get_flag( maData.mnFlags, EXC_CHTYPEGROUP_VARIEDCOLORS ) &&
2737 : : ((maTypeInfo.meVarPointMode == EXC_CHVARPOINT_MULTI) || // multiple series allowed
2738 : : ((maTypeInfo.meVarPointMode == EXC_CHVARPOINT_SINGLE) && // or exactly 1 series?
2739 [ # # ][ # # ]: 6 : (maSeries.size() == 1)));
[ # # ][ - + ]
2740 : : }
2741 : :
2742 : 6 : bool XclImpChTypeGroup::HasConnectorLines() const
2743 : : {
2744 : : // existence of connector lines (only in stacked bar charts)
2745 [ + - ][ + + ]: 6 : if ( !(maType.IsStacked() || maType.IsPercent()) || (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_BAR) )
[ + - ][ - + ]
[ + - ][ + - ]
2746 : 6 : return false;
2747 [ # # ]: 0 : XclImpChLineFormatMap::const_iterator xConLine = maChartLines.find( EXC_CHCHARTLINE_CONNECT );
2748 [ # # ][ # # ]: 6 : return ( xConLine != maChartLines.end() && xConLine->second->HasLine() );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
2749 : : }
2750 : :
2751 : 0 : const String& XclImpChTypeGroup::GetSingleSeriesTitle() const
2752 : : {
2753 : : // no automatic title for series with trendlines or error bars
2754 : : // pie charts always show an automatic title, even if more series exist
2755 : 0 : return (mxFirstSeries && !mxFirstSeries->HasChildSeries() && (maTypeInfo.mbSingleSeriesVis || (maSeries.size() == 1))) ?
2756 [ # # # # ]: 0 : mxFirstSeries->GetTitle() : String::EmptyString();
[ # # # # ]
2757 : : }
2758 : :
2759 : 6 : void XclImpChTypeGroup::ConvertChart3d( ScfPropertySet& rPropSet ) const
2760 : : {
2761 [ - + ]: 6 : if( mxChart3d )
2762 : 0 : mxChart3d->Convert( rPropSet, Is3dWallChart() );
2763 : 6 : }
2764 : :
2765 : 6 : Reference< XCoordinateSystem > XclImpChTypeGroup::CreateCoordSystem() const
2766 : : {
2767 : 6 : return maType.CreateCoordSystem( Is3dChart() );
2768 : : }
2769 : :
2770 : 6 : Reference< XChartType > XclImpChTypeGroup::CreateChartType( Reference< XDiagram > xDiagram, sal_Int32 nApiAxesSetIdx ) const
2771 : : {
2772 : : OSL_ENSURE( IsValidGroup(), "XclImpChTypeGroup::CreateChartType - type group without series" );
2773 : :
2774 : : // create the chart type object
2775 [ + - ]: 6 : Reference< XChartType > xChartType = maType.CreateChartType( xDiagram, Is3dChart() );
2776 : :
2777 : : // bar chart connector lines
2778 [ - + ][ + - ]: 6 : if( HasConnectorLines() )
2779 : : {
2780 [ # # ]: 0 : ScfPropertySet aDiaProp( xDiagram );
2781 [ # # ][ # # ]: 0 : aDiaProp.SetBoolProperty( EXC_CHPROP_CONNECTBARS, true );
[ # # ]
2782 : : }
2783 : :
2784 : : /* Stock chart needs special processing. Create one 'big' series with
2785 : : data sequences of different roles. */
2786 [ - + ]: 6 : if( maTypeInfo.meTypeId == EXC_CHTYPEID_STOCK )
2787 [ # # ]: 0 : CreateStockSeries( xChartType, nApiAxesSetIdx );
2788 : : else
2789 [ + - ]: 6 : CreateDataSeries( xChartType, nApiAxesSetIdx );
2790 : :
2791 : 6 : return xChartType;
2792 : : }
2793 : :
2794 : 6 : Reference< XLabeledDataSequence > XclImpChTypeGroup::CreateCategSequence() const
2795 : : {
2796 : 6 : Reference< XLabeledDataSequence > xLabeledSeq;
2797 : : // create category sequence from first visible series
2798 [ + - ]: 6 : if( mxFirstSeries )
2799 [ + - ][ + - ]: 6 : xLabeledSeq = mxFirstSeries->CreateCategSequence( EXC_CHPROP_ROLE_CATEG );
[ + - ]
2800 : 6 : return xLabeledSeq;
2801 : : }
2802 : :
2803 : 0 : void XclImpChTypeGroup::ReadChDropBar( XclImpStream& rStrm )
2804 : : {
2805 [ # # ][ # # ]: 0 : if (maDropBars.find(EXC_CHDROPBAR_UP) == maDropBars.end())
[ # # ]
2806 : : {
2807 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
2808 [ # # ][ # # ]: 0 : auto_ptr<XclImpChDropBar> p(new XclImpChDropBar(EXC_CHDROPBAR_UP));
2809 : : SAL_WNODEPRECATED_DECLARATIONS_POP
2810 [ # # ]: 0 : p->ReadRecordGroup(rStrm);
2811 [ # # ][ # # ]: 0 : maDropBars.insert(EXC_CHDROPBAR_UP, p);
[ # # ]
2812 : : }
2813 [ # # ][ # # ]: 0 : else if(maDropBars.find(EXC_CHDROPBAR_DOWN) == maDropBars.end())
[ # # ]
2814 : : {
2815 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
2816 [ # # ][ # # ]: 0 : auto_ptr<XclImpChDropBar> p(new XclImpChDropBar(EXC_CHDROPBAR_DOWN));
2817 : : SAL_WNODEPRECATED_DECLARATIONS_POP
2818 [ # # ]: 0 : p->ReadRecordGroup(rStrm);
2819 [ # # ][ # # ]: 0 : maDropBars.insert(EXC_CHDROPBAR_DOWN, p);
[ # # ]
2820 : : }
2821 : 0 : }
2822 : :
2823 : 0 : void XclImpChTypeGroup::ReadChChartLine( XclImpStream& rStrm )
2824 : : {
2825 [ # # ]: 0 : sal_uInt16 nLineId = rStrm.ReaduInt16();
2826 [ # # ][ # # ]: 0 : if( (rStrm.GetNextRecId() == EXC_ID_CHLINEFORMAT) && rStrm.StartNextRecord() )
[ # # ][ # # ]
[ # # ]
2827 : : {
2828 [ # # ]: 0 : XclImpChLineFormat xLineFmt;
2829 [ # # ]: 0 : xLineFmt.ReadChLineFormat( rStrm );
2830 [ # # ]: 0 : maChartLines[ nLineId ] = xLineFmt;
2831 : : }
2832 : 0 : }
2833 : :
2834 : 0 : void XclImpChTypeGroup::ReadChDataFormat( XclImpStream& rStrm )
2835 : : {
2836 : : // global series and data point format
2837 [ # # ][ # # ]: 0 : XclImpChDataFormatRef xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
[ # # ]
2838 [ # # ]: 0 : xDataFmt->ReadRecordGroup( rStrm );
2839 : 0 : const XclChDataPointPos& rPos = xDataFmt->GetPointPos();
2840 [ # # # # ]: 0 : if( (rPos.mnSeriesIdx == 0) && (rPos.mnPointIdx == 0) &&
[ # # ][ # # ]
2841 : 0 : (xDataFmt->GetFormatIdx() == EXC_CHDATAFORMAT_DEFAULT) )
2842 [ # # ][ # # ]: 0 : mxGroupFmt = xDataFmt;
2843 : 0 : }
2844 : :
2845 : :
2846 : 6 : void XclImpChTypeGroup::InsertDataSeries( Reference< XChartType > xChartType,
2847 : : Reference< XDataSeries > xSeries, sal_Int32 nApiAxesSetIdx ) const
2848 : : {
2849 [ + - ]: 6 : Reference< XDataSeriesContainer > xSeriesCont( xChartType, UNO_QUERY );
2850 [ + - ][ + - ]: 6 : if( xSeriesCont.is() && xSeries.is() )
[ + - ]
2851 : : {
2852 : : // series stacking mode
2853 : 6 : cssc2::StackingDirection eStacking = cssc2::StackingDirection_NO_STACKING;
2854 : : // stacked overrides deep-3d
2855 [ + - ][ + + ]: 6 : if( maType.IsStacked() || maType.IsPercent() )
[ + - ][ - + ]
[ + + ]
2856 : 3 : eStacking = cssc2::StackingDirection_Y_STACKING;
2857 [ + - ][ - + ]: 3 : else if( Is3dDeepChart() )
2858 : 0 : eStacking = cssc2::StackingDirection_Z_STACKING;
2859 : :
2860 : : // additional series properties
2861 [ + - ]: 6 : ScfPropertySet aSeriesProp( xSeries );
2862 [ + - ][ + - ]: 6 : aSeriesProp.SetProperty( EXC_CHPROP_STACKINGDIR, eStacking );
2863 [ + - ][ # # ]: 6 : aSeriesProp.SetProperty( EXC_CHPROP_ATTAXISINDEX, nApiAxesSetIdx );
[ + - ]
2864 : :
2865 : : // insert series into container
2866 : : try
2867 : : {
2868 [ + - ][ + - ]: 6 : xSeriesCont->addDataSeries( xSeries );
2869 : : }
2870 [ # # ]: 0 : catch( Exception& )
2871 : : {
2872 : : OSL_FAIL( "XclImpChTypeGroup::InsertDataSeries - cannot add data series" );
2873 [ + - ]: 6 : }
2874 : 6 : }
2875 : 6 : }
2876 : :
2877 : 6 : void XclImpChTypeGroup::CreateDataSeries( Reference< XChartType > xChartType, sal_Int32 nApiAxesSetIdx ) const
2878 : : {
2879 : 6 : bool bSpline = false;
2880 [ + - ][ + + ]: 12 : for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end(); aIt != aEnd; ++aIt )
2881 : : {
2882 [ + - ]: 6 : Reference< XDataSeries > xDataSeries = (*aIt)->CreateDataSeries();
2883 [ + - ]: 6 : InsertDataSeries( xChartType, xDataSeries, nApiAxesSetIdx );
2884 [ + - ]: 6 : bSpline |= (*aIt)->HasSpline();
2885 : 6 : }
2886 : : // spline - TODO: set at single series (#i66858#)
2887 [ - + ][ # # ]: 6 : if( bSpline && !maTypeInfo.IsSeriesFrameFormat() && (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_RADAR) )
[ # # ][ - + ]
2888 : : {
2889 [ # # ]: 0 : ScfPropertySet aTypeProp( xChartType );
2890 [ # # ][ # # ]: 0 : aTypeProp.SetProperty( EXC_CHPROP_CURVESTYLE, ::com::sun::star::chart2::CurveStyle_CUBIC_SPLINES );
[ # # ]
2891 : : }
2892 : 6 : }
2893 : :
2894 : 0 : void XclImpChTypeGroup::CreateStockSeries( Reference< XChartType > xChartType, sal_Int32 nApiAxesSetIdx ) const
2895 : : {
2896 : : // create the data series object
2897 [ # # ][ # # ]: 0 : Reference< XDataSeries > xDataSeries( ScfApiHelper::CreateInstance( SERVICE_CHART2_DATASERIES ), UNO_QUERY );
[ # # ]
2898 [ # # ]: 0 : Reference< XDataSink > xDataSink( xDataSeries, UNO_QUERY );
2899 [ # # ]: 0 : if( xDataSink.is() )
2900 : : {
2901 : : // create a list of data sequences from all series
2902 [ # # ]: 0 : ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
2903 : : OSL_ENSURE( maSeries.size() >= 3, "XclImpChTypeGroup::CreateChartType - missing stock series" );
2904 [ # # ]: 0 : int nRoleIdx = (maSeries.size() == 3) ? 1 : 0;
2905 [ # # ][ # # ]: 0 : for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end();
[ # # ]
2906 [ # # ]: 0 : (nRoleIdx < 4) && (aIt != aEnd); ++nRoleIdx, ++aIt )
2907 : : {
2908 : : // create a data sequence with a specific role
2909 : 0 : OUString aRole;
2910 [ # # # # : 0 : switch( nRoleIdx )
# ]
2911 : : {
2912 [ # # ]: 0 : case 0: aRole = EXC_CHPROP_ROLE_OPENVALUES; break;
2913 [ # # ]: 0 : case 1: aRole = EXC_CHPROP_ROLE_HIGHVALUES; break;
2914 [ # # ]: 0 : case 2: aRole = EXC_CHPROP_ROLE_LOWVALUES; break;
2915 [ # # ]: 0 : case 3: aRole = EXC_CHPROP_ROLE_CLOSEVALUES; break;
2916 : : }
2917 [ # # ]: 0 : Reference< XLabeledDataSequence > xDataSeq = (*aIt)->CreateValueSequence( aRole );
2918 [ # # ]: 0 : if( xDataSeq.is() )
2919 [ # # ]: 0 : aLabeledSeqVec.push_back( xDataSeq );
2920 : 0 : }
2921 : :
2922 : : // attach labeled data sequences to series and insert series into chart type
2923 [ # # ][ # # ]: 0 : xDataSink->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec ) );
[ # # ][ # # ]
2924 : :
2925 : : // formatting of special stock chart elements
2926 [ # # ]: 0 : ScfPropertySet aTypeProp( xChartType );
2927 [ # # ][ # # ]: 0 : aTypeProp.SetBoolProperty( EXC_CHPROP_JAPANESE, HasDropBars() );
[ # # ]
2928 [ # # ][ # # ]: 0 : aTypeProp.SetBoolProperty( EXC_CHPROP_SHOWFIRST, HasDropBars() );
[ # # ]
2929 [ # # ][ # # ]: 0 : aTypeProp.SetBoolProperty( EXC_CHPROP_SHOWHIGHLOW, true );
2930 : : // hi-lo line format
2931 [ # # ]: 0 : XclImpChLineFormatMap::const_iterator xHiLoLine = maChartLines.find( EXC_CHCHARTLINE_HILO );
2932 [ # # ][ # # ]: 0 : if ( xHiLoLine != maChartLines.end() )
[ # # ]
2933 : : {
2934 [ # # ]: 0 : ScfPropertySet aSeriesProp( xDataSeries );
2935 [ # # ][ # # ]: 0 : xHiLoLine->second->Convert( GetChRoot(), aSeriesProp, EXC_CHOBJTYPE_HILOLINE );
[ # # ]
2936 : : }
2937 : : // white dropbar format
2938 [ # # ]: 0 : XclImpChDropBarMap::const_iterator itr = maDropBars.find(EXC_CHDROPBAR_UP);
2939 : 0 : Reference<XPropertySet> xWhitePropSet;
2940 [ # # ][ # # ]: 0 : if (itr != maDropBars.end() && aTypeProp.GetProperty(xWhitePropSet, EXC_CHPROP_WHITEDAY))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
[ # # ]
2941 : : {
2942 [ # # ]: 0 : ScfPropertySet aBarProp( xWhitePropSet );
2943 [ # # ][ # # ]: 0 : itr->second->Convert(GetChRoot(), aBarProp);
[ # # ]
2944 : : }
2945 : : // black dropbar format
2946 [ # # ]: 0 : itr = maDropBars.find(EXC_CHDROPBAR_DOWN);
2947 : 0 : Reference<XPropertySet> xBlackPropSet;
2948 [ # # ][ # # ]: 0 : if (itr != maDropBars.end() && aTypeProp.GetProperty(xBlackPropSet, EXC_CHPROP_BLACKDAY))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
[ # # ]
2949 : : {
2950 [ # # ]: 0 : ScfPropertySet aBarProp( xBlackPropSet );
2951 [ # # ][ # # ]: 0 : itr->second->Convert(GetChRoot(), aBarProp);
[ # # ]
2952 : : }
2953 : :
2954 : : // insert the series into the chart type object
2955 [ # # ][ # # ]: 0 : InsertDataSeries( xChartType, xDataSeries, nApiAxesSetIdx );
2956 : 0 : }
2957 : 0 : }
2958 : :
2959 : : // Axes =======================================================================
2960 : :
2961 : 12 : XclImpChLabelRange::XclImpChLabelRange( const XclImpChRoot& rRoot ) :
2962 [ + - ][ + - ]: 12 : XclImpChRoot( rRoot )
2963 : : {
2964 : 12 : }
2965 : :
2966 : 6 : void XclImpChLabelRange::ReadChLabelRange( XclImpStream& rStrm )
2967 : : {
2968 : 6 : rStrm >> maLabelData.mnCross >> maLabelData.mnLabelFreq >> maLabelData.mnTickFreq >> maLabelData.mnFlags;
2969 : 6 : }
2970 : :
2971 : 6 : void XclImpChLabelRange::ReadChDateRange( XclImpStream& rStrm )
2972 : : {
2973 : 6 : rStrm >> maDateData.mnMinDate
2974 : 6 : >> maDateData.mnMaxDate
2975 : 6 : >> maDateData.mnMajorStep
2976 : 6 : >> maDateData.mnMajorUnit
2977 : 6 : >> maDateData.mnMinorStep
2978 : 6 : >> maDateData.mnMinorUnit
2979 : 6 : >> maDateData.mnBaseUnit
2980 : 6 : >> maDateData.mnCross
2981 : 6 : >> maDateData.mnFlags;
2982 : 6 : }
2983 : :
2984 : 6 : void XclImpChLabelRange::Convert( ScfPropertySet& rPropSet, ScaleData& rScaleData, bool bMirrorOrient ) const
2985 : : {
2986 : : // automatic axis type detection
2987 : 6 : rScaleData.AutoDateAxis = ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTODATE );
2988 : :
2989 : : // the flag EXC_CHDATERANGE_DATEAXIS specifies whether this is a date axis
2990 [ - + ]: 6 : if( ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_DATEAXIS ) )
2991 : : {
2992 : : /* Chart2 requires axis type CATEGORY for automatic category/date axis
2993 : : (even if it is a date axis currently). */
2994 [ # # ]: 0 : rScaleData.AxisType = rScaleData.AutoDateAxis ? cssc2::AxisType::CATEGORY : cssc2::AxisType::DATE;
2995 [ # # ][ # # ]: 0 : rScaleData.Scaling.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_LINEARSCALING ), UNO_QUERY );
2996 : : /* Min/max values depend on base time unit, they specify the number of
2997 : : days, months, or years starting from null date. */
2998 : 0 : lclConvertTimeValue( GetRoot(), rScaleData.Minimum, maDateData.mnMinDate, ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMIN ), maDateData.mnBaseUnit );
2999 : 0 : lclConvertTimeValue( GetRoot(), rScaleData.Maximum, maDateData.mnMaxDate, ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMAX ), maDateData.mnBaseUnit );
3000 : : // increment
3001 : 0 : cssc::TimeIncrement& rTimeIncrement = rScaleData.TimeIncrement;
3002 : 0 : lclConvertTimeInterval( rTimeIncrement.MajorTimeInterval, maDateData.mnMajorStep, ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMAJOR ), maDateData.mnMajorUnit );
3003 : 0 : lclConvertTimeInterval( rTimeIncrement.MinorTimeInterval, maDateData.mnMinorStep, ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMINOR ), maDateData.mnMinorUnit );
3004 : : // base unit
3005 [ # # ]: 0 : if( ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOBASE ) )
3006 : 0 : rTimeIncrement.TimeResolution.clear();
3007 : : else
3008 [ # # ]: 0 : rTimeIncrement.TimeResolution <<= lclGetApiTimeUnit( maDateData.mnBaseUnit );
3009 : : }
3010 : : else
3011 : : {
3012 : : // do not overlap text unless all labels are visible
3013 [ + - ]: 6 : rPropSet.SetBoolProperty( EXC_CHPROP_TEXTOVERLAP, maLabelData.mnLabelFreq == 1 );
3014 : : // do not break text into several lines unless all labels are visible
3015 [ + - ]: 6 : rPropSet.SetBoolProperty( EXC_CHPROP_TEXTBREAK, maLabelData.mnLabelFreq == 1 );
3016 : : // do not stagger labels in two lines
3017 [ + - ][ + - ]: 6 : rPropSet.SetProperty( EXC_CHPROP_ARRANGEORDER, cssc::ChartAxisArrangeOrderType_SIDE_BY_SIDE );
3018 : : }
3019 : :
3020 : : // reverse order
3021 : 6 : bool bReverse = ::get_flag( maLabelData.mnFlags, EXC_CHLABELRANGE_REVERSE ) != bMirrorOrient;
3022 [ - + ]: 6 : rScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL;
3023 : :
3024 : : //! TODO #i58731# show n-th category
3025 : 6 : }
3026 : :
3027 : 6 : void XclImpChLabelRange::ConvertAxisPosition( ScfPropertySet& rPropSet, bool b3dChart ) const
3028 : : {
3029 : : /* Crossing mode (max-cross flag overrides other crossing settings). Excel
3030 : : does not move the Y axis in 3D charts, regardless of actual settings.
3031 : : But: the Y axis has to be moved to "end", if the X axis is mirrored,
3032 : : to keep it at the left end of the chart. */
3033 [ - + ]: 6 : bool bMaxCross = ::get_flag( maLabelData.mnFlags, b3dChart ? EXC_CHLABELRANGE_REVERSE : EXC_CHLABELRANGE_MAXCROSS );
3034 [ - + ]: 6 : cssc::ChartAxisPosition eAxisPos = bMaxCross ? cssc::ChartAxisPosition_END : cssc::ChartAxisPosition_VALUE;
3035 [ + - ][ + - ]: 6 : rPropSet.SetProperty( EXC_CHPROP_CROSSOVERPOSITION, eAxisPos );
3036 : :
3037 : : // crossing position (depending on axis type text/date)
3038 [ - + ]: 6 : if( ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_DATEAXIS ) )
3039 : : {
3040 : 0 : bool bAutoCross = ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOCROSS );
3041 : : /* Crossing position value depends on base time unit, it specifies the
3042 : : number of days, months, or years from null date. Note that Excel
3043 : : 2007/2010 write broken BIFF8 files, they always stores the number
3044 : : of days cregardless of the base time unit (and they are reading it
3045 : : the same way, thus wrongly displaying files written by Excel
3046 : : 97-2003). This filter sticks to the correct behaviour of Excel
3047 : : 97-2003. */
3048 [ # # ][ # # ]: 0 : double fCrossingPos = bAutoCross ? 1.0 : lclGetSerialDay( GetRoot(), maDateData.mnCross, maDateData.mnBaseUnit );
3049 [ # # ][ # # ]: 0 : rPropSet.SetProperty( EXC_CHPROP_CROSSOVERVALUE, fCrossingPos );
3050 : : }
3051 : : else
3052 : : {
3053 [ - + ]: 6 : double fCrossingPos = b3dChart ? 1.0 : maLabelData.mnCross;
3054 [ + - ][ + - ]: 6 : rPropSet.SetProperty( EXC_CHPROP_CROSSOVERVALUE, fCrossingPos );
3055 : : }
3056 : 6 : }
3057 : :
3058 : : // ----------------------------------------------------------------------------
3059 : :
3060 : 12 : XclImpChValueRange::XclImpChValueRange( const XclImpChRoot& rRoot ) :
3061 [ + - ]: 12 : XclImpChRoot( rRoot )
3062 : : {
3063 : 12 : }
3064 : :
3065 : 6 : void XclImpChValueRange::ReadChValueRange( XclImpStream& rStrm )
3066 : : {
3067 : 6 : rStrm >> maData.mfMin
3068 : 6 : >> maData.mfMax
3069 : 6 : >> maData.mfMajorStep
3070 : 6 : >> maData.mfMinorStep
3071 : 6 : >> maData.mfCross
3072 : 6 : >> maData.mnFlags;
3073 : 6 : }
3074 : :
3075 : 6 : void XclImpChValueRange::Convert( ScaleData& rScaleData, bool bMirrorOrient ) const
3076 : : {
3077 : : // scaling algorithm
3078 : 6 : bool bLogScale = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE );
3079 [ # # ][ + - ]: 6 : OUString aScalingService = bLogScale ? SERVICE_CHART2_LOGSCALING : SERVICE_CHART2_LINEARSCALING;
[ - + ]
3080 [ + - ][ + - ]: 6 : rScaleData.Scaling.set( ScfApiHelper::CreateInstance( aScalingService ), UNO_QUERY );
3081 : :
3082 : : // min/max
3083 [ + - ]: 6 : lclSetExpValueOrClearAny( rScaleData.Minimum, maData.mfMin, bLogScale, ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMIN ) );
3084 [ + - ]: 6 : lclSetExpValueOrClearAny( rScaleData.Maximum, maData.mfMax, bLogScale, ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAX ) );
3085 : :
3086 : : // increment
3087 : 6 : bool bAutoMajor = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAJOR );
3088 : 6 : bool bAutoMinor = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMINOR );
3089 : : // major increment
3090 : 6 : IncrementData& rIncrementData = rScaleData.IncrementData;
3091 [ + - ]: 6 : lclSetValueOrClearAny( rIncrementData.Distance, maData.mfMajorStep, bAutoMajor );
3092 : : // minor increment
3093 : 6 : Sequence< SubIncrement >& rSubIncrementSeq = rIncrementData.SubIncrements;
3094 [ + - ]: 6 : rSubIncrementSeq.realloc( 1 );
3095 [ + - ]: 6 : Any& rIntervalCount = rSubIncrementSeq[ 0 ].IntervalCount;
3096 : 6 : rIntervalCount.clear();
3097 [ - + ]: 6 : if( bLogScale )
3098 : : {
3099 [ # # ]: 0 : if( !bAutoMinor )
3100 [ # # ]: 0 : rIntervalCount <<= sal_Int32( 9 );
3101 : : }
3102 : : else
3103 : : {
3104 [ - + ][ # # ]: 6 : if( !bAutoMajor && !bAutoMinor && (0.0 < maData.mfMinorStep) && (maData.mfMinorStep <= maData.mfMajorStep) )
[ # # ][ # # ]
3105 : : {
3106 : 0 : double fCount = maData.mfMajorStep / maData.mfMinorStep + 0.5;
3107 [ # # ][ # # ]: 0 : if( (1.0 <= fCount) && (fCount < 1001.0) )
3108 [ # # ]: 0 : rIntervalCount <<= static_cast< sal_Int32 >( fCount );
3109 : : }
3110 : : }
3111 : :
3112 : : // reverse order
3113 : 6 : bool bReverse = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE ) != bMirrorOrient;
3114 [ - + ]: 6 : rScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL;
3115 : 6 : }
3116 : :
3117 : 6 : void XclImpChValueRange::ConvertAxisPosition( ScfPropertySet& rPropSet ) const
3118 : : {
3119 : 6 : bool bMaxCross = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_MAXCROSS );
3120 : 6 : bool bAutoCross = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS );
3121 : 6 : bool bLogScale = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE );
3122 : :
3123 : : // crossing mode (max-cross flag overrides other crossing settings)
3124 [ - + ]: 6 : cssc::ChartAxisPosition eAxisPos = bMaxCross ? cssc::ChartAxisPosition_END : cssc::ChartAxisPosition_VALUE;
3125 [ + - ][ + - ]: 6 : rPropSet.SetProperty( EXC_CHPROP_CROSSOVERPOSITION, eAxisPos );
3126 : :
3127 : : // crossing position
3128 [ + - ]: 6 : double fCrossingPos = bAutoCross ? 0.0 : maData.mfCross;
3129 [ - + ]: 6 : if( bLogScale ) fCrossingPos = pow( 10.0, fCrossingPos );
3130 [ + - ][ + - ]: 6 : rPropSet.SetProperty( EXC_CHPROP_CROSSOVERVALUE, fCrossingPos );
3131 : 6 : }
3132 : :
3133 : : // ----------------------------------------------------------------------------
3134 : :
3135 : : namespace {
3136 : :
3137 : 24 : sal_Int32 lclGetApiTickmarks( sal_uInt8 nXclTickPos )
3138 : : {
3139 : : using namespace ::com::sun::star::chart2::TickmarkStyle;
3140 : 24 : sal_Int32 nApiTickmarks = NONE;
3141 : 24 : ::set_flag( nApiTickmarks, INNER, ::get_flag( nXclTickPos, EXC_CHTICK_INSIDE ) );
3142 : 24 : ::set_flag( nApiTickmarks, OUTER, ::get_flag( nXclTickPos, EXC_CHTICK_OUTSIDE ) );
3143 : 24 : return nApiTickmarks;
3144 : : }
3145 : :
3146 : 12 : cssc::ChartAxisLabelPosition lclGetApiLabelPosition( sal_Int8 nXclLabelPos )
3147 : : {
3148 : : using namespace ::com::sun::star::chart;
3149 [ - - + - ]: 12 : switch( nXclLabelPos )
3150 : : {
3151 : 0 : case EXC_CHTICK_LOW: return ChartAxisLabelPosition_OUTSIDE_START;
3152 : 0 : case EXC_CHTICK_HIGH: return ChartAxisLabelPosition_OUTSIDE_END;
3153 : 12 : case EXC_CHTICK_NEXT: return ChartAxisLabelPosition_NEAR_AXIS;
3154 : : }
3155 : 12 : return ChartAxisLabelPosition_NEAR_AXIS;
3156 : : }
3157 : :
3158 : : } // namespace
3159 : :
3160 : 12 : XclImpChTick::XclImpChTick( const XclImpChRoot& rRoot ) :
3161 [ + - ]: 12 : XclImpChRoot( rRoot )
3162 : : {
3163 : 12 : }
3164 : :
3165 : 12 : void XclImpChTick::ReadChTick( XclImpStream& rStrm )
3166 : : {
3167 : 12 : rStrm >> maData.mnMajor
3168 : 12 : >> maData.mnMinor
3169 : 12 : >> maData.mnLabelPos
3170 : 12 : >> maData.mnBackMode;
3171 : 12 : rStrm.Ignore( 16 );
3172 : 12 : rStrm >> maData.maTextColor
3173 : 12 : >> maData.mnFlags;
3174 : :
3175 [ + - ]: 12 : if( GetBiff() == EXC_BIFF8 )
3176 : : {
3177 : : // BIFF8: index into palette used instead of RGB data
3178 : 12 : maData.maTextColor = GetPalette().GetColor( rStrm.ReaduInt16() );
3179 : : // rotation
3180 : 12 : rStrm >> maData.mnRotation;
3181 : : }
3182 : : else
3183 : : {
3184 : : // BIFF2-BIFF7: get rotation from text orientation
3185 : 0 : sal_uInt8 nOrient = ::extract_value< sal_uInt8 >( maData.mnFlags, 2, 3 );
3186 : 0 : maData.mnRotation = XclTools::GetXclRotFromOrient( nOrient );
3187 : : }
3188 : 12 : }
3189 : :
3190 : 6 : Color XclImpChTick::GetFontColor() const
3191 : : {
3192 [ + - ]: 6 : return ::get_flag( maData.mnFlags, EXC_CHTICK_AUTOCOLOR ) ? GetFontAutoColor() : maData.maTextColor;
3193 : : }
3194 : :
3195 : 12 : sal_uInt16 XclImpChTick::GetRotation() const
3196 : : {
3197 : : /* n#720443: Ignore auto-rotation if there is a suggested rotation.
3198 : : * Better fix would be to improve our axis auto rotation algorithm.
3199 : : */
3200 [ + + ]: 12 : if( maData.mnRotation != EXC_ROT_NONE )
3201 : 6 : return maData.mnRotation;
3202 [ + - ]: 12 : return ::get_flag( maData.mnFlags, EXC_CHTICK_AUTOROT ) ? EXC_CHART_AUTOROTATION : maData.mnRotation;
3203 : : }
3204 : :
3205 : 12 : void XclImpChTick::Convert( ScfPropertySet& rPropSet ) const
3206 : : {
3207 [ + - ][ + - ]: 12 : rPropSet.SetProperty( EXC_CHPROP_MAJORTICKS, lclGetApiTickmarks( maData.mnMajor ) );
3208 [ + - ][ + - ]: 12 : rPropSet.SetProperty( EXC_CHPROP_MINORTICKS, lclGetApiTickmarks( maData.mnMinor ) );
3209 [ + - ][ + - ]: 12 : rPropSet.SetProperty( EXC_CHPROP_LABELPOSITION, lclGetApiLabelPosition( maData.mnLabelPos ) );
3210 [ + - ][ + - ]: 12 : rPropSet.SetProperty( EXC_CHPROP_MARKPOSITION, cssc::ChartAxisMarkPosition_AT_AXIS );
3211 : 12 : }
3212 : :
3213 : : // ----------------------------------------------------------------------------
3214 : :
3215 : 12 : XclImpChAxis::XclImpChAxis( const XclImpChRoot& rRoot, sal_uInt16 nAxisType ) :
3216 : : XclImpChRoot( rRoot ),
3217 [ + - ][ + - ]: 12 : mnNumFmtIdx( EXC_FORMAT_NOTFOUND )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
3218 : : {
3219 : 12 : maData.mnType = nAxisType;
3220 : 12 : }
3221 : :
3222 : 12 : void XclImpChAxis::ReadHeaderRecord( XclImpStream& rStrm )
3223 : : {
3224 : 12 : rStrm >> maData.mnType;
3225 : 12 : }
3226 : :
3227 : 66 : void XclImpChAxis::ReadSubRecord( XclImpStream& rStrm )
3228 : : {
3229 [ + + + - : 66 : switch( rStrm.GetRecId() )
+ + + + ]
3230 : : {
3231 : : case EXC_ID_CHLABELRANGE:
3232 [ + - ]: 6 : mxLabelRange.reset( new XclImpChLabelRange( GetChRoot() ) );
3233 : 6 : mxLabelRange->ReadChLabelRange( rStrm );
3234 : 6 : break;
3235 : : case EXC_ID_CHDATERANGE:
3236 [ - + ]: 6 : if( !mxLabelRange )
3237 [ # # ]: 0 : mxLabelRange.reset( new XclImpChLabelRange( GetChRoot() ) );
3238 : 6 : mxLabelRange->ReadChDateRange( rStrm );
3239 : 6 : break;
3240 : : case EXC_ID_CHVALUERANGE:
3241 [ + - ]: 6 : mxValueRange.reset( new XclImpChValueRange( GetChRoot() ) );
3242 : 6 : mxValueRange->ReadChValueRange( rStrm );
3243 : 6 : break;
3244 : : case EXC_ID_CHFORMAT:
3245 : 0 : rStrm >> mnNumFmtIdx;
3246 : 0 : break;
3247 : : case EXC_ID_CHTICK:
3248 [ + - ]: 12 : mxTick.reset( new XclImpChTick( GetChRoot() ) );
3249 : 12 : mxTick->ReadChTick( rStrm );
3250 : 12 : break;
3251 : : case EXC_ID_CHFONT:
3252 : 6 : mxFont.reset( new XclImpChFont );
3253 : 6 : mxFont->ReadChFont( rStrm );
3254 : 6 : break;
3255 : : case EXC_ID_CHAXISLINE:
3256 : 6 : ReadChAxisLine( rStrm );
3257 : 6 : break;
3258 : : }
3259 : 66 : }
3260 : :
3261 : 12 : void XclImpChAxis::Finalize()
3262 : : {
3263 : : // add default scaling, needed e.g. to adjust rotation direction of pie and radar charts
3264 [ + + ]: 12 : if( !mxLabelRange )
3265 [ + - ]: 6 : mxLabelRange.reset( new XclImpChLabelRange( GetChRoot() ) );
3266 [ + + ]: 12 : if( !mxValueRange )
3267 [ + - ]: 6 : mxValueRange.reset( new XclImpChValueRange( GetChRoot() ) );
3268 : : // remove invisible grid lines completely
3269 [ + + ][ - + ]: 12 : if( mxMajorGrid && !mxMajorGrid->HasLine() )
[ - + ]
3270 : 0 : mxMajorGrid.reset();
3271 [ - + ][ # # ]: 12 : if( mxMinorGrid && !mxMinorGrid->HasLine() )
[ - + ]
3272 : 0 : mxMinorGrid.reset();
3273 : : // default tick settings different in OOChart and Excel
3274 [ - + ]: 12 : if( !mxTick )
3275 [ # # ]: 0 : mxTick.reset( new XclImpChTick( GetChRoot() ) );
3276 : : // #i4140# different default axis line color
3277 [ + - ]: 12 : if( !mxAxisLine )
3278 : : {
3279 [ + - ]: 12 : XclChLineFormat aLineFmt;
3280 : : // set "show axis" flag, default if line format record is missing
3281 : 12 : ::set_flag( aLineFmt.mnFlags, EXC_CHLINEFORMAT_SHOWAXIS );
3282 [ + - ][ + - ]: 12 : mxAxisLine.reset( new XclImpChLineFormat( aLineFmt ) );
3283 : : }
3284 : : // add wall/floor frame for 3d charts
3285 [ + - ]: 12 : if( !mxWallFrame )
3286 : 12 : CreateWallFrame();
3287 : 12 : }
3288 : :
3289 : 6 : sal_uInt16 XclImpChAxis::GetFontIndex() const
3290 : : {
3291 [ + - ]: 6 : return mxFont ? mxFont->GetFontIndex() : EXC_FONT_NOTFOUND;
3292 : : }
3293 : :
3294 : 6 : Color XclImpChAxis::GetFontColor() const
3295 : : {
3296 [ + - ]: 6 : return mxTick ? mxTick->GetFontColor() : GetFontAutoColor();
3297 : : }
3298 : :
3299 : 12 : sal_uInt16 XclImpChAxis::GetRotation() const
3300 : : {
3301 [ + - ]: 12 : return mxTick ? mxTick->GetRotation() : EXC_CHART_AUTOROTATION;
3302 : : }
3303 : :
3304 : 12 : Reference< XAxis > XclImpChAxis::CreateAxis( const XclImpChTypeGroup& rTypeGroup, const XclImpChAxis* pCrossingAxis ) const
3305 : : {
3306 : : // create the axis object (always)
3307 [ + - ][ + - ]: 12 : Reference< XAxis > xAxis( ScfApiHelper::CreateInstance( SERVICE_CHART2_AXIS ), UNO_QUERY );
3308 [ + - ]: 12 : if( xAxis.is() )
3309 : : {
3310 [ + - ]: 12 : ScfPropertySet aAxisProp( xAxis );
3311 : : // #i58688# axis enabled
3312 [ + - ][ + - ]: 12 : aAxisProp.SetBoolProperty( EXC_CHPROP_SHOW, IsActivated() );
[ + - ]
3313 : :
3314 : : // axis line properties
3315 [ + - ]: 12 : if( mxAxisLine )
3316 [ + - ]: 12 : mxAxisLine->Convert( GetChRoot(), aAxisProp, EXC_CHOBJTYPE_AXISLINE );
3317 : : // axis ticks properties
3318 [ + - ]: 12 : if( mxTick )
3319 [ + - ]: 12 : mxTick->Convert( aAxisProp );
3320 : :
3321 : : // axis caption text --------------------------------------------------
3322 : :
3323 : : // radar charts disable their category labels via chart type, not via axis
3324 [ + - ]: 12 : bool bHasLabels = HasLabels() &&
3325 [ + - ][ + + ]: 12 : ((GetAxisType() != EXC_CHAXIS_X) || rTypeGroup.HasCategoryLabels());
[ + - ][ + - ]
3326 [ + - ][ + - ]: 12 : aAxisProp.SetBoolProperty( EXC_CHPROP_DISPLAYLABELS, bHasLabels );
3327 [ + - ]: 12 : if( bHasLabels )
3328 : : {
3329 : : // font settings from CHFONT record or from default text
3330 [ + + ]: 12 : if( mxFont )
3331 [ + - ]: 6 : ConvertFontBase( GetChRoot(), aAxisProp );
3332 [ + - ][ + - ]: 6 : else if( const XclImpChText* pDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_AXISLABEL ) )
[ + - ]
3333 [ + - ]: 6 : pDefText->ConvertFont( aAxisProp );
3334 : : // label text rotation
3335 [ + - ]: 12 : ConvertRotationBase( GetChRoot(), aAxisProp, true );
3336 : : // number format
3337 [ + - ][ + - ]: 12 : sal_uInt32 nScNumFmt = GetNumFmtBuffer().GetScFormat( mnNumFmtIdx );
3338 [ - + ]: 12 : if( nScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND )
3339 [ # # ][ # # ]: 0 : aAxisProp.SetProperty( EXC_CHPROP_NUMBERFORMAT, static_cast< sal_Int32 >( nScNumFmt ) );
3340 : : }
3341 : :
3342 : : // axis scaling and increment -----------------------------------------
3343 : :
3344 : 12 : const XclChExtTypeInfo& rTypeInfo = rTypeGroup.GetTypeInfo();
3345 [ + - ][ + - ]: 12 : ScaleData aScaleData = xAxis->getScaleData();
3346 : : // set axis type
3347 [ + + - - ]: 12 : switch( GetAxisType() )
3348 : : {
3349 : : case EXC_CHAXIS_X:
3350 [ + - ]: 6 : if( rTypeInfo.mbCategoryAxis )
3351 : : {
3352 : 6 : aScaleData.AxisType = cssc2::AxisType::CATEGORY;
3353 [ + - ][ + - ]: 6 : aScaleData.Categories = rTypeGroup.CreateCategSequence();
3354 : : }
3355 : : else
3356 : 0 : aScaleData.AxisType = cssc2::AxisType::REALNUMBER;
3357 : 6 : break;
3358 : : case EXC_CHAXIS_Y:
3359 [ + - ]: 6 : aScaleData.AxisType = rTypeGroup.IsPercent() ?
3360 [ - + ]: 6 : cssc2::AxisType::PERCENT : cssc2::AxisType::REALNUMBER;
3361 : 6 : break;
3362 : : case EXC_CHAXIS_Z:
3363 : 0 : aScaleData.AxisType = cssc2::AxisType::SERIES;
3364 : 0 : break;
3365 : : }
3366 : : // axis scaling settings, dependent on axis type
3367 [ + + - ]: 12 : switch( aScaleData.AxisType )
3368 : : {
3369 : : case cssc2::AxisType::CATEGORY:
3370 : : case cssc2::AxisType::SERIES:
3371 : : OSL_ENSURE( mxLabelRange, "Missing Label Range" );
3372 : : // #i71684# radar charts have reversed rotation direction
3373 [ + - ]: 6 : if (mxLabelRange)
3374 [ + - ]: 6 : mxLabelRange->Convert( aAxisProp, aScaleData, rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_RADAR );
3375 : 6 : break;
3376 : : case cssc2::AxisType::REALNUMBER:
3377 : : case cssc2::AxisType::PERCENT:
3378 : : // #i85167# pie/donut charts have reversed rotation direction (at Y axis!)
3379 [ + - ]: 6 : mxValueRange->Convert( aScaleData, rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE );
3380 : 6 : break;
3381 : : default:
3382 : : OSL_FAIL( "XclImpChAxis::CreateAxis - unknown axis type" );
3383 : : }
3384 : :
3385 : : /* Do not set a value to the Origin member anymore (will be done via
3386 : : new axis properties 'CrossoverPosition' and 'CrossoverValue'). */
3387 : 12 : aScaleData.Origin.clear();
3388 : :
3389 : : // write back
3390 [ + - ][ + - ]: 12 : xAxis->setScaleData( aScaleData );
3391 : :
3392 : : // grid ---------------------------------------------------------------
3393 : :
3394 : : // main grid
3395 [ + - ][ + - ]: 12 : ScfPropertySet aGridProp( xAxis->getGridProperties() );
[ + - ]
3396 [ + - ][ + - ]: 12 : aGridProp.SetBoolProperty( EXC_CHPROP_SHOW, HasMajorGrid() );
[ + - ]
3397 [ + + ]: 12 : if( mxMajorGrid )
3398 [ + - ]: 6 : mxMajorGrid->Convert( GetChRoot(), aGridProp, EXC_CHOBJTYPE_GRIDLINE );
3399 : : // sub grid
3400 [ + - ][ + - ]: 12 : Sequence< Reference< XPropertySet > > aSubGridPropSeq = xAxis->getSubGridProperties();
3401 [ + - ]: 12 : if( aSubGridPropSeq.hasElements() )
3402 : : {
3403 [ + - ][ + - ]: 12 : ScfPropertySet aSubGridProp( aSubGridPropSeq[ 0 ] );
3404 [ + - ][ + - ]: 12 : aSubGridProp.SetBoolProperty( EXC_CHPROP_SHOW, HasMinorGrid() );
[ + - ]
3405 [ - + ]: 12 : if( mxMinorGrid )
3406 [ # # ][ + - ]: 12 : mxMinorGrid->Convert( GetChRoot(), aSubGridProp, EXC_CHOBJTYPE_GRIDLINE );
3407 : : }
3408 : :
3409 : : // position of crossing axis ------------------------------------------
3410 : :
3411 [ + - ]: 12 : if( pCrossingAxis )
3412 [ + - ][ + - ]: 12 : pCrossingAxis->ConvertAxisPosition( aAxisProp, rTypeGroup );
[ + - ][ + - ]
[ + - ]
3413 : : }
3414 : 12 : return xAxis;
3415 : : }
3416 : :
3417 : 0 : void XclImpChAxis::ConvertWall( ScfPropertySet& rPropSet ) const
3418 : : {
3419 : : // #i71810# walls and floor in 3D charts use the CHPICFORMAT record for bitmap mode
3420 [ # # ]: 0 : if( mxWallFrame )
3421 : 0 : mxWallFrame->Convert( rPropSet, true );
3422 : 0 : }
3423 : :
3424 : 12 : void XclImpChAxis::ConvertAxisPosition( ScfPropertySet& rPropSet, const XclImpChTypeGroup& rTypeGroup ) const
3425 : : {
3426 [ + + ][ - + ]: 12 : if( ((GetAxisType() == EXC_CHAXIS_X) && rTypeGroup.GetTypeInfo().mbCategoryAxis) || (GetAxisType() == EXC_CHAXIS_Z) )
[ - + ][ + + ]
3427 : : {
3428 : : OSL_ENSURE( mxLabelRange, "Missing Label Range" );
3429 [ + - ]: 6 : if (mxLabelRange)
3430 : 6 : mxLabelRange->ConvertAxisPosition( rPropSet, rTypeGroup.Is3dChart() );
3431 : : }
3432 : : else
3433 : 6 : mxValueRange->ConvertAxisPosition( rPropSet );
3434 : 12 : }
3435 : :
3436 : 6 : void XclImpChAxis::ReadChAxisLine( XclImpStream& rStrm )
3437 : : {
3438 : 6 : XclImpChLineFormatRef* pxLineFmt = 0;
3439 : 6 : bool bWallFrame = false;
3440 [ - + - - : 6 : switch( rStrm.ReaduInt16() )
- ]
3441 : : {
3442 : 0 : case EXC_CHAXISLINE_AXISLINE: pxLineFmt = &mxAxisLine; break;
3443 : 6 : case EXC_CHAXISLINE_MAJORGRID: pxLineFmt = &mxMajorGrid; break;
3444 : 0 : case EXC_CHAXISLINE_MINORGRID: pxLineFmt = &mxMinorGrid; break;
3445 : 0 : case EXC_CHAXISLINE_WALLS: bWallFrame = true; break;
3446 : : }
3447 [ - + ]: 6 : if( bWallFrame )
3448 : 0 : CreateWallFrame();
3449 : :
3450 [ - + ][ # # ]: 6 : bool bLoop = pxLineFmt || bWallFrame;
3451 [ + + ]: 18 : while( bLoop )
3452 : : {
3453 : 12 : sal_uInt16 nRecId = rStrm.GetNextRecId();
3454 : : bLoop = ((nRecId == EXC_ID_CHLINEFORMAT) ||
3455 : : (nRecId == EXC_ID_CHAREAFORMAT) ||
3456 : : (nRecId == EXC_ID_CHESCHERFORMAT))
3457 [ + - ][ - + ]: 12 : && rStrm.StartNextRecord();
[ + - ][ + + ]
3458 [ + + ]: 12 : if( bLoop )
3459 : : {
3460 [ + - ][ + - ]: 6 : if( pxLineFmt && (nRecId == EXC_ID_CHLINEFORMAT) )
3461 : : {
3462 [ + - ]: 6 : pxLineFmt->reset( new XclImpChLineFormat );
3463 : 6 : (*pxLineFmt)->ReadChLineFormat( rStrm );
3464 : : }
3465 [ # # ][ # # ]: 0 : else if( bWallFrame && mxWallFrame )
[ # # ]
3466 : : {
3467 : 6 : mxWallFrame->ReadSubRecord( rStrm );
3468 : : }
3469 : : }
3470 : : }
3471 : 6 : }
3472 : :
3473 : 12 : void XclImpChAxis::CreateWallFrame()
3474 : : {
3475 [ + + - ]: 12 : switch( GetAxisType() )
3476 : : {
3477 : : case EXC_CHAXIS_X:
3478 [ + - ]: 6 : mxWallFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_WALL3D ) );
3479 : 6 : break;
3480 : : case EXC_CHAXIS_Y:
3481 [ + - ]: 6 : mxWallFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_FLOOR3D ) );
3482 : 6 : break;
3483 : : default:
3484 : 0 : mxWallFrame.reset();
3485 : : }
3486 : 12 : }
3487 : :
3488 : : // ----------------------------------------------------------------------------
3489 : :
3490 : 18 : XclImpChAxesSet::XclImpChAxesSet( const XclImpChRoot& rRoot, sal_uInt16 nAxesSetId ) :
3491 [ + - ][ + - ]: 18 : XclImpChRoot( rRoot )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
3492 : : {
3493 : 18 : maData.mnAxesSetId = nAxesSetId;
3494 : 18 : }
3495 : :
3496 : 6 : void XclImpChAxesSet::ReadHeaderRecord( XclImpStream& rStrm )
3497 : : {
3498 : 6 : rStrm >> maData.mnAxesSetId >> maData.maRect;
3499 : 6 : }
3500 : :
3501 : 42 : void XclImpChAxesSet::ReadSubRecord( XclImpStream& rStrm )
3502 : : {
3503 [ + + - + : 42 : switch( rStrm.GetRecId() )
+ + ]
3504 : : {
3505 : : case EXC_ID_CHFRAMEPOS:
3506 [ + - ]: 6 : mxFramePos.reset( new XclImpChFramePos );
3507 : 6 : mxFramePos->ReadChFramePos( rStrm );
3508 : 6 : break;
3509 : : case EXC_ID_CHAXIS:
3510 : 12 : ReadChAxis( rStrm );
3511 : 12 : break;
3512 : : case EXC_ID_CHTEXT:
3513 : 0 : ReadChText( rStrm );
3514 : 0 : break;
3515 : : case EXC_ID_CHPLOTFRAME:
3516 : 6 : ReadChPlotFrame( rStrm );
3517 : 6 : break;
3518 : : case EXC_ID_CHTYPEGROUP:
3519 : 6 : ReadChTypeGroup( rStrm );
3520 : 6 : break;
3521 : : }
3522 : 42 : }
3523 : :
3524 : 12 : void XclImpChAxesSet::Finalize()
3525 : : {
3526 [ + + ]: 12 : if( IsValidAxesSet() )
3527 : : {
3528 : : // finalize chart type groups, erase empty groups without series
3529 [ + - ]: 6 : XclImpChTypeGroupMap aValidGroups;
3530 [ + + ]: 12 : for( XclImpChTypeGroupMap::const_iterator aIt = maTypeGroups.begin(), aEnd = maTypeGroups.end(); aIt != aEnd; ++aIt )
3531 : : {
3532 [ + - ]: 6 : XclImpChTypeGroupRef xTypeGroup = aIt->second;
3533 [ + - ]: 6 : xTypeGroup->Finalize();
3534 [ + - ]: 6 : if( xTypeGroup->IsValidGroup() )
3535 : : aValidGroups.insert(
3536 [ + - ][ + - ]: 6 : XclImpChTypeGroupMap::value_type(aIt->first, xTypeGroup));
[ + - ]
3537 [ + - ]: 6 : }
3538 [ + - ]: 6 : maTypeGroups.swap( aValidGroups );
3539 : : }
3540 : :
3541 : : // invalid chart type groups are deleted now, check again with IsValidAxesSet()
3542 [ + + ]: 12 : if( IsValidAxesSet() )
3543 : : {
3544 : : // always create missing axis objects
3545 [ - + ]: 6 : if( !mxXAxis )
3546 [ # # ][ # # ]: 0 : mxXAxis.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_X ) );
[ # # ]
3547 [ - + ]: 6 : if( !mxYAxis )
3548 [ # # ][ # # ]: 0 : mxYAxis.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_Y ) );
[ # # ]
3549 [ + - ][ + - ]: 6 : if( !mxZAxis && GetFirstTypeGroup()->Is3dDeepChart() )
[ + - ][ - + ]
[ + - ][ + - ]
[ - + # # ]
3550 [ # # ][ # # ]: 0 : mxZAxis.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_Z ) );
[ # # ]
3551 : :
3552 : : // finalize axes
3553 [ + - ][ + - ]: 6 : if( mxXAxis ) mxXAxis->Finalize();
3554 [ + - ][ + - ]: 6 : if( mxYAxis ) mxYAxis->Finalize();
3555 [ - + ][ # # ]: 6 : if( mxZAxis ) mxZAxis->Finalize();
3556 : :
3557 : : // finalize axis titles
3558 [ + - ][ + - ]: 6 : const XclImpChText* pDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_AXISTITLE );
3559 [ + - ]: 6 : String aAutoTitle = CREATE_STRING( "Axis Title" );
3560 [ + - ]: 6 : lclFinalizeTitle( mxXAxisTitle, pDefText, aAutoTitle );
3561 [ + - ]: 6 : lclFinalizeTitle( mxYAxisTitle, pDefText, aAutoTitle );
3562 [ + - ]: 6 : lclFinalizeTitle( mxZAxisTitle, pDefText, aAutoTitle );
3563 : :
3564 : : // #i47745# missing plot frame -> invisible border and area
3565 [ - + ]: 6 : if( !mxPlotFrame )
3566 [ # # ][ # # ]: 6 : mxPlotFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_PLOTFRAME ) );
[ # # ][ + - ]
3567 : : }
3568 : 12 : }
3569 : :
3570 : 24 : XclImpChTypeGroupRef XclImpChAxesSet::GetTypeGroup( sal_uInt16 nGroupIdx ) const
3571 : : {
3572 [ + - ]: 24 : XclImpChTypeGroupMap::const_iterator itr = maTypeGroups.find(nGroupIdx);
3573 [ - + ][ # # ]: 24 : return itr == maTypeGroups.end() ? XclImpChTypeGroupRef() : itr->second;
[ + - ]
3574 : : }
3575 : :
3576 : 33 : XclImpChTypeGroupRef XclImpChAxesSet::GetFirstTypeGroup() const
3577 : : {
3578 : 33 : XclImpChTypeGroupRef xTypeGroup;
3579 [ + - ]: 33 : if( !maTypeGroups.empty() )
3580 [ + - ]: 33 : xTypeGroup = maTypeGroups.begin()->second;
3581 : 33 : return xTypeGroup;
3582 : : }
3583 : :
3584 : 6 : XclImpChLegendRef XclImpChAxesSet::GetLegend() const
3585 : : {
3586 : 6 : XclImpChLegendRef xLegend;
3587 [ + + ][ + - ]: 12 : for( XclImpChTypeGroupMap::const_iterator aIt = maTypeGroups.begin(), aEnd = maTypeGroups.end(); !xLegend && (aIt != aEnd); ++aIt )
[ + + ]
3588 [ + - ][ + - ]: 6 : xLegend = aIt->second->GetLegend();
[ + - ]
3589 : 6 : return xLegend;
3590 : : }
3591 : :
3592 : 0 : const String& XclImpChAxesSet::GetSingleSeriesTitle() const
3593 : : {
3594 [ # # ][ # # ]: 0 : return (maTypeGroups.size() == 1) ? maTypeGroups.begin()->second->GetSingleSeriesTitle() : String::EmptyString();
[ # # ][ # # ]
[ # # ]
3595 : : }
3596 : :
3597 : 12 : void XclImpChAxesSet::Convert( Reference< XDiagram > xDiagram ) const
3598 : : {
3599 [ + + ][ + - ]: 12 : if( IsValidAxesSet() && xDiagram.is() )
[ + + ]
3600 : : {
3601 : : // diagram background formatting
3602 [ + - ]: 6 : if( GetAxesSetId() == EXC_CHAXESSET_PRIMARY )
3603 [ + - ]: 6 : ConvertBackground( xDiagram );
3604 : :
3605 : : // create the coordinate system, this inserts all chart types and series
3606 [ + - ]: 6 : Reference< XCoordinateSystem > xCoordSystem = CreateCoordSystem( xDiagram );
3607 [ + - ]: 6 : if( xCoordSystem.is() )
3608 : : {
3609 : : // insert coordinate system, if not already done
3610 : : try
3611 : : {
3612 [ + - ]: 6 : Reference< XCoordinateSystemContainer > xCoordSystemCont( xDiagram, UNO_QUERY_THROW );
3613 [ + - ][ + - ]: 6 : Sequence< Reference< XCoordinateSystem > > aCoordSystems = xCoordSystemCont->getCoordinateSystems();
3614 [ + - ]: 6 : if( aCoordSystems.getLength() == 0 )
3615 [ + - ][ + - ]: 6 : xCoordSystemCont->addCoordinateSystem( xCoordSystem );
[ + - ][ # # ]
3616 : : }
3617 [ # # ]: 0 : catch( Exception& )
3618 : : {
3619 : : OSL_FAIL( "XclImpChAxesSet::Convert - cannot insert coordinate system" );
3620 : : }
3621 : :
3622 : : // create the axes with grids and axis titles and insert them into the diagram
3623 [ + - ][ + - ]: 6 : ConvertAxis( mxXAxis, mxXAxisTitle, xCoordSystem, mxYAxis.get() );
[ + - ][ + - ]
[ + - ]
3624 [ + - ][ + - ]: 6 : ConvertAxis( mxYAxis, mxYAxisTitle, xCoordSystem, mxXAxis.get() );
[ + - ][ + - ]
[ + - ]
3625 [ + - ][ + - ]: 6 : ConvertAxis( mxZAxis, mxZAxisTitle, xCoordSystem, 0 );
[ + - ][ + - ]
[ + - ]
3626 : 6 : }
3627 : : }
3628 : 12 : }
3629 : :
3630 : 12 : void XclImpChAxesSet::ConvertTitlePositions() const
3631 : : {
3632 [ - + ]: 12 : if( mxXAxisTitle )
3633 [ # # ]: 0 : mxXAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_X ) );
3634 [ - + ]: 12 : if( mxYAxisTitle )
3635 [ # # ]: 0 : mxYAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_Y ) );
3636 [ - + ]: 12 : if( mxZAxisTitle )
3637 [ # # ]: 0 : mxZAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_Z ) );
3638 : 12 : }
3639 : :
3640 : 12 : void XclImpChAxesSet::ReadChAxis( XclImpStream& rStrm )
3641 : : {
3642 [ + - ][ + - ]: 12 : XclImpChAxisRef xAxis( new XclImpChAxis( GetChRoot() ) );
[ + - ]
3643 [ + - ]: 12 : xAxis->ReadRecordGroup( rStrm );
3644 : :
3645 [ + + - - ]: 12 : switch( xAxis->GetAxisType() )
3646 : : {
3647 [ + - ]: 6 : case EXC_CHAXIS_X: mxXAxis = xAxis; break;
3648 [ + - ]: 6 : case EXC_CHAXIS_Y: mxYAxis = xAxis; break;
3649 [ # # ]: 0 : case EXC_CHAXIS_Z: mxZAxis = xAxis; break;
3650 [ + - ]: 12 : }
3651 : 12 : }
3652 : :
3653 : 0 : void XclImpChAxesSet::ReadChText( XclImpStream& rStrm )
3654 : : {
3655 [ # # ][ # # ]: 0 : XclImpChTextRef xText( new XclImpChText( GetChRoot() ) );
[ # # ]
3656 [ # # ]: 0 : xText->ReadRecordGroup( rStrm );
3657 : :
3658 [ # # # # ]: 0 : switch( xText->GetLinkTarget() )
3659 : : {
3660 [ # # ]: 0 : case EXC_CHOBJLINK_XAXIS: mxXAxisTitle = xText; break;
3661 [ # # ]: 0 : case EXC_CHOBJLINK_YAXIS: mxYAxisTitle = xText; break;
3662 [ # # ]: 0 : case EXC_CHOBJLINK_ZAXIS: mxZAxisTitle = xText; break;
3663 [ # # ]: 0 : }
3664 : 0 : }
3665 : :
3666 : 6 : void XclImpChAxesSet::ReadChPlotFrame( XclImpStream& rStrm )
3667 : : {
3668 [ + - ][ + - ]: 6 : if( (rStrm.GetNextRecId() == EXC_ID_CHFRAME) && rStrm.StartNextRecord() )
[ + - ]
3669 : : {
3670 [ + - ]: 6 : mxPlotFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_PLOTFRAME ) );
3671 : 6 : mxPlotFrame->ReadRecordGroup( rStrm );
3672 : : }
3673 : 6 : }
3674 : :
3675 : 6 : void XclImpChAxesSet::ReadChTypeGroup( XclImpStream& rStrm )
3676 : : {
3677 [ + - ][ + - ]: 6 : XclImpChTypeGroupRef xTypeGroup( new XclImpChTypeGroup( GetChRoot() ) );
[ + - ]
3678 [ + - ]: 6 : xTypeGroup->ReadRecordGroup( rStrm );
3679 : 6 : sal_uInt16 nGroupIdx = xTypeGroup->GetGroupIdx();
3680 [ + - ]: 6 : XclImpChTypeGroupMap::iterator itr = maTypeGroups.lower_bound(nGroupIdx);
3681 [ - + ][ # # ]: 6 : if (itr != maTypeGroups.end() && !maTypeGroups.key_comp()(nGroupIdx, itr->first))
[ # # ][ # # ]
[ - + ][ + - ]
[ - + # #
# # ]
3682 : : // Overwrite the existing element.
3683 [ # # ]: 0 : itr->second = xTypeGroup;
3684 : : else
3685 : : maTypeGroups.insert(
3686 [ + - ][ + - ]: 6 : itr, XclImpChTypeGroupMap::value_type(nGroupIdx, xTypeGroup));
[ + - ][ + - ]
3687 : 6 : }
3688 : :
3689 : 6 : Reference< XCoordinateSystem > XclImpChAxesSet::CreateCoordSystem( Reference< XDiagram > xDiagram ) const
3690 : : {
3691 : 6 : Reference< XCoordinateSystem > xCoordSystem;
3692 : :
3693 : : /* Try to get existing ccordinate system. For now, all series from primary
3694 : : and secondary axes sets are inserted into one coordinate system. Later,
3695 : : this should be changed to use one coordinate system for each axes set. */
3696 [ + - ]: 6 : Reference< XCoordinateSystemContainer > xCoordSystemCont( xDiagram, UNO_QUERY );
3697 [ + - ]: 6 : if( xCoordSystemCont.is() )
3698 : : {
3699 [ + - ][ + - ]: 6 : Sequence< Reference< XCoordinateSystem > > aCoordSystems = xCoordSystemCont->getCoordinateSystems();
3700 : : OSL_ENSURE( aCoordSystems.getLength() <= 1, "XclImpChAxesSet::CreateCoordSystem - too many existing coordinate systems" );
3701 [ - + ]: 6 : if( aCoordSystems.getLength() > 0 )
3702 [ # # ][ # # ]: 6 : xCoordSystem = aCoordSystems[ 0 ];
[ + - ]
3703 : : }
3704 : :
3705 : : // create the coordinate system according to the first chart type
3706 [ + - ]: 6 : if( !xCoordSystem.is() )
3707 : : {
3708 [ + - ]: 6 : XclImpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
3709 [ + - ]: 6 : if( xTypeGroup )
3710 : : {
3711 [ + - ][ + - ]: 6 : xCoordSystem = xTypeGroup->CreateCoordSystem();
3712 : : // convert 3d chart settings
3713 [ + - ]: 6 : ScfPropertySet aDiaProp( xDiagram );
3714 [ + - ][ + - ]: 6 : xTypeGroup->ConvertChart3d( aDiaProp );
3715 [ + - ]: 6 : }
3716 : : }
3717 : :
3718 : : /* Create XChartType objects for all chart type groups. Each group will
3719 : : add its series to the data provider attached to the chart document. */
3720 [ + - ]: 6 : Reference< XChartTypeContainer > xChartTypeCont( xCoordSystem, UNO_QUERY );
3721 [ + - ]: 6 : if( xChartTypeCont.is() )
3722 : : {
3723 [ + - ]: 6 : sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
3724 [ + + ]: 12 : for( XclImpChTypeGroupMap::const_iterator aIt = maTypeGroups.begin(), aEnd = maTypeGroups.end(); aIt != aEnd; ++aIt )
3725 : : {
3726 : : try
3727 : : {
3728 [ + - ]: 6 : Reference< XChartType > xChartType = aIt->second->CreateChartType( xDiagram, nApiAxesSetIdx );
3729 [ + - ]: 6 : if( xChartType.is() )
3730 [ + - ][ + - ]: 6 : xChartTypeCont->addChartType( xChartType );
[ # # ]
3731 : : }
3732 [ # # ]: 0 : catch( Exception& )
3733 : : {
3734 : : OSL_FAIL( "XclImpChAxesSet::CreateCoordSystem - cannot add chart type" );
3735 : : }
3736 : : }
3737 : : }
3738 : :
3739 : 6 : return xCoordSystem;
3740 : : }
3741 : :
3742 : 18 : void XclImpChAxesSet::ConvertAxis(
3743 : : XclImpChAxisRef xChAxis, XclImpChTextRef xChAxisTitle,
3744 : : Reference< XCoordinateSystem > xCoordSystem, const XclImpChAxis* pCrossingAxis ) const
3745 : : {
3746 [ + + ]: 18 : if( xChAxis )
3747 : : {
3748 : : // create and attach the axis object
3749 [ + - ]: 12 : Reference< XAxis > xAxis = CreateAxis( *xChAxis, pCrossingAxis );
3750 [ + - ]: 12 : if( xAxis.is() )
3751 : : {
3752 : : // create and attach the axis title
3753 [ - + ]: 12 : if( xChAxisTitle ) try
3754 : : {
3755 [ # # ]: 0 : Reference< XTitled > xTitled( xAxis, UNO_QUERY_THROW );
3756 [ # # ][ # # ]: 0 : Reference< XTitle > xTitle( xChAxisTitle->CreateTitle(), UNO_SET_THROW );
3757 [ # # ][ # # ]: 0 : xTitled->setTitleObject( xTitle );
[ # # ]
3758 : : }
3759 [ # # # # ]: 0 : catch( Exception& )
3760 : : {
3761 : : OSL_FAIL( "XclImpChAxesSet::ConvertAxis - cannot set axis title" );
3762 : : }
3763 : :
3764 : : // insert axis into coordinate system
3765 : : try
3766 : : {
3767 [ + - ]: 12 : sal_Int32 nApiAxisDim = xChAxis->GetApiAxisDimension();
3768 [ + - ]: 12 : sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
3769 [ + - ][ + - ]: 12 : xCoordSystem->setAxisByDimension( nApiAxisDim, xAxis, nApiAxesSetIdx );
3770 : : }
3771 [ # # ]: 0 : catch( Exception& )
3772 : : {
3773 : : OSL_FAIL( "XclImpChAxesSet::ConvertAxis - cannot set axis" );
3774 : : }
3775 : 12 : }
3776 : : }
3777 : 18 : }
3778 : :
3779 : 12 : Reference< XAxis > XclImpChAxesSet::CreateAxis( const XclImpChAxis& rChAxis, const XclImpChAxis* pCrossingAxis ) const
3780 : : {
3781 : 12 : Reference< XAxis > xAxis;
3782 [ + - ][ + - ]: 12 : if( const XclImpChTypeGroup* pTypeGroup = GetFirstTypeGroup().get() )
[ + - ]
3783 [ + - ][ + - ]: 12 : xAxis = rChAxis.CreateAxis( *pTypeGroup, pCrossingAxis );
3784 : 12 : return xAxis;
3785 : : }
3786 : :
3787 : 6 : void XclImpChAxesSet::ConvertBackground( Reference< XDiagram > xDiagram ) const
3788 : : {
3789 [ + - ]: 6 : XclImpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
3790 [ + - ][ + - ]: 6 : if( xTypeGroup && xTypeGroup->Is3dWallChart() )
[ - + ][ - + ]
3791 : : {
3792 : : // wall/floor formatting (3D charts)
3793 [ # # ]: 0 : if( mxXAxis )
3794 : : {
3795 [ # # ][ # # ]: 0 : ScfPropertySet aWallProp( xDiagram->getWall() );
[ # # ]
3796 [ # # ][ # # ]: 0 : mxXAxis->ConvertWall( aWallProp );
3797 : : }
3798 [ # # ]: 0 : if( mxYAxis )
3799 : : {
3800 [ # # ][ # # ]: 0 : ScfPropertySet aFloorProp( xDiagram->getFloor() );
[ # # ]
3801 [ # # ][ # # ]: 0 : mxYAxis->ConvertWall( aFloorProp );
3802 : : }
3803 : : }
3804 [ + - ]: 6 : else if( mxPlotFrame )
3805 : : {
3806 : : // diagram background formatting
3807 [ + - ][ + - ]: 6 : ScfPropertySet aWallProp( xDiagram->getWall() );
[ + - ]
3808 [ + - ][ + - ]: 6 : mxPlotFrame->Convert( aWallProp );
3809 [ + - ]: 6 : }
3810 : 6 : }
3811 : :
3812 : : // The chart object ===========================================================
3813 : :
3814 : 6 : XclImpChChart::XclImpChChart( const XclImpRoot& rRoot ) :
3815 [ + - ][ + - ]: 6 : XclImpChRoot( rRoot, *this )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
3816 : : {
3817 [ + - ][ + - ]: 6 : mxPrimAxesSet.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_PRIMARY ) );
[ + - ]
3818 [ + - ][ + - ]: 6 : mxSecnAxesSet.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_SECONDARY ) );
[ + - ]
3819 : 6 : }
3820 : :
3821 [ + - ][ + - ]: 6 : XclImpChChart::~XclImpChChart()
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
3822 : : {
3823 [ - + ]: 12 : }
3824 : :
3825 : 6 : void XclImpChChart::ReadHeaderRecord( XclImpStream& rStrm )
3826 : : {
3827 : : // coordinates are stored as 16.16 fixed point
3828 : 6 : rStrm >> maRect;
3829 : 6 : }
3830 : :
3831 : 72 : void XclImpChChart::ReadSubRecord( XclImpStream& rStrm )
3832 : : {
3833 [ + + + + : 72 : switch( rStrm.GetRecId() )
+ + + + ]
3834 : : {
3835 : : case EXC_ID_CHFRAME:
3836 [ + - ]: 6 : mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND ) );
3837 : 6 : mxFrame->ReadRecordGroup( rStrm );
3838 : 6 : break;
3839 : : case EXC_ID_CHSERIES:
3840 : 6 : ReadChSeries( rStrm );
3841 : 6 : break;
3842 : : case EXC_ID_CHPROPERTIES:
3843 : 6 : ReadChProperties( rStrm );
3844 : 6 : break;
3845 : : case EXC_ID_CHDEFAULTTEXT:
3846 : 12 : ReadChDefaultText( rStrm );
3847 : 12 : break;
3848 : : case EXC_ID_CHAXESSET:
3849 : 6 : ReadChAxesSet( rStrm );
3850 : 6 : break;
3851 : : case EXC_ID_CHTEXT:
3852 : 6 : ReadChText( rStrm );
3853 : 6 : break;
3854 : : case EXC_ID_CHEND:
3855 : 6 : Finalize(); // finalize the entire chart object
3856 : 6 : break;
3857 : : }
3858 : 72 : }
3859 : :
3860 : 12 : void XclImpChChart::ReadChDefaultText( XclImpStream& rStrm )
3861 : : {
3862 [ + - ]: 12 : sal_uInt16 nTextId = rStrm.ReaduInt16();
3863 [ + - ][ + - ]: 12 : if( (rStrm.GetNextRecId() == EXC_ID_CHTEXT) && rStrm.StartNextRecord() )
[ + - ][ + - ]
[ + - ]
3864 : : {
3865 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
3866 [ + - ][ + - ]: 12 : auto_ptr<XclImpChText> pText(new XclImpChText(GetChRoot()));
3867 : : SAL_WNODEPRECATED_DECLARATIONS_POP
3868 [ + - ]: 12 : pText->ReadRecordGroup(rStrm);
3869 [ + - ][ + - ]: 12 : maDefTexts.insert(nTextId, pText);
[ + - ]
3870 : : }
3871 : 12 : }
3872 : :
3873 : 6 : void XclImpChChart::ReadChDataFormat( XclImpStream& rStrm )
3874 : : {
3875 [ + - ][ + - ]: 6 : XclImpChDataFormatRef xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
[ + - ]
3876 [ + - ]: 6 : xDataFmt->ReadRecordGroup( rStrm );
3877 [ + - ]: 6 : if( xDataFmt->GetPointPos().mnSeriesIdx <= EXC_CHSERIES_MAXSERIES )
3878 : : {
3879 : 6 : const XclChDataPointPos& rPos = xDataFmt->GetPointPos();
3880 [ + - ]: 6 : XclImpChDataFormatMap::iterator itr = maDataFmts.lower_bound(rPos);
3881 [ - + ][ # # ]: 6 : if (itr == maDataFmts.end() || maDataFmts.key_comp()(rPos, itr->first))
[ # # ][ # # ]
[ - + ][ + - ]
[ + - # #
# # ]
3882 : : // No element exists for this data point. Insert it.
3883 : : maDataFmts.insert(
3884 [ + - ][ + - ]: 6 : itr, XclImpChDataFormatMap::value_type(rPos, xDataFmt));
[ + - ]
3885 : :
3886 : : /* Do not overwrite existing data format group, Excel always uses the
3887 : : first data format group occuring in any CHSERIES group. */
3888 [ + - ]: 6 : }
3889 : 6 : }
3890 : :
3891 : 0 : void XclImpChChart::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData )
3892 : : {
3893 [ # # ]: 0 : if( !mxFrame )
3894 [ # # ]: 0 : mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND ) );
3895 : 0 : mxFrame->UpdateObjFrame( rLineData, rFillData );
3896 : 0 : }
3897 : :
3898 : 24 : XclImpChTypeGroupRef XclImpChChart::GetTypeGroup( sal_uInt16 nGroupIdx ) const
3899 : : {
3900 : 24 : XclImpChTypeGroupRef xTypeGroup = mxPrimAxesSet->GetTypeGroup( nGroupIdx );
3901 [ # # ][ # # ]: 24 : if( !xTypeGroup ) xTypeGroup = mxSecnAxesSet->GetTypeGroup( nGroupIdx );
[ # # ][ - + ]
3902 [ - + ][ # # ]: 24 : if( !xTypeGroup ) xTypeGroup = mxPrimAxesSet->GetFirstTypeGroup();
[ # # ][ # # ]
3903 : 24 : return xTypeGroup;
3904 : : }
3905 : :
3906 : 30 : const XclImpChText* XclImpChChart::GetDefaultText( XclChTextType eTextType ) const
3907 : : {
3908 : 30 : sal_uInt16 nDefTextId = EXC_CHDEFTEXT_GLOBAL;
3909 : 30 : bool bBiff8 = GetBiff() == EXC_BIFF8;
3910 [ + + + + : 30 : switch( eTextType )
+ - ]
3911 : : {
3912 : 6 : case EXC_CHTEXTTYPE_TITLE: nDefTextId = EXC_CHDEFTEXT_GLOBAL; break;
3913 : 6 : case EXC_CHTEXTTYPE_LEGEND: nDefTextId = EXC_CHDEFTEXT_GLOBAL; break;
3914 [ + - ]: 6 : case EXC_CHTEXTTYPE_AXISTITLE: nDefTextId = bBiff8 ? EXC_CHDEFTEXT_AXESSET : EXC_CHDEFTEXT_GLOBAL; break;
3915 [ + - ]: 6 : case EXC_CHTEXTTYPE_AXISLABEL: nDefTextId = bBiff8 ? EXC_CHDEFTEXT_AXESSET : EXC_CHDEFTEXT_GLOBAL; break;
3916 [ + - ]: 6 : case EXC_CHTEXTTYPE_DATALABEL: nDefTextId = bBiff8 ? EXC_CHDEFTEXT_AXESSET : EXC_CHDEFTEXT_GLOBAL; break;
3917 : : }
3918 : :
3919 [ + - ]: 30 : XclImpChTextMap::const_iterator itr = maDefTexts.find(nDefTextId);
3920 [ + - ][ + - ]: 30 : return itr == maDefTexts.end() ? NULL : itr->second;
[ - + ][ + - ]
[ + - ][ # # ]
3921 : : }
3922 : :
3923 : 12 : bool XclImpChChart::IsManualPlotArea() const
3924 : : {
3925 : : // there is no real automatic mode in BIFF5 charts
3926 [ + - ][ + + ]: 12 : return (GetBiff() <= EXC_BIFF5) || ::get_flag( maProps.mnFlags, EXC_CHPROPS_USEMANPLOTAREA );
3927 : : }
3928 : :
3929 : 6 : void XclImpChChart::Convert( const Reference<XChartDocument>& xChartDoc,
3930 : : XclImpDffConverter& rDffConv, const OUString& rObjName, const Rectangle& rChartRect ) const
3931 : : {
3932 : : // initialize conversion (locks the model to suppress any internal updates)
3933 [ + - ]: 6 : InitConversion( xChartDoc, rChartRect );
3934 : :
3935 : : // chart frame formatting
3936 [ + - ]: 6 : if( mxFrame )
3937 : : {
3938 [ + - ][ + - ]: 6 : ScfPropertySet aFrameProp( xChartDoc->getPageBackground() );
[ + - ]
3939 [ + - ][ + - ]: 6 : mxFrame->Convert( aFrameProp );
3940 : : }
3941 : :
3942 : : // chart title
3943 [ + - ]: 6 : if( mxTitle ) try
3944 : : {
3945 [ + - ]: 6 : Reference< XTitled > xTitled( xChartDoc, UNO_QUERY_THROW );
3946 [ + - ][ + - ]: 6 : Reference< XTitle > xTitle( mxTitle->CreateTitle(), UNO_SET_THROW );
3947 [ + - ][ # # ]: 6 : xTitled->setTitleObject( xTitle );
[ + - ]
3948 : : }
3949 [ # # ]: 0 : catch( Exception& )
3950 : : {
3951 : : }
3952 : :
3953 : : /* Create the diagram object and attach it to the chart document. Currently,
3954 : : one diagram is used to carry all coordinate systems and data series. */
3955 [ + - ]: 6 : Reference< XDiagram > xDiagram = CreateDiagram();
3956 [ + - ][ + - ]: 6 : xChartDoc->setFirstDiagram( xDiagram );
3957 : :
3958 : : // coordinate systems and chart types, convert axis settings
3959 [ + - ]: 6 : mxPrimAxesSet->Convert( xDiagram );
3960 [ + - ]: 6 : mxSecnAxesSet->Convert( xDiagram );
3961 : :
3962 : : // legend
3963 [ + - ][ + - ]: 6 : if( xDiagram.is() && mxLegend )
[ + - ]
3964 [ + - ][ + - ]: 6 : xDiagram->setLegend( mxLegend->CreateLegend() );
[ + - ]
3965 : :
3966 : : /* Following all conversions needing the old Chart1 API that involves full
3967 : : initialization of the chart view. */
3968 [ + - ]: 6 : Reference< cssc::XChartDocument > xChart1Doc( xChartDoc, UNO_QUERY );
3969 [ + - ]: 6 : if( xChart1Doc.is() )
3970 : : {
3971 [ + - ][ + - ]: 6 : Reference< cssc::XDiagram > xDiagram1 = xChart1Doc->getDiagram();
3972 : :
3973 : : /* Set the 'IncludeHiddenCells' property via the old API as only this
3974 : : ensures that the data provider and all created sequences get this
3975 : : flag correctly. */
3976 [ + - ]: 6 : ScfPropertySet aDiaProp( xDiagram1 );
3977 : 6 : bool bShowVisCells = ::get_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY );
3978 [ + - ][ + - ]: 6 : aDiaProp.SetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS, !bShowVisCells );
3979 : :
3980 : : // plot area position and size (there is no real automatic mode in BIFF5 charts)
3981 [ + - ]: 6 : XclImpChFramePosRef xPlotAreaPos = mxPrimAxesSet->GetPlotAreaFramePos();
3982 [ + - ][ + + ]: 6 : if( IsManualPlotArea() && xPlotAreaPos ) try
[ + - ][ + + ]
3983 : : {
3984 : 3 : const XclChFramePos& rFramePos = xPlotAreaPos->GetFramePosData();
3985 [ + - ][ + - ]: 3 : if( (rFramePos.mnTLMode == EXC_CHFRAMEPOS_PARENT) && (rFramePos.mnBRMode == EXC_CHFRAMEPOS_PARENT) )
3986 : : {
3987 [ + - ]: 3 : Reference< cssc::XDiagramPositioning > xPositioning( xDiagram1, UNO_QUERY_THROW );
3988 [ + - ]: 3 : ::com::sun::star::awt::Rectangle aDiagramRect = CalcHmmFromChartRect( rFramePos.maRect );
3989 : : // for pie charts, always set inner plot area size to exclude the data labels as Excel does
3990 [ + - ][ + - ]: 3 : const XclImpChTypeGroup* pFirstTypeGroup = mxPrimAxesSet->GetFirstTypeGroup().get();
3991 [ + - ][ - + ]: 3 : if( pFirstTypeGroup && (pFirstTypeGroup->GetTypeInfo().meTypeCateg == EXC_CHTYPECATEG_PIE) )
[ - + ]
3992 [ # # ][ # # ]: 0 : xPositioning->setDiagramPositionExcludingAxes( aDiagramRect );
3993 [ + - ][ + - ]: 3 : else if( pFirstTypeGroup && pFirstTypeGroup->Is3dChart() )
[ - + ][ - + ]
3994 [ # # ][ # # ]: 0 : xPositioning->setDiagramPositionIncludingAxesAndAxisTitles( aDiagramRect );
3995 : : else
3996 [ + - ][ + - ]: 3 : xPositioning->setDiagramPositionIncludingAxes( aDiagramRect );
[ # # ]
3997 : : }
3998 : : }
3999 [ # # ]: 0 : catch( Exception& )
4000 : : {
4001 : : }
4002 : :
4003 : : // positions of all title objects
4004 [ + - ]: 6 : if( mxTitle )
4005 [ + - ][ + - ]: 6 : mxTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_TITLE ) );
4006 [ + - ]: 6 : mxPrimAxesSet->ConvertTitlePositions();
4007 [ + - ][ + - ]: 6 : mxSecnAxesSet->ConvertTitlePositions();
[ + - ]
4008 : : }
4009 : :
4010 : : // unlock the model
4011 [ + - ]: 6 : FinishConversion( rDffConv );
4012 : :
4013 : : // start listening to this chart
4014 : 6 : ScDocument& rDoc = GetRoot().GetDoc();
4015 [ + - ][ + - ]: 6 : if( ScChartListenerCollection* pChartCollection = rDoc.GetChartListenerCollection() )
4016 : : {
4017 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
4018 [ + - ][ + - ]: 6 : ::std::auto_ptr< ::std::vector< ScTokenRef > > xRefTokens( new ::std::vector< ScTokenRef > );
4019 : : SAL_WNODEPRECATED_DECLARATIONS_POP
4020 [ + - ][ + + ]: 12 : for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end(); aIt != aEnd; ++aIt )
4021 [ + - ]: 6 : (*aIt)->FillAllSourceLinks( *xRefTokens );
4022 [ + - ]: 6 : if( !xRefTokens->empty() )
4023 : : {
4024 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
4025 [ + - ][ + - ]: 6 : ::std::auto_ptr< ScChartListener > xListener( new ScChartListener( rObjName, &rDoc, xRefTokens.release() ) );
4026 : : SAL_WNODEPRECATED_DECLARATIONS_POP
4027 : 6 : xListener->SetUsed( true );
4028 [ + - ]: 6 : xListener->StartListeningTo();
4029 [ + - ][ + - ]: 6 : pChartCollection->insert( xListener.release() );
4030 : 6 : }
4031 : 6 : }
4032 : 6 : }
4033 : :
4034 : 6 : void XclImpChChart::ReadChSeries( XclImpStream& rStrm )
4035 : : {
4036 : 6 : sal_uInt16 nNewSeriesIdx = static_cast< sal_uInt16 >( maSeries.size() );
4037 [ + - ][ + - ]: 6 : XclImpChSeriesRef xSeries( new XclImpChSeries( GetChRoot(), nNewSeriesIdx ) );
[ + - ]
4038 [ + - ]: 6 : xSeries->ReadRecordGroup( rStrm );
4039 [ + - ][ + - ]: 6 : maSeries.push_back( xSeries );
4040 : 6 : }
4041 : :
4042 : 6 : void XclImpChChart::ReadChProperties( XclImpStream& rStrm )
4043 : : {
4044 : 6 : rStrm >> maProps.mnFlags >> maProps.mnEmptyMode;
4045 : 6 : }
4046 : :
4047 : 6 : void XclImpChChart::ReadChAxesSet( XclImpStream& rStrm )
4048 : : {
4049 [ + - ][ + - ]: 6 : XclImpChAxesSetRef xAxesSet( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_NONE ) );
[ + - ]
4050 [ + - ]: 6 : xAxesSet->ReadRecordGroup( rStrm );
4051 [ + - - ]: 6 : switch( xAxesSet->GetAxesSetId() )
4052 : : {
4053 [ + - ]: 6 : case EXC_CHAXESSET_PRIMARY: mxPrimAxesSet = xAxesSet; break;
4054 [ # # ]: 0 : case EXC_CHAXESSET_SECONDARY: mxSecnAxesSet = xAxesSet; break;
4055 [ + - ]: 6 : }
4056 : 6 : }
4057 : :
4058 : 6 : void XclImpChChart::ReadChText( XclImpStream& rStrm )
4059 : : {
4060 [ + - ][ + - ]: 6 : XclImpChTextRef xText( new XclImpChText( GetChRoot() ) );
[ + - ]
4061 [ + - ]: 6 : xText->ReadRecordGroup( rStrm );
4062 [ + - - ]: 6 : switch( xText->GetLinkTarget() )
4063 : : {
4064 : : case EXC_CHOBJLINK_TITLE:
4065 [ + - ]: 6 : mxTitle = xText;
4066 : 6 : break;
4067 : : case EXC_CHOBJLINK_DATA:
4068 : : {
4069 : 0 : sal_uInt16 nSeriesIdx = xText->GetPointPos().mnSeriesIdx;
4070 [ # # ]: 0 : if( nSeriesIdx < maSeries.size() )
4071 [ # # ]: 0 : maSeries[ nSeriesIdx ]->SetDataLabel( xText );
4072 : : }
4073 : 0 : break;
4074 [ + - ]: 6 : }
4075 : 6 : }
4076 : :
4077 : 6 : void XclImpChChart::Finalize()
4078 : : {
4079 : : // finalize series (must be done first)
4080 : 6 : FinalizeSeries();
4081 : : // #i49218# legend may be attached to primary or secondary axes set
4082 [ + - ]: 6 : mxLegend = mxPrimAxesSet->GetLegend();
4083 [ - + ]: 6 : if( !mxLegend )
4084 [ # # ]: 0 : mxLegend = mxSecnAxesSet->GetLegend();
4085 [ + - ]: 6 : if( mxLegend )
4086 : 6 : mxLegend->Finalize();
4087 : : // axes sets, updates chart type group default formats -> must be called before FinalizeDataFormats()
4088 : 6 : mxPrimAxesSet->Finalize();
4089 : 6 : mxSecnAxesSet->Finalize();
4090 : : // formatting of all series
4091 : 6 : FinalizeDataFormats();
4092 : : // #i47745# missing frame -> invisible border and area
4093 [ - + ]: 6 : if( !mxFrame )
4094 [ # # ]: 0 : mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND ) );
4095 : : // chart title
4096 : 6 : FinalizeTitle();
4097 : 6 : }
4098 : :
4099 : 6 : void XclImpChChart::FinalizeSeries()
4100 : : {
4101 [ + - ][ + + ]: 12 : for( XclImpChSeriesVec::iterator aSIt = maSeries.begin(), aSEnd = maSeries.end(); aSIt != aSEnd; ++aSIt )
4102 : : {
4103 [ + - ]: 6 : XclImpChSeriesRef xSeries = *aSIt;
4104 [ - + ]: 6 : if( xSeries->HasParentSeries() )
4105 : : {
4106 : : /* Process child series (trend lines and error bars). Data of
4107 : : child series will be set at the connected parent series. */
4108 [ # # ]: 0 : if( xSeries->GetParentIdx() < maSeries.size() )
4109 [ # # ]: 0 : maSeries[ xSeries->GetParentIdx() ]->AddChildSeries( *xSeries );
4110 : : }
4111 : : else
4112 : : {
4113 : : // insert the series into the related chart type group
4114 [ + - ][ + - ]: 6 : if( XclImpChTypeGroup* pTypeGroup = GetTypeGroup( xSeries->GetGroupIdx() ).get() )
[ + - ]
4115 [ + - ][ + - ]: 6 : pTypeGroup->AddSeries( xSeries );
[ + - ]
4116 : : }
4117 [ + - ]: 6 : }
4118 : 6 : }
4119 : :
4120 : 6 : void XclImpChChart::FinalizeDataFormats()
4121 : : {
4122 : : /* #i51639# (part 1): CHDATAFORMAT groups are part of CHSERIES groups.
4123 : : Each CHDATAFORMAT group specifies the series and data point it is
4124 : : assigned to. This makes it possible to have a data format that is
4125 : : related to another series, e.g. a CHDATAFORMAT group for series 2 is
4126 : : part of a CHSERIES group that describes series 1. Therefore the chart
4127 : : itself has collected all CHDATAFORMAT groups to be able to store data
4128 : : format groups for series that have not been imported at that time. This
4129 : : loop finally assigns these groups to the related series. */
4130 [ + + ]: 12 : for( XclImpChDataFormatMap::const_iterator aMIt = maDataFmts.begin(), aMEnd = maDataFmts.end(); aMIt != aMEnd; ++aMIt )
4131 : : {
4132 : 6 : sal_uInt16 nSeriesIdx = aMIt->first.mnSeriesIdx;
4133 [ + - ]: 6 : if( nSeriesIdx < maSeries.size() )
4134 [ + - ]: 6 : maSeries[ nSeriesIdx ]->SetDataFormat( aMIt->second );
4135 : : }
4136 : :
4137 : : /* #i51639# (part 2): Finalize data formats of all series. This adds for
4138 : : example missing CHDATAFORMAT groups for entire series that are needed
4139 : : for automatic colors of lines and areas. */
4140 [ + - ][ + + ]: 12 : for( XclImpChSeriesVec::iterator aVIt = maSeries.begin(), aVEnd = maSeries.end(); aVIt != aVEnd; ++aVIt )
4141 [ + - ]: 6 : (*aVIt)->FinalizeDataFormats();
4142 : 6 : }
4143 : :
4144 : 6 : void XclImpChChart::FinalizeTitle()
4145 : : {
4146 : : // special handling for auto-generated title
4147 [ + - ]: 6 : String aAutoTitle;
4148 [ + - ][ + - ]: 6 : if( !mxTitle || (!mxTitle->IsDeleted() && !mxTitle->HasString()) )
[ + - ][ + - ]
[ - + ][ - + ]
4149 : : {
4150 : : // automatic title from first series name (if there are no series on secondary axes set)
4151 [ # # ]: 0 : if( !mxSecnAxesSet->IsValidAxesSet() )
4152 [ # # ][ # # ]: 0 : aAutoTitle = mxPrimAxesSet->GetSingleSeriesTitle();
4153 [ # # ][ # # ]: 0 : if( mxTitle || (aAutoTitle.Len() > 0) )
[ # # ]
4154 : : {
4155 [ # # ]: 0 : if( !mxTitle )
4156 [ # # ][ # # ]: 0 : mxTitle.reset( new XclImpChText( GetChRoot() ) );
[ # # ]
4157 [ # # ]: 0 : if( aAutoTitle.Len() == 0 )
4158 [ # # ][ # # ]: 0 : aAutoTitle = CREATE_STRING( "Chart Title" );
[ # # ]
4159 : : }
4160 : : }
4161 : :
4162 : : // will reset mxTitle, if it does not contain a string and no auto title exists
4163 [ + - ][ + - ]: 6 : lclFinalizeTitle( mxTitle, GetDefaultText( EXC_CHTEXTTYPE_TITLE ), aAutoTitle );
[ + - ]
4164 : 6 : }
4165 : :
4166 : 6 : Reference< XDiagram > XclImpChChart::CreateDiagram() const
4167 : : {
4168 : : // create a diagram object
4169 [ + - ][ + - ]: 6 : Reference< XDiagram > xDiagram( ScfApiHelper::CreateInstance( SERVICE_CHART2_DIAGRAM ), UNO_QUERY );
[ + - ]
4170 : :
4171 : : // convert global chart settings
4172 [ + - ]: 6 : ScfPropertySet aDiaProp( xDiagram );
4173 : :
4174 : : // treatment of missing values
4175 : : using namespace cssc::MissingValueTreatment;
4176 : 6 : sal_Int32 nMissingValues = LEAVE_GAP;
4177 [ + - - - ]: 6 : switch( maProps.mnEmptyMode )
4178 : : {
4179 : 6 : case EXC_CHPROPS_EMPTY_SKIP: nMissingValues = LEAVE_GAP; break;
4180 : 0 : case EXC_CHPROPS_EMPTY_ZERO: nMissingValues = USE_ZERO; break;
4181 : 0 : case EXC_CHPROPS_EMPTY_INTERPOLATE: nMissingValues = CONTINUE; break;
4182 : : }
4183 [ + - ][ + - ]: 6 : aDiaProp.SetProperty( EXC_CHPROP_MISSINGVALUETREATMENT, nMissingValues );
4184 : :
4185 [ + - ]: 6 : return xDiagram;
4186 : : }
4187 : :
4188 : : // ----------------------------------------------------------------------------
4189 : :
4190 : 0 : XclImpChartDrawing::XclImpChartDrawing( const XclImpRoot& rRoot, bool bOwnTab ) :
4191 : : XclImpDrawing( rRoot, bOwnTab ), // sheet charts may contain OLE objects
4192 : 0 : mnScTab( rRoot.GetCurrScTab() ),
4193 [ # # ]: 0 : mbOwnTab( bOwnTab )
4194 : : {
4195 : 0 : }
4196 : :
4197 : 0 : void XclImpChartDrawing::ConvertObjects( XclImpDffConverter& rDffConv,
4198 : : const Reference< XModel >& rxModel, const Rectangle& rChartRect )
4199 : : {
4200 : 0 : maChartRect = rChartRect; // needed in CalcAnchorRect() callback
4201 : :
4202 : 0 : SdrModel* pSdrModel = 0;
4203 : 0 : SdrPage* pSdrPage = 0;
4204 [ # # ]: 0 : if( mbOwnTab )
4205 : : {
4206 : : // chart sheet: insert all shapes into the sheet, not into the chart object
4207 : 0 : pSdrModel = GetDoc().GetDrawLayer();
4208 : 0 : pSdrPage = GetSdrPage( mnScTab );
4209 : : }
4210 : : else
4211 : : {
4212 : : // embedded chart object: insert all shapes into the chart
4213 : : try
4214 : : {
4215 [ # # ]: 0 : Reference< XDrawPageSupplier > xDrawPageSupp( rxModel, UNO_QUERY_THROW );
4216 [ # # ][ # # ]: 0 : Reference< XDrawPage > xDrawPage( xDrawPageSupp->getDrawPage(), UNO_SET_THROW );
[ # # ]
4217 : 0 : pSdrPage = ::GetSdrPageFromXDrawPage( xDrawPage );
4218 [ # # ][ # # ]: 0 : pSdrModel = pSdrPage ? pSdrPage->GetModel() : 0;
[ # # ]
4219 : : }
4220 : 0 : catch( Exception& )
4221 : : {
4222 : : }
4223 : : }
4224 : :
4225 [ # # ][ # # ]: 0 : if( pSdrModel && pSdrPage )
4226 : 0 : ImplConvertObjects( rDffConv, *pSdrModel, *pSdrPage );
4227 : 0 : }
4228 : :
4229 : 0 : Rectangle XclImpChartDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const
4230 : : {
4231 : : /* In objects with DFF client anchor, the position of the shape is stored
4232 : : in the cell address components of the client anchor. In old BIFF3-BIFF5
4233 : : objects, the position is stored in the offset components of the anchor. */
4234 : : Rectangle aRect(
4235 : 0 : static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnCol : rAnchor.mnLX ) / EXC_CHART_TOTALUNITS * maChartRect.GetWidth() + 0.5 ),
4236 : 0 : static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnRow : rAnchor.mnTY ) / EXC_CHART_TOTALUNITS * maChartRect.GetHeight() + 0.5 ),
4237 : 0 : static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnCol : rAnchor.mnRX ) / EXC_CHART_TOTALUNITS * maChartRect.GetWidth() + 0.5 ),
4238 [ # # ][ # # ]: 0 : static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnRow : rAnchor.mnBY ) / EXC_CHART_TOTALUNITS * maChartRect.GetHeight() + 0.5 ) );
[ # # ][ # # ]
4239 : 0 : aRect.Justify();
4240 : : // move shapes into chart area for sheet charts
4241 [ # # ]: 0 : if( mbOwnTab )
4242 : 0 : aRect.Move( maChartRect.Left(), maChartRect.Top() );
4243 : 0 : return aRect;
4244 : : }
4245 : :
4246 : 0 : void XclImpChartDrawing::OnObjectInserted( const XclImpDrawObjBase& )
4247 : : {
4248 : 0 : }
4249 : :
4250 : : // ----------------------------------------------------------------------------
4251 : :
4252 : 6 : XclImpChart::XclImpChart( const XclImpRoot& rRoot, bool bOwnTab ) :
4253 : : XclImpRoot( rRoot ),
4254 : : mbOwnTab( bOwnTab ),
4255 [ + - ][ + - ]: 6 : mbIsPivotChart( false )
4256 : : {
4257 : 6 : }
4258 : :
4259 [ + - ][ + - ]: 6 : XclImpChart::~XclImpChart()
4260 : : {
4261 [ - + ]: 12 : }
4262 : :
4263 : 6 : void XclImpChart::ReadChartSubStream( XclImpStream& rStrm )
4264 : : {
4265 : 6 : XclImpPageSettings& rPageSett = GetPageSettings();
4266 : 6 : XclImpTabViewSettings& rTabViewSett = GetTabViewSettings();
4267 : :
4268 : 6 : bool bLoop = true;
4269 [ + + ][ + - ]: 231 : while( bLoop && rStrm.StartNextRecord() )
[ + + ]
4270 : : {
4271 : : // page settings - only for charts in entire sheet
4272 [ - + ][ # # : 225 : if( mbOwnTab ) switch( rStrm.GetRecId() )
# # # # #
# # # # #
# ]
4273 : : {
4274 : : case EXC_ID_HORPAGEBREAKS:
4275 : 0 : case EXC_ID_VERPAGEBREAKS: rPageSett.ReadPageBreaks( rStrm ); break;
4276 : : case EXC_ID_HEADER:
4277 : 0 : case EXC_ID_FOOTER: rPageSett.ReadHeaderFooter( rStrm ); break;
4278 : : case EXC_ID_LEFTMARGIN:
4279 : : case EXC_ID_RIGHTMARGIN:
4280 : : case EXC_ID_TOPMARGIN:
4281 : 0 : case EXC_ID_BOTTOMMARGIN: rPageSett.ReadMargin( rStrm ); break;
4282 : 0 : case EXC_ID_PRINTHEADERS: rPageSett.ReadPrintHeaders( rStrm ); break;
4283 : 0 : case EXC_ID_PRINTGRIDLINES: rPageSett.ReadPrintGridLines( rStrm ); break;
4284 : : case EXC_ID_HCENTER:
4285 : 0 : case EXC_ID_VCENTER: rPageSett.ReadCenter( rStrm ); break;
4286 : 0 : case EXC_ID_SETUP: rPageSett.ReadSetup( rStrm ); break;
4287 : 0 : case EXC_ID8_IMGDATA: rPageSett.ReadImgData( rStrm ); break;
4288 : :
4289 : 0 : case EXC_ID_WINDOW2: rTabViewSett.ReadWindow2( rStrm, true );break;
4290 : 0 : case EXC_ID_SCL: rTabViewSett.ReadScl( rStrm ); break;
4291 : :
4292 : : case EXC_ID_SHEETEXT: //0x0862
4293 : : {
4294 : : // FIXME: do not need to pass palette, XclImpTabVieSettings is derived from root
4295 : 0 : XclImpPalette& rPal = GetPalette();
4296 : 0 : rTabViewSett.ReadTabBgColor( rStrm, rPal);
4297 : : }
4298 : 0 : break;
4299 : :
4300 : 0 : case EXC_ID_CODENAME: ReadCodeName( rStrm, false ); break;
4301 : : }
4302 : :
4303 : : // common records
4304 [ + - + - : 225 : switch( rStrm.GetRecId() )
+ ]
4305 : : {
4306 : 6 : case EXC_ID_EOF: bLoop = false; break;
4307 : :
4308 : : // #i31882# ignore embedded chart objects
4309 : : case EXC_ID2_BOF:
4310 : : case EXC_ID3_BOF:
4311 : : case EXC_ID4_BOF:
4312 : 0 : case EXC_ID5_BOF: XclTools::SkipSubStream( rStrm ); break;
4313 : :
4314 : 6 : case EXC_ID_CHCHART: ReadChChart( rStrm ); break;
4315 : :
4316 : : case EXC_ID8_CHPIVOTREF:
4317 : 0 : GetTracer().TracePivotChartExists();
4318 : 0 : mbIsPivotChart = true;
4319 : 0 : break;
4320 : :
4321 : : // BIFF specific records
4322 [ - + - ]: 213 : default: switch( GetBiff() )
4323 : : {
4324 [ # # ]: 0 : case EXC_BIFF5: switch( rStrm.GetRecId() )
4325 : : {
4326 : 0 : case EXC_ID_OBJ: GetChartDrawing().ReadObj( rStrm ); break;
4327 : : }
4328 : 0 : break;
4329 [ - - + ]: 213 : case EXC_BIFF8: switch( rStrm.GetRecId() )
4330 : : {
4331 : 0 : case EXC_ID_MSODRAWING: GetChartDrawing().ReadMsoDrawing( rStrm ); break;
4332 : : // #i61786# weird documents: OBJ without MSODRAWING -> read in BIFF5 format
4333 : 0 : case EXC_ID_OBJ: GetChartDrawing().ReadObj( rStrm ); break;
4334 : : }
4335 : 213 : break;
4336 : : default:;
4337 : : }
4338 : : }
4339 : : }
4340 : 6 : }
4341 : :
4342 : 0 : void XclImpChart::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData )
4343 : : {
4344 [ # # ]: 0 : if( !mxChartData )
4345 [ # # ]: 0 : mxChartData.reset( new XclImpChChart( GetRoot() ) );
4346 : 0 : mxChartData->UpdateObjFrame( rLineData, rFillData );
4347 : 0 : }
4348 : :
4349 : 6 : sal_Size XclImpChart::GetProgressSize() const
4350 : : {
4351 : : return
4352 : 12 : (mxChartData ? mxChartData->GetProgressSize() : 0) +
4353 [ - + ][ + - ]: 12 : (mxChartDrawing ? mxChartDrawing->GetProgressSize() : 0);
4354 : : }
4355 : :
4356 : 6 : void XclImpChart::Convert( Reference< XModel > xModel, XclImpDffConverter& rDffConv, const OUString& rObjName, const Rectangle& rChartRect ) const
4357 : : {
4358 [ + - ]: 6 : Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY );
4359 [ + - ]: 6 : if( xChartDoc.is() )
4360 : : {
4361 [ + - ]: 6 : if( mxChartData )
4362 [ + - ]: 6 : mxChartData->Convert( xChartDoc, rDffConv, rObjName, rChartRect );
4363 [ - + ]: 6 : if( mxChartDrawing )
4364 [ # # ]: 0 : mxChartDrawing->ConvertObjects( rDffConv, xModel, rChartRect );
4365 : 6 : }
4366 : 6 : }
4367 : :
4368 : 0 : XclImpChartDrawing& XclImpChart::GetChartDrawing()
4369 : : {
4370 [ # # ]: 0 : if( !mxChartDrawing )
4371 [ # # ]: 0 : mxChartDrawing.reset( new XclImpChartDrawing( GetRoot(), mbOwnTab ) );
4372 : 0 : return *mxChartDrawing;
4373 : : }
4374 : :
4375 : 6 : void XclImpChart::ReadChChart( XclImpStream& rStrm )
4376 : : {
4377 [ + - ]: 6 : mxChartData.reset( new XclImpChChart( GetRoot() ) );
4378 : 6 : mxChartData->ReadRecordGroup( rStrm );
4379 [ + - ][ + - ]: 30 : }
4380 : :
4381 : : // ============================================================================
4382 : :
4383 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|