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 "ControllerCommandDispatch.hxx"
21 #include <ChartModelHelper.hxx>
22 #include <ChartModel.hxx>
23 #include <DiagramHelper.hxx>
24 #include <AxisHelper.hxx>
25 #include <TitleHelper.hxx>
26 #include <LegendHelper.hxx>
27 #include <ObjectIdentifier.hxx>
28 #include <ChartTypeHelper.hxx>
29 #include <ChartController.hxx>
30 #include <RegressionCurveHelper.hxx>
31 #include <DataSeriesHelper.hxx>
32 #include <StatisticsHelper.hxx>
33 #include <ReferenceSizeProvider.hxx>
34 #include "ShapeController.hxx"
35
36 #include <vcl/svapp.hxx>
37 #include <sal/log.hxx>
38 #include <tools/diagnose_ex.h>
39
40 #include <com/sun/star/util/XModifyBroadcaster.hpp>
41 #include <com/sun/star/frame/XStorable.hpp>
42 #include <com/sun/star/chart2/XChartDocument.hpp>
43 #include <com/sun/star/chart2/XRegressionCurve.hpp>
44 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
45 #include <com/sun/star/chart2/XDataProviderAccess.hpp>
46
47 // only needed until #i68864# is fixed
48 #include <com/sun/star/frame/XLayoutManager.hpp>
49
50 using namespace ::com::sun::star;
51
52 using ::com::sun::star::uno::Reference;
53 using ::com::sun::star::uno::Sequence;
54
55 namespace
56 {
lcl_isStatusBarVisible(const Reference<frame::XController> & xController)57 bool lcl_isStatusBarVisible( const Reference< frame::XController > & xController )
58 {
59 bool bIsStatusBarVisible = false;
60 // Status-Bar visible, workaround: this should not be necessary. @todo:
61 // remove when Issue #i68864# is fixed
62 if( xController.is())
63 {
64 Reference< beans::XPropertySet > xPropSet( xController->getFrame(), uno::UNO_QUERY );
65 if( xPropSet.is() )
66 {
67 uno::Reference< css::frame::XLayoutManager > xLayoutManager;
68 xPropSet->getPropertyValue( "LayoutManager" ) >>= xLayoutManager;
69 if ( xLayoutManager.is() )
70 bIsStatusBarVisible = xLayoutManager->isElementVisible( "private:resource/statusbar/statusbar" );
71 }
72 }
73 return bIsStatusBarVisible;
74 }
75
76 } // anonymous namespace
77
78 namespace chart
79 {
80
81 namespace impl
82 {
83
84 /// Constants for moving the series.
85 namespace {
86 static bool const MOVE_SERIES_FORWARD = true;
87 static bool const MOVE_SERIES_BACKWARD = false;
88 }
89
90 /** Represents the current state of the controller (needed for issue 63017).
91
92 You can set the state by calling update(). After this call the state is
93 preserved in this class until the next call to update().
94
95 This is useful, not to say necessary, for enabling and disabling of menu
96 entries (e.g. format>arrangement). As the status requests are sent very
97 frequently it would be impossible, from a performance point of view, to
98 query the current status every time directly at the model. So this class
99 serves as a cache for the state.
100 */
101 struct ControllerState
102 {
103 ControllerState();
104
105 void update( const Reference< frame::XController > & xController,
106 const Reference< frame::XModel > & xModel );
107
108 // -- State variables -------
109 bool bHasSelectedObject;
110 bool bIsPositionableObject;
111 bool bIsTextObject;
112 bool bIsDeleteableObjectSelected;
113 bool bIsFormateableObjectSelected;
114
115 // May the selected series be moved forward or backward (cf
116 // format>arrangement).
117 bool bMayMoveSeriesForward;
118 bool bMayMoveSeriesBackward;
119
120 // trendlines
121 bool bMayAddMenuTrendline;
122 bool bMayAddTrendline;
123 bool bMayAddTrendlineEquation;
124 bool bMayAddR2Value;
125 bool bMayAddMeanValue;
126 bool bMayAddXErrorBars;
127 bool bMayAddYErrorBars;
128
129 bool bMayDeleteTrendline;
130 bool bMayDeleteTrendlineEquation;
131 bool bMayDeleteR2Value;
132 bool bMayDeleteMeanValue;
133 bool bMayDeleteXErrorBars;
134 bool bMayDeleteYErrorBars;
135
136 bool bMayFormatTrendline;
137 bool bMayFormatTrendlineEquation;
138 bool bMayFormatMeanValue;
139 bool bMayFormatXErrorBars;
140 bool bMayFormatYErrorBars;
141 };
142
ControllerState()143 ControllerState::ControllerState() :
144 bHasSelectedObject( false ),
145 bIsPositionableObject( false ),
146 bIsTextObject(false),
147 bIsDeleteableObjectSelected(false),
148 bIsFormateableObjectSelected(false),
149 bMayMoveSeriesForward( false ),
150 bMayMoveSeriesBackward( false ),
151 bMayAddMenuTrendline( false ),
152 bMayAddTrendline( false ),
153 bMayAddTrendlineEquation( false ),
154 bMayAddR2Value( false ),
155 bMayAddMeanValue( false ),
156 bMayAddXErrorBars( false ),
157 bMayAddYErrorBars( false ),
158 bMayDeleteTrendline( false ),
159 bMayDeleteTrendlineEquation( false ),
160 bMayDeleteR2Value( false ),
161 bMayDeleteMeanValue( false ),
162 bMayDeleteXErrorBars( false ),
163 bMayDeleteYErrorBars( false ),
164 bMayFormatTrendline( false ),
165 bMayFormatTrendlineEquation( false ),
166 bMayFormatMeanValue( false ),
167 bMayFormatXErrorBars( false ),
168 bMayFormatYErrorBars( false )
169 {}
170
update(const Reference<frame::XController> & xController,const Reference<frame::XModel> & xModel)171 void ControllerState::update(
172 const Reference< frame::XController > & xController,
173 const Reference< frame::XModel > & xModel )
174 {
175 Reference< view::XSelectionSupplier > xSelectionSupplier(
176 xController, uno::UNO_QUERY );
177
178 // Update ControllerState variables.
179 if( xSelectionSupplier.is())
180 {
181 uno::Any aSelObj( xSelectionSupplier->getSelection() );
182 ObjectIdentifier aSelOID( aSelObj );
183 OUString aSelObjCID( aSelOID.getObjectCID() );
184
185 bHasSelectedObject = aSelOID.isValid();
186
187 ObjectType aObjectType(ObjectIdentifier::getObjectType( aSelObjCID ));
188
189 bIsPositionableObject = (aObjectType != OBJECTTYPE_DATA_POINT) && aSelOID.isDragableObject();
190 bIsTextObject = aObjectType == OBJECTTYPE_TITLE;
191
192 uno::Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( xModel ));
193 bIsFormateableObjectSelected = bHasSelectedObject && aSelOID.isAutoGeneratedObject();
194 if( aObjectType==OBJECTTYPE_DIAGRAM || aObjectType==OBJECTTYPE_DIAGRAM_WALL || aObjectType==OBJECTTYPE_DIAGRAM_FLOOR )
195 bIsFormateableObjectSelected = DiagramHelper::isSupportingFloorAndWall( xDiagram );
196
197 uno::Reference< chart2::XDataSeries > xGivenDataSeries(
198 ObjectIdentifier::getDataSeriesForCID(
199 aSelObjCID, xModel ) );
200
201 bIsDeleteableObjectSelected = ChartController::isObjectDeleteable( aSelObj );
202
203 bMayMoveSeriesForward = (aObjectType!=OBJECTTYPE_DATA_POINT) && DiagramHelper::isSeriesMoveable(
204 ChartModelHelper::findDiagram( xModel ),
205 xGivenDataSeries,
206 MOVE_SERIES_FORWARD );
207
208 bMayMoveSeriesBackward = (aObjectType!=OBJECTTYPE_DATA_POINT) && DiagramHelper::isSeriesMoveable(
209 ChartModelHelper::findDiagram( xModel ),
210 xGivenDataSeries,
211 MOVE_SERIES_BACKWARD );
212
213 bMayAddMenuTrendline = false;
214 bMayAddTrendline = false;
215 bMayAddTrendlineEquation = false;
216 bMayAddR2Value = false;
217 bMayAddMeanValue = false;
218 bMayAddXErrorBars = false;
219 bMayAddYErrorBars = false;
220 bMayDeleteTrendline = false;
221 bMayDeleteTrendlineEquation = false;
222 bMayDeleteR2Value = false;
223 bMayDeleteMeanValue = false;
224 bMayDeleteXErrorBars = false;
225 bMayDeleteYErrorBars = false;
226 bMayFormatTrendline = false;
227 bMayFormatTrendlineEquation = false;
228 bMayFormatMeanValue = false;
229 bMayFormatXErrorBars = false;
230 bMayFormatYErrorBars = false;
231 if( bHasSelectedObject )
232 {
233 if( xGivenDataSeries.is())
234 {
235 bMayAddMenuTrendline = true;
236 sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
237 uno::Reference< chart2::XChartType > xFirstChartType(
238 DataSeriesHelper::getChartTypeOfSeries( xGivenDataSeries, xDiagram ));
239
240 // trend lines/mean value line
241 if( (aObjectType == OBJECTTYPE_DATA_SERIES || aObjectType == OBJECTTYPE_DATA_POINT)
242 && ChartTypeHelper::isSupportingRegressionProperties( xFirstChartType, nDimensionCount ))
243 {
244 uno::Reference< chart2::XRegressionCurveContainer > xRegCurveCnt( xGivenDataSeries, uno::UNO_QUERY );
245 if( xRegCurveCnt.is())
246 {
247 // Trendline
248 bMayAddTrendline = true;
249
250 // Mean Value
251 bMayFormatMeanValue = bMayDeleteMeanValue = RegressionCurveHelper::hasMeanValueLine( xRegCurveCnt );
252 bMayAddMeanValue = ! bMayDeleteMeanValue;
253 }
254 }
255
256 // error bars
257 if( (aObjectType == OBJECTTYPE_DATA_SERIES || aObjectType == OBJECTTYPE_DATA_POINT)
258 && ChartTypeHelper::isSupportingStatisticProperties( xFirstChartType, nDimensionCount ))
259 {
260 bMayFormatXErrorBars = bMayDeleteXErrorBars = StatisticsHelper::hasErrorBars( xGivenDataSeries, false );
261 bMayAddXErrorBars = ! bMayDeleteXErrorBars;
262
263 bMayFormatYErrorBars = bMayDeleteYErrorBars = StatisticsHelper::hasErrorBars( xGivenDataSeries );
264 bMayAddYErrorBars = ! bMayDeleteYErrorBars;
265 }
266 }
267
268 if( aObjectType == OBJECTTYPE_DATA_AVERAGE_LINE )
269 bMayFormatMeanValue = true;
270
271 if( aObjectType == OBJECTTYPE_DATA_ERRORS_X)
272 bMayFormatXErrorBars = true;
273
274 if( aObjectType == OBJECTTYPE_DATA_ERRORS_Y )
275 bMayFormatYErrorBars = true;
276
277 if( aObjectType == OBJECTTYPE_DATA_CURVE )
278 {
279 bMayFormatTrendline = true;
280 bMayDeleteTrendline = true;
281 uno::Reference< chart2::XRegressionCurve > xRegCurve(
282 ObjectIdentifier::getObjectPropertySet( aSelObjCID, xModel ), uno::UNO_QUERY );
283
284 // Trendline Equation
285 bMayFormatTrendlineEquation = bMayDeleteTrendlineEquation = RegressionCurveHelper::hasEquation( xRegCurve );
286 bMayAddTrendlineEquation = !bMayDeleteTrendlineEquation;
287 }
288 else if( aObjectType == OBJECTTYPE_DATA_CURVE_EQUATION )
289 {
290 bMayFormatTrendlineEquation = true;
291 bool bHasR2Value = false;
292 try
293 {
294 uno::Reference< beans::XPropertySet > xEquationProperties =
295 ObjectIdentifier::getObjectPropertySet( aSelObjCID, xModel );
296 if( xEquationProperties.is() )
297 xEquationProperties->getPropertyValue( "ShowCorrelationCoefficient" ) >>= bHasR2Value;
298 }
299 catch(const uno::RuntimeException&)
300 {
301 TOOLS_WARN_EXCEPTION("chart2", "" );
302 }
303 bMayAddR2Value = !bHasR2Value;
304 bMayDeleteR2Value = bHasR2Value;
305 }
306 }
307 }
308 }
309
310 /** Represents the current state of the model.
311
312 You can set the state by calling update(). After this call the state is
313 preserved in this class until the next call to update().
314
315 This is useful, not to say necessary, for enabling and disabling of menu
316 entries and toolbar icons. As the status requests are sent very frequently
317 it would be impossible, from a performance point of view, to query the
318 current status every time directly at the model. So this class serves as a
319 cache for the state.
320 */
321 struct ModelState
322 {
323 ModelState();
324
325 void update( const Reference< frame::XModel > & xModel );
326
327 bool HasAnyAxis() const;
328 bool HasAnyGrid() const;
329 bool HasAnyTitle() const;
330
331 bool bIsReadOnly;
332 bool bIsThreeD;
333 bool bHasOwnData;
334 bool bHasDataFromPivotTable;
335
336 bool bHasMainTitle;
337 bool bHasSubTitle;
338 bool bHasXAxisTitle;
339 bool bHasYAxisTitle;
340 bool bHasZAxisTitle;
341 bool bHasSecondaryXAxisTitle;
342 bool bHasSecondaryYAxisTitle;
343
344 bool bHasXAxis;
345 bool bHasYAxis;
346 bool bHasZAxis;
347 bool bHasAAxis;
348 bool bHasBAxis;
349
350 bool bHasMainXGrid;
351 bool bHasMainYGrid;
352 bool bHasMainZGrid;
353 bool bHasHelpXGrid;
354 bool bHasHelpYGrid;
355 bool bHasHelpZGrid;
356
357 bool bHasAutoScaledText;
358 bool bHasLegend;
359 bool bHasWall;
360 bool bHasFloor;
361
362 bool bSupportsStatistics;
363 bool bSupportsAxes;
364 };
365
ModelState()366 ModelState::ModelState() :
367 bIsReadOnly(true),
368 bIsThreeD(false),
369 bHasOwnData(false),
370 bHasDataFromPivotTable(false),
371 bHasMainTitle(false),
372 bHasSubTitle(false),
373 bHasXAxisTitle(false),
374 bHasYAxisTitle(false),
375 bHasZAxisTitle(false),
376 bHasSecondaryXAxisTitle(false),
377 bHasSecondaryYAxisTitle(false),
378 bHasXAxis(false),
379 bHasYAxis(false),
380 bHasZAxis(false),
381 bHasAAxis(false),
382 bHasBAxis(false),
383 bHasMainXGrid(false),
384 bHasMainYGrid(false),
385 bHasMainZGrid(false),
386 bHasHelpXGrid(false),
387 bHasHelpYGrid(false),
388 bHasHelpZGrid(false),
389 bHasAutoScaledText(false),
390 bHasLegend(false),
391 bHasWall(false),
392 bHasFloor(false),
393 bSupportsStatistics(false),
394 bSupportsAxes(false)
395 {}
396
update(const Reference<frame::XModel> & xModel)397 void ModelState::update( const Reference< frame::XModel > & xModel )
398 {
399 Reference< chart2::XChartDocument > xChartDoc( xModel, uno::UNO_QUERY );
400 Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( xModel ));
401
402 bIsReadOnly = true;
403 Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY );
404 if( xStorable.is())
405 bIsReadOnly = xStorable->isReadonly();
406
407 sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
408
409 uno::Reference< chart2::XChartType > xFirstChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
410 bSupportsStatistics = ChartTypeHelper::isSupportingStatisticProperties( xFirstChartType, nDimensionCount );
411 bSupportsAxes = ChartTypeHelper::isSupportingMainAxis( xFirstChartType, nDimensionCount, 0 );
412
413 bIsThreeD = (nDimensionCount == 3);
414 if (xChartDoc.is())
415 {
416 ChartModel& rModel = dynamic_cast<ChartModel&>(*xChartDoc);
417 bHasOwnData = rModel.hasInternalDataProvider();
418 bHasDataFromPivotTable = !bHasOwnData && rModel.isDataFromPivotTable();
419 }
420
421 bHasMainTitle = TitleHelper::getTitle( TitleHelper::MAIN_TITLE, xModel ).is();
422 bHasSubTitle = TitleHelper::getTitle( TitleHelper::SUB_TITLE, xModel ).is();
423 bHasXAxisTitle = TitleHelper::getTitle( TitleHelper::X_AXIS_TITLE, xModel ).is();
424 bHasYAxisTitle = TitleHelper::getTitle( TitleHelper::Y_AXIS_TITLE, xModel ).is();
425 bHasZAxisTitle = TitleHelper::getTitle( TitleHelper::Z_AXIS_TITLE, xModel ).is();
426 bHasSecondaryXAxisTitle = TitleHelper::getTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, xModel ).is();
427 bHasSecondaryYAxisTitle = TitleHelper::getTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, xModel ).is();
428
429 bHasXAxis = bSupportsAxes && AxisHelper::getAxis( 0, true, xDiagram ).is();
430 bHasYAxis = bSupportsAxes && AxisHelper::getAxis( 1, true, xDiagram ).is();
431 bHasZAxis = bSupportsAxes && AxisHelper::getAxis( 2, true, xDiagram ).is();
432 bHasAAxis = bSupportsAxes && AxisHelper::getAxis( 0, false, xDiagram ).is();
433 bHasBAxis = bSupportsAxes && AxisHelper::getAxis( 1, false, xDiagram ).is();
434
435 bHasMainXGrid = bSupportsAxes && AxisHelper::isGridShown( 0, 0, true, xDiagram );
436 bHasMainYGrid = bSupportsAxes && AxisHelper::isGridShown( 1, 0, true, xDiagram );
437 bHasMainZGrid = bSupportsAxes && AxisHelper::isGridShown( 2, 0, true, xDiagram );
438 bHasHelpXGrid = bSupportsAxes && AxisHelper::isGridShown( 0, 0, false, xDiagram );
439 bHasHelpYGrid = bSupportsAxes && AxisHelper::isGridShown( 1, 0, false, xDiagram );
440 bHasHelpZGrid = bSupportsAxes && AxisHelper::isGridShown( 2, 0, false, xDiagram );
441
442 bHasAutoScaledText =
443 (ReferenceSizeProvider::getAutoResizeState( xChartDoc ) ==
444 ReferenceSizeProvider::AUTO_RESIZE_YES);
445
446 bHasLegend = LegendHelper::hasLegend( xDiagram );
447 bHasWall = DiagramHelper::isSupportingFloorAndWall( xDiagram );
448 bHasFloor = bHasWall && bIsThreeD;
449 }
450
HasAnyAxis() const451 bool ModelState::HasAnyAxis() const
452 {
453 return bHasXAxis || bHasYAxis || bHasZAxis || bHasAAxis || bHasBAxis;
454 }
455
HasAnyGrid() const456 bool ModelState::HasAnyGrid() const
457 {
458 return bHasMainXGrid || bHasMainYGrid || bHasMainZGrid ||
459 bHasHelpXGrid || bHasHelpYGrid || bHasHelpZGrid;
460 }
461
HasAnyTitle() const462 bool ModelState::HasAnyTitle() const
463 {
464 return bHasMainTitle || bHasSubTitle || bHasXAxisTitle || bHasYAxisTitle || bHasZAxisTitle || bHasSecondaryXAxisTitle || bHasSecondaryYAxisTitle;
465 }
466
467 } // namespace impl
468
ControllerCommandDispatch(const Reference<uno::XComponentContext> & xContext,ChartController * pController,CommandDispatchContainer * pContainer)469 ControllerCommandDispatch::ControllerCommandDispatch(
470 const Reference< uno::XComponentContext > & xContext,
471 ChartController* pController, CommandDispatchContainer* pContainer ) :
472 impl::ControllerCommandDispatch_Base( xContext ),
473 m_xChartController( pController ),
474 m_xSelectionSupplier( Reference< view::XSelectionSupplier >( pController ) ),
475 m_xDispatch( Reference< frame::XDispatch >( pController ) ),
476 m_apModelState( new impl::ModelState() ),
477 m_apControllerState( new impl::ControllerState() ),
478 m_pDispatchContainer( pContainer )
479 {
480 }
481
~ControllerCommandDispatch()482 ControllerCommandDispatch::~ControllerCommandDispatch()
483 {
484 }
485
initialize()486 void ControllerCommandDispatch::initialize()
487 {
488 if( m_xChartController.is())
489 {
490 Reference< frame::XModel > xModel( m_xChartController->getModel());
491 Reference< util::XModifyBroadcaster > xModifyBroadcaster( xModel, uno::UNO_QUERY );
492 OSL_ASSERT( xModifyBroadcaster.is());
493 if( xModifyBroadcaster.is())
494 xModifyBroadcaster->addModifyListener( this );
495
496 // Listen selection modifications (Arrangement feature - issue 63017).
497 if( m_xSelectionSupplier.is() )
498 m_xSelectionSupplier->addSelectionChangeListener( this );
499
500 if( m_apModelState.get() && xModel.is())
501 m_apModelState->update( xModel );
502
503 if( m_apControllerState.get() && xModel.is())
504 m_apControllerState->update( m_xChartController.get(), xModel );
505
506 updateCommandAvailability();
507 }
508 }
509
fireStatusEventForURLImpl(const OUString & rURL,const Reference<frame::XStatusListener> & xSingleListener)510 void ControllerCommandDispatch::fireStatusEventForURLImpl(
511 const OUString & rURL,
512 const Reference< frame::XStatusListener > & xSingleListener )
513 {
514 std::map< OUString, uno::Any >::const_iterator aArgIt( m_aCommandArguments.find( rURL ));
515 if( aArgIt != m_aCommandArguments.end())
516 fireStatusEventForURL( rURL, aArgIt->second, commandAvailable( rURL ), xSingleListener );
517 else
518 fireStatusEventForURL( rURL, uno::Any(), commandAvailable( rURL ), xSingleListener );
519 }
520
updateCommandAvailability()521 void ControllerCommandDispatch::updateCommandAvailability()
522 {
523 bool bModelStateIsValid = (m_apModelState != nullptr);
524 bool bControllerStateIsValid = (m_apControllerState != nullptr);
525 // Model and controller states exist.
526 OSL_ASSERT( bModelStateIsValid );
527 OSL_ASSERT( bControllerStateIsValid );
528
529 // read-only
530 bool bIsWritable = bModelStateIsValid && (! m_apModelState->bIsReadOnly);
531 bool bShapeContext = m_xChartController.is() && m_xChartController->isShapeContext();
532
533 bool bEnableDataTableDialog = false;
534 bool bCanCreateDataProvider = false;
535
536 if ( m_xChartController.is() )
537 {
538 Reference< beans::XPropertySet > xProps( m_xChartController->getModel(), uno::UNO_QUERY );
539 if ( xProps.is() )
540 {
541 try
542 {
543 xProps->getPropertyValue("EnableDataTableDialog") >>= bEnableDataTableDialog;
544 }
545 catch( const uno::Exception& )
546 {
547 TOOLS_WARN_EXCEPTION("chart2", "" );
548 }
549 }
550
551 Reference< chart2::XChartDocument > xChartDoc(m_xChartController->getModel(), uno::UNO_QUERY);
552 OSL_ENSURE(xChartDoc.is(), "Invalid XChartDocument");
553 if ( xChartDoc.is() )
554 {
555 ChartModel& rModel = dynamic_cast<ChartModel&>(*xChartDoc);
556 css::uno::Reference< com::sun::star::chart2::XDataProviderAccess > xCreatorDoc(rModel.getParent(), uno::UNO_QUERY);
557 bCanCreateDataProvider = xCreatorDoc.is();
558 }
559 }
560
561 // edit commands
562 m_aCommandAvailability[ ".uno:Cut" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bIsDeleteableObjectSelected;
563 m_aCommandAvailability[ ".uno:Copy" ] = bControllerStateIsValid && m_apControllerState->bHasSelectedObject;
564 m_aCommandAvailability[ ".uno:Paste" ] = bIsWritable;
565
566 // toolbar commands
567 m_aCommandAvailability[ ".uno:ToggleGridHorizontal" ] = bIsWritable;
568 m_aCommandArguments[ ".uno:ToggleGridHorizontal" ] <<= m_apModelState->bHasMainYGrid;
569 m_aCommandAvailability[ ".uno:ToggleGridVertical" ] = bIsWritable;
570 m_aCommandArguments[ ".uno:ToggleGridVertical" ] <<= m_apModelState->bHasMainXGrid;
571
572 m_aCommandAvailability[ ".uno:ToggleLegend" ] = bIsWritable;
573 m_aCommandArguments[ ".uno:ToggleLegend" ] <<= m_apModelState->bHasLegend;
574
575 m_aCommandAvailability[ ".uno:NewArrangement" ] = bIsWritable;
576 m_aCommandAvailability[ ".uno:Update" ] = bIsWritable;
577 m_aCommandAvailability[ ".uno:DefaultColors" ] = bIsWritable;
578 m_aCommandAvailability[ ".uno:BarWidth" ] = bIsWritable;
579 m_aCommandAvailability[ ".uno:NumberOfLines" ] = bIsWritable;
580 m_aCommandAvailability[ ".uno:ArrangeRow" ] =
581 bShapeContext || ( bIsWritable && bControllerStateIsValid && ( m_apControllerState->bMayMoveSeriesForward || m_apControllerState->bMayMoveSeriesBackward ) );
582
583 // insert objects
584 m_aCommandAvailability[ ".uno:InsertTitles" ] = m_aCommandAvailability[ ".uno:InsertMenuTitles" ] = bIsWritable;
585 m_aCommandAvailability[ ".uno:InsertLegend" ] = m_aCommandAvailability[ ".uno:InsertMenuLegend" ] = bIsWritable;
586 m_aCommandAvailability[ ".uno:DeleteLegend" ] = bIsWritable;
587 m_aCommandAvailability[ ".uno:InsertMenuDataLabels" ] = bIsWritable;
588 m_aCommandAvailability[ ".uno:InsertRemoveAxes" ] = m_aCommandAvailability[ ".uno:InsertMenuAxes" ] = bIsWritable && m_apModelState->bSupportsAxes;
589 m_aCommandAvailability[ ".uno:InsertMenuGrids" ] = bIsWritable && m_apModelState->bSupportsAxes;
590 m_aCommandAvailability[ ".uno:InsertMenuTrendlines" ] = bIsWritable && m_apModelState->bSupportsStatistics && m_apControllerState->bMayAddMenuTrendline;
591 m_aCommandAvailability[ ".uno:InsertMenuMeanValues" ] = bIsWritable && m_apModelState->bSupportsStatistics;
592 m_aCommandAvailability[ ".uno:InsertMenuXErrorBars" ] = bIsWritable && m_apModelState->bSupportsStatistics;
593 m_aCommandAvailability[ ".uno:InsertMenuYErrorBars" ] = bIsWritable && m_apModelState->bSupportsStatistics;
594 m_aCommandAvailability[ ".uno:InsertSymbol" ] = bIsWritable && m_apControllerState->bIsTextObject;
595
596 // format objects
597 bool bFormatObjectAvailable = bIsWritable && bControllerStateIsValid && m_apControllerState->bIsFormateableObjectSelected;
598 m_aCommandAvailability[ ".uno:FormatSelection" ] = bFormatObjectAvailable;
599 m_aCommandAvailability[ ".uno:FormatAxis" ] = bFormatObjectAvailable;
600 m_aCommandAvailability[ ".uno:FormatTitle" ] = bFormatObjectAvailable;
601 m_aCommandAvailability[ ".uno:FormatDataSeries" ] = bFormatObjectAvailable;
602 m_aCommandAvailability[ ".uno:FormatDataPoint" ] = bFormatObjectAvailable;
603 m_aCommandAvailability[ ".uno:FormatDataLabels" ] = bFormatObjectAvailable;
604 m_aCommandAvailability[ ".uno:FormatDataLabel" ] = bFormatObjectAvailable;
605 m_aCommandAvailability[ ".uno:FormatXErrorBars" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayFormatXErrorBars;
606 m_aCommandAvailability[ ".uno:FormatYErrorBars" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayFormatYErrorBars;
607 m_aCommandAvailability[ ".uno:FormatMeanValue" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayFormatMeanValue;
608 m_aCommandAvailability[ ".uno:FormatTrendline" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayFormatTrendline;
609 m_aCommandAvailability[ ".uno:FormatTrendlineEquation" ] = bFormatObjectAvailable && bControllerStateIsValid && m_apControllerState->bMayFormatTrendlineEquation;
610 m_aCommandAvailability[ ".uno:FormatStockLoss" ] = bFormatObjectAvailable;
611 m_aCommandAvailability[ ".uno:FormatStockGain" ] = bFormatObjectAvailable;
612
613 m_aCommandAvailability[ ".uno:DiagramType" ] = bIsWritable;
614 m_aCommandAvailability[ ".uno:Legend" ] = bIsWritable && m_apModelState->bHasLegend;
615 m_aCommandAvailability[ ".uno:DiagramWall" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasWall;
616 m_aCommandAvailability[ ".uno:DiagramArea" ] = bIsWritable;
617
618 m_aCommandAvailability[ ".uno:TransformDialog" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bHasSelectedObject && m_apControllerState->bIsPositionableObject;
619
620 // 3d commands
621 m_aCommandAvailability[ ".uno:View3D" ] = bIsWritable && bModelStateIsValid && m_apModelState->bIsThreeD;
622 m_aCommandAvailability[ ".uno:DiagramFloor" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasFloor;
623
624 //some more format commands with different ui text
625 m_aCommandAvailability[ ".uno:FormatWall" ] = m_aCommandAvailability[ ".uno:DiagramWall" ];
626 m_aCommandAvailability[ ".uno:FormatFloor" ] = m_aCommandAvailability[ ".uno:DiagramFloor" ];
627 m_aCommandAvailability[ ".uno:FormatChartArea" ] = m_aCommandAvailability[ ".uno:DiagramArea" ];
628 m_aCommandAvailability[ ".uno:FormatLegend" ] = m_aCommandAvailability[ ".uno:Legend" ];
629
630 // depending on own data and ability to create new data provider
631 m_aCommandAvailability[".uno:DataRanges"] = bIsWritable && bModelStateIsValid && !m_apModelState->bHasDataFromPivotTable
632 && ((m_apModelState->bHasOwnData && bCanCreateDataProvider) || !m_apModelState->bHasOwnData);
633 m_aCommandAvailability[ ".uno:DiagramData" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasOwnData && bEnableDataTableDialog;
634
635 // titles
636 m_aCommandAvailability[ ".uno:MainTitle" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasMainTitle;
637 m_aCommandAvailability[ ".uno:SubTitle" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasSubTitle;
638 m_aCommandAvailability[ ".uno:XTitle" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasXAxisTitle;
639 m_aCommandAvailability[ ".uno:YTitle" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasYAxisTitle;
640 m_aCommandAvailability[ ".uno:ZTitle" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasZAxisTitle;
641 m_aCommandAvailability[ ".uno:SecondaryXTitle" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasSecondaryXAxisTitle;
642 m_aCommandAvailability[ ".uno:SecondaryYTitle" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasSecondaryYAxisTitle;
643 m_aCommandAvailability[ ".uno:AllTitles" ] = bIsWritable && bModelStateIsValid && m_apModelState->HasAnyTitle();
644
645 // text
646 m_aCommandAvailability[ ".uno:ScaleText" ] = bIsWritable && bModelStateIsValid ;
647 m_aCommandArguments[ ".uno:ScaleText" ] <<= m_apModelState->bHasAutoScaledText;
648
649 // axes
650 m_aCommandAvailability[ ".uno:DiagramAxisX" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasXAxis;
651 m_aCommandAvailability[ ".uno:DiagramAxisY" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasYAxis;
652 m_aCommandAvailability[ ".uno:DiagramAxisZ" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasZAxis;
653 m_aCommandAvailability[ ".uno:DiagramAxisA" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasAAxis;
654 m_aCommandAvailability[ ".uno:DiagramAxisB" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasBAxis;
655 m_aCommandAvailability[ ".uno:DiagramAxisAll" ] = bIsWritable && bModelStateIsValid && m_apModelState->HasAnyAxis();
656
657 // grids
658 // note: x and y are swapped in the commands!
659 m_aCommandAvailability[ ".uno:DiagramGridYMain" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasMainXGrid;
660 m_aCommandAvailability[ ".uno:DiagramGridXMain" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasMainYGrid;
661 m_aCommandAvailability[ ".uno:DiagramGridZMain" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasMainZGrid;
662 m_aCommandAvailability[ ".uno:DiagramGridYHelp" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasHelpXGrid;
663 m_aCommandAvailability[ ".uno:DiagramGridXHelp" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasHelpYGrid;
664 m_aCommandAvailability[ ".uno:DiagramGridZHelp" ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasHelpZGrid;
665 m_aCommandAvailability[ ".uno:DiagramGridAll" ] = bIsWritable && bModelStateIsValid && m_apModelState->HasAnyGrid();
666
667 // series arrangement
668 m_aCommandAvailability[ ".uno:Forward" ] = ( bShapeContext ? isShapeControllerCommandAvailable( ".uno:Forward" ) :
669 ( bIsWritable && bControllerStateIsValid && m_apControllerState->bMayMoveSeriesForward && bEnableDataTableDialog ) );
670 m_aCommandAvailability[ ".uno:Backward" ] = ( bShapeContext ? isShapeControllerCommandAvailable( ".uno:Backward" ) :
671 ( bIsWritable && bControllerStateIsValid && m_apControllerState->bMayMoveSeriesBackward && bEnableDataTableDialog ) );
672
673 m_aCommandAvailability[ ".uno:InsertDataLabels" ] = bIsWritable;
674 m_aCommandAvailability[ ".uno:InsertDataLabel" ] = bIsWritable;
675 m_aCommandAvailability[ ".uno:InsertMeanValue" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayAddMeanValue;
676 m_aCommandAvailability[ ".uno:InsertTrendline" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayAddTrendline;
677 m_aCommandAvailability[ ".uno:InsertTrendlineEquation" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayAddTrendlineEquation;
678 m_aCommandAvailability[ ".uno:InsertTrendlineEquationAndR2" ] = m_aCommandAvailability[ ".uno:InsertTrendlineEquation" ];
679 m_aCommandAvailability[ ".uno:InsertR2Value" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayAddR2Value;
680 m_aCommandAvailability[ ".uno:DeleteR2Value" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayDeleteR2Value;
681
682 m_aCommandAvailability[ ".uno:InsertXErrorBars" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayAddXErrorBars;
683 m_aCommandAvailability[ ".uno:InsertYErrorBars" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayAddYErrorBars;
684
685 m_aCommandAvailability[ ".uno:DeleteDataLabels" ] = bIsWritable;
686 m_aCommandAvailability[ ".uno:DeleteDataLabel" ] = bIsWritable;
687 m_aCommandAvailability[ ".uno:DeleteTrendline" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayDeleteTrendline;
688 m_aCommandAvailability[ ".uno:DeleteTrendlineEquation" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayDeleteTrendlineEquation;
689 m_aCommandAvailability[ ".uno:DeleteMeanValue" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayDeleteMeanValue;
690 m_aCommandAvailability[ ".uno:DeleteXErrorBars" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayDeleteXErrorBars;
691 m_aCommandAvailability[ ".uno:DeleteYErrorBars" ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayDeleteYErrorBars;
692
693 m_aCommandAvailability[ ".uno:ResetDataPoint" ] = bIsWritable;
694 m_aCommandAvailability[ ".uno:ResetAllDataPoints" ] = bIsWritable;
695
696 m_aCommandAvailability[ ".uno:InsertAxis" ] = bIsWritable;
697 m_aCommandAvailability[ ".uno:DeleteAxis" ] = bIsWritable;
698 m_aCommandAvailability[ ".uno:InsertAxisTitle" ] = bIsWritable;
699 m_aCommandAvailability[ ".uno:FormatMajorGrid" ] = bIsWritable;
700 m_aCommandAvailability[ ".uno:InsertMajorGrid" ] = bIsWritable;
701 m_aCommandAvailability[ ".uno:DeleteMajorGrid" ] = bIsWritable;
702 m_aCommandAvailability[ ".uno:FormatMinorGrid" ] = bIsWritable;
703 m_aCommandAvailability[ ".uno:InsertMinorGrid" ] = bIsWritable;
704 m_aCommandAvailability[ ".uno:DeleteMinorGrid" ] = bIsWritable;
705 }
706
commandAvailable(const OUString & rCommand)707 bool ControllerCommandDispatch::commandAvailable( const OUString & rCommand )
708 {
709 std::map< OUString, bool >::const_iterator aIt( m_aCommandAvailability.find( rCommand ));
710 if( aIt != m_aCommandAvailability.end())
711 return aIt->second;
712 SAL_WARN("chart2", "commandAvailable: command not in availability map:" << rCommand);
713 return false;
714 }
715
isShapeControllerCommandAvailable(const OUString & rCommand)716 bool ControllerCommandDispatch::isShapeControllerCommandAvailable( const OUString& rCommand )
717 {
718 ShapeController* pShapeController(nullptr);
719 {
720 SolarMutexGuard g;
721 if (m_pDispatchContainer)
722 pShapeController = m_pDispatchContainer->getShapeController();
723 }
724 if ( pShapeController )
725 {
726 FeatureState aState( pShapeController->getState( rCommand ) );
727 return aState.bEnabled;
728 }
729 return false;
730 }
731
fireStatusEvent(const OUString & rURL,const Reference<frame::XStatusListener> & xSingleListener)732 void ControllerCommandDispatch::fireStatusEvent(
733 const OUString & rURL,
734 const Reference< frame::XStatusListener > & xSingleListener /* = 0 */ )
735 {
736 bool bIsChartSelectorURL = rURL == ".uno:ChartElementSelector";
737 if( rURL.isEmpty() || bIsChartSelectorURL )
738 {
739 uno::Any aArg;
740 aArg <<= Reference< frame::XController >(m_xChartController.get());
741 fireStatusEventForURL( ".uno:ChartElementSelector", aArg, true, xSingleListener );
742 }
743
744 if( rURL.isEmpty() )
745 {
746 for (auto const& elem : m_aCommandAvailability)
747 fireStatusEventForURLImpl( elem.first, xSingleListener );
748 }
749 else if( !bIsChartSelectorURL )
750 fireStatusEventForURLImpl( rURL, xSingleListener );
751
752 // statusbar. Should be handled by base implementation
753 // @todo: remove if Issue 68864 is fixed
754 if( rURL.isEmpty() || rURL == ".uno:StatusBarVisible" )
755 {
756 bool bIsStatusBarVisible( lcl_isStatusBarVisible( m_xChartController.get() ));
757 fireStatusEventForURL( ".uno:StatusBarVisible", uno::Any( bIsStatusBarVisible ), true, xSingleListener );
758 }
759 }
760
761 // ____ XDispatch ____
dispatch(const util::URL & URL,const Sequence<beans::PropertyValue> & Arguments)762 void SAL_CALL ControllerCommandDispatch::dispatch(
763 const util::URL& URL,
764 const Sequence< beans::PropertyValue >& Arguments )
765 {
766 if( commandAvailable( URL.Complete ))
767 m_xDispatch->dispatch( URL, Arguments );
768 }
769
770 // ____ WeakComponentImplHelperBase ____
771 /// is called when this is disposed
disposing()772 void SAL_CALL ControllerCommandDispatch::disposing()
773 {
774 m_xChartController.clear();
775 m_xDispatch.clear();
776 m_xSelectionSupplier.clear();
777 }
778
779 // ____ XEventListener (base of XModifyListener) ____
disposing(const lang::EventObject &)780 void SAL_CALL ControllerCommandDispatch::disposing( const lang::EventObject& /* Source */ )
781 {
782 m_xChartController.clear();
783 m_xDispatch.clear();
784 m_xSelectionSupplier.clear();
785 }
786
787 // ____ XModifyListener ____
modified(const lang::EventObject & aEvent)788 void SAL_CALL ControllerCommandDispatch::modified( const lang::EventObject& aEvent )
789 {
790 bool bUpdateCommandAvailability = false;
791
792 // Update the "ModelState" Struct.
793 if( m_apModelState.get() && m_xChartController.is())
794 {
795 m_apModelState->update( m_xChartController->getModel());
796 bUpdateCommandAvailability = true;
797 }
798
799 // Update the "ControllerState" Struct.
800 if( m_apControllerState.get() && m_xChartController.is())
801 {
802 m_apControllerState->update( m_xChartController.get(), m_xChartController->getModel());
803 bUpdateCommandAvailability = true;
804 }
805
806 if( bUpdateCommandAvailability )
807 updateCommandAvailability();
808
809 CommandDispatch::modified( aEvent );
810 }
811
812 // ____ XSelectionChangeListener ____
selectionChanged(const lang::EventObject & aEvent)813 void SAL_CALL ControllerCommandDispatch::selectionChanged( const lang::EventObject& aEvent )
814 {
815 // Update the "ControllerState" Struct.
816 if( m_apControllerState.get() && m_xChartController.is())
817 {
818 m_apControllerState->update( m_xChartController.get(), m_xChartController->getModel());
819 updateCommandAvailability();
820 }
821
822 CommandDispatch::modified( aEvent );
823 }
824
825 } // namespace chart
826
827 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
828