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