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 // #119999# Do not do this per default to allow the user to deselect the chart OLE with a single press to ESC 602 // select chart area per default: 603 // select( uno::makeAny( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, rtl::OUString() ) ) ); 604 605 uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY ); 606 if( xFact.is()) 607 { 608 m_xChartView = xFact->createInstance( CHART_VIEW_SERVICE_NAME ); 609 GetDrawModelWrapper(); 610 uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY ); 611 if( xViewBroadcaster.is() ) 612 xViewBroadcaster->addModeChangeListener(this); 613 } 614 615 //the frameloader is responsible to call xModel->connectController 616 { 617 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 618 if( m_pChartWindow ) 619 m_pChartWindow->Invalidate(); 620 } 621 622 uno::Reference< document::XUndoManagerSupplier > xSuppUndo( getModel(), uno::UNO_QUERY_THROW ); 623 m_xUndoManager.set( xSuppUndo->getUndoManager(), uno::UNO_QUERY_THROW ); 624 625 return sal_True; 626 } 627 628 uno::Reference< frame::XFrame > SAL_CALL ChartController 629 ::getFrame() throw(uno::RuntimeException) 630 { 631 //provides access to owner frame of this controller 632 //return the frame containing this controller 633 634 return m_xFrame; 635 } 636 637 uno::Reference< frame::XModel > SAL_CALL ChartController 638 ::getModel() throw(uno::RuntimeException) 639 { 640 //provides access to currently attached model 641 //returns the currently attached model 642 643 //return nothing, if you do not have a model 644 TheModelRef aModelRef( m_aModel, m_aModelMutex); 645 if(aModelRef.is()) 646 return aModelRef->getModel(); 647 648 return uno::Reference< frame::XModel > (); 649 } 650 651 uno::Any SAL_CALL ChartController 652 ::getViewData() throw(uno::RuntimeException) 653 { 654 //provides access to current view status 655 //set of data that can be used to restore the current view status at later time 656 // by using XController::restoreViewData() 657 658 ::vos::OGuard aGuard( Application::GetSolarMutex()); 659 if( impl_isDisposedOrSuspended() ) 660 return uno::Any(); //behave passive if already disposed or suspended //@todo? or throw an exception?? 661 662 //-- collect current view state 663 uno::Any aRet; 664 //// @todo integrate specialized implementation 665 666 return aRet; 667 } 668 669 void SAL_CALL ChartController 670 ::restoreViewData( const uno::Any& /* Value */ ) 671 throw(uno::RuntimeException) 672 { 673 //restores the view status using the data gotten from a previous call to XController::getViewData() 674 675 ::vos::OGuard aGuard( Application::GetSolarMutex()); 676 if( impl_isDisposedOrSuspended() ) 677 return; //behave passive if already disposed or suspended //@todo? or throw an exception?? 678 679 //// @todo integrate specialized implementation 680 } 681 682 sal_Bool SAL_CALL ChartController 683 ::suspend( sal_Bool bSuspend ) 684 throw(uno::RuntimeException) 685 { 686 //is called to prepare the controller for closing the view 687 //bSuspend==true: force the controller to suspend his work 688 //bSuspend==false try to reactivate the controller 689 //returns true if request was accepted and of course successfully finished, false otherwise 690 691 //we may show dialogs here to ask the user for saving changes ... @todo? 692 693 ::vos::OGuard aGuard( Application::GetSolarMutex()); 694 if( m_aLifeTimeManager.impl_isDisposed() ) 695 return sal_False; //behave passive if already disposed, return false because request was not accepted //@todo? correct 696 697 if(bSuspend==m_bSuspended) 698 { 699 OSL_ENSURE( sal_False, "new suspend mode equals old suspend mode" ); 700 return sal_True; 701 } 702 703 //change suspend mode 704 if(bSuspend) 705 { 706 //aGuard.clear(); 707 //@todo ??? try to stop all what may prevent me from becoming disposed 708 //aGuard.reset(); 709 710 m_bSuspended = bSuspend; 711 return sal_True; 712 } 713 else 714 { 715 //aGuard.clear(); 716 //@todo ??? redo what was made in section bSuspend==true 717 //aGuard.reset(); 718 719 m_bSuspended = bSuspend; 720 } 721 return sal_True; 722 723 724 /* 725 if ( bSuspend ) 726 getFrame()->removeFrameActionListener( pImp ); 727 else 728 getFrame()->addFrameActionListener( pImp ); 729 */ 730 } 731 732 733 void ChartController::impl_createDrawViewController() 734 { 735 ::vos::OGuard aGuard( Application::GetSolarMutex()); 736 if(!m_pDrawViewWrapper) 737 { 738 if( m_pDrawModelWrapper ) 739 { 740 m_pDrawViewWrapper = new DrawViewWrapper(&m_pDrawModelWrapper->getSdrModel(),m_pChartWindow,true); 741 m_pDrawViewWrapper->attachParentReferenceDevice( getModel() ); 742 } 743 } 744 } 745 void ChartController::impl_deleteDrawViewController() 746 { 747 if( m_pDrawViewWrapper ) 748 { 749 ::vos::OGuard aGuard( Application::GetSolarMutex()); 750 if( m_pDrawViewWrapper->IsTextEdit() ) 751 this->EndTextEdit(); 752 DELETEZ( m_pDrawViewWrapper ); 753 } 754 } 755 756 //----------------------------------------------------------------- 757 // XComponent (base of XController) 758 //----------------------------------------------------------------- 759 760 void SAL_CALL ChartController 761 ::dispose() throw(uno::RuntimeException) 762 { 763 try 764 { 765 //This object should release all resources and references in the 766 //easiest possible manner 767 //This object must notify all registered listeners using the method 768 //<member>XEventListener::disposing</member> 769 770 //hold no mutex 771 if( !m_aLifeTimeManager.dispose() ) 772 return; 773 774 // OSL_ENSURE( m_bSuspended, "dispose was called but controller is not suspended" ); 775 776 this->stopDoubleClickWaiting(); 777 778 //end range highlighting 779 if( m_aModel.is()) 780 { 781 uno::Reference< view::XSelectionChangeListener > xSelectionChangeListener; 782 uno::Reference< chart2::data::XDataReceiver > xDataReceiver( getModel(), uno::UNO_QUERY ); 783 if( xDataReceiver.is() ) 784 xSelectionChangeListener = uno::Reference< view::XSelectionChangeListener >( xDataReceiver->getRangeHighlighter(), uno::UNO_QUERY ); 785 if( xSelectionChangeListener.is() ) 786 { 787 uno::Reference< frame::XController > xController( this ); 788 uno::Reference< lang::XComponent > xComp( xController, uno::UNO_QUERY ); 789 //lang::EventObject aEvent( static_cast< lang::XComponent* >( this ) ); 790 lang::EventObject aEvent( xComp ); 791 xSelectionChangeListener->disposing( aEvent ); 792 } 793 } 794 795 //--release all resources and references 796 { 797 uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY ); 798 if( xViewBroadcaster.is() ) 799 xViewBroadcaster->removeModeChangeListener(this); 800 // /-- 801 impl_invalidateAccessible(); 802 ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); 803 impl_deleteDrawViewController(); 804 m_pDrawModelWrapper.reset(); 805 806 m_apDropTargetHelper.reset(); 807 808 //the accessible view is disposed within window destructor of m_pChartWindow 809 m_pChartWindow->clear(); 810 m_pChartWindow = NULL;//m_pChartWindow is deleted via UNO due to dispose of m_xViewWindow (trigerred by Framework (Controller pretends to be XWindow also)) 811 m_xViewWindow->dispose(); 812 m_xChartView.clear(); 813 // \-- 814 } 815 816 // remove as listener to layout manager events 817 if( m_xLayoutManagerEventBroadcaster.is()) 818 { 819 m_xLayoutManagerEventBroadcaster->removeLayoutManagerEventListener( this ); 820 m_xLayoutManagerEventBroadcaster.set( 0 ); 821 } 822 823 m_xFrame.clear(); 824 m_xUndoManager.clear(); 825 826 TheModelRef aModelRef( m_aModel, m_aModelMutex); 827 m_aModel = NULL; 828 829 if( aModelRef.is()) 830 { 831 uno::Reference< frame::XModel > xModel( aModelRef->getModel() ); 832 if(xModel.is()) 833 xModel->disconnectController( uno::Reference< frame::XController >( this )); 834 835 aModelRef->removeListener( this ); 836 #ifdef TEST_ENABLE_MODIFY_LISTENER 837 try 838 { 839 uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aModelRef->getModel(),uno::UNO_QUERY ); 840 if( xMBroadcaster.is()) 841 xMBroadcaster->removeModifyListener( this ); 842 } 843 catch( const uno::Exception & ex ) 844 { 845 ASSERT_EXCEPTION( ex ); 846 } 847 #endif 848 aModelRef->tryTermination(); 849 } 850 851 //// @todo integrate specialized implementation 852 //e.g. release further resources and references 853 854 m_aDispatchContainer.DisposeAndClear(); 855 } 856 catch( const uno::Exception & ex ) 857 { 858 ASSERT_EXCEPTION( ex ); 859 } 860 } 861 862 void SAL_CALL ChartController 863 ::addEventListener( const uno::Reference<lang::XEventListener>& xListener ) 864 throw(uno::RuntimeException) 865 { 866 ::vos::OGuard aGuard( Application::GetSolarMutex()); 867 if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode? 868 return; //behave passive if already disposed or suspended 869 870 //--add listener 871 m_aLifeTimeManager.m_aListenerContainer.addInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0), xListener ); 872 } 873 874 void SAL_CALL ChartController 875 ::removeEventListener( const uno::Reference< 876 lang::XEventListener>& xListener ) 877 throw(uno::RuntimeException) 878 { 879 ::vos::OGuard aGuard( Application::GetSolarMutex()); 880 if( m_aLifeTimeManager.impl_isDisposed(false) ) 881 return; //behave passive if already disposed or suspended 882 883 //--remove listener 884 m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0), xListener ); 885 } 886 887 888 //----------------------------------------------------------------- 889 // util::XCloseListener 890 //----------------------------------------------------------------- 891 void SAL_CALL ChartController 892 ::queryClosing( const lang::EventObject& rSource, sal_Bool bGetsOwnership ) 893 throw(util::CloseVetoException, uno::RuntimeException) 894 { 895 //do not use the m_aControllerMutex here because this call is not allowed to block 896 897 TheModelRef aModelRef( m_aModel, m_aModelMutex); 898 899 if( !aModelRef.is() ) 900 return; 901 902 if( !(aModelRef->getModel() == rSource.Source) ) 903 { 904 OSL_ENSURE( sal_False, "queryClosing was called on a controller from an unknown source" ); 905 return; 906 } 907 908 if( !m_bCanClose )//@todo tryaqcuire mutex 909 { 910 if( bGetsOwnership ) 911 { 912 aModelRef->SetOwnerShip( bGetsOwnership ); 913 } 914 915 throw util::CloseVetoException(); 916 } 917 else 918 { 919 //@ todo prepare to to closing model -> don't start any further hindering actions 920 } 921 } 922 923 void SAL_CALL ChartController 924 ::notifyClosing( const lang::EventObject& rSource ) 925 throw(uno::RuntimeException) 926 { 927 //Listener should deregister himself and relaese all references to the closing object. 928 929 TheModelRef aModelRef( m_aModel, m_aModelMutex); 930 if( impl_releaseThisModel( rSource.Source ) ) 931 { 932 //--stop listening to the closing model 933 aModelRef->removeListener( this ); 934 935 // #i79087# If the model using this controller is closed, the frame is 936 // expected to be closed as well 937 Reference< util::XCloseable > xFrameCloseable( m_xFrame, uno::UNO_QUERY ); 938 if( xFrameCloseable.is()) 939 { 940 try 941 { 942 xFrameCloseable->close( sal_False /* DeliverOwnership */ ); 943 m_xFrame.clear(); 944 } 945 catch( util::CloseVetoException & ) 946 { 947 // closing was vetoed 948 } 949 } 950 } 951 } 952 953 bool ChartController::impl_releaseThisModel( const uno::Reference< uno::XInterface > & xModel ) 954 { 955 bool bReleaseModel = sal_False; 956 { 957 ::osl::Guard< ::osl::Mutex > aGuard( m_aModelMutex ); 958 if( m_aModel.is() && m_aModel->getModel() == xModel ) 959 { 960 m_aModel = NULL; 961 m_xUndoManager.clear(); 962 bReleaseModel = true; 963 } 964 } 965 if( bReleaseModel ) 966 m_aDispatchContainer.setModel( 0 ); 967 return bReleaseModel; 968 } 969 970 //----------------------------------------------------------------- 971 // util::XEventListener (base of XCloseListener) 972 //----------------------------------------------------------------- 973 void SAL_CALL ChartController 974 ::disposing( const lang::EventObject& rSource ) 975 throw(uno::RuntimeException) 976 { 977 if( !impl_releaseThisModel( rSource.Source )) 978 { 979 if( rSource.Source == m_xLayoutManagerEventBroadcaster ) 980 m_xLayoutManagerEventBroadcaster.set( 0 ); 981 } 982 } 983 984 void SAL_CALL ChartController::layoutEvent( const lang::EventObject& aSource, ::sal_Int16 eLayoutEvent, const uno::Any& /* aInfo */ ) 985 throw (uno::RuntimeException) 986 { 987 if( eLayoutEvent == frame::LayoutManagerEvents::MERGEDMENUBAR ) 988 { 989 Reference< frame::XLayoutManager > xLM( aSource.Source, uno::UNO_QUERY ); 990 if( xLM.is()) 991 { 992 xLM->createElement( C2U("private:resource/statusbar/statusbar")); 993 xLM->requestElement( C2U("private:resource/statusbar/statusbar")); 994 } 995 } 996 } 997 998 999 //----------------------------------------------------------------- 1000 // XDispatchProvider (required interface) 1001 //----------------------------------------------------------------- 1002 1003 namespace 1004 { 1005 bool lcl_isFormatObjectCommand( const rtl::OString& aCommand ) 1006 { 1007 if( aCommand.equals("MainTitle") 1008 || aCommand.equals("SubTitle") 1009 || aCommand.equals("XTitle") 1010 || aCommand.equals("YTitle") 1011 || aCommand.equals("ZTitle") 1012 || aCommand.equals("SecondaryXTitle") 1013 || aCommand.equals("SecondaryYTitle") 1014 || aCommand.equals("AllTitles") 1015 || aCommand.equals("DiagramAxisX") 1016 || aCommand.equals("DiagramAxisY") 1017 || aCommand.equals("DiagramAxisZ") 1018 || aCommand.equals("DiagramAxisA") 1019 || aCommand.equals("DiagramAxisB") 1020 || aCommand.equals("DiagramAxisAll") 1021 || aCommand.equals("DiagramGridXMain") 1022 || aCommand.equals("DiagramGridYMain") 1023 || aCommand.equals("DiagramGridZMain") 1024 || aCommand.equals("DiagramGridXHelp") 1025 || aCommand.equals("DiagramGridYHelp") 1026 || aCommand.equals("DiagramGridZHelp") 1027 || aCommand.equals("DiagramGridAll") 1028 1029 || aCommand.equals("DiagramWall") 1030 || aCommand.equals("DiagramFloor") 1031 || aCommand.equals("DiagramArea") 1032 || aCommand.equals("Legend") 1033 1034 || aCommand.equals("FormatWall") 1035 || aCommand.equals("FormatFloor") 1036 || aCommand.equals("FormatChartArea") 1037 || aCommand.equals("FormatLegend") 1038 1039 || aCommand.equals("FormatTitle") 1040 || aCommand.equals("FormatAxis") 1041 || aCommand.equals("FormatDataSeries") 1042 || aCommand.equals("FormatDataPoint") 1043 || aCommand.equals("FormatDataLabels") 1044 || aCommand.equals("FormatDataLabel") 1045 || aCommand.equals("FormatYErrorBars") 1046 || aCommand.equals("FormatMeanValue") 1047 || aCommand.equals("FormatTrendline") 1048 || aCommand.equals("FormatTrendlineEquation") 1049 || aCommand.equals("FormatStockLoss") 1050 || aCommand.equals("FormatStockGain") 1051 || aCommand.equals("FormatMajorGrid") 1052 || aCommand.equals("FormatMinorGrid") 1053 ) 1054 return true; 1055 1056 // else 1057 return false; 1058 } 1059 } // anonymous namespace 1060 1061 uno::Reference<frame::XDispatch> SAL_CALL ChartController 1062 ::queryDispatch( const util::URL& rURL 1063 , const rtl::OUString& rTargetFrameName 1064 , sal_Int32 /* nSearchFlags */) 1065 throw(uno::RuntimeException) 1066 { 1067 if ( !m_aLifeTimeManager.impl_isDisposed() && getModel().is() ) 1068 { 1069 if( rTargetFrameName.getLength() && 1070 rTargetFrameName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("_self"))) 1071 return m_aDispatchContainer.getDispatchForURL( rURL ); 1072 } 1073 return uno::Reference< frame::XDispatch > (); 1074 } 1075 1076 uno::Sequence<uno::Reference<frame::XDispatch > > ChartController 1077 ::queryDispatches( const uno::Sequence< 1078 frame::DispatchDescriptor>& xDescripts) 1079 throw(uno::RuntimeException) 1080 { 1081 if ( !m_aLifeTimeManager.impl_isDisposed() ) 1082 { 1083 return m_aDispatchContainer.getDispatchesForURLs( xDescripts ); 1084 } 1085 return uno::Sequence<uno::Reference<frame::XDispatch > > (); 1086 } 1087 1088 //----------------------------------------------------------------- 1089 // frame::XDispatch 1090 //----------------------------------------------------------------- 1091 1092 void SAL_CALL ChartController 1093 ::dispatch( const util::URL& rURL 1094 , const uno::Sequence< beans::PropertyValue >& rArgs ) 1095 throw (uno::RuntimeException) 1096 { 1097 //@todo avoid OString (see Mathias mail on bug #104387#) 1098 rtl::OString aCommand( rtl::OUStringToOString( rURL.Path, RTL_TEXTENCODING_ASCII_US ) ); 1099 1100 if(aCommand.equals("Paste")) 1101 this->executeDispatch_Paste(); 1102 else if(aCommand.equals("Copy")) 1103 this->executeDispatch_Copy(); 1104 else if(aCommand.equals("Cut")) 1105 this->executeDispatch_Cut(); 1106 else if(aCommand.equals("DataRanges")) 1107 this->executeDispatch_SourceData(); 1108 //---------------------------------- 1109 else if(aCommand.equals("Update")) //Update Chart 1110 { 1111 ChartViewHelper::setViewToDirtyState( getModel() ); 1112 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1113 if( m_pChartWindow ) 1114 m_pChartWindow->Invalidate(); 1115 } 1116 else if(aCommand.equals("DiagramData")) 1117 this->executeDispatch_EditData(); 1118 //insert objects 1119 else if( aCommand.equals("InsertTitles") 1120 || aCommand.equals("InsertMenuTitles") ) 1121 this->executeDispatch_InsertTitles(); 1122 else if( aCommand.equals("InsertMenuLegend") ) 1123 this->executeDispatch_OpenLegendDialog(); 1124 else if( aCommand.equals("InsertLegend") ) 1125 this->executeDispatch_InsertLegend(); 1126 else if( aCommand.equals("DeleteLegend") ) 1127 this->executeDispatch_DeleteLegend(); 1128 else if( aCommand.equals("InsertMenuDataLabels")) 1129 this->executeDispatch_InsertMenu_DataLabels(); 1130 else if( aCommand.equals("InsertMenuAxes") 1131 || aCommand.equals("InsertRemoveAxes") ) 1132 this->executeDispatch_InsertAxes(); 1133 else if( aCommand.equals("InsertMenuGrids")) 1134 this->executeDispatch_InsertGrid(); 1135 else if( aCommand.equals("InsertMenuTrendlines")) 1136 this->executeDispatch_InsertMenu_Trendlines(); 1137 else if( aCommand.equals("InsertMenuMeanValues")) 1138 this->executeDispatch_InsertMenu_MeanValues(); 1139 else if( aCommand.equals("InsertMenuYErrorBars")) 1140 this->executeDispatch_InsertMenu_YErrorBars(); 1141 else if( aCommand.equals("InsertSymbol")) 1142 this->executeDispatch_InsertSpecialCharacter(); 1143 else if( aCommand.equals("InsertTrendline")) 1144 this->executeDispatch_InsertTrendline(); 1145 else if( aCommand.equals("DeleteTrendline")) 1146 this->executeDispatch_DeleteTrendline(); 1147 else if( aCommand.equals("InsertMeanValue")) 1148 this->executeDispatch_InsertMeanValue(); 1149 else if( aCommand.equals("DeleteMeanValue")) 1150 this->executeDispatch_DeleteMeanValue(); 1151 else if( aCommand.equals("InsertYErrorBars")) 1152 this->executeDispatch_InsertYErrorBars(); 1153 else if( aCommand.equals("DeleteYErrorBars")) 1154 this->executeDispatch_DeleteYErrorBars(); 1155 else if( aCommand.equals("InsertTrendlineEquation")) 1156 this->executeDispatch_InsertTrendlineEquation(); 1157 else if( aCommand.equals("DeleteTrendlineEquation")) 1158 this->executeDispatch_DeleteTrendlineEquation(); 1159 else if( aCommand.equals("InsertTrendlineEquationAndR2")) 1160 this->executeDispatch_InsertTrendlineEquation( true ); 1161 else if( aCommand.equals("InsertR2Value")) 1162 this->executeDispatch_InsertR2Value(); 1163 else if( aCommand.equals("DeleteR2Value")) 1164 this->executeDispatch_DeleteR2Value(); 1165 else if( aCommand.equals("InsertDataLabels") ) 1166 this->executeDispatch_InsertDataLabels(); 1167 else if( aCommand.equals("InsertDataLabel") ) 1168 this->executeDispatch_InsertDataLabel(); 1169 else if( aCommand.equals("DeleteDataLabels") ) 1170 this->executeDispatch_DeleteDataLabels(); 1171 else if( aCommand.equals("DeleteDataLabel") ) 1172 this->executeDispatch_DeleteDataLabel(); 1173 else if( aCommand.equals("ResetAllDataPoints") ) 1174 this->executeDispatch_ResetAllDataPoints(); 1175 else if( aCommand.equals("ResetDataPoint") ) 1176 this->executeDispatch_ResetDataPoint(); 1177 else if( aCommand.equals("InsertAxis") ) 1178 this->executeDispatch_InsertAxis(); 1179 else if( aCommand.equals("InsertMajorGrid") ) 1180 this->executeDispatch_InsertMajorGrid(); 1181 else if( aCommand.equals("InsertMinorGrid") ) 1182 this->executeDispatch_InsertMinorGrid(); 1183 else if( aCommand.equals("InsertAxisTitle") ) 1184 this->executeDispatch_InsertAxisTitle(); 1185 else if( aCommand.equals("DeleteAxis") ) 1186 this->executeDispatch_DeleteAxis(); 1187 else if( aCommand.equals("DeleteMajorGrid") ) 1188 this->executeDispatch_DeleteMajorGrid(); 1189 else if( aCommand.equals("DeleteMinorGrid") ) 1190 this->executeDispatch_DeleteMinorGrid(); 1191 //format objects 1192 else if( aCommand.equals("FormatSelection") ) 1193 this->executeDispatch_ObjectProperties(); 1194 else if( aCommand.equals("TransformDialog")) 1195 { 1196 if ( isShapeContext() ) 1197 { 1198 this->impl_ShapeControllerDispatch( rURL, rArgs ); 1199 } 1200 else 1201 { 1202 this->executeDispatch_PositionAndSize(); 1203 } 1204 } 1205 else if( lcl_isFormatObjectCommand(aCommand) ) 1206 this->executeDispatch_FormatObject(rURL.Path); 1207 //more format 1208 //MENUCHANGE else if(aCommand.equals("SelectSourceRanges")) 1209 //MENUCHANGE this->executeDispatch_SourceData(); 1210 else if( aCommand.equals("DiagramType")) 1211 this->executeDispatch_ChartType(); 1212 else if( aCommand.equals("View3D")) 1213 this->executeDispatch_View3D(); 1214 else if ( aCommand.equals( "Forward" ) ) 1215 { 1216 if ( isShapeContext() ) 1217 { 1218 this->impl_ShapeControllerDispatch( rURL, rArgs ); 1219 } 1220 else 1221 { 1222 this->executeDispatch_MoveSeries( sal_True ); 1223 } 1224 } 1225 else if ( aCommand.equals( "Backward" ) ) 1226 { 1227 if ( isShapeContext() ) 1228 { 1229 this->impl_ShapeControllerDispatch( rURL, rArgs ); 1230 } 1231 else 1232 { 1233 this->executeDispatch_MoveSeries( sal_False ); 1234 } 1235 } 1236 else if( aCommand.equals("NewArrangement")) 1237 this->executeDispatch_NewArrangement(); 1238 else if( aCommand.equals("ToggleLegend")) 1239 this->executeDispatch_ToggleLegend(); 1240 else if( aCommand.equals("ToggleGridHorizontal")) 1241 this->executeDispatch_ToggleGridHorizontal(); 1242 else if( aCommand.equals("ScaleText")) 1243 this->executeDispatch_ScaleText(); 1244 else if( aCommand.equals("StatusBarVisible")) 1245 { 1246 // workaround: this should not be necessary. 1247 uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY ); 1248 if( xPropSet.is() ) 1249 { 1250 uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; 1251 xPropSet->getPropertyValue( C2U( "LayoutManager" ) ) >>= xLayoutManager; 1252 if ( xLayoutManager.is() ) 1253 { 1254 bool bIsVisible( xLayoutManager->isElementVisible( C2U("private:resource/statusbar/statusbar"))); 1255 if( bIsVisible ) 1256 { 1257 xLayoutManager->hideElement( C2U( "private:resource/statusbar/statusbar")); 1258 xLayoutManager->destroyElement( C2U( "private:resource/statusbar/statusbar")); 1259 } 1260 else 1261 { 1262 xLayoutManager->createElement( C2U( "private:resource/statusbar/statusbar")); 1263 xLayoutManager->showElement( C2U( "private:resource/statusbar/statusbar")); 1264 } 1265 // @todo: update menu state (checkmark next to "Statusbar"). 1266 } 1267 } 1268 } 1269 1270 /* 1271 case SID_TEXTEDIT: 1272 this->executeDispatch_EditText(); 1273 */ 1274 } 1275 1276 void SAL_CALL ChartController 1277 ::addStatusListener( const uno::Reference<frame::XStatusListener >& /* xControl */ 1278 , const util::URL& /* aURL */ ) 1279 throw (uno::RuntimeException) 1280 { 1281 // // TODO: add listener by URL ! 1282 // ::vos::OGuard aGuard( Application::GetSolarMutex()); 1283 // if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode? 1284 // return; //behave passive if already disposed or suspended 1285 1286 // //--add listener 1287 // m_aLifeTimeManager.m_aListenerContainer.addInterface( ::getCppuType( & xControl ), xControl ); 1288 } 1289 1290 void SAL_CALL ChartController 1291 ::removeStatusListener( const uno::Reference<frame::XStatusListener >& /* xControl */ 1292 , const util::URL& /* aURL */ ) 1293 throw (uno::RuntimeException) 1294 { 1295 // // TODO: remove listener by URL ! 1296 // ::vos::OGuard aGuard( Application::GetSolarMutex()); 1297 // if( m_aLifeTimeManager.impl_isDisposed() ) 1298 // return; //behave passive if already disposed or suspended 1299 1300 // //--remove listener 1301 // m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType( & xControl ), xControl ); 1302 } 1303 1304 //----------------------------------------------------------------- 1305 // XContextMenuInterception (optional interface) 1306 //----------------------------------------------------------------- 1307 void SAL_CALL ChartController 1308 ::registerContextMenuInterceptor( const uno::Reference< 1309 ui::XContextMenuInterceptor > & /* xInterceptor */) 1310 throw(uno::RuntimeException) 1311 { 1312 //@todo 1313 } 1314 1315 void SAL_CALL ChartController 1316 ::releaseContextMenuInterceptor( const uno::Reference< 1317 ui::XContextMenuInterceptor > & /* xInterceptor */) 1318 throw(uno::RuntimeException) 1319 { 1320 //@todo 1321 } 1322 1323 // ____ XEmbeddedClient ____ 1324 // implementation see: ChartController_EditData.cxx 1325 1326 //----------------------------------------------------------------------------- 1327 //----------------------------------------------------------------------------- 1328 //----------------------------------------------------------------------------- 1329 1330 void SAL_CALL ChartController::executeDispatch_ChartType() 1331 { 1332 // using assignment for broken gcc 3.3 1333 UndoLiveUpdateGuard aUndoGuard = UndoLiveUpdateGuard( 1334 String( SchResId( STR_ACTION_EDIT_CHARTTYPE )), m_xUndoManager ); 1335 1336 // /-- 1337 ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); 1338 //prepare and open dialog 1339 ChartTypeDialog aDlg( m_pChartWindow, getModel(), m_xCC ); 1340 if( aDlg.Execute() == RET_OK ) 1341 { 1342 impl_adaptDataSeriesAutoResize(); 1343 aUndoGuard.commit(); 1344 } 1345 // \-- 1346 } 1347 1348 void SAL_CALL ChartController::executeDispatch_SourceData() 1349 { 1350 //------------------------------------------------------------- 1351 //convert properties to ItemSet 1352 uno::Reference< XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY ); 1353 DBG_ASSERT( xChartDoc.is(), "Invalid XChartDocument" ); 1354 if( !xChartDoc.is()) 1355 return; 1356 1357 // using assignment for broken gcc 3.3 1358 UndoLiveUpdateGuard aUndoGuard = UndoLiveUpdateGuard( 1359 String( SchResId( STR_ACTION_EDIT_DATA_RANGES )), m_xUndoManager ); 1360 if( xChartDoc.is()) 1361 { 1362 // /-- 1363 ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); 1364 ::chart::DataSourceDialog aDlg( m_pChartWindow, xChartDoc, m_xCC ); 1365 if( aDlg.Execute() == RET_OK ) 1366 { 1367 impl_adaptDataSeriesAutoResize(); 1368 aUndoGuard.commit(); 1369 } 1370 // \-- 1371 } 1372 } 1373 1374 void SAL_CALL ChartController::executeDispatch_MoveSeries( sal_Bool bForward ) 1375 { 1376 ControllerLockGuard aCLGuard( getModel() ); 1377 1378 //get selected series 1379 ::rtl::OUString aObjectCID(m_aSelection.getSelectedCID()); 1380 uno::Reference< XDataSeries > xGivenDataSeries( ObjectIdentifier::getDataSeriesForCID( //yyy todo also legendentries and labels? 1381 aObjectCID, getModel() ) ); 1382 1383 UndoGuardWithSelection aUndoGuard( 1384 ActionDescriptionProvider::createDescription( 1385 (bForward ? ActionDescriptionProvider::MOVE_TOTOP : ActionDescriptionProvider::MOVE_TOBOTTOM), 1386 String( SchResId( STR_OBJECT_DATASERIES ))), 1387 m_xUndoManager ); 1388 1389 bool bChanged = DiagramHelper::moveSeries( ChartModelHelper::findDiagram( getModel() ), xGivenDataSeries, bForward ); 1390 if( bChanged ) 1391 { 1392 m_aSelection.setSelection( ObjectIdentifier::getMovedSeriesCID( aObjectCID, bForward ) ); 1393 aUndoGuard.commit(); 1394 } 1395 } 1396 1397 // ____ XMultiServiceFactory ____ 1398 uno::Reference< uno::XInterface > SAL_CALL 1399 ChartController::createInstance( const ::rtl::OUString& aServiceSpecifier ) 1400 throw (uno::Exception, 1401 uno::RuntimeException) 1402 { 1403 uno::Reference< uno::XInterface > xResult; 1404 1405 if( aServiceSpecifier.equals( CHART_ACCESSIBLE_TEXT_SERVICE_NAME )) 1406 xResult.set( impl_createAccessibleTextContext()); 1407 return xResult; 1408 } 1409 1410 uno::Reference< uno::XInterface > SAL_CALL 1411 ChartController::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, 1412 const uno::Sequence< uno::Any >& /* Arguments */ ) 1413 throw (uno::Exception, 1414 uno::RuntimeException) 1415 { 1416 // ignore Arguments 1417 return createInstance( ServiceSpecifier ); 1418 } 1419 1420 uno::Sequence< ::rtl::OUString > SAL_CALL 1421 ChartController::getAvailableServiceNames() 1422 throw (uno::RuntimeException) 1423 { 1424 static uno::Sequence< ::rtl::OUString > aServiceNames; 1425 1426 if( aServiceNames.getLength() == 0 ) 1427 { 1428 aServiceNames.realloc(1); 1429 aServiceNames[0] = CHART_ACCESSIBLE_TEXT_SERVICE_NAME; 1430 } 1431 1432 return aServiceNames; 1433 } 1434 1435 // ____ XModifyListener ____ 1436 void SAL_CALL ChartController::modified( const lang::EventObject& /* aEvent */ ) 1437 throw (uno::RuntimeException) 1438 { 1439 // the source can also be a subobject of the ChartModel 1440 // @todo: change the source in ChartModel to always be the model itself ? 1441 // if( getModel() == aEvent.Source ) 1442 1443 1444 //todo? update menu states ? 1445 } 1446 1447 //----------------------------------------------------------------------------- 1448 //----------------------------------------------------------------------------- 1449 //----------------------------------------------------------------------------- 1450 1451 IMPL_LINK( ChartController, NotifyUndoActionHdl, SdrUndoAction*, pUndoAction ) 1452 { 1453 ENSURE_OR_RETURN( pUndoAction, "invalid Undo action", 1L ); 1454 1455 ::rtl::OUString aObjectCID = m_aSelection.getSelectedCID(); 1456 if ( aObjectCID.getLength() == 0 ) 1457 { 1458 try 1459 { 1460 const Reference< document::XUndoManagerSupplier > xSuppUndo( getModel(), uno::UNO_QUERY_THROW ); 1461 const Reference< document::XUndoManager > xUndoManager( xSuppUndo->getUndoManager(), uno::UNO_QUERY_THROW ); 1462 const Reference< document::XUndoAction > xAction( new impl::ShapeUndoElement( *pUndoAction ) ); 1463 xUndoManager->addUndoAction( xAction ); 1464 } 1465 catch( const uno::Exception& ) 1466 { 1467 DBG_UNHANDLED_EXCEPTION(); 1468 } 1469 } 1470 return 0L; 1471 } 1472 1473 DrawModelWrapper* ChartController::GetDrawModelWrapper() 1474 { 1475 if( !m_pDrawModelWrapper.get() ) 1476 { 1477 ExplicitValueProvider* pProvider = ExplicitValueProvider::getExplicitValueProvider( m_xChartView ); 1478 if( pProvider ) 1479 m_pDrawModelWrapper = pProvider->getDrawModelWrapper(); 1480 if ( m_pDrawModelWrapper.get() ) 1481 { 1482 m_pDrawModelWrapper->getSdrModel().SetNotifyUndoActionHdl( LINK( this, ChartController, NotifyUndoActionHdl ) ); 1483 } 1484 } 1485 return m_pDrawModelWrapper.get(); 1486 } 1487 1488 DrawViewWrapper* ChartController::GetDrawViewWrapper() 1489 { 1490 if ( !m_pDrawViewWrapper ) 1491 { 1492 impl_createDrawViewController(); 1493 } 1494 return m_pDrawViewWrapper; 1495 } 1496 1497 uno::Reference< XAccessible > ChartController::CreateAccessible() 1498 { 1499 uno::Reference< XAccessible > xResult = new AccessibleChartView( m_xCC, GetDrawViewWrapper() ); 1500 impl_initializeAccessible( uno::Reference< lang::XInitialization >( xResult, uno::UNO_QUERY ) ); 1501 return xResult; 1502 } 1503 1504 void ChartController::impl_invalidateAccessible() 1505 { 1506 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1507 if( m_pChartWindow ) 1508 { 1509 Reference< lang::XInitialization > xInit( m_pChartWindow->GetAccessible(false), uno::UNO_QUERY ); 1510 if(xInit.is()) 1511 { 1512 uno::Sequence< uno::Any > aArguments(3);//empty arguments -> invalid accessible 1513 xInit->initialize(aArguments); 1514 } 1515 } 1516 } 1517 void ChartController::impl_initializeAccessible() 1518 { 1519 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1520 if( m_pChartWindow ) 1521 this->impl_initializeAccessible( Reference< lang::XInitialization >( m_pChartWindow->GetAccessible(false), uno::UNO_QUERY ) ); 1522 } 1523 void ChartController::impl_initializeAccessible( const uno::Reference< lang::XInitialization >& xInit ) 1524 { 1525 if(xInit.is()) 1526 { 1527 uno::Sequence< uno::Any > aArguments(5); 1528 uno::Reference<view::XSelectionSupplier> xSelectionSupplier(this); 1529 aArguments[0]=uno::makeAny(xSelectionSupplier); 1530 uno::Reference<frame::XModel> xModel(getModel()); 1531 aArguments[1]=uno::makeAny(xModel); 1532 aArguments[2]=uno::makeAny(m_xChartView); 1533 uno::Reference< XAccessible > xParent; 1534 { 1535 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1536 if( m_pChartWindow ) 1537 { 1538 Window* pParentWin( m_pChartWindow->GetAccessibleParentWindow()); 1539 if( pParentWin ) 1540 xParent.set( pParentWin->GetAccessible()); 1541 } 1542 } 1543 aArguments[3]=uno::makeAny(xParent); 1544 aArguments[4]=uno::makeAny(m_xViewWindow); 1545 1546 xInit->initialize(aArguments); 1547 } 1548 } 1549 1550 ::std::set< ::rtl::OUString > ChartController::impl_getAvailableCommands() 1551 { 1552 return ::comphelper::MakeSet< ::rtl::OUString > 1553 // commands for container forward 1554 ( C2U("AddDirect")) ( C2U("NewDoc")) ( C2U("Open")) 1555 ( C2U("Save")) ( C2U("SaveAs")) ( C2U("SendMail")) 1556 ( C2U("EditDoc")) ( C2U("ExportDirectToPDF")) ( C2U("PrintDefault")) 1557 1558 // own commands 1559 ( C2U("Cut") ) ( C2U("Copy") ) ( C2U("Paste") ) 1560 ( C2U("DataRanges") ) ( C2U("DiagramData") ) 1561 // insert objects 1562 ( C2U("InsertMenuTitles") ) ( C2U("InsertTitles") ) 1563 ( C2U("InsertMenuLegend") ) ( C2U("InsertLegend") ) ( C2U("DeleteLegend") ) 1564 ( C2U("InsertMenuDataLabels") ) 1565 ( C2U("InsertMenuAxes") ) ( C2U("InsertRemoveAxes") ) ( C2U("InsertMenuGrids") ) 1566 ( C2U("InsertSymbol") ) 1567 ( C2U("InsertTrendlineEquation") ) ( C2U("InsertTrendlineEquationAndR2") ) 1568 ( C2U("InsertR2Value") ) ( C2U("DeleteR2Value") ) 1569 ( C2U("InsertMenuTrendlines") ) ( C2U("InsertTrendline") ) 1570 ( C2U("InsertMenuMeanValues") ) ( C2U("InsertMeanValue") ) 1571 ( C2U("InsertMenuYErrorBars") ) ( C2U("InsertYErrorBars") ) 1572 ( C2U("InsertDataLabels") ) ( C2U("InsertDataLabel") ) 1573 ( C2U("DeleteTrendline") ) ( C2U("DeleteMeanValue") ) ( C2U("DeleteTrendlineEquation") ) 1574 ( C2U("DeleteYErrorBars") ) 1575 ( C2U("DeleteDataLabels") ) ( C2U("DeleteDataLabel") ) 1576 //format objects 1577 //MENUCHANGE ( C2U("SelectSourceRanges") ) 1578 ( C2U("FormatSelection") ) ( C2U("TransformDialog") ) 1579 ( C2U("DiagramType") ) ( C2U("View3D") ) 1580 ( C2U("Forward") ) ( C2U("Backward") ) 1581 ( C2U("MainTitle") ) ( C2U("SubTitle") ) 1582 ( C2U("XTitle") ) ( C2U("YTitle") ) ( C2U("ZTitle") ) 1583 ( C2U("SecondaryXTitle") ) ( C2U("SecondaryYTitle") ) 1584 ( C2U("AllTitles") ) ( C2U("Legend") ) 1585 ( C2U("DiagramAxisX") ) ( C2U("DiagramAxisY") ) ( C2U("DiagramAxisZ") ) 1586 ( C2U("DiagramAxisA") ) ( C2U("DiagramAxisB") ) ( C2U("DiagramAxisAll") ) 1587 ( C2U("DiagramGridXMain") ) ( C2U("DiagramGridYMain") ) ( C2U("DiagramGridZMain") ) 1588 ( C2U("DiagramGridXHelp") ) ( C2U("DiagramGridYHelp") ) ( C2U("DiagramGridZHelp") ) 1589 ( C2U("DiagramGridAll") ) 1590 ( C2U("DiagramWall") ) ( C2U("DiagramFloor") ) ( C2U("DiagramArea") ) 1591 1592 //context menu - format objects entries 1593 ( C2U("FormatWall") ) ( C2U("FormatFloor") ) ( C2U("FormatChartArea") ) 1594 ( C2U("FormatLegend") ) 1595 1596 ( C2U("FormatAxis") ) ( C2U("FormatTitle") ) 1597 ( C2U("FormatDataSeries") ) ( C2U("FormatDataPoint") ) 1598 ( C2U("ResetAllDataPoints") ) ( C2U("ResetDataPoint") ) 1599 ( C2U("FormatDataLabels") ) ( C2U("FormatDataLabel") ) 1600 ( C2U("FormatMeanValue") ) ( C2U("FormatTrendline") ) ( C2U("FormatTrendlineEquation") ) 1601 ( C2U("FormatYErrorBars") ) 1602 ( C2U("FormatStockLoss") ) ( C2U("FormatStockGain") ) 1603 1604 ( C2U("FormatMajorGrid") ) ( C2U("InsertMajorGrid") ) ( C2U("DeleteMajorGrid") ) 1605 ( C2U("FormatMinorGrid") ) ( C2U("InsertMinorGrid") ) ( C2U("DeleteMinorGrid") ) 1606 ( C2U("InsertAxis") ) ( C2U("DeleteAxis") ) ( C2U("InsertAxisTitle") ) 1607 1608 // toolbar commands 1609 ( C2U("ToggleGridHorizontal"))( C2U("ToggleLegend") ) ( C2U("ScaleText") ) 1610 ( C2U("NewArrangement") ) ( C2U("Update") ) 1611 ( C2U("DefaultColors") ) ( C2U("BarWidth") ) ( C2U("NumberOfLines") ) 1612 ( C2U("ArrangeRow") ) 1613 ( C2U("StatusBarVisible") ) 1614 ( C2U("ChartElementSelector") ) 1615 ; 1616 } 1617 1618 //............................................................................. 1619 } //namespace chart 1620 //............................................................................. 1621