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