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