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