1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <ChartController.hxx>
21 #include <PositionAndSizeHelper.hxx>
22 #include <ObjectIdentifier.hxx>
23 #include <ChartWindow.hxx>
25 #include <CommonConverters.hxx>
26 #include <ChartModelHelper.hxx>
27 #include <DiagramHelper.hxx>
28 #include <TitleHelper.hxx>
29 #include "UndoGuard.hxx"
30 #include <ControllerLockGuard.hxx>
31 #include <ObjectNameProvider.hxx>
32 #include <strings.hrc>
33 #include "DragMethod_PieSegment.hxx"
34 #include "DragMethod_RotateDiagram.hxx"
35 #include <ObjectHierarchy.hxx>
36 #include <chartview/ExplicitValueProvider.hxx>
37 #include <RelativePositionHelper.hxx>
38 #include <chartview/DrawModelWrapper.hxx>
39 #include <RegressionCurveHelper.hxx>
40 #include <StatisticsHelper.hxx>
41 #include <DataSeriesHelper.hxx>
42 #include <ContainerHelper.hxx>
43 #include <AxisHelper.hxx>
44 #include <LegendHelper.hxx>
45 #include <servicenames_charttypes.hxx>
46 #include "DrawCommandDispatch.hxx"
47 #include <PopupRequest.hxx>
49 #include <com/sun/star/chart2/RelativePosition.hpp>
50 #include <com/sun/star/chart2/RelativeSize.hpp>
51 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
52 #include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
54 #include <com/sun/star/awt/PopupMenuDirection.hpp>
55 #include <com/sun/star/frame/DispatchHelper.hpp>
56 #include <com/sun/star/frame/FrameSearchFlag.hpp>
57 #include <com/sun/star/frame/XPopupMenuController.hpp>
58 #include <com/sun/star/util/XUpdatable.hpp>
59 #include <com/sun/star/awt/Rectangle.hpp>
61 #include <comphelper/lok.hxx>
62 #include <comphelper/propertysequence.hxx>
63 #include <comphelper/propertyvalue.hxx>
64 #include <comphelper/sequence.hxx>
66 #include <toolkit/awt/vclxmenu.hxx>
68 #include <sfx2/viewsh.hxx>
69 #include <sfx2/ipclient.hxx>
70 #include <svx/svxids.hrc>
71 #include <svx/ActionDescriptionProvider.hxx>
72 #include <svx/obj3d.hxx>
73 #include <svx/scene3d.hxx>
74 #include <svx/svddrgmt.hxx>
75 #include <vcl/svapp.hxx>
76 #include <vcl/settings.hxx>
77 #include <vcl/weld.hxx>
78 #include <rtl/math.hxx>
79 #include <svtools/acceleratorexecute.hxx>
80 #include <tools/diagnose_ex.h>
82 #define DRGPIX 2 // Drag MinMove in Pixel
84 using namespace ::com::sun::star
;
85 using namespace ::com::sun::star::chart2
;
86 using ::com::sun::star::uno::Reference
;
93 bool lcl_GrowAndShiftLogic(
94 RelativePosition
& rInOutRelPos
,
95 RelativeSize
& rInOutRelSize
,
96 const awt::Size
& rRefSize
,
100 if( rRefSize
.Width
== 0 ||
101 rRefSize
.Height
== 0 )
104 double fRelativeGrowX
= fGrowLogicX
/ rRefSize
.Width
;
105 double fRelativeGrowY
= fGrowLogicY
/ rRefSize
.Height
;
107 return ::chart::RelativePositionHelper::centerGrow(
108 rInOutRelPos
, rInOutRelSize
,
109 fRelativeGrowX
, fRelativeGrowY
);
112 bool lcl_MoveObjectLogic(
113 RelativePosition
& rInOutRelPos
,
114 RelativeSize
const & rObjectSize
,
115 const awt::Size
& rRefSize
,
117 double fShiftLogicY
)
119 if( rRefSize
.Width
== 0 ||
120 rRefSize
.Height
== 0 )
123 double fRelativeShiftX
= fShiftLogicX
/ rRefSize
.Width
;
124 double fRelativeShiftY
= fShiftLogicY
/ rRefSize
.Height
;
126 return ::chart::RelativePositionHelper::moveObject(
127 rInOutRelPos
, rObjectSize
,
128 fRelativeShiftX
, fRelativeShiftY
);
131 void lcl_insertMenuCommand(
132 const uno::Reference
< awt::XPopupMenu
> & xMenu
,
133 sal_Int16 nId
, const OUString
& rCommand
)
135 xMenu
->insertItem( nId
, "", 0, -1 );
136 xMenu
->setCommand( nId
, rCommand
);
139 OUString
lcl_getFormatCommandForObjectCID( const OUString
& rCID
)
141 OUString
aDispatchCommand( ".uno:FormatSelection" );
143 ObjectType eObjectType
= ObjectIdentifier::getObjectType( rCID
);
147 case OBJECTTYPE_DIAGRAM
:
148 case OBJECTTYPE_DIAGRAM_WALL
:
149 aDispatchCommand
= ".uno:FormatWall";
151 case OBJECTTYPE_DIAGRAM_FLOOR
:
152 aDispatchCommand
= ".uno:FormatFloor";
154 case OBJECTTYPE_PAGE
:
155 aDispatchCommand
= ".uno:FormatChartArea";
157 case OBJECTTYPE_LEGEND
:
158 aDispatchCommand
= ".uno:FormatLegend";
160 case OBJECTTYPE_TITLE
:
161 aDispatchCommand
= ".uno:FormatTitle";
163 case OBJECTTYPE_LEGEND_ENTRY
:
164 aDispatchCommand
= ".uno:FormatDataSeries";
166 case OBJECTTYPE_AXIS
:
167 case OBJECTTYPE_AXIS_UNITLABEL
:
168 aDispatchCommand
= ".uno:FormatAxis";
170 case OBJECTTYPE_GRID
:
171 aDispatchCommand
= ".uno:FormatMajorGrid";
173 case OBJECTTYPE_SUBGRID
:
174 aDispatchCommand
= ".uno:FormatMinorGrid";
176 case OBJECTTYPE_DATA_LABELS
:
177 aDispatchCommand
= ".uno:FormatDataLabels";
179 case OBJECTTYPE_DATA_SERIES
:
180 aDispatchCommand
= ".uno:FormatDataSeries";
182 case OBJECTTYPE_DATA_LABEL
:
183 aDispatchCommand
= ".uno:FormatDataLabel";
185 case OBJECTTYPE_DATA_POINT
:
186 aDispatchCommand
= ".uno:FormatDataPoint";
188 case OBJECTTYPE_DATA_AVERAGE_LINE
:
189 aDispatchCommand
= ".uno:FormatMeanValue";
191 case OBJECTTYPE_DATA_ERRORS_X
:
192 aDispatchCommand
= ".uno:FormatXErrorBars";
194 case OBJECTTYPE_DATA_ERRORS_Y
:
195 aDispatchCommand
= ".uno:FormatYErrorBars";
197 case OBJECTTYPE_DATA_ERRORS_Z
:
198 aDispatchCommand
= ".uno:FormatZErrorBars";
200 case OBJECTTYPE_DATA_CURVE
:
201 aDispatchCommand
= ".uno:FormatTrendline";
203 case OBJECTTYPE_DATA_CURVE_EQUATION
:
204 aDispatchCommand
= ".uno:FormatTrendlineEquation";
206 case OBJECTTYPE_DATA_STOCK_RANGE
:
207 aDispatchCommand
= ".uno:FormatSelection";
209 case OBJECTTYPE_DATA_STOCK_LOSS
:
210 aDispatchCommand
= ".uno:FormatStockLoss";
212 case OBJECTTYPE_DATA_STOCK_GAIN
:
213 aDispatchCommand
= ".uno:FormatStockGain";
215 default: //OBJECTTYPE_UNKNOWN
218 return aDispatchCommand
;
221 } // anonymous namespace
224 void SAL_CALL
ChartController::setPosSize(
231 SolarMutexGuard aGuard
;
232 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
233 auto pChartWindow(GetChartWindow());
235 if(xWindow
.is() && pChartWindow
)
237 Size aLogicSize
= pChartWindow
->PixelToLogic( Size( Width
, Height
), MapMode( MapUnit::Map100thMM
) );
239 //todo: for standalone chart: detect whether we are standalone
240 //change map mode to fit new size
241 awt::Size aModelPageSize
= ChartModelHelper::getPageSize( getModel() );
242 sal_Int32 nScaleXNumerator
= aLogicSize
.Width();
243 sal_Int32 nScaleXDenominator
= aModelPageSize
.Width
;
244 sal_Int32 nScaleYNumerator
= aLogicSize
.Height();
245 sal_Int32 nScaleYDenominator
= aModelPageSize
.Height
;
249 Fraction(nScaleXNumerator
, nScaleXDenominator
),
250 Fraction(nScaleYNumerator
, nScaleYDenominator
) );
251 pChartWindow
->SetMapMode(aNewMapMode
);
252 pChartWindow
->setPosSizePixel( X
, Y
, Width
, Height
, static_cast<PosSizeFlags
>(Flags
) );
254 //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
255 uno::Reference
< beans::XPropertySet
> xProp( m_xChartView
, uno::UNO_QUERY
);
258 auto aZoomFactors(::comphelper::InitPropertySequence({
259 { "ScaleXNumerator", uno::Any( nScaleXNumerator
) },
260 { "ScaleXDenominator", uno::Any( nScaleXDenominator
) },
261 { "ScaleYNumerator", uno::Any( nScaleYNumerator
) },
262 { "ScaleYDenominator", uno::Any( nScaleYDenominator
) }
264 xProp
->setPropertyValue( "ZoomFactors", uno::Any( aZoomFactors
));
267 //a correct work area is at least necessary for correct values in the position and size dialog and for dragging area
268 if(m_pDrawViewWrapper
)
270 tools::Rectangle
aRect(Point(0,0), pChartWindow
->GetOutputSize());
271 m_pDrawViewWrapper
->SetWorkArea( aRect
);
273 pChartWindow
->Invalidate();
277 awt::Rectangle SAL_CALL
ChartController::getPosSize()
280 awt::Rectangle
aRet(0, 0, 0, 0);
282 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
284 aRet
= xWindow
->getPosSize();
289 void SAL_CALL
ChartController::setVisible( sal_Bool Visible
)
292 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
295 xWindow
->setVisible( Visible
);
298 void SAL_CALL
ChartController::setEnable( sal_Bool Enable
)
301 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
304 xWindow
->setEnable( Enable
);
307 void SAL_CALL
ChartController::setFocus()
310 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
316 void SAL_CALL
ChartController::addWindowListener(
317 const uno::Reference
< awt::XWindowListener
>& xListener
)
320 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
323 xWindow
->addWindowListener( xListener
);
326 void SAL_CALL
ChartController::removeWindowListener(
327 const uno::Reference
< awt::XWindowListener
>& xListener
)
330 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
333 xWindow
->removeWindowListener( xListener
);
336 void SAL_CALL
ChartController::addFocusListener(
337 const uno::Reference
< awt::XFocusListener
>& xListener
)
340 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
343 xWindow
->addFocusListener( xListener
);
346 void SAL_CALL
ChartController::removeFocusListener(
347 const uno::Reference
< awt::XFocusListener
>& xListener
)
350 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
353 xWindow
->removeFocusListener( xListener
);
356 void SAL_CALL
ChartController::addKeyListener(
357 const uno::Reference
< awt::XKeyListener
>& xListener
)
360 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
363 xWindow
->addKeyListener( xListener
);
366 void SAL_CALL
ChartController::removeKeyListener(
367 const uno::Reference
< awt::XKeyListener
>& xListener
)
370 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
373 xWindow
->removeKeyListener( xListener
);
376 void SAL_CALL
ChartController::addMouseListener(
377 const uno::Reference
< awt::XMouseListener
>& xListener
)
380 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
383 xWindow
->addMouseListener( xListener
);
386 void SAL_CALL
ChartController::removeMouseListener(
387 const uno::Reference
< awt::XMouseListener
>& xListener
)
390 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
393 xWindow
->removeMouseListener( xListener
);
396 void SAL_CALL
ChartController::addMouseMotionListener(
397 const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
400 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
403 xWindow
->addMouseMotionListener( xListener
);
406 void SAL_CALL
ChartController::removeMouseMotionListener(
407 const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
410 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
413 xWindow
->removeMouseMotionListener( xListener
);
416 void SAL_CALL
ChartController::addPaintListener(
417 const uno::Reference
< awt::XPaintListener
>& xListener
)
420 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
423 xWindow
->addPaintListener( xListener
);
426 void SAL_CALL
ChartController::removePaintListener(
427 const uno::Reference
< awt::XPaintListener
>& xListener
)
430 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
433 xWindow
->removePaintListener( xListener
);
436 // impl vcl window controller methods
437 void ChartController::PrePaint()
439 // forward VCLs PrePaint window event to DrawingLayer
440 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
;
442 if (pDrawViewWrapper
)
444 pDrawViewWrapper
->PrePaint();
448 void ChartController::execute_Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
452 uno::Reference
<frame::XModel
> xModel(getModel());
453 //OSL_ENSURE( xModel.is(), "ChartController::execute_Paint: have no model to paint");
457 //better performance for big data
458 uno::Reference
<beans::XPropertySet
> xProp(m_xChartView
, uno::UNO_QUERY
);
461 awt::Size
aResolution(1000, 1000);
463 SolarMutexGuard aGuard
;
464 auto pChartWindow(GetChartWindow());
467 aResolution
.Width
= pChartWindow
->GetSizePixel().Width();
468 aResolution
.Height
= pChartWindow
->GetSizePixel().Height();
471 xProp
->setPropertyValue( "Resolution", uno::Any( aResolution
));
474 uno::Reference
< util::XUpdatable
> xUpdatable( m_xChartView
, uno::UNO_QUERY
);
476 xUpdatable
->update();
479 SolarMutexGuard aGuard
;
480 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
;
481 if (pDrawViewWrapper
)
482 pDrawViewWrapper
->CompleteRedraw(&rRenderContext
, vcl::Region(rRect
));
485 catch( const uno::Exception
& )
487 DBG_UNHANDLED_EXCEPTION("chart2");
494 bool isDoubleClick( const MouseEvent
& rMEvt
)
496 return rMEvt
.GetClicks() == 2 && rMEvt
.IsLeft() &&
497 !rMEvt
.IsMod1() && !rMEvt
.IsMod2() && !rMEvt
.IsShift();
500 void ChartController::startDoubleClickWaiting()
502 SolarMutexGuard aGuard
;
504 m_bWaitingForDoubleClick
= true;
506 sal_uInt64 nDblClkTime
= 500;
507 auto pChartWindow(GetChartWindow());
510 const MouseSettings
& rMSettings
= pChartWindow
->GetSettings().GetMouseSettings();
511 nDblClkTime
= rMSettings
.GetDoubleClickTime();
513 m_aDoubleClickTimer
.SetTimeout( nDblClkTime
);
514 m_aDoubleClickTimer
.Start();
517 void ChartController::stopDoubleClickWaiting()
519 m_aDoubleClickTimer
.Stop();
520 m_bWaitingForDoubleClick
= false;
523 IMPL_LINK_NOARG(ChartController
, DoubleClickWaitingHdl
, Timer
*, void)
525 m_bWaitingForDoubleClick
= false;
527 if( !m_bWaitingForMouseUp
&& m_aSelection
.maybeSwitchSelectionAfterSingleClickWasEnsured() )
529 impl_selectObjectAndNotiy();
530 SolarMutexGuard aGuard
;
531 auto pChartWindow(GetChartWindow());
534 vcl::Window::PointerState
aPointerState( pChartWindow
->GetPointerState() );
535 MouseEvent
aMouseEvent(
538 MouseEventModifiers::NONE
,
539 static_cast< sal_uInt16
>( aPointerState
.mnState
)/*nButtons*/,
541 impl_SetMousePointer( aMouseEvent
);
546 void ChartController::execute_MouseButtonDown( const MouseEvent
& rMEvt
)
548 SolarMutexGuard aGuard
;
550 m_bWaitingForMouseUp
= true;
551 m_bFieldButtonDown
= false;
553 if( isDoubleClick(rMEvt
) )
554 stopDoubleClickWaiting();
556 startDoubleClickWaiting();
558 m_aSelection
.remindSelectionBeforeMouseDown();
560 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
;
561 auto pChartWindow(GetChartWindow());
562 if(!pChartWindow
|| !pDrawViewWrapper
)
565 Point aMPos
= pChartWindow
->PixelToLogic(rMEvt
.GetPosPixel());
567 // Check if button was clicked
568 SdrObject
* pObject
= pDrawViewWrapper
->getHitObject(aMPos
);
571 OUString aCID
= pObject
->GetName();
572 if (aCID
.startsWith("FieldButton"))
574 m_bFieldButtonDown
= true;
575 return; // Don't take any action if button was clicked
579 if ( rMEvt
.GetButtons() == MOUSE_LEFT
)
581 pChartWindow
->GrabFocus();
582 pChartWindow
->CaptureMouse();
585 if( pDrawViewWrapper
->IsTextEdit() )
588 if ( pDrawViewWrapper
->IsTextEditHit( aMPos
) ||
589 // #i12587# support for shapes in chart
590 ( rMEvt
.IsRight() && pDrawViewWrapper
->PickAnything( rMEvt
, SdrMouseEventKind::BUTTONDOWN
, aVEvt
) == SdrHitKind::MarkedObject
) )
592 pDrawViewWrapper
->MouseButtonDown(rMEvt
, pChartWindow
);
601 //abort running action
602 if( pDrawViewWrapper
->IsAction() )
604 if( rMEvt
.IsRight() )
605 pDrawViewWrapper
->BckAction();
609 if( isDoubleClick(rMEvt
) ) //do not change selection if double click
610 return;//double click is handled further in mousebutton up
612 SdrHdl
* pHitSelectionHdl
= nullptr;
613 //switch from move to resize if handle is hit on a resizable object
614 if( m_aSelection
.isResizeableObjectSelected() )
615 pHitSelectionHdl
= pDrawViewWrapper
->PickHandle( aMPos
);
616 //only change selection if no selection handles are hit
617 if( !pHitSelectionHdl
)
619 // #i12587# support for shapes in chart
620 if ( m_eDrawMode
== CHARTDRAW_INSERT
&&
621 ( !pDrawViewWrapper
->IsMarkedHit( aMPos
) || !m_aSelection
.isDragableObjectSelected() ) )
623 if ( m_aSelection
.hasSelection() )
625 m_aSelection
.clearSelection();
627 if ( !pDrawViewWrapper
->IsAction() )
629 if ( pDrawViewWrapper
->GetCurrentObjIdentifier() == OBJ_CAPTION
)
631 Size
aCaptionSize( 2268, 1134 );
632 pDrawViewWrapper
->BegCreateCaptionObj( aMPos
, aCaptionSize
);
636 pDrawViewWrapper
->BegCreateObj( aMPos
);
638 SdrObject
* pObj
= pDrawViewWrapper
->GetCreateObj();
639 DrawCommandDispatch
* pDrawCommandDispatch
= m_aDispatchContainer
.getDrawCommandDispatch();
640 if ( pObj
&& m_pDrawModelWrapper
&& pDrawCommandDispatch
)
642 SfxItemSet
aSet( m_pDrawModelWrapper
->GetItemPool() );
643 pDrawCommandDispatch
->setAttributes( pObj
);
644 pDrawCommandDispatch
->setLineEnds( aSet
);
645 pObj
->SetMergedItemSet( aSet
);
648 impl_SetMousePointer( rMEvt
);
652 m_aSelection
.adaptSelectionToNewPos(
656 m_bWaitingForDoubleClick
);
658 if( !m_aSelection
.isRotateableObjectSelected( getModel() ) )
660 m_eDragMode
= SdrDragMode::Move
;
661 pDrawViewWrapper
->SetDragMode(m_eDragMode
);
664 m_aSelection
.applySelection(pDrawViewWrapper
);
666 if( m_aSelection
.isDragableObjectSelected()
667 && !rMEvt
.IsRight() )
670 sal_uInt16 nDrgLog
= static_cast<sal_uInt16
>(pChartWindow
->PixelToLogic(Size(DRGPIX
,0)).Width());
671 SdrDragMethod
* pDragMethod
= nullptr;
673 //change selection to 3D scene if rotate mode
674 SdrDragMode eDragMode
= pDrawViewWrapper
->GetDragMode();
675 if( eDragMode
==SdrDragMode::Rotate
)
677 E3dScene
* pScene
= SelectionHelper::getSceneToRotate( pDrawViewWrapper
->getNamedSdrObject( m_aSelection
.getSelectedCID() ) );
680 DragMethod_RotateDiagram::RotationDirection
eRotationDirection(DragMethod_RotateDiagram::ROTATIONDIRECTION_FREE
);
683 SdrHdlKind eKind
= pHitSelectionHdl
->GetKind();
684 if( eKind
==SdrHdlKind::Upper
|| eKind
==SdrHdlKind::Lower
)
685 eRotationDirection
= DragMethod_RotateDiagram::ROTATIONDIRECTION_X
;
686 else if( eKind
==SdrHdlKind::Left
|| eKind
==SdrHdlKind::Right
)
687 eRotationDirection
= DragMethod_RotateDiagram::ROTATIONDIRECTION_Y
;
688 else if( eKind
==SdrHdlKind::UpperLeft
|| eKind
==SdrHdlKind::UpperRight
|| eKind
==SdrHdlKind::LowerLeft
|| eKind
==SdrHdlKind::LowerRight
)
689 eRotationDirection
= DragMethod_RotateDiagram::ROTATIONDIRECTION_Z
;
691 pDragMethod
= new DragMethod_RotateDiagram( *pDrawViewWrapper
, m_aSelection
.getSelectedCID(), getModel(), eRotationDirection
);
696 OUString
aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( m_aSelection
.getSelectedCID() ) );
697 if( aDragMethodServiceName
== ObjectIdentifier::getPieSegmentDragMethodServiceName() )
698 pDragMethod
= new DragMethod_PieSegment( *pDrawViewWrapper
, m_aSelection
.getSelectedCID(), getModel() );
700 pDrawViewWrapper
->SdrView::BegDragObj(aMPos
, nullptr, pHitSelectionHdl
, nDrgLog
, pDragMethod
);
703 impl_SetMousePointer( rMEvt
);
706 void ChartController::execute_MouseMove( const MouseEvent
& rMEvt
)
708 SolarMutexGuard aGuard
;
710 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
;
711 auto pChartWindow(GetChartWindow());
712 if(!pChartWindow
|| !pDrawViewWrapper
)
715 if( m_pDrawViewWrapper
->IsTextEdit() )
717 if( m_pDrawViewWrapper
->MouseMove(rMEvt
,pChartWindow
) )
721 if(pDrawViewWrapper
->IsAction())
723 pDrawViewWrapper
->MovAction( pChartWindow
->PixelToLogic( rMEvt
.GetPosPixel() ) );
726 impl_SetMousePointer( rMEvt
);
729 void ChartController::execute_MouseButtonUp( const MouseEvent
& rMEvt
)
731 ControllerLockGuardUNO
aCLGuard( getModel() );
732 bool bMouseUpWithoutMouseDown
= !m_bWaitingForMouseUp
;
733 m_bWaitingForMouseUp
= false;
734 bool bNotifySelectionChange
= false;
736 SolarMutexGuard aGuard
;
738 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
;
739 auto pChartWindow(GetChartWindow());
740 if(!pChartWindow
|| !pDrawViewWrapper
)
743 Point aMPos
= pChartWindow
->PixelToLogic(rMEvt
.GetPosPixel());
745 // Check if button was clicked
746 if (m_bFieldButtonDown
)
748 m_bFieldButtonDown
= false;
749 SdrObject
* pObject
= pDrawViewWrapper
->getHitObject(aMPos
);
752 OUString aCID
= pObject
->GetName();
753 if (aCID
.startsWith("FieldButton"))
755 sendPopupRequest(aCID
, pObject
->GetCurrentBoundRect());
761 if(pDrawViewWrapper
->IsTextEdit())
763 if( pDrawViewWrapper
->MouseButtonUp(rMEvt
,pChartWindow
) )
767 // #i12587# support for shapes in chart
768 if ( m_eDrawMode
== CHARTDRAW_INSERT
&& pDrawViewWrapper
->IsCreateObj() )
770 pDrawViewWrapper
->EndCreateObj( SdrCreateCmd::ForceEnd
);
772 HiddenUndoContext
aUndoContext( m_xUndoManager
);
773 // don't want the positioning Undo action to appear in the UI
774 impl_switchDiagramPositioningToExcludingPositioning();
776 if ( pDrawViewWrapper
->AreObjectsMarked() )
778 if ( pDrawViewWrapper
->GetCurrentObjIdentifier() == OBJ_TEXT
)
780 executeDispatch_EditText();
784 SdrObject
* pObj
= pDrawViewWrapper
->getSelectedObject();
787 uno::Reference
< drawing::XShape
> xShape( pObj
->getUnoShape(), uno::UNO_QUERY
);
790 m_aSelection
.setSelection( xShape
);
791 m_aSelection
.applySelection( pDrawViewWrapper
);
798 m_aSelection
.adaptSelectionToNewPos( aMPos
, pDrawViewWrapper
, rMEvt
.IsRight(), m_bWaitingForDoubleClick
);
799 m_aSelection
.applySelection( pDrawViewWrapper
);
800 setDrawMode( CHARTDRAW_SELECT
);
803 else if ( pDrawViewWrapper
->IsDragObj() )
805 bool bDraggingDone
= false;
806 SdrDragMethod
* pDragMethod
= pDrawViewWrapper
->SdrView::GetDragMethod();
807 bool bIsMoveOnly
= pDragMethod
&& pDragMethod
->getMoveOnly();
808 DragMethod_Base
* pChartDragMethod
= dynamic_cast< DragMethod_Base
* >(pDragMethod
);
809 if( pChartDragMethod
)
811 UndoGuard
aUndoGuard( pChartDragMethod
->getUndoDescription(),
814 if( pDrawViewWrapper
->EndDragObj() )
816 bDraggingDone
= true;
821 if( !bDraggingDone
&& pDrawViewWrapper
->EndDragObj() )
826 SdrObject
* pObj
= pDrawViewWrapper
->getSelectedObject();
829 tools::Rectangle aObjectRect
= pObj
->GetSnapRect();
830 awt::Size
aPageSize( ChartModelHelper::getPageSize( getModel() ) );
831 tools::Rectangle
aPageRect( 0,0,aPageSize
.Width
,aPageSize
.Height
);
833 const E3dObject
* pE3dObject
= dynamic_cast< const E3dObject
*>( pObj
);
835 aObjectRect
= pE3dObject
->GetScene()->GetSnapRect();
837 ActionDescriptionProvider::ActionType
eActionType(ActionDescriptionProvider::ActionType::Move
);
838 if( !bIsMoveOnly
&& m_aSelection
.isResizeableObjectSelected() )
839 eActionType
= ActionDescriptionProvider::ActionType::Resize
;
841 ObjectType eObjectType
= ObjectIdentifier::getObjectType( m_aSelection
.getSelectedCID() );
843 UndoGuard
aUndoGuard(
844 ActionDescriptionProvider::createDescription( eActionType
, ObjectNameProvider::getName( eObjectType
)),
847 bool bChanged
= false;
848 ChartModel
* pModel
= dynamic_cast<ChartModel
*>(getModel().get());
849 if ( eObjectType
== OBJECTTYPE_LEGEND
)
850 bChanged
= DiagramHelper::switchDiagramPositioningToExcludingPositioning( *pModel
, false , true );
852 bool bMoved
= PositionAndSizeHelper::moveObject( m_aSelection
.getSelectedCID()
854 , awt::Rectangle(aObjectRect
.getX(),aObjectRect
.getY(),aObjectRect
.getWidth(),aObjectRect
.getHeight())
855 , awt::Rectangle(aPageRect
.getX(),aPageRect
.getY(),aPageRect
.getWidth(),aPageRect
.getHeight()) );
857 if( bMoved
|| bChanged
)
859 bDraggingDone
= true;
864 catch( const uno::Exception
& )
866 DBG_UNHANDLED_EXCEPTION("chart2");
868 //all wanted model changes will take effect
869 //and all unwanted view modifications are cleaned
872 if( !bDraggingDone
) //mouse wasn't moved while dragging
874 bool bClickedTwiceOnDragableObject
= SelectionHelper::isDragableObjectHitTwice( aMPos
, m_aSelection
.getSelectedCID(), *pDrawViewWrapper
);
875 bool bIsRotateable
= m_aSelection
.isRotateableObjectSelected( getModel() );
877 //toggle between move and rotate
878 if( bIsRotateable
&& bClickedTwiceOnDragableObject
&& m_eDragMode
==SdrDragMode::Move
)
879 m_eDragMode
=SdrDragMode::Rotate
;
881 m_eDragMode
=SdrDragMode::Move
;
883 pDrawViewWrapper
->SetDragMode(m_eDragMode
);
885 if( !m_bWaitingForDoubleClick
&& m_aSelection
.maybeSwitchSelectionAfterSingleClickWasEnsured() )
887 impl_selectObjectAndNotiy();
891 m_aSelection
.resetPossibleSelectionAfterSingleClickWasEnsured();
893 // In tiled rendering drag mode could be not yet over on the call
894 // that should handle the double-click, so better to perform this check
896 if( isDoubleClick(rMEvt
) && !bMouseUpWithoutMouseDown
/*#i106966#*/ )
898 Point aMousePixel
= rMEvt
.GetPosPixel();
899 execute_DoubleClick( &aMousePixel
);
902 //@todo ForcePointer(&rMEvt);
903 pChartWindow
->ReleaseMouse();
905 if( m_aSelection
.isSelectionDifferentFromBeforeMouseDown() )
906 bNotifySelectionChange
= true;
909 impl_SetMousePointer( rMEvt
);
911 if(bNotifySelectionChange
)
912 impl_notifySelectionChangeListeners();
915 void ChartController::execute_DoubleClick( const Point
* pMousePixel
)
917 bool bEditText
= false;
918 if ( m_aSelection
.hasSelection() )
920 OUString
aCID( m_aSelection
.getSelectedCID() );
921 if ( !aCID
.isEmpty() )
923 ObjectType eObjectType
= ObjectIdentifier::getObjectType( aCID
);
924 if ( eObjectType
== OBJECTTYPE_TITLE
)
931 // #i12587# support for shapes in chart
932 SdrObject
* pObj
= DrawViewWrapper::getSdrObject( m_aSelection
.getSelectedAdditionalShape() );
933 if ( dynamic_cast< const SdrTextObj
* >(pObj
) != nullptr )
942 executeDispatch_EditText( pMousePixel
);
946 executeDispatch_ObjectProperties();
950 void ChartController::execute_Resize()
952 SolarMutexGuard aGuard
;
953 auto pChartWindow(GetChartWindow());
955 pChartWindow
->Invalidate();
958 void ChartController::execute_Command( const CommandEvent
& rCEvt
)
960 SolarMutexGuard aGuard
;
961 auto pChartWindow(GetChartWindow());
962 bool bIsAction
= false;
964 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
;
965 if(!pChartWindow
|| !pDrawViewWrapper
)
967 bIsAction
= m_pDrawViewWrapper
->IsAction();
971 if(rCEvt
.GetCommand() == CommandEventId::ContextMenu
&& !bIsAction
)
975 pChartWindow
->ReleaseMouse();
978 if( m_aSelection
.isSelectionDifferentFromBeforeMouseDown() )
979 impl_notifySelectionChangeListeners();
981 css::uno::Reference
< css::awt::XPopupMenu
> xPopupMenu( m_xCC
->getServiceManager()->createInstanceWithContext(
982 "com.sun.star.awt.PopupMenu", m_xCC
), css::uno::UNO_QUERY
);
984 Point
aPos( rCEvt
.GetMousePosPixel() );
985 if( !rCEvt
.IsMouseEvent() )
988 aPos
= pChartWindow
->GetPointerState().maPos
;
992 if ( isShapeContext() )
993 // #i12587# support for shapes in chart
994 aMenuName
= m_pDrawViewWrapper
->IsTextEdit() ? OUString( "drawtext" ) : OUString( "draw" );
997 // todo: the context menu should be specified by an xml file in uiconfig
1000 sal_Int16 nUniqueId
= 1;
1001 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:Cut" );
1002 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:Copy" );
1003 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:Paste" );
1004 xPopupMenu
->insertSeparator( -1 );
1006 ObjectType eObjectType
= ObjectIdentifier::getObjectType( m_aSelection
.getSelectedCID() );
1007 Reference
< XDiagram
> xDiagram
= ChartModelHelper::findDiagram( getModel() );
1009 OUString
aFormatCommand( lcl_getFormatCommandForObjectCID( m_aSelection
.getSelectedCID() ) );
1010 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, aFormatCommand
);
1012 //some commands for dataseries and points:
1014 if( eObjectType
== OBJECTTYPE_DATA_SERIES
|| eObjectType
== OBJECTTYPE_DATA_POINT
)
1016 bool bIsPoint
= ( eObjectType
== OBJECTTYPE_DATA_POINT
);
1017 uno::Reference
< XDataSeries
> xSeries
= ObjectIdentifier::getDataSeriesForCID( m_aSelection
.getSelectedCID(), getModel() );
1018 uno::Reference
< chart2::XRegressionCurveContainer
> xCurveCnt( xSeries
, uno::UNO_QUERY
);
1019 Reference
< chart2::XRegressionCurve
> xTrendline( RegressionCurveHelper::getFirstCurveNotMeanValueLine( xCurveCnt
) );
1020 bool bHasEquation
= RegressionCurveHelper::hasEquation( xTrendline
);
1021 Reference
< chart2::XRegressionCurve
> xMeanValue( RegressionCurveHelper::getMeanValueLine( xCurveCnt
) );
1022 bool bHasYErrorBars
= StatisticsHelper::hasErrorBars( xSeries
);
1023 bool bHasXErrorBars
= StatisticsHelper::hasErrorBars( xSeries
, false );
1024 bool bHasDataLabelsAtSeries
= DataSeriesHelper::hasDataLabelsAtSeries( xSeries
);
1025 bool bHasDataLabelsAtPoints
= DataSeriesHelper::hasDataLabelsAtPoints( xSeries
);
1026 bool bHasDataLabelAtPoint
= false;
1027 sal_Int32 nPointIndex
= -1;
1030 nPointIndex
= ObjectIdentifier::getIndexFromParticleOrCID( m_aSelection
.getSelectedCID() );
1031 bHasDataLabelAtPoint
= DataSeriesHelper::hasDataLabelAtPoint( xSeries
, nPointIndex
);
1033 bool bSelectedPointIsFormatted
= false;
1034 bool bHasFormattedDataPointsOtherThanSelected
= false;
1036 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
1037 if( xSeriesProperties
.is() )
1039 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
1040 if( xSeriesProperties
->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList
)
1042 if( aAttributedDataPointIndexList
.hasElements() )
1046 std::vector
< sal_Int32
> aIndices( ContainerHelper::SequenceToVector( aAttributedDataPointIndexList
) );
1047 std::vector
< sal_Int32
>::iterator aIt
= std::find( aIndices
.begin(), aIndices
.end(), nPointIndex
);
1048 if( aIt
!= aIndices
.end())
1049 bSelectedPointIsFormatted
= true;
1051 bHasFormattedDataPointsOtherThanSelected
= true;
1054 bHasFormattedDataPointsOtherThanSelected
= true;
1061 if( bHasDataLabelAtPoint
)
1062 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatDataLabel" );
1063 if( !bHasDataLabelAtPoint
)
1064 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertDataLabel" );
1066 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteDataLabel" );
1067 if( bSelectedPointIsFormatted
)
1068 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:ResetDataPoint" );
1070 xPopupMenu
->insertSeparator( -1 );
1072 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatDataSeries" );
1075 Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram
, xSeries
) );
1076 if( xChartType
->getChartType() == CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK
)
1080 Reference
< beans::XPropertySet
> xChartTypeProp( xChartType
, uno::UNO_QUERY
);
1081 if( xChartTypeProp
.is() )
1083 bool bJapaneseStyle
= false;
1084 xChartTypeProp
->getPropertyValue( "Japanese" ) >>= bJapaneseStyle
;
1086 if( bJapaneseStyle
)
1088 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatStockLoss" );
1089 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatStockGain" );
1093 catch( const uno::Exception
& )
1095 DBG_UNHANDLED_EXCEPTION("chart2");
1099 if( bHasDataLabelsAtSeries
)
1100 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatDataLabels" );
1102 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatTrendlineEquation" );
1103 if( xMeanValue
.is() )
1104 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatMeanValue" );
1105 if( bHasXErrorBars
)
1106 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatXErrorBars" );
1107 if( bHasYErrorBars
)
1108 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatYErrorBars" );
1110 xPopupMenu
->insertSeparator( -1 );
1112 if( !bHasDataLabelsAtSeries
)
1113 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertDataLabels" );
1115 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertTrendline" );
1117 if( !xMeanValue
.is() )
1118 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertMeanValue" );
1119 if( !bHasXErrorBars
)
1120 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertXErrorBars" );
1121 if( !bHasYErrorBars
)
1122 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertYErrorBars" );
1123 if( bHasDataLabelsAtSeries
|| ( bHasDataLabelsAtPoints
&& bHasFormattedDataPointsOtherThanSelected
) )
1124 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteDataLabels" );
1126 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteTrendlineEquation" );
1127 if( xMeanValue
.is() )
1128 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteMeanValue" );
1129 if( bHasXErrorBars
)
1130 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteXErrorBars" );
1131 if( bHasYErrorBars
)
1132 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteYErrorBars" );
1134 if( bHasFormattedDataPointsOtherThanSelected
)
1135 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:ResetAllDataPoints" );
1137 xPopupMenu
->insertSeparator( -1 );
1139 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
, ".uno:ArrangeRow" );
1140 uno::Reference
< awt::XPopupMenu
> xArrangePopupMenu(
1141 m_xCC
->getServiceManager()->createInstanceWithContext(
1142 "com.sun.star.awt.PopupMenu", m_xCC
), uno::UNO_QUERY
);
1143 if( xArrangePopupMenu
.is() )
1145 sal_Int16 nSubId
= nUniqueId
+ 1;
1146 lcl_insertMenuCommand( xArrangePopupMenu
, nSubId
++, ".uno:Forward" );
1147 lcl_insertMenuCommand( xArrangePopupMenu
, nSubId
, ".uno:Backward" );
1148 xPopupMenu
->setPopupMenu( nUniqueId
, xArrangePopupMenu
);
1153 else if( eObjectType
== OBJECTTYPE_DATA_CURVE
)
1155 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteTrendline" );
1156 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatTrendlineEquation" );
1157 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertTrendlineEquation" );
1158 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertTrendlineEquationAndR2" );
1159 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertR2Value" );
1160 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteTrendlineEquation" );
1161 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteR2Value" );
1163 else if( eObjectType
== OBJECTTYPE_DATA_CURVE_EQUATION
)
1165 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertR2Value" );
1166 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteR2Value" );
1169 //some commands for axes: and grids
1171 else if( eObjectType
== OBJECTTYPE_AXIS
|| eObjectType
== OBJECTTYPE_GRID
|| eObjectType
== OBJECTTYPE_SUBGRID
)
1173 Reference
< XAxis
> xAxis
= ObjectIdentifier::getAxisForCID( m_aSelection
.getSelectedCID(), getModel() );
1174 if( xAxis
.is() && xDiagram
.is() )
1176 sal_Int32 nDimensionIndex
= -1;
1177 sal_Int32 nCooSysIndex
= -1;
1178 sal_Int32 nAxisIndex
= -1;
1179 AxisHelper::getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
);
1180 bool bIsSecondaryAxis
= nAxisIndex
!=0;
1181 bool bIsAxisVisible
= AxisHelper::isAxisVisible( xAxis
);
1182 bool bIsMajorGridVisible
= AxisHelper::isGridShown( nDimensionIndex
, nCooSysIndex
, true /*bMainGrid*/, xDiagram
);
1183 bool bIsMinorGridVisible
= AxisHelper::isGridShown( nDimensionIndex
, nCooSysIndex
, false /*bMainGrid*/, xDiagram
);
1184 bool bHasTitle
= false;
1185 uno::Reference
< XTitled
> xTitled( xAxis
, uno::UNO_QUERY
);
1187 bHasTitle
= !TitleHelper::getCompleteString( xTitled
->getTitleObject() ).isEmpty();
1189 if( eObjectType
!= OBJECTTYPE_AXIS
&& bIsAxisVisible
)
1190 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatAxis" );
1191 if( eObjectType
!= OBJECTTYPE_GRID
&& bIsMajorGridVisible
&& !bIsSecondaryAxis
)
1192 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatMajorGrid" );
1193 if( eObjectType
!= OBJECTTYPE_SUBGRID
&& bIsMinorGridVisible
&& !bIsSecondaryAxis
)
1194 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatMinorGrid" );
1196 xPopupMenu
->insertSeparator( -1 );
1198 if( eObjectType
!= OBJECTTYPE_AXIS
&& !bIsAxisVisible
)
1199 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertAxis" );
1200 if( eObjectType
!= OBJECTTYPE_GRID
&& !bIsMajorGridVisible
&& !bIsSecondaryAxis
)
1201 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertMajorGrid" );
1202 if( eObjectType
!= OBJECTTYPE_SUBGRID
&& !bIsMinorGridVisible
&& !bIsSecondaryAxis
)
1203 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertMinorGrid" );
1205 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertAxisTitle" );
1207 if( bIsAxisVisible
)
1208 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteAxis" );
1209 if( bIsMajorGridVisible
&& !bIsSecondaryAxis
)
1210 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteMajorGrid" );
1211 if( bIsMinorGridVisible
&& !bIsSecondaryAxis
)
1212 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteMinorGrid" );
1216 if( eObjectType
== OBJECTTYPE_DATA_STOCK_LOSS
)
1217 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatStockGain" );
1218 else if( eObjectType
== OBJECTTYPE_DATA_STOCK_GAIN
)
1219 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatStockLoss" );
1221 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:TransformDialog" );
1223 if( eObjectType
== OBJECTTYPE_PAGE
|| eObjectType
== OBJECTTYPE_DIAGRAM
1224 || eObjectType
== OBJECTTYPE_DIAGRAM_WALL
1225 || eObjectType
== OBJECTTYPE_DIAGRAM_FLOOR
1226 || eObjectType
== OBJECTTYPE_UNKNOWN
)
1228 if( eObjectType
!= OBJECTTYPE_UNKNOWN
)
1229 xPopupMenu
->insertSeparator( -1 );
1230 bool bHasLegend
= LegendHelper::hasLegend( xDiagram
);
1231 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertTitles" );
1233 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertLegend" );
1234 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertRemoveAxes" );
1236 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteLegend" );
1239 xPopupMenu
->insertSeparator( -1 );
1240 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DiagramType" );
1241 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DataRanges" );
1242 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DiagramData" );
1243 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:View3D" );
1247 css::uno::Sequence
< css::uno::Any
> aArgs( 3 );
1248 aArgs
[0] <<= comphelper::makePropertyValue( "IsContextMenu", true );
1249 aArgs
[1] <<= comphelper::makePropertyValue( "Frame", m_xFrame
);
1250 aArgs
[2] <<= comphelper::makePropertyValue( "Value", aMenuName
);
1252 css::uno::Reference
< css::frame::XPopupMenuController
> xPopupController(
1253 m_xCC
->getServiceManager()->createInstanceWithArgumentsAndContext(
1254 "com.sun.star.comp.framework.ResourceMenuController", aArgs
, m_xCC
), css::uno::UNO_QUERY
);
1256 if ( !xPopupController
.is() || !xPopupMenu
.is() )
1259 if (comphelper::LibreOfficeKit::isActive())
1261 PopupMenu
* pPopupMenu
= static_cast<PopupMenu
*>(VCLXMenu::GetImplementation(xPopupMenu
)->GetMenu());
1262 pPopupMenu
->SetLOKNotifier(SfxViewShell::Current());
1264 // the context menu expects a position related to the document window,
1265 // not to the chart window
1266 SfxInPlaceClient
* pIPClient
= SfxViewShell::Current()->GetIPClient();
1269 vcl::Window
* pRootWin
= pIPClient
->GetEditWin();
1272 Point aOffset
= pChartWindow
->GetOffsetPixelFrom(*pRootWin
);
1278 xPopupController
->setPopupMenu( xPopupMenu
);
1279 xPopupMenu
->execute( css::uno::Reference
< css::awt::XWindowPeer
>( m_xFrame
->getContainerWindow(), css::uno::UNO_QUERY
),
1280 css::awt::Rectangle( aPos
.X(), aPos
.Y(), 0, 0 ),
1281 css::awt::PopupMenuDirection::EXECUTE_DEFAULT
);
1283 css::uno::Reference
< css::lang::XComponent
> xComponent( xPopupController
, css::uno::UNO_QUERY
);
1284 if ( xComponent
.is() )
1285 xComponent
->dispose();
1287 else if( ( rCEvt
.GetCommand() == CommandEventId::StartExtTextInput
) ||
1288 ( rCEvt
.GetCommand() == CommandEventId::ExtTextInput
) ||
1289 ( rCEvt
.GetCommand() == CommandEventId::EndExtTextInput
) ||
1290 ( rCEvt
.GetCommand() == CommandEventId::InputContextChange
) )
1292 //#i84417# enable editing with IME
1293 if( m_pDrawViewWrapper
)
1294 m_pDrawViewWrapper
->Command( rCEvt
, pChartWindow
);
1298 bool ChartController::execute_KeyInput( const KeyEvent
& rKEvt
)
1300 SolarMutexGuard aGuard
;
1303 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
;
1304 auto pChartWindow(GetChartWindow());
1305 if(!pChartWindow
|| !pDrawViewWrapper
)
1308 // handle accelerators
1309 if( ! m_apAccelExecute
.get() && m_xFrame
.is() && m_xCC
.is() )
1311 m_apAccelExecute
= ::svt::AcceleratorExecute::createAcceleratorHelper();
1312 OSL_ASSERT( m_apAccelExecute
.get());
1313 if( m_apAccelExecute
.get() )
1314 m_apAccelExecute
->init( m_xCC
, m_xFrame
);
1317 vcl::KeyCode
aKeyCode( rKEvt
.GetKeyCode());
1318 sal_uInt16 nCode
= aKeyCode
.GetCode();
1319 bool bAlternate
= aKeyCode
.IsMod2();
1320 bool bCtrl
= aKeyCode
.IsMod1();
1322 if( m_apAccelExecute
.get() )
1323 bReturn
= m_apAccelExecute
->execute( aKeyCode
);
1328 if( pDrawViewWrapper
->IsTextEdit() )
1330 if( pDrawViewWrapper
->KeyInput(rKEvt
, pChartWindow
) )
1333 if( nCode
== KEY_ESCAPE
)
1341 // keyboard accessibility
1342 ObjectType eObjectType
= ObjectIdentifier::getObjectType( m_aSelection
.getSelectedCID() );
1345 // Navigation (Tab/F3/Home/End)
1346 uno::Reference
< XChartDocument
> xChartDoc( getModel(), uno::UNO_QUERY
);
1347 ObjectKeyNavigation
aObjNav( m_aSelection
.getSelectedOID(), xChartDoc
, ExplicitValueProvider::getExplicitValueProvider( m_xChartView
));
1348 awt::KeyEvent
aKeyEvent( ::svt::AcceleratorExecute::st_VCLKey2AWTKey( aKeyCode
));
1349 bReturn
= aObjNav
.handleKeyEvent( aKeyEvent
);
1352 ObjectIdentifier aNewOID
= aObjNav
.getCurrentSelection();
1353 uno::Any aNewSelection
;
1354 if ( aNewOID
.isValid() && !ObjectHierarchy::isRootNode( aNewOID
) )
1356 aNewSelection
= aNewOID
.getAny();
1358 if ( m_eDragMode
== SdrDragMode::Rotate
&& !SelectionHelper::isRotateableObject( aNewOID
.getObjectCID(), getModel() ) )
1360 m_eDragMode
= SdrDragMode::Move
;
1362 bReturn
= select( aNewSelection
);
1366 // Position and Size (+/-/arrow-keys) or pie segment dragging
1369 // pie segment dragging
1370 // note: could also be done for data series
1371 if( eObjectType
== OBJECTTYPE_DATA_POINT
&&
1372 ObjectIdentifier::getDragMethodServiceName( m_aSelection
.getSelectedCID() ) ==
1373 ObjectIdentifier::getPieSegmentDragMethodServiceName())
1376 bool bDragInside
= false;
1377 if( nCode
== KEY_ADD
||
1378 nCode
== KEY_SUBTRACT
)
1381 bDragInside
= ( nCode
== KEY_SUBTRACT
);
1384 nCode
== KEY_LEFT
||
1385 nCode
== KEY_RIGHT
||
1390 OUString
aParameter( ObjectIdentifier::getDragParameterString( m_aSelection
.getSelectedCID() ));
1391 sal_Int32
nOffsetPercentDummy( 0 );
1392 awt::Point
aMinimumPosition( 0, 0 );
1393 awt::Point
aMaximumPosition( 0, 0 );
1394 ObjectIdentifier::parsePieSegmentDragParameterString(
1395 aParameter
, nOffsetPercentDummy
, aMinimumPosition
, aMaximumPosition
);
1396 aMaximumPosition
.Y
-= aMinimumPosition
.Y
;
1397 aMaximumPosition
.X
-= aMinimumPosition
.X
;
1400 (nCode
== KEY_RIGHT
&& (aMaximumPosition
.X
< 0)) ||
1401 (nCode
== KEY_LEFT
&& (aMaximumPosition
.X
> 0)) ||
1402 (nCode
== KEY_DOWN
&& (aMaximumPosition
.Y
< 0)) ||
1403 (nCode
== KEY_UP
&& (aMaximumPosition
.Y
> 0));
1408 double fAmount
= bAlternate
? 0.01 : 0.05;
1412 bReturn
= impl_DragDataPoint( m_aSelection
.getSelectedCID(), fAmount
);
1418 if( nCode
== KEY_ADD
||
1419 nCode
== KEY_SUBTRACT
)
1421 if( eObjectType
== OBJECTTYPE_DIAGRAM
)
1423 // default 1 mm in each direction
1424 double fGrowAmountX
= 200.0;
1425 double fGrowAmountY
= 200.0;
1426 if( bAlternate
&& pChartWindow
)
1428 // together with Alt-key: 1 px in each direction
1431 Size aPixelSize
= pChartWindow
->PixelToLogic( Size( 2, 2 ));
1432 fGrowAmountX
= static_cast< double >( aPixelSize
.Width());
1433 fGrowAmountY
= static_cast< double >( aPixelSize
.Height());
1436 if( nCode
== KEY_SUBTRACT
)
1438 fGrowAmountX
= -fGrowAmountX
;
1439 fGrowAmountY
= -fGrowAmountY
;
1441 bReturn
= impl_moveOrResizeObject(
1442 m_aSelection
.getSelectedCID(), CENTERED_RESIZE_OBJECT
, fGrowAmountX
, fGrowAmountY
);
1446 else if( nCode
== KEY_LEFT
||
1447 nCode
== KEY_RIGHT
||
1451 if( m_aSelection
.isDragableObjectSelected() )
1454 double fShiftAmountX
= 100.0;
1455 double fShiftAmountY
= 100.0;
1456 if( bAlternate
&& pChartWindow
)
1458 // together with Alt-key: 1 px
1461 Size aPixelSize
= pChartWindow
->PixelToLogic( Size( 1, 1 ));
1462 fShiftAmountX
= static_cast< double >( aPixelSize
.Width());
1463 fShiftAmountY
= static_cast< double >( aPixelSize
.Height());
1469 fShiftAmountX
= -fShiftAmountX
;
1470 fShiftAmountY
= 0.0;
1473 fShiftAmountY
= 0.0;
1476 fShiftAmountX
= 0.0;
1477 fShiftAmountY
= -fShiftAmountY
;
1480 fShiftAmountX
= 0.0;
1483 if( !m_aSelection
.getSelectedCID().isEmpty() )
1485 //move chart objects
1486 bReturn
= impl_moveOrResizeObject(
1487 m_aSelection
.getSelectedCID(), MOVE_OBJECT
, fShiftAmountX
, fShiftAmountY
);
1491 //move additional shapes
1492 uno::Reference
< drawing::XShape
> xShape( m_aSelection
.getSelectedAdditionalShape() );
1495 awt::Point
aPos( xShape
->getPosition() );
1496 awt::Size
aSize( xShape
->getSize() );
1497 awt::Size
aPageSize( ChartModelHelper::getPageSize( getModel() ) );
1498 aPos
.X
= static_cast< long >( static_cast< double >( aPos
.X
) + fShiftAmountX
);
1499 aPos
.Y
= static_cast< long >( static_cast< double >( aPos
.Y
) + fShiftAmountY
);
1500 if( aPos
.X
+ aSize
.Width
> aPageSize
.Width
)
1501 aPos
.X
= aPageSize
.Width
- aSize
.Width
;
1504 if( aPos
.Y
+ aSize
.Height
> aPageSize
.Height
)
1505 aPos
.Y
= aPageSize
.Height
- aSize
.Height
;
1509 xShape
->setPosition( aPos
);
1517 // dumping the shape
1518 if( !bReturn
&& bCtrl
&& nCode
== KEY_F12
)
1520 uno::Reference
< qa::XDumper
> xChartModel( getModel(), uno::UNO_QUERY
);
1521 if(xChartModel
.is())
1523 OUString aDump
= xChartModel
->dump();
1524 SAL_WARN("chart2", aDump
);
1532 if( eObjectType
== OBJECTTYPE_TITLE
)
1534 executeDispatch_EditText();
1539 // deactivate inplace mode (this code should be unnecessary, but
1540 // unfortunately is not)
1542 nCode
== KEY_ESCAPE
)
1544 uno::Reference
< frame::XDispatchHelper
> xDispatchHelper( frame::DispatchHelper::create(m_xCC
) );
1545 uno::Sequence
< beans::PropertyValue
> aArgs
;
1546 xDispatchHelper
->executeDispatch(
1547 uno::Reference
< frame::XDispatchProvider
>( m_xFrame
, uno::UNO_QUERY
),
1548 ".uno:TerminateInplaceActivation",
1550 frame::FrameSearchFlag::PARENT
,
1556 (nCode
== KEY_DELETE
|| nCode
== KEY_BACKSPACE
))
1558 bReturn
= executeDispatch_Delete();
1561 std::unique_ptr
<weld::MessageDialog
> xInfoBox(Application::CreateMessageDialog(pChartWindow
? pChartWindow
->GetFrameWeld() : nullptr,
1562 VclMessageType::Info
, VclButtonsType::Ok
,
1563 SchResId(STR_ACTION_NOTPOSSIBLE
)));
1571 bool ChartController::requestQuickHelp(
1572 ::Point aAtLogicPosition
,
1573 bool bIsBalloonHelp
,
1574 OUString
& rOutQuickHelpText
,
1575 awt::Rectangle
& rOutEqualRect
)
1577 uno::Reference
< frame::XModel
> xChartModel
;
1579 xChartModel
.set( getModel() );
1580 if( !xChartModel
.is())
1585 if( m_pDrawViewWrapper
)
1587 aCID
= SelectionHelper::getHitObjectCID(
1588 aAtLogicPosition
, *m_pDrawViewWrapper
);
1590 bool bResult( !aCID
.isEmpty());
1595 rOutQuickHelpText
= ObjectNameProvider::getHelpText( aCID
, xChartModel
, bIsBalloonHelp
/* bVerbose */ );
1598 ExplicitValueProvider
* pValueProvider(
1599 ExplicitValueProvider::getExplicitValueProvider( m_xChartView
));
1600 if( pValueProvider
)
1601 rOutEqualRect
= pValueProvider
->getRectangleOfObject( aCID
, true );
1607 // XSelectionSupplier (optional interface)
1608 sal_Bool SAL_CALL
ChartController::select( const uno::Any
& rSelection
)
1610 bool bSuccess
= false;
1612 if ( rSelection
.hasValue() )
1614 const uno::Type
& rType
= rSelection
.getValueType();
1615 if ( rType
== cppu::UnoType
< OUString
>::get() )
1618 if ( ( rSelection
>>= aNewCID
) && m_aSelection
.setSelection( aNewCID
) )
1623 else if ( rType
== cppu::UnoType
<drawing::XShape
>::get() )
1625 uno::Reference
< drawing::XShape
> xShape
;
1626 if ( ( rSelection
>>= xShape
) && m_aSelection
.setSelection( xShape
) )
1634 if ( m_aSelection
.hasSelection() )
1636 m_aSelection
.clearSelection();
1643 SolarMutexGuard aGuard
;
1644 if ( m_pDrawViewWrapper
&& m_pDrawViewWrapper
->IsTextEdit() )
1648 impl_selectObjectAndNotiy();
1649 auto pChartWindow(GetChartWindow());
1652 pChartWindow
->Invalidate();
1660 uno::Any SAL_CALL
ChartController::getSelection()
1663 if ( m_aSelection
.hasSelection() )
1665 OUString
aCID( m_aSelection
.getSelectedCID() );
1666 if ( !aCID
.isEmpty() )
1672 // #i12587# support for shapes in chart
1673 aReturn
<<= m_aSelection
.getSelectedAdditionalShape();
1679 void SAL_CALL
ChartController::addSelectionChangeListener( const uno::Reference
<view::XSelectionChangeListener
> & xListener
)
1681 SolarMutexGuard aGuard
;
1682 if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode?
1683 return; //behave passive if already disposed or suspended
1686 m_aLifeTimeManager
.m_aListenerContainer
.addInterface( cppu::UnoType
<view::XSelectionChangeListener
>::get(), xListener
);
1689 void SAL_CALL
ChartController::removeSelectionChangeListener( const uno::Reference
<view::XSelectionChangeListener
> & xListener
)
1691 SolarMutexGuard aGuard
;
1692 if( impl_isDisposedOrSuspended() ) //@todo? allow removing of listeners in suspend mode?
1693 return; //behave passive if already disposed or suspended
1696 m_aLifeTimeManager
.m_aListenerContainer
.removeInterface( cppu::UnoType
<view::XSelectionChangeListener
>::get(), xListener
);
1699 void ChartController::impl_notifySelectionChangeListeners()
1701 ::cppu::OInterfaceContainerHelper
* pIC
= m_aLifeTimeManager
.m_aListenerContainer
1702 .getContainer( cppu::UnoType
<view::XSelectionChangeListener
>::get() );
1705 uno::Reference
< view::XSelectionSupplier
> xSelectionSupplier(this);
1706 lang::EventObject
aEvent( xSelectionSupplier
);
1707 ::cppu::OInterfaceIteratorHelper
aIt( *pIC
);
1708 while( aIt
.hasMoreElements() )
1710 uno::Reference
< view::XSelectionChangeListener
> xListener( aIt
.next(), uno::UNO_QUERY
);
1711 if( xListener
.is() )
1712 xListener
->selectionChanged( aEvent
);
1717 void ChartController::impl_selectObjectAndNotiy()
1720 SolarMutexGuard aGuard
;
1721 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
;
1722 if( pDrawViewWrapper
)
1724 pDrawViewWrapper
->SetDragMode( m_eDragMode
);
1725 m_aSelection
.applySelection( m_pDrawViewWrapper
);
1728 impl_notifySelectionChangeListeners();
1731 bool ChartController::impl_moveOrResizeObject(
1732 const OUString
& rCID
,
1733 eMoveOrResizeType eType
,
1734 double fAmountLogicX
,
1735 double fAmountLogicY
)
1737 bool bResult
= false;
1738 bool bNeedResize
= ( eType
== CENTERED_RESIZE_OBJECT
);
1740 uno::Reference
< frame::XModel
> xChartModel( getModel() );
1741 uno::Reference
< beans::XPropertySet
> xObjProp(
1742 ObjectIdentifier::getObjectPropertySet( rCID
, xChartModel
));
1745 awt::Size aRefSize
= ChartModelHelper::getPageSize( xChartModel
);
1747 chart2::RelativePosition aRelPos
;
1748 chart2::RelativeSize aRelSize
;
1749 bool bDeterminePos
= !(xObjProp
->getPropertyValue( "RelativePosition") >>= aRelPos
);
1750 bool bDetermineSize
= !bNeedResize
|| !(xObjProp
->getPropertyValue( "RelativeSize") >>= aRelSize
);
1752 if( ( bDeterminePos
|| bDetermineSize
) &&
1753 ( aRefSize
.Width
> 0 && aRefSize
.Height
> 0 ) )
1755 ExplicitValueProvider
* pValueProvider(
1756 ExplicitValueProvider::getExplicitValueProvider( m_xChartView
));
1757 if( pValueProvider
)
1759 awt::Rectangle
aRect( pValueProvider
->getRectangleOfObject( rCID
));
1760 double fWidth
= static_cast< double >( aRefSize
.Width
);
1761 double fHeight
= static_cast< double >( aRefSize
.Height
);
1762 if( bDetermineSize
)
1764 aRelSize
.Primary
= static_cast< double >( aRect
.Width
) / fWidth
;
1765 aRelSize
.Secondary
= static_cast< double >( aRect
.Height
) / fHeight
;
1769 if( bNeedResize
&& aRelSize
.Primary
> 0.0 && aRelSize
.Secondary
> 0.0 )
1771 aRelPos
.Primary
= (static_cast< double >( aRect
.X
) / fWidth
) +
1772 (aRelSize
.Primary
/ 2.0);
1773 aRelPos
.Secondary
= (static_cast< double >( aRect
.Y
) / fHeight
) +
1774 (aRelSize
.Secondary
/ 2.0);
1775 aRelPos
.Anchor
= drawing::Alignment_CENTER
;
1779 aRelPos
.Primary
= static_cast< double >( aRect
.X
) / fWidth
;
1780 aRelPos
.Secondary
= static_cast< double >( aRect
.Y
) / fHeight
;
1781 aRelPos
.Anchor
= drawing::Alignment_TOP_LEFT
;
1787 if( eType
== CENTERED_RESIZE_OBJECT
)
1788 bResult
= lcl_GrowAndShiftLogic( aRelPos
, aRelSize
, aRefSize
, fAmountLogicX
, fAmountLogicY
);
1789 else if( eType
== MOVE_OBJECT
)
1790 bResult
= lcl_MoveObjectLogic( aRelPos
, aRelSize
, aRefSize
, fAmountLogicX
, fAmountLogicY
);
1794 ActionDescriptionProvider::ActionType
eActionType(ActionDescriptionProvider::ActionType::Move
);
1796 eActionType
= ActionDescriptionProvider::ActionType::Resize
;
1798 ObjectType eObjectType
= ObjectIdentifier::getObjectType( rCID
);
1799 UndoGuard
aUndoGuard( ActionDescriptionProvider::createDescription(
1800 eActionType
, ObjectNameProvider::getName( eObjectType
)), m_xUndoManager
);
1802 ControllerLockGuardUNO
aCLGuard( xChartModel
);
1803 xObjProp
->setPropertyValue( "RelativePosition", uno::Any( aRelPos
));
1804 if( bNeedResize
|| (eObjectType
== OBJECTTYPE_DIAGRAM
) )//Also set an explicit size at the diagram when an explicit position is set
1805 xObjProp
->setPropertyValue( "RelativeSize", uno::Any( aRelSize
));
1807 aUndoGuard
.commit();
1813 bool ChartController::impl_DragDataPoint( const OUString
& rCID
, double fAdditionalOffset
)
1815 bool bResult
= false;
1816 if( fAdditionalOffset
< -1.0 || fAdditionalOffset
> 1.0 || fAdditionalOffset
== 0.0 )
1819 sal_Int32 nDataPointIndex
= ObjectIdentifier::getIndexFromParticleOrCID( rCID
);
1820 uno::Reference
< chart2::XDataSeries
> xSeries(
1821 ObjectIdentifier::getDataSeriesForCID( rCID
, getModel() ));
1826 uno::Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex( nDataPointIndex
));
1827 double fOffset
= 0.0;
1828 if( xPointProp
.is() &&
1829 (xPointProp
->getPropertyValue( "Offset" ) >>= fOffset
) &&
1830 (( fAdditionalOffset
> 0.0 && fOffset
< 1.0 ) || (fOffset
> 0.0)) )
1832 fOffset
+= fAdditionalOffset
;
1835 else if( fOffset
< 0.0 )
1837 xPointProp
->setPropertyValue( "Offset", uno::Any( fOffset
));
1841 catch( const uno::Exception
& )
1843 DBG_UNHANDLED_EXCEPTION("chart2");
1850 void ChartController::impl_SetMousePointer( const MouseEvent
& rEvent
)
1852 SolarMutexGuard aGuard
;
1853 auto pChartWindow(GetChartWindow());
1855 if (!m_pDrawViewWrapper
|| !pChartWindow
)
1858 Point
aMousePos( pChartWindow
->PixelToLogic( rEvent
.GetPosPixel()));
1859 sal_uInt16 nModifier
= rEvent
.GetModifier();
1860 bool bLeftDown
= rEvent
.IsLeft();
1862 // Check if object is for field button and set the normal arrow pointer in this case
1863 SdrObject
* pObject
= m_pDrawViewWrapper
->getHitObject(aMousePos
);
1864 if (pObject
&& pObject
->GetName().startsWith("FieldButton"))
1866 pChartWindow
->SetPointer(Pointer(PointerStyle::Arrow
));
1870 if ( m_pDrawViewWrapper
->IsTextEdit() )
1872 if( m_pDrawViewWrapper
->IsTextEditHit( aMousePos
) )
1874 pChartWindow
->SetPointer( m_pDrawViewWrapper
->GetPreferredPointer(
1875 aMousePos
, pChartWindow
, nModifier
, bLeftDown
) );
1879 else if( m_pDrawViewWrapper
->IsAction() )
1881 return;//don't change pointer during running action
1884 SdrHdl
* pHitSelectionHdl
= nullptr;
1885 if( m_aSelection
.isResizeableObjectSelected() )
1886 pHitSelectionHdl
= m_pDrawViewWrapper
->PickHandle( aMousePos
);
1888 if( pHitSelectionHdl
)
1890 Pointer aPointer
= m_pDrawViewWrapper
->GetPreferredPointer(
1891 aMousePos
, pChartWindow
, nModifier
, bLeftDown
);
1892 bool bForceArrowPointer
= false;
1894 ObjectIdentifier
aOID( m_aSelection
.getSelectedOID() );
1896 switch( aPointer
.GetStyle())
1898 case PointerStyle::NSize
:
1899 case PointerStyle::SSize
:
1900 case PointerStyle::WSize
:
1901 case PointerStyle::ESize
:
1902 case PointerStyle::NWSize
:
1903 case PointerStyle::NESize
:
1904 case PointerStyle::SWSize
:
1905 case PointerStyle::SESize
:
1906 if( ! m_aSelection
.isResizeableObjectSelected() )
1907 bForceArrowPointer
= true;
1909 case PointerStyle::Move
:
1910 if ( !aOID
.isDragableObject() )
1911 bForceArrowPointer
= true;
1913 case PointerStyle::MovePoint
:
1914 case PointerStyle::MoveBezierWeight
:
1915 // there is no point-editing in a chart
1916 // the PointerStyle::MoveBezierWeight appears in 3d data points
1917 bForceArrowPointer
= true;
1923 if( bForceArrowPointer
)
1924 pChartWindow
->SetPointer( Pointer( PointerStyle::Arrow
));
1926 pChartWindow
->SetPointer( aPointer
);
1931 // #i12587# support for shapes in chart
1932 if ( m_eDrawMode
== CHARTDRAW_INSERT
&&
1933 ( !m_pDrawViewWrapper
->IsMarkedHit( aMousePos
) || !m_aSelection
.isDragableObjectSelected() ) )
1935 PointerStyle ePointerStyle
= PointerStyle::DrawRect
;
1936 SdrObjKind eKind
= static_cast< SdrObjKind
>( m_pDrawViewWrapper
->GetCurrentObjIdentifier() );
1941 ePointerStyle
= PointerStyle::DrawLine
;
1945 case OBJ_CUSTOMSHAPE
:
1947 ePointerStyle
= PointerStyle::DrawRect
;
1952 ePointerStyle
= PointerStyle::DrawEllipse
;
1957 ePointerStyle
= PointerStyle::DrawPolygon
;
1962 ePointerStyle
= PointerStyle::DrawText
;
1967 ePointerStyle
= PointerStyle::DrawCaption
;
1972 ePointerStyle
= PointerStyle::DrawRect
;
1976 pChartWindow
->SetPointer( Pointer( ePointerStyle
) );
1980 OUString
aHitObjectCID(
1981 SelectionHelper::getHitObjectCID(
1982 aMousePos
, *m_pDrawViewWrapper
, true /*bGetDiagramInsteadOf_Wall*/ ));
1984 if( m_pDrawViewWrapper
->IsTextEdit() )
1986 if( aHitObjectCID
== m_aSelection
.getSelectedCID() )
1988 pChartWindow
->SetPointer( Pointer( PointerStyle::Arrow
));
1993 if( aHitObjectCID
.isEmpty() )
1995 //additional shape was hit
1996 pChartWindow
->SetPointer( PointerStyle::Move
);
1998 else if( ObjectIdentifier::isDragableObject( aHitObjectCID
) )
2000 if( (m_eDragMode
== SdrDragMode::Rotate
)
2001 && SelectionHelper::isRotateableObject( aHitObjectCID
2003 pChartWindow
->SetPointer( Pointer( PointerStyle::Rotate
) );
2006 ObjectType eHitObjectType
= ObjectIdentifier::getObjectType( aHitObjectCID
);
2007 if( eHitObjectType
== OBJECTTYPE_DATA_POINT
)
2009 if( !ObjectIdentifier::areSiblings(aHitObjectCID
,m_aSelection
.getSelectedCID())
2010 && !ObjectIdentifier::areIdenticalObjects(aHitObjectCID
,m_aSelection
.getSelectedCID()) )
2012 pChartWindow
->SetPointer( Pointer( PointerStyle::Arrow
));
2016 pChartWindow
->SetPointer( PointerStyle::Move
);
2020 pChartWindow
->SetPointer( Pointer( PointerStyle::Arrow
));
2023 css::uno::Reference
<css::uno::XInterface
> const & ChartController::getChartView()
2025 return m_xChartView
;
2028 void ChartController::sendPopupRequest(OUString
const & rCID
, tools::Rectangle aRectangle
)
2030 ChartModel
* pChartModel
= dynamic_cast<ChartModel
*>(m_aModel
->getModel().get());
2034 uno::Reference
<chart2::data::XPivotTableDataProvider
> xPivotTableDataProvider
;
2035 xPivotTableDataProvider
.set(pChartModel
->getDataProvider(), uno::UNO_QUERY
);
2036 if (!xPivotTableDataProvider
.is())
2039 OUString sPivotTableName
= xPivotTableDataProvider
->getPivotTableName();
2041 PopupRequest
* pPopupRequest
= dynamic_cast<PopupRequest
*>(pChartModel
->getPopupRequest().get());
2045 // Get dimension index from CID
2046 sal_Int32 nStartPos
= rCID
.lastIndexOf('.');
2048 sal_Int32 nEndPos
= rCID
.getLength();
2049 OUString sDimensionIndex
= rCID
.copy(nStartPos
, nEndPos
- nStartPos
);
2050 sal_Int32 nDimensionIndex
= sDimensionIndex
.toInt32();
2052 awt::Rectangle xRectangle
{
2053 sal_Int32(aRectangle
.Left()),
2054 sal_Int32(aRectangle
.Top()),
2055 sal_Int32(aRectangle
.GetWidth()),
2056 sal_Int32(aRectangle
.GetHeight())
2059 uno::Sequence
<beans::PropertyValue
> aCallbackData
= comphelper::InitPropertySequence(
2061 {"Rectangle", uno::makeAny
<awt::Rectangle
>(xRectangle
)},
2062 {"DimensionIndex", uno::makeAny
<sal_Int32
>(nDimensionIndex
)},
2063 {"PivotTableName", uno::makeAny
<OUString
>(sPivotTableName
)},
2066 pPopupRequest
->getCallback()->notify(uno::makeAny(aCallbackData
));
2071 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */