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