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