blob: 3c1cfcc5d590f74ccf20998fab6e0e8af22961be [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"
#include "ChartController.hxx"
#include "PositionAndSizeHelper.hxx"
#include "ObjectIdentifier.hxx"
#include "ChartWindow.hxx"
#include "ResId.hxx"
#include "CommonConverters.hxx"
#include "ChartModelHelper.hxx"
#include "DiagramHelper.hxx"
#include "TitleHelper.hxx"
#include "UndoGuard.hxx"
#include "ControllerLockGuard.hxx"
#include "ObjectNameProvider.hxx"
#include "Strings.hrc"
#include "SchSlotIds.hxx"
#include "macros.hxx"
#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 "StatisticsHelper.hxx"
#include "DataSeriesHelper.hxx"
#include "ContainerHelper.hxx"
#include "AxisHelper.hxx"
#include "LegendHelper.hxx"
#include "servicenames_charttypes.hxx"
#include "MenuResIds.hrc"
#include "DrawCommandDispatch.hxx"
#include <com/sun/star/chart2/RelativePosition.hpp>
#include <com/sun/star/chart2/RelativeSize.hpp>
#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
#include <com/sun/star/frame/XDispatchHelper.hpp>
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#include <com/sun/star/util/XUpdatable.hpp>
#include <comphelper/InlineContainer.hxx>
#include <svtools/contextmenuhelper.hxx>
#include <toolkit/awt/vclxmenu.hxx>
#include <svx/svxids.hrc>
#include <svx/ActionDescriptionProvider.hxx>
// header for class E3dObject
#include <svx/obj3d.hxx>
// header for class E3dScene
#include <svx/scene3d.hxx>
// header for class SdrDragMethod
#include <svx/svddrgmt.hxx>
#include <vcl/svapp.hxx>
#include <vos/mutex.hxx>
// for InfoBox
#include <vcl/msgbox.hxx>
#include <rtl/math.hxx>
#include <svtools/acceleratorexecute.hxx>
#define DRGPIX 2 // Drag MinMove in Pixel
using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;
using ::com::sun::star::uno::Reference;
using ::rtl::OUString;
//.............................................................................
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,
/* bCheck = */ true );
}
bool lcl_MoveObjectLogic(
RelativePosition & rInOutRelPos,
RelativeSize & 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,
/* bCheck = */ true );
}
void lcl_insertMenuCommand(
const uno::Reference< awt::XPopupMenu > & xMenu,
sal_Int16 nId, const ::rtl::OUString & rCommand )
{
static ::rtl::OUString aEmptyString;
xMenu->insertItem( nId, aEmptyString, 0, -1 );
xMenu->setCommand( nId, rCommand );
}
OUString lcl_getFormatCommandForObjectCID( const OUString& rCID )
{
OUString aDispatchCommand( C2U(".uno:FormatSelection") );
ObjectType eObjectType = ObjectIdentifier::getObjectType( rCID );
switch(eObjectType)
{
case OBJECTTYPE_DIAGRAM:
case OBJECTTYPE_DIAGRAM_WALL:
aDispatchCommand = C2U(".uno:FormatWall");
break;
case OBJECTTYPE_DIAGRAM_FLOOR:
aDispatchCommand = C2U(".uno:FormatFloor");
break;
case OBJECTTYPE_PAGE:
aDispatchCommand = C2U(".uno:FormatChartArea");
break;
case OBJECTTYPE_LEGEND:
aDispatchCommand = C2U(".uno:FormatLegend");
break;
case OBJECTTYPE_TITLE:
aDispatchCommand = C2U(".uno:FormatTitle");
break;
case OBJECTTYPE_LEGEND_ENTRY:
aDispatchCommand = C2U(".uno:FormatDataSeries");
break;
case OBJECTTYPE_AXIS:
case OBJECTTYPE_AXIS_UNITLABEL:
aDispatchCommand = C2U(".uno:FormatAxis");
break;
case OBJECTTYPE_GRID:
aDispatchCommand = C2U(".uno:FormatMajorGrid");
break;
case OBJECTTYPE_SUBGRID:
aDispatchCommand = C2U(".uno:FormatMinorGrid");
break;
case OBJECTTYPE_DATA_LABELS:
aDispatchCommand = C2U(".uno:FormatDataLabels");
break;
case OBJECTTYPE_DATA_SERIES:
aDispatchCommand = C2U(".uno:FormatDataSeries");
break;
case OBJECTTYPE_DATA_LABEL:
aDispatchCommand = C2U(".uno:FormatDataLabel");
break;
case OBJECTTYPE_DATA_POINT:
aDispatchCommand = C2U(".uno:FormatDataPoint");
break;
case OBJECTTYPE_DATA_AVERAGE_LINE:
aDispatchCommand = C2U(".uno:FormatMeanValue");
break;
case OBJECTTYPE_DATA_ERRORS:
case OBJECTTYPE_DATA_ERRORS_X:
case OBJECTTYPE_DATA_ERRORS_Y:
case OBJECTTYPE_DATA_ERRORS_Z:
aDispatchCommand = C2U(".uno:FormatYErrorBars");
break;
case OBJECTTYPE_DATA_CURVE:
aDispatchCommand = C2U(".uno:FormatTrendline");
break;
case OBJECTTYPE_DATA_CURVE_EQUATION:
aDispatchCommand = C2U(".uno:FormatTrendlineEquation");
break;
case OBJECTTYPE_DATA_STOCK_RANGE:
aDispatchCommand = C2U(".uno:FormatSelection");
break;
case OBJECTTYPE_DATA_STOCK_LOSS:
aDispatchCommand = C2U(".uno:FormatStockLoss");
break;
case OBJECTTYPE_DATA_STOCK_GAIN:
aDispatchCommand = C2U(".uno:FormatStockGain");
break;
default: //OBJECTTYPE_UNKNOWN
break;
}
return aDispatchCommand;
}
} // anonymous namespace
const short HITPIX=2; //hit-tolerance in pixel
//-----------------------------------------------------------------
// awt::XWindow
//-----------------------------------------------------------------
void SAL_CALL ChartController
::setPosSize( sal_Int32 X, sal_Int32 Y
, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags )
throw (uno::RuntimeException)
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
if(xWindow.is() && m_pChartWindow)
{
Size aLogicSize = m_pChartWindow->PixelToLogic( Size( Width, Height ), MapMode( MAP_100TH_MM ) );
bool bIsEmbedded = true;
//todo: for standalone chart: detect wether we are standalone
if( bIsEmbedded )
{
//change map mode to fit new size
awt::Size aModelPageSize = ChartModelHelper::getPageSize( getModel() );
sal_Int32 nScaleXNumerator = aLogicSize.Width();
sal_Int32 nScaleXDenominator = aModelPageSize.Width;
sal_Int32 nScaleYNumerator = aLogicSize.Height();
sal_Int32 nScaleYDenominator = aModelPageSize.Height;
MapMode aNewMapMode( MAP_100TH_MM, Point(0,0)
, Fraction(nScaleXNumerator,nScaleXDenominator)
, Fraction(nScaleYNumerator,nScaleYDenominator) );
m_pChartWindow->SetMapMode(aNewMapMode);
m_pChartWindow->SetPosSizePixel( X, Y, Width, Height, Flags );
//#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
uno::Reference< beans::XPropertySet > xProp( m_xChartView, uno::UNO_QUERY );
if( xProp.is() )
{
uno::Sequence< beans::PropertyValue > aZoomFactors(4);
aZoomFactors[0].Name = C2U("ScaleXNumerator");
aZoomFactors[0].Value = uno::makeAny( nScaleXNumerator );
aZoomFactors[1].Name = C2U("ScaleXDenominator");
aZoomFactors[1].Value = uno::makeAny( nScaleXDenominator );
aZoomFactors[2].Name = C2U("ScaleYNumerator");
aZoomFactors[2].Value = uno::makeAny( nScaleYNumerator );
aZoomFactors[3].Name = C2U("ScaleYDenominator");
aZoomFactors[3].Value = uno::makeAny( nScaleYDenominator );
xProp->setPropertyValue( C2U("ZoomFactors"), uno::makeAny( 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)
{
Rectangle aRect(Point(0,0), m_pChartWindow->GetOutputSize());
m_pDrawViewWrapper->SetWorkArea( aRect );
}
}
else
{
//change visarea
ChartModelHelper::setPageSize( awt::Size( aLogicSize.Width(), aLogicSize.Height() ), getModel() );
m_pChartWindow->SetPosSizePixel( X, Y, Width, Height, Flags );
}
m_pChartWindow->Invalidate();
}
}
awt::Rectangle SAL_CALL ChartController
::getPosSize()
throw (uno::RuntimeException)
{
//@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 )
throw (uno::RuntimeException)
{
//@todo
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
if(xWindow.is())
xWindow->setVisible( Visible );
}
void SAL_CALL ChartController
::setEnable( sal_Bool Enable )
throw (uno::RuntimeException)
{
//@todo
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
if(xWindow.is())
xWindow->setEnable( Enable );
}
void SAL_CALL ChartController
::setFocus() throw (uno::RuntimeException)
{
//@todo
uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
if(xWindow.is())
xWindow->setFocus();
}
void SAL_CALL ChartController
::addWindowListener( const uno::Reference<
awt::XWindowListener >& xListener )
throw (uno::RuntimeException)
{
//@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 )
throw (uno::RuntimeException)
{
//@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 )
throw (uno::RuntimeException)
{
//@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 )
throw (uno::RuntimeException)
{
//@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 )
throw (uno::RuntimeException)
{
//@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 )
throw (uno::RuntimeException)
{
//@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 )
throw (uno::RuntimeException)
{
//@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 )
throw (uno::RuntimeException)
{
//@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 )
throw (uno::RuntimeException)
{
//@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 )
throw (uno::RuntimeException)
{
//@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 )
throw (uno::RuntimeException)
{
//@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 )
throw (uno::RuntimeException)
{
//@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;
if(pDrawViewWrapper)
{
pDrawViewWrapper->PrePaint();
}
}
void ChartController::execute_Paint( const Rectangle& rRect )
{
try
{
uno::Reference< frame::XModel > xModel( getModel() );
//DBG_ASSERT( xModel.is(), "ChartController::execute_Paint: have no model to paint");
if( !xModel.is() )
return;
//better performance for big data
uno::Reference< beans::XPropertySet > xProp( m_xChartView, uno::UNO_QUERY );
if( xProp.is() )
{
awt::Size aResolution(1000,1000);
{
::vos::OGuard aGuard( Application::GetSolarMutex());
if( m_pChartWindow )
{
aResolution.Width = m_pChartWindow->GetSizePixel().Width();
aResolution.Height = m_pChartWindow->GetSizePixel().Height();
}
}
xProp->setPropertyValue( C2U("Resolution"), uno::makeAny( aResolution ));
}
//
uno::Reference< util::XUpdatable > xUpdatable( m_xChartView, uno::UNO_QUERY );
if( xUpdatable.is() )
xUpdatable->update();
{
::vos::OGuard aGuard( Application::GetSolarMutex());
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
if(pDrawViewWrapper)
pDrawViewWrapper->CompleteRedraw(m_pChartWindow, Region(rRect) );
}
}
catch( uno::Exception & ex )
{
ASSERT_EXCEPTION( ex );
}
catch( ... )
{
}
}
bool isDoubleClick( const MouseEvent& rMEvt )
{
return rMEvt.GetClicks() == 2 && rMEvt.IsLeft() &&
!rMEvt.IsMod1() && !rMEvt.IsMod2() && !rMEvt.IsShift();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void ChartController::startDoubleClickWaiting()
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
m_bWaitingForDoubleClick = true;
sal_uLong nDblClkTime = 500;
if( m_pChartWindow )
{
const MouseSettings& rMSettings = m_pChartWindow->GetSettings().GetMouseSettings();
nDblClkTime = rMSettings.GetDoubleClickTime();
}
m_aDoubleClickTimer.SetTimeout( nDblClkTime );
m_aDoubleClickTimer.Start();
}
void ChartController::stopDoubleClickWaiting()
{
m_aDoubleClickTimer.Stop();
m_bWaitingForDoubleClick = false;
}
IMPL_LINK( ChartController, DoubleClickWaitingHdl, void*, EMPTYARG )
{
m_bWaitingForDoubleClick = false;
if( !m_bWaitingForMouseUp && m_aSelection.maybeSwitchSelectionAfterSingleClickWasEnsured() )
{
this->impl_selectObjectAndNotiy();
::vos::OGuard aGuard( Application::GetSolarMutex() );
if( m_pChartWindow )
{
Window::PointerState aPointerState( m_pChartWindow->GetPointerState() );
MouseEvent aMouseEvent( aPointerState.maPos,1/*nClicks*/,
0/*nMode*/, static_cast< sal_uInt16 >( aPointerState.mnState )/*nButtons*/,
0/*nModifier*/ );
impl_SetMousePointer( aMouseEvent );
}
}
return 0;
}
//------------------------------------------------------------------------
void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt )
{
::vos::OGuard aGuard( Application::GetSolarMutex());
m_bWaitingForMouseUp = true;
if( isDoubleClick(rMEvt) )
stopDoubleClickWaiting();
else
startDoubleClickWaiting();
m_aSelection.remindSelectionBeforeMouseDown();
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
if(!m_pChartWindow || !pDrawViewWrapper )
return;
Point aMPos = m_pChartWindow->PixelToLogic(rMEvt.GetPosPixel());
if ( MOUSE_LEFT == rMEvt.GetButtons() )
{
m_pChartWindow->GrabFocus();
m_pChartWindow->CaptureMouse();
}
if( pDrawViewWrapper->IsTextEdit() )
{
SdrViewEvent aVEvt;
if ( pDrawViewWrapper->IsTextEditHit( aMPos, HITPIX ) ||
// #i12587# support for shapes in chart
( rMEvt.IsRight() && pDrawViewWrapper->PickAnything( rMEvt, SDRMOUSEBUTTONDOWN, aVEvt ) == SDRHIT_MARKEDOBJECT ) )
{
pDrawViewWrapper->MouseButtonDown(rMEvt,m_pChartWindow);
return;
}
else
{
this->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 = 0;
//switch from move to resize if handle is hit on a resizeable 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() == OBJ_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( getModel() ) )
{
m_eDragMode = SDRDRAG_MOVE;
pDrawViewWrapper->SetDragMode(m_eDragMode);
}
m_aSelection.applySelection(pDrawViewWrapper);
}
if( m_aSelection.isDragableObjectSelected()
&& !rMEvt.IsRight() )
{
//start drag
sal_uInt16 nDrgLog = (sal_uInt16)m_pChartWindow->PixelToLogic(Size(DRGPIX,0)).Width();
SdrDragMethod* pDragMethod = NULL;
//change selection to 3D scene if rotate mode
SdrDragMode eDragMode = pDrawViewWrapper->GetDragMode();
if( SDRDRAG_ROTATE==eDragMode )
{
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==HDL_UPPER || eKind==HDL_LOWER )
eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_X;
else if( eKind==HDL_LEFT || eKind==HDL_RIGHT )
eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_Y;
else if( eKind==HDL_UPLFT || eKind==HDL_UPRGT || eKind==HDL_LWLFT || eKind==HDL_LWRGT )
eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_Z;
}
pDragMethod = new DragMethod_RotateDiagram( *pDrawViewWrapper, m_aSelection.getSelectedCID(), getModel(), eRotationDirection );
}
}
else
{
rtl::OUString aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ) );
if( aDragMethodServiceName.equals( ObjectIdentifier::getPieSegmentDragMethodServiceName() ) )
pDragMethod = new DragMethod_PieSegment( *pDrawViewWrapper, m_aSelection.getSelectedCID(), getModel() );
}
pDrawViewWrapper->SdrView::BegDragObj(aMPos, NULL, pHitSelectionHdl, nDrgLog, pDragMethod);
}
impl_SetMousePointer( rMEvt );
}
void ChartController::execute_MouseMove( const MouseEvent& rMEvt )
{
::vos::OGuard aGuard( Application::GetSolarMutex());
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
if(!m_pChartWindow || !pDrawViewWrapper)
return;
if( m_pDrawViewWrapper->IsTextEdit() )
{
if( m_pDrawViewWrapper->MouseMove(rMEvt,m_pChartWindow) )
return;
}
if(pDrawViewWrapper->IsAction())
{
pDrawViewWrapper->MovAction( m_pChartWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
}
//?? pDrawViewWrapper->GetPageView()->DragPoly();
impl_SetMousePointer( rMEvt );
}
void ChartController::execute_Tracking( const TrackingEvent& /* rTEvt */ )
{
}
//-----------------
void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt )
{
ControllerLockGuard aCLGuard( getModel() );
bool bMouseUpWithoutMouseDown = !m_bWaitingForMouseUp;
m_bWaitingForMouseUp = false;
bool bNotifySelectionChange = false;
{
::vos::OGuard aGuard( Application::GetSolarMutex());
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
if(!m_pChartWindow || !pDrawViewWrapper)
return;
Point aMPos = m_pChartWindow->PixelToLogic(rMEvt.GetPosPixel());
if(pDrawViewWrapper->IsTextEdit())
{
if( pDrawViewWrapper->MouseButtonUp(rMEvt,m_pChartWindow) )
return;
}
// #i12587# support for shapes in chart
if ( m_eDrawMode == CHARTDRAW_INSERT && pDrawViewWrapper->IsCreateObj() )
{
pDrawViewWrapper->EndCreateObj( SDRCREATE_FORCEEND );
{
HiddenUndoContext aUndoContext( m_xUndoManager );
// don't want the positioning Undo action to appear in the UI
impl_switchDiagramPositioningToExcludingPositioning();
}
if ( pDrawViewWrapper->AreObjectsMarked() )
{
if ( pDrawViewWrapper->GetCurrentObjIdentifier() == OBJ_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() : false;
DragMethod_Base* pChartDragMethod = dynamic_cast< DragMethod_Base* >(pDragMethod);
if( pChartDragMethod )
{
UndoGuard aUndoGuard( pChartDragMethod->getUndoDescription(),
m_xUndoManager );
if( pDrawViewWrapper->EndDragObj(false) )
{
bDraggingDone = true;
aUndoGuard.commit();
}
}
if( !bDraggingDone && pDrawViewWrapper->EndDragObj(false) )
{
try
{
//end move or size
SdrObject* pObj = pDrawViewWrapper->getSelectedObject();
if( pObj )
{
Rectangle aObjectRect = pObj->GetSnapRect();
awt::Size aPageSize( ChartModelHelper::getPageSize( getModel() ) );
Rectangle aPageRect( 0,0,aPageSize.Width,aPageSize.Height );
const E3dObject* pE3dObject = dynamic_cast< const E3dObject*>( pObj );
if( pE3dObject )
aObjectRect = pE3dObject->GetScene()->GetSnapRect();
ActionDescriptionProvider::ActionType eActionType(ActionDescriptionProvider::MOVE);
if( !bIsMoveOnly && m_aSelection.isResizeableObjectSelected() )
eActionType = ActionDescriptionProvider::RESIZE;
ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() );
UndoGuard aUndoGuard(
ActionDescriptionProvider::createDescription( eActionType, ObjectNameProvider::getName( eObjectType)),
m_xUndoManager );
bool bChanged = false;
if ( eObjectType == OBJECTTYPE_LEGEND )
bChanged = DiagramHelper::switchDiagramPositioningToExcludingPositioning( getModel(), false , true );
bool bMoved = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID()
, getModel()
, awt::Rectangle(aObjectRect.getX(),aObjectRect.getY(),aObjectRect.getWidth(),aObjectRect.getHeight())
, awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight()) );
if( bMoved || bChanged )
{
bDraggingDone = true;
aUndoGuard.commit();
}
}
}
catch( uno::Exception & ex )
{
ASSERT_EXCEPTION( ex );
}
//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( getModel() );
//toggel between move and rotate
if( bIsRotateable && bClickedTwiceOnDragableObject && SDRDRAG_MOVE==m_eDragMode )
m_eDragMode=SDRDRAG_ROTATE;
else
m_eDragMode=SDRDRAG_MOVE;
pDrawViewWrapper->SetDragMode(m_eDragMode);
if( !m_bWaitingForDoubleClick && m_aSelection.maybeSwitchSelectionAfterSingleClickWasEnsured() )
{
this->impl_selectObjectAndNotiy();
}
}
else
m_aSelection.resetPossibleSelectionAfterSingleClickWasEnsured();
}
else if( isDoubleClick(rMEvt) && !bMouseUpWithoutMouseDown /*#i106966#*/ )
{
Point aMousePixel = rMEvt.GetPosPixel();
execute_DoubleClick( &aMousePixel );
}
//@todo ForcePointer(&rMEvt);
m_pChartWindow->ReleaseMouse();
if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() )
bNotifySelectionChange = true;
}
impl_SetMousePointer( rMEvt );
if(bNotifySelectionChange)
impl_notifySelectionChangeListeners();
}
void ChartController::execute_DoubleClick( const Point* pMousePixel )
{
bool bEditText = false;
if ( m_aSelection.hasSelection() )
{
::rtl::OUString aCID( m_aSelection.getSelectedCID() );
if ( !aCID.isEmpty() )
{
ObjectType eObjectType = ObjectIdentifier::getObjectType( aCID );
if ( OBJECTTYPE_TITLE == eObjectType )
{
bEditText = true;
}
}
else
{
// #i12587# support for shapes in chart
SdrObject* pObj = DrawViewWrapper::getSdrObject( m_aSelection.getSelectedAdditionalShape() );
if ( pObj && pObj->ISA( SdrTextObj ) )
{
bEditText = true;
}
}
}
if ( bEditText )
{
executeDispatch_EditText( pMousePixel );
}
else
{
executeDispatch_ObjectProperties();
}
}
void ChartController::execute_Resize()
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
if(m_pChartWindow)
m_pChartWindow->Invalidate();
}
void ChartController::execute_Activate()
{
///// pDrawViewWrapper->SetEditMode(sal_True);
}
void ChartController::execute_Deactivate()
{
/*
pDrawViewWrapper->SetEditMode(sal_False);
this->ReleaseMouse();
*/
}
void ChartController::execute_GetFocus()
{
}
void ChartController::execute_LoseFocus()
{
//this->ReleaseMouse();
}
void ChartController::execute_Command( const CommandEvent& rCEvt )
{
bool bIsAction = false;
{
::vos::OGuard aGuard( Application::GetSolarMutex());
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
if(!m_pChartWindow || !pDrawViewWrapper)
return;
bIsAction = m_pDrawViewWrapper->IsAction();
}
// pop-up menu
if(rCEvt.GetCommand() == COMMAND_CONTEXTMENU && !bIsAction)
{
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
if(m_pChartWindow)
m_pChartWindow->ReleaseMouse();
}
if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() )
impl_notifySelectionChangeListeners();
if ( isShapeContext() )
{
// #i12587# support for shapes in chart
PopupMenu aContextMenu( SchResId( m_pDrawViewWrapper->IsTextEdit() ?
RID_CONTEXTMENU_SHAPEEDIT : RID_CONTEXTMENU_SHAPE ) );
::svt::ContextMenuHelper aContextMenuHelper( m_xFrame );
Point aPos( rCEvt.GetMousePosPixel() );
if( !rCEvt.IsMouseEvent() )
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
if(m_pChartWindow)
aPos = m_pChartWindow->GetPointerState().maPos;
}
aContextMenuHelper.completeAndExecute( aPos, aContextMenu );
}
else
{
// todo: the context menu should be specified by an xml file in uiconfig
uno::Reference< awt::XPopupMenu > xPopupMenu(
m_xCC->getServiceManager()->createInstanceWithContext(
C2U("com.sun.star.awt.PopupMenu"), m_xCC ), uno::UNO_QUERY );
if( xPopupMenu.is())
{
sal_Int16 nUniqueId = 1;
ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() );
Reference< XDiagram > xDiagram = ChartModelHelper::findDiagram( getModel() );
OUString aFormatCommand( lcl_getFormatCommandForObjectCID( m_aSelection.getSelectedCID() ) );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, aFormatCommand );
//some commands for dataseries and points:
//-----
if( OBJECTTYPE_DATA_SERIES == eObjectType || OBJECTTYPE_DATA_POINT == eObjectType )
{
bool bIsPoint = ( OBJECTTYPE_DATA_POINT == eObjectType );
uno::Reference< XDataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() );
uno::Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY );
Reference< chart2::XRegressionCurve > xTrendline( RegressionCurveHelper::getFirstCurveNotMeanValueLine( xCurveCnt ) );
bool bHasEquation = RegressionCurveHelper::hasEquation( xTrendline );
Reference< chart2::XRegressionCurve > xMeanValue( RegressionCurveHelper::getMeanValueLine( xCurveCnt ) );
bool bHasYErrorBars = StatisticsHelper::hasErrorBars( xSeries, true );
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;
Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
if( xSeriesProperties.is() )
{
uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
{
if( aAttributedDataPointIndexList.hasElements() )
{
if( bIsPoint )
{
::std::vector< sal_Int32 > aIndices( ContainerHelper::SequenceToVector( aAttributedDataPointIndexList ) );
::std::vector< sal_Int32 >::iterator aIt = ::std::find( aIndices.begin(), aIndices.end(), nPointIndex );
if( aIt != aIndices.end())
bSelectedPointIsFormatted = true;
else
bHasFormattedDataPointsOtherThanSelected = true;
}
else
bHasFormattedDataPointsOtherThanSelected = true;
}
}
}
//const sal_Int32 nIdBeforeFormat = nUniqueId;
if( bIsPoint )
{
if( bHasDataLabelAtPoint )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatDataLabel") );
if( !bHasDataLabelAtPoint )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertDataLabel") );
else
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteDataLabel") );
if( bSelectedPointIsFormatted )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:ResetDataPoint"));
xPopupMenu->insertSeparator( -1 );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatDataSeries") );
}
Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram, xSeries ) );
if( xChartType->getChartType().equals(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
{
try
{
Reference< beans::XPropertySet > xChartTypeProp( xChartType, uno::UNO_QUERY );
if( xChartTypeProp.is() )
{
bool bJapaneseStyle = false;
xChartTypeProp->getPropertyValue( C2U( "Japanese" ) ) >>= bJapaneseStyle;
if( bJapaneseStyle )
{
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatStockLoss") );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatStockGain") );
}
}
}
catch( const uno::Exception & ex )
{
ASSERT_EXCEPTION( ex );
}
}
if( bHasDataLabelsAtSeries )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatDataLabels") );
if( xTrendline.is() )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatTrendline") );
if( bHasEquation )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatTrendlineEquation") );
if( xMeanValue.is() )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatMeanValue") );
if( bHasYErrorBars )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatYErrorBars") );
//if( nIdBeforeFormat != nUniqueId )
xPopupMenu->insertSeparator( -1 );
//const sal_Int32 nIdBeforeInsert = nUniqueId;
if( !bHasDataLabelsAtSeries )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertDataLabels") );
if( !xTrendline.is() )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertTrendline") );
else if( !bHasEquation )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertTrendlineEquation") );
if( !xMeanValue.is() )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertMeanValue") );
if( !bHasYErrorBars )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertYErrorBars") );
//if( nIdBeforeInsert != nUniqueId )
// xPopupMenu->insertSeparator( -1 );
//const sal_Int32 nIdBeforeDelete = nUniqueId;
if( bHasDataLabelsAtSeries || ( bHasDataLabelsAtPoints && bHasFormattedDataPointsOtherThanSelected ) )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteDataLabels") );
if( xTrendline.is() )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteTrendline") );
if( bHasEquation )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteTrendlineEquation") );
if( xMeanValue.is() )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteMeanValue") );
if( bHasYErrorBars )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteYErrorBars") );
if( bHasFormattedDataPointsOtherThanSelected )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:ResetAllDataPoints"));
//if( nIdBeforeDelete != nUniqueId )
xPopupMenu->insertSeparator( -1 );
lcl_insertMenuCommand( xPopupMenu, nUniqueId, C2U(".uno:ArrangeRow"));
uno::Reference< awt::XPopupMenu > xArrangePopupMenu(
m_xCC->getServiceManager()->createInstanceWithContext(
C2U("com.sun.star.awt.PopupMenu"), m_xCC ), uno::UNO_QUERY );
if( xArrangePopupMenu.is() )
{
sal_Int16 nSubId = nUniqueId + 1;
lcl_insertMenuCommand( xArrangePopupMenu, nSubId++, C2U(".uno:Forward") );
lcl_insertMenuCommand( xArrangePopupMenu, nSubId, C2U(".uno:Backward") );
xPopupMenu->setPopupMenu( nUniqueId, xArrangePopupMenu );
nUniqueId = nSubId;
}
++nUniqueId;
}
else if( OBJECTTYPE_DATA_CURVE == eObjectType )
{
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatTrendlineEquation") );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertTrendlineEquation") );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertTrendlineEquationAndR2") );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertR2Value") );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteTrendlineEquation") );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteR2Value") );
}
else if( OBJECTTYPE_DATA_CURVE_EQUATION == eObjectType )
{
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertR2Value") );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteR2Value") );
}
//some commands for axes: and grids
//-----
else if( OBJECTTYPE_AXIS == eObjectType || OBJECTTYPE_GRID == eObjectType || OBJECTTYPE_SUBGRID == eObjectType )
{
Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), getModel() );
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 = false;
uno::Reference< XTitled > xTitled( xAxis, uno::UNO_QUERY );
if( xTitled.is())
bHasTitle = ( TitleHelper::getCompleteString( xTitled->getTitleObject() ).isEmpty() == false );
if( OBJECTTYPE_AXIS != eObjectType && bIsAxisVisible )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatAxis") );
if( OBJECTTYPE_GRID != eObjectType && bIsMajorGridVisible && !bIsSecondaryAxis )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatMajorGrid") );
if( OBJECTTYPE_SUBGRID != eObjectType && bIsMinorGridVisible && !bIsSecondaryAxis )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatMinorGrid") );
xPopupMenu->insertSeparator( -1 );
if( OBJECTTYPE_AXIS != eObjectType && !bIsAxisVisible )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertAxis") );
if( OBJECTTYPE_GRID != eObjectType && !bIsMajorGridVisible && !bIsSecondaryAxis )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertMajorGrid") );
if( OBJECTTYPE_SUBGRID != eObjectType && !bIsMinorGridVisible && !bIsSecondaryAxis )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertMinorGrid") );
if( !bHasTitle )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertAxisTitle") );
if( bIsAxisVisible )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteAxis") );
if( bIsMajorGridVisible && !bIsSecondaryAxis )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteMajorGrid") );
if( bIsMinorGridVisible && !bIsSecondaryAxis )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteMinorGrid") );
}
}
if( OBJECTTYPE_DATA_STOCK_LOSS == eObjectType )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatStockGain") );
else if( OBJECTTYPE_DATA_STOCK_GAIN == eObjectType )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatStockLoss") );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:TransformDialog"));
if( OBJECTTYPE_PAGE == eObjectType || OBJECTTYPE_DIAGRAM == eObjectType
|| OBJECTTYPE_DIAGRAM_WALL == eObjectType
|| OBJECTTYPE_DIAGRAM_FLOOR == eObjectType
|| OBJECTTYPE_UNKNOWN == eObjectType )
{
if( OBJECTTYPE_UNKNOWN != eObjectType )
xPopupMenu->insertSeparator( -1 );
bool bHasLegend = LegendHelper::hasLegend( xDiagram );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertTitles") );
if( !bHasLegend )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertLegend") );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertRemoveAxes") );
if( bHasLegend )
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteLegend") );
}
//-----
xPopupMenu->insertSeparator( -1 );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DiagramType"));
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DataRanges"));
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DiagramData"));
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:View3D"));
xPopupMenu->insertSeparator( -1 );
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:Cut"));
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:Copy"));
lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:Paste"));
::svt::ContextMenuHelper aContextMenuHelper( m_xFrame );
Point aPos( rCEvt.GetMousePosPixel() );
if( !rCEvt.IsMouseEvent() )
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
if(m_pChartWindow)
aPos = m_pChartWindow->GetPointerState().maPos;
}
aContextMenuHelper.completeAndExecute( aPos, xPopupMenu );
}
}
}
else if( ( rCEvt.GetCommand() == COMMAND_STARTEXTTEXTINPUT ) ||
( rCEvt.GetCommand() == COMMAND_EXTTEXTINPUT ) ||
( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT ) ||
( rCEvt.GetCommand() == COMMAND_INPUTCONTEXTCHANGE ) )
{
//#i84417# enable editing with IME
::vos::OGuard aGuard( Application::GetSolarMutex() );
if( m_pDrawViewWrapper )
m_pDrawViewWrapper->Command( rCEvt, m_pChartWindow );
}
}
bool ChartController::execute_KeyInput( const KeyEvent& rKEvt )
{
bool bReturn=false;
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
if(!m_pChartWindow || !pDrawViewWrapper)
return bReturn;
// handle accelerators
if( ! m_apAccelExecute.get() && m_xFrame.is() && m_xCC.is() && m_xCC->getServiceManager().is() )
{
m_apAccelExecute.reset( ::svt::AcceleratorExecute::createAcceleratorHelper());
OSL_ASSERT( m_apAccelExecute.get());
if( m_apAccelExecute.get() )
m_apAccelExecute->init(
uno::Reference< lang::XMultiServiceFactory >( m_xCC->getServiceManager(), uno::UNO_QUERY ), m_xFrame );
}
KeyCode aKeyCode( rKEvt.GetKeyCode());
sal_uInt16 nCode = aKeyCode.GetCode();
// bool bShift = aKeyCode.IsShift();
bool bAlternate = aKeyCode.IsMod2();
if( m_apAccelExecute.get() )
bReturn = m_apAccelExecute->execute( aKeyCode );
if( bReturn )
return bReturn;
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
if( pDrawViewWrapper->IsTextEdit() )
{
if( pDrawViewWrapper->KeyInput(rKEvt,m_pChartWindow) )
{
bReturn = true;
if( nCode == KEY_ESCAPE )
{
this->EndTextEdit();
}
}
}
}
//if( m_pDrawViewWrapper->IsAction() );
// keyboard accessibility
ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() );
if( ! bReturn )
{
// Natvigation (Tab/F3/Home/End)
uno::Reference< XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
ObjectKeyNavigation aObjNav( m_aSelection.getSelectedOID(), xChartDoc, ExplicitValueProvider::getExplicitValueProvider( m_xChartView ));
awt::KeyEvent aKeyEvent( ::svt::AcceleratorExecute::st_VCLKey2AWTKey( aKeyCode ));
bReturn = aObjNav.handleKeyEvent( aKeyEvent );
if( bReturn )
{
ObjectIdentifier aNewOID = aObjNav.getCurrentSelection();
uno::Any aNewSelection;
if ( aNewOID.isValid() && !ObjectHierarchy::isRootNode( aNewOID ) )
{
aNewSelection = aNewOID.getAny();
}
if ( m_eDragMode == SDRDRAG_ROTATE && !SelectionHelper::isRotateableObject( aNewOID.getObjectCID(), getModel() ) )
{
m_eDragMode = SDRDRAG_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() ).equals(
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;
rtl::OUString 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 && m_pChartWindow )
{
// together with Alt-key: 1 px in each direction
::vos::OGuard aGuard( Application::GetSolarMutex() );
if( m_pChartWindow )
{
Size aPixelSize = m_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 && m_pChartWindow )
{
// together with Alt-key: 1 px
::vos::OGuard aGuard( Application::GetSolarMutex() );
if(m_pChartWindow)
{
Size aPixelSize = m_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
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( getModel() ) );
aPos.X = static_cast< long >( static_cast< double >( aPos.X ) + fShiftAmountX );
aPos.Y = static_cast< 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 );
}
}
}
}
}
}
// text edit
if( ! bReturn &&
nCode == KEY_F2 )
{
if( OBJECTTYPE_TITLE == eObjectType )
{
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(
m_xCC->getServiceManager()->createInstanceWithContext(
C2U("com.sun.star.frame.DispatchHelper"), m_xCC ), uno::UNO_QUERY );
if( xDispatchHelper.is())
{
uno::Sequence< beans::PropertyValue > aArgs;
xDispatchHelper->executeDispatch(
uno::Reference< frame::XDispatchProvider >( m_xFrame, uno::UNO_QUERY ),
C2U(".uno:TerminateInplaceActivation"),
C2U("_parent"),
frame::FrameSearchFlag::PARENT,
aArgs );
bReturn = true;
}
}
if( ! bReturn &&
(nCode == KEY_DELETE || nCode == KEY_BACKSPACE ))
{
bReturn = executeDispatch_Delete();
if( ! bReturn )
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
InfoBox( m_pChartWindow, String(SchResId( STR_ACTION_NOTPOSSIBLE ))).Execute();
}
}
/* old chart:
// Ctrl-Shift-R: Repaint
if (!bReturn && GetWindow())
{
KeyCode aKeyCode = rKEvt.GetKeyCode();
if (aKeyCode.IsMod1() && aKeyCode.IsShift()
&& aKeyCode.GetCode() == KEY_R)
{
// 3D-Kontext wieder zerstoeren
GetWindow()->Invalidate();
bReturn = sal_True;
}
}
*/
return bReturn;
}
bool ChartController::requestQuickHelp(
::Point aAtLogicPosition,
bool bIsBalloonHelp,
::rtl::OUString & rOutQuickHelpText,
awt::Rectangle & rOutEqualRect )
{
uno::Reference< frame::XModel > xChartModel;
if( m_aModel.is())
xChartModel.set( getModel() );
if( !xChartModel.is())
return false;
// help text
::rtl::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
ExplicitValueProvider * pValueProvider(
ExplicitValueProvider::getExplicitValueProvider( m_xChartView ));
if( pValueProvider )
rOutEqualRect = pValueProvider->getRectangleOfObject( aCID, true );
}
return bResult;
}
//-----------------------------------------------------------------
// XSelectionSupplier (optional interface)
//-----------------------------------------------------------------
sal_Bool SAL_CALL ChartController
::select( const uno::Any& rSelection )
throw( lang::IllegalArgumentException )
{
bool bSuccess = false;
if ( rSelection.hasValue() )
{
const uno::Type& rType = rSelection.getValueType();
if ( rType == ::getCppuType( static_cast< const ::rtl::OUString* >( 0 ) ) )
{
::rtl::OUString aNewCID;
if ( ( rSelection >>= aNewCID ) && m_aSelection.setSelection( aNewCID ) )
{
bSuccess = true;
}
}
else if ( rType == ::getCppuType( static_cast< const uno::Reference< drawing::XShape >* >( 0 ) ) )
{
uno::Reference< drawing::XShape > xShape;
if ( ( rSelection >>= xShape ) && m_aSelection.setSelection( xShape ) )
{
bSuccess = true;
}
}
}
else
{
if ( m_aSelection.hasSelection() )
{
m_aSelection.clearSelection();
bSuccess = true;
}
}
if ( bSuccess )
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
if ( m_pDrawViewWrapper && m_pDrawViewWrapper->IsTextEdit() )
{
this->EndTextEdit();
}
this->impl_selectObjectAndNotiy();
if ( m_pChartWindow )
{
m_pChartWindow->Invalidate();
}
return sal_True;
}
return sal_False;
}
uno::Any SAL_CALL ChartController
::getSelection() throw(uno::RuntimeException)
{
uno::Any aReturn;
if ( m_aSelection.hasSelection() )
{
::rtl::OUString aCID( m_aSelection.getSelectedCID() );
if ( !aCID.isEmpty() )
{
aReturn = uno::makeAny( aCID );
}
else
{
// #i12587# support for shapes in chart
aReturn = uno::makeAny( m_aSelection.getSelectedAdditionalShape() );
}
}
return aReturn;
}
void SAL_CALL ChartController
::addSelectionChangeListener( const uno::Reference<
view::XSelectionChangeListener > & xListener )
throw(uno::RuntimeException)
{
::vos::OGuard aGuard( Application::GetSolarMutex());
if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode?
return; //behave passive if already disposed or suspended
//--add listener
m_aLifeTimeManager.m_aListenerContainer.addInterface( ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0), xListener );
}
void SAL_CALL ChartController
::removeSelectionChangeListener( const uno::Reference<
view::XSelectionChangeListener > & xListener )
throw(uno::RuntimeException)
{
::vos::OGuard aGuard( Application::GetSolarMutex());
if( impl_isDisposedOrSuspended() ) //@todo? allow removing of listeners in suspend mode?
return; //behave passive if already disposed or suspended
//--remove listener
m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0), xListener );
}
void ChartController
::impl_notifySelectionChangeListeners()
{
::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
.getContainer( ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0) );
if( pIC )
{
uno::Reference< view::XSelectionSupplier > xSelectionSupplier(this);
lang::EventObject aEvent( xSelectionSupplier );
::cppu::OInterfaceIteratorHelper aIt( *pIC );
while( aIt.hasMoreElements() )
{
uno::Reference< view::XSelectionChangeListener > xListener( aIt.next(), uno::UNO_QUERY );
if( xListener.is() )
xListener->selectionChanged( aEvent );
}
}
}
void ChartController::impl_selectObjectAndNotiy()
{
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
if( pDrawViewWrapper )
{
pDrawViewWrapper->SetDragMode( m_eDragMode );
m_aSelection.applySelection( m_pDrawViewWrapper );
}
}
impl_notifySelectionChangeListeners();
}
bool ChartController::impl_moveOrResizeObject(
const ::rtl::OUString & rCID,
eMoveOrResizeType eType,
double fAmountLogicX,
double fAmountLogicY )
{
bool bResult = false;
bool bNeedShift = true;
bool bNeedResize = ( eType == CENTERED_RESIZE_OBJECT );
uno::Reference< frame::XModel > xChartModel( getModel() );
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( C2U("RelativePosition")) >>= aRelPos);
bool bDetermineSize = !bNeedResize || !(xObjProp->getPropertyValue( C2U("RelativeSize")) >>= aRelSize);
if( ( bDeterminePos || bDetermineSize ) &&
( aRefSize.Width > 0 && aRefSize.Height > 0 ) )
{
ExplicitValueProvider * pValueProvider(
ExplicitValueProvider::getExplicitValueProvider( m_xChartView ));
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::MOVE);
if( bNeedResize )
eActionType = ActionDescriptionProvider::RESIZE;
ObjectType eObjectType = ObjectIdentifier::getObjectType( rCID );
UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription(
eActionType, ObjectNameProvider::getName( eObjectType )), m_xUndoManager );
{
ControllerLockGuard aCLGuard( xChartModel );
if( bNeedShift )
xObjProp->setPropertyValue( C2U("RelativePosition"), uno::makeAny( aRelPos ));
if( bNeedResize || (eObjectType == OBJECTTYPE_DIAGRAM) )//Also set an explicat size at the diagram when an explicit position is set
xObjProp->setPropertyValue( C2U("RelativeSize"), uno::makeAny( aRelSize ));
}
aUndoGuard.commit();
}
}
return bResult;
}
bool ChartController::impl_DragDataPoint( const ::rtl::OUString & rCID, double fAdditionalOffset )
{
bool bResult = false;
if( fAdditionalOffset < -1.0 || fAdditionalOffset > 1.0 || fAdditionalOffset == 0.0 )
return bResult;
sal_Int32 nDataPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( rCID );
uno::Reference< chart2::XDataSeries > xSeries(
ObjectIdentifier::getDataSeriesForCID( rCID, getModel() ));
if( xSeries.is())
{
try
{
uno::Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex( nDataPointIndex ));
double fOffset = 0.0;
if( xPointProp.is() &&
(xPointProp->getPropertyValue( C2U("Offset" )) >>= 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( C2U("Offset"), uno::makeAny( fOffset ));
bResult = true;
}
}
catch( const uno::Exception & ex )
{
ASSERT_EXCEPTION( ex );
}
}
return bResult;
}
void ChartController::impl_SetMousePointer( const MouseEvent & rEvent )
{
::vos::OGuard aGuard( Application::GetSolarMutex());
if( m_pDrawViewWrapper && m_pChartWindow )
{
Point aMousePos( m_pChartWindow->PixelToLogic( rEvent.GetPosPixel()));
sal_uInt16 nModifier = rEvent.GetModifier();
sal_Bool bLeftDown = rEvent.IsLeft();
if ( m_pDrawViewWrapper->IsTextEdit() )
{
if( m_pDrawViewWrapper->IsTextEditHit( aMousePos, HITPIX) )
{
m_pChartWindow->SetPointer( m_pDrawViewWrapper->GetPreferedPointer(
aMousePos, m_pChartWindow, nModifier, bLeftDown ) );
return;
}
}
else if( m_pDrawViewWrapper->IsAction() )
{
return;//don't change pointer during running action
}
SdrHdl* pHitSelectionHdl = 0;
if( m_aSelection.isResizeableObjectSelected() )
pHitSelectionHdl = m_pDrawViewWrapper->PickHandle( aMousePos );
if( pHitSelectionHdl )
{
Pointer aPointer = m_pDrawViewWrapper->GetPreferedPointer(
aMousePos, m_pChartWindow, nModifier, bLeftDown );
bool bForceArrowPointer = false;
ObjectIdentifier aOID( m_aSelection.getSelectedOID() );
switch( aPointer.GetStyle())
{
case POINTER_NSIZE:
case POINTER_SSIZE:
case POINTER_WSIZE:
case POINTER_ESIZE:
case POINTER_NWSIZE:
case POINTER_NESIZE:
case POINTER_SWSIZE:
case POINTER_SESIZE:
if( ! m_aSelection.isResizeableObjectSelected() )
bForceArrowPointer = true;
break;
case POINTER_MOVE:
if ( !aOID.isDragableObject() )
bForceArrowPointer = true;
break;
case POINTER_MOVEPOINT:
case POINTER_MOVEBEZIERWEIGHT:
// there is no point-editing in a chart
// the POINTER_MOVEBEZIERWEIGHT appears in 3d data points
bForceArrowPointer = true;
break;
default:
break;
}
if( bForceArrowPointer )
m_pChartWindow->SetPointer( Pointer( POINTER_ARROW ));
else
m_pChartWindow->SetPointer( aPointer );
}
else
{
// #i12587# support for shapes in chart
if ( m_eDrawMode == CHARTDRAW_INSERT &&
( !m_pDrawViewWrapper->IsMarkedHit( aMousePos ) || !m_aSelection.isDragableObjectSelected() ) )
{
PointerStyle ePointerStyle = POINTER_DRAW_RECT;
SdrObjKind eKind = static_cast< SdrObjKind >( m_pDrawViewWrapper->GetCurrentObjIdentifier() );
switch ( eKind )
{
case OBJ_LINE:
{
ePointerStyle = POINTER_DRAW_LINE;
}
break;
case OBJ_RECT:
case OBJ_CUSTOMSHAPE:
{
ePointerStyle = POINTER_DRAW_RECT;
}
break;
case OBJ_CIRC:
{
ePointerStyle = POINTER_DRAW_ELLIPSE;
}
break;
case OBJ_FREELINE:
{
ePointerStyle = POINTER_DRAW_POLYGON;
}
break;
case OBJ_TEXT:
{
ePointerStyle = POINTER_DRAW_TEXT;
}
break;
case OBJ_CAPTION:
{
ePointerStyle = POINTER_DRAW_CAPTION;
}
break;
default:
{
ePointerStyle = POINTER_DRAW_RECT;
}
break;
}
m_pChartWindow->SetPointer( Pointer( ePointerStyle ) );
return;
}
::rtl::OUString aHitObjectCID(
SelectionHelper::getHitObjectCID(
aMousePos, *m_pDrawViewWrapper, true /*bGetDiagramInsteadOf_Wall*/ ));
if( m_pDrawViewWrapper->IsTextEdit() )
{
if( aHitObjectCID.equals(m_aSelection.getSelectedCID()) )
{
m_pChartWindow->SetPointer( Pointer( POINTER_ARROW ));
return;
}
}
if( aHitObjectCID.isEmpty() )
{
//additional shape was hit
m_pChartWindow->SetPointer( POINTER_MOVE );
}
else if( ObjectIdentifier::isDragableObject( aHitObjectCID ) )
{
if( (m_eDragMode == SDRDRAG_ROTATE)
&& SelectionHelper::isRotateableObject( aHitObjectCID
, getModel() ) )
m_pChartWindow->SetPointer( Pointer( POINTER_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()) )
{
m_pChartWindow->SetPointer( Pointer( POINTER_ARROW ));
return;
}
}
m_pChartWindow->SetPointer( POINTER_MOVE );
}
}
else
m_pChartWindow->SetPointer( Pointer( POINTER_ARROW ));
}
}
}
//.............................................................................
} //namespace chart
//.............................................................................