merged tag ooo/OOO330_m14
[LibreOffice.git] / chart2 / source / controller / main / ChartController_Window.cxx
blob56908ac4ef798b3ee982b8f47c6dfbf8cd910168
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_chart2.hxx"
30 #include "ChartController.hxx"
31 #include "PositionAndSizeHelper.hxx"
32 #include "ObjectIdentifier.hxx"
33 #include "ChartWindow.hxx"
34 #include "ResId.hxx"
35 #include "CommonConverters.hxx"
36 #include "ChartModelHelper.hxx"
37 #include "DiagramHelper.hxx"
38 #include "TitleHelper.hxx"
39 #include "UndoGuard.hxx"
40 #include "ControllerLockGuard.hxx"
41 #include "ObjectNameProvider.hxx"
42 #include "Strings.hrc"
43 #include "SchSlotIds.hxx"
44 #include "macros.hxx"
45 #include "DragMethod_PieSegment.hxx"
46 #include "DragMethod_RotateDiagram.hxx"
47 #include "ObjectHierarchy.hxx"
48 #include "chartview/ExplicitValueProvider.hxx"
49 #include "RelativePositionHelper.hxx"
50 #include "chartview/DrawModelWrapper.hxx"
51 #include "RegressionCurveHelper.hxx"
52 #include "StatisticsHelper.hxx"
53 #include "DataSeriesHelper.hxx"
54 #include "ContainerHelper.hxx"
55 #include "AxisHelper.hxx"
56 #include "LegendHelper.hxx"
57 #include "servicenames_charttypes.hxx"
58 #include "MenuResIds.hrc"
59 #include "DrawCommandDispatch.hxx"
61 #include <com/sun/star/chart2/RelativePosition.hpp>
62 #include <com/sun/star/chart2/RelativeSize.hpp>
63 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
65 #include <com/sun/star/frame/XDispatchHelper.hpp>
66 #include <com/sun/star/frame/FrameSearchFlag.hpp>
67 #include <com/sun/star/util/XUpdatable.hpp>
68 #include <comphelper/InlineContainer.hxx>
70 #include <svtools/contextmenuhelper.hxx>
71 #include <toolkit/awt/vclxmenu.hxx>
73 #include <svx/svxids.hrc>
74 #include <svx/ActionDescriptionProvider.hxx>
76 // header for class E3dObject
77 #include <svx/obj3d.hxx>
78 // header for class E3dScene
79 #include <svx/scene3d.hxx>
80 // header for class SdrDragMethod
81 #include <svx/svddrgmt.hxx>
82 #include <vcl/svapp.hxx>
83 #include <vos/mutex.hxx>
85 // for InfoBox
86 #include <vcl/msgbox.hxx>
88 #include <rtl/math.hxx>
89 #include <svtools/acceleratorexecute.hxx>
91 #define DRGPIX 2 // Drag MinMove in Pixel
93 using namespace ::com::sun::star;
94 using namespace ::com::sun::star::chart2;
95 using ::com::sun::star::uno::Reference;
96 using ::rtl::OUString;
98 //.............................................................................
99 namespace chart
101 //.............................................................................
103 namespace
105 bool lcl_GrowAndShiftLogic(
106 RelativePosition & rInOutRelPos,
107 RelativeSize & rInOutRelSize,
108 const awt::Size & rRefSize,
109 double fGrowLogicX,
110 double fGrowLogicY )
112 if( rRefSize.Width == 0 ||
113 rRefSize.Height == 0 )
114 return false;
116 double fRelativeGrowX = fGrowLogicX / rRefSize.Width;
117 double fRelativeGrowY = fGrowLogicY / rRefSize.Height;
119 return ::chart::RelativePositionHelper::centerGrow(
120 rInOutRelPos, rInOutRelSize,
121 fRelativeGrowX, fRelativeGrowY,
122 /* bCheck = */ true );
125 bool lcl_MoveObjectLogic(
126 RelativePosition & rInOutRelPos,
127 RelativeSize & rObjectSize,
128 const awt::Size & rRefSize,
129 double fShiftLogicX,
130 double fShiftLogicY )
132 if( rRefSize.Width == 0 ||
133 rRefSize.Height == 0 )
134 return false;
136 double fRelativeShiftX = fShiftLogicX / rRefSize.Width;
137 double fRelativeShiftY = fShiftLogicY / rRefSize.Height;
139 return ::chart::RelativePositionHelper::moveObject(
140 rInOutRelPos, rObjectSize,
141 fRelativeShiftX, fRelativeShiftY,
142 /* bCheck = */ true );
145 void lcl_insertMenuCommand(
146 const uno::Reference< awt::XPopupMenu > & xMenu,
147 const uno::Reference< awt::XMenuExtended > & xMenuEx,
148 sal_Int16 nId, const ::rtl::OUString & rCommand )
150 static ::rtl::OUString aEmptyString;
151 xMenu->insertItem( nId, aEmptyString, 0, -1 );
152 xMenuEx->setCommand( nId, rCommand );
155 OUString lcl_getFormatCommandForObjectCID( const OUString& rCID )
157 OUString aDispatchCommand( C2U(".uno:FormatSelection") );
159 ObjectType eObjectType = ObjectIdentifier::getObjectType( rCID );
161 switch(eObjectType)
163 case OBJECTTYPE_DIAGRAM:
164 case OBJECTTYPE_DIAGRAM_WALL:
165 aDispatchCommand = C2U(".uno:FormatWall");
166 break;
167 case OBJECTTYPE_DIAGRAM_FLOOR:
168 aDispatchCommand = C2U(".uno:FormatFloor");
169 break;
170 case OBJECTTYPE_PAGE:
171 aDispatchCommand = C2U(".uno:FormatChartArea");
172 break;
173 case OBJECTTYPE_LEGEND:
174 aDispatchCommand = C2U(".uno:FormatLegend");
175 break;
176 case OBJECTTYPE_TITLE:
177 aDispatchCommand = C2U(".uno:FormatTitle");
178 break;
179 case OBJECTTYPE_LEGEND_ENTRY:
180 aDispatchCommand = C2U(".uno:FormatDataSeries");
181 break;
182 case OBJECTTYPE_AXIS:
183 case OBJECTTYPE_AXIS_UNITLABEL:
184 aDispatchCommand = C2U(".uno:FormatAxis");
185 break;
186 case OBJECTTYPE_GRID:
187 aDispatchCommand = C2U(".uno:FormatMajorGrid");
188 break;
189 case OBJECTTYPE_SUBGRID:
190 aDispatchCommand = C2U(".uno:FormatMinorGrid");
191 break;
192 case OBJECTTYPE_DATA_LABELS:
193 aDispatchCommand = C2U(".uno:FormatDataLabels");
194 break;
195 case OBJECTTYPE_DATA_SERIES:
196 aDispatchCommand = C2U(".uno:FormatDataSeries");
197 break;
198 case OBJECTTYPE_DATA_LABEL:
199 aDispatchCommand = C2U(".uno:FormatDataLabel");
200 break;
201 case OBJECTTYPE_DATA_POINT:
202 aDispatchCommand = C2U(".uno:FormatDataPoint");
203 break;
204 case OBJECTTYPE_DATA_AVERAGE_LINE:
205 aDispatchCommand = C2U(".uno:FormatMeanValue");
206 break;
207 case OBJECTTYPE_DATA_ERRORS:
208 case OBJECTTYPE_DATA_ERRORS_X:
209 case OBJECTTYPE_DATA_ERRORS_Y:
210 case OBJECTTYPE_DATA_ERRORS_Z:
211 aDispatchCommand = C2U(".uno:FormatYErrorBars");
212 break;
213 case OBJECTTYPE_DATA_CURVE:
214 aDispatchCommand = C2U(".uno:FormatTrendline");
215 break;
216 case OBJECTTYPE_DATA_CURVE_EQUATION:
217 aDispatchCommand = C2U(".uno:FormatTrendlineEquation");
218 break;
219 case OBJECTTYPE_DATA_STOCK_RANGE:
220 aDispatchCommand = C2U(".uno:FormatSelection");
221 break;
222 case OBJECTTYPE_DATA_STOCK_LOSS:
223 aDispatchCommand = C2U(".uno:FormatStockLoss");
224 break;
225 case OBJECTTYPE_DATA_STOCK_GAIN:
226 aDispatchCommand = C2U(".uno:FormatStockGain");
227 break;
228 default: //OBJECTTYPE_UNKNOWN
229 break;
231 return aDispatchCommand;
234 } // anonymous namespace
236 const short HITPIX=2; //hit-tolerance in pixel
238 //-----------------------------------------------------------------
239 // awt::XWindow
240 //-----------------------------------------------------------------
241 void SAL_CALL ChartController
242 ::setPosSize( sal_Int32 X, sal_Int32 Y
243 , sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags )
244 throw (uno::RuntimeException)
246 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
247 Window* pWindow = m_pChartWindow;
249 if(xWindow.is() && pWindow)
251 Size aLogicSize = pWindow->PixelToLogic( Size( Width, Height ), MapMode( MAP_100TH_MM ) );
253 bool bIsEmbedded = true;
254 //todo: for standalone chart: detect wether we are standalone
255 if( bIsEmbedded )
257 //change map mode to fit new size
258 awt::Size aModelPageSize = ChartModelHelper::getPageSize( getModel() );
259 sal_Int32 nScaleXNumerator = aLogicSize.Width();
260 sal_Int32 nScaleXDenominator = aModelPageSize.Width;
261 sal_Int32 nScaleYNumerator = aLogicSize.Height();
262 sal_Int32 nScaleYDenominator = aModelPageSize.Height;
263 MapMode aNewMapMode( MAP_100TH_MM, Point(0,0)
264 , Fraction(nScaleXNumerator,nScaleXDenominator)
265 , Fraction(nScaleYNumerator,nScaleYDenominator) );
266 pWindow->SetMapMode(aNewMapMode);
267 pWindow->SetPosSizePixel( X, Y, Width, Height, Flags );
269 //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
270 uno::Reference< beans::XPropertySet > xProp( m_xChartView, uno::UNO_QUERY );
271 if( xProp.is() )
273 uno::Sequence< beans::PropertyValue > aZoomFactors(4);
274 aZoomFactors[0].Name = C2U("ScaleXNumerator");
275 aZoomFactors[0].Value = uno::makeAny( nScaleXNumerator );
276 aZoomFactors[1].Name = C2U("ScaleXDenominator");
277 aZoomFactors[1].Value = uno::makeAny( nScaleXDenominator );
278 aZoomFactors[2].Name = C2U("ScaleYNumerator");
279 aZoomFactors[2].Value = uno::makeAny( nScaleYNumerator );
280 aZoomFactors[3].Name = C2U("ScaleYDenominator");
281 aZoomFactors[3].Value = uno::makeAny( nScaleYDenominator );
282 xProp->setPropertyValue( C2U("ZoomFactors"), uno::makeAny( aZoomFactors ));
285 //a correct work area is at least necessary for correct values in the position and size dialog and for dragging area
286 if(m_pDrawViewWrapper)
288 Rectangle aRect(Point(0,0), pWindow->GetOutputSize());
289 m_pDrawViewWrapper->SetWorkArea( aRect );
292 else
294 //change visarea
295 ChartModelHelper::setPageSize( awt::Size( aLogicSize.Width(), aLogicSize.Height() ), getModel() );
296 pWindow->SetPosSizePixel( X, Y, Width, Height, Flags );
298 pWindow->Invalidate();
302 awt::Rectangle SAL_CALL ChartController
303 ::getPosSize()
304 throw (uno::RuntimeException)
306 //@todo
307 awt::Rectangle aRet(0,0,0,0);
309 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
310 if(xWindow.is())
311 aRet = xWindow->getPosSize();
313 return aRet;
316 void SAL_CALL ChartController
317 ::setVisible( sal_Bool Visible )
318 throw (uno::RuntimeException)
320 //@todo
321 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
323 if(xWindow.is())
324 xWindow->setVisible( Visible );
327 void SAL_CALL ChartController
328 ::setEnable( sal_Bool Enable )
329 throw (uno::RuntimeException)
331 //@todo
332 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
334 if(xWindow.is())
335 xWindow->setEnable( Enable );
338 void SAL_CALL ChartController
339 ::setFocus() throw (uno::RuntimeException)
341 //@todo
342 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
344 if(xWindow.is())
345 xWindow->setFocus();
348 void SAL_CALL ChartController
349 ::addWindowListener( const uno::Reference<
350 awt::XWindowListener >& xListener )
351 throw (uno::RuntimeException)
353 //@todo
354 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
356 if(xWindow.is())
357 xWindow->addWindowListener( xListener );
360 void SAL_CALL ChartController
361 ::removeWindowListener( const uno::Reference<
362 awt::XWindowListener >& xListener )
363 throw (uno::RuntimeException)
365 //@todo
366 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
368 if(xWindow.is())
369 xWindow->removeWindowListener( xListener );
372 void SAL_CALL ChartController
373 ::addFocusListener( const uno::Reference<
374 awt::XFocusListener >& xListener )
375 throw (uno::RuntimeException)
377 //@todo
378 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
380 if(xWindow.is())
381 xWindow->addFocusListener( xListener );
384 void SAL_CALL ChartController
385 ::removeFocusListener( const uno::Reference<
386 awt::XFocusListener >& xListener )
387 throw (uno::RuntimeException)
389 //@todo
390 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
392 if(xWindow.is())
393 xWindow->removeFocusListener( xListener );
396 void SAL_CALL ChartController
397 ::addKeyListener( const uno::Reference<
398 awt::XKeyListener >& xListener )
399 throw (uno::RuntimeException)
401 //@todo
402 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
404 if(xWindow.is())
405 xWindow->addKeyListener( xListener );
408 void SAL_CALL ChartController
409 ::removeKeyListener( const uno::Reference<
410 awt::XKeyListener >& xListener )
411 throw (uno::RuntimeException)
413 //@todo
414 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
416 if(xWindow.is())
417 xWindow->removeKeyListener( xListener );
420 void SAL_CALL ChartController
421 ::addMouseListener( const uno::Reference<
422 awt::XMouseListener >& xListener )
423 throw (uno::RuntimeException)
425 //@todo
426 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
428 if(xWindow.is())
429 xWindow->addMouseListener( xListener );
432 void SAL_CALL ChartController
433 ::removeMouseListener( const uno::Reference<
434 awt::XMouseListener >& xListener )
435 throw (uno::RuntimeException)
437 //@todo
438 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
440 if(xWindow.is())
441 xWindow->removeMouseListener( xListener );
444 void SAL_CALL ChartController
445 ::addMouseMotionListener( const uno::Reference<
446 awt::XMouseMotionListener >& xListener )
447 throw (uno::RuntimeException)
449 //@todo
450 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
452 if(xWindow.is())
453 xWindow->addMouseMotionListener( xListener );
456 void SAL_CALL ChartController
457 ::removeMouseMotionListener( const uno::Reference<
458 awt::XMouseMotionListener >& xListener )
459 throw (uno::RuntimeException)
461 //@todo
462 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
464 if(xWindow.is())
465 xWindow->removeMouseMotionListener( xListener );
468 void SAL_CALL ChartController
469 ::addPaintListener( const uno::Reference<
470 awt::XPaintListener >& xListener )
471 throw (uno::RuntimeException)
473 //@todo
474 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
476 if(xWindow.is())
477 xWindow->addPaintListener( xListener );
480 void SAL_CALL ChartController
481 ::removePaintListener( const uno::Reference<
482 awt::XPaintListener >& xListener )
483 throw (uno::RuntimeException)
485 //@todo
486 uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
488 if(xWindow.is())
489 xWindow->removePaintListener( xListener );
492 //-----------------------------------------------------------------
493 // impl vcl window controller methods
494 //-----------------------------------------------------------------
495 void ChartController::PrePaint()
497 // forward VCLs PrePaint window event to DrawingLayer
498 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
500 if(pDrawViewWrapper)
502 pDrawViewWrapper->PrePaint();
506 void ChartController::execute_Paint( const Rectangle& rRect )
510 uno::Reference< frame::XModel > xModel( getModel() );
511 //DBG_ASSERT( xModel.is(), "ChartController::execute_Paint: have no model to paint");
512 if( !xModel.is() )
513 return;
515 //better performance for big data
516 uno::Reference< beans::XPropertySet > xProp( m_xChartView, uno::UNO_QUERY );
517 if( xProp.is() )
519 awt::Size aResolution(1000,1000);
521 ::vos::OGuard aGuard( Application::GetSolarMutex());
522 if( m_pChartWindow )
524 aResolution.Width = m_pChartWindow->GetSizePixel().Width();
525 aResolution.Height = m_pChartWindow->GetSizePixel().Height();
528 xProp->setPropertyValue( C2U("Resolution"), uno::makeAny( aResolution ));
532 uno::Reference< util::XUpdatable > xUpdatable( m_xChartView, uno::UNO_QUERY );
533 if( xUpdatable.is() )
534 xUpdatable->update();
536 Window* pWindow = m_pChartWindow;
538 ::vos::OGuard aGuard( Application::GetSolarMutex());
539 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
540 if(pDrawViewWrapper)
541 pDrawViewWrapper->CompleteRedraw(pWindow, Region(rRect) );
544 catch( uno::Exception & ex )
546 ASSERT_EXCEPTION( ex );
548 catch( ... )
553 bool isDoubleClick( const MouseEvent& rMEvt )
555 return rMEvt.GetClicks() == 2 && rMEvt.IsLeft() &&
556 !rMEvt.IsMod1() && !rMEvt.IsMod2() && !rMEvt.IsShift();
559 //-----------------------------------------------------------------------------
560 //-----------------------------------------------------------------------------
561 //-----------------------------------------------------------------------------
563 void ChartController::startDoubleClickWaiting()
565 m_bWaitingForDoubleClick = true;
567 ULONG nDblClkTime = 500;
568 if( m_pChartWindow )
570 const MouseSettings& rMSettings = m_pChartWindow->GetSettings().GetMouseSettings();
571 nDblClkTime = rMSettings.GetDoubleClickTime();
573 m_aDoubleClickTimer.SetTimeout( nDblClkTime );
574 m_aDoubleClickTimer.Start();
577 void ChartController::stopDoubleClickWaiting()
579 m_aDoubleClickTimer.Stop();
580 m_bWaitingForDoubleClick = false;
583 IMPL_LINK( ChartController, DoubleClickWaitingHdl, void*, EMPTYARG )
585 m_bWaitingForDoubleClick = false;
587 if( !m_bWaitingForMouseUp && m_aSelection.maybeSwitchSelectionAfterSingleClickWasEnsured() )
589 this->impl_selectObjectAndNotiy();
590 if( m_pChartWindow )
592 Window::PointerState aPointerState( m_pChartWindow->GetPointerState() );
593 MouseEvent aMouseEvent( aPointerState.maPos,1/*nClicks*/,
594 0/*nMode*/, static_cast< USHORT >( aPointerState.mnState )/*nButtons*/,
595 0/*nModifier*/ );
596 impl_SetMousePointer( aMouseEvent );
600 return 0;
603 //------------------------------------------------------------------------
605 void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt )
607 ::vos::OGuard aGuard( Application::GetSolarMutex());
609 m_bWaitingForMouseUp = true;
611 if( isDoubleClick(rMEvt) )
612 stopDoubleClickWaiting();
613 else
614 startDoubleClickWaiting();
616 m_aSelection.remindSelectionBeforeMouseDown();
618 Window* pWindow = m_pChartWindow;
619 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
620 if(!pWindow || !pDrawViewWrapper )
621 return;
623 Point aMPos = pWindow->PixelToLogic(rMEvt.GetPosPixel());
625 if ( MOUSE_LEFT == rMEvt.GetButtons() )
627 pWindow->GrabFocus();
628 pWindow->CaptureMouse();
631 if( pDrawViewWrapper->IsTextEdit() )
633 SdrViewEvent aVEvt;
634 if ( pDrawViewWrapper->IsTextEditHit( aMPos, HITPIX ) ||
635 // #i12587# support for shapes in chart
636 ( rMEvt.IsRight() && pDrawViewWrapper->PickAnything( rMEvt, SDRMOUSEBUTTONDOWN, aVEvt ) == SDRHIT_MARKEDOBJECT ) )
638 pDrawViewWrapper->MouseButtonDown(rMEvt,m_pChartWindow);
639 return;
641 else
643 this->EndTextEdit();
647 //abort running action
648 if( pDrawViewWrapper->IsAction() )
650 if( rMEvt.IsRight() )
651 pDrawViewWrapper->BckAction();
652 return;
655 if( isDoubleClick(rMEvt) ) //do not change selection if double click
656 return;//double click is handled further in mousebutton up
658 SdrHdl* pHitSelectionHdl = 0;
659 //switch from move to resize if handle is hit on a resizeable object
660 if( m_aSelection.isResizeableObjectSelected() )
661 pHitSelectionHdl = pDrawViewWrapper->PickHandle( aMPos );
662 //only change selection if no selection handles are hit
663 if( !pHitSelectionHdl )
665 // #i12587# support for shapes in chart
666 if ( m_eDrawMode == CHARTDRAW_INSERT &&
667 ( !pDrawViewWrapper->IsMarkedHit( aMPos ) || !m_aSelection.isDragableObjectSelected() ) )
669 if ( m_aSelection.hasSelection() )
671 m_aSelection.clearSelection();
673 if ( !pDrawViewWrapper->IsAction() )
675 if ( pDrawViewWrapper->GetCurrentObjIdentifier() == OBJ_CAPTION )
677 Size aCaptionSize( 2268, 1134 );
678 pDrawViewWrapper->BegCreateCaptionObj( aMPos, aCaptionSize );
680 else
682 pDrawViewWrapper->BegCreateObj( aMPos);
684 SdrObject* pObj = pDrawViewWrapper->GetCreateObj();
685 DrawCommandDispatch* pDrawCommandDispatch = m_aDispatchContainer.getDrawCommandDispatch();
686 if ( pObj && m_pDrawModelWrapper && pDrawCommandDispatch )
688 SfxItemSet aSet( m_pDrawModelWrapper->GetItemPool() );
689 pDrawCommandDispatch->setAttributes( pObj );
690 pDrawCommandDispatch->setLineEnds( aSet );
691 pObj->SetMergedItemSet( aSet );
694 impl_SetMousePointer( rMEvt );
695 return;
698 m_aSelection.adaptSelectionToNewPos( aMPos, pDrawViewWrapper
699 , rMEvt.IsRight(), m_bWaitingForDoubleClick );
701 if( !m_aSelection.isRotateableObjectSelected( getModel() ) )
703 m_eDragMode = SDRDRAG_MOVE;
704 pDrawViewWrapper->SetDragMode(m_eDragMode);
707 m_aSelection.applySelection(pDrawViewWrapper);
709 if( m_aSelection.isDragableObjectSelected()
710 && !rMEvt.IsRight() )
712 //start drag
713 USHORT nDrgLog = (USHORT)pWindow->PixelToLogic(Size(DRGPIX,0)).Width();
714 SdrDragMethod* pDragMethod = NULL;
716 //change selection to 3D scene if rotate mode
717 SdrDragMode eDragMode = pDrawViewWrapper->GetDragMode();
718 if( SDRDRAG_ROTATE==eDragMode )
720 E3dScene* pScene = SelectionHelper::getSceneToRotate( pDrawViewWrapper->getNamedSdrObject( m_aSelection.getSelectedCID() ) );
721 if( pScene )
723 DragMethod_RotateDiagram::RotationDirection eRotationDirection(DragMethod_RotateDiagram::ROTATIONDIRECTION_FREE);
724 if(pHitSelectionHdl)
726 SdrHdlKind eKind = pHitSelectionHdl->GetKind();
727 if( eKind==HDL_UPPER || eKind==HDL_LOWER )
728 eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_X;
729 else if( eKind==HDL_LEFT || eKind==HDL_RIGHT )
730 eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_Y;
731 else if( eKind==HDL_UPLFT || eKind==HDL_UPRGT || eKind==HDL_LWLFT || eKind==HDL_LWRGT )
732 eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_Z;
734 pDragMethod = new DragMethod_RotateDiagram( *pDrawViewWrapper, m_aSelection.getSelectedCID(), getModel(), eRotationDirection );
737 else
739 rtl::OUString aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ) );
740 if( aDragMethodServiceName.equals( ObjectIdentifier::getPieSegmentDragMethodServiceName() ) )
741 pDragMethod = new DragMethod_PieSegment( *pDrawViewWrapper, m_aSelection.getSelectedCID(), getModel() );
743 pDrawViewWrapper->SdrView::BegDragObj(aMPos, NULL, pHitSelectionHdl, nDrgLog, pDragMethod);
746 impl_SetMousePointer( rMEvt );
749 void ChartController::execute_MouseMove( const MouseEvent& rMEvt )
751 ::vos::OGuard aGuard( Application::GetSolarMutex());
753 Window* pWindow = m_pChartWindow;
754 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
755 if(!pWindow || !pDrawViewWrapper)
756 return;
758 if( m_pDrawViewWrapper->IsTextEdit() )
760 if( m_pDrawViewWrapper->MouseMove(rMEvt,m_pChartWindow) )
761 return;
764 if(pDrawViewWrapper->IsAction())
766 pDrawViewWrapper->MovAction( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
769 //?? pDrawViewWrapper->GetPageView()->DragPoly();
771 impl_SetMousePointer( rMEvt );
773 void ChartController::execute_Tracking( const TrackingEvent& /* rTEvt */ )
777 //-----------------
779 void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt )
781 ControllerLockGuard aCLGuard( getModel() );
782 bool bMouseUpWithoutMouseDown = !m_bWaitingForMouseUp;
783 m_bWaitingForMouseUp = false;
784 bool bNotifySelectionChange = false;
786 ::vos::OGuard aGuard( Application::GetSolarMutex());
788 Window* pWindow = m_pChartWindow;
789 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
790 if(!pWindow || !pDrawViewWrapper)
791 return;
793 Point aMPos = pWindow->PixelToLogic(rMEvt.GetPosPixel());
795 if(pDrawViewWrapper->IsTextEdit())
797 if( pDrawViewWrapper->MouseButtonUp(rMEvt,m_pChartWindow) )
798 return;
801 // #i12587# support for shapes in chart
802 if ( m_eDrawMode == CHARTDRAW_INSERT && pDrawViewWrapper->IsCreateObj() )
804 pDrawViewWrapper->EndCreateObj( SDRCREATE_FORCEEND );
805 impl_switchDiagramPositioningToExcludingPositioning();
806 if ( pDrawViewWrapper->AreObjectsMarked() )
808 if ( pDrawViewWrapper->GetCurrentObjIdentifier() == OBJ_TEXT )
810 executeDispatch_EditText();
812 else
814 SdrObject* pObj = pDrawViewWrapper->getSelectedObject();
815 if ( pObj )
817 uno::Reference< drawing::XShape > xShape( pObj->getUnoShape(), uno::UNO_QUERY );
818 if ( xShape.is() )
820 m_aSelection.setSelection( xShape );
821 m_aSelection.applySelection( pDrawViewWrapper );
826 else
828 m_aSelection.adaptSelectionToNewPos( aMPos, pDrawViewWrapper, rMEvt.IsRight(), m_bWaitingForDoubleClick );
829 m_aSelection.applySelection( pDrawViewWrapper );
830 setDrawMode( CHARTDRAW_SELECT );
833 else if ( pDrawViewWrapper->IsDragObj() )
835 bool bDraggingDone = false;
836 SdrDragMethod* pDragMethod = pDrawViewWrapper->SdrView::GetDragMethod();
837 bool bIsMoveOnly = pDragMethod ? pDragMethod->getMoveOnly() : false;
838 DragMethod_Base* pChartDragMethod = dynamic_cast< DragMethod_Base* >(pDragMethod);
839 if( pChartDragMethod )
841 UndoGuard aUndoGuard( pChartDragMethod->getUndoDescription(),
842 m_xUndoManager, getModel() );
844 if( pDrawViewWrapper->EndDragObj(false) )
846 bDraggingDone = true;
847 aUndoGuard.commitAction();
851 if( !bDraggingDone && pDrawViewWrapper->EndDragObj(false) )
855 //end move or size
856 SdrObject* pObj = pDrawViewWrapper->getSelectedObject();
857 if( pObj )
859 Rectangle aObjectRect = pObj->GetSnapRect();
860 awt::Size aPageSize( ChartModelHelper::getPageSize( getModel() ) );
861 Rectangle aPageRect( 0,0,aPageSize.Width,aPageSize.Height );
863 const E3dObject* pE3dObject = dynamic_cast< const E3dObject*>( pObj );
864 if( pE3dObject )
865 aObjectRect = pE3dObject->GetScene()->GetSnapRect();
867 ActionDescriptionProvider::ActionType eActionType(ActionDescriptionProvider::MOVE);
868 if( !bIsMoveOnly && m_aSelection.isResizeableObjectSelected() )
869 eActionType = ActionDescriptionProvider::RESIZE;
871 UndoGuard aUndoGuard(
872 ActionDescriptionProvider::createDescription(
873 eActionType,
874 ObjectNameProvider::getName( ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() ))),
875 m_xUndoManager, getModel() );
876 bool bChanged = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID()
877 , getModel()
878 , awt::Rectangle(aObjectRect.getX(),aObjectRect.getY(),aObjectRect.getWidth(),aObjectRect.getHeight())
879 , awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight()) );
880 if( bChanged )
882 bDraggingDone = true;
883 aUndoGuard.commitAction();
887 catch( uno::Exception & ex )
889 ASSERT_EXCEPTION( ex );
891 //all wanted model changes will take effect
892 //and all unwanted view modifications are cleaned
895 if( !bDraggingDone ) //mouse wasn't moved while dragging
897 bool bClickedTwiceOnDragableObject = SelectionHelper::isDragableObjectHitTwice( aMPos, m_aSelection.getSelectedCID(), *pDrawViewWrapper );
898 bool bIsRotateable = m_aSelection.isRotateableObjectSelected( getModel() );
900 //toggel between move and rotate
901 if( bIsRotateable && bClickedTwiceOnDragableObject && SDRDRAG_MOVE==m_eDragMode )
902 m_eDragMode=SDRDRAG_ROTATE;
903 else
904 m_eDragMode=SDRDRAG_MOVE;
906 pDrawViewWrapper->SetDragMode(m_eDragMode);
908 if( !m_bWaitingForDoubleClick && m_aSelection.maybeSwitchSelectionAfterSingleClickWasEnsured() )
910 this->impl_selectObjectAndNotiy();
913 else
914 m_aSelection.resetPossibleSelectionAfterSingleClickWasEnsured();
916 else if( isDoubleClick(rMEvt) && !bMouseUpWithoutMouseDown /*#i106966#*/ )
918 Point aMousePixel = rMEvt.GetPosPixel();
919 execute_DoubleClick( &aMousePixel );
922 //@todo ForcePointer(&rMEvt);
923 pWindow->ReleaseMouse();
925 if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() )
926 bNotifySelectionChange = true;
929 impl_SetMousePointer( rMEvt );
931 if(bNotifySelectionChange)
932 impl_notifySelectionChangeListeners();
935 void ChartController::execute_DoubleClick( const Point* pMousePixel )
937 bool bEditText = false;
938 if ( m_aSelection.hasSelection() )
940 ::rtl::OUString aCID( m_aSelection.getSelectedCID() );
941 if ( aCID.getLength() )
943 ObjectType eObjectType = ObjectIdentifier::getObjectType( aCID );
944 if ( OBJECTTYPE_TITLE == eObjectType )
946 bEditText = true;
949 else
951 // #i12587# support for shapes in chart
952 SdrObject* pObj = DrawViewWrapper::getSdrObject( m_aSelection.getSelectedAdditionalShape() );
953 if ( pObj && pObj->ISA( SdrTextObj ) )
955 bEditText = true;
960 if ( bEditText )
962 executeDispatch_EditText( pMousePixel );
964 else
966 executeDispatch_ObjectProperties();
970 void ChartController::execute_Resize()
972 m_pChartWindow->Invalidate();
974 void ChartController::execute_Activate()
976 ///// pDrawViewWrapper->SetEditMode(TRUE);
978 void ChartController::execute_Deactivate()
981 pDrawViewWrapper->SetEditMode(FALSE);
982 this->ReleaseMouse();
985 void ChartController::execute_GetFocus()
988 void ChartController::execute_LoseFocus()
990 //this->ReleaseMouse();
993 void ChartController::execute_Command( const CommandEvent& rCEvt )
995 Window* pWindow = m_pChartWindow;
997 bool bIsAction = false;
999 ::vos::OGuard aGuard( Application::GetSolarMutex());
1000 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
1001 if(!pWindow || !pDrawViewWrapper)
1002 return;
1003 bIsAction = m_pDrawViewWrapper->IsAction();
1006 // pop-up menu
1007 if(rCEvt.GetCommand() == COMMAND_CONTEXTMENU && !bIsAction)
1009 m_pChartWindow->ReleaseMouse();
1011 if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() )
1012 impl_notifySelectionChangeListeners();
1014 if ( isShapeContext() )
1016 // #i12587# support for shapes in chart
1017 PopupMenu aContextMenu( SchResId( m_pDrawViewWrapper->IsTextEdit() ?
1018 RID_CONTEXTMENU_SHAPEEDIT : RID_CONTEXTMENU_SHAPE ) );
1019 ::svt::ContextMenuHelper aContextMenuHelper( m_xFrame );
1020 Point aPos( rCEvt.GetMousePosPixel() );
1021 if( !rCEvt.IsMouseEvent() )
1023 aPos = m_pChartWindow->GetPointerState().maPos;
1025 aContextMenuHelper.completeAndExecute( aPos, aContextMenu );
1027 else
1029 // todo: the context menu should be specified by an xml file in uiconfig
1030 uno::Reference< awt::XPopupMenu > xPopupMenu(
1031 m_xCC->getServiceManager()->createInstanceWithContext(
1032 C2U("com.sun.star.awt.PopupMenu"), m_xCC ), uno::UNO_QUERY );
1033 uno::Reference< awt::XMenuExtended > xMenuEx( xPopupMenu, uno::UNO_QUERY );
1034 if( xPopupMenu.is() && xMenuEx.is())
1036 sal_Int16 nUniqueId = 1;
1037 ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() );
1038 Reference< XDiagram > xDiagram = ChartModelHelper::findDiagram( getModel() );
1040 OUString aFormatCommand( lcl_getFormatCommandForObjectCID( m_aSelection.getSelectedCID() ) );
1041 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, aFormatCommand );
1043 //some commands for dataseries and points:
1044 //-----
1045 if( OBJECTTYPE_DATA_SERIES == eObjectType || OBJECTTYPE_DATA_POINT == eObjectType )
1047 bool bIsPoint = ( OBJECTTYPE_DATA_POINT == eObjectType );
1048 uno::Reference< XDataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() );
1049 uno::Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY );
1050 Reference< chart2::XRegressionCurve > xTrendline( RegressionCurveHelper::getFirstCurveNotMeanValueLine( xCurveCnt ) );
1051 bool bHasEquation = RegressionCurveHelper::hasEquation( xTrendline );
1052 Reference< chart2::XRegressionCurve > xMeanValue( RegressionCurveHelper::getMeanValueLine( xCurveCnt ) );
1053 bool bHasYErrorBars = StatisticsHelper::hasErrorBars( xSeries, true );
1054 bool bHasDataLabelsAtSeries = DataSeriesHelper::hasDataLabelsAtSeries( xSeries );
1055 bool bHasDataLabelsAtPoints = DataSeriesHelper::hasDataLabelsAtPoints( xSeries );
1056 bool bHasDataLabelAtPoint = false;
1057 sal_Int32 nPointIndex = -1;
1058 if( bIsPoint )
1060 nPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( m_aSelection.getSelectedCID() );
1061 bHasDataLabelAtPoint = DataSeriesHelper::hasDataLabelAtPoint( xSeries, nPointIndex );
1063 bool bSelectedPointIsFormatted = false;
1064 bool bHasFormattedDataPointsOtherThanSelected = false;
1066 Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
1067 if( xSeriesProperties.is() )
1069 uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
1070 if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
1072 if( aAttributedDataPointIndexList.hasElements() )
1074 if( bIsPoint )
1076 ::std::vector< sal_Int32 > aIndices( ContainerHelper::SequenceToVector( aAttributedDataPointIndexList ) );
1077 ::std::vector< sal_Int32 >::iterator aIt = ::std::find( aIndices.begin(), aIndices.end(), nPointIndex );
1078 if( aIt != aIndices.end())
1079 bSelectedPointIsFormatted = true;
1080 else
1081 bHasFormattedDataPointsOtherThanSelected = true;
1083 else
1084 bHasFormattedDataPointsOtherThanSelected = true;
1089 //const sal_Int32 nIdBeforeFormat = nUniqueId;
1090 if( bIsPoint )
1092 if( bHasDataLabelAtPoint )
1093 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatDataLabel") );
1094 if( !bHasDataLabelAtPoint )
1095 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertDataLabel") );
1096 else
1097 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteDataLabel") );
1098 if( bSelectedPointIsFormatted )
1099 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:ResetDataPoint"));
1101 xPopupMenu->insertSeparator( -1 );
1103 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatDataSeries") );
1106 Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram, xSeries ) );
1107 if( xChartType->getChartType().equals(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
1111 Reference< beans::XPropertySet > xChartTypeProp( xChartType, uno::UNO_QUERY );
1112 if( xChartTypeProp.is() )
1114 bool bJapaneseStyle = false;
1115 xChartTypeProp->getPropertyValue( C2U( "Japanese" ) ) >>= bJapaneseStyle;
1117 if( bJapaneseStyle )
1119 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockLoss") );
1120 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockGain") );
1124 catch( const uno::Exception & ex )
1126 ASSERT_EXCEPTION( ex );
1130 if( bHasDataLabelsAtSeries )
1131 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatDataLabels") );
1132 if( xTrendline.is() )
1133 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatTrendline") );
1134 if( bHasEquation )
1135 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatTrendlineEquation") );
1136 if( xMeanValue.is() )
1137 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatMeanValue") );
1138 if( bHasYErrorBars )
1139 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatYErrorBars") );
1141 //if( nIdBeforeFormat != nUniqueId )
1142 xPopupMenu->insertSeparator( -1 );
1144 //const sal_Int32 nIdBeforeInsert = nUniqueId;
1146 if( !bHasDataLabelsAtSeries )
1147 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertDataLabels") );
1148 if( !xTrendline.is() )
1149 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendline") );
1150 else if( !bHasEquation )
1151 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendlineEquation") );
1152 if( !xMeanValue.is() )
1153 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertMeanValue") );
1154 if( !bHasYErrorBars )
1155 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertYErrorBars") );
1157 //if( nIdBeforeInsert != nUniqueId )
1158 // xPopupMenu->insertSeparator( -1 );
1160 //const sal_Int32 nIdBeforeDelete = nUniqueId;
1162 if( bHasDataLabelsAtSeries || ( bHasDataLabelsAtPoints && bHasFormattedDataPointsOtherThanSelected ) )
1163 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteDataLabels") );
1164 if( xTrendline.is() )
1165 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteTrendline") );
1166 if( bHasEquation )
1167 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteTrendlineEquation") );
1168 if( xMeanValue.is() )
1169 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteMeanValue") );
1170 if( bHasYErrorBars )
1171 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteYErrorBars") );
1173 if( bHasFormattedDataPointsOtherThanSelected )
1174 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:ResetAllDataPoints"));
1176 //if( nIdBeforeDelete != nUniqueId )
1177 xPopupMenu->insertSeparator( -1 );
1179 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId, C2U(".uno:ArrangeRow"));
1180 uno::Reference< awt::XPopupMenu > xArrangePopupMenu(
1181 m_xCC->getServiceManager()->createInstanceWithContext(
1182 C2U("com.sun.star.awt.PopupMenu"), m_xCC ), uno::UNO_QUERY );
1183 uno::Reference< awt::XMenuExtended > xArrangeMenuEx( xArrangePopupMenu, uno::UNO_QUERY );
1184 if( xArrangePopupMenu.is() && xArrangeMenuEx.is())
1186 sal_Int16 nSubId = nUniqueId + 1;
1187 lcl_insertMenuCommand( xArrangePopupMenu, xArrangeMenuEx, nSubId++, C2U(".uno:Forward") );
1188 lcl_insertMenuCommand( xArrangePopupMenu, xArrangeMenuEx, nSubId, C2U(".uno:Backward") );
1189 xPopupMenu->setPopupMenu( nUniqueId, xArrangePopupMenu );
1190 nUniqueId = nSubId;
1192 ++nUniqueId;
1194 else if( OBJECTTYPE_DATA_CURVE == eObjectType )
1196 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatTrendlineEquation") );
1197 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendlineEquation") );
1198 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendlineEquationAndR2") );
1199 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertR2Value") );
1200 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteTrendlineEquation") );
1201 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteR2Value") );
1203 else if( OBJECTTYPE_DATA_CURVE_EQUATION == eObjectType )
1205 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertR2Value") );
1206 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteR2Value") );
1209 //some commands for axes: and grids
1210 //-----
1211 else if( OBJECTTYPE_AXIS == eObjectType || OBJECTTYPE_GRID == eObjectType || OBJECTTYPE_SUBGRID == eObjectType )
1213 Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), getModel() );
1214 if( xAxis.is() && xDiagram.is() )
1216 sal_Int32 nDimensionIndex = -1;
1217 sal_Int32 nCooSysIndex = -1;
1218 sal_Int32 nAxisIndex = -1;
1219 AxisHelper::getIndicesForAxis( xAxis, xDiagram, nCooSysIndex, nDimensionIndex, nAxisIndex );
1220 bool bIsSecondaryAxis = nAxisIndex!=0;
1221 bool bIsAxisVisible = AxisHelper::isAxisVisible( xAxis );
1222 bool bIsMajorGridVisible = AxisHelper::isGridShown( nDimensionIndex, nCooSysIndex, true /*bMainGrid*/, xDiagram );
1223 bool bIsMinorGridVisible = AxisHelper::isGridShown( nDimensionIndex, nCooSysIndex, false /*bMainGrid*/, xDiagram );
1224 bool bHasTitle = false;
1225 uno::Reference< XTitled > xTitled( xAxis, uno::UNO_QUERY );
1226 if( xTitled.is())
1227 bHasTitle = TitleHelper::getCompleteString( xTitled->getTitleObject() ).getLength()>0;
1229 if( OBJECTTYPE_AXIS != eObjectType && bIsAxisVisible )
1230 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatAxis") );
1231 if( OBJECTTYPE_GRID != eObjectType && bIsMajorGridVisible && !bIsSecondaryAxis )
1232 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatMajorGrid") );
1233 if( OBJECTTYPE_SUBGRID != eObjectType && bIsMinorGridVisible && !bIsSecondaryAxis )
1234 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatMinorGrid") );
1236 xPopupMenu->insertSeparator( -1 );
1238 if( OBJECTTYPE_AXIS != eObjectType && !bIsAxisVisible )
1239 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertAxis") );
1240 if( OBJECTTYPE_GRID != eObjectType && !bIsMajorGridVisible && !bIsSecondaryAxis )
1241 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertMajorGrid") );
1242 if( OBJECTTYPE_SUBGRID != eObjectType && !bIsMinorGridVisible && !bIsSecondaryAxis )
1243 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertMinorGrid") );
1244 if( !bHasTitle )
1245 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertAxisTitle") );
1247 if( bIsAxisVisible )
1248 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteAxis") );
1249 if( bIsMajorGridVisible && !bIsSecondaryAxis )
1250 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteMajorGrid") );
1251 if( bIsMinorGridVisible && !bIsSecondaryAxis )
1252 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteMinorGrid") );
1256 if( OBJECTTYPE_DATA_STOCK_LOSS == eObjectType )
1257 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockGain") );
1258 else if( OBJECTTYPE_DATA_STOCK_GAIN == eObjectType )
1259 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockLoss") );
1261 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:TransformDialog"));
1263 if( OBJECTTYPE_PAGE == eObjectType || OBJECTTYPE_DIAGRAM == eObjectType
1264 || OBJECTTYPE_DIAGRAM_WALL == eObjectType
1265 || OBJECTTYPE_DIAGRAM_FLOOR == eObjectType
1266 || OBJECTTYPE_UNKNOWN == eObjectType )
1268 if( OBJECTTYPE_UNKNOWN != eObjectType )
1269 xPopupMenu->insertSeparator( -1 );
1270 bool bHasLegend = LegendHelper::hasLegend( xDiagram );
1271 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTitles") );
1272 if( !bHasLegend )
1273 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertLegend") );
1274 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertRemoveAxes") );
1275 if( bHasLegend )
1276 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteLegend") );
1278 //-----
1280 xPopupMenu->insertSeparator( -1 );
1281 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DiagramType"));
1282 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DataRanges"));
1283 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DiagramData"));
1284 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:View3D"));
1285 xPopupMenu->insertSeparator( -1 );
1286 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Cut"));
1287 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Copy"));
1288 lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Paste"));
1290 ::svt::ContextMenuHelper aContextMenuHelper( m_xFrame );
1291 Point aPos( rCEvt.GetMousePosPixel() );
1292 if( !rCEvt.IsMouseEvent() )
1293 aPos = m_pChartWindow->GetPointerState().maPos;
1294 aContextMenuHelper.completeAndExecute( aPos, xPopupMenu );
1298 else if( ( rCEvt.GetCommand() == COMMAND_STARTEXTTEXTINPUT ) ||
1299 ( rCEvt.GetCommand() == COMMAND_EXTTEXTINPUT ) ||
1300 ( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT ) ||
1301 ( rCEvt.GetCommand() == COMMAND_INPUTCONTEXTCHANGE ) )
1303 //#i84417# enable editing with IME
1304 if( m_pDrawViewWrapper )
1305 m_pDrawViewWrapper->Command( rCEvt, m_pChartWindow );
1309 bool ChartController::execute_KeyInput( const KeyEvent& rKEvt )
1311 bool bReturn=false;
1313 Window* pWindow = m_pChartWindow;
1314 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
1315 if(!pWindow || !pDrawViewWrapper)
1316 return bReturn;
1318 // handle accelerators
1319 if( ! m_apAccelExecute.get() && m_xFrame.is() && m_xCC.is() && m_xCC->getServiceManager().is() )
1321 m_apAccelExecute.reset( ::svt::AcceleratorExecute::createAcceleratorHelper());
1322 OSL_ASSERT( m_apAccelExecute.get());
1323 if( m_apAccelExecute.get() )
1324 m_apAccelExecute->init(
1325 uno::Reference< lang::XMultiServiceFactory >( m_xCC->getServiceManager(), uno::UNO_QUERY ), m_xFrame );
1328 KeyCode aKeyCode( rKEvt.GetKeyCode());
1329 sal_uInt16 nCode = aKeyCode.GetCode();
1330 // bool bShift = aKeyCode.IsShift();
1331 bool bAlternate = aKeyCode.IsMod2();
1333 if( m_apAccelExecute.get() )
1334 bReturn = m_apAccelExecute->execute( aKeyCode );
1335 if( bReturn )
1336 return bReturn;
1338 if( pDrawViewWrapper->IsTextEdit() )
1340 if( pDrawViewWrapper->KeyInput(rKEvt,pWindow) )
1342 bReturn = true;
1343 if( nCode == KEY_ESCAPE )
1345 this->EndTextEdit();
1350 //if( m_pDrawViewWrapper->IsAction() );
1352 // keyboard accessibility
1353 ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() );
1354 if( ! bReturn )
1356 // Natvigation (Tab/F3/Home/End)
1357 uno::Reference< XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
1358 ObjectKeyNavigation aObjNav( m_aSelection.getSelectedOID(), xChartDoc, ExplicitValueProvider::getExplicitValueProvider( m_xChartView ));
1359 awt::KeyEvent aKeyEvent( ::svt::AcceleratorExecute::st_VCLKey2AWTKey( aKeyCode ));
1360 bReturn = aObjNav.handleKeyEvent( aKeyEvent );
1361 if( bReturn )
1363 ObjectIdentifier aNewOID = aObjNav.getCurrentSelection();
1364 uno::Any aNewSelection;
1365 if ( aNewOID.isValid() && !ObjectHierarchy::isRootNode( aNewOID ) )
1367 aNewSelection = aNewOID.getAny();
1369 if ( m_eDragMode == SDRDRAG_ROTATE && !SelectionHelper::isRotateableObject( aNewOID.getObjectCID(), getModel() ) )
1371 m_eDragMode = SDRDRAG_MOVE;
1373 bReturn = select( aNewSelection );
1377 // Position and Size (+/-/arrow-keys) or pie segment dragging
1378 if( ! bReturn )
1380 // pie segment dragging
1381 // note: could also be done for data series
1382 if( eObjectType == OBJECTTYPE_DATA_POINT &&
1383 ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ).equals(
1384 ObjectIdentifier::getPieSegmentDragMethodServiceName()))
1386 bool bDrag = false;
1387 bool bDragInside = false;
1388 if( nCode == KEY_ADD ||
1389 nCode == KEY_SUBTRACT )
1391 bDrag = true;
1392 bDragInside = ( nCode == KEY_SUBTRACT );
1394 else if(
1395 nCode == KEY_LEFT ||
1396 nCode == KEY_RIGHT ||
1397 nCode == KEY_UP ||
1398 nCode == KEY_DOWN )
1400 bDrag = true;
1401 rtl::OUString aParameter( ObjectIdentifier::getDragParameterString( m_aSelection.getSelectedCID() ));
1402 sal_Int32 nOffsetPercentDummy( 0 );
1403 awt::Point aMinimumPosition( 0, 0 );
1404 awt::Point aMaximumPosition( 0, 0 );
1405 ObjectIdentifier::parsePieSegmentDragParameterString(
1406 aParameter, nOffsetPercentDummy, aMinimumPosition, aMaximumPosition );
1407 aMaximumPosition.Y -= aMinimumPosition.Y;
1408 aMaximumPosition.X -= aMinimumPosition.X;
1410 bDragInside =
1411 (nCode == KEY_RIGHT && (aMaximumPosition.X < 0)) ||
1412 (nCode == KEY_LEFT && (aMaximumPosition.X > 0)) ||
1413 (nCode == KEY_DOWN && (aMaximumPosition.Y < 0)) ||
1414 (nCode == KEY_UP && (aMaximumPosition.Y > 0));
1417 if( bDrag )
1419 double fAmount = bAlternate ? 0.01 : 0.05;
1420 if( bDragInside )
1421 fAmount *= -1.0;
1423 bReturn = impl_DragDataPoint( m_aSelection.getSelectedCID(), fAmount );
1426 else
1428 // size
1429 if( nCode == KEY_ADD ||
1430 nCode == KEY_SUBTRACT )
1432 if( eObjectType == OBJECTTYPE_DIAGRAM )
1434 // default 1 mm in each direction
1435 double fGrowAmountX = 200.0;
1436 double fGrowAmountY = 200.0;
1437 if( bAlternate && pWindow )
1439 // together with Alt-key: 1 px in each direction
1440 Size aPixelSize = pWindow->PixelToLogic( Size( 2, 2 ));
1441 fGrowAmountX = static_cast< double >( aPixelSize.Width());
1442 fGrowAmountY = static_cast< double >( aPixelSize.Height());
1444 if( nCode == KEY_SUBTRACT )
1446 fGrowAmountX = -fGrowAmountX;
1447 fGrowAmountY = -fGrowAmountY;
1449 bReturn = impl_moveOrResizeObject(
1450 m_aSelection.getSelectedCID(), CENTERED_RESIZE_OBJECT, fGrowAmountX, fGrowAmountY );
1453 // position
1454 else if( nCode == KEY_LEFT ||
1455 nCode == KEY_RIGHT ||
1456 nCode == KEY_UP ||
1457 nCode == KEY_DOWN )
1459 if( m_aSelection.isDragableObjectSelected() )
1461 // default 1 mm
1462 double fShiftAmountX = 100.0;
1463 double fShiftAmountY = 100.0;
1464 if( bAlternate && pWindow )
1466 // together with Alt-key: 1 px
1467 Size aPixelSize = pWindow->PixelToLogic( Size( 1, 1 ));
1468 fShiftAmountX = static_cast< double >( aPixelSize.Width());
1469 fShiftAmountY = static_cast< double >( aPixelSize.Height());
1471 switch( nCode )
1473 case KEY_LEFT:
1474 fShiftAmountX = -fShiftAmountX;
1475 fShiftAmountY = 0.0;
1476 break;
1477 case KEY_RIGHT:
1478 fShiftAmountY = 0.0;
1479 break;
1480 case KEY_UP:
1481 fShiftAmountX = 0.0;
1482 fShiftAmountY = -fShiftAmountY;
1483 break;
1484 case KEY_DOWN:
1485 fShiftAmountX = 0.0;
1486 break;
1488 if( m_aSelection.getSelectedCID().getLength() )
1490 //move chart objects
1491 bReturn = impl_moveOrResizeObject(
1492 m_aSelection.getSelectedCID(), MOVE_OBJECT, fShiftAmountX, fShiftAmountY );
1494 else
1496 //move additional shapes
1497 uno::Reference< drawing::XShape > xShape( m_aSelection.getSelectedAdditionalShape() );
1498 if( xShape.is() )
1500 awt::Point aPos( xShape->getPosition() );
1501 awt::Size aSize( xShape->getSize() );
1502 awt::Size aPageSize( ChartModelHelper::getPageSize( getModel() ) );
1503 aPos.X = static_cast< long >( static_cast< double >( aPos.X ) + fShiftAmountX );
1504 aPos.Y = static_cast< long >( static_cast< double >( aPos.Y ) + fShiftAmountY );
1505 if( aPos.X + aSize.Width > aPageSize.Width )
1506 aPos.X = aPageSize.Width - aSize.Width;
1507 if( aPos.X < 0 )
1508 aPos.X = 0;
1509 if( aPos.Y + aSize.Height > aPageSize.Height )
1510 aPos.Y = aPageSize.Height - aSize.Height;
1511 if( aPos.Y < 0 )
1512 aPos.Y = 0;
1514 xShape->setPosition( aPos );
1522 // text edit
1523 if( ! bReturn &&
1524 nCode == KEY_F2 )
1526 if( OBJECTTYPE_TITLE == eObjectType )
1528 executeDispatch_EditText();
1529 bReturn = true;
1533 // deactivate inplace mode (this code should be unnecessary, but
1534 // unfortunately is not)
1535 if( ! bReturn &&
1536 nCode == KEY_ESCAPE )
1538 uno::Reference< frame::XDispatchHelper > xDispatchHelper(
1539 m_xCC->getServiceManager()->createInstanceWithContext(
1540 C2U("com.sun.star.frame.DispatchHelper"), m_xCC ), uno::UNO_QUERY );
1541 if( xDispatchHelper.is())
1543 uno::Sequence< beans::PropertyValue > aArgs;
1544 xDispatchHelper->executeDispatch(
1545 uno::Reference< frame::XDispatchProvider >( m_xFrame, uno::UNO_QUERY ),
1546 C2U(".uno:TerminateInplaceActivation"),
1547 C2U("_parent"),
1548 frame::FrameSearchFlag::PARENT,
1549 aArgs );
1550 bReturn = true;
1554 if( ! bReturn &&
1555 (nCode == KEY_DELETE || nCode == KEY_BACKSPACE ))
1557 bReturn = executeDispatch_Delete();
1558 if( ! bReturn )
1560 InfoBox( m_pChartWindow, String(SchResId( STR_ACTION_NOTPOSSIBLE ))).Execute();
1564 /* old chart:
1565 // Ctrl-Shift-R: Repaint
1566 if (!bReturn && GetWindow())
1568 KeyCode aKeyCode = rKEvt.GetKeyCode();
1570 if (aKeyCode.IsMod1() && aKeyCode.IsShift()
1571 && aKeyCode.GetCode() == KEY_R)
1573 // 3D-Kontext wieder zerstoeren
1574 GetWindow()->Invalidate();
1575 bReturn = TRUE;
1579 return bReturn;
1582 bool ChartController::requestQuickHelp(
1583 ::Point aAtLogicPosition,
1584 bool bIsBalloonHelp,
1585 ::rtl::OUString & rOutQuickHelpText,
1586 awt::Rectangle & rOutEqualRect )
1588 uno::Reference< frame::XModel > xChartModel;
1589 if( m_aModel.is())
1590 xChartModel.set( getModel() );
1591 if( !xChartModel.is())
1592 return false;
1594 // help text
1595 ::rtl::OUString aCID;
1596 if( m_pDrawViewWrapper )
1598 aCID = SelectionHelper::getHitObjectCID(
1599 aAtLogicPosition, *m_pDrawViewWrapper );
1601 bool bResult( aCID.getLength());
1603 if( bResult )
1605 // get help text
1606 rOutQuickHelpText = ObjectNameProvider::getHelpText( aCID, xChartModel, bIsBalloonHelp /* bVerbose */ );
1608 // set rectangle
1609 ExplicitValueProvider * pValueProvider(
1610 ExplicitValueProvider::getExplicitValueProvider( m_xChartView ));
1611 if( pValueProvider )
1612 rOutEqualRect = pValueProvider->getRectangleOfObject( aCID, true );
1615 return bResult;
1618 //-----------------------------------------------------------------
1619 // XSelectionSupplier (optional interface)
1620 //-----------------------------------------------------------------
1621 sal_Bool SAL_CALL ChartController
1622 ::select( const uno::Any& rSelection )
1623 throw( lang::IllegalArgumentException )
1625 bool bSuccess = false;
1627 if ( rSelection.hasValue() )
1629 const uno::Type& rType = rSelection.getValueType();
1630 if ( rType == ::getCppuType( static_cast< const ::rtl::OUString* >( 0 ) ) )
1632 ::rtl::OUString aNewCID;
1633 if ( ( rSelection >>= aNewCID ) && m_aSelection.setSelection( aNewCID ) )
1635 bSuccess = true;
1638 else if ( rType == ::getCppuType( static_cast< const uno::Reference< drawing::XShape >* >( 0 ) ) )
1640 uno::Reference< drawing::XShape > xShape;
1641 if ( ( rSelection >>= xShape ) && m_aSelection.setSelection( xShape ) )
1643 bSuccess = true;
1647 else
1649 if ( m_aSelection.hasSelection() )
1651 m_aSelection.clearSelection();
1652 bSuccess = true;
1656 if ( bSuccess )
1658 this->impl_selectObjectAndNotiy();
1659 return sal_True;
1662 return sal_False;
1665 uno::Any SAL_CALL ChartController
1666 ::getSelection() throw(uno::RuntimeException)
1668 uno::Any aReturn;
1669 if ( m_aSelection.hasSelection() )
1671 ::rtl::OUString aCID( m_aSelection.getSelectedCID() );
1672 if ( aCID.getLength() )
1674 aReturn = uno::makeAny( aCID );
1676 else
1678 // #i12587# support for shapes in chart
1679 aReturn = uno::makeAny( m_aSelection.getSelectedAdditionalShape() );
1682 return aReturn;
1685 void SAL_CALL ChartController
1686 ::addSelectionChangeListener( const uno::Reference<
1687 view::XSelectionChangeListener > & xListener )
1688 throw(uno::RuntimeException)
1690 ::vos::OGuard aGuard( Application::GetSolarMutex());
1691 if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode?
1692 return; //behave passive if already disposed or suspended
1694 //--add listener
1695 m_aLifeTimeManager.m_aListenerContainer.addInterface( ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0), xListener );
1698 void SAL_CALL ChartController
1699 ::removeSelectionChangeListener( const uno::Reference<
1700 view::XSelectionChangeListener > & xListener )
1701 throw(uno::RuntimeException)
1703 ::vos::OGuard aGuard( Application::GetSolarMutex());
1704 if( impl_isDisposedOrSuspended() ) //@todo? allow removing of listeners in suspend mode?
1705 return; //behave passive if already disposed or suspended
1707 //--remove listener
1708 m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0), xListener );
1711 void ChartController
1712 ::impl_notifySelectionChangeListeners()
1714 ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
1715 .getContainer( ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0) );
1716 if( pIC )
1718 uno::Reference< view::XSelectionSupplier > xSelectionSupplier(this);
1719 lang::EventObject aEvent( xSelectionSupplier );
1720 ::cppu::OInterfaceIteratorHelper aIt( *pIC );
1721 while( aIt.hasMoreElements() )
1723 uno::Reference< view::XSelectionChangeListener > xListener( aIt.next(), uno::UNO_QUERY );
1724 if( xListener.is() )
1725 xListener->selectionChanged( aEvent );
1730 void ChartController::impl_selectObjectAndNotiy()
1732 DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
1733 if( pDrawViewWrapper )
1735 pDrawViewWrapper->SetDragMode( m_eDragMode );
1736 m_aSelection.applySelection( m_pDrawViewWrapper );
1738 impl_notifySelectionChangeListeners();
1741 bool ChartController::impl_moveOrResizeObject(
1742 const ::rtl::OUString & rCID,
1743 eMoveOrResizeType eType,
1744 double fAmountLogicX,
1745 double fAmountLogicY )
1747 bool bResult = false;
1748 bool bNeedShift = true;
1749 bool bNeedResize = ( eType == CENTERED_RESIZE_OBJECT );
1751 uno::Reference< frame::XModel > xChartModel( getModel() );
1752 uno::Reference< beans::XPropertySet > xObjProp(
1753 ObjectIdentifier::getObjectPropertySet( rCID, xChartModel ));
1754 if( xObjProp.is())
1756 awt::Size aRefSize = ChartModelHelper::getPageSize( xChartModel );
1758 chart2::RelativePosition aRelPos;
1759 chart2::RelativeSize aRelSize;
1760 bool bDeterminePos = !(xObjProp->getPropertyValue( C2U("RelativePosition")) >>= aRelPos);
1761 bool bDetermineSize = !bNeedResize || !(xObjProp->getPropertyValue( C2U("RelativeSize")) >>= aRelSize);
1763 if( ( bDeterminePos || bDetermineSize ) &&
1764 ( aRefSize.Width > 0 && aRefSize.Height > 0 ) )
1766 ExplicitValueProvider * pValueProvider(
1767 ExplicitValueProvider::getExplicitValueProvider( m_xChartView ));
1768 if( pValueProvider )
1770 awt::Rectangle aRect( pValueProvider->getRectangleOfObject( rCID ));
1771 double fWidth = static_cast< double >( aRefSize.Width );
1772 double fHeight = static_cast< double >( aRefSize.Height );
1773 if( bDetermineSize )
1775 aRelSize.Primary = static_cast< double >( aRect.Width ) / fWidth;
1776 aRelSize.Secondary = static_cast< double >( aRect.Height ) / fHeight;
1778 if( bDeterminePos )
1780 if( bNeedResize && aRelSize.Primary > 0.0 && aRelSize.Secondary > 0.0 )
1782 aRelPos.Primary = (static_cast< double >( aRect.X ) / fWidth) +
1783 (aRelSize.Primary / 2.0);
1784 aRelPos.Secondary = (static_cast< double >( aRect.Y ) / fHeight) +
1785 (aRelSize.Secondary / 2.0);
1786 aRelPos.Anchor = drawing::Alignment_CENTER;
1788 else
1790 aRelPos.Primary = static_cast< double >( aRect.X ) / fWidth;
1791 aRelPos.Secondary = static_cast< double >( aRect.Y ) / fHeight;
1792 aRelPos.Anchor = drawing::Alignment_TOP_LEFT;
1798 if( eType == CENTERED_RESIZE_OBJECT )
1799 bResult = lcl_GrowAndShiftLogic( aRelPos, aRelSize, aRefSize, fAmountLogicX, fAmountLogicY );
1800 else if( eType == MOVE_OBJECT )
1801 bResult = lcl_MoveObjectLogic( aRelPos, aRelSize, aRefSize, fAmountLogicX, fAmountLogicY );
1803 if( bResult )
1805 ActionDescriptionProvider::ActionType eActionType(ActionDescriptionProvider::MOVE);
1806 if( bNeedResize )
1807 eActionType = ActionDescriptionProvider::RESIZE;
1809 ObjectType eObjectType = ObjectIdentifier::getObjectType( rCID );
1810 UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription(
1811 eActionType, ObjectNameProvider::getName( eObjectType )), m_xUndoManager, xChartModel );
1813 ControllerLockGuard aCLGuard( xChartModel );
1814 if( bNeedShift )
1815 xObjProp->setPropertyValue( C2U("RelativePosition"), uno::makeAny( aRelPos ));
1816 if( bNeedResize || (eObjectType == OBJECTTYPE_DIAGRAM) )//Also set an explicat size at the diagram when an explicit position is set
1817 xObjProp->setPropertyValue( C2U("RelativeSize"), uno::makeAny( aRelSize ));
1819 aUndoGuard.commitAction();
1822 return bResult;
1825 bool ChartController::impl_DragDataPoint( const ::rtl::OUString & rCID, double fAdditionalOffset )
1827 bool bResult = false;
1828 if( fAdditionalOffset < -1.0 || fAdditionalOffset > 1.0 || fAdditionalOffset == 0.0 )
1829 return bResult;
1831 sal_Int32 nDataPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( rCID );
1832 uno::Reference< chart2::XDataSeries > xSeries(
1833 ObjectIdentifier::getDataSeriesForCID( rCID, getModel() ));
1834 if( xSeries.is())
1838 uno::Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex( nDataPointIndex ));
1839 double fOffset = 0.0;
1840 if( xPointProp.is() &&
1841 (xPointProp->getPropertyValue( C2U("Offset" )) >>= fOffset ) &&
1842 (( fAdditionalOffset > 0.0 && fOffset < 1.0 ) || (fOffset > 0.0)) )
1844 fOffset += fAdditionalOffset;
1845 if( fOffset > 1.0 )
1846 fOffset = 1.0;
1847 else if( fOffset < 0.0 )
1848 fOffset = 0.0;
1849 xPointProp->setPropertyValue( C2U("Offset"), uno::makeAny( fOffset ));
1850 bResult = true;
1853 catch( const uno::Exception & ex )
1855 ASSERT_EXCEPTION( ex );
1859 return bResult;
1862 void ChartController::impl_SetMousePointer( const MouseEvent & rEvent )
1864 ::vos::OGuard aGuard( Application::GetSolarMutex());
1865 Window* pWindow = m_pChartWindow;
1866 if( m_pDrawViewWrapper && pWindow )
1868 Point aMousePos( pWindow->PixelToLogic( rEvent.GetPosPixel()));
1869 sal_uInt16 nModifier = rEvent.GetModifier();
1870 BOOL bLeftDown = rEvent.IsLeft();
1872 if ( m_pDrawViewWrapper->IsTextEdit() )
1874 if( m_pDrawViewWrapper->IsTextEditHit( aMousePos, HITPIX) )
1876 pWindow->SetPointer( m_pDrawViewWrapper->GetPreferedPointer(
1877 aMousePos, pWindow, nModifier, bLeftDown ) );
1878 return;
1881 else if( m_pDrawViewWrapper->IsAction() )
1883 return;//don't change pointer during running action
1886 SdrHdl* pHitSelectionHdl = 0;
1887 if( m_aSelection.isResizeableObjectSelected() )
1888 pHitSelectionHdl = m_pDrawViewWrapper->PickHandle( aMousePos );
1890 if( pHitSelectionHdl )
1893 Pointer aPointer = m_pDrawViewWrapper->GetPreferedPointer(
1894 aMousePos, pWindow, nModifier, bLeftDown );
1895 bool bForceArrowPointer = false;
1897 ObjectIdentifier aOID( m_aSelection.getSelectedOID() );
1899 switch( aPointer.GetStyle())
1901 case POINTER_NSIZE:
1902 case POINTER_SSIZE:
1903 case POINTER_WSIZE:
1904 case POINTER_ESIZE:
1905 case POINTER_NWSIZE:
1906 case POINTER_NESIZE:
1907 case POINTER_SWSIZE:
1908 case POINTER_SESIZE:
1909 if( ! m_aSelection.isResizeableObjectSelected() )
1910 bForceArrowPointer = true;
1911 break;
1912 case POINTER_MOVE:
1913 if ( !aOID.isDragableObject() )
1914 bForceArrowPointer = true;
1915 break;
1916 case POINTER_MOVEPOINT:
1917 case POINTER_MOVEBEZIERWEIGHT:
1918 // there is no point-editing in a chart
1919 // the POINTER_MOVEBEZIERWEIGHT appears in 3d data points
1920 bForceArrowPointer = true;
1921 break;
1922 default:
1923 break;
1926 if( bForceArrowPointer )
1927 pWindow->SetPointer( Pointer( POINTER_ARROW ));
1928 else
1929 pWindow->SetPointer( aPointer );
1931 else
1933 // #i12587# support for shapes in chart
1934 if ( m_eDrawMode == CHARTDRAW_INSERT &&
1935 ( !m_pDrawViewWrapper->IsMarkedHit( aMousePos ) || !m_aSelection.isDragableObjectSelected() ) )
1937 PointerStyle ePointerStyle = POINTER_DRAW_RECT;
1938 SdrObjKind eKind = static_cast< SdrObjKind >( m_pDrawViewWrapper->GetCurrentObjIdentifier() );
1939 switch ( eKind )
1941 case OBJ_LINE:
1943 ePointerStyle = POINTER_DRAW_LINE;
1945 break;
1946 case OBJ_RECT:
1947 case OBJ_CUSTOMSHAPE:
1949 ePointerStyle = POINTER_DRAW_RECT;
1951 break;
1952 case OBJ_CIRC:
1954 ePointerStyle = POINTER_DRAW_ELLIPSE;
1956 break;
1957 case OBJ_FREELINE:
1959 ePointerStyle = POINTER_DRAW_POLYGON;
1961 break;
1962 case OBJ_TEXT:
1964 ePointerStyle = POINTER_DRAW_TEXT;
1966 break;
1967 case OBJ_CAPTION:
1969 ePointerStyle = POINTER_DRAW_CAPTION;
1971 break;
1972 default:
1974 ePointerStyle = POINTER_DRAW_RECT;
1976 break;
1978 pWindow->SetPointer( Pointer( ePointerStyle ) );
1979 return;
1982 ::rtl::OUString aHitObjectCID(
1983 SelectionHelper::getHitObjectCID(
1984 aMousePos, *m_pDrawViewWrapper, true /*bGetDiagramInsteadOf_Wall*/ ));
1986 if( m_pDrawViewWrapper->IsTextEdit() )
1988 if( aHitObjectCID.equals(m_aSelection.getSelectedCID()) )
1990 pWindow->SetPointer( Pointer( POINTER_ARROW ));
1991 return;
1995 if( !aHitObjectCID.getLength() )
1997 //additional shape was hit
1998 pWindow->SetPointer( POINTER_MOVE );
2000 else if( ObjectIdentifier::isDragableObject( aHitObjectCID ) )
2002 if( (m_eDragMode == SDRDRAG_ROTATE)
2003 && SelectionHelper::isRotateableObject( aHitObjectCID
2004 , getModel() ) )
2005 pWindow->SetPointer( Pointer( POINTER_ROTATE ) );
2006 else
2008 ObjectType eHitObjectType = ObjectIdentifier::getObjectType( aHitObjectCID );
2009 if( eHitObjectType == OBJECTTYPE_DATA_POINT )
2011 if( !ObjectIdentifier::areSiblings(aHitObjectCID,m_aSelection.getSelectedCID())
2012 && !ObjectIdentifier::areIdenticalObjects(aHitObjectCID,m_aSelection.getSelectedCID()) )
2014 pWindow->SetPointer( Pointer( POINTER_ARROW ));
2015 return;
2018 pWindow->SetPointer( POINTER_MOVE );
2021 else
2022 pWindow->SetPointer( Pointer( POINTER_ARROW ));
2027 //.............................................................................
2028 } //namespace chart
2029 //.............................................................................