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