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