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