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 #include "ChartController.hxx" 27 #include "servicenames.hxx" 28 #include "ResId.hxx" 29 #include "dlg_DataSource.hxx" 30 #include "ChartModelHelper.hxx" 31 #include "ControllerCommandDispatch.hxx" 32 #include "Strings.hrc" 33 #include "chartview/ExplicitValueProvider.hxx" 34 #include "ChartViewHelper.hxx" 35 36 #include "ChartWindow.hxx" 37 #include "chartview/DrawModelWrapper.hxx" 38 #include "DrawViewWrapper.hxx" 39 #include "ObjectIdentifier.hxx" 40 #include "DiagramHelper.hxx" 41 #include "ControllerLockGuard.hxx" 42 #include "UndoGuard.hxx" 43 #include "ChartDropTargetHelper.hxx" 44 45 #include "macros.hxx" 46 #include "dlg_CreationWizard.hxx" 47 #include "dlg_ChartType.hxx" 48 #include "AccessibleChartView.hxx" 49 #include "DrawCommandDispatch.hxx" 50 #include "ShapeController.hxx" 51 #include "UndoActions.hxx" 52 53 #include <comphelper/InlineContainer.hxx> 54 55 #include <com/sun/star/awt/PosSize.hpp> 56 #include <com/sun/star/chart2/XChartDocument.hpp> 57 #include <com/sun/star/chart2/data/XDataReceiver.hpp> 58 #include <com/sun/star/frame/XLoadable.hpp> 59 #include <com/sun/star/util/XCloneable.hpp> 60 #include <com/sun/star/embed/XEmbeddedClient.hpp> 61 #include <com/sun/star/util/XModeChangeBroadcaster.hpp> 62 #include <com/sun/star/util/XModifyBroadcaster.hpp> 63 #include <com/sun/star/frame/LayoutManagerEvents.hpp> 64 #include <com/sun/star/document/XUndoManagerSupplier.hpp> 65 #include <com/sun/star/document/XUndoAction.hpp> 66 67 //------- 68 // header for define RET_OK 69 #include <vcl/msgbox.hxx> 70 //------- 71 72 //------- 73 #include <toolkit/awt/vclxwindow.hxx> 74 #include <toolkit/helper/vclunohelper.hxx> 75 #include <vcl/svapp.hxx> 76 #include <vos/mutex.hxx> 77 //------- 78 #include <com/sun/star/frame/XLayoutManager.hpp> 79 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> 80 81 // this is needed to properly destroy the auto_ptr to the AcceleratorExecute 82 // object in the DTOR 83 #include <svtools/acceleratorexecute.hxx> 84 #include <svx/ActionDescriptionProvider.hxx> 85 #include <tools/diagnose_ex.h> 86 87 // enable the following define to let the controller listen to model changes and 88 // react on this by rebuilding the view 89 #define TEST_ENABLE_MODIFY_LISTENER 90 91 /* 92 #include <vcl/svapp.hxx> 93 */ 94 95 //............................................................................. 96 namespace chart 97 { 98 //............................................................................. 99 100 using namespace ::com::sun::star; 101 using namespace ::com::sun::star::accessibility; 102 using namespace ::com::sun::star::chart2; 103 using ::com::sun::star::uno::Any; 104 using ::com::sun::star::uno::Reference; 105 using ::com::sun::star::uno::Sequence; 106 DBG_NAME(ChartController) 107 //----------------------------------------------------------------- 108 // ChartController Constructor and Destructor 109 //----------------------------------------------------------------- 110 111 ChartController::ChartController(uno::Reference<uno::XComponentContext> const & xContext) 112 : m_aLifeTimeManager( NULL ) 113 , m_bSuspended( sal_False ) 114 , m_bCanClose( sal_True ) 115 , m_xCC(xContext) //@todo is it allowed to hold this context?? 116 , m_xFrame( NULL ) 117 , m_aModelMutex() 118 , m_aModel( NULL, m_aModelMutex ) 119 , m_pChartWindow( NULL ) 120 , m_xViewWindow() 121 , m_xChartView() 122 , m_pDrawModelWrapper() 123 , m_pDrawViewWrapper(NULL) 124 , m_eDragMode(SDRDRAG_MOVE) 125 , m_bWaitingForDoubleClick(false) 126 , m_bWaitingForMouseUp(false) 127 , m_bConnectingToView(false) 128 , m_xUndoManager( 0 ) 129 , m_aDispatchContainer( m_xCC, this ) 130 , m_eDrawMode( CHARTDRAW_SELECT ) 131 { 132 DBG_CTOR(ChartController,NULL); 133 m_aDoubleClickTimer.SetTimeoutHdl( LINK( this, ChartController, DoubleClickWaitingHdl ) ); 134 } 135 136 ChartController::~ChartController() 137 { 138 DBG_DTOR(ChartController,NULL); 139 stopDoubleClickWaiting(); 140 } 141 142 //----------------------------------------------------------------- 143 144 ChartController::RefCountable::RefCountable() : m_nRefCount(0) 145 { 146 } 147 148 ChartController::RefCountable::~RefCountable() 149 { 150 } 151 void ChartController::RefCountable::acquire() 152 { 153 m_nRefCount++; 154 } 155 void ChartController::RefCountable::release() 156 { 157 m_nRefCount--; 158 if(!m_nRefCount) 159 delete this; 160 } 161 162 //----------------------------------------------------------------- 163 164 ChartController::TheModel::TheModel( const uno::Reference< frame::XModel > & xModel ) 165 : m_xModel( xModel ) 166 , m_xCloseable( NULL ) 167 , m_bOwnership( sal_True ) 168 , m_bOwnershipIsWellKnown( sal_False ) 169 { 170 m_xCloseable = 171 uno::Reference< util::XCloseable >( xModel, uno::UNO_QUERY ); 172 } 173 174 ChartController::TheModel::~TheModel() 175 { 176 } 177 178 void ChartController::TheModel::SetOwnerShip( sal_Bool bGetsOwnership ) 179 { 180 m_bOwnership = bGetsOwnership; 181 m_bOwnershipIsWellKnown = sal_True; 182 } 183 184 void ChartController::TheModel::addListener( ChartController* pController ) 185 { 186 if(m_xCloseable.is()) 187 { 188 //if you need to be able to veto against the destruction of the model 189 // you must add as a close listener 190 191 //otherwise you 'can' add as closelistener or 'must' add as dispose event listener 192 193 m_xCloseable->addCloseListener( 194 static_cast<util::XCloseListener*>(pController) ); 195 } 196 else if( m_xModel.is() ) 197 { 198 //we need to add as dispose event listener 199 m_xModel->addEventListener( 200 static_cast<util::XCloseListener*>(pController) ); 201 } 202 203 } 204 205 void ChartController::TheModel::removeListener( ChartController* pController ) 206 { 207 if(m_xCloseable.is()) 208 m_xCloseable->removeCloseListener( 209 static_cast<util::XCloseListener*>(pController) ); 210 211 else if( m_xModel.is() ) 212 m_xModel->removeEventListener( 213 static_cast<util::XCloseListener*>(pController) ); 214 } 215 216 void ChartController::TheModel::tryTermination() 217 { 218 if(!m_bOwnership) 219 return; 220 221 try 222 { 223 if(m_xCloseable.is()) 224 { 225 try 226 { 227 //@todo ? are we allowed to use sal_True here if we have the explicit ownership? 228 //I think yes, because there might be other closelistners later in the list which might be interested still 229 //but make sure that we do not throw the CloseVetoException here ourselfs 230 //so stop listening before trying to terminate or check the source of queryclosing event 231 m_xCloseable->close(sal_True); 232 233 m_bOwnership = false; 234 m_bOwnershipIsWellKnown = sal_True; 235 } 236 catch( util::CloseVetoException& ) 237 { 238 //since we have indicated to give up the ownership with paramter true in close call 239 //the one who has thrown the CloseVetoException is the new owner 240 241 #if OSL_DEBUG_LEVEL > 2 242 OSL_ENSURE( !m_bOwnership, 243 "INFO: a well known owner has catched a CloseVetoException after calling close(true)" ); 244 #endif 245 246 m_bOwnership = false; 247 m_bOwnershipIsWellKnown = sal_True; 248 return; 249 } 250 251 } 252 else if( m_xModel.is() ) 253 { 254 //@todo correct?? 255 m_xModel->dispose(); 256 return; 257 } 258 } 259 catch( uno::Exception& ex) 260 { 261 (void)(ex); // no warning in non-debug builds 262 OSL_ENSURE( sal_False, ( rtl::OString("Termination of model failed: ") 263 + rtl::OUStringToOString( ex.Message, RTL_TEXTENCODING_ASCII_US ) ).getStr() ); 264 } 265 } 266 267 //----------------------------------------------------------------- 268 269 ChartController::TheModelRef::TheModelRef( TheModel* pTheModel, ::osl::Mutex& rMutex ) 270 : m_pTheModel(pTheModel), m_rModelMutex(rMutex) 271 { 272 ::osl::Guard< ::osl::Mutex > aGuard( m_rModelMutex ); 273 if(m_pTheModel) 274 m_pTheModel->acquire(); 275 } 276 ChartController::TheModelRef::TheModelRef( const TheModelRef& rTheModel, ::osl::Mutex& rMutex ) 277 : m_rModelMutex(rMutex) 278 { 279 ::osl::Guard< ::osl::Mutex > aGuard( m_rModelMutex ); 280 m_pTheModel=rTheModel.operator->(); 281 if(m_pTheModel) 282 m_pTheModel->acquire(); 283 } 284 ChartController::TheModelRef& ChartController::TheModelRef::operator=(TheModel* pTheModel) 285 { 286 ::osl::Guard< ::osl::Mutex > aGuard( m_rModelMutex ); 287 if(m_pTheModel==pTheModel) 288 return *this; 289 if(m_pTheModel) 290 m_pTheModel->release(); 291 m_pTheModel=pTheModel; 292 if(m_pTheModel) 293 m_pTheModel->acquire(); 294 return *this; 295 } 296 ChartController::TheModelRef& ChartController::TheModelRef::operator=(const TheModelRef& rTheModel) 297 { 298 ::osl::Guard< ::osl::Mutex > aGuard( m_rModelMutex ); 299 TheModel* pNew=rTheModel.operator->(); 300 if(m_pTheModel==pNew) 301 return *this; 302 if(m_pTheModel) 303 m_pTheModel->release(); 304 m_pTheModel=pNew; 305 if(m_pTheModel) 306 m_pTheModel->acquire(); 307 return *this; 308 } 309 ChartController::TheModelRef::~TheModelRef() 310 { 311 ::osl::Guard< ::osl::Mutex > aGuard( m_rModelMutex ); 312 if(m_pTheModel) 313 m_pTheModel->release(); 314 } 315 sal_Bool ChartController::TheModelRef::is() const 316 { 317 return (m_pTheModel != 0); 318 } 319 320 321 //----------------------------------------------------------------- 322 // private methods 323 //----------------------------------------------------------------- 324 325 sal_Bool ChartController 326 ::impl_isDisposedOrSuspended() const 327 { 328 if( m_aLifeTimeManager.impl_isDisposed() ) 329 return sal_True; 330 331 if( m_bSuspended ) 332 { 333 OSL_ENSURE( sal_False, "This Controller is suspended" ); 334 return sal_True; 335 } 336 return sal_False; 337 } 338 339 //----------------------------------------------------------------- 340 // lang::XServiceInfo 341 //----------------------------------------------------------------- 342 343 APPHELPER_XSERVICEINFO_IMPL(ChartController,CHART_CONTROLLER_SERVICE_IMPLEMENTATION_NAME) 344 345 uno::Sequence< rtl::OUString > ChartController 346 ::getSupportedServiceNames_Static() 347 { 348 uno::Sequence< rtl::OUString > aSNS( 2 ); 349 aSNS.getArray()[ 0 ] = CHART_CONTROLLER_SERVICE_NAME; 350 aSNS.getArray()[ 1 ] = ::rtl::OUString::createFromAscii("com.sun.star.frame.Controller"); 351 //// @todo : add additional services if you support any further 352 return aSNS; 353 } 354 355 //----------------------------------------------------------------- 356 // XController 357 //----------------------------------------------------------------- 358 359 void SAL_CALL ChartController 360 ::attachFrame( const uno::Reference<frame::XFrame>& xFrame ) 361 throw(uno::RuntimeException) 362 { 363 ::vos::OGuard aGuard( Application::GetSolarMutex()); 364 365 if( impl_isDisposedOrSuspended() ) //@todo? allow attaching the frame while suspended? 366 return; //behave passive if already disposed or suspended 367 368 if(m_xFrame.is()) //what happens, if we do have a Frame already?? 369 { 370 //@todo? throw exception? 371 OSL_ENSURE( sal_False, "there is already a frame attached to the controller" ); 372 return; 373 } 374 375 //--attach frame 376 m_xFrame = xFrame; //the frameloader is responsible to call xFrame->setComponent 377 378 //add as disposelistener to the frame (due to persistent reference) ??...: 379 380 //the frame is considered to be owner of this controller and will live longer than we do 381 //the frame or the disposer of the frame has the duty to call suspend and dispose on this object 382 //so we do not need to add as lang::XEventListener for DisposingEvents right? 383 384 //@todo nothing right??? 385 386 387 388 //-------------------------------------------------- 389 //create view @todo is this the correct place here?? 390 391 Window* pParent = NULL; 392 //get the window parent from the frame to use as parent for our new window 393 if(xFrame.is()) 394 { 395 uno::Reference< awt::XWindow > xContainerWindow = xFrame->getContainerWindow(); 396 VCLXWindow* pParentComponent = VCLXWindow::GetImplementation(xContainerWindow); 397 pParentComponent->setVisible(sal_True); 398 399 pParent = VCLUnoHelper::GetWindow( xContainerWindow ); 400 } 401 402 if(m_pChartWindow) 403 { 404 //@todo delete ... 405 m_pChartWindow->clear(); 406 m_apDropTargetHelper.reset(); 407 } 408 { 409 awt::Size aPageSize( ChartModelHelper::getPageSize(getModel()) ); 410 411 // calls to VCL 412 ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); 413 m_pChartWindow = new ChartWindow(this,pParent,pParent?pParent->GetStyle():0); 414 m_pChartWindow->SetBackground();//no Background 415 m_xViewWindow = uno::Reference< awt::XWindow >( m_pChartWindow->GetComponentInterface(), uno::UNO_QUERY ); 416 m_pChartWindow->Show(); 417 m_apDropTargetHelper.reset( 418 new ChartDropTargetHelper( m_pChartWindow->GetDropTarget(), 419 uno::Reference< chart2::XChartDocument >( getModel(), uno::UNO_QUERY ))); 420 421 impl_createDrawViewController(); 422 } 423 424 //create the menu 425 { 426 uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY ); 427 if( xPropSet.is() ) 428 { 429 try 430 { 431 uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; 432 xPropSet->getPropertyValue( C2U( "LayoutManager" ) ) >>= xLayoutManager; 433 if ( xLayoutManager.is() ) 434 { 435 xLayoutManager->lock(); 436 xLayoutManager->requestElement( C2U( "private:resource/menubar/menubar" ) ); 437 //@todo: createElement should become unnecessary, remove when #i79198# is fixed 438 xLayoutManager->createElement( C2U( "private:resource/toolbar/standardbar" ) ); 439 xLayoutManager->requestElement( C2U( "private:resource/toolbar/standardbar" ) ); 440 //@todo: createElement should become unnecessary, remove when #i79198# is fixed 441 xLayoutManager->createElement( C2U( "private:resource/toolbar/toolbar" ) ); 442 xLayoutManager->requestElement( C2U( "private:resource/toolbar/toolbar" ) ); 443 444 // #i12587# support for shapes in chart 445 xLayoutManager->createElement( C2U( "private:resource/toolbar/drawbar" ) ); 446 xLayoutManager->requestElement( C2U( "private:resource/toolbar/drawbar" ) ); 447 448 xLayoutManager->requestElement( C2U( "private:resource/statusbar/statusbar" ) ); 449 xLayoutManager->unlock(); 450 451 // add as listener to get notified when 452 m_xLayoutManagerEventBroadcaster.set( xLayoutManager, uno::UNO_QUERY ); 453 if( m_xLayoutManagerEventBroadcaster.is()) 454 m_xLayoutManagerEventBroadcaster->addLayoutManagerEventListener( this ); 455 } 456 } 457 catch( uno::Exception & ex ) 458 { 459 ASSERT_EXCEPTION( ex ); 460 } 461 } 462 } 463 } 464 465 //XModeChangeListener 466 void SAL_CALL ChartController::modeChanged( const util::ModeChangeEvent& rEvent ) 467 throw ( uno::RuntimeException ) 468 { 469 //adjust controller to view status changes 470 471 if( rEvent.NewMode.equals(C2U("dirty")) ) 472 { 473 //the view has become dirty, we should repaint it if we have a window 474 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 475 if( m_pChartWindow ) 476 m_pChartWindow->ForceInvalidate(); 477 } 478 else if( rEvent.NewMode.equals(C2U("invalid")) ) 479 { 480 //the view is about to become invalid so end all actions on it 481 impl_invalidateAccessible(); 482 ::vos::OGuard aGuard( Application::GetSolarMutex()); 483 if( m_pDrawViewWrapper && m_pDrawViewWrapper->IsTextEdit() ) 484 this->EndTextEdit(); 485 if( m_pDrawViewWrapper ) 486 { 487 m_pDrawViewWrapper->UnmarkAll(); 488 //m_pDrawViewWrapper->hideMarkHandles(); todo?? 489 m_pDrawViewWrapper->HideSdrPage(); 490 } 491 } 492 else 493 { 494 //the view was rebuild so we can start some actions on it again 495 if( !m_bConnectingToView ) 496 { 497 if(m_pChartWindow && m_aModel.is() ) 498 { 499 m_bConnectingToView = true; 500 501 GetDrawModelWrapper(); 502 if(m_pDrawModelWrapper) 503 { 504 { 505 ::vos::OGuard aGuard( Application::GetSolarMutex()); 506 if( m_pDrawViewWrapper ) 507 m_pDrawViewWrapper->ReInit(); 508 } 509 510 //reselect object 511 if( m_aSelection.hasSelection() ) 512 this->impl_selectObjectAndNotiy(); 513 else 514 ChartModelHelper::triggerRangeHighlighting( getModel() ); 515 516 impl_initializeAccessible(); 517 518 { 519 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 520 if( m_pChartWindow ) 521 m_pChartWindow->Invalidate(); 522 } 523 } 524 525 m_bConnectingToView = false; 526 } 527 } 528 } 529 } 530 531 sal_Bool SAL_CALL ChartController 532 ::attachModel( const uno::Reference< frame::XModel > & xModel ) 533 throw(uno::RuntimeException) 534 { 535 impl_invalidateAccessible(); 536 537 //is called to attach the controller to a new model. 538 //return true if attach was successfully, false otherwise (e.g. if you do not work with a model) 539 540 ::vos::OClearableGuard aClearableGuard( Application::GetSolarMutex()); 541 if( impl_isDisposedOrSuspended() ) //@todo? allow attaching a new model while suspended? 542 return sal_False; //behave passive if already disposed or suspended 543 aClearableGuard.clear(); 544 545 546 TheModelRef aNewModelRef( new TheModel( xModel), m_aModelMutex); 547 TheModelRef aOldModelRef(m_aModel,m_aModelMutex); 548 m_aModel = aNewModelRef; 549 550 //--handle relations to the old model if any 551 if( aOldModelRef.is() ) 552 { 553 uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY ); 554 if( xViewBroadcaster.is() ) 555 xViewBroadcaster->removeModeChangeListener(this); 556 m_pDrawModelWrapper.reset(); 557 558 aOldModelRef->removeListener( this ); 559 //@todo?? termination correct? 560 // aOldModelRef->tryTermination(); 561 #ifdef TEST_ENABLE_MODIFY_LISTENER 562 uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aOldModelRef->getModel(),uno::UNO_QUERY ); 563 if( xMBroadcaster.is()) 564 xMBroadcaster->removeModifyListener( this ); 565 #endif 566 } 567 568 //--handle relations to the new model 569 aNewModelRef->addListener( this ); 570 571 // set new model at dispatchers 572 m_aDispatchContainer.setModel( aNewModelRef->getModel()); 573 ControllerCommandDispatch * pDispatch = new ControllerCommandDispatch( m_xCC, this, &m_aDispatchContainer ); 574 pDispatch->initialize(); 575 576 // the dispatch container will return "this" for all commands returned by 577 // impl_getAvailableCommands(). That means, for those commands dispatch() 578 // is called here at the ChartController. 579 m_aDispatchContainer.setChartDispatch( pDispatch, impl_getAvailableCommands() ); 580 581 DrawCommandDispatch* pDrawDispatch = new DrawCommandDispatch( m_xCC, this ); 582 if ( pDrawDispatch ) 583 { 584 pDrawDispatch->initialize(); 585 m_aDispatchContainer.setDrawCommandDispatch( pDrawDispatch ); 586 } 587 588 ShapeController* pShapeController = new ShapeController( m_xCC, this ); 589 if ( pShapeController ) 590 { 591 pShapeController->initialize(); 592 m_aDispatchContainer.setShapeController( pShapeController ); 593 } 594 595 #ifdef TEST_ENABLE_MODIFY_LISTENER 596 uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aNewModelRef->getModel(),uno::UNO_QUERY ); 597 if( xMBroadcaster.is()) 598 xMBroadcaster->addModifyListener( this ); 599 #endif 600 601 //select chart area per default: 602 select( uno::makeAny( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, rtl::OUString() ) ) ); 603 604 uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY ); 605 if( xFact.is()) 606 { 607 m_xChartView = xFact->createInstance( CHART_VIEW_SERVICE_NAME ); 608 GetDrawModelWrapper(); 609 uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY ); 610 if( xViewBroadcaster.is() ) 611 xViewBroadcaster->addModeChangeListener(this); 612 } 613 614 //the frameloader is responsible to call xModel->connectController 615 { 616 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 617 if( m_pChartWindow ) 618 m_pChartWindow->Invalidate(); 619 } 620 621 uno::Reference< document::XUndoManagerSupplier > xSuppUndo( getModel(), uno::UNO_QUERY_THROW ); 622 m_xUndoManager.set( xSuppUndo->getUndoManager(), uno::UNO_QUERY_THROW ); 623 624 return sal_True; 625 } 626 627 uno::Reference< frame::XFrame > SAL_CALL ChartController 628 ::getFrame() throw(uno::RuntimeException) 629 { 630 //provides access to owner frame of this controller 631 //return the frame containing this controller 632 633 return m_xFrame; 634 } 635 636 uno::Reference< frame::XModel > SAL_CALL ChartController 637 ::getModel() throw(uno::RuntimeException) 638 { 639 //provides access to currently attached model 640 //returns the currently attached model 641 642 //return nothing, if you do not have a model 643 TheModelRef aModelRef( m_aModel, m_aModelMutex); 644 if(aModelRef.is()) 645 return aModelRef->getModel(); 646 647 return uno::Reference< frame::XModel > (); 648 } 649 650 uno::Any SAL_CALL ChartController 651 ::getViewData() throw(uno::RuntimeException) 652 { 653 //provides access to current view status 654 //set of data that can be used to restore the current view status at later time 655 // by using XController::restoreViewData() 656 657 ::vos::OGuard aGuard( Application::GetSolarMutex()); 658 if( impl_isDisposedOrSuspended() ) 659 return uno::Any(); //behave passive if already disposed or suspended //@todo? or throw an exception?? 660 661 //-- collect current view state 662 uno::Any aRet; 663 //// @todo integrate specialized implementation 664 665 return aRet; 666 } 667 668 void SAL_CALL ChartController 669 ::restoreViewData( const uno::Any& /* Value */ ) 670 throw(uno::RuntimeException) 671 { 672 //restores the view status using the data gotten from a previous call to XController::getViewData() 673 674 ::vos::OGuard aGuard( Application::GetSolarMutex()); 675 if( impl_isDisposedOrSuspended() ) 676 return; //behave passive if already disposed or suspended //@todo? or throw an exception?? 677 678 //// @todo integrate specialized implementation 679 } 680 681 sal_Bool SAL_CALL ChartController 682 ::suspend( sal_Bool bSuspend ) 683 throw(uno::RuntimeException) 684 { 685 //is called to prepare the controller for closing the view 686 //bSuspend==true: force the controller to suspend his work 687 //bSuspend==false try to reactivate the controller 688 //returns true if request was accepted and of course successfully finished, false otherwise 689 690 //we may show dialogs here to ask the user for saving changes ... @todo? 691 692 ::vos::OGuard aGuard( Application::GetSolarMutex()); 693 if( m_aLifeTimeManager.impl_isDisposed() ) 694 return sal_False; //behave passive if already disposed, return false because request was not accepted //@todo? correct 695 696 if(bSuspend==m_bSuspended) 697 { 698 OSL_ENSURE( sal_False, "new suspend mode equals old suspend mode" ); 699 return sal_True; 700 } 701 702 //change suspend mode 703 if(bSuspend) 704 { 705 //aGuard.clear(); 706 //@todo ??? try to stop all what may prevent me from becoming disposed 707 //aGuard.reset(); 708 709 m_bSuspended = bSuspend; 710 return sal_True; 711 } 712 else 713 { 714 //aGuard.clear(); 715 //@todo ??? redo what was made in section bSuspend==true 716 //aGuard.reset(); 717 718 m_bSuspended = bSuspend; 719 } 720 return sal_True; 721 722 723 /* 724 if ( bSuspend ) 725 getFrame()->removeFrameActionListener( pImp ); 726 else 727 getFrame()->addFrameActionListener( pImp ); 728 */ 729 } 730 731 732 void ChartController::impl_createDrawViewController() 733 { 734 ::vos::OGuard aGuard( Application::GetSolarMutex()); 735 if(!m_pDrawViewWrapper) 736 { 737 if( m_pDrawModelWrapper ) 738 { 739 m_pDrawViewWrapper = new DrawViewWrapper(&m_pDrawModelWrapper->getSdrModel(),m_pChartWindow,true); 740 m_pDrawViewWrapper->attachParentReferenceDevice( getModel() ); 741 } 742 } 743 } 744 void ChartController::impl_deleteDrawViewController() 745 { 746 if( m_pDrawViewWrapper ) 747 { 748 ::vos::OGuard aGuard( Application::GetSolarMutex()); 749 if( m_pDrawViewWrapper->IsTextEdit() ) 750 this->EndTextEdit(); 751 DELETEZ( m_pDrawViewWrapper ); 752 } 753 } 754 755 //----------------------------------------------------------------- 756 // XComponent (base of XController) 757 //----------------------------------------------------------------- 758 759 void SAL_CALL ChartController 760 ::dispose() throw(uno::RuntimeException) 761 { 762 try 763 { 764 //This object should release all resources and references in the 765 //easiest possible manner 766 //This object must notify all registered listeners using the method 767 //<member>XEventListener::disposing</member> 768 769 //hold no mutex 770 if( !m_aLifeTimeManager.dispose() ) 771 return; 772 773 // OSL_ENSURE( m_bSuspended, "dispose was called but controller is not suspended" ); 774 775 this->stopDoubleClickWaiting(); 776 777 //end range highlighting 778 if( m_aModel.is()) 779 { 780 uno::Reference< view::XSelectionChangeListener > xSelectionChangeListener; 781 uno::Reference< chart2::data::XDataReceiver > xDataReceiver( getModel(), uno::UNO_QUERY ); 782 if( xDataReceiver.is() ) 783 xSelectionChangeListener = uno::Reference< view::XSelectionChangeListener >( xDataReceiver->getRangeHighlighter(), uno::UNO_QUERY ); 784 if( xSelectionChangeListener.is() ) 785 { 786 uno::Reference< frame::XController > xController( this ); 787 uno::Reference< lang::XComponent > xComp( xController, uno::UNO_QUERY ); 788 //lang::EventObject aEvent( static_cast< lang::XComponent* >( this ) ); 789 lang::EventObject aEvent( xComp ); 790 xSelectionChangeListener->disposing( aEvent ); 791 } 792 } 793 794 //--release all resources and references 795 { 796 uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY ); 797 if( xViewBroadcaster.is() ) 798 xViewBroadcaster->removeModeChangeListener(this); 799 // /-- 800 impl_invalidateAccessible(); 801 ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); 802 impl_deleteDrawViewController(); 803 m_pDrawModelWrapper.reset(); 804 805 m_apDropTargetHelper.reset(); 806 807 //the accessible view is disposed within window destructor of m_pChartWindow 808 m_pChartWindow->clear(); 809 m_pChartWindow = NULL;//m_pChartWindow is deleted via UNO due to dispose of m_xViewWindow (trigerred by Framework (Controller pretends to be XWindow also)) 810 m_xViewWindow->dispose(); 811 m_xChartView.clear(); 812 // \-- 813 } 814 815 // remove as listener to layout manager events 816 if( m_xLayoutManagerEventBroadcaster.is()) 817 { 818 m_xLayoutManagerEventBroadcaster->removeLayoutManagerEventListener( this ); 819 m_xLayoutManagerEventBroadcaster.set( 0 ); 820 } 821 822 m_xFrame.clear(); 823 m_xUndoManager.clear(); 824 825 TheModelRef aModelRef( m_aModel, m_aModelMutex); 826 m_aModel = NULL; 827 828 if( aModelRef.is()) 829 { 830 uno::Reference< frame::XModel > xModel( aModelRef->getModel() ); 831 if(xModel.is()) 832 xModel->disconnectController( uno::Reference< frame::XController >( this )); 833 834 aModelRef->removeListener( this ); 835 #ifdef TEST_ENABLE_MODIFY_LISTENER 836 try 837 { 838 uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aModelRef->getModel(),uno::UNO_QUERY ); 839 if( xMBroadcaster.is()) 840 xMBroadcaster->removeModifyListener( this ); 841 } 842 catch( const uno::Exception & ex ) 843 { 844 ASSERT_EXCEPTION( ex ); 845 } 846 #endif 847 aModelRef->tryTermination(); 848 } 849 850 //// @todo integrate specialized implementation 851 //e.g. release further resources and references 852 853 m_aDispatchContainer.DisposeAndClear(); 854 } 855 catch( const uno::Exception & ex ) 856 { 857 ASSERT_EXCEPTION( ex ); 858 } 859 } 860 861 void SAL_CALL ChartController 862 ::addEventListener( const uno::Reference<lang::XEventListener>& xListener ) 863 throw(uno::RuntimeException) 864 { 865 ::vos::OGuard aGuard( Application::GetSolarMutex()); 866 if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode? 867 return; //behave passive if already disposed or suspended 868 869 //--add listener 870 m_aLifeTimeManager.m_aListenerContainer.addInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0), xListener ); 871 } 872 873 void SAL_CALL ChartController 874 ::removeEventListener( const uno::Reference< 875 lang::XEventListener>& xListener ) 876 throw(uno::RuntimeException) 877 { 878 ::vos::OGuard aGuard( Application::GetSolarMutex()); 879 if( m_aLifeTimeManager.impl_isDisposed(false) ) 880 return; //behave passive if already disposed or suspended 881 882 //--remove listener 883 m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0), xListener ); 884 } 885 886 887 //----------------------------------------------------------------- 888 // util::XCloseListener 889 //----------------------------------------------------------------- 890 void SAL_CALL ChartController 891 ::queryClosing( const lang::EventObject& rSource, sal_Bool bGetsOwnership ) 892 throw(util::CloseVetoException, uno::RuntimeException) 893 { 894 //do not use the m_aControllerMutex here because this call is not allowed to block 895 896 TheModelRef aModelRef( m_aModel, m_aModelMutex); 897 898 if( !aModelRef.is() ) 899 return; 900 901 if( !(aModelRef->getModel() == rSource.Source) ) 902 { 903 OSL_ENSURE( sal_False, "queryClosing was called on a controller from an unknown source" ); 904 return; 905 } 906 907 if( !m_bCanClose )//@todo tryaqcuire mutex 908 { 909 if( bGetsOwnership ) 910 { 911 aModelRef->SetOwnerShip( bGetsOwnership ); 912 } 913 914 throw util::CloseVetoException(); 915 } 916 else 917 { 918 //@ todo prepare to to closing model -> don't start any further hindering actions 919 } 920 } 921 922 void SAL_CALL ChartController 923 ::notifyClosing( const lang::EventObject& rSource ) 924 throw(uno::RuntimeException) 925 { 926 //Listener should deregister himself and relaese all references to the closing object. 927 928 TheModelRef aModelRef( m_aModel, m_aModelMutex); 929 if( impl_releaseThisModel( rSource.Source ) ) 930 { 931 //--stop listening to the closing model 932 aModelRef->removeListener( this ); 933 934 // #i79087# If the model using this controller is closed, the frame is 935 // expected to be closed as well 936 Reference< util::XCloseable > xFrameCloseable( m_xFrame, uno::UNO_QUERY ); 937 if( xFrameCloseable.is()) 938 { 939 try 940 { 941 xFrameCloseable->close( sal_False /* DeliverOwnership */ ); 942 m_xFrame.clear(); 943 } 944 catch( util::CloseVetoException & ) 945 { 946 // closing was vetoed 947 } 948 } 949 } 950 } 951 952 bool ChartController::impl_releaseThisModel( const uno::Reference< uno::XInterface > & xModel ) 953 { 954 bool bReleaseModel = sal_False; 955 { 956 ::osl::Guard< ::osl::Mutex > aGuard( m_aModelMutex ); 957 if( m_aModel.is() && m_aModel->getModel() == xModel ) 958 { 959 m_aModel = NULL; 960 m_xUndoManager.clear(); 961 bReleaseModel = true; 962 } 963 } 964 if( bReleaseModel ) 965 m_aDispatchContainer.setModel( 0 ); 966 return bReleaseModel; 967 } 968 969 //----------------------------------------------------------------- 970 // util::XEventListener (base of XCloseListener) 971 //----------------------------------------------------------------- 972 void SAL_CALL ChartController 973 ::disposing( const lang::EventObject& rSource ) 974 throw(uno::RuntimeException) 975 { 976 if( !impl_releaseThisModel( rSource.Source )) 977 { 978 if( rSource.Source == m_xLayoutManagerEventBroadcaster ) 979 m_xLayoutManagerEventBroadcaster.set( 0 ); 980 } 981 } 982 983 void SAL_CALL ChartController::layoutEvent( const lang::EventObject& aSource, ::sal_Int16 eLayoutEvent, const uno::Any& /* aInfo */ ) 984 throw (uno::RuntimeException) 985 { 986 if( eLayoutEvent == frame::LayoutManagerEvents::MERGEDMENUBAR ) 987 { 988 Reference< frame::XLayoutManager > xLM( aSource.Source, uno::UNO_QUERY ); 989 if( xLM.is()) 990 { 991 xLM->createElement( C2U("private:resource/statusbar/statusbar")); 992 xLM->requestElement( C2U("private:resource/statusbar/statusbar")); 993 } 994 } 995 } 996 997 998 //----------------------------------------------------------------- 999 // XDispatchProvider (required interface) 1000 //----------------------------------------------------------------- 1001 1002 namespace 1003 { 1004 bool lcl_isFormatObjectCommand( const rtl::OString& aCommand ) 1005 { 1006 if( aCommand.equals("MainTitle") 1007 || aCommand.equals("SubTitle") 1008 || aCommand.equals("XTitle") 1009 || aCommand.equals("YTitle") 1010 || aCommand.equals("ZTitle") 1011 || aCommand.equals("SecondaryXTitle") 1012 || aCommand.equals("SecondaryYTitle") 1013 || aCommand.equals("AllTitles") 1014 || aCommand.equals("DiagramAxisX") 1015 || aCommand.equals("DiagramAxisY") 1016 || aCommand.equals("DiagramAxisZ") 1017 || aCommand.equals("DiagramAxisA") 1018 || aCommand.equals("DiagramAxisB") 1019 || aCommand.equals("DiagramAxisAll") 1020 || aCommand.equals("DiagramGridXMain") 1021 || aCommand.equals("DiagramGridYMain") 1022 || aCommand.equals("DiagramGridZMain") 1023 || aCommand.equals("DiagramGridXHelp") 1024 || aCommand.equals("DiagramGridYHelp") 1025 || aCommand.equals("DiagramGridZHelp") 1026 || aCommand.equals("DiagramGridAll") 1027 1028 || aCommand.equals("DiagramWall") 1029 || aCommand.equals("DiagramFloor") 1030 || aCommand.equals("DiagramArea") 1031 || aCommand.equals("Legend") 1032 1033 || aCommand.equals("FormatWall") 1034 || aCommand.equals("FormatFloor") 1035 || aCommand.equals("FormatChartArea") 1036 || aCommand.equals("FormatLegend") 1037 1038 || aCommand.equals("FormatTitle") 1039 || aCommand.equals("FormatAxis") 1040 || aCommand.equals("FormatDataSeries") 1041 || aCommand.equals("FormatDataPoint") 1042 || aCommand.equals("FormatDataLabels") 1043 || aCommand.equals("FormatDataLabel") 1044 || aCommand.equals("FormatYErrorBars") 1045 || aCommand.equals("FormatMeanValue") 1046 || aCommand.equals("FormatTrendline") 1047 || aCommand.equals("FormatTrendlineEquation") 1048 || aCommand.equals("FormatStockLoss") 1049 || aCommand.equals("FormatStockGain") 1050 || aCommand.equals("FormatMajorGrid") 1051 || aCommand.equals("FormatMinorGrid") 1052 ) 1053 return true; 1054 1055 // else 1056 return false; 1057 } 1058 } // anonymous namespace 1059 1060 uno::Reference<frame::XDispatch> SAL_CALL ChartController 1061 ::queryDispatch( const util::URL& rURL 1062 , const rtl::OUString& rTargetFrameName 1063 , sal_Int32 /* nSearchFlags */) 1064 throw(uno::RuntimeException) 1065 { 1066 if ( !m_aLifeTimeManager.impl_isDisposed() && getModel().is() ) 1067 { 1068 if( rTargetFrameName.getLength() && 1069 rTargetFrameName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("_self"))) 1070 return m_aDispatchContainer.getDispatchForURL( rURL ); 1071 } 1072 return uno::Reference< frame::XDispatch > (); 1073 } 1074 1075 uno::Sequence<uno::Reference<frame::XDispatch > > ChartController 1076 ::queryDispatches( const uno::Sequence< 1077 frame::DispatchDescriptor>& xDescripts) 1078 throw(uno::RuntimeException) 1079 { 1080 if ( !m_aLifeTimeManager.impl_isDisposed() ) 1081 { 1082 return m_aDispatchContainer.getDispatchesForURLs( xDescripts ); 1083 } 1084 return uno::Sequence<uno::Reference<frame::XDispatch > > (); 1085 } 1086 1087 //----------------------------------------------------------------- 1088 // frame::XDispatch 1089 //----------------------------------------------------------------- 1090 1091 void SAL_CALL ChartController 1092 ::dispatch( const util::URL& rURL 1093 , const uno::Sequence< beans::PropertyValue >& rArgs ) 1094 throw (uno::RuntimeException) 1095 { 1096 //@todo avoid OString (see Mathias mail on bug #104387#) 1097 rtl::OString aCommand( rtl::OUStringToOString( rURL.Path, RTL_TEXTENCODING_ASCII_US ) ); 1098 1099 if(aCommand.equals("Paste")) 1100 this->executeDispatch_Paste(); 1101 else if(aCommand.equals("Copy")) 1102 this->executeDispatch_Copy(); 1103 else if(aCommand.equals("Cut")) 1104 this->executeDispatch_Cut(); 1105 else if(aCommand.equals("DataRanges")) 1106 this->executeDispatch_SourceData(); 1107 //---------------------------------- 1108 else if(aCommand.equals("Update")) //Update Chart 1109 { 1110 ChartViewHelper::setViewToDirtyState( getModel() ); 1111 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1112 if( m_pChartWindow ) 1113 m_pChartWindow->Invalidate(); 1114 } 1115 else if(aCommand.equals("DiagramData")) 1116 this->executeDispatch_EditData(); 1117 //insert objects 1118 else if( aCommand.equals("InsertTitles") 1119 || aCommand.equals("InsertMenuTitles") ) 1120 this->executeDispatch_InsertTitles(); 1121 else if( aCommand.equals("InsertMenuLegend") ) 1122 this->executeDispatch_OpenLegendDialog(); 1123 else if( aCommand.equals("InsertLegend") ) 1124 this->executeDispatch_InsertLegend(); 1125 else if( aCommand.equals("DeleteLegend") ) 1126 this->executeDispatch_DeleteLegend(); 1127 else if( aCommand.equals("InsertMenuDataLabels")) 1128 this->executeDispatch_InsertMenu_DataLabels(); 1129 else if( aCommand.equals("InsertMenuAxes") 1130 || aCommand.equals("InsertRemoveAxes") ) 1131 this->executeDispatch_InsertAxes(); 1132 else if( aCommand.equals("InsertMenuGrids")) 1133 this->executeDispatch_InsertGrid(); 1134 else if( aCommand.equals("InsertMenuTrendlines")) 1135 this->executeDispatch_InsertMenu_Trendlines(); 1136 else if( aCommand.equals("InsertMenuMeanValues")) 1137 this->executeDispatch_InsertMenu_MeanValues(); 1138 else if( aCommand.equals("InsertMenuYErrorBars")) 1139 this->executeDispatch_InsertMenu_YErrorBars(); 1140 else if( aCommand.equals("InsertSymbol")) 1141 this->executeDispatch_InsertSpecialCharacter(); 1142 else if( aCommand.equals("InsertTrendline")) 1143 this->executeDispatch_InsertTrendline(); 1144 else if( aCommand.equals("DeleteTrendline")) 1145 this->executeDispatch_DeleteTrendline(); 1146 else if( aCommand.equals("InsertMeanValue")) 1147 this->executeDispatch_InsertMeanValue(); 1148 else if( aCommand.equals("DeleteMeanValue")) 1149 this->executeDispatch_DeleteMeanValue(); 1150 else if( aCommand.equals("InsertYErrorBars")) 1151 this->executeDispatch_InsertYErrorBars(); 1152 else if( aCommand.equals("DeleteYErrorBars")) 1153 this->executeDispatch_DeleteYErrorBars(); 1154 else if( aCommand.equals("InsertTrendlineEquation")) 1155 this->executeDispatch_InsertTrendlineEquation(); 1156 else if( aCommand.equals("DeleteTrendlineEquation")) 1157 this->executeDispatch_DeleteTrendlineEquation(); 1158 else if( aCommand.equals("InsertTrendlineEquationAndR2")) 1159 this->executeDispatch_InsertTrendlineEquation( true ); 1160 else if( aCommand.equals("InsertR2Value")) 1161 this->executeDispatch_InsertR2Value(); 1162 else if( aCommand.equals("DeleteR2Value")) 1163 this->executeDispatch_DeleteR2Value(); 1164 else if( aCommand.equals("InsertDataLabels") ) 1165 this->executeDispatch_InsertDataLabels(); 1166 else if( aCommand.equals("InsertDataLabel") ) 1167 this->executeDispatch_InsertDataLabel(); 1168 else if( aCommand.equals("DeleteDataLabels") ) 1169 this->executeDispatch_DeleteDataLabels(); 1170 else if( aCommand.equals("DeleteDataLabel") ) 1171 this->executeDispatch_DeleteDataLabel(); 1172 else if( aCommand.equals("ResetAllDataPoints") ) 1173 this->executeDispatch_ResetAllDataPoints(); 1174 else if( aCommand.equals("ResetDataPoint") ) 1175 this->executeDispatch_ResetDataPoint(); 1176 else if( aCommand.equals("InsertAxis") ) 1177 this->executeDispatch_InsertAxis(); 1178 else if( aCommand.equals("InsertMajorGrid") ) 1179 this->executeDispatch_InsertMajorGrid(); 1180 else if( aCommand.equals("InsertMinorGrid") ) 1181 this->executeDispatch_InsertMinorGrid(); 1182 else if( aCommand.equals("InsertAxisTitle") ) 1183 this->executeDispatch_InsertAxisTitle(); 1184 else if( aCommand.equals("DeleteAxis") ) 1185 this->executeDispatch_DeleteAxis(); 1186 else if( aCommand.equals("DeleteMajorGrid") ) 1187 this->executeDispatch_DeleteMajorGrid(); 1188 else if( aCommand.equals("DeleteMinorGrid") ) 1189 this->executeDispatch_DeleteMinorGrid(); 1190 //format objects 1191 else if( aCommand.equals("FormatSelection") ) 1192 this->executeDispatch_ObjectProperties(); 1193 else if( aCommand.equals("TransformDialog")) 1194 { 1195 if ( isShapeContext() ) 1196 { 1197 this->impl_ShapeControllerDispatch( rURL, rArgs ); 1198 } 1199 else 1200 { 1201 this->executeDispatch_PositionAndSize(); 1202 } 1203 } 1204 else if( lcl_isFormatObjectCommand(aCommand) ) 1205 this->executeDispatch_FormatObject(rURL.Path); 1206 //more format 1207 //MENUCHANGE else if(aCommand.equals("SelectSourceRanges")) 1208 //MENUCHANGE this->executeDispatch_SourceData(); 1209 else if( aCommand.equals("DiagramType")) 1210 this->executeDispatch_ChartType(); 1211 else if( aCommand.equals("View3D")) 1212 this->executeDispatch_View3D(); 1213 else if ( aCommand.equals( "Forward" ) ) 1214 { 1215 if ( isShapeContext() ) 1216 { 1217 this->impl_ShapeControllerDispatch( rURL, rArgs ); 1218 } 1219 else 1220 { 1221 this->executeDispatch_MoveSeries( sal_True ); 1222 } 1223 } 1224 else if ( aCommand.equals( "Backward" ) ) 1225 { 1226 if ( isShapeContext() ) 1227 { 1228 this->impl_ShapeControllerDispatch( rURL, rArgs ); 1229 } 1230 else 1231 { 1232 this->executeDispatch_MoveSeries( sal_False ); 1233 } 1234 } 1235 else if( aCommand.equals("NewArrangement")) 1236 this->executeDispatch_NewArrangement(); 1237 else if( aCommand.equals("ToggleLegend")) 1238 this->executeDispatch_ToggleLegend(); 1239 else if( aCommand.equals("ToggleGridHorizontal")) 1240 this->executeDispatch_ToggleGridHorizontal(); 1241 else if( aCommand.equals("ScaleText")) 1242 this->executeDispatch_ScaleText(); 1243 else if( aCommand.equals("StatusBarVisible")) 1244 { 1245 // workaround: this should not be necessary. 1246 uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY ); 1247 if( xPropSet.is() ) 1248 { 1249 uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; 1250 xPropSet->getPropertyValue( C2U( "LayoutManager" ) ) >>= xLayoutManager; 1251 if ( xLayoutManager.is() ) 1252 { 1253 bool bIsVisible( xLayoutManager->isElementVisible( C2U("private:resource/statusbar/statusbar"))); 1254 if( bIsVisible ) 1255 { 1256 xLayoutManager->hideElement( C2U( "private:resource/statusbar/statusbar")); 1257 xLayoutManager->destroyElement( C2U( "private:resource/statusbar/statusbar")); 1258 } 1259 else 1260 { 1261 xLayoutManager->createElement( C2U( "private:resource/statusbar/statusbar")); 1262 xLayoutManager->showElement( C2U( "private:resource/statusbar/statusbar")); 1263 } 1264 // @todo: update menu state (checkmark next to "Statusbar"). 1265 } 1266 } 1267 } 1268 1269 /* 1270 case SID_TEXTEDIT: 1271 this->executeDispatch_EditText(); 1272 */ 1273 } 1274 1275 void SAL_CALL ChartController 1276 ::addStatusListener( const uno::Reference<frame::XStatusListener >& /* xControl */ 1277 , const util::URL& /* aURL */ ) 1278 throw (uno::RuntimeException) 1279 { 1280 // // TODO: add listener by URL ! 1281 // ::vos::OGuard aGuard( Application::GetSolarMutex()); 1282 // if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode? 1283 // return; //behave passive if already disposed or suspended 1284 1285 // //--add listener 1286 // m_aLifeTimeManager.m_aListenerContainer.addInterface( ::getCppuType( & xControl ), xControl ); 1287 } 1288 1289 void SAL_CALL ChartController 1290 ::removeStatusListener( const uno::Reference<frame::XStatusListener >& /* xControl */ 1291 , const util::URL& /* aURL */ ) 1292 throw (uno::RuntimeException) 1293 { 1294 // // TODO: remove listener by URL ! 1295 // ::vos::OGuard aGuard( Application::GetSolarMutex()); 1296 // if( m_aLifeTimeManager.impl_isDisposed() ) 1297 // return; //behave passive if already disposed or suspended 1298 1299 // //--remove listener 1300 // m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType( & xControl ), xControl ); 1301 } 1302 1303 //----------------------------------------------------------------- 1304 // XContextMenuInterception (optional interface) 1305 //----------------------------------------------------------------- 1306 void SAL_CALL ChartController 1307 ::registerContextMenuInterceptor( const uno::Reference< 1308 ui::XContextMenuInterceptor > & /* xInterceptor */) 1309 throw(uno::RuntimeException) 1310 { 1311 //@todo 1312 } 1313 1314 void SAL_CALL ChartController 1315 ::releaseContextMenuInterceptor( const uno::Reference< 1316 ui::XContextMenuInterceptor > & /* xInterceptor */) 1317 throw(uno::RuntimeException) 1318 { 1319 //@todo 1320 } 1321 1322 // ____ XEmbeddedClient ____ 1323 // implementation see: ChartController_EditData.cxx 1324 1325 //----------------------------------------------------------------------------- 1326 //----------------------------------------------------------------------------- 1327 //----------------------------------------------------------------------------- 1328 1329 void SAL_CALL ChartController::executeDispatch_ChartType() 1330 { 1331 // using assignment for broken gcc 3.3 1332 UndoLiveUpdateGuard aUndoGuard = UndoLiveUpdateGuard( 1333 String( SchResId( STR_ACTION_EDIT_CHARTTYPE )), m_xUndoManager ); 1334 1335 // /-- 1336 ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); 1337 //prepare and open dialog 1338 ChartTypeDialog aDlg( m_pChartWindow, getModel(), m_xCC ); 1339 if( aDlg.Execute() == RET_OK ) 1340 { 1341 impl_adaptDataSeriesAutoResize(); 1342 aUndoGuard.commit(); 1343 } 1344 // \-- 1345 } 1346 1347 void SAL_CALL ChartController::executeDispatch_SourceData() 1348 { 1349 //------------------------------------------------------------- 1350 //convert properties to ItemSet 1351 uno::Reference< XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY ); 1352 DBG_ASSERT( xChartDoc.is(), "Invalid XChartDocument" ); 1353 if( !xChartDoc.is()) 1354 return; 1355 1356 // using assignment for broken gcc 3.3 1357 UndoLiveUpdateGuard aUndoGuard = UndoLiveUpdateGuard( 1358 String( SchResId( STR_ACTION_EDIT_DATA_RANGES )), m_xUndoManager ); 1359 if( xChartDoc.is()) 1360 { 1361 // /-- 1362 ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); 1363 ::chart::DataSourceDialog aDlg( m_pChartWindow, xChartDoc, m_xCC ); 1364 if( aDlg.Execute() == RET_OK ) 1365 { 1366 impl_adaptDataSeriesAutoResize(); 1367 aUndoGuard.commit(); 1368 } 1369 // \-- 1370 } 1371 } 1372 1373 void SAL_CALL ChartController::executeDispatch_MoveSeries( sal_Bool bForward ) 1374 { 1375 ControllerLockGuard aCLGuard( getModel() ); 1376 1377 //get selected series 1378 ::rtl::OUString aObjectCID(m_aSelection.getSelectedCID()); 1379 uno::Reference< XDataSeries > xGivenDataSeries( ObjectIdentifier::getDataSeriesForCID( //yyy todo also legendentries and labels? 1380 aObjectCID, getModel() ) ); 1381 1382 UndoGuardWithSelection aUndoGuard( 1383 ActionDescriptionProvider::createDescription( 1384 (bForward ? ActionDescriptionProvider::MOVE_TOTOP : ActionDescriptionProvider::MOVE_TOBOTTOM), 1385 String( SchResId( STR_OBJECT_DATASERIES ))), 1386 m_xUndoManager ); 1387 1388 bool bChanged = DiagramHelper::moveSeries( ChartModelHelper::findDiagram( getModel() ), xGivenDataSeries, bForward ); 1389 if( bChanged ) 1390 { 1391 m_aSelection.setSelection( ObjectIdentifier::getMovedSeriesCID( aObjectCID, bForward ) ); 1392 aUndoGuard.commit(); 1393 } 1394 } 1395 1396 // ____ XMultiServiceFactory ____ 1397 uno::Reference< uno::XInterface > SAL_CALL 1398 ChartController::createInstance( const ::rtl::OUString& aServiceSpecifier ) 1399 throw (uno::Exception, 1400 uno::RuntimeException) 1401 { 1402 uno::Reference< uno::XInterface > xResult; 1403 1404 if( aServiceSpecifier.equals( CHART_ACCESSIBLE_TEXT_SERVICE_NAME )) 1405 xResult.set( impl_createAccessibleTextContext()); 1406 return xResult; 1407 } 1408 1409 uno::Reference< uno::XInterface > SAL_CALL 1410 ChartController::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, 1411 const uno::Sequence< uno::Any >& /* Arguments */ ) 1412 throw (uno::Exception, 1413 uno::RuntimeException) 1414 { 1415 // ignore Arguments 1416 return createInstance( ServiceSpecifier ); 1417 } 1418 1419 uno::Sequence< ::rtl::OUString > SAL_CALL 1420 ChartController::getAvailableServiceNames() 1421 throw (uno::RuntimeException) 1422 { 1423 static uno::Sequence< ::rtl::OUString > aServiceNames; 1424 1425 if( aServiceNames.getLength() == 0 ) 1426 { 1427 aServiceNames.realloc(1); 1428 aServiceNames[0] = CHART_ACCESSIBLE_TEXT_SERVICE_NAME; 1429 } 1430 1431 return aServiceNames; 1432 } 1433 1434 // ____ XModifyListener ____ 1435 void SAL_CALL ChartController::modified( const lang::EventObject& /* aEvent */ ) 1436 throw (uno::RuntimeException) 1437 { 1438 // the source can also be a subobject of the ChartModel 1439 // @todo: change the source in ChartModel to always be the model itself ? 1440 // if( getModel() == aEvent.Source ) 1441 1442 1443 //todo? update menu states ? 1444 } 1445 1446 //----------------------------------------------------------------------------- 1447 //----------------------------------------------------------------------------- 1448 //----------------------------------------------------------------------------- 1449 1450 IMPL_LINK( ChartController, NotifyUndoActionHdl, SdrUndoAction*, pUndoAction ) 1451 { 1452 ENSURE_OR_RETURN( pUndoAction, "invalid Undo action", 1L ); 1453 1454 ::rtl::OUString aObjectCID = m_aSelection.getSelectedCID(); 1455 if ( aObjectCID.getLength() == 0 ) 1456 { 1457 try 1458 { 1459 const Reference< document::XUndoManagerSupplier > xSuppUndo( getModel(), uno::UNO_QUERY_THROW ); 1460 const Reference< document::XUndoManager > xUndoManager( xSuppUndo->getUndoManager(), uno::UNO_QUERY_THROW ); 1461 const Reference< document::XUndoAction > xAction( new impl::ShapeUndoElement( *pUndoAction ) ); 1462 xUndoManager->addUndoAction( xAction ); 1463 } 1464 catch( const uno::Exception& ) 1465 { 1466 DBG_UNHANDLED_EXCEPTION(); 1467 } 1468 } 1469 return 0L; 1470 } 1471 1472 DrawModelWrapper* ChartController::GetDrawModelWrapper() 1473 { 1474 if( !m_pDrawModelWrapper.get() ) 1475 { 1476 ExplicitValueProvider* pProvider = ExplicitValueProvider::getExplicitValueProvider( m_xChartView ); 1477 if( pProvider ) 1478 m_pDrawModelWrapper = pProvider->getDrawModelWrapper(); 1479 if ( m_pDrawModelWrapper.get() ) 1480 { 1481 m_pDrawModelWrapper->getSdrModel().SetNotifyUndoActionHdl( LINK( this, ChartController, NotifyUndoActionHdl ) ); 1482 } 1483 } 1484 return m_pDrawModelWrapper.get(); 1485 } 1486 1487 DrawViewWrapper* ChartController::GetDrawViewWrapper() 1488 { 1489 if ( !m_pDrawViewWrapper ) 1490 { 1491 impl_createDrawViewController(); 1492 } 1493 return m_pDrawViewWrapper; 1494 } 1495 1496 uno::Reference< XAccessible > ChartController::CreateAccessible() 1497 { 1498 uno::Reference< XAccessible > xResult = new AccessibleChartView( m_xCC, GetDrawViewWrapper() ); 1499 impl_initializeAccessible( uno::Reference< lang::XInitialization >( xResult, uno::UNO_QUERY ) ); 1500 return xResult; 1501 } 1502 1503 void ChartController::impl_invalidateAccessible() 1504 { 1505 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1506 if( m_pChartWindow ) 1507 { 1508 Reference< lang::XInitialization > xInit( m_pChartWindow->GetAccessible(false), uno::UNO_QUERY ); 1509 if(xInit.is()) 1510 { 1511 uno::Sequence< uno::Any > aArguments(3);//empty arguments -> invalid accessible 1512 xInit->initialize(aArguments); 1513 } 1514 } 1515 } 1516 void ChartController::impl_initializeAccessible() 1517 { 1518 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1519 if( m_pChartWindow ) 1520 this->impl_initializeAccessible( Reference< lang::XInitialization >( m_pChartWindow->GetAccessible(false), uno::UNO_QUERY ) ); 1521 } 1522 void ChartController::impl_initializeAccessible( const uno::Reference< lang::XInitialization >& xInit ) 1523 { 1524 if(xInit.is()) 1525 { 1526 uno::Sequence< uno::Any > aArguments(5); 1527 uno::Reference<view::XSelectionSupplier> xSelectionSupplier(this); 1528 aArguments[0]=uno::makeAny(xSelectionSupplier); 1529 uno::Reference<frame::XModel> xModel(getModel()); 1530 aArguments[1]=uno::makeAny(xModel); 1531 aArguments[2]=uno::makeAny(m_xChartView); 1532 uno::Reference< XAccessible > xParent; 1533 { 1534 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1535 if( m_pChartWindow ) 1536 { 1537 Window* pParentWin( m_pChartWindow->GetAccessibleParentWindow()); 1538 if( pParentWin ) 1539 xParent.set( pParentWin->GetAccessible()); 1540 } 1541 } 1542 aArguments[3]=uno::makeAny(xParent); 1543 aArguments[4]=uno::makeAny(m_xViewWindow); 1544 1545 xInit->initialize(aArguments); 1546 } 1547 } 1548 1549 ::std::set< ::rtl::OUString > ChartController::impl_getAvailableCommands() 1550 { 1551 return ::comphelper::MakeSet< ::rtl::OUString > 1552 // commands for container forward 1553 ( C2U("AddDirect")) ( C2U("NewDoc")) ( C2U("Open")) 1554 ( C2U("Save")) ( C2U("SaveAs")) ( C2U("SendMail")) 1555 ( C2U("EditDoc")) ( C2U("ExportDirectToPDF")) ( C2U("PrintDefault")) 1556 1557 // own commands 1558 ( C2U("Cut") ) ( C2U("Copy") ) ( C2U("Paste") ) 1559 ( C2U("DataRanges") ) ( C2U("DiagramData") ) 1560 // insert objects 1561 ( C2U("InsertMenuTitles") ) ( C2U("InsertTitles") ) 1562 ( C2U("InsertMenuLegend") ) ( C2U("InsertLegend") ) ( C2U("DeleteLegend") ) 1563 ( C2U("InsertMenuDataLabels") ) 1564 ( C2U("InsertMenuAxes") ) ( C2U("InsertRemoveAxes") ) ( C2U("InsertMenuGrids") ) 1565 ( C2U("InsertSymbol") ) 1566 ( C2U("InsertTrendlineEquation") ) ( C2U("InsertTrendlineEquationAndR2") ) 1567 ( C2U("InsertR2Value") ) ( C2U("DeleteR2Value") ) 1568 ( C2U("InsertMenuTrendlines") ) ( C2U("InsertTrendline") ) 1569 ( C2U("InsertMenuMeanValues") ) ( C2U("InsertMeanValue") ) 1570 ( C2U("InsertMenuYErrorBars") ) ( C2U("InsertYErrorBars") ) 1571 ( C2U("InsertDataLabels") ) ( C2U("InsertDataLabel") ) 1572 ( C2U("DeleteTrendline") ) ( C2U("DeleteMeanValue") ) ( C2U("DeleteTrendlineEquation") ) 1573 ( C2U("DeleteYErrorBars") ) 1574 ( C2U("DeleteDataLabels") ) ( C2U("DeleteDataLabel") ) 1575 //format objects 1576 //MENUCHANGE ( C2U("SelectSourceRanges") ) 1577 ( C2U("FormatSelection") ) ( C2U("TransformDialog") ) 1578 ( C2U("DiagramType") ) ( C2U("View3D") ) 1579 ( C2U("Forward") ) ( C2U("Backward") ) 1580 ( C2U("MainTitle") ) ( C2U("SubTitle") ) 1581 ( C2U("XTitle") ) ( C2U("YTitle") ) ( C2U("ZTitle") ) 1582 ( C2U("SecondaryXTitle") ) ( C2U("SecondaryYTitle") ) 1583 ( C2U("AllTitles") ) ( C2U("Legend") ) 1584 ( C2U("DiagramAxisX") ) ( C2U("DiagramAxisY") ) ( C2U("DiagramAxisZ") ) 1585 ( C2U("DiagramAxisA") ) ( C2U("DiagramAxisB") ) ( C2U("DiagramAxisAll") ) 1586 ( C2U("DiagramGridXMain") ) ( C2U("DiagramGridYMain") ) ( C2U("DiagramGridZMain") ) 1587 ( C2U("DiagramGridXHelp") ) ( C2U("DiagramGridYHelp") ) ( C2U("DiagramGridZHelp") ) 1588 ( C2U("DiagramGridAll") ) 1589 ( C2U("DiagramWall") ) ( C2U("DiagramFloor") ) ( C2U("DiagramArea") ) 1590 1591 //context menu - format objects entries 1592 ( C2U("FormatWall") ) ( C2U("FormatFloor") ) ( C2U("FormatChartArea") ) 1593 ( C2U("FormatLegend") ) 1594 1595 ( C2U("FormatAxis") ) ( C2U("FormatTitle") ) 1596 ( C2U("FormatDataSeries") ) ( C2U("FormatDataPoint") ) 1597 ( C2U("ResetAllDataPoints") ) ( C2U("ResetDataPoint") ) 1598 ( C2U("FormatDataLabels") ) ( C2U("FormatDataLabel") ) 1599 ( C2U("FormatMeanValue") ) ( C2U("FormatTrendline") ) ( C2U("FormatTrendlineEquation") ) 1600 ( C2U("FormatYErrorBars") ) 1601 ( C2U("FormatStockLoss") ) ( C2U("FormatStockGain") ) 1602 1603 ( C2U("FormatMajorGrid") ) ( C2U("InsertMajorGrid") ) ( C2U("DeleteMajorGrid") ) 1604 ( C2U("FormatMinorGrid") ) ( C2U("InsertMinorGrid") ) ( C2U("DeleteMinorGrid") ) 1605 ( C2U("InsertAxis") ) ( C2U("DeleteAxis") ) ( C2U("InsertAxisTitle") ) 1606 1607 // toolbar commands 1608 ( C2U("ToggleGridHorizontal"))( C2U("ToggleLegend") ) ( C2U("ScaleText") ) 1609 ( C2U("NewArrangement") ) ( C2U("Update") ) 1610 ( C2U("DefaultColors") ) ( C2U("BarWidth") ) ( C2U("NumberOfLines") ) 1611 ( C2U("ArrangeRow") ) 1612 ( C2U("StatusBarVisible") ) 1613 ( C2U("ChartElementSelector") ) 1614 ; 1615 } 1616 1617 //............................................................................. 1618 } //namespace chart 1619 //............................................................................. 1620