1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_chart2.hxx" 30 #include "DrawViewWrapper.hxx" 31 #include "chartview/DrawModelWrapper.hxx" 32 #include "ConfigurationAccess.hxx" 33 #include "macros.hxx" 34 35 #include <unotools/lingucfg.hxx> 36 #include <editeng/langitem.hxx> 37 // header for class SdrPage 38 #include <svx/svdpage.hxx> 39 //header for class SdrPageView 40 #include <svx/svdpagv.hxx> 41 // header for class SdrModel 42 #include <svx/svdmodel.hxx> 43 // header for class E3dScene 44 #include <svx/scene3d.hxx> 45 #include <svx/svdetc.hxx> 46 #include <svx/svdoutl.hxx> 47 48 // header for class SvxForbiddenCharactersTable 49 #include <editeng/forbiddencharacterstable.hxx> 50 51 #ifndef _SVX_SVXIDS_HRC 52 #include <svx/svxids.hrc> 53 #endif 54 55 // header for class SvxShape 56 #include <svx/unoshape.hxx> 57 #include <editeng/fhgtitem.hxx> 58 59 #include <com/sun/star/container/XChild.hpp> 60 #include <com/sun/star/lang/XUnoTunnel.hpp> 61 62 #include <sfx2/objsh.hxx> 63 #include <svx/helperhittest3d.hxx> 64 65 using namespace ::com::sun::star; 66 67 //............................................................................. 68 namespace chart 69 { 70 //............................................................................. 71 72 namespace 73 { 74 short lcl_getHitTolerance( OutputDevice* pOutDev ) 75 { 76 const short HITPIX=2; //hit-tolerance in pixel 77 short nHitTolerance = 50; 78 if(pOutDev) 79 nHitTolerance = static_cast<short>(pOutDev->PixelToLogic(Size(HITPIX,0)).Width()); 80 return nHitTolerance; 81 } 82 83 // this code is copied from sfx2/source/doc/objembed.cxx 84 SfxObjectShell * lcl_GetParentObjectShell( const uno::Reference< frame::XModel > & xModel ) 85 { 86 SfxObjectShell* pResult = NULL; 87 88 try 89 { 90 uno::Reference< container::XChild > xChildModel( xModel, uno::UNO_QUERY ); 91 if ( xChildModel.is() ) 92 { 93 uno::Reference< lang::XUnoTunnel > xParentTunnel( xChildModel->getParent(), uno::UNO_QUERY ); 94 if ( xParentTunnel.is() ) 95 { 96 SvGlobalName aSfxIdent( SFX_GLOBAL_CLASSID ); 97 pResult = reinterpret_cast< SfxObjectShell * >( 98 xParentTunnel->getSomething( uno::Sequence< sal_Int8 >( aSfxIdent.GetByteSequence() ) ) ); 99 } 100 } 101 } 102 catch( uno::Exception& ) 103 { 104 // TODO: error handling 105 } 106 107 return pResult; 108 } 109 110 // this code is copied from sfx2/source/doc/objembed.cxx. It is a workaround to 111 // get the reference device (e.g. printer) fromthe parent document 112 OutputDevice * lcl_GetParentRefDevice( const uno::Reference< frame::XModel > & xModel ) 113 { 114 SfxObjectShell * pParent = lcl_GetParentObjectShell( xModel ); 115 if ( pParent ) 116 return pParent->GetDocumentRefDev(); 117 return NULL; 118 } 119 120 } 121 122 /* 123 void lcl_initOutliner( SdrOutliner* pTargetOutliner, SdrOutliner* pSourceOutliner ) 124 { 125 //just an unsuccessful try to initialize the text edit outliner correctly 126 //if( bInit ) 127 { 128 pTargetOutliner->EraseVirtualDevice(); 129 pTargetOutliner->SetUpdateMode(sal_False); 130 pTargetOutliner->SetEditTextObjectPool( pSourceOutliner->GetEditTextObjectPool() ); 131 pTargetOutliner->SetDefTab( pSourceOutliner->GetDefTab() ); 132 } 133 134 pTargetOutliner->SetRefDevice( pSourceOutliner->GetRefDevice() ); 135 pTargetOutliner->SetForbiddenCharsTable( pSourceOutliner->GetForbiddenCharsTable() ); 136 pTargetOutliner->SetAsianCompressionMode( pSourceOutliner->GetAsianCompressionMode() ); 137 pTargetOutliner->SetKernAsianPunctuation( pSourceOutliner->IsKernAsianPunctuation() ); 138 pTargetOutliner->SetStyleSheetPool( pSourceOutliner->GetStyleSheetPool() ); 139 pTargetOutliner->SetRefMapMode( pSourceOutliner->GetRefMapMode() ); 140 pTargetOutliner->SetDefaultLanguage( pSourceOutliner->GetDefaultLanguage() ); 141 pTargetOutliner->SetHyphenator( pSourceOutliner->GetHyphenator() ); 142 143 sal_uInt16 nX, nY; 144 pSourceOutliner->GetGlobalCharStretching( nX, nY ); 145 pTargetOutliner->SetGlobalCharStretching( nX, nY ); 146 147 *//* 148 if ( !GetRefDevice() ) 149 { 150 MapMode aMapMode(eObjUnit, Point(0,0), aObjUnit, aObjUnit); 151 pTargetOutliner->SetRefMapMode(aMapMode); 152 } 153 *//* 154 } 155 */ 156 157 DrawViewWrapper::DrawViewWrapper( SdrModel* pSdrModel, OutputDevice* pOut, bool bPaintPageForEditMode) 158 : E3dView(pSdrModel, pOut) 159 , m_pMarkHandleProvider(NULL) 160 , m_apOutliner( SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, pSdrModel ) ) 161 , m_bRestoreMapMode( false ) 162 { 163 // #114898# 164 SetBufferedOutputAllowed(true); 165 SetBufferedOverlayAllowed(true); 166 167 SetPagePaintingAllowed(bPaintPageForEditMode); 168 169 // #i12587# support for shapes in chart 170 SdrOutliner* pOutliner = getOutliner(); 171 SfxItemPool* pOutlinerPool = ( pOutliner ? pOutliner->GetEditTextObjectPool() : NULL ); 172 if ( pOutlinerPool ) 173 { 174 SvtLinguConfig aLinguConfig; 175 SvtLinguOptions aLinguOptions; 176 if ( aLinguConfig.GetOptions( aLinguOptions ) ) 177 { 178 pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage, EE_CHAR_LANGUAGE ) ); 179 pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage_CJK, EE_CHAR_LANGUAGE_CJK ) ); 180 pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage_CTL, EE_CHAR_LANGUAGE_CTL ) ); 181 } 182 183 // set font height without changing SdrEngineDefaults 184 pOutlinerPool->SetPoolDefaultItem( SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT ) ); // 12pt 185 } 186 187 ReInit(); 188 } 189 190 void DrawViewWrapper::ReInit() 191 { 192 OutputDevice* pOutDev = this->GetFirstOutputDevice(); 193 Size aOutputSize(100,100); 194 if(pOutDev) 195 aOutputSize = pOutDev->GetOutputSize(); 196 197 bPageVisible = false; 198 bPageBorderVisible = false; 199 bBordVisible = false; 200 bGridVisible = false; 201 bHlplVisible = false; 202 203 this->SetNoDragXorPolys(true);//for interactive 3D resize-dragging: paint only a single rectangle (not a simulated 3D object) 204 //this->SetResizeAtCenter(true);//for interactive resize-dragging: keep the object center fix 205 206 //a correct work area is at least necessary for correct values in the position and size dialog 207 Rectangle aRect(Point(0,0), aOutputSize); 208 this->SetWorkArea(aRect); 209 210 this->ShowSdrPage(this->GetModel()->GetPage(0)); 211 } 212 213 DrawViewWrapper::~DrawViewWrapper() 214 { 215 aComeBackTimer.Stop();//@todo this should be done in destructor of base class 216 UnmarkAllObj();//necessary to aavoid a paint call during the destructor hierarchy 217 } 218 219 SdrPageView* DrawViewWrapper::GetPageView() const 220 { 221 SdrPageView* pSdrPageView = this->GetSdrPageView(); 222 return pSdrPageView; 223 }; 224 225 //virtual 226 void DrawViewWrapper::SetMarkHandles() 227 { 228 if( m_pMarkHandleProvider && m_pMarkHandleProvider->getMarkHandles( aHdl ) ) 229 return; 230 else 231 SdrView::SetMarkHandles(); 232 } 233 234 SdrObject* DrawViewWrapper::getHitObject( const Point& rPnt ) const 235 { 236 SdrObject* pRet = NULL; 237 //sal_uLong nOptions =SDRSEARCH_DEEP|SDRSEARCH_PASS2BOUND|SDRSEARCH_PASS3NEAREST; 238 sal_uLong nOptions = SDRSEARCH_DEEP | SDRSEARCH_TESTMARKABLE; 239 240 SdrPageView* pSdrPageView = this->GetPageView(); 241 this->SdrView::PickObj(rPnt, lcl_getHitTolerance( this->GetFirstOutputDevice() ), pRet, pSdrPageView, nOptions); 242 243 if( pRet ) 244 { 245 //ignore some special shapes 246 rtl::OUString aShapeName = pRet->GetName(); 247 if( aShapeName.match(C2U("PlotAreaIncludingAxes")) || aShapeName.match(C2U("PlotAreaExcludingAxes")) ) 248 { 249 pRet->SetMarkProtect( true ); 250 return getHitObject( rPnt ); 251 } 252 253 //3d objects need a special treatment 254 //because the simple PickObj method is not accurate in this case for performance reasons 255 E3dObject* pE3d = dynamic_cast< E3dObject* >(pRet); 256 if( pE3d ) 257 { 258 E3dScene* pScene = pE3d->GetScene(); 259 if( pScene ) 260 { 261 // prepare result vector and call helper 262 ::std::vector< const E3dCompoundObject* > aHitList; 263 const basegfx::B2DPoint aHitPoint(rPnt.X(), rPnt.Y()); 264 getAllHit3DObjectsSortedFrontToBack(aHitPoint, *pScene, aHitList); 265 266 if(aHitList.size()) 267 { 268 // choose the frontmost hit 3D object of the scene 269 pRet = const_cast< E3dCompoundObject* >(aHitList[0]); 270 } 271 } 272 } 273 } 274 return pRet; 275 } 276 277 void DrawViewWrapper::MarkObject( SdrObject* pObj ) 278 { 279 bool bFrameDragSingles = true;//true == green == surrounding handles 280 if(pObj) 281 pObj->SetMarkProtect(false); 282 if( m_pMarkHandleProvider ) 283 bFrameDragSingles = m_pMarkHandleProvider->getFrameDragSingles(); 284 285 this->SetFrameDragSingles(bFrameDragSingles);//decide wether each single object should get handles 286 this->SdrView::MarkObj( pObj, this->GetPageView() ); 287 this->showMarkHandles(); 288 } 289 290 291 void DrawViewWrapper::setMarkHandleProvider( MarkHandleProvider* pMarkHandleProvider ) 292 { 293 m_pMarkHandleProvider = pMarkHandleProvider; 294 } 295 296 void DrawViewWrapper::CompleteRedraw(OutputDevice* pOut, const Region& rReg, sdr::contact::ViewObjectContactRedirector* /* pRedirector */) 297 { 298 svtools::ColorConfig aColorConfig; 299 Color aFillColor = Color( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor ); 300 this->SetApplicationBackgroundColor(aFillColor); 301 this->E3dView::CompleteRedraw( pOut, rReg ); 302 } 303 304 SdrObject* DrawViewWrapper::getSelectedObject() const 305 { 306 SdrObject* pObj(NULL); 307 const SdrMarkList& rMarkList = this->GetMarkedObjectList(); 308 if(rMarkList.GetMarkCount() == 1) 309 { 310 SdrMark* pMark = rMarkList.GetMark(0); 311 pObj = pMark->GetMarkedSdrObj(); 312 } 313 return pObj; 314 } 315 316 SdrObject* DrawViewWrapper::getTextEditObject() const 317 { 318 SdrObject* pObj = this->getSelectedObject(); 319 SdrObject* pTextObj = NULL; 320 if( pObj && pObj->HasTextEdit()) 321 pTextObj = (SdrTextObj*)pObj; 322 return pTextObj; 323 } 324 325 void DrawViewWrapper::attachParentReferenceDevice( const uno::Reference< frame::XModel > & xChartModel ) 326 { 327 OutputDevice * pParentRefDev( lcl_GetParentRefDevice( xChartModel )); 328 SdrOutliner * pOutliner( getOutliner()); 329 if( pParentRefDev && pOutliner ) 330 { 331 pOutliner->SetRefDevice( pParentRefDev ); 332 } 333 } 334 335 SdrOutliner* DrawViewWrapper::getOutliner() const 336 { 337 // lcl_initOutliner( m_apOutliner.get(), &GetModel()->GetDrawOutliner() ); 338 return m_apOutliner.get(); 339 } 340 341 SfxItemSet DrawViewWrapper::getPositionAndSizeItemSetFromMarkedObject() const 342 { 343 SfxItemSet aFullSet( GetModel()->GetItemPool(), 344 SID_ATTR_TRANSFORM_POS_X,SID_ATTR_TRANSFORM_ANGLE, 345 SID_ATTR_TRANSFORM_PROTECT_POS,SID_ATTR_TRANSFORM_AUTOHEIGHT, 346 SDRATTR_ECKENRADIUS,SDRATTR_ECKENRADIUS, 347 SID_ATTR_METRIC,SID_ATTR_METRIC, 348 0); 349 SfxItemSet aGeoSet( E3dView::GetGeoAttrFromMarked() ); 350 aFullSet.Put( aGeoSet ); 351 aFullSet.Put( SfxUInt16Item(SID_ATTR_METRIC,static_cast< sal_uInt16 >( ConfigurationAccess::getFieldUnit()))); 352 return aFullSet; 353 } 354 355 SdrObject* DrawViewWrapper::getNamedSdrObject( const rtl::OUString& rName ) const 356 { 357 if(rName.getLength()==0) 358 return 0; 359 SdrPageView* pSdrPageView = this->GetPageView(); 360 if( pSdrPageView ) 361 { 362 return DrawModelWrapper::getNamedSdrObject( rName, pSdrPageView->GetObjList() ); 363 } 364 return 0; 365 } 366 367 bool DrawViewWrapper::IsObjectHit( SdrObject* pObj, const Point& rPnt ) const 368 { 369 if(pObj) 370 { 371 Rectangle aRect(pObj->GetCurrentBoundRect()); 372 return aRect.IsInside(rPnt); 373 } 374 return false; 375 } 376 377 void DrawViewWrapper::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) 378 { 379 //prevent wrong reselection of objects 380 SdrModel* pSdrModel( this->GetModel() ); 381 if( pSdrModel && pSdrModel->isLocked() ) 382 return; 383 384 const SdrHint* pSdrHint = dynamic_cast< const SdrHint* >( &rHint ); 385 386 //#i76053# do nothing when only changes on the hidden draw page were made ( e.g. when the symbols for the dialogs are created ) 387 SdrPageView* pSdrPageView = this->GetPageView(); 388 if( pSdrHint && pSdrPageView ) 389 { 390 if( pSdrPageView->GetPage() != pSdrHint->GetPage() ) 391 return; 392 } 393 394 E3dView::Notify(rBC, rHint); 395 396 if( pSdrHint != 0 ) 397 { 398 SdrHintKind eKind = pSdrHint->GetKind(); 399 if( eKind == HINT_BEGEDIT ) 400 { 401 // #i79965# remember map mode 402 OSL_ASSERT( ! m_bRestoreMapMode ); 403 OutputDevice* pOutDev = this->GetFirstOutputDevice(); 404 if( pOutDev ) 405 { 406 m_aMapModeToRestore = pOutDev->GetMapMode(); 407 m_bRestoreMapMode = true; 408 } 409 } 410 else if( eKind == HINT_ENDEDIT ) 411 { 412 // #i79965# scroll back view when ending text edit 413 OSL_ASSERT( m_bRestoreMapMode ); 414 if( m_bRestoreMapMode ) 415 { 416 OutputDevice* pOutDev = this->GetFirstOutputDevice(); 417 if( pOutDev ) 418 { 419 pOutDev->SetMapMode( m_aMapModeToRestore ); 420 m_bRestoreMapMode = false; 421 } 422 } 423 } 424 } 425 } 426 427 SdrObject* DrawViewWrapper::getSdrObject( const uno::Reference< 428 drawing::XShape >& xShape ) 429 { 430 SdrObject* pRet = 0; 431 uno::Reference< lang::XUnoTunnel > xUnoTunnel( xShape, uno::UNO_QUERY ); 432 uno::Reference< lang::XTypeProvider > xTypeProvider( xShape, uno::UNO_QUERY ); 433 if(xUnoTunnel.is()&&xTypeProvider.is()) 434 { 435 SvxShape* pSvxShape = reinterpret_cast<SvxShape*>(xUnoTunnel->getSomething( SvxShape::getUnoTunnelId() )); 436 if(pSvxShape) 437 pRet = pSvxShape->GetSdrObject(); 438 } 439 return pRet; 440 } 441 442 //............................................................................. 443 } //namespace chart 444 //............................................................................. 445