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