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