summaryrefslogtreecommitdiff
path: root/chart2/source/controller/main/ChartController_Window.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'chart2/source/controller/main/ChartController_Window.cxx')
-rw-r--r--chart2/source/controller/main/ChartController_Window.cxx2029
1 files changed, 2029 insertions, 0 deletions
diff --git a/chart2/source/controller/main/ChartController_Window.cxx b/chart2/source/controller/main/ChartController_Window.cxx
new file mode 100644
index 000000000000..56908ac4ef79
--- /dev/null
+++ b/chart2/source/controller/main/ChartController_Window.cxx
@@ -0,0 +1,2029 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 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,
+ const uno::Reference< awt::XMenuExtended > & xMenuEx,
+ sal_Int16 nId, const ::rtl::OUString & rCommand )
+{
+ static ::rtl::OUString aEmptyString;
+ xMenu->insertItem( nId, aEmptyString, 0, -1 );
+ xMenuEx->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)
+{
+ uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
+ Window* pWindow = m_pChartWindow;
+
+ if(xWindow.is() && pWindow)
+ {
+ Size aLogicSize = pWindow->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) );
+ pWindow->SetMapMode(aNewMapMode);
+ pWindow->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), pWindow->GetOutputSize());
+ m_pDrawViewWrapper->SetWorkArea( aRect );
+ }
+ }
+ else
+ {
+ //change visarea
+ ChartModelHelper::setPageSize( awt::Size( aLogicSize.Width(), aLogicSize.Height() ), getModel() );
+ pWindow->SetPosSizePixel( X, Y, Width, Height, Flags );
+ }
+ pWindow->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();
+
+ Window* pWindow = m_pChartWindow;
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex());
+ DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
+ if(pDrawViewWrapper)
+ pDrawViewWrapper->CompleteRedraw(pWindow, 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()
+{
+ m_bWaitingForDoubleClick = true;
+
+ 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();
+ if( m_pChartWindow )
+ {
+ Window::PointerState aPointerState( m_pChartWindow->GetPointerState() );
+ MouseEvent aMouseEvent( aPointerState.maPos,1/*nClicks*/,
+ 0/*nMode*/, static_cast< USHORT >( 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();
+
+ Window* pWindow = m_pChartWindow;
+ DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
+ if(!pWindow || !pDrawViewWrapper )
+ return;
+
+ Point aMPos = pWindow->PixelToLogic(rMEvt.GetPosPixel());
+
+ if ( MOUSE_LEFT == rMEvt.GetButtons() )
+ {
+ pWindow->GrabFocus();
+ pWindow->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
+ USHORT nDrgLog = (USHORT)pWindow->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());
+
+ Window* pWindow = m_pChartWindow;
+ DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
+ if(!pWindow || !pDrawViewWrapper)
+ return;
+
+ if( m_pDrawViewWrapper->IsTextEdit() )
+ {
+ if( m_pDrawViewWrapper->MouseMove(rMEvt,m_pChartWindow) )
+ return;
+ }
+
+ if(pDrawViewWrapper->IsAction())
+ {
+ pDrawViewWrapper->MovAction( pWindow->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());
+
+ Window* pWindow = m_pChartWindow;
+ DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
+ if(!pWindow || !pDrawViewWrapper)
+ return;
+
+ Point aMPos = pWindow->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 );
+ 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, getModel() );
+
+ if( pDrawViewWrapper->EndDragObj(false) )
+ {
+ bDraggingDone = true;
+ aUndoGuard.commitAction();
+ }
+ }
+
+ 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;
+
+ UndoGuard aUndoGuard(
+ ActionDescriptionProvider::createDescription(
+ eActionType,
+ ObjectNameProvider::getName( ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() ))),
+ m_xUndoManager, getModel() );
+ bool bChanged = 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( bChanged )
+ {
+ bDraggingDone = true;
+ aUndoGuard.commitAction();
+ }
+ }
+ }
+ 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);
+ pWindow->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.getLength() )
+ {
+ 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()
+{
+ m_pChartWindow->Invalidate();
+}
+void ChartController::execute_Activate()
+{
+ ///// pDrawViewWrapper->SetEditMode(TRUE);
+}
+void ChartController::execute_Deactivate()
+{
+ /*
+ pDrawViewWrapper->SetEditMode(FALSE);
+ this->ReleaseMouse();
+ */
+}
+void ChartController::execute_GetFocus()
+{
+}
+void ChartController::execute_LoseFocus()
+{
+ //this->ReleaseMouse();
+}
+
+void ChartController::execute_Command( const CommandEvent& rCEvt )
+{
+ Window* pWindow = m_pChartWindow;
+
+ bool bIsAction = false;
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex());
+ DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
+ if(!pWindow || !pDrawViewWrapper)
+ return;
+ bIsAction = m_pDrawViewWrapper->IsAction();
+ }
+
+ // pop-up menu
+ if(rCEvt.GetCommand() == COMMAND_CONTEXTMENU && !bIsAction)
+ {
+ 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() )
+ {
+ 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 );
+ uno::Reference< awt::XMenuExtended > xMenuEx( xPopupMenu, uno::UNO_QUERY );
+ if( xPopupMenu.is() && xMenuEx.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, xMenuEx, 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, xMenuEx, nUniqueId++, C2U(".uno:FormatDataLabel") );
+ if( !bHasDataLabelAtPoint )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertDataLabel") );
+ else
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteDataLabel") );
+ if( bSelectedPointIsFormatted )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:ResetDataPoint"));
+
+ xPopupMenu->insertSeparator( -1 );
+
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, 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, xMenuEx, nUniqueId++, C2U(".uno:FormatStockLoss") );
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockGain") );
+ }
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+
+ if( bHasDataLabelsAtSeries )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatDataLabels") );
+ if( xTrendline.is() )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatTrendline") );
+ if( bHasEquation )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatTrendlineEquation") );
+ if( xMeanValue.is() )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatMeanValue") );
+ if( bHasYErrorBars )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatYErrorBars") );
+
+ //if( nIdBeforeFormat != nUniqueId )
+ xPopupMenu->insertSeparator( -1 );
+
+ //const sal_Int32 nIdBeforeInsert = nUniqueId;
+
+ if( !bHasDataLabelsAtSeries )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertDataLabels") );
+ if( !xTrendline.is() )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendline") );
+ else if( !bHasEquation )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendlineEquation") );
+ if( !xMeanValue.is() )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertMeanValue") );
+ if( !bHasYErrorBars )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertYErrorBars") );
+
+ //if( nIdBeforeInsert != nUniqueId )
+ // xPopupMenu->insertSeparator( -1 );
+
+ //const sal_Int32 nIdBeforeDelete = nUniqueId;
+
+ if( bHasDataLabelsAtSeries || ( bHasDataLabelsAtPoints && bHasFormattedDataPointsOtherThanSelected ) )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteDataLabels") );
+ if( xTrendline.is() )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteTrendline") );
+ if( bHasEquation )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteTrendlineEquation") );
+ if( xMeanValue.is() )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteMeanValue") );
+ if( bHasYErrorBars )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteYErrorBars") );
+
+ if( bHasFormattedDataPointsOtherThanSelected )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:ResetAllDataPoints"));
+
+ //if( nIdBeforeDelete != nUniqueId )
+ xPopupMenu->insertSeparator( -1 );
+
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId, C2U(".uno:ArrangeRow"));
+ uno::Reference< awt::XPopupMenu > xArrangePopupMenu(
+ m_xCC->getServiceManager()->createInstanceWithContext(
+ C2U("com.sun.star.awt.PopupMenu"), m_xCC ), uno::UNO_QUERY );
+ uno::Reference< awt::XMenuExtended > xArrangeMenuEx( xArrangePopupMenu, uno::UNO_QUERY );
+ if( xArrangePopupMenu.is() && xArrangeMenuEx.is())
+ {
+ sal_Int16 nSubId = nUniqueId + 1;
+ lcl_insertMenuCommand( xArrangePopupMenu, xArrangeMenuEx, nSubId++, C2U(".uno:Forward") );
+ lcl_insertMenuCommand( xArrangePopupMenu, xArrangeMenuEx, nSubId, C2U(".uno:Backward") );
+ xPopupMenu->setPopupMenu( nUniqueId, xArrangePopupMenu );
+ nUniqueId = nSubId;
+ }
+ ++nUniqueId;
+ }
+ else if( OBJECTTYPE_DATA_CURVE == eObjectType )
+ {
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatTrendlineEquation") );
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendlineEquation") );
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendlineEquationAndR2") );
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertR2Value") );
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteTrendlineEquation") );
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteR2Value") );
+ }
+ else if( OBJECTTYPE_DATA_CURVE_EQUATION == eObjectType )
+ {
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertR2Value") );
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, 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() ).getLength()>0;
+
+ if( OBJECTTYPE_AXIS != eObjectType && bIsAxisVisible )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatAxis") );
+ if( OBJECTTYPE_GRID != eObjectType && bIsMajorGridVisible && !bIsSecondaryAxis )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatMajorGrid") );
+ if( OBJECTTYPE_SUBGRID != eObjectType && bIsMinorGridVisible && !bIsSecondaryAxis )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatMinorGrid") );
+
+ xPopupMenu->insertSeparator( -1 );
+
+ if( OBJECTTYPE_AXIS != eObjectType && !bIsAxisVisible )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertAxis") );
+ if( OBJECTTYPE_GRID != eObjectType && !bIsMajorGridVisible && !bIsSecondaryAxis )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertMajorGrid") );
+ if( OBJECTTYPE_SUBGRID != eObjectType && !bIsMinorGridVisible && !bIsSecondaryAxis )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertMinorGrid") );
+ if( !bHasTitle )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertAxisTitle") );
+
+ if( bIsAxisVisible )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteAxis") );
+ if( bIsMajorGridVisible && !bIsSecondaryAxis )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteMajorGrid") );
+ if( bIsMinorGridVisible && !bIsSecondaryAxis )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteMinorGrid") );
+ }
+ }
+
+ if( OBJECTTYPE_DATA_STOCK_LOSS == eObjectType )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockGain") );
+ else if( OBJECTTYPE_DATA_STOCK_GAIN == eObjectType )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockLoss") );
+
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, 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, xMenuEx, nUniqueId++, C2U(".uno:InsertTitles") );
+ if( !bHasLegend )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertLegend") );
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertRemoveAxes") );
+ if( bHasLegend )
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteLegend") );
+ }
+ //-----
+
+ xPopupMenu->insertSeparator( -1 );
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DiagramType"));
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DataRanges"));
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DiagramData"));
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:View3D"));
+ xPopupMenu->insertSeparator( -1 );
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Cut"));
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Copy"));
+ lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Paste"));
+
+ ::svt::ContextMenuHelper aContextMenuHelper( m_xFrame );
+ Point aPos( rCEvt.GetMousePosPixel() );
+ if( !rCEvt.IsMouseEvent() )
+ 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
+ if( m_pDrawViewWrapper )
+ m_pDrawViewWrapper->Command( rCEvt, m_pChartWindow );
+ }
+}
+
+bool ChartController::execute_KeyInput( const KeyEvent& rKEvt )
+{
+ bool bReturn=false;
+
+ Window* pWindow = m_pChartWindow;
+ DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
+ if(!pWindow || !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;
+
+ if( pDrawViewWrapper->IsTextEdit() )
+ {
+ if( pDrawViewWrapper->KeyInput(rKEvt,pWindow) )
+ {
+ 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 && pWindow )
+ {
+ // together with Alt-key: 1 px in each direction
+ Size aPixelSize = pWindow->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 && pWindow )
+ {
+ // together with Alt-key: 1 px
+ Size aPixelSize = pWindow->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().getLength() )
+ {
+ //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 )
+ {
+ 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 = 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.getLength());
+
+ 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 )
+ {
+ this->impl_selectObjectAndNotiy();
+ 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.getLength() )
+ {
+ 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()
+{
+ 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, xChartModel );
+ {
+ 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.commitAction();
+ }
+ }
+ 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());
+ Window* pWindow = m_pChartWindow;
+ if( m_pDrawViewWrapper && pWindow )
+ {
+ Point aMousePos( pWindow->PixelToLogic( rEvent.GetPosPixel()));
+ sal_uInt16 nModifier = rEvent.GetModifier();
+ BOOL bLeftDown = rEvent.IsLeft();
+
+ if ( m_pDrawViewWrapper->IsTextEdit() )
+ {
+ if( m_pDrawViewWrapper->IsTextEditHit( aMousePos, HITPIX) )
+ {
+ pWindow->SetPointer( m_pDrawViewWrapper->GetPreferedPointer(
+ aMousePos, pWindow, 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, pWindow, 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 )
+ pWindow->SetPointer( Pointer( POINTER_ARROW ));
+ else
+ pWindow->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;
+ }
+ pWindow->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()) )
+ {
+ pWindow->SetPointer( Pointer( POINTER_ARROW ));
+ return;
+ }
+ }
+
+ if( !aHitObjectCID.getLength() )
+ {
+ //additional shape was hit
+ pWindow->SetPointer( POINTER_MOVE );
+ }
+ else if( ObjectIdentifier::isDragableObject( aHitObjectCID ) )
+ {
+ if( (m_eDragMode == SDRDRAG_ROTATE)
+ && SelectionHelper::isRotateableObject( aHitObjectCID
+ , getModel() ) )
+ pWindow->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()) )
+ {
+ pWindow->SetPointer( Pointer( POINTER_ARROW ));
+ return;
+ }
+ }
+ pWindow->SetPointer( POINTER_MOVE );
+ }
+ }
+ else
+ pWindow->SetPointer( Pointer( POINTER_ARROW ));
+ }
+ }
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................