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