update dev300-m57
[ooovba.git] / chart2 / source / controller / main / ChartController_Window.cxx
blob16f49bd573de018b609ff1cd75b67d59e1982029
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ChartController_Window.cxx,v $
10 * $Revision: 1.31.24.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
33 #include "ChartController.hxx"
34 #include "PositionAndSizeHelper.hxx"
35 #include "ObjectIdentifier.hxx"
36 #include "ChartWindow.hxx"
37 #include "ResId.hxx"
38 #include "CommonConverters.hxx"
39 #include "ChartModelHelper.hxx"
40 #include "DiagramHelper.hxx"
41 #include "TitleHelper.hxx"
42 #include "UndoGuard.hxx"
43 #include "ControllerLockGuard.hxx"
44 #include "ObjectNameProvider.hxx"
45 #include "Strings.hrc"
46 #include "SchSlotIds.hxx"
47 #include "macros.hxx"
48 #include "DragMethod_PieSegment.hxx"
49 #include "DragMethod_RotateDiagram.hxx"
50 #include "ObjectHierarchy.hxx"
51 #include "chartview/ExplicitValueProvider.hxx"
52 #include "RelativePositionHelper.hxx"
53 #include "chartview/DrawModelWrapper.hxx"
55 #include <com/sun/star/chart2/RelativePosition.hpp>
56 #include <com/sun/star/chart2/RelativeSize.hpp>
58 #include <com/sun/star/frame/XDispatchHelper.hpp>
59 #include <com/sun/star/frame/FrameSearchFlag.hpp>
60 #include <com/sun/star/util/XUpdatable.hpp>
61 #include <comphelper/InlineContainer.hxx>
63 #include <svtools/contextmenuhelper.hxx>
64 #include <toolkit/awt/vclxmenu.hxx>
66 #include <svx/svxids.hrc>
67 #include <svx/ActionDescriptionProvider.hxx>
69 // header for class E3dObject
70 #include <svx/obj3d.hxx>
71 // header for class E3dScene
72 #include <svx/scene3d.hxx>
73 // header for class SdrDragMethod
74 #include <svx/svddrgmt.hxx>
75 #include <vcl/svapp.hxx>
76 #include <vos/mutex.hxx>
78 // for InfoBox
79 #include <vcl/msgbox.hxx>
81 #include <rtl/math.hxx>
82 #include <svtools/acceleratorexecute.hxx>
84 #define DRGPIX 2 // Drag MinMove in Pixel
86 using namespace ::com::sun::star;
87 using namespace ::com::sun::star::chart2;
89 namespace
91 bool lcl_GrowAndShiftLogic(
92 RelativePosition & rInOutRelPos,
93 RelativeSize & rInOutRelSize,
94 const awt::Size & rRefSize,
95 double fGrowLogicX,
96 double fGrowLogicY )
98 if( rRefSize.Width == 0 ||
99 rRefSize.Height == 0 )
100 return false;
102 double fRelativeGrowX = fGrowLogicX / rRefSize.Width;
103 double fRelativeGrowY = fGrowLogicY / rRefSize.Height;
105 return ::chart::RelativePositionHelper::centerGrow(
106 rInOutRelPos, rInOutRelSize,
107 fRelativeGrowX, fRelativeGrowY,
108 /* bCheck = */ true );
111 bool lcl_MoveObjectLogic(
112 RelativePosition & rInOutRelPos,
113 RelativeSize & rObjectSize,
114 const awt::Size & rRefSize,
115 double fShiftLogicX,
116 double fShiftLogicY )
118 if( rRefSize.Width == 0 ||
119 rRefSize.Height == 0 )
120 return false;
122 double fRelativeShiftX = fShiftLogicX / rRefSize.Width;
123 double fRelativeShiftY = fShiftLogicY / rRefSize.Height;
125 return ::chart::RelativePositionHelper::moveObject(
126 rInOutRelPos, rObjectSize,
127 fRelativeShiftX, fRelativeShiftY,
128 /* bCheck = */ true );
131 void lcl_insertMenuCommand(
132 const uno::Reference< awt::XPopupMenu > & xMenu,
133 const uno::Reference< awt::XMenuExtended > & xMenuEx,
134 sal_Int16 nId, const ::rtl::OUString & rCommand )
136 static ::rtl::OUString aEmptyString;
137 xMenu->insertItem( nId, aEmptyString, 0, -1 );
138 xMenuEx->setCommand( nId, rCommand );
141 } // anonymous namespace
144 //.............................................................................
145 namespace chart
147 //.............................................................................
149 const short HITPIX=2; //hit-tolerance in pixel
151 //-----------------------------------------------------------------
152 // awt::XWindow
153 //-----------------------------------------------------------------
154 void SAL_CALL ChartController
155 ::setPosSize( sal_Int32 X, sal_Int32 Y
156 , sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags )
157 throw (uno::RuntimeException)
159 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
160 Window* pWindow = m_pChartWindow;
162 if(xWindow.is() && pWindow)
164 Size aLogicSize = pWindow->PixelToLogic( Size( Width, Height ), MapMode( MAP_100TH_MM ) );
166 bool bIsEmbedded = true;
167 //todo: for standalone chart: detect wether we are standalone
168 if( bIsEmbedded )
170 //change map mode to fit new size
171 awt::Size aModelPageSize = ChartModelHelper::getPageSize( m_aModel->getModel() );
172 sal_Int32 nScaleXNumerator = aLogicSize.Width();
173 sal_Int32 nScaleXDenominator = aModelPageSize.Width;
174 sal_Int32 nScaleYNumerator = aLogicSize.Height();
175 sal_Int32 nScaleYDenominator = aModelPageSize.Height;
176 MapMode aNewMapMode( MAP_100TH_MM, Point(0,0)
177 , Fraction(nScaleXNumerator,nScaleXDenominator)
178 , Fraction(nScaleYNumerator,nScaleYDenominator) );
179 pWindow->SetMapMode(aNewMapMode);
180 pWindow->SetPosSizePixel( X, Y, Width, Height, Flags );
182 //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
183 uno::Reference< beans::XPropertySet > xProp( m_xChartView, uno::UNO_QUERY );
184 if( xProp.is() )
186 uno::Sequence< beans::PropertyValue > aZoomFactors(4);
187 aZoomFactors[0].Name = C2U("ScaleXNumerator");
188 aZoomFactors[0].Value = uno::makeAny( nScaleXNumerator );
189 aZoomFactors[1].Name = C2U("ScaleXDenominator");
190 aZoomFactors[1].Value = uno::makeAny( nScaleXDenominator );
191 aZoomFactors[2].Name = C2U("ScaleYNumerator");
192 aZoomFactors[2].Value = uno::makeAny( nScaleYNumerator );
193 aZoomFactors[3].Name = C2U("ScaleYDenominator");
194 aZoomFactors[3].Value = uno::makeAny( nScaleYDenominator );
195 xProp->setPropertyValue( C2U("ZoomFactors"), uno::makeAny( aZoomFactors ));
198 //a correct work area is at least necessary for correct values in the position and size dialog and for dragging area
199 if(m_pDrawViewWrapper)
201 Rectangle aRect(Point(0,0), pWindow->GetOutputSize());
202 m_pDrawViewWrapper->SetWorkArea( aRect );
205 else
207 //change visarea
208 ChartModelHelper::setPageSize( awt::Size( aLogicSize.Width(), aLogicSize.Height() ), m_aModel->getModel() );
209 pWindow->SetPosSizePixel( X, Y, Width, Height, Flags );
211 pWindow->Invalidate();
215 awt::Rectangle SAL_CALL ChartController
216 ::getPosSize()
217 throw (uno::RuntimeException)
219 //@todo
220 awt::Rectangle aRet(0,0,0,0);
222 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
223 if(xWindow.is())
224 aRet = xWindow->getPosSize();
226 return aRet;
229 void SAL_CALL ChartController
230 ::setVisible( sal_Bool Visible )
231 throw (uno::RuntimeException)
233 //@todo
234 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
236 if(xWindow.is())
237 xWindow->setVisible( Visible );
240 void SAL_CALL ChartController
241 ::setEnable( sal_Bool Enable )
242 throw (uno::RuntimeException)
244 //@todo
245 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
247 if(xWindow.is())
248 xWindow->setEnable( Enable );
251 void SAL_CALL ChartController
252 ::setFocus() throw (uno::RuntimeException)
254 //@todo
255 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
257 if(xWindow.is())
258 xWindow->setFocus();
261 void SAL_CALL ChartController
262 ::addWindowListener( const uno::Reference<
263 awt::XWindowListener >& xListener )
264 throw (uno::RuntimeException)
266 //@todo
267 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
269 if(xWindow.is())
270 xWindow->addWindowListener( xListener );
273 void SAL_CALL ChartController
274 ::removeWindowListener( const uno::Reference<
275 awt::XWindowListener >& xListener )
276 throw (uno::RuntimeException)
278 //@todo
279 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
281 if(xWindow.is())
282 xWindow->removeWindowListener( xListener );
285 void SAL_CALL ChartController
286 ::addFocusListener( const uno::Reference<
287 awt::XFocusListener >& xListener )
288 throw (uno::RuntimeException)
290 //@todo
291 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
293 if(xWindow.is())
294 xWindow->addFocusListener( xListener );
297 void SAL_CALL ChartController
298 ::removeFocusListener( const uno::Reference<
299 awt::XFocusListener >& xListener )
300 throw (uno::RuntimeException)
302 //@todo
303 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
305 if(xWindow.is())
306 xWindow->removeFocusListener( xListener );
309 void SAL_CALL ChartController
310 ::addKeyListener( const uno::Reference<
311 awt::XKeyListener >& xListener )
312 throw (uno::RuntimeException)
314 //@todo
315 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
317 if(xWindow.is())
318 xWindow->addKeyListener( xListener );
321 void SAL_CALL ChartController
322 ::removeKeyListener( const uno::Reference<
323 awt::XKeyListener >& xListener )
324 throw (uno::RuntimeException)
326 //@todo
327 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
329 if(xWindow.is())
330 xWindow->removeKeyListener( xListener );
333 void SAL_CALL ChartController
334 ::addMouseListener( const uno::Reference<
335 awt::XMouseListener >& xListener )
336 throw (uno::RuntimeException)
338 //@todo
339 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
341 if(xWindow.is())
342 xWindow->addMouseListener( xListener );
345 void SAL_CALL ChartController
346 ::removeMouseListener( const uno::Reference<
347 awt::XMouseListener >& xListener )
348 throw (uno::RuntimeException)
350 //@todo
351 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
353 if(xWindow.is())
354 xWindow->removeMouseListener( xListener );
357 void SAL_CALL ChartController
358 ::addMouseMotionListener( const uno::Reference<
359 awt::XMouseMotionListener >& xListener )
360 throw (uno::RuntimeException)
362 //@todo
363 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
365 if(xWindow.is())
366 xWindow->addMouseMotionListener( xListener );
369 void SAL_CALL ChartController
370 ::removeMouseMotionListener( const uno::Reference<
371 awt::XMouseMotionListener >& xListener )
372 throw (uno::RuntimeException)
374 //@todo
375 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
377 if(xWindow.is())
378 xWindow->removeMouseMotionListener( xListener );
381 void SAL_CALL ChartController
382 ::addPaintListener( const uno::Reference<
383 awt::XPaintListener >& xListener )
384 throw (uno::RuntimeException)
386 //@todo
387 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
389 if(xWindow.is())
390 xWindow->addPaintListener( xListener );
393 void SAL_CALL ChartController
394 ::removePaintListener( const uno::Reference<
395 awt::XPaintListener >& xListener )
396 throw (uno::RuntimeException)
398 //@todo
399 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
401 if(xWindow.is())
402 xWindow->removePaintListener( xListener );
405 //-----------------------------------------------------------------
406 // impl vcl window controller methods
407 //-----------------------------------------------------------------
408 void ChartController::PrePaint()
410 // forward VCLs PrePaint window event to DrawingLayer
411 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
413 if(pDrawViewWrapper)
415 pDrawViewWrapper->PrePaint();
419 void ChartController::execute_Paint( const Rectangle& rRect )
423 //better performance for big data
424 uno::Reference< beans::XPropertySet > xProp( m_xChartView, uno::UNO_QUERY );
425 if( xProp.is() )
427 awt::Size aResolution(1000,1000);
429 ::vos::OGuard aGuard( Application::GetSolarMutex());
430 if( m_pChartWindow )
432 aResolution.Width = m_pChartWindow->GetSizePixel().Width();
433 aResolution.Height = m_pChartWindow->GetSizePixel().Height();
436 xProp->setPropertyValue( C2U("Resolution"), uno::makeAny( aResolution ));
440 uno::Reference< util::XUpdatable > xUpdatable( m_xChartView, uno::UNO_QUERY );
441 if( xUpdatable.is() )
442 xUpdatable->update();
444 Window* pWindow = m_pChartWindow;
446 ::vos::OGuard aGuard( Application::GetSolarMutex());
447 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
448 if(pDrawViewWrapper)
449 pDrawViewWrapper->CompleteRedraw(pWindow, Region(rRect) );
452 catch( uno::Exception & ex )
454 ASSERT_EXCEPTION( ex );
456 catch( ... )
461 bool isDoubleClick( const MouseEvent& rMEvt )
463 return rMEvt.GetClicks() == 2 && rMEvt.IsLeft() &&
464 !rMEvt.IsMod1() && !rMEvt.IsMod2() && !rMEvt.IsShift();
467 //-----------------------------------------------------------------------------
468 //-----------------------------------------------------------------------------
469 //-----------------------------------------------------------------------------
471 void ChartController::startDoubleClickWaiting()
473 m_bWaitingForDoubleClick = true;
475 ULONG nDblClkTime = 500;
476 if( m_pChartWindow )
478 const MouseSettings& rMSettings = m_pChartWindow->GetSettings().GetMouseSettings();
479 nDblClkTime = rMSettings.GetDoubleClickTime();
481 m_aDoubleClickTimer.SetTimeout( nDblClkTime );
482 m_aDoubleClickTimer.Start();
485 void ChartController::stopDoubleClickWaiting()
487 m_aDoubleClickTimer.Stop();
488 m_bWaitingForDoubleClick = false;
491 IMPL_LINK( ChartController, DoubleClickWaitingHdl, void*, EMPTYARG )
493 m_bWaitingForDoubleClick = false;
495 if( !m_bWaitingForMouseUp && m_aSelection.maybeSwitchSelectionAfterSingleClickWasEnsured() )
497 this->impl_selectObjectAndNotiy();
498 if( m_pChartWindow )
500 Window::PointerState aPointerState( m_pChartWindow->GetPointerState() );
501 MouseEvent aMouseEvent( aPointerState.maPos,1/*nClicks*/,
502 0/*nMode*/, static_cast< USHORT >( aPointerState.mnState )/*nButtons*/,
503 0/*nModifier*/ );
504 impl_SetMousePointer( aMouseEvent );
508 return 0;
511 //------------------------------------------------------------------------
513 void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt )
515 ::vos::OGuard aGuard( Application::GetSolarMutex());
517 m_bWaitingForMouseUp = true;
519 if( isDoubleClick(rMEvt) )
520 stopDoubleClickWaiting();
521 else
522 startDoubleClickWaiting();
524 m_aSelection.remindSelectionBeforeMouseDown();
526 Window* pWindow = m_pChartWindow;
527 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
528 if(!pWindow || !pDrawViewWrapper )
529 return;
531 Point aMPos = pWindow->PixelToLogic(rMEvt.GetPosPixel());
533 if ( MOUSE_LEFT == rMEvt.GetButtons() )
535 pWindow->GrabFocus();
536 pWindow->CaptureMouse();
539 if( pDrawViewWrapper->IsTextEdit() )
541 if( pDrawViewWrapper->IsTextEditHit( aMPos, HITPIX) )
543 pDrawViewWrapper->MouseButtonDown(rMEvt,m_pChartWindow);
544 return;
546 else
548 this->EndTextEdit();
552 //abort running action
553 if( pDrawViewWrapper->IsAction() )
555 if( rMEvt.IsRight() )
556 pDrawViewWrapper->BckAction();
557 return;
560 if( isDoubleClick(rMEvt) ) //do not change selection if double click
561 return;//double click is handled further in mousebutton up
563 SdrHdl* pHitSelectionHdl = 0;
564 //switch from move to resize if handle is hit on a resizeable object
565 if( m_aSelection.isResizeableObjectSelected() )
566 pHitSelectionHdl = pDrawViewWrapper->PickHandle( aMPos );
567 //only change selection if no selection handles are hit
568 if( !pHitSelectionHdl )
570 m_aSelection.adaptSelectionToNewPos( aMPos, pDrawViewWrapper
571 , rMEvt.IsRight(), m_bWaitingForDoubleClick );
573 if( !m_aSelection.isRotateableObjectSelected( m_aModel->getModel() ) )
575 m_eDragMode = SDRDRAG_MOVE;
576 pDrawViewWrapper->SetDragMode(m_eDragMode);
579 m_aSelection.applySelection(pDrawViewWrapper);
581 if( m_aSelection.isDragableObjectSelected()
582 && !rMEvt.IsRight() )
584 //start drag
585 USHORT nDrgLog = (USHORT)pWindow->PixelToLogic(Size(DRGPIX,0)).Width();
586 SdrDragMethod* pDragMethod = NULL;
588 //change selection to 3D scene if rotate mode
589 SdrDragMode eDragMode = pDrawViewWrapper->GetDragMode();
590 if( SDRDRAG_ROTATE==eDragMode )
592 E3dScene* pScene = SelectionHelper::getSceneToRotate( pDrawViewWrapper->getNamedSdrObject( m_aSelection.getSelectedCID() ) );
593 if( pScene )
595 DragMethod_RotateDiagram::RotationDirection eRotationDirection(DragMethod_RotateDiagram::ROTATIONDIRECTION_FREE);
596 if(pHitSelectionHdl)
598 SdrHdlKind eKind = pHitSelectionHdl->GetKind();
599 if( eKind==HDL_UPPER || eKind==HDL_LOWER )
600 eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_X;
601 else if( eKind==HDL_LEFT || eKind==HDL_RIGHT )
602 eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_Y;
603 else if( eKind==HDL_UPLFT || eKind==HDL_UPRGT || eKind==HDL_LWLFT || eKind==HDL_LWRGT )
604 eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_Z;
606 pDragMethod = new DragMethod_RotateDiagram( *pDrawViewWrapper, m_aSelection.getSelectedCID(), m_aModel->getModel(), eRotationDirection );
609 else
611 rtl::OUString aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ) );
612 if( aDragMethodServiceName.equals( ObjectIdentifier::getPieSegmentDragMethodServiceName() ) )
613 pDragMethod = new DragMethod_PieSegment( *pDrawViewWrapper, m_aSelection.getSelectedCID(), m_aModel->getModel() );
615 pDrawViewWrapper->SdrView::BegDragObj(aMPos, NULL, pHitSelectionHdl, nDrgLog, pDragMethod);
618 impl_SetMousePointer( rMEvt );
621 void ChartController::execute_MouseMove( const MouseEvent& rMEvt )
623 ::vos::OGuard aGuard( Application::GetSolarMutex());
625 Window* pWindow = m_pChartWindow;
626 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
627 if(!pWindow || !pDrawViewWrapper)
628 return;
630 if( m_pDrawViewWrapper->IsTextEdit() )
632 if( m_pDrawViewWrapper->MouseMove(rMEvt,m_pChartWindow) )
633 return;
636 if(pDrawViewWrapper->IsAction())
638 pDrawViewWrapper->MovAction( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
641 //?? pDrawViewWrapper->GetPageView()->DragPoly();
643 impl_SetMousePointer( rMEvt );
645 void ChartController::execute_Tracking( const TrackingEvent& /* rTEvt */ )
649 //-----------------
651 void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt )
653 ControllerLockGuard aCLGuard( m_aModel->getModel());
654 m_bWaitingForMouseUp = false;
655 bool bNotifySelectionChange = false;
657 ::vos::OGuard aGuard( Application::GetSolarMutex());
659 Window* pWindow = m_pChartWindow;
660 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
661 if(!pWindow || !pDrawViewWrapper)
662 return;
664 Point aMPos = pWindow->PixelToLogic(rMEvt.GetPosPixel());
666 if(pDrawViewWrapper->IsTextEdit())
668 if( pDrawViewWrapper->MouseButtonUp(rMEvt,m_pChartWindow) )
669 return;
672 if(pDrawViewWrapper->IsDragObj())
674 bool bDraggingDone = false;
675 SdrDragMethod* pDragMethod = pDrawViewWrapper->SdrView::GetDragMethod();
676 bool bIsMoveOnly = pDragMethod ? pDragMethod->getMoveOnly() : false;
677 DragMethod_Base* pChartDragMethod = dynamic_cast< DragMethod_Base* >(pDragMethod);
678 if( pChartDragMethod )
680 UndoGuard aUndoGuard( pChartDragMethod->getUndoDescription(),
681 m_xUndoManager, m_aModel->getModel() );
683 if( pDrawViewWrapper->EndDragObj(false) )
685 bDraggingDone = true;
686 aUndoGuard.commitAction();
690 if( !bDraggingDone && pDrawViewWrapper->EndDragObj(false) )
694 //end move or size
695 SdrObject* pObj = pDrawViewWrapper->getSelectedObject();
696 if( pObj )
698 Rectangle aObjectRect = pObj->GetSnapRect();
699 awt::Size aPageSize( ChartModelHelper::getPageSize( m_aModel->getModel() ) );
700 Rectangle aPageRect( 0,0,aPageSize.Width,aPageSize.Height );
702 const E3dObject* pE3dObject = dynamic_cast< const E3dObject*>( pObj );
703 if( pE3dObject )
704 aObjectRect = pE3dObject->GetScene()->GetSnapRect();
706 ActionDescriptionProvider::ActionType eActionType(ActionDescriptionProvider::MOVE);
707 if( !bIsMoveOnly && m_aSelection.isResizeableObjectSelected() )
708 eActionType = ActionDescriptionProvider::RESIZE;
710 UndoGuard aUndoGuard(
711 ActionDescriptionProvider::createDescription(
712 eActionType,
713 ObjectNameProvider::getName( ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() ))),
714 m_xUndoManager, m_aModel->getModel() );
715 bool bChanged = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID()
716 , m_aModel->getModel()
717 , awt::Rectangle(aObjectRect.getX(),aObjectRect.getY(),aObjectRect.getWidth(),aObjectRect.getHeight())
718 , awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight())
719 , m_xChartView );
720 if( bChanged )
722 bDraggingDone = true;
723 aUndoGuard.commitAction();
727 catch( uno::Exception & ex )
729 ASSERT_EXCEPTION( ex );
731 //all wanted model changes will take effect
732 //and all unwanted view modifications are cleaned
735 if( !bDraggingDone ) //mouse wasn't moved while dragging
737 bool bClickedTwiceOnDragableObject = SelectionHelper::isDragableObjectHitTwice( aMPos, m_aSelection.getSelectedCID(), *pDrawViewWrapper );
738 bool bIsRotateable = m_aSelection.isRotateableObjectSelected( m_aModel->getModel() );
740 //toggel between move and rotate
741 if( bIsRotateable && bClickedTwiceOnDragableObject && SDRDRAG_MOVE==m_eDragMode )
742 m_eDragMode=SDRDRAG_ROTATE;
743 else
744 m_eDragMode=SDRDRAG_MOVE;
746 pDrawViewWrapper->SetDragMode(m_eDragMode);
748 if( !m_bWaitingForDoubleClick && m_aSelection.maybeSwitchSelectionAfterSingleClickWasEnsured() )
750 this->impl_selectObjectAndNotiy();
753 else
754 m_aSelection.resetPossibleSelectionAfterSingleClickWasEnsured();
756 else if( isDoubleClick(rMEvt) )
757 execute_DoubleClick();
759 //@todo ForcePointer(&rMEvt);
760 pWindow->ReleaseMouse();
762 if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() )
763 bNotifySelectionChange = true;
766 impl_SetMousePointer( rMEvt );
768 if(bNotifySelectionChange)
769 impl_notifySelectionChangeListeners();
772 void ChartController::execute_DoubleClick()
774 ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() );
775 if( OBJECTTYPE_TITLE==eObjectType )
776 executeDispatch_EditText();
777 else
778 executeDispatch_ObjectProperties();
781 void ChartController::execute_Resize()
783 m_pChartWindow->Invalidate();
785 void ChartController::execute_Activate()
787 ///// pDrawViewWrapper->SetEditMode(TRUE);
789 void ChartController::execute_Deactivate()
792 pDrawViewWrapper->SetEditMode(FALSE);
793 this->ReleaseMouse();
796 void ChartController::execute_GetFocus()
799 void ChartController::execute_LoseFocus()
801 //this->ReleaseMouse();
804 void ChartController::execute_Command( const CommandEvent& rCEvt )
806 Window* pWindow = m_pChartWindow;
808 bool bIsAction = false;
810 ::vos::OGuard aGuard( Application::GetSolarMutex());
811 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
812 if(!pWindow || !pDrawViewWrapper)
813 return;
814 bIsAction = m_pDrawViewWrapper->IsAction();
817 // pop-up menu
818 if(rCEvt.GetCommand() == COMMAND_CONTEXTMENU && !bIsAction)
820 m_pChartWindow->ReleaseMouse();
822 if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() )
823 impl_notifySelectionChangeListeners();
825 // todo: the context menu should be specified by an xml file in uiconfig
826 uno::Reference< awt::XPopupMenu > xPopupMenu(
827 m_xCC->getServiceManager()->createInstanceWithContext(
828 C2U("com.sun.star.awt.PopupMenu"), m_xCC ), uno::UNO_QUERY );
829 uno::Reference< awt::XMenuExtended > xMenuEx( xPopupMenu, uno::UNO_QUERY );
830 if( xPopupMenu.is() && xMenuEx.is())
832 sal_Int16 nUniqueId = 1;
833 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DiagramObjects"));
834 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:TransformDialog"));
835 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId, C2U(".uno:ArrangeRow"));
836 uno::Reference< awt::XPopupMenu > xArrangePopupMenu(
837 m_xCC->getServiceManager()->createInstanceWithContext(
838 C2U("com.sun.star.awt.PopupMenu"), m_xCC ), uno::UNO_QUERY );
839 uno::Reference< awt::XMenuExtended > xArrangeMenuEx( xArrangePopupMenu, uno::UNO_QUERY );
840 if( xArrangePopupMenu.is() && xArrangeMenuEx.is())
842 sal_Int16 nSubId = nUniqueId + 1;
843 lcl_insertMenuCommand( xArrangePopupMenu, xArrangeMenuEx, nSubId++, C2U(".uno:Forward"));
844 lcl_insertMenuCommand( xArrangePopupMenu, xArrangeMenuEx, nSubId, C2U(".uno:Backward"));
845 xPopupMenu->setPopupMenu( nUniqueId, xArrangePopupMenu );
846 nUniqueId = nSubId;
848 ++nUniqueId;
849 xPopupMenu->insertSeparator( -1 );
850 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DiagramType"));
851 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DataRanges"));
852 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:View3D"));
853 xPopupMenu->insertSeparator( -1 );
854 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DiagramData"));
855 xPopupMenu->insertSeparator( -1 );
856 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertYErrorbar"));
857 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteYErrorbar"));
858 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertMeanValue"));
859 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteMeanValue"));
860 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendline"));
861 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteTrendline"));
862 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendlineEquation"));
863 xPopupMenu->insertSeparator( -1 );
864 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Cut"));
865 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Copy"));
866 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Paste"));
868 ::svt::ContextMenuHelper aContextMenuHelper( m_xFrame );
869 Point aPos( rCEvt.GetMousePosPixel() );
870 if( !rCEvt.IsMouseEvent() )
871 aPos = m_pChartWindow->GetPointerState().maPos;
872 aContextMenuHelper.completeAndExecute( aPos, xPopupMenu );
875 else if( ( rCEvt.GetCommand() == COMMAND_STARTEXTTEXTINPUT ) ||
876 ( rCEvt.GetCommand() == COMMAND_EXTTEXTINPUT ) ||
877 ( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT ) ||
878 ( rCEvt.GetCommand() == COMMAND_INPUTCONTEXTCHANGE ) )
880 //#i84417# enable editing with IME
881 if( m_pDrawViewWrapper )
882 m_pDrawViewWrapper->Command( rCEvt, m_pChartWindow );
886 bool ChartController::execute_KeyInput( const KeyEvent& rKEvt )
888 bool bReturn=false;
890 Window* pWindow = m_pChartWindow;
891 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
892 if(!pWindow || !pDrawViewWrapper)
893 return bReturn;
895 // handle accelerators
896 if( ! m_apAccelExecute.get() && m_xFrame.is() && m_xCC.is() && m_xCC->getServiceManager().is() )
898 m_apAccelExecute.reset( ::svt::AcceleratorExecute::createAcceleratorHelper());
899 OSL_ASSERT( m_apAccelExecute.get());
900 if( m_apAccelExecute.get() )
901 m_apAccelExecute->init(
902 uno::Reference< lang::XMultiServiceFactory >( m_xCC->getServiceManager(), uno::UNO_QUERY ), m_xFrame );
905 KeyCode aKeyCode( rKEvt.GetKeyCode());
906 sal_uInt16 nCode = aKeyCode.GetCode();
907 // bool bShift = aKeyCode.IsShift();
908 bool bAlternate = aKeyCode.IsMod2();
910 if( m_apAccelExecute.get() )
911 bReturn = m_apAccelExecute->execute( aKeyCode );
912 if( bReturn )
913 return bReturn;
915 if( pDrawViewWrapper->IsTextEdit() )
917 if( pDrawViewWrapper->KeyInput(rKEvt,pWindow) )
919 bReturn = true;
920 if( nCode == KEY_ESCAPE )
922 this->EndTextEdit();
927 //if( m_pDrawViewWrapper->IsAction() );
929 // keyboard accessibility
930 ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() );
931 if( ! bReturn )
933 // Natvigation (Tab/F3/Home/End)
934 uno::Reference< XChartDocument > xChartDoc( m_aModel->getModel(), uno::UNO_QUERY );
935 ObjectKeyNavigation aObjNav( m_aSelection.getSelectedCID(), xChartDoc, ExplicitValueProvider::getExplicitValueProvider( m_xChartView ));
936 awt::KeyEvent aKeyEvent( ::svt::AcceleratorExecute::st_VCLKey2AWTKey( aKeyCode ));
937 bReturn = aObjNav.handleKeyEvent( aKeyEvent );
938 if( bReturn )
940 ::rtl::OUString aNewCID = aObjNav.getCurrentSelection();
941 uno::Any aNewSelection;
942 if( aNewCID.getLength()>0 && !ObjectHierarchy::isRootNode( aNewCID ))
943 aNewSelection <<= aNewCID;
944 if( m_eDragMode == SDRDRAG_ROTATE && !SelectionHelper::isRotateableObject( aNewCID, m_aModel->getModel() ) )
945 m_eDragMode = SDRDRAG_MOVE;
946 bReturn = select( aNewSelection );
950 // Position and Size (+/-/arrow-keys) or pie segment dragging
951 if( ! bReturn )
953 // pie segment dragging
954 // note: could also be done for data series
955 if( eObjectType == OBJECTTYPE_DATA_POINT &&
956 ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ).equals(
957 ObjectIdentifier::getPieSegmentDragMethodServiceName()))
959 bool bDrag = false;
960 bool bDragInside = false;
961 if( nCode == KEY_ADD ||
962 nCode == KEY_SUBTRACT )
964 bDrag = true;
965 bDragInside = ( nCode == KEY_SUBTRACT );
967 else if(
968 nCode == KEY_LEFT ||
969 nCode == KEY_RIGHT ||
970 nCode == KEY_UP ||
971 nCode == KEY_DOWN )
973 bDrag = true;
974 rtl::OUString aParameter( ObjectIdentifier::getDragParameterString( m_aSelection.getSelectedCID() ));
975 sal_Int32 nOffsetPercentDummy( 0 );
976 awt::Point aMinimumPosition( 0, 0 );
977 awt::Point aMaximumPosition( 0, 0 );
978 ObjectIdentifier::parsePieSegmentDragParameterString(
979 aParameter, nOffsetPercentDummy, aMinimumPosition, aMaximumPosition );
980 aMaximumPosition.Y -= aMinimumPosition.Y;
981 aMaximumPosition.X -= aMinimumPosition.X;
983 bDragInside =
984 (nCode == KEY_RIGHT && (aMaximumPosition.X < 0)) ||
985 (nCode == KEY_LEFT && (aMaximumPosition.X > 0)) ||
986 (nCode == KEY_DOWN && (aMaximumPosition.Y < 0)) ||
987 (nCode == KEY_UP && (aMaximumPosition.Y > 0));
990 if( bDrag )
992 double fAmount = bAlternate ? 0.01 : 0.05;
993 if( bDragInside )
994 fAmount *= -1.0;
996 bReturn = impl_DragDataPoint( m_aSelection.getSelectedCID(), fAmount );
999 else
1001 // size
1002 if( nCode == KEY_ADD ||
1003 nCode == KEY_SUBTRACT )
1005 if( eObjectType == OBJECTTYPE_DIAGRAM )
1007 // default 1 mm in each direction
1008 double fGrowAmountX = 200.0;
1009 double fGrowAmountY = 200.0;
1010 if( bAlternate && pWindow )
1012 // together with Alt-key: 1 px in each direction
1013 Size aPixelSize = pWindow->PixelToLogic( Size( 2, 2 ));
1014 fGrowAmountX = static_cast< double >( aPixelSize.Width());
1015 fGrowAmountY = static_cast< double >( aPixelSize.Height());
1017 if( nCode == KEY_SUBTRACT )
1019 fGrowAmountX = -fGrowAmountX;
1020 fGrowAmountY = -fGrowAmountY;
1022 bReturn = impl_moveOrResizeObject(
1023 m_aSelection.getSelectedCID(), CENTERED_RESIZE_OBJECT, fGrowAmountX, fGrowAmountY );
1026 // position
1027 else if( nCode == KEY_LEFT ||
1028 nCode == KEY_RIGHT ||
1029 nCode == KEY_UP ||
1030 nCode == KEY_DOWN )
1032 if( m_aSelection.isDragableObjectSelected() )
1034 // default 1 mm
1035 double fShiftAmountX = 100.0;
1036 double fShiftAmountY = 100.0;
1037 if( bAlternate && pWindow )
1039 // together with Alt-key: 1 px
1040 Size aPixelSize = pWindow->PixelToLogic( Size( 1, 1 ));
1041 fShiftAmountX = static_cast< double >( aPixelSize.Width());
1042 fShiftAmountY = static_cast< double >( aPixelSize.Height());
1044 switch( nCode )
1046 case KEY_LEFT:
1047 fShiftAmountX = -fShiftAmountX;
1048 fShiftAmountY = 0.0;
1049 break;
1050 case KEY_RIGHT:
1051 fShiftAmountY = 0.0;
1052 break;
1053 case KEY_UP:
1054 fShiftAmountX = 0.0;
1055 fShiftAmountY = -fShiftAmountY;
1056 break;
1057 case KEY_DOWN:
1058 fShiftAmountX = 0.0;
1059 break;
1061 if( m_aSelection.getSelectedCID().getLength() )
1063 //move chart objects
1064 bReturn = impl_moveOrResizeObject(
1065 m_aSelection.getSelectedCID(), MOVE_OBJECT, fShiftAmountX, fShiftAmountY );
1067 else
1069 //move additional shapes
1070 uno::Reference< drawing::XShape > xShape( m_aSelection.getSelectedAdditionalShape() );
1071 if( xShape.is() )
1073 awt::Point aPos( xShape->getPosition() );
1074 awt::Size aSize( xShape->getSize() );
1075 awt::Size aPageSize( ChartModelHelper::getPageSize( m_aModel->getModel() ) );
1076 aPos.X = static_cast< long >( static_cast< double >( aPos.X ) + fShiftAmountX );
1077 aPos.Y = static_cast< long >( static_cast< double >( aPos.Y ) + fShiftAmountY );
1078 if( aPos.X + aSize.Width > aPageSize.Width )
1079 aPos.X = aPageSize.Width - aSize.Width;
1080 if( aPos.X < 0 )
1081 aPos.X = 0;
1082 if( aPos.Y + aSize.Height > aPageSize.Height )
1083 aPos.Y = aPageSize.Height - aSize.Height;
1084 if( aPos.Y < 0 )
1085 aPos.Y = 0;
1087 xShape->setPosition( aPos );
1095 // text edit
1096 if( ! bReturn &&
1097 nCode == KEY_F2 )
1099 if( OBJECTTYPE_TITLE == eObjectType )
1101 executeDispatch_EditText();
1102 bReturn = true;
1106 // deactivate inplace mode (this code should be unnecessary, but
1107 // unfortunately is not)
1108 if( ! bReturn &&
1109 nCode == KEY_ESCAPE )
1111 uno::Reference< frame::XDispatchHelper > xDispatchHelper(
1112 m_xCC->getServiceManager()->createInstanceWithContext(
1113 C2U("com.sun.star.frame.DispatchHelper"), m_xCC ), uno::UNO_QUERY );
1114 if( xDispatchHelper.is())
1116 uno::Sequence< beans::PropertyValue > aArgs;
1117 xDispatchHelper->executeDispatch(
1118 uno::Reference< frame::XDispatchProvider >( m_xFrame, uno::UNO_QUERY ),
1119 C2U(".uno:TerminateInplaceActivation"),
1120 C2U("_parent"),
1121 frame::FrameSearchFlag::PARENT,
1122 aArgs );
1123 bReturn = true;
1127 if( ! bReturn &&
1128 (nCode == KEY_DELETE || nCode == KEY_BACKSPACE ))
1130 bReturn = executeDispatch_Delete();
1131 if( ! bReturn )
1133 InfoBox( m_pChartWindow, String(SchResId( STR_ACTION_NOTPOSSIBLE ))).Execute();
1137 /* old chart:
1138 // Ctrl-Shift-R: Repaint
1139 if (!bReturn && GetWindow())
1141 KeyCode aKeyCode = rKEvt.GetKeyCode();
1143 if (aKeyCode.IsMod1() && aKeyCode.IsShift()
1144 && aKeyCode.GetCode() == KEY_R)
1146 // 3D-Kontext wieder zerstoeren
1147 GetWindow()->Invalidate();
1148 bReturn = TRUE;
1152 return bReturn;
1155 bool ChartController::requestQuickHelp(
1156 ::Point aAtLogicPosition,
1157 bool bIsBalloonHelp,
1158 ::rtl::OUString & rOutQuickHelpText,
1159 awt::Rectangle & rOutEqualRect )
1161 uno::Reference< frame::XModel > xChartModel;
1162 if( m_aModel.is())
1163 xChartModel.set( m_aModel->getModel());
1164 if( !xChartModel.is())
1165 return false;
1167 // help text
1168 ::rtl::OUString aCID;
1169 if( m_pDrawViewWrapper )
1171 aCID = SelectionHelper::getHitObjectCID(
1172 aAtLogicPosition, *m_pDrawViewWrapper );
1174 bool bResult( aCID.getLength());
1176 if( bResult )
1178 // get help text
1179 rOutQuickHelpText = ObjectNameProvider::getHelpText( aCID, xChartModel, bIsBalloonHelp /* bVerbose */ );
1181 // set rectangle
1182 ExplicitValueProvider * pValueProvider(
1183 ExplicitValueProvider::getExplicitValueProvider( m_xChartView ));
1184 if( pValueProvider )
1185 rOutEqualRect = pValueProvider->getRectangleOfObject( aCID, true );
1188 return bResult;
1191 //-----------------------------------------------------------------
1192 // XSelectionSupplier (optional interface)
1193 //-----------------------------------------------------------------
1194 sal_Bool SAL_CALL ChartController
1195 ::select( const uno::Any& rSelection )
1196 throw( lang::IllegalArgumentException )
1198 rtl::OUString aNewCID;
1199 if( rSelection.hasValue() &&
1200 ! (rSelection >>= aNewCID))
1201 return sal_False;
1204 if( m_aSelection.setSelection( aNewCID ) )
1206 this->impl_selectObjectAndNotiy();
1207 return sal_True;
1209 return sal_False;
1212 uno::Any SAL_CALL ChartController
1213 ::getSelection() throw(uno::RuntimeException)
1215 return uno::makeAny(m_aSelection.getSelectedCID());
1218 void SAL_CALL ChartController
1219 ::addSelectionChangeListener( const uno::Reference<
1220 view::XSelectionChangeListener > & xListener )
1221 throw(uno::RuntimeException)
1223 ::vos::OGuard aGuard( Application::GetSolarMutex());
1224 if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode?
1225 return; //behave passive if already disposed or suspended
1227 //--add listener
1228 m_aLifeTimeManager.m_aListenerContainer.addInterface( ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0), xListener );
1231 void SAL_CALL ChartController
1232 ::removeSelectionChangeListener( const uno::Reference<
1233 view::XSelectionChangeListener > & xListener )
1234 throw(uno::RuntimeException)
1236 ::vos::OGuard aGuard( Application::GetSolarMutex());
1237 if( impl_isDisposedOrSuspended() ) //@todo? allow removing of listeners in suspend mode?
1238 return; //behave passive if already disposed or suspended
1240 //--remove listener
1241 m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0), xListener );
1244 void ChartController
1245 ::impl_notifySelectionChangeListeners()
1247 ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
1248 .getContainer( ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0) );
1249 if( pIC )
1251 uno::Reference< view::XSelectionSupplier > xSelectionSupplier(this);
1252 lang::EventObject aEvent( xSelectionSupplier );
1253 ::cppu::OInterfaceIteratorHelper aIt( *pIC );
1254 while( aIt.hasMoreElements() )
1255 (static_cast< view::XSelectionChangeListener*>(aIt.next()))->selectionChanged( aEvent );
1259 void ChartController::impl_selectObjectAndNotiy()
1261 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
1262 if( pDrawViewWrapper )
1264 pDrawViewWrapper->SetDragMode( m_eDragMode );
1265 m_aSelection.applySelection( m_pDrawViewWrapper );
1267 impl_notifySelectionChangeListeners();
1270 bool ChartController::impl_moveOrResizeObject(
1271 const ::rtl::OUString & rCID,
1272 eMoveOrResizeType eType,
1273 double fAmountLogicX,
1274 double fAmountLogicY )
1276 bool bResult = false;
1277 bool bNeedShift = true;
1278 bool bNeedResize = ( eType == CENTERED_RESIZE_OBJECT );
1280 uno::Reference< frame::XModel > xChartModel( m_aModel->getModel());
1281 uno::Reference< beans::XPropertySet > xObjProp(
1282 ObjectIdentifier::getObjectPropertySet( rCID, xChartModel ));
1283 if( xObjProp.is())
1285 awt::Size aRefSize = ChartModelHelper::getPageSize( xChartModel );
1287 chart2::RelativePosition aRelPos;
1288 chart2::RelativeSize aRelSize;
1289 bool bDeterminePos = !(xObjProp->getPropertyValue( C2U("RelativePosition")) >>= aRelPos);
1290 bool bDetermineSize = !bNeedResize || !(xObjProp->getPropertyValue( C2U("RelativeSize")) >>= aRelSize);
1292 if( ( bDeterminePos || bDetermineSize ) &&
1293 ( aRefSize.Width > 0 && aRefSize.Height > 0 ) )
1295 ExplicitValueProvider * pValueProvider(
1296 ExplicitValueProvider::getExplicitValueProvider( m_xChartView ));
1297 if( pValueProvider )
1299 awt::Rectangle aRect( pValueProvider->getRectangleOfObject( rCID ));
1300 double fWidth = static_cast< double >( aRefSize.Width );
1301 double fHeight = static_cast< double >( aRefSize.Height );
1302 if( bDetermineSize )
1304 aRelSize.Primary = static_cast< double >( aRect.Width ) / fWidth;
1305 aRelSize.Secondary = static_cast< double >( aRect.Height ) / fHeight;
1307 if( bDeterminePos )
1309 if( bNeedResize && aRelSize.Primary > 0.0 && aRelSize.Secondary > 0.0 )
1311 aRelPos.Primary = (static_cast< double >( aRect.X ) / fWidth) +
1312 (aRelSize.Primary / 2.0);
1313 aRelPos.Secondary = (static_cast< double >( aRect.Y ) / fHeight) +
1314 (aRelSize.Secondary / 2.0);
1315 aRelPos.Anchor = drawing::Alignment_CENTER;
1317 else
1319 aRelPos.Primary = static_cast< double >( aRect.X ) / fWidth;
1320 aRelPos.Secondary = static_cast< double >( aRect.Y ) / fHeight;
1321 aRelPos.Anchor = drawing::Alignment_TOP_LEFT;
1327 if( eType == CENTERED_RESIZE_OBJECT )
1328 bResult = lcl_GrowAndShiftLogic( aRelPos, aRelSize, aRefSize, fAmountLogicX, fAmountLogicY );
1329 else if( eType == MOVE_OBJECT )
1330 bResult = lcl_MoveObjectLogic( aRelPos, aRelSize, aRefSize, fAmountLogicX, fAmountLogicY );
1332 if( bResult )
1334 ActionDescriptionProvider::ActionType eActionType(ActionDescriptionProvider::MOVE);
1335 if( bNeedResize )
1336 eActionType = ActionDescriptionProvider::RESIZE;
1338 ObjectType eObjectType = ObjectIdentifier::getObjectType( rCID );
1339 UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription(
1340 eActionType, ObjectNameProvider::getName( eObjectType )), m_xUndoManager, xChartModel );
1342 ControllerLockGuard aCLGuard( xChartModel );
1343 if( bNeedShift )
1344 xObjProp->setPropertyValue( C2U("RelativePosition"), uno::makeAny( aRelPos ));
1345 if( bNeedResize || (eObjectType == OBJECTTYPE_DIAGRAM) )//Also set an explicat size at the diagram when an explicit position is set
1346 xObjProp->setPropertyValue( C2U("RelativeSize"), uno::makeAny( aRelSize ));
1348 aUndoGuard.commitAction();
1351 return bResult;
1354 bool ChartController::impl_DragDataPoint( const ::rtl::OUString & rCID, double fAdditionalOffset )
1356 bool bResult = false;
1357 if( fAdditionalOffset < -1.0 || fAdditionalOffset > 1.0 || fAdditionalOffset == 0.0 )
1358 return bResult;
1360 sal_Int32 nDataPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( rCID );
1361 uno::Reference< chart2::XDataSeries > xSeries(
1362 ObjectIdentifier::getDataSeriesForCID( rCID, m_aModel->getModel()));
1363 if( xSeries.is())
1367 uno::Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex( nDataPointIndex ));
1368 double fOffset = 0.0;
1369 if( xPointProp.is() &&
1370 (xPointProp->getPropertyValue( C2U("Offset" )) >>= fOffset ) &&
1371 (( fAdditionalOffset > 0.0 && fOffset < 1.0 ) || (fOffset > 0.0)) )
1373 fOffset += fAdditionalOffset;
1374 if( fOffset > 1.0 )
1375 fOffset = 1.0;
1376 else if( fOffset < 0.0 )
1377 fOffset = 0.0;
1378 xPointProp->setPropertyValue( C2U("Offset"), uno::makeAny( fOffset ));
1379 bResult = true;
1382 catch( const uno::Exception & ex )
1384 ASSERT_EXCEPTION( ex );
1388 return bResult;
1391 void ChartController::impl_SetMousePointer( const MouseEvent & rEvent )
1393 ::vos::OGuard aGuard( Application::GetSolarMutex());
1394 Window* pWindow = m_pChartWindow;
1395 if( m_pDrawViewWrapper && pWindow )
1397 Point aMousePos( pWindow->PixelToLogic( rEvent.GetPosPixel()));
1398 sal_uInt16 nModifier = rEvent.GetModifier();
1399 BOOL bLeftDown = rEvent.IsLeft();
1401 if( m_pDrawViewWrapper->IsTextEdit() )
1403 if( m_pDrawViewWrapper->IsTextEditHit( aMousePos, HITPIX) )
1405 pWindow->SetPointer( m_pDrawViewWrapper->GetPreferedPointer(
1406 aMousePos, pWindow, nModifier, bLeftDown ) );
1407 return;
1410 else if( m_pDrawViewWrapper->IsAction() )
1412 return;//don't change pointer during running action
1415 SdrHdl* pHitSelectionHdl = 0;
1416 if( m_aSelection.isResizeableObjectSelected() )
1417 pHitSelectionHdl = m_pDrawViewWrapper->PickHandle( aMousePos );
1419 if( pHitSelectionHdl )
1422 Pointer aPointer = m_pDrawViewWrapper->GetPreferedPointer(
1423 aMousePos, pWindow, nModifier, bLeftDown );
1424 bool bForceArrowPointer = false;
1426 ::rtl::OUString aObjectCID = m_aSelection.getSelectedCID();
1428 switch( aPointer.GetStyle())
1430 case POINTER_NSIZE:
1431 case POINTER_SSIZE:
1432 case POINTER_WSIZE:
1433 case POINTER_ESIZE:
1434 case POINTER_NWSIZE:
1435 case POINTER_NESIZE:
1436 case POINTER_SWSIZE:
1437 case POINTER_SESIZE:
1438 if( ! m_aSelection.isResizeableObjectSelected() )
1439 bForceArrowPointer = true;
1440 break;
1441 case POINTER_MOVE:
1442 if( ! ObjectIdentifier::isDragableObject( aObjectCID ))
1443 bForceArrowPointer = true;
1444 break;
1445 case POINTER_MOVEPOINT:
1446 case POINTER_MOVEBEZIERWEIGHT:
1447 // there is no point-editing in a chart
1448 // the POINTER_MOVEBEZIERWEIGHT appears in 3d data points
1449 bForceArrowPointer = true;
1450 break;
1451 default:
1452 break;
1455 if( bForceArrowPointer )
1456 pWindow->SetPointer( Pointer( POINTER_ARROW ));
1457 else
1458 pWindow->SetPointer( aPointer );
1460 else
1462 ::rtl::OUString aHitObjectCID(
1463 SelectionHelper::getHitObjectCID(
1464 aMousePos, *m_pDrawViewWrapper, true /*bGetDiagramInsteadOf_Wall*/ ));
1466 if( m_pDrawViewWrapper->IsTextEdit() )
1468 if( aHitObjectCID.equals(m_aSelection.getSelectedCID()) )
1470 pWindow->SetPointer( Pointer( POINTER_ARROW ));
1471 return;
1475 if( !aHitObjectCID.getLength() )
1477 //additional shape was hit
1478 pWindow->SetPointer( POINTER_MOVE );
1480 else if( ObjectIdentifier::isDragableObject( aHitObjectCID ) )
1482 if( (m_eDragMode == SDRDRAG_ROTATE)
1483 && SelectionHelper::isRotateableObject( aHitObjectCID
1484 , m_aModel->getModel() ) )
1485 pWindow->SetPointer( Pointer( POINTER_ROTATE ) );
1486 else
1488 ObjectType eHitObjectType = ObjectIdentifier::getObjectType( aHitObjectCID );
1489 if( eHitObjectType == OBJECTTYPE_DATA_POINT )
1491 if( !ObjectIdentifier::areSiblings(aHitObjectCID,m_aSelection.getSelectedCID())
1492 && !ObjectIdentifier::areIdenticalObjects(aHitObjectCID,m_aSelection.getSelectedCID()) )
1494 pWindow->SetPointer( Pointer( POINTER_ARROW ));
1495 return;
1498 pWindow->SetPointer( POINTER_MOVE );
1501 else
1502 pWindow->SetPointer( Pointer( POINTER_ARROW ));
1507 //.............................................................................
1508 } //namespace chart
1509 //.............................................................................