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