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