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 <ChartModel.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 <AxisHelper.hxx>
43 #include <LegendHelper.hxx>
44 #include <servicenames_charttypes.hxx>
45 #include "DrawCommandDispatch.hxx"
46 #include <PopupRequest.hxx>
48 #include <com/sun/star/chart2/RelativePosition.hpp>
49 #include <com/sun/star/chart2/RelativeSize.hpp>
50 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
51 #include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
52 #include <com/sun/star/chart2/XChartDocument.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>
60 #include <com/sun/star/qa/XDumper.hpp>
62 #include <comphelper/lok.hxx>
63 #include <comphelper/propertysequence.hxx>
64 #include <comphelper/propertyvalue.hxx>
65 #include <comphelper/sequence.hxx>
67 #include <toolkit/awt/vclxmenu.hxx>
69 #include <sfx2/viewsh.hxx>
70 #include <sfx2/ipclient.hxx>
71 #include <svx/ActionDescriptionProvider.hxx>
72 #include <svx/obj3d.hxx>
73 #include <svx/scene3d.hxx>
74 #include <svx/svddrgmt.hxx>
75 #include <vcl/commandevent.hxx>
76 #include <vcl/event.hxx>
77 #include <vcl/svapp.hxx>
78 #include <vcl/settings.hxx>
79 #include <vcl/weld.hxx>
80 #include <vcl/ptrstyle.hxx>
81 #include <svtools/acceleratorexecute.hxx>
82 #include <tools/diagnose_ex.h>
83 #include <sal/log.hxx>
85 #include <sfx2/lokhelper.hxx>
87 #define DRGPIX 2 // Drag MinMove in Pixel
89 using namespace ::com::sun::star
;
90 using namespace ::com::sun::star::chart2
;
91 using ::com::sun::star::uno::Reference
;
98 bool lcl_GrowAndShiftLogic(
99 RelativePosition
& rInOutRelPos
,
100 RelativeSize
& rInOutRelSize
,
101 const awt::Size
& rRefSize
,
105 if( rRefSize
.Width
== 0 ||
106 rRefSize
.Height
== 0 )
109 double fRelativeGrowX
= fGrowLogicX
/ rRefSize
.Width
;
110 double fRelativeGrowY
= fGrowLogicY
/ rRefSize
.Height
;
112 return ::chart::RelativePositionHelper::centerGrow(
113 rInOutRelPos
, rInOutRelSize
,
114 fRelativeGrowX
, fRelativeGrowY
);
117 bool lcl_MoveObjectLogic(
118 RelativePosition
& rInOutRelPos
,
119 RelativeSize
const & rObjectSize
,
120 const awt::Size
& rRefSize
,
122 double fShiftLogicY
)
124 if( rRefSize
.Width
== 0 ||
125 rRefSize
.Height
== 0 )
128 double fRelativeShiftX
= fShiftLogicX
/ rRefSize
.Width
;
129 double fRelativeShiftY
= fShiftLogicY
/ rRefSize
.Height
;
131 return ::chart::RelativePositionHelper::moveObject(
132 rInOutRelPos
, rObjectSize
,
133 fRelativeShiftX
, fRelativeShiftY
);
136 void lcl_insertMenuCommand(
137 const uno::Reference
< awt::XPopupMenu
> & xMenu
,
138 sal_Int16 nId
, const OUString
& rCommand
)
140 xMenu
->insertItem( nId
, "", 0, -1 );
141 xMenu
->setCommand( nId
, rCommand
);
144 OUString
lcl_getFormatCommandForObjectCID( const OUString
& rCID
)
146 OUString
aDispatchCommand( ".uno:FormatSelection" );
148 ObjectType eObjectType
= ObjectIdentifier::getObjectType( rCID
);
152 case OBJECTTYPE_DIAGRAM
:
153 case OBJECTTYPE_DIAGRAM_WALL
:
154 aDispatchCommand
= ".uno:FormatWall";
156 case OBJECTTYPE_DIAGRAM_FLOOR
:
157 aDispatchCommand
= ".uno:FormatFloor";
159 case OBJECTTYPE_PAGE
:
160 aDispatchCommand
= ".uno:FormatChartArea";
162 case OBJECTTYPE_LEGEND
:
163 aDispatchCommand
= ".uno:FormatLegend";
165 case OBJECTTYPE_TITLE
:
166 aDispatchCommand
= ".uno:FormatTitle";
168 case OBJECTTYPE_LEGEND_ENTRY
:
169 aDispatchCommand
= ".uno:FormatDataSeries";
171 case OBJECTTYPE_AXIS
:
172 case OBJECTTYPE_AXIS_UNITLABEL
:
173 aDispatchCommand
= ".uno:FormatAxis";
175 case OBJECTTYPE_GRID
:
176 aDispatchCommand
= ".uno:FormatMajorGrid";
178 case OBJECTTYPE_SUBGRID
:
179 aDispatchCommand
= ".uno:FormatMinorGrid";
181 case OBJECTTYPE_DATA_LABELS
:
182 aDispatchCommand
= ".uno:FormatDataLabels";
184 case OBJECTTYPE_DATA_SERIES
:
185 aDispatchCommand
= ".uno:FormatDataSeries";
187 case OBJECTTYPE_DATA_LABEL
:
188 aDispatchCommand
= ".uno:FormatDataLabel";
190 case OBJECTTYPE_DATA_POINT
:
191 aDispatchCommand
= ".uno:FormatDataPoint";
193 case OBJECTTYPE_DATA_AVERAGE_LINE
:
194 aDispatchCommand
= ".uno:FormatMeanValue";
196 case OBJECTTYPE_DATA_ERRORS_X
:
197 aDispatchCommand
= ".uno:FormatXErrorBars";
199 case OBJECTTYPE_DATA_ERRORS_Y
:
200 aDispatchCommand
= ".uno:FormatYErrorBars";
202 case OBJECTTYPE_DATA_ERRORS_Z
:
203 aDispatchCommand
= ".uno:FormatZErrorBars";
205 case OBJECTTYPE_DATA_CURVE
:
206 aDispatchCommand
= ".uno:FormatTrendline";
208 case OBJECTTYPE_DATA_CURVE_EQUATION
:
209 aDispatchCommand
= ".uno:FormatTrendlineEquation";
211 case OBJECTTYPE_DATA_STOCK_RANGE
:
212 aDispatchCommand
= ".uno:FormatSelection";
214 case OBJECTTYPE_DATA_STOCK_LOSS
:
215 aDispatchCommand
= ".uno:FormatStockLoss";
217 case OBJECTTYPE_DATA_STOCK_GAIN
:
218 aDispatchCommand
= ".uno:FormatStockGain";
220 default: //OBJECTTYPE_UNKNOWN
223 return aDispatchCommand
;
226 } // anonymous namespace
229 void SAL_CALL
ChartController::setPosSize(
236 SolarMutexGuard aGuard
;
237 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
238 auto pChartWindow(GetChartWindow());
240 if(xWindow
.is() && pChartWindow
)
242 Size aLogicSize
= pChartWindow
->PixelToLogic( Size( Width
, Height
), MapMode( MapUnit::Map100thMM
) );
244 //todo: for standalone chart: detect whether we are standalone
245 //change map mode to fit new size
246 awt::Size aModelPageSize
= ChartModelHelper::getPageSize( getModel() );
247 sal_Int32 nScaleXNumerator
= aLogicSize
.Width();
248 sal_Int32 nScaleXDenominator
= aModelPageSize
.Width
;
249 sal_Int32 nScaleYNumerator
= aLogicSize
.Height();
250 sal_Int32 nScaleYDenominator
= aModelPageSize
.Height
;
254 Fraction(nScaleXNumerator
, nScaleXDenominator
),
255 Fraction(nScaleYNumerator
, nScaleYDenominator
) );
256 pChartWindow
->SetMapMode(aNewMapMode
);
257 pChartWindow
->setPosSizePixel( X
, Y
, Width
, Height
, static_cast<PosSizeFlags
>(Flags
) );
259 //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
260 uno::Reference
< beans::XPropertySet
> xProp( m_xChartView
, uno::UNO_QUERY
);
263 auto aZoomFactors(::comphelper::InitPropertySequence({
264 { "ScaleXNumerator", uno::Any( nScaleXNumerator
) },
265 { "ScaleXDenominator", uno::Any( nScaleXDenominator
) },
266 { "ScaleYNumerator", uno::Any( nScaleYNumerator
) },
267 { "ScaleYDenominator", uno::Any( nScaleYDenominator
) }
269 xProp
->setPropertyValue( "ZoomFactors", uno::Any( aZoomFactors
));
272 //a correct work area is at least necessary for correct values in the position and size dialog and for dragging area
273 if(m_pDrawViewWrapper
)
275 tools::Rectangle
aRect(Point(0,0), pChartWindow
->GetOutputSize());
276 m_pDrawViewWrapper
->SetWorkArea( aRect
);
278 pChartWindow
->Invalidate();
282 awt::Rectangle SAL_CALL
ChartController::getPosSize()
285 awt::Rectangle
aRet(0, 0, 0, 0);
287 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
289 aRet
= xWindow
->getPosSize();
294 void SAL_CALL
ChartController::setVisible( sal_Bool Visible
)
297 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
300 xWindow
->setVisible( Visible
);
303 void SAL_CALL
ChartController::setEnable( sal_Bool Enable
)
306 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
309 xWindow
->setEnable( Enable
);
312 void SAL_CALL
ChartController::setFocus()
315 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
321 void SAL_CALL
ChartController::addWindowListener(
322 const uno::Reference
< awt::XWindowListener
>& xListener
)
325 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
328 xWindow
->addWindowListener( xListener
);
331 void SAL_CALL
ChartController::removeWindowListener(
332 const uno::Reference
< awt::XWindowListener
>& xListener
)
335 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
338 xWindow
->removeWindowListener( xListener
);
341 void SAL_CALL
ChartController::addFocusListener(
342 const uno::Reference
< awt::XFocusListener
>& xListener
)
345 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
348 xWindow
->addFocusListener( xListener
);
351 void SAL_CALL
ChartController::removeFocusListener(
352 const uno::Reference
< awt::XFocusListener
>& xListener
)
355 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
358 xWindow
->removeFocusListener( xListener
);
361 void SAL_CALL
ChartController::addKeyListener(
362 const uno::Reference
< awt::XKeyListener
>& xListener
)
365 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
368 xWindow
->addKeyListener( xListener
);
371 void SAL_CALL
ChartController::removeKeyListener(
372 const uno::Reference
< awt::XKeyListener
>& xListener
)
375 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
378 xWindow
->removeKeyListener( xListener
);
381 void SAL_CALL
ChartController::addMouseListener(
382 const uno::Reference
< awt::XMouseListener
>& xListener
)
385 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
388 xWindow
->addMouseListener( xListener
);
391 void SAL_CALL
ChartController::removeMouseListener(
392 const uno::Reference
< awt::XMouseListener
>& xListener
)
395 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
398 xWindow
->removeMouseListener( xListener
);
401 void SAL_CALL
ChartController::addMouseMotionListener(
402 const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
405 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
408 xWindow
->addMouseMotionListener( xListener
);
411 void SAL_CALL
ChartController::removeMouseMotionListener(
412 const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
415 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
418 xWindow
->removeMouseMotionListener( xListener
);
421 void SAL_CALL
ChartController::addPaintListener(
422 const uno::Reference
< awt::XPaintListener
>& xListener
)
425 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
428 xWindow
->addPaintListener( xListener
);
431 void SAL_CALL
ChartController::removePaintListener(
432 const uno::Reference
< awt::XPaintListener
>& xListener
)
435 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
438 xWindow
->removePaintListener( xListener
);
441 // impl vcl window controller methods
442 void ChartController::PrePaint()
444 // forward VCLs PrePaint window event to DrawingLayer
445 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
447 if (pDrawViewWrapper
)
449 pDrawViewWrapper
->PrePaint();
453 void ChartController::execute_Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
457 uno::Reference
<frame::XModel
> xModel(getModel());
458 //OSL_ENSURE( xModel.is(), "ChartController::execute_Paint: have no model to paint");
462 //better performance for big data
463 uno::Reference
<beans::XPropertySet
> xProp(m_xChartView
, uno::UNO_QUERY
);
466 awt::Size
aResolution(1000, 1000);
468 SolarMutexGuard aGuard
;
469 auto pChartWindow(GetChartWindow());
472 aResolution
.Width
= pChartWindow
->GetSizePixel().Width();
473 aResolution
.Height
= pChartWindow
->GetSizePixel().Height();
476 xProp
->setPropertyValue( "Resolution", uno::Any( aResolution
));
479 uno::Reference
< util::XUpdatable
> xUpdatable( m_xChartView
, uno::UNO_QUERY
);
481 xUpdatable
->update();
484 SolarMutexGuard aGuard
;
485 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
486 if (pDrawViewWrapper
)
487 pDrawViewWrapper
->CompleteRedraw(&rRenderContext
, vcl::Region(rRect
));
490 catch( const uno::Exception
& )
492 DBG_UNHANDLED_EXCEPTION("chart2");
499 static bool isDoubleClick( const MouseEvent
& rMEvt
)
501 return rMEvt
.GetClicks() == 2 && rMEvt
.IsLeft() &&
502 !rMEvt
.IsMod1() && !rMEvt
.IsMod2() && !rMEvt
.IsShift();
505 void ChartController::startDoubleClickWaiting()
507 SolarMutexGuard aGuard
;
509 m_bWaitingForDoubleClick
= true;
511 sal_uInt64 nDblClkTime
= 500;
512 auto pChartWindow(GetChartWindow());
515 const MouseSettings
& rMSettings
= pChartWindow
->GetSettings().GetMouseSettings();
516 nDblClkTime
= rMSettings
.GetDoubleClickTime();
518 m_aDoubleClickTimer
.SetTimeout( nDblClkTime
);
519 m_aDoubleClickTimer
.Start();
522 void ChartController::stopDoubleClickWaiting()
524 m_aDoubleClickTimer
.Stop();
525 m_bWaitingForDoubleClick
= false;
528 IMPL_LINK_NOARG(ChartController
, DoubleClickWaitingHdl
, Timer
*, void)
530 m_bWaitingForDoubleClick
= false;
532 if( !m_bWaitingForMouseUp
&& m_aSelection
.maybeSwitchSelectionAfterSingleClickWasEnsured() )
534 impl_selectObjectAndNotiy();
535 SolarMutexGuard aGuard
;
536 auto pChartWindow(GetChartWindow());
539 vcl::Window::PointerState
aPointerState( pChartWindow
->GetPointerState() );
540 MouseEvent
aMouseEvent(
543 MouseEventModifiers::NONE
,
544 static_cast< sal_uInt16
>( aPointerState
.mnState
)/*nButtons*/,
546 impl_SetMousePointer( aMouseEvent
);
551 void ChartController::execute_MouseButtonDown( const MouseEvent
& rMEvt
)
553 SolarMutexGuard aGuard
;
555 m_bWaitingForMouseUp
= true;
556 m_bFieldButtonDown
= false;
558 if( isDoubleClick(rMEvt
) )
559 stopDoubleClickWaiting();
561 startDoubleClickWaiting();
563 m_aSelection
.remindSelectionBeforeMouseDown();
565 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
566 auto pChartWindow(GetChartWindow());
567 if(!pChartWindow
|| !pDrawViewWrapper
)
570 Point aMPos
= pChartWindow
->PixelToLogic(rMEvt
.GetPosPixel());
572 // Check if button was clicked
573 SdrObject
* pObject
= pDrawViewWrapper
->getHitObject(aMPos
);
576 OUString aCID
= pObject
->GetName();
577 if (aCID
.startsWith("FieldButton"))
579 m_bFieldButtonDown
= true;
580 return; // Don't take any action if button was clicked
584 if ( rMEvt
.GetButtons() == MOUSE_LEFT
)
586 pChartWindow
->GrabFocus();
587 pChartWindow
->CaptureMouse();
590 if( pDrawViewWrapper
->IsTextEdit() )
593 if ( pDrawViewWrapper
->IsTextEditHit( aMPos
) ||
594 // #i12587# support for shapes in chart
595 ( rMEvt
.IsRight() && pDrawViewWrapper
->PickAnything( rMEvt
, SdrMouseEventKind::BUTTONDOWN
, aVEvt
) == SdrHitKind::MarkedObject
) )
597 pDrawViewWrapper
->MouseButtonDown(rMEvt
, pChartWindow
);
606 //abort running action
607 if( pDrawViewWrapper
->IsAction() )
609 if( rMEvt
.IsRight() )
610 pDrawViewWrapper
->BckAction();
614 if( isDoubleClick(rMEvt
) ) //do not change selection if double click
615 return;//double click is handled further in mousebutton up
617 SdrHdl
* pHitSelectionHdl
= nullptr;
618 //switch from move to resize if handle is hit on a resizable object
619 if( m_aSelection
.isResizeableObjectSelected() )
620 pHitSelectionHdl
= pDrawViewWrapper
->PickHandle( aMPos
);
621 //only change selection if no selection handles are hit
622 if( !pHitSelectionHdl
)
624 // #i12587# support for shapes in chart
625 if ( m_eDrawMode
== CHARTDRAW_INSERT
&&
626 ( !pDrawViewWrapper
->IsMarkedHit( aMPos
) || !m_aSelection
.isDragableObjectSelected() ) )
628 if ( m_aSelection
.hasSelection() )
630 m_aSelection
.clearSelection();
632 if ( !pDrawViewWrapper
->IsAction() )
634 if ( pDrawViewWrapper
->GetCurrentObjIdentifier() == OBJ_CAPTION
)
636 Size
aCaptionSize( 2268, 1134 );
637 pDrawViewWrapper
->BegCreateCaptionObj( aMPos
, aCaptionSize
);
641 pDrawViewWrapper
->BegCreateObj( aMPos
);
643 SdrObject
* pObj
= pDrawViewWrapper
->GetCreateObj();
644 DrawCommandDispatch
* pDrawCommandDispatch
= m_aDispatchContainer
.getDrawCommandDispatch();
645 if ( pObj
&& m_pDrawModelWrapper
&& pDrawCommandDispatch
)
647 SfxItemSet
aSet( m_pDrawModelWrapper
->GetItemPool() );
648 pDrawCommandDispatch
->setAttributes( pObj
);
649 pDrawCommandDispatch
->setLineEnds( aSet
);
650 pObj
->SetMergedItemSet( aSet
);
653 impl_SetMousePointer( rMEvt
);
657 m_aSelection
.adaptSelectionToNewPos(
661 m_bWaitingForDoubleClick
);
663 if( !m_aSelection
.isRotateableObjectSelected( getModel() ) )
665 m_eDragMode
= SdrDragMode::Move
;
666 pDrawViewWrapper
->SetDragMode(m_eDragMode
);
669 m_aSelection
.applySelection(pDrawViewWrapper
);
671 if( m_aSelection
.isDragableObjectSelected()
672 && !rMEvt
.IsRight() )
675 sal_uInt16 nDrgLog
= static_cast<sal_uInt16
>(pChartWindow
->PixelToLogic(Size(DRGPIX
,0)).Width());
676 SdrDragMethod
* pDragMethod
= nullptr;
678 //change selection to 3D scene if rotate mode
679 SdrDragMode eDragMode
= pDrawViewWrapper
->GetDragMode();
680 if( eDragMode
==SdrDragMode::Rotate
)
682 E3dScene
* pScene
= SelectionHelper::getSceneToRotate( pDrawViewWrapper
->getNamedSdrObject( m_aSelection
.getSelectedCID() ) );
685 DragMethod_RotateDiagram::RotationDirection
eRotationDirection(DragMethod_RotateDiagram::ROTATIONDIRECTION_FREE
);
688 SdrHdlKind eKind
= pHitSelectionHdl
->GetKind();
689 if( eKind
==SdrHdlKind::Upper
|| eKind
==SdrHdlKind::Lower
)
690 eRotationDirection
= DragMethod_RotateDiagram::ROTATIONDIRECTION_X
;
691 else if( eKind
==SdrHdlKind::Left
|| eKind
==SdrHdlKind::Right
)
692 eRotationDirection
= DragMethod_RotateDiagram::ROTATIONDIRECTION_Y
;
693 else if( eKind
==SdrHdlKind::UpperLeft
|| eKind
==SdrHdlKind::UpperRight
|| eKind
==SdrHdlKind::LowerLeft
|| eKind
==SdrHdlKind::LowerRight
)
694 eRotationDirection
= DragMethod_RotateDiagram::ROTATIONDIRECTION_Z
;
696 pDragMethod
= new DragMethod_RotateDiagram( *pDrawViewWrapper
, m_aSelection
.getSelectedCID(), getModel(), eRotationDirection
);
701 OUString
aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( m_aSelection
.getSelectedCID() ) );
702 if( aDragMethodServiceName
== ObjectIdentifier::getPieSegmentDragMethodServiceName() )
703 pDragMethod
= new DragMethod_PieSegment( *pDrawViewWrapper
, m_aSelection
.getSelectedCID(), getModel() );
705 pDrawViewWrapper
->SdrView::BegDragObj(aMPos
, nullptr, pHitSelectionHdl
, nDrgLog
, pDragMethod
);
708 impl_SetMousePointer( rMEvt
);
711 void ChartController::execute_MouseMove( const MouseEvent
& rMEvt
)
713 SolarMutexGuard aGuard
;
715 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
716 auto pChartWindow(GetChartWindow());
717 if(!pChartWindow
|| !pDrawViewWrapper
)
720 if( m_pDrawViewWrapper
->IsTextEdit() )
722 if( m_pDrawViewWrapper
->MouseMove(rMEvt
,pChartWindow
) )
726 if(pDrawViewWrapper
->IsAction())
728 pDrawViewWrapper
->MovAction( pChartWindow
->PixelToLogic( rMEvt
.GetPosPixel() ) );
731 impl_SetMousePointer( rMEvt
);
734 void ChartController::execute_MouseButtonUp( const MouseEvent
& rMEvt
)
736 ControllerLockGuardUNO
aCLGuard( getModel() );
737 bool bMouseUpWithoutMouseDown
= !m_bWaitingForMouseUp
;
738 m_bWaitingForMouseUp
= false;
739 bool bNotifySelectionChange
= false;
741 SolarMutexGuard aGuard
;
743 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
744 auto pChartWindow(GetChartWindow());
745 if(!pChartWindow
|| !pDrawViewWrapper
)
748 Point aMPos
= pChartWindow
->PixelToLogic(rMEvt
.GetPosPixel());
750 // Check if button was clicked
751 if (m_bFieldButtonDown
)
753 m_bFieldButtonDown
= false;
754 SdrObject
* pObject
= pDrawViewWrapper
->getHitObject(aMPos
);
757 OUString aCID
= pObject
->GetName();
758 if (aCID
.startsWith("FieldButton"))
760 sendPopupRequest(aCID
, pObject
->GetCurrentBoundRect());
766 if(pDrawViewWrapper
->IsTextEdit())
768 if( pDrawViewWrapper
->MouseButtonUp(rMEvt
,pChartWindow
) )
772 // #i12587# support for shapes in chart
773 if ( m_eDrawMode
== CHARTDRAW_INSERT
&& pDrawViewWrapper
->IsCreateObj() )
775 pDrawViewWrapper
->EndCreateObj( SdrCreateCmd::ForceEnd
);
777 HiddenUndoContext
aUndoContext( m_xUndoManager
);
778 // don't want the positioning Undo action to appear in the UI
779 impl_switchDiagramPositioningToExcludingPositioning();
781 if ( pDrawViewWrapper
->AreObjectsMarked() )
783 if ( pDrawViewWrapper
->GetCurrentObjIdentifier() == OBJ_TEXT
)
785 executeDispatch_EditText();
789 SdrObject
* pObj
= pDrawViewWrapper
->getSelectedObject();
792 uno::Reference
< drawing::XShape
> xShape( pObj
->getUnoShape(), uno::UNO_QUERY
);
795 m_aSelection
.setSelection( xShape
);
796 m_aSelection
.applySelection( pDrawViewWrapper
);
803 m_aSelection
.adaptSelectionToNewPos( aMPos
, pDrawViewWrapper
, rMEvt
.IsRight(), m_bWaitingForDoubleClick
);
804 m_aSelection
.applySelection( pDrawViewWrapper
);
805 setDrawMode( CHARTDRAW_SELECT
);
808 else if ( pDrawViewWrapper
->IsDragObj() )
810 bool bDraggingDone
= false;
811 SdrDragMethod
* pDragMethod
= pDrawViewWrapper
->SdrView::GetDragMethod();
812 bool bIsMoveOnly
= pDragMethod
&& pDragMethod
->getMoveOnly();
813 DragMethod_Base
* pChartDragMethod
= dynamic_cast< DragMethod_Base
* >(pDragMethod
);
814 if( pChartDragMethod
)
816 UndoGuard
aUndoGuard( pChartDragMethod
->getUndoDescription(),
819 if( pDrawViewWrapper
->EndDragObj() )
821 bDraggingDone
= true;
826 if( !bDraggingDone
&& pDrawViewWrapper
->EndDragObj() )
831 SdrObject
* pObj
= pDrawViewWrapper
->getSelectedObject();
834 tools::Rectangle aObjectRect
= pObj
->GetSnapRect();
835 awt::Size
aPageSize( ChartModelHelper::getPageSize( getModel() ) );
836 tools::Rectangle
aPageRect( 0,0,aPageSize
.Width
,aPageSize
.Height
);
838 const E3dObject
* pE3dObject(dynamic_cast< const E3dObject
*>(pObj
));
839 if(nullptr != pE3dObject
)
841 E3dScene
* pScene(pE3dObject
->getRootE3dSceneFromE3dObject());
842 if(nullptr != pScene
)
844 aObjectRect
= pScene
->GetSnapRect();
848 ActionDescriptionProvider::ActionType
eActionType(ActionDescriptionProvider::ActionType::Move
);
849 if( !bIsMoveOnly
&& m_aSelection
.isResizeableObjectSelected() )
850 eActionType
= ActionDescriptionProvider::ActionType::Resize
;
852 ObjectType eObjectType
= ObjectIdentifier::getObjectType( m_aSelection
.getSelectedCID() );
854 UndoGuard
aUndoGuard(
855 ActionDescriptionProvider::createDescription( eActionType
, ObjectNameProvider::getName( eObjectType
)),
858 bool bChanged
= false;
859 ChartModel
* pModel
= dynamic_cast<ChartModel
*>(getModel().get());
861 if ( eObjectType
== OBJECTTYPE_LEGEND
)
862 bChanged
= DiagramHelper::switchDiagramPositioningToExcludingPositioning( *pModel
, false , true );
864 bool bMoved
= PositionAndSizeHelper::moveObject( m_aSelection
.getSelectedCID()
866 , awt::Rectangle(aObjectRect
.getX(),aObjectRect
.getY(),aObjectRect
.getWidth(),aObjectRect
.getHeight())
867 , awt::Rectangle(aPageRect
.getX(),aPageRect
.getY(),aPageRect
.getWidth(),aPageRect
.getHeight()) );
869 if( bMoved
|| bChanged
)
871 bDraggingDone
= true;
876 catch( const uno::Exception
& )
878 DBG_UNHANDLED_EXCEPTION("chart2");
880 //all wanted model changes will take effect
881 //and all unwanted view modifications are cleaned
884 if( !bDraggingDone
) //mouse wasn't moved while dragging
886 bool bClickedTwiceOnDragableObject
= SelectionHelper::isDragableObjectHitTwice( aMPos
, m_aSelection
.getSelectedCID(), *pDrawViewWrapper
);
887 bool bIsRotateable
= m_aSelection
.isRotateableObjectSelected( getModel() );
889 //toggle between move and rotate
890 if( bIsRotateable
&& bClickedTwiceOnDragableObject
&& m_eDragMode
==SdrDragMode::Move
)
891 m_eDragMode
=SdrDragMode::Rotate
;
893 m_eDragMode
=SdrDragMode::Move
;
895 pDrawViewWrapper
->SetDragMode(m_eDragMode
);
897 if( !m_bWaitingForDoubleClick
&& m_aSelection
.maybeSwitchSelectionAfterSingleClickWasEnsured() )
899 impl_selectObjectAndNotiy();
903 m_aSelection
.resetPossibleSelectionAfterSingleClickWasEnsured();
906 //@todo ForcePointer(&rMEvt);
907 pChartWindow
->ReleaseMouse();
909 // In tiled rendering drag mode could be not yet over on the call
910 // that should handle the double-click, so better to perform this check
912 if( isDoubleClick(rMEvt
) && !bMouseUpWithoutMouseDown
/*#i106966#*/ )
914 Point aMousePixel
= rMEvt
.GetPosPixel();
915 execute_DoubleClick( &aMousePixel
);
918 if( m_aSelection
.isSelectionDifferentFromBeforeMouseDown() )
919 bNotifySelectionChange
= true;
922 impl_SetMousePointer( rMEvt
);
924 if(bNotifySelectionChange
)
925 impl_notifySelectionChangeListeners();
928 void ChartController::execute_DoubleClick( const Point
* pMousePixel
)
930 bool isMobile
= comphelper::LibreOfficeKit::isMobile(SfxLokHelper::getView());
934 bool bEditText
= false;
935 if ( m_aSelection
.hasSelection() )
937 OUString
aCID( m_aSelection
.getSelectedCID() );
938 if ( !aCID
.isEmpty() )
940 ObjectType eObjectType
= ObjectIdentifier::getObjectType( aCID
);
941 if ( eObjectType
== OBJECTTYPE_TITLE
)
948 // #i12587# support for shapes in chart
949 SdrObject
* pObj
= DrawViewWrapper::getSdrObject( m_aSelection
.getSelectedAdditionalShape() );
950 if ( dynamic_cast< const SdrTextObj
* >(pObj
) != nullptr )
959 executeDispatch_EditText( pMousePixel
);
963 executeDispatch_ObjectProperties();
967 void ChartController::execute_Resize()
969 SolarMutexGuard aGuard
;
970 auto pChartWindow(GetChartWindow());
972 pChartWindow
->Invalidate();
975 void ChartController::execute_Command( const CommandEvent
& rCEvt
)
977 SolarMutexGuard aGuard
;
978 auto pChartWindow(GetChartWindow());
979 bool bIsAction
= false;
981 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
982 if(!pChartWindow
|| !pDrawViewWrapper
)
984 bIsAction
= m_pDrawViewWrapper
->IsAction();
988 if(rCEvt
.GetCommand() == CommandEventId::ContextMenu
&& !bIsAction
)
992 pChartWindow
->ReleaseMouse();
995 if( m_aSelection
.isSelectionDifferentFromBeforeMouseDown() )
996 impl_notifySelectionChangeListeners();
998 css::uno::Reference
< css::awt::XPopupMenu
> xPopupMenu( m_xCC
->getServiceManager()->createInstanceWithContext(
999 "com.sun.star.awt.PopupMenu", m_xCC
), css::uno::UNO_QUERY
);
1001 Point
aPos( rCEvt
.GetMousePosPixel() );
1002 if( !rCEvt
.IsMouseEvent() )
1005 aPos
= pChartWindow
->GetPointerState().maPos
;
1009 if ( isShapeContext() )
1010 // #i12587# support for shapes in chart
1011 aMenuName
= m_pDrawViewWrapper
->IsTextEdit() ? OUStringLiteral( "drawtext" ) : OUStringLiteral( "draw" );
1014 // todo: the context menu should be specified by an xml file in uiconfig
1015 if( xPopupMenu
.is())
1017 sal_Int16 nUniqueId
= 1;
1018 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:Cut" );
1019 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:Copy" );
1020 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:Paste" );
1021 xPopupMenu
->insertSeparator( -1 );
1023 ObjectType eObjectType
= ObjectIdentifier::getObjectType( m_aSelection
.getSelectedCID() );
1024 Reference
< XDiagram
> xDiagram
= ChartModelHelper::findDiagram( getModel() );
1026 OUString
aFormatCommand( lcl_getFormatCommandForObjectCID( m_aSelection
.getSelectedCID() ) );
1027 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, aFormatCommand
);
1029 //some commands for dataseries and points:
1031 if( eObjectType
== OBJECTTYPE_DATA_SERIES
|| eObjectType
== OBJECTTYPE_DATA_POINT
)
1033 bool bIsPoint
= ( eObjectType
== OBJECTTYPE_DATA_POINT
);
1034 uno::Reference
< XDataSeries
> xSeries
= ObjectIdentifier::getDataSeriesForCID( m_aSelection
.getSelectedCID(), getModel() );
1035 uno::Reference
< chart2::XRegressionCurveContainer
> xCurveCnt( xSeries
, uno::UNO_QUERY
);
1036 Reference
< chart2::XRegressionCurve
> xTrendline( RegressionCurveHelper::getFirstCurveNotMeanValueLine( xCurveCnt
) );
1037 bool bHasEquation
= RegressionCurveHelper::hasEquation( xTrendline
);
1038 Reference
< chart2::XRegressionCurve
> xMeanValue( RegressionCurveHelper::getMeanValueLine( xCurveCnt
) );
1039 bool bHasYErrorBars
= StatisticsHelper::hasErrorBars( xSeries
);
1040 bool bHasXErrorBars
= StatisticsHelper::hasErrorBars( xSeries
, false );
1041 bool bHasDataLabelsAtSeries
= DataSeriesHelper::hasDataLabelsAtSeries( xSeries
);
1042 bool bHasDataLabelsAtPoints
= DataSeriesHelper::hasDataLabelsAtPoints( xSeries
);
1043 bool bHasDataLabelAtPoint
= false;
1044 sal_Int32 nPointIndex
= -1;
1047 nPointIndex
= ObjectIdentifier::getIndexFromParticleOrCID( m_aSelection
.getSelectedCID() );
1048 bHasDataLabelAtPoint
= DataSeriesHelper::hasDataLabelAtPoint( xSeries
, nPointIndex
);
1050 bool bSelectedPointIsFormatted
= false;
1051 bool bHasFormattedDataPointsOtherThanSelected
= false;
1053 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
1054 if( xSeriesProperties
.is() )
1056 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
1057 if( xSeriesProperties
->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList
)
1059 if( aAttributedDataPointIndexList
.hasElements() )
1063 auto aIndices( comphelper::sequenceToContainer
<std::vector
< sal_Int32
>>( aAttributedDataPointIndexList
) );
1064 std::vector
< sal_Int32
>::iterator aIt
= std::find( aIndices
.begin(), aIndices
.end(), nPointIndex
);
1065 if( aIt
!= aIndices
.end())
1066 bSelectedPointIsFormatted
= true;
1068 bHasFormattedDataPointsOtherThanSelected
= true;
1071 bHasFormattedDataPointsOtherThanSelected
= true;
1078 if( bHasDataLabelAtPoint
)
1079 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatDataLabel" );
1080 if( !bHasDataLabelAtPoint
)
1081 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertDataLabel" );
1083 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteDataLabel" );
1084 if( bSelectedPointIsFormatted
)
1085 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:ResetDataPoint" );
1087 xPopupMenu
->insertSeparator( -1 );
1089 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatDataSeries" );
1092 Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram
, xSeries
) );
1093 if( xChartType
->getChartType() == CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK
)
1097 Reference
< beans::XPropertySet
> xChartTypeProp( xChartType
, uno::UNO_QUERY
);
1098 if( xChartTypeProp
.is() )
1100 bool bJapaneseStyle
= false;
1101 xChartTypeProp
->getPropertyValue( "Japanese" ) >>= bJapaneseStyle
;
1103 if( bJapaneseStyle
)
1105 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatStockLoss" );
1106 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatStockGain" );
1110 catch( const uno::Exception
& )
1112 DBG_UNHANDLED_EXCEPTION("chart2");
1116 if( bHasDataLabelsAtSeries
)
1117 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatDataLabels" );
1119 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatTrendlineEquation" );
1120 if( xMeanValue
.is() )
1121 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatMeanValue" );
1122 if( bHasXErrorBars
)
1123 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatXErrorBars" );
1124 if( bHasYErrorBars
)
1125 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatYErrorBars" );
1127 xPopupMenu
->insertSeparator( -1 );
1129 if( !bHasDataLabelsAtSeries
)
1130 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertDataLabels" );
1132 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertTrendline" );
1134 if( !xMeanValue
.is() )
1135 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertMeanValue" );
1136 if( !bHasXErrorBars
)
1137 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertXErrorBars" );
1138 if( !bHasYErrorBars
)
1139 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertYErrorBars" );
1140 if( bHasDataLabelsAtSeries
|| ( bHasDataLabelsAtPoints
&& bHasFormattedDataPointsOtherThanSelected
) )
1141 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteDataLabels" );
1143 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteTrendlineEquation" );
1144 if( xMeanValue
.is() )
1145 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteMeanValue" );
1146 if( bHasXErrorBars
)
1147 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteXErrorBars" );
1148 if( bHasYErrorBars
)
1149 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteYErrorBars" );
1151 if( bHasFormattedDataPointsOtherThanSelected
)
1152 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:ResetAllDataPoints" );
1154 xPopupMenu
->insertSeparator( -1 );
1156 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
, ".uno:ArrangeRow" );
1157 uno::Reference
< awt::XPopupMenu
> xArrangePopupMenu(
1158 m_xCC
->getServiceManager()->createInstanceWithContext(
1159 "com.sun.star.awt.PopupMenu", m_xCC
), uno::UNO_QUERY
);
1160 if( xArrangePopupMenu
.is() )
1162 sal_Int16 nSubId
= nUniqueId
+ 1;
1163 lcl_insertMenuCommand( xArrangePopupMenu
, nSubId
++, ".uno:Forward" );
1164 lcl_insertMenuCommand( xArrangePopupMenu
, nSubId
, ".uno:Backward" );
1165 xPopupMenu
->setPopupMenu( nUniqueId
, xArrangePopupMenu
);
1170 else if( eObjectType
== OBJECTTYPE_DATA_CURVE
)
1172 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteTrendline" );
1173 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatTrendlineEquation" );
1174 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertTrendlineEquation" );
1175 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertTrendlineEquationAndR2" );
1176 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertR2Value" );
1177 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteTrendlineEquation" );
1178 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteR2Value" );
1180 else if( eObjectType
== OBJECTTYPE_DATA_CURVE_EQUATION
)
1182 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertR2Value" );
1183 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteR2Value" );
1186 //some commands for axes: and grids
1188 else if( eObjectType
== OBJECTTYPE_AXIS
|| eObjectType
== OBJECTTYPE_GRID
|| eObjectType
== OBJECTTYPE_SUBGRID
)
1190 Reference
< XAxis
> xAxis
= ObjectIdentifier::getAxisForCID( m_aSelection
.getSelectedCID(), getModel() );
1191 if( xAxis
.is() && xDiagram
.is() )
1193 sal_Int32 nDimensionIndex
= -1;
1194 sal_Int32 nCooSysIndex
= -1;
1195 sal_Int32 nAxisIndex
= -1;
1196 AxisHelper::getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
);
1197 bool bIsSecondaryAxis
= nAxisIndex
!=0;
1198 bool bIsAxisVisible
= AxisHelper::isAxisVisible( xAxis
);
1199 bool bIsMajorGridVisible
= AxisHelper::isGridShown( nDimensionIndex
, nCooSysIndex
, true /*bMainGrid*/, xDiagram
);
1200 bool bIsMinorGridVisible
= AxisHelper::isGridShown( nDimensionIndex
, nCooSysIndex
, false /*bMainGrid*/, xDiagram
);
1201 bool bHasTitle
= false;
1202 uno::Reference
< XTitled
> xTitled( xAxis
, uno::UNO_QUERY
);
1204 bHasTitle
= !TitleHelper::getCompleteString( xTitled
->getTitleObject() ).isEmpty();
1206 if( eObjectType
!= OBJECTTYPE_AXIS
&& bIsAxisVisible
)
1207 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatAxis" );
1208 if( eObjectType
!= OBJECTTYPE_GRID
&& bIsMajorGridVisible
&& !bIsSecondaryAxis
)
1209 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatMajorGrid" );
1210 if( eObjectType
!= OBJECTTYPE_SUBGRID
&& bIsMinorGridVisible
&& !bIsSecondaryAxis
)
1211 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatMinorGrid" );
1213 xPopupMenu
->insertSeparator( -1 );
1215 if( eObjectType
!= OBJECTTYPE_AXIS
&& !bIsAxisVisible
)
1216 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertAxis" );
1217 if( eObjectType
!= OBJECTTYPE_GRID
&& !bIsMajorGridVisible
&& !bIsSecondaryAxis
)
1218 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertMajorGrid" );
1219 if( eObjectType
!= OBJECTTYPE_SUBGRID
&& !bIsMinorGridVisible
&& !bIsSecondaryAxis
)
1220 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertMinorGrid" );
1222 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertAxisTitle" );
1224 if( bIsAxisVisible
)
1225 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteAxis" );
1226 if( bIsMajorGridVisible
&& !bIsSecondaryAxis
)
1227 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteMajorGrid" );
1228 if( bIsMinorGridVisible
&& !bIsSecondaryAxis
)
1229 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteMinorGrid" );
1233 if( eObjectType
== OBJECTTYPE_DATA_STOCK_LOSS
)
1234 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatStockGain" );
1235 else if( eObjectType
== OBJECTTYPE_DATA_STOCK_GAIN
)
1236 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatStockLoss" );
1238 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:TransformDialog" );
1240 if( eObjectType
== OBJECTTYPE_PAGE
|| eObjectType
== OBJECTTYPE_DIAGRAM
1241 || eObjectType
== OBJECTTYPE_DIAGRAM_WALL
1242 || eObjectType
== OBJECTTYPE_DIAGRAM_FLOOR
1243 || eObjectType
== OBJECTTYPE_UNKNOWN
)
1245 if( eObjectType
!= OBJECTTYPE_UNKNOWN
)
1246 xPopupMenu
->insertSeparator( -1 );
1247 bool bHasLegend
= LegendHelper::hasLegend( xDiagram
);
1248 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertTitles" );
1250 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertLegend" );
1251 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertRemoveAxes" );
1253 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteLegend" );
1256 xPopupMenu
->insertSeparator( -1 );
1257 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DiagramType" );
1258 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DataRanges" );
1259 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DiagramData" );
1260 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:View3D" );
1264 css::uno::Sequence
< css::uno::Any
> aArgs( 3 );
1265 aArgs
[0] <<= comphelper::makePropertyValue( "IsContextMenu", true );
1266 aArgs
[1] <<= comphelper::makePropertyValue( "Frame", m_xFrame
);
1267 aArgs
[2] <<= comphelper::makePropertyValue( "Value", aMenuName
);
1269 css::uno::Reference
< css::frame::XPopupMenuController
> xPopupController(
1270 m_xCC
->getServiceManager()->createInstanceWithArgumentsAndContext(
1271 "com.sun.star.comp.framework.ResourceMenuController", aArgs
, m_xCC
), css::uno::UNO_QUERY
);
1273 if ( !xPopupController
.is() || !xPopupMenu
.is() )
1276 if (comphelper::LibreOfficeKit::isActive())
1278 PopupMenu
* pPopupMenu
= static_cast<PopupMenu
*>(comphelper::getUnoTunnelImplementation
<VCLXMenu
>(xPopupMenu
)->GetMenu());
1279 pPopupMenu
->SetLOKNotifier(SfxViewShell::Current());
1281 // the context menu expects a position related to the document window,
1282 // not to the chart window
1283 SfxInPlaceClient
* pIPClient
= SfxViewShell::Current()->GetIPClient();
1286 vcl::Window
* pRootWin
= pIPClient
->GetEditWin();
1289 Point aOffset
= pChartWindow
->GetOffsetPixelFrom(*pRootWin
);
1295 xPopupController
->setPopupMenu( xPopupMenu
);
1296 xPopupMenu
->execute( css::uno::Reference
< css::awt::XWindowPeer
>( m_xFrame
->getContainerWindow(), css::uno::UNO_QUERY
),
1297 css::awt::Rectangle( aPos
.X(), aPos
.Y(), 0, 0 ),
1298 css::awt::PopupMenuDirection::EXECUTE_DEFAULT
);
1300 css::uno::Reference
< css::lang::XComponent
> xComponent( xPopupController
, css::uno::UNO_QUERY
);
1301 if ( xComponent
.is() )
1302 xComponent
->dispose();
1304 else if( ( rCEvt
.GetCommand() == CommandEventId::StartExtTextInput
) ||
1305 ( rCEvt
.GetCommand() == CommandEventId::ExtTextInput
) ||
1306 ( rCEvt
.GetCommand() == CommandEventId::EndExtTextInput
) ||
1307 ( rCEvt
.GetCommand() == CommandEventId::InputContextChange
) )
1309 //#i84417# enable editing with IME
1310 if( m_pDrawViewWrapper
)
1311 m_pDrawViewWrapper
->Command( rCEvt
, pChartWindow
);
1315 bool ChartController::execute_KeyInput( const KeyEvent
& rKEvt
)
1317 SolarMutexGuard aGuard
;
1320 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
1321 auto pChartWindow(GetChartWindow());
1322 if (!pChartWindow
|| !pDrawViewWrapper
)
1325 // handle accelerators
1326 if (!m_apAccelExecute
&& m_xFrame
.is() && m_xCC
.is())
1328 m_apAccelExecute
= ::svt::AcceleratorExecute::createAcceleratorHelper();
1329 OSL_ASSERT(m_apAccelExecute
);
1330 if (m_apAccelExecute
)
1331 m_apAccelExecute
->init( m_xCC
, m_xFrame
);
1334 vcl::KeyCode
aKeyCode( rKEvt
.GetKeyCode());
1335 sal_uInt16 nCode
= aKeyCode
.GetCode();
1336 bool bAlternate
= aKeyCode
.IsMod2();
1337 bool bCtrl
= aKeyCode
.IsMod1();
1339 if (m_apAccelExecute
)
1340 bReturn
= m_apAccelExecute
->execute( aKeyCode
);
1345 if( pDrawViewWrapper
->IsTextEdit() )
1347 if( pDrawViewWrapper
->KeyInput(rKEvt
, pChartWindow
) )
1350 if( nCode
== KEY_ESCAPE
)
1358 // keyboard accessibility
1359 ObjectType eObjectType
= ObjectIdentifier::getObjectType( m_aSelection
.getSelectedCID() );
1362 // Navigation (Tab/F3/Home/End)
1363 uno::Reference
< XChartDocument
> xChartDoc( getModel(), uno::UNO_QUERY
);
1364 ObjectKeyNavigation
aObjNav( m_aSelection
.getSelectedOID(), xChartDoc
, comphelper::getUnoTunnelImplementation
<ExplicitValueProvider
>( m_xChartView
));
1365 awt::KeyEvent
aKeyEvent( ::svt::AcceleratorExecute::st_VCLKey2AWTKey( aKeyCode
));
1366 bReturn
= aObjNav
.handleKeyEvent( aKeyEvent
);
1369 const ObjectIdentifier
& aNewOID
= aObjNav
.getCurrentSelection();
1370 uno::Any aNewSelection
;
1371 if ( aNewOID
.isValid() && !ObjectHierarchy::isRootNode( aNewOID
) )
1373 aNewSelection
= aNewOID
.getAny();
1375 if ( m_eDragMode
== SdrDragMode::Rotate
&& !SelectionHelper::isRotateableObject( aNewOID
.getObjectCID(), getModel() ) )
1377 m_eDragMode
= SdrDragMode::Move
;
1379 bReturn
= select( aNewSelection
);
1383 // Position and Size (+/-/arrow-keys) or pie segment dragging
1386 // pie segment dragging
1387 // note: could also be done for data series
1388 if( eObjectType
== OBJECTTYPE_DATA_POINT
&&
1389 ObjectIdentifier::getDragMethodServiceName( m_aSelection
.getSelectedCID() ) ==
1390 ObjectIdentifier::getPieSegmentDragMethodServiceName())
1393 bool bDragInside
= false;
1394 if( nCode
== KEY_ADD
||
1395 nCode
== KEY_SUBTRACT
)
1398 bDragInside
= ( nCode
== KEY_SUBTRACT
);
1401 nCode
== KEY_LEFT
||
1402 nCode
== KEY_RIGHT
||
1407 OUString
aParameter( ObjectIdentifier::getDragParameterString( m_aSelection
.getSelectedCID() ));
1408 sal_Int32
nOffsetPercentDummy( 0 );
1409 awt::Point
aMinimumPosition( 0, 0 );
1410 awt::Point
aMaximumPosition( 0, 0 );
1411 ObjectIdentifier::parsePieSegmentDragParameterString(
1412 aParameter
, nOffsetPercentDummy
, aMinimumPosition
, aMaximumPosition
);
1413 aMaximumPosition
.Y
-= aMinimumPosition
.Y
;
1414 aMaximumPosition
.X
-= aMinimumPosition
.X
;
1417 (nCode
== KEY_RIGHT
&& (aMaximumPosition
.X
< 0)) ||
1418 (nCode
== KEY_LEFT
&& (aMaximumPosition
.X
> 0)) ||
1419 (nCode
== KEY_DOWN
&& (aMaximumPosition
.Y
< 0)) ||
1420 (nCode
== KEY_UP
&& (aMaximumPosition
.Y
> 0));
1425 double fAmount
= bAlternate
? 0.01 : 0.05;
1429 bReturn
= impl_DragDataPoint( m_aSelection
.getSelectedCID(), fAmount
);
1435 if( nCode
== KEY_ADD
||
1436 nCode
== KEY_SUBTRACT
)
1438 if( eObjectType
== OBJECTTYPE_DIAGRAM
)
1440 // default 1 mm in each direction
1441 double fGrowAmountX
= 200.0;
1442 double fGrowAmountY
= 200.0;
1445 // together with Alt-key: 1 px in each direction
1446 Size aPixelSize
= pChartWindow
->PixelToLogic( Size( 2, 2 ));
1447 fGrowAmountX
= static_cast< double >( aPixelSize
.Width());
1448 fGrowAmountY
= static_cast< double >( aPixelSize
.Height());
1450 if( nCode
== KEY_SUBTRACT
)
1452 fGrowAmountX
= -fGrowAmountX
;
1453 fGrowAmountY
= -fGrowAmountY
;
1455 bReturn
= impl_moveOrResizeObject(
1456 m_aSelection
.getSelectedCID(), CENTERED_RESIZE_OBJECT
, fGrowAmountX
, fGrowAmountY
);
1460 else if( nCode
== KEY_LEFT
||
1461 nCode
== KEY_RIGHT
||
1465 if( m_aSelection
.isDragableObjectSelected() )
1468 double fShiftAmountX
= 100.0;
1469 double fShiftAmountY
= 100.0;
1472 // together with Alt-key: 1 px
1473 Size aPixelSize
= pChartWindow
->PixelToLogic( Size( 1, 1 ));
1474 fShiftAmountX
= static_cast< double >( aPixelSize
.Width());
1475 fShiftAmountY
= static_cast< double >( aPixelSize
.Height());
1480 fShiftAmountX
= -fShiftAmountX
;
1481 fShiftAmountY
= 0.0;
1484 fShiftAmountY
= 0.0;
1487 fShiftAmountX
= 0.0;
1488 fShiftAmountY
= -fShiftAmountY
;
1491 fShiftAmountX
= 0.0;
1494 if( !m_aSelection
.getSelectedCID().isEmpty() )
1496 //move chart objects
1497 bReturn
= impl_moveOrResizeObject(
1498 m_aSelection
.getSelectedCID(), MOVE_OBJECT
, fShiftAmountX
, fShiftAmountY
);
1502 //move additional shapes
1503 uno::Reference
< drawing::XShape
> xShape( m_aSelection
.getSelectedAdditionalShape() );
1506 awt::Point
aPos( xShape
->getPosition() );
1507 awt::Size
aSize( xShape
->getSize() );
1508 awt::Size
aPageSize( ChartModelHelper::getPageSize( getModel() ) );
1509 aPos
.X
= static_cast< long >( static_cast< double >( aPos
.X
) + fShiftAmountX
);
1510 aPos
.Y
= static_cast< long >( static_cast< double >( aPos
.Y
) + fShiftAmountY
);
1511 if( aPos
.X
+ aSize
.Width
> aPageSize
.Width
)
1512 aPos
.X
= aPageSize
.Width
- aSize
.Width
;
1515 if( aPos
.Y
+ aSize
.Height
> aPageSize
.Height
)
1516 aPos
.Y
= aPageSize
.Height
- aSize
.Height
;
1520 xShape
->setPosition( aPos
);
1528 // dumping the shape
1529 if( !bReturn
&& bCtrl
&& nCode
== KEY_F12
)
1531 uno::Reference
< qa::XDumper
> xChartModel( getModel(), uno::UNO_QUERY
);
1532 if(xChartModel
.is())
1534 OUString aDump
= xChartModel
->dump();
1535 SAL_WARN("chart2", aDump
);
1543 if( eObjectType
== OBJECTTYPE_TITLE
)
1545 executeDispatch_EditText();
1550 // deactivate inplace mode (this code should be unnecessary, but
1551 // unfortunately is not)
1553 nCode
== KEY_ESCAPE
)
1555 uno::Reference
< frame::XDispatchHelper
> xDispatchHelper( frame::DispatchHelper::create(m_xCC
) );
1556 uno::Sequence
< beans::PropertyValue
> aArgs
;
1557 xDispatchHelper
->executeDispatch(
1558 uno::Reference
< frame::XDispatchProvider
>( m_xFrame
, uno::UNO_QUERY
),
1559 ".uno:TerminateInplaceActivation",
1561 frame::FrameSearchFlag::PARENT
,
1567 (nCode
== KEY_DELETE
|| nCode
== KEY_BACKSPACE
))
1569 bReturn
= executeDispatch_Delete();
1572 std::unique_ptr
<weld::MessageDialog
> xInfoBox(Application::CreateMessageDialog(pChartWindow
->GetFrameWeld(),
1573 VclMessageType::Info
, VclButtonsType::Ok
,
1574 SchResId(STR_ACTION_NOTPOSSIBLE
)));
1582 bool ChartController::requestQuickHelp(
1583 ::Point aAtLogicPosition
,
1584 bool bIsBalloonHelp
,
1585 OUString
& rOutQuickHelpText
,
1586 awt::Rectangle
& rOutEqualRect
)
1588 uno::Reference
< frame::XModel
> xChartModel
;
1590 xChartModel
.set( getModel() );
1591 if( !xChartModel
.is())
1596 if( m_pDrawViewWrapper
)
1598 aCID
= SelectionHelper::getHitObjectCID(
1599 aAtLogicPosition
, *m_pDrawViewWrapper
);
1601 bool bResult( !aCID
.isEmpty());
1606 rOutQuickHelpText
= ObjectNameProvider::getHelpText( aCID
, xChartModel
, bIsBalloonHelp
/* bVerbose */ );
1609 ExplicitValueProvider
* pValueProvider(
1610 comphelper::getUnoTunnelImplementation
<ExplicitValueProvider
>( m_xChartView
));
1611 if( pValueProvider
)
1612 rOutEqualRect
= pValueProvider
->getRectangleOfObject( aCID
, true );
1618 // XSelectionSupplier (optional interface)
1619 sal_Bool SAL_CALL
ChartController::select( const uno::Any
& rSelection
)
1621 bool bSuccess
= false;
1623 if ( rSelection
.hasValue() )
1625 const uno::Type
& rType
= rSelection
.getValueType();
1626 if ( rType
== cppu::UnoType
< OUString
>::get() )
1629 if ( ( rSelection
>>= aNewCID
) && m_aSelection
.setSelection( aNewCID
) )
1634 else if ( rType
== cppu::UnoType
<drawing::XShape
>::get() )
1636 uno::Reference
< drawing::XShape
> xShape
;
1637 if ( ( rSelection
>>= xShape
) && m_aSelection
.setSelection( xShape
) )
1645 if ( m_aSelection
.hasSelection() )
1647 m_aSelection
.clearSelection();
1654 SolarMutexGuard aGuard
;
1655 if ( m_pDrawViewWrapper
&& m_pDrawViewWrapper
->IsTextEdit() )
1659 impl_selectObjectAndNotiy();
1660 auto pChartWindow(GetChartWindow());
1663 pChartWindow
->Invalidate();
1671 uno::Any SAL_CALL
ChartController::getSelection()
1674 if ( m_aSelection
.hasSelection() )
1676 OUString
aCID( m_aSelection
.getSelectedCID() );
1677 if ( !aCID
.isEmpty() )
1679 if ( comphelper::LibreOfficeKit::isActive() )
1681 sal_Int32 nPos
= aCID
.lastIndexOf('/');
1682 OUString sFirst
= aCID
.copy(0, nPos
);
1683 OUString sSecond
= aCID
.copy(nPos
);
1685 "/Draggable=" + OUString::number(static_cast<int>(isSelectedObjectDraggable())) +
1686 ":Resizable=" + OUString::number(static_cast<int>(isSelectedObjectResizable())) +
1687 ":Rotatable=" + OUString::number(static_cast<int>(isSelectedObjectRotatable())) +
1694 // #i12587# support for shapes in chart
1695 aReturn
<<= m_aSelection
.getSelectedAdditionalShape();
1701 void SAL_CALL
ChartController::addSelectionChangeListener( const uno::Reference
<view::XSelectionChangeListener
> & xListener
)
1703 SolarMutexGuard aGuard
;
1704 if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode?
1705 return; //behave passive if already disposed or suspended
1708 m_aLifeTimeManager
.m_aListenerContainer
.addInterface( cppu::UnoType
<view::XSelectionChangeListener
>::get(), xListener
);
1711 void SAL_CALL
ChartController::removeSelectionChangeListener( const uno::Reference
<view::XSelectionChangeListener
> & xListener
)
1713 SolarMutexGuard aGuard
;
1714 if( impl_isDisposedOrSuspended() ) //@todo? allow removing of listeners in suspend mode?
1715 return; //behave passive if already disposed or suspended
1718 m_aLifeTimeManager
.m_aListenerContainer
.removeInterface( cppu::UnoType
<view::XSelectionChangeListener
>::get(), xListener
);
1721 void ChartController::impl_notifySelectionChangeListeners()
1723 ::cppu::OInterfaceContainerHelper
* pIC
= m_aLifeTimeManager
.m_aListenerContainer
1724 .getContainer( cppu::UnoType
<view::XSelectionChangeListener
>::get() );
1727 uno::Reference
< view::XSelectionSupplier
> xSelectionSupplier(this);
1728 lang::EventObject
aEvent( xSelectionSupplier
);
1729 ::cppu::OInterfaceIteratorHelper
aIt( *pIC
);
1730 while( aIt
.hasMoreElements() )
1732 uno::Reference
< view::XSelectionChangeListener
> xListener( aIt
.next(), uno::UNO_QUERY
);
1733 if( xListener
.is() )
1734 xListener
->selectionChanged( aEvent
);
1739 void ChartController::impl_selectObjectAndNotiy()
1742 SolarMutexGuard aGuard
;
1743 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
1744 if( pDrawViewWrapper
)
1746 pDrawViewWrapper
->SetDragMode( m_eDragMode
);
1747 m_aSelection
.applySelection( m_pDrawViewWrapper
.get() );
1750 impl_notifySelectionChangeListeners();
1753 bool ChartController::impl_moveOrResizeObject(
1754 const OUString
& rCID
,
1755 eMoveOrResizeType eType
,
1756 double fAmountLogicX
,
1757 double fAmountLogicY
)
1759 bool bResult
= false;
1760 bool bNeedResize
= ( eType
== CENTERED_RESIZE_OBJECT
);
1762 uno::Reference
< frame::XModel
> xChartModel( getModel() );
1763 uno::Reference
< beans::XPropertySet
> xObjProp(
1764 ObjectIdentifier::getObjectPropertySet( rCID
, xChartModel
));
1767 awt::Size aRefSize
= ChartModelHelper::getPageSize( xChartModel
);
1769 chart2::RelativePosition aRelPos
;
1770 chart2::RelativeSize aRelSize
;
1771 bool bDeterminePos
= !(xObjProp
->getPropertyValue( "RelativePosition") >>= aRelPos
);
1772 bool bDetermineSize
= !bNeedResize
|| !(xObjProp
->getPropertyValue( "RelativeSize") >>= aRelSize
);
1774 if( ( bDeterminePos
|| bDetermineSize
) &&
1775 ( aRefSize
.Width
> 0 && aRefSize
.Height
> 0 ) )
1777 ExplicitValueProvider
* pValueProvider(
1778 comphelper::getUnoTunnelImplementation
<ExplicitValueProvider
>( m_xChartView
));
1779 if( pValueProvider
)
1781 awt::Rectangle
aRect( pValueProvider
->getRectangleOfObject( rCID
));
1782 double fWidth
= static_cast< double >( aRefSize
.Width
);
1783 double fHeight
= static_cast< double >( aRefSize
.Height
);
1784 if( bDetermineSize
)
1786 aRelSize
.Primary
= static_cast< double >( aRect
.Width
) / fWidth
;
1787 aRelSize
.Secondary
= static_cast< double >( aRect
.Height
) / fHeight
;
1791 if( bNeedResize
&& aRelSize
.Primary
> 0.0 && aRelSize
.Secondary
> 0.0 )
1793 aRelPos
.Primary
= (static_cast< double >( aRect
.X
) / fWidth
) +
1794 (aRelSize
.Primary
/ 2.0);
1795 aRelPos
.Secondary
= (static_cast< double >( aRect
.Y
) / fHeight
) +
1796 (aRelSize
.Secondary
/ 2.0);
1797 aRelPos
.Anchor
= drawing::Alignment_CENTER
;
1801 aRelPos
.Primary
= static_cast< double >( aRect
.X
) / fWidth
;
1802 aRelPos
.Secondary
= static_cast< double >( aRect
.Y
) / fHeight
;
1803 aRelPos
.Anchor
= drawing::Alignment_TOP_LEFT
;
1809 if( eType
== CENTERED_RESIZE_OBJECT
)
1810 bResult
= lcl_GrowAndShiftLogic( aRelPos
, aRelSize
, aRefSize
, fAmountLogicX
, fAmountLogicY
);
1811 else if( eType
== MOVE_OBJECT
)
1812 bResult
= lcl_MoveObjectLogic( aRelPos
, aRelSize
, aRefSize
, fAmountLogicX
, fAmountLogicY
);
1816 ActionDescriptionProvider::ActionType
eActionType(ActionDescriptionProvider::ActionType::Move
);
1818 eActionType
= ActionDescriptionProvider::ActionType::Resize
;
1820 ObjectType eObjectType
= ObjectIdentifier::getObjectType( rCID
);
1821 UndoGuard
aUndoGuard( ActionDescriptionProvider::createDescription(
1822 eActionType
, ObjectNameProvider::getName( eObjectType
)), m_xUndoManager
);
1824 ControllerLockGuardUNO
aCLGuard( xChartModel
);
1825 xObjProp
->setPropertyValue( "RelativePosition", uno::Any( aRelPos
));
1826 if( bNeedResize
|| (eObjectType
== OBJECTTYPE_DIAGRAM
) )//Also set an explicit size at the diagram when an explicit position is set
1827 xObjProp
->setPropertyValue( "RelativeSize", uno::Any( aRelSize
));
1829 aUndoGuard
.commit();
1835 bool ChartController::impl_DragDataPoint( const OUString
& rCID
, double fAdditionalOffset
)
1837 bool bResult
= false;
1838 if( fAdditionalOffset
< -1.0 || fAdditionalOffset
> 1.0 || fAdditionalOffset
== 0.0 )
1841 sal_Int32 nDataPointIndex
= ObjectIdentifier::getIndexFromParticleOrCID( rCID
);
1842 uno::Reference
< chart2::XDataSeries
> xSeries(
1843 ObjectIdentifier::getDataSeriesForCID( rCID
, getModel() ));
1848 uno::Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex( nDataPointIndex
));
1849 double fOffset
= 0.0;
1850 if( xPointProp
.is() &&
1851 (xPointProp
->getPropertyValue( "Offset" ) >>= fOffset
) &&
1852 (( fAdditionalOffset
> 0.0 && fOffset
< 1.0 ) || (fOffset
> 0.0)) )
1854 fOffset
+= fAdditionalOffset
;
1857 else if( fOffset
< 0.0 )
1859 xPointProp
->setPropertyValue( "Offset", uno::Any( fOffset
));
1863 catch( const uno::Exception
& )
1865 DBG_UNHANDLED_EXCEPTION("chart2");
1872 void ChartController::impl_SetMousePointer( const MouseEvent
& rEvent
)
1874 SolarMutexGuard aGuard
;
1875 auto pChartWindow(GetChartWindow());
1877 if (!m_pDrawViewWrapper
|| !pChartWindow
)
1880 Point
aMousePos( pChartWindow
->PixelToLogic( rEvent
.GetPosPixel()));
1881 sal_uInt16 nModifier
= rEvent
.GetModifier();
1882 bool bLeftDown
= rEvent
.IsLeft();
1884 // Check if object is for field button and set the normal arrow pointer in this case
1885 SdrObject
* pObject
= m_pDrawViewWrapper
->getHitObject(aMousePos
);
1886 if (pObject
&& pObject
->GetName().startsWith("FieldButton"))
1888 pChartWindow
->SetPointer(PointerStyle::Arrow
);
1892 if ( m_pDrawViewWrapper
->IsTextEdit() )
1894 if( m_pDrawViewWrapper
->IsTextEditHit( aMousePos
) )
1896 pChartWindow
->SetPointer( m_pDrawViewWrapper
->GetPreferredPointer(
1897 aMousePos
, pChartWindow
, nModifier
, bLeftDown
) );
1901 else if( m_pDrawViewWrapper
->IsAction() )
1903 return;//don't change pointer during running action
1906 SdrHdl
* pHitSelectionHdl
= nullptr;
1907 if( m_aSelection
.isResizeableObjectSelected() )
1908 pHitSelectionHdl
= m_pDrawViewWrapper
->PickHandle( aMousePos
);
1910 if( pHitSelectionHdl
)
1912 PointerStyle aPointer
= m_pDrawViewWrapper
->GetPreferredPointer(
1913 aMousePos
, pChartWindow
, nModifier
, bLeftDown
);
1914 bool bForceArrowPointer
= false;
1916 ObjectIdentifier
aOID( m_aSelection
.getSelectedOID() );
1920 case PointerStyle::NSize
:
1921 case PointerStyle::SSize
:
1922 case PointerStyle::WSize
:
1923 case PointerStyle::ESize
:
1924 case PointerStyle::NWSize
:
1925 case PointerStyle::NESize
:
1926 case PointerStyle::SWSize
:
1927 case PointerStyle::SESize
:
1928 if( ! m_aSelection
.isResizeableObjectSelected() )
1929 bForceArrowPointer
= true;
1931 case PointerStyle::Move
:
1932 if ( !aOID
.isDragableObject() )
1933 bForceArrowPointer
= true;
1935 case PointerStyle::MovePoint
:
1936 case PointerStyle::MoveBezierWeight
:
1937 // there is no point-editing in a chart
1938 // the PointerStyle::MoveBezierWeight appears in 3d data points
1939 bForceArrowPointer
= true;
1945 if( bForceArrowPointer
)
1946 pChartWindow
->SetPointer( PointerStyle::Arrow
);
1948 pChartWindow
->SetPointer( aPointer
);
1953 // #i12587# support for shapes in chart
1954 if ( m_eDrawMode
== CHARTDRAW_INSERT
&&
1955 ( !m_pDrawViewWrapper
->IsMarkedHit( aMousePos
) || !m_aSelection
.isDragableObjectSelected() ) )
1957 PointerStyle ePointerStyle
= PointerStyle::DrawRect
;
1958 SdrObjKind eKind
= static_cast< SdrObjKind
>( m_pDrawViewWrapper
->GetCurrentObjIdentifier() );
1963 ePointerStyle
= PointerStyle::DrawLine
;
1967 case OBJ_CUSTOMSHAPE
:
1969 ePointerStyle
= PointerStyle::DrawRect
;
1974 ePointerStyle
= PointerStyle::DrawEllipse
;
1979 ePointerStyle
= PointerStyle::DrawPolygon
;
1984 ePointerStyle
= PointerStyle::DrawText
;
1989 ePointerStyle
= PointerStyle::DrawCaption
;
1994 ePointerStyle
= PointerStyle::DrawRect
;
1998 pChartWindow
->SetPointer( ePointerStyle
);
2002 OUString
aHitObjectCID(
2003 SelectionHelper::getHitObjectCID(
2004 aMousePos
, *m_pDrawViewWrapper
, true /*bGetDiagramInsteadOf_Wall*/ ));
2006 if( m_pDrawViewWrapper
->IsTextEdit() )
2008 if( aHitObjectCID
== m_aSelection
.getSelectedCID() )
2010 pChartWindow
->SetPointer( PointerStyle::Arrow
);
2015 if( aHitObjectCID
.isEmpty() )
2017 //additional shape was hit
2018 pChartWindow
->SetPointer( PointerStyle::Move
);
2020 else if( ObjectIdentifier::isDragableObject( aHitObjectCID
) )
2022 if( (m_eDragMode
== SdrDragMode::Rotate
)
2023 && SelectionHelper::isRotateableObject( aHitObjectCID
2025 pChartWindow
->SetPointer( PointerStyle::Rotate
);
2028 ObjectType eHitObjectType
= ObjectIdentifier::getObjectType( aHitObjectCID
);
2029 if( eHitObjectType
== OBJECTTYPE_DATA_POINT
)
2031 if( !ObjectIdentifier::areSiblings(aHitObjectCID
,m_aSelection
.getSelectedCID())
2032 && !ObjectIdentifier::areIdenticalObjects(aHitObjectCID
,m_aSelection
.getSelectedCID()) )
2034 pChartWindow
->SetPointer( PointerStyle::Arrow
);
2038 pChartWindow
->SetPointer( PointerStyle::Move
);
2042 pChartWindow
->SetPointer( PointerStyle::Arrow
);
2045 css::uno::Reference
<css::uno::XInterface
> const & ChartController::getChartView() const
2047 return m_xChartView
;
2050 void ChartController::sendPopupRequest(OUString
const & rCID
, tools::Rectangle aRectangle
)
2052 ChartModel
* pChartModel
= dynamic_cast<ChartModel
*>(m_aModel
->getModel().get());
2056 uno::Reference
<chart2::data::XPivotTableDataProvider
> xPivotTableDataProvider
;
2057 xPivotTableDataProvider
.set(pChartModel
->getDataProvider(), uno::UNO_QUERY
);
2058 if (!xPivotTableDataProvider
.is())
2061 OUString sPivotTableName
= xPivotTableDataProvider
->getPivotTableName();
2063 PopupRequest
* pPopupRequest
= dynamic_cast<PopupRequest
*>(pChartModel
->getPopupRequest().get());
2067 // Get dimension index from CID
2068 sal_Int32 nStartPos
= rCID
.lastIndexOf('.');
2070 sal_Int32 nEndPos
= rCID
.getLength();
2071 OUString sDimensionIndex
= rCID
.copy(nStartPos
, nEndPos
- nStartPos
);
2072 sal_Int32 nDimensionIndex
= sDimensionIndex
.toInt32();
2074 awt::Rectangle xRectangle
{
2075 sal_Int32(aRectangle
.Left()),
2076 sal_Int32(aRectangle
.Top()),
2077 sal_Int32(aRectangle
.GetWidth()),
2078 sal_Int32(aRectangle
.GetHeight())
2081 uno::Sequence
<beans::PropertyValue
> aCallbackData
= comphelper::InitPropertySequence(
2083 {"Rectangle", uno::makeAny
<awt::Rectangle
>(xRectangle
)},
2084 {"DimensionIndex", uno::makeAny
<sal_Int32
>(nDimensionIndex
)},
2085 {"PivotTableName", uno::makeAny
<OUString
>(sPivotTableName
)},
2088 pPopupRequest
->getCallback()->notify(uno::makeAny(aCallbackData
));
2093 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */