1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_chart2.hxx"
30 
31 #include "ObjectNameProvider.hxx"
32 #include "ResId.hxx"
33 #include "Strings.hrc"
34 #include "macros.hxx"
35 #include "AxisHelper.hxx"
36 #include "ChartModelHelper.hxx"
37 #include "DiagramHelper.hxx"
38 #include "DataSeriesHelper.hxx"
39 #include "TitleHelper.hxx"
40 #include "AxisIndexDefines.hxx"
41 #include "ExplicitCategoriesProvider.hxx"
42 #include "CommonConverters.hxx"
43 #include "NumberFormatterWrapper.hxx"
44 #include "RegressionCurveHelper.hxx"
45 #include <rtl/math.hxx>
46 #include <tools/debug.hxx>
47 #include <tools/string.hxx>
48 
49 #include <com/sun/star/chart2/XTitle.hpp>
50 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
51 
52 //.............................................................................
53 namespace chart
54 {
55 //.............................................................................
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::chart2;
58 using ::com::sun::star::uno::Reference;
59 using ::com::sun::star::uno::Sequence;
60 using ::com::sun::star::uno::Any;
61 using rtl::OUString;
62 
63 namespace
64 {
65 
66 OUString lcl_getDataSeriesName( const rtl::OUString& rObjectCID, const Reference< frame::XModel >& xChartModel )
67 {
68     OUString aRet;
69 
70     Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
71     Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel ), uno::UNO_QUERY );
72     if( xDiagram.is() && xSeries.is() )
73     {
74         Reference< XChartType > xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram, xSeries ) );
75         if( xChartType.is() )
76         {
77             aRet = ::chart::DataSeriesHelper::getDataSeriesLabel(
78                     xSeries, xChartType->getRoleOfSequenceForSeriesLabel() ) ;
79         }
80     }
81 
82     return aRet;
83 }
84 
85 OUString lcl_getFullSeriesName( const rtl::OUString& rObjectCID, const Reference< frame::XModel >& xChartModel )
86 {
87     OUString aRet = String(SchResId(STR_TIP_DATASERIES));
88     OUString aWildcard( C2U("%SERIESNAME") );
89     sal_Int32 nIndex = aRet.indexOf( aWildcard );
90     if( nIndex != -1 )
91         aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), lcl_getDataSeriesName( rObjectCID, xChartModel ) );
92     return aRet;
93 }
94 
95 void lcl_addText( OUString& rOut, const OUString& rSeparator, const OUString& rNext )
96 {
97     if( rOut.getLength() && rNext.getLength() )
98         rOut+=rSeparator;
99     if( rNext.getLength() )
100         rOut+=rNext;
101 }
102 
103 OUString lcl_getDataPointValueText( const Reference< XDataSeries >& xSeries, sal_Int32 nPointIndex,
104                                     const Reference< XCoordinateSystem >& xCooSys,
105                                     const Reference< frame::XModel >& xChartModel )
106 {
107 
108     OUString aRet;
109 
110     Reference<data::XDataSource> xDataSource(
111             uno::Reference<data::XDataSource>( xSeries, uno::UNO_QUERY ) );
112     if(!xDataSource.is())
113         return aRet;
114 
115     Sequence< Reference< data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );
116 
117     rtl::OUString aX, aY, aY_Min, aY_Max, aY_First, aY_Last, a_Size;
118     double fValue = 0;
119 
120     uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xChartModel, uno::UNO_QUERY );
121     NumberFormatterWrapper aNumberFormatterWrapper( xNumberFormatsSupplier );
122     sal_Int32 nLabelColor = 0;//dummy
123     bool bColorChanged;//dummy
124 
125     for(sal_Int32 nN = aDataSequences.getLength();nN--;)
126     {
127         uno::Reference<data::XDataSequence>  xDataSequence( aDataSequences[nN]->getValues());
128         if( !xDataSequence.is() )
129             continue;
130         Sequence< Any > aData( xDataSequence->getData() );
131         if( nPointIndex >= aData.getLength() )
132             continue;
133         uno::Reference<beans::XPropertySet> xProp(xDataSequence, uno::UNO_QUERY );
134 	    if( xProp.is())
135 	    {
136 		    try
137 		    {
138                 uno::Any aARole = xProp->getPropertyValue( C2U( "Role" ) );
139                 rtl::OUString aRole;
140                 aARole >>= aRole;
141 
142                 if( aRole.equals(C2U("values-x")) )
143                 {
144                     aData[nPointIndex]>>= fValue;
145                     sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
146                     aX = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
147                 }
148                 else if( aRole.equals(C2U("values-y")) )
149                 {
150                     aData[nPointIndex]>>= fValue;
151                     sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
152                     aY = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
153                 }
154                 else if( aRole.equals(C2U("values-first")) )
155                 {
156                     aData[nPointIndex]>>= fValue;
157                     sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
158                     aY_First = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
159                 }
160                 else if( aRole.equals(C2U("values-min")) )
161                 {
162                     aData[nPointIndex]>>= fValue;
163                     sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
164                     aY_Min = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
165                 }
166                 else if( aRole.equals(C2U("values-max")) )
167                 {
168                     aData[nPointIndex]>>= fValue;
169                     sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
170                     aY_Max = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
171                 }
172                 else if( aRole.equals(C2U("values-last")) )
173                 {
174                     aData[nPointIndex]>>= fValue;
175                     sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
176                     aY_Last = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
177                 }
178                 else if( aRole.equals(C2U("values-size")) )
179                 {
180                     aData[nPointIndex]>>= fValue;
181                     sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
182                     a_Size = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
183                 }
184             }
185             catch( uno::Exception& e )
186 		    {
187                 ASSERT_EXCEPTION( e );
188             }
189         }
190     }
191 
192     if( aX.getLength() == 0 )
193     {
194         aRet = ExplicitCategoriesProvider::getCategoryByIndex( xCooSys, xChartModel, nPointIndex );
195     }
196     else
197     {
198         aRet = aX;
199     }
200 
201     OUString aSeparator(C2U(" "));
202 
203     lcl_addText( aRet, aSeparator, aY );
204     lcl_addText( aRet, aSeparator, aY_First );
205     lcl_addText( aRet, aSeparator, aY_Min );
206     lcl_addText( aRet, aSeparator, aY_Max );
207     lcl_addText( aRet, aSeparator, aY_Last );
208     lcl_addText( aRet, aSeparator, a_Size );
209 
210     return aRet;
211 }
212 
213 } //end anonymous namespace
214 
215 rtl::OUString ObjectNameProvider::getName( ObjectType eObjectType, bool bPlural )
216 {
217     rtl::OUString aRet;
218     switch( eObjectType )
219     {
220         case OBJECTTYPE_PAGE:
221                 aRet=String(SchResId(STR_OBJECT_PAGE));
222                 break;
223         case OBJECTTYPE_TITLE:
224             {
225                 if(bPlural)
226                     aRet=String(SchResId(STR_OBJECT_TITLES));
227                 else
228                     aRet=String(SchResId(STR_OBJECT_TITLE));
229             }
230                 break;
231         case OBJECTTYPE_LEGEND:
232                 aRet=String(SchResId(STR_OBJECT_LEGEND));
233                 break;
234         case OBJECTTYPE_LEGEND_ENTRY:
235                 aRet=String(SchResId(STR_OBJECT_LEGEND_SYMBOL));//@todo change string if we do differenciate symbol and legend entry in future
236                 break;
237         case OBJECTTYPE_DIAGRAM:
238                 aRet=String(SchResId(STR_OBJECT_DIAGRAM));
239                 break;
240         case OBJECTTYPE_DIAGRAM_WALL:
241                 aRet=String(SchResId(STR_OBJECT_DIAGRAM_WALL));
242                 break;
243         case OBJECTTYPE_DIAGRAM_FLOOR:
244                 aRet=String(SchResId(STR_OBJECT_DIAGRAM_FLOOR));
245                 break;
246         case OBJECTTYPE_AXIS:
247             {
248                 if(bPlural)
249                     aRet=String(SchResId(STR_OBJECT_AXES));
250                 else
251                     aRet=String(SchResId(STR_OBJECT_AXIS));
252             }
253                 break;
254         case OBJECTTYPE_AXIS_UNITLABEL:
255                 aRet=String(SchResId(STR_OBJECT_LABEL));//@todo maybe a more concrete name
256                 break;
257         case OBJECTTYPE_GRID:
258         case OBJECTTYPE_SUBGRID: //maybe todo: different names for subgrids
259             {
260                 if(bPlural)
261                     aRet=String(SchResId(STR_OBJECT_GRIDS));
262                 else
263                     aRet=String(SchResId(STR_OBJECT_GRID));
264             }
265                 break;
266         case OBJECTTYPE_DATA_SERIES:
267             {
268                 if(bPlural)
269                     aRet=String(SchResId(STR_OBJECT_DATASERIES_PLURAL));
270                 else
271                     aRet=String(SchResId(STR_OBJECT_DATASERIES));
272             }
273                 break;
274         case OBJECTTYPE_DATA_POINT:
275             {
276                 if(bPlural)
277                     aRet=String(SchResId(STR_OBJECT_DATAPOINTS));
278                 else
279                     aRet=String(SchResId(STR_OBJECT_DATAPOINT));
280             }
281                 break;
282         case OBJECTTYPE_DATA_LABELS:
283                 aRet=String(SchResId(STR_OBJECT_DATALABELS));
284                 break;
285         case OBJECTTYPE_DATA_LABEL:
286                 aRet=String(SchResId(STR_OBJECT_LABEL));
287                 break;
288         case OBJECTTYPE_DATA_ERRORS:
289                 aRet=String(SchResId(STR_OBJECT_ERROR_BARS));//@todo? maybe distinguish plural singular
290                 break;
291         case OBJECTTYPE_DATA_ERRORS_X:
292                 aRet=String(SchResId(STR_OBJECT_ERROR_BARS));//@todo? maybe specialize in future
293                 break;
294         case OBJECTTYPE_DATA_ERRORS_Y:
295                 aRet=String(SchResId(STR_OBJECT_ERROR_BARS));//@todo? maybe specialize in future
296                 break;
297         case OBJECTTYPE_DATA_ERRORS_Z:
298                 aRet=String(SchResId(STR_OBJECT_ERROR_BARS));//@todo? maybe specialize in future
299                 break;
300         case OBJECTTYPE_DATA_AVERAGE_LINE:
301                 aRet=String(SchResId(STR_OBJECT_AVERAGE_LINE));
302                 break;
303         case OBJECTTYPE_DATA_CURVE:
304             {
305                 if(bPlural)
306                     aRet=String(SchResId(STR_OBJECT_CURVES));
307                 else
308                     aRet=String(SchResId(STR_OBJECT_CURVE));
309             }
310                 break;
311         case OBJECTTYPE_DATA_STOCK_RANGE:
312                 //aRet=String(SchResId());
313                 break;
314         case OBJECTTYPE_DATA_STOCK_LOSS:
315                 aRet=String(SchResId(STR_OBJECT_STOCK_LOSS));
316                 break;
317         case OBJECTTYPE_DATA_STOCK_GAIN:
318                 aRet=String(SchResId(STR_OBJECT_STOCK_GAIN));
319                 break;
320         case OBJECTTYPE_DATA_CURVE_EQUATION:
321                 aRet=String(SchResId(STR_OBJECT_CURVE_EQUATION));
322                 break;
323         default: //OBJECTTYPE_UNKNOWN
324             ;
325     }
326     return aRet;
327 }
328 
329 rtl::OUString ObjectNameProvider::getAxisName( const rtl::OUString& rObjectCID
330                         , const uno::Reference< frame::XModel >& xChartModel  )
331 {
332     rtl::OUString aRet;
333 
334 
335 
336     Reference< XAxis > xAxis(
337         ObjectIdentifier::getObjectPropertySet( rObjectCID , xChartModel ), uno::UNO_QUERY );
338 
339     sal_Int32 nCooSysIndex = 0;
340     sal_Int32 nDimensionIndex = 0;
341     sal_Int32 nAxisIndex = 0;
342     AxisHelper::getIndicesForAxis( xAxis, ChartModelHelper::findDiagram( xChartModel ), nCooSysIndex, nDimensionIndex, nAxisIndex );
343 
344     switch(nDimensionIndex)
345     {
346         case 0://x-axis
347             if( nAxisIndex == 0 )
348                 aRet=String(SchResId(STR_OBJECT_AXIS_X));
349             else
350                 aRet=String(SchResId(STR_OBJECT_SECONDARY_X_AXIS));
351             break;
352         case 1://y-axis
353             if( nAxisIndex == 0 )
354                 aRet=String(SchResId(STR_OBJECT_AXIS_Y));
355             else
356                 aRet=String(SchResId(STR_OBJECT_SECONDARY_Y_AXIS));
357             break;
358         case 2://z-axis
359             aRet=String(SchResId(STR_OBJECT_AXIS_Z));
360             break;
361         default://axis
362             aRet=String(SchResId(STR_OBJECT_AXIS));
363             break;
364     }
365 
366     return aRet;
367 }
368 
369 OUString ObjectNameProvider::getTitleNameByType( TitleHelper::eTitleType eType )
370 {
371     OUString aRet;
372 
373     switch(eType)
374     {
375         case TitleHelper::MAIN_TITLE:
376             aRet=String(SchResId(STR_OBJECT_TITLE_MAIN));
377             break;
378         case TitleHelper::SUB_TITLE:
379             aRet=String(SchResId(STR_OBJECT_TITLE_SUB));
380             break;
381         case TitleHelper::X_AXIS_TITLE:
382             aRet=String(SchResId(STR_OBJECT_TITLE_X_AXIS));
383             break;
384         case TitleHelper::Y_AXIS_TITLE:
385             aRet=String(SchResId(STR_OBJECT_TITLE_Y_AXIS));
386             break;
387         case TitleHelper::Z_AXIS_TITLE:
388             aRet=String(SchResId(STR_OBJECT_TITLE_Z_AXIS));
389             break;
390         case TitleHelper::SECONDARY_X_AXIS_TITLE:
391             aRet=String(SchResId(STR_OBJECT_TITLE_SECONDARY_X_AXIS));
392             break;
393         case TitleHelper::SECONDARY_Y_AXIS_TITLE:
394             aRet=String(SchResId(STR_OBJECT_TITLE_SECONDARY_Y_AXIS));
395             break;
396         default:
397             DBG_ERROR("unknown title type");
398             break;
399     }
400 
401     if( !aRet.getLength() )
402         aRet=String(SchResId(STR_OBJECT_TITLE));
403 
404     return aRet;
405 }
406 
407 OUString ObjectNameProvider::getTitleName( const OUString& rObjectCID
408                         , const Reference< frame::XModel >& xChartModel )
409 {
410     OUString aRet;
411 
412     Reference< XTitle > xTitle(
413         ObjectIdentifier::getObjectPropertySet( rObjectCID , xChartModel ), uno::UNO_QUERY );
414     if( xTitle.is() )
415     {
416         TitleHelper::eTitleType eType;
417         if( TitleHelper::getTitleType( eType, xTitle, xChartModel ) )
418             aRet = ObjectNameProvider::getTitleNameByType( eType );
419     }
420     if( !aRet.getLength() )
421         aRet=String(SchResId(STR_OBJECT_TITLE));
422 
423     return aRet;
424 }
425 
426 rtl::OUString ObjectNameProvider::getGridName( const rtl::OUString& rObjectCID
427                         , const uno::Reference< frame::XModel >& xChartModel )
428 {
429     rtl::OUString aRet;
430 
431 
432     sal_Int32 nCooSysIndex = -1;
433     sal_Int32 nDimensionIndex = -1;
434     sal_Int32 nAxisIndex = -1;
435     Reference< XAxis > xAxis( ObjectIdentifier::getAxisForCID( rObjectCID , xChartModel ) );
436     AxisHelper::getIndicesForAxis( xAxis, ChartModelHelper::findDiagram( xChartModel )
437               , nCooSysIndex , nDimensionIndex, nAxisIndex );
438 
439     bool bMainGrid = (ObjectIdentifier::getObjectType( rObjectCID ) == OBJECTTYPE_GRID);
440 
441     if( bMainGrid )
442     {
443         switch(nDimensionIndex)
444         {
445             case 0://x-axis
446                 aRet=String(SchResId(STR_OBJECT_GRID_MAJOR_X));
447                 break;
448             case 1://y-axis
449                 aRet=String(SchResId(STR_OBJECT_GRID_MAJOR_Y));
450                 break;
451             case 2://z-axis
452                 aRet=String(SchResId(STR_OBJECT_GRID_MAJOR_Z));
453                 break;
454             default://axis
455                 aRet=String(SchResId(STR_OBJECT_GRID));
456                 break;
457         }
458     }
459     else
460     {
461         switch(nDimensionIndex)
462         {
463             case 0://x-axis
464                 aRet=String(SchResId(STR_OBJECT_GRID_MINOR_X));
465                 break;
466             case 1://y-axis
467                 aRet=String(SchResId(STR_OBJECT_GRID_MINOR_Y));
468                 break;
469             case 2://z-axis
470                 aRet=String(SchResId(STR_OBJECT_GRID_MINOR_Z));
471                 break;
472             default://axis
473                 aRet=String(SchResId(STR_OBJECT_GRID));
474                 break;
475         }
476     }
477     return aRet;
478 }
479 
480 rtl::OUString ObjectNameProvider::getHelpText( const rtl::OUString& rObjectCID, const Reference< chart2::XChartDocument >& xChartDocument, bool bVerbose )
481 {
482     return getHelpText( rObjectCID, Reference< frame::XModel >( xChartDocument, uno::UNO_QUERY ), bVerbose );
483 }
484 
485 rtl::OUString ObjectNameProvider::getHelpText( const rtl::OUString& rObjectCID, const Reference< frame::XModel >& xChartModel, bool bVerbose )
486 {
487     rtl::OUString aRet;
488     ObjectType eObjectType( ObjectIdentifier::getObjectType(rObjectCID) );
489     if( OBJECTTYPE_AXIS == eObjectType )
490     {
491         aRet=ObjectNameProvider::getAxisName( rObjectCID, xChartModel );
492     }
493     else if( OBJECTTYPE_GRID == eObjectType
494         || OBJECTTYPE_SUBGRID == eObjectType )
495     {
496         aRet=ObjectNameProvider::getGridName( rObjectCID, xChartModel );
497     }
498     else if( OBJECTTYPE_TITLE == eObjectType )
499     {
500         aRet=ObjectNameProvider::getTitleName( rObjectCID, xChartModel );
501     }
502     else if( OBJECTTYPE_DATA_SERIES == eObjectType )
503     {
504         aRet = lcl_getFullSeriesName( rObjectCID, xChartModel );
505     }
506     else if( OBJECTTYPE_DATA_POINT == eObjectType )
507     {
508         if( bVerbose )
509         {
510             OUString aNewLine(C2U("\n"));
511 
512             aRet=String(SchResId(STR_TIP_DATAPOINT_INDEX));
513             aRet+=aNewLine;
514             aRet+=String(SchResId(STR_TIP_DATASERIES));
515             aRet+=aNewLine;
516             aRet+=String(SchResId(STR_TIP_DATAPOINT_VALUES));
517         }
518         else
519             aRet=String(SchResId(STR_TIP_DATAPOINT));
520 
521         Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
522         Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel ), uno::UNO_QUERY );
523         if( xDiagram.is() && xSeries.is() )
524         {
525             sal_Int32 nPointIndex( ObjectIdentifier::getParticleID(rObjectCID).toInt32() );
526 
527             //replace data point index
528             sal_Int32 nIndex = -1;
529             OUString aWildcard( C2U("%POINTNUMBER") );
530             nIndex = aRet.indexOf( aWildcard );
531             if( nIndex != -1 )
532             {
533                 aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), OUString::valueOf(nPointIndex+1) );
534             }
535 
536             //replace data series index
537             aWildcard = C2U("%SERIESNUMBER");
538             nIndex = aRet.indexOf( aWildcard );
539             if( nIndex != -1 )
540             {
541                 ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector(
542                     DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
543                 sal_Int32 nSeriesIndex = -1;
544                 for( nSeriesIndex=aSeriesVector.size();nSeriesIndex--;)
545                 {
546                     if( aSeriesVector[nSeriesIndex] == xSeries )
547                     {
548                         break;
549                     }
550                 }
551 
552                 OUString aReplacement( OUString::valueOf(nSeriesIndex+1) );
553                 aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), aReplacement );
554             }
555 
556             //replace point values
557             aWildcard = C2U("%POINTVALUES");
558             nIndex = aRet.indexOf( aWildcard );
559             if( nIndex != -1 )
560                 aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), lcl_getDataPointValueText(
561                 xSeries,nPointIndex, DataSeriesHelper::getCoordinateSystemOfSeries(xSeries, xDiagram), xChartModel ) );
562 
563             //replace series name
564             aWildcard = C2U("%SERIESNAME");
565             nIndex = aRet.indexOf( aWildcard );
566             if( nIndex != -1 )
567                 aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), lcl_getDataSeriesName( rObjectCID, xChartModel ) );
568         }
569     }
570     /*
571     else if( OBJECTTYPE_DIAGRAM == eObjectType )
572     {
573         //todo different names for different diagram types ???
574         //or different names for series of diferent charttypes
575     }
576     */
577     else if( OBJECTTYPE_DATA_CURVE == eObjectType )
578     {
579         if( bVerbose )
580         {
581             aRet = String( SchResId( STR_OBJECT_CURVE_WITH_PARAMETERS ));
582             Reference< chart2::XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel ));
583             Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY );
584             if( xCurveCnt.is())
585             {
586                 Reference< chart2::XRegressionCurve > xCurve( RegressionCurveHelper::getFirstCurveNotMeanValueLine( xCurveCnt ));
587                 if( xCurve.is())
588                 {
589                     try
590                     {
591                         Reference< chart2::XRegressionCurveCalculator > xCalculator( xCurve->getCalculator(), uno::UNO_QUERY_THROW );
592                         RegressionCurveHelper::initializeCurveCalculator( xCalculator, xSeries, xChartModel );
593 
594                         // replace formula
595                         sal_Int32 nIndex = -1;
596                         OUString aWildcard( C2U("%FORMULA") );
597                         nIndex = aRet.indexOf( aWildcard );
598                         if( nIndex != -1 )
599                             aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), xCalculator->getRepresentation());
600 
601                         // replace r^2
602                         aWildcard = C2U("%RSQUARED");
603                         nIndex = aRet.indexOf( aWildcard );
604                         if( nIndex != -1 )
605                         {
606                             sal_Unicode aDecimalSep( '.' );
607                             //@todo: enable this code when a localized decimal
608                             //separator is also available for the formula
609 //                             SvtSysLocale aSysLocale;
610 //                             OUString aSep( aSysLocale.GetLocaleData().getNumDecimalSep());
611 //                             if( aSep.getLength() == 1 )
612 //                                 aDecimalSep = aSep.toChar();
613                             double fR( xCalculator->getCorrelationCoefficient());
614                             aRet = aRet.replaceAt(
615                                 nIndex, aWildcard.getLength(),
616                                 ::rtl::math::doubleToUString(
617                                     fR*fR, rtl_math_StringFormat_G, 4, aDecimalSep, true ));
618                         }
619                     }
620                     catch( const uno::Exception & ex )
621                     {
622                         ASSERT_EXCEPTION( ex );
623                     }
624                 }
625             }
626         }
627         else
628         {
629             // non-verbose
630             aRet = ObjectNameProvider::getName( eObjectType, false );
631         }
632     }
633     else if( OBJECTTYPE_DATA_AVERAGE_LINE == eObjectType )
634     {
635         if( bVerbose )
636         {
637             aRet = String( SchResId( STR_OBJECT_AVERAGE_LINE_WITH_PARAMETERS ));
638             Reference< chart2::XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel ));
639             Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY );
640             if( xCurveCnt.is())
641             {
642                 Reference< chart2::XRegressionCurve > xCurve( RegressionCurveHelper::getMeanValueLine( xCurveCnt ));
643                 if( xCurve.is())
644                 {
645                     try
646                     {
647                         Reference< chart2::XRegressionCurveCalculator > xCalculator( xCurve->getCalculator(), uno::UNO_QUERY_THROW );
648                         RegressionCurveHelper::initializeCurveCalculator( xCalculator, xSeries, xChartModel );
649 
650                         sal_Unicode aDecimalSep( '.' );
651                         // replace average value
652 //                             SvtSysLocale aSysLocale;
653 //                             OUString aSep( aSysLocale.GetLocaleData().getNumDecimalSep());
654 //                             if( aSep.getLength() == 1 )
655 //                                 aDecimalSep = aSep.toChar();
656 
657                         sal_Int32 nIndex = -1;
658                         OUString aWildcard( C2U("%AVERAGE_VALUE") );
659                         nIndex = aRet.indexOf( aWildcard );
660                         // as the curve is constant, the value at any x-value is ok
661                         if( nIndex != -1 )
662                         {
663                             const double fMeanValue( xCalculator->getCurveValue( 0.0 ));
664                             aRet = aRet.replaceAt(
665                                 nIndex, aWildcard.getLength(),
666                                 ::rtl::math::doubleToUString(
667                                     fMeanValue, rtl_math_StringFormat_G, 4, aDecimalSep, true ));
668                         }
669 
670                         // replace standard deviation
671                         aWildcard = C2U("%STD_DEVIATION");
672                         nIndex = aRet.indexOf( aWildcard );
673                         if( nIndex != -1 )
674                         {
675                             const double fStdDev( xCalculator->getCorrelationCoefficient());
676                             aRet = aRet.replaceAt(
677                                 nIndex, aWildcard.getLength(),
678                                 ::rtl::math::doubleToUString(
679                                     fStdDev, rtl_math_StringFormat_G, 4, aDecimalSep, true ));
680                         }
681                     }
682                     catch( const uno::Exception & ex )
683                     {
684                         ASSERT_EXCEPTION( ex );
685                     }
686                 }
687             }
688         }
689         else
690         {
691             // non-verbose
692             aRet = ObjectNameProvider::getName( eObjectType, false );
693         }
694     }
695     else
696     {
697         aRet = ObjectNameProvider::getName( eObjectType, false );
698     }
699     return aRet;
700 }
701 
702 rtl::OUString ObjectNameProvider::getSelectedObjectText( const rtl::OUString & rObjectCID, const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& xChartDocument )
703 {
704     rtl::OUString aRet;
705     ObjectType eObjectType( ObjectIdentifier::getObjectType(rObjectCID) );
706     Reference< frame::XModel > xChartModel( xChartDocument, uno::UNO_QUERY );
707 
708     if( OBJECTTYPE_DATA_POINT == eObjectType )
709     {
710         aRet = String( SchResId( STR_STATUS_DATAPOINT_MARKED ));
711 
712         Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
713         Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel ), uno::UNO_QUERY );
714         if( xDiagram.is() && xSeries.is() )
715         {
716             sal_Int32 nPointIndex( ObjectIdentifier::getParticleID(rObjectCID).toInt32() );
717 
718             // replace data point index
719             replaceParamterInString( aRet, C2U("%POINTNUMBER"), OUString::valueOf( nPointIndex + 1 ));
720 
721             // replace data series index
722             {
723                 ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector(
724                     DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
725                 sal_Int32 nSeriesIndex = -1;
726                 for( nSeriesIndex=aSeriesVector.size();nSeriesIndex--;)
727                 {
728                     if( aSeriesVector[nSeriesIndex] == xSeries )
729                         break;
730                 }
731                 replaceParamterInString( aRet, C2U("%SERIESNUMBER"), OUString::valueOf( nSeriesIndex + 1 ) );
732             }
733 
734             // replace point value
735             replaceParamterInString( aRet, C2U("%POINTVALUES"), lcl_getDataPointValueText(
736                 xSeries, nPointIndex, DataSeriesHelper::getCoordinateSystemOfSeries(xSeries, xDiagram), xChartModel ) );
737         }
738     }
739     else
740     {
741         // use the verbose text including the formula for trend lines
742         const bool bVerbose( OBJECTTYPE_DATA_CURVE == eObjectType || OBJECTTYPE_DATA_AVERAGE_LINE == eObjectType );
743         const OUString aHelpText( getHelpText( rObjectCID, xChartModel, bVerbose ));
744         if( aHelpText.getLength())
745         {
746             aRet = String( SchResId( STR_STATUS_OBJECT_MARKED ));
747             replaceParamterInString( aRet, C2U("%OBJECTNAME"), aHelpText );
748         }
749     }
750 
751     return aRet;
752 }
753 
754 rtl::OUString ObjectNameProvider::getNameForCID(
755     const rtl::OUString& rObjectCID,
756     const uno::Reference< chart2::XChartDocument >& xChartDocument )
757 {
758     ObjectType eType( ObjectIdentifier::getObjectType( rObjectCID ));
759     Reference< frame::XModel > xModel( xChartDocument, uno::UNO_QUERY );
760 
761     switch( eType )
762     {
763         case OBJECTTYPE_AXIS:
764             return getAxisName( rObjectCID, xModel );
765         case OBJECTTYPE_TITLE:
766             return getTitleName( rObjectCID, xModel );
767         case OBJECTTYPE_GRID:
768         case OBJECTTYPE_SUBGRID:
769             return getGridName( rObjectCID, xModel );
770         case OBJECTTYPE_DATA_SERIES:
771             return lcl_getFullSeriesName( rObjectCID, xModel );
772         //case OBJECTTYPE_LEGEND_ENTRY:
773         case OBJECTTYPE_DATA_POINT:
774         case OBJECTTYPE_DATA_LABELS:
775         case OBJECTTYPE_DATA_LABEL:
776         case OBJECTTYPE_DATA_ERRORS:
777         case OBJECTTYPE_DATA_ERRORS_X:
778         case OBJECTTYPE_DATA_ERRORS_Y:
779         case OBJECTTYPE_DATA_ERRORS_Z:
780         case OBJECTTYPE_DATA_CURVE:
781         case OBJECTTYPE_DATA_AVERAGE_LINE:
782         case OBJECTTYPE_DATA_CURVE_EQUATION:
783             {
784                 rtl::OUString aRet = lcl_getFullSeriesName( rObjectCID, xModel );
785                 aRet += C2U(" ");
786                 if( eType == OBJECTTYPE_DATA_POINT || eType == OBJECTTYPE_DATA_LABEL )
787                 {
788                     aRet += getName( OBJECTTYPE_DATA_POINT  );
789                     sal_Int32 nPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( rObjectCID );
790                     aRet += C2U(" ");
791                     aRet += OUString::valueOf(nPointIndex+1);
792 
793                     if( eType == OBJECTTYPE_DATA_LABEL )
794                     {
795                         aRet += C2U(" ");
796                         aRet += getName( OBJECTTYPE_DATA_LABEL  );
797                     }
798                 }
799                 else
800                     aRet += getName( eType );
801                 return aRet;
802             }
803         default:
804             break;
805     }
806 
807     return getName( eType );
808 }
809 
810 rtl::OUString ObjectNameProvider::getName_ObjectForSeries(
811         ObjectType eObjectType,
812         const rtl::OUString& rSeriesCID,
813         const uno::Reference< chart2::XChartDocument >& xChartDocument )
814 {
815     uno::Reference< frame::XModel> xChartModel( xChartDocument, uno::UNO_QUERY );
816     Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rSeriesCID , xChartModel ), uno::UNO_QUERY );
817     if( xSeries.is() )
818     {
819         OUString aRet = String(SchResId(STR_OBJECT_FOR_SERIES));
820         replaceParamterInString( aRet, C2U("%OBJECTNAME"), getName( eObjectType, false /*bPlural*/ ) );
821         replaceParamterInString( aRet, C2U("%SERIESNAME"), lcl_getDataSeriesName( rSeriesCID, xChartModel ) );
822         return aRet;
823     }
824     else
825         return ObjectNameProvider::getName_ObjectForAllSeries( eObjectType );
826 }
827 
828 rtl::OUString ObjectNameProvider::getName_ObjectForAllSeries( ObjectType eObjectType )
829 {
830     OUString aRet = String(SchResId(STR_OBJECT_FOR_ALL_SERIES));
831     replaceParamterInString( aRet, C2U("%OBJECTNAME"), getName( eObjectType, true /*bPlural*/ ) );
832     return aRet;
833 }
834 
835 //.............................................................................
836 } //namespace chart
837 //.............................................................................
838