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 <comphelper/lok.hxx>
86 #include <sfx2/lokhelper.hxx>
88 #define DRGPIX 2 // Drag MinMove in Pixel
90 using namespace ::com::sun::star
;
91 using namespace ::com::sun::star::chart2
;
92 using ::com::sun::star::uno::Reference
;
99 bool lcl_GrowAndShiftLogic(
100 RelativePosition
& rInOutRelPos
,
101 RelativeSize
& rInOutRelSize
,
102 const awt::Size
& rRefSize
,
106 if( rRefSize
.Width
== 0 ||
107 rRefSize
.Height
== 0 )
110 double fRelativeGrowX
= fGrowLogicX
/ rRefSize
.Width
;
111 double fRelativeGrowY
= fGrowLogicY
/ rRefSize
.Height
;
113 return ::chart::RelativePositionHelper::centerGrow(
114 rInOutRelPos
, rInOutRelSize
,
115 fRelativeGrowX
, fRelativeGrowY
);
118 bool lcl_MoveObjectLogic(
119 RelativePosition
& rInOutRelPos
,
120 RelativeSize
const & rObjectSize
,
121 const awt::Size
& rRefSize
,
123 double fShiftLogicY
)
125 if( rRefSize
.Width
== 0 ||
126 rRefSize
.Height
== 0 )
129 double fRelativeShiftX
= fShiftLogicX
/ rRefSize
.Width
;
130 double fRelativeShiftY
= fShiftLogicY
/ rRefSize
.Height
;
132 return ::chart::RelativePositionHelper::moveObject(
133 rInOutRelPos
, rObjectSize
,
134 fRelativeShiftX
, fRelativeShiftY
);
137 void lcl_insertMenuCommand(
138 const uno::Reference
< awt::XPopupMenu
> & xMenu
,
139 sal_Int16 nId
, const OUString
& rCommand
)
141 xMenu
->insertItem( nId
, "", 0, -1 );
142 xMenu
->setCommand( nId
, rCommand
);
145 OUString
lcl_getFormatCommandForObjectCID( const OUString
& rCID
)
147 OUString
aDispatchCommand( ".uno:FormatSelection" );
149 ObjectType eObjectType
= ObjectIdentifier::getObjectType( rCID
);
153 case OBJECTTYPE_DIAGRAM
:
154 case OBJECTTYPE_DIAGRAM_WALL
:
155 aDispatchCommand
= ".uno:FormatWall";
157 case OBJECTTYPE_DIAGRAM_FLOOR
:
158 aDispatchCommand
= ".uno:FormatFloor";
160 case OBJECTTYPE_PAGE
:
161 aDispatchCommand
= ".uno:FormatChartArea";
163 case OBJECTTYPE_LEGEND
:
164 aDispatchCommand
= ".uno:FormatLegend";
166 case OBJECTTYPE_TITLE
:
167 aDispatchCommand
= ".uno:FormatTitle";
169 case OBJECTTYPE_LEGEND_ENTRY
:
170 aDispatchCommand
= ".uno:FormatDataSeries";
172 case OBJECTTYPE_AXIS
:
173 case OBJECTTYPE_AXIS_UNITLABEL
:
174 aDispatchCommand
= ".uno:FormatAxis";
176 case OBJECTTYPE_GRID
:
177 aDispatchCommand
= ".uno:FormatMajorGrid";
179 case OBJECTTYPE_SUBGRID
:
180 aDispatchCommand
= ".uno:FormatMinorGrid";
182 case OBJECTTYPE_DATA_LABELS
:
183 aDispatchCommand
= ".uno:FormatDataLabels";
185 case OBJECTTYPE_DATA_SERIES
:
186 aDispatchCommand
= ".uno:FormatDataSeries";
188 case OBJECTTYPE_DATA_LABEL
:
189 aDispatchCommand
= ".uno:FormatDataLabel";
191 case OBJECTTYPE_DATA_POINT
:
192 aDispatchCommand
= ".uno:FormatDataPoint";
194 case OBJECTTYPE_DATA_AVERAGE_LINE
:
195 aDispatchCommand
= ".uno:FormatMeanValue";
197 case OBJECTTYPE_DATA_ERRORS_X
:
198 aDispatchCommand
= ".uno:FormatXErrorBars";
200 case OBJECTTYPE_DATA_ERRORS_Y
:
201 aDispatchCommand
= ".uno:FormatYErrorBars";
203 case OBJECTTYPE_DATA_ERRORS_Z
:
204 aDispatchCommand
= ".uno:FormatZErrorBars";
206 case OBJECTTYPE_DATA_CURVE
:
207 aDispatchCommand
= ".uno:FormatTrendline";
209 case OBJECTTYPE_DATA_CURVE_EQUATION
:
210 aDispatchCommand
= ".uno:FormatTrendlineEquation";
212 case OBJECTTYPE_DATA_STOCK_RANGE
:
213 aDispatchCommand
= ".uno:FormatSelection";
215 case OBJECTTYPE_DATA_STOCK_LOSS
:
216 aDispatchCommand
= ".uno:FormatStockLoss";
218 case OBJECTTYPE_DATA_STOCK_GAIN
:
219 aDispatchCommand
= ".uno:FormatStockGain";
221 default: //OBJECTTYPE_UNKNOWN
224 return aDispatchCommand
;
227 } // anonymous namespace
230 void SAL_CALL
ChartController::setPosSize(
237 SolarMutexGuard aGuard
;
238 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
239 auto pChartWindow(GetChartWindow());
241 if(xWindow
.is() && pChartWindow
)
243 Size aLogicSize
= pChartWindow
->PixelToLogic( Size( Width
, Height
), MapMode( MapUnit::Map100thMM
) );
245 //todo: for standalone chart: detect whether we are standalone
246 //change map mode to fit new size
247 awt::Size aModelPageSize
= ChartModelHelper::getPageSize( getModel() );
248 sal_Int32 nScaleXNumerator
= aLogicSize
.Width();
249 sal_Int32 nScaleXDenominator
= aModelPageSize
.Width
;
250 sal_Int32 nScaleYNumerator
= aLogicSize
.Height();
251 sal_Int32 nScaleYDenominator
= aModelPageSize
.Height
;
255 Fraction(nScaleXNumerator
, nScaleXDenominator
),
256 Fraction(nScaleYNumerator
, nScaleYDenominator
) );
257 pChartWindow
->SetMapMode(aNewMapMode
);
258 pChartWindow
->setPosSizePixel( X
, Y
, Width
, Height
, static_cast<PosSizeFlags
>(Flags
) );
260 //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
261 uno::Reference
< beans::XPropertySet
> xProp( m_xChartView
, uno::UNO_QUERY
);
264 auto aZoomFactors(::comphelper::InitPropertySequence({
265 { "ScaleXNumerator", uno::Any( nScaleXNumerator
) },
266 { "ScaleXDenominator", uno::Any( nScaleXDenominator
) },
267 { "ScaleYNumerator", uno::Any( nScaleYNumerator
) },
268 { "ScaleYDenominator", uno::Any( nScaleYDenominator
) }
270 xProp
->setPropertyValue( "ZoomFactors", uno::Any( aZoomFactors
));
273 //a correct work area is at least necessary for correct values in the position and size dialog and for dragging area
274 if(m_pDrawViewWrapper
)
276 tools::Rectangle
aRect(Point(0,0), pChartWindow
->GetOutputSize());
277 m_pDrawViewWrapper
->SetWorkArea( aRect
);
279 pChartWindow
->Invalidate();
283 awt::Rectangle SAL_CALL
ChartController::getPosSize()
286 awt::Rectangle
aRet(0, 0, 0, 0);
288 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
290 aRet
= xWindow
->getPosSize();
295 void SAL_CALL
ChartController::setVisible( sal_Bool Visible
)
298 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
301 xWindow
->setVisible( Visible
);
304 void SAL_CALL
ChartController::setEnable( sal_Bool Enable
)
307 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
310 xWindow
->setEnable( Enable
);
313 void SAL_CALL
ChartController::setFocus()
316 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
322 void SAL_CALL
ChartController::addWindowListener(
323 const uno::Reference
< awt::XWindowListener
>& xListener
)
326 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
329 xWindow
->addWindowListener( xListener
);
332 void SAL_CALL
ChartController::removeWindowListener(
333 const uno::Reference
< awt::XWindowListener
>& xListener
)
336 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
339 xWindow
->removeWindowListener( xListener
);
342 void SAL_CALL
ChartController::addFocusListener(
343 const uno::Reference
< awt::XFocusListener
>& xListener
)
346 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
349 xWindow
->addFocusListener( xListener
);
352 void SAL_CALL
ChartController::removeFocusListener(
353 const uno::Reference
< awt::XFocusListener
>& xListener
)
356 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
359 xWindow
->removeFocusListener( xListener
);
362 void SAL_CALL
ChartController::addKeyListener(
363 const uno::Reference
< awt::XKeyListener
>& xListener
)
366 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
369 xWindow
->addKeyListener( xListener
);
372 void SAL_CALL
ChartController::removeKeyListener(
373 const uno::Reference
< awt::XKeyListener
>& xListener
)
376 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
379 xWindow
->removeKeyListener( xListener
);
382 void SAL_CALL
ChartController::addMouseListener(
383 const uno::Reference
< awt::XMouseListener
>& xListener
)
386 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
389 xWindow
->addMouseListener( xListener
);
392 void SAL_CALL
ChartController::removeMouseListener(
393 const uno::Reference
< awt::XMouseListener
>& xListener
)
396 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
399 xWindow
->removeMouseListener( xListener
);
402 void SAL_CALL
ChartController::addMouseMotionListener(
403 const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
406 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
409 xWindow
->addMouseMotionListener( xListener
);
412 void SAL_CALL
ChartController::removeMouseMotionListener(
413 const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
416 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
419 xWindow
->removeMouseMotionListener( xListener
);
422 void SAL_CALL
ChartController::addPaintListener(
423 const uno::Reference
< awt::XPaintListener
>& xListener
)
426 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
429 xWindow
->addPaintListener( xListener
);
432 void SAL_CALL
ChartController::removePaintListener(
433 const uno::Reference
< awt::XPaintListener
>& xListener
)
436 uno::Reference
<awt::XWindow
> xWindow
= m_xViewWindow
;
439 xWindow
->removePaintListener( xListener
);
442 // impl vcl window controller methods
443 void ChartController::PrePaint()
445 // forward VCLs PrePaint window event to DrawingLayer
446 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
448 if (pDrawViewWrapper
)
450 pDrawViewWrapper
->PrePaint();
454 void ChartController::execute_Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
458 uno::Reference
<frame::XModel
> xModel(getModel());
459 //OSL_ENSURE( xModel.is(), "ChartController::execute_Paint: have no model to paint");
463 //better performance for big data
464 uno::Reference
<beans::XPropertySet
> xProp(m_xChartView
, uno::UNO_QUERY
);
467 awt::Size
aResolution(1000, 1000);
469 SolarMutexGuard aGuard
;
470 auto pChartWindow(GetChartWindow());
473 aResolution
.Width
= pChartWindow
->GetSizePixel().Width();
474 aResolution
.Height
= pChartWindow
->GetSizePixel().Height();
477 xProp
->setPropertyValue( "Resolution", uno::Any( aResolution
));
480 uno::Reference
< util::XUpdatable
> xUpdatable( m_xChartView
, uno::UNO_QUERY
);
482 xUpdatable
->update();
485 SolarMutexGuard aGuard
;
486 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
487 if (pDrawViewWrapper
)
488 pDrawViewWrapper
->CompleteRedraw(&rRenderContext
, vcl::Region(rRect
));
491 catch( const uno::Exception
& )
493 DBG_UNHANDLED_EXCEPTION("chart2");
500 static bool isDoubleClick( const MouseEvent
& rMEvt
)
502 return rMEvt
.GetClicks() == 2 && rMEvt
.IsLeft() &&
503 !rMEvt
.IsMod1() && !rMEvt
.IsMod2() && !rMEvt
.IsShift();
506 void ChartController::startDoubleClickWaiting()
508 SolarMutexGuard aGuard
;
510 m_bWaitingForDoubleClick
= true;
512 sal_uInt64 nDblClkTime
= 500;
513 auto pChartWindow(GetChartWindow());
516 const MouseSettings
& rMSettings
= pChartWindow
->GetSettings().GetMouseSettings();
517 nDblClkTime
= rMSettings
.GetDoubleClickTime();
519 m_aDoubleClickTimer
.SetTimeout( nDblClkTime
);
520 m_aDoubleClickTimer
.Start();
523 void ChartController::stopDoubleClickWaiting()
525 m_aDoubleClickTimer
.Stop();
526 m_bWaitingForDoubleClick
= false;
529 IMPL_LINK_NOARG(ChartController
, DoubleClickWaitingHdl
, Timer
*, void)
531 m_bWaitingForDoubleClick
= false;
533 if( !m_bWaitingForMouseUp
&& m_aSelection
.maybeSwitchSelectionAfterSingleClickWasEnsured() )
535 impl_selectObjectAndNotiy();
536 SolarMutexGuard aGuard
;
537 auto pChartWindow(GetChartWindow());
540 vcl::Window::PointerState
aPointerState( pChartWindow
->GetPointerState() );
541 MouseEvent
aMouseEvent(
544 MouseEventModifiers::NONE
,
545 static_cast< sal_uInt16
>( aPointerState
.mnState
)/*nButtons*/,
547 impl_SetMousePointer( aMouseEvent
);
552 void ChartController::execute_MouseButtonDown( const MouseEvent
& rMEvt
)
554 SolarMutexGuard aGuard
;
556 m_bWaitingForMouseUp
= true;
557 m_bFieldButtonDown
= false;
559 if( isDoubleClick(rMEvt
) )
560 stopDoubleClickWaiting();
562 startDoubleClickWaiting();
564 m_aSelection
.remindSelectionBeforeMouseDown();
566 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
567 auto pChartWindow(GetChartWindow());
568 if(!pChartWindow
|| !pDrawViewWrapper
)
571 Point aMPos
= pChartWindow
->PixelToLogic(rMEvt
.GetPosPixel());
573 // Check if button was clicked
574 SdrObject
* pObject
= pDrawViewWrapper
->getHitObject(aMPos
);
577 OUString aCID
= pObject
->GetName();
578 if (aCID
.startsWith("FieldButton"))
580 m_bFieldButtonDown
= true;
581 return; // Don't take any action if button was clicked
585 if ( rMEvt
.GetButtons() == MOUSE_LEFT
)
587 pChartWindow
->GrabFocus();
588 pChartWindow
->CaptureMouse();
591 if( pDrawViewWrapper
->IsTextEdit() )
594 if ( pDrawViewWrapper
->IsTextEditHit( aMPos
) ||
595 // #i12587# support for shapes in chart
596 ( rMEvt
.IsRight() && pDrawViewWrapper
->PickAnything( rMEvt
, SdrMouseEventKind::BUTTONDOWN
, aVEvt
) == SdrHitKind::MarkedObject
) )
598 pDrawViewWrapper
->MouseButtonDown(rMEvt
, pChartWindow
);
607 //abort running action
608 if( pDrawViewWrapper
->IsAction() )
610 if( rMEvt
.IsRight() )
611 pDrawViewWrapper
->BckAction();
615 if( isDoubleClick(rMEvt
) ) //do not change selection if double click
616 return;//double click is handled further in mousebutton up
618 SdrHdl
* pHitSelectionHdl
= nullptr;
619 //switch from move to resize if handle is hit on a resizable object
620 if( m_aSelection
.isResizeableObjectSelected() )
621 pHitSelectionHdl
= pDrawViewWrapper
->PickHandle( aMPos
);
622 //only change selection if no selection handles are hit
623 if( !pHitSelectionHdl
)
625 // #i12587# support for shapes in chart
626 if ( m_eDrawMode
== CHARTDRAW_INSERT
&&
627 ( !pDrawViewWrapper
->IsMarkedHit( aMPos
) || !m_aSelection
.isDragableObjectSelected() ) )
629 if ( m_aSelection
.hasSelection() )
631 m_aSelection
.clearSelection();
633 if ( !pDrawViewWrapper
->IsAction() )
635 if ( pDrawViewWrapper
->GetCurrentObjIdentifier() == OBJ_CAPTION
)
637 Size
aCaptionSize( 2268, 1134 );
638 pDrawViewWrapper
->BegCreateCaptionObj( aMPos
, aCaptionSize
);
642 pDrawViewWrapper
->BegCreateObj( aMPos
);
644 SdrObject
* pObj
= pDrawViewWrapper
->GetCreateObj();
645 DrawCommandDispatch
* pDrawCommandDispatch
= m_aDispatchContainer
.getDrawCommandDispatch();
646 if ( pObj
&& m_pDrawModelWrapper
&& pDrawCommandDispatch
)
648 SfxItemSet
aSet( m_pDrawModelWrapper
->GetItemPool() );
649 pDrawCommandDispatch
->setAttributes( pObj
);
650 pDrawCommandDispatch
->setLineEnds( aSet
);
651 pObj
->SetMergedItemSet( aSet
);
654 impl_SetMousePointer( rMEvt
);
658 m_aSelection
.adaptSelectionToNewPos(
662 m_bWaitingForDoubleClick
);
664 if( !m_aSelection
.isRotateableObjectSelected( getModel() ) )
666 m_eDragMode
= SdrDragMode::Move
;
667 pDrawViewWrapper
->SetDragMode(m_eDragMode
);
670 m_aSelection
.applySelection(pDrawViewWrapper
);
672 if( m_aSelection
.isDragableObjectSelected()
673 && !rMEvt
.IsRight() )
676 sal_uInt16 nDrgLog
= static_cast<sal_uInt16
>(pChartWindow
->PixelToLogic(Size(DRGPIX
,0)).Width());
677 SdrDragMethod
* pDragMethod
= nullptr;
679 //change selection to 3D scene if rotate mode
680 SdrDragMode eDragMode
= pDrawViewWrapper
->GetDragMode();
681 if( eDragMode
==SdrDragMode::Rotate
)
683 E3dScene
* pScene
= SelectionHelper::getSceneToRotate( pDrawViewWrapper
->getNamedSdrObject( m_aSelection
.getSelectedCID() ) );
686 DragMethod_RotateDiagram::RotationDirection
eRotationDirection(DragMethod_RotateDiagram::ROTATIONDIRECTION_FREE
);
689 SdrHdlKind eKind
= pHitSelectionHdl
->GetKind();
690 if( eKind
==SdrHdlKind::Upper
|| eKind
==SdrHdlKind::Lower
)
691 eRotationDirection
= DragMethod_RotateDiagram::ROTATIONDIRECTION_X
;
692 else if( eKind
==SdrHdlKind::Left
|| eKind
==SdrHdlKind::Right
)
693 eRotationDirection
= DragMethod_RotateDiagram::ROTATIONDIRECTION_Y
;
694 else if( eKind
==SdrHdlKind::UpperLeft
|| eKind
==SdrHdlKind::UpperRight
|| eKind
==SdrHdlKind::LowerLeft
|| eKind
==SdrHdlKind::LowerRight
)
695 eRotationDirection
= DragMethod_RotateDiagram::ROTATIONDIRECTION_Z
;
697 pDragMethod
= new DragMethod_RotateDiagram( *pDrawViewWrapper
, m_aSelection
.getSelectedCID(), getModel(), eRotationDirection
);
702 OUString
aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( m_aSelection
.getSelectedCID() ) );
703 if( aDragMethodServiceName
== ObjectIdentifier::getPieSegmentDragMethodServiceName() )
704 pDragMethod
= new DragMethod_PieSegment( *pDrawViewWrapper
, m_aSelection
.getSelectedCID(), getModel() );
706 pDrawViewWrapper
->SdrView::BegDragObj(aMPos
, nullptr, pHitSelectionHdl
, nDrgLog
, pDragMethod
);
709 impl_SetMousePointer( rMEvt
);
712 void ChartController::execute_MouseMove( const MouseEvent
& rMEvt
)
714 SolarMutexGuard aGuard
;
716 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
717 auto pChartWindow(GetChartWindow());
718 if(!pChartWindow
|| !pDrawViewWrapper
)
721 if( m_pDrawViewWrapper
->IsTextEdit() )
723 if( m_pDrawViewWrapper
->MouseMove(rMEvt
,pChartWindow
) )
727 if(pDrawViewWrapper
->IsAction())
729 pDrawViewWrapper
->MovAction( pChartWindow
->PixelToLogic( rMEvt
.GetPosPixel() ) );
732 impl_SetMousePointer( rMEvt
);
735 void ChartController::execute_MouseButtonUp( const MouseEvent
& rMEvt
)
737 ControllerLockGuardUNO
aCLGuard( getModel() );
738 bool bMouseUpWithoutMouseDown
= !m_bWaitingForMouseUp
;
739 m_bWaitingForMouseUp
= false;
740 bool bNotifySelectionChange
= false;
742 SolarMutexGuard aGuard
;
744 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
745 auto pChartWindow(GetChartWindow());
746 if(!pChartWindow
|| !pDrawViewWrapper
)
749 Point aMPos
= pChartWindow
->PixelToLogic(rMEvt
.GetPosPixel());
751 // Check if button was clicked
752 if (m_bFieldButtonDown
)
754 m_bFieldButtonDown
= false;
755 SdrObject
* pObject
= pDrawViewWrapper
->getHitObject(aMPos
);
758 OUString aCID
= pObject
->GetName();
759 if (aCID
.startsWith("FieldButton"))
761 sendPopupRequest(aCID
, pObject
->GetCurrentBoundRect());
767 if(pDrawViewWrapper
->IsTextEdit())
769 if( pDrawViewWrapper
->MouseButtonUp(rMEvt
,pChartWindow
) )
773 // #i12587# support for shapes in chart
774 if ( m_eDrawMode
== CHARTDRAW_INSERT
&& pDrawViewWrapper
->IsCreateObj() )
776 pDrawViewWrapper
->EndCreateObj( SdrCreateCmd::ForceEnd
);
778 HiddenUndoContext
aUndoContext( m_xUndoManager
);
779 // don't want the positioning Undo action to appear in the UI
780 impl_switchDiagramPositioningToExcludingPositioning();
782 if ( pDrawViewWrapper
->AreObjectsMarked() )
784 if ( pDrawViewWrapper
->GetCurrentObjIdentifier() == OBJ_TEXT
)
786 executeDispatch_EditText();
790 SdrObject
* pObj
= pDrawViewWrapper
->getSelectedObject();
793 uno::Reference
< drawing::XShape
> xShape( pObj
->getUnoShape(), uno::UNO_QUERY
);
796 m_aSelection
.setSelection( xShape
);
797 m_aSelection
.applySelection( pDrawViewWrapper
);
804 m_aSelection
.adaptSelectionToNewPos( aMPos
, pDrawViewWrapper
, rMEvt
.IsRight(), m_bWaitingForDoubleClick
);
805 m_aSelection
.applySelection( pDrawViewWrapper
);
806 setDrawMode( CHARTDRAW_SELECT
);
809 else if ( pDrawViewWrapper
->IsDragObj() )
811 bool bDraggingDone
= false;
812 SdrDragMethod
* pDragMethod
= pDrawViewWrapper
->SdrView::GetDragMethod();
813 bool bIsMoveOnly
= pDragMethod
&& pDragMethod
->getMoveOnly();
814 DragMethod_Base
* pChartDragMethod
= dynamic_cast< DragMethod_Base
* >(pDragMethod
);
815 if( pChartDragMethod
)
817 UndoGuard
aUndoGuard( pChartDragMethod
->getUndoDescription(),
820 if( pDrawViewWrapper
->EndDragObj() )
822 bDraggingDone
= true;
827 if( !bDraggingDone
&& pDrawViewWrapper
->EndDragObj() )
832 SdrObject
* pObj
= pDrawViewWrapper
->getSelectedObject();
835 tools::Rectangle aObjectRect
= pObj
->GetSnapRect();
836 awt::Size
aPageSize( ChartModelHelper::getPageSize( getModel() ) );
837 tools::Rectangle
aPageRect( 0,0,aPageSize
.Width
,aPageSize
.Height
);
839 const E3dObject
* pE3dObject(dynamic_cast< const E3dObject
*>(pObj
));
840 if(nullptr != pE3dObject
)
842 E3dScene
* pScene(pE3dObject
->getRootE3dSceneFromE3dObject());
843 if(nullptr != pScene
)
845 aObjectRect
= pScene
->GetSnapRect();
849 ActionDescriptionProvider::ActionType
eActionType(ActionDescriptionProvider::ActionType::Move
);
850 if( !bIsMoveOnly
&& m_aSelection
.isResizeableObjectSelected() )
851 eActionType
= ActionDescriptionProvider::ActionType::Resize
;
853 ObjectType eObjectType
= ObjectIdentifier::getObjectType( m_aSelection
.getSelectedCID() );
855 UndoGuard
aUndoGuard(
856 ActionDescriptionProvider::createDescription( eActionType
, ObjectNameProvider::getName( eObjectType
)),
859 bool bChanged
= false;
860 ChartModel
* pModel
= dynamic_cast<ChartModel
*>(getModel().get());
862 if ( eObjectType
== OBJECTTYPE_LEGEND
)
863 bChanged
= DiagramHelper::switchDiagramPositioningToExcludingPositioning( *pModel
, false , true );
865 bool bMoved
= PositionAndSizeHelper::moveObject( m_aSelection
.getSelectedCID()
867 , awt::Rectangle(aObjectRect
.getX(),aObjectRect
.getY(),aObjectRect
.getWidth(),aObjectRect
.getHeight())
868 , awt::Rectangle(aPageRect
.getX(),aPageRect
.getY(),aPageRect
.getWidth(),aPageRect
.getHeight()) );
870 if( bMoved
|| bChanged
)
872 bDraggingDone
= true;
877 catch( const uno::Exception
& )
879 DBG_UNHANDLED_EXCEPTION("chart2");
881 //all wanted model changes will take effect
882 //and all unwanted view modifications are cleaned
885 if( !bDraggingDone
) //mouse wasn't moved while dragging
887 bool bClickedTwiceOnDragableObject
= SelectionHelper::isDragableObjectHitTwice( aMPos
, m_aSelection
.getSelectedCID(), *pDrawViewWrapper
);
888 bool bIsRotateable
= m_aSelection
.isRotateableObjectSelected( getModel() );
890 //toggle between move and rotate
891 if( bIsRotateable
&& bClickedTwiceOnDragableObject
&& m_eDragMode
==SdrDragMode::Move
)
892 m_eDragMode
=SdrDragMode::Rotate
;
894 m_eDragMode
=SdrDragMode::Move
;
896 pDrawViewWrapper
->SetDragMode(m_eDragMode
);
898 if( !m_bWaitingForDoubleClick
&& m_aSelection
.maybeSwitchSelectionAfterSingleClickWasEnsured() )
900 impl_selectObjectAndNotiy();
904 m_aSelection
.resetPossibleSelectionAfterSingleClickWasEnsured();
907 //@todo ForcePointer(&rMEvt);
908 pChartWindow
->ReleaseMouse();
910 // In tiled rendering drag mode could be not yet over on the call
911 // that should handle the double-click, so better to perform this check
913 if( isDoubleClick(rMEvt
) && !bMouseUpWithoutMouseDown
/*#i106966#*/ )
915 Point aMousePixel
= rMEvt
.GetPosPixel();
916 execute_DoubleClick( &aMousePixel
);
919 if( m_aSelection
.isSelectionDifferentFromBeforeMouseDown() )
920 bNotifySelectionChange
= true;
923 impl_SetMousePointer( rMEvt
);
925 if(bNotifySelectionChange
)
926 impl_notifySelectionChangeListeners();
929 void ChartController::execute_DoubleClick( const Point
* pMousePixel
)
931 bool isMobile
= comphelper::LibreOfficeKit::isMobile(SfxLokHelper::getView());
935 bool bEditText
= false;
936 if ( m_aSelection
.hasSelection() )
938 OUString
aCID( m_aSelection
.getSelectedCID() );
939 if ( !aCID
.isEmpty() )
941 ObjectType eObjectType
= ObjectIdentifier::getObjectType( aCID
);
942 if ( eObjectType
== OBJECTTYPE_TITLE
)
949 // #i12587# support for shapes in chart
950 SdrObject
* pObj
= DrawViewWrapper::getSdrObject( m_aSelection
.getSelectedAdditionalShape() );
951 if ( dynamic_cast< const SdrTextObj
* >(pObj
) != nullptr )
960 executeDispatch_EditText( pMousePixel
);
964 executeDispatch_ObjectProperties();
968 void ChartController::execute_Resize()
970 SolarMutexGuard aGuard
;
971 auto pChartWindow(GetChartWindow());
973 pChartWindow
->Invalidate();
976 void ChartController::execute_Command( const CommandEvent
& rCEvt
)
978 SolarMutexGuard aGuard
;
979 auto pChartWindow(GetChartWindow());
980 bool bIsAction
= false;
982 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
983 if(!pChartWindow
|| !pDrawViewWrapper
)
985 bIsAction
= m_pDrawViewWrapper
->IsAction();
989 if(rCEvt
.GetCommand() == CommandEventId::ContextMenu
&& !bIsAction
)
993 pChartWindow
->ReleaseMouse();
996 if( m_aSelection
.isSelectionDifferentFromBeforeMouseDown() )
997 impl_notifySelectionChangeListeners();
999 css::uno::Reference
< css::awt::XPopupMenu
> xPopupMenu( m_xCC
->getServiceManager()->createInstanceWithContext(
1000 "com.sun.star.awt.PopupMenu", m_xCC
), css::uno::UNO_QUERY
);
1002 Point
aPos( rCEvt
.GetMousePosPixel() );
1003 if( !rCEvt
.IsMouseEvent() )
1006 aPos
= pChartWindow
->GetPointerState().maPos
;
1010 if ( isShapeContext() )
1011 // #i12587# support for shapes in chart
1012 aMenuName
= m_pDrawViewWrapper
->IsTextEdit() ? OUString( "drawtext" ) : OUString( "draw" );
1015 // todo: the context menu should be specified by an xml file in uiconfig
1016 if( xPopupMenu
.is())
1018 sal_Int16 nUniqueId
= 1;
1019 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:Cut" );
1020 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:Copy" );
1021 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:Paste" );
1022 xPopupMenu
->insertSeparator( -1 );
1024 ObjectType eObjectType
= ObjectIdentifier::getObjectType( m_aSelection
.getSelectedCID() );
1025 Reference
< XDiagram
> xDiagram
= ChartModelHelper::findDiagram( getModel() );
1027 OUString
aFormatCommand( lcl_getFormatCommandForObjectCID( m_aSelection
.getSelectedCID() ) );
1028 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, aFormatCommand
);
1030 //some commands for dataseries and points:
1032 if( eObjectType
== OBJECTTYPE_DATA_SERIES
|| eObjectType
== OBJECTTYPE_DATA_POINT
)
1034 bool bIsPoint
= ( eObjectType
== OBJECTTYPE_DATA_POINT
);
1035 uno::Reference
< XDataSeries
> xSeries
= ObjectIdentifier::getDataSeriesForCID( m_aSelection
.getSelectedCID(), getModel() );
1036 uno::Reference
< chart2::XRegressionCurveContainer
> xCurveCnt( xSeries
, uno::UNO_QUERY
);
1037 Reference
< chart2::XRegressionCurve
> xTrendline( RegressionCurveHelper::getFirstCurveNotMeanValueLine( xCurveCnt
) );
1038 bool bHasEquation
= RegressionCurveHelper::hasEquation( xTrendline
);
1039 Reference
< chart2::XRegressionCurve
> xMeanValue( RegressionCurveHelper::getMeanValueLine( xCurveCnt
) );
1040 bool bHasYErrorBars
= StatisticsHelper::hasErrorBars( xSeries
);
1041 bool bHasXErrorBars
= StatisticsHelper::hasErrorBars( xSeries
, false );
1042 bool bHasDataLabelsAtSeries
= DataSeriesHelper::hasDataLabelsAtSeries( xSeries
);
1043 bool bHasDataLabelsAtPoints
= DataSeriesHelper::hasDataLabelsAtPoints( xSeries
);
1044 bool bHasDataLabelAtPoint
= false;
1045 sal_Int32 nPointIndex
= -1;
1048 nPointIndex
= ObjectIdentifier::getIndexFromParticleOrCID( m_aSelection
.getSelectedCID() );
1049 bHasDataLabelAtPoint
= DataSeriesHelper::hasDataLabelAtPoint( xSeries
, nPointIndex
);
1051 bool bSelectedPointIsFormatted
= false;
1052 bool bHasFormattedDataPointsOtherThanSelected
= false;
1054 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
1055 if( xSeriesProperties
.is() )
1057 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
1058 if( xSeriesProperties
->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList
)
1060 if( aAttributedDataPointIndexList
.hasElements() )
1064 auto aIndices( comphelper::sequenceToContainer
<std::vector
< sal_Int32
>>( aAttributedDataPointIndexList
) );
1065 std::vector
< sal_Int32
>::iterator aIt
= std::find( aIndices
.begin(), aIndices
.end(), nPointIndex
);
1066 if( aIt
!= aIndices
.end())
1067 bSelectedPointIsFormatted
= true;
1069 bHasFormattedDataPointsOtherThanSelected
= true;
1072 bHasFormattedDataPointsOtherThanSelected
= true;
1079 if( bHasDataLabelAtPoint
)
1080 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatDataLabel" );
1081 if( !bHasDataLabelAtPoint
)
1082 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertDataLabel" );
1084 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteDataLabel" );
1085 if( bSelectedPointIsFormatted
)
1086 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:ResetDataPoint" );
1088 xPopupMenu
->insertSeparator( -1 );
1090 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatDataSeries" );
1093 Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram
, xSeries
) );
1094 if( xChartType
->getChartType() == CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK
)
1098 Reference
< beans::XPropertySet
> xChartTypeProp( xChartType
, uno::UNO_QUERY
);
1099 if( xChartTypeProp
.is() )
1101 bool bJapaneseStyle
= false;
1102 xChartTypeProp
->getPropertyValue( "Japanese" ) >>= bJapaneseStyle
;
1104 if( bJapaneseStyle
)
1106 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatStockLoss" );
1107 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatStockGain" );
1111 catch( const uno::Exception
& )
1113 DBG_UNHANDLED_EXCEPTION("chart2");
1117 if( bHasDataLabelsAtSeries
)
1118 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatDataLabels" );
1120 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatTrendlineEquation" );
1121 if( xMeanValue
.is() )
1122 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatMeanValue" );
1123 if( bHasXErrorBars
)
1124 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatXErrorBars" );
1125 if( bHasYErrorBars
)
1126 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatYErrorBars" );
1128 xPopupMenu
->insertSeparator( -1 );
1130 if( !bHasDataLabelsAtSeries
)
1131 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertDataLabels" );
1133 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertTrendline" );
1135 if( !xMeanValue
.is() )
1136 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertMeanValue" );
1137 if( !bHasXErrorBars
)
1138 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertXErrorBars" );
1139 if( !bHasYErrorBars
)
1140 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertYErrorBars" );
1141 if( bHasDataLabelsAtSeries
|| ( bHasDataLabelsAtPoints
&& bHasFormattedDataPointsOtherThanSelected
) )
1142 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteDataLabels" );
1144 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteTrendlineEquation" );
1145 if( xMeanValue
.is() )
1146 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteMeanValue" );
1147 if( bHasXErrorBars
)
1148 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteXErrorBars" );
1149 if( bHasYErrorBars
)
1150 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteYErrorBars" );
1152 if( bHasFormattedDataPointsOtherThanSelected
)
1153 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:ResetAllDataPoints" );
1155 xPopupMenu
->insertSeparator( -1 );
1157 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
, ".uno:ArrangeRow" );
1158 uno::Reference
< awt::XPopupMenu
> xArrangePopupMenu(
1159 m_xCC
->getServiceManager()->createInstanceWithContext(
1160 "com.sun.star.awt.PopupMenu", m_xCC
), uno::UNO_QUERY
);
1161 if( xArrangePopupMenu
.is() )
1163 sal_Int16 nSubId
= nUniqueId
+ 1;
1164 lcl_insertMenuCommand( xArrangePopupMenu
, nSubId
++, ".uno:Forward" );
1165 lcl_insertMenuCommand( xArrangePopupMenu
, nSubId
, ".uno:Backward" );
1166 xPopupMenu
->setPopupMenu( nUniqueId
, xArrangePopupMenu
);
1171 else if( eObjectType
== OBJECTTYPE_DATA_CURVE
)
1173 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteTrendline" );
1174 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatTrendlineEquation" );
1175 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertTrendlineEquation" );
1176 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertTrendlineEquationAndR2" );
1177 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertR2Value" );
1178 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteTrendlineEquation" );
1179 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteR2Value" );
1181 else if( eObjectType
== OBJECTTYPE_DATA_CURVE_EQUATION
)
1183 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertR2Value" );
1184 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteR2Value" );
1187 //some commands for axes: and grids
1189 else if( eObjectType
== OBJECTTYPE_AXIS
|| eObjectType
== OBJECTTYPE_GRID
|| eObjectType
== OBJECTTYPE_SUBGRID
)
1191 Reference
< XAxis
> xAxis
= ObjectIdentifier::getAxisForCID( m_aSelection
.getSelectedCID(), getModel() );
1192 if( xAxis
.is() && xDiagram
.is() )
1194 sal_Int32 nDimensionIndex
= -1;
1195 sal_Int32 nCooSysIndex
= -1;
1196 sal_Int32 nAxisIndex
= -1;
1197 AxisHelper::getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
);
1198 bool bIsSecondaryAxis
= nAxisIndex
!=0;
1199 bool bIsAxisVisible
= AxisHelper::isAxisVisible( xAxis
);
1200 bool bIsMajorGridVisible
= AxisHelper::isGridShown( nDimensionIndex
, nCooSysIndex
, true /*bMainGrid*/, xDiagram
);
1201 bool bIsMinorGridVisible
= AxisHelper::isGridShown( nDimensionIndex
, nCooSysIndex
, false /*bMainGrid*/, xDiagram
);
1202 bool bHasTitle
= false;
1203 uno::Reference
< XTitled
> xTitled( xAxis
, uno::UNO_QUERY
);
1205 bHasTitle
= !TitleHelper::getCompleteString( xTitled
->getTitleObject() ).isEmpty();
1207 if( eObjectType
!= OBJECTTYPE_AXIS
&& bIsAxisVisible
)
1208 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatAxis" );
1209 if( eObjectType
!= OBJECTTYPE_GRID
&& bIsMajorGridVisible
&& !bIsSecondaryAxis
)
1210 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatMajorGrid" );
1211 if( eObjectType
!= OBJECTTYPE_SUBGRID
&& bIsMinorGridVisible
&& !bIsSecondaryAxis
)
1212 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatMinorGrid" );
1214 xPopupMenu
->insertSeparator( -1 );
1216 if( eObjectType
!= OBJECTTYPE_AXIS
&& !bIsAxisVisible
)
1217 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertAxis" );
1218 if( eObjectType
!= OBJECTTYPE_GRID
&& !bIsMajorGridVisible
&& !bIsSecondaryAxis
)
1219 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertMajorGrid" );
1220 if( eObjectType
!= OBJECTTYPE_SUBGRID
&& !bIsMinorGridVisible
&& !bIsSecondaryAxis
)
1221 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertMinorGrid" );
1223 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertAxisTitle" );
1225 if( bIsAxisVisible
)
1226 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteAxis" );
1227 if( bIsMajorGridVisible
&& !bIsSecondaryAxis
)
1228 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteMajorGrid" );
1229 if( bIsMinorGridVisible
&& !bIsSecondaryAxis
)
1230 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteMinorGrid" );
1234 if( eObjectType
== OBJECTTYPE_DATA_STOCK_LOSS
)
1235 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatStockGain" );
1236 else if( eObjectType
== OBJECTTYPE_DATA_STOCK_GAIN
)
1237 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:FormatStockLoss" );
1239 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:TransformDialog" );
1241 if( eObjectType
== OBJECTTYPE_PAGE
|| eObjectType
== OBJECTTYPE_DIAGRAM
1242 || eObjectType
== OBJECTTYPE_DIAGRAM_WALL
1243 || eObjectType
== OBJECTTYPE_DIAGRAM_FLOOR
1244 || eObjectType
== OBJECTTYPE_UNKNOWN
)
1246 if( eObjectType
!= OBJECTTYPE_UNKNOWN
)
1247 xPopupMenu
->insertSeparator( -1 );
1248 bool bHasLegend
= LegendHelper::hasLegend( xDiagram
);
1249 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertTitles" );
1251 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertLegend" );
1252 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:InsertRemoveAxes" );
1254 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DeleteLegend" );
1257 xPopupMenu
->insertSeparator( -1 );
1258 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DiagramType" );
1259 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DataRanges" );
1260 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:DiagramData" );
1261 lcl_insertMenuCommand( xPopupMenu
, nUniqueId
++, ".uno:View3D" );
1265 css::uno::Sequence
< css::uno::Any
> aArgs( 3 );
1266 aArgs
[0] <<= comphelper::makePropertyValue( "IsContextMenu", true );
1267 aArgs
[1] <<= comphelper::makePropertyValue( "Frame", m_xFrame
);
1268 aArgs
[2] <<= comphelper::makePropertyValue( "Value", aMenuName
);
1270 css::uno::Reference
< css::frame::XPopupMenuController
> xPopupController(
1271 m_xCC
->getServiceManager()->createInstanceWithArgumentsAndContext(
1272 "com.sun.star.comp.framework.ResourceMenuController", aArgs
, m_xCC
), css::uno::UNO_QUERY
);
1274 if ( !xPopupController
.is() || !xPopupMenu
.is() )
1277 if (comphelper::LibreOfficeKit::isActive())
1279 PopupMenu
* pPopupMenu
= static_cast<PopupMenu
*>(comphelper::getUnoTunnelImplementation
<VCLXMenu
>(xPopupMenu
)->GetMenu());
1280 pPopupMenu
->SetLOKNotifier(SfxViewShell::Current());
1282 // the context menu expects a position related to the document window,
1283 // not to the chart window
1284 SfxInPlaceClient
* pIPClient
= SfxViewShell::Current()->GetIPClient();
1287 vcl::Window
* pRootWin
= pIPClient
->GetEditWin();
1290 Point aOffset
= pChartWindow
->GetOffsetPixelFrom(*pRootWin
);
1296 xPopupController
->setPopupMenu( xPopupMenu
);
1297 xPopupMenu
->execute( css::uno::Reference
< css::awt::XWindowPeer
>( m_xFrame
->getContainerWindow(), css::uno::UNO_QUERY
),
1298 css::awt::Rectangle( aPos
.X(), aPos
.Y(), 0, 0 ),
1299 css::awt::PopupMenuDirection::EXECUTE_DEFAULT
);
1301 css::uno::Reference
< css::lang::XComponent
> xComponent( xPopupController
, css::uno::UNO_QUERY
);
1302 if ( xComponent
.is() )
1303 xComponent
->dispose();
1305 else if( ( rCEvt
.GetCommand() == CommandEventId::StartExtTextInput
) ||
1306 ( rCEvt
.GetCommand() == CommandEventId::ExtTextInput
) ||
1307 ( rCEvt
.GetCommand() == CommandEventId::EndExtTextInput
) ||
1308 ( rCEvt
.GetCommand() == CommandEventId::InputContextChange
) )
1310 //#i84417# enable editing with IME
1311 if( m_pDrawViewWrapper
)
1312 m_pDrawViewWrapper
->Command( rCEvt
, pChartWindow
);
1316 bool ChartController::execute_KeyInput( const KeyEvent
& rKEvt
)
1318 SolarMutexGuard aGuard
;
1321 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
1322 auto pChartWindow(GetChartWindow());
1323 if (!pChartWindow
|| !pDrawViewWrapper
)
1326 // handle accelerators
1327 if (!m_apAccelExecute
&& m_xFrame
.is() && m_xCC
.is())
1329 m_apAccelExecute
= ::svt::AcceleratorExecute::createAcceleratorHelper();
1330 OSL_ASSERT(m_apAccelExecute
);
1331 if (m_apAccelExecute
)
1332 m_apAccelExecute
->init( m_xCC
, m_xFrame
);
1335 vcl::KeyCode
aKeyCode( rKEvt
.GetKeyCode());
1336 sal_uInt16 nCode
= aKeyCode
.GetCode();
1337 bool bAlternate
= aKeyCode
.IsMod2();
1338 bool bCtrl
= aKeyCode
.IsMod1();
1340 if (m_apAccelExecute
)
1341 bReturn
= m_apAccelExecute
->execute( aKeyCode
);
1346 if( pDrawViewWrapper
->IsTextEdit() )
1348 if( pDrawViewWrapper
->KeyInput(rKEvt
, pChartWindow
) )
1351 if( nCode
== KEY_ESCAPE
)
1359 // keyboard accessibility
1360 ObjectType eObjectType
= ObjectIdentifier::getObjectType( m_aSelection
.getSelectedCID() );
1363 // Navigation (Tab/F3/Home/End)
1364 uno::Reference
< XChartDocument
> xChartDoc( getModel(), uno::UNO_QUERY
);
1365 ObjectKeyNavigation
aObjNav( m_aSelection
.getSelectedOID(), xChartDoc
, comphelper::getUnoTunnelImplementation
<ExplicitValueProvider
>( m_xChartView
));
1366 awt::KeyEvent
aKeyEvent( ::svt::AcceleratorExecute::st_VCLKey2AWTKey( aKeyCode
));
1367 bReturn
= aObjNav
.handleKeyEvent( aKeyEvent
);
1370 const ObjectIdentifier
& aNewOID
= aObjNav
.getCurrentSelection();
1371 uno::Any aNewSelection
;
1372 if ( aNewOID
.isValid() && !ObjectHierarchy::isRootNode( aNewOID
) )
1374 aNewSelection
= aNewOID
.getAny();
1376 if ( m_eDragMode
== SdrDragMode::Rotate
&& !SelectionHelper::isRotateableObject( aNewOID
.getObjectCID(), getModel() ) )
1378 m_eDragMode
= SdrDragMode::Move
;
1380 bReturn
= select( aNewSelection
);
1384 // Position and Size (+/-/arrow-keys) or pie segment dragging
1387 // pie segment dragging
1388 // note: could also be done for data series
1389 if( eObjectType
== OBJECTTYPE_DATA_POINT
&&
1390 ObjectIdentifier::getDragMethodServiceName( m_aSelection
.getSelectedCID() ) ==
1391 ObjectIdentifier::getPieSegmentDragMethodServiceName())
1394 bool bDragInside
= false;
1395 if( nCode
== KEY_ADD
||
1396 nCode
== KEY_SUBTRACT
)
1399 bDragInside
= ( nCode
== KEY_SUBTRACT
);
1402 nCode
== KEY_LEFT
||
1403 nCode
== KEY_RIGHT
||
1408 OUString
aParameter( ObjectIdentifier::getDragParameterString( m_aSelection
.getSelectedCID() ));
1409 sal_Int32
nOffsetPercentDummy( 0 );
1410 awt::Point
aMinimumPosition( 0, 0 );
1411 awt::Point
aMaximumPosition( 0, 0 );
1412 ObjectIdentifier::parsePieSegmentDragParameterString(
1413 aParameter
, nOffsetPercentDummy
, aMinimumPosition
, aMaximumPosition
);
1414 aMaximumPosition
.Y
-= aMinimumPosition
.Y
;
1415 aMaximumPosition
.X
-= aMinimumPosition
.X
;
1418 (nCode
== KEY_RIGHT
&& (aMaximumPosition
.X
< 0)) ||
1419 (nCode
== KEY_LEFT
&& (aMaximumPosition
.X
> 0)) ||
1420 (nCode
== KEY_DOWN
&& (aMaximumPosition
.Y
< 0)) ||
1421 (nCode
== KEY_UP
&& (aMaximumPosition
.Y
> 0));
1426 double fAmount
= bAlternate
? 0.01 : 0.05;
1430 bReturn
= impl_DragDataPoint( m_aSelection
.getSelectedCID(), fAmount
);
1436 if( nCode
== KEY_ADD
||
1437 nCode
== KEY_SUBTRACT
)
1439 if( eObjectType
== OBJECTTYPE_DIAGRAM
)
1441 // default 1 mm in each direction
1442 double fGrowAmountX
= 200.0;
1443 double fGrowAmountY
= 200.0;
1446 // together with Alt-key: 1 px in each direction
1447 Size aPixelSize
= pChartWindow
->PixelToLogic( Size( 2, 2 ));
1448 fGrowAmountX
= static_cast< double >( aPixelSize
.Width());
1449 fGrowAmountY
= static_cast< double >( aPixelSize
.Height());
1451 if( nCode
== KEY_SUBTRACT
)
1453 fGrowAmountX
= -fGrowAmountX
;
1454 fGrowAmountY
= -fGrowAmountY
;
1456 bReturn
= impl_moveOrResizeObject(
1457 m_aSelection
.getSelectedCID(), CENTERED_RESIZE_OBJECT
, fGrowAmountX
, fGrowAmountY
);
1461 else if( nCode
== KEY_LEFT
||
1462 nCode
== KEY_RIGHT
||
1466 if( m_aSelection
.isDragableObjectSelected() )
1469 double fShiftAmountX
= 100.0;
1470 double fShiftAmountY
= 100.0;
1473 // together with Alt-key: 1 px
1474 Size aPixelSize
= pChartWindow
->PixelToLogic( Size( 1, 1 ));
1475 fShiftAmountX
= static_cast< double >( aPixelSize
.Width());
1476 fShiftAmountY
= static_cast< double >( aPixelSize
.Height());
1481 fShiftAmountX
= -fShiftAmountX
;
1482 fShiftAmountY
= 0.0;
1485 fShiftAmountY
= 0.0;
1488 fShiftAmountX
= 0.0;
1489 fShiftAmountY
= -fShiftAmountY
;
1492 fShiftAmountX
= 0.0;
1495 if( !m_aSelection
.getSelectedCID().isEmpty() )
1497 //move chart objects
1498 bReturn
= impl_moveOrResizeObject(
1499 m_aSelection
.getSelectedCID(), MOVE_OBJECT
, fShiftAmountX
, fShiftAmountY
);
1503 //move additional shapes
1504 uno::Reference
< drawing::XShape
> xShape( m_aSelection
.getSelectedAdditionalShape() );
1507 awt::Point
aPos( xShape
->getPosition() );
1508 awt::Size
aSize( xShape
->getSize() );
1509 awt::Size
aPageSize( ChartModelHelper::getPageSize( getModel() ) );
1510 aPos
.X
= static_cast< long >( static_cast< double >( aPos
.X
) + fShiftAmountX
);
1511 aPos
.Y
= static_cast< long >( static_cast< double >( aPos
.Y
) + fShiftAmountY
);
1512 if( aPos
.X
+ aSize
.Width
> aPageSize
.Width
)
1513 aPos
.X
= aPageSize
.Width
- aSize
.Width
;
1516 if( aPos
.Y
+ aSize
.Height
> aPageSize
.Height
)
1517 aPos
.Y
= aPageSize
.Height
- aSize
.Height
;
1521 xShape
->setPosition( aPos
);
1529 // dumping the shape
1530 if( !bReturn
&& bCtrl
&& nCode
== KEY_F12
)
1532 uno::Reference
< qa::XDumper
> xChartModel( getModel(), uno::UNO_QUERY
);
1533 if(xChartModel
.is())
1535 OUString aDump
= xChartModel
->dump();
1536 SAL_WARN("chart2", aDump
);
1544 if( eObjectType
== OBJECTTYPE_TITLE
)
1546 executeDispatch_EditText();
1551 // deactivate inplace mode (this code should be unnecessary, but
1552 // unfortunately is not)
1554 nCode
== KEY_ESCAPE
)
1556 uno::Reference
< frame::XDispatchHelper
> xDispatchHelper( frame::DispatchHelper::create(m_xCC
) );
1557 uno::Sequence
< beans::PropertyValue
> aArgs
;
1558 xDispatchHelper
->executeDispatch(
1559 uno::Reference
< frame::XDispatchProvider
>( m_xFrame
, uno::UNO_QUERY
),
1560 ".uno:TerminateInplaceActivation",
1562 frame::FrameSearchFlag::PARENT
,
1568 (nCode
== KEY_DELETE
|| nCode
== KEY_BACKSPACE
))
1570 bReturn
= executeDispatch_Delete();
1573 std::unique_ptr
<weld::MessageDialog
> xInfoBox(Application::CreateMessageDialog(pChartWindow
->GetFrameWeld(),
1574 VclMessageType::Info
, VclButtonsType::Ok
,
1575 SchResId(STR_ACTION_NOTPOSSIBLE
)));
1583 bool ChartController::requestQuickHelp(
1584 ::Point aAtLogicPosition
,
1585 bool bIsBalloonHelp
,
1586 OUString
& rOutQuickHelpText
,
1587 awt::Rectangle
& rOutEqualRect
)
1589 uno::Reference
< frame::XModel
> xChartModel
;
1591 xChartModel
.set( getModel() );
1592 if( !xChartModel
.is())
1597 if( m_pDrawViewWrapper
)
1599 aCID
= SelectionHelper::getHitObjectCID(
1600 aAtLogicPosition
, *m_pDrawViewWrapper
);
1602 bool bResult( !aCID
.isEmpty());
1607 rOutQuickHelpText
= ObjectNameProvider::getHelpText( aCID
, xChartModel
, bIsBalloonHelp
/* bVerbose */ );
1610 ExplicitValueProvider
* pValueProvider(
1611 comphelper::getUnoTunnelImplementation
<ExplicitValueProvider
>( m_xChartView
));
1612 if( pValueProvider
)
1613 rOutEqualRect
= pValueProvider
->getRectangleOfObject( aCID
, true );
1619 // XSelectionSupplier (optional interface)
1620 sal_Bool SAL_CALL
ChartController::select( const uno::Any
& rSelection
)
1622 bool bSuccess
= false;
1624 if ( rSelection
.hasValue() )
1626 const uno::Type
& rType
= rSelection
.getValueType();
1627 if ( rType
== cppu::UnoType
< OUString
>::get() )
1630 if ( ( rSelection
>>= aNewCID
) && m_aSelection
.setSelection( aNewCID
) )
1635 else if ( rType
== cppu::UnoType
<drawing::XShape
>::get() )
1637 uno::Reference
< drawing::XShape
> xShape
;
1638 if ( ( rSelection
>>= xShape
) && m_aSelection
.setSelection( xShape
) )
1646 if ( m_aSelection
.hasSelection() )
1648 m_aSelection
.clearSelection();
1655 SolarMutexGuard aGuard
;
1656 if ( m_pDrawViewWrapper
&& m_pDrawViewWrapper
->IsTextEdit() )
1660 impl_selectObjectAndNotiy();
1661 auto pChartWindow(GetChartWindow());
1664 pChartWindow
->Invalidate();
1672 uno::Any SAL_CALL
ChartController::getSelection()
1675 if ( m_aSelection
.hasSelection() )
1677 OUString
aCID( m_aSelection
.getSelectedCID() );
1678 if ( !aCID
.isEmpty() )
1680 if ( comphelper::LibreOfficeKit::isActive() )
1682 sal_Int32 nPos
= aCID
.lastIndexOf('/');
1683 OUString sFirst
= aCID
.copy(0, nPos
);
1684 OUString sSecond
= aCID
.copy(nPos
);
1686 aCID
+= "/Draggable=" + OUString::number(static_cast<int>(isSelectedObjectDraggable()));
1687 aCID
+= ":Resizable=" + OUString::number(static_cast<int>(isSelectedObjectResizable()));
1688 aCID
+= ":Rotatable=" + OUString::number(static_cast<int>(isSelectedObjectRotatable()));
1695 // #i12587# support for shapes in chart
1696 aReturn
<<= m_aSelection
.getSelectedAdditionalShape();
1702 void SAL_CALL
ChartController::addSelectionChangeListener( const uno::Reference
<view::XSelectionChangeListener
> & xListener
)
1704 SolarMutexGuard aGuard
;
1705 if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode?
1706 return; //behave passive if already disposed or suspended
1709 m_aLifeTimeManager
.m_aListenerContainer
.addInterface( cppu::UnoType
<view::XSelectionChangeListener
>::get(), xListener
);
1712 void SAL_CALL
ChartController::removeSelectionChangeListener( const uno::Reference
<view::XSelectionChangeListener
> & xListener
)
1714 SolarMutexGuard aGuard
;
1715 if( impl_isDisposedOrSuspended() ) //@todo? allow removing of listeners in suspend mode?
1716 return; //behave passive if already disposed or suspended
1719 m_aLifeTimeManager
.m_aListenerContainer
.removeInterface( cppu::UnoType
<view::XSelectionChangeListener
>::get(), xListener
);
1722 void ChartController::impl_notifySelectionChangeListeners()
1724 ::cppu::OInterfaceContainerHelper
* pIC
= m_aLifeTimeManager
.m_aListenerContainer
1725 .getContainer( cppu::UnoType
<view::XSelectionChangeListener
>::get() );
1728 uno::Reference
< view::XSelectionSupplier
> xSelectionSupplier(this);
1729 lang::EventObject
aEvent( xSelectionSupplier
);
1730 ::cppu::OInterfaceIteratorHelper
aIt( *pIC
);
1731 while( aIt
.hasMoreElements() )
1733 uno::Reference
< view::XSelectionChangeListener
> xListener( aIt
.next(), uno::UNO_QUERY
);
1734 if( xListener
.is() )
1735 xListener
->selectionChanged( aEvent
);
1740 void ChartController::impl_selectObjectAndNotiy()
1743 SolarMutexGuard aGuard
;
1744 DrawViewWrapper
* pDrawViewWrapper
= m_pDrawViewWrapper
.get();
1745 if( pDrawViewWrapper
)
1747 pDrawViewWrapper
->SetDragMode( m_eDragMode
);
1748 m_aSelection
.applySelection( m_pDrawViewWrapper
.get() );
1751 impl_notifySelectionChangeListeners();
1754 bool ChartController::impl_moveOrResizeObject(
1755 const OUString
& rCID
,
1756 eMoveOrResizeType eType
,
1757 double fAmountLogicX
,
1758 double fAmountLogicY
)
1760 bool bResult
= false;
1761 bool bNeedResize
= ( eType
== CENTERED_RESIZE_OBJECT
);
1763 uno::Reference
< frame::XModel
> xChartModel( getModel() );
1764 uno::Reference
< beans::XPropertySet
> xObjProp(
1765 ObjectIdentifier::getObjectPropertySet( rCID
, xChartModel
));
1768 awt::Size aRefSize
= ChartModelHelper::getPageSize( xChartModel
);
1770 chart2::RelativePosition aRelPos
;
1771 chart2::RelativeSize aRelSize
;
1772 bool bDeterminePos
= !(xObjProp
->getPropertyValue( "RelativePosition") >>= aRelPos
);
1773 bool bDetermineSize
= !bNeedResize
|| !(xObjProp
->getPropertyValue( "RelativeSize") >>= aRelSize
);
1775 if( ( bDeterminePos
|| bDetermineSize
) &&
1776 ( aRefSize
.Width
> 0 && aRefSize
.Height
> 0 ) )
1778 ExplicitValueProvider
* pValueProvider(
1779 comphelper::getUnoTunnelImplementation
<ExplicitValueProvider
>( m_xChartView
));
1780 if( pValueProvider
)
1782 awt::Rectangle
aRect( pValueProvider
->getRectangleOfObject( rCID
));
1783 double fWidth
= static_cast< double >( aRefSize
.Width
);
1784 double fHeight
= static_cast< double >( aRefSize
.Height
);
1785 if( bDetermineSize
)
1787 aRelSize
.Primary
= static_cast< double >( aRect
.Width
) / fWidth
;
1788 aRelSize
.Secondary
= static_cast< double >( aRect
.Height
) / fHeight
;
1792 if( bNeedResize
&& aRelSize
.Primary
> 0.0 && aRelSize
.Secondary
> 0.0 )
1794 aRelPos
.Primary
= (static_cast< double >( aRect
.X
) / fWidth
) +
1795 (aRelSize
.Primary
/ 2.0);
1796 aRelPos
.Secondary
= (static_cast< double >( aRect
.Y
) / fHeight
) +
1797 (aRelSize
.Secondary
/ 2.0);
1798 aRelPos
.Anchor
= drawing::Alignment_CENTER
;
1802 aRelPos
.Primary
= static_cast< double >( aRect
.X
) / fWidth
;
1803 aRelPos
.Secondary
= static_cast< double >( aRect
.Y
) / fHeight
;
1804 aRelPos
.Anchor
= drawing::Alignment_TOP_LEFT
;
1810 if( eType
== CENTERED_RESIZE_OBJECT
)
1811 bResult
= lcl_GrowAndShiftLogic( aRelPos
, aRelSize
, aRefSize
, fAmountLogicX
, fAmountLogicY
);
1812 else if( eType
== MOVE_OBJECT
)
1813 bResult
= lcl_MoveObjectLogic( aRelPos
, aRelSize
, aRefSize
, fAmountLogicX
, fAmountLogicY
);
1817 ActionDescriptionProvider::ActionType
eActionType(ActionDescriptionProvider::ActionType::Move
);
1819 eActionType
= ActionDescriptionProvider::ActionType::Resize
;
1821 ObjectType eObjectType
= ObjectIdentifier::getObjectType( rCID
);
1822 UndoGuard
aUndoGuard( ActionDescriptionProvider::createDescription(
1823 eActionType
, ObjectNameProvider::getName( eObjectType
)), m_xUndoManager
);
1825 ControllerLockGuardUNO
aCLGuard( xChartModel
);
1826 xObjProp
->setPropertyValue( "RelativePosition", uno::Any( aRelPos
));
1827 if( bNeedResize
|| (eObjectType
== OBJECTTYPE_DIAGRAM
) )//Also set an explicit size at the diagram when an explicit position is set
1828 xObjProp
->setPropertyValue( "RelativeSize", uno::Any( aRelSize
));
1830 aUndoGuard
.commit();
1836 bool ChartController::impl_DragDataPoint( const OUString
& rCID
, double fAdditionalOffset
)
1838 bool bResult
= false;
1839 if( fAdditionalOffset
< -1.0 || fAdditionalOffset
> 1.0 || fAdditionalOffset
== 0.0 )
1842 sal_Int32 nDataPointIndex
= ObjectIdentifier::getIndexFromParticleOrCID( rCID
);
1843 uno::Reference
< chart2::XDataSeries
> xSeries(
1844 ObjectIdentifier::getDataSeriesForCID( rCID
, getModel() ));
1849 uno::Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex( nDataPointIndex
));
1850 double fOffset
= 0.0;
1851 if( xPointProp
.is() &&
1852 (xPointProp
->getPropertyValue( "Offset" ) >>= fOffset
) &&
1853 (( fAdditionalOffset
> 0.0 && fOffset
< 1.0 ) || (fOffset
> 0.0)) )
1855 fOffset
+= fAdditionalOffset
;
1858 else if( fOffset
< 0.0 )
1860 xPointProp
->setPropertyValue( "Offset", uno::Any( fOffset
));
1864 catch( const uno::Exception
& )
1866 DBG_UNHANDLED_EXCEPTION("chart2");
1873 void ChartController::impl_SetMousePointer( const MouseEvent
& rEvent
)
1875 SolarMutexGuard aGuard
;
1876 auto pChartWindow(GetChartWindow());
1878 if (!m_pDrawViewWrapper
|| !pChartWindow
)
1881 Point
aMousePos( pChartWindow
->PixelToLogic( rEvent
.GetPosPixel()));
1882 sal_uInt16 nModifier
= rEvent
.GetModifier();
1883 bool bLeftDown
= rEvent
.IsLeft();
1885 // Check if object is for field button and set the normal arrow pointer in this case
1886 SdrObject
* pObject
= m_pDrawViewWrapper
->getHitObject(aMousePos
);
1887 if (pObject
&& pObject
->GetName().startsWith("FieldButton"))
1889 pChartWindow
->SetPointer(PointerStyle::Arrow
);
1893 if ( m_pDrawViewWrapper
->IsTextEdit() )
1895 if( m_pDrawViewWrapper
->IsTextEditHit( aMousePos
) )
1897 pChartWindow
->SetPointer( m_pDrawViewWrapper
->GetPreferredPointer(
1898 aMousePos
, pChartWindow
, nModifier
, bLeftDown
) );
1902 else if( m_pDrawViewWrapper
->IsAction() )
1904 return;//don't change pointer during running action
1907 SdrHdl
* pHitSelectionHdl
= nullptr;
1908 if( m_aSelection
.isResizeableObjectSelected() )
1909 pHitSelectionHdl
= m_pDrawViewWrapper
->PickHandle( aMousePos
);
1911 if( pHitSelectionHdl
)
1913 PointerStyle aPointer
= m_pDrawViewWrapper
->GetPreferredPointer(
1914 aMousePos
, pChartWindow
, nModifier
, bLeftDown
);
1915 bool bForceArrowPointer
= false;
1917 ObjectIdentifier
aOID( m_aSelection
.getSelectedOID() );
1921 case PointerStyle::NSize
:
1922 case PointerStyle::SSize
:
1923 case PointerStyle::WSize
:
1924 case PointerStyle::ESize
:
1925 case PointerStyle::NWSize
:
1926 case PointerStyle::NESize
:
1927 case PointerStyle::SWSize
:
1928 case PointerStyle::SESize
:
1929 if( ! m_aSelection
.isResizeableObjectSelected() )
1930 bForceArrowPointer
= true;
1932 case PointerStyle::Move
:
1933 if ( !aOID
.isDragableObject() )
1934 bForceArrowPointer
= true;
1936 case PointerStyle::MovePoint
:
1937 case PointerStyle::MoveBezierWeight
:
1938 // there is no point-editing in a chart
1939 // the PointerStyle::MoveBezierWeight appears in 3d data points
1940 bForceArrowPointer
= true;
1946 if( bForceArrowPointer
)
1947 pChartWindow
->SetPointer( PointerStyle::Arrow
);
1949 pChartWindow
->SetPointer( aPointer
);
1954 // #i12587# support for shapes in chart
1955 if ( m_eDrawMode
== CHARTDRAW_INSERT
&&
1956 ( !m_pDrawViewWrapper
->IsMarkedHit( aMousePos
) || !m_aSelection
.isDragableObjectSelected() ) )
1958 PointerStyle ePointerStyle
= PointerStyle::DrawRect
;
1959 SdrObjKind eKind
= static_cast< SdrObjKind
>( m_pDrawViewWrapper
->GetCurrentObjIdentifier() );
1964 ePointerStyle
= PointerStyle::DrawLine
;
1968 case OBJ_CUSTOMSHAPE
:
1970 ePointerStyle
= PointerStyle::DrawRect
;
1975 ePointerStyle
= PointerStyle::DrawEllipse
;
1980 ePointerStyle
= PointerStyle::DrawPolygon
;
1985 ePointerStyle
= PointerStyle::DrawText
;
1990 ePointerStyle
= PointerStyle::DrawCaption
;
1995 ePointerStyle
= PointerStyle::DrawRect
;
1999 pChartWindow
->SetPointer( ePointerStyle
);
2003 OUString
aHitObjectCID(
2004 SelectionHelper::getHitObjectCID(
2005 aMousePos
, *m_pDrawViewWrapper
, true /*bGetDiagramInsteadOf_Wall*/ ));
2007 if( m_pDrawViewWrapper
->IsTextEdit() )
2009 if( aHitObjectCID
== m_aSelection
.getSelectedCID() )
2011 pChartWindow
->SetPointer( PointerStyle::Arrow
);
2016 if( aHitObjectCID
.isEmpty() )
2018 //additional shape was hit
2019 pChartWindow
->SetPointer( PointerStyle::Move
);
2021 else if( ObjectIdentifier::isDragableObject( aHitObjectCID
) )
2023 if( (m_eDragMode
== SdrDragMode::Rotate
)
2024 && SelectionHelper::isRotateableObject( aHitObjectCID
2026 pChartWindow
->SetPointer( PointerStyle::Rotate
);
2029 ObjectType eHitObjectType
= ObjectIdentifier::getObjectType( aHitObjectCID
);
2030 if( eHitObjectType
== OBJECTTYPE_DATA_POINT
)
2032 if( !ObjectIdentifier::areSiblings(aHitObjectCID
,m_aSelection
.getSelectedCID())
2033 && !ObjectIdentifier::areIdenticalObjects(aHitObjectCID
,m_aSelection
.getSelectedCID()) )
2035 pChartWindow
->SetPointer( PointerStyle::Arrow
);
2039 pChartWindow
->SetPointer( PointerStyle::Move
);
2043 pChartWindow
->SetPointer( PointerStyle::Arrow
);
2046 css::uno::Reference
<css::uno::XInterface
> const & ChartController::getChartView() const
2048 return m_xChartView
;
2051 void ChartController::sendPopupRequest(OUString
const & rCID
, tools::Rectangle aRectangle
)
2053 ChartModel
* pChartModel
= dynamic_cast<ChartModel
*>(m_aModel
->getModel().get());
2057 uno::Reference
<chart2::data::XPivotTableDataProvider
> xPivotTableDataProvider
;
2058 xPivotTableDataProvider
.set(pChartModel
->getDataProvider(), uno::UNO_QUERY
);
2059 if (!xPivotTableDataProvider
.is())
2062 OUString sPivotTableName
= xPivotTableDataProvider
->getPivotTableName();
2064 PopupRequest
* pPopupRequest
= dynamic_cast<PopupRequest
*>(pChartModel
->getPopupRequest().get());
2068 // Get dimension index from CID
2069 sal_Int32 nStartPos
= rCID
.lastIndexOf('.');
2071 sal_Int32 nEndPos
= rCID
.getLength();
2072 OUString sDimensionIndex
= rCID
.copy(nStartPos
, nEndPos
- nStartPos
);
2073 sal_Int32 nDimensionIndex
= sDimensionIndex
.toInt32();
2075 awt::Rectangle xRectangle
{
2076 sal_Int32(aRectangle
.Left()),
2077 sal_Int32(aRectangle
.Top()),
2078 sal_Int32(aRectangle
.GetWidth()),
2079 sal_Int32(aRectangle
.GetHeight())
2082 uno::Sequence
<beans::PropertyValue
> aCallbackData
= comphelper::InitPropertySequence(
2084 {"Rectangle", uno::makeAny
<awt::Rectangle
>(xRectangle
)},
2085 {"DimensionIndex", uno::makeAny
<sal_Int32
>(nDimensionIndex
)},
2086 {"PivotTableName", uno::makeAny
<OUString
>(sPivotTableName
)},
2089 pPopupRequest
->getCallback()->notify(uno::makeAny(aCallbackData
));
2094 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */