2092 lines
79 KiB
C++
2092 lines
79 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <sal/config.h>
|
|
|
|
#include <string_view>
|
|
|
|
#include <ChartController.hxx>
|
|
#include <ChartView.hxx>
|
|
#include <PositionAndSizeHelper.hxx>
|
|
#include <ObjectIdentifier.hxx>
|
|
#include <ChartWindow.hxx>
|
|
#include <ResId.hxx>
|
|
#include <ChartModel.hxx>
|
|
#include <ChartModelHelper.hxx>
|
|
#include <ChartType.hxx>
|
|
#include <DiagramHelper.hxx>
|
|
#include <Diagram.hxx>
|
|
#include <TitleHelper.hxx>
|
|
#include "UndoGuard.hxx"
|
|
#include <ControllerLockGuard.hxx>
|
|
#include <ObjectNameProvider.hxx>
|
|
#include <strings.hrc>
|
|
#include "DragMethod_PieSegment.hxx"
|
|
#include "DragMethod_RotateDiagram.hxx"
|
|
#include <ObjectHierarchy.hxx>
|
|
#include <chartview/ExplicitValueProvider.hxx>
|
|
#include <RelativePositionHelper.hxx>
|
|
#include <chartview/DrawModelWrapper.hxx>
|
|
#include <RegressionCurveHelper.hxx>
|
|
#include <RegressionCurveModel.hxx>
|
|
#include <StatisticsHelper.hxx>
|
|
#include <DataSeries.hxx>
|
|
#include <DataSeriesHelper.hxx>
|
|
#include <DataSeriesProperties.hxx>
|
|
#include <Axis.hxx>
|
|
#include <AxisHelper.hxx>
|
|
#include <LegendHelper.hxx>
|
|
#include <servicenames_charttypes.hxx>
|
|
#include "DrawCommandDispatch.hxx"
|
|
#include <PopupRequest.hxx>
|
|
#include "ControllerCommandDispatch.hxx"
|
|
|
|
#include <com/sun/star/chart2/RelativePosition.hpp>
|
|
#include <com/sun/star/chart2/RelativeSize.hpp>
|
|
#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
|
|
|
|
#include <com/sun/star/awt/PopupMenuDirection.hpp>
|
|
#include <com/sun/star/frame/DispatchHelper.hpp>
|
|
#include <com/sun/star/frame/FrameSearchFlag.hpp>
|
|
#include <com/sun/star/frame/XPopupMenuController.hpp>
|
|
#include <com/sun/star/awt/Rectangle.hpp>
|
|
|
|
#include <comphelper/lok.hxx>
|
|
#include <comphelper/propertysequence.hxx>
|
|
#include <comphelper/propertyvalue.hxx>
|
|
|
|
#include <sfx2/viewsh.hxx>
|
|
#include <svx/ActionDescriptionProvider.hxx>
|
|
#include <svx/obj3d.hxx>
|
|
#include <svx/scene3d.hxx>
|
|
#include <svx/svddrgmt.hxx>
|
|
#include <vcl/commandevent.hxx>
|
|
#include <vcl/event.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <vcl/settings.hxx>
|
|
#include <vcl/weld.hxx>
|
|
#include <vcl/ptrstyle.hxx>
|
|
#include <svtools/acceleratorexecute.hxx>
|
|
#include <comphelper/diagnose_ex.hxx>
|
|
#include <toolkit/awt/vclxmenu.hxx>
|
|
#include <sal/log.hxx>
|
|
#include <o3tl/string_view.hxx>
|
|
|
|
#include <boost/property_tree/json_parser.hpp>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
|
|
|
|
#define DRGPIX 2 // Drag MinMove in Pixel
|
|
|
|
using namespace ::com::sun::star;
|
|
using namespace ::com::sun::star::chart2;
|
|
using namespace ::chart::DataSeriesProperties;
|
|
using ::com::sun::star::uno::Reference;
|
|
|
|
namespace chart
|
|
{
|
|
|
|
namespace
|
|
{
|
|
bool lcl_GrowAndShiftLogic(
|
|
RelativePosition & rInOutRelPos,
|
|
RelativeSize & rInOutRelSize,
|
|
const awt::Size & rRefSize,
|
|
double fGrowLogicX,
|
|
double fGrowLogicY )
|
|
{
|
|
if( rRefSize.Width == 0 ||
|
|
rRefSize.Height == 0 )
|
|
return false;
|
|
|
|
double fRelativeGrowX = fGrowLogicX / rRefSize.Width;
|
|
double fRelativeGrowY = fGrowLogicY / rRefSize.Height;
|
|
|
|
return ::chart::RelativePositionHelper::centerGrow(
|
|
rInOutRelPos, rInOutRelSize,
|
|
fRelativeGrowX, fRelativeGrowY );
|
|
}
|
|
|
|
bool lcl_MoveObjectLogic(
|
|
RelativePosition & rInOutRelPos,
|
|
RelativeSize const & rObjectSize,
|
|
const awt::Size & rRefSize,
|
|
double fShiftLogicX,
|
|
double fShiftLogicY )
|
|
{
|
|
if( rRefSize.Width == 0 ||
|
|
rRefSize.Height == 0 )
|
|
return false;
|
|
|
|
double fRelativeShiftX = fShiftLogicX / rRefSize.Width;
|
|
double fRelativeShiftY = fShiftLogicY / rRefSize.Height;
|
|
|
|
return ::chart::RelativePositionHelper::moveObject(
|
|
rInOutRelPos, rObjectSize,
|
|
fRelativeShiftX, fRelativeShiftY );
|
|
}
|
|
|
|
void lcl_insertMenuCommand(
|
|
const uno::Reference< awt::XPopupMenu > & xMenu,
|
|
sal_Int16 nId, const OUString & rCommand )
|
|
{
|
|
xMenu->insertItem( nId, u""_ustr, 0, -1 );
|
|
xMenu->setCommand( nId, rCommand );
|
|
}
|
|
|
|
OUString lcl_getFormatCommandForObjectCID( std::u16string_view rCID )
|
|
{
|
|
OUString aDispatchCommand( u".uno:FormatSelection"_ustr );
|
|
|
|
ObjectType eObjectType = ObjectIdentifier::getObjectType( rCID );
|
|
|
|
switch(eObjectType)
|
|
{
|
|
case OBJECTTYPE_DIAGRAM:
|
|
case OBJECTTYPE_DIAGRAM_WALL:
|
|
aDispatchCommand = ".uno:FormatWall";
|
|
break;
|
|
case OBJECTTYPE_DIAGRAM_FLOOR:
|
|
aDispatchCommand = ".uno:FormatFloor";
|
|
break;
|
|
case OBJECTTYPE_PAGE:
|
|
aDispatchCommand = ".uno:FormatChartArea";
|
|
break;
|
|
case OBJECTTYPE_LEGEND:
|
|
aDispatchCommand = ".uno:FormatLegend";
|
|
break;
|
|
case OBJECTTYPE_TITLE:
|
|
aDispatchCommand = ".uno:FormatTitle";
|
|
break;
|
|
case OBJECTTYPE_LEGEND_ENTRY:
|
|
case OBJECTTYPE_DATA_SERIES:
|
|
aDispatchCommand = ".uno:FormatDataSeries";
|
|
break;
|
|
case OBJECTTYPE_AXIS:
|
|
case OBJECTTYPE_AXIS_UNITLABEL:
|
|
aDispatchCommand = ".uno:FormatAxis";
|
|
break;
|
|
case OBJECTTYPE_GRID:
|
|
aDispatchCommand = ".uno:FormatMajorGrid";
|
|
break;
|
|
case OBJECTTYPE_SUBGRID:
|
|
aDispatchCommand = ".uno:FormatMinorGrid";
|
|
break;
|
|
case OBJECTTYPE_DATA_LABELS:
|
|
aDispatchCommand = ".uno:FormatDataLabels";
|
|
break;
|
|
case OBJECTTYPE_DATA_LABEL:
|
|
aDispatchCommand = ".uno:FormatDataLabel";
|
|
break;
|
|
case OBJECTTYPE_DATA_POINT:
|
|
aDispatchCommand = ".uno:FormatDataPoint";
|
|
break;
|
|
case OBJECTTYPE_DATA_AVERAGE_LINE:
|
|
aDispatchCommand = ".uno:FormatMeanValue";
|
|
break;
|
|
case OBJECTTYPE_DATA_ERRORS_X:
|
|
aDispatchCommand = ".uno:FormatXErrorBars";
|
|
break;
|
|
case OBJECTTYPE_DATA_ERRORS_Y:
|
|
aDispatchCommand = ".uno:FormatYErrorBars";
|
|
break;
|
|
case OBJECTTYPE_DATA_ERRORS_Z:
|
|
aDispatchCommand = ".uno:FormatZErrorBars";
|
|
break;
|
|
case OBJECTTYPE_DATA_CURVE:
|
|
aDispatchCommand = ".uno:FormatTrendline";
|
|
break;
|
|
case OBJECTTYPE_DATA_CURVE_EQUATION:
|
|
aDispatchCommand = ".uno:FormatTrendlineEquation";
|
|
break;
|
|
case OBJECTTYPE_DATA_STOCK_RANGE:
|
|
aDispatchCommand = ".uno:FormatSelection";
|
|
break;
|
|
case OBJECTTYPE_DATA_STOCK_LOSS:
|
|
aDispatchCommand = ".uno:FormatStockLoss";
|
|
break;
|
|
case OBJECTTYPE_DATA_STOCK_GAIN:
|
|
aDispatchCommand = ".uno:FormatStockGain";
|
|
break;
|
|
default: //OBJECTTYPE_UNKNOWN
|
|
break;
|
|
}
|
|
return aDispatchCommand;
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
// awt::XWindow
|
|
void SAL_CALL ChartController::setPosSize(
|
|
sal_Int32 X,
|
|
sal_Int32 Y,
|
|
sal_Int32 Width,
|
|
sal_Int32 Height,
|
|
sal_Int16 Flags )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
auto pChartWindow(GetChartWindow());
|
|
|
|
if(!(xWindow.is() && pChartWindow))
|
|
return;
|
|
|
|
Size aLogicSize = pChartWindow->PixelToLogic( Size( Width, Height ), MapMode( MapUnit::Map100thMM ) );
|
|
|
|
//todo: for standalone chart: detect whether we are standalone
|
|
//change map mode to fit new size
|
|
awt::Size aModelPageSize = ChartModelHelper::getPageSize( getChartModel() );
|
|
sal_Int32 nScaleXNumerator = aLogicSize.Width();
|
|
sal_Int32 nScaleXDenominator = aModelPageSize.Width;
|
|
sal_Int32 nScaleYNumerator = aLogicSize.Height();
|
|
sal_Int32 nScaleYDenominator = aModelPageSize.Height;
|
|
MapMode aNewMapMode(
|
|
MapUnit::Map100thMM,
|
|
Point(0,0),
|
|
Fraction(nScaleXNumerator, nScaleXDenominator),
|
|
Fraction(nScaleYNumerator, nScaleYDenominator) );
|
|
pChartWindow->SetMapMode(aNewMapMode);
|
|
pChartWindow->setPosSizePixel( X, Y, Width, Height, static_cast<PosSizeFlags>(Flags) );
|
|
|
|
//#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
|
|
if( m_xChartView.is() )
|
|
{
|
|
auto aZoomFactors(::comphelper::InitPropertySequence({
|
|
{ "ScaleXNumerator", uno::Any( nScaleXNumerator ) },
|
|
{ "ScaleXDenominator", uno::Any( nScaleXDenominator ) },
|
|
{ "ScaleYNumerator", uno::Any( nScaleYNumerator ) },
|
|
{ "ScaleYDenominator", uno::Any( nScaleYDenominator ) }
|
|
}));
|
|
m_xChartView->setPropertyValue( u"ZoomFactors"_ustr, uno::Any( aZoomFactors ));
|
|
}
|
|
|
|
//a correct work area is at least necessary for correct values in the position and size dialog and for dragging area
|
|
if(m_pDrawViewWrapper)
|
|
{
|
|
tools::Rectangle aRect(Point(0,0), pChartWindow->GetOutDev()->GetOutputSize());
|
|
m_pDrawViewWrapper->SetWorkArea( aRect );
|
|
}
|
|
pChartWindow->Invalidate();
|
|
}
|
|
|
|
awt::Rectangle SAL_CALL ChartController::getPosSize()
|
|
{
|
|
//@todo
|
|
awt::Rectangle aRet(0, 0, 0, 0);
|
|
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
if(xWindow.is())
|
|
aRet = xWindow->getPosSize();
|
|
|
|
return aRet;
|
|
}
|
|
|
|
void SAL_CALL ChartController::setVisible( sal_Bool Visible )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->setVisible( Visible );
|
|
}
|
|
|
|
void SAL_CALL ChartController::setEnable( sal_Bool Enable )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->setEnable( Enable );
|
|
}
|
|
|
|
void SAL_CALL ChartController::setFocus()
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->setFocus();
|
|
}
|
|
|
|
void SAL_CALL ChartController::addWindowListener(
|
|
const uno::Reference< awt::XWindowListener >& xListener )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->addWindowListener( xListener );
|
|
}
|
|
|
|
void SAL_CALL ChartController::removeWindowListener(
|
|
const uno::Reference< awt::XWindowListener >& xListener )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->removeWindowListener( xListener );
|
|
}
|
|
|
|
void SAL_CALL ChartController::addFocusListener(
|
|
const uno::Reference< awt::XFocusListener >& xListener )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->addFocusListener( xListener );
|
|
}
|
|
|
|
void SAL_CALL ChartController::removeFocusListener(
|
|
const uno::Reference< awt::XFocusListener >& xListener )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->removeFocusListener( xListener );
|
|
}
|
|
|
|
void SAL_CALL ChartController::addKeyListener(
|
|
const uno::Reference< awt::XKeyListener >& xListener )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->addKeyListener( xListener );
|
|
}
|
|
|
|
void SAL_CALL ChartController::removeKeyListener(
|
|
const uno::Reference< awt::XKeyListener >& xListener )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->removeKeyListener( xListener );
|
|
}
|
|
|
|
void SAL_CALL ChartController::addMouseListener(
|
|
const uno::Reference< awt::XMouseListener >& xListener )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->addMouseListener( xListener );
|
|
}
|
|
|
|
void SAL_CALL ChartController::removeMouseListener(
|
|
const uno::Reference< awt::XMouseListener >& xListener )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->removeMouseListener( xListener );
|
|
}
|
|
|
|
void SAL_CALL ChartController::addMouseMotionListener(
|
|
const uno::Reference< awt::XMouseMotionListener >& xListener )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->addMouseMotionListener( xListener );
|
|
}
|
|
|
|
void SAL_CALL ChartController::removeMouseMotionListener(
|
|
const uno::Reference< awt::XMouseMotionListener >& xListener )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->removeMouseMotionListener( xListener );
|
|
}
|
|
|
|
void SAL_CALL ChartController::addPaintListener(
|
|
const uno::Reference< awt::XPaintListener >& xListener )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->addPaintListener( xListener );
|
|
}
|
|
|
|
void SAL_CALL ChartController::removePaintListener(
|
|
const uno::Reference< awt::XPaintListener >& xListener )
|
|
{
|
|
//@todo
|
|
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
|
|
|
|
if(xWindow.is())
|
|
xWindow->removePaintListener( xListener );
|
|
}
|
|
|
|
// impl vcl window controller methods
|
|
void ChartController::PrePaint()
|
|
{
|
|
// forward VCLs PrePaint window event to DrawingLayer
|
|
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get();
|
|
|
|
if (pDrawViewWrapper)
|
|
{
|
|
pDrawViewWrapper->PrePaint();
|
|
}
|
|
}
|
|
|
|
void ChartController::execute_Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
|
|
{
|
|
try
|
|
{
|
|
rtl::Reference<ChartModel> xModel(getChartModel());
|
|
//OSL_ENSURE( xModel.is(), "ChartController::execute_Paint: have no model to paint");
|
|
if (!xModel.is())
|
|
return;
|
|
|
|
//better performance for big data
|
|
if (m_xChartView.is())
|
|
{
|
|
awt::Size aResolution(1000, 1000);
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
auto pChartWindow(GetChartWindow());
|
|
if (pChartWindow)
|
|
{
|
|
aResolution.Width = pChartWindow->GetSizePixel().Width();
|
|
aResolution.Height = pChartWindow->GetSizePixel().Height();
|
|
}
|
|
}
|
|
m_xChartView->setPropertyValue( u"Resolution"_ustr, uno::Any( aResolution ));
|
|
}
|
|
|
|
if (m_xChartView.is())
|
|
m_xChartView->update();
|
|
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get();
|
|
if (pDrawViewWrapper)
|
|
pDrawViewWrapper->CompleteRedraw(&rRenderContext, vcl::Region(rRect));
|
|
}
|
|
}
|
|
catch( const uno::Exception & )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("chart2");
|
|
}
|
|
catch( ... )
|
|
{
|
|
}
|
|
}
|
|
|
|
static bool isDoubleClick( const MouseEvent& rMEvt )
|
|
{
|
|
return rMEvt.GetClicks() == 2 && rMEvt.IsLeft() &&
|
|
!rMEvt.IsMod1() && !rMEvt.IsMod2() && !rMEvt.IsShift();
|
|
}
|
|
|
|
void ChartController::startDoubleClickWaiting()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
m_bWaitingForDoubleClick = true;
|
|
|
|
sal_uInt64 nDblClkTime = 500;
|
|
auto pChartWindow(GetChartWindow());
|
|
if( pChartWindow )
|
|
{
|
|
const MouseSettings& rMSettings = pChartWindow->GetSettings().GetMouseSettings();
|
|
nDblClkTime = rMSettings.GetDoubleClickTime();
|
|
}
|
|
m_aDoubleClickTimer.SetTimeout( nDblClkTime );
|
|
m_aDoubleClickTimer.Start();
|
|
}
|
|
|
|
void ChartController::stopDoubleClickWaiting()
|
|
{
|
|
m_aDoubleClickTimer.Stop();
|
|
m_bWaitingForDoubleClick = false;
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ChartController, DoubleClickWaitingHdl, Timer *, void)
|
|
{
|
|
m_bWaitingForDoubleClick = false;
|
|
|
|
if( m_bWaitingForMouseUp || !m_aSelection.maybeSwitchSelectionAfterSingleClickWasEnsured() )
|
|
return;
|
|
|
|
impl_selectObjectAndNotiy();
|
|
SolarMutexGuard aGuard;
|
|
auto pChartWindow(GetChartWindow());
|
|
if( pChartWindow )
|
|
{
|
|
vcl::Window::PointerState aPointerState( pChartWindow->GetPointerState() );
|
|
MouseEvent aMouseEvent(
|
|
aPointerState.maPos,
|
|
1/*nClicks*/,
|
|
MouseEventModifiers::NONE,
|
|
static_cast< sal_uInt16 >( aPointerState.mnState )/*nButtons*/,
|
|
0/*nModifier*/ );
|
|
impl_SetMousePointer( aMouseEvent );
|
|
}
|
|
}
|
|
|
|
void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
m_bWaitingForMouseUp = true;
|
|
m_bFieldButtonDown = false;
|
|
|
|
if( isDoubleClick(rMEvt) )
|
|
stopDoubleClickWaiting();
|
|
else
|
|
startDoubleClickWaiting();
|
|
|
|
m_aSelection.remindSelectionBeforeMouseDown();
|
|
|
|
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get();
|
|
auto pChartWindow(GetChartWindow());
|
|
if(!pChartWindow || !pDrawViewWrapper )
|
|
return;
|
|
|
|
Point aMPos = pChartWindow->PixelToLogic(rMEvt.GetPosPixel());
|
|
|
|
// Check if button was clicked
|
|
SdrObject* pObject = pDrawViewWrapper->getHitObject(aMPos);
|
|
if (pObject)
|
|
{
|
|
OUString aCID = pObject->GetName();
|
|
if (aCID.startsWith("FieldButton"))
|
|
{
|
|
m_bFieldButtonDown = true;
|
|
return; // Don't take any action if button was clicked
|
|
}
|
|
}
|
|
|
|
if ( rMEvt.GetButtons() == MOUSE_LEFT )
|
|
{
|
|
pChartWindow->GrabFocus();
|
|
pChartWindow->CaptureMouse();
|
|
}
|
|
|
|
if( pDrawViewWrapper->IsTextEdit() )
|
|
{
|
|
SdrViewEvent aVEvt;
|
|
if ( pDrawViewWrapper->IsTextEditHit( aMPos ) ||
|
|
// #i12587# support for shapes in chart
|
|
( rMEvt.IsRight() && pDrawViewWrapper->PickAnything( rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt ) == SdrHitKind::MarkedObject ) )
|
|
{
|
|
pDrawViewWrapper->MouseButtonDown(rMEvt, pChartWindow->GetOutDev());
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
EndTextEdit();
|
|
}
|
|
}
|
|
|
|
//abort running action
|
|
if( pDrawViewWrapper->IsAction() )
|
|
{
|
|
if( rMEvt.IsRight() )
|
|
pDrawViewWrapper->BckAction();
|
|
return;
|
|
}
|
|
|
|
if( isDoubleClick(rMEvt) ) //do not change selection if double click
|
|
return;//double click is handled further in mousebutton up
|
|
|
|
SdrHdl* pHitSelectionHdl = nullptr;
|
|
//switch from move to resize if handle is hit on a resizable object
|
|
if( m_aSelection.isResizeableObjectSelected() )
|
|
pHitSelectionHdl = pDrawViewWrapper->PickHandle( aMPos );
|
|
//only change selection if no selection handles are hit
|
|
if( !pHitSelectionHdl )
|
|
{
|
|
// #i12587# support for shapes in chart
|
|
if ( m_eDrawMode == CHARTDRAW_INSERT &&
|
|
( !pDrawViewWrapper->IsMarkedHit( aMPos ) || !m_aSelection.isDragableObjectSelected() ) )
|
|
{
|
|
if ( m_aSelection.hasSelection() )
|
|
{
|
|
m_aSelection.clearSelection();
|
|
}
|
|
if ( !pDrawViewWrapper->IsAction() )
|
|
{
|
|
if ( pDrawViewWrapper->GetCurrentObjIdentifier() == SdrObjKind::Caption )
|
|
{
|
|
Size aCaptionSize( 2268, 1134 );
|
|
pDrawViewWrapper->BegCreateCaptionObj( aMPos, aCaptionSize );
|
|
}
|
|
else
|
|
{
|
|
pDrawViewWrapper->BegCreateObj( aMPos);
|
|
}
|
|
SdrObject* pObj = pDrawViewWrapper->GetCreateObj();
|
|
DrawCommandDispatch* pDrawCommandDispatch = m_aDispatchContainer.getDrawCommandDispatch();
|
|
if ( pObj && m_pDrawModelWrapper && pDrawCommandDispatch )
|
|
{
|
|
SfxItemSet aSet( m_pDrawModelWrapper->GetItemPool() );
|
|
pDrawCommandDispatch->setAttributes( pObj );
|
|
pDrawCommandDispatch->setLineEnds( aSet );
|
|
pObj->SetMergedItemSet( aSet );
|
|
}
|
|
}
|
|
impl_SetMousePointer( rMEvt );
|
|
return;
|
|
}
|
|
|
|
m_aSelection.adaptSelectionToNewPos(
|
|
aMPos,
|
|
pDrawViewWrapper,
|
|
rMEvt.IsRight(),
|
|
m_bWaitingForDoubleClick );
|
|
|
|
if( !m_aSelection.isRotateableObjectSelected( getChartModel() ) )
|
|
{
|
|
m_eDragMode = SdrDragMode::Move;
|
|
pDrawViewWrapper->SetDragMode(m_eDragMode);
|
|
}
|
|
|
|
m_aSelection.applySelection(pDrawViewWrapper);
|
|
}
|
|
if( m_aSelection.isDragableObjectSelected()
|
|
&& !rMEvt.IsRight() )
|
|
{
|
|
//start drag
|
|
sal_uInt16 nDrgLog = static_cast<sal_uInt16>(pChartWindow->PixelToLogic(Size(DRGPIX,0)).Width());
|
|
SdrDragMethod* pDragMethod = nullptr;
|
|
|
|
//change selection to 3D scene if rotate mode
|
|
SdrDragMode eDragMode = pDrawViewWrapper->GetDragMode();
|
|
if( eDragMode==SdrDragMode::Rotate )
|
|
{
|
|
E3dScene* pScene = SelectionHelper::getSceneToRotate( pDrawViewWrapper->getNamedSdrObject( m_aSelection.getSelectedCID() ) );
|
|
if( pScene )
|
|
{
|
|
DragMethod_RotateDiagram::RotationDirection eRotationDirection(DragMethod_RotateDiagram::ROTATIONDIRECTION_FREE);
|
|
if(pHitSelectionHdl)
|
|
{
|
|
SdrHdlKind eKind = pHitSelectionHdl->GetKind();
|
|
if( eKind==SdrHdlKind::Upper || eKind==SdrHdlKind::Lower )
|
|
eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_X;
|
|
else if( eKind==SdrHdlKind::Left || eKind==SdrHdlKind::Right )
|
|
eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_Y;
|
|
else if( eKind==SdrHdlKind::UpperLeft || eKind==SdrHdlKind::UpperRight || eKind==SdrHdlKind::LowerLeft || eKind==SdrHdlKind::LowerRight )
|
|
eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_Z;
|
|
}
|
|
pDragMethod = new DragMethod_RotateDiagram( *pDrawViewWrapper, m_aSelection.getSelectedCID(), getChartModel(), eRotationDirection );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::u16string_view aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ) );
|
|
if( aDragMethodServiceName == ObjectIdentifier::getPieSegmentDragMethodServiceName() )
|
|
pDragMethod = new DragMethod_PieSegment( *pDrawViewWrapper, m_aSelection.getSelectedCID(), getChartModel() );
|
|
}
|
|
pDrawViewWrapper->SdrView::BegDragObj(aMPos, nullptr, pHitSelectionHdl, nDrgLog, pDragMethod);
|
|
}
|
|
|
|
impl_SetMousePointer( rMEvt );
|
|
}
|
|
|
|
void ChartController::execute_MouseMove( const MouseEvent& rMEvt )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get();
|
|
auto pChartWindow(GetChartWindow());
|
|
if(!pChartWindow || !pDrawViewWrapper)
|
|
return;
|
|
|
|
if( m_pDrawViewWrapper->IsTextEdit() )
|
|
{
|
|
if( m_pDrawViewWrapper->MouseMove(rMEvt,pChartWindow->GetOutDev()) )
|
|
return;
|
|
}
|
|
|
|
if(pDrawViewWrapper->IsAction())
|
|
{
|
|
pDrawViewWrapper->MovAction( pChartWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
|
|
}
|
|
|
|
impl_SetMousePointer( rMEvt );
|
|
}
|
|
|
|
void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt )
|
|
{
|
|
ControllerLockGuardUNO aCLGuard( getChartModel() );
|
|
bool bMouseUpWithoutMouseDown = !m_bWaitingForMouseUp;
|
|
m_bWaitingForMouseUp = false;
|
|
bool bNotifySelectionChange = false;
|
|
bool bEditText = false;
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get();
|
|
auto pChartWindow(GetChartWindow());
|
|
if(!pChartWindow || !pDrawViewWrapper)
|
|
return;
|
|
|
|
Point aMPos = pChartWindow->PixelToLogic(rMEvt.GetPosPixel());
|
|
|
|
// Check if button was clicked
|
|
if (m_bFieldButtonDown)
|
|
{
|
|
m_bFieldButtonDown = false;
|
|
SdrObject* pObject = pDrawViewWrapper->getHitObject(aMPos);
|
|
if (pObject)
|
|
{
|
|
OUString aCID = pObject->GetName();
|
|
if (aCID.startsWith("FieldButton"))
|
|
{
|
|
sendPopupRequest(aCID, pObject->GetCurrentBoundRect());
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(pDrawViewWrapper->IsTextEdit())
|
|
{
|
|
if( pDrawViewWrapper->MouseButtonUp(rMEvt,pChartWindow->GetOutDev()) )
|
|
return;
|
|
}
|
|
|
|
// #i12587# support for shapes in chart
|
|
if ( m_eDrawMode == CHARTDRAW_INSERT && pDrawViewWrapper->IsCreateObj() )
|
|
{
|
|
pDrawViewWrapper->EndCreateObj( SdrCreateCmd::ForceEnd );
|
|
{
|
|
HiddenUndoContext aUndoContext( m_xUndoManager );
|
|
// don't want the positioning Undo action to appear in the UI
|
|
impl_switchDiagramPositioningToExcludingPositioning();
|
|
}
|
|
if ( pDrawViewWrapper->GetMarkedObjectList().GetMarkCount() != 0 )
|
|
{
|
|
if ( pDrawViewWrapper->GetCurrentObjIdentifier() == SdrObjKind::Text )
|
|
{
|
|
executeDispatch_EditText();
|
|
}
|
|
else
|
|
{
|
|
SdrObject* pObj = pDrawViewWrapper->getSelectedObject();
|
|
if ( pObj )
|
|
{
|
|
uno::Reference< drawing::XShape > xShape( pObj->getUnoShape(), uno::UNO_QUERY );
|
|
if ( xShape.is() )
|
|
{
|
|
m_aSelection.setSelection( xShape );
|
|
m_aSelection.applySelection( pDrawViewWrapper );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_aSelection.adaptSelectionToNewPos( aMPos, pDrawViewWrapper, rMEvt.IsRight(), m_bWaitingForDoubleClick );
|
|
m_aSelection.applySelection( pDrawViewWrapper );
|
|
setDrawMode( CHARTDRAW_SELECT );
|
|
}
|
|
}
|
|
else if ( pDrawViewWrapper->IsDragObj() )
|
|
{
|
|
bool bDraggingDone = false;
|
|
SdrDragMethod* pDragMethod = pDrawViewWrapper->SdrView::GetDragMethod();
|
|
bool bIsMoveOnly = pDragMethod && pDragMethod->getMoveOnly();
|
|
DragMethod_Base* pChartDragMethod = dynamic_cast< DragMethod_Base* >(pDragMethod);
|
|
if( pChartDragMethod )
|
|
{
|
|
UndoGuard aUndoGuard( pChartDragMethod->getUndoDescription(),
|
|
m_xUndoManager );
|
|
|
|
if( pDrawViewWrapper->EndDragObj() )
|
|
{
|
|
bDraggingDone = true;
|
|
aUndoGuard.commit();
|
|
}
|
|
}
|
|
|
|
if( !bDraggingDone && pDrawViewWrapper->EndDragObj() )
|
|
{
|
|
try
|
|
{
|
|
//end move or size
|
|
SdrObject* pObj = pDrawViewWrapper->getSelectedObject();
|
|
if( pObj )
|
|
{
|
|
tools::Rectangle aObjectRect = pObj->GetSnapRect();
|
|
tools::Rectangle aOldObjectRect = pObj->GetLastBoundRect();
|
|
awt::Size aPageSize( ChartModelHelper::getPageSize( getChartModel() ) );
|
|
tools::Rectangle aPageRect( 0,0,aPageSize.Width,aPageSize.Height );
|
|
|
|
const E3dObject* pE3dObject(DynCastE3dObject(pObj));
|
|
if(nullptr != pE3dObject)
|
|
{
|
|
E3dScene* pScene(pE3dObject->getRootE3dSceneFromE3dObject());
|
|
if(nullptr != pScene)
|
|
{
|
|
aObjectRect = pScene->GetSnapRect();
|
|
}
|
|
}
|
|
|
|
ActionDescriptionProvider::ActionType eActionType(ActionDescriptionProvider::ActionType::Move);
|
|
if( !bIsMoveOnly && m_aSelection.isResizeableObjectSelected() )
|
|
eActionType = ActionDescriptionProvider::ActionType::Resize;
|
|
|
|
ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() );
|
|
|
|
UndoGuard aUndoGuard(
|
|
ActionDescriptionProvider::createDescription( eActionType, ObjectNameProvider::getName( eObjectType)),
|
|
m_xUndoManager );
|
|
|
|
bool bChanged = false;
|
|
rtl::Reference< ChartModel > xModel = getChartModel();
|
|
if ( eObjectType == OBJECTTYPE_LEGEND )
|
|
bChanged = DiagramHelper::switchDiagramPositioningToExcludingPositioning( *xModel, false , true );
|
|
|
|
bool bMoved = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID()
|
|
, xModel
|
|
, awt::Rectangle(aObjectRect.Left(),aObjectRect.Top(),aObjectRect.getOpenWidth(),aObjectRect.getOpenHeight())
|
|
, awt::Rectangle(aOldObjectRect.Left(), aOldObjectRect.Top(), 0, 0)
|
|
, awt::Rectangle(aPageRect.Left(),aPageRect.Top(),aPageRect.getOpenWidth(),aPageRect.getOpenHeight()) );
|
|
|
|
if( bMoved || bChanged )
|
|
{
|
|
bDraggingDone = true;
|
|
aUndoGuard.commit();
|
|
}
|
|
}
|
|
}
|
|
catch( const uno::Exception & )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("chart2");
|
|
}
|
|
//all wanted model changes will take effect
|
|
//and all unwanted view modifications are cleaned
|
|
}
|
|
|
|
if( !bDraggingDone ) //mouse wasn't moved while dragging
|
|
{
|
|
bool bClickedTwiceOnDragableObject = SelectionHelper::isDragableObjectHitTwice( aMPos, m_aSelection.getSelectedCID(), *pDrawViewWrapper );
|
|
bool bIsRotateable = m_aSelection.isRotateableObjectSelected( getChartModel() );
|
|
|
|
//toggle between move and rotate
|
|
if( bIsRotateable && bClickedTwiceOnDragableObject && m_eDragMode==SdrDragMode::Move )
|
|
m_eDragMode=SdrDragMode::Rotate;
|
|
else
|
|
m_eDragMode=SdrDragMode::Move;
|
|
|
|
pDrawViewWrapper->SetDragMode(m_eDragMode);
|
|
|
|
if( !m_bWaitingForDoubleClick && m_aSelection.maybeSwitchSelectionAfterSingleClickWasEnsured() )
|
|
{
|
|
impl_selectObjectAndNotiy();
|
|
}
|
|
}
|
|
else
|
|
m_aSelection.resetPossibleSelectionAfterSingleClickWasEnsured();
|
|
}
|
|
|
|
//@todo ForcePointer(&rMEvt);
|
|
pChartWindow->ReleaseMouse();
|
|
|
|
// In tiled rendering drag mode could be not yet over on the call
|
|
// that should handle the double-click, so better to perform this check
|
|
// always.
|
|
if( isDoubleClick(rMEvt) && !bMouseUpWithoutMouseDown /*#i106966#*/ )
|
|
{
|
|
Point aMousePixel = rMEvt.GetPosPixel();
|
|
execute_DoubleClick( &aMousePixel, bEditText );
|
|
}
|
|
|
|
if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() )
|
|
bNotifySelectionChange = true;
|
|
}
|
|
|
|
impl_SetMousePointer( rMEvt );
|
|
|
|
if(bNotifySelectionChange || bEditText)
|
|
impl_notifySelectionChangeListeners();
|
|
}
|
|
|
|
void ChartController::execute_DoubleClick( const Point* pMousePixel, bool &bEditText )
|
|
{
|
|
const SfxViewShell* pViewShell = SfxViewShell::Current();
|
|
bool notAllowed = pViewShell && (pViewShell->isLOKMobilePhone() || pViewShell->IsLokReadOnlyView());
|
|
if (notAllowed)
|
|
return;
|
|
|
|
if ( m_aSelection.hasSelection() )
|
|
{
|
|
OUString aCID( m_aSelection.getSelectedCID() );
|
|
if ( !aCID.isEmpty() )
|
|
{
|
|
ObjectType eObjectType = ObjectIdentifier::getObjectType( aCID );
|
|
if ( eObjectType == OBJECTTYPE_TITLE )
|
|
{
|
|
bEditText = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// #i12587# support for shapes in chart
|
|
SdrObject* pObj = DrawViewWrapper::getSdrObject( m_aSelection.getSelectedAdditionalShape() );
|
|
if ( DynCastSdrTextObj(pObj) != nullptr )
|
|
{
|
|
bEditText = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( bEditText )
|
|
{
|
|
executeDispatch_EditText( pMousePixel );
|
|
}
|
|
else
|
|
{
|
|
executeDispatch_ObjectProperties();
|
|
}
|
|
}
|
|
|
|
void ChartController::execute_Resize()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
auto pChartWindow(GetChartWindow());
|
|
if(pChartWindow)
|
|
pChartWindow->Invalidate();
|
|
}
|
|
|
|
void ChartController::execute_Command( const CommandEvent& rCEvt )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
auto pChartWindow(GetChartWindow());
|
|
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get();
|
|
if(!pChartWindow || !pDrawViewWrapper)
|
|
return;
|
|
bool bIsAction = m_pDrawViewWrapper->IsAction();
|
|
|
|
// pop-up menu
|
|
if(rCEvt.GetCommand() == CommandEventId::ContextMenu && !bIsAction)
|
|
{
|
|
pChartWindow->ReleaseMouse();
|
|
|
|
if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() )
|
|
impl_notifySelectionChangeListeners();
|
|
|
|
rtl::Reference< VCLXPopupMenu > xPopupMenu = new VCLXPopupMenu();
|
|
|
|
Point aPos( rCEvt.GetMousePosPixel() );
|
|
if( !rCEvt.IsMouseEvent() )
|
|
{
|
|
aPos = pChartWindow->GetPointerState().maPos;
|
|
}
|
|
|
|
OUString aMenuName;
|
|
if ( isShapeContext() )
|
|
// #i12587# support for shapes in chart
|
|
aMenuName = m_pDrawViewWrapper->IsTextEdit() ? std::u16string_view( u"drawtext" ) : std::u16string_view( u"draw" );
|
|
else
|
|
{
|
|
ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() );
|
|
|
|
// todo: the context menu should be specified by an xml file in uiconfig
|
|
sal_Int16 nUniqueId = 1;
|
|
if (eObjectType != OBJECTTYPE_DATA_TABLE)
|
|
{
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:Cut"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:Copy"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:Paste"_ustr );
|
|
xPopupMenu->insertSeparator( -1 );
|
|
}
|
|
|
|
rtl::Reference< Diagram > xDiagram = getFirstDiagram();
|
|
|
|
OUString aFormatCommand( lcl_getFormatCommandForObjectCID( m_aSelection.getSelectedCID() ) );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, aFormatCommand );
|
|
if (eObjectType == OBJECTTYPE_TITLE && m_pDrawViewWrapper->IsTextEdit())
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FontDialog"_ustr );
|
|
|
|
//some commands for dataseries and points:
|
|
|
|
if( eObjectType == OBJECTTYPE_DATA_SERIES || eObjectType == OBJECTTYPE_DATA_POINT )
|
|
{
|
|
bool bIsPoint = ( eObjectType == OBJECTTYPE_DATA_POINT );
|
|
rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getChartModel() );
|
|
rtl::Reference< RegressionCurveModel > xTrendline = RegressionCurveHelper::getFirstCurveNotMeanValueLine( xSeries );
|
|
bool bHasEquation = RegressionCurveHelper::hasEquation( xTrendline );
|
|
rtl::Reference< RegressionCurveModel > xMeanValue = RegressionCurveHelper::getMeanValueLine( xSeries );
|
|
bool bHasYErrorBars = StatisticsHelper::hasErrorBars( xSeries );
|
|
bool bHasXErrorBars = StatisticsHelper::hasErrorBars( xSeries, false );
|
|
bool bHasDataLabelsAtSeries = DataSeriesHelper::hasDataLabelsAtSeries( xSeries );
|
|
bool bHasDataLabelsAtPoints = DataSeriesHelper::hasDataLabelsAtPoints( xSeries );
|
|
bool bHasDataLabelAtPoint = false;
|
|
sal_Int32 nPointIndex = -1;
|
|
if( bIsPoint )
|
|
{
|
|
nPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( m_aSelection.getSelectedCID() );
|
|
bHasDataLabelAtPoint = DataSeriesHelper::hasDataLabelAtPoint( xSeries, nPointIndex );
|
|
}
|
|
bool bSelectedPointIsFormatted = false;
|
|
bool bHasFormattedDataPointsOtherThanSelected = false;
|
|
|
|
if( xSeries.is() )
|
|
{
|
|
uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
|
|
// "AttributedDataPoints"
|
|
if( xSeries->getFastPropertyValue( PROP_DATASERIES_ATTRIBUTED_DATA_POINTS ) >>= aAttributedDataPointIndexList )
|
|
{
|
|
if( aAttributedDataPointIndexList.hasElements() )
|
|
{
|
|
if( bIsPoint )
|
|
{
|
|
auto aIt = std::find( aAttributedDataPointIndexList.begin(), aAttributedDataPointIndexList.end(), nPointIndex );
|
|
if (aIt != aAttributedDataPointIndexList.end())
|
|
bSelectedPointIsFormatted = true;
|
|
else
|
|
bHasFormattedDataPointsOtherThanSelected = true;
|
|
}
|
|
else
|
|
bHasFormattedDataPointsOtherThanSelected = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( bIsPoint )
|
|
{
|
|
if( bHasDataLabelAtPoint )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatDataLabel"_ustr );
|
|
if( !bHasDataLabelAtPoint )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertDataLabel"_ustr );
|
|
else
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteDataLabel"_ustr );
|
|
if( bSelectedPointIsFormatted )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:ResetDataPoint"_ustr );
|
|
|
|
xPopupMenu->insertSeparator( -1 );
|
|
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatDataSeries"_ustr );
|
|
}
|
|
|
|
rtl::Reference< ChartType > xChartType( xDiagram->getChartTypeOfSeries( xSeries ) );
|
|
if( xChartType->getChartType() == CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK )
|
|
{
|
|
try
|
|
{
|
|
bool bJapaneseStyle = false;
|
|
xChartType->getPropertyValue( u"Japanese"_ustr ) >>= bJapaneseStyle;
|
|
|
|
if( bJapaneseStyle )
|
|
{
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatStockLoss"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatStockGain"_ustr );
|
|
}
|
|
}
|
|
catch( const uno::Exception & )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("chart2");
|
|
}
|
|
}
|
|
|
|
if( bHasDataLabelsAtSeries )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatDataLabels"_ustr );
|
|
if( bHasEquation )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatTrendlineEquation"_ustr );
|
|
if( xMeanValue.is() )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatMeanValue"_ustr );
|
|
if( bHasXErrorBars )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatXErrorBars"_ustr );
|
|
if( bHasYErrorBars )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatYErrorBars"_ustr );
|
|
|
|
xPopupMenu->insertSeparator( -1 );
|
|
|
|
if( !bHasDataLabelsAtSeries )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertDataLabels"_ustr );
|
|
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertTrendline"_ustr );
|
|
|
|
if( !xMeanValue.is() )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertMeanValue"_ustr );
|
|
if( !bHasXErrorBars )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertXErrorBars"_ustr );
|
|
if( !bHasYErrorBars )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertYErrorBars"_ustr );
|
|
if( bHasDataLabelsAtSeries || ( bHasDataLabelsAtPoints && bHasFormattedDataPointsOtherThanSelected ) )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteDataLabels"_ustr );
|
|
if( bHasEquation )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteTrendlineEquation"_ustr );
|
|
if( xMeanValue.is() )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteMeanValue"_ustr );
|
|
if( bHasXErrorBars )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteXErrorBars"_ustr );
|
|
if( bHasYErrorBars )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteYErrorBars"_ustr );
|
|
|
|
if( bHasFormattedDataPointsOtherThanSelected )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:ResetAllDataPoints"_ustr );
|
|
|
|
xPopupMenu->insertSeparator( -1 );
|
|
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId, u".uno:ArrangeRow"_ustr );
|
|
rtl::Reference< VCLXPopupMenu > xArrangePopupMenu = new VCLXPopupMenu();
|
|
sal_Int16 nSubId = nUniqueId + 1;
|
|
lcl_insertMenuCommand( xArrangePopupMenu, nSubId++, u".uno:Forward"_ustr );
|
|
lcl_insertMenuCommand( xArrangePopupMenu, nSubId, u".uno:Backward"_ustr );
|
|
xPopupMenu->setPopupMenu( nUniqueId, xArrangePopupMenu );
|
|
nUniqueId = nSubId;
|
|
++nUniqueId;
|
|
}
|
|
else if( eObjectType == OBJECTTYPE_DATA_CURVE )
|
|
{
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteTrendline"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatTrendlineEquation"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertTrendlineEquation"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertTrendlineEquationAndR2"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertR2Value"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteTrendlineEquation"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteR2Value"_ustr );
|
|
}
|
|
else if( eObjectType == OBJECTTYPE_DATA_CURVE_EQUATION )
|
|
{
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertR2Value"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteR2Value"_ustr );
|
|
}
|
|
|
|
//some commands for axes: and grids
|
|
|
|
else if( eObjectType == OBJECTTYPE_AXIS || eObjectType == OBJECTTYPE_GRID || eObjectType == OBJECTTYPE_SUBGRID )
|
|
{
|
|
rtl::Reference< Axis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), getChartModel() );
|
|
if( xAxis.is() && xDiagram.is() )
|
|
{
|
|
sal_Int32 nDimensionIndex = -1;
|
|
sal_Int32 nCooSysIndex = -1;
|
|
sal_Int32 nAxisIndex = -1;
|
|
AxisHelper::getIndicesForAxis( xAxis, xDiagram, nCooSysIndex, nDimensionIndex, nAxisIndex );
|
|
bool bIsSecondaryAxis = nAxisIndex!=0;
|
|
bool bIsAxisVisible = AxisHelper::isAxisVisible( xAxis );
|
|
bool bIsMajorGridVisible = AxisHelper::isGridShown( nDimensionIndex, nCooSysIndex, true /*bMainGrid*/, xDiagram );
|
|
bool bIsMinorGridVisible = AxisHelper::isGridShown( nDimensionIndex, nCooSysIndex, false /*bMainGrid*/, xDiagram );
|
|
bool bHasTitle = !TitleHelper::getCompleteString( xAxis->getTitleObject2() ).isEmpty();
|
|
|
|
if( eObjectType != OBJECTTYPE_AXIS && bIsAxisVisible )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatAxis"_ustr );
|
|
if( eObjectType != OBJECTTYPE_GRID && bIsMajorGridVisible && !bIsSecondaryAxis )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatMajorGrid"_ustr );
|
|
if( eObjectType != OBJECTTYPE_SUBGRID && bIsMinorGridVisible && !bIsSecondaryAxis )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatMinorGrid"_ustr );
|
|
|
|
xPopupMenu->insertSeparator( -1 );
|
|
|
|
if( eObjectType != OBJECTTYPE_AXIS && !bIsAxisVisible )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertAxis"_ustr );
|
|
if( eObjectType != OBJECTTYPE_GRID && !bIsMajorGridVisible && !bIsSecondaryAxis )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertMajorGrid"_ustr );
|
|
if( eObjectType != OBJECTTYPE_SUBGRID && !bIsMinorGridVisible && !bIsSecondaryAxis )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertMinorGrid"_ustr );
|
|
if( !bHasTitle )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertAxisTitle"_ustr );
|
|
|
|
if( bIsAxisVisible )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteAxis"_ustr );
|
|
if( bIsMajorGridVisible && !bIsSecondaryAxis )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteMajorGrid"_ustr );
|
|
if( bIsMinorGridVisible && !bIsSecondaryAxis )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteMinorGrid"_ustr );
|
|
if (bIsAxisVisible)
|
|
lcl_insertMenuCommand(xPopupMenu, nUniqueId++, u".uno:InsertDataTable"_ustr);
|
|
}
|
|
}
|
|
else if (eObjectType == OBJECTTYPE_DATA_TABLE)
|
|
{
|
|
lcl_insertMenuCommand(xPopupMenu, nUniqueId++, u".uno:DeleteDataTable"_ustr);
|
|
}
|
|
|
|
if( eObjectType == OBJECTTYPE_DATA_STOCK_LOSS )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatStockGain"_ustr );
|
|
else if( eObjectType == OBJECTTYPE_DATA_STOCK_GAIN )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatStockLoss"_ustr );
|
|
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:TransformDialog"_ustr );
|
|
|
|
if( eObjectType == OBJECTTYPE_PAGE || eObjectType == OBJECTTYPE_DIAGRAM
|
|
|| eObjectType == OBJECTTYPE_DIAGRAM_WALL
|
|
|| eObjectType == OBJECTTYPE_DIAGRAM_FLOOR
|
|
|| eObjectType == OBJECTTYPE_UNKNOWN )
|
|
{
|
|
if( eObjectType != OBJECTTYPE_UNKNOWN )
|
|
xPopupMenu->insertSeparator( -1 );
|
|
bool bHasLegend = LegendHelper::hasLegend( xDiagram );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertTitles"_ustr );
|
|
if( !bHasLegend )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertLegend"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertRemoveAxes"_ustr );
|
|
if( bHasLegend )
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteLegend"_ustr );
|
|
}
|
|
|
|
xPopupMenu->insertSeparator( -1 );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DiagramType"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DataRanges"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DiagramData"_ustr );
|
|
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:View3D"_ustr );
|
|
}
|
|
|
|
css::uno::Sequence< css::uno::Any > aArgs{
|
|
css::uno::Any(comphelper::makePropertyValue( u"IsContextMenu"_ustr, true )),
|
|
css::uno::Any(comphelper::makePropertyValue( u"Frame"_ustr, m_xFrame )),
|
|
css::uno::Any(comphelper::makePropertyValue( u"Value"_ustr, aMenuName ))
|
|
};
|
|
|
|
css::uno::Reference< css::frame::XPopupMenuController > xPopupController(
|
|
m_xCC->getServiceManager()->createInstanceWithArgumentsAndContext(
|
|
u"com.sun.star.comp.framework.ResourceMenuController"_ustr, aArgs, m_xCC ), css::uno::UNO_QUERY );
|
|
|
|
if ( !xPopupController.is() || !xPopupMenu.is() )
|
|
return;
|
|
|
|
xPopupController->setPopupMenu( xPopupMenu );
|
|
|
|
if (comphelper::LibreOfficeKit::isActive())
|
|
{
|
|
if (SfxViewShell* pViewShell = SfxViewShell::Current())
|
|
{
|
|
ControllerCommandDispatch* pCommandDispatch = dynamic_cast<ControllerCommandDispatch*>(m_aDispatchContainer.getChartDispatcher().get());
|
|
if (pCommandDispatch)
|
|
{
|
|
for (int nPos = 0, nCount = xPopupMenu->getItemCount(); nPos < nCount; ++nPos)
|
|
{
|
|
auto nItemId = xPopupMenu->getItemId(nPos);
|
|
OUString aCommandURL = xPopupMenu->getCommand(nItemId);
|
|
if (!pCommandDispatch->commandAvailable(aCommandURL))
|
|
xPopupMenu->enableItem(nItemId, false);
|
|
}
|
|
}
|
|
|
|
boost::property_tree::ptree aMenu = SfxDispatcher::fillPopupMenu(xPopupMenu);
|
|
boost::property_tree::ptree aRoot;
|
|
aRoot.add_child("menu", aMenu);
|
|
|
|
std::stringstream aStream;
|
|
boost::property_tree::write_json(aStream, aRoot, true);
|
|
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_CONTEXT_MENU, OString(aStream.str()));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xPopupMenu->execute( css::uno::Reference< css::awt::XWindowPeer >( m_xFrame->getContainerWindow(), css::uno::UNO_QUERY ),
|
|
css::awt::Rectangle( aPos.X(), aPos.Y(), 0, 0 ),
|
|
css::awt::PopupMenuDirection::EXECUTE_DEFAULT );
|
|
}
|
|
|
|
css::uno::Reference< css::lang::XComponent > xComponent( xPopupController, css::uno::UNO_QUERY );
|
|
if ( xComponent.is() )
|
|
xComponent->dispose();
|
|
}
|
|
else if( ( rCEvt.GetCommand() == CommandEventId::StartExtTextInput ) ||
|
|
( rCEvt.GetCommand() == CommandEventId::ExtTextInput ) ||
|
|
( rCEvt.GetCommand() == CommandEventId::EndExtTextInput ) ||
|
|
( rCEvt.GetCommand() == CommandEventId::InputContextChange ) )
|
|
{
|
|
//#i84417# enable editing with IME
|
|
m_pDrawViewWrapper->Command( rCEvt, pChartWindow );
|
|
}
|
|
}
|
|
|
|
bool ChartController::execute_KeyInput( const KeyEvent& rKEvt )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
bool bReturn=false;
|
|
|
|
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get();
|
|
auto pChartWindow(GetChartWindow());
|
|
if (!pChartWindow || !pDrawViewWrapper)
|
|
return bReturn;
|
|
|
|
// handle accelerators
|
|
if (!m_apAccelExecute && m_xFrame.is() && m_xCC.is())
|
|
{
|
|
m_apAccelExecute = ::svt::AcceleratorExecute::createAcceleratorHelper();
|
|
OSL_ASSERT(m_apAccelExecute);
|
|
if (m_apAccelExecute)
|
|
m_apAccelExecute->init( m_xCC, m_xFrame );
|
|
}
|
|
|
|
vcl::KeyCode aKeyCode( rKEvt.GetKeyCode());
|
|
sal_uInt16 nCode = aKeyCode.GetCode();
|
|
bool bAlternate = aKeyCode.IsMod2();
|
|
bool bCtrl = aKeyCode.IsMod1();
|
|
|
|
if (m_apAccelExecute)
|
|
bReturn = m_apAccelExecute->execute( aKeyCode );
|
|
if( bReturn )
|
|
return bReturn;
|
|
|
|
{
|
|
if( pDrawViewWrapper->IsTextEdit() )
|
|
{
|
|
if( pDrawViewWrapper->KeyInput(rKEvt, pChartWindow) )
|
|
{
|
|
bReturn = true;
|
|
if( nCode == KEY_ESCAPE )
|
|
{
|
|
EndTextEdit();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// keyboard accessibility
|
|
ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() );
|
|
if( ! bReturn )
|
|
{
|
|
// Navigation (Tab/F3/Home/End)
|
|
rtl::Reference<::chart::ChartModel> xChartDoc( getChartModel() );
|
|
ObjectKeyNavigation aObjNav( m_aSelection.getSelectedOID(), xChartDoc, m_xChartView.get() );
|
|
awt::KeyEvent aKeyEvent( ::svt::AcceleratorExecute::st_VCLKey2AWTKey( aKeyCode ));
|
|
bReturn = aObjNav.handleKeyEvent( aKeyEvent );
|
|
if( bReturn )
|
|
{
|
|
const ObjectIdentifier& aNewOID = aObjNav.getCurrentSelection();
|
|
uno::Any aNewSelection;
|
|
if ( aNewOID.isValid() && !ObjectHierarchy::isRootNode( aNewOID ) )
|
|
{
|
|
aNewSelection = aNewOID.getAny();
|
|
}
|
|
if ( m_eDragMode == SdrDragMode::Rotate && !SelectionHelper::isRotateableObject( aNewOID.getObjectCID(), getChartModel() ) )
|
|
{
|
|
m_eDragMode = SdrDragMode::Move;
|
|
}
|
|
bReturn = select( aNewSelection );
|
|
}
|
|
}
|
|
|
|
// Position and Size (+/-/arrow-keys) or pie segment dragging
|
|
if( ! bReturn )
|
|
{
|
|
// pie segment dragging
|
|
// note: could also be done for data series
|
|
if( eObjectType == OBJECTTYPE_DATA_POINT &&
|
|
ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ) ==
|
|
ObjectIdentifier::getPieSegmentDragMethodServiceName())
|
|
{
|
|
bool bDrag = false;
|
|
bool bDragInside = false;
|
|
if( nCode == KEY_ADD ||
|
|
nCode == KEY_SUBTRACT )
|
|
{
|
|
bDrag = true;
|
|
bDragInside = ( nCode == KEY_SUBTRACT );
|
|
}
|
|
else if(
|
|
nCode == KEY_LEFT ||
|
|
nCode == KEY_RIGHT ||
|
|
nCode == KEY_UP ||
|
|
nCode == KEY_DOWN )
|
|
{
|
|
bDrag = true;
|
|
std::u16string_view aParameter( ObjectIdentifier::getDragParameterString( m_aSelection.getSelectedCID() ));
|
|
sal_Int32 nOffsetPercentDummy( 0 );
|
|
awt::Point aMinimumPosition( 0, 0 );
|
|
awt::Point aMaximumPosition( 0, 0 );
|
|
ObjectIdentifier::parsePieSegmentDragParameterString(
|
|
aParameter, nOffsetPercentDummy, aMinimumPosition, aMaximumPosition );
|
|
aMaximumPosition.Y -= aMinimumPosition.Y;
|
|
aMaximumPosition.X -= aMinimumPosition.X;
|
|
|
|
bDragInside =
|
|
(nCode == KEY_RIGHT && (aMaximumPosition.X < 0)) ||
|
|
(nCode == KEY_LEFT && (aMaximumPosition.X > 0)) ||
|
|
(nCode == KEY_DOWN && (aMaximumPosition.Y < 0)) ||
|
|
(nCode == KEY_UP && (aMaximumPosition.Y > 0));
|
|
}
|
|
|
|
if( bDrag )
|
|
{
|
|
double fAmount = bAlternate ? 0.01 : 0.05;
|
|
if( bDragInside )
|
|
fAmount *= -1.0;
|
|
|
|
bReturn = impl_DragDataPoint( m_aSelection.getSelectedCID(), fAmount );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// size
|
|
if( nCode == KEY_ADD ||
|
|
nCode == KEY_SUBTRACT )
|
|
{
|
|
if( eObjectType == OBJECTTYPE_DIAGRAM )
|
|
{
|
|
// default 1 mm in each direction
|
|
double fGrowAmountX = 200.0;
|
|
double fGrowAmountY = 200.0;
|
|
if (bAlternate)
|
|
{
|
|
// together with Alt-key: 1 px in each direction
|
|
Size aPixelSize = pChartWindow->PixelToLogic( Size( 2, 2 ));
|
|
fGrowAmountX = static_cast< double >( aPixelSize.Width());
|
|
fGrowAmountY = static_cast< double >( aPixelSize.Height());
|
|
}
|
|
if( nCode == KEY_SUBTRACT )
|
|
{
|
|
fGrowAmountX = -fGrowAmountX;
|
|
fGrowAmountY = -fGrowAmountY;
|
|
}
|
|
bReturn = impl_moveOrResizeObject(
|
|
m_aSelection.getSelectedCID(), CENTERED_RESIZE_OBJECT, fGrowAmountX, fGrowAmountY );
|
|
}
|
|
}
|
|
// position
|
|
else if( nCode == KEY_LEFT ||
|
|
nCode == KEY_RIGHT ||
|
|
nCode == KEY_UP ||
|
|
nCode == KEY_DOWN )
|
|
{
|
|
if( m_aSelection.isDragableObjectSelected() )
|
|
{
|
|
// default 1 mm
|
|
double fShiftAmountX = 100.0;
|
|
double fShiftAmountY = 100.0;
|
|
if (bAlternate)
|
|
{
|
|
// together with Alt-key: 1 px
|
|
Size aPixelSize = pChartWindow->PixelToLogic( Size( 1, 1 ));
|
|
fShiftAmountX = static_cast< double >( aPixelSize.Width());
|
|
fShiftAmountY = static_cast< double >( aPixelSize.Height());
|
|
}
|
|
switch( nCode )
|
|
{
|
|
case KEY_LEFT:
|
|
fShiftAmountX = -fShiftAmountX;
|
|
fShiftAmountY = 0.0;
|
|
break;
|
|
case KEY_RIGHT:
|
|
fShiftAmountY = 0.0;
|
|
break;
|
|
case KEY_UP:
|
|
fShiftAmountX = 0.0;
|
|
fShiftAmountY = -fShiftAmountY;
|
|
break;
|
|
case KEY_DOWN:
|
|
fShiftAmountX = 0.0;
|
|
break;
|
|
}
|
|
if( !m_aSelection.getSelectedCID().isEmpty() )
|
|
{
|
|
//move chart objects
|
|
if (eObjectType == OBJECTTYPE_DATA_LABEL)
|
|
{
|
|
SdrObject* pObj = pDrawViewWrapper->getSelectedObject();
|
|
if (pObj)
|
|
{
|
|
tools::Rectangle aRect = pObj->GetSnapRect();
|
|
awt::Size aPageSize(ChartModelHelper::getPageSize(getChartModel()));
|
|
if ((fShiftAmountX > 0.0 && (aRect.Right() + fShiftAmountX > aPageSize.Width)) ||
|
|
(fShiftAmountX < 0.0 && (aRect.Left() + fShiftAmountX < 0)) ||
|
|
(fShiftAmountY > 0.0 && (aRect.Bottom() + fShiftAmountY > aPageSize.Height)) ||
|
|
(fShiftAmountY < 0.0 && (aRect.Top() + fShiftAmountY < 0)))
|
|
bReturn = false;
|
|
else
|
|
bReturn = PositionAndSizeHelper::moveObject(
|
|
m_aSelection.getSelectedCID(), getChartModel(),
|
|
awt::Rectangle(aRect.Left() + fShiftAmountX, aRect.Top() + fShiftAmountY, aRect.getOpenWidth(), aRect.getOpenHeight()),
|
|
awt::Rectangle(aRect.Left(), aRect.Top(), 0, 0),
|
|
awt::Rectangle(0, 0, aPageSize.Width, aPageSize.Height));
|
|
}
|
|
}
|
|
else
|
|
bReturn = impl_moveOrResizeObject(
|
|
m_aSelection.getSelectedCID(), MOVE_OBJECT, fShiftAmountX, fShiftAmountY );
|
|
}
|
|
else
|
|
{
|
|
//move additional shapes
|
|
uno::Reference< drawing::XShape > xShape( m_aSelection.getSelectedAdditionalShape() );
|
|
if( xShape.is() )
|
|
{
|
|
awt::Point aPos( xShape->getPosition() );
|
|
awt::Size aSize( xShape->getSize() );
|
|
awt::Size aPageSize( ChartModelHelper::getPageSize( getChartModel() ) );
|
|
aPos.X = static_cast< tools::Long >( static_cast< double >( aPos.X ) + fShiftAmountX );
|
|
aPos.Y = static_cast< tools::Long >( static_cast< double >( aPos.Y ) + fShiftAmountY );
|
|
if( aPos.X + aSize.Width > aPageSize.Width )
|
|
aPos.X = aPageSize.Width - aSize.Width;
|
|
if( aPos.X < 0 )
|
|
aPos.X = 0;
|
|
if( aPos.Y + aSize.Height > aPageSize.Height )
|
|
aPos.Y = aPageSize.Height - aSize.Height;
|
|
if( aPos.Y < 0 )
|
|
aPos.Y = 0;
|
|
|
|
xShape->setPosition( aPos );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// dumping the shape
|
|
if( !bReturn && bCtrl && nCode == KEY_F12)
|
|
{
|
|
rtl::Reference< ChartModel > xChartModel = getChartModel();
|
|
if(xChartModel.is())
|
|
{
|
|
OUString aDump = xChartModel->dump(u"shapes"_ustr);
|
|
SAL_WARN("chart2", aDump);
|
|
}
|
|
}
|
|
|
|
// text edit
|
|
if( ! bReturn &&
|
|
nCode == KEY_F2 )
|
|
{
|
|
if( eObjectType == OBJECTTYPE_TITLE )
|
|
{
|
|
executeDispatch_EditText();
|
|
bReturn = true;
|
|
}
|
|
}
|
|
|
|
// deactivate inplace mode (this code should be unnecessary, but
|
|
// unfortunately is not)
|
|
if( ! bReturn &&
|
|
nCode == KEY_ESCAPE )
|
|
{
|
|
uno::Reference< frame::XDispatchHelper > xDispatchHelper( frame::DispatchHelper::create(m_xCC) );
|
|
uno::Sequence< beans::PropertyValue > aArgs;
|
|
xDispatchHelper->executeDispatch(
|
|
uno::Reference< frame::XDispatchProvider >( m_xFrame, uno::UNO_QUERY ),
|
|
u".uno:TerminateInplaceActivation"_ustr,
|
|
u"_parent"_ustr,
|
|
frame::FrameSearchFlag::PARENT,
|
|
aArgs );
|
|
bReturn = true;
|
|
}
|
|
|
|
if( ! bReturn &&
|
|
(nCode == KEY_DELETE || nCode == KEY_BACKSPACE ))
|
|
{
|
|
bReturn = executeDispatch_Delete();
|
|
if( ! bReturn )
|
|
{
|
|
std::shared_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pChartWindow->GetFrameWeld(),
|
|
VclMessageType::Info, VclButtonsType::Ok,
|
|
SchResId(STR_ACTION_NOTPOSSIBLE)));
|
|
xInfoBox->runAsync(xInfoBox, [] (int) {});
|
|
}
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
bool ChartController::requestQuickHelp(
|
|
::Point aAtLogicPosition,
|
|
bool bIsBalloonHelp,
|
|
OUString & rOutQuickHelpText,
|
|
awt::Rectangle & rOutEqualRect )
|
|
{
|
|
rtl::Reference<::chart::ChartModel> xChartModel;
|
|
if( m_aModel.is())
|
|
xChartModel = getChartModel();
|
|
if( !xChartModel.is())
|
|
return false;
|
|
|
|
// help text
|
|
OUString aCID;
|
|
if( m_pDrawViewWrapper )
|
|
{
|
|
aCID = SelectionHelper::getHitObjectCID(
|
|
aAtLogicPosition, *m_pDrawViewWrapper );
|
|
}
|
|
bool bResult( !aCID.isEmpty());
|
|
|
|
if( bResult )
|
|
{
|
|
// get help text
|
|
rOutQuickHelpText = ObjectNameProvider::getHelpText( aCID, xChartModel, bIsBalloonHelp /* bVerbose */ );
|
|
|
|
// set rectangle
|
|
if( m_xChartView )
|
|
rOutEqualRect = m_xChartView->getRectangleOfObject( aCID, true );
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
// XSelectionSupplier (optional interface)
|
|
sal_Bool SAL_CALL ChartController::select( const uno::Any& rSelection )
|
|
{
|
|
bool bSuccess = false;
|
|
|
|
if ( rSelection.hasValue() )
|
|
{
|
|
if (rSelection.getValueType() == cppu::UnoType<OUString>::get())
|
|
{
|
|
OUString aNewCID;
|
|
if ( ( rSelection >>= aNewCID ) && m_aSelection.setSelection( aNewCID ) )
|
|
{
|
|
bSuccess = true;
|
|
}
|
|
}
|
|
else if (uno::Reference<drawing::XShape> xShape; rSelection >>= xShape)
|
|
{
|
|
if (m_aSelection.setSelection(xShape))
|
|
{
|
|
bSuccess = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( m_aSelection.hasSelection() )
|
|
{
|
|
m_aSelection.clearSelection();
|
|
bSuccess = true;
|
|
}
|
|
}
|
|
|
|
if ( bSuccess )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if ( m_pDrawViewWrapper && m_pDrawViewWrapper->IsTextEdit() )
|
|
{
|
|
EndTextEdit();
|
|
}
|
|
impl_selectObjectAndNotiy();
|
|
auto pChartWindow(GetChartWindow());
|
|
if ( pChartWindow )
|
|
{
|
|
pChartWindow->Invalidate();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
uno::Any SAL_CALL ChartController::getSelection()
|
|
{
|
|
uno::Any aReturn;
|
|
if ( m_aSelection.hasSelection() )
|
|
{
|
|
OUString aCID( m_aSelection.getSelectedCID() );
|
|
if ( !aCID.isEmpty() )
|
|
{
|
|
aReturn <<= aCID;
|
|
}
|
|
else
|
|
{
|
|
// #i12587# support for shapes in chart
|
|
aReturn <<= m_aSelection.getSelectedAdditionalShape();
|
|
}
|
|
}
|
|
return aReturn;
|
|
}
|
|
|
|
void SAL_CALL ChartController::addSelectionChangeListener( const uno::Reference<view::XSelectionChangeListener> & xListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode?
|
|
return; //behave passive if already disposed or suspended
|
|
|
|
//--add listener
|
|
std::unique_lock aGuard2(m_aLifeTimeManager.m_aAccessMutex);
|
|
m_aLifeTimeManager.m_aSelectionChangeListeners.addInterface( aGuard2, xListener );
|
|
}
|
|
|
|
void SAL_CALL ChartController::removeSelectionChangeListener( const uno::Reference<view::XSelectionChangeListener> & xListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if( impl_isDisposedOrSuspended() ) //@todo? allow removing of listeners in suspend mode?
|
|
return; //behave passive if already disposed or suspended
|
|
|
|
//--remove listener
|
|
std::unique_lock aGuard2(m_aLifeTimeManager.m_aAccessMutex);
|
|
m_aLifeTimeManager.m_aSelectionChangeListeners.removeInterface( aGuard2, xListener );
|
|
}
|
|
|
|
void ChartController::impl_notifySelectionChangeListeners()
|
|
{
|
|
std::unique_lock aGuard(m_aLifeTimeManager.m_aAccessMutex);
|
|
if( m_aLifeTimeManager.m_aSelectionChangeListeners.getLength(aGuard) )
|
|
{
|
|
uno::Reference< view::XSelectionSupplier > xSelectionSupplier(this);
|
|
lang::EventObject aEvent( xSelectionSupplier );
|
|
m_aLifeTimeManager.m_aSelectionChangeListeners.notifyEach(aGuard, &view::XSelectionChangeListener::selectionChanged, aEvent);
|
|
}
|
|
}
|
|
|
|
void ChartController::impl_selectObjectAndNotiy()
|
|
{
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get();
|
|
if( pDrawViewWrapper )
|
|
{
|
|
pDrawViewWrapper->SetDragMode( m_eDragMode );
|
|
m_aSelection.applySelection( m_pDrawViewWrapper.get() );
|
|
}
|
|
}
|
|
impl_notifySelectionChangeListeners();
|
|
}
|
|
|
|
bool ChartController::impl_moveOrResizeObject(
|
|
const OUString & rCID,
|
|
eMoveOrResizeType eType,
|
|
double fAmountLogicX,
|
|
double fAmountLogicY )
|
|
{
|
|
bool bResult = false;
|
|
bool bNeedResize = ( eType == CENTERED_RESIZE_OBJECT );
|
|
|
|
rtl::Reference<::chart::ChartModel> xChartModel( getChartModel() );
|
|
uno::Reference< beans::XPropertySet > xObjProp(
|
|
ObjectIdentifier::getObjectPropertySet( rCID, xChartModel ));
|
|
if( xObjProp.is())
|
|
{
|
|
awt::Size aRefSize = ChartModelHelper::getPageSize( xChartModel );
|
|
|
|
chart2::RelativePosition aRelPos;
|
|
chart2::RelativeSize aRelSize;
|
|
bool bDeterminePos = !(xObjProp->getPropertyValue( u"RelativePosition"_ustr) >>= aRelPos);
|
|
bool bDetermineSize = !bNeedResize || !(xObjProp->getPropertyValue( u"RelativeSize"_ustr) >>= aRelSize);
|
|
|
|
if( ( bDeterminePos || bDetermineSize ) &&
|
|
( aRefSize.Width > 0 && aRefSize.Height > 0 ) )
|
|
{
|
|
ExplicitValueProvider * pValueProvider( m_xChartView.get() );
|
|
if( pValueProvider )
|
|
{
|
|
awt::Rectangle aRect( pValueProvider->getRectangleOfObject( rCID ));
|
|
double fWidth = static_cast< double >( aRefSize.Width );
|
|
double fHeight = static_cast< double >( aRefSize.Height );
|
|
if( bDetermineSize )
|
|
{
|
|
aRelSize.Primary = static_cast< double >( aRect.Width ) / fWidth;
|
|
aRelSize.Secondary = static_cast< double >( aRect.Height ) / fHeight;
|
|
}
|
|
if( bDeterminePos )
|
|
{
|
|
if( bNeedResize && aRelSize.Primary > 0.0 && aRelSize.Secondary > 0.0 )
|
|
{
|
|
aRelPos.Primary = (static_cast< double >( aRect.X ) / fWidth) +
|
|
(aRelSize.Primary / 2.0);
|
|
aRelPos.Secondary = (static_cast< double >( aRect.Y ) / fHeight) +
|
|
(aRelSize.Secondary / 2.0);
|
|
aRelPos.Anchor = drawing::Alignment_CENTER;
|
|
}
|
|
else
|
|
{
|
|
aRelPos.Primary = static_cast< double >( aRect.X ) / fWidth;
|
|
aRelPos.Secondary = static_cast< double >( aRect.Y ) / fHeight;
|
|
aRelPos.Anchor = drawing::Alignment_TOP_LEFT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( eType == CENTERED_RESIZE_OBJECT )
|
|
bResult = lcl_GrowAndShiftLogic( aRelPos, aRelSize, aRefSize, fAmountLogicX, fAmountLogicY );
|
|
else if( eType == MOVE_OBJECT )
|
|
bResult = lcl_MoveObjectLogic( aRelPos, aRelSize, aRefSize, fAmountLogicX, fAmountLogicY );
|
|
|
|
if( bResult )
|
|
{
|
|
ActionDescriptionProvider::ActionType eActionType(ActionDescriptionProvider::ActionType::Move);
|
|
if( bNeedResize )
|
|
eActionType = ActionDescriptionProvider::ActionType::Resize;
|
|
|
|
ObjectType eObjectType = ObjectIdentifier::getObjectType( rCID );
|
|
UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription(
|
|
eActionType, ObjectNameProvider::getName( eObjectType )), m_xUndoManager );
|
|
{
|
|
ControllerLockGuardUNO aCLGuard( xChartModel );
|
|
xObjProp->setPropertyValue( u"RelativePosition"_ustr, uno::Any( aRelPos ));
|
|
if( bNeedResize || (eObjectType == OBJECTTYPE_DIAGRAM) )//Also set an explicit size at the diagram when an explicit position is set
|
|
xObjProp->setPropertyValue( u"RelativeSize"_ustr, uno::Any( aRelSize ));
|
|
}
|
|
aUndoGuard.commit();
|
|
}
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
bool ChartController::impl_DragDataPoint( std::u16string_view rCID, double fAdditionalOffset )
|
|
{
|
|
bool bResult = false;
|
|
if( fAdditionalOffset < -1.0 || fAdditionalOffset > 1.0 || fAdditionalOffset == 0.0 )
|
|
return bResult;
|
|
|
|
sal_Int32 nDataPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( rCID );
|
|
rtl::Reference< DataSeries > xSeries =
|
|
ObjectIdentifier::getDataSeriesForCID( rCID, getChartModel() );
|
|
if( xSeries.is())
|
|
{
|
|
try
|
|
{
|
|
uno::Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex( nDataPointIndex ));
|
|
double fOffset = 0.0;
|
|
if( xPointProp.is() &&
|
|
(xPointProp->getPropertyValue( u"Offset"_ustr ) >>= fOffset ) &&
|
|
(( fAdditionalOffset > 0.0 && fOffset < 1.0 ) || (fOffset > 0.0)) )
|
|
{
|
|
fOffset += fAdditionalOffset;
|
|
if( fOffset > 1.0 )
|
|
fOffset = 1.0;
|
|
else if( fOffset < 0.0 )
|
|
fOffset = 0.0;
|
|
xPointProp->setPropertyValue( u"Offset"_ustr, uno::Any( fOffset ));
|
|
bResult = true;
|
|
}
|
|
}
|
|
catch( const uno::Exception & )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("chart2");
|
|
}
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
void ChartController::impl_SetMousePointer( const MouseEvent & rEvent )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
auto pChartWindow(GetChartWindow());
|
|
|
|
if (!m_pDrawViewWrapper || !pChartWindow)
|
|
return;
|
|
|
|
Point aMousePos( pChartWindow->PixelToLogic( rEvent.GetPosPixel()));
|
|
sal_uInt16 nModifier = rEvent.GetModifier();
|
|
bool bLeftDown = rEvent.IsLeft();
|
|
|
|
// Check if object is for field button and set the normal arrow pointer in this case
|
|
SdrObject* pObject = m_pDrawViewWrapper->getHitObject(aMousePos);
|
|
if (pObject && pObject->GetName().startsWith("FieldButton"))
|
|
{
|
|
pChartWindow->SetPointer(PointerStyle::Arrow);
|
|
return;
|
|
}
|
|
|
|
if ( m_pDrawViewWrapper->IsTextEdit() )
|
|
{
|
|
if( m_pDrawViewWrapper->IsTextEditHit( aMousePos ) )
|
|
{
|
|
pChartWindow->SetPointer( m_pDrawViewWrapper->GetPreferredPointer(
|
|
aMousePos, pChartWindow->GetOutDev(), nModifier, bLeftDown ) );
|
|
return;
|
|
}
|
|
}
|
|
else if( m_pDrawViewWrapper->IsAction() )
|
|
{
|
|
return;//don't change pointer during running action
|
|
}
|
|
|
|
SdrHdl* pHitSelectionHdl = nullptr;
|
|
if( m_aSelection.isResizeableObjectSelected() )
|
|
pHitSelectionHdl = m_pDrawViewWrapper->PickHandle( aMousePos );
|
|
|
|
if( pHitSelectionHdl )
|
|
{
|
|
PointerStyle aPointer = m_pDrawViewWrapper->GetPreferredPointer(
|
|
aMousePos, pChartWindow->GetOutDev(), nModifier, bLeftDown );
|
|
bool bForceArrowPointer = false;
|
|
|
|
ObjectIdentifier aOID( m_aSelection.getSelectedOID() );
|
|
|
|
switch( aPointer)
|
|
{
|
|
case PointerStyle::NSize:
|
|
case PointerStyle::SSize:
|
|
case PointerStyle::WSize:
|
|
case PointerStyle::ESize:
|
|
case PointerStyle::NWSize:
|
|
case PointerStyle::NESize:
|
|
case PointerStyle::SWSize:
|
|
case PointerStyle::SESize:
|
|
if( ! m_aSelection.isResizeableObjectSelected() )
|
|
bForceArrowPointer = true;
|
|
break;
|
|
case PointerStyle::Move:
|
|
if ( !aOID.isDragableObject() )
|
|
bForceArrowPointer = true;
|
|
break;
|
|
case PointerStyle::MovePoint:
|
|
case PointerStyle::MoveBezierWeight:
|
|
// there is no point-editing in a chart
|
|
// the PointerStyle::MoveBezierWeight appears in 3d data points
|
|
bForceArrowPointer = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if( bForceArrowPointer )
|
|
pChartWindow->SetPointer( PointerStyle::Arrow );
|
|
else
|
|
pChartWindow->SetPointer( aPointer );
|
|
|
|
return;
|
|
}
|
|
|
|
// #i12587# support for shapes in chart
|
|
if ( m_eDrawMode == CHARTDRAW_INSERT &&
|
|
( !m_pDrawViewWrapper->IsMarkedHit( aMousePos ) || !m_aSelection.isDragableObjectSelected() ) )
|
|
{
|
|
PointerStyle ePointerStyle = PointerStyle::DrawRect;
|
|
SdrObjKind eKind = m_pDrawViewWrapper->GetCurrentObjIdentifier();
|
|
switch ( eKind )
|
|
{
|
|
case SdrObjKind::Line:
|
|
{
|
|
ePointerStyle = PointerStyle::DrawLine;
|
|
}
|
|
break;
|
|
case SdrObjKind::Rectangle:
|
|
case SdrObjKind::CustomShape:
|
|
{
|
|
ePointerStyle = PointerStyle::DrawRect;
|
|
}
|
|
break;
|
|
case SdrObjKind::CircleOrEllipse:
|
|
{
|
|
ePointerStyle = PointerStyle::DrawEllipse;
|
|
}
|
|
break;
|
|
case SdrObjKind::FreehandLine:
|
|
{
|
|
ePointerStyle = PointerStyle::DrawPolygon;
|
|
}
|
|
break;
|
|
case SdrObjKind::Text:
|
|
{
|
|
ePointerStyle = PointerStyle::DrawText;
|
|
}
|
|
break;
|
|
case SdrObjKind::Caption:
|
|
{
|
|
ePointerStyle = PointerStyle::DrawCaption;
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
ePointerStyle = PointerStyle::DrawRect;
|
|
}
|
|
break;
|
|
}
|
|
pChartWindow->SetPointer( ePointerStyle );
|
|
return;
|
|
}
|
|
|
|
OUString aHitObjectCID(
|
|
SelectionHelper::getHitObjectCID(
|
|
aMousePos, *m_pDrawViewWrapper, true /*bGetDiagramInsteadOf_Wall*/ ));
|
|
|
|
if( m_pDrawViewWrapper->IsTextEdit() )
|
|
{
|
|
if( aHitObjectCID == m_aSelection.getSelectedCID() )
|
|
{
|
|
pChartWindow->SetPointer( PointerStyle::Arrow );
|
|
return;
|
|
}
|
|
}
|
|
|
|
if( aHitObjectCID.isEmpty() )
|
|
{
|
|
//additional shape was hit
|
|
pChartWindow->SetPointer( PointerStyle::Move );
|
|
}
|
|
else if( ObjectIdentifier::isDragableObject( aHitObjectCID ) )
|
|
{
|
|
if( (m_eDragMode == SdrDragMode::Rotate)
|
|
&& SelectionHelper::isRotateableObject( aHitObjectCID
|
|
, getChartModel() ) )
|
|
pChartWindow->SetPointer( PointerStyle::Rotate );
|
|
else
|
|
{
|
|
ObjectType eHitObjectType = ObjectIdentifier::getObjectType( aHitObjectCID );
|
|
if( eHitObjectType == OBJECTTYPE_DATA_POINT )
|
|
{
|
|
if( !ObjectIdentifier::areSiblings(aHitObjectCID,m_aSelection.getSelectedCID())
|
|
&& !ObjectIdentifier::areIdenticalObjects(aHitObjectCID,m_aSelection.getSelectedCID()) )
|
|
{
|
|
pChartWindow->SetPointer( PointerStyle::Arrow );
|
|
return;
|
|
}
|
|
}
|
|
pChartWindow->SetPointer( PointerStyle::Move );
|
|
}
|
|
}
|
|
else
|
|
pChartWindow->SetPointer( PointerStyle::Arrow );
|
|
}
|
|
|
|
void ChartController::sendPopupRequest(std::u16string_view rCID, tools::Rectangle aRectangle)
|
|
{
|
|
ChartModel* pChartModel = m_aModel->getModel().get();
|
|
if (!pChartModel)
|
|
return;
|
|
|
|
uno::Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider;
|
|
xPivotTableDataProvider.set(pChartModel->getDataProvider(), uno::UNO_QUERY);
|
|
if (!xPivotTableDataProvider.is())
|
|
return;
|
|
|
|
OUString sPivotTableName = xPivotTableDataProvider->getPivotTableName();
|
|
|
|
css::uno::Reference<css::awt::XRequestCallback> xPopupRequest = pChartModel->getPopupRequest();
|
|
PopupRequest* pPopupRequest = dynamic_cast<PopupRequest*>(xPopupRequest.get());
|
|
if (!pPopupRequest)
|
|
return;
|
|
|
|
// Get dimension index from CID
|
|
size_t nStartPos = rCID.rfind('.');
|
|
nStartPos = (nStartPos == std::u16string_view::npos) ? 0 : (nStartPos + 1);
|
|
sal_Int32 nEndPos = rCID.size();
|
|
std::u16string_view sDimensionIndex = rCID.substr(nStartPos, nEndPos - nStartPos);
|
|
sal_Int32 nDimensionIndex = o3tl::toInt32(sDimensionIndex);
|
|
|
|
awt::Rectangle xRectangle {
|
|
sal_Int32(aRectangle.Left()),
|
|
sal_Int32(aRectangle.Top()),
|
|
sal_Int32(aRectangle.GetWidth()),
|
|
sal_Int32(aRectangle.GetHeight())
|
|
};
|
|
|
|
uno::Sequence<beans::PropertyValue> aCallbackData = comphelper::InitPropertySequence(
|
|
{
|
|
{"Rectangle", uno::Any(xRectangle)},
|
|
{"DimensionIndex", uno::Any(sal_Int32(nDimensionIndex))},
|
|
{"PivotTableName", uno::Any(sPivotTableName)},
|
|
});
|
|
|
|
pPopupRequest->getCallback()->notify(uno::Any(aCallbackData));
|
|
}
|
|
|
|
} //namespace chart
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|