1ca5ec200SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3ca5ec200SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4ca5ec200SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5ca5ec200SAndrew Rist  * distributed with this work for additional information
6ca5ec200SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7ca5ec200SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8ca5ec200SAndrew Rist  * "License"); you may not use this file except in compliance
9ca5ec200SAndrew Rist  * with the License.  You may obtain a copy of the License at
10ca5ec200SAndrew Rist  *
11ca5ec200SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12ca5ec200SAndrew Rist  *
13ca5ec200SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14ca5ec200SAndrew Rist  * software distributed under the License is distributed on an
15ca5ec200SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16ca5ec200SAndrew Rist  * KIND, either express or implied.  See the License for the
17ca5ec200SAndrew Rist  * specific language governing permissions and limitations
18ca5ec200SAndrew Rist  * under the License.
19ca5ec200SAndrew Rist  *
20ca5ec200SAndrew Rist  *************************************************************/
21ca5ec200SAndrew Rist 
22ca5ec200SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "oox/drawingml/chart/titleconverter.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <com/sun/star/chart/ChartLegendExpansion.hpp>
27cdf0e10cSrcweir #include <com/sun/star/chart2/LegendPosition.hpp>
28cdf0e10cSrcweir #include <com/sun/star/chart2/XDiagram.hpp>
29cdf0e10cSrcweir #include <com/sun/star/chart2/XFormattedString.hpp>
30cdf0e10cSrcweir #include <com/sun/star/chart2/XLegend.hpp>
31cdf0e10cSrcweir #include <com/sun/star/chart2/XTitle.hpp>
32cdf0e10cSrcweir #include <com/sun/star/chart2/XTitled.hpp>
33cdf0e10cSrcweir #include "oox/drawingml/textbody.hxx"
34cdf0e10cSrcweir #include "oox/drawingml/textparagraph.hxx"
35cdf0e10cSrcweir #include "oox/drawingml/chart/datasourceconverter.hxx"
36cdf0e10cSrcweir #include "oox/drawingml/chart/titlemodel.hxx"
37cdf0e10cSrcweir #include "oox/helper/containerhelper.hxx"
38*f325a5bfSJian Fang Zhang #include <com/sun/star/chart2/RelativePosition.hpp>
39*f325a5bfSJian Fang Zhang #include <com/sun/star/drawing/Alignment.hpp>
40cdf0e10cSrcweir 
41*f325a5bfSJian Fang Zhang #include "oox/drawingml/chart/modelbase.hxx"
42cdf0e10cSrcweir namespace oox {
43cdf0e10cSrcweir namespace drawingml {
44cdf0e10cSrcweir namespace chart {
45cdf0e10cSrcweir 
46cdf0e10cSrcweir // ============================================================================
47cdf0e10cSrcweir 
48cdf0e10cSrcweir using namespace ::com::sun::star::awt;
49cdf0e10cSrcweir using namespace ::com::sun::star::chart2;
50cdf0e10cSrcweir using namespace ::com::sun::star::chart2::data;
51cdf0e10cSrcweir using namespace ::com::sun::star::uno;
52cdf0e10cSrcweir 
53cdf0e10cSrcweir using ::oox::core::XmlFilterBase;
54cdf0e10cSrcweir using ::rtl::OUString;
55*f325a5bfSJian Fang Zhang using namespace ::com::sun::star::drawing;
56cdf0e10cSrcweir 
57cdf0e10cSrcweir // ============================================================================
58cdf0e10cSrcweir 
TextConverter(const ConverterRoot & rParent,TextModel & rModel)59cdf0e10cSrcweir TextConverter::TextConverter( const ConverterRoot& rParent, TextModel& rModel ) :
60cdf0e10cSrcweir     ConverterBase< TextModel >( rParent, rModel )
61cdf0e10cSrcweir {
62cdf0e10cSrcweir }
63cdf0e10cSrcweir 
~TextConverter()64cdf0e10cSrcweir TextConverter::~TextConverter()
65cdf0e10cSrcweir {
66cdf0e10cSrcweir }
67cdf0e10cSrcweir 
createDataSequence(const OUString & rRole)68cdf0e10cSrcweir Reference< XDataSequence > TextConverter::createDataSequence( const OUString& rRole )
69cdf0e10cSrcweir {
70cdf0e10cSrcweir     Reference< XDataSequence > xDataSeq;
71cdf0e10cSrcweir     if( mrModel.mxDataSeq.is() )
72cdf0e10cSrcweir     {
73cdf0e10cSrcweir         DataSequenceConverter aDataSeqConv( *this, *mrModel.mxDataSeq );
74cdf0e10cSrcweir         xDataSeq = aDataSeqConv.createDataSequence( rRole );
75cdf0e10cSrcweir     }
76cdf0e10cSrcweir     return xDataSeq;
77cdf0e10cSrcweir }
78cdf0e10cSrcweir 
createStringSequence(const OUString & rDefaultText,const ModelRef<TextBody> & rxTextProp,ObjectType eObjType)79cdf0e10cSrcweir Sequence< Reference< XFormattedString > > TextConverter::createStringSequence(
80cdf0e10cSrcweir         const OUString& rDefaultText, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
81cdf0e10cSrcweir {
82cdf0e10cSrcweir     OSL_ENSURE( !mrModel.mxDataSeq || !mrModel.mxTextBody, "TextConverter::createStringSequence - linked string and rich text found" );
83cdf0e10cSrcweir     ::std::vector< Reference< XFormattedString > > aStringVec;
84cdf0e10cSrcweir     if( mrModel.mxTextBody.is() )
85cdf0e10cSrcweir     {
86cdf0e10cSrcweir         // rich-formatted text objects can be created, but currently Chart2 is not able to show them
87cdf0e10cSrcweir         const TextParagraphVector& rTextParas = mrModel.mxTextBody->getParagraphs();
88cdf0e10cSrcweir         for( TextParagraphVector::const_iterator aPIt = rTextParas.begin(), aPEnd = rTextParas.end(); aPIt != aPEnd; ++aPIt )
89cdf0e10cSrcweir         {
90cdf0e10cSrcweir             const TextParagraph& rTextPara = **aPIt;
91cdf0e10cSrcweir             const TextCharacterProperties& rParaProps = rTextPara.getProperties().getTextCharacterProperties();
92cdf0e10cSrcweir             for( TextRunVector::const_iterator aRIt = rTextPara.getRuns().begin(), aREnd = rTextPara.getRuns().end(); aRIt != aREnd; ++aRIt )
93cdf0e10cSrcweir             {
94cdf0e10cSrcweir                 const TextRun& rTextRun = **aRIt;
95cdf0e10cSrcweir                 bool bAddNewLine = (aRIt + 1 == aREnd) && (aPIt + 1 != aPEnd);
96cdf0e10cSrcweir                 Reference< XFormattedString > xFmtStr = appendFormattedString( aStringVec, rTextRun.getText(), bAddNewLine );
97cdf0e10cSrcweir                 PropertySet aPropSet( xFmtStr );
98cdf0e10cSrcweir                 TextCharacterProperties aRunProps( rParaProps );
99cdf0e10cSrcweir                 aRunProps.assignUsed( rTextRun.getTextCharacterProperties() );
100cdf0e10cSrcweir                 getFormatter().convertTextFormatting( aPropSet, aRunProps, eObjType );
101cdf0e10cSrcweir             }
102cdf0e10cSrcweir         }
103cdf0e10cSrcweir     }
104cdf0e10cSrcweir     else
105cdf0e10cSrcweir     {
106cdf0e10cSrcweir         OUString aString;
107cdf0e10cSrcweir         // try to create string from linked data
108cdf0e10cSrcweir         if( mrModel.mxDataSeq.is() && !mrModel.mxDataSeq->maData.empty() )
109cdf0e10cSrcweir             mrModel.mxDataSeq->maData.begin()->second >>= aString;
110cdf0e10cSrcweir         // no linked string -> fall back to default string
111cdf0e10cSrcweir         if( aString.getLength() == 0 )
112cdf0e10cSrcweir             aString = rDefaultText;
113cdf0e10cSrcweir 
114cdf0e10cSrcweir         // create formatted string object
115cdf0e10cSrcweir         if( aString.getLength() > 0 )
116cdf0e10cSrcweir         {
117cdf0e10cSrcweir             Reference< XFormattedString > xFmtStr = appendFormattedString( aStringVec, aString, false );
118cdf0e10cSrcweir             PropertySet aPropSet( xFmtStr );
119cdf0e10cSrcweir             getFormatter().convertTextFormatting( aPropSet, rxTextProp, eObjType );
120cdf0e10cSrcweir         }
121cdf0e10cSrcweir     }
122cdf0e10cSrcweir 
123cdf0e10cSrcweir     return ContainerHelper::vectorToSequence( aStringVec );
124cdf0e10cSrcweir }
125cdf0e10cSrcweir 
appendFormattedString(::std::vector<Reference<XFormattedString>> & orStringVec,const OUString & rString,bool bAddNewLine) const126cdf0e10cSrcweir Reference< XFormattedString > TextConverter::appendFormattedString(
127cdf0e10cSrcweir         ::std::vector< Reference< XFormattedString > >& orStringVec, const OUString& rString, bool bAddNewLine ) const
128cdf0e10cSrcweir {
129cdf0e10cSrcweir     Reference< XFormattedString > xFmtStr;
130cdf0e10cSrcweir     try
131cdf0e10cSrcweir     {
132cdf0e10cSrcweir         xFmtStr.set( ConverterRoot::createInstance( CREATE_OUSTRING( "com.sun.star.chart2.FormattedString" ) ), UNO_QUERY_THROW );
133cdf0e10cSrcweir         xFmtStr->setString( bAddNewLine ? (rString + OUString( sal_Unicode( '\n' ) )) : rString );
134cdf0e10cSrcweir         orStringVec.push_back( xFmtStr );
135cdf0e10cSrcweir     }
136cdf0e10cSrcweir     catch( Exception& )
137cdf0e10cSrcweir     {
138cdf0e10cSrcweir     }
139cdf0e10cSrcweir     return xFmtStr;
140cdf0e10cSrcweir }
141cdf0e10cSrcweir 
142cdf0e10cSrcweir // ============================================================================
143cdf0e10cSrcweir 
TitleConverter(const ConverterRoot & rParent,TitleModel & rModel)144cdf0e10cSrcweir TitleConverter::TitleConverter( const ConverterRoot& rParent, TitleModel& rModel ) :
145cdf0e10cSrcweir     ConverterBase< TitleModel >( rParent, rModel )
146cdf0e10cSrcweir {
147cdf0e10cSrcweir }
148cdf0e10cSrcweir 
~TitleConverter()149cdf0e10cSrcweir TitleConverter::~TitleConverter()
150cdf0e10cSrcweir {
151cdf0e10cSrcweir }
152cdf0e10cSrcweir 
convertFromModel(const Reference<XTitled> & rxTitled,const OUString & rAutoTitle,ObjectType eObjType,sal_Int32 nMainIdx,sal_Int32 nSubIdx)153cdf0e10cSrcweir void TitleConverter::convertFromModel( const Reference< XTitled >& rxTitled, const OUString& rAutoTitle, ObjectType eObjType, sal_Int32 nMainIdx, sal_Int32 nSubIdx )
154cdf0e10cSrcweir {
155cdf0e10cSrcweir     if( rxTitled.is() )
156cdf0e10cSrcweir     {
157cdf0e10cSrcweir         // create the formatted strings
158cdf0e10cSrcweir         TextModel& rText = mrModel.mxText.getOrCreate();
159cdf0e10cSrcweir         TextConverter aTextConv( *this, rText );
160cdf0e10cSrcweir         Sequence< Reference< XFormattedString > > aStringSeq = aTextConv.createStringSequence( rAutoTitle, mrModel.mxTextProp, eObjType );
161cdf0e10cSrcweir         if( aStringSeq.hasElements() ) try
162cdf0e10cSrcweir         {
163cdf0e10cSrcweir             // create the title object and set the string data
164cdf0e10cSrcweir             Reference< XTitle > xTitle( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.Title" ) ), UNO_QUERY_THROW );
165cdf0e10cSrcweir             xTitle->setText( aStringSeq );
166cdf0e10cSrcweir             rxTitled->setTitleObject( xTitle );
167cdf0e10cSrcweir 
168cdf0e10cSrcweir             // frame formatting (text formatting already done in TextConverter::createStringSequence())
169cdf0e10cSrcweir             PropertySet aPropSet( xTitle );
170cdf0e10cSrcweir             getFormatter().convertFrameFormatting( aPropSet, mrModel.mxShapeProp, eObjType );
171cdf0e10cSrcweir 
172cdf0e10cSrcweir             // frame rotation
173cdf0e10cSrcweir             OSL_ENSURE( !mrModel.mxTextProp || !rText.mxTextBody, "TitleConverter::convertFromModel - multiple text properties" );
174cdf0e10cSrcweir             ModelRef< TextBody > xTextProp = mrModel.mxTextProp.is() ? mrModel.mxTextProp : rText.mxTextBody;
175cdf0e10cSrcweir             getFormatter().convertTextRotation( aPropSet, xTextProp, true );
176cdf0e10cSrcweir 
177cdf0e10cSrcweir             // register the title and layout data for conversion of position
178cdf0e10cSrcweir             registerTitleLayout( xTitle, mrModel.mxLayout, eObjType, nMainIdx, nSubIdx );
179cdf0e10cSrcweir         }
180cdf0e10cSrcweir         catch( Exception& )
181cdf0e10cSrcweir         {
182cdf0e10cSrcweir         }
183cdf0e10cSrcweir     }
184cdf0e10cSrcweir }
185cdf0e10cSrcweir 
186cdf0e10cSrcweir // ============================================================================
187cdf0e10cSrcweir 
LegendConverter(const ConverterRoot & rParent,LegendModel & rModel)188cdf0e10cSrcweir LegendConverter::LegendConverter( const ConverterRoot& rParent, LegendModel& rModel ) :
189cdf0e10cSrcweir     ConverterBase< LegendModel >( rParent, rModel )
190cdf0e10cSrcweir {
191cdf0e10cSrcweir }
192cdf0e10cSrcweir 
~LegendConverter()193cdf0e10cSrcweir LegendConverter::~LegendConverter()
194cdf0e10cSrcweir {
195cdf0e10cSrcweir }
196cdf0e10cSrcweir 
convertFromModel(const Reference<XDiagram> & rxDiagram)197cdf0e10cSrcweir void LegendConverter::convertFromModel( const Reference< XDiagram >& rxDiagram )
198cdf0e10cSrcweir {
199cdf0e10cSrcweir     if( rxDiagram.is() ) try
200cdf0e10cSrcweir     {
201cdf0e10cSrcweir         namespace cssc = ::com::sun::star::chart;
202cdf0e10cSrcweir         namespace cssc2 = ::com::sun::star::chart2;
203cdf0e10cSrcweir 
204cdf0e10cSrcweir         // create the legend
205cdf0e10cSrcweir         Reference< XLegend > xLegend( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.Legend" ) ), UNO_QUERY_THROW );
206cdf0e10cSrcweir         rxDiagram->setLegend( xLegend );
207cdf0e10cSrcweir         PropertySet aPropSet( xLegend );
208cdf0e10cSrcweir         aPropSet.setProperty( PROP_Show, true );
209cdf0e10cSrcweir 
210cdf0e10cSrcweir         // legend formatting
211cdf0e10cSrcweir         getFormatter().convertFormatting( aPropSet, mrModel.mxShapeProp, mrModel.mxTextProp, OBJECTTYPE_LEGEND );
212cdf0e10cSrcweir 
213cdf0e10cSrcweir         // predefined legend position and expansion
214cdf0e10cSrcweir         cssc2::LegendPosition eLegendPos = cssc2::LegendPosition_CUSTOM;
215cdf0e10cSrcweir         cssc::ChartLegendExpansion eLegendExpand = cssc::ChartLegendExpansion_CUSTOM;
216*f325a5bfSJian Fang Zhang         RelativePosition eRelPos;
217*f325a5bfSJian Fang Zhang         bool bTopRight=0;
218cdf0e10cSrcweir         switch( mrModel.mnPosition )
219cdf0e10cSrcweir         {
220cdf0e10cSrcweir             case XML_l:
221cdf0e10cSrcweir                 eLegendPos = cssc2::LegendPosition_LINE_START;
222cdf0e10cSrcweir                 eLegendExpand = cssc::ChartLegendExpansion_HIGH;
223cdf0e10cSrcweir             break;
224cdf0e10cSrcweir             case XML_r:
225cdf0e10cSrcweir                 eLegendPos = cssc2::LegendPosition_LINE_END;
226cdf0e10cSrcweir                 eLegendExpand = cssc::ChartLegendExpansion_HIGH;
227*f325a5bfSJian Fang Zhang                 break;
228*f325a5bfSJian Fang Zhang             case XML_tr:    // top-right not supported
229*f325a5bfSJian Fang Zhang                 eLegendPos = LegendPosition_CUSTOM;
230*f325a5bfSJian Fang Zhang                 eRelPos.Primary = 1;
231*f325a5bfSJian Fang Zhang                 eRelPos.Secondary =0;
232*f325a5bfSJian Fang Zhang                 eRelPos.Anchor = Alignment_TOP_RIGHT;
233*f325a5bfSJian Fang Zhang                 bTopRight=1;
234*f325a5bfSJian Fang Zhang 
235cdf0e10cSrcweir             break;
236cdf0e10cSrcweir             case XML_t:
237cdf0e10cSrcweir                 eLegendPos = cssc2::LegendPosition_PAGE_START;
238cdf0e10cSrcweir                 eLegendExpand = cssc::ChartLegendExpansion_WIDE;
239cdf0e10cSrcweir             break;
240cdf0e10cSrcweir             case XML_b:
241cdf0e10cSrcweir                 eLegendPos = cssc2::LegendPosition_PAGE_END;
242cdf0e10cSrcweir                 eLegendExpand = cssc::ChartLegendExpansion_WIDE;
243cdf0e10cSrcweir             break;
244cdf0e10cSrcweir         }
245*f325a5bfSJian Fang Zhang         bool bManualLayout=false;
246cdf0e10cSrcweir         // manual positioning and size
247*f325a5bfSJian Fang Zhang         if( mrModel.mxLayout.get() )
248cdf0e10cSrcweir         {
249cdf0e10cSrcweir             LayoutConverter aLayoutConv( *this, *mrModel.mxLayout );
250cdf0e10cSrcweir             // manual size needs ChartLegendExpansion_CUSTOM
251cdf0e10cSrcweir             if( aLayoutConv.convertFromModel( aPropSet ) )
252cdf0e10cSrcweir                 eLegendExpand = cssc::ChartLegendExpansion_CUSTOM;
253*f325a5bfSJian Fang Zhang             bManualLayout = !aLayoutConv.getAutoLayout();
254cdf0e10cSrcweir         }
255cdf0e10cSrcweir 
256cdf0e10cSrcweir         // set position and expansion properties
257cdf0e10cSrcweir         aPropSet.setProperty( PROP_AnchorPosition, eLegendPos );
258cdf0e10cSrcweir         aPropSet.setProperty( PROP_Expansion, eLegendExpand );
259*f325a5bfSJian Fang Zhang 
260*f325a5bfSJian Fang Zhang         if(eLegendPos == LegendPosition_CUSTOM && 1 == bTopRight && bManualLayout==false)
261*f325a5bfSJian Fang Zhang             aPropSet.setProperty( PROP_RelativePosition , makeAny(eRelPos));
262cdf0e10cSrcweir     }
263cdf0e10cSrcweir     catch( Exception& )
264cdf0e10cSrcweir     {
265cdf0e10cSrcweir     }
266cdf0e10cSrcweir }
267cdf0e10cSrcweir 
268cdf0e10cSrcweir // ============================================================================
269cdf0e10cSrcweir 
270cdf0e10cSrcweir } // namespace chart
271cdf0e10cSrcweir } // namespace drawingml
272cdf0e10cSrcweir } // namespace oox
273