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