xref: /trunk/main/chart2/source/controller/main/ChartController_Window.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chartcontroller.hxx"
26 #include "ChartController.hxx"
27 #include "PositionAndSizeHelper.hxx"
28 #include "ObjectIdentifier.hxx"
29 #include "ChartWindow.hxx"
30 #include "ResId.hxx"
31 #include "CommonConverters.hxx"
32 #include "ChartModelHelper.hxx"
33 #include "DiagramHelper.hxx"
34 #include "TitleHelper.hxx"
35 #include "UndoGuard.hxx"
36 #include "ControllerLockGuard.hxx"
37 #include "ObjectNameProvider.hxx"
38 #include "Strings.hrc"
39 #include "SchSlotIds.hxx"
40 #include "macros.hxx"
41 #include "DragMethod_PieSegment.hxx"
42 #include "DragMethod_RotateDiagram.hxx"
43 #include "ObjectHierarchy.hxx"
44 #include "chartview/ExplicitValueProvider.hxx"
45 #include "RelativePositionHelper.hxx"
46 #include "chartview/DrawModelWrapper.hxx"
47 #include "RegressionCurveHelper.hxx"
48 #include "StatisticsHelper.hxx"
49 #include "DataSeriesHelper.hxx"
50 #include "ContainerHelper.hxx"
51 #include "AxisHelper.hxx"
52 #include "LegendHelper.hxx"
53 #include "servicenames_charttypes.hxx"
54 #include "MenuResIds.hrc"
55 #include "DrawCommandDispatch.hxx"
56 
57 #include <com/sun/star/chart2/RelativePosition.hpp>
58 #include <com/sun/star/chart2/RelativeSize.hpp>
59 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
60 
61 #include <com/sun/star/frame/XDispatchHelper.hpp>
62 #include <com/sun/star/frame/FrameSearchFlag.hpp>
63 #include <com/sun/star/util/XUpdatable.hpp>
64 #include <comphelper/InlineContainer.hxx>
65 
66 #include <svtools/contextmenuhelper.hxx>
67 #include <toolkit/awt/vclxmenu.hxx>
68 
69 #include <svx/svxids.hrc>
70 #include <svx/ActionDescriptionProvider.hxx>
71 
72 // header for class E3dObject
73 #include <svx/obj3d.hxx>
74 // header for class E3dScene
75 #include <svx/scene3d.hxx>
76 // header for class SdrDragMethod
77 #include <svx/svddrgmt.hxx>
78 #include <vcl/svapp.hxx>
79 #include <vos/mutex.hxx>
80 
81 // for InfoBox
82 #include <vcl/msgbox.hxx>
83 
84 #include <rtl/math.hxx>
85 #include <svtools/acceleratorexecute.hxx>
86 
87 #define DRGPIX    2     // Drag MinMove in Pixel
88 
89 using namespace ::com::sun::star;
90 using namespace ::com::sun::star::chart2;
91 using ::com::sun::star::uno::Reference;
92 using ::rtl::OUString;
93 
94 //.............................................................................
95 namespace chart
96 {
97 //.............................................................................
98 
99 namespace
100 {
lcl_GrowAndShiftLogic(RelativePosition & rInOutRelPos,RelativeSize & rInOutRelSize,const awt::Size & rRefSize,double fGrowLogicX,double fGrowLogicY)101 bool lcl_GrowAndShiftLogic(
102     RelativePosition &  rInOutRelPos,
103     RelativeSize &      rInOutRelSize,
104     const awt::Size &   rRefSize,
105     double              fGrowLogicX,
106     double              fGrowLogicY )
107 {
108     if( rRefSize.Width == 0 ||
109         rRefSize.Height == 0 )
110         return false;
111 
112     double fRelativeGrowX = fGrowLogicX / rRefSize.Width;
113     double fRelativeGrowY = fGrowLogicY / rRefSize.Height;
114 
115     return ::chart::RelativePositionHelper::centerGrow(
116         rInOutRelPos, rInOutRelSize,
117         fRelativeGrowX, fRelativeGrowY,
118         /* bCheck = */ true );
119 }
120 
lcl_MoveObjectLogic(RelativePosition & rInOutRelPos,RelativeSize & rObjectSize,const awt::Size & rRefSize,double fShiftLogicX,double fShiftLogicY)121 bool lcl_MoveObjectLogic(
122     RelativePosition &  rInOutRelPos,
123     RelativeSize &      rObjectSize,
124     const awt::Size &   rRefSize,
125     double              fShiftLogicX,
126     double              fShiftLogicY )
127 {
128     if( rRefSize.Width == 0 ||
129         rRefSize.Height == 0 )
130         return false;
131 
132     double fRelativeShiftX = fShiftLogicX / rRefSize.Width;
133     double fRelativeShiftY = fShiftLogicY / rRefSize.Height;
134 
135     return ::chart::RelativePositionHelper::moveObject(
136         rInOutRelPos, rObjectSize,
137         fRelativeShiftX, fRelativeShiftY,
138         /* bCheck = */ true );
139 }
140 
lcl_insertMenuCommand(const uno::Reference<awt::XPopupMenu> & xMenu,sal_Int16 nId,const::rtl::OUString & rCommand)141 void lcl_insertMenuCommand(
142     const uno::Reference< awt::XPopupMenu > & xMenu,
143     sal_Int16 nId, const ::rtl::OUString & rCommand )
144 {
145     static ::rtl::OUString aEmptyString;
146     xMenu->insertItem( nId, aEmptyString, 0, -1 );
147     xMenu->setCommand( nId, rCommand );
148 }
149 
lcl_getFormatCommandForObjectCID(const OUString & rCID)150 OUString lcl_getFormatCommandForObjectCID( const OUString& rCID )
151 {
152     OUString aDispatchCommand( C2U(".uno:FormatSelection") );
153 
154     ObjectType eObjectType = ObjectIdentifier::getObjectType( rCID );
155 
156     switch(eObjectType)
157     {
158         case OBJECTTYPE_DIAGRAM:
159         case OBJECTTYPE_DIAGRAM_WALL:
160             aDispatchCommand = C2U(".uno:FormatWall");
161             break;
162         case OBJECTTYPE_DIAGRAM_FLOOR:
163             aDispatchCommand = C2U(".uno:FormatFloor");
164             break;
165         case OBJECTTYPE_PAGE:
166             aDispatchCommand = C2U(".uno:FormatChartArea");
167             break;
168         case OBJECTTYPE_LEGEND:
169             aDispatchCommand = C2U(".uno:FormatLegend");
170             break;
171         case OBJECTTYPE_TITLE:
172             aDispatchCommand = C2U(".uno:FormatTitle");
173             break;
174         case OBJECTTYPE_LEGEND_ENTRY:
175             aDispatchCommand = C2U(".uno:FormatDataSeries");
176             break;
177         case OBJECTTYPE_AXIS:
178         case OBJECTTYPE_AXIS_UNITLABEL:
179             aDispatchCommand = C2U(".uno:FormatAxis");
180             break;
181         case OBJECTTYPE_GRID:
182             aDispatchCommand = C2U(".uno:FormatMajorGrid");
183             break;
184         case OBJECTTYPE_SUBGRID:
185             aDispatchCommand = C2U(".uno:FormatMinorGrid");
186             break;
187         case OBJECTTYPE_DATA_LABELS:
188             aDispatchCommand = C2U(".uno:FormatDataLabels");
189             break;
190         case OBJECTTYPE_DATA_SERIES:
191             aDispatchCommand = C2U(".uno:FormatDataSeries");
192             break;
193         case OBJECTTYPE_DATA_LABEL:
194             aDispatchCommand = C2U(".uno:FormatDataLabel");
195             break;
196         case OBJECTTYPE_DATA_POINT:
197             aDispatchCommand = C2U(".uno:FormatDataPoint");
198             break;
199         case OBJECTTYPE_DATA_AVERAGE_LINE:
200             aDispatchCommand = C2U(".uno:FormatMeanValue");
201             break;
202         case OBJECTTYPE_DATA_ERRORS:
203         case OBJECTTYPE_DATA_ERRORS_X:
204         case OBJECTTYPE_DATA_ERRORS_Y:
205         case OBJECTTYPE_DATA_ERRORS_Z:
206             aDispatchCommand = C2U(".uno:FormatYErrorBars");
207             break;
208         case OBJECTTYPE_DATA_CURVE:
209             aDispatchCommand = C2U(".uno:FormatTrendline");
210             break;
211         case OBJECTTYPE_DATA_CURVE_EQUATION:
212             aDispatchCommand = C2U(".uno:FormatTrendlineEquation");
213             break;
214         case OBJECTTYPE_DATA_STOCK_RANGE:
215             aDispatchCommand = C2U(".uno:FormatSelection");
216             break;
217         case OBJECTTYPE_DATA_STOCK_LOSS:
218             aDispatchCommand = C2U(".uno:FormatStockLoss");
219             break;
220         case OBJECTTYPE_DATA_STOCK_GAIN:
221             aDispatchCommand = C2U(".uno:FormatStockGain");
222             break;
223         default: //OBJECTTYPE_UNKNOWN
224             break;
225     }
226     return aDispatchCommand;
227 }
228 
229 } // anonymous namespace
230 
231 const short HITPIX=2; //hit-tolerance in pixel
232 
233 //-----------------------------------------------------------------
234 // awt::XWindow
235 //-----------------------------------------------------------------
236     void SAL_CALL ChartController
setPosSize(sal_Int32 X,sal_Int32 Y,sal_Int32 Width,sal_Int32 Height,sal_Int16 Flags)237 ::setPosSize( sal_Int32 X, sal_Int32 Y
238             , sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags )
239 {
240     ::vos::OGuard aGuard( Application::GetSolarMutex() );
241     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
242 
243     if(xWindow.is() && m_pChartWindow)
244     {
245         Size aLogicSize = m_pChartWindow->PixelToLogic( Size( Width, Height ), MapMode( MAP_100TH_MM )  );
246 
247         bool bIsEmbedded = true;
248         //todo: for standalone chart: detect whether we are standalone
249         if( bIsEmbedded )
250         {
251             //change map mode to fit new size
252             awt::Size aModelPageSize = ChartModelHelper::getPageSize( getModel() );
253             sal_Int32 nScaleXNumerator = aLogicSize.Width();
254             sal_Int32 nScaleXDenominator = aModelPageSize.Width;
255             sal_Int32 nScaleYNumerator = aLogicSize.Height();
256             sal_Int32 nScaleYDenominator = aModelPageSize.Height;
257             MapMode aNewMapMode( MAP_100TH_MM, Point(0,0)
258             , Fraction(nScaleXNumerator,nScaleXDenominator)
259             , Fraction(nScaleYNumerator,nScaleYDenominator) );
260             m_pChartWindow->SetMapMode(aNewMapMode);
261             m_pChartWindow->SetPosSizePixel( X, Y, Width, Height, Flags );
262 
263             //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
264             uno::Reference< beans::XPropertySet > xProp( m_xChartView, uno::UNO_QUERY );
265             if( xProp.is() )
266             {
267                 uno::Sequence< beans::PropertyValue > aZoomFactors(4);
268                 aZoomFactors[0].Name = C2U("ScaleXNumerator");
269                 aZoomFactors[0].Value = uno::makeAny( nScaleXNumerator );
270                 aZoomFactors[1].Name = C2U("ScaleXDenominator");
271                 aZoomFactors[1].Value = uno::makeAny( nScaleXDenominator );
272                 aZoomFactors[2].Name = C2U("ScaleYNumerator");
273                 aZoomFactors[2].Value = uno::makeAny( nScaleYNumerator );
274                 aZoomFactors[3].Name = C2U("ScaleYDenominator");
275                 aZoomFactors[3].Value = uno::makeAny( nScaleYDenominator );
276                 xProp->setPropertyValue( C2U("ZoomFactors"), uno::makeAny( aZoomFactors ));
277             }
278 
279             //a correct work area is at least necessary for correct values in the position and  size dialog and for dragging area
280             if(m_pDrawViewWrapper)
281             {
282                 Rectangle aRect(Point(0,0), m_pChartWindow->GetOutputSize());
283                 m_pDrawViewWrapper->SetWorkArea( aRect );
284             }
285         }
286         else
287         {
288             //change visarea
289             ChartModelHelper::setPageSize( awt::Size( aLogicSize.Width(), aLogicSize.Height() ), getModel() );
290             m_pChartWindow->SetPosSizePixel( X, Y, Width, Height, Flags );
291         }
292         m_pChartWindow->Invalidate();
293     }
294 }
295 
296     awt::Rectangle SAL_CALL ChartController
getPosSize()297 ::getPosSize()
298 {
299     //@todo
300     awt::Rectangle aRet(0,0,0,0);
301 
302     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
303     if(xWindow.is())
304         aRet = xWindow->getPosSize();
305 
306     return aRet;
307 }
308 
309     void SAL_CALL ChartController
setVisible(sal_Bool Visible)310 ::setVisible( sal_Bool Visible )
311 {
312     //@todo
313     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
314 
315     if(xWindow.is())
316         xWindow->setVisible( Visible );
317 }
318 
319     void SAL_CALL ChartController
setEnable(sal_Bool Enable)320 ::setEnable( sal_Bool Enable )
321 {
322     //@todo
323     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
324 
325     if(xWindow.is())
326         xWindow->setEnable( Enable );
327 }
328 
329     void SAL_CALL ChartController
setFocus()330 ::setFocus()
331 {
332     //@todo
333     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
334 
335     if(xWindow.is())
336         xWindow->setFocus();
337 }
338 
339     void SAL_CALL ChartController
addWindowListener(const uno::Reference<awt::XWindowListener> & xListener)340 ::addWindowListener( const uno::Reference<
341             awt::XWindowListener >& xListener )
342 {
343     //@todo
344     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
345 
346     if(xWindow.is())
347         xWindow->addWindowListener( xListener );
348 }
349 
350     void SAL_CALL ChartController
removeWindowListener(const uno::Reference<awt::XWindowListener> & xListener)351 ::removeWindowListener( const uno::Reference<
352             awt::XWindowListener >& xListener )
353 {
354     //@todo
355     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
356 
357     if(xWindow.is())
358         xWindow->removeWindowListener( xListener );
359 }
360 
361     void SAL_CALL ChartController
addFocusListener(const uno::Reference<awt::XFocusListener> & xListener)362 ::addFocusListener( const uno::Reference<
363             awt::XFocusListener >& xListener )
364 {
365     //@todo
366     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
367 
368     if(xWindow.is())
369         xWindow->addFocusListener( xListener );
370 }
371 
372     void SAL_CALL ChartController
removeFocusListener(const uno::Reference<awt::XFocusListener> & xListener)373 ::removeFocusListener( const uno::Reference<
374             awt::XFocusListener >& xListener )
375 {
376     //@todo
377     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
378 
379     if(xWindow.is())
380         xWindow->removeFocusListener( xListener );
381 }
382 
383     void SAL_CALL ChartController
addKeyListener(const uno::Reference<awt::XKeyListener> & xListener)384 ::addKeyListener( const uno::Reference<
385             awt::XKeyListener >& xListener )
386 {
387     //@todo
388     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
389 
390     if(xWindow.is())
391         xWindow->addKeyListener( xListener );
392 }
393 
394     void SAL_CALL ChartController
removeKeyListener(const uno::Reference<awt::XKeyListener> & xListener)395 ::removeKeyListener( const uno::Reference<
396             awt::XKeyListener >& xListener )
397 {
398     //@todo
399     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
400 
401     if(xWindow.is())
402         xWindow->removeKeyListener( xListener );
403 }
404 
405     void SAL_CALL ChartController
addMouseListener(const uno::Reference<awt::XMouseListener> & xListener)406 ::addMouseListener( const uno::Reference<
407             awt::XMouseListener >& xListener )
408 {
409     //@todo
410     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
411 
412     if(xWindow.is())
413         xWindow->addMouseListener( xListener );
414 }
415 
416     void SAL_CALL ChartController
removeMouseListener(const uno::Reference<awt::XMouseListener> & xListener)417 ::removeMouseListener( const uno::Reference<
418             awt::XMouseListener >& xListener )
419 {
420     //@todo
421     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
422 
423     if(xWindow.is())
424         xWindow->removeMouseListener( xListener );
425 }
426 
427     void SAL_CALL ChartController
addMouseMotionListener(const uno::Reference<awt::XMouseMotionListener> & xListener)428 ::addMouseMotionListener( const uno::Reference<
429             awt::XMouseMotionListener >& xListener )
430 {
431     //@todo
432     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
433 
434     if(xWindow.is())
435         xWindow->addMouseMotionListener( xListener );
436 }
437 
438     void SAL_CALL ChartController
removeMouseMotionListener(const uno::Reference<awt::XMouseMotionListener> & xListener)439 ::removeMouseMotionListener( const uno::Reference<
440             awt::XMouseMotionListener >& xListener )
441 {
442     //@todo
443     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
444 
445     if(xWindow.is())
446         xWindow->removeMouseMotionListener( xListener );
447 }
448 
449     void SAL_CALL ChartController
addPaintListener(const uno::Reference<awt::XPaintListener> & xListener)450 ::addPaintListener( const uno::Reference<
451             awt::XPaintListener >& xListener )
452 {
453     //@todo
454     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
455 
456     if(xWindow.is())
457         xWindow->addPaintListener( xListener );
458 }
459 
460     void SAL_CALL ChartController
removePaintListener(const uno::Reference<awt::XPaintListener> & xListener)461 ::removePaintListener( const uno::Reference<
462             awt::XPaintListener >& xListener )
463 {
464     //@todo
465     uno::Reference<awt::XWindow> xWindow = m_xViewWindow;
466 
467     if(xWindow.is())
468         xWindow->removePaintListener( xListener );
469 }
470 
471 //-----------------------------------------------------------------
472 // impl vcl window controller methods
473 //-----------------------------------------------------------------
PrePaint()474 void ChartController::PrePaint()
475 {
476     // forward VCLs PrePaint window event to DrawingLayer
477     DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
478 
479     if(pDrawViewWrapper)
480     {
481         pDrawViewWrapper->PrePaint();
482     }
483 }
484 
execute_Paint(const Rectangle & rRect)485 void ChartController::execute_Paint( const Rectangle& rRect )
486 {
487     try
488     {
489         uno::Reference< frame::XModel > xModel( getModel() );
490         //DBG_ASSERT( xModel.is(), "ChartController::execute_Paint: have no model to paint");
491         if( !xModel.is() )
492             return;
493 
494         //better performance for big data
495         uno::Reference< beans::XPropertySet > xProp( m_xChartView, uno::UNO_QUERY );
496         if( xProp.is() )
497         {
498             awt::Size aResolution(1000,1000);
499             {
500                 ::vos::OGuard aGuard( Application::GetSolarMutex());
501                 if( m_pChartWindow )
502                 {
503                     aResolution.Width = m_pChartWindow->GetSizePixel().Width();
504                     aResolution.Height = m_pChartWindow->GetSizePixel().Height();
505                 }
506             }
507             xProp->setPropertyValue( C2U("Resolution"), uno::makeAny( aResolution ));
508         }
509         //
510 
511         uno::Reference< util::XUpdatable > xUpdatable( m_xChartView, uno::UNO_QUERY );
512         if( xUpdatable.is() )
513             xUpdatable->update();
514 
515         {
516             ::vos::OGuard aGuard( Application::GetSolarMutex());
517             DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
518             if(pDrawViewWrapper)
519                 pDrawViewWrapper->CompleteRedraw(m_pChartWindow, Region(rRect) );
520         }
521     }
522     catch( uno::Exception & ex )
523     {
524         ASSERT_EXCEPTION( ex );
525     }
526     catch( ... )
527     {
528     }
529 }
530 
isDoubleClick(const MouseEvent & rMEvt)531 bool isDoubleClick( const MouseEvent& rMEvt )
532 {
533     return rMEvt.GetClicks() == 2 && rMEvt.IsLeft() &&
534         !rMEvt.IsMod1() && !rMEvt.IsMod2() && !rMEvt.IsShift();
535 }
536 
537 //-----------------------------------------------------------------------------
538 //-----------------------------------------------------------------------------
539 //-----------------------------------------------------------------------------
540 
startDoubleClickWaiting()541 void ChartController::startDoubleClickWaiting()
542 {
543     ::vos::OGuard aGuard( Application::GetSolarMutex() );
544 
545     m_bWaitingForDoubleClick = true;
546 
547     sal_uLong nDblClkTime = 500;
548     if( m_pChartWindow )
549     {
550         const MouseSettings& rMSettings = m_pChartWindow->GetSettings().GetMouseSettings();
551         nDblClkTime = rMSettings.GetDoubleClickTime();
552     }
553     m_aDoubleClickTimer.SetTimeout( nDblClkTime );
554     m_aDoubleClickTimer.Start();
555 }
556 
stopDoubleClickWaiting()557 void ChartController::stopDoubleClickWaiting()
558 {
559     m_aDoubleClickTimer.Stop();
560     m_bWaitingForDoubleClick = false;
561 }
562 
IMPL_LINK(ChartController,DoubleClickWaitingHdl,void *,EMPTYARG)563 IMPL_LINK( ChartController, DoubleClickWaitingHdl, void*, EMPTYARG )
564 {
565     m_bWaitingForDoubleClick = false;
566 
567     if( !m_bWaitingForMouseUp && m_aSelection.maybeSwitchSelectionAfterSingleClickWasEnsured() )
568     {
569         this->impl_selectObjectAndNotiy();
570         ::vos::OGuard aGuard( Application::GetSolarMutex() );
571         if( m_pChartWindow )
572         {
573             Window::PointerState aPointerState( m_pChartWindow->GetPointerState() );
574             MouseEvent aMouseEvent( aPointerState.maPos,1/*nClicks*/,
575                                     0/*nMode*/, static_cast< sal_uInt16 >( aPointerState.mnState )/*nButtons*/,
576                                     0/*nModifier*/ );
577             impl_SetMousePointer( aMouseEvent );
578         }
579     }
580 
581     return 0;
582 }
583 
584 //------------------------------------------------------------------------
585 
execute_MouseButtonDown(const MouseEvent & rMEvt)586 void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt )
587 {
588     ::vos::OGuard aGuard( Application::GetSolarMutex());
589 
590     m_bWaitingForMouseUp = true;
591 
592     if( isDoubleClick(rMEvt) )
593         stopDoubleClickWaiting();
594     else
595         startDoubleClickWaiting();
596 
597     m_aSelection.remindSelectionBeforeMouseDown();
598 
599     DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
600     if(!m_pChartWindow || !pDrawViewWrapper )
601         return;
602 
603     Point   aMPos   = m_pChartWindow->PixelToLogic(rMEvt.GetPosPixel());
604 
605     if ( MOUSE_LEFT == rMEvt.GetButtons() )
606     {
607         m_pChartWindow->GrabFocus();
608         m_pChartWindow->CaptureMouse();
609     }
610 
611     if( pDrawViewWrapper->IsTextEdit() )
612     {
613         SdrViewEvent aVEvt;
614         if ( pDrawViewWrapper->IsTextEditHit( aMPos, HITPIX ) ||
615              // #i12587# support for shapes in chart
616              ( rMEvt.IsRight() && pDrawViewWrapper->PickAnything( rMEvt, SDRMOUSEBUTTONDOWN, aVEvt ) == SDRHIT_MARKEDOBJECT ) )
617         {
618             pDrawViewWrapper->MouseButtonDown(rMEvt,m_pChartWindow);
619             return;
620         }
621         else
622         {
623             this->EndTextEdit();
624         }
625     }
626 
627     //abort running action
628     if( pDrawViewWrapper->IsAction() )
629     {
630         if( rMEvt.IsRight() )
631             pDrawViewWrapper->BckAction();
632         return;
633     }
634 
635     if( isDoubleClick(rMEvt) ) //do not change selection if double click
636         return;//double click is handled further in mousebutton up
637 
638     SdrHdl* pHitSelectionHdl = 0;
639     //switch from move to resize if handle is hit on a resizeable object
640     if( m_aSelection.isResizeableObjectSelected() )
641         pHitSelectionHdl = pDrawViewWrapper->PickHandle( aMPos );
642     //only change selection if no selection handles are hit
643     if( !pHitSelectionHdl )
644     {
645         // #i12587# support for shapes in chart
646         if ( m_eDrawMode == CHARTDRAW_INSERT &&
647              ( !pDrawViewWrapper->IsMarkedHit( aMPos ) || !m_aSelection.isDragableObjectSelected() ) )
648         {
649             if ( m_aSelection.hasSelection() )
650             {
651                 m_aSelection.clearSelection();
652             }
653             if ( !pDrawViewWrapper->IsAction() )
654             {
655                 if ( pDrawViewWrapper->GetCurrentObjIdentifier() == OBJ_CAPTION )
656                 {
657                     Size aCaptionSize( 2268, 1134 );
658                     pDrawViewWrapper->BegCreateCaptionObj( aMPos, aCaptionSize );
659                 }
660                 else
661                 {
662                     pDrawViewWrapper->BegCreateObj( aMPos);
663                 }
664                 SdrObject* pObj = pDrawViewWrapper->GetCreateObj();
665                 DrawCommandDispatch* pDrawCommandDispatch = m_aDispatchContainer.getDrawCommandDispatch();
666                 if ( pObj && m_pDrawModelWrapper && pDrawCommandDispatch )
667                 {
668                     SfxItemSet aSet( m_pDrawModelWrapper->GetItemPool() );
669                     pDrawCommandDispatch->setAttributes( pObj );
670                     pDrawCommandDispatch->setLineEnds( aSet );
671                     pObj->SetMergedItemSet( aSet );
672                 }
673             }
674             impl_SetMousePointer( rMEvt );
675             return;
676         }
677 
678         m_aSelection.adaptSelectionToNewPos( aMPos, pDrawViewWrapper
679             , rMEvt.IsRight(), m_bWaitingForDoubleClick );
680 
681         if( !m_aSelection.isRotateableObjectSelected( getModel() ) )
682         {
683                 m_eDragMode = SDRDRAG_MOVE;
684                 pDrawViewWrapper->SetDragMode(m_eDragMode);
685         }
686 
687         m_aSelection.applySelection(pDrawViewWrapper);
688     }
689     if( m_aSelection.isDragableObjectSelected()
690          && !rMEvt.IsRight() )
691     {
692         //start drag
693         sal_uInt16  nDrgLog = (sal_uInt16)m_pChartWindow->PixelToLogic(Size(DRGPIX,0)).Width();
694         SdrDragMethod* pDragMethod = NULL;
695 
696         //change selection to 3D scene if rotate mode
697         SdrDragMode eDragMode = pDrawViewWrapper->GetDragMode();
698         if( SDRDRAG_ROTATE==eDragMode )
699         {
700             E3dScene* pScene = SelectionHelper::getSceneToRotate( pDrawViewWrapper->getNamedSdrObject( m_aSelection.getSelectedCID() ) );
701             if( pScene )
702             {
703                 DragMethod_RotateDiagram::RotationDirection eRotationDirection(DragMethod_RotateDiagram::ROTATIONDIRECTION_FREE);
704                 if(pHitSelectionHdl)
705                 {
706                     SdrHdlKind eKind = pHitSelectionHdl->GetKind();
707                     if( eKind==HDL_UPPER || eKind==HDL_LOWER )
708                         eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_X;
709                     else if( eKind==HDL_LEFT || eKind==HDL_RIGHT )
710                         eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_Y;
711                     else if( eKind==HDL_UPLFT || eKind==HDL_UPRGT || eKind==HDL_LWLFT || eKind==HDL_LWRGT )
712                         eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_Z;
713                 }
714                 pDragMethod = new DragMethod_RotateDiagram( *pDrawViewWrapper, m_aSelection.getSelectedCID(), getModel(), eRotationDirection );
715             }
716         }
717         else
718         {
719             rtl::OUString aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ) );
720             if( aDragMethodServiceName.equals( ObjectIdentifier::getPieSegmentDragMethodServiceName() ) )
721                 pDragMethod = new DragMethod_PieSegment( *pDrawViewWrapper, m_aSelection.getSelectedCID(), getModel() );
722         }
723         pDrawViewWrapper->SdrView::BegDragObj(aMPos, NULL, pHitSelectionHdl, nDrgLog, pDragMethod);
724     }
725 
726     impl_SetMousePointer( rMEvt );
727 }
728 
execute_MouseMove(const MouseEvent & rMEvt)729 void ChartController::execute_MouseMove( const MouseEvent& rMEvt )
730 {
731     ::vos::OGuard aGuard( Application::GetSolarMutex());
732 
733     DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
734     if(!m_pChartWindow || !pDrawViewWrapper)
735         return;
736 
737     if( m_pDrawViewWrapper->IsTextEdit() )
738     {
739         if( m_pDrawViewWrapper->MouseMove(rMEvt,m_pChartWindow) )
740             return;
741     }
742 
743     if(pDrawViewWrapper->IsAction())
744     {
745         pDrawViewWrapper->MovAction( m_pChartWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
746     }
747 
748     //??    pDrawViewWrapper->GetPageView()->DragPoly();
749 
750     impl_SetMousePointer( rMEvt );
751 }
execute_Tracking(const TrackingEvent &)752 void ChartController::execute_Tracking( const TrackingEvent& /* rTEvt */ )
753 {
754 }
755 
756 //-----------------
757 
execute_MouseButtonUp(const MouseEvent & rMEvt)758 void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt )
759 {
760     ControllerLockGuard aCLGuard( getModel() );
761     bool bMouseUpWithoutMouseDown = !m_bWaitingForMouseUp;
762     m_bWaitingForMouseUp = false;
763     bool bNotifySelectionChange = false;
764     {
765         ::vos::OGuard aGuard( Application::GetSolarMutex());
766 
767         DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
768         if(!m_pChartWindow || !pDrawViewWrapper)
769             return;
770 
771         Point   aMPos   = m_pChartWindow->PixelToLogic(rMEvt.GetPosPixel());
772 
773         if(pDrawViewWrapper->IsTextEdit())
774         {
775             if( pDrawViewWrapper->MouseButtonUp(rMEvt,m_pChartWindow) )
776                 return;
777         }
778 
779         // #i12587# support for shapes in chart
780         if ( m_eDrawMode == CHARTDRAW_INSERT && pDrawViewWrapper->IsCreateObj() )
781         {
782             pDrawViewWrapper->EndCreateObj( SDRCREATE_FORCEEND );
783             {
784                 HiddenUndoContext aUndoContext( m_xUndoManager );
785                     // don't want the positioning Undo action to appear in the UI
786                 impl_switchDiagramPositioningToExcludingPositioning();
787             }
788             if ( pDrawViewWrapper->AreObjectsMarked() )
789             {
790                 if ( pDrawViewWrapper->GetCurrentObjIdentifier() == OBJ_TEXT )
791                 {
792                     executeDispatch_EditText();
793                 }
794                 else
795                 {
796                     SdrObject* pObj = pDrawViewWrapper->getSelectedObject();
797                     if ( pObj )
798                     {
799                         uno::Reference< drawing::XShape > xShape( pObj->getUnoShape(), uno::UNO_QUERY );
800                         if ( xShape.is() )
801                         {
802                             m_aSelection.setSelection( xShape );
803                             m_aSelection.applySelection( pDrawViewWrapper );
804                         }
805                     }
806                 }
807             }
808             else
809             {
810                 m_aSelection.adaptSelectionToNewPos( aMPos, pDrawViewWrapper, rMEvt.IsRight(), m_bWaitingForDoubleClick );
811                 m_aSelection.applySelection( pDrawViewWrapper );
812                 setDrawMode( CHARTDRAW_SELECT );
813             }
814         }
815         else if ( pDrawViewWrapper->IsDragObj() )
816         {
817             bool bDraggingDone = false;
818             SdrDragMethod* pDragMethod = pDrawViewWrapper->SdrView::GetDragMethod();
819             bool bIsMoveOnly = pDragMethod ? pDragMethod->getMoveOnly() : false;
820             DragMethod_Base* pChartDragMethod = dynamic_cast< DragMethod_Base* >(pDragMethod);
821             if( pChartDragMethod )
822             {
823                 UndoGuard aUndoGuard( pChartDragMethod->getUndoDescription(),
824                         m_xUndoManager );
825 
826                 if( pDrawViewWrapper->EndDragObj(false) )
827                 {
828                     bDraggingDone = true;
829                     aUndoGuard.commit();
830                 }
831             }
832 
833             if( !bDraggingDone && pDrawViewWrapper->EndDragObj(false) )
834             {
835                 try
836                 {
837                     //end move or size
838                     SdrObject* pObj = pDrawViewWrapper->getSelectedObject();
839                     if( pObj )
840                     {
841                         Rectangle aObjectRect = pObj->GetSnapRect();
842                         awt::Size aPageSize( ChartModelHelper::getPageSize( getModel() ) );
843                         Rectangle aPageRect( 0,0,aPageSize.Width,aPageSize.Height );
844 
845                         const E3dObject* pE3dObject = dynamic_cast< const E3dObject*>( pObj );
846                         if( pE3dObject )
847                             aObjectRect = pE3dObject->GetScene()->GetSnapRect();
848 
849                         ActionDescriptionProvider::ActionType eActionType(ActionDescriptionProvider::MOVE);
850                         if( !bIsMoveOnly && m_aSelection.isResizeableObjectSelected() )
851                             eActionType = ActionDescriptionProvider::RESIZE;
852 
853                         ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() );
854 
855                         UndoGuard aUndoGuard(
856                             ActionDescriptionProvider::createDescription( eActionType, ObjectNameProvider::getName( eObjectType)),
857                             m_xUndoManager );
858 
859                         bool bChanged = false;
860                         if ( eObjectType == OBJECTTYPE_LEGEND )
861                             bChanged = DiagramHelper::switchDiagramPositioningToExcludingPositioning( getModel(), false , true );
862 
863                         bool bMoved = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID()
864                                         , getModel()
865                                         , awt::Rectangle(aObjectRect.getX(),aObjectRect.getY(),aObjectRect.getWidth(),aObjectRect.getHeight())
866                                         , awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight()) );
867 
868                         if( bMoved || bChanged )
869                         {
870                             bDraggingDone = true;
871                             aUndoGuard.commit();
872                         }
873                     }
874                 }
875                 catch( uno::Exception & ex )
876                 {
877                     ASSERT_EXCEPTION( ex );
878                 }
879                 //all wanted model changes will take effect
880                 //and all unwanted view modifications are cleaned
881             }
882 
883             if( !bDraggingDone ) //mouse wasn't moved while dragging
884             {
885                 bool bClickedTwiceOnDragableObject = SelectionHelper::isDragableObjectHitTwice( aMPos, m_aSelection.getSelectedCID(), *pDrawViewWrapper );
886                 bool bIsRotateable = m_aSelection.isRotateableObjectSelected( getModel() );
887 
888                 //toggel between move and rotate
889                 if( bIsRotateable && bClickedTwiceOnDragableObject && SDRDRAG_MOVE==m_eDragMode )
890                     m_eDragMode=SDRDRAG_ROTATE;
891                 else
892                     m_eDragMode=SDRDRAG_MOVE;
893 
894                 pDrawViewWrapper->SetDragMode(m_eDragMode);
895 
896                 if( !m_bWaitingForDoubleClick && m_aSelection.maybeSwitchSelectionAfterSingleClickWasEnsured() )
897                 {
898                     this->impl_selectObjectAndNotiy();
899                 }
900             }
901             else
902                 m_aSelection.resetPossibleSelectionAfterSingleClickWasEnsured();
903         }
904         else if( isDoubleClick(rMEvt) && !bMouseUpWithoutMouseDown /*#i106966#*/ )
905         {
906             Point aMousePixel = rMEvt.GetPosPixel();
907             execute_DoubleClick( &aMousePixel );
908         }
909 
910         //@todo ForcePointer(&rMEvt);
911         m_pChartWindow->ReleaseMouse();
912 
913         if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() )
914             bNotifySelectionChange = true;
915     }
916 
917     impl_SetMousePointer( rMEvt );
918 
919     if(bNotifySelectionChange)
920         impl_notifySelectionChangeListeners();
921 }
922 
execute_DoubleClick(const Point * pMousePixel)923 void ChartController::execute_DoubleClick( const Point* pMousePixel )
924 {
925     bool bEditText = false;
926     if ( m_aSelection.hasSelection() )
927     {
928         ::rtl::OUString aCID( m_aSelection.getSelectedCID() );
929         if ( !aCID.isEmpty() )
930         {
931             ObjectType eObjectType = ObjectIdentifier::getObjectType( aCID );
932             if ( OBJECTTYPE_TITLE == eObjectType )
933             {
934                 bEditText = true;
935             }
936         }
937         else
938         {
939             // #i12587# support for shapes in chart
940             SdrObject* pObj = DrawViewWrapper::getSdrObject( m_aSelection.getSelectedAdditionalShape() );
941             if ( pObj && pObj->ISA( SdrTextObj ) )
942             {
943                 bEditText = true;
944             }
945         }
946     }
947 
948     if ( bEditText )
949     {
950         executeDispatch_EditText( pMousePixel );
951     }
952     else
953     {
954         executeDispatch_ObjectProperties();
955     }
956 }
957 
execute_Resize()958 void ChartController::execute_Resize()
959 {
960     ::vos::OGuard aGuard( Application::GetSolarMutex() );
961     if(m_pChartWindow)
962         m_pChartWindow->Invalidate();
963 }
execute_Activate()964 void ChartController::execute_Activate()
965 {
966     ///// pDrawViewWrapper->SetEditMode(sal_True);
967 }
execute_Deactivate()968 void ChartController::execute_Deactivate()
969 {
970     /*
971     pDrawViewWrapper->SetEditMode(sal_False);
972     this->ReleaseMouse();
973     */
974 }
execute_GetFocus()975 void ChartController::execute_GetFocus()
976 {
977 }
execute_LoseFocus()978 void ChartController::execute_LoseFocus()
979 {
980     //this->ReleaseMouse();
981 }
982 
execute_Command(const CommandEvent & rCEvt)983 void ChartController::execute_Command( const CommandEvent& rCEvt )
984 {
985     bool bIsAction = false;
986     {
987         ::vos::OGuard aGuard( Application::GetSolarMutex());
988         DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
989         if(!m_pChartWindow || !pDrawViewWrapper)
990             return;
991         bIsAction = m_pDrawViewWrapper->IsAction();
992     }
993 
994     // pop-up menu
995     if(rCEvt.GetCommand() == COMMAND_CONTEXTMENU && !bIsAction)
996     {
997         {
998             ::vos::OGuard aGuard( Application::GetSolarMutex() );
999             if(m_pChartWindow)
1000                 m_pChartWindow->ReleaseMouse();
1001         }
1002 
1003         if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() )
1004             impl_notifySelectionChangeListeners();
1005 
1006         if ( isShapeContext() )
1007         {
1008             // #i12587# support for shapes in chart
1009             PopupMenu aContextMenu( SchResId( m_pDrawViewWrapper->IsTextEdit() ?
1010                 RID_CONTEXTMENU_SHAPEEDIT : RID_CONTEXTMENU_SHAPE ) );
1011             ::svt::ContextMenuHelper aContextMenuHelper( m_xFrame );
1012             Point aPos( rCEvt.GetMousePosPixel() );
1013             if( !rCEvt.IsMouseEvent() )
1014             {
1015                 ::vos::OGuard aGuard( Application::GetSolarMutex() );
1016                 if(m_pChartWindow)
1017                     aPos = m_pChartWindow->GetPointerState().maPos;
1018             }
1019             aContextMenuHelper.completeAndExecute( aPos, aContextMenu );
1020         }
1021         else
1022         {
1023             // todo: the context menu should be specified by an xml file in uiconfig
1024             uno::Reference< awt::XPopupMenu > xPopupMenu(
1025                 m_xCC->getServiceManager()->createInstanceWithContext(
1026                     C2U("com.sun.star.awt.PopupMenu"), m_xCC ), uno::UNO_QUERY );
1027             if( xPopupMenu.is())
1028             {
1029                 sal_Int16 nUniqueId = 1;
1030                 ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() );
1031                 Reference< XDiagram > xDiagram = ChartModelHelper::findDiagram( getModel() );
1032 
1033                 OUString aFormatCommand( lcl_getFormatCommandForObjectCID( m_aSelection.getSelectedCID() ) );
1034                 lcl_insertMenuCommand( xPopupMenu, nUniqueId++, aFormatCommand );
1035 
1036                 //some commands for dataseries and points:
1037                 //-----
1038                 if( OBJECTTYPE_DATA_SERIES == eObjectType || OBJECTTYPE_DATA_POINT == eObjectType )
1039                 {
1040                     bool bIsPoint = ( OBJECTTYPE_DATA_POINT == eObjectType );
1041                     uno::Reference< XDataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() );
1042                     uno::Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY );
1043                     Reference< chart2::XRegressionCurve > xTrendline( RegressionCurveHelper::getFirstCurveNotMeanValueLine( xCurveCnt ) );
1044                     bool bHasEquation = RegressionCurveHelper::hasEquation( xTrendline );
1045                     Reference< chart2::XRegressionCurve > xMeanValue( RegressionCurveHelper::getMeanValueLine( xCurveCnt ) );
1046                     bool bHasYErrorBars = StatisticsHelper::hasErrorBars( xSeries, true );
1047                     bool bHasDataLabelsAtSeries = DataSeriesHelper::hasDataLabelsAtSeries( xSeries );
1048                     bool bHasDataLabelsAtPoints = DataSeriesHelper::hasDataLabelsAtPoints( xSeries );
1049                     bool bHasDataLabelAtPoint = false;
1050                     sal_Int32 nPointIndex = -1;
1051                     if( bIsPoint )
1052                     {
1053                         nPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( m_aSelection.getSelectedCID() );
1054                         bHasDataLabelAtPoint = DataSeriesHelper::hasDataLabelAtPoint( xSeries, nPointIndex );
1055                     }
1056                     bool bSelectedPointIsFormatted = false;
1057                     bool bHasFormattedDataPointsOtherThanSelected = false;
1058 
1059                     Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
1060                     if( xSeriesProperties.is() )
1061                     {
1062                         uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
1063                         if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
1064                         {
1065                             if( aAttributedDataPointIndexList.hasElements() )
1066                             {
1067                                 if( bIsPoint )
1068                                 {
1069                                     ::std::vector< sal_Int32 > aIndices( ContainerHelper::SequenceToVector( aAttributedDataPointIndexList ) );
1070                                     ::std::vector< sal_Int32 >::iterator aIt = ::std::find( aIndices.begin(), aIndices.end(), nPointIndex );
1071                                     if( aIt != aIndices.end())
1072                                         bSelectedPointIsFormatted = true;
1073                                     else
1074                                         bHasFormattedDataPointsOtherThanSelected = true;
1075                                 }
1076                                 else
1077                                     bHasFormattedDataPointsOtherThanSelected = true;
1078                             }
1079                         }
1080                     }
1081 
1082                     //const sal_Int32 nIdBeforeFormat = nUniqueId;
1083                     if( bIsPoint )
1084                     {
1085                         if( bHasDataLabelAtPoint )
1086                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatDataLabel") );
1087                         if( !bHasDataLabelAtPoint )
1088                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertDataLabel") );
1089                         else
1090                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteDataLabel") );
1091                         if( bSelectedPointIsFormatted )
1092                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:ResetDataPoint"));
1093 
1094                         xPopupMenu->insertSeparator( -1 );
1095 
1096                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatDataSeries") );
1097                     }
1098 
1099                     Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram, xSeries ) );
1100                     if( xChartType->getChartType().equals(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
1101                     {
1102                         try
1103                         {
1104                             Reference< beans::XPropertySet > xChartTypeProp( xChartType, uno::UNO_QUERY );
1105                             if( xChartTypeProp.is() )
1106                             {
1107                                 bool bJapaneseStyle = false;
1108                                 xChartTypeProp->getPropertyValue( C2U( "Japanese" ) ) >>= bJapaneseStyle;
1109 
1110                                 if( bJapaneseStyle )
1111                                 {
1112                                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatStockLoss") );
1113                                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatStockGain") );
1114                                 }
1115                             }
1116                         }
1117                         catch( const uno::Exception & ex )
1118                         {
1119                             ASSERT_EXCEPTION( ex );
1120                         }
1121                     }
1122 
1123                     if( bHasDataLabelsAtSeries )
1124                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatDataLabels") );
1125                     if( xTrendline.is() )
1126                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatTrendline") );
1127                     if( bHasEquation )
1128                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatTrendlineEquation") );
1129                     if( xMeanValue.is() )
1130                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatMeanValue") );
1131                     if( bHasYErrorBars )
1132                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatYErrorBars") );
1133 
1134                     //if( nIdBeforeFormat != nUniqueId )
1135                         xPopupMenu->insertSeparator( -1 );
1136 
1137                     //const sal_Int32 nIdBeforeInsert = nUniqueId;
1138 
1139                     if( !bHasDataLabelsAtSeries )
1140                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertDataLabels") );
1141                     if( !xTrendline.is() )
1142                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertTrendline") );
1143                     else if( !bHasEquation )
1144                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertTrendlineEquation") );
1145                     if( !xMeanValue.is() )
1146                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertMeanValue") );
1147                     if( !bHasYErrorBars )
1148                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertYErrorBars") );
1149 
1150                     //if( nIdBeforeInsert != nUniqueId )
1151                     //    xPopupMenu->insertSeparator( -1 );
1152 
1153                     //const sal_Int32 nIdBeforeDelete = nUniqueId;
1154 
1155                     if( bHasDataLabelsAtSeries || ( bHasDataLabelsAtPoints && bHasFormattedDataPointsOtherThanSelected ) )
1156                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteDataLabels") );
1157                     if( xTrendline.is() )
1158                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteTrendline") );
1159                     if( bHasEquation )
1160                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteTrendlineEquation") );
1161                     if( xMeanValue.is() )
1162                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteMeanValue") );
1163                     if( bHasYErrorBars )
1164                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteYErrorBars") );
1165 
1166                     if( bHasFormattedDataPointsOtherThanSelected )
1167                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:ResetAllDataPoints"));
1168 
1169                     //if( nIdBeforeDelete != nUniqueId )
1170                         xPopupMenu->insertSeparator( -1 );
1171 
1172                     lcl_insertMenuCommand( xPopupMenu, nUniqueId, C2U(".uno:ArrangeRow"));
1173                     uno::Reference< awt::XPopupMenu > xArrangePopupMenu(
1174                         m_xCC->getServiceManager()->createInstanceWithContext(
1175                             C2U("com.sun.star.awt.PopupMenu"), m_xCC ), uno::UNO_QUERY );
1176                     if( xArrangePopupMenu.is() )
1177                     {
1178                         sal_Int16 nSubId = nUniqueId + 1;
1179                         lcl_insertMenuCommand( xArrangePopupMenu, nSubId++, C2U(".uno:Forward") );
1180                         lcl_insertMenuCommand( xArrangePopupMenu, nSubId, C2U(".uno:Backward") );
1181                         xPopupMenu->setPopupMenu( nUniqueId, xArrangePopupMenu );
1182                         nUniqueId = nSubId;
1183                     }
1184                     ++nUniqueId;
1185                 }
1186                 else if( OBJECTTYPE_DATA_CURVE == eObjectType )
1187                 {
1188                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatTrendlineEquation") );
1189                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertTrendlineEquation") );
1190                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertTrendlineEquationAndR2") );
1191                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertR2Value") );
1192                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteTrendlineEquation") );
1193                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteR2Value") );
1194                 }
1195                 else if( OBJECTTYPE_DATA_CURVE_EQUATION == eObjectType )
1196                 {
1197                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertR2Value") );
1198                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteR2Value") );
1199                 }
1200 
1201                 //some commands for axes: and grids
1202                 //-----
1203                 else if( OBJECTTYPE_AXIS  == eObjectType || OBJECTTYPE_GRID == eObjectType || OBJECTTYPE_SUBGRID == eObjectType )
1204                 {
1205                     Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), getModel() );
1206                     if( xAxis.is() && xDiagram.is() )
1207                     {
1208                         sal_Int32 nDimensionIndex = -1;
1209                         sal_Int32 nCooSysIndex = -1;
1210                         sal_Int32 nAxisIndex = -1;
1211                         AxisHelper::getIndicesForAxis( xAxis, xDiagram, nCooSysIndex, nDimensionIndex, nAxisIndex );
1212                         bool bIsSecondaryAxis = nAxisIndex!=0;
1213                         bool bIsAxisVisible = AxisHelper::isAxisVisible( xAxis );
1214                         bool bIsMajorGridVisible = AxisHelper::isGridShown( nDimensionIndex, nCooSysIndex, true /*bMainGrid*/, xDiagram );
1215                         bool bIsMinorGridVisible = AxisHelper::isGridShown( nDimensionIndex, nCooSysIndex, false /*bMainGrid*/, xDiagram );
1216                         bool bHasTitle = false;
1217                         uno::Reference< XTitled > xTitled( xAxis, uno::UNO_QUERY );
1218                         if( xTitled.is())
1219                             bHasTitle = ( TitleHelper::getCompleteString( xTitled->getTitleObject() ).isEmpty() == false );
1220 
1221                         if( OBJECTTYPE_AXIS  != eObjectType && bIsAxisVisible )
1222                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatAxis") );
1223                         if( OBJECTTYPE_GRID != eObjectType && bIsMajorGridVisible && !bIsSecondaryAxis )
1224                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatMajorGrid") );
1225                         if( OBJECTTYPE_SUBGRID != eObjectType && bIsMinorGridVisible && !bIsSecondaryAxis )
1226                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatMinorGrid") );
1227 
1228                         xPopupMenu->insertSeparator( -1 );
1229 
1230                         if( OBJECTTYPE_AXIS  != eObjectType && !bIsAxisVisible )
1231                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertAxis") );
1232                         if( OBJECTTYPE_GRID != eObjectType && !bIsMajorGridVisible && !bIsSecondaryAxis )
1233                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertMajorGrid") );
1234                         if( OBJECTTYPE_SUBGRID != eObjectType && !bIsMinorGridVisible && !bIsSecondaryAxis )
1235                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertMinorGrid") );
1236                         if( !bHasTitle )
1237                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertAxisTitle") );
1238 
1239                         if( bIsAxisVisible )
1240                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteAxis") );
1241                         if( bIsMajorGridVisible && !bIsSecondaryAxis )
1242                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteMajorGrid") );
1243                         if( bIsMinorGridVisible && !bIsSecondaryAxis )
1244                             lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteMinorGrid") );
1245                     }
1246                 }
1247 
1248                 if( OBJECTTYPE_DATA_STOCK_LOSS == eObjectType )
1249                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatStockGain") );
1250                 else if( OBJECTTYPE_DATA_STOCK_GAIN == eObjectType )
1251                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:FormatStockLoss") );
1252 
1253                 lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:TransformDialog"));
1254 
1255                 if( OBJECTTYPE_PAGE == eObjectType || OBJECTTYPE_DIAGRAM == eObjectType
1256                     || OBJECTTYPE_DIAGRAM_WALL == eObjectType
1257                     || OBJECTTYPE_DIAGRAM_FLOOR == eObjectType
1258                     || OBJECTTYPE_UNKNOWN == eObjectType )
1259                 {
1260                     if( OBJECTTYPE_UNKNOWN != eObjectType )
1261                         xPopupMenu->insertSeparator( -1 );
1262                     bool bHasLegend = LegendHelper::hasLegend( xDiagram );
1263                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertTitles") );
1264                     if( !bHasLegend )
1265                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertLegend") );
1266                     lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:InsertRemoveAxes") );
1267                     if( bHasLegend )
1268                         lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DeleteLegend") );
1269                 }
1270                 //-----
1271 
1272                 xPopupMenu->insertSeparator( -1 );
1273                 lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DiagramType"));
1274                 lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DataRanges"));
1275                 lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:DiagramData"));
1276                 lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:View3D"));
1277                 xPopupMenu->insertSeparator( -1 );
1278                 lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:Cut"));
1279                 lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:Copy"));
1280                 lcl_insertMenuCommand( xPopupMenu, nUniqueId++, C2U(".uno:Paste"));
1281 
1282                 ::svt::ContextMenuHelper aContextMenuHelper( m_xFrame );
1283                 Point aPos( rCEvt.GetMousePosPixel() );
1284                 if( !rCEvt.IsMouseEvent() )
1285                 {
1286                     ::vos::OGuard aGuard( Application::GetSolarMutex() );
1287                     if(m_pChartWindow)
1288                         aPos = m_pChartWindow->GetPointerState().maPos;
1289                 }
1290                 aContextMenuHelper.completeAndExecute( aPos, xPopupMenu );
1291             }
1292         }
1293     }
1294     else if( ( rCEvt.GetCommand() == COMMAND_STARTEXTTEXTINPUT ) ||
1295              ( rCEvt.GetCommand() == COMMAND_EXTTEXTINPUT ) ||
1296              ( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT ) ||
1297              ( rCEvt.GetCommand() == COMMAND_INPUTCONTEXTCHANGE ) )
1298     {
1299         //#i84417# enable editing with IME
1300         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1301         if( m_pDrawViewWrapper )
1302             m_pDrawViewWrapper->Command( rCEvt, m_pChartWindow );
1303     }
1304 }
1305 
execute_KeyInput(const KeyEvent & rKEvt)1306 bool ChartController::execute_KeyInput( const KeyEvent& rKEvt )
1307 {
1308     bool bReturn=false;
1309 
1310     DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
1311     if(!m_pChartWindow || !pDrawViewWrapper)
1312         return bReturn;
1313 
1314     // handle accelerators
1315     if( ! m_apAccelExecute.get() && m_xFrame.is() && m_xCC.is() && m_xCC->getServiceManager().is() )
1316     {
1317         m_apAccelExecute.reset( ::svt::AcceleratorExecute::createAcceleratorHelper());
1318         OSL_ASSERT( m_apAccelExecute.get());
1319         if( m_apAccelExecute.get() )
1320             m_apAccelExecute->init(
1321                 uno::Reference< lang::XMultiServiceFactory >( m_xCC->getServiceManager(), uno::UNO_QUERY ), m_xFrame );
1322     }
1323 
1324     KeyCode aKeyCode( rKEvt.GetKeyCode());
1325     sal_uInt16 nCode = aKeyCode.GetCode();
1326 //     bool bShift = aKeyCode.IsShift();
1327     bool bAlternate = aKeyCode.IsMod2();
1328 
1329     if( m_apAccelExecute.get() )
1330         bReturn = m_apAccelExecute->execute( aKeyCode );
1331     if( bReturn )
1332         return bReturn;
1333 
1334     {
1335         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1336         if( pDrawViewWrapper->IsTextEdit() )
1337         {
1338             if( pDrawViewWrapper->KeyInput(rKEvt,m_pChartWindow) )
1339             {
1340                 bReturn = true;
1341                 if( nCode == KEY_ESCAPE )
1342                 {
1343                     this->EndTextEdit();
1344                 }
1345             }
1346         }
1347     }
1348 
1349     //if( m_pDrawViewWrapper->IsAction() );
1350 
1351     // keyboard accessibility
1352     ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() );
1353     if( ! bReturn )
1354     {
1355         // Navigation (Tab/F3/Home/End)
1356         uno::Reference< XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
1357         ObjectKeyNavigation aObjNav( m_aSelection.getSelectedOID(), xChartDoc, ExplicitValueProvider::getExplicitValueProvider( m_xChartView ));
1358         awt::KeyEvent aKeyEvent( ::svt::AcceleratorExecute::st_VCLKey2AWTKey( aKeyCode ));
1359         bReturn = aObjNav.handleKeyEvent( aKeyEvent );
1360         if( bReturn )
1361         {
1362             ObjectIdentifier aNewOID = aObjNav.getCurrentSelection();
1363             uno::Any aNewSelection;
1364             if ( aNewOID.isValid() && !ObjectHierarchy::isRootNode( aNewOID ) )
1365             {
1366                 aNewSelection = aNewOID.getAny();
1367             }
1368             if ( m_eDragMode == SDRDRAG_ROTATE && !SelectionHelper::isRotateableObject( aNewOID.getObjectCID(), getModel() ) )
1369             {
1370                 m_eDragMode = SDRDRAG_MOVE;
1371             }
1372             bReturn = select( aNewSelection );
1373         }
1374     }
1375 
1376     // Position and Size (+/-/arrow-keys) or pie segment dragging
1377     if( ! bReturn  )
1378     {
1379         // pie segment dragging
1380         // note: could also be done for data series
1381         if( eObjectType == OBJECTTYPE_DATA_POINT &&
1382             ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ).equals(
1383                 ObjectIdentifier::getPieSegmentDragMethodServiceName()))
1384         {
1385             bool bDrag = false;
1386             bool bDragInside = false;
1387             if( nCode == KEY_ADD ||
1388                 nCode == KEY_SUBTRACT )
1389             {
1390                 bDrag = true;
1391                 bDragInside = ( nCode == KEY_SUBTRACT );
1392             }
1393             else if(
1394                 nCode == KEY_LEFT ||
1395                 nCode == KEY_RIGHT ||
1396                 nCode == KEY_UP ||
1397                 nCode == KEY_DOWN )
1398             {
1399                 bDrag = true;
1400                 rtl::OUString aParameter( ObjectIdentifier::getDragParameterString( m_aSelection.getSelectedCID() ));
1401                 sal_Int32 nOffsetPercentDummy( 0 );
1402                 awt::Point aMinimumPosition( 0, 0 );
1403                 awt::Point aMaximumPosition( 0, 0 );
1404                 ObjectIdentifier::parsePieSegmentDragParameterString(
1405                     aParameter, nOffsetPercentDummy, aMinimumPosition, aMaximumPosition );
1406                 aMaximumPosition.Y -= aMinimumPosition.Y;
1407                 aMaximumPosition.X -= aMinimumPosition.X;
1408 
1409                 bDragInside =
1410                     (nCode == KEY_RIGHT && (aMaximumPosition.X < 0)) ||
1411                     (nCode == KEY_LEFT  && (aMaximumPosition.X > 0)) ||
1412                     (nCode == KEY_DOWN  && (aMaximumPosition.Y < 0)) ||
1413                     (nCode == KEY_UP    && (aMaximumPosition.Y > 0));
1414             }
1415 
1416             if( bDrag )
1417             {
1418                 double fAmount = bAlternate ? 0.01 : 0.05;
1419                 if( bDragInside )
1420                     fAmount *= -1.0;
1421 
1422                 bReturn = impl_DragDataPoint( m_aSelection.getSelectedCID(), fAmount );
1423             }
1424         }
1425         else
1426         {
1427             // size
1428             if( nCode == KEY_ADD ||
1429                 nCode == KEY_SUBTRACT )
1430             {
1431                 if( eObjectType == OBJECTTYPE_DIAGRAM )
1432                 {
1433                     // default 1 mm in each direction
1434                     double fGrowAmountX = 200.0;
1435                     double fGrowAmountY = 200.0;
1436                     if( bAlternate && m_pChartWindow )
1437                     {
1438                         // together with Alt-key: 1 px in each direction
1439                         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1440                         if( m_pChartWindow )
1441                         {
1442                             Size aPixelSize = m_pChartWindow->PixelToLogic( Size( 2, 2 ));
1443                             fGrowAmountX = static_cast< double >( aPixelSize.Width());
1444                             fGrowAmountY = static_cast< double >( aPixelSize.Height());
1445                         }
1446                     }
1447                     if( nCode == KEY_SUBTRACT )
1448                     {
1449                         fGrowAmountX = -fGrowAmountX;
1450                         fGrowAmountY = -fGrowAmountY;
1451                     }
1452                     bReturn = impl_moveOrResizeObject(
1453                         m_aSelection.getSelectedCID(), CENTERED_RESIZE_OBJECT, fGrowAmountX, fGrowAmountY );
1454                 }
1455             }
1456             // position
1457             else if( nCode == KEY_LEFT  ||
1458                      nCode == KEY_RIGHT ||
1459                      nCode == KEY_UP ||
1460                      nCode == KEY_DOWN )
1461             {
1462                 if( m_aSelection.isDragableObjectSelected() )
1463                 {
1464                     // default 1 mm
1465                     double fShiftAmountX = 100.0;
1466                     double fShiftAmountY = 100.0;
1467                     if( bAlternate && m_pChartWindow )
1468                     {
1469                         // together with Alt-key: 1 px
1470                         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1471                         if(m_pChartWindow)
1472                         {
1473                             Size aPixelSize = m_pChartWindow->PixelToLogic( Size( 1, 1 ));
1474                             fShiftAmountX = static_cast< double >( aPixelSize.Width());
1475                             fShiftAmountY = static_cast< double >( aPixelSize.Height());
1476                         }
1477                     }
1478                     switch( nCode )
1479                     {
1480                         case KEY_LEFT:
1481                             fShiftAmountX = -fShiftAmountX;
1482                             fShiftAmountY = 0.0;
1483                             break;
1484                         case KEY_RIGHT:
1485                             fShiftAmountY = 0.0;
1486                             break;
1487                         case KEY_UP:
1488                             fShiftAmountX = 0.0;
1489                             fShiftAmountY = -fShiftAmountY;
1490                             break;
1491                         case KEY_DOWN:
1492                             fShiftAmountX = 0.0;
1493                             break;
1494                     }
1495                     if( !m_aSelection.getSelectedCID().isEmpty() )
1496                     {
1497                         //move chart objects
1498                         bReturn = impl_moveOrResizeObject(
1499                             m_aSelection.getSelectedCID(), MOVE_OBJECT, fShiftAmountX, fShiftAmountY );
1500                     }
1501                     else
1502                     {
1503                         //move additional shapes
1504                         uno::Reference< drawing::XShape > xShape( m_aSelection.getSelectedAdditionalShape() );
1505                         if( xShape.is() )
1506                         {
1507                             awt::Point aPos( xShape->getPosition() );
1508                             awt::Size aSize( xShape->getSize() );
1509                             awt::Size aPageSize( ChartModelHelper::getPageSize( getModel() ) );
1510                             aPos.X = static_cast< long >( static_cast< double >( aPos.X ) + fShiftAmountX );
1511                             aPos.Y = static_cast< long >( static_cast< double >( aPos.Y ) + fShiftAmountY );
1512                             if( aPos.X + aSize.Width > aPageSize.Width )
1513                                 aPos.X = aPageSize.Width - aSize.Width;
1514                             if( aPos.X < 0 )
1515                                 aPos.X = 0;
1516                             if( aPos.Y + aSize.Height > aPageSize.Height )
1517                                 aPos.Y = aPageSize.Height - aSize.Height;
1518                             if( aPos.Y < 0 )
1519                                 aPos.Y = 0;
1520 
1521                             xShape->setPosition( aPos );
1522                         }
1523                     }
1524                 }
1525             }
1526         }
1527     }
1528 
1529     // text edit
1530     if( ! bReturn &&
1531         nCode == KEY_F2 )
1532     {
1533         if( OBJECTTYPE_TITLE == eObjectType )
1534         {
1535             executeDispatch_EditText();
1536             bReturn = true;
1537         }
1538     }
1539 
1540     // deactivate inplace mode (this code should be unnecessary, but
1541     // unfortunately is not)
1542     if( ! bReturn &&
1543         nCode == KEY_ESCAPE )
1544     {
1545         uno::Reference< frame::XDispatchHelper > xDispatchHelper(
1546             m_xCC->getServiceManager()->createInstanceWithContext(
1547                 C2U("com.sun.star.frame.DispatchHelper"), m_xCC ), uno::UNO_QUERY );
1548         if( xDispatchHelper.is())
1549         {
1550             uno::Sequence< beans::PropertyValue > aArgs;
1551             xDispatchHelper->executeDispatch(
1552                 uno::Reference< frame::XDispatchProvider >( m_xFrame, uno::UNO_QUERY ),
1553                 C2U(".uno:TerminateInplaceActivation"),
1554                 C2U("_parent"),
1555                 frame::FrameSearchFlag::PARENT,
1556                 aArgs );
1557             bReturn = true;
1558         }
1559     }
1560 
1561     if( ! bReturn &&
1562         (nCode == KEY_DELETE || nCode == KEY_BACKSPACE ))
1563     {
1564         bReturn = executeDispatch_Delete();
1565         if( ! bReturn )
1566         {
1567             ::vos::OGuard aGuard( Application::GetSolarMutex() );
1568             InfoBox( m_pChartWindow, String(SchResId( STR_ACTION_NOTPOSSIBLE ))).Execute();
1569         }
1570     }
1571 
1572     /* old chart:
1573     // Ctrl-Shift-R: Repaint
1574     if (!bReturn && GetWindow())
1575     {
1576         KeyCode aKeyCode = rKEvt.GetKeyCode();
1577 
1578         if (aKeyCode.IsMod1() && aKeyCode.IsShift()
1579             && aKeyCode.GetCode() == KEY_R)
1580         {
1581                 // 3D-Kontext wieder zerstoeren
1582             GetWindow()->Invalidate();
1583             bReturn = sal_True;
1584         }
1585     }
1586     */
1587     return bReturn;
1588 }
1589 
requestQuickHelp(::Point aAtLogicPosition,bool bIsBalloonHelp,::rtl::OUString & rOutQuickHelpText,awt::Rectangle & rOutEqualRect)1590 bool ChartController::requestQuickHelp(
1591     ::Point aAtLogicPosition,
1592     bool bIsBalloonHelp,
1593     ::rtl::OUString & rOutQuickHelpText,
1594     awt::Rectangle & rOutEqualRect )
1595 {
1596     uno::Reference< frame::XModel > xChartModel;
1597     if( m_aModel.is())
1598         xChartModel.set( getModel() );
1599     if( !xChartModel.is())
1600         return false;
1601 
1602     // help text
1603     ::rtl::OUString aCID;
1604     if( m_pDrawViewWrapper )
1605     {
1606         aCID = SelectionHelper::getHitObjectCID(
1607             aAtLogicPosition, *m_pDrawViewWrapper );
1608     }
1609     bool bResult( !aCID.isEmpty() );
1610 
1611     if( bResult )
1612     {
1613         // get help text
1614         rOutQuickHelpText = ObjectNameProvider::getHelpText( aCID, xChartModel, bIsBalloonHelp /* bVerbose */ );
1615 
1616         // set rectangle
1617         ExplicitValueProvider * pValueProvider(
1618             ExplicitValueProvider::getExplicitValueProvider( m_xChartView ));
1619         if( pValueProvider )
1620             rOutEqualRect = pValueProvider->getRectangleOfObject( aCID, true );
1621     }
1622 
1623     return bResult;
1624 }
1625 
1626 //-----------------------------------------------------------------
1627 // XSelectionSupplier (optional interface)
1628 //-----------------------------------------------------------------
1629         sal_Bool SAL_CALL ChartController
select(const uno::Any & rSelection)1630 ::select( const uno::Any& rSelection )
1631 {
1632     bool bSuccess = false;
1633 
1634     if ( rSelection.hasValue() )
1635     {
1636         const uno::Type& rType = rSelection.getValueType();
1637         if ( rType == ::getCppuType( static_cast< const ::rtl::OUString* >( 0 ) ) )
1638         {
1639             ::rtl::OUString aNewCID;
1640             if ( ( rSelection >>= aNewCID ) && m_aSelection.setSelection( aNewCID ) )
1641             {
1642                 bSuccess = true;
1643             }
1644         }
1645         else if ( rType == ::getCppuType( static_cast< const uno::Reference< drawing::XShape >* >( 0 ) ) )
1646         {
1647             uno::Reference< drawing::XShape > xShape;
1648             if ( ( rSelection >>= xShape ) && m_aSelection.setSelection( xShape ) )
1649             {
1650                 bSuccess = true;
1651             }
1652         }
1653     }
1654     else
1655     {
1656         if ( m_aSelection.hasSelection() )
1657         {
1658             m_aSelection.clearSelection();
1659             bSuccess = true;
1660         }
1661     }
1662 
1663     if ( bSuccess )
1664     {
1665         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1666         if ( m_pDrawViewWrapper && m_pDrawViewWrapper->IsTextEdit() )
1667         {
1668             this->EndTextEdit();
1669         }
1670         this->impl_selectObjectAndNotiy();
1671         if ( m_pChartWindow )
1672         {
1673             m_pChartWindow->Invalidate();
1674         }
1675         return sal_True;
1676     }
1677 
1678     return sal_False;
1679 }
1680 
1681         uno::Any SAL_CALL ChartController
getSelection()1682 ::getSelection()
1683 {
1684     uno::Any aReturn;
1685     if ( m_aSelection.hasSelection() )
1686     {
1687         ::rtl::OUString aCID( m_aSelection.getSelectedCID() );
1688         if ( !aCID.isEmpty() )
1689         {
1690             aReturn = uno::makeAny( aCID );
1691         }
1692         else
1693         {
1694             // #i12587# support for shapes in chart
1695             aReturn = uno::makeAny( m_aSelection.getSelectedAdditionalShape() );
1696         }
1697     }
1698     return aReturn;
1699 }
1700 
1701         void SAL_CALL ChartController
addSelectionChangeListener(const uno::Reference<view::XSelectionChangeListener> & xListener)1702 ::addSelectionChangeListener( const uno::Reference<
1703         view::XSelectionChangeListener > & xListener )
1704 {
1705     ::vos::OGuard aGuard( Application::GetSolarMutex());
1706     if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode?
1707         return; //behave passive if already disposed or suspended
1708 
1709     //--add listener
1710     m_aLifeTimeManager.m_aListenerContainer.addInterface( ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0), xListener );
1711 }
1712 
1713         void SAL_CALL ChartController
removeSelectionChangeListener(const uno::Reference<view::XSelectionChangeListener> & xListener)1714 ::removeSelectionChangeListener( const uno::Reference<
1715         view::XSelectionChangeListener > & xListener )
1716 {
1717     ::vos::OGuard aGuard( Application::GetSolarMutex());
1718     if( impl_isDisposedOrSuspended() ) //@todo? allow removing of listeners in suspend mode?
1719         return; //behave passive if already disposed or suspended
1720 
1721     //--remove listener
1722     m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0), xListener );
1723 }
1724 
1725         void ChartController
impl_notifySelectionChangeListeners()1726 ::impl_notifySelectionChangeListeners()
1727 {
1728     ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
1729         .getContainer( ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0) );
1730     if( pIC )
1731     {
1732         uno::Reference< view::XSelectionSupplier > xSelectionSupplier(this);
1733         lang::EventObject aEvent( xSelectionSupplier );
1734         ::cppu::OInterfaceIteratorHelper aIt( *pIC );
1735         while( aIt.hasMoreElements() )
1736         {
1737             uno::Reference< view::XSelectionChangeListener > xListener( aIt.next(), uno::UNO_QUERY );
1738             if( xListener.is() )
1739                 xListener->selectionChanged( aEvent );
1740         }
1741     }
1742 }
1743 
impl_selectObjectAndNotiy()1744 void ChartController::impl_selectObjectAndNotiy()
1745 {
1746     {
1747         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1748         DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper;
1749         if( pDrawViewWrapper )
1750         {
1751             pDrawViewWrapper->SetDragMode( m_eDragMode );
1752             m_aSelection.applySelection( m_pDrawViewWrapper );
1753         }
1754     }
1755     impl_notifySelectionChangeListeners();
1756 }
1757 
impl_moveOrResizeObject(const::rtl::OUString & rCID,eMoveOrResizeType eType,double fAmountLogicX,double fAmountLogicY)1758 bool ChartController::impl_moveOrResizeObject(
1759     const ::rtl::OUString & rCID,
1760     eMoveOrResizeType eType,
1761     double fAmountLogicX,
1762     double fAmountLogicY )
1763 {
1764     bool bResult = false;
1765     bool bNeedShift = true;
1766     bool bNeedResize = ( eType == CENTERED_RESIZE_OBJECT );
1767 
1768     uno::Reference< frame::XModel > xChartModel( getModel() );
1769     uno::Reference< beans::XPropertySet > xObjProp(
1770         ObjectIdentifier::getObjectPropertySet( rCID, xChartModel ));
1771     if( xObjProp.is())
1772     {
1773         awt::Size aRefSize = ChartModelHelper::getPageSize( xChartModel );
1774 
1775         chart2::RelativePosition aRelPos;
1776         chart2::RelativeSize     aRelSize;
1777         bool bDeterminePos  = !(xObjProp->getPropertyValue( C2U("RelativePosition")) >>= aRelPos);
1778         bool bDetermineSize = !bNeedResize || !(xObjProp->getPropertyValue( C2U("RelativeSize")) >>= aRelSize);
1779 
1780         if( ( bDeterminePos || bDetermineSize ) &&
1781             ( aRefSize.Width > 0 && aRefSize.Height > 0 ) )
1782         {
1783             ExplicitValueProvider * pValueProvider(
1784                 ExplicitValueProvider::getExplicitValueProvider( m_xChartView ));
1785             if( pValueProvider )
1786             {
1787                 awt::Rectangle aRect( pValueProvider->getRectangleOfObject( rCID ));
1788                 double fWidth = static_cast< double >( aRefSize.Width );
1789                 double fHeight = static_cast< double >( aRefSize.Height );
1790                 if( bDetermineSize )
1791                 {
1792                     aRelSize.Primary   = static_cast< double >( aRect.Width ) / fWidth;
1793                     aRelSize.Secondary = static_cast< double >( aRect.Height ) / fHeight;
1794                 }
1795                 if( bDeterminePos )
1796                 {
1797                     if( bNeedResize && aRelSize.Primary > 0.0 && aRelSize.Secondary > 0.0 )
1798                     {
1799                         aRelPos.Primary   = (static_cast< double >( aRect.X ) / fWidth) +
1800                             (aRelSize.Primary / 2.0);
1801                         aRelPos.Secondary = (static_cast< double >( aRect.Y ) / fHeight) +
1802                             (aRelSize.Secondary / 2.0);
1803                         aRelPos.Anchor = drawing::Alignment_CENTER;
1804                     }
1805                     else
1806                     {
1807                         aRelPos.Primary   = static_cast< double >( aRect.X ) / fWidth;
1808                         aRelPos.Secondary = static_cast< double >( aRect.Y ) / fHeight;
1809                         aRelPos.Anchor = drawing::Alignment_TOP_LEFT;
1810                     }
1811                 }
1812             }
1813         }
1814 
1815         if( eType == CENTERED_RESIZE_OBJECT )
1816             bResult = lcl_GrowAndShiftLogic( aRelPos, aRelSize, aRefSize, fAmountLogicX, fAmountLogicY );
1817         else if( eType == MOVE_OBJECT )
1818             bResult = lcl_MoveObjectLogic( aRelPos, aRelSize, aRefSize, fAmountLogicX, fAmountLogicY );
1819 
1820         if( bResult )
1821         {
1822             ActionDescriptionProvider::ActionType eActionType(ActionDescriptionProvider::MOVE);
1823             if( bNeedResize )
1824                 eActionType = ActionDescriptionProvider::RESIZE;
1825 
1826             ObjectType eObjectType = ObjectIdentifier::getObjectType( rCID );
1827             UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription(
1828                     eActionType, ObjectNameProvider::getName( eObjectType )), m_xUndoManager );
1829             {
1830                 ControllerLockGuard aCLGuard( xChartModel );
1831                 if( bNeedShift )
1832                     xObjProp->setPropertyValue( C2U("RelativePosition"), uno::makeAny( aRelPos ));
1833                 if( bNeedResize || (eObjectType == OBJECTTYPE_DIAGRAM) )//Also set an explicat size at the diagram when an explicit position is set
1834                     xObjProp->setPropertyValue( C2U("RelativeSize"), uno::makeAny( aRelSize ));
1835             }
1836             aUndoGuard.commit();
1837         }
1838     }
1839     return bResult;
1840 }
1841 
impl_DragDataPoint(const::rtl::OUString & rCID,double fAdditionalOffset)1842 bool ChartController::impl_DragDataPoint( const ::rtl::OUString & rCID, double fAdditionalOffset )
1843 {
1844     bool bResult = false;
1845     if( fAdditionalOffset < -1.0 || fAdditionalOffset > 1.0 || fAdditionalOffset == 0.0 )
1846         return bResult;
1847 
1848     sal_Int32 nDataPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( rCID );
1849     uno::Reference< chart2::XDataSeries > xSeries(
1850         ObjectIdentifier::getDataSeriesForCID( rCID, getModel() ));
1851     if( xSeries.is())
1852     {
1853         try
1854         {
1855             uno::Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex( nDataPointIndex ));
1856             double fOffset = 0.0;
1857             if( xPointProp.is() &&
1858                 (xPointProp->getPropertyValue( C2U("Offset" )) >>= fOffset ) &&
1859                 (( fAdditionalOffset > 0.0 && fOffset < 1.0 ) || (fOffset > 0.0)) )
1860             {
1861                 fOffset += fAdditionalOffset;
1862                 if( fOffset > 1.0 )
1863                     fOffset = 1.0;
1864                 else if( fOffset < 0.0 )
1865                     fOffset = 0.0;
1866                 xPointProp->setPropertyValue( C2U("Offset"), uno::makeAny( fOffset ));
1867                 bResult = true;
1868             }
1869         }
1870         catch( const uno::Exception & ex )
1871         {
1872             ASSERT_EXCEPTION( ex );
1873         }
1874     }
1875 
1876     return bResult;
1877 }
1878 
impl_SetMousePointer(const MouseEvent & rEvent)1879 void ChartController::impl_SetMousePointer( const MouseEvent & rEvent )
1880 {
1881     ::vos::OGuard aGuard( Application::GetSolarMutex());
1882     if( m_pDrawViewWrapper && m_pChartWindow )
1883     {
1884         Point aMousePos( m_pChartWindow->PixelToLogic( rEvent.GetPosPixel()));
1885         sal_uInt16 nModifier = rEvent.GetModifier();
1886         sal_Bool bLeftDown = rEvent.IsLeft();
1887 
1888         if ( m_pDrawViewWrapper->IsTextEdit() )
1889         {
1890             if( m_pDrawViewWrapper->IsTextEditHit( aMousePos, HITPIX) )
1891             {
1892                 m_pChartWindow->SetPointer( m_pDrawViewWrapper->GetPreferedPointer(
1893                     aMousePos, m_pChartWindow, nModifier, bLeftDown ) );
1894                 return;
1895             }
1896         }
1897         else if( m_pDrawViewWrapper->IsAction() )
1898         {
1899             return;//don't change pointer during running action
1900         }
1901 
1902         SdrHdl* pHitSelectionHdl = 0;
1903         if( m_aSelection.isResizeableObjectSelected() )
1904             pHitSelectionHdl = m_pDrawViewWrapper->PickHandle( aMousePos );
1905 
1906         if( pHitSelectionHdl )
1907         {
1908 
1909             Pointer aPointer = m_pDrawViewWrapper->GetPreferedPointer(
1910                 aMousePos, m_pChartWindow, nModifier, bLeftDown );
1911             bool bForceArrowPointer = false;
1912 
1913             ObjectIdentifier aOID( m_aSelection.getSelectedOID() );
1914 
1915             switch( aPointer.GetStyle())
1916             {
1917                 case POINTER_NSIZE:
1918                 case POINTER_SSIZE:
1919                 case POINTER_WSIZE:
1920                 case POINTER_ESIZE:
1921                 case POINTER_NWSIZE:
1922                 case POINTER_NESIZE:
1923                 case POINTER_SWSIZE:
1924                 case POINTER_SESIZE:
1925                     if( ! m_aSelection.isResizeableObjectSelected() )
1926                         bForceArrowPointer = true;
1927                     break;
1928                 case POINTER_MOVE:
1929                     if ( !aOID.isDragableObject() )
1930                         bForceArrowPointer = true;
1931                     break;
1932                 case POINTER_MOVEPOINT:
1933                 case POINTER_MOVEBEZIERWEIGHT:
1934                     // there is no point-editing in a chart
1935                     // the POINTER_MOVEBEZIERWEIGHT appears in 3d data points
1936                     bForceArrowPointer = true;
1937                     break;
1938                 default:
1939                     break;
1940             }
1941 
1942             if( bForceArrowPointer )
1943                 m_pChartWindow->SetPointer( Pointer( POINTER_ARROW ));
1944             else
1945                 m_pChartWindow->SetPointer( aPointer );
1946         }
1947         else
1948         {
1949             // #i12587# support for shapes in chart
1950             if ( m_eDrawMode == CHARTDRAW_INSERT &&
1951                  ( !m_pDrawViewWrapper->IsMarkedHit( aMousePos ) || !m_aSelection.isDragableObjectSelected() ) )
1952             {
1953                 PointerStyle ePointerStyle = POINTER_DRAW_RECT;
1954                 SdrObjKind eKind = static_cast< SdrObjKind >( m_pDrawViewWrapper->GetCurrentObjIdentifier() );
1955                 switch ( eKind )
1956                 {
1957                     case OBJ_LINE:
1958                         {
1959                             ePointerStyle = POINTER_DRAW_LINE;
1960                         }
1961                         break;
1962                     case OBJ_RECT:
1963                     case OBJ_CUSTOMSHAPE:
1964                         {
1965                             ePointerStyle = POINTER_DRAW_RECT;
1966                         }
1967                         break;
1968                     case OBJ_CIRC:
1969                         {
1970                             ePointerStyle = POINTER_DRAW_ELLIPSE;
1971                         }
1972                         break;
1973                     case OBJ_FREELINE:
1974                         {
1975                             ePointerStyle = POINTER_DRAW_POLYGON;
1976                         }
1977                         break;
1978                     case OBJ_TEXT:
1979                         {
1980                             ePointerStyle = POINTER_DRAW_TEXT;
1981                         }
1982                         break;
1983                     case OBJ_CAPTION:
1984                         {
1985                             ePointerStyle = POINTER_DRAW_CAPTION;
1986                         }
1987                         break;
1988                     default:
1989                         {
1990                             ePointerStyle = POINTER_DRAW_RECT;
1991                         }
1992                         break;
1993                 }
1994                 m_pChartWindow->SetPointer( Pointer( ePointerStyle ) );
1995                 return;
1996             }
1997 
1998             ::rtl::OUString aHitObjectCID(
1999                 SelectionHelper::getHitObjectCID(
2000                     aMousePos, *m_pDrawViewWrapper, true /*bGetDiagramInsteadOf_Wall*/ ));
2001 
2002             if( m_pDrawViewWrapper->IsTextEdit() )
2003             {
2004                 if( aHitObjectCID.equals(m_aSelection.getSelectedCID()) )
2005                 {
2006                     m_pChartWindow->SetPointer( Pointer( POINTER_ARROW ));
2007                     return;
2008                 }
2009             }
2010 
2011             if( aHitObjectCID.isEmpty() )
2012             {
2013                 //additional shape was hit
2014                 m_pChartWindow->SetPointer( POINTER_MOVE );
2015             }
2016             else if( ObjectIdentifier::isDragableObject( aHitObjectCID ) )
2017             {
2018                 if( (m_eDragMode == SDRDRAG_ROTATE)
2019                     && SelectionHelper::isRotateableObject( aHitObjectCID
2020                         , getModel() ) )
2021                     m_pChartWindow->SetPointer( Pointer( POINTER_ROTATE ) );
2022                 else
2023                 {
2024                     ObjectType eHitObjectType = ObjectIdentifier::getObjectType( aHitObjectCID );
2025                     if( eHitObjectType == OBJECTTYPE_DATA_POINT )
2026                     {
2027                         if( !ObjectIdentifier::areSiblings(aHitObjectCID,m_aSelection.getSelectedCID())
2028                             && !ObjectIdentifier::areIdenticalObjects(aHitObjectCID,m_aSelection.getSelectedCID()) )
2029                         {
2030                             m_pChartWindow->SetPointer( Pointer( POINTER_ARROW ));
2031                             return;
2032                         }
2033                     }
2034                     m_pChartWindow->SetPointer( POINTER_MOVE );
2035                 }
2036             }
2037             else
2038                 m_pChartWindow->SetPointer( Pointer( POINTER_ARROW ));
2039         }
2040     }
2041 }
2042 
2043 //.............................................................................
2044 } //namespace chart
2045 //.............................................................................
2046