xref: /trunk/main/chart2/source/controller/main/ChartController.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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