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