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