LibreOffice Module oox (master) 1
titleconverter.cxx
Go to the documentation of this file.
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
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 <com/sun/star/chart2/XChartTypeContainer.hpp>
30#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
31#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
32
34#include <osl/diagnose.h>
39#include <oox/token/properties.hxx>
40#include <oox/token/tokens.hxx>
41#include <com/sun/star/chart2/RelativePosition.hpp>
42#include <com/sun/star/drawing/Alignment.hpp>
43
45namespace oox::drawingml::chart {
46
47using namespace ::com::sun::star::awt;
48using namespace ::com::sun::star::chart2;
49using namespace ::com::sun::star::chart2::data;
50using namespace ::com::sun::star::drawing;
51using namespace ::com::sun::star::uno;
52
53
55 ConverterBase< TextModel >( rParent, rModel )
56{
57}
58
60{
61}
62
64{
66 if( mrModel.mxDataSeq.is() )
67 {
68 DataSequenceConverter aDataSeqConv( *this, *mrModel.mxDataSeq );
69 xDataSeq = aDataSeqConv.createDataSequence( rRole );
70 }
71 return xDataSeq;
72}
73
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 ::std::vector< Reference< XFormattedString > > aStringVec;
79 if( mrModel.mxTextBody.is() )
80 {
81 // rich-formatted text objects can be created, but currently Chart2 is not able to show them
82 const TextParagraphVector& rTextParas = mrModel.mxTextBody->getParagraphs();
83 for( TextParagraphVector::const_iterator aPIt = rTextParas.begin(), aPEnd = rTextParas.end(); aPIt != aPEnd; ++aPIt )
84 {
85 const TextParagraph& rTextPara = **aPIt;
87 for( TextRunVector::const_iterator aRIt = rTextPara.getRuns().begin(), aREnd = rTextPara.getRuns().end(); aRIt != aREnd; ++aRIt )
88 {
89 const TextRun& rTextRun = **aRIt;
90 bool bAddNewLine = ((aRIt + 1 == aREnd) && (aPIt + 1 != aPEnd)) || rTextRun.isLineBreak();
91 Reference< XFormattedString > xFmtStr = appendFormattedString( aStringVec, rTextRun.getText(), bAddNewLine );
92 PropertySet aPropSet( xFmtStr );
93 TextCharacterProperties aRunProps( rParaProps );
94 aRunProps.assignUsed( rTextRun.getTextCharacterProperties() );
95 getFormatter().convertTextFormatting( aPropSet, aRunProps, eObjType );
96 }
97 }
98 }
99 else
100 {
101 OUString aString;
102 // try to create string from linked data
103 if( mrModel.mxDataSeq.is() && !mrModel.mxDataSeq->maData.empty() )
104 mrModel.mxDataSeq->maData.begin()->second >>= aString;
105 // no linked string -> fall back to default string
106 if( aString.isEmpty() )
107 aString = rDefaultText;
108
109 // create formatted string object
110 if( !aString.isEmpty() )
111 {
112 Reference< XFormattedString > xFmtStr = appendFormattedString( aStringVec, aString, false );
113 PropertySet aPropSet( xFmtStr );
114 getFormatter().convertTextFormatting( aPropSet, rxTextProp, eObjType );
115 }
116 }
117
118 return comphelper::containerToSequence( aStringVec );
119}
120
122 ::std::vector< Reference< XFormattedString > >& orStringVec, const OUString& rString, bool bAddNewLine ) const
123{
125 try
126 {
127 xFmtStr = FormattedString::create( ConverterRoot::getComponentContext() );
128 xFmtStr->setString( bAddNewLine ? (rString + "\n") : rString );
129 orStringVec.emplace_back(xFmtStr );
130 }
131 catch( Exception& )
132 {
133 }
134 return xFmtStr;
135}
136
138 ConverterBase< TitleModel >( rParent, rModel )
139{
140}
141
143{
144}
145
146void TitleConverter::convertFromModel( const Reference< XTitled >& rxTitled, const OUString& rAutoTitle, ObjectType eObjType, sal_Int32 nMainIdx, sal_Int32 nSubIdx )
147{
148 if( !rxTitled.is() )
149 return;
150
151 // create the formatted strings
153 TextConverter aTextConv( *this, rText );
154 Sequence< Reference< XFormattedString > > aStringSeq = aTextConv.createStringSequence( rAutoTitle, mrModel.mxTextProp, eObjType );
155 if( !aStringSeq.hasElements() )
156 return;
157
158 try
159 {
160 // create the title object and set the string data
161 Reference< XTitle > xTitle( createInstance( "com.sun.star.chart2.Title" ), UNO_QUERY_THROW );
162 xTitle->setText( aStringSeq );
163 rxTitled->setTitleObject( xTitle );
164
165 // frame formatting (text formatting already done in TextConverter::createStringSequence())
166 PropertySet aPropSet( xTitle );
168
169 // frame rotation
170 OSL_ENSURE( !mrModel.mxTextProp || !rText.mxTextBody, "TitleConverter::convertFromModel - multiple text properties" );
173
174 // register the title and layout data for conversion of position
175 registerTitleLayout( xTitle, mrModel.mxLayout, eObjType, nMainIdx, nSubIdx );
176 }
177 catch( Exception& )
178 {
179 }
180}
181
183 ConverterBase< LegendModel >( rParent, rModel )
184{
185}
186
188{
189}
190
192{
193 if( !rxDiagram.is() )
194 return;
195
196 try
197 {
198 namespace cssc = ::com::sun::star::chart;
199 namespace cssc2 = ::com::sun::star::chart2;
200
201 // create the legend
202 Reference< XLegend > xLegend( createInstance( "com.sun.star.chart2.Legend" ), UNO_QUERY_THROW );
203 rxDiagram->setLegend( xLegend );
204 PropertySet aPropSet( xLegend );
205 aPropSet.setProperty( PROP_Show, true );
206
207 // legend formatting
209
210 // predefined legend position and expansion
211 cssc2::LegendPosition eLegendPos = cssc2::LegendPosition_LINE_END;
212 cssc::ChartLegendExpansion eLegendExpand = cssc::ChartLegendExpansion_CUSTOM;
213 RelativePosition eRelPos;
214 bool bTopRight=false;
215 switch( mrModel.mnPosition )
216 {
217 case XML_l:
218 eLegendPos = cssc2::LegendPosition_LINE_START;
219 eLegendExpand = cssc::ChartLegendExpansion_HIGH;
220 break;
221 case XML_r:
222 eLegendPos = cssc2::LegendPosition_LINE_END;
223 eLegendExpand = cssc::ChartLegendExpansion_HIGH;
224 break;
225 case XML_tr: // top-right not supported
226 eRelPos.Primary = 1;
227 eRelPos.Secondary =0;
228 eRelPos.Anchor = Alignment_TOP_RIGHT;
229 bTopRight=true;
230 break;
231 case XML_t:
232 eLegendPos = cssc2::LegendPosition_PAGE_START;
233 eLegendExpand = cssc::ChartLegendExpansion_WIDE;
234 break;
235 case XML_b:
236 eLegendPos = cssc2::LegendPosition_PAGE_END;
237 eLegendExpand = cssc::ChartLegendExpansion_WIDE;
238 break;
239 }
240 bool bManualLayout=false;
241 // manual positioning and size
242 if( mrModel.mxLayout )
243 {
244 LayoutConverter aLayoutConv( *this, *mrModel.mxLayout );
245 // manual size needs ChartLegendExpansion_CUSTOM
246 if( aLayoutConv.convertFromModel( aPropSet ) )
247 {
248 eLegendExpand = cssc::ChartLegendExpansion_CUSTOM;
249 }
250 bManualLayout = !aLayoutConv.getAutoLayout();
251 }
252
253 // set position and expansion properties
254 aPropSet.setProperty( PROP_AnchorPosition, eLegendPos );
255 aPropSet.setProperty( PROP_Expansion, eLegendExpand );
256
257 if (bTopRight && !bManualLayout)
258 aPropSet.setProperty( PROP_RelativePosition , Any(eRelPos));
259
260 aPropSet.setProperty(PROP_Overlay, mrModel.mbOverlay);
261
262 if (mrModel.maLegendEntries.size() > 0)
263 legendEntriesFormatting(rxDiagram);
264 }
265 catch( Exception& )
266 {
267 }
268}
269
271{
272 Reference<XCoordinateSystemContainer> xCooSysContainer(rxDiagram, UNO_QUERY_THROW);
273 const Sequence<Reference<XCoordinateSystem>> xCooSysSequence(xCooSysContainer->getCoordinateSystems());
274 if (!xCooSysSequence.hasElements())
275 return;
276
277 sal_Int32 nIndex = 0;
278 for (const auto& rCooSys : xCooSysSequence)
279 {
280 PropertySet aCooSysProp(rCooSys);
281 bool bSwapXAndY = aCooSysProp.getBoolProperty(PROP_SwapXAndYAxis);
282
283 Reference<XChartTypeContainer> xChartTypeContainer(rCooSys, UNO_QUERY_THROW);
284 const Sequence<Reference<XChartType>> xChartTypeSequence(xChartTypeContainer->getChartTypes());
285 if (!xChartTypeSequence.hasElements())
286 continue;
287
288 for (const auto& rCT : xChartTypeSequence)
289 {
290 Reference<XDataSeriesContainer> xDSCont(rCT, UNO_QUERY);
291 if (!xDSCont.is())
292 continue;
293
294 bool bIsPie
295 = rCT->getChartType().equalsIgnoreAsciiCase("com.sun.star.chart2.PieChartType");
296 if (bIsPie)
297 {
298 PropertySet xChartTypeProp(rCT);
299 bIsPie = !xChartTypeProp.getBoolProperty(PROP_UseRings);
300 }
301 const Sequence<Reference<XDataSeries>> aDataSeriesSeq = xDSCont->getDataSeries();
302 if (bSwapXAndY)
303 nIndex += aDataSeriesSeq.getLength() - 1;
304 for (const auto& rDataSeries : aDataSeriesSeq)
305 {
306 PropertySet aSeriesProp(rDataSeries);
307 bool bVaryColorsByPoint = aSeriesProp.getBoolProperty(PROP_VaryColorsByPoint);
308
309 if (bVaryColorsByPoint || bIsPie)
310 {
311 Reference<XDataSource> xDSrc(rDataSeries, UNO_QUERY);
312 if (!xDSrc.is())
313 continue;
314
315 const Sequence<Reference<XLabeledDataSequence> > aDataSeqs = xDSrc->getDataSequences();
316 std::vector<sal_Int32> deletedLegendEntries;
317 sal_Int32 j = 0;
318 for (const auto& rDataSeq : aDataSeqs)
319 {
320 Reference<XDataSequence> xValues = rDataSeq->getValues();
321 if (!xValues.is())
322 continue;
323
324 sal_Int32 nDataSeqSize = xValues->getData().getLength();
325 for (sal_Int32 i = 0; i < nDataSeqSize; ++i)
326 {
327 for (const auto& rLegendEntry : mrModel.maLegendEntries)
328 {
329 if (nIndex == rLegendEntry->mnLegendEntryIdx && rLegendEntry->mbLabelDeleted)
330 {
331 deletedLegendEntries.push_back(j + i);
332 break;
333 }
334 }
335 nIndex++;
336 }
337 j += nDataSeqSize;
338 }
339 if (deletedLegendEntries.size() > 0)
340 aSeriesProp.setProperty(PROP_DeletedLegendEntries, comphelper::containerToSequence(deletedLegendEntries));
341 }
342 else
343 {
344 for (const auto& rLegendEntry : mrModel.maLegendEntries)
345 {
346 if (nIndex == rLegendEntry->mnLegendEntryIdx)
347 {
348 aSeriesProp.setProperty(PROP_ShowLegendEntry, !rLegendEntry->mbLabelDeleted);
349 break;
350 }
351 }
352 bSwapXAndY ? nIndex-- : nIndex++;
353 }
354 }
355 if (bSwapXAndY)
356 nIndex += aDataSeriesSeq.getLength() + 1;
357 }
358 }
359}
360
361} // namespace oox::drawingml::chart
362
363/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
A wrapper for a UNO property set.
Definition: propertyset.hxx:58
bool getBoolProperty(sal_Int32 nPropId) const
Gets the specified boolean property from the property set.
Definition: propertyset.hxx:99
bool setProperty(sal_Int32 nPropId, const Type &rValue)
Puts the passed value into the property set.
TextCharacterProperties & getTextCharacterProperties()
TextParagraphProperties & getProperties()
TextCharacterProperties & getTextCharacterProperties()
Definition: textrun.hxx:40
OUString & getText()
Definition: textrun.hxx:37
bool isLineBreak() const
Definition: textrun.hxx:44
Base class of all converter classes.
void registerTitleLayout(const css::uno::Reference< css::chart2::XTitle > &rxTitle, const ModelRef< LayoutModel > &rxLayout, ObjectType eObjType, sal_Int32 nMainIdx, sal_Int32 nSubIdx)
Registers a title object and its layout data, needed for conversion of the title position using the o...
ObjectFormatter & getFormatter() const
Returns the object formatter.
css::uno::Reference< css::uno::XInterface > createInstance(const OUString &rServiceName) const
Creates an instance for the passed service name, using the process service factory.
css::uno::Reference< css::uno::XComponentContext > const & getComponentContext() const
css::uno::Reference< css::chart2::data::XDataSequence > createDataSequence(const OUString &rRole)
Creates a data sequence object from the contained formula link.
A layout converter calculates positions and sizes for various chart objects.
bool convertFromModel(PropertySet &rPropSet)
Tries to set the position and size from the contained OOXML layout model.
void legendEntriesFormatting(const css::uno::Reference< css::chart2::XDiagram > &rxDiagram)
void convertFromModel(const css::uno::Reference< css::chart2::XDiagram > &rxDiagram)
Creates a legend object and attaches it at the passed diagram.
LegendConverter(const ConverterRoot &rParent, LegendModel &rModel)
void convertFrameFormatting(PropertySet &rPropSet, const ModelRef< Shape > &rxShapeProp, ObjectType eObjType, sal_Int32 nSeriesIdx=-1)
Sets frame formatting properties to the passed property set.
void convertTextFormatting(PropertySet &rPropSet, const ModelRef< TextBody > &rxTextProp, ObjectType eObjType)
Sets text formatting properties to the passed property set.
void convertFormatting(PropertySet &rPropSet, const ModelRef< Shape > &rxShapeProp, const ModelRef< TextBody > &rxTextProp, ObjectType eObjType)
Sets frame/text formatting properties to the passed property set.
static void convertTextRotation(PropertySet &rPropSet, const ModelRef< TextBody > &rxTextProp, bool bSupportsStacked, sal_Int32 nDefaultRotation=0)
Sets text rotation properties to the passed property set.
css::uno::Sequence< css::uno::Reference< css::chart2::XFormattedString > > createStringSequence(const OUString &rDefaultText, const ModelRef< TextBody > &rxTextProp, ObjectType eObjType)
Creates a sequence of formatted string objects.
TextConverter(const ConverterRoot &rParent, TextModel &rModel)
css::uno::Reference< css::chart2::XFormattedString > appendFormattedString(::std::vector< css::uno::Reference< css::chart2::XFormattedString > > &orStringVec, const OUString &rString, bool bAddNewLine) const
css::uno::Reference< css::chart2::data::XDataSequence > createDataSequence(const OUString &rRole)
Creates a data sequence object from the contained text data.
void convertFromModel(const css::uno::Reference< css::chart2::XTitled > &rxTitled, const OUString &rAutoTitle, ObjectType eObjType, sal_Int32 nMainIdx=-1, sal_Int32 nSubIdx=-1)
Creates a title text object and attaches it at the passed interface.
TitleConverter(const ConverterRoot &rParent, TitleModel &rModel)
sal_Int32 nIndex
@ Exception
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
ObjectType
Enumerates different object types for specific automatic formatting behaviour.
@ OBJECTTYPE_LEGEND
Chart title.
void assignUsed(const TextCharacterProperties &rSourceProps)
Overwrites all members that are explicitly set in rSourceProps.
ShapeRef mxShapeProp
Legend entries formatting.
Definition: titlemodel.hxx:74
LayoutRef mxLayout
Legend text formatting.
Definition: titlemodel.hxx:76
TextBodyRef mxTextProp
Legend shape formatting.
Definition: titlemodel.hxx:75
bool mbOverlay
Legend position.
Definition: titlemodel.hxx:78
sal_Int32 mnPosition
Layout/position of the legend.
Definition: titlemodel.hxx:77
TextBodyRef mxTextBody
The string data or formula link of this text.
Definition: titlemodel.hxx:34
LayoutRef mxLayout
Title text formatting.
Definition: titlemodel.hxx:49
TextBodyRef mxTextProp
Title shape formatting.
Definition: titlemodel.hxx:48
sal_Int32 mnDefaultRotation
True = title may overlay other objects.
Definition: titlemodel.hxx:52
TextRef mxText
Layout/position of the frame.
Definition: titlemodel.hxx:50