xref: /trunk/main/oox/source/drawingml/chart/converterbase.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1*ca5ec200SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*ca5ec200SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*ca5ec200SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*ca5ec200SAndrew Rist  * distributed with this work for additional information
6*ca5ec200SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*ca5ec200SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*ca5ec200SAndrew Rist  * "License"); you may not use this file except in compliance
9*ca5ec200SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*ca5ec200SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*ca5ec200SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*ca5ec200SAndrew Rist  * software distributed under the License is distributed on an
15*ca5ec200SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*ca5ec200SAndrew Rist  * KIND, either express or implied.  See the License for the
17*ca5ec200SAndrew Rist  * specific language governing permissions and limitations
18*ca5ec200SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*ca5ec200SAndrew Rist  *************************************************************/
21*ca5ec200SAndrew Rist 
22*ca5ec200SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "oox/drawingml/chart/converterbase.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <com/sun/star/chart/XAxisXSupplier.hpp>
27cdf0e10cSrcweir #include <com/sun/star/chart/XAxisYSupplier.hpp>
28cdf0e10cSrcweir #include <com/sun/star/chart/XAxisZSupplier.hpp>
29cdf0e10cSrcweir #include <com/sun/star/chart/XChartDocument.hpp>
30cdf0e10cSrcweir #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
31cdf0e10cSrcweir #include <com/sun/star/chart2/RelativePosition.hpp>
32cdf0e10cSrcweir #include <com/sun/star/chart2/RelativeSize.hpp>
33cdf0e10cSrcweir #include <com/sun/star/drawing/FillStyle.hpp>
34cdf0e10cSrcweir #include <com/sun/star/drawing/LineStyle.hpp>
35cdf0e10cSrcweir #include <com/sun/star/frame/XModel.hpp>
36cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37cdf0e10cSrcweir #include <tools/solar.h>    // for F_PI180
38cdf0e10cSrcweir #include "oox/core/xmlfilterbase.hxx"
39cdf0e10cSrcweir #include "oox/drawingml/theme.hxx"
40cdf0e10cSrcweir 
41cdf0e10cSrcweir namespace oox {
42cdf0e10cSrcweir namespace drawingml {
43cdf0e10cSrcweir namespace chart {
44cdf0e10cSrcweir 
45cdf0e10cSrcweir // ============================================================================
46cdf0e10cSrcweir 
47cdf0e10cSrcweir namespace cssc = ::com::sun::star::chart;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir using namespace ::com::sun::star::awt;
50cdf0e10cSrcweir using namespace ::com::sun::star::chart2;
51cdf0e10cSrcweir using namespace ::com::sun::star::drawing;
52cdf0e10cSrcweir using namespace ::com::sun::star::frame;
53cdf0e10cSrcweir using namespace ::com::sun::star::lang;
54cdf0e10cSrcweir using namespace ::com::sun::star::uno;
55cdf0e10cSrcweir 
56cdf0e10cSrcweir using ::oox::core::XmlFilterBase;
57cdf0e10cSrcweir using ::rtl::OUString;
58cdf0e10cSrcweir 
59cdf0e10cSrcweir // ============================================================================
60cdf0e10cSrcweir 
61cdf0e10cSrcweir namespace {
62cdf0e10cSrcweir 
63cdf0e10cSrcweir struct TitleKey : public ::std::pair< ObjectType, ::std::pair< sal_Int32, sal_Int32 > >
64cdf0e10cSrcweir {
TitleKeyoox::drawingml::chart::__anonea31acc40111::TitleKey65cdf0e10cSrcweir     inline explicit     TitleKey( ObjectType eObjType, sal_Int32 nMainIdx = -1, sal_Int32 nSubIdx = -1 )
66cdf0e10cSrcweir                             { first = eObjType; second.first = nMainIdx; second.second = nSubIdx; }
67cdf0e10cSrcweir };
68cdf0e10cSrcweir 
69cdf0e10cSrcweir // ----------------------------------------------------------------------------
70cdf0e10cSrcweir 
71cdf0e10cSrcweir /** A helper structure to store all data related to title objects. Needed for
72cdf0e10cSrcweir     the conversion of manual title positions that needs the old Chart1 API.
73cdf0e10cSrcweir  */
74cdf0e10cSrcweir struct TitleLayoutInfo
75cdf0e10cSrcweir {
76cdf0e10cSrcweir     typedef Reference< XShape > (*GetShapeFunc)( const Reference< cssc::XChartDocument >& );
77cdf0e10cSrcweir 
78cdf0e10cSrcweir     Reference< XTitle > mxTitle;        /// The API title object.
79cdf0e10cSrcweir     ModelRef< LayoutModel > mxLayout;   /// The layout model, if existing.
80cdf0e10cSrcweir     GetShapeFunc        mpGetShape;     /// Helper function to receive the title shape.
81cdf0e10cSrcweir 
TitleLayoutInfooox::drawingml::chart::__anonea31acc40111::TitleLayoutInfo82cdf0e10cSrcweir     inline explicit     TitleLayoutInfo() : mpGetShape( 0 ) {}
83cdf0e10cSrcweir 
84cdf0e10cSrcweir     void                convertTitlePos(
85cdf0e10cSrcweir                             ConverterRoot& rRoot,
86cdf0e10cSrcweir                             const Reference< cssc::XChartDocument >& rxChart1Doc );
87cdf0e10cSrcweir };
88cdf0e10cSrcweir 
convertTitlePos(ConverterRoot & rRoot,const Reference<cssc::XChartDocument> & rxChart1Doc)89cdf0e10cSrcweir void TitleLayoutInfo::convertTitlePos( ConverterRoot& rRoot, const Reference< cssc::XChartDocument >& rxChart1Doc )
90cdf0e10cSrcweir {
91cdf0e10cSrcweir     if( mxTitle.is() && mpGetShape ) try
92cdf0e10cSrcweir     {
93cdf0e10cSrcweir         // try to get the title shape
94cdf0e10cSrcweir         Reference< XShape > xTitleShape( mpGetShape( rxChart1Doc ), UNO_SET_THROW );
95cdf0e10cSrcweir         // get title rotation angle, needed for correction of position of top-left edge
96cdf0e10cSrcweir         double fAngle = 0.0;
97cdf0e10cSrcweir         PropertySet aTitleProp( mxTitle );
98cdf0e10cSrcweir         aTitleProp.getProperty( fAngle, PROP_TextRotation );
99cdf0e10cSrcweir         // convert the position
100cdf0e10cSrcweir         LayoutModel& rLayout = mxLayout.getOrCreate();
101cdf0e10cSrcweir         LayoutConverter aLayoutConv( rRoot, rLayout );
102cdf0e10cSrcweir         aLayoutConv.convertFromModel( xTitleShape, fAngle );
103cdf0e10cSrcweir     }
104cdf0e10cSrcweir     catch( Exception& )
105cdf0e10cSrcweir     {
106cdf0e10cSrcweir     }
107cdf0e10cSrcweir }
108cdf0e10cSrcweir 
109cdf0e10cSrcweir // ----------------------------------------------------------------------------
110cdf0e10cSrcweir 
111cdf0e10cSrcweir /*  The following local functions implement getting the XShape interface of all
112cdf0e10cSrcweir     supported title objects (chart and axes). This needs some effort due to the
113cdf0e10cSrcweir     design of the old Chart1 API used to access these objects. */
114cdf0e10cSrcweir 
115cdf0e10cSrcweir /** A code fragment that returns a shape object from the passed shape supplier
116cdf0e10cSrcweir     using the specified interface function. Checks a boolean property first. */
117cdf0e10cSrcweir #define OOX_FRAGMENT_GETTITLESHAPE( shape_supplier, supplier_func, property_name ) \
118cdf0e10cSrcweir     PropertySet aPropSet( shape_supplier ); \
119cdf0e10cSrcweir     if( shape_supplier.is() && aPropSet.getBoolProperty( PROP_##property_name ) ) \
120cdf0e10cSrcweir         return shape_supplier->supplier_func(); \
121cdf0e10cSrcweir     return Reference< XShape >(); \
122cdf0e10cSrcweir 
123cdf0e10cSrcweir /** Implements a function returning the drawing shape of an axis title, if
124cdf0e10cSrcweir     existing, using the specified API interface and its function. */
125cdf0e10cSrcweir #define OOX_DEFINEFUNC_GETAXISTITLESHAPE( func_name, interface_type, supplier_func, property_name ) \
126cdf0e10cSrcweir Reference< XShape > func_name( const Reference< cssc::XChartDocument >& rxChart1Doc ) \
127cdf0e10cSrcweir { \
128cdf0e10cSrcweir     Reference< cssc::interface_type > xAxisSupp( rxChart1Doc->getDiagram(), UNO_QUERY ); \
129cdf0e10cSrcweir     OOX_FRAGMENT_GETTITLESHAPE( xAxisSupp, supplier_func, property_name ) \
130cdf0e10cSrcweir }
131cdf0e10cSrcweir 
132cdf0e10cSrcweir /** Returns the drawing shape of the main title, if existing. */
lclGetMainTitleShape(const Reference<cssc::XChartDocument> & rxChart1Doc)133cdf0e10cSrcweir Reference< XShape > lclGetMainTitleShape( const Reference< cssc::XChartDocument >& rxChart1Doc )
134cdf0e10cSrcweir {
135cdf0e10cSrcweir     OOX_FRAGMENT_GETTITLESHAPE( rxChart1Doc, getTitle, HasMainTitle )
136cdf0e10cSrcweir }
137cdf0e10cSrcweir 
138cdf0e10cSrcweir OOX_DEFINEFUNC_GETAXISTITLESHAPE( lclGetXAxisTitleShape, XAxisXSupplier, getXAxisTitle, HasXAxisTitle )
139cdf0e10cSrcweir OOX_DEFINEFUNC_GETAXISTITLESHAPE( lclGetYAxisTitleShape, XAxisYSupplier, getYAxisTitle, HasYAxisTitle )
140cdf0e10cSrcweir OOX_DEFINEFUNC_GETAXISTITLESHAPE( lclGetZAxisTitleShape, XAxisZSupplier, getZAxisTitle, HasZAxisTitle )
141cdf0e10cSrcweir OOX_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecXAxisTitleShape, XSecondAxisTitleSupplier, getSecondXAxisTitle, HasSecondaryXAxisTitle )
142cdf0e10cSrcweir OOX_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecYAxisTitleShape, XSecondAxisTitleSupplier, getSecondYAxisTitle, HasSecondaryYAxisTitle )
143cdf0e10cSrcweir 
144cdf0e10cSrcweir #undef OOX_DEFINEFUNC_GETAXISTITLESHAPE
145cdf0e10cSrcweir #undef OOX_IMPLEMENT_GETTITLESHAPE
146cdf0e10cSrcweir 
147cdf0e10cSrcweir } // namespace
148cdf0e10cSrcweir 
149cdf0e10cSrcweir // ============================================================================
150cdf0e10cSrcweir 
151cdf0e10cSrcweir struct ConverterData
152cdf0e10cSrcweir {
153cdf0e10cSrcweir     typedef ::std::map< TitleKey, TitleLayoutInfo > TitleMap;
154cdf0e10cSrcweir 
155cdf0e10cSrcweir     ObjectFormatter     maFormatter;
156cdf0e10cSrcweir     TitleMap            maTitles;
157cdf0e10cSrcweir     XmlFilterBase&      mrFilter;
158cdf0e10cSrcweir     ChartConverter&     mrConverter;
159cdf0e10cSrcweir     Reference< XChartDocument > mxDoc;
160cdf0e10cSrcweir     Size                maSize;
161cdf0e10cSrcweir 
162cdf0e10cSrcweir     explicit            ConverterData(
163cdf0e10cSrcweir                             XmlFilterBase& rFilter,
164cdf0e10cSrcweir                             ChartConverter& rChartConverter,
165cdf0e10cSrcweir                             const ChartSpaceModel& rChartModel,
166cdf0e10cSrcweir                             const Reference< XChartDocument >& rxChartDoc,
167cdf0e10cSrcweir                             const Size& rChartSize );
168cdf0e10cSrcweir                         ~ConverterData();
169cdf0e10cSrcweir };
170cdf0e10cSrcweir 
171cdf0e10cSrcweir // ----------------------------------------------------------------------------
172cdf0e10cSrcweir 
ConverterData(XmlFilterBase & rFilter,ChartConverter & rChartConverter,const ChartSpaceModel & rChartModel,const Reference<XChartDocument> & rxChartDoc,const Size & rChartSize)173cdf0e10cSrcweir ConverterData::ConverterData(
174cdf0e10cSrcweir         XmlFilterBase& rFilter,
175cdf0e10cSrcweir         ChartConverter& rChartConverter,
176cdf0e10cSrcweir         const ChartSpaceModel& rChartModel,
177cdf0e10cSrcweir         const Reference< XChartDocument >& rxChartDoc,
178cdf0e10cSrcweir         const Size& rChartSize ) :
179cdf0e10cSrcweir     maFormatter( rFilter, rxChartDoc, rChartModel ),
180cdf0e10cSrcweir     mrFilter( rFilter ),
181cdf0e10cSrcweir     mrConverter( rChartConverter ),
182cdf0e10cSrcweir     mxDoc( rxChartDoc ),
183cdf0e10cSrcweir     maSize( rChartSize )
184cdf0e10cSrcweir {
185cdf0e10cSrcweir     OSL_ENSURE( mxDoc.is(), "ConverterData::ConverterData - missing chart document" );
186cdf0e10cSrcweir     // lock the model to suppress internal updates during conversion
187cdf0e10cSrcweir     try
188cdf0e10cSrcweir     {
189cdf0e10cSrcweir         Reference< XModel > xModel( mxDoc, UNO_QUERY_THROW );
190cdf0e10cSrcweir         xModel->lockControllers();
191cdf0e10cSrcweir     }
192cdf0e10cSrcweir     catch( Exception& )
193cdf0e10cSrcweir     {
194cdf0e10cSrcweir     }
195cdf0e10cSrcweir 
196cdf0e10cSrcweir     // prepare conversion of title positions
197cdf0e10cSrcweir     maTitles[ TitleKey( OBJECTTYPE_CHARTTITLE ) ].mpGetShape = lclGetMainTitleShape;
198cdf0e10cSrcweir     maTitles[ TitleKey( OBJECTTYPE_AXISTITLE, API_PRIM_AXESSET, API_X_AXIS ) ].mpGetShape = lclGetXAxisTitleShape;
199cdf0e10cSrcweir     maTitles[ TitleKey( OBJECTTYPE_AXISTITLE, API_PRIM_AXESSET, API_Y_AXIS ) ].mpGetShape = lclGetYAxisTitleShape;
200cdf0e10cSrcweir     maTitles[ TitleKey( OBJECTTYPE_AXISTITLE, API_PRIM_AXESSET, API_Z_AXIS ) ].mpGetShape = lclGetZAxisTitleShape;
201cdf0e10cSrcweir     maTitles[ TitleKey( OBJECTTYPE_AXISTITLE, API_SECN_AXESSET, API_X_AXIS ) ].mpGetShape = lclGetSecXAxisTitleShape;
202cdf0e10cSrcweir     maTitles[ TitleKey( OBJECTTYPE_AXISTITLE, API_SECN_AXESSET, API_Y_AXIS ) ].mpGetShape = lclGetSecYAxisTitleShape;
203cdf0e10cSrcweir }
204cdf0e10cSrcweir 
~ConverterData()205cdf0e10cSrcweir ConverterData::~ConverterData()
206cdf0e10cSrcweir {
207cdf0e10cSrcweir     // unlock the model
208cdf0e10cSrcweir     try
209cdf0e10cSrcweir     {
210cdf0e10cSrcweir         Reference< XModel > xModel( mxDoc, UNO_QUERY_THROW );
211cdf0e10cSrcweir         xModel->unlockControllers();
212cdf0e10cSrcweir     }
213cdf0e10cSrcweir     catch( Exception& )
214cdf0e10cSrcweir     {
215cdf0e10cSrcweir     }
216cdf0e10cSrcweir }
217cdf0e10cSrcweir 
218cdf0e10cSrcweir // ============================================================================
219cdf0e10cSrcweir 
ConverterRoot(XmlFilterBase & rFilter,ChartConverter & rChartConverter,const ChartSpaceModel & rChartModel,const Reference<XChartDocument> & rxChartDoc,const Size & rChartSize)220cdf0e10cSrcweir ConverterRoot::ConverterRoot(
221cdf0e10cSrcweir         XmlFilterBase& rFilter,
222cdf0e10cSrcweir         ChartConverter& rChartConverter,
223cdf0e10cSrcweir         const ChartSpaceModel& rChartModel,
224cdf0e10cSrcweir         const Reference< XChartDocument >& rxChartDoc,
225cdf0e10cSrcweir         const Size& rChartSize ) :
226cdf0e10cSrcweir     mxData( new ConverterData( rFilter, rChartConverter, rChartModel, rxChartDoc, rChartSize ) )
227cdf0e10cSrcweir {
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
~ConverterRoot()230cdf0e10cSrcweir ConverterRoot::~ConverterRoot()
231cdf0e10cSrcweir {
232cdf0e10cSrcweir }
233cdf0e10cSrcweir 
createInstance(const OUString & rServiceName) const234cdf0e10cSrcweir Reference< XInterface > ConverterRoot::createInstance( const OUString& rServiceName ) const
235cdf0e10cSrcweir {
236cdf0e10cSrcweir     Reference< XInterface > xInt;
237cdf0e10cSrcweir     try
238cdf0e10cSrcweir     {
239cdf0e10cSrcweir         xInt = mxData->mrFilter.getServiceFactory()->createInstance( rServiceName );
240cdf0e10cSrcweir     }
241cdf0e10cSrcweir     catch( Exception& )
242cdf0e10cSrcweir     {
243cdf0e10cSrcweir     }
244cdf0e10cSrcweir     OSL_ENSURE( xInt.is(), "ConverterRoot::createInstance - cannot create instance" );
245cdf0e10cSrcweir     return xInt;
246cdf0e10cSrcweir }
247cdf0e10cSrcweir 
getFilter() const248cdf0e10cSrcweir XmlFilterBase& ConverterRoot::getFilter() const
249cdf0e10cSrcweir {
250cdf0e10cSrcweir     return mxData->mrFilter;
251cdf0e10cSrcweir }
252cdf0e10cSrcweir 
getChartConverter() const253cdf0e10cSrcweir ChartConverter& ConverterRoot::getChartConverter() const
254cdf0e10cSrcweir {
255cdf0e10cSrcweir     return mxData->mrConverter;
256cdf0e10cSrcweir }
257cdf0e10cSrcweir 
getChartDocument() const258cdf0e10cSrcweir Reference< XChartDocument > ConverterRoot::getChartDocument() const
259cdf0e10cSrcweir {
260cdf0e10cSrcweir     return mxData->mxDoc;
261cdf0e10cSrcweir }
262cdf0e10cSrcweir 
getChartSize() const263cdf0e10cSrcweir const Size& ConverterRoot::getChartSize() const
264cdf0e10cSrcweir {
265cdf0e10cSrcweir     return mxData->maSize;
266cdf0e10cSrcweir }
267cdf0e10cSrcweir 
getFormatter() const268cdf0e10cSrcweir ObjectFormatter& ConverterRoot::getFormatter() const
269cdf0e10cSrcweir {
270cdf0e10cSrcweir     return mxData->maFormatter;
271cdf0e10cSrcweir }
272cdf0e10cSrcweir 
registerTitleLayout(const Reference<XTitle> & rxTitle,const ModelRef<LayoutModel> & rxLayout,ObjectType eObjType,sal_Int32 nMainIdx,sal_Int32 nSubIdx)273cdf0e10cSrcweir void ConverterRoot::registerTitleLayout( const Reference< XTitle >& rxTitle,
274cdf0e10cSrcweir         const ModelRef< LayoutModel >& rxLayout, ObjectType eObjType, sal_Int32 nMainIdx, sal_Int32 nSubIdx )
275cdf0e10cSrcweir {
276cdf0e10cSrcweir     OSL_ENSURE( rxTitle.is(), "ConverterRoot::registerTitleLayout - missing title object" );
277cdf0e10cSrcweir     TitleLayoutInfo& rTitleInfo = mxData->maTitles[ TitleKey( eObjType, nMainIdx, nSubIdx ) ];
278cdf0e10cSrcweir     OSL_ENSURE( rTitleInfo.mpGetShape, "ConverterRoot::registerTitleLayout - invalid title key" );
279cdf0e10cSrcweir     rTitleInfo.mxTitle = rxTitle;
280cdf0e10cSrcweir     rTitleInfo.mxLayout = rxLayout;
281cdf0e10cSrcweir }
282cdf0e10cSrcweir 
convertTitlePositions()283cdf0e10cSrcweir void ConverterRoot::convertTitlePositions()
284cdf0e10cSrcweir {
285cdf0e10cSrcweir     try
286cdf0e10cSrcweir     {
287cdf0e10cSrcweir         Reference< cssc::XChartDocument > xChart1Doc( mxData->mxDoc, UNO_QUERY_THROW );
288cdf0e10cSrcweir         for( ConverterData::TitleMap::iterator aIt = mxData->maTitles.begin(), aEnd = mxData->maTitles.end(); aIt != aEnd; ++aIt )
289cdf0e10cSrcweir             aIt->second.convertTitlePos( *this, xChart1Doc );
290cdf0e10cSrcweir     }
291cdf0e10cSrcweir     catch( Exception& )
292cdf0e10cSrcweir     {
293cdf0e10cSrcweir     }
294cdf0e10cSrcweir }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir // ============================================================================
297cdf0e10cSrcweir 
298cdf0e10cSrcweir namespace {
299cdf0e10cSrcweir 
300cdf0e10cSrcweir /** Returns a position value in the chart area in 1/100 mm. */
lclCalcPosition(sal_Int32 nChartSize,double fPos,sal_Int32 nPosMode)301cdf0e10cSrcweir sal_Int32 lclCalcPosition( sal_Int32 nChartSize, double fPos, sal_Int32 nPosMode )
302cdf0e10cSrcweir {
303cdf0e10cSrcweir     switch( nPosMode )
304cdf0e10cSrcweir     {
305cdf0e10cSrcweir         case XML_edge:      // absolute start position as factor of chart size
306cdf0e10cSrcweir             return getLimitedValue< sal_Int32, double >( nChartSize * fPos + 0.5, 0, nChartSize );
307cdf0e10cSrcweir         case XML_factor:    // position relative to object default position
308cdf0e10cSrcweir             OSL_ENSURE( false, "lclCalcPosition - relative positioning not supported" );
309cdf0e10cSrcweir             return -1;
310cdf0e10cSrcweir     };
311cdf0e10cSrcweir 
312cdf0e10cSrcweir     OSL_ENSURE( false, "lclCalcPosition - unknown positioning mode" );
313cdf0e10cSrcweir     return -1;
314cdf0e10cSrcweir }
315cdf0e10cSrcweir 
316cdf0e10cSrcweir /** Returns a size value in the chart area in 1/100 mm. */
lclCalcSize(sal_Int32 nPos,sal_Int32 nChartSize,double fSize,sal_Int32 nSizeMode)317cdf0e10cSrcweir sal_Int32 lclCalcSize( sal_Int32 nPos, sal_Int32 nChartSize, double fSize, sal_Int32 nSizeMode )
318cdf0e10cSrcweir {
319cdf0e10cSrcweir     sal_Int32 nValue = getLimitedValue< sal_Int32, double >( nChartSize * fSize + 0.5, 0, nChartSize );
320cdf0e10cSrcweir     switch( nSizeMode )
321cdf0e10cSrcweir     {
322cdf0e10cSrcweir         case XML_factor:    // passed value is width/height
323cdf0e10cSrcweir             return nValue;
324cdf0e10cSrcweir         case XML_edge:      // passed value is right/bottom position
325cdf0e10cSrcweir             return nValue - nPos + 1;
326cdf0e10cSrcweir     };
327cdf0e10cSrcweir 
328cdf0e10cSrcweir     OSL_ENSURE( false, "lclCalcSize - unknown size mode" );
329cdf0e10cSrcweir     return -1;
330cdf0e10cSrcweir }
331cdf0e10cSrcweir 
332cdf0e10cSrcweir /** Returns a relative size value in the chart area. */
lclCalcRelSize(double fPos,double fSize,sal_Int32 nSizeMode)333cdf0e10cSrcweir double lclCalcRelSize( double fPos, double fSize, sal_Int32 nSizeMode )
334cdf0e10cSrcweir {
335cdf0e10cSrcweir     switch( nSizeMode )
336cdf0e10cSrcweir     {
337cdf0e10cSrcweir         case XML_factor:    // passed value is width/height
338cdf0e10cSrcweir         break;
339cdf0e10cSrcweir         case XML_edge:      // passed value is right/bottom position
340cdf0e10cSrcweir             fSize -= fPos;
341cdf0e10cSrcweir         break;
342cdf0e10cSrcweir         default:
343cdf0e10cSrcweir             OSL_ENSURE( false, "lclCalcRelSize - unknown size mode" );
344cdf0e10cSrcweir             fSize = 0.0;
345cdf0e10cSrcweir     };
346cdf0e10cSrcweir     return getLimitedValue< double, double >( fSize, 0.0, 1.0 - fPos );
347cdf0e10cSrcweir }
348cdf0e10cSrcweir 
349cdf0e10cSrcweir } // namespace
350cdf0e10cSrcweir 
351cdf0e10cSrcweir // ----------------------------------------------------------------------------
352cdf0e10cSrcweir 
LayoutConverter(const ConverterRoot & rParent,LayoutModel & rModel)353cdf0e10cSrcweir LayoutConverter::LayoutConverter( const ConverterRoot& rParent, LayoutModel& rModel ) :
354cdf0e10cSrcweir     ConverterBase< LayoutModel >( rParent, rModel )
355cdf0e10cSrcweir {
356cdf0e10cSrcweir }
357cdf0e10cSrcweir 
~LayoutConverter()358cdf0e10cSrcweir LayoutConverter::~LayoutConverter()
359cdf0e10cSrcweir {
360cdf0e10cSrcweir }
361cdf0e10cSrcweir 
calcAbsRectangle(Rectangle & orRect) const362cdf0e10cSrcweir bool LayoutConverter::calcAbsRectangle( Rectangle& orRect ) const
363cdf0e10cSrcweir {
364cdf0e10cSrcweir     if( !mrModel.mbAutoLayout )
365cdf0e10cSrcweir     {
366cdf0e10cSrcweir         const Size& rChartSize = getChartSize();
367cdf0e10cSrcweir         orRect.X = lclCalcPosition( rChartSize.Width,  mrModel.mfX, mrModel.mnXMode );
368cdf0e10cSrcweir         orRect.Y = lclCalcPosition( rChartSize.Height, mrModel.mfY, mrModel.mnYMode );
369cdf0e10cSrcweir         if( (orRect.X >= 0) && (orRect.Y >= 0) )
370cdf0e10cSrcweir         {
371cdf0e10cSrcweir             orRect.Width  = lclCalcSize( orRect.X, rChartSize.Width,  mrModel.mfW, mrModel.mnWMode );
372cdf0e10cSrcweir             orRect.Height = lclCalcSize( orRect.Y, rChartSize.Height, mrModel.mfH, mrModel.mnHMode );
373cdf0e10cSrcweir             return (orRect.Width > 0) && (orRect.Height > 0);
374cdf0e10cSrcweir         }
375cdf0e10cSrcweir     }
376cdf0e10cSrcweir     return false;
377cdf0e10cSrcweir }
378cdf0e10cSrcweir 
convertFromModel(PropertySet & rPropSet)379cdf0e10cSrcweir bool LayoutConverter::convertFromModel( PropertySet& rPropSet )
380cdf0e10cSrcweir {
381cdf0e10cSrcweir     if( !mrModel.mbAutoLayout &&
382cdf0e10cSrcweir         (mrModel.mnXMode == XML_edge) && (mrModel.mfX >= 0.0) &&
383cdf0e10cSrcweir         (mrModel.mnYMode == XML_edge) && (mrModel.mfY >= 0.0) )
384cdf0e10cSrcweir     {
385cdf0e10cSrcweir         RelativePosition aPos(
386cdf0e10cSrcweir             getLimitedValue< double, double >( mrModel.mfX, 0.0, 1.0 ),
387cdf0e10cSrcweir             getLimitedValue< double, double >( mrModel.mfY, 0.0, 1.0 ),
388cdf0e10cSrcweir             Alignment_TOP_LEFT );
389cdf0e10cSrcweir         rPropSet.setProperty( PROP_RelativePosition, aPos );
390cdf0e10cSrcweir 
391cdf0e10cSrcweir         RelativeSize aSize(
392cdf0e10cSrcweir             lclCalcRelSize( aPos.Primary, mrModel.mfW, mrModel.mnWMode ),
393cdf0e10cSrcweir             lclCalcRelSize( aPos.Secondary, mrModel.mfH, mrModel.mnHMode ) );
394cdf0e10cSrcweir         if( (aSize.Primary > 0.0) && (aSize.Secondary > 0.0) )
395cdf0e10cSrcweir         {
396cdf0e10cSrcweir             rPropSet.setProperty( PROP_RelativeSize, aSize );
397cdf0e10cSrcweir             return true;
398cdf0e10cSrcweir         }
399cdf0e10cSrcweir     }
400cdf0e10cSrcweir     return false;
401cdf0e10cSrcweir }
402cdf0e10cSrcweir 
convertFromModel(const Reference<XShape> & rxShape,double fRotationAngle)403cdf0e10cSrcweir bool LayoutConverter::convertFromModel( const Reference< XShape >& rxShape, double fRotationAngle )
404cdf0e10cSrcweir {
405cdf0e10cSrcweir     if( !mrModel.mbAutoLayout )
406cdf0e10cSrcweir     {
407cdf0e10cSrcweir         const Size& rChartSize = getChartSize();
408cdf0e10cSrcweir         Point aShapePos(
409cdf0e10cSrcweir             lclCalcPosition( rChartSize.Width,  mrModel.mfX, mrModel.mnXMode ),
410cdf0e10cSrcweir             lclCalcPosition( rChartSize.Height, mrModel.mfY, mrModel.mnYMode ) );
411cdf0e10cSrcweir         if( (aShapePos.X >= 0) && (aShapePos.Y >= 0) )
412cdf0e10cSrcweir         {
413cdf0e10cSrcweir             // the call to XShape.getSize() may recalc the chart view
414cdf0e10cSrcweir             Size aShapeSize = rxShape->getSize();
415cdf0e10cSrcweir             // rotated shapes need special handling...
416cdf0e10cSrcweir             double fSin = fabs( sin( fRotationAngle * F_PI180 ) );
417cdf0e10cSrcweir             // add part of height to X direction, if title is rotated down
418cdf0e10cSrcweir             if( fRotationAngle > 180.0 )
419cdf0e10cSrcweir                 aShapePos.X += static_cast< sal_Int32 >( fSin * aShapeSize.Height + 0.5 );
420cdf0e10cSrcweir             // add part of width to Y direction, if title is rotated up
421cdf0e10cSrcweir             else if( fRotationAngle > 0.0 )
422cdf0e10cSrcweir                 aShapePos.Y += static_cast< sal_Int32 >( fSin * aShapeSize.Width + 0.5 );
423cdf0e10cSrcweir             // set the resulting position at the shape
424cdf0e10cSrcweir             rxShape->setPosition( aShapePos );
425cdf0e10cSrcweir             return true;
426cdf0e10cSrcweir         }
427cdf0e10cSrcweir     }
428cdf0e10cSrcweir     return false;
429cdf0e10cSrcweir }
430cdf0e10cSrcweir 
431cdf0e10cSrcweir // ============================================================================
432cdf0e10cSrcweir 
433cdf0e10cSrcweir } // namespace chart
434cdf0e10cSrcweir } // namespace drawingml
435cdf0e10cSrcweir } // namespace oox
436