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