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