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