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