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