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