1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <ChartController.hxx>
21 #include <ChartWindow.hxx>
22 #include <chartview/DrawModelWrapper.hxx>
23 #include <chartview/ChartSfxItemIds.hxx>
24 #include <ObjectIdentifier.hxx>
25 #include <chartview/ExplicitScaleValues.hxx>
26 #include <chartview/ExplicitValueProvider.hxx>
27 #include <dlg_ObjectProperties.hxx>
28 #include <dlg_View3D.hxx>
29 #include <dlg_InsertErrorBars.hxx>
30 #include <ViewElementListProvider.hxx>
31 #include <DataPointItemConverter.hxx>
32 #include <TextLabelItemConverter.hxx>
33 #include <AxisItemConverter.hxx>
34 #include <MultipleChartConverters.hxx>
35 #include <TitleItemConverter.hxx>
36 #include <LegendItemConverter.hxx>
37 #include <RegressionCurveItemConverter.hxx>
38 #include <RegressionEquationItemConverter.hxx>
39 #include <ErrorBarItemConverter.hxx>
40 #include <ChartModelHelper.hxx>
41 #include <AxisHelper.hxx>
42 #include <TitleHelper.hxx>
43 #include <ChartTypeHelper.hxx>
44 #include <ColorPerPointHelper.hxx>
45 #include <DiagramHelper.hxx>
46 #include <ControllerLockGuard.hxx>
47 #include "UndoGuard.hxx"
48 #include <ObjectNameProvider.hxx>
49 #include <ResId.hxx>
50 #include <strings.hrc>
51 #include <ReferenceSizeProvider.hxx>
52 #include <RegressionCurveHelper.hxx>
53 #include <com/sun/star/chart2/XChartDocument.hpp>
54 #include <com/sun/star/util/CloseVetoException.hpp>
55 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
56 #include <comphelper/servicehelper.hxx>
57 
58 #include <memory>
59 
60 #include <sal/log.hxx>
61 #include <vcl/svapp.hxx>
62 #include <svx/ActionDescriptionProvider.hxx>
63 #include <tools/diagnose_ex.h>
64 
65 namespace chart
66 {
67 using namespace ::com::sun::star;
68 using namespace ::com::sun::star::chart2;
69 using ::com::sun::star::uno::Reference;
70 
71 namespace
72 {
73 
createItemConverter(const OUString & aObjectCID,const uno::Reference<frame::XModel> & xChartModel,const uno::Reference<uno::XComponentContext> & xContext,SdrModel & rDrawModel,ExplicitValueProvider * pExplicitValueProvider,ReferenceSizeProvider const * pRefSizeProvider)74 wrapper::ItemConverter* createItemConverter(
75     const OUString & aObjectCID, const uno::Reference<frame::XModel>& xChartModel,
76     const uno::Reference<uno::XComponentContext>& xContext, SdrModel& rDrawModel,
77     ExplicitValueProvider* pExplicitValueProvider, ReferenceSizeProvider const * pRefSizeProvider )
78 {
79     wrapper::ItemConverter* pItemConverter=nullptr;
80 
81     //get type of selected object
82     ObjectType eObjectType = ObjectIdentifier::getObjectType( aObjectCID );
83     if( eObjectType==OBJECTTYPE_UNKNOWN )
84     {
85         OSL_FAIL("unknown ObjectType");
86         return nullptr;
87     }
88 
89     OUString aParticleID = ObjectIdentifier::getParticleID( aObjectCID );
90     bool bAffectsMultipleObjects = aParticleID == "ALLELEMENTS";
91     if( !bAffectsMultipleObjects )
92     {
93         uno::Reference< beans::XPropertySet > xObjectProperties =
94             ObjectIdentifier::getObjectPropertySet( aObjectCID, xChartModel );
95         if(!xObjectProperties.is())
96             return nullptr;
97         //create itemconverter for a single object
98         switch(eObjectType)
99         {
100             case OBJECTTYPE_PAGE:
101                 pItemConverter =  new wrapper::GraphicPropertyItemConverter(
102                                         xObjectProperties, rDrawModel.GetItemPool(),
103                                         rDrawModel, uno::Reference< lang::XMultiServiceFactory >( xChartModel, uno::UNO_QUERY ),
104                                         wrapper::GraphicObjectType::LineAndFillProperties );
105                     break;
106             case OBJECTTYPE_TITLE:
107             {
108                 std::unique_ptr<awt::Size> pRefSize;
109                 if (pRefSizeProvider)
110                     pRefSize.reset(new awt::Size(pRefSizeProvider->getPageSize()));
111 
112                 pItemConverter = new wrapper::TitleItemConverter(
113                     xObjectProperties, rDrawModel.GetItemPool(), rDrawModel,
114                     uno::Reference<lang::XMultiServiceFactory>(xChartModel, uno::UNO_QUERY),
115                     pRefSize.get());
116             }
117             break;
118             case OBJECTTYPE_LEGEND:
119             {
120                 std::unique_ptr<awt::Size> pRefSize;
121                 if (pRefSizeProvider)
122                     pRefSize.reset( new awt::Size( pRefSizeProvider->getPageSize()));
123 
124                 pItemConverter = new wrapper::LegendItemConverter(
125                     xObjectProperties, rDrawModel.GetItemPool(), rDrawModel,
126                     uno::Reference<lang::XMultiServiceFactory>(xChartModel, uno::UNO_QUERY),
127                     pRefSize.get());
128             }
129             break;
130             case OBJECTTYPE_LEGEND_ENTRY:
131                     break;
132             case OBJECTTYPE_DIAGRAM:
133                     break;
134             case OBJECTTYPE_DIAGRAM_WALL:
135             case OBJECTTYPE_DIAGRAM_FLOOR:
136                 pItemConverter =  new wrapper::GraphicPropertyItemConverter(
137                                         xObjectProperties, rDrawModel.GetItemPool(),
138                                         rDrawModel, uno::Reference< lang::XMultiServiceFactory >( xChartModel, uno::UNO_QUERY ),
139                                         wrapper::GraphicObjectType::LineAndFillProperties );
140                     break;
141             case OBJECTTYPE_AXIS:
142             {
143                 std::unique_ptr<awt::Size> pRefSize;
144                 if (pRefSizeProvider)
145                     pRefSize.reset( new awt::Size( pRefSizeProvider->getPageSize()));
146 
147                 uno::Reference< beans::XPropertySet > xDiaProp;
148                 xDiaProp.set( ChartModelHelper::findDiagram( xChartModel ), uno::UNO_QUERY );
149 
150                 // the second property set contains the property CoordinateOrigin
151                 // nOriginIndex is the index of the corresponding index of the
152                 // origin (x=0, y=1, z=2)
153 
154                 ExplicitScaleData aExplicitScale;
155                 ExplicitIncrementData aExplicitIncrement;
156                 if( pExplicitValueProvider )
157                     pExplicitValueProvider->getExplicitValuesForAxis(
158                         uno::Reference< XAxis >( xObjectProperties, uno::UNO_QUERY ),
159                         aExplicitScale, aExplicitIncrement );
160 
161                 pItemConverter =  new wrapper::AxisItemConverter(
162                     xObjectProperties, rDrawModel.GetItemPool(),
163                     rDrawModel,
164                     uno::Reference< chart2::XChartDocument >( xChartModel, uno::UNO_QUERY ),
165                     &aExplicitScale, &aExplicitIncrement,
166                     pRefSize.get() );
167             }
168             break;
169             case OBJECTTYPE_AXIS_UNITLABEL:
170                     break;
171             case OBJECTTYPE_DATA_LABELS:
172             case OBJECTTYPE_DATA_LABEL:
173             {
174                 std::unique_ptr<awt::Size> pRefSize;
175                 if (pRefSizeProvider)
176                     pRefSize.reset( new awt::Size( pRefSizeProvider->getPageSize()));
177 
178                 uno::Reference<XDataSeries> xSeries = ObjectIdentifier::getDataSeriesForCID(aObjectCID, xChartModel);
179 
180                 uno::Reference<XDiagram> xDiagram = ChartModelHelper::findDiagram(xChartModel);
181 
182                 bool bDataSeries = eObjectType == OBJECTTYPE_DATA_LABELS;
183 
184                 sal_Int32 nPointIndex = -1; /*-1 for whole series*/
185                 if (!bDataSeries)
186                     nPointIndex = aParticleID.toInt32();
187 
188                 sal_Int32 nNumberFormat = ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel(
189                     xObjectProperties, xSeries, nPointIndex, xDiagram);
190                 sal_Int32 nPercentNumberFormat = ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabel(
191                     xObjectProperties,uno::Reference<util::XNumberFormatsSupplier>(xChartModel, uno::UNO_QUERY));
192 
193                 pItemConverter = new wrapper::TextLabelItemConverter(
194                     xChartModel, xObjectProperties, xSeries,
195                     rDrawModel.GetItemPool(), pRefSize.get(), bDataSeries,
196                     nNumberFormat, nPercentNumberFormat);
197             }
198             break;
199             case OBJECTTYPE_DATA_SERIES:
200             case OBJECTTYPE_DATA_POINT:
201             {
202                 std::unique_ptr<awt::Size> pRefSize;
203                 if (pRefSizeProvider)
204                     pRefSize.reset( new awt::Size( pRefSizeProvider->getPageSize()));
205 
206                 wrapper::GraphicObjectType eMapTo =
207                     wrapper::GraphicObjectType::FilledDataPoint;
208 
209                 uno::Reference< XDataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( aObjectCID, xChartModel );
210                 uno::Reference< XChartType > xChartType = ChartModelHelper::getChartTypeOfSeries( xChartModel, xSeries );
211 
212                 uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
213                 sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
214                 if( !ChartTypeHelper::isSupportingAreaProperties( xChartType, nDimensionCount ) )
215                     eMapTo = wrapper::GraphicObjectType::LineDataPoint;
216 
217                 bool bDataSeries = eObjectType == OBJECTTYPE_DATA_SERIES;
218 
219                 //special color for pie chart:
220                 bool bUseSpecialFillColor = false;
221                 sal_Int32 nSpecialFillColor =0;
222                 sal_Int32 nPointIndex = -1; /*-1 for whole series*/
223                 if(!bDataSeries)
224                 {
225                     nPointIndex = aParticleID.toInt32();
226                     uno::Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
227                     bool bVaryColorsByPoint = false;
228                     if( xSeriesProp.is() &&
229                         (xSeriesProp->getPropertyValue("VaryColorsByPoint") >>= bVaryColorsByPoint) &&
230                         bVaryColorsByPoint )
231                     {
232                         if( !ColorPerPointHelper::hasPointOwnColor( xSeriesProp, nPointIndex, xObjectProperties ) )
233                         {
234                             bUseSpecialFillColor = true;
235                             OSL_ASSERT( xDiagram.is());
236                             uno::Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme() );
237                             if( xColorScheme.is())
238                                 nSpecialFillColor = xColorScheme->getColorByIndex( nPointIndex );
239                         }
240                     }
241                 }
242                 sal_Int32 nNumberFormat=ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel( xObjectProperties, xSeries, nPointIndex, xDiagram );
243                 sal_Int32 nPercentNumberFormat=ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabel(
244                         xObjectProperties,uno::Reference< util::XNumberFormatsSupplier >(xChartModel, uno::UNO_QUERY));
245 
246                 pItemConverter =  new wrapper::DataPointItemConverter( xChartModel, xContext,
247                                         xObjectProperties, xSeries, rDrawModel.GetItemPool(), rDrawModel,
248                                         uno::Reference< lang::XMultiServiceFactory >( xChartModel, uno::UNO_QUERY ),
249                                         eMapTo, pRefSize.get(), bDataSeries, bUseSpecialFillColor, nSpecialFillColor, true,
250                                         nNumberFormat, nPercentNumberFormat );
251                 break;
252             }
253             case OBJECTTYPE_GRID:
254             case OBJECTTYPE_SUBGRID:
255             case OBJECTTYPE_DATA_AVERAGE_LINE:
256                 pItemConverter =  new wrapper::GraphicPropertyItemConverter(
257                                         xObjectProperties, rDrawModel.GetItemPool(),
258                                         rDrawModel, uno::Reference< lang::XMultiServiceFactory >( xChartModel, uno::UNO_QUERY ),
259                                         wrapper::GraphicObjectType::LineProperties );
260                     break;
261 
262             case OBJECTTYPE_DATA_ERRORS_X:
263             case OBJECTTYPE_DATA_ERRORS_Y:
264             case OBJECTTYPE_DATA_ERRORS_Z:
265                 pItemConverter =  new wrapper::ErrorBarItemConverter(
266                     xChartModel, xObjectProperties, rDrawModel.GetItemPool(),
267                     rDrawModel, uno::Reference< lang::XMultiServiceFactory >( xChartModel, uno::UNO_QUERY ));
268                 break;
269 
270             case OBJECTTYPE_DATA_CURVE:
271                 pItemConverter =  new wrapper::RegressionCurveItemConverter(
272                     xObjectProperties, uno::Reference< chart2::XRegressionCurveContainer >(
273                         ObjectIdentifier::getDataSeriesForCID( aObjectCID, xChartModel ), uno::UNO_QUERY ),
274                     rDrawModel.GetItemPool(), rDrawModel,
275                     uno::Reference< lang::XMultiServiceFactory >( xChartModel, uno::UNO_QUERY ));
276                 break;
277             case OBJECTTYPE_DATA_CURVE_EQUATION:
278             {
279                 std::unique_ptr<awt::Size> pRefSize;
280                 if (pRefSizeProvider)
281                     pRefSize.reset(new awt::Size(pRefSizeProvider->getPageSize()));
282 
283                 pItemConverter =  new wrapper::RegressionEquationItemConverter(
284                                         xObjectProperties, rDrawModel.GetItemPool(), rDrawModel,
285                                         uno::Reference< lang::XMultiServiceFactory >( xChartModel, uno::UNO_QUERY ),
286                                         pRefSize.get());
287                 break;
288             }
289             case OBJECTTYPE_DATA_STOCK_RANGE:
290                     break;
291             case OBJECTTYPE_DATA_STOCK_LOSS:
292             case OBJECTTYPE_DATA_STOCK_GAIN:
293                 pItemConverter =  new wrapper::GraphicPropertyItemConverter(
294                                         xObjectProperties, rDrawModel.GetItemPool(),
295                                         rDrawModel, uno::Reference< lang::XMultiServiceFactory >( xChartModel, uno::UNO_QUERY ),
296                                         wrapper::GraphicObjectType::LineAndFillProperties );
297                     break;
298             default: //OBJECTTYPE_UNKNOWN
299                     break;
300         }
301     }
302     else
303     {
304         //create itemconverter for all objects of given type
305         switch(eObjectType)
306         {
307             case OBJECTTYPE_TITLE:
308                 pItemConverter =  new wrapper::AllTitleItemConverter( xChartModel, rDrawModel.GetItemPool(),
309                                                                      rDrawModel, uno::Reference< lang::XMultiServiceFactory >( xChartModel, uno::UNO_QUERY ));
310                 break;
311             case OBJECTTYPE_AXIS:
312             {
313                 std::unique_ptr<awt::Size> pRefSize;
314                 if (pRefSizeProvider)
315                     pRefSize.reset( new awt::Size( pRefSizeProvider->getPageSize()));
316 
317                 pItemConverter =  new wrapper::AllAxisItemConverter(
318                     xChartModel, rDrawModel.GetItemPool(),
319                     rDrawModel, pRefSize.get());
320             }
321             break;
322             case OBJECTTYPE_GRID:
323             case OBJECTTYPE_SUBGRID:
324                 pItemConverter =  new wrapper::AllGridItemConverter( xChartModel, rDrawModel.GetItemPool(),
325                                                                      rDrawModel, uno::Reference< lang::XMultiServiceFactory >( xChartModel, uno::UNO_QUERY ));
326                 break;
327             default: //for this type it is not supported to change all elements at once
328                 break;
329         }
330 
331     }
332     return pItemConverter;
333 }
334 
lcl_getTitleCIDForCommand(const OString & rDispatchCommand,const uno::Reference<frame::XModel> & xChartModel)335 OUString lcl_getTitleCIDForCommand( const OString& rDispatchCommand, const uno::Reference< frame::XModel > & xChartModel )
336 {
337     if( rDispatchCommand == "AllTitles")
338         return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_TITLE, "ALLELEMENTS" );
339 
340     TitleHelper::eTitleType nTitleType( TitleHelper::MAIN_TITLE );
341     if( rDispatchCommand == "SubTitle" )
342         nTitleType = TitleHelper::SUB_TITLE;
343     else if( rDispatchCommand == "XTitle" )
344         nTitleType = TitleHelper::X_AXIS_TITLE;
345     else if( rDispatchCommand == "YTitle" )
346         nTitleType = TitleHelper::Y_AXIS_TITLE;
347     else if( rDispatchCommand == "ZTitle" )
348         nTitleType = TitleHelper::Z_AXIS_TITLE;
349     else if( rDispatchCommand == "SecondaryXTitle" )
350         nTitleType = TitleHelper::SECONDARY_X_AXIS_TITLE;
351     else if( rDispatchCommand == "SecondaryYTitle" )
352         nTitleType = TitleHelper::SECONDARY_Y_AXIS_TITLE;
353 
354     uno::Reference< XTitle > xTitle( TitleHelper::getTitle( nTitleType, xChartModel ) );
355     return ObjectIdentifier::createClassifiedIdentifierForObject( xTitle, xChartModel );
356 }
357 
lcl_getAxisCIDForCommand(const OString & rDispatchCommand,const uno::Reference<frame::XModel> & xChartModel)358 OUString lcl_getAxisCIDForCommand( const OString& rDispatchCommand, const uno::Reference< frame::XModel >& xChartModel )
359 {
360     if( rDispatchCommand == "DiagramAxisAll")
361         return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_AXIS, "ALLELEMENTS" );
362 
363     sal_Int32   nDimensionIndex=0;
364     bool        bMainAxis=true;
365     if( rDispatchCommand == "DiagramAxisX")
366     {
367         nDimensionIndex=0; bMainAxis=true;
368     }
369     else if( rDispatchCommand == "DiagramAxisY")
370     {
371         nDimensionIndex=1; bMainAxis=true;
372     }
373     else if( rDispatchCommand == "DiagramAxisZ")
374     {
375         nDimensionIndex=2; bMainAxis=true;
376     }
377     else if( rDispatchCommand == "DiagramAxisA")
378     {
379         nDimensionIndex=0; bMainAxis=false;
380     }
381     else if( rDispatchCommand == "DiagramAxisB")
382     {
383         nDimensionIndex=1; bMainAxis=false;
384     }
385 
386     uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
387     uno::Reference< XAxis > xAxis( AxisHelper::getAxis( nDimensionIndex, bMainAxis, xDiagram ) );
388     return ObjectIdentifier::createClassifiedIdentifierForObject( xAxis, xChartModel );
389 }
390 
lcl_getGridCIDForCommand(const OString & rDispatchCommand,const uno::Reference<frame::XModel> & xChartModel)391 OUString lcl_getGridCIDForCommand( const OString& rDispatchCommand, const uno::Reference< frame::XModel >& xChartModel )
392 {
393     uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
394 
395     if( rDispatchCommand == "DiagramGridAll")
396         return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_GRID, "ALLELEMENTS" );
397 
398     sal_Int32   nDimensionIndex=0;
399     bool        bMainGrid=true;
400 
401     //x and y is swapped in the commands
402 
403     if( rDispatchCommand == "DiagramGridYMain")
404     {
405         nDimensionIndex=0; bMainGrid=true;
406     }
407     else if( rDispatchCommand == "DiagramGridXMain")
408     {
409         nDimensionIndex=1; bMainGrid=true;
410     }
411     else if( rDispatchCommand == "DiagramGridZMain")
412     {
413         nDimensionIndex=2; bMainGrid=true;
414     }
415     else if( rDispatchCommand == "DiagramGridYHelp")
416     {
417         nDimensionIndex=0; bMainGrid=false;
418     }
419     else if( rDispatchCommand == "DiagramGridXHelp")
420     {
421         nDimensionIndex=1; bMainGrid=false;
422     }
423     else if( rDispatchCommand == "DiagramGridZHelp")
424     {
425         nDimensionIndex=2; bMainGrid=false;
426     }
427 
428     uno::Reference< XAxis > xAxis( AxisHelper::getAxis( nDimensionIndex, true/*bMainAxis*/, xDiagram ) );
429 
430     sal_Int32   nSubGridIndex= bMainGrid ? -1 : 0;
431     OUString aCID( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel, nSubGridIndex ) );
432     return aCID;
433 }
434 
lcl_getErrorCIDForCommand(const ObjectType eDispatchType,const ObjectType & eSelectedType,const OUString & rSelectedCID)435 OUString lcl_getErrorCIDForCommand( const ObjectType eDispatchType, const ObjectType &eSelectedType, const OUString &rSelectedCID)
436 {
437     if( eSelectedType == eDispatchType )
438         return rSelectedCID;
439 
440     return ObjectIdentifier::createClassifiedIdentifierWithParent( eDispatchType, OUString(), rSelectedCID );
441 }
442 
lcl_getObjectCIDForCommand(const OString & rDispatchCommand,const uno::Reference<XChartDocument> & xChartDocument,const OUString & rSelectedCID)443 OUString lcl_getObjectCIDForCommand( const OString& rDispatchCommand, const uno::Reference< XChartDocument > & xChartDocument, const OUString& rSelectedCID )
444 {
445     ObjectType eObjectType = OBJECTTYPE_UNKNOWN;
446 
447     uno::Reference< frame::XModel > xChartModel = xChartDocument;
448     const ObjectType eSelectedType = ObjectIdentifier::getObjectType( rSelectedCID );
449     uno::Reference< XDataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( rSelectedCID, xChartModel );
450     uno::Reference< chart2::XRegressionCurveContainer > xRegCurveCnt( xSeries, uno::UNO_QUERY );
451 
452     //legend
453     if( rDispatchCommand == "Legend" || rDispatchCommand == "FormatLegend" )
454     {
455         eObjectType = OBJECTTYPE_LEGEND;
456         //@todo set particular aParticleID if we have more than one legend
457     }
458     //wall floor area
459     else if( rDispatchCommand == "DiagramWall" || rDispatchCommand == "FormatWall" )
460     {
461         //OBJECTTYPE_DIAGRAM;
462         eObjectType = OBJECTTYPE_DIAGRAM_WALL;
463         //@todo set particular aParticleID if we have more than one diagram
464     }
465     else if( rDispatchCommand == "DiagramFloor" || rDispatchCommand == "FormatFloor" )
466     {
467         eObjectType = OBJECTTYPE_DIAGRAM_FLOOR;
468         //@todo set particular aParticleID if we have more than one diagram
469     }
470     else if( rDispatchCommand == "DiagramArea" || rDispatchCommand == "FormatChartArea" )
471     {
472         eObjectType = OBJECTTYPE_PAGE;
473     }
474     //title
475     else if( rDispatchCommand == "MainTitle"
476         || rDispatchCommand == "SubTitle"
477         || rDispatchCommand == "XTitle"
478         || rDispatchCommand == "YTitle"
479         || rDispatchCommand == "ZTitle"
480         || rDispatchCommand == "SecondaryXTitle"
481         || rDispatchCommand == "SecondaryYTitle"
482         || rDispatchCommand == "AllTitles"
483         )
484     {
485         return lcl_getTitleCIDForCommand( rDispatchCommand, xChartModel );
486     }
487     //axis
488     else if( rDispatchCommand == "DiagramAxisX"
489         || rDispatchCommand == "DiagramAxisY"
490         || rDispatchCommand == "DiagramAxisZ"
491         || rDispatchCommand == "DiagramAxisA"
492         || rDispatchCommand == "DiagramAxisB"
493         || rDispatchCommand == "DiagramAxisAll"
494         )
495     {
496         return lcl_getAxisCIDForCommand( rDispatchCommand, xChartModel );
497     }
498     //grid
499     else if( rDispatchCommand == "DiagramGridYMain"
500         || rDispatchCommand == "DiagramGridXMain"
501         || rDispatchCommand == "DiagramGridZMain"
502         || rDispatchCommand == "DiagramGridYHelp"
503         || rDispatchCommand == "DiagramGridXHelp"
504         || rDispatchCommand == "DiagramGridZHelp"
505         || rDispatchCommand == "DiagramGridAll"
506         )
507     {
508         return lcl_getGridCIDForCommand( rDispatchCommand, xChartModel );
509     }
510     //data series
511     else if( rDispatchCommand == "FormatDataSeries" )
512     {
513         if( eSelectedType == OBJECTTYPE_DATA_SERIES )
514             return rSelectedCID;
515         else
516             return ObjectIdentifier::createClassifiedIdentifier(
517                 OBJECTTYPE_DATA_SERIES, ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID ) );
518     }
519     //data point
520     else if( rDispatchCommand == "FormatDataPoint" )
521     {
522         return rSelectedCID;
523     }
524     //data labels
525     else if( rDispatchCommand == "FormatDataLabels" )
526     {
527         if( eSelectedType == OBJECTTYPE_DATA_LABELS )
528             return rSelectedCID;
529         else
530             return ObjectIdentifier::createClassifiedIdentifierWithParent(
531                 OBJECTTYPE_DATA_LABELS, OUString(), rSelectedCID );
532     }
533     //data labels
534     else if( rDispatchCommand == "FormatDataLabel" )
535     {
536         if( eSelectedType == OBJECTTYPE_DATA_LABEL )
537             return rSelectedCID;
538         else
539         {
540             sal_Int32 nPointIndex = ObjectIdentifier::getParticleID( rSelectedCID ).toInt32();
541             if( nPointIndex>=0 )
542             {
543                 OUString aSeriesParticle = ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID );
544                 OUString aChildParticle( ObjectIdentifier::getStringForType( OBJECTTYPE_DATA_LABELS ) + "=" );
545                 OUString aLabelsCID = ObjectIdentifier::createClassifiedIdentifierForParticles( aSeriesParticle, aChildParticle );
546                 OUString aLabelCID_Stub = ObjectIdentifier::createClassifiedIdentifierWithParent(
547                     OBJECTTYPE_DATA_LABEL, OUString(), aLabelsCID );
548 
549                 return ObjectIdentifier::createPointCID( aLabelCID_Stub, nPointIndex );
550             }
551         }
552     }
553     //mean value line
554     else if( rDispatchCommand == "FormatMeanValue" )
555     {
556         if( eSelectedType == OBJECTTYPE_DATA_AVERAGE_LINE )
557             return rSelectedCID;
558         else
559             return ObjectIdentifier::createDataCurveCID(
560                 ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID ),
561                     RegressionCurveHelper::getRegressionCurveIndex( xRegCurveCnt,
562                         RegressionCurveHelper::getMeanValueLine( xRegCurveCnt ) ), true );
563     }
564     //trend line
565     else if( rDispatchCommand == "FormatTrendline" )
566     {
567         if( eSelectedType == OBJECTTYPE_DATA_CURVE )
568             return rSelectedCID;
569         else
570             return ObjectIdentifier::createDataCurveCID(
571                 ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID ),
572                     RegressionCurveHelper::getRegressionCurveIndex( xRegCurveCnt,
573                         RegressionCurveHelper::getFirstCurveNotMeanValueLine( xRegCurveCnt ) ), false );
574     }
575     //trend line equation
576     else if( rDispatchCommand == "FormatTrendlineEquation" )
577     {
578         if( eSelectedType == OBJECTTYPE_DATA_CURVE_EQUATION )
579             return rSelectedCID;
580         else
581             return ObjectIdentifier::createDataCurveEquationCID(
582                 ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID ),
583                     RegressionCurveHelper::getRegressionCurveIndex( xRegCurveCnt,
584                         RegressionCurveHelper::getFirstCurveNotMeanValueLine( xRegCurveCnt ) ) );
585     }
586     // y error bars
587     else if( rDispatchCommand == "FormatXErrorBars" )
588     {
589         return lcl_getErrorCIDForCommand(OBJECTTYPE_DATA_ERRORS_X, eSelectedType, rSelectedCID );
590     }
591     // y error bars
592     else if( rDispatchCommand == "FormatYErrorBars" )
593     {
594         return lcl_getErrorCIDForCommand(OBJECTTYPE_DATA_ERRORS_Y, eSelectedType, rSelectedCID );
595     }
596     // axis
597     else if( rDispatchCommand == "FormatAxis" )
598     {
599         if( eSelectedType == OBJECTTYPE_AXIS )
600             return rSelectedCID;
601         else
602         {
603             Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( rSelectedCID, xChartModel );
604             return ObjectIdentifier::createClassifiedIdentifierForObject( xAxis , xChartModel );
605         }
606     }
607     // major grid
608     else if( rDispatchCommand == "FormatMajorGrid" )
609     {
610         if( eSelectedType == OBJECTTYPE_GRID )
611             return rSelectedCID;
612         else
613         {
614             Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( rSelectedCID, xChartModel );
615             return ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel );
616         }
617 
618     }
619     // minor grid
620     else if( rDispatchCommand == "FormatMinorGrid" )
621     {
622         if( eSelectedType == OBJECTTYPE_SUBGRID )
623             return rSelectedCID;
624         else
625         {
626             Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( rSelectedCID, xChartModel );
627             return ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel, 0 /*sub grid index*/ );
628         }
629     }
630     // title
631     else if( rDispatchCommand == "FormatTitle" )
632     {
633         if( eSelectedType == OBJECTTYPE_TITLE )
634             return rSelectedCID;
635     }
636     // stock loss
637     else if( rDispatchCommand == "FormatStockLoss" )
638     {
639         if( eSelectedType == OBJECTTYPE_DATA_STOCK_LOSS )
640             return rSelectedCID;
641         else
642             return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DATA_STOCK_LOSS, OUString());
643     }
644     // stock gain
645     else if( rDispatchCommand == "FormatStockGain" )
646     {
647         if( eSelectedType == OBJECTTYPE_DATA_STOCK_GAIN )
648             return rSelectedCID;
649         else
650             return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DATA_STOCK_GAIN, OUString() );
651     }
652 
653     return ObjectIdentifier::createClassifiedIdentifier(
654         eObjectType,
655         OUString() ); // aParticleID
656 }
657 
658 }
659 // anonymous namespace
660 
executeDispatch_FormatObject(const OUString & rDispatchCommand)661 void ChartController::executeDispatch_FormatObject(const OUString& rDispatchCommand)
662 {
663     uno::Reference< XChartDocument > xChartDocument( getModel(), uno::UNO_QUERY );
664     OString aCommand( OUStringToOString( rDispatchCommand, RTL_TEXTENCODING_ASCII_US ) );
665     OUString rObjectCID = lcl_getObjectCIDForCommand( aCommand, xChartDocument, m_aSelection.getSelectedCID() );
666     executeDlg_ObjectProperties( rObjectCID );
667 }
668 
executeDispatch_ObjectProperties()669 void ChartController::executeDispatch_ObjectProperties()
670 {
671     executeDlg_ObjectProperties( m_aSelection.getSelectedCID() );
672 }
673 
674 namespace
675 {
676 
lcl_getFormatCIDforSelectedCID(const OUString & rSelectedCID)677 OUString lcl_getFormatCIDforSelectedCID( const OUString& rSelectedCID )
678 {
679     OUString aFormatCID(rSelectedCID);
680 
681     //get type of selected object
682     ObjectType eObjectType = ObjectIdentifier::getObjectType( aFormatCID );
683 
684     // some legend entries are handled as if they were data series
685     if( eObjectType==OBJECTTYPE_LEGEND_ENTRY )
686     {
687         OUString aParentParticle( ObjectIdentifier::getFullParentParticle( rSelectedCID ) );
688         aFormatCID  = ObjectIdentifier::createClassifiedIdentifierForParticle( aParentParticle );
689     }
690 
691     // treat diagram as wall
692     if( eObjectType==OBJECTTYPE_DIAGRAM )
693         aFormatCID  = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() );
694 
695     return aFormatCID;
696 }
697 
698 }//end anonymous namespace
699 
executeDlg_ObjectProperties(const OUString & rSelectedObjectCID)700 void ChartController::executeDlg_ObjectProperties( const OUString& rSelectedObjectCID )
701 {
702     OUString aObjectCID = lcl_getFormatCIDforSelectedCID( rSelectedObjectCID );
703 
704     UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription(
705                 ActionDescriptionProvider::ActionType::Format,
706                 ObjectNameProvider::getName( ObjectIdentifier::getObjectType( aObjectCID ))),
707             m_xUndoManager );
708 
709     bool bSuccess = ChartController::executeDlg_ObjectProperties_withoutUndoGuard( aObjectCID, false );
710     if( bSuccess )
711         aUndoGuard.commit();
712 }
713 
executeDlg_ObjectProperties_withoutUndoGuard(const OUString & rObjectCID,bool bSuccessOnUnchanged)714 bool ChartController::executeDlg_ObjectProperties_withoutUndoGuard(
715     const OUString& rObjectCID, bool bSuccessOnUnchanged )
716 {
717     //return true if the properties were changed successfully
718     bool bRet = false;
719     if( rObjectCID.isEmpty() )
720     {
721        return bRet;
722     }
723     try
724     {
725         //get type of object
726         ObjectType eObjectType = ObjectIdentifier::getObjectType( rObjectCID );
727         if( eObjectType==OBJECTTYPE_UNKNOWN )
728         {
729             return bRet;
730         }
731         if( eObjectType==OBJECTTYPE_DIAGRAM_WALL || eObjectType==OBJECTTYPE_DIAGRAM_FLOOR )
732         {
733             if( !DiagramHelper::isSupportingFloorAndWall( ChartModelHelper::findDiagram( getModel() ) ) )
734                 return bRet;
735         }
736 
737         //convert properties to ItemSet
738 
739         std::unique_ptr<ReferenceSizeProvider> pRefSizeProv(impl_createReferenceSizeProvider());
740 
741         std::unique_ptr<wrapper::ItemConverter> pItemConverter(
742             createItemConverter( rObjectCID, getModel(), m_xCC,
743                                  m_pDrawModelWrapper->getSdrModel(),
744                                  comphelper::getUnoTunnelImplementation<ExplicitValueProvider>(m_xChartView),
745                                  pRefSizeProv.get()));
746 
747         if (!pItemConverter)
748             return bRet;
749 
750         SfxItemSet aItemSet = pItemConverter->CreateEmptyItemSet();
751 
752         if ( eObjectType == OBJECTTYPE_DATA_ERRORS_X || eObjectType == OBJECTTYPE_DATA_ERRORS_Y )
753             aItemSet.Put(SfxBoolItem(SCHATTR_STAT_ERRORBAR_TYPE, eObjectType == OBJECTTYPE_DATA_ERRORS_Y ));
754 
755         pItemConverter->FillItemSet(aItemSet);
756 
757         //prepare dialog
758         ObjectPropertiesDialogParameter aDialogParameter( rObjectCID );
759         aDialogParameter.init( getModel() );
760         ViewElementListProvider aViewElementListProvider( m_pDrawModelWrapper.get() );
761 
762         SolarMutexGuard aGuard;
763         SchAttribTabDlg aDlg(
764                 GetChartFrame(), &aItemSet, &aDialogParameter,
765                 &aViewElementListProvider,
766                 uno::Reference< util::XNumberFormatsSupplier >(
767                         getModel(), uno::UNO_QUERY ) );
768 
769         if(aDialogParameter.HasSymbolProperties())
770         {
771             uno::Reference< beans::XPropertySet > xObjectProperties =
772                 ObjectIdentifier::getObjectPropertySet( rObjectCID, getModel() );
773             wrapper::DataPointItemConverter aSymbolItemConverter( getModel(), m_xCC
774                                         , xObjectProperties, ObjectIdentifier::getDataSeriesForCID( rObjectCID, getModel() )
775                                         , m_pDrawModelWrapper->getSdrModel().GetItemPool()
776                                         , m_pDrawModelWrapper->getSdrModel()
777                                         , uno::Reference< lang::XMultiServiceFactory >( getModel(), uno::UNO_QUERY )
778                                         , wrapper::GraphicObjectType::FilledDataPoint );
779 
780             std::unique_ptr<SfxItemSet> pSymbolShapeProperties(new SfxItemSet( aSymbolItemConverter.CreateEmptyItemSet() ));
781             aSymbolItemConverter.FillItemSet( *pSymbolShapeProperties );
782 
783             sal_Int32 const nStandardSymbol=0;//@todo get from somewhere
784             std::unique_ptr<Graphic> pAutoSymbolGraphic(new Graphic( aViewElementListProvider.GetSymbolGraphic( nStandardSymbol, pSymbolShapeProperties.get() ) ));
785             // note: the dialog takes the ownership of pSymbolShapeProperties and pAutoSymbolGraphic
786             aDlg.setSymbolInformation( std::move(pSymbolShapeProperties), std::move(pAutoSymbolGraphic) );
787         }
788         if( aDialogParameter.HasStatisticProperties() )
789         {
790             aDlg.SetAxisMinorStepWidthForErrorBarDecimals(
791                 InsertErrorBarsDialog::getAxisMinorStepWidthForErrorBarDecimals( getModel(), m_xChartView, rObjectCID ) );
792         }
793 
794         //open the dialog
795         if (aDlg.run() == RET_OK || (bSuccessOnUnchanged && aDlg.DialogWasClosedWithOK()))
796         {
797             const SfxItemSet* pOutItemSet = aDlg.GetOutputItemSet();
798             if(pOutItemSet)
799             {
800                 ControllerLockGuardUNO aCLGuard( getModel());
801                 (void)pItemConverter->ApplyItemSet(*pOutItemSet); //model should be changed now
802                 bRet = true;
803             }
804         }
805     }
806     catch( const util::CloseVetoException& )
807     {
808     }
809     catch( const uno::RuntimeException& )
810     {
811     }
812     return bRet;
813 }
814 
executeDispatch_View3D()815 void ChartController::executeDispatch_View3D()
816 {
817     try
818     {
819         UndoLiveUpdateGuard aUndoGuard(
820             SchResId( STR_ACTION_EDIT_3D_VIEW ),
821             m_xUndoManager );
822 
823         //open dialog
824         SolarMutexGuard aSolarGuard;
825         View3DDialog aDlg(GetChartFrame(), getModel());
826         if (aDlg.run() == RET_OK)
827             aUndoGuard.commit();
828     }
829     catch(const uno::RuntimeException&)
830     {
831         TOOLS_WARN_EXCEPTION("chart2", "" );
832     }
833 }
834 
835 } //namespace chart
836 
837 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
838