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