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