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