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