xref: /aoo4110/main/sc/source/filter/excel/xechart.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_sc.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include "xechart.hxx"
28*b1cdbd2cSJim Jagielski 
29*b1cdbd2cSJim Jagielski #include <com/sun/star/i18n/XBreakIterator.hpp>
30*b1cdbd2cSJim Jagielski #include <com/sun/star/i18n/ScriptType.hpp>
31*b1cdbd2cSJim Jagielski #include <com/sun/star/drawing/FillStyle.hpp>
32*b1cdbd2cSJim Jagielski #include <com/sun/star/drawing/XShapes.hpp>
33*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
34*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/ChartAxisPosition.hpp>
35*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/ChartLegendExpansion.hpp>
36*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/DataLabelPlacement.hpp>
37*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/ErrorBarStyle.hpp>
38*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/MissingValueTreatment.hpp>
39*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/TimeInterval.hpp>
40*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/TimeUnit.hpp>
41*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/XAxisSupplier.hpp>
42*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/XChartDocument.hpp>
43*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/XDiagramPositioning.hpp>
44*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/XChartDocument.hpp>
45*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/XDiagram.hpp>
46*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
47*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/XChartTypeContainer.hpp>
48*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
49*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
50*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/XTitled.hpp>
51*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/XColorScheme.hpp>
52*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/data/XDataSource.hpp>
53*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/AxisType.hpp>
54*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/CurveStyle.hpp>
55*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
56*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/DataPointLabel.hpp>
57*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/LegendPosition.hpp>
58*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/RelativePosition.hpp>
59*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/RelativeSize.hpp>
60*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/StackingDirection.hpp>
61*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/TickmarkStyle.hpp>
62*b1cdbd2cSJim Jagielski 
63*b1cdbd2cSJim Jagielski #include <vcl/outdev.hxx>
64*b1cdbd2cSJim Jagielski #include <filter/msfilter/escherex.hxx>
65*b1cdbd2cSJim Jagielski 
66*b1cdbd2cSJim Jagielski #include "document.hxx"
67*b1cdbd2cSJim Jagielski #include "rangelst.hxx"
68*b1cdbd2cSJim Jagielski #include "rangeutl.hxx"
69*b1cdbd2cSJim Jagielski #include "compiler.hxx"
70*b1cdbd2cSJim Jagielski #include "tokenarray.hxx"
71*b1cdbd2cSJim Jagielski #include "token.hxx"
72*b1cdbd2cSJim Jagielski #include "xeescher.hxx"
73*b1cdbd2cSJim Jagielski #include "xeformula.hxx"
74*b1cdbd2cSJim Jagielski #include "xehelper.hxx"
75*b1cdbd2cSJim Jagielski #include "xepage.hxx"
76*b1cdbd2cSJim Jagielski #include "xestyle.hxx"
77*b1cdbd2cSJim Jagielski 
78*b1cdbd2cSJim Jagielski using ::rtl::OUString;
79*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::Any;
80*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::Reference;
81*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::Sequence;
82*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::UNO_QUERY;
83*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::UNO_QUERY_THROW;
84*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::UNO_SET_THROW;
85*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::Exception;
86*b1cdbd2cSJim Jagielski using ::com::sun::star::beans::XPropertySet;
87*b1cdbd2cSJim Jagielski using ::com::sun::star::i18n::XBreakIterator;
88*b1cdbd2cSJim Jagielski using ::com::sun::star::frame::XModel;
89*b1cdbd2cSJim Jagielski using ::com::sun::star::drawing::XShape;
90*b1cdbd2cSJim Jagielski using ::com::sun::star::drawing::XShapes;
91*b1cdbd2cSJim Jagielski 
92*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::IncrementData;
93*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::RelativePosition;
94*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::RelativeSize;
95*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::ScaleData;
96*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::SubIncrement;
97*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XAxis;
98*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XChartDocument;
99*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XChartTypeContainer;
100*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XColorScheme;
101*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XCoordinateSystem;
102*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XCoordinateSystemContainer;
103*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XChartType;
104*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XDataSeries;
105*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XDataSeriesContainer;
106*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XDiagram;
107*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XFormattedString;
108*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XLegend;
109*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XRegressionCurve;
110*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XRegressionCurveContainer;
111*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XScaling;
112*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XTitle;
113*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::XTitled;
114*b1cdbd2cSJim Jagielski 
115*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::data::XDataSequence;
116*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::data::XDataSource;
117*b1cdbd2cSJim Jagielski using ::com::sun::star::chart2::data::XLabeledDataSequence;
118*b1cdbd2cSJim Jagielski 
119*b1cdbd2cSJim Jagielski using ::formula::FormulaGrammar;
120*b1cdbd2cSJim Jagielski using ::formula::FormulaToken;
121*b1cdbd2cSJim Jagielski 
122*b1cdbd2cSJim Jagielski namespace cssc = ::com::sun::star::chart;
123*b1cdbd2cSJim Jagielski namespace cssc2 = ::com::sun::star::chart2;
124*b1cdbd2cSJim Jagielski 
125*b1cdbd2cSJim Jagielski // Helpers ====================================================================
126*b1cdbd2cSJim Jagielski 
127*b1cdbd2cSJim Jagielski namespace {
128*b1cdbd2cSJim Jagielski 
operator <<(XclExpStream & rStrm,const XclChRectangle & rRect)129*b1cdbd2cSJim Jagielski XclExpStream& operator<<( XclExpStream& rStrm, const XclChRectangle& rRect )
130*b1cdbd2cSJim Jagielski {
131*b1cdbd2cSJim Jagielski     return rStrm << rRect.mnX << rRect.mnY << rRect.mnWidth << rRect.mnHeight;
132*b1cdbd2cSJim Jagielski }
133*b1cdbd2cSJim Jagielski 
lclSaveRecord(XclExpStream & rStrm,XclExpRecordRef xRec)134*b1cdbd2cSJim Jagielski inline void lclSaveRecord( XclExpStream& rStrm, XclExpRecordRef xRec )
135*b1cdbd2cSJim Jagielski {
136*b1cdbd2cSJim Jagielski     if( xRec.is() )
137*b1cdbd2cSJim Jagielski         xRec->Save( rStrm );
138*b1cdbd2cSJim Jagielski }
139*b1cdbd2cSJim Jagielski 
140*b1cdbd2cSJim Jagielski /** Saves the passed record (group) together with a leading value record. */
141*b1cdbd2cSJim Jagielski template< typename Type >
lclSaveRecord(XclExpStream & rStrm,XclExpRecordRef xRec,sal_uInt16 nRecId,Type nValue)142*b1cdbd2cSJim Jagielski void lclSaveRecord( XclExpStream& rStrm, XclExpRecordRef xRec, sal_uInt16 nRecId, Type nValue )
143*b1cdbd2cSJim Jagielski {
144*b1cdbd2cSJim Jagielski     if( xRec.is() )
145*b1cdbd2cSJim Jagielski     {
146*b1cdbd2cSJim Jagielski         XclExpValueRecord< Type >( nRecId, nValue ).Save( rStrm );
147*b1cdbd2cSJim Jagielski         xRec->Save( rStrm );
148*b1cdbd2cSJim Jagielski     }
149*b1cdbd2cSJim Jagielski }
150*b1cdbd2cSJim Jagielski 
lclWriteChFrBlockRecord(XclExpStream & rStrm,const XclChFrBlock & rFrBlock,bool bBegin)151*b1cdbd2cSJim Jagielski void lclWriteChFrBlockRecord( XclExpStream& rStrm, const XclChFrBlock& rFrBlock, bool bBegin )
152*b1cdbd2cSJim Jagielski {
153*b1cdbd2cSJim Jagielski     sal_uInt16 nRecId = bBegin ? EXC_ID_CHFRBLOCKBEGIN : EXC_ID_CHFRBLOCKEND;
154*b1cdbd2cSJim Jagielski     rStrm.StartRecord( nRecId, 12 );
155*b1cdbd2cSJim Jagielski     rStrm << nRecId << EXC_FUTUREREC_EMPTYFLAGS << rFrBlock.mnType << rFrBlock.mnContext << rFrBlock.mnValue1 << rFrBlock.mnValue2;
156*b1cdbd2cSJim Jagielski     rStrm.EndRecord();
157*b1cdbd2cSJim Jagielski }
158*b1cdbd2cSJim Jagielski 
159*b1cdbd2cSJim Jagielski template< typename Type >
lclIsAutoAnyOrGetValue(Type & rValue,const Any & rAny)160*b1cdbd2cSJim Jagielski inline bool lclIsAutoAnyOrGetValue( Type& rValue, const Any& rAny )
161*b1cdbd2cSJim Jagielski {
162*b1cdbd2cSJim Jagielski     return !rAny.hasValue() || !(rAny >>= rValue);
163*b1cdbd2cSJim Jagielski }
164*b1cdbd2cSJim Jagielski 
lclIsAutoAnyOrGetScaledValue(double & rfValue,const Any & rAny,bool bLogScale)165*b1cdbd2cSJim Jagielski bool lclIsAutoAnyOrGetScaledValue( double& rfValue, const Any& rAny, bool bLogScale )
166*b1cdbd2cSJim Jagielski {
167*b1cdbd2cSJim Jagielski     bool bIsAuto = lclIsAutoAnyOrGetValue( rfValue, rAny );
168*b1cdbd2cSJim Jagielski     if( !bIsAuto && bLogScale )
169*b1cdbd2cSJim Jagielski         rfValue = log( rfValue ) / log( 10.0 );
170*b1cdbd2cSJim Jagielski     return bIsAuto;
171*b1cdbd2cSJim Jagielski }
172*b1cdbd2cSJim Jagielski 
lclGetTimeValue(const XclExpRoot & rRoot,double fSerialDate,sal_uInt16 nTimeUnit)173*b1cdbd2cSJim Jagielski sal_uInt16 lclGetTimeValue( const XclExpRoot& rRoot, double fSerialDate, sal_uInt16 nTimeUnit )
174*b1cdbd2cSJim Jagielski {
175*b1cdbd2cSJim Jagielski     DateTime aDateTime = rRoot.GetDateTimeFromDouble( fSerialDate );
176*b1cdbd2cSJim Jagielski     switch( nTimeUnit )
177*b1cdbd2cSJim Jagielski     {
178*b1cdbd2cSJim Jagielski         case EXC_CHDATERANGE_DAYS:
179*b1cdbd2cSJim Jagielski             return ::limit_cast< sal_uInt16, double >( fSerialDate, 0, SAL_MAX_UINT16 );
180*b1cdbd2cSJim Jagielski         case EXC_CHDATERANGE_MONTHS:
181*b1cdbd2cSJim Jagielski             return ::limit_cast< sal_uInt16, sal_uInt16 >( 12 * (aDateTime.GetYear() - rRoot.GetBaseYear()) + aDateTime.GetMonth() - 1, 0, SAL_MAX_INT16 );
182*b1cdbd2cSJim Jagielski         case EXC_CHDATERANGE_YEARS:
183*b1cdbd2cSJim Jagielski             return ::limit_cast< sal_uInt16, sal_uInt16 >( aDateTime.GetYear() - rRoot.GetBaseYear(), 0, SAL_MAX_INT16 );
184*b1cdbd2cSJim Jagielski         default:
185*b1cdbd2cSJim Jagielski             OSL_ENSURE( false, "lclGetTimeValue - unexpected time unit" );
186*b1cdbd2cSJim Jagielski     }
187*b1cdbd2cSJim Jagielski     return ::limit_cast< sal_uInt16, double >( fSerialDate, 0, SAL_MAX_UINT16 );
188*b1cdbd2cSJim Jagielski }
189*b1cdbd2cSJim Jagielski 
lclConvertTimeValue(const XclExpRoot & rRoot,sal_uInt16 & rnValue,const Any & rAny,sal_uInt16 nTimeUnit)190*b1cdbd2cSJim Jagielski bool lclConvertTimeValue( const XclExpRoot& rRoot, sal_uInt16& rnValue, const Any& rAny, sal_uInt16 nTimeUnit )
191*b1cdbd2cSJim Jagielski {
192*b1cdbd2cSJim Jagielski     double fSerialDate = 0;
193*b1cdbd2cSJim Jagielski     bool bAuto = lclIsAutoAnyOrGetValue( fSerialDate, rAny );
194*b1cdbd2cSJim Jagielski     if( !bAuto )
195*b1cdbd2cSJim Jagielski         rnValue = lclGetTimeValue( rRoot, fSerialDate, nTimeUnit );
196*b1cdbd2cSJim Jagielski     return bAuto;
197*b1cdbd2cSJim Jagielski }
198*b1cdbd2cSJim Jagielski 
lclGetTimeUnit(sal_Int32 nApiTimeUnit)199*b1cdbd2cSJim Jagielski sal_uInt16 lclGetTimeUnit( sal_Int32 nApiTimeUnit )
200*b1cdbd2cSJim Jagielski {
201*b1cdbd2cSJim Jagielski     switch( nApiTimeUnit )
202*b1cdbd2cSJim Jagielski     {
203*b1cdbd2cSJim Jagielski         case cssc::TimeUnit::DAY:   return EXC_CHDATERANGE_DAYS;
204*b1cdbd2cSJim Jagielski         case cssc::TimeUnit::MONTH: return EXC_CHDATERANGE_MONTHS;
205*b1cdbd2cSJim Jagielski         case cssc::TimeUnit::YEAR:  return EXC_CHDATERANGE_YEARS;
206*b1cdbd2cSJim Jagielski         default:                    OSL_ENSURE( false, "lclGetTimeUnit - unexpected time unit" );
207*b1cdbd2cSJim Jagielski     }
208*b1cdbd2cSJim Jagielski     return EXC_CHDATERANGE_DAYS;
209*b1cdbd2cSJim Jagielski }
210*b1cdbd2cSJim Jagielski 
lclConvertTimeInterval(sal_uInt16 & rnValue,sal_uInt16 & rnTimeUnit,const Any & rAny)211*b1cdbd2cSJim Jagielski bool lclConvertTimeInterval( sal_uInt16& rnValue, sal_uInt16& rnTimeUnit, const Any& rAny )
212*b1cdbd2cSJim Jagielski {
213*b1cdbd2cSJim Jagielski     cssc::TimeInterval aInterval;
214*b1cdbd2cSJim Jagielski     bool bAuto = lclIsAutoAnyOrGetValue( aInterval, rAny );
215*b1cdbd2cSJim Jagielski     if( !bAuto )
216*b1cdbd2cSJim Jagielski     {
217*b1cdbd2cSJim Jagielski         rnValue = ::limit_cast< sal_uInt16, sal_Int32 >( aInterval.Number, 1, SAL_MAX_UINT16 );
218*b1cdbd2cSJim Jagielski         rnTimeUnit = lclGetTimeUnit( aInterval.TimeUnit );
219*b1cdbd2cSJim Jagielski     }
220*b1cdbd2cSJim Jagielski     return bAuto;
221*b1cdbd2cSJim Jagielski }
222*b1cdbd2cSJim Jagielski 
223*b1cdbd2cSJim Jagielski } // namespace
224*b1cdbd2cSJim Jagielski 
225*b1cdbd2cSJim Jagielski // Common =====================================================================
226*b1cdbd2cSJim Jagielski 
227*b1cdbd2cSJim Jagielski /** Stores global data needed in various classes of the Chart export filter. */
228*b1cdbd2cSJim Jagielski struct XclExpChRootData : public XclChRootData
229*b1cdbd2cSJim Jagielski {
230*b1cdbd2cSJim Jagielski     typedef ::std::vector< XclChFrBlock > XclChFrBlockVector;
231*b1cdbd2cSJim Jagielski 
232*b1cdbd2cSJim Jagielski     XclExpChChart&      mrChartData;            /// The chart data object.
233*b1cdbd2cSJim Jagielski     XclChFrBlockVector  maWrittenFrBlocks;      /// Stack of future record levels already written out.
234*b1cdbd2cSJim Jagielski     XclChFrBlockVector  maUnwrittenFrBlocks;    /// Stack of future record levels not yet written out.
235*b1cdbd2cSJim Jagielski 
XclExpChRootDataXclExpChRootData236*b1cdbd2cSJim Jagielski     inline explicit     XclExpChRootData( XclExpChChart& rChartData ) : mrChartData( rChartData ) {}
237*b1cdbd2cSJim Jagielski 
238*b1cdbd2cSJim Jagielski     /** Registers a new future record level. */
239*b1cdbd2cSJim Jagielski     void                RegisterFutureRecBlock( const XclChFrBlock& rFrBlock );
240*b1cdbd2cSJim Jagielski     /** Initializes the current future record level (writes all unwritten CHFRBLOCKBEGIN records). */
241*b1cdbd2cSJim Jagielski     void                InitializeFutureRecBlock( XclExpStream& rStrm );
242*b1cdbd2cSJim Jagielski     /** Finalizes the current future record level (writes CHFRBLOCKEND record if needed). */
243*b1cdbd2cSJim Jagielski     void                FinalizeFutureRecBlock( XclExpStream& rStrm );
244*b1cdbd2cSJim Jagielski };
245*b1cdbd2cSJim Jagielski 
246*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
247*b1cdbd2cSJim Jagielski 
RegisterFutureRecBlock(const XclChFrBlock & rFrBlock)248*b1cdbd2cSJim Jagielski void XclExpChRootData::RegisterFutureRecBlock( const XclChFrBlock& rFrBlock )
249*b1cdbd2cSJim Jagielski {
250*b1cdbd2cSJim Jagielski     maUnwrittenFrBlocks.push_back( rFrBlock );
251*b1cdbd2cSJim Jagielski }
252*b1cdbd2cSJim Jagielski 
InitializeFutureRecBlock(XclExpStream & rStrm)253*b1cdbd2cSJim Jagielski void XclExpChRootData::InitializeFutureRecBlock( XclExpStream& rStrm )
254*b1cdbd2cSJim Jagielski {
255*b1cdbd2cSJim Jagielski     // first call from a future record writes all missing CHFRBLOCKBEGIN records
256*b1cdbd2cSJim Jagielski     if( !maUnwrittenFrBlocks.empty() )
257*b1cdbd2cSJim Jagielski     {
258*b1cdbd2cSJim Jagielski         // write the leading CHFRINFO record
259*b1cdbd2cSJim Jagielski         if( maWrittenFrBlocks.empty() )
260*b1cdbd2cSJim Jagielski         {
261*b1cdbd2cSJim Jagielski             rStrm.StartRecord( EXC_ID_CHFRINFO, 20 );
262*b1cdbd2cSJim Jagielski             rStrm << EXC_ID_CHFRINFO << EXC_FUTUREREC_EMPTYFLAGS << EXC_CHFRINFO_EXCELXP2003 << EXC_CHFRINFO_EXCELXP2003 << sal_uInt16( 3 );
263*b1cdbd2cSJim Jagielski             rStrm << sal_uInt16( 0x0850 ) << sal_uInt16( 0x085A ) << sal_uInt16( 0x0861 ) << sal_uInt16( 0x0861 ) << sal_uInt16( 0x086A ) << sal_uInt16( 0x086B );
264*b1cdbd2cSJim Jagielski             rStrm.EndRecord();
265*b1cdbd2cSJim Jagielski         }
266*b1cdbd2cSJim Jagielski         // write all unwritten CHFRBLOCKBEGIN records
267*b1cdbd2cSJim Jagielski         for( XclChFrBlockVector::const_iterator aIt = maUnwrittenFrBlocks.begin(), aEnd = maUnwrittenFrBlocks.end(); aIt != aEnd; ++aIt )
268*b1cdbd2cSJim Jagielski         {
269*b1cdbd2cSJim Jagielski             DBG_ASSERT( aIt->mnType != EXC_CHFRBLOCK_TYPE_UNKNOWN, "XclExpChRootData::InitializeFutureRecBlock - unknown future record block type" );
270*b1cdbd2cSJim Jagielski             lclWriteChFrBlockRecord( rStrm, *aIt, true );
271*b1cdbd2cSJim Jagielski         }
272*b1cdbd2cSJim Jagielski         // move all record infos to vector of written blocks
273*b1cdbd2cSJim Jagielski         maWrittenFrBlocks.insert( maWrittenFrBlocks.end(), maUnwrittenFrBlocks.begin(), maUnwrittenFrBlocks.end() );
274*b1cdbd2cSJim Jagielski         maUnwrittenFrBlocks.clear();
275*b1cdbd2cSJim Jagielski     }
276*b1cdbd2cSJim Jagielski }
277*b1cdbd2cSJim Jagielski 
FinalizeFutureRecBlock(XclExpStream & rStrm)278*b1cdbd2cSJim Jagielski void XclExpChRootData::FinalizeFutureRecBlock( XclExpStream& rStrm )
279*b1cdbd2cSJim Jagielski {
280*b1cdbd2cSJim Jagielski     DBG_ASSERT( !maUnwrittenFrBlocks.empty() || !maWrittenFrBlocks.empty(), "XclExpChRootData::FinalizeFutureRecBlock - no future record level found" );
281*b1cdbd2cSJim Jagielski     if( !maUnwrittenFrBlocks.empty() )
282*b1cdbd2cSJim Jagielski     {
283*b1cdbd2cSJim Jagielski         // no future record has been written, just forget the topmost level
284*b1cdbd2cSJim Jagielski         maUnwrittenFrBlocks.pop_back();
285*b1cdbd2cSJim Jagielski     }
286*b1cdbd2cSJim Jagielski     else if( !maWrittenFrBlocks.empty() )
287*b1cdbd2cSJim Jagielski     {
288*b1cdbd2cSJim Jagielski         // write the CHFRBLOCKEND record for the topmost block and delete it
289*b1cdbd2cSJim Jagielski         lclWriteChFrBlockRecord( rStrm, maWrittenFrBlocks.back(), false );
290*b1cdbd2cSJim Jagielski         maWrittenFrBlocks.pop_back();
291*b1cdbd2cSJim Jagielski     }
292*b1cdbd2cSJim Jagielski }
293*b1cdbd2cSJim Jagielski 
294*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
295*b1cdbd2cSJim Jagielski 
XclExpChRoot(const XclExpRoot & rRoot,XclExpChChart & rChartData)296*b1cdbd2cSJim Jagielski XclExpChRoot::XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart& rChartData ) :
297*b1cdbd2cSJim Jagielski     XclExpRoot( rRoot ),
298*b1cdbd2cSJim Jagielski     mxChData( new XclExpChRootData( rChartData ) )
299*b1cdbd2cSJim Jagielski {
300*b1cdbd2cSJim Jagielski }
301*b1cdbd2cSJim Jagielski 
~XclExpChRoot()302*b1cdbd2cSJim Jagielski XclExpChRoot::~XclExpChRoot()
303*b1cdbd2cSJim Jagielski {
304*b1cdbd2cSJim Jagielski }
305*b1cdbd2cSJim Jagielski 
GetChartDocument() const306*b1cdbd2cSJim Jagielski Reference< XChartDocument > XclExpChRoot::GetChartDocument() const
307*b1cdbd2cSJim Jagielski {
308*b1cdbd2cSJim Jagielski     return mxChData->mxChartDoc;
309*b1cdbd2cSJim Jagielski }
310*b1cdbd2cSJim Jagielski 
GetChartData() const311*b1cdbd2cSJim Jagielski XclExpChChart& XclExpChRoot::GetChartData() const
312*b1cdbd2cSJim Jagielski {
313*b1cdbd2cSJim Jagielski     return mxChData->mrChartData;
314*b1cdbd2cSJim Jagielski }
315*b1cdbd2cSJim Jagielski 
GetChartTypeInfo(XclChTypeId eType) const316*b1cdbd2cSJim Jagielski const XclChTypeInfo& XclExpChRoot::GetChartTypeInfo( XclChTypeId eType ) const
317*b1cdbd2cSJim Jagielski {
318*b1cdbd2cSJim Jagielski     return mxChData->mxTypeInfoProv->GetTypeInfo( eType );
319*b1cdbd2cSJim Jagielski }
320*b1cdbd2cSJim Jagielski 
GetChartTypeInfo(const OUString & rServiceName) const321*b1cdbd2cSJim Jagielski const XclChTypeInfo& XclExpChRoot::GetChartTypeInfo( const OUString& rServiceName ) const
322*b1cdbd2cSJim Jagielski {
323*b1cdbd2cSJim Jagielski     return mxChData->mxTypeInfoProv->GetTypeInfoFromService( rServiceName );
324*b1cdbd2cSJim Jagielski }
325*b1cdbd2cSJim Jagielski 
GetFormatInfo(XclChObjectType eObjType) const326*b1cdbd2cSJim Jagielski const XclChFormatInfo& XclExpChRoot::GetFormatInfo( XclChObjectType eObjType ) const
327*b1cdbd2cSJim Jagielski {
328*b1cdbd2cSJim Jagielski     return mxChData->mxFmtInfoProv->GetFormatInfo( eObjType );
329*b1cdbd2cSJim Jagielski }
330*b1cdbd2cSJim Jagielski 
InitConversion(XChartDocRef xChartDoc,const Rectangle & rChartRect) const331*b1cdbd2cSJim Jagielski void XclExpChRoot::InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const
332*b1cdbd2cSJim Jagielski {
333*b1cdbd2cSJim Jagielski     mxChData->InitConversion( GetRoot(), xChartDoc, rChartRect );
334*b1cdbd2cSJim Jagielski }
335*b1cdbd2cSJim Jagielski 
FinishConversion() const336*b1cdbd2cSJim Jagielski void XclExpChRoot::FinishConversion() const
337*b1cdbd2cSJim Jagielski {
338*b1cdbd2cSJim Jagielski     mxChData->FinishConversion();
339*b1cdbd2cSJim Jagielski }
340*b1cdbd2cSJim Jagielski 
IsSystemColor(const Color & rColor,sal_uInt16 nSysColorIdx) const341*b1cdbd2cSJim Jagielski bool XclExpChRoot::IsSystemColor( const Color& rColor, sal_uInt16 nSysColorIdx ) const
342*b1cdbd2cSJim Jagielski {
343*b1cdbd2cSJim Jagielski     XclExpPalette& rPal = GetPalette();
344*b1cdbd2cSJim Jagielski     return rPal.IsSystemColor( nSysColorIdx ) && (rColor == rPal.GetDefColor( nSysColorIdx ));
345*b1cdbd2cSJim Jagielski }
346*b1cdbd2cSJim Jagielski 
SetSystemColor(Color & rColor,sal_uInt32 & rnColorId,sal_uInt16 nSysColorIdx) const347*b1cdbd2cSJim Jagielski void XclExpChRoot::SetSystemColor( Color& rColor, sal_uInt32& rnColorId, sal_uInt16 nSysColorIdx ) const
348*b1cdbd2cSJim Jagielski {
349*b1cdbd2cSJim Jagielski     DBG_ASSERT( GetPalette().IsSystemColor( nSysColorIdx ), "XclExpChRoot::SetSystemColor - invalid color index" );
350*b1cdbd2cSJim Jagielski     rColor = GetPalette().GetDefColor( nSysColorIdx );
351*b1cdbd2cSJim Jagielski     rnColorId = XclExpPalette::GetColorIdFromIndex( nSysColorIdx );
352*b1cdbd2cSJim Jagielski }
353*b1cdbd2cSJim Jagielski 
CalcChartXFromHmm(sal_Int32 nPosX) const354*b1cdbd2cSJim Jagielski sal_Int32 XclExpChRoot::CalcChartXFromHmm( sal_Int32 nPosX ) const
355*b1cdbd2cSJim Jagielski {
356*b1cdbd2cSJim Jagielski     return ::limit_cast< sal_Int32, double >( (nPosX - mxChData->mnBorderGapX) / mxChData->mfUnitSizeX, 0, EXC_CHART_TOTALUNITS );
357*b1cdbd2cSJim Jagielski }
358*b1cdbd2cSJim Jagielski 
CalcChartYFromHmm(sal_Int32 nPosY) const359*b1cdbd2cSJim Jagielski sal_Int32 XclExpChRoot::CalcChartYFromHmm( sal_Int32 nPosY ) const
360*b1cdbd2cSJim Jagielski {
361*b1cdbd2cSJim Jagielski     return ::limit_cast< sal_Int32, double >( (nPosY - mxChData->mnBorderGapY) / mxChData->mfUnitSizeY, 0, EXC_CHART_TOTALUNITS );
362*b1cdbd2cSJim Jagielski }
363*b1cdbd2cSJim Jagielski 
CalcChartRectFromHmm(const::com::sun::star::awt::Rectangle & rRect) const364*b1cdbd2cSJim Jagielski XclChRectangle XclExpChRoot::CalcChartRectFromHmm( const ::com::sun::star::awt::Rectangle& rRect ) const
365*b1cdbd2cSJim Jagielski {
366*b1cdbd2cSJim Jagielski     XclChRectangle aRect;
367*b1cdbd2cSJim Jagielski     aRect.mnX = CalcChartXFromHmm( rRect.X );
368*b1cdbd2cSJim Jagielski     aRect.mnY = CalcChartYFromHmm( rRect.Y );
369*b1cdbd2cSJim Jagielski     aRect.mnWidth = CalcChartXFromHmm( rRect.Width );
370*b1cdbd2cSJim Jagielski     aRect.mnHeight = CalcChartYFromHmm( rRect.Height );
371*b1cdbd2cSJim Jagielski     return aRect;
372*b1cdbd2cSJim Jagielski }
373*b1cdbd2cSJim Jagielski 
CalcChartXFromRelative(double fPosX) const374*b1cdbd2cSJim Jagielski sal_Int32 XclExpChRoot::CalcChartXFromRelative( double fPosX ) const
375*b1cdbd2cSJim Jagielski {
376*b1cdbd2cSJim Jagielski     return CalcChartXFromHmm( static_cast< sal_Int32 >( fPosX * mxChData->maChartRect.GetWidth() + 0.5 ) );
377*b1cdbd2cSJim Jagielski }
378*b1cdbd2cSJim Jagielski 
CalcChartYFromRelative(double fPosY) const379*b1cdbd2cSJim Jagielski sal_Int32 XclExpChRoot::CalcChartYFromRelative( double fPosY ) const
380*b1cdbd2cSJim Jagielski {
381*b1cdbd2cSJim Jagielski     return CalcChartYFromHmm( static_cast< sal_Int32 >( fPosY * mxChData->maChartRect.GetHeight() + 0.5 ) );
382*b1cdbd2cSJim Jagielski }
383*b1cdbd2cSJim Jagielski 
ConvertLineFormat(XclChLineFormat & rLineFmt,const ScfPropertySet & rPropSet,XclChPropertyMode ePropMode) const384*b1cdbd2cSJim Jagielski void XclExpChRoot::ConvertLineFormat( XclChLineFormat& rLineFmt,
385*b1cdbd2cSJim Jagielski         const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
386*b1cdbd2cSJim Jagielski {
387*b1cdbd2cSJim Jagielski     GetChartPropSetHelper().ReadLineProperties(
388*b1cdbd2cSJim Jagielski         rLineFmt, *mxChData->mxLineDashTable, rPropSet, ePropMode );
389*b1cdbd2cSJim Jagielski }
390*b1cdbd2cSJim Jagielski 
ConvertAreaFormat(XclChAreaFormat & rAreaFmt,const ScfPropertySet & rPropSet,XclChPropertyMode ePropMode) const391*b1cdbd2cSJim Jagielski bool XclExpChRoot::ConvertAreaFormat( XclChAreaFormat& rAreaFmt,
392*b1cdbd2cSJim Jagielski         const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
393*b1cdbd2cSJim Jagielski {
394*b1cdbd2cSJim Jagielski     return GetChartPropSetHelper().ReadAreaProperties( rAreaFmt, rPropSet, ePropMode );
395*b1cdbd2cSJim Jagielski }
396*b1cdbd2cSJim Jagielski 
ConvertEscherFormat(XclChEscherFormat & rEscherFmt,XclChPicFormat & rPicFmt,const ScfPropertySet & rPropSet,XclChPropertyMode ePropMode) const397*b1cdbd2cSJim Jagielski void XclExpChRoot::ConvertEscherFormat(
398*b1cdbd2cSJim Jagielski         XclChEscherFormat& rEscherFmt, XclChPicFormat& rPicFmt,
399*b1cdbd2cSJim Jagielski         const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
400*b1cdbd2cSJim Jagielski {
401*b1cdbd2cSJim Jagielski     GetChartPropSetHelper().ReadEscherProperties( rEscherFmt, rPicFmt,
402*b1cdbd2cSJim Jagielski         *mxChData->mxGradientTable, *mxChData->mxHatchTable, *mxChData->mxBitmapTable, rPropSet, ePropMode );
403*b1cdbd2cSJim Jagielski }
404*b1cdbd2cSJim Jagielski 
ConvertFont(const ScfPropertySet & rPropSet,sal_Int16 nScript) const405*b1cdbd2cSJim Jagielski sal_uInt16 XclExpChRoot::ConvertFont( const ScfPropertySet& rPropSet, sal_Int16 nScript ) const
406*b1cdbd2cSJim Jagielski {
407*b1cdbd2cSJim Jagielski     XclFontData aFontData;
408*b1cdbd2cSJim Jagielski     GetFontPropSetHelper().ReadFontProperties( aFontData, rPropSet, EXC_FONTPROPSET_CHART, nScript );
409*b1cdbd2cSJim Jagielski     return GetFontBuffer().Insert( aFontData, EXC_COLOR_CHARTTEXT );
410*b1cdbd2cSJim Jagielski }
411*b1cdbd2cSJim Jagielski 
ConvertPieRotation(const ScfPropertySet & rPropSet)412*b1cdbd2cSJim Jagielski sal_uInt16 XclExpChRoot::ConvertPieRotation( const ScfPropertySet& rPropSet )
413*b1cdbd2cSJim Jagielski {
414*b1cdbd2cSJim Jagielski     sal_Int32 nApiRot = 0;
415*b1cdbd2cSJim Jagielski     rPropSet.GetProperty( nApiRot, EXC_CHPROP_STARTINGANGLE );
416*b1cdbd2cSJim Jagielski     return static_cast< sal_uInt16 >( (450 - (nApiRot % 360)) % 360 );
417*b1cdbd2cSJim Jagielski }
418*b1cdbd2cSJim Jagielski 
RegisterFutureRecBlock(const XclChFrBlock & rFrBlock)419*b1cdbd2cSJim Jagielski void XclExpChRoot::RegisterFutureRecBlock( const XclChFrBlock& rFrBlock )
420*b1cdbd2cSJim Jagielski {
421*b1cdbd2cSJim Jagielski     mxChData->RegisterFutureRecBlock( rFrBlock );
422*b1cdbd2cSJim Jagielski }
423*b1cdbd2cSJim Jagielski 
InitializeFutureRecBlock(XclExpStream & rStrm)424*b1cdbd2cSJim Jagielski void XclExpChRoot::InitializeFutureRecBlock( XclExpStream& rStrm )
425*b1cdbd2cSJim Jagielski {
426*b1cdbd2cSJim Jagielski     mxChData->InitializeFutureRecBlock( rStrm );
427*b1cdbd2cSJim Jagielski }
428*b1cdbd2cSJim Jagielski 
FinalizeFutureRecBlock(XclExpStream & rStrm)429*b1cdbd2cSJim Jagielski void XclExpChRoot::FinalizeFutureRecBlock( XclExpStream& rStrm )
430*b1cdbd2cSJim Jagielski {
431*b1cdbd2cSJim Jagielski     mxChData->FinalizeFutureRecBlock( rStrm );
432*b1cdbd2cSJim Jagielski }
433*b1cdbd2cSJim Jagielski 
434*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
435*b1cdbd2cSJim Jagielski 
XclExpChGroupBase(const XclExpChRoot & rRoot,sal_uInt16 nFrType,sal_uInt16 nRecId,sal_Size nRecSize)436*b1cdbd2cSJim Jagielski XclExpChGroupBase::XclExpChGroupBase( const XclExpChRoot& rRoot,
437*b1cdbd2cSJim Jagielski         sal_uInt16 nFrType, sal_uInt16 nRecId, sal_Size nRecSize ) :
438*b1cdbd2cSJim Jagielski     XclExpRecord( nRecId, nRecSize ),
439*b1cdbd2cSJim Jagielski     XclExpChRoot( rRoot ),
440*b1cdbd2cSJim Jagielski     maFrBlock( nFrType )
441*b1cdbd2cSJim Jagielski {
442*b1cdbd2cSJim Jagielski }
443*b1cdbd2cSJim Jagielski 
~XclExpChGroupBase()444*b1cdbd2cSJim Jagielski XclExpChGroupBase::~XclExpChGroupBase()
445*b1cdbd2cSJim Jagielski {
446*b1cdbd2cSJim Jagielski }
447*b1cdbd2cSJim Jagielski 
Save(XclExpStream & rStrm)448*b1cdbd2cSJim Jagielski void XclExpChGroupBase::Save( XclExpStream& rStrm )
449*b1cdbd2cSJim Jagielski {
450*b1cdbd2cSJim Jagielski     // header record
451*b1cdbd2cSJim Jagielski     XclExpRecord::Save( rStrm );
452*b1cdbd2cSJim Jagielski     // group records
453*b1cdbd2cSJim Jagielski     if( HasSubRecords() )
454*b1cdbd2cSJim Jagielski     {
455*b1cdbd2cSJim Jagielski         // register the future record context corresponding to this record group
456*b1cdbd2cSJim Jagielski         RegisterFutureRecBlock( maFrBlock );
457*b1cdbd2cSJim Jagielski         // CHBEGIN record
458*b1cdbd2cSJim Jagielski         XclExpEmptyRecord( EXC_ID_CHBEGIN ).Save( rStrm );
459*b1cdbd2cSJim Jagielski         // embedded records
460*b1cdbd2cSJim Jagielski         WriteSubRecords( rStrm );
461*b1cdbd2cSJim Jagielski         // finalize the future records, must be done before the closing CHEND
462*b1cdbd2cSJim Jagielski         FinalizeFutureRecBlock( rStrm );
463*b1cdbd2cSJim Jagielski         // CHEND record
464*b1cdbd2cSJim Jagielski         XclExpEmptyRecord( EXC_ID_CHEND ).Save( rStrm );
465*b1cdbd2cSJim Jagielski     }
466*b1cdbd2cSJim Jagielski }
467*b1cdbd2cSJim Jagielski 
HasSubRecords() const468*b1cdbd2cSJim Jagielski bool XclExpChGroupBase::HasSubRecords() const
469*b1cdbd2cSJim Jagielski {
470*b1cdbd2cSJim Jagielski     return true;
471*b1cdbd2cSJim Jagielski }
472*b1cdbd2cSJim Jagielski 
SetFutureRecordContext(sal_uInt16 nFrContext,sal_uInt16 nFrValue1,sal_uInt16 nFrValue2)473*b1cdbd2cSJim Jagielski void XclExpChGroupBase::SetFutureRecordContext( sal_uInt16 nFrContext, sal_uInt16 nFrValue1, sal_uInt16 nFrValue2 )
474*b1cdbd2cSJim Jagielski {
475*b1cdbd2cSJim Jagielski     maFrBlock.mnContext = nFrContext;
476*b1cdbd2cSJim Jagielski     maFrBlock.mnValue1  = nFrValue1;
477*b1cdbd2cSJim Jagielski     maFrBlock.mnValue2  = nFrValue2;
478*b1cdbd2cSJim Jagielski }
479*b1cdbd2cSJim Jagielski 
480*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
481*b1cdbd2cSJim Jagielski 
XclExpChFutureRecordBase(const XclExpChRoot & rRoot,XclFutureRecType eRecType,sal_uInt16 nRecId,sal_Size nRecSize)482*b1cdbd2cSJim Jagielski XclExpChFutureRecordBase::XclExpChFutureRecordBase( const XclExpChRoot& rRoot,
483*b1cdbd2cSJim Jagielski         XclFutureRecType eRecType, sal_uInt16 nRecId, sal_Size nRecSize ) :
484*b1cdbd2cSJim Jagielski     XclExpFutureRecord( eRecType, nRecId, nRecSize ),
485*b1cdbd2cSJim Jagielski     XclExpChRoot( rRoot )
486*b1cdbd2cSJim Jagielski {
487*b1cdbd2cSJim Jagielski }
488*b1cdbd2cSJim Jagielski 
Save(XclExpStream & rStrm)489*b1cdbd2cSJim Jagielski void XclExpChFutureRecordBase::Save( XclExpStream& rStrm )
490*b1cdbd2cSJim Jagielski {
491*b1cdbd2cSJim Jagielski     InitializeFutureRecBlock( rStrm );
492*b1cdbd2cSJim Jagielski     XclExpFutureRecord::Save( rStrm );
493*b1cdbd2cSJim Jagielski }
494*b1cdbd2cSJim Jagielski 
495*b1cdbd2cSJim Jagielski // Frame formatting ===========================================================
496*b1cdbd2cSJim Jagielski 
XclExpChFramePos(sal_uInt16 nTLMode,sal_uInt16 nBRMode)497*b1cdbd2cSJim Jagielski XclExpChFramePos::XclExpChFramePos( sal_uInt16 nTLMode, sal_uInt16 nBRMode ) :
498*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CHFRAMEPOS, 20 )
499*b1cdbd2cSJim Jagielski {
500*b1cdbd2cSJim Jagielski     maData.mnTLMode = nTLMode;
501*b1cdbd2cSJim Jagielski     maData.mnBRMode = nBRMode;
502*b1cdbd2cSJim Jagielski }
503*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)504*b1cdbd2cSJim Jagielski void XclExpChFramePos::WriteBody( XclExpStream& rStrm )
505*b1cdbd2cSJim Jagielski {
506*b1cdbd2cSJim Jagielski     rStrm << maData.mnTLMode << maData.mnBRMode << maData.maRect;
507*b1cdbd2cSJim Jagielski }
508*b1cdbd2cSJim Jagielski 
509*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
510*b1cdbd2cSJim Jagielski 
XclExpChLineFormat(const XclExpChRoot & rRoot)511*b1cdbd2cSJim Jagielski XclExpChLineFormat::XclExpChLineFormat( const XclExpChRoot& rRoot ) :
512*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CHLINEFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 12 : 10 ),
513*b1cdbd2cSJim Jagielski     mnColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
514*b1cdbd2cSJim Jagielski {
515*b1cdbd2cSJim Jagielski }
516*b1cdbd2cSJim Jagielski 
SetDefault(XclChFrameType eDefFrameType)517*b1cdbd2cSJim Jagielski void XclExpChLineFormat::SetDefault( XclChFrameType eDefFrameType )
518*b1cdbd2cSJim Jagielski {
519*b1cdbd2cSJim Jagielski     switch( eDefFrameType )
520*b1cdbd2cSJim Jagielski     {
521*b1cdbd2cSJim Jagielski         case EXC_CHFRAMETYPE_AUTO:
522*b1cdbd2cSJim Jagielski             SetAuto( true );
523*b1cdbd2cSJim Jagielski         break;
524*b1cdbd2cSJim Jagielski         case EXC_CHFRAMETYPE_INVISIBLE:
525*b1cdbd2cSJim Jagielski             SetAuto( false );
526*b1cdbd2cSJim Jagielski             maData.mnPattern = EXC_CHLINEFORMAT_NONE;
527*b1cdbd2cSJim Jagielski         break;
528*b1cdbd2cSJim Jagielski         default:
529*b1cdbd2cSJim Jagielski             DBG_ERRORFILE( "XclExpChLineFormat::SetDefault - unknown frame type" );
530*b1cdbd2cSJim Jagielski     }
531*b1cdbd2cSJim Jagielski }
532*b1cdbd2cSJim Jagielski 
Convert(const XclExpChRoot & rRoot,const ScfPropertySet & rPropSet,XclChObjectType eObjType)533*b1cdbd2cSJim Jagielski void XclExpChLineFormat::Convert( const XclExpChRoot& rRoot,
534*b1cdbd2cSJim Jagielski         const ScfPropertySet& rPropSet, XclChObjectType eObjType )
535*b1cdbd2cSJim Jagielski {
536*b1cdbd2cSJim Jagielski     const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
537*b1cdbd2cSJim Jagielski     rRoot.ConvertLineFormat( maData, rPropSet, rFmtInfo.mePropMode );
538*b1cdbd2cSJim Jagielski     if( HasLine() )
539*b1cdbd2cSJim Jagielski     {
540*b1cdbd2cSJim Jagielski         // detect system color, set color identifier (TODO: detect automatic series line)
541*b1cdbd2cSJim Jagielski         if( (eObjType != EXC_CHOBJTYPE_LINEARSERIES) && rRoot.IsSystemColor( maData.maColor, rFmtInfo.mnAutoLineColorIdx ) )
542*b1cdbd2cSJim Jagielski         {
543*b1cdbd2cSJim Jagielski             // store color index from automatic format data
544*b1cdbd2cSJim Jagielski             mnColorId = XclExpPalette::GetColorIdFromIndex( rFmtInfo.mnAutoLineColorIdx );
545*b1cdbd2cSJim Jagielski             // try to set automatic mode
546*b1cdbd2cSJim Jagielski             bool bAuto = (maData.mnPattern == EXC_CHLINEFORMAT_SOLID) && (maData.mnWeight == rFmtInfo.mnAutoLineWeight);
547*b1cdbd2cSJim Jagielski             ::set_flag( maData.mnFlags, EXC_CHLINEFORMAT_AUTO, bAuto );
548*b1cdbd2cSJim Jagielski         }
549*b1cdbd2cSJim Jagielski         else
550*b1cdbd2cSJim Jagielski         {
551*b1cdbd2cSJim Jagielski             // user defined color - register in palette
552*b1cdbd2cSJim Jagielski             mnColorId = rRoot.GetPalette().InsertColor( maData.maColor, EXC_COLOR_CHARTLINE );
553*b1cdbd2cSJim Jagielski         }
554*b1cdbd2cSJim Jagielski     }
555*b1cdbd2cSJim Jagielski     else
556*b1cdbd2cSJim Jagielski     {
557*b1cdbd2cSJim Jagielski         // no line - set default system color
558*b1cdbd2cSJim Jagielski         rRoot.SetSystemColor( maData.maColor, mnColorId, EXC_COLOR_CHWINDOWTEXT );
559*b1cdbd2cSJim Jagielski     }
560*b1cdbd2cSJim Jagielski }
561*b1cdbd2cSJim Jagielski 
IsDefault(XclChFrameType eDefFrameType) const562*b1cdbd2cSJim Jagielski bool XclExpChLineFormat::IsDefault( XclChFrameType eDefFrameType ) const
563*b1cdbd2cSJim Jagielski {
564*b1cdbd2cSJim Jagielski     return
565*b1cdbd2cSJim Jagielski         ((eDefFrameType == EXC_CHFRAMETYPE_INVISIBLE) && !HasLine()) ||
566*b1cdbd2cSJim Jagielski         ((eDefFrameType == EXC_CHFRAMETYPE_AUTO) && IsAuto());
567*b1cdbd2cSJim Jagielski }
568*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)569*b1cdbd2cSJim Jagielski void XclExpChLineFormat::WriteBody( XclExpStream& rStrm )
570*b1cdbd2cSJim Jagielski {
571*b1cdbd2cSJim Jagielski     rStrm << maData.maColor << maData.mnPattern << maData.mnWeight << maData.mnFlags;
572*b1cdbd2cSJim Jagielski     if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
573*b1cdbd2cSJim Jagielski         rStrm << rStrm.GetRoot().GetPalette().GetColorIndex( mnColorId );
574*b1cdbd2cSJim Jagielski }
575*b1cdbd2cSJim Jagielski 
576*b1cdbd2cSJim Jagielski namespace {
577*b1cdbd2cSJim Jagielski 
578*b1cdbd2cSJim Jagielski /** Creates a CHLINEFORMAT record from the passed property set. */
lclCreateLineFormat(const XclExpChRoot & rRoot,const ScfPropertySet & rPropSet,XclChObjectType eObjType)579*b1cdbd2cSJim Jagielski XclExpChLineFormatRef lclCreateLineFormat( const XclExpChRoot& rRoot,
580*b1cdbd2cSJim Jagielski         const ScfPropertySet& rPropSet, XclChObjectType eObjType )
581*b1cdbd2cSJim Jagielski {
582*b1cdbd2cSJim Jagielski     XclExpChLineFormatRef xLineFmt( new XclExpChLineFormat( rRoot ) );
583*b1cdbd2cSJim Jagielski     xLineFmt->Convert( rRoot, rPropSet, eObjType );
584*b1cdbd2cSJim Jagielski     const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
585*b1cdbd2cSJim Jagielski     if( rFmtInfo.mbDeleteDefFrame && xLineFmt->IsDefault( rFmtInfo.meDefFrameType ) )
586*b1cdbd2cSJim Jagielski         xLineFmt.reset();
587*b1cdbd2cSJim Jagielski     return xLineFmt;
588*b1cdbd2cSJim Jagielski }
589*b1cdbd2cSJim Jagielski 
590*b1cdbd2cSJim Jagielski } // namespace
591*b1cdbd2cSJim Jagielski 
592*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
593*b1cdbd2cSJim Jagielski 
XclExpChAreaFormat(const XclExpChRoot & rRoot)594*b1cdbd2cSJim Jagielski XclExpChAreaFormat::XclExpChAreaFormat( const XclExpChRoot& rRoot ) :
595*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CHAREAFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 16 : 12 ),
596*b1cdbd2cSJim Jagielski     mnPattColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) ),
597*b1cdbd2cSJim Jagielski     mnBackColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
598*b1cdbd2cSJim Jagielski {
599*b1cdbd2cSJim Jagielski }
600*b1cdbd2cSJim Jagielski 
Convert(const XclExpChRoot & rRoot,const ScfPropertySet & rPropSet,XclChObjectType eObjType)601*b1cdbd2cSJim Jagielski bool XclExpChAreaFormat::Convert( const XclExpChRoot& rRoot,
602*b1cdbd2cSJim Jagielski         const ScfPropertySet& rPropSet, XclChObjectType eObjType )
603*b1cdbd2cSJim Jagielski {
604*b1cdbd2cSJim Jagielski     const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
605*b1cdbd2cSJim Jagielski     bool bComplexFill = rRoot.ConvertAreaFormat( maData, rPropSet, rFmtInfo.mePropMode );
606*b1cdbd2cSJim Jagielski     if( HasArea() )
607*b1cdbd2cSJim Jagielski     {
608*b1cdbd2cSJim Jagielski         bool bSolid = maData.mnPattern == EXC_PATT_SOLID;
609*b1cdbd2cSJim Jagielski         // detect system color, set color identifier (TODO: detect automatic series area)
610*b1cdbd2cSJim Jagielski         if( (eObjType != EXC_CHOBJTYPE_FILLEDSERIES) && rRoot.IsSystemColor( maData.maPattColor, rFmtInfo.mnAutoPattColorIdx ) )
611*b1cdbd2cSJim Jagielski         {
612*b1cdbd2cSJim Jagielski             // store color index from automatic format data
613*b1cdbd2cSJim Jagielski             mnPattColorId = XclExpPalette::GetColorIdFromIndex( rFmtInfo.mnAutoPattColorIdx );
614*b1cdbd2cSJim Jagielski             // set automatic mode
615*b1cdbd2cSJim Jagielski             ::set_flag( maData.mnFlags, EXC_CHAREAFORMAT_AUTO, bSolid );
616*b1cdbd2cSJim Jagielski         }
617*b1cdbd2cSJim Jagielski         else
618*b1cdbd2cSJim Jagielski         {
619*b1cdbd2cSJim Jagielski             // user defined color - register color in palette
620*b1cdbd2cSJim Jagielski             mnPattColorId = rRoot.GetPalette().InsertColor( maData.maPattColor, EXC_COLOR_CHARTAREA );
621*b1cdbd2cSJim Jagielski         }
622*b1cdbd2cSJim Jagielski         // background color (default system color for solid fills)
623*b1cdbd2cSJim Jagielski         if( bSolid )
624*b1cdbd2cSJim Jagielski             rRoot.SetSystemColor( maData.maBackColor, mnBackColorId, EXC_COLOR_CHWINDOWTEXT );
625*b1cdbd2cSJim Jagielski         else
626*b1cdbd2cSJim Jagielski             mnBackColorId = rRoot.GetPalette().InsertColor( maData.maBackColor, EXC_COLOR_CHARTAREA );
627*b1cdbd2cSJim Jagielski     }
628*b1cdbd2cSJim Jagielski     else
629*b1cdbd2cSJim Jagielski     {
630*b1cdbd2cSJim Jagielski         // no area - set default system colors
631*b1cdbd2cSJim Jagielski         rRoot.SetSystemColor( maData.maPattColor, mnPattColorId, EXC_COLOR_CHWINDOWBACK );
632*b1cdbd2cSJim Jagielski         rRoot.SetSystemColor( maData.maBackColor, mnBackColorId, EXC_COLOR_CHWINDOWTEXT );
633*b1cdbd2cSJim Jagielski     }
634*b1cdbd2cSJim Jagielski     return bComplexFill;
635*b1cdbd2cSJim Jagielski }
636*b1cdbd2cSJim Jagielski 
SetDefault(XclChFrameType eDefFrameType)637*b1cdbd2cSJim Jagielski void XclExpChAreaFormat::SetDefault( XclChFrameType eDefFrameType )
638*b1cdbd2cSJim Jagielski {
639*b1cdbd2cSJim Jagielski     switch( eDefFrameType )
640*b1cdbd2cSJim Jagielski     {
641*b1cdbd2cSJim Jagielski         case EXC_CHFRAMETYPE_AUTO:
642*b1cdbd2cSJim Jagielski             SetAuto( true );
643*b1cdbd2cSJim Jagielski         break;
644*b1cdbd2cSJim Jagielski         case EXC_CHFRAMETYPE_INVISIBLE:
645*b1cdbd2cSJim Jagielski             SetAuto( false );
646*b1cdbd2cSJim Jagielski             maData.mnPattern = EXC_PATT_NONE;
647*b1cdbd2cSJim Jagielski         break;
648*b1cdbd2cSJim Jagielski         default:
649*b1cdbd2cSJim Jagielski             DBG_ERRORFILE( "XclExpChAreaFormat::SetDefault - unknown frame type" );
650*b1cdbd2cSJim Jagielski     }
651*b1cdbd2cSJim Jagielski }
652*b1cdbd2cSJim Jagielski 
IsDefault(XclChFrameType eDefFrameType) const653*b1cdbd2cSJim Jagielski bool XclExpChAreaFormat::IsDefault( XclChFrameType eDefFrameType ) const
654*b1cdbd2cSJim Jagielski {
655*b1cdbd2cSJim Jagielski     return
656*b1cdbd2cSJim Jagielski         ((eDefFrameType == EXC_CHFRAMETYPE_INVISIBLE) && !HasArea()) ||
657*b1cdbd2cSJim Jagielski         ((eDefFrameType == EXC_CHFRAMETYPE_AUTO) && IsAuto());
658*b1cdbd2cSJim Jagielski }
659*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)660*b1cdbd2cSJim Jagielski void XclExpChAreaFormat::WriteBody( XclExpStream& rStrm )
661*b1cdbd2cSJim Jagielski {
662*b1cdbd2cSJim Jagielski     rStrm << maData.maPattColor << maData.maBackColor << maData.mnPattern << maData.mnFlags;
663*b1cdbd2cSJim Jagielski     if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
664*b1cdbd2cSJim Jagielski     {
665*b1cdbd2cSJim Jagielski         const XclExpPalette& rPal = rStrm.GetRoot().GetPalette();
666*b1cdbd2cSJim Jagielski         rStrm << rPal.GetColorIndex( mnPattColorId ) << rPal.GetColorIndex( mnBackColorId );
667*b1cdbd2cSJim Jagielski     }
668*b1cdbd2cSJim Jagielski }
669*b1cdbd2cSJim Jagielski 
670*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
671*b1cdbd2cSJim Jagielski 
XclExpChEscherFormat(const XclExpChRoot & rRoot)672*b1cdbd2cSJim Jagielski XclExpChEscherFormat::XclExpChEscherFormat( const XclExpChRoot& rRoot ) :
673*b1cdbd2cSJim Jagielski     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_UNKNOWN, EXC_ID_CHESCHERFORMAT ),
674*b1cdbd2cSJim Jagielski     mnColor1Id( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) ),
675*b1cdbd2cSJim Jagielski     mnColor2Id( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) )
676*b1cdbd2cSJim Jagielski {
677*b1cdbd2cSJim Jagielski     DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
678*b1cdbd2cSJim Jagielski }
679*b1cdbd2cSJim Jagielski 
Convert(const ScfPropertySet & rPropSet,XclChObjectType eObjType)680*b1cdbd2cSJim Jagielski void XclExpChEscherFormat::Convert( const ScfPropertySet& rPropSet, XclChObjectType eObjType )
681*b1cdbd2cSJim Jagielski {
682*b1cdbd2cSJim Jagielski     const XclChFormatInfo& rFmtInfo = GetFormatInfo( eObjType );
683*b1cdbd2cSJim Jagielski     ConvertEscherFormat( maData, maPicFmt, rPropSet, rFmtInfo.mePropMode );
684*b1cdbd2cSJim Jagielski     // register colors in palette
685*b1cdbd2cSJim Jagielski     mnColor1Id = RegisterColor( ESCHER_Prop_fillColor );
686*b1cdbd2cSJim Jagielski     mnColor2Id = RegisterColor( ESCHER_Prop_fillBackColor );
687*b1cdbd2cSJim Jagielski }
688*b1cdbd2cSJim Jagielski 
IsValid() const689*b1cdbd2cSJim Jagielski bool XclExpChEscherFormat::IsValid() const
690*b1cdbd2cSJim Jagielski {
691*b1cdbd2cSJim Jagielski     return maData.mxEscherSet.is();
692*b1cdbd2cSJim Jagielski }
693*b1cdbd2cSJim Jagielski 
Save(XclExpStream & rStrm)694*b1cdbd2cSJim Jagielski void XclExpChEscherFormat::Save( XclExpStream& rStrm )
695*b1cdbd2cSJim Jagielski {
696*b1cdbd2cSJim Jagielski     if( maData.mxEscherSet.is() )
697*b1cdbd2cSJim Jagielski     {
698*b1cdbd2cSJim Jagielski         // replace RGB colors with palette indexes in the Escher container
699*b1cdbd2cSJim Jagielski         const XclExpPalette& rPal = GetPalette();
700*b1cdbd2cSJim Jagielski         maData.mxEscherSet->AddOpt( ESCHER_Prop_fillColor, 0x08000000 | rPal.GetColorIndex( mnColor1Id ) );
701*b1cdbd2cSJim Jagielski         maData.mxEscherSet->AddOpt( ESCHER_Prop_fillBackColor, 0x08000000 | rPal.GetColorIndex( mnColor2Id ) );
702*b1cdbd2cSJim Jagielski 
703*b1cdbd2cSJim Jagielski         // save the record group
704*b1cdbd2cSJim Jagielski         XclExpChGroupBase::Save( rStrm );
705*b1cdbd2cSJim Jagielski     }
706*b1cdbd2cSJim Jagielski }
707*b1cdbd2cSJim Jagielski 
HasSubRecords() const708*b1cdbd2cSJim Jagielski bool XclExpChEscherFormat::HasSubRecords() const
709*b1cdbd2cSJim Jagielski {
710*b1cdbd2cSJim Jagielski     // no subrecords for gradients
711*b1cdbd2cSJim Jagielski     return maPicFmt.mnBmpMode != EXC_CHPICFORMAT_NONE;
712*b1cdbd2cSJim Jagielski }
713*b1cdbd2cSJim Jagielski 
WriteSubRecords(XclExpStream & rStrm)714*b1cdbd2cSJim Jagielski void XclExpChEscherFormat::WriteSubRecords( XclExpStream& rStrm )
715*b1cdbd2cSJim Jagielski {
716*b1cdbd2cSJim Jagielski     rStrm.StartRecord( EXC_ID_CHPICFORMAT, 14 );
717*b1cdbd2cSJim Jagielski     rStrm << maPicFmt.mnBmpMode << sal_uInt16( 0 ) << maPicFmt.mnFlags << maPicFmt.mfScale;
718*b1cdbd2cSJim Jagielski     rStrm.EndRecord();
719*b1cdbd2cSJim Jagielski }
720*b1cdbd2cSJim Jagielski 
RegisterColor(sal_uInt16 nPropId)721*b1cdbd2cSJim Jagielski sal_uInt32 XclExpChEscherFormat::RegisterColor( sal_uInt16 nPropId )
722*b1cdbd2cSJim Jagielski {
723*b1cdbd2cSJim Jagielski     sal_uInt32 nBGRValue;
724*b1cdbd2cSJim Jagielski     if( maData.mxEscherSet.is() && maData.mxEscherSet->GetOpt( nPropId, nBGRValue ) )
725*b1cdbd2cSJim Jagielski     {
726*b1cdbd2cSJim Jagielski         // swap red and blue
727*b1cdbd2cSJim Jagielski         Color aColor( RGB_COLORDATA(
728*b1cdbd2cSJim Jagielski             COLORDATA_BLUE( nBGRValue ),
729*b1cdbd2cSJim Jagielski             COLORDATA_GREEN( nBGRValue ),
730*b1cdbd2cSJim Jagielski             COLORDATA_RED( nBGRValue ) ) );
731*b1cdbd2cSJim Jagielski         return GetPalette().InsertColor( aColor, EXC_COLOR_CHARTAREA );
732*b1cdbd2cSJim Jagielski     }
733*b1cdbd2cSJim Jagielski     return XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK );
734*b1cdbd2cSJim Jagielski }
735*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)736*b1cdbd2cSJim Jagielski void XclExpChEscherFormat::WriteBody( XclExpStream& rStrm )
737*b1cdbd2cSJim Jagielski {
738*b1cdbd2cSJim Jagielski     DBG_ASSERT( maData.mxEscherSet.is(), "XclExpChEscherFormat::WriteBody - missing property container" );
739*b1cdbd2cSJim Jagielski     // write Escher property container via temporary memory stream
740*b1cdbd2cSJim Jagielski     SvMemoryStream aMemStrm;
741*b1cdbd2cSJim Jagielski     maData.mxEscherSet->Commit( aMemStrm );
742*b1cdbd2cSJim Jagielski     aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
743*b1cdbd2cSJim Jagielski     rStrm.CopyFromStream( aMemStrm );
744*b1cdbd2cSJim Jagielski }
745*b1cdbd2cSJim Jagielski 
746*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
747*b1cdbd2cSJim Jagielski 
XclExpChFrameBase()748*b1cdbd2cSJim Jagielski XclExpChFrameBase::XclExpChFrameBase()
749*b1cdbd2cSJim Jagielski {
750*b1cdbd2cSJim Jagielski }
751*b1cdbd2cSJim Jagielski 
~XclExpChFrameBase()752*b1cdbd2cSJim Jagielski XclExpChFrameBase::~XclExpChFrameBase()
753*b1cdbd2cSJim Jagielski {
754*b1cdbd2cSJim Jagielski }
755*b1cdbd2cSJim Jagielski 
ConvertFrameBase(const XclExpChRoot & rRoot,const ScfPropertySet & rPropSet,XclChObjectType eObjType)756*b1cdbd2cSJim Jagielski void XclExpChFrameBase::ConvertFrameBase( const XclExpChRoot& rRoot,
757*b1cdbd2cSJim Jagielski         const ScfPropertySet& rPropSet, XclChObjectType eObjType )
758*b1cdbd2cSJim Jagielski {
759*b1cdbd2cSJim Jagielski     // line format
760*b1cdbd2cSJim Jagielski     mxLineFmt.reset( new XclExpChLineFormat( rRoot ) );
761*b1cdbd2cSJim Jagielski     mxLineFmt->Convert( rRoot, rPropSet, eObjType );
762*b1cdbd2cSJim Jagielski     // area format (only for frame objects)
763*b1cdbd2cSJim Jagielski     if( rRoot.GetFormatInfo( eObjType ).mbIsFrame )
764*b1cdbd2cSJim Jagielski     {
765*b1cdbd2cSJim Jagielski         mxAreaFmt.reset( new XclExpChAreaFormat( rRoot ) );
766*b1cdbd2cSJim Jagielski         bool bComplexFill = mxAreaFmt->Convert( rRoot, rPropSet, eObjType );
767*b1cdbd2cSJim Jagielski         if( (rRoot.GetBiff() == EXC_BIFF8) && bComplexFill )
768*b1cdbd2cSJim Jagielski         {
769*b1cdbd2cSJim Jagielski             mxEscherFmt.reset( new XclExpChEscherFormat( rRoot ) );
770*b1cdbd2cSJim Jagielski             mxEscherFmt->Convert( rPropSet, eObjType );
771*b1cdbd2cSJim Jagielski             if( mxEscherFmt->IsValid() )
772*b1cdbd2cSJim Jagielski                 mxAreaFmt->SetAuto( false );
773*b1cdbd2cSJim Jagielski             else
774*b1cdbd2cSJim Jagielski                 mxEscherFmt.reset();
775*b1cdbd2cSJim Jagielski         }
776*b1cdbd2cSJim Jagielski     }
777*b1cdbd2cSJim Jagielski }
778*b1cdbd2cSJim Jagielski 
SetDefaultFrameBase(const XclExpChRoot & rRoot,XclChFrameType eDefFrameType,bool bIsFrame)779*b1cdbd2cSJim Jagielski void XclExpChFrameBase::SetDefaultFrameBase( const XclExpChRoot& rRoot,
780*b1cdbd2cSJim Jagielski         XclChFrameType eDefFrameType, bool bIsFrame )
781*b1cdbd2cSJim Jagielski {
782*b1cdbd2cSJim Jagielski     // line format
783*b1cdbd2cSJim Jagielski     mxLineFmt.reset( new XclExpChLineFormat( rRoot ) );
784*b1cdbd2cSJim Jagielski     mxLineFmt->SetDefault( eDefFrameType );
785*b1cdbd2cSJim Jagielski     // area format (only for frame objects)
786*b1cdbd2cSJim Jagielski     if( bIsFrame )
787*b1cdbd2cSJim Jagielski     {
788*b1cdbd2cSJim Jagielski         mxAreaFmt.reset( new XclExpChAreaFormat( rRoot ) );
789*b1cdbd2cSJim Jagielski         mxAreaFmt->SetDefault( eDefFrameType );
790*b1cdbd2cSJim Jagielski         mxEscherFmt.reset();
791*b1cdbd2cSJim Jagielski     }
792*b1cdbd2cSJim Jagielski }
793*b1cdbd2cSJim Jagielski 
IsDefaultFrameBase(XclChFrameType eDefFrameType) const794*b1cdbd2cSJim Jagielski bool XclExpChFrameBase::IsDefaultFrameBase( XclChFrameType eDefFrameType ) const
795*b1cdbd2cSJim Jagielski {
796*b1cdbd2cSJim Jagielski     return
797*b1cdbd2cSJim Jagielski         (!mxLineFmt || mxLineFmt->IsDefault( eDefFrameType )) &&
798*b1cdbd2cSJim Jagielski         (!mxAreaFmt || mxAreaFmt->IsDefault( eDefFrameType ));
799*b1cdbd2cSJim Jagielski }
800*b1cdbd2cSJim Jagielski 
WriteFrameRecords(XclExpStream & rStrm)801*b1cdbd2cSJim Jagielski void XclExpChFrameBase::WriteFrameRecords( XclExpStream& rStrm )
802*b1cdbd2cSJim Jagielski {
803*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxLineFmt );
804*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxAreaFmt );
805*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxEscherFmt );
806*b1cdbd2cSJim Jagielski }
807*b1cdbd2cSJim Jagielski 
808*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
809*b1cdbd2cSJim Jagielski 
XclExpChFrame(const XclExpChRoot & rRoot,XclChObjectType eObjType)810*b1cdbd2cSJim Jagielski XclExpChFrame::XclExpChFrame( const XclExpChRoot& rRoot, XclChObjectType eObjType ) :
811*b1cdbd2cSJim Jagielski     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_FRAME, EXC_ID_CHFRAME, 4 ),
812*b1cdbd2cSJim Jagielski     meObjType( eObjType )
813*b1cdbd2cSJim Jagielski {
814*b1cdbd2cSJim Jagielski }
815*b1cdbd2cSJim Jagielski 
Convert(const ScfPropertySet & rPropSet)816*b1cdbd2cSJim Jagielski void XclExpChFrame::Convert( const ScfPropertySet& rPropSet )
817*b1cdbd2cSJim Jagielski {
818*b1cdbd2cSJim Jagielski     ConvertFrameBase( GetChRoot(), rPropSet, meObjType );
819*b1cdbd2cSJim Jagielski }
820*b1cdbd2cSJim Jagielski 
SetAutoFlags(bool bAutoPos,bool bAutoSize)821*b1cdbd2cSJim Jagielski void XclExpChFrame::SetAutoFlags( bool bAutoPos, bool bAutoSize )
822*b1cdbd2cSJim Jagielski {
823*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHFRAME_AUTOPOS, bAutoPos );
824*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHFRAME_AUTOSIZE, bAutoSize );
825*b1cdbd2cSJim Jagielski }
826*b1cdbd2cSJim Jagielski 
IsDefault() const827*b1cdbd2cSJim Jagielski bool XclExpChFrame::IsDefault() const
828*b1cdbd2cSJim Jagielski {
829*b1cdbd2cSJim Jagielski     return IsDefaultFrameBase( GetFormatInfo( meObjType ).meDefFrameType );
830*b1cdbd2cSJim Jagielski }
831*b1cdbd2cSJim Jagielski 
IsDeleteable() const832*b1cdbd2cSJim Jagielski bool XclExpChFrame::IsDeleteable() const
833*b1cdbd2cSJim Jagielski {
834*b1cdbd2cSJim Jagielski     return IsDefault() && GetFormatInfo( meObjType ).mbDeleteDefFrame;
835*b1cdbd2cSJim Jagielski }
836*b1cdbd2cSJim Jagielski 
Save(XclExpStream & rStrm)837*b1cdbd2cSJim Jagielski void XclExpChFrame::Save( XclExpStream& rStrm )
838*b1cdbd2cSJim Jagielski {
839*b1cdbd2cSJim Jagielski     switch( meObjType )
840*b1cdbd2cSJim Jagielski     {
841*b1cdbd2cSJim Jagielski         // wall/floor frame without CHFRAME header record
842*b1cdbd2cSJim Jagielski         case EXC_CHOBJTYPE_WALL3D:
843*b1cdbd2cSJim Jagielski         case EXC_CHOBJTYPE_FLOOR3D:
844*b1cdbd2cSJim Jagielski             WriteFrameRecords( rStrm );
845*b1cdbd2cSJim Jagielski         break;
846*b1cdbd2cSJim Jagielski         default:
847*b1cdbd2cSJim Jagielski             XclExpChGroupBase::Save( rStrm );
848*b1cdbd2cSJim Jagielski     }
849*b1cdbd2cSJim Jagielski }
850*b1cdbd2cSJim Jagielski 
WriteSubRecords(XclExpStream & rStrm)851*b1cdbd2cSJim Jagielski void XclExpChFrame::WriteSubRecords( XclExpStream& rStrm )
852*b1cdbd2cSJim Jagielski {
853*b1cdbd2cSJim Jagielski     WriteFrameRecords( rStrm );
854*b1cdbd2cSJim Jagielski }
855*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)856*b1cdbd2cSJim Jagielski void XclExpChFrame::WriteBody( XclExpStream& rStrm )
857*b1cdbd2cSJim Jagielski {
858*b1cdbd2cSJim Jagielski     rStrm << maData.mnFormat << maData.mnFlags;
859*b1cdbd2cSJim Jagielski }
860*b1cdbd2cSJim Jagielski 
861*b1cdbd2cSJim Jagielski namespace {
862*b1cdbd2cSJim Jagielski 
863*b1cdbd2cSJim Jagielski /** Creates a CHFRAME record from the passed property set. */
lclCreateFrame(const XclExpChRoot & rRoot,const ScfPropertySet & rPropSet,XclChObjectType eObjType)864*b1cdbd2cSJim Jagielski XclExpChFrameRef lclCreateFrame( const XclExpChRoot& rRoot,
865*b1cdbd2cSJim Jagielski         const ScfPropertySet& rPropSet, XclChObjectType eObjType )
866*b1cdbd2cSJim Jagielski {
867*b1cdbd2cSJim Jagielski     XclExpChFrameRef xFrame( new XclExpChFrame( rRoot, eObjType ) );
868*b1cdbd2cSJim Jagielski     xFrame->Convert( rPropSet );
869*b1cdbd2cSJim Jagielski     if( xFrame->IsDeleteable() )
870*b1cdbd2cSJim Jagielski         xFrame.reset();
871*b1cdbd2cSJim Jagielski     return xFrame;
872*b1cdbd2cSJim Jagielski }
873*b1cdbd2cSJim Jagielski 
874*b1cdbd2cSJim Jagielski } // namespace
875*b1cdbd2cSJim Jagielski 
876*b1cdbd2cSJim Jagielski // Source links ===============================================================
877*b1cdbd2cSJim Jagielski 
878*b1cdbd2cSJim Jagielski namespace {
879*b1cdbd2cSJim Jagielski 
lclAddDoubleRefData(ScTokenArray & orArray,const FormulaToken & rToken,SCsTAB nScTab1,SCsCOL nScCol1,SCsROW nScRow1,SCsTAB nScTab2,SCsCOL nScCol2,SCsROW nScRow2)880*b1cdbd2cSJim Jagielski void lclAddDoubleRefData(
881*b1cdbd2cSJim Jagielski         ScTokenArray& orArray, const FormulaToken& rToken,
882*b1cdbd2cSJim Jagielski         SCsTAB nScTab1, SCsCOL nScCol1, SCsROW nScRow1,
883*b1cdbd2cSJim Jagielski         SCsTAB nScTab2, SCsCOL nScCol2, SCsROW nScRow2 )
884*b1cdbd2cSJim Jagielski {
885*b1cdbd2cSJim Jagielski     ScComplexRefData aComplexRef;
886*b1cdbd2cSJim Jagielski     aComplexRef.InitFlags();
887*b1cdbd2cSJim Jagielski     aComplexRef.Ref1.SetFlag3D( true );
888*b1cdbd2cSJim Jagielski     aComplexRef.Ref1.nTab = nScTab1;
889*b1cdbd2cSJim Jagielski     aComplexRef.Ref1.nCol = nScCol1;
890*b1cdbd2cSJim Jagielski     aComplexRef.Ref1.nRow = nScRow1;
891*b1cdbd2cSJim Jagielski     aComplexRef.Ref2.nTab = nScTab2;
892*b1cdbd2cSJim Jagielski     aComplexRef.Ref2.nCol = nScCol2;
893*b1cdbd2cSJim Jagielski     aComplexRef.Ref2.nRow = nScRow2;
894*b1cdbd2cSJim Jagielski 
895*b1cdbd2cSJim Jagielski     if( orArray.GetLen() > 0 )
896*b1cdbd2cSJim Jagielski         orArray.AddOpCode( ocUnion );
897*b1cdbd2cSJim Jagielski 
898*b1cdbd2cSJim Jagielski     DBG_ASSERT( (rToken.GetType() == ::formula::svDoubleRef) || (rToken.GetType() == ::formula::svExternalDoubleRef),
899*b1cdbd2cSJim Jagielski         "lclAddDoubleRefData - double reference token expected");
900*b1cdbd2cSJim Jagielski     if( rToken.GetType() == ::formula::svExternalDoubleRef )
901*b1cdbd2cSJim Jagielski         orArray.AddExternalDoubleReference( rToken.GetIndex(), rToken.GetString(), aComplexRef );
902*b1cdbd2cSJim Jagielski     else
903*b1cdbd2cSJim Jagielski         orArray.AddDoubleReference( aComplexRef );
904*b1cdbd2cSJim Jagielski }
905*b1cdbd2cSJim Jagielski 
906*b1cdbd2cSJim Jagielski } // namespace
907*b1cdbd2cSJim Jagielski 
908*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
909*b1cdbd2cSJim Jagielski 
XclExpChSourceLink(const XclExpChRoot & rRoot,sal_uInt8 nDestType)910*b1cdbd2cSJim Jagielski XclExpChSourceLink::XclExpChSourceLink( const XclExpChRoot& rRoot, sal_uInt8 nDestType ) :
911*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CHSOURCELINK ),
912*b1cdbd2cSJim Jagielski     XclExpChRoot( rRoot )
913*b1cdbd2cSJim Jagielski {
914*b1cdbd2cSJim Jagielski     maData.mnDestType = nDestType;
915*b1cdbd2cSJim Jagielski     maData.mnLinkType = EXC_CHSRCLINK_DIRECTLY;
916*b1cdbd2cSJim Jagielski }
917*b1cdbd2cSJim Jagielski 
ConvertDataSequence(Reference<XDataSequence> xDataSeq,bool bSplitToColumns,sal_uInt16 nDefCount)918*b1cdbd2cSJim Jagielski sal_uInt16 XclExpChSourceLink::ConvertDataSequence( Reference< XDataSequence > xDataSeq, bool bSplitToColumns, sal_uInt16 nDefCount )
919*b1cdbd2cSJim Jagielski {
920*b1cdbd2cSJim Jagielski     mxLinkFmla.reset();
921*b1cdbd2cSJim Jagielski     maData.mnLinkType = EXC_CHSRCLINK_DEFAULT;
922*b1cdbd2cSJim Jagielski 
923*b1cdbd2cSJim Jagielski     if( !xDataSeq.is() )
924*b1cdbd2cSJim Jagielski         return nDefCount;
925*b1cdbd2cSJim Jagielski 
926*b1cdbd2cSJim Jagielski     // Compile the range representation string into token array.  Note that the
927*b1cdbd2cSJim Jagielski     // source range text depends on the current grammar.
928*b1cdbd2cSJim Jagielski     OUString aRangeRepr = xDataSeq->getSourceRangeRepresentation();
929*b1cdbd2cSJim Jagielski     ScCompiler aComp( GetDocPtr(), ScAddress() );
930*b1cdbd2cSJim Jagielski     aComp.SetGrammar( GetDocPtr()->GetGrammar() );
931*b1cdbd2cSJim Jagielski     ScTokenArray* pArray = aComp.CompileString( aRangeRepr );
932*b1cdbd2cSJim Jagielski     if( !pArray )
933*b1cdbd2cSJim Jagielski         return nDefCount;
934*b1cdbd2cSJim Jagielski 
935*b1cdbd2cSJim Jagielski     ScTokenArray aArray;
936*b1cdbd2cSJim Jagielski     sal_uInt32 nValueCount = 0;
937*b1cdbd2cSJim Jagielski     pArray->Reset();
938*b1cdbd2cSJim Jagielski     for( const FormulaToken* pToken = pArray->First(); pToken; pToken = pArray->Next() )
939*b1cdbd2cSJim Jagielski     {
940*b1cdbd2cSJim Jagielski         switch( pToken->GetType() )
941*b1cdbd2cSJim Jagielski         {
942*b1cdbd2cSJim Jagielski             case ::formula::svSingleRef:
943*b1cdbd2cSJim Jagielski             case ::formula::svExternalSingleRef:
944*b1cdbd2cSJim Jagielski                 // for a single ref token, just add it to the new token array as is
945*b1cdbd2cSJim Jagielski                 if( aArray.GetLen() > 0 )
946*b1cdbd2cSJim Jagielski                     aArray.AddOpCode( ocUnion );
947*b1cdbd2cSJim Jagielski                 aArray.AddToken( *pToken );
948*b1cdbd2cSJim Jagielski                 ++nValueCount;
949*b1cdbd2cSJim Jagielski             break;
950*b1cdbd2cSJim Jagielski 
951*b1cdbd2cSJim Jagielski             case ::formula::svDoubleRef:
952*b1cdbd2cSJim Jagielski             case ::formula::svExternalDoubleRef:
953*b1cdbd2cSJim Jagielski             {
954*b1cdbd2cSJim Jagielski                 // split 3-dimensional ranges into single sheets
955*b1cdbd2cSJim Jagielski                 const ScComplexRefData& rComplexRef = static_cast< const ScToken* >( pToken )->GetDoubleRef();
956*b1cdbd2cSJim Jagielski                 const ScSingleRefData& rRef1 = rComplexRef.Ref1;
957*b1cdbd2cSJim Jagielski                 const ScSingleRefData& rRef2 = rComplexRef.Ref2;
958*b1cdbd2cSJim Jagielski                 for( SCsTAB nScTab = rRef1.nTab; nScTab <= rRef2.nTab; ++nScTab )
959*b1cdbd2cSJim Jagielski                 {
960*b1cdbd2cSJim Jagielski                     // split 2-dimensional ranges into single columns
961*b1cdbd2cSJim Jagielski                     if( bSplitToColumns && (rRef1.nCol < rRef2.nCol) && (rRef1.nRow < rRef2.nRow) )
962*b1cdbd2cSJim Jagielski                         for( SCsCOL nScCol = rRef1.nCol; nScCol <= rRef2.nCol; ++nScCol )
963*b1cdbd2cSJim Jagielski                             lclAddDoubleRefData( aArray, *pToken, nScTab, nScCol, rRef1.nRow, nScTab, nScCol, rRef2.nRow );
964*b1cdbd2cSJim Jagielski                     else
965*b1cdbd2cSJim Jagielski                         lclAddDoubleRefData( aArray, *pToken, nScTab, rRef1.nCol, rRef1.nRow, nScTab, rRef2.nCol, rRef2.nRow );
966*b1cdbd2cSJim Jagielski                 }
967*b1cdbd2cSJim Jagielski                 sal_uInt32 nTabs = static_cast< sal_uInt32 >( rRef2.nTab - rRef1.nTab + 1 );
968*b1cdbd2cSJim Jagielski                 sal_uInt32 nCols = static_cast< sal_uInt32 >( rRef2.nCol - rRef1.nCol + 1 );
969*b1cdbd2cSJim Jagielski                 sal_uInt32 nRows = static_cast< sal_uInt32 >( rRef2.nRow - rRef1.nRow + 1 );
970*b1cdbd2cSJim Jagielski                 nValueCount += nCols * nRows * nTabs;
971*b1cdbd2cSJim Jagielski             }
972*b1cdbd2cSJim Jagielski             break;
973*b1cdbd2cSJim Jagielski 
974*b1cdbd2cSJim Jagielski             default:;
975*b1cdbd2cSJim Jagielski         }
976*b1cdbd2cSJim Jagielski     }
977*b1cdbd2cSJim Jagielski 
978*b1cdbd2cSJim Jagielski     const ScAddress aBaseCell;
979*b1cdbd2cSJim Jagielski     mxLinkFmla = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CHART, aArray, &aBaseCell );
980*b1cdbd2cSJim Jagielski     maData.mnLinkType = EXC_CHSRCLINK_WORKSHEET;
981*b1cdbd2cSJim Jagielski     return ulimit_cast< sal_uInt16 >( nValueCount, EXC_CHDATAFORMAT_MAXPOINTCOUNT );
982*b1cdbd2cSJim Jagielski }
983*b1cdbd2cSJim Jagielski 
ConvertStringSequence(const Sequence<Reference<XFormattedString>> & rStringSeq)984*b1cdbd2cSJim Jagielski sal_uInt16 XclExpChSourceLink::ConvertStringSequence( const Sequence< Reference< XFormattedString > >& rStringSeq )
985*b1cdbd2cSJim Jagielski {
986*b1cdbd2cSJim Jagielski     mxString.reset();
987*b1cdbd2cSJim Jagielski     sal_uInt16 nFontIdx = EXC_FONT_APP;
988*b1cdbd2cSJim Jagielski     if( rStringSeq.hasElements() )
989*b1cdbd2cSJim Jagielski     {
990*b1cdbd2cSJim Jagielski         mxString = XclExpStringHelper::CreateString( GetRoot(), String::EmptyString(), EXC_STR_FORCEUNICODE | EXC_STR_8BITLENGTH | EXC_STR_SEPARATEFORMATS );
991*b1cdbd2cSJim Jagielski         Reference< XBreakIterator > xBreakIt = GetDoc().GetBreakIterator();
992*b1cdbd2cSJim Jagielski         namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
993*b1cdbd2cSJim Jagielski 
994*b1cdbd2cSJim Jagielski         // convert all formatted string entries from the sequence
995*b1cdbd2cSJim Jagielski         const Reference< XFormattedString >* pBeg = rStringSeq.getConstArray();
996*b1cdbd2cSJim Jagielski         const Reference< XFormattedString >* pEnd = pBeg + rStringSeq.getLength();
997*b1cdbd2cSJim Jagielski         for( const Reference< XFormattedString >* pIt = pBeg; pIt != pEnd; ++pIt )
998*b1cdbd2cSJim Jagielski         {
999*b1cdbd2cSJim Jagielski             if( pIt->is() )
1000*b1cdbd2cSJim Jagielski             {
1001*b1cdbd2cSJim Jagielski                 sal_uInt16 nWstrnFontIdx = EXC_FONT_NOTFOUND;
1002*b1cdbd2cSJim Jagielski                 sal_uInt16 nAsianFontIdx = EXC_FONT_NOTFOUND;
1003*b1cdbd2cSJim Jagielski                 sal_uInt16 nCmplxFontIdx = EXC_FONT_NOTFOUND;
1004*b1cdbd2cSJim Jagielski                 OUString aText = (*pIt)->getString();
1005*b1cdbd2cSJim Jagielski                 ScfPropertySet aStrProp( *pIt );
1006*b1cdbd2cSJim Jagielski 
1007*b1cdbd2cSJim Jagielski                 // #i63255# get script type for leading weak characters
1008*b1cdbd2cSJim Jagielski                 sal_Int16 nLastScript = XclExpStringHelper::GetLeadingScriptType( GetRoot(), aText );
1009*b1cdbd2cSJim Jagielski 
1010*b1cdbd2cSJim Jagielski                 // process all script portions
1011*b1cdbd2cSJim Jagielski                 sal_Int32 nPortionPos = 0;
1012*b1cdbd2cSJim Jagielski                 sal_Int32 nTextLen = aText.getLength();
1013*b1cdbd2cSJim Jagielski                 while( nPortionPos < nTextLen )
1014*b1cdbd2cSJim Jagielski                 {
1015*b1cdbd2cSJim Jagielski                     // get script type and end position of next script portion
1016*b1cdbd2cSJim Jagielski                     sal_Int16 nScript = xBreakIt->getScriptType( aText, nPortionPos );
1017*b1cdbd2cSJim Jagielski                     sal_Int32 nPortionEnd = xBreakIt->endOfScript( aText, nPortionPos, nScript );
1018*b1cdbd2cSJim Jagielski 
1019*b1cdbd2cSJim Jagielski                     // reuse previous script for following weak portions
1020*b1cdbd2cSJim Jagielski                     if( nScript == ApiScriptType::WEAK )
1021*b1cdbd2cSJim Jagielski                         nScript = nLastScript;
1022*b1cdbd2cSJim Jagielski 
1023*b1cdbd2cSJim Jagielski                     // Excel start position of this portion
1024*b1cdbd2cSJim Jagielski                     sal_uInt16 nXclPortionStart = mxString->Len();
1025*b1cdbd2cSJim Jagielski                     // add portion text to Excel string
1026*b1cdbd2cSJim Jagielski                     XclExpStringHelper::AppendString( *mxString, GetRoot(), aText.copy( nPortionPos, nPortionEnd - nPortionPos ) );
1027*b1cdbd2cSJim Jagielski                     if( nXclPortionStart < mxString->Len() )
1028*b1cdbd2cSJim Jagielski                     {
1029*b1cdbd2cSJim Jagielski                         // find font index variable dependent on script type
1030*b1cdbd2cSJim Jagielski                         sal_uInt16& rnFontIdx = (nScript == ApiScriptType::COMPLEX) ? nCmplxFontIdx :
1031*b1cdbd2cSJim Jagielski                             ((nScript == ApiScriptType::ASIAN) ? nAsianFontIdx : nWstrnFontIdx);
1032*b1cdbd2cSJim Jagielski 
1033*b1cdbd2cSJim Jagielski                         // insert font into buffer (if not yet done)
1034*b1cdbd2cSJim Jagielski                         if( rnFontIdx == EXC_FONT_NOTFOUND )
1035*b1cdbd2cSJim Jagielski                             rnFontIdx = ConvertFont( aStrProp, nScript );
1036*b1cdbd2cSJim Jagielski 
1037*b1cdbd2cSJim Jagielski                         // insert font index into format run vector
1038*b1cdbd2cSJim Jagielski                         mxString->AppendFormat( nXclPortionStart, rnFontIdx );
1039*b1cdbd2cSJim Jagielski                     }
1040*b1cdbd2cSJim Jagielski 
1041*b1cdbd2cSJim Jagielski                     // go to next script portion
1042*b1cdbd2cSJim Jagielski                     nLastScript = nScript;
1043*b1cdbd2cSJim Jagielski                     nPortionPos = nPortionEnd;
1044*b1cdbd2cSJim Jagielski                 }
1045*b1cdbd2cSJim Jagielski             }
1046*b1cdbd2cSJim Jagielski         }
1047*b1cdbd2cSJim Jagielski         if( !mxString->IsEmpty() )
1048*b1cdbd2cSJim Jagielski         {
1049*b1cdbd2cSJim Jagielski             // get leading font index
1050*b1cdbd2cSJim Jagielski             const XclFormatRunVec& rFormats = mxString->GetFormats();
1051*b1cdbd2cSJim Jagielski             DBG_ASSERT( !rFormats.empty() && (rFormats.front().mnChar == 0),
1052*b1cdbd2cSJim Jagielski                 "XclExpChSourceLink::ConvertStringSequenc - missing leading format" );
1053*b1cdbd2cSJim Jagielski             // remove leading format run, if entire string is equally formatted
1054*b1cdbd2cSJim Jagielski             if( rFormats.size() == 1 )
1055*b1cdbd2cSJim Jagielski                 nFontIdx = mxString->RemoveLeadingFont();
1056*b1cdbd2cSJim Jagielski             else if( !rFormats.empty() )
1057*b1cdbd2cSJim Jagielski                 nFontIdx = rFormats.front().mnFontIdx;
1058*b1cdbd2cSJim Jagielski             // add trailing format run, if string is rich-formatted
1059*b1cdbd2cSJim Jagielski             if( mxString->IsRich() )
1060*b1cdbd2cSJim Jagielski                 mxString->AppendTrailingFormat( EXC_FONT_APP );
1061*b1cdbd2cSJim Jagielski         }
1062*b1cdbd2cSJim Jagielski     }
1063*b1cdbd2cSJim Jagielski     return nFontIdx;
1064*b1cdbd2cSJim Jagielski }
1065*b1cdbd2cSJim Jagielski 
ConvertNumFmt(const ScfPropertySet & rPropSet,bool bPercent)1066*b1cdbd2cSJim Jagielski void XclExpChSourceLink::ConvertNumFmt( const ScfPropertySet& rPropSet, bool bPercent )
1067*b1cdbd2cSJim Jagielski {
1068*b1cdbd2cSJim Jagielski     sal_Int32 nApiNumFmt = 0;
1069*b1cdbd2cSJim Jagielski     if( bPercent ? rPropSet.GetProperty( nApiNumFmt, EXC_CHPROP_PERCENTAGENUMFMT ) : rPropSet.GetProperty( nApiNumFmt, EXC_CHPROP_NUMBERFORMAT ) )
1070*b1cdbd2cSJim Jagielski     {
1071*b1cdbd2cSJim Jagielski         ::set_flag( maData.mnFlags, EXC_CHSRCLINK_NUMFMT );
1072*b1cdbd2cSJim Jagielski         maData.mnNumFmtIdx = GetNumFmtBuffer().Insert( static_cast< sal_uInt32 >( nApiNumFmt ) );
1073*b1cdbd2cSJim Jagielski     }
1074*b1cdbd2cSJim Jagielski }
1075*b1cdbd2cSJim Jagielski 
Save(XclExpStream & rStrm)1076*b1cdbd2cSJim Jagielski void XclExpChSourceLink::Save( XclExpStream& rStrm )
1077*b1cdbd2cSJim Jagielski {
1078*b1cdbd2cSJim Jagielski     // CHFORMATRUNS record
1079*b1cdbd2cSJim Jagielski     if( mxString.is() && mxString->IsRich() )
1080*b1cdbd2cSJim Jagielski     {
1081*b1cdbd2cSJim Jagielski         sal_Size nRecSize = (1 + mxString->GetFormatsCount()) * ((GetBiff() == EXC_BIFF8) ? 2 : 1);
1082*b1cdbd2cSJim Jagielski         rStrm.StartRecord( EXC_ID_CHFORMATRUNS, nRecSize );
1083*b1cdbd2cSJim Jagielski         mxString->WriteFormats( rStrm, true );
1084*b1cdbd2cSJim Jagielski         rStrm.EndRecord();
1085*b1cdbd2cSJim Jagielski     }
1086*b1cdbd2cSJim Jagielski     // CHSOURCELINK record
1087*b1cdbd2cSJim Jagielski     XclExpRecord::Save( rStrm );
1088*b1cdbd2cSJim Jagielski     // CHSTRING record
1089*b1cdbd2cSJim Jagielski     if( mxString.is() && !mxString->IsEmpty() )
1090*b1cdbd2cSJim Jagielski     {
1091*b1cdbd2cSJim Jagielski         rStrm.StartRecord( EXC_ID_CHSTRING, 2 + mxString->GetSize() );
1092*b1cdbd2cSJim Jagielski         rStrm << sal_uInt16( 0 ) << *mxString;
1093*b1cdbd2cSJim Jagielski         rStrm.EndRecord();
1094*b1cdbd2cSJim Jagielski     }
1095*b1cdbd2cSJim Jagielski }
1096*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)1097*b1cdbd2cSJim Jagielski void XclExpChSourceLink::WriteBody( XclExpStream& rStrm )
1098*b1cdbd2cSJim Jagielski {
1099*b1cdbd2cSJim Jagielski     rStrm   << maData.mnDestType
1100*b1cdbd2cSJim Jagielski             << maData.mnLinkType
1101*b1cdbd2cSJim Jagielski             << maData.mnFlags
1102*b1cdbd2cSJim Jagielski             << maData.mnNumFmtIdx
1103*b1cdbd2cSJim Jagielski             << mxLinkFmla;
1104*b1cdbd2cSJim Jagielski }
1105*b1cdbd2cSJim Jagielski 
1106*b1cdbd2cSJim Jagielski // Text =======================================================================
1107*b1cdbd2cSJim Jagielski 
XclExpChFont(sal_uInt16 nFontIdx)1108*b1cdbd2cSJim Jagielski XclExpChFont::XclExpChFont( sal_uInt16 nFontIdx ) :
1109*b1cdbd2cSJim Jagielski     XclExpUInt16Record( EXC_ID_CHFONT, nFontIdx )
1110*b1cdbd2cSJim Jagielski {
1111*b1cdbd2cSJim Jagielski }
1112*b1cdbd2cSJim Jagielski 
1113*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1114*b1cdbd2cSJim Jagielski 
XclExpChObjectLink(sal_uInt16 nLinkTarget,const XclChDataPointPos & rPointPos)1115*b1cdbd2cSJim Jagielski XclExpChObjectLink::XclExpChObjectLink( sal_uInt16 nLinkTarget, const XclChDataPointPos& rPointPos ) :
1116*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CHOBJECTLINK, 6 )
1117*b1cdbd2cSJim Jagielski {
1118*b1cdbd2cSJim Jagielski     maData.mnTarget = nLinkTarget;
1119*b1cdbd2cSJim Jagielski     maData.maPointPos = rPointPos;
1120*b1cdbd2cSJim Jagielski }
1121*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)1122*b1cdbd2cSJim Jagielski void XclExpChObjectLink::WriteBody( XclExpStream& rStrm )
1123*b1cdbd2cSJim Jagielski {
1124*b1cdbd2cSJim Jagielski     rStrm << maData.mnTarget << maData.maPointPos.mnSeriesIdx << maData.maPointPos.mnPointIdx;
1125*b1cdbd2cSJim Jagielski }
1126*b1cdbd2cSJim Jagielski 
1127*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1128*b1cdbd2cSJim Jagielski 
XclExpChFrLabelProps(const XclExpChRoot & rRoot)1129*b1cdbd2cSJim Jagielski XclExpChFrLabelProps::XclExpChFrLabelProps( const XclExpChRoot& rRoot ) :
1130*b1cdbd2cSJim Jagielski     XclExpChFutureRecordBase( rRoot, EXC_FUTUREREC_UNUSEDREF, EXC_ID_CHFRLABELPROPS, 4 )
1131*b1cdbd2cSJim Jagielski {
1132*b1cdbd2cSJim Jagielski }
1133*b1cdbd2cSJim Jagielski 
Convert(const ScfPropertySet & rPropSet,bool bShowSeries,bool bShowCateg,bool bShowValue,bool bShowPercent,bool bShowBubble)1134*b1cdbd2cSJim Jagielski void XclExpChFrLabelProps::Convert( const ScfPropertySet& rPropSet, bool bShowSeries,
1135*b1cdbd2cSJim Jagielski         bool bShowCateg, bool bShowValue, bool bShowPercent, bool bShowBubble )
1136*b1cdbd2cSJim Jagielski {
1137*b1cdbd2cSJim Jagielski     // label value flags
1138*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWSERIES,  bShowSeries );
1139*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWCATEG,   bShowCateg );
1140*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWVALUE,   bShowValue );
1141*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWPERCENT, bShowPercent );
1142*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWBUBBLE,  bShowBubble );
1143*b1cdbd2cSJim Jagielski 
1144*b1cdbd2cSJim Jagielski     // label value separator
1145*b1cdbd2cSJim Jagielski     rPropSet.GetStringProperty( maData.maSeparator, EXC_CHPROP_LABELSEPARATOR );
1146*b1cdbd2cSJim Jagielski     if( maData.maSeparator.Len() == 0 )
1147*b1cdbd2cSJim Jagielski         maData.maSeparator = String( sal_Unicode( ' ' ) );
1148*b1cdbd2cSJim Jagielski }
1149*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)1150*b1cdbd2cSJim Jagielski void XclExpChFrLabelProps::WriteBody( XclExpStream& rStrm )
1151*b1cdbd2cSJim Jagielski {
1152*b1cdbd2cSJim Jagielski     XclExpString aXclSep( maData.maSeparator, EXC_STR_FORCEUNICODE | EXC_STR_SMARTFLAGS );
1153*b1cdbd2cSJim Jagielski     rStrm << maData.mnFlags << aXclSep;
1154*b1cdbd2cSJim Jagielski }
1155*b1cdbd2cSJim Jagielski 
1156*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1157*b1cdbd2cSJim Jagielski 
~XclExpChFontBase()1158*b1cdbd2cSJim Jagielski XclExpChFontBase::~XclExpChFontBase()
1159*b1cdbd2cSJim Jagielski {
1160*b1cdbd2cSJim Jagielski }
1161*b1cdbd2cSJim Jagielski 
ConvertFontBase(const XclExpChRoot & rRoot,sal_uInt16 nFontIdx)1162*b1cdbd2cSJim Jagielski void XclExpChFontBase::ConvertFontBase( const XclExpChRoot& rRoot, sal_uInt16 nFontIdx )
1163*b1cdbd2cSJim Jagielski {
1164*b1cdbd2cSJim Jagielski     if( const XclExpFont* pFont = rRoot.GetFontBuffer().GetFont( nFontIdx ) )
1165*b1cdbd2cSJim Jagielski     {
1166*b1cdbd2cSJim Jagielski         XclExpChFontRef xFont( new XclExpChFont( nFontIdx ) );
1167*b1cdbd2cSJim Jagielski         SetFont( xFont, pFont->GetFontData().maColor, pFont->GetFontColorId() );
1168*b1cdbd2cSJim Jagielski     }
1169*b1cdbd2cSJim Jagielski }
1170*b1cdbd2cSJim Jagielski 
ConvertFontBase(const XclExpChRoot & rRoot,const ScfPropertySet & rPropSet)1171*b1cdbd2cSJim Jagielski void XclExpChFontBase::ConvertFontBase( const XclExpChRoot& rRoot, const ScfPropertySet& rPropSet )
1172*b1cdbd2cSJim Jagielski {
1173*b1cdbd2cSJim Jagielski     ConvertFontBase( rRoot, rRoot.ConvertFont( rPropSet, rRoot.GetDefApiScript() ) );
1174*b1cdbd2cSJim Jagielski }
1175*b1cdbd2cSJim Jagielski 
ConvertRotationBase(const XclExpChRoot & rRoot,const ScfPropertySet & rPropSet,bool bSupportsStacked)1176*b1cdbd2cSJim Jagielski void XclExpChFontBase::ConvertRotationBase(
1177*b1cdbd2cSJim Jagielski         const XclExpChRoot& rRoot, const ScfPropertySet& rPropSet, bool bSupportsStacked )
1178*b1cdbd2cSJim Jagielski {
1179*b1cdbd2cSJim Jagielski     sal_uInt16 nRotation = rRoot.GetChartPropSetHelper().ReadRotationProperties( rPropSet, bSupportsStacked );
1180*b1cdbd2cSJim Jagielski     SetRotation( nRotation );
1181*b1cdbd2cSJim Jagielski }
1182*b1cdbd2cSJim Jagielski 
1183*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1184*b1cdbd2cSJim Jagielski 
XclExpChText(const XclExpChRoot & rRoot)1185*b1cdbd2cSJim Jagielski XclExpChText::XclExpChText( const XclExpChRoot& rRoot ) :
1186*b1cdbd2cSJim Jagielski     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_TEXT, EXC_ID_CHTEXT, (rRoot.GetBiff() == EXC_BIFF8) ? 32 : 26 ),
1187*b1cdbd2cSJim Jagielski     mnTextColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
1188*b1cdbd2cSJim Jagielski {
1189*b1cdbd2cSJim Jagielski }
1190*b1cdbd2cSJim Jagielski 
SetFont(XclExpChFontRef xFont,const Color & rColor,sal_uInt32 nColorId)1191*b1cdbd2cSJim Jagielski void XclExpChText::SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId )
1192*b1cdbd2cSJim Jagielski {
1193*b1cdbd2cSJim Jagielski     mxFont = xFont;
1194*b1cdbd2cSJim Jagielski     maData.maTextColor = rColor;
1195*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOCOLOR, rColor == COL_AUTO );
1196*b1cdbd2cSJim Jagielski     mnTextColorId = nColorId;
1197*b1cdbd2cSJim Jagielski }
1198*b1cdbd2cSJim Jagielski 
SetRotation(sal_uInt16 nRotation)1199*b1cdbd2cSJim Jagielski void XclExpChText::SetRotation( sal_uInt16 nRotation )
1200*b1cdbd2cSJim Jagielski {
1201*b1cdbd2cSJim Jagielski     maData.mnRotation = nRotation;
1202*b1cdbd2cSJim Jagielski     ::insert_value( maData.mnFlags, XclTools::GetXclOrientFromRot( nRotation ), 8, 3 );
1203*b1cdbd2cSJim Jagielski }
1204*b1cdbd2cSJim Jagielski 
ConvertTitle(Reference<XTitle> xTitle,sal_uInt16 nTarget)1205*b1cdbd2cSJim Jagielski void XclExpChText::ConvertTitle( Reference< XTitle > xTitle, sal_uInt16 nTarget )
1206*b1cdbd2cSJim Jagielski {
1207*b1cdbd2cSJim Jagielski     switch( nTarget )
1208*b1cdbd2cSJim Jagielski     {
1209*b1cdbd2cSJim Jagielski         case EXC_CHOBJLINK_TITLE:   SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_TITLE );         break;
1210*b1cdbd2cSJim Jagielski         case EXC_CHOBJLINK_YAXIS:   SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_AXISTITLE, 1 );  break;
1211*b1cdbd2cSJim Jagielski         case EXC_CHOBJLINK_XAXIS:   SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_AXISTITLE, 0 );  break;
1212*b1cdbd2cSJim Jagielski         case EXC_CHOBJLINK_ZAXIS:   SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_AXISTITLE, 2 );  break;
1213*b1cdbd2cSJim Jagielski     }
1214*b1cdbd2cSJim Jagielski 
1215*b1cdbd2cSJim Jagielski     mxSrcLink.reset();
1216*b1cdbd2cSJim Jagielski     mxObjLink.reset( new XclExpChObjectLink( nTarget, XclChDataPointPos( 0, 0 ) ) );
1217*b1cdbd2cSJim Jagielski 
1218*b1cdbd2cSJim Jagielski     if( xTitle.is() )
1219*b1cdbd2cSJim Jagielski     {
1220*b1cdbd2cSJim Jagielski         // title frame formatting
1221*b1cdbd2cSJim Jagielski         ScfPropertySet aTitleProp( xTitle );
1222*b1cdbd2cSJim Jagielski         mxFrame = lclCreateFrame( GetChRoot(), aTitleProp, EXC_CHOBJTYPE_TEXT );
1223*b1cdbd2cSJim Jagielski 
1224*b1cdbd2cSJim Jagielski         // string sequence
1225*b1cdbd2cSJim Jagielski         mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
1226*b1cdbd2cSJim Jagielski         sal_uInt16 nFontIdx = mxSrcLink->ConvertStringSequence( xTitle->getText() );
1227*b1cdbd2cSJim Jagielski         ConvertFontBase( GetChRoot(), nFontIdx );
1228*b1cdbd2cSJim Jagielski 
1229*b1cdbd2cSJim Jagielski         // rotation
1230*b1cdbd2cSJim Jagielski         ConvertRotationBase( GetChRoot(), aTitleProp, true );
1231*b1cdbd2cSJim Jagielski 
1232*b1cdbd2cSJim Jagielski         // manual text position - only for main title
1233*b1cdbd2cSJim Jagielski         mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_PARENT, EXC_CHFRAMEPOS_PARENT ) );
1234*b1cdbd2cSJim Jagielski         if( nTarget == EXC_CHOBJLINK_TITLE )
1235*b1cdbd2cSJim Jagielski         {
1236*b1cdbd2cSJim Jagielski             Any aRelPos;
1237*b1cdbd2cSJim Jagielski             if( aTitleProp.GetAnyProperty( aRelPos, EXC_CHPROP_RELATIVEPOSITION ) && aRelPos.has< RelativePosition >() ) try
1238*b1cdbd2cSJim Jagielski             {
1239*b1cdbd2cSJim Jagielski                 // calculate absolute position for CHTEXT record
1240*b1cdbd2cSJim Jagielski                 Reference< cssc::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
1241*b1cdbd2cSJim Jagielski                 Reference< XShape > xTitleShape( xChart1Doc->getTitle(), UNO_SET_THROW );
1242*b1cdbd2cSJim Jagielski                 ::com::sun::star::awt::Point aPos = xTitleShape->getPosition();
1243*b1cdbd2cSJim Jagielski                 ::com::sun::star::awt::Size aSize = xTitleShape->getSize();
1244*b1cdbd2cSJim Jagielski                 ::com::sun::star::awt::Rectangle aRect( aPos.X, aPos.Y, aSize.Width, aSize.Height );
1245*b1cdbd2cSJim Jagielski                 maData.maRect = CalcChartRectFromHmm( aRect );
1246*b1cdbd2cSJim Jagielski                 ::insert_value( maData.mnFlags2, EXC_CHTEXT_POS_MOVED, 0, 4 );
1247*b1cdbd2cSJim Jagielski                 // manual title position implies manual plot area
1248*b1cdbd2cSJim Jagielski                 GetChartData().SetManualPlotArea();
1249*b1cdbd2cSJim Jagielski                 // calculate the default title position in chart units
1250*b1cdbd2cSJim Jagielski                 sal_Int32 nDefPosX = ::std::max< sal_Int32 >( (EXC_CHART_TOTALUNITS - maData.maRect.mnWidth) / 2, 0 );
1251*b1cdbd2cSJim Jagielski                 sal_Int32 nDefPosY = 85;
1252*b1cdbd2cSJim Jagielski                 // set the position relative to the standard position
1253*b1cdbd2cSJim Jagielski                 XclChRectangle& rFrameRect = mxFramePos->GetFramePosData().maRect;
1254*b1cdbd2cSJim Jagielski                 rFrameRect.mnX = maData.maRect.mnX - nDefPosX;
1255*b1cdbd2cSJim Jagielski                 rFrameRect.mnY = maData.maRect.mnY - nDefPosY;
1256*b1cdbd2cSJim Jagielski             }
1257*b1cdbd2cSJim Jagielski             catch( Exception& )
1258*b1cdbd2cSJim Jagielski             {
1259*b1cdbd2cSJim Jagielski             }
1260*b1cdbd2cSJim Jagielski         }
1261*b1cdbd2cSJim Jagielski     }
1262*b1cdbd2cSJim Jagielski     else
1263*b1cdbd2cSJim Jagielski     {
1264*b1cdbd2cSJim Jagielski         ::set_flag( maData.mnFlags, EXC_CHTEXT_DELETED );
1265*b1cdbd2cSJim Jagielski     }
1266*b1cdbd2cSJim Jagielski }
1267*b1cdbd2cSJim Jagielski 
ConvertLegend(const ScfPropertySet & rPropSet)1268*b1cdbd2cSJim Jagielski void XclExpChText::ConvertLegend( const ScfPropertySet& rPropSet )
1269*b1cdbd2cSJim Jagielski {
1270*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOTEXT );
1271*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOGEN );
1272*b1cdbd2cSJim Jagielski     ConvertFontBase( GetChRoot(), rPropSet );
1273*b1cdbd2cSJim Jagielski }
1274*b1cdbd2cSJim Jagielski 
ConvertDataLabel(const ScfPropertySet & rPropSet,const XclChTypeInfo & rTypeInfo,const XclChDataPointPos & rPointPos)1275*b1cdbd2cSJim Jagielski bool XclExpChText::ConvertDataLabel( const ScfPropertySet& rPropSet,
1276*b1cdbd2cSJim Jagielski         const XclChTypeInfo& rTypeInfo, const XclChDataPointPos& rPointPos )
1277*b1cdbd2cSJim Jagielski {
1278*b1cdbd2cSJim Jagielski     SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_DATALABEL, rPointPos.mnPointIdx, rPointPos.mnSeriesIdx );
1279*b1cdbd2cSJim Jagielski 
1280*b1cdbd2cSJim Jagielski     cssc2::DataPointLabel aPointLabel;
1281*b1cdbd2cSJim Jagielski     if( !rPropSet.GetProperty( aPointLabel, EXC_CHPROP_LABEL ) )
1282*b1cdbd2cSJim Jagielski         return false;
1283*b1cdbd2cSJim Jagielski 
1284*b1cdbd2cSJim Jagielski     // percentage only allowed in pie and donut charts
1285*b1cdbd2cSJim Jagielski     bool bIsPie = rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE;
1286*b1cdbd2cSJim Jagielski     // bubble sizes only allowed in bubble charts
1287*b1cdbd2cSJim Jagielski     bool bIsBubble = rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES;
1288*b1cdbd2cSJim Jagielski     DBG_ASSERT( (GetBiff() == EXC_BIFF8) || !bIsBubble, "XclExpChText::ConvertDataLabel - bubble charts only in BIFF8" );
1289*b1cdbd2cSJim Jagielski 
1290*b1cdbd2cSJim Jagielski     // raw show flags
1291*b1cdbd2cSJim Jagielski     bool bShowValue   = !bIsBubble && aPointLabel.ShowNumber;       // Chart2 uses 'ShowNumber' for bubble size
1292*b1cdbd2cSJim Jagielski     bool bShowPercent = bIsPie && aPointLabel.ShowNumberInPercent;  // percentage only in pie/donut charts
1293*b1cdbd2cSJim Jagielski     bool bShowCateg   = aPointLabel.ShowCategoryName;
1294*b1cdbd2cSJim Jagielski     bool bShowBubble  = bIsBubble && aPointLabel.ShowNumber;        // Chart2 uses 'ShowNumber' for bubble size
1295*b1cdbd2cSJim Jagielski     bool bShowAny     = bShowValue || bShowPercent || bShowCateg || bShowBubble;
1296*b1cdbd2cSJim Jagielski 
1297*b1cdbd2cSJim Jagielski     // create the CHFRLABELPROPS record for extended settings in BIFF8
1298*b1cdbd2cSJim Jagielski     if( bShowAny && (GetBiff() == EXC_BIFF8) )
1299*b1cdbd2cSJim Jagielski     {
1300*b1cdbd2cSJim Jagielski         mxLabelProps.reset( new XclExpChFrLabelProps( GetChRoot() ) );
1301*b1cdbd2cSJim Jagielski         mxLabelProps->Convert( rPropSet, false, bShowCateg, bShowValue, bShowPercent, bShowBubble );
1302*b1cdbd2cSJim Jagielski     }
1303*b1cdbd2cSJim Jagielski 
1304*b1cdbd2cSJim Jagielski     // restrict to combinations allowed in CHTEXT
1305*b1cdbd2cSJim Jagielski     if( bShowPercent ) bShowValue = false;              // percent wins over value
1306*b1cdbd2cSJim Jagielski     if( bShowValue ) bShowCateg = false;                // value wins over category
1307*b1cdbd2cSJim Jagielski     if( bShowValue || bShowCateg ) bShowBubble = false; // value or category wins over bubble size
1308*b1cdbd2cSJim Jagielski 
1309*b1cdbd2cSJim Jagielski     // set all flags
1310*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOTEXT );
1311*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWVALUE, bShowValue );
1312*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWPERCENT, bShowPercent );
1313*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG, bShowCateg );
1314*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEGPERC, bShowPercent && bShowCateg );
1315*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWBUBBLE, bShowBubble );
1316*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWSYMBOL, bShowAny && aPointLabel.ShowLegendSymbol );
1317*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTEXT_DELETED, !bShowAny );
1318*b1cdbd2cSJim Jagielski 
1319*b1cdbd2cSJim Jagielski     if( bShowAny )
1320*b1cdbd2cSJim Jagielski     {
1321*b1cdbd2cSJim Jagielski         // font settings
1322*b1cdbd2cSJim Jagielski         ConvertFontBase( GetChRoot(), rPropSet );
1323*b1cdbd2cSJim Jagielski         ConvertRotationBase( GetChRoot(), rPropSet, false );
1324*b1cdbd2cSJim Jagielski         // label placement
1325*b1cdbd2cSJim Jagielski         sal_Int32 nPlacement = 0;
1326*b1cdbd2cSJim Jagielski         sal_uInt16 nLabelPos = EXC_CHTEXT_POS_AUTO;
1327*b1cdbd2cSJim Jagielski         if( rPropSet.GetProperty( nPlacement, EXC_CHPROP_LABELPLACEMENT ) )
1328*b1cdbd2cSJim Jagielski         {
1329*b1cdbd2cSJim Jagielski             using namespace cssc::DataLabelPlacement;
1330*b1cdbd2cSJim Jagielski             if( nPlacement == rTypeInfo.mnDefaultLabelPos )
1331*b1cdbd2cSJim Jagielski             {
1332*b1cdbd2cSJim Jagielski                 nLabelPos = EXC_CHTEXT_POS_DEFAULT;
1333*b1cdbd2cSJim Jagielski             }
1334*b1cdbd2cSJim Jagielski             else switch( nPlacement )
1335*b1cdbd2cSJim Jagielski             {
1336*b1cdbd2cSJim Jagielski                 case AVOID_OVERLAP:     nLabelPos = EXC_CHTEXT_POS_AUTO;    break;
1337*b1cdbd2cSJim Jagielski                 case CENTER:            nLabelPos = EXC_CHTEXT_POS_CENTER;  break;
1338*b1cdbd2cSJim Jagielski                 case TOP:               nLabelPos = EXC_CHTEXT_POS_ABOVE;   break;
1339*b1cdbd2cSJim Jagielski                 case TOP_LEFT:          nLabelPos = EXC_CHTEXT_POS_LEFT;    break;
1340*b1cdbd2cSJim Jagielski                 case LEFT:              nLabelPos = EXC_CHTEXT_POS_LEFT;    break;
1341*b1cdbd2cSJim Jagielski                 case BOTTOM_LEFT:       nLabelPos = EXC_CHTEXT_POS_LEFT;    break;
1342*b1cdbd2cSJim Jagielski                 case BOTTOM:            nLabelPos = EXC_CHTEXT_POS_BELOW;   break;
1343*b1cdbd2cSJim Jagielski                 case BOTTOM_RIGHT:      nLabelPos = EXC_CHTEXT_POS_RIGHT;   break;
1344*b1cdbd2cSJim Jagielski                 case RIGHT:             nLabelPos = EXC_CHTEXT_POS_RIGHT;   break;
1345*b1cdbd2cSJim Jagielski                 case TOP_RIGHT:         nLabelPos = EXC_CHTEXT_POS_RIGHT;   break;
1346*b1cdbd2cSJim Jagielski                 case INSIDE:            nLabelPos = EXC_CHTEXT_POS_INSIDE;  break;
1347*b1cdbd2cSJim Jagielski                 case OUTSIDE:           nLabelPos = EXC_CHTEXT_POS_OUTSIDE; break;
1348*b1cdbd2cSJim Jagielski                 case NEAR_ORIGIN:       nLabelPos = EXC_CHTEXT_POS_AXIS;    break;
1349*b1cdbd2cSJim Jagielski                 default:                DBG_ERRORFILE( "XclExpChText::ConvertDataLabel - unknown label placement type" );
1350*b1cdbd2cSJim Jagielski             }
1351*b1cdbd2cSJim Jagielski         }
1352*b1cdbd2cSJim Jagielski         ::insert_value( maData.mnFlags2, nLabelPos, 0, 4 );
1353*b1cdbd2cSJim Jagielski         // source link (contains number format)
1354*b1cdbd2cSJim Jagielski         mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
1355*b1cdbd2cSJim Jagielski         if( bShowValue || bShowPercent )
1356*b1cdbd2cSJim Jagielski             // percentage format wins over value format
1357*b1cdbd2cSJim Jagielski             mxSrcLink->ConvertNumFmt( rPropSet, bShowPercent );
1358*b1cdbd2cSJim Jagielski         // object link
1359*b1cdbd2cSJim Jagielski         mxObjLink.reset( new XclExpChObjectLink( EXC_CHOBJLINK_DATA, rPointPos ) );
1360*b1cdbd2cSJim Jagielski     }
1361*b1cdbd2cSJim Jagielski 
1362*b1cdbd2cSJim Jagielski     /*  Return true to indicate valid label settings:
1363*b1cdbd2cSJim Jagielski         - for existing labels at entire series
1364*b1cdbd2cSJim Jagielski         - for any settings at single data point (to be able to delete a point label) */
1365*b1cdbd2cSJim Jagielski     return bShowAny || (rPointPos.mnPointIdx != EXC_CHDATAFORMAT_ALLPOINTS);
1366*b1cdbd2cSJim Jagielski }
1367*b1cdbd2cSJim Jagielski 
ConvertTrendLineEquation(const ScfPropertySet & rPropSet,const XclChDataPointPos & rPointPos)1368*b1cdbd2cSJim Jagielski void XclExpChText::ConvertTrendLineEquation( const ScfPropertySet& rPropSet, const XclChDataPointPos& rPointPos )
1369*b1cdbd2cSJim Jagielski {
1370*b1cdbd2cSJim Jagielski     // required flags
1371*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOTEXT );
1372*b1cdbd2cSJim Jagielski     if( GetBiff() == EXC_BIFF8 )
1373*b1cdbd2cSJim Jagielski         ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG ); // must set this to make equation visible in Excel
1374*b1cdbd2cSJim Jagielski     // frame formatting
1375*b1cdbd2cSJim Jagielski     mxFrame = lclCreateFrame( GetChRoot(), rPropSet, EXC_CHOBJTYPE_TEXT );
1376*b1cdbd2cSJim Jagielski     // font settings
1377*b1cdbd2cSJim Jagielski     maData.mnHAlign = EXC_CHTEXT_ALIGN_TOPLEFT;
1378*b1cdbd2cSJim Jagielski     maData.mnVAlign = EXC_CHTEXT_ALIGN_TOPLEFT;
1379*b1cdbd2cSJim Jagielski     ConvertFontBase( GetChRoot(), rPropSet );
1380*b1cdbd2cSJim Jagielski     // source link (contains number format)
1381*b1cdbd2cSJim Jagielski     mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
1382*b1cdbd2cSJim Jagielski     mxSrcLink->ConvertNumFmt( rPropSet, false );
1383*b1cdbd2cSJim Jagielski     // object link
1384*b1cdbd2cSJim Jagielski     mxObjLink.reset( new XclExpChObjectLink( EXC_CHOBJLINK_DATA, rPointPos ) );
1385*b1cdbd2cSJim Jagielski }
1386*b1cdbd2cSJim Jagielski 
GetAttLabelFlags() const1387*b1cdbd2cSJim Jagielski sal_uInt16 XclExpChText::GetAttLabelFlags() const
1388*b1cdbd2cSJim Jagielski {
1389*b1cdbd2cSJim Jagielski     sal_uInt16 nFlags = 0;
1390*b1cdbd2cSJim Jagielski     ::set_flag( nFlags, EXC_CHATTLABEL_SHOWVALUE,     ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWVALUE ) );
1391*b1cdbd2cSJim Jagielski     ::set_flag( nFlags, EXC_CHATTLABEL_SHOWPERCENT,   ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWPERCENT ) );
1392*b1cdbd2cSJim Jagielski     ::set_flag( nFlags, EXC_CHATTLABEL_SHOWCATEGPERC, ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEGPERC ) );
1393*b1cdbd2cSJim Jagielski     ::set_flag( nFlags, EXC_CHATTLABEL_SHOWCATEG,     ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG ) );
1394*b1cdbd2cSJim Jagielski     return nFlags;
1395*b1cdbd2cSJim Jagielski }
1396*b1cdbd2cSJim Jagielski 
WriteSubRecords(XclExpStream & rStrm)1397*b1cdbd2cSJim Jagielski void XclExpChText::WriteSubRecords( XclExpStream& rStrm )
1398*b1cdbd2cSJim Jagielski {
1399*b1cdbd2cSJim Jagielski     // CHFRAMEPOS record
1400*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxFramePos );
1401*b1cdbd2cSJim Jagielski     // CHFONT record
1402*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxFont );
1403*b1cdbd2cSJim Jagielski     // CHSOURCELINK group
1404*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxSrcLink );
1405*b1cdbd2cSJim Jagielski     // CHFRAME group
1406*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxFrame );
1407*b1cdbd2cSJim Jagielski     // CHOBJECTLINK record
1408*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxObjLink );
1409*b1cdbd2cSJim Jagielski     // CHFRLABELPROPS record
1410*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxLabelProps );
1411*b1cdbd2cSJim Jagielski }
1412*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)1413*b1cdbd2cSJim Jagielski void XclExpChText::WriteBody( XclExpStream& rStrm )
1414*b1cdbd2cSJim Jagielski {
1415*b1cdbd2cSJim Jagielski     rStrm   << maData.mnHAlign
1416*b1cdbd2cSJim Jagielski             << maData.mnVAlign
1417*b1cdbd2cSJim Jagielski             << maData.mnBackMode
1418*b1cdbd2cSJim Jagielski             << maData.maTextColor
1419*b1cdbd2cSJim Jagielski             << maData.maRect
1420*b1cdbd2cSJim Jagielski             << maData.mnFlags;
1421*b1cdbd2cSJim Jagielski 
1422*b1cdbd2cSJim Jagielski     if( GetBiff() == EXC_BIFF8 )
1423*b1cdbd2cSJim Jagielski     {
1424*b1cdbd2cSJim Jagielski         rStrm   << GetPalette().GetColorIndex( mnTextColorId )
1425*b1cdbd2cSJim Jagielski                 << maData.mnFlags2
1426*b1cdbd2cSJim Jagielski                 << maData.mnRotation;
1427*b1cdbd2cSJim Jagielski     }
1428*b1cdbd2cSJim Jagielski }
1429*b1cdbd2cSJim Jagielski 
1430*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1431*b1cdbd2cSJim Jagielski 
1432*b1cdbd2cSJim Jagielski namespace {
1433*b1cdbd2cSJim Jagielski 
1434*b1cdbd2cSJim Jagielski /** Creates and returns an Excel text object from the passed title. */
lclCreateTitle(const XclExpChRoot & rRoot,Reference<XTitled> xTitled,sal_uInt16 nTarget)1435*b1cdbd2cSJim Jagielski XclExpChTextRef lclCreateTitle( const XclExpChRoot& rRoot, Reference< XTitled > xTitled, sal_uInt16 nTarget )
1436*b1cdbd2cSJim Jagielski {
1437*b1cdbd2cSJim Jagielski     Reference< XTitle > xTitle;
1438*b1cdbd2cSJim Jagielski     if( xTitled.is() )
1439*b1cdbd2cSJim Jagielski         xTitle = xTitled->getTitleObject();
1440*b1cdbd2cSJim Jagielski 
1441*b1cdbd2cSJim Jagielski     XclExpChTextRef xText( new XclExpChText( rRoot ) );
1442*b1cdbd2cSJim Jagielski     xText->ConvertTitle( xTitle, nTarget );
1443*b1cdbd2cSJim Jagielski     /*  Do not delete the CHTEXT group for the main title. A missing CHTEXT
1444*b1cdbd2cSJim Jagielski         will be interpreted as auto-generated title showing the series title in
1445*b1cdbd2cSJim Jagielski         charts that contain exactly one data series. */
1446*b1cdbd2cSJim Jagielski     if( (nTarget != EXC_CHOBJLINK_TITLE) && !xText->HasString() )
1447*b1cdbd2cSJim Jagielski         xText.reset();
1448*b1cdbd2cSJim Jagielski 
1449*b1cdbd2cSJim Jagielski     return xText;
1450*b1cdbd2cSJim Jagielski }
1451*b1cdbd2cSJim Jagielski 
1452*b1cdbd2cSJim Jagielski }
1453*b1cdbd2cSJim Jagielski 
1454*b1cdbd2cSJim Jagielski // Data series ================================================================
1455*b1cdbd2cSJim Jagielski 
XclExpChMarkerFormat(const XclExpChRoot & rRoot)1456*b1cdbd2cSJim Jagielski XclExpChMarkerFormat::XclExpChMarkerFormat( const XclExpChRoot& rRoot ) :
1457*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CHMARKERFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 20 : 12 ),
1458*b1cdbd2cSJim Jagielski     mnLineColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) ),
1459*b1cdbd2cSJim Jagielski     mnFillColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) )
1460*b1cdbd2cSJim Jagielski {
1461*b1cdbd2cSJim Jagielski }
1462*b1cdbd2cSJim Jagielski 
Convert(const XclExpChRoot & rRoot,const ScfPropertySet & rPropSet,sal_uInt16 nFormatIdx)1463*b1cdbd2cSJim Jagielski void XclExpChMarkerFormat::Convert( const XclExpChRoot& rRoot,
1464*b1cdbd2cSJim Jagielski         const ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx )
1465*b1cdbd2cSJim Jagielski {
1466*b1cdbd2cSJim Jagielski     rRoot.GetChartPropSetHelper().ReadMarkerProperties( maData, rPropSet, nFormatIdx );
1467*b1cdbd2cSJim Jagielski     /*  Set marker line/fill color to series line color.
1468*b1cdbd2cSJim Jagielski         TODO: remove this if OOChart supports own colors in markers. */
1469*b1cdbd2cSJim Jagielski     Color aLineColor;
1470*b1cdbd2cSJim Jagielski     if( rPropSet.GetColorProperty( aLineColor, EXC_CHPROP_COLOR ) )
1471*b1cdbd2cSJim Jagielski         maData.maLineColor = maData.maFillColor = aLineColor;
1472*b1cdbd2cSJim Jagielski     // register colors in palette
1473*b1cdbd2cSJim Jagielski     RegisterColors( rRoot );
1474*b1cdbd2cSJim Jagielski }
1475*b1cdbd2cSJim Jagielski 
ConvertStockSymbol(const XclExpChRoot & rRoot,const ScfPropertySet & rPropSet,bool bCloseSymbol)1476*b1cdbd2cSJim Jagielski void XclExpChMarkerFormat::ConvertStockSymbol( const XclExpChRoot& rRoot,
1477*b1cdbd2cSJim Jagielski         const ScfPropertySet& rPropSet, bool bCloseSymbol )
1478*b1cdbd2cSJim Jagielski {
1479*b1cdbd2cSJim Jagielski     // clear the automatic flag
1480*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHMARKERFORMAT_AUTO, false );
1481*b1cdbd2cSJim Jagielski     // symbol type and color
1482*b1cdbd2cSJim Jagielski     if( bCloseSymbol )
1483*b1cdbd2cSJim Jagielski     {
1484*b1cdbd2cSJim Jagielski         // set symbol type for the 'close' data series
1485*b1cdbd2cSJim Jagielski         maData.mnMarkerType = EXC_CHMARKERFORMAT_DOWJ;
1486*b1cdbd2cSJim Jagielski         maData.mnMarkerSize = EXC_CHMARKERFORMAT_DOUBLESIZE;
1487*b1cdbd2cSJim Jagielski         // set symbol line/fill color to series line color
1488*b1cdbd2cSJim Jagielski         Color aLineColor;
1489*b1cdbd2cSJim Jagielski         if( rPropSet.GetColorProperty( aLineColor, EXC_CHPROP_COLOR ) )
1490*b1cdbd2cSJim Jagielski         {
1491*b1cdbd2cSJim Jagielski             maData.maLineColor = maData.maFillColor = aLineColor;
1492*b1cdbd2cSJim Jagielski             RegisterColors( rRoot );
1493*b1cdbd2cSJim Jagielski         }
1494*b1cdbd2cSJim Jagielski     }
1495*b1cdbd2cSJim Jagielski     else
1496*b1cdbd2cSJim Jagielski     {
1497*b1cdbd2cSJim Jagielski         // set invisible symbol
1498*b1cdbd2cSJim Jagielski         maData.mnMarkerType = EXC_CHMARKERFORMAT_NOSYMBOL;
1499*b1cdbd2cSJim Jagielski     }
1500*b1cdbd2cSJim Jagielski }
1501*b1cdbd2cSJim Jagielski 
RegisterColors(const XclExpChRoot & rRoot)1502*b1cdbd2cSJim Jagielski void XclExpChMarkerFormat::RegisterColors( const XclExpChRoot& rRoot )
1503*b1cdbd2cSJim Jagielski {
1504*b1cdbd2cSJim Jagielski     if( HasMarker() )
1505*b1cdbd2cSJim Jagielski     {
1506*b1cdbd2cSJim Jagielski         if( HasLineColor() )
1507*b1cdbd2cSJim Jagielski             mnLineColorId = rRoot.GetPalette().InsertColor( maData.maLineColor, EXC_COLOR_CHARTLINE );
1508*b1cdbd2cSJim Jagielski         if( HasFillColor() )
1509*b1cdbd2cSJim Jagielski             mnFillColorId = rRoot.GetPalette().InsertColor( maData.maFillColor, EXC_COLOR_CHARTAREA );
1510*b1cdbd2cSJim Jagielski     }
1511*b1cdbd2cSJim Jagielski }
1512*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)1513*b1cdbd2cSJim Jagielski void XclExpChMarkerFormat::WriteBody( XclExpStream& rStrm )
1514*b1cdbd2cSJim Jagielski {
1515*b1cdbd2cSJim Jagielski     rStrm << maData.maLineColor << maData.maFillColor << maData.mnMarkerType << maData.mnFlags;
1516*b1cdbd2cSJim Jagielski     if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
1517*b1cdbd2cSJim Jagielski     {
1518*b1cdbd2cSJim Jagielski         const XclExpPalette& rPal = rStrm.GetRoot().GetPalette();
1519*b1cdbd2cSJim Jagielski         rStrm << rPal.GetColorIndex( mnLineColorId ) << rPal.GetColorIndex( mnFillColorId ) << maData.mnMarkerSize;
1520*b1cdbd2cSJim Jagielski     }
1521*b1cdbd2cSJim Jagielski }
1522*b1cdbd2cSJim Jagielski 
1523*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1524*b1cdbd2cSJim Jagielski 
XclExpChPieFormat()1525*b1cdbd2cSJim Jagielski XclExpChPieFormat::XclExpChPieFormat() :
1526*b1cdbd2cSJim Jagielski     XclExpUInt16Record( EXC_ID_CHPIEFORMAT, 0 )
1527*b1cdbd2cSJim Jagielski {
1528*b1cdbd2cSJim Jagielski }
1529*b1cdbd2cSJim Jagielski 
Convert(const ScfPropertySet & rPropSet)1530*b1cdbd2cSJim Jagielski void XclExpChPieFormat::Convert( const ScfPropertySet& rPropSet )
1531*b1cdbd2cSJim Jagielski {
1532*b1cdbd2cSJim Jagielski     double fApiDist(0.0);
1533*b1cdbd2cSJim Jagielski     if( rPropSet.GetProperty( fApiDist, EXC_CHPROP_OFFSET ) )
1534*b1cdbd2cSJim Jagielski         SetValue( limit_cast< sal_uInt16 >( fApiDist * 100.0, 0, 100 ) );
1535*b1cdbd2cSJim Jagielski }
1536*b1cdbd2cSJim Jagielski 
1537*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1538*b1cdbd2cSJim Jagielski 
XclExpCh3dDataFormat()1539*b1cdbd2cSJim Jagielski XclExpCh3dDataFormat::XclExpCh3dDataFormat() :
1540*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CH3DDATAFORMAT, 2 )
1541*b1cdbd2cSJim Jagielski {
1542*b1cdbd2cSJim Jagielski }
1543*b1cdbd2cSJim Jagielski 
Convert(const ScfPropertySet & rPropSet)1544*b1cdbd2cSJim Jagielski void XclExpCh3dDataFormat::Convert( const ScfPropertySet& rPropSet )
1545*b1cdbd2cSJim Jagielski {
1546*b1cdbd2cSJim Jagielski     sal_Int32 nApiType(0);
1547*b1cdbd2cSJim Jagielski     if( rPropSet.GetProperty( nApiType, EXC_CHPROP_GEOMETRY3D ) )
1548*b1cdbd2cSJim Jagielski     {
1549*b1cdbd2cSJim Jagielski         using namespace cssc2::DataPointGeometry3D;
1550*b1cdbd2cSJim Jagielski         switch( nApiType )
1551*b1cdbd2cSJim Jagielski         {
1552*b1cdbd2cSJim Jagielski             case CUBOID:
1553*b1cdbd2cSJim Jagielski                 maData.mnBase = EXC_CH3DDATAFORMAT_RECT;
1554*b1cdbd2cSJim Jagielski                 maData.mnTop = EXC_CH3DDATAFORMAT_STRAIGHT;
1555*b1cdbd2cSJim Jagielski             break;
1556*b1cdbd2cSJim Jagielski             case PYRAMID:
1557*b1cdbd2cSJim Jagielski                 maData.mnBase = EXC_CH3DDATAFORMAT_RECT;
1558*b1cdbd2cSJim Jagielski                 maData.mnTop = EXC_CH3DDATAFORMAT_SHARP;
1559*b1cdbd2cSJim Jagielski             break;
1560*b1cdbd2cSJim Jagielski             case CYLINDER:
1561*b1cdbd2cSJim Jagielski                 maData.mnBase = EXC_CH3DDATAFORMAT_CIRC;
1562*b1cdbd2cSJim Jagielski                 maData.mnTop = EXC_CH3DDATAFORMAT_STRAIGHT;
1563*b1cdbd2cSJim Jagielski             break;
1564*b1cdbd2cSJim Jagielski             case CONE:
1565*b1cdbd2cSJim Jagielski                 maData.mnBase = EXC_CH3DDATAFORMAT_CIRC;
1566*b1cdbd2cSJim Jagielski                 maData.mnTop = EXC_CH3DDATAFORMAT_SHARP;
1567*b1cdbd2cSJim Jagielski             break;
1568*b1cdbd2cSJim Jagielski             default:
1569*b1cdbd2cSJim Jagielski                 DBG_ERRORFILE( "XclExpCh3dDataFormat::Convert - unknown 3D bar format" );
1570*b1cdbd2cSJim Jagielski         }
1571*b1cdbd2cSJim Jagielski     }
1572*b1cdbd2cSJim Jagielski }
1573*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)1574*b1cdbd2cSJim Jagielski void XclExpCh3dDataFormat::WriteBody( XclExpStream& rStrm )
1575*b1cdbd2cSJim Jagielski {
1576*b1cdbd2cSJim Jagielski     rStrm << maData.mnBase << maData.mnTop;
1577*b1cdbd2cSJim Jagielski }
1578*b1cdbd2cSJim Jagielski 
1579*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1580*b1cdbd2cSJim Jagielski 
XclExpChAttachedLabel(sal_uInt16 nFlags)1581*b1cdbd2cSJim Jagielski XclExpChAttachedLabel::XclExpChAttachedLabel( sal_uInt16 nFlags ) :
1582*b1cdbd2cSJim Jagielski     XclExpUInt16Record( EXC_ID_CHATTACHEDLABEL, nFlags )
1583*b1cdbd2cSJim Jagielski {
1584*b1cdbd2cSJim Jagielski }
1585*b1cdbd2cSJim Jagielski 
1586*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1587*b1cdbd2cSJim Jagielski 
XclExpChDataFormat(const XclExpChRoot & rRoot,const XclChDataPointPos & rPointPos,sal_uInt16 nFormatIdx)1588*b1cdbd2cSJim Jagielski XclExpChDataFormat::XclExpChDataFormat( const XclExpChRoot& rRoot,
1589*b1cdbd2cSJim Jagielski         const XclChDataPointPos& rPointPos, sal_uInt16 nFormatIdx ) :
1590*b1cdbd2cSJim Jagielski     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_DATAFORMAT, EXC_ID_CHDATAFORMAT, 8 )
1591*b1cdbd2cSJim Jagielski {
1592*b1cdbd2cSJim Jagielski     maData.maPointPos = rPointPos;
1593*b1cdbd2cSJim Jagielski     maData.mnFormatIdx = nFormatIdx;
1594*b1cdbd2cSJim Jagielski }
1595*b1cdbd2cSJim Jagielski 
ConvertDataSeries(const ScfPropertySet & rPropSet,const XclChExtTypeInfo & rTypeInfo)1596*b1cdbd2cSJim Jagielski void XclExpChDataFormat::ConvertDataSeries( const ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo )
1597*b1cdbd2cSJim Jagielski {
1598*b1cdbd2cSJim Jagielski     // line and area formatting
1599*b1cdbd2cSJim Jagielski     ConvertFrameBase( GetChRoot(), rPropSet, rTypeInfo.GetSeriesObjectType() );
1600*b1cdbd2cSJim Jagielski 
1601*b1cdbd2cSJim Jagielski     // data point symbols
1602*b1cdbd2cSJim Jagielski     bool bIsFrame = rTypeInfo.IsSeriesFrameFormat();
1603*b1cdbd2cSJim Jagielski     if( !bIsFrame )
1604*b1cdbd2cSJim Jagielski     {
1605*b1cdbd2cSJim Jagielski         mxMarkerFmt.reset( new XclExpChMarkerFormat( GetChRoot() ) );
1606*b1cdbd2cSJim Jagielski         mxMarkerFmt->Convert( GetChRoot(), rPropSet, maData.mnFormatIdx );
1607*b1cdbd2cSJim Jagielski     }
1608*b1cdbd2cSJim Jagielski 
1609*b1cdbd2cSJim Jagielski     // pie segments
1610*b1cdbd2cSJim Jagielski     if( rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE )
1611*b1cdbd2cSJim Jagielski     {
1612*b1cdbd2cSJim Jagielski         mxPieFmt.reset( new XclExpChPieFormat );
1613*b1cdbd2cSJim Jagielski         mxPieFmt->Convert( rPropSet );
1614*b1cdbd2cSJim Jagielski     }
1615*b1cdbd2cSJim Jagielski 
1616*b1cdbd2cSJim Jagielski     // 3D bars (only allowed for entire series in BIFF8)
1617*b1cdbd2cSJim Jagielski     if( IsSeriesFormat() && (GetBiff() == EXC_BIFF8) && rTypeInfo.mb3dChart && (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_BAR) )
1618*b1cdbd2cSJim Jagielski     {
1619*b1cdbd2cSJim Jagielski         mx3dDataFmt.reset( new XclExpCh3dDataFormat );
1620*b1cdbd2cSJim Jagielski         mx3dDataFmt->Convert( rPropSet );
1621*b1cdbd2cSJim Jagielski     }
1622*b1cdbd2cSJim Jagielski 
1623*b1cdbd2cSJim Jagielski     // spline
1624*b1cdbd2cSJim Jagielski     if( IsSeriesFormat() && rTypeInfo.mbSpline && !bIsFrame )
1625*b1cdbd2cSJim Jagielski         mxSeriesFmt.reset( new XclExpUInt16Record( EXC_ID_CHSERIESFORMAT, EXC_CHSERIESFORMAT_SMOOTHED ) );
1626*b1cdbd2cSJim Jagielski 
1627*b1cdbd2cSJim Jagielski     // data point labels
1628*b1cdbd2cSJim Jagielski     XclExpChTextRef xLabel( new XclExpChText( GetChRoot() ) );
1629*b1cdbd2cSJim Jagielski     if( xLabel->ConvertDataLabel( rPropSet, rTypeInfo, maData.maPointPos ) )
1630*b1cdbd2cSJim Jagielski     {
1631*b1cdbd2cSJim Jagielski         // CHTEXT groups for data labels are stored in global CHCHART group
1632*b1cdbd2cSJim Jagielski         GetChartData().SetDataLabel( xLabel );
1633*b1cdbd2cSJim Jagielski         mxAttLabel.reset( new XclExpChAttachedLabel( xLabel->GetAttLabelFlags() ) );
1634*b1cdbd2cSJim Jagielski     }
1635*b1cdbd2cSJim Jagielski }
1636*b1cdbd2cSJim Jagielski 
ConvertStockSeries(const ScfPropertySet & rPropSet,bool bCloseSymbol)1637*b1cdbd2cSJim Jagielski void XclExpChDataFormat::ConvertStockSeries( const ScfPropertySet& rPropSet, bool bCloseSymbol )
1638*b1cdbd2cSJim Jagielski {
1639*b1cdbd2cSJim Jagielski     // set line format to invisible
1640*b1cdbd2cSJim Jagielski     SetDefaultFrameBase( GetChRoot(), EXC_CHFRAMETYPE_INVISIBLE, false );
1641*b1cdbd2cSJim Jagielski     // set symbols to invisible or to 'close' series symbol
1642*b1cdbd2cSJim Jagielski     mxMarkerFmt.reset( new XclExpChMarkerFormat( GetChRoot() ) );
1643*b1cdbd2cSJim Jagielski     mxMarkerFmt->ConvertStockSymbol( GetChRoot(), rPropSet, bCloseSymbol );
1644*b1cdbd2cSJim Jagielski }
1645*b1cdbd2cSJim Jagielski 
ConvertLine(const ScfPropertySet & rPropSet,XclChObjectType eObjType)1646*b1cdbd2cSJim Jagielski void XclExpChDataFormat::ConvertLine( const ScfPropertySet& rPropSet, XclChObjectType eObjType )
1647*b1cdbd2cSJim Jagielski {
1648*b1cdbd2cSJim Jagielski     ConvertFrameBase( GetChRoot(), rPropSet, eObjType );
1649*b1cdbd2cSJim Jagielski }
1650*b1cdbd2cSJim Jagielski 
WriteSubRecords(XclExpStream & rStrm)1651*b1cdbd2cSJim Jagielski void XclExpChDataFormat::WriteSubRecords( XclExpStream& rStrm )
1652*b1cdbd2cSJim Jagielski {
1653*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mx3dDataFmt );
1654*b1cdbd2cSJim Jagielski     WriteFrameRecords( rStrm );
1655*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxPieFmt );
1656*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxMarkerFmt );
1657*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxSeriesFmt );
1658*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxAttLabel );
1659*b1cdbd2cSJim Jagielski }
1660*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)1661*b1cdbd2cSJim Jagielski void XclExpChDataFormat::WriteBody( XclExpStream& rStrm )
1662*b1cdbd2cSJim Jagielski {
1663*b1cdbd2cSJim Jagielski     rStrm   << maData.maPointPos.mnPointIdx
1664*b1cdbd2cSJim Jagielski             << maData.maPointPos.mnSeriesIdx
1665*b1cdbd2cSJim Jagielski             << maData.mnFormatIdx
1666*b1cdbd2cSJim Jagielski             << maData.mnFlags;
1667*b1cdbd2cSJim Jagielski }
1668*b1cdbd2cSJim Jagielski 
1669*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1670*b1cdbd2cSJim Jagielski 
XclExpChSerTrendLine(const XclExpChRoot & rRoot)1671*b1cdbd2cSJim Jagielski XclExpChSerTrendLine::XclExpChSerTrendLine( const XclExpChRoot& rRoot ) :
1672*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CHSERTRENDLINE, 28 ),
1673*b1cdbd2cSJim Jagielski     XclExpChRoot( rRoot )
1674*b1cdbd2cSJim Jagielski {
1675*b1cdbd2cSJim Jagielski }
1676*b1cdbd2cSJim Jagielski 
Convert(Reference<XRegressionCurve> xRegCurve,sal_uInt16 nSeriesIdx)1677*b1cdbd2cSJim Jagielski bool XclExpChSerTrendLine::Convert( Reference< XRegressionCurve > xRegCurve, sal_uInt16 nSeriesIdx )
1678*b1cdbd2cSJim Jagielski {
1679*b1cdbd2cSJim Jagielski     if( !xRegCurve.is() )
1680*b1cdbd2cSJim Jagielski         return false;
1681*b1cdbd2cSJim Jagielski 
1682*b1cdbd2cSJim Jagielski     // trend line type
1683*b1cdbd2cSJim Jagielski     ScfPropertySet aCurveProp( xRegCurve );
1684*b1cdbd2cSJim Jagielski     OUString aService = aCurveProp.GetServiceName();
1685*b1cdbd2cSJim Jagielski     if( aService == SERVICE_CHART2_LINEARREGCURVE )
1686*b1cdbd2cSJim Jagielski     {
1687*b1cdbd2cSJim Jagielski         maData.mnLineType = EXC_CHSERTREND_POLYNOMIAL;
1688*b1cdbd2cSJim Jagielski         maData.mnOrder = 1;
1689*b1cdbd2cSJim Jagielski     }
1690*b1cdbd2cSJim Jagielski     else if( aService == SERVICE_CHART2_EXPREGCURVE )
1691*b1cdbd2cSJim Jagielski         maData.mnLineType = EXC_CHSERTREND_EXPONENTIAL;
1692*b1cdbd2cSJim Jagielski     else if( aService == SERVICE_CHART2_LOGREGCURVE )
1693*b1cdbd2cSJim Jagielski         maData.mnLineType = EXC_CHSERTREND_LOGARITHMIC;
1694*b1cdbd2cSJim Jagielski     else if( aService == SERVICE_CHART2_POTREGCURVE )
1695*b1cdbd2cSJim Jagielski         maData.mnLineType = EXC_CHSERTREND_POWER;
1696*b1cdbd2cSJim Jagielski     else
1697*b1cdbd2cSJim Jagielski         return false;
1698*b1cdbd2cSJim Jagielski 
1699*b1cdbd2cSJim Jagielski     // line formatting
1700*b1cdbd2cSJim Jagielski     XclChDataPointPos aPointPos( nSeriesIdx );
1701*b1cdbd2cSJim Jagielski     mxDataFmt.reset( new XclExpChDataFormat( GetChRoot(), aPointPos, 0 ) );
1702*b1cdbd2cSJim Jagielski     mxDataFmt->ConvertLine( aCurveProp, EXC_CHOBJTYPE_TRENDLINE );
1703*b1cdbd2cSJim Jagielski 
1704*b1cdbd2cSJim Jagielski     // #i83100# show equation and correlation coefficient
1705*b1cdbd2cSJim Jagielski     ScfPropertySet aEquationProp( xRegCurve->getEquationProperties() );
1706*b1cdbd2cSJim Jagielski     maData.mnShowEquation = aEquationProp.GetBoolProperty( EXC_CHPROP_SHOWEQUATION ) ? 1 : 0;
1707*b1cdbd2cSJim Jagielski     maData.mnShowRSquared = aEquationProp.GetBoolProperty( EXC_CHPROP_SHOWCORRELATION ) ? 1 : 0;
1708*b1cdbd2cSJim Jagielski 
1709*b1cdbd2cSJim Jagielski     // #i83100# formatting of the equation text box
1710*b1cdbd2cSJim Jagielski     if( (maData.mnShowEquation != 0) || (maData.mnShowRSquared != 0) )
1711*b1cdbd2cSJim Jagielski     {
1712*b1cdbd2cSJim Jagielski         mxLabel.reset( new XclExpChText( GetChRoot() ) );
1713*b1cdbd2cSJim Jagielski         mxLabel->ConvertTrendLineEquation( aEquationProp, aPointPos );
1714*b1cdbd2cSJim Jagielski     }
1715*b1cdbd2cSJim Jagielski 
1716*b1cdbd2cSJim Jagielski     // missing features
1717*b1cdbd2cSJim Jagielski     // #i20819# polynomial trend lines
1718*b1cdbd2cSJim Jagielski     // #i66819# moving average trend lines
1719*b1cdbd2cSJim Jagielski     // #i5085# manual trend line size
1720*b1cdbd2cSJim Jagielski     // #i34093# manual crossing point
1721*b1cdbd2cSJim Jagielski     return true;
1722*b1cdbd2cSJim Jagielski }
1723*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)1724*b1cdbd2cSJim Jagielski void XclExpChSerTrendLine::WriteBody( XclExpStream& rStrm )
1725*b1cdbd2cSJim Jagielski {
1726*b1cdbd2cSJim Jagielski     rStrm   << maData.mnLineType
1727*b1cdbd2cSJim Jagielski             << maData.mnOrder
1728*b1cdbd2cSJim Jagielski             << maData.mfIntercept
1729*b1cdbd2cSJim Jagielski             << maData.mnShowEquation
1730*b1cdbd2cSJim Jagielski             << maData.mnShowRSquared
1731*b1cdbd2cSJim Jagielski             << maData.mfForecastFor
1732*b1cdbd2cSJim Jagielski             << maData.mfForecastBack;
1733*b1cdbd2cSJim Jagielski }
1734*b1cdbd2cSJim Jagielski 
1735*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1736*b1cdbd2cSJim Jagielski 
XclExpChSerErrorBar(const XclExpChRoot & rRoot,sal_uInt8 nBarType)1737*b1cdbd2cSJim Jagielski XclExpChSerErrorBar::XclExpChSerErrorBar( const XclExpChRoot& rRoot, sal_uInt8 nBarType ) :
1738*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CHSERERRORBAR, 14 ),
1739*b1cdbd2cSJim Jagielski     XclExpChRoot( rRoot )
1740*b1cdbd2cSJim Jagielski {
1741*b1cdbd2cSJim Jagielski     maData.mnBarType = nBarType;
1742*b1cdbd2cSJim Jagielski }
1743*b1cdbd2cSJim Jagielski 
Convert(XclExpChSourceLink & rValueLink,sal_uInt16 & rnValueCount,const ScfPropertySet & rPropSet)1744*b1cdbd2cSJim Jagielski bool XclExpChSerErrorBar::Convert( XclExpChSourceLink& rValueLink, sal_uInt16& rnValueCount, const ScfPropertySet& rPropSet )
1745*b1cdbd2cSJim Jagielski {
1746*b1cdbd2cSJim Jagielski     sal_Int32 nBarStyle = 0;
1747*b1cdbd2cSJim Jagielski     bool bOk = rPropSet.GetProperty( nBarStyle, EXC_CHPROP_ERRORBARSTYLE );
1748*b1cdbd2cSJim Jagielski     if( bOk )
1749*b1cdbd2cSJim Jagielski     {
1750*b1cdbd2cSJim Jagielski         switch( nBarStyle )
1751*b1cdbd2cSJim Jagielski         {
1752*b1cdbd2cSJim Jagielski             case cssc::ErrorBarStyle::ABSOLUTE:
1753*b1cdbd2cSJim Jagielski                 maData.mnSourceType = EXC_CHSERERR_FIXED;
1754*b1cdbd2cSJim Jagielski                 rPropSet.GetProperty( maData.mfValue, EXC_CHPROP_POSITIVEERROR );
1755*b1cdbd2cSJim Jagielski             break;
1756*b1cdbd2cSJim Jagielski             case cssc::ErrorBarStyle::RELATIVE:
1757*b1cdbd2cSJim Jagielski                 maData.mnSourceType = EXC_CHSERERR_PERCENT;
1758*b1cdbd2cSJim Jagielski                 rPropSet.GetProperty( maData.mfValue, EXC_CHPROP_POSITIVEERROR );
1759*b1cdbd2cSJim Jagielski             break;
1760*b1cdbd2cSJim Jagielski             case cssc::ErrorBarStyle::STANDARD_DEVIATION:
1761*b1cdbd2cSJim Jagielski                 maData.mnSourceType = EXC_CHSERERR_STDDEV;
1762*b1cdbd2cSJim Jagielski                 rPropSet.GetProperty( maData.mfValue, EXC_CHPROP_WEIGHT );
1763*b1cdbd2cSJim Jagielski             break;
1764*b1cdbd2cSJim Jagielski             case cssc::ErrorBarStyle::STANDARD_ERROR:
1765*b1cdbd2cSJim Jagielski                 maData.mnSourceType = EXC_CHSERERR_STDERR;
1766*b1cdbd2cSJim Jagielski             break;
1767*b1cdbd2cSJim Jagielski             case cssc::ErrorBarStyle::FROM_DATA:
1768*b1cdbd2cSJim Jagielski             {
1769*b1cdbd2cSJim Jagielski                 bOk = false;
1770*b1cdbd2cSJim Jagielski                 maData.mnSourceType = EXC_CHSERERR_CUSTOM;
1771*b1cdbd2cSJim Jagielski                 Reference< XDataSource > xDataSource( rPropSet.GetApiPropertySet(), UNO_QUERY );
1772*b1cdbd2cSJim Jagielski                 if( xDataSource.is() )
1773*b1cdbd2cSJim Jagielski                 {
1774*b1cdbd2cSJim Jagielski                     // find first sequence with current role
1775*b1cdbd2cSJim Jagielski                     OUString aRole = XclChartHelper::GetErrorBarValuesRole( maData.mnBarType );
1776*b1cdbd2cSJim Jagielski                     Reference< XDataSequence > xValueSeq;
1777*b1cdbd2cSJim Jagielski 
1778*b1cdbd2cSJim Jagielski                     Sequence< Reference< XLabeledDataSequence > > aLabeledSeqVec = xDataSource->getDataSequences();
1779*b1cdbd2cSJim Jagielski                     const Reference< XLabeledDataSequence >* pBeg = aLabeledSeqVec.getConstArray();
1780*b1cdbd2cSJim Jagielski                     const Reference< XLabeledDataSequence >* pEnd = pBeg + aLabeledSeqVec.getLength();
1781*b1cdbd2cSJim Jagielski                     for( const Reference< XLabeledDataSequence >* pIt = pBeg; !xValueSeq.is() && (pIt != pEnd); ++pIt )
1782*b1cdbd2cSJim Jagielski                     {
1783*b1cdbd2cSJim Jagielski                         Reference< XDataSequence > xTmpValueSeq = (*pIt)->getValues();
1784*b1cdbd2cSJim Jagielski                         ScfPropertySet aValueProp( xTmpValueSeq );
1785*b1cdbd2cSJim Jagielski                         OUString aCurrRole;
1786*b1cdbd2cSJim Jagielski                         if( aValueProp.GetProperty( aCurrRole, EXC_CHPROP_ROLE ) && (aCurrRole == aRole) )
1787*b1cdbd2cSJim Jagielski                             xValueSeq = xTmpValueSeq;
1788*b1cdbd2cSJim Jagielski                     }
1789*b1cdbd2cSJim Jagielski                     if( xValueSeq.is() )
1790*b1cdbd2cSJim Jagielski                     {
1791*b1cdbd2cSJim Jagielski                         // #i86465# pass value count back to series
1792*b1cdbd2cSJim Jagielski                         rnValueCount = maData.mnValueCount = rValueLink.ConvertDataSequence( xValueSeq, true );
1793*b1cdbd2cSJim Jagielski                         bOk = maData.mnValueCount > 0;
1794*b1cdbd2cSJim Jagielski                     }
1795*b1cdbd2cSJim Jagielski                 }
1796*b1cdbd2cSJim Jagielski             }
1797*b1cdbd2cSJim Jagielski             break;
1798*b1cdbd2cSJim Jagielski             default:
1799*b1cdbd2cSJim Jagielski                 bOk = false;
1800*b1cdbd2cSJim Jagielski         }
1801*b1cdbd2cSJim Jagielski     }
1802*b1cdbd2cSJim Jagielski     return bOk;
1803*b1cdbd2cSJim Jagielski }
1804*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)1805*b1cdbd2cSJim Jagielski void XclExpChSerErrorBar::WriteBody( XclExpStream& rStrm )
1806*b1cdbd2cSJim Jagielski {
1807*b1cdbd2cSJim Jagielski     rStrm   << maData.mnBarType
1808*b1cdbd2cSJim Jagielski             << maData.mnSourceType
1809*b1cdbd2cSJim Jagielski             << maData.mnLineEnd
1810*b1cdbd2cSJim Jagielski             << sal_uInt8( 1 )       // must be 1 to make line visible
1811*b1cdbd2cSJim Jagielski             << maData.mfValue
1812*b1cdbd2cSJim Jagielski             << maData.mnValueCount;
1813*b1cdbd2cSJim Jagielski }
1814*b1cdbd2cSJim Jagielski 
1815*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1816*b1cdbd2cSJim Jagielski 
1817*b1cdbd2cSJim Jagielski namespace {
1818*b1cdbd2cSJim Jagielski 
1819*b1cdbd2cSJim Jagielski /** Returns the property set of the specified data point. */
lclGetPointPropSet(Reference<XDataSeries> xDataSeries,sal_Int32 nPointIdx)1820*b1cdbd2cSJim Jagielski ScfPropertySet lclGetPointPropSet( Reference< XDataSeries > xDataSeries, sal_Int32 nPointIdx )
1821*b1cdbd2cSJim Jagielski {
1822*b1cdbd2cSJim Jagielski     ScfPropertySet aPropSet;
1823*b1cdbd2cSJim Jagielski     try
1824*b1cdbd2cSJim Jagielski     {
1825*b1cdbd2cSJim Jagielski         aPropSet.Set( xDataSeries->getDataPointByIndex( nPointIdx ) );
1826*b1cdbd2cSJim Jagielski     }
1827*b1cdbd2cSJim Jagielski     catch( Exception& )
1828*b1cdbd2cSJim Jagielski     {
1829*b1cdbd2cSJim Jagielski         DBG_ERRORFILE( "lclGetPointPropSet - no data point property set" );
1830*b1cdbd2cSJim Jagielski     }
1831*b1cdbd2cSJim Jagielski     return aPropSet;
1832*b1cdbd2cSJim Jagielski }
1833*b1cdbd2cSJim Jagielski 
1834*b1cdbd2cSJim Jagielski } // namespace
1835*b1cdbd2cSJim Jagielski 
XclExpChSeries(const XclExpChRoot & rRoot,sal_uInt16 nSeriesIdx)1836*b1cdbd2cSJim Jagielski XclExpChSeries::XclExpChSeries( const XclExpChRoot& rRoot, sal_uInt16 nSeriesIdx ) :
1837*b1cdbd2cSJim Jagielski     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_SERIES, EXC_ID_CHSERIES, (rRoot.GetBiff() == EXC_BIFF8) ? 12 : 8 ),
1838*b1cdbd2cSJim Jagielski     mnGroupIdx( EXC_CHSERGROUP_NONE ),
1839*b1cdbd2cSJim Jagielski     mnSeriesIdx( nSeriesIdx ),
1840*b1cdbd2cSJim Jagielski     mnParentIdx( EXC_CHSERIES_INVALID )
1841*b1cdbd2cSJim Jagielski {
1842*b1cdbd2cSJim Jagielski     // CHSOURCELINK records are always required, even if unused
1843*b1cdbd2cSJim Jagielski     mxTitleLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
1844*b1cdbd2cSJim Jagielski     mxValueLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_VALUES ) );
1845*b1cdbd2cSJim Jagielski     mxCategLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_CATEGORY ) );
1846*b1cdbd2cSJim Jagielski     if( GetBiff() == EXC_BIFF8 )
1847*b1cdbd2cSJim Jagielski         mxBubbleLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_BUBBLES ) );
1848*b1cdbd2cSJim Jagielski }
1849*b1cdbd2cSJim Jagielski 
ConvertDataSeries(Reference<XDiagram> xDiagram,Reference<XDataSeries> xDataSeries,const XclChExtTypeInfo & rTypeInfo,sal_uInt16 nGroupIdx,sal_uInt16 nFormatIdx)1850*b1cdbd2cSJim Jagielski bool XclExpChSeries::ConvertDataSeries(
1851*b1cdbd2cSJim Jagielski         Reference< XDiagram > xDiagram, Reference< XDataSeries > xDataSeries,
1852*b1cdbd2cSJim Jagielski         const XclChExtTypeInfo& rTypeInfo, sal_uInt16 nGroupIdx, sal_uInt16 nFormatIdx )
1853*b1cdbd2cSJim Jagielski {
1854*b1cdbd2cSJim Jagielski     bool bOk = false;
1855*b1cdbd2cSJim Jagielski     Reference< XDataSource > xDataSource( xDataSeries, UNO_QUERY );
1856*b1cdbd2cSJim Jagielski     if( xDataSource.is() )
1857*b1cdbd2cSJim Jagielski     {
1858*b1cdbd2cSJim Jagielski         Reference< XDataSequence > xYValueSeq, xTitleSeq, xXValueSeq, xBubbleSeq;
1859*b1cdbd2cSJim Jagielski 
1860*b1cdbd2cSJim Jagielski         // find first sequence with role 'values-y'
1861*b1cdbd2cSJim Jagielski         Sequence< Reference< XLabeledDataSequence > > aLabeledSeqVec = xDataSource->getDataSequences();
1862*b1cdbd2cSJim Jagielski         const Reference< XLabeledDataSequence >* pBeg = aLabeledSeqVec.getConstArray();
1863*b1cdbd2cSJim Jagielski         const Reference< XLabeledDataSequence >* pEnd = pBeg + aLabeledSeqVec.getLength();
1864*b1cdbd2cSJim Jagielski         for( const Reference< XLabeledDataSequence >* pIt = pBeg; pIt != pEnd; ++pIt )
1865*b1cdbd2cSJim Jagielski         {
1866*b1cdbd2cSJim Jagielski             Reference< XDataSequence > xTmpValueSeq = (*pIt)->getValues();
1867*b1cdbd2cSJim Jagielski             ScfPropertySet aValueProp( xTmpValueSeq );
1868*b1cdbd2cSJim Jagielski             OUString aRole;
1869*b1cdbd2cSJim Jagielski             if( aValueProp.GetProperty( aRole, EXC_CHPROP_ROLE ) )
1870*b1cdbd2cSJim Jagielski             {
1871*b1cdbd2cSJim Jagielski                 if( !xYValueSeq.is() && (aRole == EXC_CHPROP_ROLE_YVALUES) )
1872*b1cdbd2cSJim Jagielski                 {
1873*b1cdbd2cSJim Jagielski                     xYValueSeq = xTmpValueSeq;
1874*b1cdbd2cSJim Jagielski                     if( !xTitleSeq.is() )
1875*b1cdbd2cSJim Jagielski                         xTitleSeq = (*pIt)->getLabel(); // ignore role of label sequence
1876*b1cdbd2cSJim Jagielski                 }
1877*b1cdbd2cSJim Jagielski                 else if( !xXValueSeq.is() && !rTypeInfo.mbCategoryAxis && (aRole == EXC_CHPROP_ROLE_XVALUES) )
1878*b1cdbd2cSJim Jagielski                 {
1879*b1cdbd2cSJim Jagielski                     xXValueSeq = xTmpValueSeq;
1880*b1cdbd2cSJim Jagielski                 }
1881*b1cdbd2cSJim Jagielski                 else if( !xBubbleSeq.is() && (rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES) && (aRole == EXC_CHPROP_ROLE_SIZEVALUES) )
1882*b1cdbd2cSJim Jagielski                 {
1883*b1cdbd2cSJim Jagielski                     xBubbleSeq = xTmpValueSeq;
1884*b1cdbd2cSJim Jagielski                     xTitleSeq = (*pIt)->getLabel();     // ignore role of label sequence
1885*b1cdbd2cSJim Jagielski                 }
1886*b1cdbd2cSJim Jagielski             }
1887*b1cdbd2cSJim Jagielski         }
1888*b1cdbd2cSJim Jagielski 
1889*b1cdbd2cSJim Jagielski         bOk = xYValueSeq.is();
1890*b1cdbd2cSJim Jagielski         if( bOk )
1891*b1cdbd2cSJim Jagielski         {
1892*b1cdbd2cSJim Jagielski             // chart type group index
1893*b1cdbd2cSJim Jagielski             mnGroupIdx = nGroupIdx;
1894*b1cdbd2cSJim Jagielski 
1895*b1cdbd2cSJim Jagielski             // convert source links
1896*b1cdbd2cSJim Jagielski             maData.mnValueCount = mxValueLink->ConvertDataSequence( xYValueSeq, true );
1897*b1cdbd2cSJim Jagielski             mxTitleLink->ConvertDataSequence( xTitleSeq, true );
1898*b1cdbd2cSJim Jagielski 
1899*b1cdbd2cSJim Jagielski             // X values of XY charts
1900*b1cdbd2cSJim Jagielski             maData.mnCategCount = mxCategLink->ConvertDataSequence( xXValueSeq, false, maData.mnValueCount );
1901*b1cdbd2cSJim Jagielski 
1902*b1cdbd2cSJim Jagielski             // size values of bubble charts
1903*b1cdbd2cSJim Jagielski             if( mxBubbleLink.is() )
1904*b1cdbd2cSJim Jagielski                 mxBubbleLink->ConvertDataSequence( xBubbleSeq, false, maData.mnValueCount );
1905*b1cdbd2cSJim Jagielski 
1906*b1cdbd2cSJim Jagielski             // series formatting
1907*b1cdbd2cSJim Jagielski             XclChDataPointPos aPointPos( mnSeriesIdx );
1908*b1cdbd2cSJim Jagielski             ScfPropertySet aSeriesProp( xDataSeries );
1909*b1cdbd2cSJim Jagielski             mxSeriesFmt.reset( new XclExpChDataFormat( GetChRoot(), aPointPos, nFormatIdx ) );
1910*b1cdbd2cSJim Jagielski             mxSeriesFmt->ConvertDataSeries( aSeriesProp, rTypeInfo );
1911*b1cdbd2cSJim Jagielski 
1912*b1cdbd2cSJim Jagielski             // trend lines
1913*b1cdbd2cSJim Jagielski             CreateTrendLines( xDataSeries );
1914*b1cdbd2cSJim Jagielski 
1915*b1cdbd2cSJim Jagielski             // error bars
1916*b1cdbd2cSJim Jagielski             CreateErrorBars( aSeriesProp, EXC_CHPROP_ERRORBARX, EXC_CHSERERR_XPLUS, EXC_CHSERERR_XMINUS );
1917*b1cdbd2cSJim Jagielski             CreateErrorBars( aSeriesProp, EXC_CHPROP_ERRORBARY, EXC_CHSERERR_YPLUS, EXC_CHSERERR_YMINUS );
1918*b1cdbd2cSJim Jagielski 
1919*b1cdbd2cSJim Jagielski             if( maData.mnValueCount > 0 )
1920*b1cdbd2cSJim Jagielski             {
1921*b1cdbd2cSJim Jagielski                 const sal_Int32 nMaxPointCount = maData.mnValueCount;
1922*b1cdbd2cSJim Jagielski 
1923*b1cdbd2cSJim Jagielski                 /*  #i91063# Create missing fill properties in pie/doughnut charts.
1924*b1cdbd2cSJim Jagielski                     If freshly created (never saved to ODF), these charts show
1925*b1cdbd2cSJim Jagielski                     varying point colors but do not return these points via API. */
1926*b1cdbd2cSJim Jagielski                 if( xDiagram.is() && (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE) )
1927*b1cdbd2cSJim Jagielski                 {
1928*b1cdbd2cSJim Jagielski                     Reference< XColorScheme > xColorScheme = xDiagram->getDefaultColorScheme();
1929*b1cdbd2cSJim Jagielski                     if( xColorScheme.is() )
1930*b1cdbd2cSJim Jagielski                     {
1931*b1cdbd2cSJim Jagielski                         const OUString aFillStyleName = CREATE_OUSTRING( "FillStyle" );
1932*b1cdbd2cSJim Jagielski                         const OUString aColorName = CREATE_OUSTRING( "Color" );
1933*b1cdbd2cSJim Jagielski                         namespace cssd = ::com::sun::star::drawing;
1934*b1cdbd2cSJim Jagielski                         for( sal_Int32 nPointIdx = 0; nPointIdx < nMaxPointCount; ++nPointIdx )
1935*b1cdbd2cSJim Jagielski                         {
1936*b1cdbd2cSJim Jagielski                             aPointPos.mnPointIdx = static_cast< sal_uInt16 >( nPointIdx );
1937*b1cdbd2cSJim Jagielski                             ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, nPointIdx );
1938*b1cdbd2cSJim Jagielski                             // test that the point fill style is solid, but no color is set
1939*b1cdbd2cSJim Jagielski                             cssd::FillStyle eFillStyle = cssd::FillStyle_NONE;
1940*b1cdbd2cSJim Jagielski                             if( aPointProp.GetProperty( eFillStyle, aFillStyleName ) &&
1941*b1cdbd2cSJim Jagielski                                 (eFillStyle == cssd::FillStyle_SOLID) &&
1942*b1cdbd2cSJim Jagielski                                 !aPointProp.HasProperty( aColorName ) )
1943*b1cdbd2cSJim Jagielski                             {
1944*b1cdbd2cSJim Jagielski                                 aPointProp.SetProperty( aColorName, xColorScheme->getColorByIndex( nPointIdx ) );
1945*b1cdbd2cSJim Jagielski                             }
1946*b1cdbd2cSJim Jagielski                         }
1947*b1cdbd2cSJim Jagielski                     }
1948*b1cdbd2cSJim Jagielski                 }
1949*b1cdbd2cSJim Jagielski 
1950*b1cdbd2cSJim Jagielski                 // data point formatting
1951*b1cdbd2cSJim Jagielski                 Sequence< sal_Int32 > aPointIndexes;
1952*b1cdbd2cSJim Jagielski                 if( aSeriesProp.GetProperty( aPointIndexes, EXC_CHPROP_ATTRIBDATAPOINTS ) && aPointIndexes.hasElements() )
1953*b1cdbd2cSJim Jagielski                 {
1954*b1cdbd2cSJim Jagielski                     const sal_Int32* pnBeg = aPointIndexes.getConstArray();
1955*b1cdbd2cSJim Jagielski                     const sal_Int32* pnEnd = pnBeg + aPointIndexes.getLength();
1956*b1cdbd2cSJim Jagielski                     for( const sal_Int32* pnIt = pnBeg; (pnIt != pnEnd) && (*pnIt < nMaxPointCount); ++pnIt )
1957*b1cdbd2cSJim Jagielski                     {
1958*b1cdbd2cSJim Jagielski                         aPointPos.mnPointIdx = static_cast< sal_uInt16 >( *pnIt );
1959*b1cdbd2cSJim Jagielski                         ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, *pnIt );
1960*b1cdbd2cSJim Jagielski                         XclExpChDataFormatRef xPointFmt( new XclExpChDataFormat( GetChRoot(), aPointPos, nFormatIdx ) );
1961*b1cdbd2cSJim Jagielski                         xPointFmt->ConvertDataSeries( aPointProp, rTypeInfo );
1962*b1cdbd2cSJim Jagielski                         maPointFmts.AppendRecord( xPointFmt );
1963*b1cdbd2cSJim Jagielski                     }
1964*b1cdbd2cSJim Jagielski                 }
1965*b1cdbd2cSJim Jagielski             }
1966*b1cdbd2cSJim Jagielski         }
1967*b1cdbd2cSJim Jagielski     }
1968*b1cdbd2cSJim Jagielski     return bOk;
1969*b1cdbd2cSJim Jagielski }
1970*b1cdbd2cSJim Jagielski 
ConvertStockSeries(XDataSeriesRef xDataSeries,const OUString & rValueRole,sal_uInt16 nGroupIdx,sal_uInt16 nFormatIdx,bool bCloseSymbol)1971*b1cdbd2cSJim Jagielski bool XclExpChSeries::ConvertStockSeries( XDataSeriesRef xDataSeries,
1972*b1cdbd2cSJim Jagielski         const OUString& rValueRole, sal_uInt16 nGroupIdx, sal_uInt16 nFormatIdx, bool bCloseSymbol )
1973*b1cdbd2cSJim Jagielski {
1974*b1cdbd2cSJim Jagielski     bool bOk = false;
1975*b1cdbd2cSJim Jagielski     Reference< XDataSource > xDataSource( xDataSeries, UNO_QUERY );
1976*b1cdbd2cSJim Jagielski     if( xDataSource.is() )
1977*b1cdbd2cSJim Jagielski     {
1978*b1cdbd2cSJim Jagielski         Reference< XDataSequence > xYValueSeq, xTitleSeq;
1979*b1cdbd2cSJim Jagielski 
1980*b1cdbd2cSJim Jagielski         // find first sequence with passed role
1981*b1cdbd2cSJim Jagielski         Sequence< Reference< XLabeledDataSequence > > aLabeledSeqVec = xDataSource->getDataSequences();
1982*b1cdbd2cSJim Jagielski         const Reference< XLabeledDataSequence >* pBeg = aLabeledSeqVec.getConstArray();
1983*b1cdbd2cSJim Jagielski         const Reference< XLabeledDataSequence >* pEnd = pBeg + aLabeledSeqVec.getLength();
1984*b1cdbd2cSJim Jagielski         for( const Reference< XLabeledDataSequence >* pIt = pBeg; !xYValueSeq.is() && (pIt != pEnd); ++pIt )
1985*b1cdbd2cSJim Jagielski         {
1986*b1cdbd2cSJim Jagielski             Reference< XDataSequence > xTmpValueSeq = (*pIt)->getValues();
1987*b1cdbd2cSJim Jagielski             ScfPropertySet aValueProp( xTmpValueSeq );
1988*b1cdbd2cSJim Jagielski             OUString aRole;
1989*b1cdbd2cSJim Jagielski             if( aValueProp.GetProperty( aRole, EXC_CHPROP_ROLE ) && (aRole == rValueRole) )
1990*b1cdbd2cSJim Jagielski             {
1991*b1cdbd2cSJim Jagielski                 xYValueSeq = xTmpValueSeq;
1992*b1cdbd2cSJim Jagielski                 xTitleSeq = (*pIt)->getLabel();     // ignore role of label sequence
1993*b1cdbd2cSJim Jagielski             }
1994*b1cdbd2cSJim Jagielski         }
1995*b1cdbd2cSJim Jagielski 
1996*b1cdbd2cSJim Jagielski         bOk = xYValueSeq.is();
1997*b1cdbd2cSJim Jagielski         if( bOk )
1998*b1cdbd2cSJim Jagielski         {
1999*b1cdbd2cSJim Jagielski             // chart type group index
2000*b1cdbd2cSJim Jagielski             mnGroupIdx = nGroupIdx;
2001*b1cdbd2cSJim Jagielski             // convert source links
2002*b1cdbd2cSJim Jagielski             maData.mnValueCount = mxValueLink->ConvertDataSequence( xYValueSeq, true );
2003*b1cdbd2cSJim Jagielski             mxTitleLink->ConvertDataSequence( xTitleSeq, true );
2004*b1cdbd2cSJim Jagielski             // series formatting
2005*b1cdbd2cSJim Jagielski             ScfPropertySet aSeriesProp( xDataSeries );
2006*b1cdbd2cSJim Jagielski             mxSeriesFmt.reset( new XclExpChDataFormat( GetChRoot(), XclChDataPointPos( mnSeriesIdx ), nFormatIdx ) );
2007*b1cdbd2cSJim Jagielski             mxSeriesFmt->ConvertStockSeries( aSeriesProp, bCloseSymbol );
2008*b1cdbd2cSJim Jagielski         }
2009*b1cdbd2cSJim Jagielski     }
2010*b1cdbd2cSJim Jagielski     return bOk;
2011*b1cdbd2cSJim Jagielski }
2012*b1cdbd2cSJim Jagielski 
ConvertTrendLine(const XclExpChSeries & rParent,Reference<XRegressionCurve> xRegCurve)2013*b1cdbd2cSJim Jagielski bool XclExpChSeries::ConvertTrendLine( const XclExpChSeries& rParent, Reference< XRegressionCurve > xRegCurve )
2014*b1cdbd2cSJim Jagielski {
2015*b1cdbd2cSJim Jagielski     InitFromParent( rParent );
2016*b1cdbd2cSJim Jagielski     mxTrendLine.reset( new XclExpChSerTrendLine( GetChRoot() ) );
2017*b1cdbd2cSJim Jagielski     bool bOk = mxTrendLine->Convert( xRegCurve, mnSeriesIdx );
2018*b1cdbd2cSJim Jagielski     if( bOk )
2019*b1cdbd2cSJim Jagielski     {
2020*b1cdbd2cSJim Jagielski         mxSeriesFmt = mxTrendLine->GetDataFormat();
2021*b1cdbd2cSJim Jagielski         GetChartData().SetDataLabel( mxTrendLine->GetDataLabel() );
2022*b1cdbd2cSJim Jagielski     }
2023*b1cdbd2cSJim Jagielski     return bOk;
2024*b1cdbd2cSJim Jagielski }
2025*b1cdbd2cSJim Jagielski 
ConvertErrorBar(const XclExpChSeries & rParent,const ScfPropertySet & rPropSet,sal_uInt8 nBarId)2026*b1cdbd2cSJim Jagielski bool XclExpChSeries::ConvertErrorBar( const XclExpChSeries& rParent, const ScfPropertySet& rPropSet, sal_uInt8 nBarId )
2027*b1cdbd2cSJim Jagielski {
2028*b1cdbd2cSJim Jagielski     InitFromParent( rParent );
2029*b1cdbd2cSJim Jagielski     // error bar settings
2030*b1cdbd2cSJim Jagielski     mxErrorBar.reset( new XclExpChSerErrorBar( GetChRoot(), nBarId ) );
2031*b1cdbd2cSJim Jagielski     bool bOk = mxErrorBar->Convert( *mxValueLink, maData.mnValueCount, rPropSet );
2032*b1cdbd2cSJim Jagielski     if( bOk )
2033*b1cdbd2cSJim Jagielski     {
2034*b1cdbd2cSJim Jagielski         // error bar formatting
2035*b1cdbd2cSJim Jagielski         mxSeriesFmt.reset( new XclExpChDataFormat( GetChRoot(), XclChDataPointPos( mnSeriesIdx ), 0 ) );
2036*b1cdbd2cSJim Jagielski         mxSeriesFmt->ConvertLine( rPropSet, EXC_CHOBJTYPE_ERRORBAR );
2037*b1cdbd2cSJim Jagielski     }
2038*b1cdbd2cSJim Jagielski     return bOk;
2039*b1cdbd2cSJim Jagielski }
2040*b1cdbd2cSJim Jagielski 
ConvertCategSequence(Reference<XLabeledDataSequence> xCategSeq)2041*b1cdbd2cSJim Jagielski void XclExpChSeries::ConvertCategSequence( Reference< XLabeledDataSequence > xCategSeq )
2042*b1cdbd2cSJim Jagielski {
2043*b1cdbd2cSJim Jagielski     if( xCategSeq.is() )
2044*b1cdbd2cSJim Jagielski         maData.mnCategCount = mxCategLink->ConvertDataSequence( xCategSeq->getValues(), false );
2045*b1cdbd2cSJim Jagielski }
2046*b1cdbd2cSJim Jagielski 
WriteSubRecords(XclExpStream & rStrm)2047*b1cdbd2cSJim Jagielski void XclExpChSeries::WriteSubRecords( XclExpStream& rStrm )
2048*b1cdbd2cSJim Jagielski {
2049*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxTitleLink );
2050*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxValueLink );
2051*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxCategLink );
2052*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxBubbleLink );
2053*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxSeriesFmt );
2054*b1cdbd2cSJim Jagielski     maPointFmts.Save( rStrm );
2055*b1cdbd2cSJim Jagielski     if( mnGroupIdx != EXC_CHSERGROUP_NONE )
2056*b1cdbd2cSJim Jagielski         XclExpUInt16Record( EXC_ID_CHSERGROUP, mnGroupIdx ).Save( rStrm );
2057*b1cdbd2cSJim Jagielski     if( mnParentIdx != EXC_CHSERIES_INVALID )
2058*b1cdbd2cSJim Jagielski         XclExpUInt16Record( EXC_ID_CHSERPARENT, mnParentIdx ).Save( rStrm );
2059*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxTrendLine );
2060*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxErrorBar );
2061*b1cdbd2cSJim Jagielski }
2062*b1cdbd2cSJim Jagielski 
InitFromParent(const XclExpChSeries & rParent)2063*b1cdbd2cSJim Jagielski void XclExpChSeries::InitFromParent( const XclExpChSeries& rParent )
2064*b1cdbd2cSJim Jagielski {
2065*b1cdbd2cSJim Jagielski     // index to parent series is stored 1-based
2066*b1cdbd2cSJim Jagielski     mnParentIdx = rParent.mnSeriesIdx + 1;
2067*b1cdbd2cSJim Jagielski     /*  #i86465# MSO2007 SP1 expects correct point counts in child series
2068*b1cdbd2cSJim Jagielski         (there was no problem in Excel2003 or Excel2007 without SP1...) */
2069*b1cdbd2cSJim Jagielski     maData.mnCategCount = rParent.maData.mnCategCount;
2070*b1cdbd2cSJim Jagielski     maData.mnValueCount = rParent.maData.mnValueCount;
2071*b1cdbd2cSJim Jagielski }
2072*b1cdbd2cSJim Jagielski 
CreateTrendLines(XDataSeriesRef xDataSeries)2073*b1cdbd2cSJim Jagielski void XclExpChSeries::CreateTrendLines( XDataSeriesRef xDataSeries )
2074*b1cdbd2cSJim Jagielski {
2075*b1cdbd2cSJim Jagielski     Reference< XRegressionCurveContainer > xRegCurveCont( xDataSeries, UNO_QUERY );
2076*b1cdbd2cSJim Jagielski     if( xRegCurveCont.is() )
2077*b1cdbd2cSJim Jagielski     {
2078*b1cdbd2cSJim Jagielski         Sequence< Reference< XRegressionCurve > > aRegCurveSeq = xRegCurveCont->getRegressionCurves();
2079*b1cdbd2cSJim Jagielski         const Reference< XRegressionCurve >* pBeg = aRegCurveSeq.getConstArray();
2080*b1cdbd2cSJim Jagielski         const Reference< XRegressionCurve >* pEnd = pBeg + aRegCurveSeq.getLength();
2081*b1cdbd2cSJim Jagielski         for( const Reference< XRegressionCurve >* pIt = pBeg; pIt != pEnd; ++pIt )
2082*b1cdbd2cSJim Jagielski         {
2083*b1cdbd2cSJim Jagielski             XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
2084*b1cdbd2cSJim Jagielski             if( xSeries.is() && !xSeries->ConvertTrendLine( *this, *pIt ) )
2085*b1cdbd2cSJim Jagielski                 GetChartData().RemoveLastSeries();
2086*b1cdbd2cSJim Jagielski         }
2087*b1cdbd2cSJim Jagielski     }
2088*b1cdbd2cSJim Jagielski }
2089*b1cdbd2cSJim Jagielski 
CreateErrorBars(const ScfPropertySet & rPropSet,const OUString & rBarPropName,sal_uInt8 nPosBarId,sal_uInt8 nNegBarId)2090*b1cdbd2cSJim Jagielski void XclExpChSeries::CreateErrorBars( const ScfPropertySet& rPropSet,
2091*b1cdbd2cSJim Jagielski         const OUString& rBarPropName, sal_uInt8 nPosBarId, sal_uInt8 nNegBarId )
2092*b1cdbd2cSJim Jagielski {
2093*b1cdbd2cSJim Jagielski     Reference< XPropertySet > xErrorBar;
2094*b1cdbd2cSJim Jagielski     if( rPropSet.GetProperty( xErrorBar, rBarPropName ) && xErrorBar.is() )
2095*b1cdbd2cSJim Jagielski     {
2096*b1cdbd2cSJim Jagielski         ScfPropertySet aErrorProp( xErrorBar );
2097*b1cdbd2cSJim Jagielski         CreateErrorBar( aErrorProp, EXC_CHPROP_SHOWPOSITIVEERROR, nPosBarId );
2098*b1cdbd2cSJim Jagielski         CreateErrorBar( aErrorProp, EXC_CHPROP_SHOWNEGATIVEERROR, nNegBarId );
2099*b1cdbd2cSJim Jagielski     }
2100*b1cdbd2cSJim Jagielski }
2101*b1cdbd2cSJim Jagielski 
CreateErrorBar(const ScfPropertySet & rPropSet,const OUString & rShowPropName,sal_uInt8 nBarId)2102*b1cdbd2cSJim Jagielski void XclExpChSeries::CreateErrorBar( const ScfPropertySet& rPropSet,
2103*b1cdbd2cSJim Jagielski         const OUString& rShowPropName, sal_uInt8 nBarId )
2104*b1cdbd2cSJim Jagielski {
2105*b1cdbd2cSJim Jagielski     if( rPropSet.GetBoolProperty( rShowPropName ) )
2106*b1cdbd2cSJim Jagielski     {
2107*b1cdbd2cSJim Jagielski         XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
2108*b1cdbd2cSJim Jagielski         if( xSeries.is() && !xSeries->ConvertErrorBar( *this, rPropSet, nBarId ) )
2109*b1cdbd2cSJim Jagielski             GetChartData().RemoveLastSeries();
2110*b1cdbd2cSJim Jagielski     }
2111*b1cdbd2cSJim Jagielski }
2112*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)2113*b1cdbd2cSJim Jagielski void XclExpChSeries::WriteBody( XclExpStream& rStrm )
2114*b1cdbd2cSJim Jagielski {
2115*b1cdbd2cSJim Jagielski     rStrm << maData.mnCategType << maData.mnValueType << maData.mnCategCount << maData.mnValueCount;
2116*b1cdbd2cSJim Jagielski     if( GetBiff() == EXC_BIFF8 )
2117*b1cdbd2cSJim Jagielski         rStrm << maData.mnBubbleType << maData.mnBubbleCount;
2118*b1cdbd2cSJim Jagielski }
2119*b1cdbd2cSJim Jagielski 
2120*b1cdbd2cSJim Jagielski // Chart type groups ==========================================================
2121*b1cdbd2cSJim Jagielski 
XclExpChType(const XclExpChRoot & rRoot)2122*b1cdbd2cSJim Jagielski XclExpChType::XclExpChType( const XclExpChRoot& rRoot ) :
2123*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CHUNKNOWN ),
2124*b1cdbd2cSJim Jagielski     XclExpChRoot( rRoot ),
2125*b1cdbd2cSJim Jagielski     maTypeInfo( rRoot.GetChartTypeInfo( EXC_CHTYPEID_UNKNOWN ) )
2126*b1cdbd2cSJim Jagielski {
2127*b1cdbd2cSJim Jagielski }
2128*b1cdbd2cSJim Jagielski 
Convert(Reference<XDiagram> xDiagram,Reference<XChartType> xChartType,sal_Int32 nApiAxesSetIdx,bool bSwappedAxesSet,bool bHasXLabels)2129*b1cdbd2cSJim Jagielski void XclExpChType::Convert( Reference< XDiagram > xDiagram, Reference< XChartType > xChartType,
2130*b1cdbd2cSJim Jagielski         sal_Int32 nApiAxesSetIdx, bool bSwappedAxesSet, bool bHasXLabels )
2131*b1cdbd2cSJim Jagielski {
2132*b1cdbd2cSJim Jagielski     if( xChartType.is() )
2133*b1cdbd2cSJim Jagielski     {
2134*b1cdbd2cSJim Jagielski         maTypeInfo = GetChartTypeInfo( xChartType->getChartType() );
2135*b1cdbd2cSJim Jagielski         // special handling for some chart types
2136*b1cdbd2cSJim Jagielski         switch( maTypeInfo.meTypeCateg )
2137*b1cdbd2cSJim Jagielski         {
2138*b1cdbd2cSJim Jagielski             case EXC_CHTYPECATEG_BAR:
2139*b1cdbd2cSJim Jagielski             {
2140*b1cdbd2cSJim Jagielski                 maTypeInfo = GetChartTypeInfo( bSwappedAxesSet ? EXC_CHTYPEID_HORBAR : EXC_CHTYPEID_BAR );
2141*b1cdbd2cSJim Jagielski                 ::set_flag( maData.mnFlags, EXC_CHBAR_HORIZONTAL, bSwappedAxesSet );
2142*b1cdbd2cSJim Jagielski                 ScfPropertySet aTypeProp( xChartType );
2143*b1cdbd2cSJim Jagielski                 Sequence< sal_Int32 > aInt32Seq;
2144*b1cdbd2cSJim Jagielski                 maData.mnOverlap = 0;
2145*b1cdbd2cSJim Jagielski                 if( aTypeProp.GetProperty( aInt32Seq, EXC_CHPROP_OVERLAPSEQ ) && (nApiAxesSetIdx < aInt32Seq.getLength()) )
2146*b1cdbd2cSJim Jagielski                     maData.mnOverlap = limit_cast< sal_Int16 >( -aInt32Seq[ nApiAxesSetIdx ], -100, 100 );
2147*b1cdbd2cSJim Jagielski                 maData.mnGap = 150;
2148*b1cdbd2cSJim Jagielski                 if( aTypeProp.GetProperty( aInt32Seq, EXC_CHPROP_GAPWIDTHSEQ ) && (nApiAxesSetIdx < aInt32Seq.getLength()) )
2149*b1cdbd2cSJim Jagielski                     maData.mnGap = limit_cast< sal_uInt16 >( aInt32Seq[ nApiAxesSetIdx ], 0, 500 );
2150*b1cdbd2cSJim Jagielski             }
2151*b1cdbd2cSJim Jagielski             break;
2152*b1cdbd2cSJim Jagielski             case EXC_CHTYPECATEG_RADAR:
2153*b1cdbd2cSJim Jagielski                 ::set_flag( maData.mnFlags, EXC_CHRADAR_AXISLABELS, bHasXLabels );
2154*b1cdbd2cSJim Jagielski             break;
2155*b1cdbd2cSJim Jagielski             case EXC_CHTYPECATEG_PIE:
2156*b1cdbd2cSJim Jagielski             {
2157*b1cdbd2cSJim Jagielski                 ScfPropertySet aTypeProp( xChartType );
2158*b1cdbd2cSJim Jagielski                 bool bDonut = aTypeProp.GetBoolProperty( EXC_CHPROP_USERINGS );
2159*b1cdbd2cSJim Jagielski                 maTypeInfo = GetChartTypeInfo( bDonut ? EXC_CHTYPEID_DONUT : EXC_CHTYPEID_PIE );
2160*b1cdbd2cSJim Jagielski                 maData.mnPieHole = bDonut ? 50 : 0;
2161*b1cdbd2cSJim Jagielski                 // #i85166# starting angle of first pie slice
2162*b1cdbd2cSJim Jagielski                 ScfPropertySet aDiaProp( xDiagram );
2163*b1cdbd2cSJim Jagielski                 maData.mnRotation = XclExpChRoot::ConvertPieRotation( aDiaProp );
2164*b1cdbd2cSJim Jagielski             }
2165*b1cdbd2cSJim Jagielski             break;
2166*b1cdbd2cSJim Jagielski             case EXC_CHTYPECATEG_SCATTER:
2167*b1cdbd2cSJim Jagielski                 if( GetBiff() == EXC_BIFF8 )
2168*b1cdbd2cSJim Jagielski                     ::set_flag( maData.mnFlags, EXC_CHSCATTER_BUBBLES, maTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES );
2169*b1cdbd2cSJim Jagielski             break;
2170*b1cdbd2cSJim Jagielski             default:;
2171*b1cdbd2cSJim Jagielski         }
2172*b1cdbd2cSJim Jagielski         SetRecId( maTypeInfo.mnRecId );
2173*b1cdbd2cSJim Jagielski     }
2174*b1cdbd2cSJim Jagielski }
2175*b1cdbd2cSJim Jagielski 
SetStacked(bool bPercent)2176*b1cdbd2cSJim Jagielski void XclExpChType::SetStacked( bool bPercent )
2177*b1cdbd2cSJim Jagielski {
2178*b1cdbd2cSJim Jagielski     switch( maTypeInfo.meTypeCateg )
2179*b1cdbd2cSJim Jagielski     {
2180*b1cdbd2cSJim Jagielski         case EXC_CHTYPECATEG_LINE:
2181*b1cdbd2cSJim Jagielski             ::set_flag( maData.mnFlags, EXC_CHLINE_STACKED );
2182*b1cdbd2cSJim Jagielski             ::set_flag( maData.mnFlags, EXC_CHLINE_PERCENT, bPercent );
2183*b1cdbd2cSJim Jagielski         break;
2184*b1cdbd2cSJim Jagielski         case EXC_CHTYPECATEG_BAR:
2185*b1cdbd2cSJim Jagielski             ::set_flag( maData.mnFlags, EXC_CHBAR_STACKED );
2186*b1cdbd2cSJim Jagielski             ::set_flag( maData.mnFlags, EXC_CHBAR_PERCENT, bPercent );
2187*b1cdbd2cSJim Jagielski             maData.mnOverlap = -100;
2188*b1cdbd2cSJim Jagielski         break;
2189*b1cdbd2cSJim Jagielski         default:;
2190*b1cdbd2cSJim Jagielski     }
2191*b1cdbd2cSJim Jagielski }
2192*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)2193*b1cdbd2cSJim Jagielski void XclExpChType::WriteBody( XclExpStream& rStrm )
2194*b1cdbd2cSJim Jagielski {
2195*b1cdbd2cSJim Jagielski     switch( GetRecId() )
2196*b1cdbd2cSJim Jagielski     {
2197*b1cdbd2cSJim Jagielski         case EXC_ID_CHBAR:
2198*b1cdbd2cSJim Jagielski             rStrm << maData.mnOverlap << maData.mnGap << maData.mnFlags;
2199*b1cdbd2cSJim Jagielski         break;
2200*b1cdbd2cSJim Jagielski 
2201*b1cdbd2cSJim Jagielski         case EXC_ID_CHLINE:
2202*b1cdbd2cSJim Jagielski         case EXC_ID_CHAREA:
2203*b1cdbd2cSJim Jagielski         case EXC_ID_CHRADARLINE:
2204*b1cdbd2cSJim Jagielski         case EXC_ID_CHRADARAREA:
2205*b1cdbd2cSJim Jagielski             rStrm << maData.mnFlags;
2206*b1cdbd2cSJim Jagielski         break;
2207*b1cdbd2cSJim Jagielski 
2208*b1cdbd2cSJim Jagielski         case EXC_ID_CHPIE:
2209*b1cdbd2cSJim Jagielski             rStrm << maData.mnRotation << maData.mnPieHole;
2210*b1cdbd2cSJim Jagielski             if( GetBiff() == EXC_BIFF8 )
2211*b1cdbd2cSJim Jagielski                 rStrm << maData.mnFlags;
2212*b1cdbd2cSJim Jagielski         break;
2213*b1cdbd2cSJim Jagielski 
2214*b1cdbd2cSJim Jagielski         case EXC_ID_CHSCATTER:
2215*b1cdbd2cSJim Jagielski             if( GetBiff() == EXC_BIFF8 )
2216*b1cdbd2cSJim Jagielski                 rStrm << maData.mnBubbleSize << maData.mnBubbleType << maData.mnFlags;
2217*b1cdbd2cSJim Jagielski         break;
2218*b1cdbd2cSJim Jagielski 
2219*b1cdbd2cSJim Jagielski         default:
2220*b1cdbd2cSJim Jagielski             DBG_ERRORFILE( "XclExpChType::WriteBody - unknown chart type" );
2221*b1cdbd2cSJim Jagielski     }
2222*b1cdbd2cSJim Jagielski }
2223*b1cdbd2cSJim Jagielski 
2224*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
2225*b1cdbd2cSJim Jagielski 
XclExpChChart3d()2226*b1cdbd2cSJim Jagielski XclExpChChart3d::XclExpChChart3d() :
2227*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CHCHART3D, 14 )
2228*b1cdbd2cSJim Jagielski {
2229*b1cdbd2cSJim Jagielski }
2230*b1cdbd2cSJim Jagielski 
Convert(const ScfPropertySet & rPropSet,bool b3dWallChart)2231*b1cdbd2cSJim Jagielski void XclExpChChart3d::Convert( const ScfPropertySet& rPropSet, bool b3dWallChart )
2232*b1cdbd2cSJim Jagielski {
2233*b1cdbd2cSJim Jagielski     sal_Int32 nRotationY = 0;
2234*b1cdbd2cSJim Jagielski     rPropSet.GetProperty( nRotationY, EXC_CHPROP_ROTATIONVERTICAL );
2235*b1cdbd2cSJim Jagielski     sal_Int32 nRotationX = 0;
2236*b1cdbd2cSJim Jagielski     rPropSet.GetProperty( nRotationX, EXC_CHPROP_ROTATIONHORIZONTAL );
2237*b1cdbd2cSJim Jagielski     sal_Int32 nPerspective = 15;
2238*b1cdbd2cSJim Jagielski     rPropSet.GetProperty( nPerspective, EXC_CHPROP_PERSPECTIVE );
2239*b1cdbd2cSJim Jagielski 
2240*b1cdbd2cSJim Jagielski     if( b3dWallChart )
2241*b1cdbd2cSJim Jagielski     {
2242*b1cdbd2cSJim Jagielski         // Y rotation (Excel [0..359], Chart2 [-179,180])
2243*b1cdbd2cSJim Jagielski         if( nRotationY < 0 ) nRotationY += 360;
2244*b1cdbd2cSJim Jagielski         maData.mnRotation = static_cast< sal_uInt16 >( nRotationY );
2245*b1cdbd2cSJim Jagielski         // X rotation a.k.a. elevation (Excel [-90..90], Chart2 [-179,180])
2246*b1cdbd2cSJim Jagielski         maData.mnElevation = limit_cast< sal_Int16 >( nRotationX, -90, 90 );
2247*b1cdbd2cSJim Jagielski         // perspective (Excel and Chart2 [0,100])
2248*b1cdbd2cSJim Jagielski         maData.mnEyeDist = limit_cast< sal_uInt16 >( nPerspective, 0, 100 );
2249*b1cdbd2cSJim Jagielski         // flags
2250*b1cdbd2cSJim Jagielski         maData.mnFlags = 0;
2251*b1cdbd2cSJim Jagielski         ::set_flag( maData.mnFlags, EXC_CHCHART3D_REAL3D, !rPropSet.GetBoolProperty( EXC_CHPROP_RIGHTANGLEDAXES ) );
2252*b1cdbd2cSJim Jagielski         ::set_flag( maData.mnFlags, EXC_CHCHART3D_AUTOHEIGHT );
2253*b1cdbd2cSJim Jagielski         ::set_flag( maData.mnFlags, EXC_CHCHART3D_HASWALLS );
2254*b1cdbd2cSJim Jagielski     }
2255*b1cdbd2cSJim Jagielski     else
2256*b1cdbd2cSJim Jagielski     {
2257*b1cdbd2cSJim Jagielski         // Y rotation not used in pie charts, but 'first pie slice angle'
2258*b1cdbd2cSJim Jagielski         maData.mnRotation = XclExpChRoot::ConvertPieRotation( rPropSet );
2259*b1cdbd2cSJim Jagielski         // X rotation a.k.a. elevation (map Chart2 [-80,-10] to Excel [10..80])
2260*b1cdbd2cSJim Jagielski         maData.mnElevation = limit_cast< sal_Int16 >( (nRotationX + 270) % 180, 10, 80 );
2261*b1cdbd2cSJim Jagielski         // perspective (Excel and Chart2 [0,100])
2262*b1cdbd2cSJim Jagielski         maData.mnEyeDist = limit_cast< sal_uInt16 >( nPerspective, 0, 100 );
2263*b1cdbd2cSJim Jagielski         // flags
2264*b1cdbd2cSJim Jagielski         maData.mnFlags = 0;
2265*b1cdbd2cSJim Jagielski     }
2266*b1cdbd2cSJim Jagielski }
2267*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)2268*b1cdbd2cSJim Jagielski void XclExpChChart3d::WriteBody( XclExpStream& rStrm )
2269*b1cdbd2cSJim Jagielski {
2270*b1cdbd2cSJim Jagielski     rStrm   << maData.mnRotation
2271*b1cdbd2cSJim Jagielski             << maData.mnElevation
2272*b1cdbd2cSJim Jagielski             << maData.mnEyeDist
2273*b1cdbd2cSJim Jagielski             << maData.mnRelHeight
2274*b1cdbd2cSJim Jagielski             << maData.mnRelDepth
2275*b1cdbd2cSJim Jagielski             << maData.mnDepthGap
2276*b1cdbd2cSJim Jagielski             << maData.mnFlags;
2277*b1cdbd2cSJim Jagielski }
2278*b1cdbd2cSJim Jagielski 
2279*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
2280*b1cdbd2cSJim Jagielski 
XclExpChLegend(const XclExpChRoot & rRoot)2281*b1cdbd2cSJim Jagielski XclExpChLegend::XclExpChLegend( const XclExpChRoot& rRoot ) :
2282*b1cdbd2cSJim Jagielski     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_LEGEND, EXC_ID_CHLEGEND, 20 )
2283*b1cdbd2cSJim Jagielski {
2284*b1cdbd2cSJim Jagielski }
2285*b1cdbd2cSJim Jagielski 
Convert(const ScfPropertySet & rPropSet)2286*b1cdbd2cSJim Jagielski void XclExpChLegend::Convert( const ScfPropertySet& rPropSet )
2287*b1cdbd2cSJim Jagielski {
2288*b1cdbd2cSJim Jagielski     // frame properties
2289*b1cdbd2cSJim Jagielski     mxFrame = lclCreateFrame( GetChRoot(), rPropSet, EXC_CHOBJTYPE_LEGEND );
2290*b1cdbd2cSJim Jagielski     // text properties
2291*b1cdbd2cSJim Jagielski     mxText.reset( new XclExpChText( GetChRoot() ) );
2292*b1cdbd2cSJim Jagielski     mxText->ConvertLegend( rPropSet );
2293*b1cdbd2cSJim Jagielski 
2294*b1cdbd2cSJim Jagielski     // legend position and size
2295*b1cdbd2cSJim Jagielski     Any aRelPosAny, aRelSizeAny;
2296*b1cdbd2cSJim Jagielski     rPropSet.GetAnyProperty( aRelPosAny, EXC_CHPROP_RELATIVEPOSITION );
2297*b1cdbd2cSJim Jagielski     rPropSet.GetAnyProperty( aRelSizeAny, EXC_CHPROP_RELATIVESIZE );
2298*b1cdbd2cSJim Jagielski     cssc::ChartLegendExpansion eApiExpand = cssc::ChartLegendExpansion_CUSTOM;
2299*b1cdbd2cSJim Jagielski     rPropSet.GetProperty( eApiExpand, EXC_CHPROP_EXPANSION );
2300*b1cdbd2cSJim Jagielski     if( aRelPosAny.has< RelativePosition >() || ((eApiExpand == cssc::ChartLegendExpansion_CUSTOM) && aRelSizeAny.has< RelativeSize >()) )
2301*b1cdbd2cSJim Jagielski     {
2302*b1cdbd2cSJim Jagielski         try
2303*b1cdbd2cSJim Jagielski         {
2304*b1cdbd2cSJim Jagielski             /*  The 'RelativePosition' or 'RelativeSize' properties are used as
2305*b1cdbd2cSJim Jagielski                 indicator of manually changed legend position/size, but due to
2306*b1cdbd2cSJim Jagielski                 the different anchor modes used by this property (in the
2307*b1cdbd2cSJim Jagielski                 RelativePosition.Anchor member) it cannot be used to calculate
2308*b1cdbd2cSJim Jagielski                 the position easily. For this, the Chart1 API will be used
2309*b1cdbd2cSJim Jagielski                 instead. */
2310*b1cdbd2cSJim Jagielski             Reference< cssc::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
2311*b1cdbd2cSJim Jagielski             Reference< XShape > xChart1Legend( xChart1Doc->getLegend(), UNO_SET_THROW );
2312*b1cdbd2cSJim Jagielski             // coordinates in CHLEGEND record written but not used by Excel
2313*b1cdbd2cSJim Jagielski             mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_CHARTSIZE, EXC_CHFRAMEPOS_PARENT ) );
2314*b1cdbd2cSJim Jagielski             XclChFramePos& rFramePos = mxFramePos->GetFramePosData();
2315*b1cdbd2cSJim Jagielski             rFramePos.mnTLMode = EXC_CHFRAMEPOS_CHARTSIZE;
2316*b1cdbd2cSJim Jagielski             ::com::sun::star::awt::Point aLegendPos = xChart1Legend->getPosition();
2317*b1cdbd2cSJim Jagielski             rFramePos.maRect.mnX = maData.maRect.mnX = CalcChartXFromHmm( aLegendPos.X );
2318*b1cdbd2cSJim Jagielski             rFramePos.maRect.mnY = maData.maRect.mnY = CalcChartYFromHmm( aLegendPos.Y );
2319*b1cdbd2cSJim Jagielski             // legend size, Excel expects points in CHFRAMEPOS record
2320*b1cdbd2cSJim Jagielski             rFramePos.mnBRMode = EXC_CHFRAMEPOS_ABSSIZE_POINTS;
2321*b1cdbd2cSJim Jagielski             ::com::sun::star::awt::Size aLegendSize = xChart1Legend->getSize();
2322*b1cdbd2cSJim Jagielski             rFramePos.maRect.mnWidth = static_cast< sal_uInt16 >( aLegendSize.Width * EXC_POINTS_PER_HMM + 0.5 );
2323*b1cdbd2cSJim Jagielski             rFramePos.maRect.mnHeight = static_cast< sal_uInt16 >( aLegendSize.Height * EXC_POINTS_PER_HMM + 0.5 );
2324*b1cdbd2cSJim Jagielski             maData.maRect.mnWidth = CalcChartXFromHmm( aLegendSize.Width );
2325*b1cdbd2cSJim Jagielski             maData.maRect.mnHeight = CalcChartYFromHmm( aLegendSize.Height );
2326*b1cdbd2cSJim Jagielski             eApiExpand = cssc::ChartLegendExpansion_CUSTOM;
2327*b1cdbd2cSJim Jagielski             // manual legend position implies manual plot area
2328*b1cdbd2cSJim Jagielski             GetChartData().SetManualPlotArea();
2329*b1cdbd2cSJim Jagielski             maData.mnDockMode = EXC_CHLEGEND_NOTDOCKED;
2330*b1cdbd2cSJim Jagielski             // a CHFRAME record with cleared auto flags is needed
2331*b1cdbd2cSJim Jagielski             if( !mxFrame )
2332*b1cdbd2cSJim Jagielski                 mxFrame.reset( new XclExpChFrame( GetChRoot(), EXC_CHOBJTYPE_LEGEND ) );
2333*b1cdbd2cSJim Jagielski             mxFrame->SetAutoFlags( false, false );
2334*b1cdbd2cSJim Jagielski         }
2335*b1cdbd2cSJim Jagielski         catch( Exception& )
2336*b1cdbd2cSJim Jagielski         {
2337*b1cdbd2cSJim Jagielski             OSL_ENSURE( false, "XclExpChLegend::Convert - cannot get legend shape" );
2338*b1cdbd2cSJim Jagielski             maData.mnDockMode = EXC_CHLEGEND_RIGHT;
2339*b1cdbd2cSJim Jagielski             eApiExpand = cssc::ChartLegendExpansion_HIGH;
2340*b1cdbd2cSJim Jagielski         }
2341*b1cdbd2cSJim Jagielski     }
2342*b1cdbd2cSJim Jagielski     else
2343*b1cdbd2cSJim Jagielski     {
2344*b1cdbd2cSJim Jagielski         cssc2::LegendPosition eApiPos = cssc2::LegendPosition_CUSTOM;
2345*b1cdbd2cSJim Jagielski         rPropSet.GetProperty( eApiPos, EXC_CHPROP_ANCHORPOSITION );
2346*b1cdbd2cSJim Jagielski         switch( eApiPos )
2347*b1cdbd2cSJim Jagielski         {
2348*b1cdbd2cSJim Jagielski             case cssc2::LegendPosition_LINE_START:   maData.mnDockMode = EXC_CHLEGEND_LEFT;      break;
2349*b1cdbd2cSJim Jagielski             case cssc2::LegendPosition_LINE_END:     maData.mnDockMode = EXC_CHLEGEND_RIGHT;     break;
2350*b1cdbd2cSJim Jagielski             case cssc2::LegendPosition_PAGE_START:   maData.mnDockMode = EXC_CHLEGEND_TOP;       break;
2351*b1cdbd2cSJim Jagielski             case cssc2::LegendPosition_PAGE_END:     maData.mnDockMode = EXC_CHLEGEND_BOTTOM;    break;
2352*b1cdbd2cSJim Jagielski             default:
2353*b1cdbd2cSJim Jagielski                 OSL_ENSURE( false, "XclExpChLegend::Convert - unrecognized legend position" );
2354*b1cdbd2cSJim Jagielski                 maData.mnDockMode = EXC_CHLEGEND_RIGHT;
2355*b1cdbd2cSJim Jagielski                 eApiExpand = cssc::ChartLegendExpansion_HIGH;
2356*b1cdbd2cSJim Jagielski         }
2357*b1cdbd2cSJim Jagielski     }
2358*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHLEGEND_STACKED, eApiExpand == cssc::ChartLegendExpansion_HIGH );
2359*b1cdbd2cSJim Jagielski 
2360*b1cdbd2cSJim Jagielski     // other flags
2361*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHLEGEND_AUTOSERIES );
2362*b1cdbd2cSJim Jagielski     const sal_uInt16 nAutoFlags = EXC_CHLEGEND_DOCKED | EXC_CHLEGEND_AUTOPOSX | EXC_CHLEGEND_AUTOPOSY;
2363*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, nAutoFlags, maData.mnDockMode != EXC_CHLEGEND_NOTDOCKED );
2364*b1cdbd2cSJim Jagielski }
2365*b1cdbd2cSJim Jagielski 
WriteSubRecords(XclExpStream & rStrm)2366*b1cdbd2cSJim Jagielski void XclExpChLegend::WriteSubRecords( XclExpStream& rStrm )
2367*b1cdbd2cSJim Jagielski {
2368*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxFramePos );
2369*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxText );
2370*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxFrame );
2371*b1cdbd2cSJim Jagielski }
2372*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)2373*b1cdbd2cSJim Jagielski void XclExpChLegend::WriteBody( XclExpStream& rStrm )
2374*b1cdbd2cSJim Jagielski {
2375*b1cdbd2cSJim Jagielski     rStrm << maData.maRect << maData.mnDockMode << maData.mnSpacing << maData.mnFlags;
2376*b1cdbd2cSJim Jagielski }
2377*b1cdbd2cSJim Jagielski 
2378*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
2379*b1cdbd2cSJim Jagielski 
XclExpChDropBar(const XclExpChRoot & rRoot,XclChObjectType eObjType)2380*b1cdbd2cSJim Jagielski XclExpChDropBar::XclExpChDropBar( const XclExpChRoot& rRoot, XclChObjectType eObjType ) :
2381*b1cdbd2cSJim Jagielski     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_DROPBAR, EXC_ID_CHDROPBAR, 2 ),
2382*b1cdbd2cSJim Jagielski     meObjType( eObjType ),
2383*b1cdbd2cSJim Jagielski     mnBarDist( 100 )
2384*b1cdbd2cSJim Jagielski {
2385*b1cdbd2cSJim Jagielski }
2386*b1cdbd2cSJim Jagielski 
Convert(const ScfPropertySet & rPropSet)2387*b1cdbd2cSJim Jagielski void XclExpChDropBar::Convert( const ScfPropertySet& rPropSet )
2388*b1cdbd2cSJim Jagielski {
2389*b1cdbd2cSJim Jagielski     if( rPropSet.Is() )
2390*b1cdbd2cSJim Jagielski         ConvertFrameBase( GetChRoot(), rPropSet, meObjType );
2391*b1cdbd2cSJim Jagielski     else
2392*b1cdbd2cSJim Jagielski         SetDefaultFrameBase( GetChRoot(), EXC_CHFRAMETYPE_INVISIBLE, true );
2393*b1cdbd2cSJim Jagielski }
2394*b1cdbd2cSJim Jagielski 
WriteSubRecords(XclExpStream & rStrm)2395*b1cdbd2cSJim Jagielski void XclExpChDropBar::WriteSubRecords( XclExpStream& rStrm )
2396*b1cdbd2cSJim Jagielski {
2397*b1cdbd2cSJim Jagielski     WriteFrameRecords( rStrm );
2398*b1cdbd2cSJim Jagielski }
2399*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)2400*b1cdbd2cSJim Jagielski void XclExpChDropBar::WriteBody( XclExpStream& rStrm )
2401*b1cdbd2cSJim Jagielski {
2402*b1cdbd2cSJim Jagielski     rStrm << mnBarDist;
2403*b1cdbd2cSJim Jagielski }
2404*b1cdbd2cSJim Jagielski 
2405*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
2406*b1cdbd2cSJim Jagielski 
XclExpChTypeGroup(const XclExpChRoot & rRoot,sal_uInt16 nGroupIdx)2407*b1cdbd2cSJim Jagielski XclExpChTypeGroup::XclExpChTypeGroup( const XclExpChRoot& rRoot, sal_uInt16 nGroupIdx ) :
2408*b1cdbd2cSJim Jagielski     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_TYPEGROUP, EXC_ID_CHTYPEGROUP, 20 ),
2409*b1cdbd2cSJim Jagielski     maType( rRoot ),
2410*b1cdbd2cSJim Jagielski     maTypeInfo( maType.GetTypeInfo() )
2411*b1cdbd2cSJim Jagielski {
2412*b1cdbd2cSJim Jagielski     maData.mnGroupIdx = nGroupIdx;
2413*b1cdbd2cSJim Jagielski }
2414*b1cdbd2cSJim Jagielski 
ConvertType(Reference<XDiagram> xDiagram,Reference<XChartType> xChartType,sal_Int32 nApiAxesSetIdx,bool b3dChart,bool bSwappedAxesSet,bool bHasXLabels)2415*b1cdbd2cSJim Jagielski void XclExpChTypeGroup::ConvertType(
2416*b1cdbd2cSJim Jagielski         Reference< XDiagram > xDiagram, Reference< XChartType > xChartType,
2417*b1cdbd2cSJim Jagielski         sal_Int32 nApiAxesSetIdx, bool b3dChart, bool bSwappedAxesSet, bool bHasXLabels )
2418*b1cdbd2cSJim Jagielski {
2419*b1cdbd2cSJim Jagielski     // chart type settings
2420*b1cdbd2cSJim Jagielski     maType.Convert( xDiagram, xChartType, nApiAxesSetIdx, bSwappedAxesSet, bHasXLabels );
2421*b1cdbd2cSJim Jagielski 
2422*b1cdbd2cSJim Jagielski     // spline - TODO: get from single series (#i66858#)
2423*b1cdbd2cSJim Jagielski     ScfPropertySet aTypeProp( xChartType );
2424*b1cdbd2cSJim Jagielski     cssc2::CurveStyle eCurveStyle;
2425*b1cdbd2cSJim Jagielski     bool bSpline = aTypeProp.GetProperty( eCurveStyle, EXC_CHPROP_CURVESTYLE ) &&
2426*b1cdbd2cSJim Jagielski         (eCurveStyle != cssc2::CurveStyle_LINES);
2427*b1cdbd2cSJim Jagielski 
2428*b1cdbd2cSJim Jagielski     // extended type info
2429*b1cdbd2cSJim Jagielski     maTypeInfo.Set( maType.GetTypeInfo(), b3dChart, bSpline );
2430*b1cdbd2cSJim Jagielski 
2431*b1cdbd2cSJim Jagielski     // 3d chart settings
2432*b1cdbd2cSJim Jagielski     if( maTypeInfo.mb3dChart )  // only true, if Excel chart supports 3d mode
2433*b1cdbd2cSJim Jagielski     {
2434*b1cdbd2cSJim Jagielski         mxChart3d.reset( new XclExpChChart3d );
2435*b1cdbd2cSJim Jagielski         ScfPropertySet aDiaProp( xDiagram );
2436*b1cdbd2cSJim Jagielski         mxChart3d->Convert( aDiaProp, Is3dWallChart() );
2437*b1cdbd2cSJim Jagielski     }
2438*b1cdbd2cSJim Jagielski }
2439*b1cdbd2cSJim Jagielski 
ConvertSeries(Reference<XDiagram> xDiagram,Reference<XChartType> xChartType,sal_Int32 nGroupAxesSetIdx,bool bPercent,bool bConnectBars)2440*b1cdbd2cSJim Jagielski void XclExpChTypeGroup::ConvertSeries(
2441*b1cdbd2cSJim Jagielski         Reference< XDiagram > xDiagram, Reference< XChartType > xChartType,
2442*b1cdbd2cSJim Jagielski         sal_Int32 nGroupAxesSetIdx, bool bPercent, bool bConnectBars )
2443*b1cdbd2cSJim Jagielski {
2444*b1cdbd2cSJim Jagielski     Reference< XDataSeriesContainer > xSeriesCont( xChartType, UNO_QUERY );
2445*b1cdbd2cSJim Jagielski     if( xSeriesCont.is() )
2446*b1cdbd2cSJim Jagielski     {
2447*b1cdbd2cSJim Jagielski         typedef ::std::vector< Reference< XDataSeries > > XDataSeriesVec;
2448*b1cdbd2cSJim Jagielski         XDataSeriesVec aSeriesVec;
2449*b1cdbd2cSJim Jagielski 
2450*b1cdbd2cSJim Jagielski         // copy data series attached to the current axes set to the vector
2451*b1cdbd2cSJim Jagielski         Sequence< Reference< XDataSeries > > aSeriesSeq = xSeriesCont->getDataSeries();
2452*b1cdbd2cSJim Jagielski         const Reference< XDataSeries >* pBeg = aSeriesSeq.getConstArray();
2453*b1cdbd2cSJim Jagielski         const Reference< XDataSeries >* pEnd = pBeg + aSeriesSeq.getLength();
2454*b1cdbd2cSJim Jagielski         for( const Reference< XDataSeries >* pIt = pBeg; pIt != pEnd; ++pIt )
2455*b1cdbd2cSJim Jagielski         {
2456*b1cdbd2cSJim Jagielski             ScfPropertySet aSeriesProp( *pIt );
2457*b1cdbd2cSJim Jagielski             sal_Int32 nSeriesAxesSetIdx(0);
2458*b1cdbd2cSJim Jagielski             if( aSeriesProp.GetProperty( nSeriesAxesSetIdx, EXC_CHPROP_ATTAXISINDEX ) && (nSeriesAxesSetIdx == nGroupAxesSetIdx) )
2459*b1cdbd2cSJim Jagielski                 aSeriesVec.push_back( *pIt );
2460*b1cdbd2cSJim Jagielski         }
2461*b1cdbd2cSJim Jagielski 
2462*b1cdbd2cSJim Jagielski         // Are there any series in the current axes set?
2463*b1cdbd2cSJim Jagielski         if( !aSeriesVec.empty() )
2464*b1cdbd2cSJim Jagielski         {
2465*b1cdbd2cSJim Jagielski             // stacking direction (stacked/percent/deep 3d) from first series
2466*b1cdbd2cSJim Jagielski             ScfPropertySet aSeriesProp( aSeriesVec.front() );
2467*b1cdbd2cSJim Jagielski             cssc2::StackingDirection eStacking;
2468*b1cdbd2cSJim Jagielski             if( !aSeriesProp.GetProperty( eStacking, EXC_CHPROP_STACKINGDIR ) )
2469*b1cdbd2cSJim Jagielski                 eStacking = cssc2::StackingDirection_NO_STACKING;
2470*b1cdbd2cSJim Jagielski 
2471*b1cdbd2cSJim Jagielski             // stacked or percent chart
2472*b1cdbd2cSJim Jagielski             if( maTypeInfo.mbSupportsStacking && (eStacking == cssc2::StackingDirection_Y_STACKING) )
2473*b1cdbd2cSJim Jagielski             {
2474*b1cdbd2cSJim Jagielski                 // percent overrides simple stacking
2475*b1cdbd2cSJim Jagielski                 maType.SetStacked( bPercent );
2476*b1cdbd2cSJim Jagielski 
2477*b1cdbd2cSJim Jagielski                 // connected data points (only in stacked bar charts)
2478*b1cdbd2cSJim Jagielski                 if( bConnectBars && (maTypeInfo.meTypeCateg == EXC_CHTYPECATEG_BAR) )
2479*b1cdbd2cSJim Jagielski                     maChartLines[ EXC_CHCHARTLINE_CONNECT ].reset( new XclExpChLineFormat( GetChRoot() ) );
2480*b1cdbd2cSJim Jagielski             }
2481*b1cdbd2cSJim Jagielski             else
2482*b1cdbd2cSJim Jagielski             {
2483*b1cdbd2cSJim Jagielski                 // reverse series order for some unstacked 2D chart types
2484*b1cdbd2cSJim Jagielski                 if( maTypeInfo.mbReverseSeries && !Is3dChart() )
2485*b1cdbd2cSJim Jagielski                     ::std::reverse( aSeriesVec.begin(), aSeriesVec.end() );
2486*b1cdbd2cSJim Jagielski             }
2487*b1cdbd2cSJim Jagielski 
2488*b1cdbd2cSJim Jagielski             // deep 3d chart or clustered 3d chart (stacked is not clustered)
2489*b1cdbd2cSJim Jagielski             if( (eStacking == cssc2::StackingDirection_NO_STACKING) && Is3dWallChart() )
2490*b1cdbd2cSJim Jagielski                 mxChart3d->SetClustered();
2491*b1cdbd2cSJim Jagielski 
2492*b1cdbd2cSJim Jagielski             // varied point colors
2493*b1cdbd2cSJim Jagielski             ::set_flag( maData.mnFlags, EXC_CHTYPEGROUP_VARIEDCOLORS, aSeriesProp.GetBoolProperty( EXC_CHPROP_VARYCOLORSBY ) );
2494*b1cdbd2cSJim Jagielski 
2495*b1cdbd2cSJim Jagielski             // process all series
2496*b1cdbd2cSJim Jagielski             for( XDataSeriesVec::const_iterator aIt = aSeriesVec.begin(), aEnd = aSeriesVec.end(); aIt != aEnd; ++aIt )
2497*b1cdbd2cSJim Jagielski             {
2498*b1cdbd2cSJim Jagielski                 // create Excel series object, stock charts need special processing
2499*b1cdbd2cSJim Jagielski                 if( maTypeInfo.meTypeId == EXC_CHTYPEID_STOCK )
2500*b1cdbd2cSJim Jagielski                     CreateAllStockSeries( xChartType, *aIt );
2501*b1cdbd2cSJim Jagielski                 else
2502*b1cdbd2cSJim Jagielski                     CreateDataSeries( xDiagram, *aIt );
2503*b1cdbd2cSJim Jagielski             }
2504*b1cdbd2cSJim Jagielski         }
2505*b1cdbd2cSJim Jagielski     }
2506*b1cdbd2cSJim Jagielski }
2507*b1cdbd2cSJim Jagielski 
ConvertCategSequence(Reference<XLabeledDataSequence> xCategSeq)2508*b1cdbd2cSJim Jagielski void XclExpChTypeGroup::ConvertCategSequence( Reference< XLabeledDataSequence > xCategSeq )
2509*b1cdbd2cSJim Jagielski {
2510*b1cdbd2cSJim Jagielski     for( size_t nIdx = 0, nSize = maSeries.GetSize(); nIdx < nSize; ++nIdx )
2511*b1cdbd2cSJim Jagielski         maSeries.GetRecord( nIdx )->ConvertCategSequence( xCategSeq );
2512*b1cdbd2cSJim Jagielski }
2513*b1cdbd2cSJim Jagielski 
ConvertLegend(const ScfPropertySet & rPropSet)2514*b1cdbd2cSJim Jagielski void XclExpChTypeGroup::ConvertLegend( const ScfPropertySet& rPropSet )
2515*b1cdbd2cSJim Jagielski {
2516*b1cdbd2cSJim Jagielski     if( rPropSet.GetBoolProperty( EXC_CHPROP_SHOW ) )
2517*b1cdbd2cSJim Jagielski     {
2518*b1cdbd2cSJim Jagielski         mxLegend.reset( new XclExpChLegend( GetChRoot() ) );
2519*b1cdbd2cSJim Jagielski         mxLegend->Convert( rPropSet );
2520*b1cdbd2cSJim Jagielski     }
2521*b1cdbd2cSJim Jagielski }
2522*b1cdbd2cSJim Jagielski 
WriteSubRecords(XclExpStream & rStrm)2523*b1cdbd2cSJim Jagielski void XclExpChTypeGroup::WriteSubRecords( XclExpStream& rStrm )
2524*b1cdbd2cSJim Jagielski {
2525*b1cdbd2cSJim Jagielski     maType.Save( rStrm );
2526*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxChart3d );
2527*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxLegend );
2528*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxUpBar );
2529*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxDownBar );
2530*b1cdbd2cSJim Jagielski     for( XclExpChLineFormatMap::iterator aLIt = maChartLines.begin(), aLEnd = maChartLines.end(); aLIt != aLEnd; ++aLIt )
2531*b1cdbd2cSJim Jagielski         lclSaveRecord( rStrm, aLIt->second, EXC_ID_CHCHARTLINE, aLIt->first );
2532*b1cdbd2cSJim Jagielski }
2533*b1cdbd2cSJim Jagielski 
GetFreeFormatIdx() const2534*b1cdbd2cSJim Jagielski sal_uInt16 XclExpChTypeGroup::GetFreeFormatIdx() const
2535*b1cdbd2cSJim Jagielski {
2536*b1cdbd2cSJim Jagielski     return static_cast< sal_uInt16 >( maSeries.GetSize() );
2537*b1cdbd2cSJim Jagielski }
2538*b1cdbd2cSJim Jagielski 
CreateDataSeries(Reference<XDiagram> xDiagram,Reference<XDataSeries> xDataSeries)2539*b1cdbd2cSJim Jagielski void XclExpChTypeGroup::CreateDataSeries(
2540*b1cdbd2cSJim Jagielski         Reference< XDiagram > xDiagram, Reference< XDataSeries > xDataSeries )
2541*b1cdbd2cSJim Jagielski {
2542*b1cdbd2cSJim Jagielski     // let chart create series object with correct series index
2543*b1cdbd2cSJim Jagielski     XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
2544*b1cdbd2cSJim Jagielski     if( xSeries.is() )
2545*b1cdbd2cSJim Jagielski     {
2546*b1cdbd2cSJim Jagielski         if( xSeries->ConvertDataSeries( xDiagram, xDataSeries, maTypeInfo, GetGroupIdx(), GetFreeFormatIdx() ) )
2547*b1cdbd2cSJim Jagielski             maSeries.AppendRecord( xSeries );
2548*b1cdbd2cSJim Jagielski         else
2549*b1cdbd2cSJim Jagielski             GetChartData().RemoveLastSeries();
2550*b1cdbd2cSJim Jagielski     }
2551*b1cdbd2cSJim Jagielski }
2552*b1cdbd2cSJim Jagielski 
CreateAllStockSeries(Reference<XChartType> xChartType,Reference<XDataSeries> xDataSeries)2553*b1cdbd2cSJim Jagielski void XclExpChTypeGroup::CreateAllStockSeries(
2554*b1cdbd2cSJim Jagielski         Reference< XChartType > xChartType, Reference< XDataSeries > xDataSeries )
2555*b1cdbd2cSJim Jagielski {
2556*b1cdbd2cSJim Jagielski     // create existing series objects
2557*b1cdbd2cSJim Jagielski     bool bHasOpen = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_OPENVALUES, false );
2558*b1cdbd2cSJim Jagielski     bool bHasHigh = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_HIGHVALUES, false );
2559*b1cdbd2cSJim Jagielski     bool bHasLow = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_LOWVALUES, false );
2560*b1cdbd2cSJim Jagielski     bool bHasClose = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_CLOSEVALUES, !bHasOpen );
2561*b1cdbd2cSJim Jagielski 
2562*b1cdbd2cSJim Jagielski     // formatting of special stock chart elements
2563*b1cdbd2cSJim Jagielski     ScfPropertySet aTypeProp( xChartType );
2564*b1cdbd2cSJim Jagielski     // hi-lo lines
2565*b1cdbd2cSJim Jagielski     if( bHasHigh && bHasLow && aTypeProp.GetBoolProperty( EXC_CHPROP_SHOWHIGHLOW ) )
2566*b1cdbd2cSJim Jagielski     {
2567*b1cdbd2cSJim Jagielski         ScfPropertySet aSeriesProp( xDataSeries );
2568*b1cdbd2cSJim Jagielski         XclExpChLineFormatRef xLineFmt( new XclExpChLineFormat( GetChRoot() ) );
2569*b1cdbd2cSJim Jagielski         xLineFmt->Convert( GetChRoot(), aSeriesProp, EXC_CHOBJTYPE_HILOLINE );
2570*b1cdbd2cSJim Jagielski         maChartLines[ EXC_CHCHARTLINE_HILO ] = xLineFmt;
2571*b1cdbd2cSJim Jagielski     }
2572*b1cdbd2cSJim Jagielski     // dropbars
2573*b1cdbd2cSJim Jagielski     if( bHasOpen && bHasClose )
2574*b1cdbd2cSJim Jagielski     {
2575*b1cdbd2cSJim Jagielski         // dropbar type is dependent on position in the file - always create both
2576*b1cdbd2cSJim Jagielski         Reference< XPropertySet > xWhitePropSet, xBlackPropSet;
2577*b1cdbd2cSJim Jagielski         // white dropbar format
2578*b1cdbd2cSJim Jagielski         aTypeProp.GetProperty( xWhitePropSet, EXC_CHPROP_WHITEDAY );
2579*b1cdbd2cSJim Jagielski         ScfPropertySet aWhiteProp( xWhitePropSet );
2580*b1cdbd2cSJim Jagielski         mxUpBar.reset( new XclExpChDropBar( GetChRoot(), EXC_CHOBJTYPE_WHITEDROPBAR ) );
2581*b1cdbd2cSJim Jagielski         mxUpBar->Convert( aWhiteProp );
2582*b1cdbd2cSJim Jagielski         // black dropbar format
2583*b1cdbd2cSJim Jagielski         aTypeProp.GetProperty( xBlackPropSet, EXC_CHPROP_BLACKDAY );
2584*b1cdbd2cSJim Jagielski         ScfPropertySet aBlackProp( xBlackPropSet );
2585*b1cdbd2cSJim Jagielski         mxDownBar.reset( new XclExpChDropBar( GetChRoot(), EXC_CHOBJTYPE_BLACKDROPBAR ) );
2586*b1cdbd2cSJim Jagielski         mxDownBar->Convert( aBlackProp );
2587*b1cdbd2cSJim Jagielski     }
2588*b1cdbd2cSJim Jagielski }
2589*b1cdbd2cSJim Jagielski 
CreateStockSeries(Reference<XDataSeries> xDataSeries,const OUString & rValueRole,bool bCloseSymbol)2590*b1cdbd2cSJim Jagielski bool XclExpChTypeGroup::CreateStockSeries( Reference< XDataSeries > xDataSeries,
2591*b1cdbd2cSJim Jagielski         const OUString& rValueRole, bool bCloseSymbol )
2592*b1cdbd2cSJim Jagielski {
2593*b1cdbd2cSJim Jagielski     bool bOk = false;
2594*b1cdbd2cSJim Jagielski     // let chart create series object with correct series index
2595*b1cdbd2cSJim Jagielski     XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
2596*b1cdbd2cSJim Jagielski     if( xSeries.is() )
2597*b1cdbd2cSJim Jagielski     {
2598*b1cdbd2cSJim Jagielski         bOk = xSeries->ConvertStockSeries( xDataSeries,
2599*b1cdbd2cSJim Jagielski             rValueRole, GetGroupIdx(), GetFreeFormatIdx(), bCloseSymbol );
2600*b1cdbd2cSJim Jagielski         if( bOk )
2601*b1cdbd2cSJim Jagielski             maSeries.AppendRecord( xSeries );
2602*b1cdbd2cSJim Jagielski         else
2603*b1cdbd2cSJim Jagielski             GetChartData().RemoveLastSeries();
2604*b1cdbd2cSJim Jagielski     }
2605*b1cdbd2cSJim Jagielski     return bOk;
2606*b1cdbd2cSJim Jagielski }
2607*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)2608*b1cdbd2cSJim Jagielski void XclExpChTypeGroup::WriteBody( XclExpStream& rStrm )
2609*b1cdbd2cSJim Jagielski {
2610*b1cdbd2cSJim Jagielski     rStrm.WriteZeroBytes( 16 );
2611*b1cdbd2cSJim Jagielski     rStrm << maData.mnFlags << maData.mnGroupIdx;
2612*b1cdbd2cSJim Jagielski }
2613*b1cdbd2cSJim Jagielski 
2614*b1cdbd2cSJim Jagielski // Axes =======================================================================
2615*b1cdbd2cSJim Jagielski 
XclExpChLabelRange(const XclExpChRoot & rRoot)2616*b1cdbd2cSJim Jagielski XclExpChLabelRange::XclExpChLabelRange( const XclExpChRoot& rRoot ) :
2617*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CHLABELRANGE, 8 ),
2618*b1cdbd2cSJim Jagielski     XclExpChRoot( rRoot )
2619*b1cdbd2cSJim Jagielski {
2620*b1cdbd2cSJim Jagielski }
2621*b1cdbd2cSJim Jagielski 
Convert(const ScaleData & rScaleData,const ScfPropertySet & rChart1Axis,bool bMirrorOrient)2622*b1cdbd2cSJim Jagielski void XclExpChLabelRange::Convert( const ScaleData& rScaleData, const ScfPropertySet& rChart1Axis, bool bMirrorOrient )
2623*b1cdbd2cSJim Jagielski {
2624*b1cdbd2cSJim Jagielski     /*  Base time unit (using the property 'ExplicitTimeIncrement' from the old
2625*b1cdbd2cSJim Jagielski         chart API allows to detect axis type (date axis, if property exists),
2626*b1cdbd2cSJim Jagielski         and to receive the base time unit currently used in case the base time
2627*b1cdbd2cSJim Jagielski         unit is set to 'automatic'. */
2628*b1cdbd2cSJim Jagielski     cssc::TimeIncrement aTimeIncrement;
2629*b1cdbd2cSJim Jagielski     if( rChart1Axis.GetProperty( aTimeIncrement, EXC_CHPROP_EXPTIMEINCREMENT ) )
2630*b1cdbd2cSJim Jagielski     {
2631*b1cdbd2cSJim Jagielski         // property exists -> this is a date axis currently
2632*b1cdbd2cSJim Jagielski         ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_DATEAXIS );
2633*b1cdbd2cSJim Jagielski 
2634*b1cdbd2cSJim Jagielski         // automatic base time unit, if the UNO Any 'rScaleData.TimeIncrement.TimeResolution' does not contain a valid value...
2635*b1cdbd2cSJim Jagielski         bool bAutoBase = !rScaleData.TimeIncrement.TimeResolution.has< cssc::TimeIncrement >();
2636*b1cdbd2cSJim Jagielski         ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOBASE, bAutoBase );
2637*b1cdbd2cSJim Jagielski 
2638*b1cdbd2cSJim Jagielski         // ...but get the current base time unit from the property of the old chart API
2639*b1cdbd2cSJim Jagielski         sal_Int32 nApiTimeUnit = 0;
2640*b1cdbd2cSJim Jagielski         bool bValidBaseUnit = aTimeIncrement.TimeResolution >>= nApiTimeUnit;
2641*b1cdbd2cSJim Jagielski         DBG_ASSERT( bValidBaseUnit, "XclExpChLabelRange::Convert - cannot ghet base time unit" );
2642*b1cdbd2cSJim Jagielski         maDateData.mnBaseUnit = bValidBaseUnit ? lclGetTimeUnit( nApiTimeUnit ) : EXC_CHDATERANGE_DAYS;
2643*b1cdbd2cSJim Jagielski 
2644*b1cdbd2cSJim Jagielski         /*  Min/max values depend on base time unit, they specify the number of
2645*b1cdbd2cSJim Jagielski             days, months, or years starting from null date. */
2646*b1cdbd2cSJim Jagielski         bool bAutoMin = lclConvertTimeValue( GetRoot(), maDateData.mnMinDate, rScaleData.Minimum, maDateData.mnBaseUnit );
2647*b1cdbd2cSJim Jagielski         ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMIN, bAutoMin );
2648*b1cdbd2cSJim Jagielski         bool bAutoMax = lclConvertTimeValue( GetRoot(), maDateData.mnMaxDate, rScaleData.Maximum, maDateData.mnBaseUnit );
2649*b1cdbd2cSJim Jagielski         ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMAX, bAutoMax );
2650*b1cdbd2cSJim Jagielski     }
2651*b1cdbd2cSJim Jagielski 
2652*b1cdbd2cSJim Jagielski     // automatic axis type detection
2653*b1cdbd2cSJim Jagielski     ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTODATE, rScaleData.AutoDateAxis );
2654*b1cdbd2cSJim Jagielski 
2655*b1cdbd2cSJim Jagielski     // increment
2656*b1cdbd2cSJim Jagielski     bool bAutoMajor = lclConvertTimeInterval( maDateData.mnMajorStep, maDateData.mnMajorUnit, rScaleData.TimeIncrement.MajorTimeInterval );
2657*b1cdbd2cSJim Jagielski     ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMAJOR, bAutoMajor );
2658*b1cdbd2cSJim Jagielski     bool bAutoMinor = lclConvertTimeInterval( maDateData.mnMinorStep, maDateData.mnMinorUnit, rScaleData.TimeIncrement.MinorTimeInterval );
2659*b1cdbd2cSJim Jagielski     ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMINOR, bAutoMinor );
2660*b1cdbd2cSJim Jagielski 
2661*b1cdbd2cSJim Jagielski     // origin
2662*b1cdbd2cSJim Jagielski     double fOrigin = 0.0;
2663*b1cdbd2cSJim Jagielski     if( !lclIsAutoAnyOrGetValue( fOrigin, rScaleData.Origin ) )
2664*b1cdbd2cSJim Jagielski         maLabelData.mnCross = limit_cast< sal_uInt16 >( fOrigin, 1, 31999 );
2665*b1cdbd2cSJim Jagielski 
2666*b1cdbd2cSJim Jagielski     // reverse order
2667*b1cdbd2cSJim Jagielski     if( (rScaleData.Orientation == cssc2::AxisOrientation_REVERSE) != bMirrorOrient )
2668*b1cdbd2cSJim Jagielski         ::set_flag( maLabelData.mnFlags, EXC_CHLABELRANGE_REVERSE );
2669*b1cdbd2cSJim Jagielski }
2670*b1cdbd2cSJim Jagielski 
ConvertAxisPosition(const ScfPropertySet & rPropSet)2671*b1cdbd2cSJim Jagielski void XclExpChLabelRange::ConvertAxisPosition( const ScfPropertySet& rPropSet )
2672*b1cdbd2cSJim Jagielski {
2673*b1cdbd2cSJim Jagielski     cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE;
2674*b1cdbd2cSJim Jagielski     rPropSet.GetProperty( eAxisPos, EXC_CHPROP_CROSSOVERPOSITION );
2675*b1cdbd2cSJim Jagielski     double fCrossingPos = 1.0;
2676*b1cdbd2cSJim Jagielski     rPropSet.GetProperty( fCrossingPos, EXC_CHPROP_CROSSOVERVALUE );
2677*b1cdbd2cSJim Jagielski 
2678*b1cdbd2cSJim Jagielski     bool bDateAxis = ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_DATEAXIS );
2679*b1cdbd2cSJim Jagielski     switch( eAxisPos )
2680*b1cdbd2cSJim Jagielski     {
2681*b1cdbd2cSJim Jagielski         case cssc::ChartAxisPosition_ZERO:
2682*b1cdbd2cSJim Jagielski         case cssc::ChartAxisPosition_START:
2683*b1cdbd2cSJim Jagielski             maLabelData.mnCross = 1;
2684*b1cdbd2cSJim Jagielski             ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOCROSS );
2685*b1cdbd2cSJim Jagielski         break;
2686*b1cdbd2cSJim Jagielski         case cssc::ChartAxisPosition_END:
2687*b1cdbd2cSJim Jagielski             ::set_flag( maLabelData.mnFlags, EXC_CHLABELRANGE_MAXCROSS );
2688*b1cdbd2cSJim Jagielski         break;
2689*b1cdbd2cSJim Jagielski         case cssc::ChartAxisPosition_VALUE:
2690*b1cdbd2cSJim Jagielski             maLabelData.mnCross = limit_cast< sal_uInt16 >( fCrossingPos, 1, 31999 );
2691*b1cdbd2cSJim Jagielski             ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOCROSS, false );
2692*b1cdbd2cSJim Jagielski             if( bDateAxis )
2693*b1cdbd2cSJim Jagielski                 maDateData.mnCross = lclGetTimeValue( GetRoot(), fCrossingPos, maDateData.mnBaseUnit );
2694*b1cdbd2cSJim Jagielski         break;
2695*b1cdbd2cSJim Jagielski         default:
2696*b1cdbd2cSJim Jagielski             maLabelData.mnCross = 1;
2697*b1cdbd2cSJim Jagielski             ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOCROSS );
2698*b1cdbd2cSJim Jagielski     }
2699*b1cdbd2cSJim Jagielski }
2700*b1cdbd2cSJim Jagielski 
Save(XclExpStream & rStrm)2701*b1cdbd2cSJim Jagielski void XclExpChLabelRange::Save( XclExpStream& rStrm )
2702*b1cdbd2cSJim Jagielski {
2703*b1cdbd2cSJim Jagielski     // the CHLABELRANGE record
2704*b1cdbd2cSJim Jagielski     XclExpRecord::Save( rStrm );
2705*b1cdbd2cSJim Jagielski 
2706*b1cdbd2cSJim Jagielski     // the CHDATERANGE record with date axis settings (BIFF8 only)
2707*b1cdbd2cSJim Jagielski     if( GetBiff() == EXC_BIFF8 )
2708*b1cdbd2cSJim Jagielski     {
2709*b1cdbd2cSJim Jagielski         rStrm.StartRecord( EXC_ID_CHDATERANGE, 18 );
2710*b1cdbd2cSJim Jagielski         rStrm   << maDateData.mnMinDate
2711*b1cdbd2cSJim Jagielski                 << maDateData.mnMaxDate
2712*b1cdbd2cSJim Jagielski                 << maDateData.mnMajorStep
2713*b1cdbd2cSJim Jagielski                 << maDateData.mnMajorUnit
2714*b1cdbd2cSJim Jagielski                 << maDateData.mnMinorStep
2715*b1cdbd2cSJim Jagielski                 << maDateData.mnMinorUnit
2716*b1cdbd2cSJim Jagielski                 << maDateData.mnBaseUnit
2717*b1cdbd2cSJim Jagielski                 << maDateData.mnCross
2718*b1cdbd2cSJim Jagielski                 << maDateData.mnFlags;
2719*b1cdbd2cSJim Jagielski         rStrm.EndRecord();
2720*b1cdbd2cSJim Jagielski     }
2721*b1cdbd2cSJim Jagielski }
2722*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)2723*b1cdbd2cSJim Jagielski void XclExpChLabelRange::WriteBody( XclExpStream& rStrm )
2724*b1cdbd2cSJim Jagielski {
2725*b1cdbd2cSJim Jagielski     rStrm << maLabelData.mnCross << maLabelData.mnLabelFreq << maLabelData.mnTickFreq << maLabelData.mnFlags;
2726*b1cdbd2cSJim Jagielski }
2727*b1cdbd2cSJim Jagielski 
2728*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
2729*b1cdbd2cSJim Jagielski 
XclExpChValueRange(const XclExpChRoot & rRoot)2730*b1cdbd2cSJim Jagielski XclExpChValueRange::XclExpChValueRange( const XclExpChRoot& rRoot ) :
2731*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CHVALUERANGE, 42 ),
2732*b1cdbd2cSJim Jagielski     XclExpChRoot( rRoot )
2733*b1cdbd2cSJim Jagielski {
2734*b1cdbd2cSJim Jagielski }
2735*b1cdbd2cSJim Jagielski 
Convert(const ScaleData & rScaleData)2736*b1cdbd2cSJim Jagielski void XclExpChValueRange::Convert( const ScaleData& rScaleData )
2737*b1cdbd2cSJim Jagielski {
2738*b1cdbd2cSJim Jagielski     // scaling algorithm
2739*b1cdbd2cSJim Jagielski     bool bLogScale = ScfApiHelper::GetServiceName( rScaleData.Scaling ) == SERVICE_CHART2_LOGSCALING;
2740*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE, bLogScale );
2741*b1cdbd2cSJim Jagielski 
2742*b1cdbd2cSJim Jagielski     // min/max
2743*b1cdbd2cSJim Jagielski     bool bAutoMin = lclIsAutoAnyOrGetScaledValue( maData.mfMin, rScaleData.Minimum, bLogScale );
2744*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMIN, bAutoMin );
2745*b1cdbd2cSJim Jagielski     bool bAutoMax = lclIsAutoAnyOrGetScaledValue( maData.mfMax, rScaleData.Maximum, bLogScale );
2746*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAX, bAutoMax );
2747*b1cdbd2cSJim Jagielski 
2748*b1cdbd2cSJim Jagielski     // origin
2749*b1cdbd2cSJim Jagielski     bool bAutoCross = lclIsAutoAnyOrGetScaledValue( maData.mfCross, rScaleData.Origin, bLogScale );
2750*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS, bAutoCross );
2751*b1cdbd2cSJim Jagielski 
2752*b1cdbd2cSJim Jagielski     // major increment
2753*b1cdbd2cSJim Jagielski     const IncrementData& rIncrementData = rScaleData.IncrementData;
2754*b1cdbd2cSJim Jagielski     bool bAutoMajor = lclIsAutoAnyOrGetValue( maData.mfMajorStep, rIncrementData.Distance ) || (maData.mfMajorStep <= 0.0);
2755*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAJOR, bAutoMajor );
2756*b1cdbd2cSJim Jagielski     // minor increment
2757*b1cdbd2cSJim Jagielski     const Sequence< SubIncrement >& rSubIncrementSeq = rIncrementData.SubIncrements;
2758*b1cdbd2cSJim Jagielski     sal_Int32 nCount = 0;
2759*b1cdbd2cSJim Jagielski     bool bAutoMinor = bLogScale || bAutoMajor || (rSubIncrementSeq.getLength() < 1) ||
2760*b1cdbd2cSJim Jagielski         lclIsAutoAnyOrGetValue( nCount, rSubIncrementSeq[ 0 ].IntervalCount ) || (nCount < 1);
2761*b1cdbd2cSJim Jagielski     if( !bAutoMinor )
2762*b1cdbd2cSJim Jagielski         maData.mfMinorStep = maData.mfMajorStep / nCount;
2763*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMINOR, bAutoMinor );
2764*b1cdbd2cSJim Jagielski 
2765*b1cdbd2cSJim Jagielski     // reverse order
2766*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE, rScaleData.Orientation == cssc2::AxisOrientation_REVERSE );
2767*b1cdbd2cSJim Jagielski }
2768*b1cdbd2cSJim Jagielski 
ConvertAxisPosition(const ScfPropertySet & rPropSet)2769*b1cdbd2cSJim Jagielski void XclExpChValueRange::ConvertAxisPosition( const ScfPropertySet& rPropSet )
2770*b1cdbd2cSJim Jagielski {
2771*b1cdbd2cSJim Jagielski     cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE;
2772*b1cdbd2cSJim Jagielski     double fCrossingPos = 0.0;
2773*b1cdbd2cSJim Jagielski     if( rPropSet.GetProperty( eAxisPos, EXC_CHPROP_CROSSOVERPOSITION ) && rPropSet.GetProperty( fCrossingPos, EXC_CHPROP_CROSSOVERVALUE ) )
2774*b1cdbd2cSJim Jagielski     {
2775*b1cdbd2cSJim Jagielski         switch( eAxisPos )
2776*b1cdbd2cSJim Jagielski         {
2777*b1cdbd2cSJim Jagielski             case cssc::ChartAxisPosition_ZERO:
2778*b1cdbd2cSJim Jagielski             case cssc::ChartAxisPosition_START:
2779*b1cdbd2cSJim Jagielski                 ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS );
2780*b1cdbd2cSJim Jagielski             break;
2781*b1cdbd2cSJim Jagielski             case cssc::ChartAxisPosition_END:
2782*b1cdbd2cSJim Jagielski                 ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_MAXCROSS );
2783*b1cdbd2cSJim Jagielski             break;
2784*b1cdbd2cSJim Jagielski             case cssc::ChartAxisPosition_VALUE:
2785*b1cdbd2cSJim Jagielski                 ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS, false );
2786*b1cdbd2cSJim Jagielski                 maData.mfCross = ::get_flagvalue< double >( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE, log( fCrossingPos ) / log( 10.0 ), fCrossingPos );
2787*b1cdbd2cSJim Jagielski             break;
2788*b1cdbd2cSJim Jagielski             default:
2789*b1cdbd2cSJim Jagielski                 ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS );
2790*b1cdbd2cSJim Jagielski         }
2791*b1cdbd2cSJim Jagielski     }
2792*b1cdbd2cSJim Jagielski }
2793*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)2794*b1cdbd2cSJim Jagielski void XclExpChValueRange::WriteBody( XclExpStream& rStrm )
2795*b1cdbd2cSJim Jagielski {
2796*b1cdbd2cSJim Jagielski     rStrm   << maData.mfMin
2797*b1cdbd2cSJim Jagielski             << maData.mfMax
2798*b1cdbd2cSJim Jagielski             << maData.mfMajorStep
2799*b1cdbd2cSJim Jagielski             << maData.mfMinorStep
2800*b1cdbd2cSJim Jagielski             << maData.mfCross
2801*b1cdbd2cSJim Jagielski             << maData.mnFlags;
2802*b1cdbd2cSJim Jagielski }
2803*b1cdbd2cSJim Jagielski 
2804*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
2805*b1cdbd2cSJim Jagielski 
2806*b1cdbd2cSJim Jagielski namespace {
2807*b1cdbd2cSJim Jagielski 
lclGetXclTickPos(sal_Int32 nApiTickmarks)2808*b1cdbd2cSJim Jagielski sal_uInt8 lclGetXclTickPos( sal_Int32 nApiTickmarks )
2809*b1cdbd2cSJim Jagielski {
2810*b1cdbd2cSJim Jagielski     using namespace cssc2::TickmarkStyle;
2811*b1cdbd2cSJim Jagielski     sal_uInt8 nXclTickPos = 0;
2812*b1cdbd2cSJim Jagielski     ::set_flag( nXclTickPos, EXC_CHTICK_INSIDE,  ::get_flag( nApiTickmarks, INNER ) );
2813*b1cdbd2cSJim Jagielski     ::set_flag( nXclTickPos, EXC_CHTICK_OUTSIDE, ::get_flag( nApiTickmarks, OUTER ) );
2814*b1cdbd2cSJim Jagielski     return nXclTickPos;
2815*b1cdbd2cSJim Jagielski }
2816*b1cdbd2cSJim Jagielski 
2817*b1cdbd2cSJim Jagielski } // namespace
2818*b1cdbd2cSJim Jagielski 
XclExpChTick(const XclExpChRoot & rRoot)2819*b1cdbd2cSJim Jagielski XclExpChTick::XclExpChTick( const XclExpChRoot& rRoot ) :
2820*b1cdbd2cSJim Jagielski     XclExpRecord( EXC_ID_CHTICK, (rRoot.GetBiff() == EXC_BIFF8) ? 30 : 26 ),
2821*b1cdbd2cSJim Jagielski     XclExpChRoot( rRoot ),
2822*b1cdbd2cSJim Jagielski     mnTextColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
2823*b1cdbd2cSJim Jagielski {
2824*b1cdbd2cSJim Jagielski }
2825*b1cdbd2cSJim Jagielski 
Convert(const ScfPropertySet & rPropSet,const XclChExtTypeInfo & rTypeInfo,sal_uInt16 nAxisType)2826*b1cdbd2cSJim Jagielski void XclExpChTick::Convert( const ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo, sal_uInt16 nAxisType )
2827*b1cdbd2cSJim Jagielski {
2828*b1cdbd2cSJim Jagielski     // tick mark style
2829*b1cdbd2cSJim Jagielski     sal_Int32 nApiTickmarks = 0;
2830*b1cdbd2cSJim Jagielski     if( rPropSet.GetProperty( nApiTickmarks, EXC_CHPROP_MAJORTICKS ) )
2831*b1cdbd2cSJim Jagielski         maData.mnMajor = lclGetXclTickPos( nApiTickmarks );
2832*b1cdbd2cSJim Jagielski     if( rPropSet.GetProperty( nApiTickmarks, EXC_CHPROP_MINORTICKS ) )
2833*b1cdbd2cSJim Jagielski         maData.mnMinor = lclGetXclTickPos( nApiTickmarks );
2834*b1cdbd2cSJim Jagielski 
2835*b1cdbd2cSJim Jagielski     // axis labels
2836*b1cdbd2cSJim Jagielski     if( (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_RADAR) && (nAxisType == EXC_CHAXIS_X) )
2837*b1cdbd2cSJim Jagielski     {
2838*b1cdbd2cSJim Jagielski         /*  Radar charts disable their category labels via chart type, not via
2839*b1cdbd2cSJim Jagielski             axis, and axis labels are always 'near axis'. */
2840*b1cdbd2cSJim Jagielski         maData.mnLabelPos = EXC_CHTICK_NEXT;
2841*b1cdbd2cSJim Jagielski     }
2842*b1cdbd2cSJim Jagielski     else if( !rPropSet.GetBoolProperty( EXC_CHPROP_DISPLAYLABELS ) )
2843*b1cdbd2cSJim Jagielski     {
2844*b1cdbd2cSJim Jagielski         // no labels
2845*b1cdbd2cSJim Jagielski         maData.mnLabelPos = EXC_CHTICK_NOLABEL;
2846*b1cdbd2cSJim Jagielski     }
2847*b1cdbd2cSJim Jagielski     else if( rTypeInfo.mb3dChart && (nAxisType == EXC_CHAXIS_Y) )
2848*b1cdbd2cSJim Jagielski     {
2849*b1cdbd2cSJim Jagielski         // Excel expects 'near axis' at Y axes in 3D charts
2850*b1cdbd2cSJim Jagielski         maData.mnLabelPos = EXC_CHTICK_NEXT;
2851*b1cdbd2cSJim Jagielski     }
2852*b1cdbd2cSJim Jagielski     else
2853*b1cdbd2cSJim Jagielski     {
2854*b1cdbd2cSJim Jagielski         cssc::ChartAxisLabelPosition eApiLabelPos = cssc::ChartAxisLabelPosition_NEAR_AXIS;
2855*b1cdbd2cSJim Jagielski         rPropSet.GetProperty( eApiLabelPos, EXC_CHPROP_LABELPOSITION );
2856*b1cdbd2cSJim Jagielski         switch( eApiLabelPos )
2857*b1cdbd2cSJim Jagielski         {
2858*b1cdbd2cSJim Jagielski             case cssc::ChartAxisLabelPosition_NEAR_AXIS:
2859*b1cdbd2cSJim Jagielski             case cssc::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE: maData.mnLabelPos = EXC_CHTICK_NEXT;    break;
2860*b1cdbd2cSJim Jagielski             case cssc::ChartAxisLabelPosition_OUTSIDE_START:        maData.mnLabelPos = EXC_CHTICK_LOW;     break;
2861*b1cdbd2cSJim Jagielski             case cssc::ChartAxisLabelPosition_OUTSIDE_END:          maData.mnLabelPos = EXC_CHTICK_HIGH;    break;
2862*b1cdbd2cSJim Jagielski             default:                                                maData.mnLabelPos = EXC_CHTICK_NEXT;
2863*b1cdbd2cSJim Jagielski         }
2864*b1cdbd2cSJim Jagielski     }
2865*b1cdbd2cSJim Jagielski }
2866*b1cdbd2cSJim Jagielski 
SetFontColor(const Color & rColor,sal_uInt32 nColorId)2867*b1cdbd2cSJim Jagielski void XclExpChTick::SetFontColor( const Color& rColor, sal_uInt32 nColorId )
2868*b1cdbd2cSJim Jagielski {
2869*b1cdbd2cSJim Jagielski     maData.maTextColor = rColor;
2870*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTICK_AUTOCOLOR, rColor == COL_AUTO );
2871*b1cdbd2cSJim Jagielski     mnTextColorId = nColorId;
2872*b1cdbd2cSJim Jagielski }
2873*b1cdbd2cSJim Jagielski 
SetRotation(sal_uInt16 nRotation)2874*b1cdbd2cSJim Jagielski void XclExpChTick::SetRotation( sal_uInt16 nRotation )
2875*b1cdbd2cSJim Jagielski {
2876*b1cdbd2cSJim Jagielski     maData.mnRotation = nRotation;
2877*b1cdbd2cSJim Jagielski     ::set_flag( maData.mnFlags, EXC_CHTICK_AUTOROT, false );
2878*b1cdbd2cSJim Jagielski     ::insert_value( maData.mnFlags, XclTools::GetXclOrientFromRot( nRotation ), 2, 3 );
2879*b1cdbd2cSJim Jagielski }
2880*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)2881*b1cdbd2cSJim Jagielski void XclExpChTick::WriteBody( XclExpStream& rStrm )
2882*b1cdbd2cSJim Jagielski {
2883*b1cdbd2cSJim Jagielski     rStrm   << maData.mnMajor
2884*b1cdbd2cSJim Jagielski             << maData.mnMinor
2885*b1cdbd2cSJim Jagielski             << maData.mnLabelPos
2886*b1cdbd2cSJim Jagielski             << maData.mnBackMode;
2887*b1cdbd2cSJim Jagielski     rStrm.WriteZeroBytes( 16 );
2888*b1cdbd2cSJim Jagielski     rStrm   << maData.maTextColor
2889*b1cdbd2cSJim Jagielski             << maData.mnFlags;
2890*b1cdbd2cSJim Jagielski     if( GetBiff() == EXC_BIFF8 )
2891*b1cdbd2cSJim Jagielski         rStrm << GetPalette().GetColorIndex( mnTextColorId ) << maData.mnRotation;
2892*b1cdbd2cSJim Jagielski }
2893*b1cdbd2cSJim Jagielski 
2894*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
2895*b1cdbd2cSJim Jagielski 
2896*b1cdbd2cSJim Jagielski namespace {
2897*b1cdbd2cSJim Jagielski 
2898*b1cdbd2cSJim Jagielski /** Returns an API axis object from the passed coordinate system. */
lclGetApiAxis(Reference<XCoordinateSystem> xCoordSystem,sal_Int32 nApiAxisDim,sal_Int32 nApiAxesSetIdx)2899*b1cdbd2cSJim Jagielski Reference< XAxis > lclGetApiAxis( Reference< XCoordinateSystem > xCoordSystem,
2900*b1cdbd2cSJim Jagielski         sal_Int32 nApiAxisDim, sal_Int32 nApiAxesSetIdx )
2901*b1cdbd2cSJim Jagielski {
2902*b1cdbd2cSJim Jagielski     Reference< XAxis > xAxis;
2903*b1cdbd2cSJim Jagielski     if( (nApiAxisDim >= 0) && xCoordSystem.is() ) try
2904*b1cdbd2cSJim Jagielski     {
2905*b1cdbd2cSJim Jagielski         xAxis = xCoordSystem->getAxisByDimension( nApiAxisDim, nApiAxesSetIdx );
2906*b1cdbd2cSJim Jagielski     }
2907*b1cdbd2cSJim Jagielski     catch( Exception& )
2908*b1cdbd2cSJim Jagielski     {
2909*b1cdbd2cSJim Jagielski     }
2910*b1cdbd2cSJim Jagielski     return xAxis;
2911*b1cdbd2cSJim Jagielski }
2912*b1cdbd2cSJim Jagielski 
lclGetApiChart1Axis(Reference<XChartDocument> xChartDoc,sal_Int32 nApiAxisDim,sal_Int32 nApiAxesSetIdx)2913*b1cdbd2cSJim Jagielski Reference< cssc::XAxis > lclGetApiChart1Axis( Reference< XChartDocument > xChartDoc,
2914*b1cdbd2cSJim Jagielski         sal_Int32 nApiAxisDim, sal_Int32 nApiAxesSetIdx )
2915*b1cdbd2cSJim Jagielski {
2916*b1cdbd2cSJim Jagielski     Reference< cssc::XAxis > xChart1Axis;
2917*b1cdbd2cSJim Jagielski     try
2918*b1cdbd2cSJim Jagielski     {
2919*b1cdbd2cSJim Jagielski         Reference< cssc::XChartDocument > xChart1Doc( xChartDoc, UNO_QUERY_THROW );
2920*b1cdbd2cSJim Jagielski         Reference< cssc::XAxisSupplier > xChart1AxisSupp( xChart1Doc->getDiagram(), UNO_QUERY_THROW );
2921*b1cdbd2cSJim Jagielski         switch( nApiAxesSetIdx )
2922*b1cdbd2cSJim Jagielski         {
2923*b1cdbd2cSJim Jagielski             case EXC_CHART_AXESSET_PRIMARY:
2924*b1cdbd2cSJim Jagielski                 xChart1Axis = xChart1AxisSupp->getAxis( nApiAxisDim );
2925*b1cdbd2cSJim Jagielski             break;
2926*b1cdbd2cSJim Jagielski             case EXC_CHART_AXESSET_SECONDARY:
2927*b1cdbd2cSJim Jagielski                 xChart1Axis = xChart1AxisSupp->getSecondaryAxis( nApiAxisDim );
2928*b1cdbd2cSJim Jagielski             break;
2929*b1cdbd2cSJim Jagielski         }
2930*b1cdbd2cSJim Jagielski     }
2931*b1cdbd2cSJim Jagielski     catch( Exception& )
2932*b1cdbd2cSJim Jagielski     {
2933*b1cdbd2cSJim Jagielski     }
2934*b1cdbd2cSJim Jagielski     return xChart1Axis;
2935*b1cdbd2cSJim Jagielski }
2936*b1cdbd2cSJim Jagielski 
2937*b1cdbd2cSJim Jagielski } // namespace
2938*b1cdbd2cSJim Jagielski 
XclExpChAxis(const XclExpChRoot & rRoot,sal_uInt16 nAxisType)2939*b1cdbd2cSJim Jagielski XclExpChAxis::XclExpChAxis( const XclExpChRoot& rRoot, sal_uInt16 nAxisType ) :
2940*b1cdbd2cSJim Jagielski     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_AXIS, EXC_ID_CHAXIS, 18 ),
2941*b1cdbd2cSJim Jagielski     mnNumFmtIdx( EXC_FORMAT_NOTFOUND )
2942*b1cdbd2cSJim Jagielski {
2943*b1cdbd2cSJim Jagielski     maData.mnType = nAxisType;
2944*b1cdbd2cSJim Jagielski }
2945*b1cdbd2cSJim Jagielski 
SetFont(XclExpChFontRef xFont,const Color & rColor,sal_uInt32 nColorId)2946*b1cdbd2cSJim Jagielski void XclExpChAxis::SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId )
2947*b1cdbd2cSJim Jagielski {
2948*b1cdbd2cSJim Jagielski     mxFont = xFont;
2949*b1cdbd2cSJim Jagielski     if( mxTick.is() )
2950*b1cdbd2cSJim Jagielski         mxTick->SetFontColor( rColor, nColorId );
2951*b1cdbd2cSJim Jagielski }
2952*b1cdbd2cSJim Jagielski 
SetRotation(sal_uInt16 nRotation)2953*b1cdbd2cSJim Jagielski void XclExpChAxis::SetRotation( sal_uInt16 nRotation )
2954*b1cdbd2cSJim Jagielski {
2955*b1cdbd2cSJim Jagielski     if( mxTick.is() )
2956*b1cdbd2cSJim Jagielski         mxTick->SetRotation( nRotation );
2957*b1cdbd2cSJim Jagielski }
2958*b1cdbd2cSJim Jagielski 
Convert(Reference<XAxis> xAxis,Reference<XAxis> xCrossingAxis,Reference<cssc::XAxis> xChart1Axis,const XclChExtTypeInfo & rTypeInfo)2959*b1cdbd2cSJim Jagielski void XclExpChAxis::Convert( Reference< XAxis > xAxis, Reference< XAxis > xCrossingAxis,
2960*b1cdbd2cSJim Jagielski         Reference< cssc::XAxis > xChart1Axis, const XclChExtTypeInfo& rTypeInfo )
2961*b1cdbd2cSJim Jagielski {
2962*b1cdbd2cSJim Jagielski     ScfPropertySet aAxisProp( xAxis );
2963*b1cdbd2cSJim Jagielski     bool bCategoryAxis = ((GetAxisType() == EXC_CHAXIS_X) && rTypeInfo.mbCategoryAxis) || (GetAxisType() == EXC_CHAXIS_Z);
2964*b1cdbd2cSJim Jagielski 
2965*b1cdbd2cSJim Jagielski     // axis line format -------------------------------------------------------
2966*b1cdbd2cSJim Jagielski 
2967*b1cdbd2cSJim Jagielski     mxAxisLine.reset( new XclExpChLineFormat( GetChRoot() ) );
2968*b1cdbd2cSJim Jagielski     mxAxisLine->Convert( GetChRoot(), aAxisProp, EXC_CHOBJTYPE_AXISLINE );
2969*b1cdbd2cSJim Jagielski     // #i58688# axis enabled
2970*b1cdbd2cSJim Jagielski     mxAxisLine->SetShowAxis( aAxisProp.GetBoolProperty( EXC_CHPROP_SHOW ) );
2971*b1cdbd2cSJim Jagielski 
2972*b1cdbd2cSJim Jagielski     // axis scaling and increment ---------------------------------------------
2973*b1cdbd2cSJim Jagielski 
2974*b1cdbd2cSJim Jagielski     ScfPropertySet aCrossingProp( xCrossingAxis );
2975*b1cdbd2cSJim Jagielski     if( bCategoryAxis )
2976*b1cdbd2cSJim Jagielski     {
2977*b1cdbd2cSJim Jagielski         mxLabelRange.reset( new XclExpChLabelRange( GetChRoot() ) );
2978*b1cdbd2cSJim Jagielski         mxLabelRange->SetTicksBetweenCateg( rTypeInfo.mbTicksBetweenCateg );
2979*b1cdbd2cSJim Jagielski         if( xAxis.is() )
2980*b1cdbd2cSJim Jagielski         {
2981*b1cdbd2cSJim Jagielski             ScfPropertySet aChart1AxisProp( xChart1Axis );
2982*b1cdbd2cSJim Jagielski             // #i71684# radar charts have reversed rotation direction
2983*b1cdbd2cSJim Jagielski             mxLabelRange->Convert( xAxis->getScaleData(), aChart1AxisProp, (GetAxisType() == EXC_CHAXIS_X) && (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_RADAR) );
2984*b1cdbd2cSJim Jagielski         }
2985*b1cdbd2cSJim Jagielski         // get position of crossing axis on this axis from passed axis object
2986*b1cdbd2cSJim Jagielski         if( aCrossingProp.Is() )
2987*b1cdbd2cSJim Jagielski             mxLabelRange->ConvertAxisPosition( aCrossingProp );
2988*b1cdbd2cSJim Jagielski     }
2989*b1cdbd2cSJim Jagielski     else
2990*b1cdbd2cSJim Jagielski     {
2991*b1cdbd2cSJim Jagielski         mxValueRange.reset( new XclExpChValueRange( GetChRoot() ) );
2992*b1cdbd2cSJim Jagielski         if( xAxis.is() )
2993*b1cdbd2cSJim Jagielski             mxValueRange->Convert( xAxis->getScaleData() );
2994*b1cdbd2cSJim Jagielski         // get position of crossing axis on this axis from passed axis object
2995*b1cdbd2cSJim Jagielski         if( aCrossingProp.Is() )
2996*b1cdbd2cSJim Jagielski             mxValueRange->ConvertAxisPosition( aCrossingProp );
2997*b1cdbd2cSJim Jagielski     }
2998*b1cdbd2cSJim Jagielski 
2999*b1cdbd2cSJim Jagielski     // axis caption text ------------------------------------------------------
3000*b1cdbd2cSJim Jagielski 
3001*b1cdbd2cSJim Jagielski     // axis ticks properties
3002*b1cdbd2cSJim Jagielski     mxTick.reset( new XclExpChTick( GetChRoot() ) );
3003*b1cdbd2cSJim Jagielski     mxTick->Convert( aAxisProp, rTypeInfo, GetAxisType() );
3004*b1cdbd2cSJim Jagielski 
3005*b1cdbd2cSJim Jagielski     // axis label formatting and rotation
3006*b1cdbd2cSJim Jagielski     ConvertFontBase( GetChRoot(), aAxisProp );
3007*b1cdbd2cSJim Jagielski     ConvertRotationBase( GetChRoot(), aAxisProp, true );
3008*b1cdbd2cSJim Jagielski 
3009*b1cdbd2cSJim Jagielski     // axis number format
3010*b1cdbd2cSJim Jagielski     sal_Int32 nApiNumFmt = 0;
3011*b1cdbd2cSJim Jagielski     if( !bCategoryAxis && aAxisProp.GetProperty( nApiNumFmt, EXC_CHPROP_NUMBERFORMAT ) )
3012*b1cdbd2cSJim Jagielski         mnNumFmtIdx = GetNumFmtBuffer().Insert( static_cast< sal_uInt32 >( nApiNumFmt ) );
3013*b1cdbd2cSJim Jagielski 
3014*b1cdbd2cSJim Jagielski     // grid -------------------------------------------------------------------
3015*b1cdbd2cSJim Jagielski 
3016*b1cdbd2cSJim Jagielski     if( xAxis.is() )
3017*b1cdbd2cSJim Jagielski     {
3018*b1cdbd2cSJim Jagielski         // main grid
3019*b1cdbd2cSJim Jagielski         ScfPropertySet aGridProp( xAxis->getGridProperties() );
3020*b1cdbd2cSJim Jagielski         if( aGridProp.GetBoolProperty( EXC_CHPROP_SHOW ) )
3021*b1cdbd2cSJim Jagielski             mxMajorGrid = lclCreateLineFormat( GetChRoot(), aGridProp, EXC_CHOBJTYPE_GRIDLINE );
3022*b1cdbd2cSJim Jagielski         // sub grid
3023*b1cdbd2cSJim Jagielski         Sequence< Reference< XPropertySet > > aSubGridPropSeq = xAxis->getSubGridProperties();
3024*b1cdbd2cSJim Jagielski         if( aSubGridPropSeq.hasElements() )
3025*b1cdbd2cSJim Jagielski         {
3026*b1cdbd2cSJim Jagielski             ScfPropertySet aSubGridProp( aSubGridPropSeq[ 0 ] );
3027*b1cdbd2cSJim Jagielski             if( aSubGridProp.GetBoolProperty( EXC_CHPROP_SHOW ) )
3028*b1cdbd2cSJim Jagielski                 mxMinorGrid = lclCreateLineFormat( GetChRoot(), aSubGridProp, EXC_CHOBJTYPE_GRIDLINE );
3029*b1cdbd2cSJim Jagielski         }
3030*b1cdbd2cSJim Jagielski     }
3031*b1cdbd2cSJim Jagielski }
3032*b1cdbd2cSJim Jagielski 
ConvertWall(XDiagramRef xDiagram)3033*b1cdbd2cSJim Jagielski void XclExpChAxis::ConvertWall( XDiagramRef xDiagram )
3034*b1cdbd2cSJim Jagielski {
3035*b1cdbd2cSJim Jagielski     if( xDiagram.is() ) switch( GetAxisType() )
3036*b1cdbd2cSJim Jagielski     {
3037*b1cdbd2cSJim Jagielski         case EXC_CHAXIS_X:
3038*b1cdbd2cSJim Jagielski         {
3039*b1cdbd2cSJim Jagielski             ScfPropertySet aWallProp( xDiagram->getWall() );
3040*b1cdbd2cSJim Jagielski             mxWallFrame = lclCreateFrame( GetChRoot(), aWallProp, EXC_CHOBJTYPE_WALL3D );
3041*b1cdbd2cSJim Jagielski         }
3042*b1cdbd2cSJim Jagielski         break;
3043*b1cdbd2cSJim Jagielski         case EXC_CHAXIS_Y:
3044*b1cdbd2cSJim Jagielski         {
3045*b1cdbd2cSJim Jagielski             ScfPropertySet aFloorProp( xDiagram->getFloor() );
3046*b1cdbd2cSJim Jagielski             mxWallFrame = lclCreateFrame( GetChRoot(), aFloorProp, EXC_CHOBJTYPE_FLOOR3D );
3047*b1cdbd2cSJim Jagielski         }
3048*b1cdbd2cSJim Jagielski         break;
3049*b1cdbd2cSJim Jagielski         default:
3050*b1cdbd2cSJim Jagielski             mxWallFrame.reset();
3051*b1cdbd2cSJim Jagielski     }
3052*b1cdbd2cSJim Jagielski }
3053*b1cdbd2cSJim Jagielski 
WriteSubRecords(XclExpStream & rStrm)3054*b1cdbd2cSJim Jagielski void XclExpChAxis::WriteSubRecords( XclExpStream& rStrm )
3055*b1cdbd2cSJim Jagielski {
3056*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxLabelRange );
3057*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxValueRange );
3058*b1cdbd2cSJim Jagielski     if( mnNumFmtIdx != EXC_FORMAT_NOTFOUND )
3059*b1cdbd2cSJim Jagielski         XclExpUInt16Record( EXC_ID_CHFORMAT, mnNumFmtIdx ).Save( rStrm );
3060*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxTick );
3061*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxFont );
3062*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxAxisLine, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_AXISLINE );
3063*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxMajorGrid, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_MAJORGRID );
3064*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxMinorGrid, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_MINORGRID );
3065*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxWallFrame, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_WALLS );
3066*b1cdbd2cSJim Jagielski }
3067*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)3068*b1cdbd2cSJim Jagielski void XclExpChAxis::WriteBody( XclExpStream& rStrm )
3069*b1cdbd2cSJim Jagielski {
3070*b1cdbd2cSJim Jagielski     rStrm << maData.mnType;
3071*b1cdbd2cSJim Jagielski     rStrm.WriteZeroBytes( 16 );
3072*b1cdbd2cSJim Jagielski }
3073*b1cdbd2cSJim Jagielski 
3074*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
3075*b1cdbd2cSJim Jagielski 
XclExpChAxesSet(const XclExpChRoot & rRoot,sal_uInt16 nAxesSetId)3076*b1cdbd2cSJim Jagielski XclExpChAxesSet::XclExpChAxesSet( const XclExpChRoot& rRoot, sal_uInt16 nAxesSetId ) :
3077*b1cdbd2cSJim Jagielski     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_AXESSET, EXC_ID_CHAXESSET, 18 )
3078*b1cdbd2cSJim Jagielski {
3079*b1cdbd2cSJim Jagielski     maData.mnAxesSetId = nAxesSetId;
3080*b1cdbd2cSJim Jagielski     SetFutureRecordContext( 0, nAxesSetId );
3081*b1cdbd2cSJim Jagielski 
3082*b1cdbd2cSJim Jagielski     /*  Need to set a reasonable size for the plot area, otherwise Excel will
3083*b1cdbd2cSJim Jagielski         move away embedded shapes while auto-sizing the plot area. This is just
3084*b1cdbd2cSJim Jagielski         a wild guess, but will be fixed with implementing manual positioning of
3085*b1cdbd2cSJim Jagielski         chart elements. */
3086*b1cdbd2cSJim Jagielski     maData.maRect.mnX = 262;
3087*b1cdbd2cSJim Jagielski     maData.maRect.mnY = 626;
3088*b1cdbd2cSJim Jagielski     maData.maRect.mnWidth = 3187;
3089*b1cdbd2cSJim Jagielski     maData.maRect.mnHeight = 2633;
3090*b1cdbd2cSJim Jagielski }
3091*b1cdbd2cSJim Jagielski 
Convert(Reference<XDiagram> xDiagram,sal_uInt16 nFirstGroupIdx)3092*b1cdbd2cSJim Jagielski sal_uInt16 XclExpChAxesSet::Convert( Reference< XDiagram > xDiagram, sal_uInt16 nFirstGroupIdx )
3093*b1cdbd2cSJim Jagielski {
3094*b1cdbd2cSJim Jagielski     /*  First unused chart type group index is passed to be able to continue
3095*b1cdbd2cSJim Jagielski         counting of chart type groups for secondary axes set. */
3096*b1cdbd2cSJim Jagielski     sal_uInt16 nGroupIdx = nFirstGroupIdx;
3097*b1cdbd2cSJim Jagielski     Reference< XCoordinateSystemContainer > xCoordSysCont( xDiagram, UNO_QUERY );
3098*b1cdbd2cSJim Jagielski     if( xCoordSysCont.is() )
3099*b1cdbd2cSJim Jagielski     {
3100*b1cdbd2cSJim Jagielski         Sequence< Reference< XCoordinateSystem > > aCoordSysSeq = xCoordSysCont->getCoordinateSystems();
3101*b1cdbd2cSJim Jagielski         if( aCoordSysSeq.getLength() > 0 )
3102*b1cdbd2cSJim Jagielski         {
3103*b1cdbd2cSJim Jagielski             /*  Process first coordinate system only. Import filter puts all
3104*b1cdbd2cSJim Jagielski                 chart types into one coordinate system. */
3105*b1cdbd2cSJim Jagielski             Reference< XCoordinateSystem > xCoordSystem = aCoordSysSeq[ 0 ];
3106*b1cdbd2cSJim Jagielski             sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
3107*b1cdbd2cSJim Jagielski 
3108*b1cdbd2cSJim Jagielski             // 3d mode
3109*b1cdbd2cSJim Jagielski             bool b3dChart = xCoordSystem.is() && (xCoordSystem->getDimension() == 3);
3110*b1cdbd2cSJim Jagielski 
3111*b1cdbd2cSJim Jagielski             // percent charts
3112*b1cdbd2cSJim Jagielski             namespace ApiAxisType = cssc2::AxisType;
3113*b1cdbd2cSJim Jagielski             Reference< XAxis > xApiYAxis = lclGetApiAxis( xCoordSystem, EXC_CHART_AXIS_Y, nApiAxesSetIdx );
3114*b1cdbd2cSJim Jagielski             bool bPercent = xApiYAxis.is() && (xApiYAxis->getScaleData().AxisType == ApiAxisType::PERCENT);
3115*b1cdbd2cSJim Jagielski 
3116*b1cdbd2cSJim Jagielski             // connector lines in bar charts
3117*b1cdbd2cSJim Jagielski             ScfPropertySet aDiaProp( xDiagram );
3118*b1cdbd2cSJim Jagielski             bool bConnectBars = aDiaProp.GetBoolProperty( EXC_CHPROP_CONNECTBARS );
3119*b1cdbd2cSJim Jagielski 
3120*b1cdbd2cSJim Jagielski             // swapped axes sets
3121*b1cdbd2cSJim Jagielski             ScfPropertySet aCoordSysProp( xCoordSystem );
3122*b1cdbd2cSJim Jagielski             bool bSwappedAxesSet = aCoordSysProp.GetBoolProperty( EXC_CHPROP_SWAPXANDYAXIS );
3123*b1cdbd2cSJim Jagielski 
3124*b1cdbd2cSJim Jagielski             // X axis for later use
3125*b1cdbd2cSJim Jagielski             Reference< XAxis > xApiXAxis = lclGetApiAxis( xCoordSystem, EXC_CHART_AXIS_X, nApiAxesSetIdx );
3126*b1cdbd2cSJim Jagielski             // X axis labels
3127*b1cdbd2cSJim Jagielski             ScfPropertySet aXAxisProp( xApiXAxis );
3128*b1cdbd2cSJim Jagielski             bool bHasXLabels = aXAxisProp.GetBoolProperty( EXC_CHPROP_DISPLAYLABELS );
3129*b1cdbd2cSJim Jagielski 
3130*b1cdbd2cSJim Jagielski             // process chart types
3131*b1cdbd2cSJim Jagielski             Reference< XChartTypeContainer > xChartTypeCont( xCoordSystem, UNO_QUERY );
3132*b1cdbd2cSJim Jagielski             if( xChartTypeCont.is() )
3133*b1cdbd2cSJim Jagielski             {
3134*b1cdbd2cSJim Jagielski                 Sequence< Reference< XChartType > > aChartTypeSeq = xChartTypeCont->getChartTypes();
3135*b1cdbd2cSJim Jagielski                 const Reference< XChartType >* pBeg = aChartTypeSeq.getConstArray();
3136*b1cdbd2cSJim Jagielski                 const Reference< XChartType >* pEnd = pBeg + aChartTypeSeq.getLength();
3137*b1cdbd2cSJim Jagielski                 for( const Reference< XChartType >* pIt = pBeg; pIt != pEnd; ++pIt )
3138*b1cdbd2cSJim Jagielski                 {
3139*b1cdbd2cSJim Jagielski                     XclExpChTypeGroupRef xTypeGroup( new XclExpChTypeGroup( GetChRoot(), nGroupIdx ) );
3140*b1cdbd2cSJim Jagielski                     xTypeGroup->ConvertType( xDiagram, *pIt, nApiAxesSetIdx, b3dChart, bSwappedAxesSet, bHasXLabels );
3141*b1cdbd2cSJim Jagielski                     /*  If new chart type group cannot be inserted into a combination
3142*b1cdbd2cSJim Jagielski                         chart with existing type groups, insert all series into last
3143*b1cdbd2cSJim Jagielski                         contained chart type group instead of creating a new group. */
3144*b1cdbd2cSJim Jagielski                     XclExpChTypeGroupRef xLastGroup = GetLastTypeGroup();
3145*b1cdbd2cSJim Jagielski                     if( xLastGroup.is() && !(xTypeGroup->IsCombinable2d() && xLastGroup->IsCombinable2d()) )
3146*b1cdbd2cSJim Jagielski                     {
3147*b1cdbd2cSJim Jagielski                         xLastGroup->ConvertSeries( xDiagram, *pIt, nApiAxesSetIdx, bPercent, bConnectBars );
3148*b1cdbd2cSJim Jagielski                     }
3149*b1cdbd2cSJim Jagielski                     else
3150*b1cdbd2cSJim Jagielski                     {
3151*b1cdbd2cSJim Jagielski                         xTypeGroup->ConvertSeries( xDiagram, *pIt, nApiAxesSetIdx, bPercent, bConnectBars );
3152*b1cdbd2cSJim Jagielski                         if( xTypeGroup->IsValidGroup() )
3153*b1cdbd2cSJim Jagielski                         {
3154*b1cdbd2cSJim Jagielski                             maTypeGroups.AppendRecord( xTypeGroup );
3155*b1cdbd2cSJim Jagielski                             ++nGroupIdx;
3156*b1cdbd2cSJim Jagielski                         }
3157*b1cdbd2cSJim Jagielski                     }
3158*b1cdbd2cSJim Jagielski                 }
3159*b1cdbd2cSJim Jagielski             }
3160*b1cdbd2cSJim Jagielski 
3161*b1cdbd2cSJim Jagielski             if( XclExpChTypeGroup* pGroup = GetFirstTypeGroup().get() )
3162*b1cdbd2cSJim Jagielski             {
3163*b1cdbd2cSJim Jagielski                 const XclChExtTypeInfo& rTypeInfo = pGroup->GetTypeInfo();
3164*b1cdbd2cSJim Jagielski 
3165*b1cdbd2cSJim Jagielski                 // create axes according to chart type (no axes for pie and donut charts)
3166*b1cdbd2cSJim Jagielski                 if( rTypeInfo.meTypeCateg != EXC_CHTYPECATEG_PIE )
3167*b1cdbd2cSJim Jagielski                 {
3168*b1cdbd2cSJim Jagielski                     ConvertAxis( mxXAxis, EXC_CHAXIS_X, mxXAxisTitle, EXC_CHOBJLINK_XAXIS, xCoordSystem, rTypeInfo, EXC_CHART_AXIS_Y );
3169*b1cdbd2cSJim Jagielski                     ConvertAxis( mxYAxis, EXC_CHAXIS_Y, mxYAxisTitle, EXC_CHOBJLINK_YAXIS, xCoordSystem, rTypeInfo, EXC_CHART_AXIS_X );
3170*b1cdbd2cSJim Jagielski                     if( pGroup->Is3dDeepChart() )
3171*b1cdbd2cSJim Jagielski                         ConvertAxis( mxZAxis, EXC_CHAXIS_Z, mxZAxisTitle, EXC_CHOBJLINK_ZAXIS, xCoordSystem, rTypeInfo, EXC_CHART_AXIS_NONE );
3172*b1cdbd2cSJim Jagielski                 }
3173*b1cdbd2cSJim Jagielski 
3174*b1cdbd2cSJim Jagielski                 // X axis category ranges
3175*b1cdbd2cSJim Jagielski                 if( rTypeInfo.mbCategoryAxis && xApiXAxis.is() )
3176*b1cdbd2cSJim Jagielski                 {
3177*b1cdbd2cSJim Jagielski                     const ScaleData aScaleData = xApiXAxis->getScaleData();
3178*b1cdbd2cSJim Jagielski                     for( size_t nIdx = 0, nSize = maTypeGroups.GetSize(); nIdx < nSize; ++nIdx )
3179*b1cdbd2cSJim Jagielski                         maTypeGroups.GetRecord( nIdx )->ConvertCategSequence( aScaleData.Categories );
3180*b1cdbd2cSJim Jagielski                 }
3181*b1cdbd2cSJim Jagielski 
3182*b1cdbd2cSJim Jagielski                 // legend
3183*b1cdbd2cSJim Jagielski                 if( xDiagram.is() && (GetAxesSetId() == EXC_CHAXESSET_PRIMARY) )
3184*b1cdbd2cSJim Jagielski                 {
3185*b1cdbd2cSJim Jagielski                     Reference< XLegend > xLegend = xDiagram->getLegend();
3186*b1cdbd2cSJim Jagielski                     if( xLegend.is() )
3187*b1cdbd2cSJim Jagielski                     {
3188*b1cdbd2cSJim Jagielski                         ScfPropertySet aLegendProp( xLegend );
3189*b1cdbd2cSJim Jagielski                         pGroup->ConvertLegend( aLegendProp );
3190*b1cdbd2cSJim Jagielski                     }
3191*b1cdbd2cSJim Jagielski                 }
3192*b1cdbd2cSJim Jagielski             }
3193*b1cdbd2cSJim Jagielski         }
3194*b1cdbd2cSJim Jagielski     }
3195*b1cdbd2cSJim Jagielski 
3196*b1cdbd2cSJim Jagielski     // wall/floor/diagram frame formatting
3197*b1cdbd2cSJim Jagielski     if( xDiagram.is() && (GetAxesSetId() == EXC_CHAXESSET_PRIMARY) )
3198*b1cdbd2cSJim Jagielski     {
3199*b1cdbd2cSJim Jagielski         XclExpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
3200*b1cdbd2cSJim Jagielski         if( xTypeGroup.is() && xTypeGroup->Is3dWallChart() )
3201*b1cdbd2cSJim Jagielski         {
3202*b1cdbd2cSJim Jagielski             // wall/floor formatting (3D charts)
3203*b1cdbd2cSJim Jagielski             if( mxXAxis.is() )
3204*b1cdbd2cSJim Jagielski                 mxXAxis->ConvertWall( xDiagram );
3205*b1cdbd2cSJim Jagielski             if( mxYAxis.is() )
3206*b1cdbd2cSJim Jagielski                 mxYAxis->ConvertWall( xDiagram );
3207*b1cdbd2cSJim Jagielski         }
3208*b1cdbd2cSJim Jagielski         else
3209*b1cdbd2cSJim Jagielski         {
3210*b1cdbd2cSJim Jagielski             // diagram background formatting
3211*b1cdbd2cSJim Jagielski             ScfPropertySet aWallProp( xDiagram->getWall() );
3212*b1cdbd2cSJim Jagielski             mxPlotFrame = lclCreateFrame( GetChRoot(), aWallProp, EXC_CHOBJTYPE_PLOTFRAME );
3213*b1cdbd2cSJim Jagielski         }
3214*b1cdbd2cSJim Jagielski     }
3215*b1cdbd2cSJim Jagielski 
3216*b1cdbd2cSJim Jagielski     // inner and outer plot area position and size
3217*b1cdbd2cSJim Jagielski     try
3218*b1cdbd2cSJim Jagielski     {
3219*b1cdbd2cSJim Jagielski         Reference< cssc::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
3220*b1cdbd2cSJim Jagielski         Reference< cssc::XDiagramPositioning > xPositioning( xChart1Doc->getDiagram(), UNO_QUERY_THROW );
3221*b1cdbd2cSJim Jagielski         // set manual flag in chart data
3222*b1cdbd2cSJim Jagielski         if( !xPositioning->isAutomaticDiagramPositioning() )
3223*b1cdbd2cSJim Jagielski             GetChartData().SetManualPlotArea();
3224*b1cdbd2cSJim Jagielski         // the CHAXESSET record contains the inner plot area
3225*b1cdbd2cSJim Jagielski         maData.maRect = CalcChartRectFromHmm( xPositioning->calculateDiagramPositionExcludingAxes() );
3226*b1cdbd2cSJim Jagielski         // the embedded CHFRAMEPOS record contains the outer plot area
3227*b1cdbd2cSJim Jagielski         mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_PARENT, EXC_CHFRAMEPOS_PARENT ) );
3228*b1cdbd2cSJim Jagielski         // for pie charts, always use inner plot area size to exclude the data labels as Excel does
3229*b1cdbd2cSJim Jagielski         const XclExpChTypeGroup* pFirstTypeGroup = GetFirstTypeGroup().get();
3230*b1cdbd2cSJim Jagielski         bool bPieChart = pFirstTypeGroup && (pFirstTypeGroup->GetTypeInfo().meTypeCateg == EXC_CHTYPECATEG_PIE);
3231*b1cdbd2cSJim Jagielski         mxFramePos->GetFramePosData().maRect = bPieChart ? maData.maRect :
3232*b1cdbd2cSJim Jagielski             CalcChartRectFromHmm( xPositioning->calculateDiagramPositionIncludingAxes() );
3233*b1cdbd2cSJim Jagielski     }
3234*b1cdbd2cSJim Jagielski     catch( Exception& )
3235*b1cdbd2cSJim Jagielski     {
3236*b1cdbd2cSJim Jagielski     }
3237*b1cdbd2cSJim Jagielski 
3238*b1cdbd2cSJim Jagielski     // return first unused chart type group index for next axes set
3239*b1cdbd2cSJim Jagielski     return nGroupIdx;
3240*b1cdbd2cSJim Jagielski }
3241*b1cdbd2cSJim Jagielski 
Is3dChart() const3242*b1cdbd2cSJim Jagielski bool XclExpChAxesSet::Is3dChart() const
3243*b1cdbd2cSJim Jagielski {
3244*b1cdbd2cSJim Jagielski     XclExpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
3245*b1cdbd2cSJim Jagielski     return xTypeGroup.is() && xTypeGroup->Is3dChart();
3246*b1cdbd2cSJim Jagielski }
3247*b1cdbd2cSJim Jagielski 
WriteSubRecords(XclExpStream & rStrm)3248*b1cdbd2cSJim Jagielski void XclExpChAxesSet::WriteSubRecords( XclExpStream& rStrm )
3249*b1cdbd2cSJim Jagielski {
3250*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxFramePos );
3251*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxXAxis );
3252*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxYAxis );
3253*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxZAxis );
3254*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxXAxisTitle );
3255*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxYAxisTitle );
3256*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxZAxisTitle );
3257*b1cdbd2cSJim Jagielski     if( mxPlotFrame.is() )
3258*b1cdbd2cSJim Jagielski     {
3259*b1cdbd2cSJim Jagielski         XclExpEmptyRecord( EXC_ID_CHPLOTFRAME ).Save( rStrm );
3260*b1cdbd2cSJim Jagielski         mxPlotFrame->Save( rStrm );
3261*b1cdbd2cSJim Jagielski     }
3262*b1cdbd2cSJim Jagielski     maTypeGroups.Save( rStrm );
3263*b1cdbd2cSJim Jagielski }
3264*b1cdbd2cSJim Jagielski 
GetFirstTypeGroup() const3265*b1cdbd2cSJim Jagielski XclExpChTypeGroupRef XclExpChAxesSet::GetFirstTypeGroup() const
3266*b1cdbd2cSJim Jagielski {
3267*b1cdbd2cSJim Jagielski     return maTypeGroups.GetFirstRecord();
3268*b1cdbd2cSJim Jagielski }
3269*b1cdbd2cSJim Jagielski 
GetLastTypeGroup() const3270*b1cdbd2cSJim Jagielski XclExpChTypeGroupRef XclExpChAxesSet::GetLastTypeGroup() const
3271*b1cdbd2cSJim Jagielski {
3272*b1cdbd2cSJim Jagielski     return maTypeGroups.GetLastRecord();
3273*b1cdbd2cSJim Jagielski }
3274*b1cdbd2cSJim Jagielski 
ConvertAxis(XclExpChAxisRef & rxChAxis,sal_uInt16 nAxisType,XclExpChTextRef & rxChAxisTitle,sal_uInt16 nTitleTarget,Reference<XCoordinateSystem> xCoordSystem,const XclChExtTypeInfo & rTypeInfo,sal_Int32 nCrossingAxisDim)3275*b1cdbd2cSJim Jagielski void XclExpChAxesSet::ConvertAxis(
3276*b1cdbd2cSJim Jagielski         XclExpChAxisRef& rxChAxis, sal_uInt16 nAxisType,
3277*b1cdbd2cSJim Jagielski         XclExpChTextRef& rxChAxisTitle, sal_uInt16 nTitleTarget,
3278*b1cdbd2cSJim Jagielski         Reference< XCoordinateSystem > xCoordSystem, const XclChExtTypeInfo& rTypeInfo,
3279*b1cdbd2cSJim Jagielski         sal_Int32 nCrossingAxisDim )
3280*b1cdbd2cSJim Jagielski {
3281*b1cdbd2cSJim Jagielski     // create and convert axis object
3282*b1cdbd2cSJim Jagielski     rxChAxis.reset( new XclExpChAxis( GetChRoot(), nAxisType ) );
3283*b1cdbd2cSJim Jagielski     sal_Int32 nApiAxisDim = rxChAxis->GetApiAxisDimension();
3284*b1cdbd2cSJim Jagielski     sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
3285*b1cdbd2cSJim Jagielski     Reference< XAxis > xAxis = lclGetApiAxis( xCoordSystem, nApiAxisDim, nApiAxesSetIdx );
3286*b1cdbd2cSJim Jagielski     Reference< XAxis > xCrossingAxis = lclGetApiAxis( xCoordSystem, nCrossingAxisDim, nApiAxesSetIdx );
3287*b1cdbd2cSJim Jagielski     Reference< cssc::XAxis > xChart1Axis = lclGetApiChart1Axis( GetChartDocument(), nApiAxisDim, nApiAxesSetIdx );
3288*b1cdbd2cSJim Jagielski     rxChAxis->Convert( xAxis, xCrossingAxis, xChart1Axis, rTypeInfo );
3289*b1cdbd2cSJim Jagielski 
3290*b1cdbd2cSJim Jagielski     // create and convert axis title
3291*b1cdbd2cSJim Jagielski     Reference< XTitled > xTitled( xAxis, UNO_QUERY );
3292*b1cdbd2cSJim Jagielski     rxChAxisTitle = lclCreateTitle( GetChRoot(), xTitled, nTitleTarget );
3293*b1cdbd2cSJim Jagielski }
3294*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)3295*b1cdbd2cSJim Jagielski void XclExpChAxesSet::WriteBody( XclExpStream& rStrm )
3296*b1cdbd2cSJim Jagielski {
3297*b1cdbd2cSJim Jagielski     rStrm << maData.mnAxesSetId << maData.maRect;
3298*b1cdbd2cSJim Jagielski }
3299*b1cdbd2cSJim Jagielski 
3300*b1cdbd2cSJim Jagielski // The chart object ===========================================================
3301*b1cdbd2cSJim Jagielski 
XclExpChChart(const XclExpRoot & rRoot,Reference<XChartDocument> xChartDoc,const Rectangle & rChartRect)3302*b1cdbd2cSJim Jagielski XclExpChChart::XclExpChChart( const XclExpRoot& rRoot,
3303*b1cdbd2cSJim Jagielski         Reference< XChartDocument > xChartDoc, const Rectangle& rChartRect ) :
3304*b1cdbd2cSJim Jagielski     XclExpChGroupBase( XclExpChRoot( rRoot, *this ), EXC_CHFRBLOCK_TYPE_CHART, EXC_ID_CHCHART, 16 )
3305*b1cdbd2cSJim Jagielski {
3306*b1cdbd2cSJim Jagielski     Size aPtSize = OutputDevice::LogicToLogic( rChartRect.GetSize(), MapMode( MAP_100TH_MM ), MapMode( MAP_POINT ) );
3307*b1cdbd2cSJim Jagielski     // rectangle is stored in 16.16 fixed-point format
3308*b1cdbd2cSJim Jagielski     maRect.mnX = maRect.mnY = 0;
3309*b1cdbd2cSJim Jagielski     maRect.mnWidth = static_cast< sal_Int32 >( aPtSize.Width() << 16 );
3310*b1cdbd2cSJim Jagielski     maRect.mnHeight = static_cast< sal_Int32 >( aPtSize.Height() << 16 );
3311*b1cdbd2cSJim Jagielski 
3312*b1cdbd2cSJim Jagielski     // global chart properties (default values)
3313*b1cdbd2cSJim Jagielski     ::set_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY, false );
3314*b1cdbd2cSJim Jagielski     ::set_flag( maProps.mnFlags, EXC_CHPROPS_MANPLOTAREA );
3315*b1cdbd2cSJim Jagielski     maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_SKIP;
3316*b1cdbd2cSJim Jagielski 
3317*b1cdbd2cSJim Jagielski     // always create both axes set objects
3318*b1cdbd2cSJim Jagielski     mxPrimAxesSet.reset( new XclExpChAxesSet( GetChRoot(), EXC_CHAXESSET_PRIMARY ) );
3319*b1cdbd2cSJim Jagielski     mxSecnAxesSet.reset( new XclExpChAxesSet( GetChRoot(), EXC_CHAXESSET_SECONDARY ) );
3320*b1cdbd2cSJim Jagielski 
3321*b1cdbd2cSJim Jagielski     if( xChartDoc.is() )
3322*b1cdbd2cSJim Jagielski     {
3323*b1cdbd2cSJim Jagielski         Reference< XDiagram > xDiagram = xChartDoc->getFirstDiagram();
3324*b1cdbd2cSJim Jagielski 
3325*b1cdbd2cSJim Jagielski         // global chart properties (only 'include hidden cells' attribute for now)
3326*b1cdbd2cSJim Jagielski         ScfPropertySet aDiagramProp( xDiagram );
3327*b1cdbd2cSJim Jagielski         bool bIncludeHidden = aDiagramProp.GetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS );
3328*b1cdbd2cSJim Jagielski         ::set_flag( maProps.mnFlags,  EXC_CHPROPS_SHOWVISIBLEONLY, !bIncludeHidden );
3329*b1cdbd2cSJim Jagielski 
3330*b1cdbd2cSJim Jagielski         // initialize API conversion (remembers xChartDoc and rChartRect internally)
3331*b1cdbd2cSJim Jagielski         InitConversion( xChartDoc, rChartRect );
3332*b1cdbd2cSJim Jagielski 
3333*b1cdbd2cSJim Jagielski         // chart frame
3334*b1cdbd2cSJim Jagielski         ScfPropertySet aFrameProp( xChartDoc->getPageBackground() );
3335*b1cdbd2cSJim Jagielski         mxFrame = lclCreateFrame( GetChRoot(), aFrameProp, EXC_CHOBJTYPE_BACKGROUND );
3336*b1cdbd2cSJim Jagielski 
3337*b1cdbd2cSJim Jagielski         // chart title
3338*b1cdbd2cSJim Jagielski         Reference< XTitled > xTitled( xChartDoc, UNO_QUERY );
3339*b1cdbd2cSJim Jagielski         mxTitle = lclCreateTitle( GetChRoot(), xTitled, EXC_CHOBJLINK_TITLE );
3340*b1cdbd2cSJim Jagielski 
3341*b1cdbd2cSJim Jagielski         // diagrams (axes sets)
3342*b1cdbd2cSJim Jagielski         sal_uInt16 nFreeGroupIdx = mxPrimAxesSet->Convert( xDiagram, 0 );
3343*b1cdbd2cSJim Jagielski         if( !mxPrimAxesSet->Is3dChart() )
3344*b1cdbd2cSJim Jagielski             mxSecnAxesSet->Convert( xDiagram, nFreeGroupIdx );
3345*b1cdbd2cSJim Jagielski 
3346*b1cdbd2cSJim Jagielski         // treatment of missing values
3347*b1cdbd2cSJim Jagielski         ScfPropertySet aDiaProp( xDiagram );
3348*b1cdbd2cSJim Jagielski         sal_Int32 nMissingValues = 0;
3349*b1cdbd2cSJim Jagielski         if( aDiaProp.GetProperty( nMissingValues, EXC_CHPROP_MISSINGVALUETREATMENT ) )
3350*b1cdbd2cSJim Jagielski         {
3351*b1cdbd2cSJim Jagielski             using namespace cssc::MissingValueTreatment;
3352*b1cdbd2cSJim Jagielski             switch( nMissingValues )
3353*b1cdbd2cSJim Jagielski             {
3354*b1cdbd2cSJim Jagielski                 case LEAVE_GAP: maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_SKIP;           break;
3355*b1cdbd2cSJim Jagielski                 case USE_ZERO:  maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_ZERO;           break;
3356*b1cdbd2cSJim Jagielski                 case CONTINUE:  maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_INTERPOLATE;    break;
3357*b1cdbd2cSJim Jagielski             }
3358*b1cdbd2cSJim Jagielski         }
3359*b1cdbd2cSJim Jagielski 
3360*b1cdbd2cSJim Jagielski         // finish API conversion
3361*b1cdbd2cSJim Jagielski         FinishConversion();
3362*b1cdbd2cSJim Jagielski     }
3363*b1cdbd2cSJim Jagielski }
3364*b1cdbd2cSJim Jagielski 
CreateSeries()3365*b1cdbd2cSJim Jagielski XclExpChSeriesRef XclExpChChart::CreateSeries()
3366*b1cdbd2cSJim Jagielski {
3367*b1cdbd2cSJim Jagielski     XclExpChSeriesRef xSeries;
3368*b1cdbd2cSJim Jagielski     sal_uInt16 nSeriesIdx = static_cast< sal_uInt16 >( maSeries.GetSize() );
3369*b1cdbd2cSJim Jagielski     if( nSeriesIdx <= EXC_CHSERIES_MAXSERIES )
3370*b1cdbd2cSJim Jagielski     {
3371*b1cdbd2cSJim Jagielski         xSeries.reset( new XclExpChSeries( GetChRoot(), nSeriesIdx ) );
3372*b1cdbd2cSJim Jagielski         maSeries.AppendRecord( xSeries );
3373*b1cdbd2cSJim Jagielski     }
3374*b1cdbd2cSJim Jagielski     return xSeries;
3375*b1cdbd2cSJim Jagielski }
3376*b1cdbd2cSJim Jagielski 
RemoveLastSeries()3377*b1cdbd2cSJim Jagielski void XclExpChChart::RemoveLastSeries()
3378*b1cdbd2cSJim Jagielski {
3379*b1cdbd2cSJim Jagielski     if( !maSeries.IsEmpty() )
3380*b1cdbd2cSJim Jagielski         maSeries.RemoveRecord( maSeries.GetSize() - 1 );
3381*b1cdbd2cSJim Jagielski }
3382*b1cdbd2cSJim Jagielski 
SetDataLabel(XclExpChTextRef xText)3383*b1cdbd2cSJim Jagielski void XclExpChChart::SetDataLabel( XclExpChTextRef xText )
3384*b1cdbd2cSJim Jagielski {
3385*b1cdbd2cSJim Jagielski     if( xText.is() )
3386*b1cdbd2cSJim Jagielski         maLabels.AppendRecord( xText );
3387*b1cdbd2cSJim Jagielski }
3388*b1cdbd2cSJim Jagielski 
SetManualPlotArea()3389*b1cdbd2cSJim Jagielski void XclExpChChart::SetManualPlotArea()
3390*b1cdbd2cSJim Jagielski {
3391*b1cdbd2cSJim Jagielski     // this flag does not exist in BIFF5
3392*b1cdbd2cSJim Jagielski     if( GetBiff() == EXC_BIFF8 )
3393*b1cdbd2cSJim Jagielski         ::set_flag( maProps.mnFlags, EXC_CHPROPS_USEMANPLOTAREA );
3394*b1cdbd2cSJim Jagielski }
3395*b1cdbd2cSJim Jagielski 
WriteSubRecords(XclExpStream & rStrm)3396*b1cdbd2cSJim Jagielski void XclExpChChart::WriteSubRecords( XclExpStream& rStrm )
3397*b1cdbd2cSJim Jagielski {
3398*b1cdbd2cSJim Jagielski     // background format
3399*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxFrame );
3400*b1cdbd2cSJim Jagielski 
3401*b1cdbd2cSJim Jagielski     // data series
3402*b1cdbd2cSJim Jagielski     maSeries.Save( rStrm );
3403*b1cdbd2cSJim Jagielski 
3404*b1cdbd2cSJim Jagielski     // CHPROPERTIES record
3405*b1cdbd2cSJim Jagielski     rStrm.StartRecord( EXC_ID_CHPROPERTIES, 4 );
3406*b1cdbd2cSJim Jagielski     rStrm << maProps.mnFlags << maProps.mnEmptyMode << sal_uInt8( 0 );
3407*b1cdbd2cSJim Jagielski     rStrm.EndRecord();
3408*b1cdbd2cSJim Jagielski 
3409*b1cdbd2cSJim Jagielski     // axes sets (always save primary axes set)
3410*b1cdbd2cSJim Jagielski     sal_uInt16 nUsedAxesSets = mxSecnAxesSet->IsValidAxesSet() ? 2 : 1;
3411*b1cdbd2cSJim Jagielski     XclExpUInt16Record( EXC_ID_CHUSEDAXESSETS, nUsedAxesSets ).Save( rStrm );
3412*b1cdbd2cSJim Jagielski     mxPrimAxesSet->Save( rStrm );
3413*b1cdbd2cSJim Jagielski     if( mxSecnAxesSet->IsValidAxesSet() )
3414*b1cdbd2cSJim Jagielski         mxSecnAxesSet->Save( rStrm );
3415*b1cdbd2cSJim Jagielski 
3416*b1cdbd2cSJim Jagielski     // chart title and data labels
3417*b1cdbd2cSJim Jagielski     lclSaveRecord( rStrm, mxTitle );
3418*b1cdbd2cSJim Jagielski     maLabels.Save( rStrm );
3419*b1cdbd2cSJim Jagielski }
3420*b1cdbd2cSJim Jagielski 
WriteBody(XclExpStream & rStrm)3421*b1cdbd2cSJim Jagielski void XclExpChChart::WriteBody( XclExpStream& rStrm )
3422*b1cdbd2cSJim Jagielski {
3423*b1cdbd2cSJim Jagielski      rStrm << maRect;
3424*b1cdbd2cSJim Jagielski }
3425*b1cdbd2cSJim Jagielski 
3426*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
3427*b1cdbd2cSJim Jagielski 
XclExpChartDrawing(const XclExpRoot & rRoot,const Reference<XModel> & rxModel,const Size & rChartSize)3428*b1cdbd2cSJim Jagielski XclExpChartDrawing::XclExpChartDrawing( const XclExpRoot& rRoot,
3429*b1cdbd2cSJim Jagielski         const Reference< XModel >& rxModel, const Size& rChartSize ) :
3430*b1cdbd2cSJim Jagielski     XclExpRoot( rRoot )
3431*b1cdbd2cSJim Jagielski {
3432*b1cdbd2cSJim Jagielski     if( (rChartSize.Width() > 0) && (rChartSize.Height() > 0) )
3433*b1cdbd2cSJim Jagielski     {
3434*b1cdbd2cSJim Jagielski         ScfPropertySet aPropSet( rxModel );
3435*b1cdbd2cSJim Jagielski         Reference< XShapes > xShapes;
3436*b1cdbd2cSJim Jagielski         if( aPropSet.GetProperty( xShapes, EXC_CHPROP_ADDITIONALSHAPES ) && xShapes.is() && (xShapes->getCount() > 0) )
3437*b1cdbd2cSJim Jagielski         {
3438*b1cdbd2cSJim Jagielski             /*  Create a new independent object manager with own DFF stream for the
3439*b1cdbd2cSJim Jagielski                 DGCONTAINER, pass global manager as parent for shared usage of
3440*b1cdbd2cSJim Jagielski                 global DFF data (picture container etc.). */
3441*b1cdbd2cSJim Jagielski             mxObjMgr.reset( new XclExpEmbeddedObjectManager( GetObjectManager(), rChartSize, EXC_CHART_TOTALUNITS, EXC_CHART_TOTALUNITS ) );
3442*b1cdbd2cSJim Jagielski             // initialize the drawing object list
3443*b1cdbd2cSJim Jagielski             mxObjMgr->StartSheet();
3444*b1cdbd2cSJim Jagielski             // process the draw page (convert all shapes)
3445*b1cdbd2cSJim Jagielski             mxObjRecs = mxObjMgr->ProcessDrawing( xShapes );
3446*b1cdbd2cSJim Jagielski             // finalize the DFF stream
3447*b1cdbd2cSJim Jagielski             mxObjMgr->EndDocument();
3448*b1cdbd2cSJim Jagielski         }
3449*b1cdbd2cSJim Jagielski     }
3450*b1cdbd2cSJim Jagielski }
3451*b1cdbd2cSJim Jagielski 
~XclExpChartDrawing()3452*b1cdbd2cSJim Jagielski XclExpChartDrawing::~XclExpChartDrawing()
3453*b1cdbd2cSJim Jagielski {
3454*b1cdbd2cSJim Jagielski }
3455*b1cdbd2cSJim Jagielski 
Save(XclExpStream & rStrm)3456*b1cdbd2cSJim Jagielski void XclExpChartDrawing::Save( XclExpStream& rStrm )
3457*b1cdbd2cSJim Jagielski {
3458*b1cdbd2cSJim Jagielski     if( mxObjRecs.is() )
3459*b1cdbd2cSJim Jagielski         mxObjRecs->Save( rStrm );
3460*b1cdbd2cSJim Jagielski }
3461*b1cdbd2cSJim Jagielski 
3462*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
3463*b1cdbd2cSJim Jagielski 
XclExpChart(const XclExpRoot & rRoot,Reference<XModel> xModel,const Rectangle & rChartRect)3464*b1cdbd2cSJim Jagielski XclExpChart::XclExpChart( const XclExpRoot& rRoot, Reference< XModel > xModel, const Rectangle& rChartRect ) :
3465*b1cdbd2cSJim Jagielski     XclExpSubStream( EXC_BOF_CHART ),
3466*b1cdbd2cSJim Jagielski     XclExpRoot( rRoot )
3467*b1cdbd2cSJim Jagielski {
3468*b1cdbd2cSJim Jagielski     AppendNewRecord( new XclExpChartPageSettings( rRoot ) );
3469*b1cdbd2cSJim Jagielski     AppendNewRecord( new XclExpBoolRecord( EXC_ID_PROTECT, false ) );
3470*b1cdbd2cSJim Jagielski     AppendNewRecord( new XclExpChartDrawing( rRoot, xModel, rChartRect.GetSize() ) );
3471*b1cdbd2cSJim Jagielski     AppendNewRecord( new XclExpUInt16Record( EXC_ID_CHUNITS, EXC_CHUNITS_TWIPS ) );
3472*b1cdbd2cSJim Jagielski 
3473*b1cdbd2cSJim Jagielski     Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY );
3474*b1cdbd2cSJim Jagielski     AppendNewRecord( new XclExpChChart( rRoot, xChartDoc, rChartRect ) );
3475*b1cdbd2cSJim Jagielski }
3476*b1cdbd2cSJim Jagielski 
3477*b1cdbd2cSJim Jagielski // ============================================================================
3478*b1cdbd2cSJim Jagielski 
3479