1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chart2.hxx"
26 #include "TitleHelper.hxx"
27 #include "ChartModelHelper.hxx"
28 #include "macros.hxx"
29 #include "AxisHelper.hxx"
30 #include "DiagramHelper.hxx"
31 #include <com/sun/star/chart2/XChartDocument.hpp>
32 #include <rtl/ustrbuf.hxx>
33 
34 //.............................................................................
35 namespace chart
36 {
37 //.............................................................................
38 
39 using namespace ::com::sun::star;
40 using namespace ::com::sun::star::chart2;
41 using ::com::sun::star::uno::Reference;
42 
lcl_getTitleParentFromDiagram(TitleHelper::eTitleType nTitleIndex,const uno::Reference<XDiagram> & xDiagram)43 uno::Reference< XTitled > lcl_getTitleParentFromDiagram(
44       TitleHelper::eTitleType nTitleIndex
45     , const uno::Reference< XDiagram >& xDiagram )
46 {
47     uno::Reference< XTitled > xResult;
48 
49     if( nTitleIndex == TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION ||
50         nTitleIndex == TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION )
51     {
52         bool bDummy = false;
53         bool bIsVertical = DiagramHelper::getVertical( xDiagram, bDummy, bDummy );
54 
55         if( nTitleIndex == TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION )
56             nTitleIndex = bIsVertical ? TitleHelper::X_AXIS_TITLE : TitleHelper::Y_AXIS_TITLE;
57         else
58             nTitleIndex = bIsVertical ? TitleHelper::Y_AXIS_TITLE : TitleHelper::X_AXIS_TITLE;
59     }
60 
61 
62     switch( nTitleIndex )
63     {
64         case TitleHelper::SUB_TITLE:
65             if( xDiagram.is())
66                 xResult.set( xDiagram, uno::UNO_QUERY );
67             break;
68         case TitleHelper::X_AXIS_TITLE:
69             if( xDiagram.is())
70                 xResult.set( AxisHelper::getAxis( 0, true, xDiagram ), uno::UNO_QUERY );
71             break;
72         case TitleHelper::Y_AXIS_TITLE:
73             if( xDiagram.is())
74                 xResult.set( AxisHelper::getAxis( 1, true, xDiagram ), uno::UNO_QUERY );
75             break;
76         case TitleHelper::Z_AXIS_TITLE:
77             if( xDiagram.is())
78                 xResult.set( AxisHelper::getAxis( 2, true, xDiagram ), uno::UNO_QUERY );
79             break;
80         case TitleHelper::SECONDARY_X_AXIS_TITLE:
81             if( xDiagram.is())
82                 xResult.set( AxisHelper::getAxis( 0, false, xDiagram ), uno::UNO_QUERY );
83             break;
84         case TitleHelper::SECONDARY_Y_AXIS_TITLE:
85             if( xDiagram.is())
86                 xResult.set( AxisHelper::getAxis( 1, false, xDiagram ), uno::UNO_QUERY );
87             break;
88 
89         case TitleHelper::MAIN_TITLE:
90         default:
91             OSL_ENSURE( false, "Unsupported Title-Type requested" );
92             break;
93     }
94 
95     return xResult;
96 }
97 
lcl_getTitleParent(TitleHelper::eTitleType nTitleIndex,const uno::Reference<frame::XModel> & xModel)98 uno::Reference< XTitled > lcl_getTitleParent( TitleHelper::eTitleType nTitleIndex
99                                               , const uno::Reference< frame::XModel >& xModel )
100 {
101     uno::Reference< XTitled > xResult;
102     uno::Reference< XChartDocument > xChartDoc( xModel, uno::UNO_QUERY );
103     uno::Reference< XDiagram > xDiagram;
104     if( xChartDoc.is())
105         xDiagram.set( xChartDoc->getFirstDiagram());
106 
107     switch( nTitleIndex )
108     {
109         case TitleHelper::MAIN_TITLE:
110             xResult.set( xModel, uno::UNO_QUERY );
111             break;
112         case TitleHelper::SUB_TITLE:
113         case TitleHelper::X_AXIS_TITLE:
114         case TitleHelper::Y_AXIS_TITLE:
115         case TitleHelper::Z_AXIS_TITLE:
116         case TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION:
117         case TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION:
118         case TitleHelper::SECONDARY_X_AXIS_TITLE:
119         case TitleHelper::SECONDARY_Y_AXIS_TITLE:
120             xResult.set( lcl_getTitleParentFromDiagram( nTitleIndex, xDiagram ));
121             break;
122         default:
123             OSL_ENSURE( false, "Unsupported Title-Type requested" );
124             break;
125     }
126 
127     return xResult;
128 }
129 
getTitle(TitleHelper::eTitleType nTitleIndex,const uno::Reference<frame::XModel> & xModel)130 uno::Reference< XTitle > TitleHelper::getTitle( TitleHelper::eTitleType nTitleIndex
131                             , const uno::Reference< frame::XModel >& xModel )
132 {
133     uno::Reference< XTitled > xTitled( lcl_getTitleParent( nTitleIndex, xModel ) );
134     if( xTitled.is())
135         return xTitled->getTitleObject();
136     return NULL;
137 }
138 
createTitle(TitleHelper::eTitleType eTitleType,const rtl::OUString & rTitleText,const uno::Reference<frame::XModel> & xModel,const uno::Reference<uno::XComponentContext> & xContext,ReferenceSizeProvider * pRefSizeProvider)139 uno::Reference< XTitle > TitleHelper::createTitle(
140       TitleHelper::eTitleType eTitleType
141     , const rtl::OUString& rTitleText
142     , const uno::Reference< frame::XModel >& xModel
143     , const uno::Reference< uno::XComponentContext > & xContext
144     , ReferenceSizeProvider * pRefSizeProvider )
145 {
146     uno::Reference< XTitle > xTitle;
147     uno::Reference< XTitled > xTitled( lcl_getTitleParent( eTitleType, xModel ) );
148 
149     if( !xTitled.is() )
150     {
151         uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xModel ) );
152         uno::Reference< chart2::XAxis > xAxis;
153         switch( eTitleType )
154         {
155             case TitleHelper::SECONDARY_X_AXIS_TITLE:
156                 xAxis = AxisHelper::createAxis( 0, false, xDiagram, xContext );
157                 break;
158             case TitleHelper::SECONDARY_Y_AXIS_TITLE:
159                 xAxis = AxisHelper::createAxis( 1, false, xDiagram, xContext );
160                break;
161             default:
162                break;
163         }
164         uno::Reference< beans::XPropertySet > xProps( xAxis, uno::UNO_QUERY );
165         if( xProps.is() )
166         {
167             xProps->setPropertyValue( C2U( "Show" ), uno::makeAny( sal_False ) );
168             xTitled = lcl_getTitleParent( eTitleType, xModel );
169         }
170     }
171 
172     if(xTitled.is())
173     {
174         uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xModel ) );
175 
176         xTitle.set( xContext->getServiceManager()->createInstanceWithContext(
177                         C2U( "com.sun.star.chart2.Title" ),
178                         xContext ), uno::UNO_QUERY );
179 
180         if(xTitle.is())
181         {
182             // default char height (main: 13.0 == default)
183             float fDefaultCharHeightSub = 11.0;
184             float fDefaultCharHeightAxis = 9.0;
185             switch( eTitleType )
186             {
187                 case TitleHelper::SUB_TITLE:
188                     TitleHelper::setCompleteString(
189                         rTitleText, xTitle, xContext, & fDefaultCharHeightSub );
190                     break;
191                 case TitleHelper::X_AXIS_TITLE:
192                 case TitleHelper::Y_AXIS_TITLE:
193                 case TitleHelper::Z_AXIS_TITLE:
194                 case TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION:
195                 case TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION:
196                 case TitleHelper::SECONDARY_X_AXIS_TITLE:
197                 case TitleHelper::SECONDARY_Y_AXIS_TITLE:
198                     TitleHelper::setCompleteString(
199                         rTitleText, xTitle, xContext, & fDefaultCharHeightAxis );
200                     break;
201                 default:
202                     TitleHelper::setCompleteString( rTitleText, xTitle, xContext );
203                     break;
204             }
205 
206             // set/clear autoscale
207             if( pRefSizeProvider )
208                 pRefSizeProvider->setValuesAtTitle( xTitle );
209 
210             xTitled->setTitleObject( xTitle );
211 
212             //default rotation 90 degree for y axis title in normal coordinatesystems or for x axis title for swapped coordinatesystems
213             if( eTitleType == TitleHelper::X_AXIS_TITLE ||
214                 eTitleType == TitleHelper::Y_AXIS_TITLE ||
215                 eTitleType == TitleHelper::SECONDARY_X_AXIS_TITLE ||
216                 eTitleType == TitleHelper::SECONDARY_Y_AXIS_TITLE )
217 
218             {
219                 try
220                 {
221                     bool bDummy = false;
222                     bool bIsVertical = DiagramHelper::getVertical( xDiagram, bDummy, bDummy );
223 
224                     Reference< beans::XPropertySet > xTitleProps( xTitle, uno::UNO_QUERY );
225                     if( xTitleProps.is() )
226                     {
227                         double fNewAngleDegree = 90.0;
228                         if( (!bIsVertical && eTitleType == TitleHelper::Y_AXIS_TITLE)
229                             || (bIsVertical && eTitleType == TitleHelper::X_AXIS_TITLE)
230                             || (!bIsVertical && eTitleType == TitleHelper::SECONDARY_Y_AXIS_TITLE)
231                             || (bIsVertical && eTitleType == TitleHelper::SECONDARY_X_AXIS_TITLE) )
232                             xTitleProps->setPropertyValue( C2U( "TextRotation" ), uno::makeAny( fNewAngleDegree ));
233                     }
234                 }
235                 catch( uno::Exception & ex )
236                 {
237                     ASSERT_EXCEPTION( ex );
238                 }
239             }
240         }
241     }
242     return xTitle;
243 
244 }
245 
getCompleteString(const uno::Reference<XTitle> & xTitle)246 rtl::OUString TitleHelper::getCompleteString( const uno::Reference< XTitle >& xTitle )
247 {
248     rtl::OUString aRet;
249     if(!xTitle.is())
250         return aRet;
251     uno::Sequence< uno::Reference< XFormattedString > > aStringList = xTitle->getText();
252     for( sal_Int32 nN=0; nN<aStringList.getLength();nN++ )
253         aRet += aStringList[nN]->getString();
254     return aRet;
255 }
256 
setCompleteString(const rtl::OUString & rNewText,const uno::Reference<XTitle> & xTitle,const uno::Reference<uno::XComponentContext> & xContext,float * pDefaultCharHeight)257 void TitleHelper::setCompleteString( const rtl::OUString& rNewText
258                     , const uno::Reference< XTitle >& xTitle
259                     , const uno::Reference< uno::XComponentContext > & xContext
260                     , float * pDefaultCharHeight /* = 0 */ )
261 {
262     //the format of the first old text portion will be maintained if there is any
263     if(!xTitle.is())
264         return;
265 
266     rtl::OUString aNewText = rNewText;
267 
268     bool bStacked = false;
269     uno::Reference< beans::XPropertySet > xTitleProperties( xTitle, uno::UNO_QUERY );
270     if( xTitleProperties.is() )
271         xTitleProperties->getPropertyValue( C2U( "StackCharacters" ) ) >>= bStacked;
272 
273     if( bStacked )
274     {
275         //#i99841# remove linebreaks that were added for vertical stacking
276         rtl::OUStringBuffer aUnstackedStr;
277         rtl::OUStringBuffer aSource(rNewText);
278 
279         bool bBreakIgnored = false;
280         sal_Int32 nLen = rNewText.getLength();
281         for( sal_Int32 nPos = 0; nPos < nLen; ++nPos )
282         {
283             sal_Unicode aChar = aSource.charAt( nPos );
284             if( aChar != '\n' )
285             {
286                 aUnstackedStr.append( aChar );
287                 bBreakIgnored = false;
288             }
289             else if( aChar == '\n' && bBreakIgnored )
290                 aUnstackedStr.append( aChar );
291             else
292                 bBreakIgnored = true;
293         }
294         aNewText = aUnstackedStr.makeStringAndClear();
295     }
296 
297     uno::Sequence< uno::Reference< XFormattedString > > aNewStringList(1);
298 
299     uno::Sequence< uno::Reference< XFormattedString > >  aOldStringList = xTitle->getText();
300     if( aOldStringList.getLength() )
301     {
302         aNewStringList[0].set( aOldStringList[0] );
303         aNewStringList[0]->setString( aNewText );
304     }
305     else
306     {
307         uno::Reference< uno::XInterface > xI(
308             xContext->getServiceManager()->createInstanceWithContext(
309             C2U( "com.sun.star.chart2.FormattedString" ), xContext ) );
310         uno::Reference< XFormattedString > xFormattedString( xI, uno::UNO_QUERY );
311 
312         if(xFormattedString.is())
313         {
314             xFormattedString->setString( aNewText );
315             aNewStringList[0].set( xFormattedString );
316             if( pDefaultCharHeight != 0 )
317             {
318                 try
319                 {
320                     uno::Reference< beans::XPropertySet > xProp( xFormattedString, uno::UNO_QUERY_THROW );
321 
322                     uno::Any aFontSize( uno::makeAny( *pDefaultCharHeight ));
323                     xProp->setPropertyValue( C2U("CharHeight"), aFontSize );
324                     xProp->setPropertyValue( C2U("CharHeightAsian"), aFontSize );
325                     xProp->setPropertyValue( C2U("CharHeightComplex"), aFontSize );
326                 }
327                 catch( uno::Exception & ex )
328                 {
329                     ASSERT_EXCEPTION( ex );
330                 }
331             }
332         }
333     }
334     xTitle->setText( aNewStringList );
335 }
336 
removeTitle(TitleHelper::eTitleType nTitleIndex,const::com::sun::star::uno::Reference<::com::sun::star::frame::XModel> & xModel)337 void TitleHelper::removeTitle( TitleHelper::eTitleType nTitleIndex
338                     , const ::com::sun::star::uno::Reference<
339                             ::com::sun::star::frame::XModel >& xModel )
340 {
341     uno::Reference< XTitled > xTitled( lcl_getTitleParent( nTitleIndex, xModel ) );
342     if( xTitled.is())
343     {
344         xTitled->setTitleObject(NULL);
345     }
346 }
347 
getTitleType(eTitleType & rType,const::com::sun::star::uno::Reference<::com::sun::star::chart2::XTitle> & xTitle,const::com::sun::star::uno::Reference<::com::sun::star::frame::XModel> & xModel)348 bool TitleHelper::getTitleType( eTitleType& rType
349                     , const ::com::sun::star::uno::Reference<
350                         ::com::sun::star::chart2::XTitle >& xTitle
351                     , const ::com::sun::star::uno::Reference<
352                         ::com::sun::star::frame::XModel >& xModel )
353 {
354     if( !xTitle.is() || !xModel.is() )
355         return false;
356 
357     Reference< chart2::XTitle > xCurrentTitle;
358     for( sal_Int32 nTitleType = TITLE_BEGIN; nTitleType < NORMAL_TITLE_END; nTitleType++ )
359     {
360         xCurrentTitle = TitleHelper::getTitle( static_cast<eTitleType>(nTitleType), xModel );
361         if( xCurrentTitle == xTitle )
362         {
363             rType = static_cast<eTitleType>(nTitleType);
364             return true;
365         }
366     }
367 
368     return false;
369 }
370 
371 //.............................................................................
372 } //namespace chart
373 //.............................................................................
374 
375