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