tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / chart2 / source / tools / TitleHelper.cxx
blob56d6fcbf44c1d1d8569abbc1c5ca610c628a140f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <TitleHelper.hxx>
21 #include <Title.hxx>
22 #include <ChartModel.hxx>
23 #include <Axis.hxx>
24 #include <AxisHelper.hxx>
25 #include <Diagram.hxx>
26 #include <ReferenceSizeProvider.hxx>
27 #include <com/sun/star/chart2/FormattedString.hpp>
28 #include <rtl/ustrbuf.hxx>
29 #include <comphelper/diagnose_ex.hxx>
30 #include <sal/log.hxx>
32 namespace chart
35 using namespace ::com::sun::star;
36 using namespace ::com::sun::star::chart2;
37 using ::com::sun::star::uno::Reference;
39 namespace {
41 uno::Reference< XTitled > lcl_getTitleParentFromDiagram(
42 TitleHelper::eTitleType nTitleIndex
43 , const rtl::Reference< Diagram >& xDiagram )
45 uno::Reference< XTitled > xResult;
47 if( nTitleIndex == TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION ||
48 nTitleIndex == TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION )
50 bool bDummy = false;
51 bool bIsVertical = xDiagram && xDiagram->getVertical( bDummy, bDummy );
53 if( nTitleIndex == TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION )
54 nTitleIndex = bIsVertical ? TitleHelper::X_AXIS_TITLE : TitleHelper::Y_AXIS_TITLE;
55 else
56 nTitleIndex = bIsVertical ? TitleHelper::Y_AXIS_TITLE : TitleHelper::X_AXIS_TITLE;
59 switch( nTitleIndex )
61 case TitleHelper::SUB_TITLE:
62 if( xDiagram.is())
63 xResult = xDiagram;
64 break;
65 case TitleHelper::X_AXIS_TITLE:
66 if( xDiagram.is())
67 xResult = AxisHelper::getAxis( 0, true, xDiagram );
68 break;
69 case TitleHelper::Y_AXIS_TITLE:
70 if( xDiagram.is())
71 xResult = AxisHelper::getAxis( 1, true, xDiagram );
72 break;
73 case TitleHelper::Z_AXIS_TITLE:
74 if( xDiagram.is())
75 xResult = AxisHelper::getAxis( 2, true, xDiagram );
76 break;
77 case TitleHelper::SECONDARY_X_AXIS_TITLE:
78 if( xDiagram.is())
79 xResult = AxisHelper::getAxis( 0, false, xDiagram );
80 break;
81 case TitleHelper::SECONDARY_Y_AXIS_TITLE:
82 if( xDiagram.is())
83 xResult = AxisHelper::getAxis( 1, false, xDiagram );
84 break;
86 case TitleHelper::MAIN_TITLE:
87 default:
88 OSL_FAIL( "Unsupported Title-Type requested" );
89 break;
92 return xResult;
95 uno::Reference< XTitled > lcl_getTitleParent( TitleHelper::eTitleType nTitleIndex
96 , const rtl::Reference< Diagram >& xDiagram )
98 uno::Reference< XTitled > xResult;
99 switch( nTitleIndex )
101 case TitleHelper::MAIN_TITLE:
102 SAL_WARN("chart2", "should not be reached");
103 break;
104 case TitleHelper::SUB_TITLE:
105 case TitleHelper::X_AXIS_TITLE:
106 case TitleHelper::Y_AXIS_TITLE:
107 case TitleHelper::Z_AXIS_TITLE:
108 case TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION:
109 case TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION:
110 case TitleHelper::SECONDARY_X_AXIS_TITLE:
111 case TitleHelper::SECONDARY_Y_AXIS_TITLE:
112 xResult.set( lcl_getTitleParentFromDiagram( nTitleIndex, xDiagram ));
113 break;
114 default:
115 OSL_FAIL( "Unsupported Title-Type requested" );
116 break;
119 return xResult;
122 uno::Reference< XTitled > lcl_getTitleParent( TitleHelper::eTitleType nTitleIndex
123 , const rtl::Reference<::chart::ChartModel>& xModel )
125 if(nTitleIndex == TitleHelper::MAIN_TITLE)
127 return xModel;
130 rtl::Reference< Diagram > xDiagram;
132 if( xModel.is())
133 xDiagram = xModel->getFirstChartDiagram();
135 return lcl_getTitleParent( nTitleIndex, xDiagram );
140 rtl::Reference< Title > TitleHelper::getTitle( TitleHelper::eTitleType nTitleIndex
141 , ChartModel& rModel )
143 if(nTitleIndex == TitleHelper::MAIN_TITLE)
144 return rModel.getTitleObject2();
146 rtl::Reference< Diagram > xDiagram = rModel.getFirstChartDiagram();
147 uno::Reference< XTitled > xTitled( lcl_getTitleParent( nTitleIndex, xDiagram ) );
148 if( !xTitled )
149 return nullptr;
150 uno::Reference<XTitle> xTitle = xTitled->getTitleObject();
151 auto pTitle = dynamic_cast<Title*>(xTitle.get());
152 assert(!xTitle || pTitle);
153 return pTitle;
156 rtl::Reference< Title > TitleHelper::getTitle( TitleHelper::eTitleType nTitleIndex
157 , const rtl::Reference<ChartModel>& xModel )
159 uno::Reference< XTitled > xTitled;
160 if(nTitleIndex == TitleHelper::MAIN_TITLE)
162 xTitled = xModel;
164 else
166 rtl::Reference< Diagram > xDiagram;
167 if( xModel.is())
168 xDiagram = xModel->getFirstChartDiagram();
169 xTitled = lcl_getTitleParent( nTitleIndex, xDiagram );
171 if( !xTitled )
172 return nullptr;
173 uno::Reference<XTitle> xTitle = xTitled->getTitleObject();
174 Title* pTitle = dynamic_cast<Title*>(xTitle.get());
175 assert(!xTitle || pTitle);
176 return pTitle;
179 rtl::Reference< Title > TitleHelper::createOrShowTitle(
180 TitleHelper::eTitleType eTitleType
181 , const OUString& rTitleText
182 , const rtl::Reference<ChartModel>& xModel
183 , const uno::Reference< uno::XComponentContext > & xContext )
185 rtl::Reference< Title > xTitled( TitleHelper::getTitle( eTitleType, xModel ) );
186 if( xTitled.is())
188 xTitled->setPropertyValue(u"Visible"_ustr,css::uno::Any(true));
189 return xTitled;
191 else
193 return createTitle(eTitleType, rTitleText, xModel, xContext, nullptr/*pRefSizeProvider*/);
197 rtl::Reference< Title > TitleHelper::createTitle(
198 TitleHelper::eTitleType eTitleType
199 , const OUString& rTitleText
200 , const rtl::Reference<ChartModel>& xModel
201 , const uno::Reference< uno::XComponentContext > & xContext
202 , ReferenceSizeProvider * pRefSizeProvider )
204 rtl::Reference< ::chart::Title > xTitle;
205 uno::Reference< XTitled > xTitled( lcl_getTitleParent( eTitleType, xModel ) );
207 if( !xTitled.is() )
209 rtl::Reference< Diagram > xDiagram( xModel->getFirstChartDiagram() );
210 rtl::Reference< Axis > xAxis;
211 switch( eTitleType )
213 case TitleHelper::SECONDARY_X_AXIS_TITLE:
214 xAxis = AxisHelper::createAxis( 0, false, xDiagram, xContext );
215 break;
216 case TitleHelper::SECONDARY_Y_AXIS_TITLE:
217 xAxis = AxisHelper::createAxis( 1, false, xDiagram, xContext );
218 break;
219 default:
220 break;
222 if( xAxis.is() )
224 xAxis->setPropertyValue( u"Show"_ustr, uno::Any( false ) );
225 xTitled = lcl_getTitleParent( eTitleType, xModel );
229 if(xTitled.is())
231 rtl::Reference< Diagram > xDiagram( xModel->getFirstChartDiagram() );
233 xTitle = new ::chart::Title();
235 // default char height (main: 13.0 == default)
236 float fDefaultCharHeightSub = 11.0;
237 float fDefaultCharHeightAxis = 9.0;
238 switch( eTitleType )
240 case TitleHelper::SUB_TITLE:
241 TitleHelper::setCompleteString(
242 rTitleText, xTitle, xContext, & fDefaultCharHeightSub );
243 break;
244 case TitleHelper::X_AXIS_TITLE:
245 case TitleHelper::Y_AXIS_TITLE:
246 case TitleHelper::Z_AXIS_TITLE:
247 case TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION:
248 case TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION:
249 case TitleHelper::SECONDARY_X_AXIS_TITLE:
250 case TitleHelper::SECONDARY_Y_AXIS_TITLE:
251 TitleHelper::setCompleteString(
252 rTitleText, xTitle, xContext, & fDefaultCharHeightAxis );
253 break;
254 default:
255 TitleHelper::setCompleteString( rTitleText, xTitle, xContext );
256 break;
259 // set/clear autoscale
260 if( pRefSizeProvider )
261 pRefSizeProvider->setValuesAtTitle( xTitle );
263 xTitled->setTitleObject( xTitle );
265 //default rotation 90 degree for y axis title in normal coordinatesystems or for x axis title for swapped coordinatesystems
266 if( eTitleType == TitleHelper::X_AXIS_TITLE ||
267 eTitleType == TitleHelper::Y_AXIS_TITLE ||
268 eTitleType == TitleHelper::SECONDARY_X_AXIS_TITLE ||
269 eTitleType == TitleHelper::SECONDARY_Y_AXIS_TITLE )
274 bool bDummy = false;
275 bool bIsVertical = xDiagram->getVertical( bDummy, bDummy );
277 if( (!bIsVertical && eTitleType == TitleHelper::Y_AXIS_TITLE)
278 || (bIsVertical && eTitleType == TitleHelper::X_AXIS_TITLE)
279 || (!bIsVertical && eTitleType == TitleHelper::SECONDARY_Y_AXIS_TITLE)
280 || (bIsVertical && eTitleType == TitleHelper::SECONDARY_X_AXIS_TITLE) )
282 xTitle->setPropertyValue( u"TextRotation"_ustr, uno::Any( 90.0 ));
285 catch( const uno::Exception & )
287 DBG_UNHANDLED_EXCEPTION("chart2");
291 return xTitle;
295 OUString TitleHelper::getCompleteString( const rtl::Reference< Title >& xTitle )
297 if(!xTitle.is())
298 return OUString();
299 OUStringBuffer aRet;
300 const uno::Sequence< uno::Reference< XFormattedString > > aStringList = xTitle->getText();
301 for( uno::Reference< XFormattedString > const & formattedStr : aStringList )
302 aRet.append( formattedStr->getString() );
303 return aRet.makeStringAndClear();
306 OUString TitleHelper::getUnstackedStr(const OUString& rNewText)
308 //#i99841# remove linebreaks that were added for vertical stacking
309 OUStringBuffer aUnstackedStr;
310 OUStringBuffer aSource(rNewText);
312 bool bBreakIgnored = false;
313 sal_Int32 nLen = rNewText.getLength();
314 for (sal_Int32 nPos = 0; nPos < nLen; ++nPos)
316 sal_Unicode aChar = aSource[nPos];
317 if (aChar != '\n')
319 aUnstackedStr.append(aChar);
320 bBreakIgnored = false;
322 else if (aChar == '\n' && bBreakIgnored)
323 aUnstackedStr.append(aChar);
324 else
325 bBreakIgnored = true;
327 return aUnstackedStr.makeStringAndClear();
330 void TitleHelper::setFormattedString( const rtl::Reference< Title >& xTitle,
331 const css::uno::Sequence< css::uno::Reference< css::chart2::XFormattedString > >& aNewFormattedTitle )
333 if (!xTitle.is() || !aNewFormattedTitle.hasElements())
334 return;
336 bool bStacked = false;
337 xTitle->getPropertyValue(u"StackCharacters"_ustr) >>= bStacked;
339 if (bStacked)
341 for (uno::Reference< chart2::XFormattedString >const& formattedStr : aNewFormattedTitle)
343 formattedStr->setString(TitleHelper::getUnstackedStr(formattedStr->getString()));
347 xTitle->setText(aNewFormattedTitle);
350 void TitleHelper::setCompleteString( const OUString& rNewText
351 , const rtl::Reference< Title >& xTitle
352 , const uno::Reference< uno::XComponentContext > & xContext
353 , const float * pDefaultCharHeight /* = 0 */
354 , bool bDialogTitle /*= false*/ )
356 if (!xTitle.is())
357 return;
359 bool bStacked = false;
360 if( xTitle.is() )
361 xTitle->getPropertyValue( u"StackCharacters"_ustr ) >>= bStacked;
363 OUString aNewText = rNewText;
364 if( bStacked )
366 aNewText = getUnstackedStr(rNewText);
369 uno::Sequence< uno::Reference< XFormattedString > > aNewStringList;
370 uno::Sequence< uno::Reference< XFormattedString > > aOldStringList = xTitle->getText();
371 if( aOldStringList.hasElements())
373 const OUString aFullString = getCompleteString(xTitle);
374 if (bDialogTitle && aNewText.equals(getUnstackedStr(aFullString)))
376 // If the new title setted from a dialog window to a new string
377 // the first old text portion will be maintained if it's a new string,
378 // otherwise we use the original one.
379 aNewStringList = std::move(aOldStringList);
381 else
383 // If the new title setted from a dialog to a new string the first
384 // old text portion will be maintained if there was any. Also in case of ODF
385 // import which still not support non-uniform formatted titles
386 aNewStringList = { aOldStringList[0] };
387 aNewStringList[0]->setString(aNewText);
390 else
392 uno::Reference< chart2::XFormattedString2 > xFormattedString =
393 chart2::FormattedString::create( xContext );
395 xFormattedString->setString( aNewText );
396 aNewStringList = { xFormattedString };
397 if( pDefaultCharHeight != nullptr )
401 uno::Any aFontSize( *pDefaultCharHeight );
402 xFormattedString->setPropertyValue( u"CharHeight"_ustr, aFontSize );
403 xFormattedString->setPropertyValue( u"CharHeightAsian"_ustr, aFontSize );
404 xFormattedString->setPropertyValue( u"CharHeightComplex"_ustr, aFontSize );
406 catch( const uno::Exception & )
408 DBG_UNHANDLED_EXCEPTION("chart2");
412 xTitle->setText( aNewStringList );
415 void TitleHelper::removeTitle( TitleHelper::eTitleType nTitleIndex
416 , const rtl::Reference<ChartModel>& xModel )
418 uno::Reference< XTitled > xTitled( lcl_getTitleParent( nTitleIndex, xModel ) );
419 if( xTitled.is())
421 xTitled->setTitleObject(nullptr);
425 bool TitleHelper::getTitleType( eTitleType& rType
426 , const rtl::Reference< Title >& xTitle
427 , const rtl::Reference<ChartModel>& xModel )
429 if( !xTitle.is() || !xModel.is() )
430 return false;
432 rtl::Reference< Title > xCurrentTitle;
433 for( sal_Int32 nTitleType = TITLE_BEGIN; nTitleType < NORMAL_TITLE_END; nTitleType++ )
435 xCurrentTitle = TitleHelper::getTitle( static_cast<eTitleType>(nTitleType), xModel );
436 if( xCurrentTitle == xTitle )
438 rType = static_cast<eTitleType>(nTitleType);
439 return true;
443 return false;
446 void TitleHelper::hideTitle( TitleHelper::eTitleType nTitleIndex
447 , const rtl::Reference<ChartModel>& xModel)
449 uno::Reference< chart2::XTitle > xTitled( TitleHelper::getTitle( nTitleIndex, xModel ) );
450 if( xTitled.is())
452 css::uno::Reference<css::beans::XPropertySet> xProps(xTitled, css::uno::UNO_QUERY_THROW);
453 xProps->setPropertyValue(u"Visible"_ustr,css::uno::Any(false));
457 } //namespace chart
459 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */