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 ReInit(); 184 } 185 186 void DrawViewWrapper::ReInit() 187 { 188 OutputDevice* pOutDev = this->GetFirstOutputDevice(); 189 Size aOutputSize(100,100); 190 if(pOutDev) 191 aOutputSize = pOutDev->GetOutputSize(); 192 193 bPageVisible = false; 194 bPageBorderVisible = false; 195 bBordVisible = false; 196 bGridVisible = false; 197 bHlplVisible = false; 198 199 this->SetNoDragXorPolys(true);//for interactive 3D resize-dragging: paint only a single rectangle (not a simulated 3D object) 200 //this->SetResizeAtCenter(true);//for interactive resize-dragging: keep the object center fix 201 202 //a correct work area is at least necessary for correct values in the position and size dialog 203 Rectangle aRect(Point(0,0), aOutputSize); 204 this->SetWorkArea(aRect); 205 206 this->ShowSdrPage(this->GetModel()->GetPage(0)); 207 } 208 209 DrawViewWrapper::~DrawViewWrapper() 210 { 211 aComeBackTimer.Stop();//@todo this should be done in destructor of base class 212 UnmarkAllObj();//necessary to aavoid a paint call during the destructor hierarchy 213 } 214 215 SdrPageView* DrawViewWrapper::GetPageView() const 216 { 217 SdrPageView* pSdrPageView = this->GetSdrPageView(); 218 return pSdrPageView; 219 }; 220 221 //virtual 222 void DrawViewWrapper::SetMarkHandles() 223 { 224 if( m_pMarkHandleProvider && m_pMarkHandleProvider->getMarkHandles( aHdl ) ) 225 return; 226 else 227 SdrView::SetMarkHandles(); 228 } 229 230 SdrObject* DrawViewWrapper::getHitObject( const Point& rPnt ) const 231 { 232 SdrObject* pRet = NULL; 233 //sal_uLong nOptions =SDRSEARCH_DEEP|SDRSEARCH_PASS2BOUND|SDRSEARCH_PASS3NEAREST; 234 sal_uLong nOptions = SDRSEARCH_DEEP | SDRSEARCH_TESTMARKABLE; 235 236 SdrPageView* pSdrPageView = this->GetPageView(); 237 this->SdrView::PickObj(rPnt, lcl_getHitTolerance( this->GetFirstOutputDevice() ), pRet, pSdrPageView, nOptions); 238 239 if( pRet ) 240 { 241 //ignore some special shapes 242 rtl::OUString aShapeName = pRet->GetName(); 243 if( aShapeName.match(C2U("PlotAreaIncludingAxes")) || aShapeName.match(C2U("PlotAreaExcludingAxes")) ) 244 { 245 pRet->SetMarkProtect( true ); 246 return getHitObject( rPnt ); 247 } 248 249 //3d objects need a special treatment 250 //because the simple PickObj method is not accurate in this case for performance reasons 251 E3dObject* pE3d = dynamic_cast< E3dObject* >(pRet); 252 if( pE3d ) 253 { 254 E3dScene* pScene = pE3d->GetScene(); 255 if( pScene ) 256 { 257 // prepare result vector and call helper 258 ::std::vector< const E3dCompoundObject* > aHitList; 259 const basegfx::B2DPoint aHitPoint(rPnt.X(), rPnt.Y()); 260 getAllHit3DObjectsSortedFrontToBack(aHitPoint, *pScene, aHitList); 261 262 if(aHitList.size()) 263 { 264 // choose the frontmost hit 3D object of the scene 265 pRet = const_cast< E3dCompoundObject* >(aHitList[0]); 266 } 267 } 268 } 269 } 270 return pRet; 271 } 272 273 void DrawViewWrapper::MarkObject( SdrObject* pObj ) 274 { 275 bool bFrameDragSingles = true;//true == green == surrounding handles 276 if(pObj) 277 pObj->SetMarkProtect(false); 278 if( m_pMarkHandleProvider ) 279 bFrameDragSingles = m_pMarkHandleProvider->getFrameDragSingles(); 280 281 this->SetFrameDragSingles(bFrameDragSingles);//decide wether each single object should get handles 282 this->SdrView::MarkObj( pObj, this->GetPageView() ); 283 this->showMarkHandles(); 284 } 285 286 287 void DrawViewWrapper::setMarkHandleProvider( MarkHandleProvider* pMarkHandleProvider ) 288 { 289 m_pMarkHandleProvider = pMarkHandleProvider; 290 } 291 292 void DrawViewWrapper::CompleteRedraw(OutputDevice* pOut, const Region& rReg, sdr::contact::ViewObjectContactRedirector* /* pRedirector */) 293 { 294 svtools::ColorConfig aColorConfig; 295 Color aFillColor = Color( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor ); 296 this->SetApplicationBackgroundColor(aFillColor); 297 this->E3dView::CompleteRedraw( pOut, rReg ); 298 } 299 300 SdrObject* DrawViewWrapper::getSelectedObject() const 301 { 302 SdrObject* pObj(NULL); 303 const SdrMarkList& rMarkList = this->GetMarkedObjectList(); 304 if(rMarkList.GetMarkCount() == 1) 305 { 306 SdrMark* pMark = rMarkList.GetMark(0); 307 pObj = pMark->GetMarkedSdrObj(); 308 } 309 return pObj; 310 } 311 312 SdrObject* DrawViewWrapper::getTextEditObject() const 313 { 314 SdrObject* pObj = this->getSelectedObject(); 315 SdrObject* pTextObj = NULL; 316 if( pObj && pObj->HasTextEdit()) 317 pTextObj = (SdrTextObj*)pObj; 318 return pTextObj; 319 } 320 321 void DrawViewWrapper::attachParentReferenceDevice( const uno::Reference< frame::XModel > & xChartModel ) 322 { 323 OutputDevice * pParentRefDev( lcl_GetParentRefDevice( xChartModel )); 324 SdrOutliner * pOutliner( getOutliner()); 325 if( pParentRefDev && pOutliner ) 326 { 327 pOutliner->SetRefDevice( pParentRefDev ); 328 } 329 } 330 331 SdrOutliner* DrawViewWrapper::getOutliner() const 332 { 333 // lcl_initOutliner( m_apOutliner.get(), &GetModel()->GetDrawOutliner() ); 334 return m_apOutliner.get(); 335 } 336 337 SfxItemSet DrawViewWrapper::getPositionAndSizeItemSetFromMarkedObject() const 338 { 339 SfxItemSet aFullSet( GetModel()->GetItemPool(), 340 SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_ANGLE, 341 SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_AUTOHEIGHT, 342 SDRATTR_ECKENRADIUS, SDRATTR_ECKENRADIUS, 343 SID_ATTR_METRIC, SID_ATTR_METRIC, 344 0); 345 SfxItemSet aGeoSet( E3dView::GetGeoAttrFromMarked() ); 346 aFullSet.Put( aGeoSet ); 347 aFullSet.Put( SfxUInt16Item(SID_ATTR_METRIC,static_cast< sal_uInt16 >( ConfigurationAccess::getFieldUnit()))); 348 return aFullSet; 349 } 350 351 SdrObject* DrawViewWrapper::getNamedSdrObject( const rtl::OUString& rName ) const 352 { 353 if(rName.getLength()==0) 354 return 0; 355 SdrPageView* pSdrPageView = this->GetPageView(); 356 if( pSdrPageView ) 357 { 358 return DrawModelWrapper::getNamedSdrObject( rName, pSdrPageView->GetObjList() ); 359 } 360 return 0; 361 } 362 363 bool DrawViewWrapper::IsObjectHit( SdrObject* pObj, const Point& rPnt ) const 364 { 365 if(pObj) 366 { 367 Rectangle aRect(pObj->GetCurrentBoundRect()); 368 return aRect.IsInside(rPnt); 369 } 370 return false; 371 } 372 373 void DrawViewWrapper::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) 374 { 375 //prevent wrong reselection of objects 376 SdrModel* pSdrModel( this->GetModel() ); 377 if( pSdrModel && pSdrModel->isLocked() ) 378 return; 379 380 const SdrHint* pSdrHint = dynamic_cast< const SdrHint* >( &rHint ); 381 382 //#i76053# do nothing when only changes on the hidden draw page were made ( e.g. when the symbols for the dialogs are created ) 383 SdrPageView* pSdrPageView = this->GetPageView(); 384 if( pSdrHint && pSdrPageView ) 385 { 386 if( pSdrPageView->GetPage() != pSdrHint->GetPage() ) 387 return; 388 } 389 390 E3dView::Notify(rBC, rHint); 391 392 if( pSdrHint != 0 ) 393 { 394 SdrHintKind eKind = pSdrHint->GetKind(); 395 if( eKind == HINT_BEGEDIT ) 396 { 397 // #i79965# remember map mode 398 OSL_ASSERT( ! m_bRestoreMapMode ); 399 OutputDevice* pOutDev = this->GetFirstOutputDevice(); 400 if( pOutDev ) 401 { 402 m_aMapModeToRestore = pOutDev->GetMapMode(); 403 m_bRestoreMapMode = true; 404 } 405 } 406 else if( eKind == HINT_ENDEDIT ) 407 { 408 // #i79965# scroll back view when ending text edit 409 OSL_ASSERT( m_bRestoreMapMode ); 410 if( m_bRestoreMapMode ) 411 { 412 OutputDevice* pOutDev = this->GetFirstOutputDevice(); 413 if( pOutDev ) 414 { 415 pOutDev->SetMapMode( m_aMapModeToRestore ); 416 m_bRestoreMapMode = false; 417 } 418 } 419 } 420 } 421 } 422 423 SdrObject* DrawViewWrapper::getSdrObject( const uno::Reference< 424 drawing::XShape >& xShape ) 425 { 426 SdrObject* pRet = 0; 427 uno::Reference< lang::XUnoTunnel > xUnoTunnel( xShape, uno::UNO_QUERY ); 428 uno::Reference< lang::XTypeProvider > xTypeProvider( xShape, uno::UNO_QUERY ); 429 if(xUnoTunnel.is()&&xTypeProvider.is()) 430 { 431 SvxShape* pSvxShape = reinterpret_cast<SvxShape*>(xUnoTunnel->getSomething( SvxShape::getUnoTunnelId() )); 432 if(pSvxShape) 433 pRet = pSvxShape->GetSdrObject(); 434 } 435 return pRet; 436 } 437 438 //............................................................................. 439 } //namespace chart 440 //............................................................................. 441